@wp-typia/project-tools 0.11.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/README.md +32 -0
- package/dist/runtime/cli-add.d.ts +38 -0
- package/dist/runtime/cli-add.js +561 -0
- package/dist/runtime/cli-core.d.ts +25 -0
- package/dist/runtime/cli-core.js +25 -0
- package/dist/runtime/cli-doctor.d.ts +34 -0
- package/dist/runtime/cli-doctor.js +131 -0
- package/dist/runtime/cli-help.d.ts +9 -0
- package/dist/runtime/cli-help.js +37 -0
- package/dist/runtime/cli-prompt.d.ts +21 -0
- package/dist/runtime/cli-prompt.js +53 -0
- package/dist/runtime/cli-scaffold.d.ts +79 -0
- package/dist/runtime/cli-scaffold.js +206 -0
- package/dist/runtime/cli-templates.d.ts +30 -0
- package/dist/runtime/cli-templates.js +61 -0
- package/dist/runtime/index.d.ts +9 -0
- package/dist/runtime/index.js +7 -0
- package/dist/runtime/json-utils.d.ts +10 -0
- package/dist/runtime/json-utils.js +12 -0
- package/dist/runtime/local-dev-presets.d.ts +26 -0
- package/dist/runtime/local-dev-presets.js +132 -0
- package/dist/runtime/metadata-analysis.d.ts +11 -0
- package/dist/runtime/metadata-analysis.js +285 -0
- package/dist/runtime/metadata-model.d.ts +84 -0
- package/dist/runtime/metadata-model.js +59 -0
- package/dist/runtime/metadata-parser.d.ts +53 -0
- package/dist/runtime/metadata-parser.js +794 -0
- package/dist/runtime/metadata-php-render.d.ts +29 -0
- package/dist/runtime/metadata-php-render.js +549 -0
- package/dist/runtime/metadata-projection.d.ts +7 -0
- package/dist/runtime/metadata-projection.js +233 -0
- package/dist/runtime/migration-constants.d.ts +15 -0
- package/dist/runtime/migration-constants.js +16 -0
- package/dist/runtime/migration-diff.d.ts +2 -0
- package/dist/runtime/migration-diff.js +537 -0
- package/dist/runtime/migration-fixtures.d.ts +8 -0
- package/dist/runtime/migration-fixtures.js +94 -0
- package/dist/runtime/migration-fuzz-plan.d.ts +2 -0
- package/dist/runtime/migration-fuzz-plan.js +50 -0
- package/dist/runtime/migration-manifest.d.ts +19 -0
- package/dist/runtime/migration-manifest.js +129 -0
- package/dist/runtime/migration-project.d.ts +94 -0
- package/dist/runtime/migration-project.js +1101 -0
- package/dist/runtime/migration-render.d.ts +11 -0
- package/dist/runtime/migration-render.js +741 -0
- package/dist/runtime/migration-risk.d.ts +4 -0
- package/dist/runtime/migration-risk.js +52 -0
- package/dist/runtime/migration-types.d.ts +249 -0
- package/dist/runtime/migration-types.js +1 -0
- package/dist/runtime/migration-ui-capability.d.ts +17 -0
- package/dist/runtime/migration-ui-capability.js +190 -0
- package/dist/runtime/migration-utils.d.ts +69 -0
- package/dist/runtime/migration-utils.js +246 -0
- package/dist/runtime/migrations.d.ts +249 -0
- package/dist/runtime/migrations.js +1061 -0
- package/dist/runtime/object-utils.d.ts +12 -0
- package/dist/runtime/object-utils.js +14 -0
- package/dist/runtime/package-managers.d.ts +28 -0
- package/dist/runtime/package-managers.js +156 -0
- package/dist/runtime/package-versions.d.ts +10 -0
- package/dist/runtime/package-versions.js +68 -0
- package/dist/runtime/scaffold-onboarding.d.ts +32 -0
- package/dist/runtime/scaffold-onboarding.js +99 -0
- package/dist/runtime/scaffold.d.ts +146 -0
- package/dist/runtime/scaffold.js +612 -0
- package/dist/runtime/schema-core.d.ts +267 -0
- package/dist/runtime/schema-core.js +597 -0
- package/dist/runtime/starter-manifests.d.ts +25 -0
- package/dist/runtime/starter-manifests.js +383 -0
- package/dist/runtime/string-case.d.ts +36 -0
- package/dist/runtime/string-case.js +69 -0
- package/dist/runtime/template-builtins.d.ts +38 -0
- package/dist/runtime/template-builtins.js +72 -0
- package/dist/runtime/template-defaults.d.ts +75 -0
- package/dist/runtime/template-defaults.js +65 -0
- package/dist/runtime/template-registry.d.ts +36 -0
- package/dist/runtime/template-registry.js +94 -0
- package/dist/runtime/template-render.d.ts +24 -0
- package/dist/runtime/template-render.js +113 -0
- package/dist/runtime/template-source.d.ts +71 -0
- package/dist/runtime/template-source.js +821 -0
- package/dist/runtime/typia-tags.d.ts +1 -0
- package/dist/runtime/typia-tags.js +1 -0
- package/package.json +79 -0
- package/templates/_shared/base/languages/.gitkeep +1 -0
- package/templates/_shared/base/package.json.mustache +41 -0
- package/templates/_shared/base/scripts/sync-types-to-block-json.ts.mustache +118 -0
- package/templates/_shared/base/src/hooks.ts.mustache +19 -0
- package/templates/_shared/base/src/validator-toolkit.ts.mustache +31 -0
- package/templates/_shared/base/tsconfig.json.mustache +21 -0
- package/templates/_shared/base/webpack.config.js.mustache +99 -0
- package/templates/_shared/base/{{slugKebabCase}}.php.mustache +53 -0
- package/templates/_shared/compound/core/package.json.mustache +45 -0
- package/templates/_shared/compound/core/scripts/add-compound-child.ts.mustache +559 -0
- package/templates/_shared/compound/core/scripts/block-config.ts.mustache +13 -0
- package/templates/_shared/compound/core/scripts/sync-types-to-block-json.ts.mustache +53 -0
- package/templates/_shared/compound/core/webpack.config.js.mustache +141 -0
- package/templates/_shared/compound/core/{{slugKebabCase}}.php.mustache +51 -0
- package/templates/_shared/compound/persistence/package.json.mustache +50 -0
- package/templates/_shared/compound/persistence/scripts/block-config.ts.mustache +59 -0
- package/templates/_shared/compound/persistence/scripts/sync-rest-contracts.ts.mustache +101 -0
- package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/api-types.ts.mustache +21 -0
- package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/api-validators.ts.mustache +32 -0
- package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/api.ts.mustache +68 -0
- package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/block.json.mustache +52 -0
- package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/data.ts.mustache +192 -0
- package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/edit.tsx.mustache +123 -0
- package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/hooks.ts.mustache +11 -0
- package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/interactivity.ts.mustache +132 -0
- package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/render.php.mustache +158 -0
- package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/save.tsx.mustache +3 -0
- package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/types.ts.mustache +56 -0
- package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/validators.ts.mustache +32 -0
- package/templates/_shared/compound/persistence-auth/{{slugKebabCase}}.php.mustache +294 -0
- package/templates/_shared/compound/persistence-public/{{slugKebabCase}}.php.mustache +312 -0
- package/templates/_shared/migration-ui/common/src/admin/migration-dashboard.tsx +394 -0
- package/templates/_shared/migration-ui/common/src/migration-detector.ts +9 -0
- package/templates/_shared/migration-ui/common/src/migrations/helpers.ts +490 -0
- package/templates/_shared/migration-ui/common/src/migrations/index.ts +886 -0
- package/templates/_shared/persistence/auth/{{slugKebabCase}}.php.mustache +290 -0
- package/templates/_shared/persistence/core/package.json.mustache +46 -0
- package/templates/_shared/persistence/core/scripts/sync-rest-contracts.ts.mustache +113 -0
- package/templates/_shared/persistence/core/scripts/sync-types-to-block-json.ts.mustache +125 -0
- package/templates/_shared/persistence/core/src/api-types.ts.mustache +21 -0
- package/templates/_shared/persistence/core/src/api-validators.ts.mustache +32 -0
- package/templates/_shared/persistence/core/src/api.ts.mustache +68 -0
- package/templates/_shared/persistence/core/src/data.ts.mustache +192 -0
- package/templates/_shared/persistence/core/src/index.tsx.mustache +25 -0
- package/templates/_shared/persistence/core/src/interactivity.ts.mustache +134 -0
- package/templates/_shared/persistence/core/src/save.tsx.mustache +5 -0
- package/templates/_shared/persistence/core/src/validators.ts.mustache +32 -0
- package/templates/_shared/persistence/core/{{slugKebabCase}}.php.mustache +336 -0
- package/templates/_shared/persistence/public/{{slugKebabCase}}.php.mustache +308 -0
- package/templates/_shared/presets/test-preset/.wp-env.test.json.mustache +16 -0
- package/templates/_shared/presets/test-preset/playwright.config.ts.mustache +22 -0
- package/templates/_shared/presets/test-preset/scripts/wait-for-wp-env.mjs.mustache +102 -0
- package/templates/_shared/presets/test-preset/scripts/wp-env-utils.cjs.mustache +32 -0
- package/templates/_shared/presets/test-preset/tests/e2e/smoke.spec.ts.mustache +34 -0
- package/templates/_shared/presets/wp-env/.wp-env.json.mustache +16 -0
- package/templates/_shared/rest-helpers/auth/inc/rest-auth.php.mustache +37 -0
- package/templates/_shared/rest-helpers/public/inc/rest-public.php.mustache +314 -0
- package/templates/_shared/rest-helpers/shared/inc/rest-shared.php.mustache +58 -0
- package/templates/_shared/workspace/persistence-auth/inc/rest-auth.php.mustache +36 -0
- package/templates/_shared/workspace/persistence-auth/inc/rest-shared.php.mustache +55 -0
- package/templates/_shared/workspace/persistence-auth/server.php.mustache +237 -0
- package/templates/_shared/workspace/persistence-public/inc/rest-public.php.mustache +273 -0
- package/templates/_shared/workspace/persistence-public/inc/rest-shared.php.mustache +55 -0
- package/templates/_shared/workspace/persistence-public/server.php.mustache +252 -0
- package/templates/basic/src/block.json.mustache +51 -0
- package/templates/basic/src/edit.tsx.mustache +128 -0
- package/templates/basic/src/editor.scss.mustache +8 -0
- package/templates/basic/src/hooks.ts.mustache +18 -0
- package/templates/basic/src/index.tsx.mustache +45 -0
- package/templates/basic/src/save.tsx.mustache +30 -0
- package/templates/basic/src/style.scss.mustache +40 -0
- package/templates/basic/src/types.ts.mustache +56 -0
- package/templates/basic/src/validators.ts.mustache +26 -0
- package/templates/compound/src/blocks/{{slugKebabCase}}/block.json.mustache +37 -0
- package/templates/compound/src/blocks/{{slugKebabCase}}/children.ts.mustache +25 -0
- package/templates/compound/src/blocks/{{slugKebabCase}}/edit.tsx.mustache +93 -0
- package/templates/compound/src/blocks/{{slugKebabCase}}/hooks.ts.mustache +11 -0
- package/templates/compound/src/blocks/{{slugKebabCase}}/index.tsx.mustache +25 -0
- package/templates/compound/src/blocks/{{slugKebabCase}}/save.tsx.mustache +32 -0
- package/templates/compound/src/blocks/{{slugKebabCase}}/style.scss.mustache +31 -0
- package/templates/compound/src/blocks/{{slugKebabCase}}/types.ts.mustache +13 -0
- package/templates/compound/src/blocks/{{slugKebabCase}}/validators.ts.mustache +17 -0
- package/templates/compound/src/blocks/{{slugKebabCase}}-item/block.json.mustache +35 -0
- package/templates/compound/src/blocks/{{slugKebabCase}}-item/edit.tsx.mustache +50 -0
- package/templates/compound/src/blocks/{{slugKebabCase}}-item/hooks.ts.mustache +11 -0
- package/templates/compound/src/blocks/{{slugKebabCase}}-item/index.tsx.mustache +25 -0
- package/templates/compound/src/blocks/{{slugKebabCase}}-item/save.tsx.mustache +24 -0
- package/templates/compound/src/blocks/{{slugKebabCase}}-item/types.ts.mustache +12 -0
- package/templates/compound/src/blocks/{{slugKebabCase}}-item/validators.ts.mustache +17 -0
- package/templates/interactivity/package.json.mustache +42 -0
- package/templates/interactivity/src/block.json.mustache +73 -0
- package/templates/interactivity/src/edit.tsx.mustache +270 -0
- package/templates/interactivity/src/index.tsx.mustache +32 -0
- package/templates/interactivity/src/interactivity.ts.mustache +152 -0
- package/templates/interactivity/src/save.tsx.mustache +101 -0
- package/templates/interactivity/src/style.scss.mustache +60 -0
- package/templates/interactivity/src/types.ts.mustache +32 -0
- package/templates/interactivity/src/validators.ts.mustache +36 -0
- package/templates/persistence/src/block.json.mustache +52 -0
- package/templates/persistence/src/edit.tsx.mustache +165 -0
- package/templates/persistence/src/render.php.mustache +126 -0
- package/templates/persistence/src/style.scss.mustache +46 -0
- package/templates/persistence/src/types.ts.mustache +55 -0
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { execSync } from "node:child_process";
|
|
4
|
+
import { formatRunScript } from "./package-managers.js";
|
|
5
|
+
export { cloneJsonValue } from "./json-utils.js";
|
|
6
|
+
const MIGRATION_VERSION_LABEL_PATTERN = /^v([1-9]\d*)$/;
|
|
7
|
+
const LEGACY_SEMVER_MIGRATION_VERSION_PATTERN = /^\d+\.\d+\.\d+$/;
|
|
8
|
+
export function getValueAtPath(input, pathLabel) {
|
|
9
|
+
return String(pathLabel)
|
|
10
|
+
.split(".")
|
|
11
|
+
.reduce((value, segment) => value && typeof value === "object" ? value[segment] : undefined, input);
|
|
12
|
+
}
|
|
13
|
+
export function setValueAtPath(input, pathLabel, value) {
|
|
14
|
+
const segments = String(pathLabel).split(".");
|
|
15
|
+
let target = input;
|
|
16
|
+
while (segments.length > 1) {
|
|
17
|
+
const segment = segments.shift();
|
|
18
|
+
if (!segment) {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
if (!target[segment] || typeof target[segment] !== "object" || Array.isArray(target[segment])) {
|
|
22
|
+
target[segment] = {};
|
|
23
|
+
}
|
|
24
|
+
target = target[segment];
|
|
25
|
+
}
|
|
26
|
+
target[segments[0]] = value;
|
|
27
|
+
}
|
|
28
|
+
export function deleteValueAtPath(input, pathLabel) {
|
|
29
|
+
const segments = String(pathLabel).split(".");
|
|
30
|
+
let target = input;
|
|
31
|
+
while (segments.length > 1) {
|
|
32
|
+
const segment = segments.shift();
|
|
33
|
+
if (!segment || !target[segment] || typeof target[segment] !== "object") {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
target = target[segment];
|
|
37
|
+
}
|
|
38
|
+
delete target[segments[0]];
|
|
39
|
+
}
|
|
40
|
+
export function createFixtureScalarValue(pathLabel) {
|
|
41
|
+
const normalized = String(pathLabel).toLowerCase();
|
|
42
|
+
if (normalized.includes("id")) {
|
|
43
|
+
return "00000000-0000-4000-8000-000000000000";
|
|
44
|
+
}
|
|
45
|
+
if (normalized.includes("count") || normalized.includes("number")) {
|
|
46
|
+
return 1;
|
|
47
|
+
}
|
|
48
|
+
if (normalized.includes("visible") || normalized.startsWith("is")) {
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
return `legacy:${pathLabel}`;
|
|
52
|
+
}
|
|
53
|
+
export function createTransformFixtureValue(attribute, pathLabel) {
|
|
54
|
+
switch (attribute?.ts?.kind) {
|
|
55
|
+
case "number":
|
|
56
|
+
return "42";
|
|
57
|
+
case "boolean":
|
|
58
|
+
return "1";
|
|
59
|
+
case "union":
|
|
60
|
+
return { kind: "unknown" };
|
|
61
|
+
default:
|
|
62
|
+
return createFixtureScalarValue(pathLabel);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
export function readJson(filePath) {
|
|
66
|
+
return JSON.parse(fs.readFileSync(filePath, "utf8"));
|
|
67
|
+
}
|
|
68
|
+
export function renderPhpValue(value, indentLevel) {
|
|
69
|
+
const indent = "\t".repeat(indentLevel);
|
|
70
|
+
const nestedIndent = "\t".repeat(indentLevel + 1);
|
|
71
|
+
if (value === null) {
|
|
72
|
+
return "null";
|
|
73
|
+
}
|
|
74
|
+
if (typeof value === "string") {
|
|
75
|
+
return `'${value.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
|
|
76
|
+
}
|
|
77
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
78
|
+
return String(value);
|
|
79
|
+
}
|
|
80
|
+
if (Array.isArray(value)) {
|
|
81
|
+
if (value.length === 0) {
|
|
82
|
+
return "[]";
|
|
83
|
+
}
|
|
84
|
+
const items = value.map((item) => `${nestedIndent}${renderPhpValue(item, indentLevel + 1)}`);
|
|
85
|
+
return `[\n${items.join(",\n")}\n${indent}]`;
|
|
86
|
+
}
|
|
87
|
+
if (typeof value === "object") {
|
|
88
|
+
const entries = Object.entries(value);
|
|
89
|
+
if (entries.length === 0) {
|
|
90
|
+
return "[]";
|
|
91
|
+
}
|
|
92
|
+
const items = entries.map(([key, item]) => `${nestedIndent}'${String(key).replace(/\\/g, "\\\\").replace(/'/g, "\\'")}' => ${renderPhpValue(item, indentLevel + 1)}`);
|
|
93
|
+
return `[\n${items.join(",\n")}\n${indent}]`;
|
|
94
|
+
}
|
|
95
|
+
throw new Error(`Unable to encode PHP migration registry value for ${String(value)}`);
|
|
96
|
+
}
|
|
97
|
+
export function copyFile(sourcePath, targetPath) {
|
|
98
|
+
fs.mkdirSync(path.dirname(targetPath), { recursive: true });
|
|
99
|
+
fs.copyFileSync(sourcePath, targetPath);
|
|
100
|
+
}
|
|
101
|
+
export function sanitizeSaveSnapshotSource(source) {
|
|
102
|
+
return source
|
|
103
|
+
.replace(/^import\s+\{[^}]+\}\s+from\s+['"]\.\/types['"];?\n?/gm, "")
|
|
104
|
+
.replace(/^interface\s+SaveProps\s*\{[\s\S]*?\}\n?/m, "")
|
|
105
|
+
.replace(/: SaveProps/g, ": { attributes: any }")
|
|
106
|
+
.replace(/attributes:\s*[A-Za-z0-9_<>{}\[\]|&,\s]+;/g, "attributes: any;")
|
|
107
|
+
.replace(/\(\{\s*attributes\s*\}:\s*\{\s*attributes:\s*any\s*\}\)/g, "({ attributes }: { attributes: any })")
|
|
108
|
+
.replace(/\n{3,}/g, "\n\n")
|
|
109
|
+
.trimEnd()
|
|
110
|
+
.concat("\n");
|
|
111
|
+
}
|
|
112
|
+
export function sanitizeSnapshotBlockJson(blockJson) {
|
|
113
|
+
const snapshot = { ...blockJson };
|
|
114
|
+
for (const key of [
|
|
115
|
+
"editorScript",
|
|
116
|
+
"script",
|
|
117
|
+
"scriptModule",
|
|
118
|
+
"viewScript",
|
|
119
|
+
"viewScriptModule",
|
|
120
|
+
"style",
|
|
121
|
+
"editorStyle",
|
|
122
|
+
"render",
|
|
123
|
+
]) {
|
|
124
|
+
delete snapshot[key];
|
|
125
|
+
}
|
|
126
|
+
return snapshot;
|
|
127
|
+
}
|
|
128
|
+
export function runProjectScriptIfPresent(projectDir, scriptName) {
|
|
129
|
+
const packageJson = readJson(path.join(projectDir, "package.json"));
|
|
130
|
+
if (!packageJson.scripts?.[scriptName]) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const packageManagerId = detectPackageManagerId(projectDir);
|
|
134
|
+
execSync(formatRunScript(packageManagerId, scriptName), {
|
|
135
|
+
cwd: projectDir,
|
|
136
|
+
stdio: "inherit",
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
export function detectPackageManagerId(projectDir) {
|
|
140
|
+
const packageJson = readJson(path.join(projectDir, "package.json"));
|
|
141
|
+
const field = String(packageJson.packageManager ?? "");
|
|
142
|
+
if (field.startsWith("bun@"))
|
|
143
|
+
return "bun";
|
|
144
|
+
if (field.startsWith("npm@"))
|
|
145
|
+
return "npm";
|
|
146
|
+
if (field.startsWith("pnpm@"))
|
|
147
|
+
return "pnpm";
|
|
148
|
+
if (field.startsWith("yarn@"))
|
|
149
|
+
return "yarn";
|
|
150
|
+
return "bun";
|
|
151
|
+
}
|
|
152
|
+
export function getLocalTsxBinary(projectDir) {
|
|
153
|
+
const filename = process.platform === "win32" ? "tsx.cmd" : "tsx";
|
|
154
|
+
const binaryPath = path.join(projectDir, "node_modules", ".bin", filename);
|
|
155
|
+
if (!fs.existsSync(binaryPath)) {
|
|
156
|
+
throw new Error("Local tsx binary was not found. Install project dependencies before running migration verification.");
|
|
157
|
+
}
|
|
158
|
+
return binaryPath;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Returns whether isInteractiveTerminal() is running with both stdin and stdout
|
|
162
|
+
* attached to a TTY so CLI and migration flows can safely prompt the user.
|
|
163
|
+
*/
|
|
164
|
+
export function isInteractiveTerminal() {
|
|
165
|
+
return Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Resolves the `current` sentinel to the current migration version label.
|
|
169
|
+
*
|
|
170
|
+
* @param currentMigrationVersion Current migration version label for the workspace.
|
|
171
|
+
* @param value Requested target value, which may be `current`.
|
|
172
|
+
* @returns The concrete migration version label that should be used.
|
|
173
|
+
*/
|
|
174
|
+
export function resolveTargetMigrationVersion(currentMigrationVersion, value) {
|
|
175
|
+
return value === "current" ? currentMigrationVersion : value;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Returns whether a value matches the canonical `vN` migration label format.
|
|
179
|
+
*
|
|
180
|
+
* @param value Candidate migration version label.
|
|
181
|
+
* @returns `true` when the value is a valid `vN` label with `N >= 1`.
|
|
182
|
+
*/
|
|
183
|
+
export function isMigrationVersionLabel(value) {
|
|
184
|
+
return MIGRATION_VERSION_LABEL_PATTERN.test(value);
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Returns whether a value looks like a legacy semver-based migration label.
|
|
188
|
+
*
|
|
189
|
+
* @param value Candidate migration version label.
|
|
190
|
+
* @returns `true` when the value matches the legacy `x.y.z` semver pattern.
|
|
191
|
+
*/
|
|
192
|
+
export function isLegacySemverMigrationVersion(value) {
|
|
193
|
+
return LEGACY_SEMVER_MIGRATION_VERSION_PATTERN.test(value);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Throws when a migration version label does not match the canonical `vN` format.
|
|
197
|
+
*
|
|
198
|
+
* @param value Candidate migration version label.
|
|
199
|
+
* @param label Human-readable label used in the thrown error message.
|
|
200
|
+
* @returns Nothing.
|
|
201
|
+
* @throws Error When the provided value is not a valid `vN` migration label.
|
|
202
|
+
*/
|
|
203
|
+
export function assertMigrationVersionLabel(value, label) {
|
|
204
|
+
if (!isMigrationVersionLabel(value)) {
|
|
205
|
+
throw new Error(`Invalid ${label}: ${value}. Expected vN with N >= 1.`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
function parseMigrationVersionNumber(value) {
|
|
209
|
+
const match = value.match(MIGRATION_VERSION_LABEL_PATTERN);
|
|
210
|
+
if (!match) {
|
|
211
|
+
throw new Error(`Invalid migration version label: ${value}. Expected vN with N >= 1.`);
|
|
212
|
+
}
|
|
213
|
+
return Number.parseInt(match[1], 10);
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Compares two migration version labels by their numeric suffix.
|
|
217
|
+
*
|
|
218
|
+
* @param left Left migration version label.
|
|
219
|
+
* @param right Right migration version label.
|
|
220
|
+
* @returns A negative number when `left < right`, zero when equal, and a positive number when `left > right`.
|
|
221
|
+
*/
|
|
222
|
+
export function compareMigrationVersionLabels(left, right) {
|
|
223
|
+
return parseMigrationVersionNumber(left) - parseMigrationVersionNumber(right);
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Formats the reset guidance shown when a legacy semver migration workspace is detected.
|
|
227
|
+
*
|
|
228
|
+
* @param reason Optional leading reason that explains what legacy pattern was found.
|
|
229
|
+
* @returns A user-facing guidance string that explains how to reset to `v1` labels.
|
|
230
|
+
*/
|
|
231
|
+
export function formatLegacyMigrationWorkspaceResetGuidance(reason) {
|
|
232
|
+
return [
|
|
233
|
+
reason ? `${reason} ` : "",
|
|
234
|
+
"Back up `src/migrations/` if needed, remove or reset the existing migration workspace, ",
|
|
235
|
+
"then rerun `wp-typia migrate init --current-migration-version v1`.",
|
|
236
|
+
].join("");
|
|
237
|
+
}
|
|
238
|
+
export function escapeForCode(value) {
|
|
239
|
+
return String(value).replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
240
|
+
}
|
|
241
|
+
export function renderObjectKey(key) {
|
|
242
|
+
return JSON.stringify(String(key));
|
|
243
|
+
}
|
|
244
|
+
export function isNumber(value) {
|
|
245
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
246
|
+
}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { createMigrationDiff } from "./migration-diff.js";
|
|
2
|
+
import { formatDiffReport } from "./migration-render.js";
|
|
3
|
+
import { createMigrationRiskSummary } from "./migration-risk.js";
|
|
4
|
+
import type { MigrationBlockConfig, ParsedMigrationArgs, RenderLine } from "./migration-types.js";
|
|
5
|
+
import type { ReadlinePrompt } from "./cli-prompt.js";
|
|
6
|
+
type CommandRenderOptions = {
|
|
7
|
+
prompt?: ReadlinePrompt;
|
|
8
|
+
renderLine?: RenderLine;
|
|
9
|
+
};
|
|
10
|
+
type DiffLikeOptions = {
|
|
11
|
+
fromMigrationVersion?: string;
|
|
12
|
+
renderLine?: RenderLine;
|
|
13
|
+
toMigrationVersion?: string;
|
|
14
|
+
};
|
|
15
|
+
type VerifyOptions = {
|
|
16
|
+
all?: boolean;
|
|
17
|
+
fromMigrationVersion?: string;
|
|
18
|
+
renderLine?: RenderLine;
|
|
19
|
+
};
|
|
20
|
+
type FixturesOptions = {
|
|
21
|
+
all?: boolean;
|
|
22
|
+
confirmOverwrite?: ((message: string) => boolean) | undefined;
|
|
23
|
+
force?: boolean;
|
|
24
|
+
fromMigrationVersion?: string;
|
|
25
|
+
isInteractive?: boolean;
|
|
26
|
+
renderLine?: RenderLine;
|
|
27
|
+
toMigrationVersion?: string;
|
|
28
|
+
};
|
|
29
|
+
type FuzzOptions = {
|
|
30
|
+
all?: boolean;
|
|
31
|
+
fromMigrationVersion?: string;
|
|
32
|
+
iterations?: number;
|
|
33
|
+
renderLine?: RenderLine;
|
|
34
|
+
seed?: number;
|
|
35
|
+
};
|
|
36
|
+
type MigrationPlanBlockSummary = {
|
|
37
|
+
blockName: string;
|
|
38
|
+
diff: ReturnType<typeof createMigrationDiff>;
|
|
39
|
+
riskSummary: ReturnType<typeof createMigrationRiskSummary>;
|
|
40
|
+
};
|
|
41
|
+
type MigrationPlanSummary = {
|
|
42
|
+
availableLegacyVersions: string[];
|
|
43
|
+
currentMigrationVersion: string;
|
|
44
|
+
fromMigrationVersion: string;
|
|
45
|
+
includedBlocks: string[];
|
|
46
|
+
nextSteps: string[];
|
|
47
|
+
skippedBlocks: string[];
|
|
48
|
+
summaries: MigrationPlanBlockSummary[];
|
|
49
|
+
targetMigrationVersion: string;
|
|
50
|
+
};
|
|
51
|
+
type WizardOptions = CommandRenderOptions & {
|
|
52
|
+
isInteractive?: boolean;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Returns the formatted help text for migration CLI commands and flags.
|
|
56
|
+
*
|
|
57
|
+
* @returns Multi-line usage text for the `wp-typia migrate` command surface.
|
|
58
|
+
*/
|
|
59
|
+
export declare function formatMigrationHelpText(): string;
|
|
60
|
+
/**
|
|
61
|
+
* Parses migration CLI arguments into a structured command payload.
|
|
62
|
+
*
|
|
63
|
+
* @param argv Command-line arguments that follow the `migrate` subcommand.
|
|
64
|
+
* @returns Parsed migration command and normalized flags for runtime dispatch.
|
|
65
|
+
* @throws Error When no arguments are provided, an unknown flag is encountered, or legacy semver flags are used.
|
|
66
|
+
*/
|
|
67
|
+
export declare function parseMigrationArgs(argv: string[]): ParsedMigrationArgs;
|
|
68
|
+
export { formatDiffReport };
|
|
69
|
+
/**
|
|
70
|
+
* Dispatch a parsed migration command to the matching runtime workflow.
|
|
71
|
+
*
|
|
72
|
+
* Most commands execute synchronously and preserve direct throw semantics for
|
|
73
|
+
* existing callers. The interactive `wizard` command returns a promise because
|
|
74
|
+
* it waits for prompt selection before running the shared read-only planner.
|
|
75
|
+
*
|
|
76
|
+
* @param command Parsed migration command and flags.
|
|
77
|
+
* @param cwd Project directory to operate on.
|
|
78
|
+
* @param options Optional prompt/render hooks for testable and interactive execution.
|
|
79
|
+
* @returns The command result, or a promise when the selected command is interactive.
|
|
80
|
+
*/
|
|
81
|
+
export declare function runMigrationCommand(command: ParsedMigrationArgs, cwd: string, { prompt, renderLine }?: CommandRenderOptions): import("./migration-types.js").MigrationProjectState | import("./migration-types.js").MigrationDiff | MigrationPlanSummary | Promise<MigrationPlanSummary | {
|
|
82
|
+
cancelled: true;
|
|
83
|
+
}> | {
|
|
84
|
+
block: import("./migration-types.js").ResolvedMigrationBlockTarget;
|
|
85
|
+
diff: import("./migration-types.js").MigrationDiff;
|
|
86
|
+
}[] | {
|
|
87
|
+
blockName: string;
|
|
88
|
+
diff: ReturnType<typeof createMigrationDiff>;
|
|
89
|
+
rulePath: string;
|
|
90
|
+
} | {
|
|
91
|
+
scaffolded: {
|
|
92
|
+
blockName: string;
|
|
93
|
+
diff: ReturnType<typeof createMigrationDiff>;
|
|
94
|
+
rulePath: string;
|
|
95
|
+
}[];
|
|
96
|
+
} | {
|
|
97
|
+
verifiedVersions: string[];
|
|
98
|
+
} | {
|
|
99
|
+
checkedVersions: string[];
|
|
100
|
+
checks: {
|
|
101
|
+
detail: string;
|
|
102
|
+
label: string;
|
|
103
|
+
status: "fail" | "pass";
|
|
104
|
+
}[];
|
|
105
|
+
} | {
|
|
106
|
+
generatedVersions: string[];
|
|
107
|
+
skippedVersions: string[];
|
|
108
|
+
} | {
|
|
109
|
+
fuzzedVersions: never[];
|
|
110
|
+
seed?: undefined;
|
|
111
|
+
} | {
|
|
112
|
+
fuzzedVersions: string[];
|
|
113
|
+
seed: number | undefined;
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* Preview one migration edge without scaffolding rules, fixtures, or generated files.
|
|
117
|
+
*
|
|
118
|
+
* @param projectDir Absolute or relative project directory containing the migration workspace.
|
|
119
|
+
* @param options Selected source/target versions plus optional line rendering overrides.
|
|
120
|
+
* @returns A structured summary of the selected edge, included/skipped block targets, and next steps.
|
|
121
|
+
*/
|
|
122
|
+
export declare function planProjectMigrations(projectDir: string, { fromMigrationVersion, renderLine, toMigrationVersion }?: DiffLikeOptions): MigrationPlanSummary;
|
|
123
|
+
/**
|
|
124
|
+
* Interactively choose one legacy version to preview, then run the same read-only planner.
|
|
125
|
+
*
|
|
126
|
+
* @param projectDir Absolute or relative project directory containing the migration workspace.
|
|
127
|
+
* @param options Interactive prompt and rendering settings. Throws when no TTY is available.
|
|
128
|
+
* @returns The planned migration summary, or `{ cancelled: true }` when the user exits the wizard.
|
|
129
|
+
*/
|
|
130
|
+
export declare function wizardProjectMigrations(projectDir: string, { isInteractive, prompt, renderLine, }?: WizardOptions): Promise<MigrationPlanSummary | {
|
|
131
|
+
cancelled: true;
|
|
132
|
+
}>;
|
|
133
|
+
/**
|
|
134
|
+
* Initializes migration scaffolding for a detected single-block or multi-block project layout.
|
|
135
|
+
*
|
|
136
|
+
* @param projectDir Absolute or relative project directory containing the migration workspace.
|
|
137
|
+
* @param currentMigrationVersion Initial migration version label to seed, such as `v1`.
|
|
138
|
+
* @param options Console rendering options used to report retrofit detection and initialization output.
|
|
139
|
+
* @returns The loaded migration project state after the config, snapshots, and generated files are written.
|
|
140
|
+
* @throws Error When the project layout is unsupported or the migration version label is invalid.
|
|
141
|
+
*/
|
|
142
|
+
export declare function initProjectMigrations(projectDir: string, currentMigrationVersion: string, { renderLine }?: CommandRenderOptions): import("./migration-types.js").MigrationProjectState;
|
|
143
|
+
/**
|
|
144
|
+
* Captures the current project state as a named migration snapshot and refreshes generated artifacts.
|
|
145
|
+
*
|
|
146
|
+
* @param projectDir Absolute or relative project directory containing the migration workspace.
|
|
147
|
+
* @param migrationVersion Migration version label to snapshot, such as `v2`.
|
|
148
|
+
* @param options Console rendering options and snapshot side-effect flags.
|
|
149
|
+
* @returns The loaded migration project state after the snapshot files and registry outputs are refreshed.
|
|
150
|
+
* @throws Error When the label is invalid, the project is not migration-capable, or `sync-types` fails.
|
|
151
|
+
*/
|
|
152
|
+
export declare function snapshotProjectVersion(projectDir: string, migrationVersion: string, { renderLine, skipConfigUpdate, skipSyncTypes, }?: CommandRenderOptions & {
|
|
153
|
+
skipConfigUpdate?: boolean;
|
|
154
|
+
skipSyncTypes?: boolean;
|
|
155
|
+
}): import("./migration-types.js").MigrationProjectState;
|
|
156
|
+
/**
|
|
157
|
+
* Computes and renders migration diffs for a selected legacy-to-target edge.
|
|
158
|
+
*
|
|
159
|
+
* @param projectDir Absolute or relative project directory containing the migration workspace.
|
|
160
|
+
* @param options Selected source and target migration versions plus optional line rendering overrides.
|
|
161
|
+
* @returns A single diff for single-block workspaces, or an array of per-block diffs for multi-block workspaces.
|
|
162
|
+
* @throws Error When `fromMigrationVersion` is missing or no eligible snapshots exist for the selected edge.
|
|
163
|
+
*/
|
|
164
|
+
export declare function diffProjectMigrations(projectDir: string, { fromMigrationVersion, toMigrationVersion, renderLine, }?: DiffLikeOptions): import("./migration-types.js").MigrationDiff | {
|
|
165
|
+
block: import("./migration-types.js").ResolvedMigrationBlockTarget;
|
|
166
|
+
diff: import("./migration-types.js").MigrationDiff;
|
|
167
|
+
}[];
|
|
168
|
+
/**
|
|
169
|
+
* Scaffolds migration rule and fixture files for a selected legacy-to-target edge.
|
|
170
|
+
*
|
|
171
|
+
* @param projectDir Absolute or relative project directory containing the migration workspace.
|
|
172
|
+
* @param options Selected source and target migration versions plus optional line rendering overrides.
|
|
173
|
+
* @returns A single scaffold result for single-block workspaces, or a grouped result for multi-block workspaces.
|
|
174
|
+
* @throws Error When `fromMigrationVersion` is missing or no eligible snapshots exist for the selected edge.
|
|
175
|
+
*/
|
|
176
|
+
export declare function scaffoldProjectMigrations(projectDir: string, { fromMigrationVersion, toMigrationVersion, renderLine, }?: DiffLikeOptions): {
|
|
177
|
+
blockName: string;
|
|
178
|
+
diff: ReturnType<typeof createMigrationDiff>;
|
|
179
|
+
rulePath: string;
|
|
180
|
+
} | {
|
|
181
|
+
scaffolded: {
|
|
182
|
+
blockName: string;
|
|
183
|
+
diff: ReturnType<typeof createMigrationDiff>;
|
|
184
|
+
rulePath: string;
|
|
185
|
+
}[];
|
|
186
|
+
};
|
|
187
|
+
/**
|
|
188
|
+
* Run deterministic migration verification against generated fixtures.
|
|
189
|
+
*
|
|
190
|
+
* @param projectDir Absolute or relative project directory containing the migration workspace.
|
|
191
|
+
* @param options Verification scope and console rendering options.
|
|
192
|
+
* @returns Verified legacy versions.
|
|
193
|
+
*/
|
|
194
|
+
export declare function verifyProjectMigrations(projectDir: string, { all, fromMigrationVersion, renderLine }?: VerifyOptions): {
|
|
195
|
+
verifiedVersions: string[];
|
|
196
|
+
};
|
|
197
|
+
/**
|
|
198
|
+
* Validate the migration workspace without mutating files.
|
|
199
|
+
*
|
|
200
|
+
* @param projectDir Absolute or relative project directory containing the migration workspace.
|
|
201
|
+
* @param options Doctor scope and console rendering options.
|
|
202
|
+
* @returns Structured doctor check results for the selected legacy versions.
|
|
203
|
+
*/
|
|
204
|
+
export declare function doctorProjectMigrations(projectDir: string, { all, fromMigrationVersion, renderLine }?: VerifyOptions): {
|
|
205
|
+
checkedVersions: string[];
|
|
206
|
+
checks: {
|
|
207
|
+
detail: string;
|
|
208
|
+
label: string;
|
|
209
|
+
status: "fail" | "pass";
|
|
210
|
+
}[];
|
|
211
|
+
};
|
|
212
|
+
/**
|
|
213
|
+
* Generate or refresh migration fixtures for one or more legacy edges.
|
|
214
|
+
*
|
|
215
|
+
* @param projectDir Absolute or relative project directory containing the migration workspace.
|
|
216
|
+
* @param options Fixture generation scope and refresh options.
|
|
217
|
+
* @returns Generated and skipped legacy versions.
|
|
218
|
+
*/
|
|
219
|
+
export declare function fixturesProjectMigrations(projectDir: string, { all, confirmOverwrite, force, fromMigrationVersion, isInteractive, renderLine, toMigrationVersion, }?: FixturesOptions): {
|
|
220
|
+
generatedVersions: string[];
|
|
221
|
+
skippedVersions: string[];
|
|
222
|
+
};
|
|
223
|
+
/**
|
|
224
|
+
* Run seeded migration fuzz verification against generated fuzz artifacts.
|
|
225
|
+
*
|
|
226
|
+
* @param projectDir Absolute or relative project directory containing the migration workspace.
|
|
227
|
+
* @param options Fuzz scope, iteration count, seed, and console rendering options.
|
|
228
|
+
* @returns Fuzzed legacy versions and the effective seed.
|
|
229
|
+
*/
|
|
230
|
+
export declare function fuzzProjectMigrations(projectDir: string, { all, fromMigrationVersion, iterations, renderLine, seed, }?: FuzzOptions): {
|
|
231
|
+
fuzzedVersions: never[];
|
|
232
|
+
seed?: undefined;
|
|
233
|
+
} | {
|
|
234
|
+
fuzzedVersions: string[];
|
|
235
|
+
seed: number | undefined;
|
|
236
|
+
};
|
|
237
|
+
/**
|
|
238
|
+
* Initialize migration scaffolding for one or more block targets.
|
|
239
|
+
*
|
|
240
|
+
* Writes the migration config, creates the initial scaffold files, snapshots
|
|
241
|
+
* the current project state, and regenerates generated migration artifacts.
|
|
242
|
+
*
|
|
243
|
+
* @param projectDir Absolute or relative project directory containing the migration workspace.
|
|
244
|
+
* @param currentMigrationVersion Initial migration version label to seed into the migration config.
|
|
245
|
+
* @param blocks Block targets to register for migration-aware scaffolding.
|
|
246
|
+
* @param options Console rendering options for initialization output.
|
|
247
|
+
* @returns The loaded migration project state after initialization completes.
|
|
248
|
+
*/
|
|
249
|
+
export declare function seedProjectMigrations(projectDir: string, currentMigrationVersion: string, blocks: MigrationBlockConfig[], { renderLine }?: CommandRenderOptions): import("./migration-types.js").MigrationProjectState;
|