@ni-kismet/sl-webapp-nipkg 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +212 -5
- package/dist/cli.js +218 -0
- package/dist/cli.js.map +1 -1
- package/dist/cli.test.js +305 -1
- package/dist/cli.test.js.map +1 -1
- package/dist/credentialStore.d.ts +18 -0
- package/dist/credentialStore.d.ts.map +1 -0
- package/dist/credentialStore.js +68 -0
- package/dist/credentialStore.js.map +1 -0
- package/dist/credentialStore.test.d.ts +2 -0
- package/dist/credentialStore.test.d.ts.map +1 -0
- package/dist/credentialStore.test.js +86 -0
- package/dist/credentialStore.test.js.map +1 -0
- package/dist/deployer.d.ts +47 -0
- package/dist/deployer.d.ts.map +1 -0
- package/dist/deployer.js +305 -0
- package/dist/deployer.js.map +1 -0
- package/dist/deployer.test.d.ts +2 -0
- package/dist/deployer.test.d.ts.map +1 -0
- package/dist/deployer.test.js +144 -0
- package/dist/deployer.test.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/slApiClient.d.ts +56 -0
- package/dist/slApiClient.d.ts.map +1 -0
- package/dist/slApiClient.js +118 -0
- package/dist/slApiClient.js.map +1 -0
- package/dist/types.d.ts +130 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +10 -7
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deployer.d.ts","sourceRoot":"","sources":["../src/deployer.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAKxD,qBAAa,wBAAwB;IACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAc;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyC;IAChE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;gBAE5B,UAAU,GAAE,WAAgB,EAAE,OAAO,GAAE,aAAkB;IAMrE;;;;OAIG;IACU,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IA4DpC;;;OAGG;IACU,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAoB1C,OAAO,CAAC,eAAe;IAIvB;;OAEG;YACW,UAAU;IAgCxB;;;OAGG;YACW,iBAAiB;IA4B/B;;OAEG;YACW,gBAAgB;IAc9B,OAAO,CAAC,WAAW;YAQL,aAAa;IAY3B,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,gBAAgB;IAgBxB;;OAEG;YACW,iBAAiB;YA0BjB,cAAc;IAa5B,OAAO,CAAC,cAAc;YAIR,UAAU;YAiBV,iBAAiB;YAOjB,gBAAgB;CAgDjC"}
|
package/dist/deployer.js
ADDED
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
import fs from 'fs-extra';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import readline from 'readline';
|
|
6
|
+
import { Readable } from 'stream';
|
|
7
|
+
import { SystemLinkNipkgBuilder } from './builder.js';
|
|
8
|
+
import { SlApiClient } from './slApiClient.js';
|
|
9
|
+
import { getCredential, normalizeHost } from './credentialStore.js';
|
|
10
|
+
export class SystemLinkWebAppDeployer {
|
|
11
|
+
fullConfig;
|
|
12
|
+
config;
|
|
13
|
+
options;
|
|
14
|
+
constructor(fullConfig = {}, options = {}) {
|
|
15
|
+
this.fullConfig = fullConfig;
|
|
16
|
+
this.config = fullConfig.deployment ?? {};
|
|
17
|
+
this.options = options;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Deploy a nipkg file to SystemLink.
|
|
21
|
+
* Creates a new WebApp if update=false, or updates existing if update=true.
|
|
22
|
+
* Throws on any failure — callers are responsible for error handling.
|
|
23
|
+
*/
|
|
24
|
+
async deploy() {
|
|
25
|
+
console.log(chalk.cyan('🚀 Starting SystemLink WebApp deployment...'));
|
|
26
|
+
let builtNipkgDir;
|
|
27
|
+
if (this.options.build !== undefined && this.options.build !== false) {
|
|
28
|
+
builtNipkgDir = await this.buildNipkg();
|
|
29
|
+
}
|
|
30
|
+
const host = this.resolveHost();
|
|
31
|
+
const apiKey = await this.resolveApiKey(host);
|
|
32
|
+
if (!host) {
|
|
33
|
+
throw new Error('SystemLink host is required (--host, SYSTEMLINK_HOST env var, or config.deployment.host)');
|
|
34
|
+
}
|
|
35
|
+
if (!apiKey) {
|
|
36
|
+
throw new Error('API key is required for deployment. Use --api-key, set SYSTEMLINK_API_KEY env var, or run: sl-webapp-nipkg login');
|
|
37
|
+
}
|
|
38
|
+
let nipkgPath;
|
|
39
|
+
if (this.options.nipkg) {
|
|
40
|
+
const stat = await fs.stat(this.options.nipkg).catch(() => null);
|
|
41
|
+
if (stat?.isDirectory()) {
|
|
42
|
+
nipkgPath = await this.pickNipkgFromDir(this.options.nipkg, this.options.latest ?? false);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
nipkgPath = this.options.nipkg;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
else if (builtNipkgDir) {
|
|
49
|
+
nipkgPath = await this.pickNipkgFromDir(builtNipkgDir, this.options.latest ?? false);
|
|
50
|
+
}
|
|
51
|
+
if (!nipkgPath) {
|
|
52
|
+
nipkgPath = await this.discoverNipkgPath();
|
|
53
|
+
}
|
|
54
|
+
if (!nipkgPath) {
|
|
55
|
+
throw new Error('No .nipkg file found. Provide --nipkg (file or directory), set outputDir in config, or use --build to build first.');
|
|
56
|
+
}
|
|
57
|
+
if (!fs.existsSync(nipkgPath)) {
|
|
58
|
+
throw new Error(`nipkg file not found: ${nipkgPath}`);
|
|
59
|
+
}
|
|
60
|
+
const client = this.createApiClient(host, apiKey);
|
|
61
|
+
const appId = this.options.appId;
|
|
62
|
+
if (this.options.update) {
|
|
63
|
+
if (!appId) {
|
|
64
|
+
throw new Error('--app-id is required when using --update flag');
|
|
65
|
+
}
|
|
66
|
+
console.log(chalk.cyan(`📖 Fetching current WebApp data (${appId})...`));
|
|
67
|
+
const currentData = await client.getWebApp(appId);
|
|
68
|
+
console.log(chalk.green('✓ WebApp data fetched'));
|
|
69
|
+
await this.putWebAppMetadata(client, appId, currentData);
|
|
70
|
+
await this.putWebAppContent(client, appId, nipkgPath);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
const newAppId = await this.postWebApp(client);
|
|
74
|
+
await this.putWebAppContent(client, newAppId, nipkgPath);
|
|
75
|
+
}
|
|
76
|
+
console.log(chalk.green.bold('🎯 Deployment completed successfully!'));
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Delete a WebApp by ID.
|
|
80
|
+
* Throws on any failure — callers are responsible for error handling.
|
|
81
|
+
*/
|
|
82
|
+
async deleteWebApp() {
|
|
83
|
+
const host = this.resolveHost();
|
|
84
|
+
const apiKey = await this.resolveApiKey(host);
|
|
85
|
+
const appId = this.options.appId;
|
|
86
|
+
if (!host) {
|
|
87
|
+
throw new Error('SystemLink host is required (--host, SYSTEMLINK_HOST env var, or config.deployment.host)');
|
|
88
|
+
}
|
|
89
|
+
if (!apiKey) {
|
|
90
|
+
throw new Error('API key is required. Use --api-key, set SYSTEMLINK_API_KEY env var, or run: sl-webapp-nipkg login');
|
|
91
|
+
}
|
|
92
|
+
if (!appId) {
|
|
93
|
+
throw new Error('--app-id is required for delete');
|
|
94
|
+
}
|
|
95
|
+
console.log(chalk.cyan(`🗑️ Deleting WebApp (${appId})...`));
|
|
96
|
+
await this.createApiClient(host, apiKey).deleteWebApp(appId);
|
|
97
|
+
console.log(chalk.green.bold(`🗑️ WebApp ${appId} deleted successfully!`));
|
|
98
|
+
}
|
|
99
|
+
createApiClient(host, apiKey) {
|
|
100
|
+
return new SlApiClient(host, apiKey, this.resolveTimeout());
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Create a new WebApp in SystemLink. Returns the new WebApp ID.
|
|
104
|
+
*/
|
|
105
|
+
async postWebApp(client) {
|
|
106
|
+
const name = this.resolveName();
|
|
107
|
+
const workspaceId = this.resolveWorkspaceId();
|
|
108
|
+
const policyIds = this.resolvePolicyIds();
|
|
109
|
+
const properties = await this.resolveProperties();
|
|
110
|
+
if (!name) {
|
|
111
|
+
throw new Error('WebApp name is required (--name, config.deployment.name)');
|
|
112
|
+
}
|
|
113
|
+
if (!workspaceId) {
|
|
114
|
+
throw new Error('Workspace ID is required (--workspace-id, config.deployment.workspaceId)');
|
|
115
|
+
}
|
|
116
|
+
const body = {
|
|
117
|
+
name,
|
|
118
|
+
type: 'WebVI',
|
|
119
|
+
workspace: workspaceId,
|
|
120
|
+
policyIds,
|
|
121
|
+
...(properties !== undefined && { properties })
|
|
122
|
+
};
|
|
123
|
+
if (this.options.verbose) {
|
|
124
|
+
console.log(chalk.blue('📝 Creating WebApp with:'));
|
|
125
|
+
console.log(chalk.gray(JSON.stringify(body, null, 2)));
|
|
126
|
+
}
|
|
127
|
+
console.log(chalk.cyan(`📦 Creating WebApp "${name}"...`));
|
|
128
|
+
const result = await client.createWebApp(body);
|
|
129
|
+
console.log(chalk.green(`✓ WebApp created with ID: ${result.id}`));
|
|
130
|
+
return result.id;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Update WebApp metadata (name, workspace, policyIds, properties).
|
|
134
|
+
* Preserves existing values for any field not explicitly provided.
|
|
135
|
+
*/
|
|
136
|
+
async putWebAppMetadata(client, appId, currentData) {
|
|
137
|
+
const nameOverride = this.resolveName();
|
|
138
|
+
const workspaceOverride = this.resolveWorkspaceId();
|
|
139
|
+
const policyIdsOverride = this.resolvePolicyIds();
|
|
140
|
+
const propertiesOverride = await this.resolveProperties();
|
|
141
|
+
const body = {
|
|
142
|
+
name: nameOverride || currentData.name,
|
|
143
|
+
workspace: workspaceOverride || currentData.workspace,
|
|
144
|
+
policyIds: policyIdsOverride.length > 0 ? policyIdsOverride : (currentData.policyIds ?? [])
|
|
145
|
+
};
|
|
146
|
+
if (propertiesOverride !== undefined) {
|
|
147
|
+
body.properties = propertiesOverride;
|
|
148
|
+
}
|
|
149
|
+
else if (currentData.properties !== undefined) {
|
|
150
|
+
body.properties = currentData.properties;
|
|
151
|
+
}
|
|
152
|
+
if (this.options.verbose) {
|
|
153
|
+
console.log(chalk.blue('📝 Updating WebApp metadata with:'));
|
|
154
|
+
console.log(chalk.gray(JSON.stringify(body, null, 2)));
|
|
155
|
+
}
|
|
156
|
+
console.log(chalk.cyan(`🧾 Updating WebApp metadata (${appId})...`));
|
|
157
|
+
await client.updateWebApp(appId, body);
|
|
158
|
+
console.log(chalk.green('✓ Metadata updated successfully'));
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Upload nipkg content to a WebApp via streaming.
|
|
162
|
+
*/
|
|
163
|
+
async putWebAppContent(client, appId, nipkgPath) {
|
|
164
|
+
console.log(chalk.cyan(`📤 Uploading content to WebApp (${appId})...`));
|
|
165
|
+
const fileSize = (await fs.stat(nipkgPath)).size;
|
|
166
|
+
if (this.options.verbose) {
|
|
167
|
+
console.log(chalk.blue(`📊 File size: ${(fileSize / 1024 / 1024).toFixed(2)} MB`));
|
|
168
|
+
}
|
|
169
|
+
const fileStream = Readable.toWeb(fs.createReadStream(nipkgPath));
|
|
170
|
+
await client.uploadContent(appId, fileStream, fileSize);
|
|
171
|
+
console.log(chalk.green('✓ Content uploaded successfully'));
|
|
172
|
+
}
|
|
173
|
+
resolveHost() {
|
|
174
|
+
const rawHost = this.options.host || process.env.SYSTEMLINK_HOST || this.config.host;
|
|
175
|
+
if (!rawHost) {
|
|
176
|
+
return undefined;
|
|
177
|
+
}
|
|
178
|
+
return rawHost.trim().replace(/\/+$/, '');
|
|
179
|
+
}
|
|
180
|
+
async resolveApiKey(host) {
|
|
181
|
+
const explicit = this.options.apiKey || process.env.SYSTEMLINK_API_KEY;
|
|
182
|
+
if (explicit) {
|
|
183
|
+
return explicit.trim() || undefined;
|
|
184
|
+
}
|
|
185
|
+
if (host) {
|
|
186
|
+
const stored = await getCredential(normalizeHost(host));
|
|
187
|
+
return stored?.apiKey;
|
|
188
|
+
}
|
|
189
|
+
return undefined;
|
|
190
|
+
}
|
|
191
|
+
resolveName() {
|
|
192
|
+
return this.options.name || this.config.name || this.fullConfig.displayName;
|
|
193
|
+
}
|
|
194
|
+
resolveWorkspaceId() {
|
|
195
|
+
return this.options.workspaceId || this.config.workspaceId;
|
|
196
|
+
}
|
|
197
|
+
resolvePolicyIds() {
|
|
198
|
+
const policyIds = this.options.policyIds ?? this.config.policyIds;
|
|
199
|
+
if (policyIds === undefined) {
|
|
200
|
+
return [];
|
|
201
|
+
}
|
|
202
|
+
if (typeof policyIds === 'string') {
|
|
203
|
+
return policyIds.split(',').map(id => id.trim()).filter(id => id);
|
|
204
|
+
}
|
|
205
|
+
return policyIds
|
|
206
|
+
.map((id) => id.trim())
|
|
207
|
+
.filter((id) => id);
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Resolve properties, auto-injecting `version` from package.json if absent.
|
|
211
|
+
*/
|
|
212
|
+
async resolveProperties() {
|
|
213
|
+
const properties = this.options.properties ?? this.config.properties;
|
|
214
|
+
if (properties === undefined) {
|
|
215
|
+
const version = await this.resolveVersion();
|
|
216
|
+
if (version) {
|
|
217
|
+
return { version };
|
|
218
|
+
}
|
|
219
|
+
return undefined;
|
|
220
|
+
}
|
|
221
|
+
const result = {};
|
|
222
|
+
for (const [key, value] of Object.entries(properties)) {
|
|
223
|
+
result[key] = String(value);
|
|
224
|
+
}
|
|
225
|
+
if (!result.version) {
|
|
226
|
+
const version = await this.resolveVersion();
|
|
227
|
+
if (version) {
|
|
228
|
+
result.version = version;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return result;
|
|
232
|
+
}
|
|
233
|
+
async resolveVersion() {
|
|
234
|
+
if (this.options.version) {
|
|
235
|
+
return this.options.version;
|
|
236
|
+
}
|
|
237
|
+
try {
|
|
238
|
+
const packageJson = await fs.readJson(path.resolve('package.json'));
|
|
239
|
+
return packageJson.version;
|
|
240
|
+
}
|
|
241
|
+
catch (_error) {
|
|
242
|
+
return undefined;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
resolveTimeout() {
|
|
246
|
+
return this.options.timeout ?? this.config.timeout ?? 30000;
|
|
247
|
+
}
|
|
248
|
+
async buildNipkg() {
|
|
249
|
+
console.log(chalk.cyan('🏗️ Building nipkg package...'));
|
|
250
|
+
const buildCommand = typeof this.options.build === 'string' ? this.options.build : undefined;
|
|
251
|
+
const builder = new SystemLinkNipkgBuilder(this.fullConfig, {
|
|
252
|
+
build: buildCommand || true,
|
|
253
|
+
verbose: this.options.verbose,
|
|
254
|
+
buildSuffix: this.options.buildSuffix,
|
|
255
|
+
skipCleanup: this.options.skipCleanup
|
|
256
|
+
});
|
|
257
|
+
await builder.build();
|
|
258
|
+
return this.fullConfig.outputDir ?? path.resolve('dist', 'nipkg');
|
|
259
|
+
}
|
|
260
|
+
async discoverNipkgPath() {
|
|
261
|
+
const nipkgDir = this.fullConfig.outputDir
|
|
262
|
+
?? path.resolve('dist', 'nipkg');
|
|
263
|
+
return await this.pickNipkgFromDir(nipkgDir, this.options.latest ?? false);
|
|
264
|
+
}
|
|
265
|
+
async pickNipkgFromDir(dir, autoLatest) {
|
|
266
|
+
if (!fs.existsSync(dir)) {
|
|
267
|
+
return undefined;
|
|
268
|
+
}
|
|
269
|
+
const files = await fs.readdir(dir);
|
|
270
|
+
const nipkgFilesWithStats = await Promise.all(files
|
|
271
|
+
.filter(f => f.endsWith('.nipkg'))
|
|
272
|
+
.map(async (f) => ({ name: f, mtime: (await fs.stat(path.join(dir, f))).mtime })));
|
|
273
|
+
const nipkgFiles = nipkgFilesWithStats
|
|
274
|
+
.sort((a, b) => b.mtime.getTime() - a.mtime.getTime())
|
|
275
|
+
.map(f => f.name);
|
|
276
|
+
if (nipkgFiles.length === 0) {
|
|
277
|
+
return undefined;
|
|
278
|
+
}
|
|
279
|
+
if (autoLatest || nipkgFiles.length === 1) {
|
|
280
|
+
const selected = nipkgFiles[0];
|
|
281
|
+
console.log(chalk.green(`✓ Selected nipkg: ${selected}`));
|
|
282
|
+
return path.join(dir, selected);
|
|
283
|
+
}
|
|
284
|
+
// Multiple files found — prompt user to pick one
|
|
285
|
+
console.log(chalk.cyan('📦 Found multiple nipkg files:'));
|
|
286
|
+
nipkgFiles.forEach((file, index) => {
|
|
287
|
+
console.log(chalk.gray(` ${index + 1}. ${file}`));
|
|
288
|
+
});
|
|
289
|
+
console.log(chalk.yellow('💡 Use --latest to auto-select the newest file without prompting.'));
|
|
290
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
291
|
+
const answer = await new Promise(resolve => {
|
|
292
|
+
rl.question(chalk.yellow(`Select a file [1-${nipkgFiles.length}] (default: 1 for latest): `), resolve);
|
|
293
|
+
});
|
|
294
|
+
rl.close();
|
|
295
|
+
const trimmed = answer.trim();
|
|
296
|
+
const choice = trimmed === '' ? 1 : parseInt(trimmed, 10);
|
|
297
|
+
if (isNaN(choice) || choice < 1 || choice > nipkgFiles.length) {
|
|
298
|
+
throw new Error(`Invalid selection: "${trimmed}". Enter a number between 1 and ${nipkgFiles.length}.`);
|
|
299
|
+
}
|
|
300
|
+
const selected = nipkgFiles[choice - 1];
|
|
301
|
+
console.log(chalk.green(`✓ Selected nipkg: ${selected}`));
|
|
302
|
+
return path.join(dir, selected);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
//# sourceMappingURL=deployer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deployer.js","sourceRoot":"","sources":["../src/deployer.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAElC,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,WAAW,EAA0C,MAAM,kBAAkB,CAAC;AACvF,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAEpE,MAAM,OAAO,wBAAwB;IAChB,UAAU,CAAc;IACxB,MAAM,CAAyC;IAC/C,OAAO,CAAgB;IAExC,YAAY,aAA0B,EAAE,EAAE,UAAyB,EAAE;QACjE,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,UAAU,IAAI,EAAE,CAAC;QAC1C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IAC3B,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,MAAM;QACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC,CAAC;QAEvE,IAAI,aAAiC,CAAC;QACtC,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;YACnE,aAAa,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QAC5C,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAE9C,IAAI,CAAC,IAAI,EAAE,CAAC;YACR,MAAM,IAAI,KAAK,CAAC,0FAA0F,CAAC,CAAC;QAChH,CAAC;QACD,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,kHAAkH,CAAC,CAAC;QACxI,CAAC;QAED,IAAI,SAA6B,CAAC;QAClC,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACrB,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;YACjE,IAAI,IAAI,EAAE,WAAW,EAAE,EAAE,CAAC;gBACtB,SAAS,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC;YAC9F,CAAC;iBAAM,CAAC;gBACJ,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;YACnC,CAAC;QACL,CAAC;aAAM,IAAI,aAAa,EAAE,CAAC;YACvB,SAAS,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,aAAa,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC;QACzF,CAAC;QACD,IAAI,CAAC,SAAS,EAAE,CAAC;YACb,SAAS,GAAG,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC/C,CAAC;QAED,IAAI,CAAC,SAAS,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,oHAAoH,CAAC,CAAC;QAC1I,CAAC;QACD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,yBAAyB,SAAS,EAAE,CAAC,CAAC;QAC1D,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAClD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QAEjC,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YACtB,IAAI,CAAC,KAAK,EAAE,CAAC;gBACT,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;YACrE,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,oCAAoC,KAAK,MAAM,CAAC,CAAC,CAAC;YACzE,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YAClD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAC;YAClD,MAAM,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;YACzD,MAAM,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QAC1D,CAAC;aAAM,CAAC;YACJ,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YAC/C,MAAM,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC7D,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC,CAAC;IAC3E,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,YAAY;QACrB,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QAEjC,IAAI,CAAC,IAAI,EAAE,CAAC;YACR,MAAM,IAAI,KAAK,CAAC,0FAA0F,CAAC,CAAC;QAChH,CAAC;QACD,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,mGAAmG,CAAC,CAAC;QACzH,CAAC;QACD,IAAI,CAAC,KAAK,EAAE,CAAC;YACT,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACvD,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,wBAAwB,KAAK,MAAM,CAAC,CAAC,CAAC;QAC7D,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAC7D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,KAAK,wBAAwB,CAAC,CAAC,CAAC;IAC/E,CAAC;IAEO,eAAe,CAAC,IAAY,EAAE,MAAc;QAChD,OAAO,IAAI,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC;IAChE,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,UAAU,CAAC,MAAmB;QACxC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QAChC,MAAM,WAAW,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC9C,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC1C,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAElD,IAAI,CAAC,IAAI,EAAE,CAAC;YACR,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;QAChF,CAAC;QACD,IAAI,CAAC,WAAW,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,0EAA0E,CAAC,CAAC;QAChG,CAAC;QAED,MAAM,IAAI,GAAwB;YAC9B,IAAI;YACJ,IAAI,EAAE,OAAO;YACb,SAAS,EAAE,WAAW;YACtB,SAAS;YACT,GAAG,CAAC,UAAU,KAAK,SAAS,IAAI,EAAE,UAAU,EAAE,CAAC;SAClD,CAAC;QAEF,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC;YACpD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3D,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,uBAAuB,IAAI,MAAM,CAAC,CAAC,CAAC;QAC3D,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,6BAA6B,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QACnE,OAAO,MAAM,CAAC,EAAE,CAAC;IACrB,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,iBAAiB,CAAC,MAAmB,EAAE,KAAa,EAAE,WAA8B;QAC9F,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QACxC,MAAM,iBAAiB,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACpD,MAAM,iBAAiB,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAClD,MAAM,kBAAkB,GAAG,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAE1D,MAAM,IAAI,GAA+B;YACrC,IAAI,EAAE,YAAY,IAAI,WAAW,CAAC,IAAI;YACtC,SAAS,EAAE,iBAAiB,IAAI,WAAW,CAAC,SAAS;YACrD,SAAS,EAAE,iBAAiB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,SAAS,IAAI,EAAE,CAAC;SAC9F,CAAC;QAEF,IAAI,kBAAkB,KAAK,SAAS,EAAE,CAAC;YACnC,IAAI,CAAC,UAAU,GAAG,kBAAkB,CAAC;QACzC,CAAC;aAAM,IAAI,WAAW,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YAC9C,IAAI,CAAC,UAAU,GAAG,WAAW,CAAC,UAAU,CAAC;QAC7C,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC,CAAC;YAC7D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3D,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gCAAgC,KAAK,MAAM,CAAC,CAAC,CAAC;QACrE,MAAM,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACvC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC,CAAC;IAChE,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,gBAAgB,CAAC,MAAmB,EAAE,KAAa,EAAE,SAAiB;QAChF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,mCAAmC,KAAK,MAAM,CAAC,CAAC,CAAC;QAExE,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;QAEjD,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,QAAQ,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QACvF,CAAC;QAED,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAA+B,CAAC;QAChG,MAAM,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC,CAAC;IAChE,CAAC;IAEO,WAAW;QACf,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;QACrF,IAAI,CAAC,OAAO,EAAE,CAAC;YACX,OAAO,SAAS,CAAC;QACrB,CAAC;QACD,OAAO,OAAO,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC9C,CAAC;IAEO,KAAK,CAAC,aAAa,CAAC,IAAwB;QAChD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;QACvE,IAAI,QAAQ,EAAE,CAAC;YACX,OAAO,QAAQ,CAAC,IAAI,EAAE,IAAI,SAAS,CAAC;QACxC,CAAC;QACD,IAAI,IAAI,EAAE,CAAC;YACP,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;YACxD,OAAO,MAAM,EAAE,MAAM,CAAC;QAC1B,CAAC;QACD,OAAO,SAAS,CAAC;IACrB,CAAC;IAEO,WAAW;QACf,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;IAChF,CAAC;IAEO,kBAAkB;QACtB,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;IAC/D,CAAC;IAEO,gBAAgB;QACpB,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;QAElE,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,EAAE,CAAC;QACd,CAAC;QAED,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;YAChC,OAAO,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACtE,CAAC;QAED,OAAO,SAAS;aACX,GAAG,CAAC,CAAC,EAAU,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;aAC9B,MAAM,CAAC,CAAC,EAAU,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;IACpC,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,iBAAiB;QAC3B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC;QAErE,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC3B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;YAC5C,IAAI,OAAO,EAAE,CAAC;gBACV,OAAO,EAAE,OAAO,EAAE,CAAC;YACvB,CAAC;YACD,OAAO,SAAS,CAAC;QACrB,CAAC;QAED,MAAM,MAAM,GAA8B,EAAE,CAAC;QAC7C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;YACpD,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAClB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;YAC5C,IAAI,OAAO,EAAE,CAAC;gBACV,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC;YAC7B,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAC;IAClB,CAAC;IAEO,KAAK,CAAC,cAAc;QACxB,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;QAChC,CAAC;QAED,IAAI,CAAC;YACD,MAAM,WAAW,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAyB,CAAC;YAC5F,OAAO,WAAW,CAAC,OAAO,CAAC;QAC/B,CAAC;QAAC,OAAO,MAAM,EAAE,CAAC;YACd,OAAO,SAAS,CAAC;QACrB,CAAC;IACL,CAAC;IAEO,cAAc;QAClB,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,KAAK,CAAC;IAChE,CAAC;IAEO,KAAK,CAAC,UAAU;QACpB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC,CAAC;QAEzD,MAAM,YAAY,GAAG,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;QAE7F,MAAM,OAAO,GAAG,IAAI,sBAAsB,CAAC,IAAI,CAAC,UAAU,EAAE;YACxD,KAAK,EAAE,YAAY,IAAI,IAAI;YAC3B,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO;YAC7B,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW;YACrC,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW;SACxC,CAAC,CAAC;QAEH,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QAEtB,OAAO,IAAI,CAAC,UAAU,CAAC,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtE,CAAC;IAEO,KAAK,CAAC,iBAAiB;QAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS;eACnC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAErC,OAAO,MAAM,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC;IAC/E,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAC,GAAW,EAAE,UAAmB;QAC3D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACtB,OAAO,SAAS,CAAC;QACrB,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,mBAAmB,GAAG,MAAM,OAAO,CAAC,GAAG,CACzC,KAAK;aACA,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;aACjC,GAAG,CAAC,KAAK,EAAC,CAAC,EAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CACtF,CAAC;QACF,MAAM,UAAU,GAAG,mBAAmB;aACjC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;aACrD,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAEtB,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,SAAS,CAAC;QACrB,CAAC;QAED,IAAI,UAAU,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxC,MAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;YAC/B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,qBAAqB,QAAQ,EAAE,CAAC,CAAC,CAAC;YAC1D,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACpC,CAAC;QAED,iDAAiD;QACjD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC,CAAC;QAC1D,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;YAC/B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,mEAAmE,CAAC,CAAC,CAAC;QAE/F,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QACtF,MAAM,MAAM,GAAG,MAAM,IAAI,OAAO,CAAS,OAAO,CAAC,EAAE;YAC/C,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,oBAAoB,UAAU,CAAC,MAAM,6BAA6B,CAAC,EAAE,OAAO,CAAC,CAAC;QAC3G,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,KAAK,EAAE,CAAC;QAEX,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAC1D,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,IAAI,MAAM,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC;YAC5D,MAAM,IAAI,KAAK,CAAC,uBAAuB,OAAO,mCAAmC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;QAC3G,CAAC;QAED,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACxC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,qBAAqB,QAAQ,EAAE,CAAC,CAAC,CAAC;QAC1D,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACpC,CAAC;CACJ"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deployer.test.d.ts","sourceRoot":"","sources":["../src/deployer.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import os from 'os';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { afterAll, afterEach, beforeAll, describe, expect, it, vi } from 'vitest';
|
|
5
|
+
import { SystemLinkWebAppDeployer } from './deployer.js';
|
|
6
|
+
import * as credentialStore from './credentialStore.js';
|
|
7
|
+
function createMockResponse(ok, status, jsonBody, textBody = '') {
|
|
8
|
+
return {
|
|
9
|
+
ok,
|
|
10
|
+
status,
|
|
11
|
+
json: async () => await Promise.resolve(jsonBody),
|
|
12
|
+
text: async () => await Promise.resolve(textBody)
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
describe('SystemLinkWebAppDeployer', () => {
|
|
16
|
+
const host = 'https://test.systemlink.example.com';
|
|
17
|
+
const apiKey = 'test-api-key';
|
|
18
|
+
const webAppId = '35075240-68a1-431b-afe1-9ce76da46de3';
|
|
19
|
+
let nipkgPath = '';
|
|
20
|
+
let fetchMock;
|
|
21
|
+
beforeAll(async () => {
|
|
22
|
+
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'sl-webapp-nipkg-'));
|
|
23
|
+
nipkgPath = path.join(tempDir, 'test-app.nipkg');
|
|
24
|
+
await fs.writeFile(nipkgPath, Buffer.from('test nipkg content'));
|
|
25
|
+
});
|
|
26
|
+
afterAll(async () => {
|
|
27
|
+
if (nipkgPath.length > 0) {
|
|
28
|
+
await fs.remove(path.dirname(nipkgPath));
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
afterEach(() => {
|
|
32
|
+
vi.unstubAllGlobals();
|
|
33
|
+
vi.restoreAllMocks();
|
|
34
|
+
});
|
|
35
|
+
it('creates webapp and uploads content', async () => {
|
|
36
|
+
fetchMock = vi.fn();
|
|
37
|
+
fetchMock.mockResolvedValueOnce(createMockResponse(true, 200, { id: webAppId }));
|
|
38
|
+
fetchMock.mockResolvedValueOnce(createMockResponse(true, 200, {}, ''));
|
|
39
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
40
|
+
const deployer = new SystemLinkWebAppDeployer({
|
|
41
|
+
deployment: {
|
|
42
|
+
host,
|
|
43
|
+
name: 'My App',
|
|
44
|
+
workspaceId: '45bc27cf-85c6-485c-945d-a51e664f511d',
|
|
45
|
+
policyIds: [],
|
|
46
|
+
properties: { version: '1.0.0', description: 'sample' }
|
|
47
|
+
}
|
|
48
|
+
}, { nipkg: nipkgPath, apiKey });
|
|
49
|
+
await deployer.deploy();
|
|
50
|
+
expect(fetchMock).toHaveBeenCalledTimes(2);
|
|
51
|
+
expect(fetchMock.mock.calls[0]?.[0]).toBe(`${host}/niapp/v1/webapps`);
|
|
52
|
+
expect(fetchMock.mock.calls[1]?.[0]).toBe(`${host}/niapp/v1/webapps/${webAppId}/content`);
|
|
53
|
+
});
|
|
54
|
+
it('updates existing webapp with --update mode', async () => {
|
|
55
|
+
fetchMock = vi.fn();
|
|
56
|
+
// GET current data
|
|
57
|
+
fetchMock.mockResolvedValueOnce(createMockResponse(true, 200, {
|
|
58
|
+
id: webAppId,
|
|
59
|
+
name: 'My App',
|
|
60
|
+
workspace: '45bc27cf-85c6-485c-945d-a51e664f511d',
|
|
61
|
+
policyIds: []
|
|
62
|
+
}));
|
|
63
|
+
// PUT metadata
|
|
64
|
+
fetchMock.mockResolvedValueOnce(createMockResponse(true, 200, {}, ''));
|
|
65
|
+
// PUT content
|
|
66
|
+
fetchMock.mockResolvedValueOnce(createMockResponse(true, 200, {}, ''));
|
|
67
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
68
|
+
const deployer = new SystemLinkWebAppDeployer({
|
|
69
|
+
deployment: {
|
|
70
|
+
host,
|
|
71
|
+
name: 'My App',
|
|
72
|
+
workspaceId: '45bc27cf-85c6-485c-945d-a51e664f511d'
|
|
73
|
+
}
|
|
74
|
+
}, { nipkg: nipkgPath, update: true, appId: webAppId, apiKey });
|
|
75
|
+
await deployer.deploy();
|
|
76
|
+
expect(fetchMock).toHaveBeenCalledTimes(3);
|
|
77
|
+
expect(fetchMock.mock.calls[0]?.[0]).toBe(`${host}/niapp/v1/webapps/${webAppId}`);
|
|
78
|
+
expect(fetchMock.mock.calls[1]?.[0]).toBe(`${host}/niapp/v1/webapps/${webAppId}`);
|
|
79
|
+
expect(fetchMock.mock.calls[2]?.[0]).toBe(`${host}/niapp/v1/webapps/${webAppId}/content`);
|
|
80
|
+
});
|
|
81
|
+
it('parses policyIds from comma-separated string', async () => {
|
|
82
|
+
fetchMock = vi.fn();
|
|
83
|
+
fetchMock.mockResolvedValueOnce(createMockResponse(true, 200, { id: webAppId }));
|
|
84
|
+
fetchMock.mockResolvedValueOnce(createMockResponse(true, 200, {}, ''));
|
|
85
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
86
|
+
const deployer = new SystemLinkWebAppDeployer({
|
|
87
|
+
deployment: {
|
|
88
|
+
host,
|
|
89
|
+
name: 'My App',
|
|
90
|
+
workspaceId: '45bc27cf-85c6-485c-945d-a51e664f511d'
|
|
91
|
+
}
|
|
92
|
+
}, { nipkg: nipkgPath, policyIds: 'policy-1, policy-2,policy-3', apiKey });
|
|
93
|
+
await deployer.deploy();
|
|
94
|
+
const requestInit = fetchMock.mock.calls[0]?.[1];
|
|
95
|
+
const bodyText = requestInit.body;
|
|
96
|
+
const body = JSON.parse(bodyText);
|
|
97
|
+
expect(body.policyIds).toEqual(['policy-1', 'policy-2', 'policy-3']);
|
|
98
|
+
});
|
|
99
|
+
it('uses properties object for webapp creation', async () => {
|
|
100
|
+
fetchMock = vi.fn();
|
|
101
|
+
fetchMock.mockResolvedValueOnce(createMockResponse(true, 200, { id: webAppId }));
|
|
102
|
+
fetchMock.mockResolvedValueOnce(createMockResponse(true, 200, {}, ''));
|
|
103
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
104
|
+
const deployer = new SystemLinkWebAppDeployer({
|
|
105
|
+
deployment: {
|
|
106
|
+
host,
|
|
107
|
+
name: 'My App',
|
|
108
|
+
workspaceId: '45bc27cf-85c6-485c-945d-a51e664f511d'
|
|
109
|
+
}
|
|
110
|
+
}, {
|
|
111
|
+
nipkg: nipkgPath,
|
|
112
|
+
apiKey,
|
|
113
|
+
properties: { version: '2.0.0', description: 'my description' }
|
|
114
|
+
});
|
|
115
|
+
await deployer.deploy();
|
|
116
|
+
const requestInit = fetchMock.mock.calls[0]?.[1];
|
|
117
|
+
const bodyText = requestInit.body;
|
|
118
|
+
const body = JSON.parse(bodyText);
|
|
119
|
+
expect(body.properties.version).toBe('2.0.0');
|
|
120
|
+
expect(body.properties.description).toBe('my description');
|
|
121
|
+
});
|
|
122
|
+
it('uses stored credential when no explicit api key is given', async () => {
|
|
123
|
+
fetchMock = vi.fn();
|
|
124
|
+
fetchMock.mockResolvedValueOnce(createMockResponse(true, 200, { id: webAppId }));
|
|
125
|
+
fetchMock.mockResolvedValueOnce(createMockResponse(true, 200, {}, ''));
|
|
126
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
127
|
+
vi.spyOn(credentialStore, 'getCredential').mockResolvedValue({ apiKey: 'stored-api-key', savedAt: '2026-01-01T00:00:00.000Z' });
|
|
128
|
+
const deployer = new SystemLinkWebAppDeployer({
|
|
129
|
+
deployment: {
|
|
130
|
+
host,
|
|
131
|
+
name: 'My App',
|
|
132
|
+
workspaceId: '45bc27cf-85c6-485c-945d-a51e664f511d'
|
|
133
|
+
}
|
|
134
|
+
}, { nipkg: nipkgPath }
|
|
135
|
+
// no apiKey in options, no env var
|
|
136
|
+
);
|
|
137
|
+
await deployer.deploy();
|
|
138
|
+
// Verify the stored key was sent in the auth header
|
|
139
|
+
const requestInit = fetchMock.mock.calls[0]?.[1];
|
|
140
|
+
const headers = requestInit.headers;
|
|
141
|
+
expect(headers.get('x-ni-api-key')).toBe('stored-api-key');
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
//# sourceMappingURL=deployer.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deployer.test.js","sourceRoot":"","sources":["../src/deployer.test.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export interface CreateWebAppRequest {
|
|
2
|
+
name: string;
|
|
3
|
+
type: string;
|
|
4
|
+
workspace: string;
|
|
5
|
+
policyIds: string[];
|
|
6
|
+
properties?: {
|
|
7
|
+
[key: string]: string;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export interface CreateWebAppResponse {
|
|
11
|
+
[key: string]: unknown;
|
|
12
|
+
id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
type: string;
|
|
15
|
+
created: string;
|
|
16
|
+
}
|
|
17
|
+
export interface GetWebAppResponse {
|
|
18
|
+
[key: string]: unknown;
|
|
19
|
+
id: string;
|
|
20
|
+
name: string;
|
|
21
|
+
workspace: string;
|
|
22
|
+
policyIds?: string[];
|
|
23
|
+
properties?: {
|
|
24
|
+
[key: string]: string;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Thin HTTP client for the SystemLink WebApps API.
|
|
29
|
+
* Centralises auth, timeout/abort, and error-response handling.
|
|
30
|
+
*/
|
|
31
|
+
export declare class SlApiClient {
|
|
32
|
+
private readonly host;
|
|
33
|
+
private readonly apiKey;
|
|
34
|
+
private readonly timeout;
|
|
35
|
+
constructor(host: string, apiKey: string, timeout: number);
|
|
36
|
+
createWebApp(body: CreateWebAppRequest): Promise<CreateWebAppResponse>;
|
|
37
|
+
getWebApp(appId: string): Promise<GetWebAppResponse>;
|
|
38
|
+
updateWebApp(appId: string, body: {
|
|
39
|
+
[key: string]: unknown;
|
|
40
|
+
}): Promise<void>;
|
|
41
|
+
uploadContent(appId: string, stream: ReadableStream<Uint8Array>, size: number): Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* Verify that the host and API key are valid by making a cheap read-only request.
|
|
44
|
+
* Returns `{ ok: true }` on success, `{ ok: false, status: 401 }` on auth failure.
|
|
45
|
+
* Does NOT throw on HTTP error responses — only throws on network/transport errors.
|
|
46
|
+
*/
|
|
47
|
+
verifyAuth(): Promise<{
|
|
48
|
+
ok: boolean;
|
|
49
|
+
status: number;
|
|
50
|
+
}>;
|
|
51
|
+
deleteWebApp(appId: string): Promise<void>;
|
|
52
|
+
private authHeaders;
|
|
53
|
+
private jsonHeaders;
|
|
54
|
+
private fetchWithTimeout;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=slApiClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slApiClient.d.ts","sourceRoot":"","sources":["../src/slApiClient.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CAC1C;AAED,MAAM,WAAW,oBAAoB;IACjC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAC9B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CAC1C;AAED;;;GAGG;AACH,qBAAa,WAAW;IAEhB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAFP,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM;IAavB,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAgBtE,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAWpD,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAW5E,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAe1G;;;;OAIG;IACU,UAAU,IAAI,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAQtD,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUvD,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,WAAW;YAML,gBAAgB;CAcjC"}
|