@nlabs/lex 1.48.7 → 1.49.1
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/.storybook/main.ts +9 -2
- package/.vscode/settings.json +1 -6
- package/README.md +249 -0
- package/eslint.config.mjs +24 -0
- package/examples/lex.config.js +18 -8
- package/examples/serverless-example/README.md +109 -0
- package/examples/serverless-example/dist/handlers/echo.js +15 -0
- package/examples/serverless-example/dist/handlers/graphql.js +137 -0
- package/examples/serverless-example/dist/handlers/hello.js +15 -0
- package/examples/serverless-example/dist/handlers/test.js +17 -0
- package/examples/serverless-example/dist/handlers/websocket.js +14 -0
- package/examples/serverless-example/lex.config.mjs +74 -0
- package/jest.config.mjs +13 -12
- package/{dist → lib}/LexConfig.d.ts +7 -6
- package/lib/LexConfig.js +268 -0
- package/lib/commands/ai/ai.js +303 -0
- package/{dist → lib}/commands/build/build.d.ts +3 -0
- package/lib/commands/build/build.js +494 -0
- package/{dist → lib}/commands/clean/clean.js +1 -1
- package/lib/commands/compile/compile.js +241 -0
- package/lib/commands/copy/copy.js +38 -0
- package/{dist → lib}/commands/create/create.js +1 -1
- package/{dist → lib}/commands/dev/dev.d.ts +2 -0
- package/lib/commands/dev/dev.js +286 -0
- package/{dist → lib}/commands/init/init.js +1 -1
- package/lib/commands/lint/lint.js +962 -0
- package/{dist → lib}/commands/migrate/migrate.js +1 -1
- package/lib/commands/publish/publish.js +104 -0
- package/lib/commands/serverless/serverless.d.ts +17 -0
- package/lib/commands/serverless/serverless.js +662 -0
- package/lib/commands/storybook/storybook.js +249 -0
- package/lib/commands/test/test.js +428 -0
- package/lib/commands/update/update.js +128 -0
- package/{dist → lib}/create/changelog.js +1 -1
- package/{dist → lib}/index.d.ts +1 -0
- package/{dist → lib}/index.js +2 -1
- package/lib/lex.js +73 -0
- package/lib/utils/aiService.d.ts +9 -0
- package/lib/utils/aiService.js +299 -0
- package/{dist → lib}/utils/app.d.ts +3 -0
- package/lib/utils/app.js +296 -0
- package/{dist → lib}/utils/file.d.ts +7 -3
- package/lib/utils/file.js +229 -0
- package/lib/utils/translations.d.ts +1 -0
- package/lib/utils/translations.js +74 -0
- package/package.json +60 -54
- package/postcss.config.js +5 -3
- package/tsconfig.build.json +2 -2
- package/webpack.config.js +229 -39
- package/dist/LexConfig.js +0 -287
- package/dist/commands/ai/ai.js +0 -303
- package/dist/commands/build/build.js +0 -404
- package/dist/commands/compile/compile.js +0 -234
- package/dist/commands/copy/copy.js +0 -38
- package/dist/commands/dev/dev.js +0 -74
- package/dist/commands/lint/lint.js +0 -993
- package/dist/commands/publish/publish.js +0 -104
- package/dist/commands/storybook/storybook.js +0 -249
- package/dist/commands/test/test.js +0 -429
- package/dist/commands/update/update.js +0 -132
- package/dist/lex.js +0 -70
- package/dist/utils/aiService.d.ts +0 -9
- package/dist/utils/aiService.js +0 -299
- package/dist/utils/app.js +0 -267
- package/dist/utils/file.js +0 -185
- package/emptyModule.js +0 -0
- package/eslint.config.js +0 -3
- /package/{dist → lib}/Button.stories.d.ts +0 -0
- /package/{dist → lib}/commands/ai/ai.d.ts +0 -0
- /package/{dist → lib}/commands/ai/index.d.ts +0 -0
- /package/{dist → lib}/commands/ai/index.js +0 -0
- /package/{dist → lib}/commands/clean/clean.d.ts +0 -0
- /package/{dist → lib}/commands/compile/compile.d.ts +0 -0
- /package/{dist → lib}/commands/config/config.d.ts +0 -0
- /package/{dist → lib}/commands/config/config.js +0 -0
- /package/{dist → lib}/commands/copy/copy.d.ts +0 -0
- /package/{dist → lib}/commands/create/create.d.ts +0 -0
- /package/{dist → lib}/commands/init/init.d.ts +0 -0
- /package/{dist → lib}/commands/link/link.d.ts +0 -0
- /package/{dist → lib}/commands/link/link.js +0 -0
- /package/{dist → lib}/commands/lint/autofix.d.ts +0 -0
- /package/{dist → lib}/commands/lint/lint.d.ts +0 -0
- /package/{dist → lib}/commands/migrate/migrate.d.ts +0 -0
- /package/{dist → lib}/commands/publish/publish.d.ts +0 -0
- /package/{dist → lib}/commands/storybook/storybook.d.ts +0 -0
- /package/{dist → lib}/commands/test/test.d.ts +0 -0
- /package/{dist → lib}/commands/update/update.d.ts +0 -0
- /package/{dist → lib}/commands/upgrade/upgrade.d.ts +0 -0
- /package/{dist → lib}/commands/upgrade/upgrade.js +0 -0
- /package/{dist → lib}/commands/versions/versions.d.ts +0 -0
- /package/{dist → lib}/commands/versions/versions.js +0 -0
- /package/{dist → lib}/create/changelog.d.ts +0 -0
- /package/{dist → lib}/lex.d.ts +0 -0
- /package/{dist → lib}/storybook/index.d.ts +0 -0
- /package/{dist → lib}/storybook/index.js +0 -0
- /package/{dist → lib}/test-react/index.d.ts +0 -0
- /package/{dist → lib}/test-react/index.js +0 -0
- /package/{dist → lib}/types.d.ts +0 -0
- /package/{dist → lib}/types.js +0 -0
- /package/{dist → lib}/utils/deepMerge.d.ts +0 -0
- /package/{dist → lib}/utils/deepMerge.js +0 -0
- /package/{dist → lib}/utils/log.d.ts +0 -0
- /package/{dist → lib}/utils/log.js +0 -0
- /package/{dist → lib}/utils/reactShim.d.ts +0 -0
- /package/{dist → lib}/utils/reactShim.js +0 -0
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
import { execa } from "execa";
|
|
2
|
+
import { existsSync, readFileSync } from "fs";
|
|
3
|
+
import { sync as globSync } from "glob";
|
|
4
|
+
import { resolve as pathResolve } from "path";
|
|
5
|
+
import { LexConfig, getTypeScriptConfigPath } from "../../LexConfig.js";
|
|
6
|
+
import { createSpinner } from "../../utils/app.js";
|
|
7
|
+
import { getDirName, resolveBinaryPath } from "../../utils/file.js";
|
|
8
|
+
import { log } from "../../utils/log.js";
|
|
9
|
+
import { aiFunction } from "../ai/ai.js";
|
|
10
|
+
const detectESM = (cwd) => {
|
|
11
|
+
const packageJsonPath = pathResolve(cwd, "package.json");
|
|
12
|
+
if (existsSync(packageJsonPath)) {
|
|
13
|
+
try {
|
|
14
|
+
const packageJsonContent = readFileSync(packageJsonPath, "utf8");
|
|
15
|
+
const packageJson = JSON.parse(packageJsonContent);
|
|
16
|
+
return packageJson.type === "module";
|
|
17
|
+
} catch (_error) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return false;
|
|
22
|
+
};
|
|
23
|
+
const getTestFilePatterns = (testPathPattern) => {
|
|
24
|
+
const defaultPatterns = ["**/*.test.*", "**/*.spec.*", "**/*.integration.*"];
|
|
25
|
+
if (!testPathPattern) {
|
|
26
|
+
return defaultPatterns;
|
|
27
|
+
}
|
|
28
|
+
return [testPathPattern];
|
|
29
|
+
};
|
|
30
|
+
const findUncoveredSourceFiles = () => {
|
|
31
|
+
const sourceFiles = globSync("src/**/*.{ts,tsx,js,jsx}", {
|
|
32
|
+
cwd: process.cwd(),
|
|
33
|
+
ignore: ["**/node_modules/**", "**/dist/**", "**/*.test.*", "**/*.spec.*"]
|
|
34
|
+
});
|
|
35
|
+
const testFiles = globSync("**/*.{test,spec}.{ts,tsx,js,jsx}", {
|
|
36
|
+
cwd: process.cwd(),
|
|
37
|
+
ignore: ["**/node_modules/**", "**/dist/**"]
|
|
38
|
+
});
|
|
39
|
+
return sourceFiles.filter((sourceFile) => {
|
|
40
|
+
const baseName = sourceFile.replace(/\.[^/.]+$/, "");
|
|
41
|
+
return !testFiles.some((testFile) => testFile.includes(baseName));
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
const processTestResults = (outputFile) => {
|
|
45
|
+
if (!outputFile) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
const content = readFileSync(outputFile, "utf-8");
|
|
50
|
+
return JSON.parse(content);
|
|
51
|
+
} catch (_error) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
const test = async (options, args, callback = process.exit) => {
|
|
56
|
+
const {
|
|
57
|
+
analyze = false,
|
|
58
|
+
aiAnalyze = false,
|
|
59
|
+
aiDebug = false,
|
|
60
|
+
aiGenerate = false,
|
|
61
|
+
bail,
|
|
62
|
+
changedFilesWithAncestor,
|
|
63
|
+
changedSince,
|
|
64
|
+
ci,
|
|
65
|
+
cliName = "Lex",
|
|
66
|
+
collectCoverageFrom,
|
|
67
|
+
colors,
|
|
68
|
+
config,
|
|
69
|
+
debug = false,
|
|
70
|
+
debugTests = false,
|
|
71
|
+
detectOpenHandles,
|
|
72
|
+
env,
|
|
73
|
+
errorOnDeprecated,
|
|
74
|
+
expand,
|
|
75
|
+
forceExit,
|
|
76
|
+
generate = false,
|
|
77
|
+
json,
|
|
78
|
+
lastCommit,
|
|
79
|
+
listTests,
|
|
80
|
+
logHeapUsage,
|
|
81
|
+
maxWorkers,
|
|
82
|
+
noStackTrace,
|
|
83
|
+
notify,
|
|
84
|
+
onlyChanged,
|
|
85
|
+
outputFile,
|
|
86
|
+
passWithNoTests,
|
|
87
|
+
quiet,
|
|
88
|
+
removeCache,
|
|
89
|
+
runInBand,
|
|
90
|
+
setup,
|
|
91
|
+
showConfig,
|
|
92
|
+
silent,
|
|
93
|
+
testLocationInResults,
|
|
94
|
+
testNamePattern,
|
|
95
|
+
testPathPattern,
|
|
96
|
+
update,
|
|
97
|
+
useStderr,
|
|
98
|
+
verbose,
|
|
99
|
+
watch,
|
|
100
|
+
watchAll
|
|
101
|
+
} = options;
|
|
102
|
+
const useGenerate = generate || aiGenerate;
|
|
103
|
+
const useAnalyze = analyze || aiAnalyze;
|
|
104
|
+
const useDebug = debugTests || aiDebug;
|
|
105
|
+
log(`${cliName} testing...`, "info", quiet);
|
|
106
|
+
const spinner = createSpinner(quiet);
|
|
107
|
+
await LexConfig.parseConfig(options);
|
|
108
|
+
const { useTypescript } = LexConfig.config;
|
|
109
|
+
if (useTypescript) {
|
|
110
|
+
const testConfigPath = getTypeScriptConfigPath("tsconfig.test.json");
|
|
111
|
+
if (existsSync(testConfigPath)) {
|
|
112
|
+
log("Using tsconfig.test.json for testing...", "info", quiet);
|
|
113
|
+
} else {
|
|
114
|
+
LexConfig.checkTestTypescriptConfig();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (useGenerate) {
|
|
118
|
+
spinner.start("AI is analyzing code to generate test cases...");
|
|
119
|
+
try {
|
|
120
|
+
const uncoveredFiles = findUncoveredSourceFiles();
|
|
121
|
+
if (uncoveredFiles.length > 0) {
|
|
122
|
+
const targetFile = uncoveredFiles[0];
|
|
123
|
+
await aiFunction({
|
|
124
|
+
context: true,
|
|
125
|
+
file: targetFile,
|
|
126
|
+
prompt: `Generate Jest unit tests for this file: ${targetFile}
|
|
127
|
+
|
|
128
|
+
${readFileSync(targetFile, "utf-8")}
|
|
129
|
+
|
|
130
|
+
Please create comprehensive tests that cover the main functionality. Include test fixtures and mocks where necessary.`,
|
|
131
|
+
quiet,
|
|
132
|
+
task: "test"
|
|
133
|
+
});
|
|
134
|
+
spinner.succeed(`AI test generation suggestions provided for ${targetFile}`);
|
|
135
|
+
} else {
|
|
136
|
+
spinner.succeed("All source files appear to have corresponding test files");
|
|
137
|
+
}
|
|
138
|
+
} catch (aiError) {
|
|
139
|
+
spinner.fail("Could not generate AI test suggestions");
|
|
140
|
+
if (!quiet) {
|
|
141
|
+
console.error("AI test generation error:", aiError);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
const dirName = getDirName();
|
|
146
|
+
const projectJestBin = pathResolve(process.cwd(), "node_modules/.bin/jest");
|
|
147
|
+
let jestPath;
|
|
148
|
+
if (existsSync(projectJestBin)) {
|
|
149
|
+
jestPath = projectJestBin;
|
|
150
|
+
} else {
|
|
151
|
+
jestPath = resolveBinaryPath("jest");
|
|
152
|
+
}
|
|
153
|
+
if (!jestPath) {
|
|
154
|
+
log(`
|
|
155
|
+
${cliName} Error: Jest binary not found in Lex's node_modules or monorepo root`, "error", quiet);
|
|
156
|
+
log("Please reinstall Lex or check your installation.", "info", quiet);
|
|
157
|
+
return 1;
|
|
158
|
+
}
|
|
159
|
+
let jestConfigFile;
|
|
160
|
+
let projectJestConfig = null;
|
|
161
|
+
if (config) {
|
|
162
|
+
jestConfigFile = config;
|
|
163
|
+
} else {
|
|
164
|
+
const projectJestConfigPath = pathResolve(process.cwd(), "jest.config.js");
|
|
165
|
+
const projectJestConfigCjsPath = pathResolve(process.cwd(), "jest.config.cjs");
|
|
166
|
+
const projectJestConfigMjsPath = pathResolve(process.cwd(), "jest.config.mjs");
|
|
167
|
+
const projectJestConfigJsonPath = pathResolve(process.cwd(), "jest.config.json");
|
|
168
|
+
if (existsSync(projectJestConfigPath)) {
|
|
169
|
+
jestConfigFile = projectJestConfigPath;
|
|
170
|
+
if (debug) {
|
|
171
|
+
log(`Using project Jest config file: ${jestConfigFile}`, "info", quiet);
|
|
172
|
+
}
|
|
173
|
+
} else if (existsSync(projectJestConfigCjsPath)) {
|
|
174
|
+
jestConfigFile = projectJestConfigCjsPath;
|
|
175
|
+
if (debug) {
|
|
176
|
+
log(`Using project Jest config file (CJS): ${jestConfigFile}`, "info", quiet);
|
|
177
|
+
}
|
|
178
|
+
} else if (existsSync(projectJestConfigMjsPath)) {
|
|
179
|
+
jestConfigFile = projectJestConfigMjsPath;
|
|
180
|
+
if (debug) {
|
|
181
|
+
log(`Using project Jest config file (MJS): ${jestConfigFile}`, "info", quiet);
|
|
182
|
+
}
|
|
183
|
+
} else if (existsSync(projectJestConfigJsonPath)) {
|
|
184
|
+
jestConfigFile = projectJestConfigJsonPath;
|
|
185
|
+
if (debug) {
|
|
186
|
+
log(`Using project Jest config file (JSON): ${jestConfigFile}`, "info", quiet);
|
|
187
|
+
}
|
|
188
|
+
} else {
|
|
189
|
+
projectJestConfig = LexConfig.config.jest;
|
|
190
|
+
const lexDir = LexConfig.getLexDir();
|
|
191
|
+
const lexJestConfig = pathResolve(lexDir, "jest.config.mjs");
|
|
192
|
+
if (debug) {
|
|
193
|
+
log(`Looking for Jest config at: ${lexJestConfig}`, "info", quiet);
|
|
194
|
+
log(`File exists: ${existsSync(lexJestConfig)}`, "info", quiet);
|
|
195
|
+
}
|
|
196
|
+
if (existsSync(lexJestConfig)) {
|
|
197
|
+
jestConfigFile = lexJestConfig;
|
|
198
|
+
if (projectJestConfig && Object.keys(projectJestConfig).length > 0) {
|
|
199
|
+
if (debug) {
|
|
200
|
+
log(`Using Lex Jest config with project Jest config from lex.config.cjs: ${jestConfigFile}`, "info", quiet);
|
|
201
|
+
}
|
|
202
|
+
} else {
|
|
203
|
+
if (debug) {
|
|
204
|
+
log(`Using Lex Jest config (no project Jest config found): ${jestConfigFile}`, "info", quiet);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
} else {
|
|
208
|
+
if (debug) {
|
|
209
|
+
log("No Jest config found in project or Lex", "warn", quiet);
|
|
210
|
+
}
|
|
211
|
+
jestConfigFile = "";
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
const jestSetupFile = setup || pathResolve(process.cwd(), "jest.setup.js");
|
|
216
|
+
const jestOptions = ["--no-cache"];
|
|
217
|
+
const isESM = detectESM(process.cwd());
|
|
218
|
+
let nodeOptions = process.env.NODE_OPTIONS || "";
|
|
219
|
+
if (isESM) {
|
|
220
|
+
if (!nodeOptions.includes("--experimental-vm-modules")) {
|
|
221
|
+
nodeOptions = `${nodeOptions} --experimental-vm-modules`.trim();
|
|
222
|
+
}
|
|
223
|
+
log("ESM project detected, using --experimental-vm-modules in NODE_OPTIONS", "info", quiet);
|
|
224
|
+
}
|
|
225
|
+
if (jestConfigFile) {
|
|
226
|
+
jestOptions.push("--config", jestConfigFile);
|
|
227
|
+
}
|
|
228
|
+
if (bail) {
|
|
229
|
+
jestOptions.push("--bail");
|
|
230
|
+
}
|
|
231
|
+
if (changedFilesWithAncestor) {
|
|
232
|
+
jestOptions.push("--changedFilesWithAncestor");
|
|
233
|
+
}
|
|
234
|
+
if (changedSince) {
|
|
235
|
+
jestOptions.push("--changedSince");
|
|
236
|
+
}
|
|
237
|
+
if (ci) {
|
|
238
|
+
jestOptions.push("--ci");
|
|
239
|
+
}
|
|
240
|
+
if (collectCoverageFrom) {
|
|
241
|
+
jestOptions.push("--collectCoverageFrom", collectCoverageFrom);
|
|
242
|
+
}
|
|
243
|
+
if (colors) {
|
|
244
|
+
jestOptions.push("--colors");
|
|
245
|
+
}
|
|
246
|
+
if (debug) {
|
|
247
|
+
jestOptions.push("--debug");
|
|
248
|
+
}
|
|
249
|
+
if (detectOpenHandles) {
|
|
250
|
+
jestOptions.push("--detectOpenHandles");
|
|
251
|
+
}
|
|
252
|
+
if (env) {
|
|
253
|
+
jestOptions.push("--env");
|
|
254
|
+
}
|
|
255
|
+
if (errorOnDeprecated) {
|
|
256
|
+
jestOptions.push("--errorOnDeprecated");
|
|
257
|
+
}
|
|
258
|
+
if (expand) {
|
|
259
|
+
jestOptions.push("--expand");
|
|
260
|
+
}
|
|
261
|
+
if (forceExit) {
|
|
262
|
+
jestOptions.push("--forceExit");
|
|
263
|
+
}
|
|
264
|
+
if (json) {
|
|
265
|
+
jestOptions.push("--json");
|
|
266
|
+
}
|
|
267
|
+
if (lastCommit) {
|
|
268
|
+
jestOptions.push("--lastCommit");
|
|
269
|
+
}
|
|
270
|
+
if (listTests) {
|
|
271
|
+
jestOptions.push("--listTests");
|
|
272
|
+
}
|
|
273
|
+
if (logHeapUsage) {
|
|
274
|
+
jestOptions.push("--logHeapUsage");
|
|
275
|
+
}
|
|
276
|
+
if (maxWorkers) {
|
|
277
|
+
jestOptions.push("--maxWorkers", maxWorkers);
|
|
278
|
+
}
|
|
279
|
+
if (noStackTrace) {
|
|
280
|
+
jestOptions.push("--noStackTrace");
|
|
281
|
+
}
|
|
282
|
+
if (notify) {
|
|
283
|
+
jestOptions.push("--notify");
|
|
284
|
+
}
|
|
285
|
+
if (onlyChanged) {
|
|
286
|
+
jestOptions.push("--onlyChanged");
|
|
287
|
+
}
|
|
288
|
+
let tempOutputFile = outputFile;
|
|
289
|
+
if ((useAnalyze || useDebug) && !outputFile) {
|
|
290
|
+
tempOutputFile = ".lex-test-results.json";
|
|
291
|
+
jestOptions.push("--json", "--outputFile", tempOutputFile);
|
|
292
|
+
} else if (outputFile) {
|
|
293
|
+
jestOptions.push("--outputFile", outputFile);
|
|
294
|
+
}
|
|
295
|
+
if (passWithNoTests) {
|
|
296
|
+
jestOptions.push("--passWithNoTests");
|
|
297
|
+
}
|
|
298
|
+
if (runInBand) {
|
|
299
|
+
jestOptions.push("--runInBand");
|
|
300
|
+
}
|
|
301
|
+
if (showConfig) {
|
|
302
|
+
jestOptions.push("--showConfig");
|
|
303
|
+
}
|
|
304
|
+
if (silent) {
|
|
305
|
+
jestOptions.push("--silent");
|
|
306
|
+
}
|
|
307
|
+
if (testLocationInResults) {
|
|
308
|
+
jestOptions.push("--testLocationInResults");
|
|
309
|
+
}
|
|
310
|
+
if (testNamePattern) {
|
|
311
|
+
jestOptions.push("--testNamePattern", testNamePattern);
|
|
312
|
+
}
|
|
313
|
+
if (testPathPattern) {
|
|
314
|
+
jestOptions.push("--testPathPattern", testPathPattern);
|
|
315
|
+
}
|
|
316
|
+
if (useStderr) {
|
|
317
|
+
jestOptions.push("--useStderr");
|
|
318
|
+
}
|
|
319
|
+
if (verbose) {
|
|
320
|
+
jestOptions.push("--verbose");
|
|
321
|
+
}
|
|
322
|
+
if (watchAll) {
|
|
323
|
+
jestOptions.push("--watchAll");
|
|
324
|
+
}
|
|
325
|
+
if (removeCache) {
|
|
326
|
+
jestOptions.push("--no-cache");
|
|
327
|
+
}
|
|
328
|
+
if (jestSetupFile && existsSync(jestSetupFile)) {
|
|
329
|
+
jestOptions.push(`--setupFilesAfterEnv=${jestSetupFile}`);
|
|
330
|
+
}
|
|
331
|
+
if (update) {
|
|
332
|
+
jestOptions.push("--updateSnapshot");
|
|
333
|
+
}
|
|
334
|
+
if (watch) {
|
|
335
|
+
jestOptions.push("--watch", watch);
|
|
336
|
+
}
|
|
337
|
+
if (args) {
|
|
338
|
+
jestOptions.push(...args);
|
|
339
|
+
}
|
|
340
|
+
if (debug) {
|
|
341
|
+
log(`Jest options: ${jestOptions.join(" ")}`, "info", quiet);
|
|
342
|
+
log(`NODE_OPTIONS: ${nodeOptions}`, "info", quiet);
|
|
343
|
+
}
|
|
344
|
+
try {
|
|
345
|
+
const env2 = {
|
|
346
|
+
...process.env,
|
|
347
|
+
NODE_OPTIONS: nodeOptions
|
|
348
|
+
};
|
|
349
|
+
await execa(jestPath, jestOptions, {
|
|
350
|
+
encoding: "utf8",
|
|
351
|
+
stdio: "inherit",
|
|
352
|
+
env: env2
|
|
353
|
+
});
|
|
354
|
+
spinner.succeed("Testing completed!");
|
|
355
|
+
if (useAnalyze) {
|
|
356
|
+
spinner.start("AI is analyzing test coverage and suggesting improvements...");
|
|
357
|
+
try {
|
|
358
|
+
const testResults = processTestResults(tempOutputFile);
|
|
359
|
+
const filePatterns = getTestFilePatterns(testPathPattern);
|
|
360
|
+
await aiFunction({
|
|
361
|
+
prompt: `Analyze these Jest test results and suggest test coverage improvements:
|
|
362
|
+
|
|
363
|
+
${JSON.stringify(testResults, null, 2)}
|
|
364
|
+
|
|
365
|
+
Test patterns: ${filePatterns.join(", ")}
|
|
366
|
+
|
|
367
|
+
Please provide:
|
|
368
|
+
1. Analysis of current coverage gaps
|
|
369
|
+
2. Suggestions for improving test cases
|
|
370
|
+
3. Recommendations for additional integration test scenarios
|
|
371
|
+
4. Best practices for increasing test effectiveness`,
|
|
372
|
+
task: "optimize",
|
|
373
|
+
context: true,
|
|
374
|
+
quiet
|
|
375
|
+
});
|
|
376
|
+
spinner.succeed("AI test analysis complete");
|
|
377
|
+
} catch (aiError) {
|
|
378
|
+
spinner.fail("Could not generate AI test analysis");
|
|
379
|
+
if (!quiet) {
|
|
380
|
+
console.error("AI analysis error:", aiError);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
callback(0);
|
|
385
|
+
return 0;
|
|
386
|
+
} catch (error) {
|
|
387
|
+
log(`
|
|
388
|
+
${cliName} Error: Check for unit test errors and/or coverage.`, "error", quiet);
|
|
389
|
+
spinner.fail("Testing failed!");
|
|
390
|
+
if (useDebug) {
|
|
391
|
+
spinner.start("AI is analyzing test failures...");
|
|
392
|
+
try {
|
|
393
|
+
const testResults = processTestResults(tempOutputFile);
|
|
394
|
+
await aiFunction({
|
|
395
|
+
context: true,
|
|
396
|
+
prompt: `Debug these failed Jest tests and suggest fixes:
|
|
397
|
+
|
|
398
|
+
${JSON.stringify(error.message, null, 2)}
|
|
399
|
+
|
|
400
|
+
Test results: ${JSON.stringify(testResults, null, 2)}
|
|
401
|
+
|
|
402
|
+
Please provide:
|
|
403
|
+
1. Analysis of why the tests are failing
|
|
404
|
+
2. Specific suggestions to fix each failing test
|
|
405
|
+
3. Any potential issues with test fixtures or mocks
|
|
406
|
+
4. Code examples for solutions`,
|
|
407
|
+
quiet,
|
|
408
|
+
task: "help"
|
|
409
|
+
});
|
|
410
|
+
spinner.succeed("AI debugging assistance complete");
|
|
411
|
+
} catch (aiError) {
|
|
412
|
+
spinner.fail("Could not generate AI debugging assistance");
|
|
413
|
+
if (!quiet) {
|
|
414
|
+
console.error("AI debugging error:", aiError);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
callback(1);
|
|
419
|
+
return 1;
|
|
420
|
+
}
|
|
421
|
+
};
|
|
422
|
+
var test_default = test;
|
|
423
|
+
export {
|
|
424
|
+
test_default as default,
|
|
425
|
+
getTestFilePatterns,
|
|
426
|
+
test
|
|
427
|
+
};
|
|
428
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2NvbW1hbmRzL3Rlc3QvdGVzdC50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTgtUHJlc2VudCwgTml0cm9nZW4gTGFicywgSW5jLlxuICogQ29weXJpZ2h0cyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSB0aGUgYWNjb21wYW55aW5nIExJQ0VOU0UgZmlsZSBmb3IgdGVybXMuXG4gKi9cbmltcG9ydCB7ZXhlY2F9IGZyb20gJ2V4ZWNhJztcbmltcG9ydCB7ZXhpc3RzU3luYywgcmVhZEZpbGVTeW5jfSBmcm9tICdmcyc7XG5pbXBvcnQge3N5bmMgYXMgZ2xvYlN5bmN9IGZyb20gJ2dsb2InO1xuaW1wb3J0IHtyZXNvbHZlIGFzIHBhdGhSZXNvbHZlfSBmcm9tICdwYXRoJztcblxuaW1wb3J0IHtMZXhDb25maWcsIGdldFR5cGVTY3JpcHRDb25maWdQYXRofSBmcm9tICcuLi8uLi9MZXhDb25maWcuanMnO1xuaW1wb3J0IHtjcmVhdGVTcGlubmVyfSBmcm9tICcuLi8uLi91dGlscy9hcHAuanMnO1xuaW1wb3J0IHtnZXREaXJOYW1lLCByZXNvbHZlQmluYXJ5UGF0aH0gZnJvbSAnLi4vLi4vdXRpbHMvZmlsZS5qcyc7XG5pbXBvcnQge2xvZ30gZnJvbSAnLi4vLi4vdXRpbHMvbG9nLmpzJztcbmltcG9ydCB7YWlGdW5jdGlvbn0gZnJvbSAnLi4vYWkvYWkuanMnO1xuXG5jb25zdCBkZXRlY3RFU00gPSAoY3dkOiBzdHJpbmcpOiBib29sZWFuID0+IHtcbiAgY29uc3QgcGFja2FnZUpzb25QYXRoID0gcGF0aFJlc29sdmUoY3dkLCAncGFja2FnZS5qc29uJyk7XG5cbiAgaWYoZXhpc3RzU3luYyhwYWNrYWdlSnNvblBhdGgpKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBhY2thZ2VKc29uQ29udGVudCA9IHJlYWRGaWxlU3luYyhwYWNrYWdlSnNvblBhdGgsICd1dGY4Jyk7XG4gICAgICBjb25zdCBwYWNrYWdlSnNvbiA9IEpTT04ucGFyc2UocGFja2FnZUpzb25Db250ZW50KTtcbiAgICAgIHJldHVybiBwYWNrYWdlSnNvbi50eXBlID09PSAnbW9kdWxlJztcbiAgICB9IGNhdGNoIChfZXJyb3IpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIFRlc3RPcHRpb25zIHtcbiAgcmVhZG9ubHkgYW5hbHl6ZT86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGFpRGVidWc/OiBib29sZWFuO1xuICByZWFkb25seSBhaUdlbmVyYXRlPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgYWlBbmFseXplPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgYmFpbD86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGNoYW5nZWRGaWxlc1dpdGhBbmNlc3Rvcj86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGNoYW5nZWRTaW5jZT86IHN0cmluZztcbiAgcmVhZG9ubHkgY2k/OiBib29sZWFuO1xuICByZWFkb25seSBjbGlOYW1lPzogc3RyaW5nO1xuICByZWFkb25seSBjb2xsZWN0Q292ZXJhZ2VGcm9tPzogc3RyaW5nO1xuICByZWFkb25seSBjb2xvcnM/OiBib29sZWFuO1xuICByZWFkb25seSBjb25maWc/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGRlYnVnPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgZGVidWdUZXN0cz86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGRldGVjdE9wZW5IYW5kbGVzPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgZW52Pzogc3RyaW5nO1xuICByZWFkb25seSBlcnJvck9uRGVwcmVjYXRlZD86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGV4cGFuZD86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGZvcmNlRXhpdD86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGdlbmVyYXRlPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkganNvbj86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGxhc3RDb21taXQ/OiBib29sZWFuO1xuICByZWFkb25seSBsaXN0VGVzdHM/OiBib29sZWFuO1xuICByZWFkb25seSBsb2dIZWFwVXNhZ2U/OiBib29sZWFuO1xuICByZWFkb25seSBtYXhXb3JrZXJzPzogc3RyaW5nO1xuICByZWFkb25seSBub1N0YWNrVHJhY2U/OiBib29sZWFuO1xuICByZWFkb25seSBub3RpZnk/OiBib29sZWFuO1xuICByZWFkb25seSBvbmx5Q2hhbmdlZD86IGJvb2xlYW47XG4gIHJlYWRvbmx5IG91dHB1dEZpbGU/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHBhc3NXaXRoTm9UZXN0cz86IGJvb2xlYW47XG4gIHJlYWRvbmx5IHF1aWV0PzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgcmVtb3ZlQ2FjaGU/OiBib29sZWFuO1xuICByZWFkb25seSBydW5JbkJhbmQ/OiBib29sZWFuO1xuICByZWFkb25seSBzZXR1cD86IHN0cmluZztcbiAgcmVhZG9ubHkgc2hvd0NvbmZpZz86IGJvb2xlYW47XG4gIHJlYWRvbmx5IHNpbGVudD86IGJvb2xlYW47XG4gIHJlYWRvbmx5IHRlc3RMb2NhdGlvbkluUmVzdWx0cz86IGJvb2xlYW47XG4gIHJlYWRvbmx5IHRlc3ROYW1lUGF0dGVybj86IHN0cmluZztcbiAgcmVhZG9ubHkgdGVzdFBhdGhQYXR0ZXJuPzogc3RyaW5nO1xuICByZWFkb25seSB1cGRhdGU/OiBib29sZWFuO1xuICByZWFkb25seSB1c2VTdGRlcnI/OiBib29sZWFuO1xuICByZWFkb25seSB2ZXJib3NlPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgd2F0Y2g/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHdhdGNoQWxsPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IHR5cGUgVGVzdENhbGxiYWNrID0gdHlwZW9mIHByb2Nlc3MuZXhpdDtcblxuZXhwb3J0IGNvbnN0IGdldFRlc3RGaWxlUGF0dGVybnMgPSAodGVzdFBhdGhQYXR0ZXJuPzogc3RyaW5nKTogc3RyaW5nW10gPT4ge1xuICBjb25zdCBkZWZhdWx0UGF0dGVybnMgPSBbJyoqLyoudGVzdC4qJywgJyoqLyouc3BlYy4qJywgJyoqLyouaW50ZWdyYXRpb24uKiddO1xuXG4gIGlmKCF0ZXN0UGF0aFBhdHRlcm4pIHtcbiAgICByZXR1cm4gZGVmYXVsdFBhdHRlcm5zO1xuICB9XG5cbiAgcmV0dXJuIFt0ZXN0UGF0aFBhdHRlcm5dO1xufTtcblxuY29uc3QgZmluZFVuY292ZXJlZFNvdXJjZUZpbGVzID0gKCk6IHN0cmluZ1tdID0+IHtcbiAgY29uc3Qgc291cmNlRmlsZXMgPSBnbG9iU3luYygnc3JjLyoqLyoue3RzLHRzeCxqcyxqc3h9Jywge1xuICAgIGN3ZDogcHJvY2Vzcy5jd2QoKSxcbiAgICBpZ25vcmU6IFsnKiovbm9kZV9tb2R1bGVzLyoqJywgJyoqL2Rpc3QvKionLCAnKiovKi50ZXN0LionLCAnKiovKi5zcGVjLionXVxuICB9KTtcblxuICBjb25zdCB0ZXN0RmlsZXMgPSBnbG9iU3luYygnKiovKi57dGVzdCxzcGVjfS57dHMsdHN4LGpzLGpzeH0nLCB7XG4gICAgY3dkOiBwcm9jZXNzLmN3ZCgpLFxuICAgIGlnbm9yZTogWycqKi9ub2RlX21vZHVsZXMvKionLCAnKiovZGlzdC8qKiddXG4gIH0pO1xuXG4gIHJldHVybiBzb3VyY2VGaWxlcy5maWx0ZXIoKHNvdXJjZUZpbGUpID0+IHtcbiAgICBjb25zdCBiYXNlTmFtZSA9IHNvdXJjZUZpbGUucmVwbGFjZSgvXFwuW14vLl0rJC8sICcnKTtcbiAgICByZXR1cm4gIXRlc3RGaWxlcy5zb21lKCh0ZXN0RmlsZSkgPT4gdGVzdEZpbGUuaW5jbHVkZXMoYmFzZU5hbWUpKTtcbiAgfSk7XG59O1xuXG5jb25zdCBwcm9jZXNzVGVzdFJlc3VsdHMgPSAob3V0cHV0RmlsZT86IHN0cmluZyk6IGFueSA9PiB7XG4gIGlmKCFvdXRwdXRGaWxlKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB0cnkge1xuICAgIGNvbnN0IGNvbnRlbnQgPSByZWFkRmlsZVN5bmMob3V0cHV0RmlsZSwgJ3V0Zi04Jyk7XG4gICAgcmV0dXJuIEpTT04ucGFyc2UoY29udGVudCk7XG4gIH0gY2F0Y2ggKF9lcnJvcikge1xuICAgIHJldHVybiBudWxsO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgdGVzdCA9IGFzeW5jIChcbiAgb3B0aW9uczogVGVzdE9wdGlvbnMsXG4gIGFyZ3M6IHN0cmluZ1tdLFxuICBjYWxsYmFjazogVGVzdENhbGxiYWNrID0gcHJvY2Vzcy5leGl0XG4pOiBQcm9taXNlPG51bWJlcj4gPT4ge1xuICBjb25zdCB7XG4gICAgYW5hbHl6ZSA9IGZhbHNlLFxuICAgIGFpQW5hbHl6ZSA9IGZhbHNlLFxuICAgIGFpRGVidWcgPSBmYWxzZSxcbiAgICBhaUdlbmVyYXRlID0gZmFsc2UsXG4gICAgYmFpbCxcbiAgICBjaGFuZ2VkRmlsZXNXaXRoQW5jZXN0b3IsXG4gICAgY2hhbmdlZFNpbmNlLFxuICAgIGNpLFxuICAgIGNsaU5hbWUgPSAnTGV4JyxcbiAgICBjb2xsZWN0Q292ZXJhZ2VGcm9tLFxuICAgIGNvbG9ycyxcbiAgICBjb25maWcsXG4gICAgZGVidWcgPSBmYWxzZSxcbiAgICBkZWJ1Z1Rlc3RzID0gZmFsc2UsXG4gICAgZGV0ZWN0T3BlbkhhbmRsZXMsXG4gICAgZW52LFxuICAgIGVycm9yT25EZXByZWNhdGVkLFxuICAgIGV4cGFuZCxcbiAgICBmb3JjZUV4aXQsXG4gICAgZ2VuZXJhdGUgPSBmYWxzZSxcbiAgICBqc29uLFxuICAgIGxhc3RDb21taXQsXG4gICAgbGlzdFRlc3RzLFxuICAgIGxvZ0hlYXBVc2FnZSxcbiAgICBtYXhXb3JrZXJzLFxuICAgIG5vU3RhY2tUcmFjZSxcbiAgICBub3RpZnksXG4gICAgb25seUNoYW5nZWQsXG4gICAgb3V0cHV0RmlsZSxcbiAgICBwYXNzV2l0aE5vVGVzdHMsXG4gICAgcXVpZXQsXG4gICAgcmVtb3ZlQ2FjaGUsXG4gICAgcnVuSW5CYW5kLFxuICAgIHNldHVwLFxuICAgIHNob3dDb25maWcsXG4gICAgc2lsZW50LFxuICAgIHRlc3RMb2NhdGlvbkluUmVzdWx0cyxcbiAgICB0ZXN0TmFtZVBhdHRlcm4sXG4gICAgdGVzdFBhdGhQYXR0ZXJuLFxuICAgIHVwZGF0ZSxcbiAgICB1c2VTdGRlcnIsXG4gICAgdmVyYm9zZSxcbiAgICB3YXRjaCxcbiAgICB3YXRjaEFsbFxuICB9ID0gb3B0aW9ucztcblxuICBjb25zdCB1c2VHZW5lcmF0ZSA9IGdlbmVyYXRlIHx8IGFpR2VuZXJhdGU7XG4gIGNvbnN0IHVzZUFuYWx5emUgPSBhbmFseXplIHx8IGFpQW5hbHl6ZTtcbiAgY29uc3QgdXNlRGVidWcgPSBkZWJ1Z1Rlc3RzIHx8IGFpRGVidWc7XG5cbiAgbG9nKGAke2NsaU5hbWV9IHRlc3RpbmcuLi5gLCAnaW5mbycsIHF1aWV0KTtcblxuICBjb25zdCBzcGlubmVyID0gY3JlYXRlU3Bpbm5lcihxdWlldCk7XG5cbiAgYXdhaXQgTGV4Q29uZmlnLnBhcnNlQ29uZmlnKG9wdGlvbnMpO1xuXG4gIGNvbnN0IHt1c2VUeXBlc2NyaXB0fSA9IExleENvbmZpZy5jb25maWc7XG5cbiAgaWYodXNlVHlwZXNjcmlwdCkge1xuICAgIGNvbnN0IHRlc3RDb25maWdQYXRoID0gZ2V0VHlwZVNjcmlwdENvbmZpZ1BhdGgoJ3RzY29uZmlnLnRlc3QuanNvbicpO1xuICAgIGlmKGV4aXN0c1N5bmModGVzdENvbmZpZ1BhdGgpKSB7XG4gICAgICBsb2coJ1VzaW5nIHRzY29uZmlnLnRlc3QuanNvbiBmb3IgdGVzdGluZy4uLicsICdpbmZvJywgcXVpZXQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBMZXhDb25maWcuY2hlY2tUZXN0VHlwZXNjcmlwdENvbmZpZygpO1xuICAgIH1cbiAgfVxuXG4gIGlmKHVzZUdlbmVyYXRlKSB7XG4gICAgc3Bpbm5lci5zdGFydCgnQUkgaXMgYW5hbHl6aW5nIGNvZGUgdG8gZ2VuZXJhdGUgdGVzdCBjYXNlcy4uLicpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHVuY292ZXJlZEZpbGVzID0gZmluZFVuY292ZXJlZFNvdXJjZUZpbGVzKCk7XG5cbiAgICAgIGlmKHVuY292ZXJlZEZpbGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3QgdGFyZ2V0RmlsZSA9IHVuY292ZXJlZEZpbGVzWzBdO1xuXG4gICAgICAgIGF3YWl0IGFpRnVuY3Rpb24oe1xuICAgICAgICAgIGNvbnRleHQ6IHRydWUsXG4gICAgICAgICAgZmlsZTogdGFyZ2V0RmlsZSxcbiAgICAgICAgICBwcm9tcHQ6IGBHZW5lcmF0ZSBKZXN0IHVuaXQgdGVzdHMgZm9yIHRoaXMgZmlsZTogJHt0YXJnZXRGaWxlfVxcblxcbiR7cmVhZEZpbGVTeW5jKHRhcmdldEZpbGUsICd1dGYtOCcpfVxcblxcblBsZWFzZSBjcmVhdGUgY29tcHJlaGVuc2l2ZSB0ZXN0cyB0aGF0IGNvdmVyIHRoZSBtYWluIGZ1bmN0aW9uYWxpdHkuIEluY2x1ZGUgdGVzdCBmaXh0dXJlcyBhbmQgbW9ja3Mgd2hlcmUgbmVjZXNzYXJ5LmAsXG4gICAgICAgICAgcXVpZXQsXG4gICAgICAgICAgdGFzazogJ3Rlc3QnXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNwaW5uZXIuc3VjY2VlZChgQUkgdGVzdCBnZW5lcmF0aW9uIHN1Z2dlc3Rpb25zIHByb3ZpZGVkIGZvciAke3RhcmdldEZpbGV9YCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzcGlubmVyLnN1Y2NlZWQoJ0FsbCBzb3VyY2UgZmlsZXMgYXBwZWFyIHRvIGhhdmUgY29ycmVzcG9uZGluZyB0ZXN0IGZpbGVzJyk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoYWlFcnJvcikge1xuICAgICAgc3Bpbm5lci5mYWlsKCdDb3VsZCBub3QgZ2VuZXJhdGUgQUkgdGVzdCBzdWdnZXN0aW9ucycpO1xuICAgICAgaWYoIXF1aWV0KSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ0FJIHRlc3QgZ2VuZXJhdGlvbiBlcnJvcjonLCBhaUVycm9yKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjb25zdCBkaXJOYW1lID0gZ2V0RGlyTmFtZSgpO1xuXG4gIGNvbnN0IHByb2plY3RKZXN0QmluID0gcGF0aFJlc29sdmUocHJvY2Vzcy5jd2QoKSwgJ25vZGVfbW9kdWxlcy8uYmluL2plc3QnKTtcbiAgbGV0IGplc3RQYXRoOiBzdHJpbmc7XG5cbiAgaWYoZXhpc3RzU3luYyhwcm9qZWN0SmVzdEJpbikpIHtcbiAgICBqZXN0UGF0aCA9IHByb2plY3RKZXN0QmluO1xuICB9IGVsc2Uge1xuICAgIGplc3RQYXRoID0gcmVzb2x2ZUJpbmFyeVBhdGgoJ2plc3QnKTtcbiAgfVxuXG4gIGlmKCFqZXN0UGF0aCkge1xuICAgIGxvZyhgXFxuJHtjbGlOYW1lfSBFcnJvcjogSmVzdCBiaW5hcnkgbm90IGZvdW5kIGluIExleCdzIG5vZGVfbW9kdWxlcyBvciBtb25vcmVwbyByb290YCwgJ2Vycm9yJywgcXVpZXQpO1xuICAgIGxvZygnUGxlYXNlIHJlaW5zdGFsbCBMZXggb3IgY2hlY2sgeW91ciBpbnN0YWxsYXRpb24uJywgJ2luZm8nLCBxdWlldCk7XG4gICAgcmV0dXJuIDE7XG4gIH1cblxuICBsZXQgamVzdENvbmZpZ0ZpbGU6IHN0cmluZztcbiAgbGV0IHByb2plY3RKZXN0Q29uZmlnOiBhbnkgPSBudWxsO1xuXG4gIGlmKGNvbmZpZykge1xuICAgIGplc3RDb25maWdGaWxlID0gY29uZmlnO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IHByb2plY3RKZXN0Q29uZmlnUGF0aCA9IHBhdGhSZXNvbHZlKHByb2Nlc3MuY3dkKCksICdqZXN0LmNvbmZpZy5qcycpO1xuICAgIGNvbnN0IHByb2plY3RKZXN0Q29uZmlnQ2pzUGF0aCA9IHBhdGhSZXNvbHZlKHByb2Nlc3MuY3dkKCksICdqZXN0LmNvbmZpZy5janMnKTtcbiAgICBjb25zdCBwcm9qZWN0SmVzdENvbmZpZ01qc1BhdGggPSBwYXRoUmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCAnamVzdC5jb25maWcubWpzJyk7XG4gICAgY29uc3QgcHJvamVjdEplc3RDb25maWdKc29uUGF0aCA9IHBhdGhSZXNvbHZlKHByb2Nlc3MuY3dkKCksICdqZXN0LmNvbmZpZy5qc29uJyk7XG5cbiAgICBpZihleGlzdHNTeW5jKHByb2plY3RKZXN0Q29uZmlnUGF0aCkpIHtcbiAgICAgIGplc3RDb25maWdGaWxlID0gcHJvamVjdEplc3RDb25maWdQYXRoO1xuICAgICAgaWYoZGVidWcpIHtcbiAgICAgICAgbG9nKGBVc2luZyBwcm9qZWN0IEplc3QgY29uZmlnIGZpbGU6ICR7amVzdENvbmZpZ0ZpbGV9YCwgJ2luZm8nLCBxdWlldCk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmKGV4aXN0c1N5bmMocHJvamVjdEplc3RDb25maWdDanNQYXRoKSkge1xuICAgICAgamVzdENvbmZpZ0ZpbGUgPSBwcm9qZWN0SmVzdENvbmZpZ0Nqc1BhdGg7XG4gICAgICBpZihkZWJ1Zykge1xuICAgICAgICBsb2coYFVzaW5nIHByb2plY3QgSmVzdCBjb25maWcgZmlsZSAoQ0pTKTogJHtqZXN0Q29uZmlnRmlsZX1gLCAnaW5mbycsIHF1aWV0KTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYoZXhpc3RzU3luYyhwcm9qZWN0SmVzdENvbmZpZ01qc1BhdGgpKSB7XG4gICAgICBqZXN0Q29uZmlnRmlsZSA9IHByb2plY3RKZXN0Q29uZmlnTWpzUGF0aDtcbiAgICAgIGlmKGRlYnVnKSB7XG4gICAgICAgIGxvZyhgVXNpbmcgcHJvamVjdCBKZXN0IGNvbmZpZyBmaWxlIChNSlMpOiAke2plc3RDb25maWdGaWxlfWAsICdpbmZvJywgcXVpZXQpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZihleGlzdHNTeW5jKHByb2plY3RKZXN0Q29uZmlnSnNvblBhdGgpKSB7XG4gICAgICBqZXN0Q29uZmlnRmlsZSA9IHByb2plY3RKZXN0Q29uZmlnSnNvblBhdGg7XG4gICAgICBpZihkZWJ1Zykge1xuICAgICAgICBsb2coYFVzaW5nIHByb2plY3QgSmVzdCBjb25maWcgZmlsZSAoSlNPTik6ICR7amVzdENvbmZpZ0ZpbGV9YCwgJ2luZm8nLCBxdWlldCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIE5vIEplc3QgY29uZmlnIGZpbGUgZXhpc3RzIGluIHRoZSBwcm9qZWN0XG4gICAgICAvLyBDaGVjayBpZiB0aGVyZSdzIGEgSmVzdCBjb25maWcgaW4gbGV4LmNvbmZpZy5janNcbiAgICAgIHByb2plY3RKZXN0Q29uZmlnID0gTGV4Q29uZmlnLmNvbmZpZy5qZXN0O1xuXG4gICAgICBjb25zdCBsZXhEaXIgPSBMZXhDb25maWcuZ2V0TGV4RGlyKCk7XG4gICAgICBjb25zdCBsZXhKZXN0Q29uZmlnID0gcGF0aFJlc29sdmUobGV4RGlyLCAnamVzdC5jb25maWcubWpzJyk7XG5cbiAgICAgIGlmKGRlYnVnKSB7XG4gICAgICAgIGxvZyhgTG9va2luZyBmb3IgSmVzdCBjb25maWcgYXQ6ICR7bGV4SmVzdENvbmZpZ31gLCAnaW5mbycsIHF1aWV0KTtcbiAgICAgICAgbG9nKGBGaWxlIGV4aXN0czogJHtleGlzdHNTeW5jKGxleEplc3RDb25maWcpfWAsICdpbmZvJywgcXVpZXQpO1xuICAgICAgfVxuXG4gICAgICBpZihleGlzdHNTeW5jKGxleEplc3RDb25maWcpKSB7XG4gICAgICAgIGplc3RDb25maWdGaWxlID0gbGV4SmVzdENvbmZpZztcbiAgICAgICAgaWYocHJvamVjdEplc3RDb25maWcgJiYgT2JqZWN0LmtleXMocHJvamVjdEplc3RDb25maWcpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBpZihkZWJ1Zykge1xuICAgICAgICAgICAgbG9nKGBVc2luZyBMZXggSmVzdCBjb25maWcgd2l0aCBwcm9qZWN0IEplc3QgY29uZmlnIGZyb20gbGV4LmNvbmZpZy5janM6ICR7amVzdENvbmZpZ0ZpbGV9YCwgJ2luZm8nLCBxdWlldCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmKGRlYnVnKSB7XG4gICAgICAgICAgICBsb2coYFVzaW5nIExleCBKZXN0IGNvbmZpZyAobm8gcHJvamVjdCBKZXN0IGNvbmZpZyBmb3VuZCk6ICR7amVzdENvbmZpZ0ZpbGV9YCwgJ2luZm8nLCBxdWlldCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZihkZWJ1Zykge1xuICAgICAgICAgIGxvZygnTm8gSmVzdCBjb25maWcgZm91bmQgaW4gcHJvamVjdCBvciBMZXgnLCAnd2FybicsIHF1aWV0KTtcbiAgICAgICAgfVxuICAgICAgICBqZXN0Q29uZmlnRmlsZSA9ICcnO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGplc3RTZXR1cEZpbGU6IHN0cmluZyA9IHNldHVwIHx8IHBhdGhSZXNvbHZlKHByb2Nlc3MuY3dkKCksICdqZXN0LnNldHVwLmpzJyk7XG4gIGNvbnN0IGplc3RPcHRpb25zOiBzdHJpbmdbXSA9IFsnLS1uby1jYWNoZSddO1xuXG4gIGNvbnN0IGlzRVNNID0gZGV0ZWN0RVNNKHByb2Nlc3MuY3dkKCkpO1xuICBsZXQgbm9kZU9wdGlvbnMgPSBwcm9jZXNzLmVudi5OT0RFX09QVElPTlMgfHwgJyc7XG4gIGlmKGlzRVNNKSB7XG4gICAgaWYoIW5vZGVPcHRpb25zLmluY2x1ZGVzKCctLWV4cGVyaW1lbnRhbC12bS1tb2R1bGVzJykpIHtcbiAgICAgIG5vZGVPcHRpb25zID0gYCR7bm9kZU9wdGlvbnN9IC0tZXhwZXJpbWVudGFsLXZtLW1vZHVsZXNgLnRyaW0oKTtcbiAgICB9XG4gICAgbG9nKCdFU00gcHJvamVjdCBkZXRlY3RlZCwgdXNpbmcgLS1leHBlcmltZW50YWwtdm0tbW9kdWxlcyBpbiBOT0RFX09QVElPTlMnLCAnaW5mbycsIHF1aWV0KTtcbiAgfVxuXG4gIGlmKGplc3RDb25maWdGaWxlKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1jb25maWcnLCBqZXN0Q29uZmlnRmlsZSk7XG4gIH1cblxuICBpZihiYWlsKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1iYWlsJyk7XG4gIH1cblxuICBpZihjaGFuZ2VkRmlsZXNXaXRoQW5jZXN0b3IpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLWNoYW5nZWRGaWxlc1dpdGhBbmNlc3RvcicpO1xuICB9XG5cbiAgaWYoY2hhbmdlZFNpbmNlKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1jaGFuZ2VkU2luY2UnKTtcbiAgfVxuXG4gIGlmKGNpKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1jaScpO1xuICB9XG5cbiAgaWYoY29sbGVjdENvdmVyYWdlRnJvbSkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tY29sbGVjdENvdmVyYWdlRnJvbScsIGNvbGxlY3RDb3ZlcmFnZUZyb20pO1xuICB9XG5cbiAgaWYoY29sb3JzKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1jb2xvcnMnKTtcbiAgfVxuXG4gIGlmKGRlYnVnKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1kZWJ1ZycpO1xuICB9XG5cbiAgaWYoZGV0ZWN0T3BlbkhhbmRsZXMpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLWRldGVjdE9wZW5IYW5kbGVzJyk7XG4gIH1cblxuICBpZihlbnYpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLWVudicpO1xuICB9XG5cbiAgaWYoZXJyb3JPbkRlcHJlY2F0ZWQpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLWVycm9yT25EZXByZWNhdGVkJyk7XG4gIH1cblxuICBpZihleHBhbmQpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLWV4cGFuZCcpO1xuICB9XG5cbiAgaWYoZm9yY2VFeGl0KSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1mb3JjZUV4aXQnKTtcbiAgfVxuXG4gIGlmKGpzb24pIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLWpzb24nKTtcbiAgfVxuXG4gIGlmKGxhc3RDb21taXQpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLWxhc3RDb21taXQnKTtcbiAgfVxuXG4gIGlmKGxpc3RUZXN0cykge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tbGlzdFRlc3RzJyk7XG4gIH1cblxuICBpZihsb2dIZWFwVXNhZ2UpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLWxvZ0hlYXBVc2FnZScpO1xuICB9XG5cbiAgaWYobWF4V29ya2Vycykge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tbWF4V29ya2VycycsIG1heFdvcmtlcnMpO1xuICB9XG5cbiAgaWYobm9TdGFja1RyYWNlKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1ub1N0YWNrVHJhY2UnKTtcbiAgfVxuXG4gIGlmKG5vdGlmeSkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tbm90aWZ5Jyk7XG4gIH1cblxuICBpZihvbmx5Q2hhbmdlZCkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tb25seUNoYW5nZWQnKTtcbiAgfVxuXG4gIGxldCB0ZW1wT3V0cHV0RmlsZSA9IG91dHB1dEZpbGU7XG5cbiAgaWYoKHVzZUFuYWx5emUgfHwgdXNlRGVidWcpICYmICFvdXRwdXRGaWxlKSB7XG4gICAgdGVtcE91dHB1dEZpbGUgPSAnLmxleC10ZXN0LXJlc3VsdHMuanNvbic7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1qc29uJywgJy0tb3V0cHV0RmlsZScsIHRlbXBPdXRwdXRGaWxlKTtcbiAgfSBlbHNlIGlmKG91dHB1dEZpbGUpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLW91dHB1dEZpbGUnLCBvdXRwdXRGaWxlKTtcbiAgfVxuXG4gIGlmKHBhc3NXaXRoTm9UZXN0cykge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tcGFzc1dpdGhOb1Rlc3RzJyk7XG4gIH1cblxuICBpZihydW5JbkJhbmQpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLXJ1bkluQmFuZCcpO1xuICB9XG5cbiAgaWYoc2hvd0NvbmZpZykge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tc2hvd0NvbmZpZycpO1xuICB9XG5cbiAgaWYoc2lsZW50KSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS1zaWxlbnQnKTtcbiAgfVxuXG4gIGlmKHRlc3RMb2NhdGlvbkluUmVzdWx0cykge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tdGVzdExvY2F0aW9uSW5SZXN1bHRzJyk7XG4gIH1cblxuICBpZih0ZXN0TmFtZVBhdHRlcm4pIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLXRlc3ROYW1lUGF0dGVybicsIHRlc3ROYW1lUGF0dGVybik7XG4gIH1cblxuICBpZih0ZXN0UGF0aFBhdHRlcm4pIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLXRlc3RQYXRoUGF0dGVybicsIHRlc3RQYXRoUGF0dGVybik7XG4gIH1cblxuICBpZih1c2VTdGRlcnIpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLXVzZVN0ZGVycicpO1xuICB9XG5cbiAgaWYodmVyYm9zZSkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tdmVyYm9zZScpO1xuICB9XG5cbiAgaWYod2F0Y2hBbGwpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKCctLXdhdGNoQWxsJyk7XG4gIH1cblxuICBpZihyZW1vdmVDYWNoZSkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tbm8tY2FjaGUnKTtcbiAgfVxuXG4gIGlmKGplc3RTZXR1cEZpbGUgJiYgZXhpc3RzU3luYyhqZXN0U2V0dXBGaWxlKSkge1xuICAgIGplc3RPcHRpb25zLnB1c2goYC0tc2V0dXBGaWxlc0FmdGVyRW52PSR7amVzdFNldHVwRmlsZX1gKTtcbiAgfVxuXG4gIGlmKHVwZGF0ZSkge1xuICAgIGplc3RPcHRpb25zLnB1c2goJy0tdXBkYXRlU25hcHNob3QnKTtcbiAgfVxuXG4gIGlmKHdhdGNoKSB7XG4gICAgamVzdE9wdGlvbnMucHVzaCgnLS13YXRjaCcsIHdhdGNoKTtcbiAgfVxuXG4gIGlmKGFyZ3MpIHtcbiAgICBqZXN0T3B0aW9ucy5wdXNoKC4uLmFyZ3MpO1xuICB9XG5cbiAgaWYoZGVidWcpIHtcbiAgICBsb2coYEplc3Qgb3B0aW9uczogJHtqZXN0T3B0aW9ucy5qb2luKCcgJyl9YCwgJ2luZm8nLCBxdWlldCk7XG4gICAgbG9nKGBOT0RFX09QVElPTlM6ICR7bm9kZU9wdGlvbnN9YCwgJ2luZm8nLCBxdWlldCk7XG4gIH1cblxuICB0cnkge1xuICAgIGNvbnN0IGVudjogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICAgIC4uLnByb2Nlc3MuZW52LFxuICAgICAgTk9ERV9PUFRJT05TOiBub2RlT3B0aW9uc1xuICAgIH07XG5cbiAgICBhd2FpdCBleGVjYShqZXN0UGF0aCwgamVzdE9wdGlvbnMsIHtcbiAgICAgIGVuY29kaW5nOiAndXRmOCcsXG4gICAgICBzdGRpbzogJ2luaGVyaXQnLFxuICAgICAgZW52XG4gICAgfSk7XG5cbiAgICBzcGlubmVyLnN1Y2NlZWQoJ1Rlc3RpbmcgY29tcGxldGVkIScpO1xuXG4gICAgaWYodXNlQW5hbHl6ZSkge1xuICAgICAgc3Bpbm5lci5zdGFydCgnQUkgaXMgYW5hbHl6aW5nIHRlc3QgY292ZXJhZ2UgYW5kIHN1Z2dlc3RpbmcgaW1wcm92ZW1lbnRzLi4uJyk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHRlc3RSZXN1bHRzID0gcHJvY2Vzc1Rlc3RSZXN1bHRzKHRlbXBPdXRwdXRGaWxlKTtcbiAgICAgICAgY29uc3QgZmlsZVBhdHRlcm5zID0gZ2V0VGVzdEZpbGVQYXR0ZXJucyh0ZXN0UGF0aFBhdHRlcm4pO1xuXG4gICAgICAgIGF3YWl0IGFpRnVuY3Rpb24oe1xuICAgICAgICAgIHByb21wdDogYEFuYWx5emUgdGhlc2UgSmVzdCB0ZXN0IHJlc3VsdHMgYW5kIHN1Z2dlc3QgdGVzdCBjb3ZlcmFnZSBpbXByb3ZlbWVudHM6XG5cbiR7SlNPTi5zdHJpbmdpZnkodGVzdFJlc3VsdHMsIG51bGwsIDIpfVxuXG5UZXN0IHBhdHRlcm5zOiAke2ZpbGVQYXR0ZXJucy5qb2luKCcsICcpfVxuXG5QbGVhc2UgcHJvdmlkZTpcbjEuIEFuYWx5c2lzIG9mIGN1cnJlbnQgY292ZXJhZ2UgZ2Fwc1xuMi4gU3VnZ2VzdGlvbnMgZm9yIGltcHJvdmluZyB0ZXN0IGNhc2VzXG4zLiBSZWNvbW1lbmRhdGlvbnMgZm9yIGFkZGl0aW9uYWwgaW50ZWdyYXRpb24gdGVzdCBzY2VuYXJpb3NcbjQuIEJlc3QgcHJhY3RpY2VzIGZvciBpbmNyZWFzaW5nIHRlc3QgZWZmZWN0aXZlbmVzc2AsXG4gICAgICAgICAgdGFzazogJ29wdGltaXplJyxcbiAgICAgICAgICBjb250ZXh0OiB0cnVlLFxuICAgICAgICAgIHF1aWV0XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNwaW5uZXIuc3VjY2VlZCgnQUkgdGVzdCBhbmFseXNpcyBjb21wbGV0ZScpO1xuICAgICAgfSBjYXRjaCAoYWlFcnJvcikge1xuICAgICAgICBzcGlubmVyLmZhaWwoJ0NvdWxkIG5vdCBnZW5lcmF0ZSBBSSB0ZXN0IGFuYWx5c2lzJyk7XG4gICAgICAgIGlmKCFxdWlldCkge1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgICAgY29uc29sZS5lcnJvcignQUkgYW5hbHlzaXMgZXJyb3I6JywgYWlFcnJvcik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBjYWxsYmFjaygwKTtcbiAgICByZXR1cm4gMDtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBsb2coYFxcbiR7Y2xpTmFtZX0gRXJyb3I6IENoZWNrIGZvciB1bml0IHRlc3QgZXJyb3JzIGFuZC9vciBjb3ZlcmFnZS5gLCAnZXJyb3InLCBxdWlldCk7XG5cbiAgICBzcGlubmVyLmZhaWwoJ1Rlc3RpbmcgZmFpbGVkIScpO1xuXG4gICAgaWYodXNlRGVidWcpIHtcbiAgICAgIHNwaW5uZXIuc3RhcnQoJ0FJIGlzIGFuYWx5emluZyB0ZXN0IGZhaWx1cmVzLi4uJyk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHRlc3RSZXN1bHRzID0gcHJvY2Vzc1Rlc3RSZXN1bHRzKHRlbXBPdXRwdXRGaWxlKTtcblxuICAgICAgICBhd2FpdCBhaUZ1bmN0aW9uKHtcbiAgICAgICAgICBjb250ZXh0OiB0cnVlLFxuICAgICAgICAgIHByb21wdDogYERlYnVnIHRoZXNlIGZhaWxlZCBKZXN0IHRlc3RzIGFuZCBzdWdnZXN0IGZpeGVzOlxuXG4ke0pTT04uc3RyaW5naWZ5KGVycm9yLm1lc3NhZ2UsIG51bGwsIDIpfVxuXG5UZXN0IHJlc3VsdHM6ICR7SlNPTi5zdHJpbmdpZnkodGVzdFJlc3VsdHMsIG51bGwsIDIpfVxuXG5QbGVhc2UgcHJvdmlkZTpcbjEuIEFuYWx5c2lzIG9mIHdoeSB0aGUgdGVzdHMgYXJlIGZhaWxpbmdcbjIuIFNwZWNpZmljIHN1Z2dlc3Rpb25zIHRvIGZpeCBlYWNoIGZhaWxpbmcgdGVzdFxuMy4gQW55IHBvdGVudGlhbCBpc3N1ZXMgd2l0aCB0ZXN0IGZpeHR1cmVzIG9yIG1vY2tzXG40LiBDb2RlIGV4YW1wbGVzIGZvciBzb2x1dGlvbnNgLFxuICAgICAgICAgIHF1aWV0LFxuICAgICAgICAgIHRhc2s6ICdoZWxwJ1xuICAgICAgICB9KTtcblxuICAgICAgICBzcGlubmVyLnN1Y2NlZWQoJ0FJIGRlYnVnZ2luZyBhc3Npc3RhbmNlIGNvbXBsZXRlJyk7XG4gICAgICB9IGNhdGNoIChhaUVycm9yKSB7XG4gICAgICAgIHNwaW5uZXIuZmFpbCgnQ291bGQgbm90IGdlbmVyYXRlIEFJIGRlYnVnZ2luZyBhc3Npc3RhbmNlJyk7XG4gICAgICAgIGlmKCFxdWlldCkge1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgICAgY29uc29sZS5lcnJvcignQUkgZGVidWdnaW5nIGVycm9yOicsIGFpRXJyb3IpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgY2FsbGJh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
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { execa } from "execa";
|
|
2
|
+
import { LexConfig } from "../../LexConfig.js";
|
|
3
|
+
import { createSpinner } from "../../utils/app.js";
|
|
4
|
+
import { log } from "../../utils/log.js";
|
|
5
|
+
const update = async (cmd, callback = process.exit) => {
|
|
6
|
+
const { cliName = "Lex", packageManager: cmdPackageManager, quiet, registry } = cmd;
|
|
7
|
+
log(`${cliName} updating packages...`, "info", quiet);
|
|
8
|
+
const spinner = createSpinner(quiet);
|
|
9
|
+
await LexConfig.parseConfig(cmd);
|
|
10
|
+
const { packageManager: configPackageManager } = LexConfig.config;
|
|
11
|
+
const packageManager = cmdPackageManager || configPackageManager || "npm";
|
|
12
|
+
const isNpm = packageManager === "npm";
|
|
13
|
+
try {
|
|
14
|
+
if (isNpm) {
|
|
15
|
+
let ncuCommand;
|
|
16
|
+
let ncuArgs;
|
|
17
|
+
try {
|
|
18
|
+
ncuCommand = "npx";
|
|
19
|
+
ncuArgs = [
|
|
20
|
+
"npm-check-updates",
|
|
21
|
+
"--concurrency",
|
|
22
|
+
"10",
|
|
23
|
+
"--packageManager",
|
|
24
|
+
packageManager,
|
|
25
|
+
"--pre",
|
|
26
|
+
"0",
|
|
27
|
+
"--target",
|
|
28
|
+
"latest",
|
|
29
|
+
...cmd.interactive ? ["--interactive"] : [],
|
|
30
|
+
"--upgrade"
|
|
31
|
+
];
|
|
32
|
+
if (registry) {
|
|
33
|
+
ncuArgs.push("--registry", registry);
|
|
34
|
+
}
|
|
35
|
+
await execa(ncuCommand, ncuArgs, {
|
|
36
|
+
encoding: "utf8",
|
|
37
|
+
stdio: "inherit"
|
|
38
|
+
});
|
|
39
|
+
} catch {
|
|
40
|
+
try {
|
|
41
|
+
ncuCommand = "npm-check-updates";
|
|
42
|
+
ncuArgs = [
|
|
43
|
+
"--concurrency",
|
|
44
|
+
"10",
|
|
45
|
+
"--packageManager",
|
|
46
|
+
packageManager,
|
|
47
|
+
"--pre",
|
|
48
|
+
"0",
|
|
49
|
+
"--target",
|
|
50
|
+
"latest",
|
|
51
|
+
...cmd.interactive ? ["--interactive"] : [],
|
|
52
|
+
"--upgrade"
|
|
53
|
+
];
|
|
54
|
+
if (registry) {
|
|
55
|
+
ncuArgs.push("--registry", registry);
|
|
56
|
+
}
|
|
57
|
+
await execa(ncuCommand, ncuArgs, {
|
|
58
|
+
encoding: "utf8",
|
|
59
|
+
stdio: "inherit"
|
|
60
|
+
});
|
|
61
|
+
} catch {
|
|
62
|
+
log("npm-check-updates not found. Installing it globally...", "info", quiet);
|
|
63
|
+
try {
|
|
64
|
+
await execa("npm", ["install", "-g", "npm-check-updates"], {
|
|
65
|
+
encoding: "utf8",
|
|
66
|
+
stdio: "inherit"
|
|
67
|
+
});
|
|
68
|
+
ncuCommand = "npm-check-updates";
|
|
69
|
+
ncuArgs = [
|
|
70
|
+
"--concurrency",
|
|
71
|
+
"10",
|
|
72
|
+
"--packageManager",
|
|
73
|
+
packageManager,
|
|
74
|
+
"--pre",
|
|
75
|
+
"0",
|
|
76
|
+
"--target",
|
|
77
|
+
"latest",
|
|
78
|
+
...cmd.interactive ? ["--interactive"] : [],
|
|
79
|
+
"--upgrade"
|
|
80
|
+
];
|
|
81
|
+
if (registry) {
|
|
82
|
+
ncuArgs.push("--registry", registry);
|
|
83
|
+
}
|
|
84
|
+
await execa(ncuCommand, ncuArgs, {
|
|
85
|
+
encoding: "utf8",
|
|
86
|
+
stdio: "inherit"
|
|
87
|
+
});
|
|
88
|
+
} catch (installError) {
|
|
89
|
+
log(`Failed to install or use npm-check-updates: ${installError.message}`, "error", quiet);
|
|
90
|
+
log("Please install npm-check-updates manually: npm install -g npm-check-updates", "info", quiet);
|
|
91
|
+
throw installError;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
await execa("npm", ["i", "--force"], {
|
|
96
|
+
encoding: "utf8",
|
|
97
|
+
stdio: "inherit"
|
|
98
|
+
});
|
|
99
|
+
await execa("npm", ["audit", "fix"], {
|
|
100
|
+
encoding: "utf8",
|
|
101
|
+
stdio: "inherit"
|
|
102
|
+
});
|
|
103
|
+
} else {
|
|
104
|
+
const updateApp = "yarn";
|
|
105
|
+
const updateOptions = [cmd.interactive ? "upgrade-interactive" : "upgrade", "--latest"];
|
|
106
|
+
if (registry) {
|
|
107
|
+
updateOptions.push("--registry", registry);
|
|
108
|
+
}
|
|
109
|
+
await execa(updateApp, updateOptions, {
|
|
110
|
+
encoding: "utf8",
|
|
111
|
+
stdio: "inherit"
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
spinner.succeed("Successfully updated packages!");
|
|
115
|
+
callback(0);
|
|
116
|
+
return 0;
|
|
117
|
+
} catch (error) {
|
|
118
|
+
log(`
|
|
119
|
+
${cliName} Error: ${error.message}`, "error", quiet);
|
|
120
|
+
spinner.fail("Failed to update packages.");
|
|
121
|
+
callback(1);
|
|
122
|
+
return 1;
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
export {
|
|
126
|
+
update
|
|
127
|
+
};
|
|
128
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2NvbW1hbmRzL3VwZGF0ZS91cGRhdGUudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQ29weXJpZ2h0IChjKSAyMDE4LVByZXNlbnQsIE5pdHJvZ2VuIExhYnMsIEluYy5cbiAqIENvcHlyaWdodHMgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLiBTZWUgdGhlIGFjY29tcGFueWluZyBMSUNFTlNFIGZpbGUgZm9yIHRlcm1zLlxuICovXG5pbXBvcnQge2V4ZWNhfSBmcm9tICdleGVjYSc7XG5cbmltcG9ydCB7TGV4Q29uZmlnfSBmcm9tICcuLi8uLi9MZXhDb25maWcuanMnO1xuaW1wb3J0IHtjcmVhdGVTcGlubmVyfSBmcm9tICcuLi8uLi91dGlscy9hcHAuanMnO1xuaW1wb3J0IHtsb2d9IGZyb20gJy4uLy4uL3V0aWxzL2xvZy5qcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVXBkYXRlT3B0aW9ucyB7XG4gIHJlYWRvbmx5IGNsaU5hbWU/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGludGVyYWN0aXZlPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgcGFja2FnZU1hbmFnZXI/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHF1aWV0PzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgcmVnaXN0cnk/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCB0eXBlIFVwZGF0ZUNhbGxiYWNrID0gdHlwZW9mIHByb2Nlc3MuZXhpdDtcblxuZXhwb3J0IGNvbnN0IHVwZGF0ZSA9IGFzeW5jIChjbWQ6IFVwZGF0ZU9wdGlvbnMsIGNhbGxiYWNrOiBVcGRhdGVDYWxsYmFjayA9IHByb2Nlc3MuZXhpdCk6IFByb21pc2U8bnVtYmVyPiA9PiB7XG4gIGNvbnN0IHtjbGlOYW1lID0gJ0xleCcsIHBhY2thZ2VNYW5hZ2VyOiBjbWRQYWNrYWdlTWFuYWdlciwgcXVpZXQsIHJlZ2lzdHJ5fSA9IGNtZDtcblxuICBsb2coYCR7Y2xpTmFtZX0gdXBkYXRpbmcgcGFja2FnZXMuLi5gLCAnaW5mbycsIHF1aWV0KTtcblxuICBjb25zdCBzcGlubmVyID0gY3JlYXRlU3Bpbm5lcihxdWlldCk7XG5cbiAgYXdhaXQgTGV4Q29uZmlnLnBhcnNlQ29uZmlnKGNtZCk7XG5cbiAgY29uc3Qge3BhY2thZ2VNYW5hZ2VyOiBjb25maWdQYWNrYWdlTWFuYWdlcn0gPSBMZXhDb25maWcuY29uZmlnO1xuICBjb25zdCBwYWNrYWdlTWFuYWdlcjogc3RyaW5nID0gY21kUGFja2FnZU1hbmFnZXIgfHwgY29uZmlnUGFja2FnZU1hbmFnZXIgfHwgJ25wbSc7XG4gIGNvbnN0IGlzTnBtOiBib29sZWFuID0gcGFja2FnZU1hbmFnZXIgPT09ICducG0nO1xuXG4gIHRyeSB7XG4gICAgaWYoaXNOcG0pIHtcbiAgICAgIGxldCBuY3VDb21tYW5kOiBzdHJpbmc7XG4gICAgICBsZXQgbmN1QXJnczogc3RyaW5nW107XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIG5jdUNvbW1hbmQgPSAnbnB4JztcbiAgICAgICAgbmN1QXJncyA9IFtcbiAgICAgICAgICAnbnBtLWNoZWNrLXVwZGF0ZXMnLFxuICAgICAgICAgICctLWNvbmN1cnJlbmN5JywgJzEwJyxcbiAgICAgICAgICAnLS1wYWNrYWdlTWFuYWdlcicsIHBhY2thZ2VNYW5hZ2VyLFxuICAgICAgICAgICctLXByZScsICcwJyxcbiAgICAgICAgICAnLS10YXJnZXQnLCAnbGF0ZXN0JyxcbiAgICAgICAgICAuLi4oY21kLmludGVyYWN0aXZlID8gWyctLWludGVyYWN0aXZlJ10gOiBbXSksXG4gICAgICAgICAgJy0tdXBncmFkZSdcbiAgICAgICAgXTtcblxuICAgICAgICBpZihyZWdpc3RyeSkge1xuICAgICAgICAgIG5jdUFyZ3MucHVzaCgnLS1yZWdpc3RyeScsIHJlZ2lzdHJ5KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGF3YWl0IGV4ZWNhKG5jdUNvbW1hbmQsIG5jdUFyZ3MsIHtcbiAgICAgICAgICBlbmNvZGluZzogJ3V0ZjgnLFxuICAgICAgICAgIHN0ZGlvOiAnaW5oZXJpdCdcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBuY3VDb21tYW5kID0gJ25wbS1jaGVjay11cGRhdGVzJztcbiAgICAgICAgICBuY3VBcmdzID0gW1xuICAgICAgICAgICAgJy0tY29uY3VycmVuY3knLCAnMTAnLFxuICAgICAgICAgICAgJy0tcGFja2FnZU1hbmFnZXInLCBwYWNrYWdlTWFuYWdlcixcbiAgICAgICAgICAgICctLXByZScsICcwJyxcbiAgICAgICAgICAgICctLXRhcmdldCcsICdsYXRlc3QnLFxuICAgICAgICAgICAgLi4uKGNtZC5pbnRlcmFjdGl2ZSA/IFsnLS1pbnRlcmFjdGl2ZSddIDogW10pLFxuICAgICAgICAgICAgJy0tdXBncmFkZSdcbiAgICAgICAgICBdO1xuXG4gICAgICAgICAgaWYocmVnaXN0cnkpIHtcbiAgICAgICAgICAgIG5jdUFyZ3MucHVzaCgnLS1yZWdpc3RyeScsIHJlZ2lzdHJ5KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBhd2FpdCBleGVjYShuY3VDb21tYW5kLCBuY3VBcmdzLCB7XG4gICAgICAgICAgICBlbmNvZGluZzogJ3V0ZjgnLFxuICAgICAgICAgICAgc3RkaW86ICdpbmhlcml0J1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICBsb2coJ25wbS1jaGVjay11cGRhdGVzIG5vdCBmb3VuZC4gSW5zdGFsbGluZyBpdCBnbG9iYWxseS4uLicsICdpbmZvJywgcXVpZXQpO1xuXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IGV4ZWNhKCducG0nLCBbJ2luc3RhbGwnLCAnLWcnLCAnbnBtLWNoZWNrLXVwZGF0ZXMnXSwge1xuICAgICAgICAgICAgICBlbmNvZGluZzogJ3V0ZjgnLFxuICAgICAgICAgICAgICBzdGRpbzogJ2luaGVyaXQnXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgbmN1Q29tbWFuZCA9ICducG0tY2hlY2stdXBkYXRlcyc7XG4gICAgICAgICAgICBuY3VBcmdzID0gW1xuICAgICAgICAgICAgICAnLS1jb25jdXJyZW5jeScsICcxMCcsXG4gICAgICAgICAgICAgICctLXBhY2thZ2VNYW5hZ2VyJywgcGFja2FnZU1hbmFnZXIsXG4gICAgICAgICAgICAgICctLXByZScsICcwJyxcbiAgICAgICAgICAgICAgJy0tdGFyZ2V0JywgJ2xhdGVzdCcsXG4gICAgICAgICAgICAgIC4uLihjbWQuaW50ZXJhY3RpdmUgPyBbJy0taW50ZXJhY3RpdmUnXSA6IFtdKSxcbiAgICAgICAgICAgICAgJy0tdXBncmFkZSdcbiAgICAgICAgICAgIF07XG5cbiAgICAgICAgICAgIGlmKHJlZ2lzdHJ5KSB7XG4gICAgICAgICAgICAgIG5jdUFyZ3MucHVzaCgnLS1yZWdpc3RyeScsIHJlZ2lzdHJ5KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgYXdhaXQgZXhlY2EobmN1Q29tbWFuZCwgbmN1QXJncywge1xuICAgICAgICAgICAgICBlbmNvZGluZzogJ3V0ZjgnLFxuICAgICAgICAgICAgICBzdGRpbzogJ2luaGVyaXQnXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9IGNhdGNoIChpbnN0YWxsRXJyb3IpIHtcbiAgICAgICAgICAgIGxvZyhgRmFpbGVkIHRvIGluc3RhbGwgb3IgdXNlIG5wbS1jaGVjay11cGRhdGVzOiAke2luc3RhbGxFcnJvci5tZXNzYWdlfWAsICdlcnJvcicsIHF1aWV0KTtcbiAgICAgICAgICAgIGxvZygnUGxlYXNlIGluc3RhbGwgbnBtLWNoZWNrLXVwZGF0ZXMgbWFudWFsbHk6IG5wbSBpbnN0YWxsIC1nIG5wbS1jaGVjay11cGRhdGVzJywgJ2luZm8nLCBxdWlldCk7XG4gICAgICAgICAgICB0aHJvdyBpbnN0YWxsRXJyb3I7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIEFmdGVyIHN1Y2Nlc3NmdWwgdXBkYXRlLCBydW4gbnBtIGluc3RhbGwgYW5kIGF1ZGl0IGZpeFxuICAgICAgYXdhaXQgZXhlY2EoJ25wbScsIFsnaScsICctLWZvcmNlJ10sIHtcbiAgICAgICAgZW5jb2Rpbmc6ICd1dGY4JyxcbiAgICAgICAgc3RkaW86ICdpbmhlcml0J1xuICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IGV4ZWNhKCducG0nLCBbJ2F1ZGl0JywgJ2ZpeCddLCB7XG4gICAgICAgIGVuY29kaW5nOiAndXRmOCcsXG4gICAgICAgIHN0ZGlvOiAnaW5oZXJpdCdcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBVc2UgeWFyblxuICAgICAgY29uc3QgdXBkYXRlQXBwID0gJ3lhcm4nO1xuICAgICAgY29uc3QgdXBkYXRlT3B0aW9uczogc3RyaW5nW10gPSBbY21kLmludGVyYWN0aXZlID8gJ3VwZ3JhZGUtaW50ZXJhY3RpdmUnIDogJ3VwZ3JhZGUnLCAnLS1sYXRlc3QnXTtcblxuICAgICAgaWYocmVnaXN0cnkpIHtcbiAgICAgICAgdXBkYXRlT3B0aW9ucy5wdXNoKCctLXJlZ2lzdHJ5JywgcmVnaXN0cnkpO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCBleGVjYSh1cGRhdGVBcHAsIHVwZGF0ZU9wdGlvbnMsIHtcbiAgICAgICAgZW5jb2Rpbmc6ICd1dGY4JyxcbiAgICAgICAgc3RkaW86ICdpbmhlcml0J1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgc3Bpbm5lci5zdWNjZWVkKCdTdWNjZXNzZnVsbHkgdXBkYXRlZCBwYWNrYWdlcyEnKTtcblxuICAgIGNhbGxiYWNrKDApO1xuICAgIHJldHVybiAwO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGxvZyhgXFxuJHtjbGlOYW1lfSBFcnJvcjogJHtlcnJvci5tZXNzYWdlfWAsICdlcnJvcicsIHF1aWV0KTtcblxuICAgIHNwaW5uZXIuZmFpbCgnRmFpbGVkIHRvIHVwZGF0ZSBwYWNrYWdlcy4nKTtcblxuICAgIGNhbGxiYWNrKDEpO1xuICAgIHJldHVybiAxO1xuICB9XG59OyJdLAogICJtYXBwaW5ncyI6ICJBQUlBLFNBQVEsYUFBWTtBQUVwQixTQUFRLGlCQUFnQjtBQUN4QixTQUFRLHFCQUFvQjtBQUM1QixTQUFRLFdBQVU7QUFZWCxNQUFNLFNBQVMsT0FBTyxLQUFvQixXQUEyQixRQUFRLFNBQTBCO0FBQzVHLFFBQU0sRUFBQyxVQUFVLE9BQU8sZ0JBQWdCLG1CQUFtQixPQUFPLFNBQVEsSUFBSTtBQUU5RSxNQUFJLEdBQUcsT0FBTyx5QkFBeUIsUUFBUSxLQUFLO0FBRXBELFFBQU0sVUFBVSxjQUFjLEtBQUs7QUFFbkMsUUFBTSxVQUFVLFlBQVksR0FBRztBQUUvQixRQUFNLEVBQUMsZ0JBQWdCLHFCQUFvQixJQUFJLFVBQVU7QUFDekQsUUFBTSxpQkFBeUIscUJBQXFCLHdCQUF3QjtBQUM1RSxRQUFNLFFBQWlCLG1CQUFtQjtBQUUxQyxNQUFJO0FBQ0YsUUFBRyxPQUFPO0FBQ1IsVUFBSTtBQUNKLFVBQUk7QUFFSixVQUFJO0FBQ0YscUJBQWE7QUFDYixrQkFBVTtBQUFBLFVBQ1I7QUFBQSxVQUNBO0FBQUEsVUFBaUI7QUFBQSxVQUNqQjtBQUFBLFVBQW9CO0FBQUEsVUFDcEI7QUFBQSxVQUFTO0FBQUEsVUFDVDtBQUFBLFVBQVk7QUFBQSxVQUNaLEdBQUksSUFBSSxjQUFjLENBQUMsZUFBZSxJQUFJLENBQUM7QUFBQSxVQUMzQztBQUFBLFFBQ0Y7QUFFQSxZQUFHLFVBQVU7QUFDWCxrQkFBUSxLQUFLLGNBQWMsUUFBUTtBQUFBLFFBQ3JDO0FBRUEsY0FBTSxNQUFNLFlBQVksU0FBUztBQUFBLFVBQy9CLFVBQVU7QUFBQSxVQUNWLE9BQU87QUFBQSxRQUNULENBQUM7QUFBQSxNQUNILFFBQVE7QUFDTixZQUFJO0FBQ0YsdUJBQWE7QUFDYixvQkFBVTtBQUFBLFlBQ1I7QUFBQSxZQUFpQjtBQUFBLFlBQ2pCO0FBQUEsWUFBb0I7QUFBQSxZQUNwQjtBQUFBLFlBQVM7QUFBQSxZQUNUO0FBQUEsWUFBWTtBQUFBLFlBQ1osR0FBSSxJQUFJLGNBQWMsQ0FBQyxlQUFlLElBQUksQ0FBQztBQUFBLFlBQzNDO0FBQUEsVUFDRjtBQUVBLGNBQUcsVUFBVTtBQUNYLG9CQUFRLEtBQUssY0FBYyxRQUFRO0FBQUEsVUFDckM7QUFFQSxnQkFBTSxNQUFNLFlBQVksU0FBUztBQUFBLFlBQy9CLFVBQVU7QUFBQSxZQUNWLE9BQU87QUFBQSxVQUNULENBQUM7QUFBQSxRQUNILFFBQVE7QUFDTixjQUFJLDBEQUEwRCxRQUFRLEtBQUs7QUFFM0UsY0FBSTtBQUNGLGtCQUFNLE1BQU0sT0FBTyxDQUFDLFdBQVcsTUFBTSxtQkFBbUIsR0FBRztBQUFBLGNBQ3pELFVBQVU7QUFBQSxjQUNWLE9BQU87QUFBQSxZQUNULENBQUM7QUFFRCx5QkFBYTtBQUNiLHNCQUFVO0FBQUEsY0FDUjtBQUFBLGNBQWlCO0FBQUEsY0FDakI7QUFBQSxjQUFvQjtBQUFBLGNBQ3BCO0FBQUEsY0FBUztBQUFBLGNBQ1Q7QUFBQSxjQUFZO0FBQUEsY0FDWixHQUFJLElBQUksY0FBYyxDQUFDLGVBQWUsSUFBSSxDQUFDO0FBQUEsY0FDM0M7QUFBQSxZQUNGO0FBRUEsZ0JBQUcsVUFBVTtBQUNYLHNCQUFRLEtBQUssY0FBYyxRQUFRO0FBQUEsWUFDckM7QUFFQSxrQkFBTSxNQUFNLFlBQVksU0FBUztBQUFBLGNBQy9CLFVBQVU7QUFBQSxjQUNWLE9BQU87QUFBQSxZQUNULENBQUM7QUFBQSxVQUNILFNBQVMsY0FBYztBQUNyQixnQkFBSSwrQ0FBK0MsYUFBYSxPQUFPLElBQUksU0FBUyxLQUFLO0FBQ3pGLGdCQUFJLCtFQUErRSxRQUFRLEtBQUs7QUFDaEcsa0JBQU07QUFBQSxVQUNSO0FBQUEsUUFDRjtBQUFBLE1BQ0Y7QUFHQSxZQUFNLE1BQU0sT0FBTyxDQUFDLEtBQUssU0FBUyxHQUFHO0FBQUEsUUFDbkMsVUFBVTtBQUFBLFFBQ1YsT0FBTztBQUFBLE1BQ1QsQ0FBQztBQUVELFlBQU0sTUFBTSxPQUFPLENBQUMsU0FBUyxLQUFLLEdBQUc7QUFBQSxRQUNuQyxVQUFVO0FBQUEsUUFDVixPQUFPO0FBQUEsTUFDVCxDQUFDO0FBQUEsSUFDSCxPQUFPO0FBRUwsWUFBTSxZQUFZO0FBQ2xCLFlBQU0sZ0JBQTBCLENBQUMsSUFBSSxjQUFjLHdCQUF3QixXQUFXLFVBQVU7QUFFaEcsVUFBRyxVQUFVO0FBQ1gsc0JBQWMsS0FBSyxjQUFjLFFBQVE7QUFBQSxNQUMzQztBQUVBLFlBQU0sTUFBTSxXQUFXLGVBQWU7QUFBQSxRQUNwQyxVQUFVO0FBQUEsUUFDVixPQUFPO0FBQUEsTUFDVCxDQUFDO0FBQUEsSUFDSDtBQUVBLFlBQVEsUUFBUSxnQ0FBZ0M7QUFFaEQsYUFBUyxDQUFDO0FBQ1YsV0FBTztBQUFBLEVBQ1QsU0FBUyxPQUFPO0FBQ2QsUUFBSTtBQUFBLEVBQUssT0FBTyxXQUFXLE1BQU0sT0FBTyxJQUFJLFNBQVMsS0FBSztBQUUxRCxZQUFRLEtBQUssNEJBQTRCO0FBRXpDLGFBQVMsQ0FBQztBQUNWLFdBQU87QUFBQSxFQUNUO0FBQ0Y7IiwKICAibmFtZXMiOiBbXQp9Cg==
|