wp-typia 0.22.5 → 0.22.7
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 +7 -0
- package/bin/wp-typia.js +83 -0
- package/dist-bunli/.bunli/commands.gen.js +2000 -1256
- package/dist-bunli/{cli-xbzfx7qz.js → cli-27v2qpjg.js} +4 -4
- package/dist-bunli/{cli-1sm60g1z.js → cli-2hsp17nd.js} +2 -2
- package/dist-bunli/{cli-hb9vpsev.js → cli-2rqf6t0b.js} +1 -1
- package/dist-bunli/{cli-6bhfzq5e.js → cli-52ke0ptp.js} +2 -2
- package/dist-bunli/{cli-ctddkm3n.js → cli-8snabymq.js} +405 -204
- package/dist-bunli/{cli-add-1gqgshf0.js → cli-add-8jpdnz1r.js} +85 -64
- package/dist-bunli/{cli-nzwpmw4y.js → cli-cjygr56g.js} +98 -32
- package/dist-bunli/{cli-doctor-w35s8y9w.js → cli-doctor-h5tq4ztr.js} +15 -18
- package/dist-bunli/cli-fys8vm2t.js +20 -0
- package/dist-bunli/{cli-btbpt84c.js → cli-hhp1d348.js} +1 -1
- package/dist-bunli/{cli-init-z8sjmkvc.js → cli-init-w9p558th.js} +414 -393
- package/dist-bunli/{cli-scaffold-ad3bd555.js → cli-scaffold-qve8rqja.js} +9 -8
- package/dist-bunli/{cli-j30rk466.js → cli-ta3y0hp2.js} +697 -298
- package/dist-bunli/cli.js +8 -6
- package/dist-bunli/{command-list-scd6zqp8.js → command-list-6zr1tj96.js} +16 -12
- package/dist-bunli/{migrations-skkzdvhm.js → migrations-v0avgyg6.js} +7 -6
- package/dist-bunli/node-cli.js +253 -97
- package/dist-bunli/{workspace-project-7826tewa.js → workspace-project-csnnggz6.js} +2 -2
- package/package.json +2 -2
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
getPackageVersions
|
|
4
|
-
} from "./cli-
|
|
4
|
+
} from "./cli-2hsp17nd.js";
|
|
5
5
|
import {
|
|
6
6
|
discoverMigrationInitLayout
|
|
7
|
-
} from "./cli-
|
|
7
|
+
} from "./cli-2rqf6t0b.js";
|
|
8
8
|
import"./cli-tke8twkn.js";
|
|
9
9
|
import {
|
|
10
10
|
quoteTsString,
|
|
@@ -13,7 +13,8 @@ import {
|
|
|
13
13
|
snapshotWorkspaceFiles,
|
|
14
14
|
toPascalCase,
|
|
15
15
|
updateWorkspaceInventorySource
|
|
16
|
-
} from "./cli-
|
|
16
|
+
} from "./cli-ta3y0hp2.js";
|
|
17
|
+
import"./cli-fys8vm2t.js";
|
|
17
18
|
import {
|
|
18
19
|
CLI_DIAGNOSTIC_CODES,
|
|
19
20
|
createCliDiagnosticCodeError
|
|
@@ -21,27 +22,26 @@ import {
|
|
|
21
22
|
import {
|
|
22
23
|
parseWorkspacePackageManagerId,
|
|
23
24
|
tryResolveWorkspaceProject
|
|
24
|
-
} from "./cli-
|
|
25
|
+
} from "./cli-hhp1d348.js";
|
|
25
26
|
import {
|
|
26
27
|
formatAddDevDependenciesCommand,
|
|
27
28
|
formatPackageExecCommand,
|
|
28
29
|
formatRunScript,
|
|
29
30
|
getPackageManager,
|
|
30
31
|
transformPackageManagerText
|
|
31
|
-
} from "./cli-
|
|
32
|
+
} from "./cli-52ke0ptp.js";
|
|
32
33
|
import {
|
|
33
34
|
__toESM
|
|
34
35
|
} from "./cli-xnn9xjcy.js";
|
|
35
36
|
|
|
36
|
-
// ../wp-typia-project-tools/src/runtime/cli-init.ts
|
|
37
|
-
|
|
38
|
-
import fs from "fs";
|
|
37
|
+
// ../wp-typia-project-tools/src/runtime/cli-init-apply.ts
|
|
38
|
+
import fs3 from "fs";
|
|
39
39
|
import { promises as fsp } from "fs";
|
|
40
|
+
import path4 from "path";
|
|
41
|
+
|
|
42
|
+
// ../wp-typia-project-tools/src/runtime/cli-init-package-json.ts
|
|
43
|
+
import fs from "fs";
|
|
40
44
|
import path from "path";
|
|
41
|
-
import { analyzeSourceTypes } from "@wp-typia/block-runtime/metadata-parser";
|
|
42
|
-
var SUPPORTED_RETROFIT_LAYOUT_NOTE = "Supported retrofit layouts currently mirror the migration bootstrap detector: `src/block.json` + `src/types.ts` + `src/save.tsx`, legacy root `block.json` + `src/types.ts` + `src/save.tsx`, or multi-block `src/blocks/*/block.json` workspaces.";
|
|
43
|
-
var RETROFIT_APPLY_PREVIEW_NOTE = "If you rerun with `wp-typia init --apply`, package.json and generated helper files are snapshotted and rolled back automatically if a write fails.";
|
|
44
|
-
var RETROFIT_ROLLBACK_NOTE = "Apply mode writes package.json and generated helper files with rollback-on-failure protection.";
|
|
45
45
|
var BASE_RETROFIT_SCRIPTS = {
|
|
46
46
|
sync: "tsx scripts/sync-project.ts",
|
|
47
47
|
"sync-types": "tsx scripts/sync-types-to-block-json.ts",
|
|
@@ -55,9 +55,6 @@ var BASE_RETROFIT_DEV_DEPENDENCIES = [
|
|
|
55
55
|
"typescript",
|
|
56
56
|
"typia"
|
|
57
57
|
];
|
|
58
|
-
function normalizeRelativePath(value) {
|
|
59
|
-
return value.replace(/\\/gu, "/");
|
|
60
|
-
}
|
|
61
58
|
function readProjectPackageJson(projectDir) {
|
|
62
59
|
const packageJsonPath = path.join(projectDir, "package.json");
|
|
63
60
|
if (!fs.existsSync(packageJsonPath)) {
|
|
@@ -164,14 +161,148 @@ function buildPackageManagerFieldChange(packageJson, packageManager, options = {
|
|
|
164
161
|
requiredValue
|
|
165
162
|
};
|
|
166
163
|
}
|
|
164
|
+
function hasExistingWpTypiaProjectSurface(projectDir, packageJson) {
|
|
165
|
+
const scripts = packageJson?.scripts ?? {};
|
|
166
|
+
const hasSyncSurface = typeof scripts.sync === "string" || typeof scripts["sync-types"] === "string";
|
|
167
|
+
const hasHelperFiles = [
|
|
168
|
+
path.join("scripts", "block-config.ts"),
|
|
169
|
+
path.join("scripts", "sync-project.ts"),
|
|
170
|
+
path.join("scripts", "sync-types-to-block-json.ts")
|
|
171
|
+
].every((relativePath) => fs.existsSync(path.join(projectDir, relativePath)));
|
|
172
|
+
const hasRuntimeDeps = typeof getExistingDependencyVersion(packageJson, "@wp-typia/block-runtime") === "string" && typeof getExistingDependencyVersion(packageJson, "@wp-typia/block-types") === "string";
|
|
173
|
+
return hasSyncSurface && hasHelperFiles && hasRuntimeDeps;
|
|
174
|
+
}
|
|
175
|
+
function buildRequiredDevDependencyMapEntries() {
|
|
176
|
+
return Object.entries(buildRequiredDevDependencyMap()).map(([name, version]) => `${name}@${version.replace(/^workspace:/u, "")}`);
|
|
177
|
+
}
|
|
178
|
+
function setDependencyVersion(packageJson, name, requiredValue) {
|
|
179
|
+
if (packageJson.devDependencies?.[name] !== undefined) {
|
|
180
|
+
packageJson.devDependencies[name] = requiredValue;
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
if (packageJson.dependencies?.[name] !== undefined) {
|
|
184
|
+
packageJson.dependencies[name] = requiredValue;
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
packageJson.devDependencies ??= {};
|
|
188
|
+
packageJson.devDependencies[name] = requiredValue;
|
|
189
|
+
}
|
|
190
|
+
function buildNextProjectPackageJson(options) {
|
|
191
|
+
const nextPackageJson = options.packageJson ? JSON.parse(JSON.stringify(options.packageJson)) : {
|
|
192
|
+
name: options.projectName,
|
|
193
|
+
private: true
|
|
194
|
+
};
|
|
195
|
+
nextPackageJson.devDependencies ??= {};
|
|
196
|
+
nextPackageJson.scripts ??= {};
|
|
197
|
+
for (const dependencyChange of options.packageChanges.addDevDependencies) {
|
|
198
|
+
setDependencyVersion(nextPackageJson, dependencyChange.name, dependencyChange.requiredValue);
|
|
199
|
+
}
|
|
200
|
+
if (options.packageChanges.packageManagerField) {
|
|
201
|
+
nextPackageJson.packageManager = options.packageChanges.packageManagerField.requiredValue;
|
|
202
|
+
} else if (!nextPackageJson.packageManager && options.packageManager !== "npm") {
|
|
203
|
+
nextPackageJson.packageManager = getPackageManager(options.packageManager).packageManagerField;
|
|
204
|
+
}
|
|
205
|
+
for (const scriptChange of options.packageChanges.scripts) {
|
|
206
|
+
nextPackageJson.scripts[scriptChange.name] = scriptChange.requiredValue;
|
|
207
|
+
}
|
|
208
|
+
return nextPackageJson;
|
|
209
|
+
}
|
|
210
|
+
function buildProjectPackageJsonSource(packageJson) {
|
|
211
|
+
return `${JSON.stringify(packageJson, null, 2)}
|
|
212
|
+
`;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// ../wp-typia-project-tools/src/runtime/cli-init-plan.ts
|
|
216
|
+
var import_typescript = __toESM(require_typescript(), 1);
|
|
217
|
+
import fs2 from "fs";
|
|
218
|
+
import path2 from "path";
|
|
219
|
+
import { analyzeSourceTypes } from "@wp-typia/block-runtime/metadata-parser";
|
|
220
|
+
|
|
221
|
+
// ../wp-typia-project-tools/src/runtime/cli-init-plan-presentation.ts
|
|
222
|
+
function buildInitPlanChangeSummary(changes, options) {
|
|
223
|
+
const lines = [];
|
|
224
|
+
for (const dependencyChange of changes.packageChanges.addDevDependencies) {
|
|
225
|
+
lines.push(`devDependency ${dependencyChange.action} ${dependencyChange.name} -> ${dependencyChange.requiredValue}`);
|
|
226
|
+
}
|
|
227
|
+
if (changes.packageChanges.packageManagerField) {
|
|
228
|
+
lines.push(`packageManager ${changes.packageChanges.packageManagerField.action} -> ${changes.packageChanges.packageManagerField.requiredValue}`);
|
|
229
|
+
}
|
|
230
|
+
for (const scriptChange of changes.packageChanges.scripts) {
|
|
231
|
+
lines.push(`script ${scriptChange.action} ${scriptChange.name} -> ${scriptChange.requiredValue}`);
|
|
232
|
+
}
|
|
233
|
+
for (const filePlan of changes.plannedFiles) {
|
|
234
|
+
lines.push(`file ${filePlan.action} ${filePlan.path} (${filePlan.purpose})`);
|
|
235
|
+
}
|
|
236
|
+
if (options.includeGeneratedArtifacts) {
|
|
237
|
+
for (const artifactPath of changes.generatedArtifacts) {
|
|
238
|
+
lines.push(`generated artifact ${artifactPath}`);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return lines;
|
|
242
|
+
}
|
|
243
|
+
function buildInitPlanNextSteps(options) {
|
|
244
|
+
const cliSpecifier = getWpTypiaCliSpecifier();
|
|
245
|
+
const syncTypesRun = formatRunScript(options.packageManager, "sync-types");
|
|
246
|
+
const syncRun = formatRunScript(options.packageManager, "sync");
|
|
247
|
+
const doctorRun = formatPackageExecCommand(options.packageManager, cliSpecifier, "doctor");
|
|
248
|
+
const migrationInitRun = formatPackageExecCommand(options.packageManager, cliSpecifier, "migrate init --current-migration-version v1");
|
|
249
|
+
const dependencyInstallCommand = formatAddDevDependenciesCommand(options.packageManager, buildRequiredDevDependencyMapEntries());
|
|
250
|
+
if (options.layoutKind === "unsupported") {
|
|
251
|
+
return [
|
|
252
|
+
"Align the project to one of the supported retrofit layouts listed below, then rerun `wp-typia init`.",
|
|
253
|
+
dependencyInstallCommand,
|
|
254
|
+
syncTypesRun,
|
|
255
|
+
doctorRun
|
|
256
|
+
];
|
|
257
|
+
}
|
|
258
|
+
if (options.commandMode === "apply") {
|
|
259
|
+
return [
|
|
260
|
+
...options.dependencyChangeCount > 0 ? [
|
|
261
|
+
"Install or reinstall project dependencies so the retrofit sync scripts and metadata generators are available locally.",
|
|
262
|
+
dependencyInstallCommand
|
|
263
|
+
] : [],
|
|
264
|
+
syncRun,
|
|
265
|
+
doctorRun,
|
|
266
|
+
`Optional migration bootstrap: ${migrationInitRun}`
|
|
267
|
+
];
|
|
268
|
+
}
|
|
269
|
+
return [
|
|
270
|
+
...options.hasPlannedChanges ? [
|
|
271
|
+
"Re-run `wp-typia init --apply` to write the planned package.json changes and helper files automatically.",
|
|
272
|
+
...options.dependencyChangeCount > 0 ? [dependencyInstallCommand] : []
|
|
273
|
+
] : [],
|
|
274
|
+
syncRun,
|
|
275
|
+
doctorRun,
|
|
276
|
+
`Optional migration bootstrap: ${migrationInitRun}`
|
|
277
|
+
];
|
|
278
|
+
}
|
|
279
|
+
function buildRetrofitPlanSummary(options) {
|
|
280
|
+
if (options.status === "already-initialized") {
|
|
281
|
+
return options.commandMode === "apply" ? "This project already exposes the minimum wp-typia retrofit surface. No files were changed." : "This project already exposes the minimum wp-typia retrofit surface.";
|
|
282
|
+
}
|
|
283
|
+
if (options.commandMode === "apply") {
|
|
284
|
+
return "Applied the minimum wp-typia retrofit surface so package.json and helper scripts are ready for the next install and sync run.";
|
|
285
|
+
}
|
|
286
|
+
return "This command previews the minimum wp-typia adoption layer for the current project without rewriting it into a full scaffold.";
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// ../wp-typia-project-tools/src/runtime/cli-init-types.ts
|
|
290
|
+
var SUPPORTED_RETROFIT_LAYOUT_NOTE = "Supported retrofit layouts currently mirror the migration bootstrap detector: `src/block.json` + `src/types.ts` + `src/save.tsx`, legacy root `block.json` + `src/types.ts` + `src/save.tsx`, or multi-block `src/blocks/*/block.json` workspaces.";
|
|
291
|
+
var RETROFIT_APPLY_PREVIEW_NOTE = "If you rerun with `wp-typia init --apply`, package.json and generated helper files are snapshotted and rolled back automatically if a write fails.";
|
|
292
|
+
var RETROFIT_ROLLBACK_NOTE = "Apply mode writes package.json and generated helper files with rollback-on-failure protection.";
|
|
293
|
+
|
|
294
|
+
// ../wp-typia-project-tools/src/runtime/cli-init-plan.ts
|
|
295
|
+
function normalizeRelativePath(value) {
|
|
296
|
+
return value.replace(/\\/gu, "/");
|
|
297
|
+
}
|
|
167
298
|
function buildGeneratedArtifactPaths(blockJsonFile, manifestFile) {
|
|
168
|
-
const manifestDir =
|
|
299
|
+
const manifestDir = path2.dirname(manifestFile);
|
|
169
300
|
const artifactPaths = [
|
|
170
301
|
blockJsonFile,
|
|
171
302
|
manifestFile,
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
303
|
+
path2.join(manifestDir, "typia.schema.json"),
|
|
304
|
+
path2.join(manifestDir, "typia-validator.php"),
|
|
305
|
+
path2.join(manifestDir, "typia.openapi.json")
|
|
175
306
|
];
|
|
176
307
|
return Array.from(new Set(artifactPaths.map((filePath) => normalizeRelativePath(filePath))));
|
|
177
308
|
}
|
|
@@ -192,8 +323,8 @@ function isObjectLikeSourceType(projectDir, typesFile, sourceTypeName) {
|
|
|
192
323
|
return analyzedTypes[sourceTypeName]?.kind === "object";
|
|
193
324
|
}
|
|
194
325
|
function inferRetrofitAttributeTypeName(projectDir, block) {
|
|
195
|
-
const typesPath =
|
|
196
|
-
const typesSource =
|
|
326
|
+
const typesPath = path2.join(projectDir, block.typesFile);
|
|
327
|
+
const typesSource = fs2.readFileSync(typesPath, "utf8");
|
|
197
328
|
const blockNameSegments = block.blockName.split("/");
|
|
198
329
|
const slug = blockNameSegments[blockNameSegments.length - 1] ?? block.key;
|
|
199
330
|
const candidateNames = collectNamedSourceTypeCandidates(typesSource);
|
|
@@ -227,58 +358,248 @@ function buildRetrofitBlockTarget(projectDir, block) {
|
|
|
227
358
|
typesFile: block.typesFile
|
|
228
359
|
};
|
|
229
360
|
}
|
|
230
|
-
function
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
361
|
+
function buildInitLayoutDetails(projectDir) {
|
|
362
|
+
try {
|
|
363
|
+
const discoveredLayout = discoverMigrationInitLayout(projectDir);
|
|
364
|
+
const discoveredBlocks = discoveredLayout.mode === "multi" ? discoveredLayout.blocks : [discoveredLayout.block];
|
|
365
|
+
let blockTargets;
|
|
366
|
+
try {
|
|
367
|
+
blockTargets = discoveredBlocks.map((block) => buildRetrofitBlockTarget(projectDir, block));
|
|
368
|
+
} catch (error) {
|
|
369
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
370
|
+
return {
|
|
371
|
+
blockNames: discoveredBlocks.map((block) => block.blockName),
|
|
372
|
+
blockTargets: [],
|
|
373
|
+
description: "Detected supported block files, but could not infer retrofit block-config metadata automatically yet.",
|
|
374
|
+
generatedArtifacts: [],
|
|
375
|
+
kind: "unsupported",
|
|
376
|
+
notes: [message, SUPPORTED_RETROFIT_LAYOUT_NOTE]
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
if (discoveredLayout.mode === "multi") {
|
|
380
|
+
return {
|
|
381
|
+
blockNames: discoveredBlocks.map((block) => block.blockName),
|
|
382
|
+
blockTargets,
|
|
383
|
+
description: `Detected a supported multi-block retrofit candidate (${discoveredBlocks.length} targets).`,
|
|
384
|
+
generatedArtifacts: discoveredBlocks.flatMap((block) => buildGeneratedArtifactPaths(block.blockJsonFile, block.manifestFile)),
|
|
385
|
+
kind: "multi-block",
|
|
386
|
+
notes: [
|
|
387
|
+
"Migration bootstrap can stay optional. Add it later with `wp-typia migrate init --current-migration-version v1` once the typed sync surface is in place."
|
|
388
|
+
]
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
return {
|
|
392
|
+
blockNames: [discoveredLayout.block.blockName],
|
|
393
|
+
blockTargets,
|
|
394
|
+
description: "Detected a supported single-block retrofit candidate.",
|
|
395
|
+
generatedArtifacts: buildGeneratedArtifactPaths(discoveredLayout.block.blockJsonFile, discoveredLayout.block.manifestFile),
|
|
396
|
+
kind: "single-block",
|
|
397
|
+
notes: discoveredLayout.block.blockJsonFile === "block.json" ? [
|
|
398
|
+
"Legacy root `block.json` layouts are still supported for retrofit planning, but newer scaffolds keep generated block metadata under `src/`."
|
|
399
|
+
] : []
|
|
400
|
+
};
|
|
401
|
+
} catch (error) {
|
|
402
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
403
|
+
return {
|
|
404
|
+
blockNames: [],
|
|
405
|
+
blockTargets: [],
|
|
406
|
+
description: "No supported retrofit layout was auto-detected yet.",
|
|
407
|
+
generatedArtifacts: [],
|
|
408
|
+
kind: "unsupported",
|
|
409
|
+
notes: [message, SUPPORTED_RETROFIT_LAYOUT_NOTE]
|
|
410
|
+
};
|
|
411
|
+
}
|
|
256
412
|
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
413
|
+
function buildPlannedFiles(projectDir, layoutKind) {
|
|
414
|
+
if (layoutKind === "unsupported") {
|
|
415
|
+
return [];
|
|
416
|
+
}
|
|
417
|
+
return [
|
|
418
|
+
{
|
|
419
|
+
action: fs2.existsSync(path2.join(projectDir, "scripts", "block-config.ts")) ? "update" : "add",
|
|
420
|
+
path: "scripts/block-config.ts",
|
|
421
|
+
purpose: "Declare the current retrofit block targets so sync-types can regenerate metadata from the existing TypeScript source of truth."
|
|
422
|
+
},
|
|
423
|
+
{
|
|
424
|
+
action: fs2.existsSync(path2.join(projectDir, "scripts", "sync-types-to-block-json.ts")) ? "update" : "add",
|
|
425
|
+
path: "scripts/sync-types-to-block-json.ts",
|
|
426
|
+
purpose: "Generate block.json and Typia metadata artifacts from the current TypeScript source of truth."
|
|
427
|
+
},
|
|
428
|
+
{
|
|
429
|
+
action: fs2.existsSync(path2.join(projectDir, "scripts", "sync-project.ts")) ? "update" : "add",
|
|
430
|
+
path: "scripts/sync-project.ts",
|
|
431
|
+
purpose: "Provide one shared sync entrypoint that can grow into sync-rest or workspace-aware refresh steps later."
|
|
432
|
+
}
|
|
433
|
+
];
|
|
264
434
|
}
|
|
265
|
-
function
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
435
|
+
function createRetrofitPlan(options) {
|
|
436
|
+
const includeGeneratedArtifacts = options.commandMode === "preview-only";
|
|
437
|
+
const plannedChanges = buildInitPlanChangeSummary({
|
|
438
|
+
generatedArtifacts: options.generatedArtifacts,
|
|
439
|
+
packageChanges: options.packageChanges,
|
|
440
|
+
plannedFiles: options.plannedFiles
|
|
441
|
+
}, {
|
|
442
|
+
includeGeneratedArtifacts
|
|
443
|
+
});
|
|
444
|
+
return {
|
|
445
|
+
blockTargets: options.blockTargets,
|
|
446
|
+
commandMode: options.commandMode,
|
|
447
|
+
detectedLayout: options.detectedLayout,
|
|
448
|
+
generatedArtifacts: options.generatedArtifacts,
|
|
449
|
+
nextSteps: options.nextSteps ?? buildInitPlanNextSteps({
|
|
450
|
+
commandMode: options.commandMode,
|
|
451
|
+
dependencyChangeCount: options.packageChanges.addDevDependencies.length,
|
|
452
|
+
hasPlannedChanges: plannedChanges.length > 0,
|
|
453
|
+
layoutKind: options.detectedLayout.kind,
|
|
454
|
+
packageManager: options.packageManager
|
|
455
|
+
}),
|
|
456
|
+
notes: options.notes,
|
|
457
|
+
packageChanges: options.packageChanges,
|
|
458
|
+
plannedFiles: options.plannedFiles,
|
|
459
|
+
packageManager: options.packageManager,
|
|
460
|
+
projectDir: options.projectDir,
|
|
461
|
+
projectName: options.projectName,
|
|
462
|
+
status: options.status,
|
|
463
|
+
summary: buildRetrofitPlanSummary({
|
|
464
|
+
commandMode: options.commandMode,
|
|
465
|
+
status: options.status
|
|
466
|
+
})
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
function getInitPlan(projectDir, options = {}) {
|
|
470
|
+
const resolvedProjectDir = path2.resolve(projectDir);
|
|
471
|
+
const packageJson = readProjectPackageJson(resolvedProjectDir);
|
|
472
|
+
const packageManager = resolveInitPackageManager(resolvedProjectDir, packageJson, options.packageManager);
|
|
473
|
+
const workspace = tryResolveWorkspaceProject(resolvedProjectDir);
|
|
474
|
+
if (workspace) {
|
|
475
|
+
const workspacePackageJson = readProjectPackageJson(workspace.projectDir);
|
|
476
|
+
const workspacePackageManager = resolveInitPackageManager(workspace.projectDir, workspacePackageJson, options.packageManager);
|
|
477
|
+
const cliSpecifier = getWpTypiaCliSpecifier();
|
|
478
|
+
return createRetrofitPlan({
|
|
479
|
+
blockTargets: [],
|
|
480
|
+
commandMode: "preview-only",
|
|
481
|
+
detectedLayout: {
|
|
482
|
+
blockNames: [],
|
|
483
|
+
description: "Already an official wp-typia workspace.",
|
|
484
|
+
kind: "official-workspace"
|
|
485
|
+
},
|
|
486
|
+
generatedArtifacts: [],
|
|
487
|
+
nextSteps: [
|
|
488
|
+
"Use `wp-typia add <kind> <name>` to extend the official workspace instead of rerunning init.",
|
|
489
|
+
formatRunScript(workspacePackageManager, "sync"),
|
|
490
|
+
formatPackageExecCommand(workspacePackageManager, cliSpecifier, "doctor")
|
|
491
|
+
],
|
|
492
|
+
notes: [
|
|
493
|
+
"The official workspace template already owns inventory, doctor, and add-command workflows."
|
|
494
|
+
],
|
|
495
|
+
packageChanges: {
|
|
496
|
+
addDevDependencies: [],
|
|
497
|
+
scripts: []
|
|
498
|
+
},
|
|
499
|
+
packageManager: workspacePackageManager,
|
|
500
|
+
plannedFiles: [],
|
|
501
|
+
projectDir: workspace.projectDir,
|
|
502
|
+
projectName: workspace.packageName,
|
|
503
|
+
status: "already-initialized"
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
const projectName = typeof packageJson?.name === "string" && packageJson.name.length > 0 ? packageJson.name : path2.basename(resolvedProjectDir);
|
|
507
|
+
const layout = buildInitLayoutDetails(resolvedProjectDir);
|
|
508
|
+
const dependencyChanges = buildDependencyChanges(packageJson);
|
|
509
|
+
const scriptChanges = buildScriptChanges(packageJson, packageManager);
|
|
510
|
+
const packageManagerFieldChange = buildPackageManagerFieldChange(packageJson, packageManager, {
|
|
511
|
+
persistExplicitOverride: typeof options.packageManager === "string"
|
|
512
|
+
});
|
|
513
|
+
const rawPlannedFiles = layout.kind === "generated-project" || layout.kind === "official-workspace" ? [] : buildPlannedFiles(resolvedProjectDir, layout.kind);
|
|
514
|
+
const hasExistingSurface = hasExistingWpTypiaProjectSurface(resolvedProjectDir, packageJson);
|
|
515
|
+
const status = hasExistingSurface && dependencyChanges.length === 0 && scriptChanges.length === 0 && packageManagerFieldChange === undefined ? "already-initialized" : "preview";
|
|
516
|
+
const plannedFiles = status === "already-initialized" ? [] : rawPlannedFiles;
|
|
517
|
+
const detectedLayout = status === "already-initialized" && hasExistingSurface ? {
|
|
518
|
+
blockNames: layout.blockNames,
|
|
519
|
+
description: layout.kind === "unsupported" ? "Already exposes the minimum wp-typia sync surface." : `Already exposes the minimum wp-typia sync surface for ${layout.kind === "multi-block" ? "a multi-block project" : "a single-block project"}.`,
|
|
520
|
+
kind: "generated-project"
|
|
521
|
+
} : {
|
|
522
|
+
blockNames: layout.blockNames,
|
|
523
|
+
description: layout.description,
|
|
524
|
+
kind: layout.kind
|
|
525
|
+
};
|
|
526
|
+
return createRetrofitPlan({
|
|
527
|
+
blockTargets: layout.blockTargets,
|
|
528
|
+
commandMode: "preview-only",
|
|
529
|
+
detectedLayout,
|
|
530
|
+
generatedArtifacts: status === "already-initialized" && detectedLayout.kind === "generated-project" ? [] : layout.generatedArtifacts,
|
|
531
|
+
notes: Array.from(new Set([
|
|
532
|
+
"Preview only: `wp-typia init` does not write files yet.",
|
|
533
|
+
RETROFIT_APPLY_PREVIEW_NOTE,
|
|
534
|
+
...layout.notes
|
|
535
|
+
])),
|
|
536
|
+
packageChanges: {
|
|
537
|
+
addDevDependencies: dependencyChanges,
|
|
538
|
+
...packageManagerFieldChange ? { packageManagerField: packageManagerFieldChange } : {},
|
|
539
|
+
scripts: scriptChanges
|
|
540
|
+
},
|
|
541
|
+
packageManager,
|
|
542
|
+
plannedFiles,
|
|
543
|
+
projectDir: resolvedProjectDir,
|
|
544
|
+
projectName,
|
|
545
|
+
status
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
// ../wp-typia-project-tools/src/runtime/cli-init-templates.ts
|
|
550
|
+
import path3 from "path";
|
|
551
|
+
function buildRetrofitBlockConfigEntry(target) {
|
|
552
|
+
return [
|
|
553
|
+
"\t{",
|
|
554
|
+
` slug: ${quoteTsString(target.slug)},`,
|
|
555
|
+
` attributeTypeName: ${quoteTsString(target.attributeTypeName)},`,
|
|
556
|
+
` blockJsonFile: ${quoteTsString(target.blockJsonFile)},`,
|
|
557
|
+
` manifestFile: ${quoteTsString(target.manifestFile)},`,
|
|
558
|
+
` typesFile: ${quoteTsString(target.typesFile)},`,
|
|
559
|
+
"\t},"
|
|
560
|
+
].join(`
|
|
561
|
+
`);
|
|
562
|
+
}
|
|
563
|
+
function buildRetrofitBlockConfigSource(targets) {
|
|
564
|
+
const blockEntries = targets.map(buildRetrofitBlockConfigEntry).join(`
|
|
565
|
+
`);
|
|
566
|
+
const baseSource = `export interface WorkspaceBlockConfig {
|
|
567
|
+
attributeTypeName: string;
|
|
568
|
+
apiTypesFile?: string;
|
|
569
|
+
blockJsonFile?: string;
|
|
570
|
+
manifestFile?: string;
|
|
571
|
+
openApiFile?: string;
|
|
572
|
+
restManifest?: ReturnType<
|
|
573
|
+
typeof import( '@wp-typia/block-runtime/metadata-core' ).defineEndpointManifest
|
|
574
|
+
>;
|
|
575
|
+
slug: string;
|
|
576
|
+
typesFile: string;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
export const BLOCKS: WorkspaceBlockConfig[] = [
|
|
580
|
+
${blockEntries}
|
|
581
|
+
];
|
|
582
|
+
`;
|
|
583
|
+
return `${updateWorkspaceInventorySource(baseSource)}
|
|
584
|
+
`;
|
|
585
|
+
}
|
|
586
|
+
function buildRetrofitSyncTypesScriptSource() {
|
|
587
|
+
return `/* eslint-disable no-console */
|
|
588
|
+
import path from 'node:path';
|
|
589
|
+
|
|
590
|
+
import { syncBlockMetadata } from '@wp-typia/block-runtime/metadata-core';
|
|
591
|
+
|
|
592
|
+
import { BLOCKS } from './block-config';
|
|
593
|
+
|
|
594
|
+
function parseCliOptions( argv: string[] ) {
|
|
595
|
+
const options = {
|
|
596
|
+
check: false,
|
|
597
|
+
};
|
|
598
|
+
|
|
599
|
+
for ( const argument of argv ) {
|
|
600
|
+
if ( argument === '--check' ) {
|
|
601
|
+
options.check = true;
|
|
602
|
+
continue;
|
|
282
603
|
}
|
|
283
604
|
|
|
284
605
|
throw new Error( \`Unknown sync-types flag: \${ argument }\` );
|
|
@@ -442,241 +763,18 @@ main().catch( ( error ) => {
|
|
|
442
763
|
} );
|
|
443
764
|
`;
|
|
444
765
|
}
|
|
445
|
-
function buildLayoutDetails(projectDir) {
|
|
446
|
-
try {
|
|
447
|
-
const discoveredLayout = discoverMigrationInitLayout(projectDir);
|
|
448
|
-
const discoveredBlocks = discoveredLayout.mode === "multi" ? discoveredLayout.blocks : [discoveredLayout.block];
|
|
449
|
-
let blockTargets;
|
|
450
|
-
try {
|
|
451
|
-
blockTargets = discoveredBlocks.map((block) => buildRetrofitBlockTarget(projectDir, block));
|
|
452
|
-
} catch (error) {
|
|
453
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
454
|
-
return {
|
|
455
|
-
blockNames: discoveredBlocks.map((block) => block.blockName),
|
|
456
|
-
blockTargets: [],
|
|
457
|
-
description: "Detected supported block files, but could not infer retrofit block-config metadata automatically yet.",
|
|
458
|
-
generatedArtifacts: [],
|
|
459
|
-
kind: "unsupported",
|
|
460
|
-
notes: [message, SUPPORTED_RETROFIT_LAYOUT_NOTE]
|
|
461
|
-
};
|
|
462
|
-
}
|
|
463
|
-
if (discoveredLayout.mode === "multi") {
|
|
464
|
-
return {
|
|
465
|
-
blockNames: discoveredBlocks.map((block) => block.blockName),
|
|
466
|
-
blockTargets,
|
|
467
|
-
description: `Detected a supported multi-block retrofit candidate (${discoveredBlocks.length} targets).`,
|
|
468
|
-
generatedArtifacts: discoveredBlocks.flatMap((block) => buildGeneratedArtifactPaths(block.blockJsonFile, block.manifestFile)),
|
|
469
|
-
kind: "multi-block",
|
|
470
|
-
notes: [
|
|
471
|
-
"Migration bootstrap can stay optional. Add it later with `wp-typia migrate init --current-migration-version v1` once the typed sync surface is in place."
|
|
472
|
-
]
|
|
473
|
-
};
|
|
474
|
-
}
|
|
475
|
-
return {
|
|
476
|
-
blockNames: [discoveredLayout.block.blockName],
|
|
477
|
-
blockTargets,
|
|
478
|
-
description: "Detected a supported single-block retrofit candidate.",
|
|
479
|
-
generatedArtifacts: buildGeneratedArtifactPaths(discoveredLayout.block.blockJsonFile, discoveredLayout.block.manifestFile),
|
|
480
|
-
kind: "single-block",
|
|
481
|
-
notes: discoveredLayout.block.blockJsonFile === "block.json" ? [
|
|
482
|
-
"Legacy root `block.json` layouts are still supported for retrofit planning, but newer scaffolds keep generated block metadata under `src/`."
|
|
483
|
-
] : []
|
|
484
|
-
};
|
|
485
|
-
} catch (error) {
|
|
486
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
487
|
-
return {
|
|
488
|
-
blockNames: [],
|
|
489
|
-
blockTargets: [],
|
|
490
|
-
description: "No supported retrofit layout was auto-detected yet.",
|
|
491
|
-
generatedArtifacts: [],
|
|
492
|
-
kind: "unsupported",
|
|
493
|
-
notes: [message, SUPPORTED_RETROFIT_LAYOUT_NOTE]
|
|
494
|
-
};
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
function hasExistingWpTypiaProjectSurface(projectDir, packageJson) {
|
|
498
|
-
const scripts = packageJson?.scripts ?? {};
|
|
499
|
-
const hasSyncSurface = typeof scripts.sync === "string" || typeof scripts["sync-types"] === "string";
|
|
500
|
-
const hasHelperFiles = [
|
|
501
|
-
path.join("scripts", "block-config.ts"),
|
|
502
|
-
path.join("scripts", "sync-project.ts"),
|
|
503
|
-
path.join("scripts", "sync-types-to-block-json.ts")
|
|
504
|
-
].every((relativePath) => fs.existsSync(path.join(projectDir, relativePath)));
|
|
505
|
-
const hasRuntimeDeps = typeof getExistingDependencyVersion(packageJson, "@wp-typia/block-runtime") === "string" && typeof getExistingDependencyVersion(packageJson, "@wp-typia/block-types") === "string";
|
|
506
|
-
return hasSyncSurface && hasHelperFiles && hasRuntimeDeps;
|
|
507
|
-
}
|
|
508
|
-
function buildPlannedFiles(projectDir, layoutKind) {
|
|
509
|
-
if (layoutKind === "unsupported") {
|
|
510
|
-
return [];
|
|
511
|
-
}
|
|
512
|
-
return [
|
|
513
|
-
{
|
|
514
|
-
action: fs.existsSync(path.join(projectDir, "scripts", "block-config.ts")) ? "update" : "add",
|
|
515
|
-
path: "scripts/block-config.ts",
|
|
516
|
-
purpose: "Declare the current retrofit block targets so sync-types can regenerate metadata from the existing TypeScript source of truth."
|
|
517
|
-
},
|
|
518
|
-
{
|
|
519
|
-
action: fs.existsSync(path.join(projectDir, "scripts", "sync-types-to-block-json.ts")) ? "update" : "add",
|
|
520
|
-
path: "scripts/sync-types-to-block-json.ts",
|
|
521
|
-
purpose: "Generate block.json and Typia metadata artifacts from the current TypeScript source of truth."
|
|
522
|
-
},
|
|
523
|
-
{
|
|
524
|
-
action: fs.existsSync(path.join(projectDir, "scripts", "sync-project.ts")) ? "update" : "add",
|
|
525
|
-
path: "scripts/sync-project.ts",
|
|
526
|
-
purpose: "Provide one shared sync entrypoint that can grow into sync-rest or workspace-aware refresh steps later."
|
|
527
|
-
}
|
|
528
|
-
];
|
|
529
|
-
}
|
|
530
|
-
function buildChangeSummary(changes, options) {
|
|
531
|
-
const lines = [];
|
|
532
|
-
for (const dependencyChange of changes.packageChanges.addDevDependencies) {
|
|
533
|
-
lines.push(`devDependency ${dependencyChange.action} ${dependencyChange.name} -> ${dependencyChange.requiredValue}`);
|
|
534
|
-
}
|
|
535
|
-
if (changes.packageChanges.packageManagerField) {
|
|
536
|
-
lines.push(`packageManager ${changes.packageChanges.packageManagerField.action} -> ${changes.packageChanges.packageManagerField.requiredValue}`);
|
|
537
|
-
}
|
|
538
|
-
for (const scriptChange of changes.packageChanges.scripts) {
|
|
539
|
-
lines.push(`script ${scriptChange.action} ${scriptChange.name} -> ${scriptChange.requiredValue}`);
|
|
540
|
-
}
|
|
541
|
-
for (const filePlan of changes.plannedFiles) {
|
|
542
|
-
lines.push(`file ${filePlan.action} ${filePlan.path} (${filePlan.purpose})`);
|
|
543
|
-
}
|
|
544
|
-
if (options.includeGeneratedArtifacts) {
|
|
545
|
-
for (const artifactPath of changes.generatedArtifacts) {
|
|
546
|
-
lines.push(`generated artifact ${artifactPath}`);
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
return lines;
|
|
550
|
-
}
|
|
551
|
-
function buildNextSteps(options) {
|
|
552
|
-
const cliSpecifier = getWpTypiaCliSpecifier();
|
|
553
|
-
const syncTypesRun = formatRunScript(options.packageManager, "sync-types");
|
|
554
|
-
const syncRun = formatRunScript(options.packageManager, "sync");
|
|
555
|
-
const doctorRun = formatPackageExecCommand(options.packageManager, cliSpecifier, "doctor");
|
|
556
|
-
const migrationInitRun = formatPackageExecCommand(options.packageManager, cliSpecifier, "migrate init --current-migration-version v1");
|
|
557
|
-
const dependencyInstallCommand = formatAddDevDependenciesCommand(options.packageManager, buildRequiredDevDependencyMapEntries());
|
|
558
|
-
if (options.layoutKind === "unsupported") {
|
|
559
|
-
return [
|
|
560
|
-
"Align the project to one of the supported retrofit layouts listed below, then rerun `wp-typia init`.",
|
|
561
|
-
dependencyInstallCommand,
|
|
562
|
-
syncTypesRun,
|
|
563
|
-
doctorRun
|
|
564
|
-
];
|
|
565
|
-
}
|
|
566
|
-
if (options.commandMode === "apply") {
|
|
567
|
-
return [
|
|
568
|
-
...options.dependencyChangeCount > 0 ? [
|
|
569
|
-
"Install or reinstall project dependencies so the retrofit sync scripts and metadata generators are available locally.",
|
|
570
|
-
dependencyInstallCommand
|
|
571
|
-
] : [],
|
|
572
|
-
syncRun,
|
|
573
|
-
doctorRun,
|
|
574
|
-
`Optional migration bootstrap: ${migrationInitRun}`
|
|
575
|
-
];
|
|
576
|
-
}
|
|
577
|
-
const steps = [
|
|
578
|
-
...options.hasPlannedChanges ? [
|
|
579
|
-
"Re-run `wp-typia init --apply` to write the planned package.json changes and helper files automatically.",
|
|
580
|
-
...options.dependencyChangeCount > 0 ? [dependencyInstallCommand] : []
|
|
581
|
-
] : [],
|
|
582
|
-
syncRun,
|
|
583
|
-
doctorRun,
|
|
584
|
-
`Optional migration bootstrap: ${migrationInitRun}`
|
|
585
|
-
];
|
|
586
|
-
return steps;
|
|
587
|
-
}
|
|
588
|
-
function buildRequiredDevDependencyMapEntries() {
|
|
589
|
-
return Object.entries(buildRequiredDevDependencyMap()).map(([name, version]) => `${name}@${version.replace(/^workspace:/u, "")}`);
|
|
590
|
-
}
|
|
591
|
-
function buildRetrofitPlanSummary(options) {
|
|
592
|
-
if (options.status === "already-initialized") {
|
|
593
|
-
return options.commandMode === "apply" ? "This project already exposes the minimum wp-typia retrofit surface. No files were changed." : "This project already exposes the minimum wp-typia retrofit surface.";
|
|
594
|
-
}
|
|
595
|
-
if (options.commandMode === "apply") {
|
|
596
|
-
return "Applied the minimum wp-typia retrofit surface so package.json and helper scripts are ready for the next install and sync run.";
|
|
597
|
-
}
|
|
598
|
-
return "This command previews the minimum wp-typia adoption layer for the current project without rewriting it into a full scaffold.";
|
|
599
|
-
}
|
|
600
|
-
function createRetrofitPlan(options) {
|
|
601
|
-
const includeGeneratedArtifacts = options.commandMode === "preview-only";
|
|
602
|
-
const plannedChanges = buildChangeSummary({
|
|
603
|
-
generatedArtifacts: options.generatedArtifacts,
|
|
604
|
-
packageChanges: options.packageChanges,
|
|
605
|
-
plannedFiles: options.plannedFiles
|
|
606
|
-
}, {
|
|
607
|
-
includeGeneratedArtifacts
|
|
608
|
-
});
|
|
609
|
-
return {
|
|
610
|
-
blockTargets: options.blockTargets,
|
|
611
|
-
commandMode: options.commandMode,
|
|
612
|
-
detectedLayout: options.detectedLayout,
|
|
613
|
-
generatedArtifacts: options.generatedArtifacts,
|
|
614
|
-
nextSteps: options.nextSteps ?? buildNextSteps({
|
|
615
|
-
commandMode: options.commandMode,
|
|
616
|
-
dependencyChangeCount: options.packageChanges.addDevDependencies.length,
|
|
617
|
-
hasPlannedChanges: plannedChanges.length > 0,
|
|
618
|
-
layoutKind: options.detectedLayout.kind,
|
|
619
|
-
packageManager: options.packageManager
|
|
620
|
-
}),
|
|
621
|
-
notes: options.notes,
|
|
622
|
-
packageChanges: options.packageChanges,
|
|
623
|
-
plannedFiles: options.plannedFiles,
|
|
624
|
-
packageManager: options.packageManager,
|
|
625
|
-
projectDir: options.projectDir,
|
|
626
|
-
projectName: options.projectName,
|
|
627
|
-
status: options.status,
|
|
628
|
-
summary: buildRetrofitPlanSummary({
|
|
629
|
-
commandMode: options.commandMode,
|
|
630
|
-
status: options.status
|
|
631
|
-
})
|
|
632
|
-
};
|
|
633
|
-
}
|
|
634
|
-
function setDependencyVersion(packageJson, name, requiredValue) {
|
|
635
|
-
if (packageJson.devDependencies?.[name] !== undefined) {
|
|
636
|
-
packageJson.devDependencies[name] = requiredValue;
|
|
637
|
-
return;
|
|
638
|
-
}
|
|
639
|
-
if (packageJson.dependencies?.[name] !== undefined) {
|
|
640
|
-
packageJson.dependencies[name] = requiredValue;
|
|
641
|
-
return;
|
|
642
|
-
}
|
|
643
|
-
packageJson.devDependencies ??= {};
|
|
644
|
-
packageJson.devDependencies[name] = requiredValue;
|
|
645
|
-
}
|
|
646
|
-
function buildNextProjectPackageJson(options) {
|
|
647
|
-
const nextPackageJson = options.packageJson ? JSON.parse(JSON.stringify(options.packageJson)) : {
|
|
648
|
-
name: options.projectName,
|
|
649
|
-
private: true
|
|
650
|
-
};
|
|
651
|
-
nextPackageJson.devDependencies ??= {};
|
|
652
|
-
nextPackageJson.scripts ??= {};
|
|
653
|
-
for (const dependencyChange of options.packageChanges.addDevDependencies) {
|
|
654
|
-
setDependencyVersion(nextPackageJson, dependencyChange.name, dependencyChange.requiredValue);
|
|
655
|
-
}
|
|
656
|
-
if (options.packageChanges.packageManagerField) {
|
|
657
|
-
nextPackageJson.packageManager = options.packageChanges.packageManagerField.requiredValue;
|
|
658
|
-
} else if (!nextPackageJson.packageManager && options.packageManager !== "npm") {
|
|
659
|
-
nextPackageJson.packageManager = getPackageManager(options.packageManager).packageManagerField;
|
|
660
|
-
}
|
|
661
|
-
for (const scriptChange of options.packageChanges.scripts) {
|
|
662
|
-
nextPackageJson.scripts[scriptChange.name] = scriptChange.requiredValue;
|
|
663
|
-
}
|
|
664
|
-
return nextPackageJson;
|
|
665
|
-
}
|
|
666
|
-
function buildProjectPackageJsonSource(packageJson) {
|
|
667
|
-
return `${JSON.stringify(packageJson, null, 2)}
|
|
668
|
-
`;
|
|
669
|
-
}
|
|
670
766
|
function buildRetrofitHelperFiles(blockTargets) {
|
|
671
767
|
return {
|
|
672
|
-
[
|
|
673
|
-
[
|
|
674
|
-
[
|
|
768
|
+
[path3.join("scripts", "block-config.ts")]: buildRetrofitBlockConfigSource(blockTargets),
|
|
769
|
+
[path3.join("scripts", "sync-project.ts")]: buildRetrofitSyncProjectScriptSource(),
|
|
770
|
+
[path3.join("scripts", "sync-types-to-block-json.ts")]: buildRetrofitSyncTypesScriptSource()
|
|
675
771
|
};
|
|
676
772
|
}
|
|
773
|
+
|
|
774
|
+
// ../wp-typia-project-tools/src/runtime/cli-init-apply.ts
|
|
677
775
|
async function createRetrofitMutationSnapshot(projectDir, filePaths) {
|
|
678
|
-
const scriptsDir =
|
|
679
|
-
const scriptsDirExisted =
|
|
776
|
+
const scriptsDir = path4.join(projectDir, "scripts");
|
|
777
|
+
const scriptsDirExisted = fs3.existsSync(scriptsDir);
|
|
680
778
|
const fileSources = await snapshotWorkspaceFiles(filePaths);
|
|
681
779
|
const targetPaths = fileSources.filter((entry) => entry.source === null).map((entry) => entry.filePath);
|
|
682
780
|
if (!scriptsDirExisted) {
|
|
@@ -690,95 +788,22 @@ async function createRetrofitMutationSnapshot(projectDir, filePaths) {
|
|
|
690
788
|
}
|
|
691
789
|
async function writeRetrofitFiles(options) {
|
|
692
790
|
const helperFiles = buildRetrofitHelperFiles(options.blockTargets);
|
|
693
|
-
const scriptsDir =
|
|
791
|
+
const scriptsDir = path4.join(options.projectDir, "scripts");
|
|
694
792
|
await fsp.mkdir(scriptsDir, { recursive: true });
|
|
695
|
-
await fsp.writeFile(
|
|
793
|
+
await fsp.writeFile(path4.join(options.projectDir, "package.json"), buildProjectPackageJsonSource(options.packageJson), "utf8");
|
|
696
794
|
for (const [relativePath, source] of Object.entries(helperFiles)) {
|
|
697
|
-
await fsp.writeFile(
|
|
795
|
+
await fsp.writeFile(path4.join(options.projectDir, relativePath), source, "utf8");
|
|
698
796
|
}
|
|
699
797
|
}
|
|
700
798
|
function buildApplyFailureError(error) {
|
|
701
799
|
const message = error instanceof Error ? error.message : String(error);
|
|
702
800
|
return createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.INVALID_ARGUMENT, `Unable to apply the retrofit init plan safely. The command restored the previous package.json/helper-file snapshot. ${message}`, error instanceof Error ? { cause: error } : undefined);
|
|
703
801
|
}
|
|
704
|
-
function
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
if (workspace) {
|
|
710
|
-
const workspacePackageJson = readProjectPackageJson(workspace.projectDir);
|
|
711
|
-
const workspacePackageManager = resolveInitPackageManager(workspace.projectDir, workspacePackageJson, options.packageManager);
|
|
712
|
-
const cliSpecifier = getWpTypiaCliSpecifier();
|
|
713
|
-
return createRetrofitPlan({
|
|
714
|
-
blockTargets: [],
|
|
715
|
-
commandMode: "preview-only",
|
|
716
|
-
detectedLayout: {
|
|
717
|
-
blockNames: [],
|
|
718
|
-
description: "Already an official wp-typia workspace.",
|
|
719
|
-
kind: "official-workspace"
|
|
720
|
-
},
|
|
721
|
-
generatedArtifacts: [],
|
|
722
|
-
nextSteps: [
|
|
723
|
-
"Use `wp-typia add <kind> <name>` to extend the official workspace instead of rerunning init.",
|
|
724
|
-
formatRunScript(workspacePackageManager, "sync"),
|
|
725
|
-
formatPackageExecCommand(workspacePackageManager, cliSpecifier, "doctor")
|
|
726
|
-
],
|
|
727
|
-
notes: [
|
|
728
|
-
"The official workspace template already owns inventory, doctor, and add-command workflows."
|
|
729
|
-
],
|
|
730
|
-
packageChanges: {
|
|
731
|
-
addDevDependencies: [],
|
|
732
|
-
scripts: []
|
|
733
|
-
},
|
|
734
|
-
packageManager: workspacePackageManager,
|
|
735
|
-
plannedFiles: [],
|
|
736
|
-
projectDir: workspace.projectDir,
|
|
737
|
-
projectName: workspace.packageName,
|
|
738
|
-
status: "already-initialized"
|
|
739
|
-
});
|
|
740
|
-
}
|
|
741
|
-
const projectName = typeof packageJson?.name === "string" && packageJson.name.length > 0 ? packageJson.name : path.basename(resolvedProjectDir);
|
|
742
|
-
const layout = buildLayoutDetails(resolvedProjectDir);
|
|
743
|
-
const dependencyChanges = buildDependencyChanges(packageJson);
|
|
744
|
-
const scriptChanges = buildScriptChanges(packageJson, packageManager);
|
|
745
|
-
const packageManagerFieldChange = buildPackageManagerFieldChange(packageJson, packageManager, {
|
|
746
|
-
persistExplicitOverride: typeof options.packageManager === "string"
|
|
747
|
-
});
|
|
748
|
-
const rawPlannedFiles = layout.kind === "generated-project" || layout.kind === "official-workspace" ? [] : buildPlannedFiles(resolvedProjectDir, layout.kind);
|
|
749
|
-
const hasExistingSurface = hasExistingWpTypiaProjectSurface(resolvedProjectDir, packageJson);
|
|
750
|
-
const status = hasExistingSurface && dependencyChanges.length === 0 && scriptChanges.length === 0 && packageManagerFieldChange === undefined ? "already-initialized" : "preview";
|
|
751
|
-
const plannedFiles = status === "already-initialized" ? [] : rawPlannedFiles;
|
|
752
|
-
const detectedLayout = status === "already-initialized" && hasExistingSurface ? {
|
|
753
|
-
blockNames: layout.blockNames,
|
|
754
|
-
description: layout.kind === "unsupported" ? "Already exposes the minimum wp-typia sync surface." : `Already exposes the minimum wp-typia sync surface for ${layout.kind === "multi-block" ? "a multi-block project" : "a single-block project"}.`,
|
|
755
|
-
kind: "generated-project"
|
|
756
|
-
} : {
|
|
757
|
-
blockNames: layout.blockNames,
|
|
758
|
-
description: layout.description,
|
|
759
|
-
kind: layout.kind
|
|
760
|
-
};
|
|
761
|
-
return createRetrofitPlan({
|
|
762
|
-
blockTargets: layout.blockTargets,
|
|
763
|
-
commandMode: "preview-only",
|
|
764
|
-
detectedLayout,
|
|
765
|
-
generatedArtifacts: status === "already-initialized" && detectedLayout.kind === "generated-project" ? [] : layout.generatedArtifacts,
|
|
766
|
-
notes: Array.from(new Set([
|
|
767
|
-
"Preview only: `wp-typia init` does not write files yet.",
|
|
768
|
-
RETROFIT_APPLY_PREVIEW_NOTE,
|
|
769
|
-
...layout.notes
|
|
770
|
-
])),
|
|
771
|
-
packageChanges: {
|
|
772
|
-
addDevDependencies: dependencyChanges,
|
|
773
|
-
...packageManagerFieldChange ? { packageManagerField: packageManagerFieldChange } : {},
|
|
774
|
-
scripts: scriptChanges
|
|
775
|
-
},
|
|
776
|
-
packageManager,
|
|
777
|
-
plannedFiles,
|
|
778
|
-
projectDir: resolvedProjectDir,
|
|
779
|
-
projectName,
|
|
780
|
-
status
|
|
781
|
-
});
|
|
802
|
+
function toApplyNotes(previewNotes) {
|
|
803
|
+
return Array.from(new Set([
|
|
804
|
+
...previewNotes.filter((note) => note !== "Preview only: `wp-typia init` does not write files yet." && note !== RETROFIT_APPLY_PREVIEW_NOTE),
|
|
805
|
+
RETROFIT_ROLLBACK_NOTE
|
|
806
|
+
]));
|
|
782
807
|
}
|
|
783
808
|
async function applyInitPlan(projectDir, options = {}) {
|
|
784
809
|
const previewPlan = getInitPlan(projectDir, options);
|
|
@@ -789,10 +814,7 @@ async function applyInitPlan(projectDir, options = {}) {
|
|
|
789
814
|
return createRetrofitPlan({
|
|
790
815
|
...previewPlan,
|
|
791
816
|
commandMode: "apply",
|
|
792
|
-
notes:
|
|
793
|
-
...previewPlan.notes.filter((note) => note !== "Preview only: `wp-typia init` does not write files yet." && note !== RETROFIT_APPLY_PREVIEW_NOTE),
|
|
794
|
-
RETROFIT_ROLLBACK_NOTE
|
|
795
|
-
])),
|
|
817
|
+
notes: toApplyNotes(previewPlan.notes),
|
|
796
818
|
status: "already-initialized"
|
|
797
819
|
});
|
|
798
820
|
}
|
|
@@ -804,8 +826,8 @@ async function applyInitPlan(projectDir, options = {}) {
|
|
|
804
826
|
});
|
|
805
827
|
const helperFiles = buildRetrofitHelperFiles(previewPlan.blockTargets);
|
|
806
828
|
const filePaths = [
|
|
807
|
-
|
|
808
|
-
...Object.keys(helperFiles).map((relativePath) =>
|
|
829
|
+
path4.join(previewPlan.projectDir, "package.json"),
|
|
830
|
+
...Object.keys(helperFiles).map((relativePath) => path4.join(previewPlan.projectDir, relativePath))
|
|
809
831
|
];
|
|
810
832
|
const mutationSnapshot = await createRetrofitMutationSnapshot(previewPlan.projectDir, filePaths);
|
|
811
833
|
try {
|
|
@@ -821,13 +843,12 @@ async function applyInitPlan(projectDir, options = {}) {
|
|
|
821
843
|
return createRetrofitPlan({
|
|
822
844
|
...previewPlan,
|
|
823
845
|
commandMode: "apply",
|
|
824
|
-
notes:
|
|
825
|
-
...previewPlan.notes.filter((note) => note !== "Preview only: `wp-typia init` does not write files yet." && note !== RETROFIT_APPLY_PREVIEW_NOTE),
|
|
826
|
-
RETROFIT_ROLLBACK_NOTE
|
|
827
|
-
])),
|
|
846
|
+
notes: toApplyNotes(previewPlan.notes),
|
|
828
847
|
status: "applied"
|
|
829
848
|
});
|
|
830
849
|
}
|
|
850
|
+
|
|
851
|
+
// ../wp-typia-project-tools/src/runtime/cli-init.ts
|
|
831
852
|
async function runInitCommand(options) {
|
|
832
853
|
return options.apply ? applyInitPlan(options.projectDir, {
|
|
833
854
|
packageManager: options.packageManager
|
|
@@ -841,4 +862,4 @@ export {
|
|
|
841
862
|
applyInitPlan
|
|
842
863
|
};
|
|
843
864
|
|
|
844
|
-
//# debugId=
|
|
865
|
+
//# debugId=4F60C8DD81E9727764756E2164756E21
|