@nestia/migrate 14.0.1 → 14.0.3
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/lib/NestiaMigrateApplication.d.ts +111 -0
- package/lib/NestiaMigrateApplication.js +148 -9
- package/lib/NestiaMigrateApplication.js.map +1 -1
- package/lib/NestiaMigrateApplication.mjs +147 -5
- package/lib/_virtual/_rolldown/runtime.mjs +6 -1
- package/lib/analyzers/NestiaMigrateControllerAnalyzer.d.ts +45 -0
- package/lib/analyzers/NestiaMigrateControllerAnalyzer.js +59 -3
- package/lib/analyzers/NestiaMigrateControllerAnalyzer.js.map +1 -1
- package/lib/analyzers/NestiaMigrateControllerAnalyzer.mjs +9 -3
- package/lib/archivers/NestiaMigrateFileArchiver.d.ts +34 -0
- package/lib/archivers/NestiaMigrateFileArchiver.js +34 -0
- package/lib/archivers/NestiaMigrateFileArchiver.js.map +1 -1
- package/lib/bundles/NEST_TEMPLATE.js +1 -1
- package/lib/bundles/NEST_TEMPLATE.mjs +1 -1
- package/lib/bundles/SDK_TEMPLATE.js +1 -1
- package/lib/bundles/SDK_TEMPLATE.mjs +1 -1
- package/lib/executable/NestiaMigrateCommander.d.ts +39 -1
- package/lib/executable/NestiaMigrateCommander.js +42 -2
- package/lib/executable/NestiaMigrateCommander.js.map +1 -1
- package/lib/executable/NestiaMigrateCommander.mjs +5 -3
- package/lib/executable/NestiaMigrateInquirer.d.ts +32 -1
- package/lib/executable/NestiaMigrateInquirer.js +33 -10
- package/lib/executable/NestiaMigrateInquirer.js.map +1 -1
- package/lib/executable/NestiaMigrateInquirer.mjs +4 -3
- package/lib/executable/TemplateBundleCache.d.ts +23 -0
- package/lib/executable/TemplateBundleCache.js +60 -0
- package/lib/executable/TemplateBundleCache.js.map +1 -0
- package/lib/executable/TemplateBundleCache.mjs +39 -0
- package/lib/executable/TemplateBundleCache.mjs.map +1 -0
- package/lib/executable/bundle.d.ts +1 -0
- package/lib/executable/bundle.js +404 -0
- package/lib/executable/bundle.js.map +1 -0
- package/lib/executable/bundle.mjs +324 -0
- package/lib/executable/bundle.mjs.map +1 -0
- package/lib/factories/ExpressionFactory.d.ts +14 -0
- package/lib/factories/ExpressionFactory.js +14 -0
- package/lib/factories/ExpressionFactory.js.map +1 -1
- package/lib/factories/IdentifierFactory.d.ts +20 -0
- package/lib/factories/IdentifierFactory.js +20 -0
- package/lib/factories/IdentifierFactory.js.map +1 -1
- package/lib/factories/LiteralFactory.d.ts +18 -2
- package/lib/factories/LiteralFactory.js +18 -2
- package/lib/factories/LiteralFactory.js.map +1 -1
- package/lib/factories/StatementFactory.d.ts +26 -1
- package/lib/factories/StatementFactory.js +26 -1
- package/lib/factories/StatementFactory.js.map +1 -1
- package/lib/factories/SupportedStringFormats.d.ts +6 -0
- package/lib/factories/SupportedStringFormats.js +33 -0
- package/lib/factories/SupportedStringFormats.js.map +1 -0
- package/lib/factories/SupportedStringFormats.mjs +34 -0
- package/lib/factories/SupportedStringFormats.mjs.map +1 -0
- package/lib/factories/TypeFactory.d.ts +21 -0
- package/lib/factories/TypeFactory.js +13 -0
- package/lib/factories/TypeFactory.js.map +1 -1
- package/lib/factories/TypeLiteralFactory.d.ts +18 -0
- package/lib/factories/TypeLiteralFactory.js +18 -0
- package/lib/factories/TypeLiteralFactory.js.map +1 -1
- package/lib/internal/ts.d.ts +153 -0
- package/lib/internal/ts.js.map +1 -1
- package/lib/package.mjs +55 -0
- package/lib/package.mjs.map +1 -0
- package/lib/programmers/NestiaMigrateApiFileProgrammer.d.ts +31 -0
- package/lib/programmers/NestiaMigrateApiFileProgrammer.js +17 -0
- package/lib/programmers/NestiaMigrateApiFileProgrammer.js.map +1 -1
- package/lib/programmers/NestiaMigrateApiFunctionProgrammer.d.ts +40 -0
- package/lib/programmers/NestiaMigrateApiFunctionProgrammer.js +27 -0
- package/lib/programmers/NestiaMigrateApiFunctionProgrammer.js.map +1 -1
- package/lib/programmers/NestiaMigrateApiNamespaceProgrammer.d.ts +39 -0
- package/lib/programmers/NestiaMigrateApiNamespaceProgrammer.js +26 -0
- package/lib/programmers/NestiaMigrateApiNamespaceProgrammer.js.map +1 -1
- package/lib/programmers/NestiaMigrateApiProgrammer.d.ts +18 -0
- package/lib/programmers/NestiaMigrateApiProgrammer.js +18 -0
- package/lib/programmers/NestiaMigrateApiProgrammer.js.map +1 -1
- package/lib/programmers/NestiaMigrateApiProgrammer.mjs +1 -1
- package/lib/programmers/NestiaMigrateApiSimulationProgrammer.d.ts +40 -0
- package/lib/programmers/NestiaMigrateApiSimulationProgrammer.js +27 -0
- package/lib/programmers/NestiaMigrateApiSimulationProgrammer.js.map +1 -1
- package/lib/programmers/NestiaMigrateApiStartProgrammer.d.ts +17 -0
- package/lib/programmers/NestiaMigrateApiStartProgrammer.js +19 -8
- package/lib/programmers/NestiaMigrateApiStartProgrammer.js.map +1 -1
- package/lib/programmers/NestiaMigrateApiStartProgrammer.mjs +1 -6
- package/lib/programmers/NestiaMigrateDtoProgrammer.d.ts +30 -0
- package/lib/programmers/NestiaMigrateDtoProgrammer.js +17 -0
- package/lib/programmers/NestiaMigrateDtoProgrammer.js.map +1 -1
- package/lib/programmers/NestiaMigrateE2eFileProgrammer.d.ts +39 -0
- package/lib/programmers/NestiaMigrateE2eFileProgrammer.js +26 -0
- package/lib/programmers/NestiaMigrateE2eFileProgrammer.js.map +1 -1
- package/lib/programmers/NestiaMigrateE2eProgrammer.d.ts +16 -0
- package/lib/programmers/NestiaMigrateE2eProgrammer.js +16 -0
- package/lib/programmers/NestiaMigrateE2eProgrammer.js.map +1 -1
- package/lib/programmers/NestiaMigrateImportProgrammer.d.ts +75 -0
- package/lib/programmers/NestiaMigrateImportProgrammer.js +58 -3
- package/lib/programmers/NestiaMigrateImportProgrammer.js.map +1 -1
- package/lib/programmers/NestiaMigrateImportProgrammer.mjs +58 -3
- package/lib/programmers/NestiaMigrateNestControllerProgrammer.d.ts +28 -0
- package/lib/programmers/NestiaMigrateNestControllerProgrammer.js +16 -0
- package/lib/programmers/NestiaMigrateNestControllerProgrammer.js.map +1 -1
- package/lib/programmers/NestiaMigrateNestMethodProgrammer.d.ts +30 -0
- package/lib/programmers/NestiaMigrateNestMethodProgrammer.js +16 -0
- package/lib/programmers/NestiaMigrateNestMethodProgrammer.js.map +1 -1
- package/lib/programmers/NestiaMigrateNestModuleProgrammer.d.ts +16 -0
- package/lib/programmers/NestiaMigrateNestModuleProgrammer.js +16 -0
- package/lib/programmers/NestiaMigrateNestModuleProgrammer.js.map +1 -1
- package/lib/programmers/NestiaMigrateNestProgrammer.d.ts +17 -0
- package/lib/programmers/NestiaMigrateNestProgrammer.js +17 -0
- package/lib/programmers/NestiaMigrateNestProgrammer.js.map +1 -1
- package/lib/programmers/NestiaMigrateSchemaProgrammer.d.ts +16 -0
- package/lib/programmers/NestiaMigrateSchemaProgrammer.js +20 -5
- package/lib/programmers/NestiaMigrateSchemaProgrammer.js.map +1 -1
- package/lib/programmers/NestiaMigrateSchemaProgrammer.mjs +4 -4
- package/lib/structures/INestiaMigrateConfig.d.ts +21 -0
- package/lib/structures/INestiaMigrateContext.d.ts +15 -0
- package/lib/structures/INestiaMigrateController.d.ts +13 -0
- package/lib/structures/INestiaMigrateFile.d.ts +11 -0
- package/lib/utils/FilePrinter.d.ts +33 -0
- package/lib/utils/FilePrinter.js +33 -0
- package/lib/utils/FilePrinter.js.map +1 -1
- package/lib/utils/MapUtil.d.ts +17 -0
- package/lib/utils/MapUtil.js +19 -3
- package/lib/utils/MapUtil.js.map +1 -1
- package/lib/utils/MapUtil.mjs +1 -2
- package/lib/utils/PathTemplate.d.ts +23 -1
- package/lib/utils/PathTemplate.js +15 -1
- package/lib/utils/PathTemplate.js.map +1 -1
- package/lib/utils/RequestBody.d.ts +13 -0
- package/lib/utils/RequestBody.js +13 -0
- package/lib/utils/RequestBody.js.map +1 -1
- package/lib/utils/StringUtil.d.ts +55 -0
- package/lib/utils/StringUtil.js +93 -8
- package/lib/utils/StringUtil.js.map +1 -1
- package/lib/utils/StringUtil.mjs +30 -8
- package/lib/utils/SuccessStatus.d.ts +21 -1
- package/lib/utils/SuccessStatus.js +21 -1
- package/lib/utils/SuccessStatus.js.map +1 -1
- package/package.json +5 -4
- package/src/NestiaMigrateApplication.ts +151 -13
- package/src/analyzers/NestiaMigrateControllerAnalyzer.ts +59 -4
- package/src/archivers/NestiaMigrateFileArchiver.ts +34 -0
- package/src/bundles/NEST_TEMPLATE.ts +1 -1
- package/src/bundles/SDK_TEMPLATE.ts +1 -1
- package/src/executable/NestiaMigrateCommander.ts +44 -2
- package/src/executable/NestiaMigrateInquirer.ts +35 -3
- package/src/executable/TemplateBundleCache.ts +65 -0
- package/src/executable/{bundle.js → bundle.ts} +110 -43
- package/src/factories/ExpressionFactory.ts +14 -0
- package/src/factories/IdentifierFactory.ts +20 -0
- package/src/factories/LiteralFactory.ts +18 -2
- package/src/factories/StatementFactory.ts +26 -1
- package/src/factories/SupportedStringFormats.ts +29 -0
- package/src/factories/TypeFactory.ts +21 -0
- package/src/factories/TypeLiteralFactory.ts +18 -0
- package/src/internal/ts.ts +153 -0
- package/src/programmers/NestiaMigrateApiFileProgrammer.ts +35 -0
- package/src/programmers/NestiaMigrateApiFunctionProgrammer.ts +43 -0
- package/src/programmers/NestiaMigrateApiNamespaceProgrammer.ts +42 -0
- package/src/programmers/NestiaMigrateApiProgrammer.ts +18 -0
- package/src/programmers/NestiaMigrateApiSimulationProgrammer.ts +43 -0
- package/src/programmers/NestiaMigrateApiStartProgrammer.ts +19 -10
- package/src/programmers/NestiaMigrateDtoProgrammer.ts +33 -0
- package/src/programmers/NestiaMigrateE2eFileProgrammer.ts +42 -0
- package/src/programmers/NestiaMigrateE2eProgrammer.ts +16 -0
- package/src/programmers/NestiaMigrateImportProgrammer.ts +86 -5
- package/src/programmers/NestiaMigrateNestControllerProgrammer.ts +30 -0
- package/src/programmers/NestiaMigrateNestMethodProgrammer.ts +34 -0
- package/src/programmers/NestiaMigrateNestModuleProgrammer.ts +16 -0
- package/src/programmers/NestiaMigrateNestProgrammer.ts +17 -0
- package/src/programmers/NestiaMigrateSchemaProgrammer.ts +25 -8
- package/src/structures/INestiaMigrateConfig.ts +26 -0
- package/src/structures/INestiaMigrateContext.ts +17 -0
- package/src/structures/INestiaMigrateController.ts +16 -0
- package/src/structures/INestiaMigrateFile.ts +13 -0
- package/src/utils/FilePrinter.ts +33 -0
- package/src/utils/MapUtil.ts +18 -2
- package/src/utils/PathTemplate.ts +23 -1
- package/src/utils/RequestBody.ts +13 -0
- package/src/utils/StringUtil.ts +101 -9
- package/src/utils/SuccessStatus.ts +21 -1
- package/lib/factories/FormatCheatSheet.d.ts +0 -25
- package/lib/factories/FormatCheatSheet.js +0 -34
- package/lib/factories/FormatCheatSheet.js.map +0 -1
- package/lib/factories/FormatCheatSheet.mjs +0 -31
- package/lib/factories/FormatCheatSheet.mjs.map +0 -1
- package/src/factories/FormatCheatSheet.ts +0 -71
|
@@ -1,16 +1,25 @@
|
|
|
1
|
+
import cp from "node:child_process";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
|
|
4
|
+
import { run as runCached } from "./TemplateBundleCache";
|
|
5
|
+
|
|
1
6
|
const { version } = require("../../../../package.json");
|
|
2
|
-
const cp = require("child_process");
|
|
3
|
-
const fs = require("fs");
|
|
4
7
|
|
|
5
8
|
const ROOT = `${__dirname}/../..`;
|
|
6
9
|
const ASSETS = `${ROOT}/assets`;
|
|
7
|
-
const CATALOGS
|
|
10
|
+
const CATALOGS: Record<
|
|
11
|
+
string,
|
|
12
|
+
Record<string, { specifier: string }>
|
|
13
|
+
> = require("js-yaml").load(
|
|
8
14
|
fs.readFileSync(`${__dirname}/../../../../pnpm-lock.yaml`, "utf8"),
|
|
9
15
|
).catalogs;
|
|
10
|
-
const TYPIA = CATALOGS.samchon
|
|
16
|
+
const TYPIA = CATALOGS.samchon!;
|
|
11
17
|
const TYPESCRIPT = CATALOGS.typescript ?? {};
|
|
12
18
|
|
|
13
|
-
const update = (
|
|
19
|
+
const update = (
|
|
20
|
+
content: string,
|
|
21
|
+
options: { sdkAggregate?: boolean } = {},
|
|
22
|
+
): string => {
|
|
14
23
|
const parsed = JSON.parse(content);
|
|
15
24
|
for (const record of [
|
|
16
25
|
parsed.dependencies ?? {},
|
|
@@ -47,7 +56,11 @@ const update = (content, options = {}) => {
|
|
|
47
56
|
return JSON.stringify(parsed, null, 2);
|
|
48
57
|
};
|
|
49
58
|
|
|
50
|
-
const migratePackageJson = (parsed
|
|
59
|
+
const migratePackageJson = (parsed: {
|
|
60
|
+
scripts?: Record<string, string>;
|
|
61
|
+
dependencies?: Record<string, string>;
|
|
62
|
+
devDependencies?: Record<string, string>;
|
|
63
|
+
}): void => {
|
|
51
64
|
if (parsed.scripts)
|
|
52
65
|
for (const [key, value] of Object.entries(parsed.scripts))
|
|
53
66
|
if (typeof value === "string")
|
|
@@ -70,14 +83,14 @@ const migratePackageJson = (parsed) => {
|
|
|
70
83
|
// current versions. Keep the rewrite line-targeted so quoted package names,
|
|
71
84
|
// comments, ordering, and any anchors supplied by the upstream template remain
|
|
72
85
|
// intact.
|
|
73
|
-
const updateWorkspaceCatalog = (content) => {
|
|
74
|
-
const replace = (line) => {
|
|
86
|
+
const updateWorkspaceCatalog = (content: string): string => {
|
|
87
|
+
const replace = (line: string): string => {
|
|
75
88
|
const match = line.match(
|
|
76
89
|
/^(\s+(?:"([^"]+)"|'([^']+)'|([^:\s]+)): (?:&[A-Za-z0-9_-]+ )?)\S[^\r\n]*(\r?)$/,
|
|
77
90
|
);
|
|
78
91
|
if (match === null) return line;
|
|
79
92
|
|
|
80
|
-
const name = match[2] ?? match[3] ?? match[4]
|
|
93
|
+
const name = (match[2] ?? match[3] ?? match[4])!;
|
|
81
94
|
const specifier =
|
|
82
95
|
name === "nestia" || name.startsWith("@nestia/")
|
|
83
96
|
? `^${version}`
|
|
@@ -88,7 +101,10 @@ const updateWorkspaceCatalog = (content) => {
|
|
|
88
101
|
return content.split("\n").map(replace).join("\n");
|
|
89
102
|
};
|
|
90
103
|
|
|
91
|
-
const trimTemplateDependencies = (parsed
|
|
104
|
+
const trimTemplateDependencies = (parsed: {
|
|
105
|
+
dependencies?: Record<string, string>;
|
|
106
|
+
devDependencies?: Record<string, string>;
|
|
107
|
+
}): void => {
|
|
92
108
|
if (parsed.dependencies) {
|
|
93
109
|
delete parsed.dependencies.commander;
|
|
94
110
|
delete parsed.dependencies.inquirer;
|
|
@@ -100,7 +116,7 @@ const trimTemplateDependencies = (parsed) => {
|
|
|
100
116
|
}
|
|
101
117
|
};
|
|
102
118
|
|
|
103
|
-
const normalizeScript = (script) =>
|
|
119
|
+
const normalizeScript = (script: string): string =>
|
|
104
120
|
script.replace(/(^|[^A-Za-z0-9_-])tsc(?=$|[^A-Za-z0-9_-])/g, "$1ttsc");
|
|
105
121
|
|
|
106
122
|
const ARGUMENT_PARSER = `import { createInterface } from "node:readline/promises";
|
|
@@ -214,7 +230,7 @@ export namespace ArgumentParser {
|
|
|
214
230
|
}
|
|
215
231
|
`;
|
|
216
232
|
|
|
217
|
-
const updateTsConfig = (content) => {
|
|
233
|
+
const updateTsConfig = (content: string): string => {
|
|
218
234
|
content = content.replace(
|
|
219
235
|
/^\s*\{\s*"transform":\s*"typescript-transform-paths"\s*\},\r?\n/gm,
|
|
220
236
|
"",
|
|
@@ -244,7 +260,13 @@ const bundle = async ({
|
|
|
244
260
|
revision,
|
|
245
261
|
exceptions,
|
|
246
262
|
transform,
|
|
247
|
-
}
|
|
263
|
+
}: {
|
|
264
|
+
mode: string;
|
|
265
|
+
repository: string;
|
|
266
|
+
revision: string;
|
|
267
|
+
exceptions?: readonly string[];
|
|
268
|
+
transform?: (key: string, value: string) => string;
|
|
269
|
+
}): Promise<void> => {
|
|
248
270
|
const root = `${__dirname}/../..`;
|
|
249
271
|
const assets = `${root}/assets`;
|
|
250
272
|
const template = `${assets}/${mode}`;
|
|
@@ -262,44 +284,68 @@ const bundle = async ({
|
|
|
262
284
|
// on every platform: with core.autocrlf=true (the common Windows default)
|
|
263
285
|
// the checkout would rewrite LF to CRLF and break the line-targeted
|
|
264
286
|
// transforms below.
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
{
|
|
268
|
-
cwd: ASSETS,
|
|
269
|
-
},
|
|
270
|
-
);
|
|
287
|
+
await fs.promises.mkdir(template, { recursive: true });
|
|
288
|
+
cp.execFileSync("git", ["init", "--quiet"], { cwd: template });
|
|
271
289
|
// The template repositories are live projects; an unpinned clone lets any
|
|
272
290
|
// upstream push break this build (samchon/nestia-start#632 did exactly
|
|
273
291
|
// that), so every bundle checks out a reviewed revision.
|
|
274
|
-
cp.
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
292
|
+
cp.execFileSync(
|
|
293
|
+
"git",
|
|
294
|
+
[
|
|
295
|
+
"fetch",
|
|
296
|
+
"--quiet",
|
|
297
|
+
"--depth=1",
|
|
298
|
+
// This checkout is consumed and removed immediately. Fetch's default
|
|
299
|
+
// auto-maintenance can detach a writer into .git/objects after fetch
|
|
300
|
+
// returns, racing the awaited removal below on a cold CI build.
|
|
301
|
+
"--no-auto-maintenance",
|
|
302
|
+
`https://github.com/samchon/${repository}`,
|
|
303
|
+
revision,
|
|
304
|
+
],
|
|
305
|
+
{ cwd: template },
|
|
306
|
+
);
|
|
307
|
+
cp.execFileSync(
|
|
308
|
+
"git",
|
|
309
|
+
[
|
|
310
|
+
"-c",
|
|
311
|
+
"core.autocrlf=false",
|
|
312
|
+
"checkout",
|
|
313
|
+
"--quiet",
|
|
314
|
+
"--detach",
|
|
315
|
+
revision,
|
|
316
|
+
],
|
|
317
|
+
{
|
|
318
|
+
cwd: template,
|
|
319
|
+
stdio: "pipe",
|
|
320
|
+
},
|
|
321
|
+
);
|
|
278
322
|
|
|
279
323
|
// REMOVE VULNERABLE FILES
|
|
280
324
|
for (const location of exceptions ?? [])
|
|
281
325
|
await fs.promises.rm(`${template}/${location}`, { recursive: true });
|
|
282
326
|
};
|
|
283
327
|
|
|
284
|
-
const iterate =
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
const
|
|
288
|
-
const
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
(
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
328
|
+
const iterate =
|
|
329
|
+
(collection: Record<string, string>) =>
|
|
330
|
+
async (location: string): Promise<void> => {
|
|
331
|
+
const directory = await fs.promises.readdir(location);
|
|
332
|
+
for (const file of directory) {
|
|
333
|
+
const absolute = location + "/" + file;
|
|
334
|
+
const stats = await fs.promises.stat(absolute);
|
|
335
|
+
if (stats.isDirectory()) await iterate(collection)(absolute);
|
|
336
|
+
else {
|
|
337
|
+
const content = await fs.promises.readFile(absolute, "utf-8");
|
|
338
|
+
collection[
|
|
339
|
+
(() => {
|
|
340
|
+
const str = absolute.replace(template, "");
|
|
341
|
+
return str[0] === "/" ? str.substring(1) : str;
|
|
342
|
+
})()
|
|
343
|
+
] = content;
|
|
344
|
+
}
|
|
298
345
|
}
|
|
299
|
-
}
|
|
300
|
-
};
|
|
346
|
+
};
|
|
301
347
|
|
|
302
|
-
const archive = async (collection) => {
|
|
348
|
+
const archive = async (collection: Record<string, string>): Promise<void> => {
|
|
303
349
|
const name = `${mode.toUpperCase()}_TEMPLATE`;
|
|
304
350
|
const body = JSON.stringify(collection, null, 2);
|
|
305
351
|
const content = `export const ${name}: Record<string, string> = ${body}`;
|
|
@@ -314,7 +360,7 @@ const bundle = async ({
|
|
|
314
360
|
);
|
|
315
361
|
};
|
|
316
362
|
|
|
317
|
-
const collection = {};
|
|
363
|
+
const collection: Record<string, string> = {};
|
|
318
364
|
await clone();
|
|
319
365
|
await iterate(collection)(template);
|
|
320
366
|
if (transform)
|
|
@@ -327,12 +373,22 @@ const bundle = async ({
|
|
|
327
373
|
await archive(collection);
|
|
328
374
|
};
|
|
329
375
|
|
|
330
|
-
const writeTransformedAsset = async (
|
|
376
|
+
const writeTransformedAsset = async (
|
|
377
|
+
template: string,
|
|
378
|
+
key: string,
|
|
379
|
+
value: string,
|
|
380
|
+
): Promise<string> => {
|
|
331
381
|
await fs.promises.writeFile(`${template}/${key}`, value, "utf8");
|
|
332
382
|
return value;
|
|
333
383
|
};
|
|
334
384
|
|
|
335
|
-
|
|
385
|
+
/**
|
|
386
|
+
* Generates both pinned templates using the current release and catalog stamps.
|
|
387
|
+
*
|
|
388
|
+
* The complete script is a cache input because it contains the revisions,
|
|
389
|
+
* exclusions and every transformation rule. A hit still verifies output bytes.
|
|
390
|
+
*/
|
|
391
|
+
const generate = async () => {
|
|
336
392
|
await bundle({
|
|
337
393
|
mode: "nest",
|
|
338
394
|
repository: "nestia-start",
|
|
@@ -399,6 +455,17 @@ const main = async () => {
|
|
|
399
455
|
},
|
|
400
456
|
});
|
|
401
457
|
};
|
|
458
|
+
const main = async () => {
|
|
459
|
+
const reused = await runCached({
|
|
460
|
+
inputs: [version, CATALOGS, fs.readFileSync(__filename, "utf8")],
|
|
461
|
+
outputs: ["NEST_TEMPLATE", "SDK_TEMPLATE"].map(
|
|
462
|
+
(name) => `${ROOT}/src/bundles/${name}.ts`,
|
|
463
|
+
),
|
|
464
|
+
stampFile: `${ASSETS}/.bundle-cache.json`,
|
|
465
|
+
generate,
|
|
466
|
+
});
|
|
467
|
+
if (reused) console.log("Reuse verified migration template bundles.");
|
|
468
|
+
};
|
|
402
469
|
main().catch((exp) => {
|
|
403
470
|
console.error(exp);
|
|
404
471
|
process.exit(-1);
|
|
@@ -9,8 +9,22 @@ import {
|
|
|
9
9
|
* Numeric-literal helper that handles negative values via a leading
|
|
10
10
|
* `MinusToken` prefix unary, matching how the TypeScript factory itself emits
|
|
11
11
|
* negative numeric literals.
|
|
12
|
+
*
|
|
13
|
+
* @evidence contracts/common.md#principled-implementation The namespace holds the number literal builder that the generators need.
|
|
14
|
+
* @evidence contracts/common.md#clear-and-simple-design One function.
|
|
15
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts It only builds nodes.
|
|
16
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states its purpose.
|
|
12
17
|
*/
|
|
13
18
|
export namespace ExpressionFactory {
|
|
19
|
+
/**
|
|
20
|
+
* Builds a numeric literal, using a prefix minus for a negative value,
|
|
21
|
+
* because a negative numeric literal is not a valid node.
|
|
22
|
+
*
|
|
23
|
+
* @evidence contracts/common.md#principled-implementation TypeScript represents a negative number as a prefix unary minus applied to a positive literal, so the function builds that shape for values below zero and a plain literal otherwise.
|
|
24
|
+
* @evidence contracts/common.md#clear-and-simple-design One conditional.
|
|
25
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts It follows the syntax tree grammar.
|
|
26
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the negative case.
|
|
27
|
+
*/
|
|
14
28
|
export const number = (
|
|
15
29
|
value: number,
|
|
16
30
|
): NumericLiteral | PrefixUnaryExpression =>
|
|
@@ -19,11 +19,21 @@ const isVariableName = (str: string): boolean => VARIABLE_REGEX.test(str);
|
|
|
19
19
|
/**
|
|
20
20
|
* Identifier and member-access helpers. The surface kept here is the subset
|
|
21
21
|
* nestia generators actually call (`identifier`, `access`, `parameter`).
|
|
22
|
+
*
|
|
23
|
+
* @evidence contracts/common.md#principled-implementation The functions decide between an identifier and a string literal by the syntax of the name, so any string can be used as a key.
|
|
24
|
+
* @evidence contracts/common.md#clear-and-simple-design Three small functions and one private predicate.
|
|
25
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The variable-name test is a regular expression of the language's identifier syntax, which is inlined so that the package need not load a larger namespace.
|
|
26
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states its purpose.
|
|
22
27
|
*/
|
|
23
28
|
export namespace IdentifierFactory {
|
|
24
29
|
/**
|
|
25
30
|
* Build an identifier or string literal depending on whether `name` is a
|
|
26
31
|
* valid JavaScript identifier.
|
|
32
|
+
*
|
|
33
|
+
* @evidence contracts/common.md#principled-implementation The name is tested against the identifier grammar `[A-Za-z_$][A-Za-z0-9_$]*`, which is conservative: a valid name outside it, such as one with non-ASCII letters, becomes a quoted key, which is equivalent.
|
|
34
|
+
* @evidence contracts/common.md#clear-and-simple-design One conditional.
|
|
35
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The test applies to every name.
|
|
36
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the two results.
|
|
27
37
|
*/
|
|
28
38
|
export const identifier = (name: string): Identifier | StringLiteral =>
|
|
29
39
|
isVariableName(name)
|
|
@@ -33,6 +43,11 @@ export namespace IdentifierFactory {
|
|
|
33
43
|
/**
|
|
34
44
|
* Member access on `input` by `key`. Falls back to element access when the
|
|
35
45
|
* key is not a valid identifier.
|
|
46
|
+
*
|
|
47
|
+
* @evidence contracts/common.md#principled-implementation The postfix is built by `identifier`, and its kind selects the property form or the element form, with the chain token added when requested.
|
|
48
|
+
* @evidence contracts/common.md#clear-and-simple-design One function delegating the naming rule.
|
|
49
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts It never concatenates source text.
|
|
50
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the forms.
|
|
36
51
|
*/
|
|
37
52
|
export const access = (
|
|
38
53
|
input: Expression,
|
|
@@ -60,6 +75,11 @@ export namespace IdentifierFactory {
|
|
|
60
75
|
/**
|
|
61
76
|
* Parameter declaration with default `any` type when the caller omits one.
|
|
62
77
|
* Passing a `QuestionToken` as `init` marks the parameter optional.
|
|
78
|
+
*
|
|
79
|
+
* @evidence contracts/common.md#principled-implementation An initializer that is the question token becomes the optional marker and is not an initializer, and any other initializer is passed through.
|
|
80
|
+
* @evidence contracts/common.md#clear-and-simple-design One function with one branch.
|
|
81
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts It follows the declaration grammar.
|
|
82
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the optional marker and the default type.
|
|
63
83
|
*/
|
|
64
84
|
export const parameter = (
|
|
65
85
|
name: string | Identifier,
|
|
@@ -16,10 +16,26 @@ const isNode = (value: unknown): value is Expression =>
|
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Recursive value-to-AST-literal builder. Hands back already-AST inputs
|
|
19
|
-
* unchanged
|
|
20
|
-
*
|
|
19
|
+
* unchanged for arrow functions, calls and identifiers (so callers can mix
|
|
20
|
+
* those factory expressions with raw values inside objects/arrays), and emits
|
|
21
|
+
* the appropriate literal node otherwise.
|
|
22
|
+
*
|
|
23
|
+
* @evidence contracts/common.md#principled-implementation The namespace maps null, booleans, numbers, strings, bigint text, arrays and object entries to literal expressions, passes through the three accepted AST kinds, maps functions to undefined and refuses unsupported primitive types.
|
|
24
|
+
* @evidence contracts/common.md#clear-and-simple-design One entry function and two private helpers for containers.
|
|
25
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The mapping is by type, with no value special-cased.
|
|
26
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states its purpose.
|
|
21
27
|
*/
|
|
22
28
|
export namespace LiteralFactory {
|
|
29
|
+
/**
|
|
30
|
+
* Builds the expression of a value: `null`, a boolean, a number, a string, a
|
|
31
|
+
* bigint as its text, an array, an object without its `undefined` members, or
|
|
32
|
+
* an expression node as it is.
|
|
33
|
+
*
|
|
34
|
+
* @evidence contracts/common.md#principled-implementation The value is dispatched by type in a fixed order; nodes of the kinds arrow function, call, and identifier pass through, functions become `undefined`, and an unsupported type is a `TypeError`, so the result is total over the listed types.
|
|
35
|
+
* @evidence contracts/common.md#clear-and-simple-design One function with one branch per type.
|
|
36
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The dispatch is general, and a bigint becomes text because a literal bigint is not supported by the target syntax here.
|
|
37
|
+
* @evidence contracts/common.md#meaningful-documentation The comment lists the mapping.
|
|
38
|
+
*/
|
|
23
39
|
export const write = (input: any): Expression => {
|
|
24
40
|
if (input === null) return factory.createNull();
|
|
25
41
|
if (isNode(input) && PASSTHROUGH_KINDS.has(input.kind)) return input;
|
|
@@ -8,8 +8,24 @@ import {
|
|
|
8
8
|
|
|
9
9
|
import { TypeFactory } from "./TypeFactory";
|
|
10
10
|
|
|
11
|
-
/**
|
|
11
|
+
/**
|
|
12
|
+
* Variable-statement helpers. `constant` emits `const`, `mut` emits `let`.
|
|
13
|
+
*
|
|
14
|
+
* @evidence contracts/common.md#principled-implementation The namespace builds `let` and `const` statements from a name, an optional type, and an optional value.
|
|
15
|
+
* @evidence contracts/common.md#clear-and-simple-design Two functions.
|
|
16
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts It only builds nodes.
|
|
17
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states its purpose.
|
|
18
|
+
*/
|
|
12
19
|
export namespace StatementFactory {
|
|
20
|
+
/**
|
|
21
|
+
* Builds a `let` statement; a declaration without a type and without an
|
|
22
|
+
* initializer is typed `any`.
|
|
23
|
+
*
|
|
24
|
+
* @evidence contracts/common.md#principled-implementation A `let` without both a type and an initializer would be implicitly any, so the type is stated explicitly in that case.
|
|
25
|
+
* @evidence contracts/common.md#clear-and-simple-design One expression.
|
|
26
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts It follows the declaration grammar.
|
|
27
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the default type.
|
|
28
|
+
*/
|
|
13
29
|
export const mut = (props: {
|
|
14
30
|
name: string;
|
|
15
31
|
type?: TypeNode | undefined;
|
|
@@ -34,6 +50,15 @@ export namespace StatementFactory {
|
|
|
34
50
|
),
|
|
35
51
|
);
|
|
36
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Builds a `const` statement from a name, an optional type, and an optional
|
|
55
|
+
* value.
|
|
56
|
+
*
|
|
57
|
+
* @evidence contracts/common.md#principled-implementation The declaration list carries the const flag and the given parts.
|
|
58
|
+
* @evidence contracts/common.md#clear-and-simple-design One expression.
|
|
59
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts It follows the declaration grammar.
|
|
60
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states its inputs.
|
|
61
|
+
*/
|
|
37
62
|
export const constant = (props: {
|
|
38
63
|
name: string;
|
|
39
64
|
type?: TypeNode | undefined;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The string formats of the OpenAPI document that the typia `Format` tag
|
|
3
|
+
* validates, so a schema carrying one of them is generated as a `Format` tag
|
|
4
|
+
* and a schema carrying any other format stays a plain `string`.
|
|
5
|
+
*/
|
|
6
|
+
export const SUPPORTED_STRING_FORMATS: ReadonlySet<string> = new Set([
|
|
7
|
+
"byte",
|
|
8
|
+
"password",
|
|
9
|
+
"regex",
|
|
10
|
+
"uuid",
|
|
11
|
+
"email",
|
|
12
|
+
"hostname",
|
|
13
|
+
"idn-email",
|
|
14
|
+
"idn-hostname",
|
|
15
|
+
"iri",
|
|
16
|
+
"iri-reference",
|
|
17
|
+
"ipv4",
|
|
18
|
+
"ipv6",
|
|
19
|
+
"uri",
|
|
20
|
+
"uri-reference",
|
|
21
|
+
"uri-template",
|
|
22
|
+
"url",
|
|
23
|
+
"date-time",
|
|
24
|
+
"date",
|
|
25
|
+
"time",
|
|
26
|
+
"duration",
|
|
27
|
+
"json-pointer",
|
|
28
|
+
"relative-json-pointer",
|
|
29
|
+
]);
|
|
@@ -6,6 +6,11 @@ import { type KeywordTypeNode, SyntaxKind, factory } from "@ttsc/factory";
|
|
|
6
6
|
* Wraps {@link factory.createKeywordTypeNode} with a name-based interface so
|
|
7
7
|
* generator code reads as `TypeFactory.keyword("any")` instead of selecting the
|
|
8
8
|
* `SyntaxKind.AnyKeyword` token by hand.
|
|
9
|
+
*
|
|
10
|
+
* @evidence contracts/common.md#principled-implementation The namespace maps the names of the nine keyword types to their syntax kinds.
|
|
11
|
+
* @evidence contracts/common.md#clear-and-simple-design One table, one type, and one function.
|
|
12
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts It only builds nodes.
|
|
13
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states its purpose.
|
|
9
14
|
*/
|
|
10
15
|
export namespace TypeFactory {
|
|
11
16
|
const KEYWORDS = {
|
|
@@ -20,8 +25,24 @@ export namespace TypeFactory {
|
|
|
20
25
|
undefined: SyntaxKind.UndefinedKeyword,
|
|
21
26
|
} as const;
|
|
22
27
|
|
|
28
|
+
/**
|
|
29
|
+
* The names of the supported keyword types.
|
|
30
|
+
*
|
|
31
|
+
* @evidence contracts/common.md#principled-implementation The type is the key set of the table that maps names to syntax kinds, so a new keyword is one table entry.
|
|
32
|
+
* @evidence contracts/common.md#clear-and-simple-design One derived type.
|
|
33
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts It is a type and adds no runtime behavior.
|
|
34
|
+
* @evidence contracts/common.md#meaningful-documentation The comment names the set.
|
|
35
|
+
*/
|
|
23
36
|
export type Keyword = keyof typeof KEYWORDS;
|
|
24
37
|
|
|
38
|
+
/**
|
|
39
|
+
* Builds the keyword type node of a keyword name.
|
|
40
|
+
*
|
|
41
|
+
* @evidence contracts/common.md#principled-implementation The name is looked up in the table, so an unsupported name is a compile error.
|
|
42
|
+
* @evidence contracts/common.md#clear-and-simple-design One lookup.
|
|
43
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts It follows the type grammar.
|
|
44
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states its input.
|
|
45
|
+
*/
|
|
25
46
|
export const keyword = (type: Keyword): KeywordTypeNode =>
|
|
26
47
|
factory.createKeywordTypeNode(KEYWORDS[type]);
|
|
27
48
|
}
|
|
@@ -3,7 +3,25 @@ import { NamingConvention } from "@typia/utils";
|
|
|
3
3
|
|
|
4
4
|
import ts from "../internal/ts";
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Builds type nodes from JavaScript values, so a value can be written as a
|
|
8
|
+
* literal type.
|
|
9
|
+
*
|
|
10
|
+
* @evidence contracts/common.md#principled-implementation The namespace maps booleans, numbers, strings, null, arrays as tuples, and objects as type literals, and anything else to `any`.
|
|
11
|
+
* @evidence contracts/common.md#clear-and-simple-design One entry function and small private builders per kind.
|
|
12
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The mapping is by type, with no value special-cased.
|
|
13
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states its purpose.
|
|
14
|
+
*/
|
|
6
15
|
export namespace TypeLiteralFactory {
|
|
16
|
+
/**
|
|
17
|
+
* Builds the literal type of a value: a literal for a primitive, a tuple for
|
|
18
|
+
* an array, a type literal for an object, and `any` for other values.
|
|
19
|
+
*
|
|
20
|
+
* @evidence contracts/common.md#principled-implementation The value is dispatched by type, negative numbers use a prefix minus as expressions do, and object keys that are not identifiers are quoted.
|
|
21
|
+
* @evidence contracts/common.md#clear-and-simple-design One function with one branch per kind.
|
|
22
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The dispatch is general.
|
|
23
|
+
* @evidence contracts/common.md#meaningful-documentation The comment lists the mapping.
|
|
24
|
+
*/
|
|
7
25
|
export const generate = (value: any): ts.TypeNode =>
|
|
8
26
|
typeof value === "boolean"
|
|
9
27
|
? generateBoolean(value)
|