@dudousxd/nestjs-codegen 0.16.0 → 0.17.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/CHANGELOG.md +37 -0
- package/dist/cli/main.cjs +142 -97
- package/dist/cli/main.cjs.map +1 -1
- package/dist/cli/main.js +83 -38
- package/dist/cli/main.js.map +1 -1
- package/dist/extension/index.cjs.map +1 -1
- package/dist/extension/index.d.cts +1 -1
- package/dist/extension/index.d.ts +1 -1
- package/dist/extension/index.js.map +1 -1
- package/dist/{index-LQNP7Ms3.d.cts → index-DCF9QSPY.d.cts} +24 -0
- package/dist/{index-LQNP7Ms3.d.ts → index-DCF9QSPY.d.ts} +24 -0
- package/dist/index.cjs +105 -60
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -3
- package/dist/index.d.ts +12 -3
- package/dist/index.js +77 -32
- package/dist/index.js.map +1 -1
- package/dist/nest/index.cjs +105 -60
- package/dist/nest/index.cjs.map +1 -1
- package/dist/nest/index.d.cts +1 -1
- package/dist/nest/index.d.ts +1 -1
- package/dist/nest/index.js +77 -32
- package/dist/nest/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/main.js
CHANGED
|
@@ -514,9 +514,10 @@ function inferExpressionType(node) {
|
|
|
514
514
|
|
|
515
515
|
// src/emit/emit-api.ts
|
|
516
516
|
import { mkdir, writeFile } from "fs/promises";
|
|
517
|
-
import { isAbsolute as isAbsolute2, join as join4, relative as
|
|
517
|
+
import { isAbsolute as isAbsolute2, join as join4, relative as relative4 } from "path";
|
|
518
518
|
|
|
519
519
|
// src/extension/registry.ts
|
|
520
|
+
import { relative as relative3, resolve as resolve2 } from "path";
|
|
520
521
|
import { Project as Project2 } from "ts-morph";
|
|
521
522
|
function resolveApiSlots(extensions) {
|
|
522
523
|
let layer;
|
|
@@ -549,7 +550,7 @@ function mergeExclusive(target, incoming, {
|
|
|
549
550
|
target.set(key, { value, owner });
|
|
550
551
|
}
|
|
551
552
|
}
|
|
552
|
-
function createExtensionContext(config, getRoutes) {
|
|
553
|
+
function createExtensionContext(config, getRoutes, trackedInputs) {
|
|
553
554
|
let project;
|
|
554
555
|
return {
|
|
555
556
|
cwd: config.codegen.cwd,
|
|
@@ -558,6 +559,13 @@ function createExtensionContext(config, getRoutes) {
|
|
|
558
559
|
get routes() {
|
|
559
560
|
return getRoutes();
|
|
560
561
|
},
|
|
562
|
+
trackInput(...paths) {
|
|
563
|
+
if (!trackedInputs) return;
|
|
564
|
+
for (const path of paths) {
|
|
565
|
+
if (!path) continue;
|
|
566
|
+
trackedInputs.add(relative3(config.codegen.cwd, resolve2(config.codegen.cwd, path)));
|
|
567
|
+
}
|
|
568
|
+
},
|
|
561
569
|
project() {
|
|
562
570
|
if (!project) {
|
|
563
571
|
project = new Project2({
|
|
@@ -725,7 +733,7 @@ function rawResponseType(c, outDir) {
|
|
|
725
733
|
return c.contractSource.response;
|
|
726
734
|
}
|
|
727
735
|
if (c.controllerRef) {
|
|
728
|
-
let relPath =
|
|
736
|
+
let relPath = relative4(outDir, c.controllerRef.filePath).replace(/\.ts$/, "");
|
|
729
737
|
if (!relPath.startsWith(".")) relPath = `./${relPath}`;
|
|
730
738
|
return `Awaited<ReturnType<import('${relPath}').${c.controllerRef.className}['${c.controllerRef.methodName}']>>`;
|
|
731
739
|
}
|
|
@@ -1051,6 +1059,11 @@ function buildApiFile(routes, outDir, opts = {}) {
|
|
|
1051
1059
|
config: {},
|
|
1052
1060
|
project: () => {
|
|
1053
1061
|
throw new Error("ExtensionContext.project() is unavailable in standalone emitApi.");
|
|
1062
|
+
},
|
|
1063
|
+
// No manifest is written on the standalone path, so there is nothing for
|
|
1064
|
+
// tracked dependencies to be recorded into — accept and discard them
|
|
1065
|
+
// rather than making every caller supply a sink.
|
|
1066
|
+
trackInput: () => {
|
|
1054
1067
|
}
|
|
1055
1068
|
};
|
|
1056
1069
|
const importsByFile = /* @__PURE__ */ new Map();
|
|
@@ -1107,7 +1120,7 @@ function buildApiFile(routes, outDir, opts = {}) {
|
|
|
1107
1120
|
for (const [filePath, names] of importsByFile) {
|
|
1108
1121
|
let relPath;
|
|
1109
1122
|
if (isAbsolute2(filePath)) {
|
|
1110
|
-
relPath =
|
|
1123
|
+
relPath = relative4(outDir, filePath).replace(/\.ts$/, "");
|
|
1111
1124
|
if (!relPath.startsWith(".")) relPath = `./${relPath}`;
|
|
1112
1125
|
} else {
|
|
1113
1126
|
relPath = filePath;
|
|
@@ -1221,7 +1234,7 @@ async function emitCache(pages, outDir) {
|
|
|
1221
1234
|
|
|
1222
1235
|
// src/emit/emit-forms.ts
|
|
1223
1236
|
import { mkdir as mkdir3, writeFile as writeFile3 } from "fs/promises";
|
|
1224
|
-
import { join as join6, relative as
|
|
1237
|
+
import { join as join6, relative as relative5 } from "path";
|
|
1225
1238
|
async function emitForms(routes, outDir, config, adapter) {
|
|
1226
1239
|
if (config && config.enabled === false) return false;
|
|
1227
1240
|
const content = buildFormsFileWithAdapter(routes, outDir, adapter, config);
|
|
@@ -1240,7 +1253,7 @@ function deriveBaseName(routeName) {
|
|
|
1240
1253
|
return { method, full };
|
|
1241
1254
|
}
|
|
1242
1255
|
function relImport(outDir, filePath) {
|
|
1243
|
-
let relPath =
|
|
1256
|
+
let relPath = relative5(outDir, filePath).replace(/\.ts$/, "");
|
|
1244
1257
|
if (!relPath.startsWith(".")) relPath = `./${relPath}`;
|
|
1245
1258
|
return relPath;
|
|
1246
1259
|
}
|
|
@@ -1988,7 +2001,7 @@ async function emitOpenApi(routes, outDir, opts = {}) {
|
|
|
1988
2001
|
|
|
1989
2002
|
// src/emit/emit-pages.ts
|
|
1990
2003
|
import { mkdir as mkdir7, writeFile as writeFile7 } from "fs/promises";
|
|
1991
|
-
import { join as join10, relative as
|
|
2004
|
+
import { join as join10, relative as relative6 } from "path";
|
|
1992
2005
|
async function emitPages(pages, outDir, _options = {}) {
|
|
1993
2006
|
await mkdir7(outDir, { recursive: true });
|
|
1994
2007
|
const pageNameUnion = pages.length > 0 ? pages.map((p) => JSON.stringify(p.name)).join(" | ") : "never";
|
|
@@ -2028,7 +2041,7 @@ ${propsBody}
|
|
|
2028
2041
|
`;
|
|
2029
2042
|
}
|
|
2030
2043
|
function buildAugmentationType(page, outDir) {
|
|
2031
|
-
let importPath =
|
|
2044
|
+
let importPath = relative6(outDir, page.absolutePath).replace(/\.(tsx?|vue|svelte)$/, "");
|
|
2032
2045
|
if (!importPath.startsWith(".")) {
|
|
2033
2046
|
importPath = `./${importPath}`;
|
|
2034
2047
|
}
|
|
@@ -2159,7 +2172,7 @@ function buildEmpty() {
|
|
|
2159
2172
|
// src/generate-manifest.ts
|
|
2160
2173
|
import { createHash } from "crypto";
|
|
2161
2174
|
import { readFile as readFile2, readdir, writeFile as writeFile9 } from "fs/promises";
|
|
2162
|
-
import { join as join12, relative as
|
|
2175
|
+
import { join as join12, relative as relative7 } from "path";
|
|
2163
2176
|
import fg2 from "fast-glob";
|
|
2164
2177
|
var MANIFEST_FILE = ".codegen-manifest.json";
|
|
2165
2178
|
var LOCK_FILE = ".watcher.lock";
|
|
@@ -2182,6 +2195,9 @@ function isManifestShape(value) {
|
|
|
2182
2195
|
if (candidate.configKeyHashes !== void 0 && !isStringRecord(candidate.configKeyHashes)) {
|
|
2183
2196
|
return false;
|
|
2184
2197
|
}
|
|
2198
|
+
if (candidate.extraInputs !== void 0 && (!Array.isArray(candidate.extraInputs) || !candidate.extraInputs.every((entry) => typeof entry === "string"))) {
|
|
2199
|
+
return false;
|
|
2200
|
+
}
|
|
2185
2201
|
if (!Array.isArray(candidate.files)) return false;
|
|
2186
2202
|
return candidate.files.every((entry) => typeof entry === "string");
|
|
2187
2203
|
}
|
|
@@ -2221,21 +2237,30 @@ async function discoverInputFiles(config) {
|
|
|
2221
2237
|
const matched = await fg2(globs, { cwd, absolute: true, onlyFiles: true });
|
|
2222
2238
|
return [...new Set(matched)].sort();
|
|
2223
2239
|
}
|
|
2224
|
-
async function computeInputsHash(config) {
|
|
2240
|
+
async function computeInputsHash(config, extraInputs = []) {
|
|
2225
2241
|
const hash = createHash("sha256");
|
|
2226
2242
|
hash.update(`version:${VERSION}
|
|
2227
2243
|
`);
|
|
2228
2244
|
hash.update(`config:${serializeConfig(config)}
|
|
2229
2245
|
`);
|
|
2230
|
-
const inputFiles = await discoverInputFiles(config);
|
|
2231
2246
|
const cwd = config.codegen.cwd;
|
|
2232
|
-
|
|
2247
|
+
const globbed = await discoverInputFiles(config);
|
|
2248
|
+
const globbedRelative = new Set(globbed.map((file) => relative7(cwd, file)));
|
|
2249
|
+
const extra = [...new Set(extraInputs)].filter((file) => !globbedRelative.has(file)).sort();
|
|
2250
|
+
for (const file of globbed) {
|
|
2233
2251
|
const contents = await readFile2(file, "utf8");
|
|
2234
|
-
hash.update(`file:${
|
|
2252
|
+
hash.update(`file:${relative7(cwd, file)}
|
|
2235
2253
|
`);
|
|
2236
2254
|
hash.update(contents);
|
|
2237
2255
|
hash.update("\n");
|
|
2238
2256
|
}
|
|
2257
|
+
for (const file of extra) {
|
|
2258
|
+
const contents = await readFile2(join12(cwd, file), "utf8").catch(() => null);
|
|
2259
|
+
hash.update(`extra:${file}
|
|
2260
|
+
`);
|
|
2261
|
+
hash.update(contents ?? "\0missing");
|
|
2262
|
+
hash.update("\n");
|
|
2263
|
+
}
|
|
2239
2264
|
return hash.digest("hex");
|
|
2240
2265
|
}
|
|
2241
2266
|
async function readManifest(outDir) {
|
|
@@ -2249,6 +2274,7 @@ async function readManifest(outDir) {
|
|
|
2249
2274
|
...parsed.entryPoint ? { entryPoint: parsed.entryPoint } : {},
|
|
2250
2275
|
...parsed.configHash ? { configHash: parsed.configHash } : {},
|
|
2251
2276
|
...parsed.configKeyHashes ? { configKeyHashes: parsed.configKeyHashes } : {},
|
|
2277
|
+
...parsed.extraInputs ? { extraInputs: parsed.extraInputs } : {},
|
|
2252
2278
|
files: parsed.files
|
|
2253
2279
|
};
|
|
2254
2280
|
} catch {
|
|
@@ -2271,7 +2297,7 @@ async function listOutputFiles(outDir) {
|
|
|
2271
2297
|
if (entry.isDirectory()) {
|
|
2272
2298
|
await walk(abs);
|
|
2273
2299
|
} else if (entry.isFile()) {
|
|
2274
|
-
const rel =
|
|
2300
|
+
const rel = relative7(outDir, abs);
|
|
2275
2301
|
if (rel === MANIFEST_FILE || rel === LOCK_FILE) continue;
|
|
2276
2302
|
found.push(rel);
|
|
2277
2303
|
}
|
|
@@ -2308,8 +2334,8 @@ function driftGuardMessage(outDir, previousEntryPoint, currentEntryPoint, differ
|
|
|
2308
2334
|
}
|
|
2309
2335
|
async function generate(config, inputRoutes = [], entryPoint = "cli") {
|
|
2310
2336
|
setCodegenDebug(config.debug);
|
|
2311
|
-
const inputsHash = await computeInputsHash(config);
|
|
2312
2337
|
const manifest = await readManifest(config.codegen.outDir);
|
|
2338
|
+
const inputsHash = await computeInputsHash(config, manifest?.extraInputs ?? []);
|
|
2313
2339
|
if (await isManifestFresh(config.codegen.outDir, manifest, inputsHash)) {
|
|
2314
2340
|
console.log(`[nestjs-codegen] ${config.codegen.outDir} up to date, skipped`);
|
|
2315
2341
|
return;
|
|
@@ -2330,7 +2356,8 @@ async function generate(config, inputRoutes = [], entryPoint = "cli") {
|
|
|
2330
2356
|
}
|
|
2331
2357
|
const extensions = config.extensions ?? [];
|
|
2332
2358
|
let routes = inputRoutes;
|
|
2333
|
-
const
|
|
2359
|
+
const trackedInputs = /* @__PURE__ */ new Set();
|
|
2360
|
+
const ctx = createExtensionContext(config, () => routes, trackedInputs);
|
|
2334
2361
|
if (extensions.length > 0) {
|
|
2335
2362
|
routes = await applyTransformRoutes(routes, extensions, ctx);
|
|
2336
2363
|
}
|
|
@@ -2390,13 +2417,16 @@ async function generate(config, inputRoutes = [], entryPoint = "cli") {
|
|
|
2390
2417
|
}
|
|
2391
2418
|
}
|
|
2392
2419
|
const outputFiles = await listOutputFiles(config.codegen.outDir);
|
|
2420
|
+
const extraInputs = [...trackedInputs].sort();
|
|
2421
|
+
const recordedHash = extraInputs.length > 0 ? await computeInputsHash(config, extraInputs) : inputsHash;
|
|
2393
2422
|
await writeManifest(config.codegen.outDir, {
|
|
2394
2423
|
version: VERSION,
|
|
2395
|
-
hash:
|
|
2424
|
+
hash: recordedHash,
|
|
2396
2425
|
entryPoint,
|
|
2397
2426
|
configHash,
|
|
2398
2427
|
configKeyHashes,
|
|
2399
|
-
files: outputFiles
|
|
2428
|
+
files: outputFiles,
|
|
2429
|
+
...extraInputs.length > 0 ? { extraInputs } : {}
|
|
2400
2430
|
});
|
|
2401
2431
|
}
|
|
2402
2432
|
|
|
@@ -2406,7 +2436,7 @@ import { join as join16 } from "path";
|
|
|
2406
2436
|
import chokidar from "chokidar";
|
|
2407
2437
|
|
|
2408
2438
|
// src/discovery/contracts-fast.ts
|
|
2409
|
-
import { join as join14, resolve as
|
|
2439
|
+
import { join as join14, resolve as resolve4 } from "path";
|
|
2410
2440
|
import fg3 from "fast-glob";
|
|
2411
2441
|
import {
|
|
2412
2442
|
Node as Node9,
|
|
@@ -2426,7 +2456,7 @@ import {
|
|
|
2426
2456
|
|
|
2427
2457
|
// src/discovery/type-ref-resolution.ts
|
|
2428
2458
|
import { readFileSync } from "fs";
|
|
2429
|
-
import { dirname as dirname3, resolve as
|
|
2459
|
+
import { dirname as dirname3, resolve as resolve3 } from "path";
|
|
2430
2460
|
import {
|
|
2431
2461
|
Node as Node2
|
|
2432
2462
|
} from "ts-morph";
|
|
@@ -2483,9 +2513,9 @@ function resolveModuleSpecifier(moduleSpecifier, sourceFile, project) {
|
|
|
2483
2513
|
const dir = dirname3(sourceFile.getFilePath());
|
|
2484
2514
|
const noExt = moduleSpecifier.replace(/\.(js|ts)$/, "");
|
|
2485
2515
|
return [
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2516
|
+
resolve3(dir, `${noExt}.ts`),
|
|
2517
|
+
resolve3(dir, `${moduleSpecifier}.ts`),
|
|
2518
|
+
resolve3(dir, moduleSpecifier, "index.ts")
|
|
2489
2519
|
];
|
|
2490
2520
|
}
|
|
2491
2521
|
const ctx = _ctxFor(project);
|
|
@@ -2506,8 +2536,8 @@ function resolveModuleSpecifier(moduleSpecifier, sourceFile, project) {
|
|
|
2506
2536
|
const rest = moduleSpecifier.slice(prefix.length);
|
|
2507
2537
|
const candidates = [];
|
|
2508
2538
|
for (const mapping of mappings) {
|
|
2509
|
-
const resolved =
|
|
2510
|
-
candidates.push(`${resolved}.ts`,
|
|
2539
|
+
const resolved = resolve3(baseUrl, mapping.replace("*", rest));
|
|
2540
|
+
candidates.push(`${resolved}.ts`, resolve3(resolved, "index.ts"));
|
|
2511
2541
|
}
|
|
2512
2542
|
dbg(" resolved candidates:", candidates);
|
|
2513
2543
|
return candidates;
|
|
@@ -4154,6 +4184,19 @@ function resolveParamClass(method, decoratorName, sourceFile, project) {
|
|
|
4154
4184
|
|
|
4155
4185
|
// src/discovery/heritage.ts
|
|
4156
4186
|
import { Node as Node7, Project as Project3 } from "ts-morph";
|
|
4187
|
+
function resolveHeritageCall(node) {
|
|
4188
|
+
if (!node) return void 0;
|
|
4189
|
+
const expr = unwrapExpression(node);
|
|
4190
|
+
if (Node7.isCallExpression(expr)) return expr;
|
|
4191
|
+
if (!Node7.isIdentifier(expr)) return void 0;
|
|
4192
|
+
const decl = expr.getDefinitions().map((d) => d.getDeclarationNode()).find(
|
|
4193
|
+
(n) => n !== void 0 && Node7.isVariableDeclaration(n)
|
|
4194
|
+
);
|
|
4195
|
+
const init = decl?.getInitializer();
|
|
4196
|
+
if (!init) return void 0;
|
|
4197
|
+
const unwrapped = unwrapExpression(init);
|
|
4198
|
+
return Node7.isCallExpression(unwrapped) ? unwrapped : void 0;
|
|
4199
|
+
}
|
|
4157
4200
|
function unwrapExpression(node) {
|
|
4158
4201
|
let current = node;
|
|
4159
4202
|
while (Node7.isAsExpression(current) || Node7.isSatisfiesExpression(current) || Node7.isParenthesizedExpression(current) || Node7.isTypeAssertion(current)) {
|
|
@@ -4181,8 +4224,8 @@ function resolveReturnedClass(factoryDecl) {
|
|
|
4181
4224
|
return void 0;
|
|
4182
4225
|
}
|
|
4183
4226
|
function resolveInheritedMethods(cls) {
|
|
4184
|
-
const expr = cls.getExtends()?.getExpression();
|
|
4185
|
-
if (!expr
|
|
4227
|
+
const expr = resolveHeritageCall(cls.getExtends()?.getExpression());
|
|
4228
|
+
if (!expr) return void 0;
|
|
4186
4229
|
const callee = expr.getExpression();
|
|
4187
4230
|
if (!Node7.isIdentifier(callee)) return void 0;
|
|
4188
4231
|
const factoryDecl = callee.getDefinitions().map((d) => d.getDeclarationNode()).find((n) => Node7.isFunctionDeclaration(n));
|
|
@@ -4371,7 +4414,7 @@ async function discoverContractsFast(opts) {
|
|
|
4371
4414
|
return extractAllRoutes(project);
|
|
4372
4415
|
}
|
|
4373
4416
|
function resolveTsconfigPath(cwd, tsconfig) {
|
|
4374
|
-
return tsconfig ?
|
|
4417
|
+
return tsconfig ? resolve4(tsconfig) : join14(cwd, "tsconfig.json");
|
|
4375
4418
|
}
|
|
4376
4419
|
function createDiscoveryProject(tsconfigPath) {
|
|
4377
4420
|
try {
|
|
@@ -4457,7 +4500,7 @@ var PersistentDiscovery = class _PersistentDiscovery {
|
|
|
4457
4500
|
async rediscover(changedPaths) {
|
|
4458
4501
|
if (changedPaths) {
|
|
4459
4502
|
for (const p of changedPaths) {
|
|
4460
|
-
const abs =
|
|
4503
|
+
const abs = resolve4(p);
|
|
4461
4504
|
const sf = this.project.getSourceFile(abs);
|
|
4462
4505
|
if (sf) {
|
|
4463
4506
|
await sf.refreshFromFileSystem();
|
|
@@ -4737,9 +4780,11 @@ function extractFromSourceFile(sourceFile, project) {
|
|
|
4737
4780
|
factoryFilePath: inherited.factoryFilePath,
|
|
4738
4781
|
classArgs: inherited.classArgs
|
|
4739
4782
|
} : void 0;
|
|
4783
|
+
const ownMethods = cls.getMethods();
|
|
4784
|
+
const ownNames = new Set(ownMethods.map((m) => m.getName()));
|
|
4740
4785
|
const methods = [
|
|
4741
|
-
...
|
|
4742
|
-
...(inherited?.methods ?? []).map((method) => ({ method, mixin: mixinBinding }))
|
|
4786
|
+
...ownMethods.map((method) => ({ method, mixin: mixinBinding })),
|
|
4787
|
+
...(inherited?.methods ?? []).filter((method) => !ownNames.has(method.getName())).map((method) => ({ method, mixin: mixinBinding }))
|
|
4743
4788
|
];
|
|
4744
4789
|
for (const { method, mixin } of methods) {
|
|
4745
4790
|
const verb = resolveVerb(method);
|
|
@@ -4965,7 +5010,7 @@ async function watch(config, onChange, options = {}) {
|
|
|
4965
5010
|
}
|
|
4966
5011
|
|
|
4967
5012
|
// src/index.ts
|
|
4968
|
-
var VERSION = "0.
|
|
5013
|
+
var VERSION = "0.17.1";
|
|
4969
5014
|
|
|
4970
5015
|
// src/cli/codegen.ts
|
|
4971
5016
|
async function runCodegen(opts = {}) {
|
|
@@ -4973,9 +5018,9 @@ async function runCodegen(opts = {}) {
|
|
|
4973
5018
|
const config = await loadConfig(cwd);
|
|
4974
5019
|
if (opts.watch) {
|
|
4975
5020
|
const watcher = await watch(config, void 0, { entryPoint: "cli" });
|
|
4976
|
-
await new Promise((
|
|
5021
|
+
await new Promise((resolve5) => {
|
|
4977
5022
|
function onSignal() {
|
|
4978
|
-
watcher.close().then(
|
|
5023
|
+
watcher.close().then(resolve5).catch(resolve5);
|
|
4979
5024
|
}
|
|
4980
5025
|
process.once("SIGINT", onSignal);
|
|
4981
5026
|
process.once("SIGTERM", onSignal);
|
|
@@ -5105,16 +5150,16 @@ async function detectPackageManager(cwd) {
|
|
|
5105
5150
|
}
|
|
5106
5151
|
async function promptFramework() {
|
|
5107
5152
|
if (!process.stdin.isTTY) return "react";
|
|
5108
|
-
return new Promise((
|
|
5153
|
+
return new Promise((resolve5) => {
|
|
5109
5154
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
5110
5155
|
rl.question(
|
|
5111
5156
|
"[nestjs-codegen] Which frontend framework? (react/vue/svelte) [react]: ",
|
|
5112
5157
|
(answer) => {
|
|
5113
5158
|
rl.close();
|
|
5114
5159
|
const trimmed = answer.trim().toLowerCase();
|
|
5115
|
-
if (trimmed === "vue")
|
|
5116
|
-
else if (trimmed === "svelte")
|
|
5117
|
-
else
|
|
5160
|
+
if (trimmed === "vue") resolve5("vue");
|
|
5161
|
+
else if (trimmed === "svelte") resolve5("svelte");
|
|
5162
|
+
else resolve5("react");
|
|
5118
5163
|
}
|
|
5119
5164
|
);
|
|
5120
5165
|
});
|