@nestia/migrate 14.0.2 → 14.0.4
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/_virtual/_rolldown/runtime.mjs +6 -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 +4 -2
- package/lib/executable/NestiaMigrateCommander.js +5 -3
- package/lib/executable/NestiaMigrateCommander.js.map +1 -1
- package/lib/executable/NestiaMigrateCommander.mjs +2 -2
- package/lib/executable/NestiaMigrateInquirer.d.ts +6 -4
- package/lib/executable/NestiaMigrateInquirer.js +16 -13
- 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/package.mjs +55 -0
- package/lib/package.mjs.map +1 -0
- package/package.json +3 -3
- package/src/bundles/NEST_TEMPLATE.ts +1 -1
- package/src/bundles/SDK_TEMPLATE.ts +1 -1
- package/src/executable/NestiaMigrateCommander.ts +5 -3
- package/src/executable/NestiaMigrateInquirer.ts +9 -6
- package/src/executable/TemplateBundleCache.ts +65 -0
- package/src/executable/{bundle.js → bundle.ts} +110 -43
|
@@ -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);
|