wp-typia 0.22.4 → 0.22.6
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/dist-bunli/.bunli/commands.gen.js +2097 -1366
- package/dist-bunli/{cli-2mt6bvcj.js → cli-0q0tz4dq.js} +4 -4
- 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-qr2ek735.js → cli-5kn2p7ee.js} +942 -477
- package/dist-bunli/{cli-6ymn63t4.js → cli-6a65qfb1.js} +475 -249
- package/dist-bunli/{cli-add-6s6kzf7x.js → cli-add-5vmxpgmn.js} +94 -184
- package/dist-bunli/{cli-doctor-70zd5m3b.js → cli-doctor-ngzs8kkc.js} +15 -18
- package/dist-bunli/{cli-gsj6vyn5.js → cli-f44sphgv.js} +183 -81
- package/dist-bunli/cli-fys8vm2t.js +20 -0
- package/dist-bunli/{cli-btbpt84c.js → cli-hhp1d348.js} +1 -1
- package/dist-bunli/{cli-init-kjjyky1y.js → cli-init-df1wg71p.js} +421 -401
- package/dist-bunli/{cli-scaffold-f57ccf5v.js → cli-scaffold-btx3wfsn.js} +8 -7
- package/dist-bunli/cli.js +10 -7
- package/dist-bunli/{command-list-wsaa4t2p.js → command-list-bqr2tp8w.js} +16 -12
- package/dist-bunli/{migrations-vw502qf9.js → migrations-bnrjw4k1.js} +7 -6
- package/dist-bunli/node-cli.js +318 -189
- package/dist-bunli/{workspace-project-7826tewa.js → workspace-project-csnnggz6.js} +2 -2
- package/package.json +2 -2
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from "./cli-1sm60g1z.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-5kn2p7ee.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,80 @@ 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-types.ts
|
|
222
|
+
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.";
|
|
223
|
+
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.";
|
|
224
|
+
var RETROFIT_ROLLBACK_NOTE = "Apply mode writes package.json and generated helper files with rollback-on-failure protection.";
|
|
225
|
+
|
|
226
|
+
// ../wp-typia-project-tools/src/runtime/cli-init-plan.ts
|
|
227
|
+
function normalizeRelativePath(value) {
|
|
228
|
+
return value.replace(/\\/gu, "/");
|
|
229
|
+
}
|
|
167
230
|
function buildGeneratedArtifactPaths(blockJsonFile, manifestFile) {
|
|
168
|
-
const manifestDir =
|
|
231
|
+
const manifestDir = path2.dirname(manifestFile);
|
|
169
232
|
const artifactPaths = [
|
|
170
233
|
blockJsonFile,
|
|
171
234
|
manifestFile,
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
235
|
+
path2.join(manifestDir, "typia.schema.json"),
|
|
236
|
+
path2.join(manifestDir, "typia-validator.php"),
|
|
237
|
+
path2.join(manifestDir, "typia.openapi.json")
|
|
175
238
|
];
|
|
176
239
|
return Array.from(new Set(artifactPaths.map((filePath) => normalizeRelativePath(filePath))));
|
|
177
240
|
}
|
|
@@ -192,8 +255,8 @@ function isObjectLikeSourceType(projectDir, typesFile, sourceTypeName) {
|
|
|
192
255
|
return analyzedTypes[sourceTypeName]?.kind === "object";
|
|
193
256
|
}
|
|
194
257
|
function inferRetrofitAttributeTypeName(projectDir, block) {
|
|
195
|
-
const typesPath =
|
|
196
|
-
const typesSource =
|
|
258
|
+
const typesPath = path2.join(projectDir, block.typesFile);
|
|
259
|
+
const typesSource = fs2.readFileSync(typesPath, "utf8");
|
|
197
260
|
const blockNameSegments = block.blockName.split("/");
|
|
198
261
|
const slug = blockNameSegments[blockNameSegments.length - 1] ?? block.key;
|
|
199
262
|
const candidateNames = collectNamedSourceTypeCandidates(typesSource);
|
|
@@ -227,69 +290,326 @@ function buildRetrofitBlockTarget(projectDir, block) {
|
|
|
227
290
|
typesFile: block.typesFile
|
|
228
291
|
};
|
|
229
292
|
}
|
|
230
|
-
function
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
293
|
+
function buildInitLayoutDetails(projectDir) {
|
|
294
|
+
try {
|
|
295
|
+
const discoveredLayout = discoverMigrationInitLayout(projectDir);
|
|
296
|
+
const discoveredBlocks = discoveredLayout.mode === "multi" ? discoveredLayout.blocks : [discoveredLayout.block];
|
|
297
|
+
let blockTargets;
|
|
298
|
+
try {
|
|
299
|
+
blockTargets = discoveredBlocks.map((block) => buildRetrofitBlockTarget(projectDir, block));
|
|
300
|
+
} catch (error) {
|
|
301
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
302
|
+
return {
|
|
303
|
+
blockNames: discoveredBlocks.map((block) => block.blockName),
|
|
304
|
+
blockTargets: [],
|
|
305
|
+
description: "Detected supported block files, but could not infer retrofit block-config metadata automatically yet.",
|
|
306
|
+
generatedArtifacts: [],
|
|
307
|
+
kind: "unsupported",
|
|
308
|
+
notes: [message, SUPPORTED_RETROFIT_LAYOUT_NOTE]
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
if (discoveredLayout.mode === "multi") {
|
|
312
|
+
return {
|
|
313
|
+
blockNames: discoveredBlocks.map((block) => block.blockName),
|
|
314
|
+
blockTargets,
|
|
315
|
+
description: `Detected a supported multi-block retrofit candidate (${discoveredBlocks.length} targets).`,
|
|
316
|
+
generatedArtifacts: discoveredBlocks.flatMap((block) => buildGeneratedArtifactPaths(block.blockJsonFile, block.manifestFile)),
|
|
317
|
+
kind: "multi-block",
|
|
318
|
+
notes: [
|
|
319
|
+
"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."
|
|
320
|
+
]
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
return {
|
|
324
|
+
blockNames: [discoveredLayout.block.blockName],
|
|
325
|
+
blockTargets,
|
|
326
|
+
description: "Detected a supported single-block retrofit candidate.",
|
|
327
|
+
generatedArtifacts: buildGeneratedArtifactPaths(discoveredLayout.block.blockJsonFile, discoveredLayout.block.manifestFile),
|
|
328
|
+
kind: "single-block",
|
|
329
|
+
notes: discoveredLayout.block.blockJsonFile === "block.json" ? [
|
|
330
|
+
"Legacy root `block.json` layouts are still supported for retrofit planning, but newer scaffolds keep generated block metadata under `src/`."
|
|
331
|
+
] : []
|
|
332
|
+
};
|
|
333
|
+
} catch (error) {
|
|
334
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
335
|
+
return {
|
|
336
|
+
blockNames: [],
|
|
337
|
+
blockTargets: [],
|
|
338
|
+
description: "No supported retrofit layout was auto-detected yet.",
|
|
339
|
+
generatedArtifacts: [],
|
|
340
|
+
kind: "unsupported",
|
|
341
|
+
notes: [message, SUPPORTED_RETROFIT_LAYOUT_NOTE]
|
|
342
|
+
};
|
|
343
|
+
}
|
|
241
344
|
}
|
|
242
|
-
function
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
345
|
+
function buildPlannedFiles(projectDir, layoutKind) {
|
|
346
|
+
if (layoutKind === "unsupported") {
|
|
347
|
+
return [];
|
|
348
|
+
}
|
|
349
|
+
return [
|
|
350
|
+
{
|
|
351
|
+
action: fs2.existsSync(path2.join(projectDir, "scripts", "block-config.ts")) ? "update" : "add",
|
|
352
|
+
path: "scripts/block-config.ts",
|
|
353
|
+
purpose: "Declare the current retrofit block targets so sync-types can regenerate metadata from the existing TypeScript source of truth."
|
|
354
|
+
},
|
|
355
|
+
{
|
|
356
|
+
action: fs2.existsSync(path2.join(projectDir, "scripts", "sync-types-to-block-json.ts")) ? "update" : "add",
|
|
357
|
+
path: "scripts/sync-types-to-block-json.ts",
|
|
358
|
+
purpose: "Generate block.json and Typia metadata artifacts from the current TypeScript source of truth."
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
action: fs2.existsSync(path2.join(projectDir, "scripts", "sync-project.ts")) ? "update" : "add",
|
|
362
|
+
path: "scripts/sync-project.ts",
|
|
363
|
+
purpose: "Provide one shared sync entrypoint that can grow into sync-rest or workspace-aware refresh steps later."
|
|
364
|
+
}
|
|
365
|
+
];
|
|
256
366
|
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
367
|
+
function buildChangeSummary(changes, options) {
|
|
368
|
+
const lines = [];
|
|
369
|
+
for (const dependencyChange of changes.packageChanges.addDevDependencies) {
|
|
370
|
+
lines.push(`devDependency ${dependencyChange.action} ${dependencyChange.name} -> ${dependencyChange.requiredValue}`);
|
|
371
|
+
}
|
|
372
|
+
if (changes.packageChanges.packageManagerField) {
|
|
373
|
+
lines.push(`packageManager ${changes.packageChanges.packageManagerField.action} -> ${changes.packageChanges.packageManagerField.requiredValue}`);
|
|
374
|
+
}
|
|
375
|
+
for (const scriptChange of changes.packageChanges.scripts) {
|
|
376
|
+
lines.push(`script ${scriptChange.action} ${scriptChange.name} -> ${scriptChange.requiredValue}`);
|
|
377
|
+
}
|
|
378
|
+
for (const filePlan of changes.plannedFiles) {
|
|
379
|
+
lines.push(`file ${filePlan.action} ${filePlan.path} (${filePlan.purpose})`);
|
|
380
|
+
}
|
|
381
|
+
if (options.includeGeneratedArtifacts) {
|
|
382
|
+
for (const artifactPath of changes.generatedArtifacts) {
|
|
383
|
+
lines.push(`generated artifact ${artifactPath}`);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
return lines;
|
|
264
387
|
}
|
|
265
|
-
function
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
388
|
+
function buildNextSteps(options) {
|
|
389
|
+
const cliSpecifier = getWpTypiaCliSpecifier();
|
|
390
|
+
const syncTypesRun = formatRunScript(options.packageManager, "sync-types");
|
|
391
|
+
const syncRun = formatRunScript(options.packageManager, "sync");
|
|
392
|
+
const doctorRun = formatPackageExecCommand(options.packageManager, cliSpecifier, "doctor");
|
|
393
|
+
const migrationInitRun = formatPackageExecCommand(options.packageManager, cliSpecifier, "migrate init --current-migration-version v1");
|
|
394
|
+
const dependencyInstallCommand = formatAddDevDependenciesCommand(options.packageManager, buildRequiredDevDependencyMapEntries());
|
|
395
|
+
if (options.layoutKind === "unsupported") {
|
|
396
|
+
return [
|
|
397
|
+
"Align the project to one of the supported retrofit layouts listed below, then rerun `wp-typia init`.",
|
|
398
|
+
dependencyInstallCommand,
|
|
399
|
+
syncTypesRun,
|
|
400
|
+
doctorRun
|
|
401
|
+
];
|
|
402
|
+
}
|
|
403
|
+
if (options.commandMode === "apply") {
|
|
404
|
+
return [
|
|
405
|
+
...options.dependencyChangeCount > 0 ? [
|
|
406
|
+
"Install or reinstall project dependencies so the retrofit sync scripts and metadata generators are available locally.",
|
|
407
|
+
dependencyInstallCommand
|
|
408
|
+
] : [],
|
|
409
|
+
syncRun,
|
|
410
|
+
doctorRun,
|
|
411
|
+
`Optional migration bootstrap: ${migrationInitRun}`
|
|
412
|
+
];
|
|
413
|
+
}
|
|
414
|
+
const steps = [
|
|
415
|
+
...options.hasPlannedChanges ? [
|
|
416
|
+
"Re-run `wp-typia init --apply` to write the planned package.json changes and helper files automatically.",
|
|
417
|
+
...options.dependencyChangeCount > 0 ? [dependencyInstallCommand] : []
|
|
418
|
+
] : [],
|
|
419
|
+
syncRun,
|
|
420
|
+
doctorRun,
|
|
421
|
+
`Optional migration bootstrap: ${migrationInitRun}`
|
|
422
|
+
];
|
|
423
|
+
return steps;
|
|
288
424
|
}
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
425
|
+
function buildRetrofitPlanSummary(options) {
|
|
426
|
+
if (options.status === "already-initialized") {
|
|
427
|
+
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.";
|
|
428
|
+
}
|
|
429
|
+
if (options.commandMode === "apply") {
|
|
430
|
+
return "Applied the minimum wp-typia retrofit surface so package.json and helper scripts are ready for the next install and sync run.";
|
|
431
|
+
}
|
|
432
|
+
return "This command previews the minimum wp-typia adoption layer for the current project without rewriting it into a full scaffold.";
|
|
433
|
+
}
|
|
434
|
+
function createRetrofitPlan(options) {
|
|
435
|
+
const includeGeneratedArtifacts = options.commandMode === "preview-only";
|
|
436
|
+
const plannedChanges = buildChangeSummary({
|
|
437
|
+
generatedArtifacts: options.generatedArtifacts,
|
|
438
|
+
packageChanges: options.packageChanges,
|
|
439
|
+
plannedFiles: options.plannedFiles
|
|
440
|
+
}, {
|
|
441
|
+
includeGeneratedArtifacts
|
|
442
|
+
});
|
|
443
|
+
return {
|
|
444
|
+
blockTargets: options.blockTargets,
|
|
445
|
+
commandMode: options.commandMode,
|
|
446
|
+
detectedLayout: options.detectedLayout,
|
|
447
|
+
generatedArtifacts: options.generatedArtifacts,
|
|
448
|
+
nextSteps: options.nextSteps ?? buildNextSteps({
|
|
449
|
+
commandMode: options.commandMode,
|
|
450
|
+
dependencyChangeCount: options.packageChanges.addDevDependencies.length,
|
|
451
|
+
hasPlannedChanges: plannedChanges.length > 0,
|
|
452
|
+
layoutKind: options.detectedLayout.kind,
|
|
453
|
+
packageManager: options.packageManager
|
|
454
|
+
}),
|
|
455
|
+
notes: options.notes,
|
|
456
|
+
packageChanges: options.packageChanges,
|
|
457
|
+
plannedFiles: options.plannedFiles,
|
|
458
|
+
packageManager: options.packageManager,
|
|
459
|
+
projectDir: options.projectDir,
|
|
460
|
+
projectName: options.projectName,
|
|
461
|
+
status: options.status,
|
|
462
|
+
summary: buildRetrofitPlanSummary({
|
|
463
|
+
commandMode: options.commandMode,
|
|
464
|
+
status: options.status
|
|
465
|
+
})
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
function getInitPlan(projectDir, options = {}) {
|
|
469
|
+
const resolvedProjectDir = path2.resolve(projectDir);
|
|
470
|
+
const packageJson = readProjectPackageJson(resolvedProjectDir);
|
|
471
|
+
const packageManager = resolveInitPackageManager(resolvedProjectDir, packageJson, options.packageManager);
|
|
472
|
+
const workspace = tryResolveWorkspaceProject(resolvedProjectDir);
|
|
473
|
+
if (workspace) {
|
|
474
|
+
const workspacePackageJson = readProjectPackageJson(workspace.projectDir);
|
|
475
|
+
const workspacePackageManager = resolveInitPackageManager(workspace.projectDir, workspacePackageJson, options.packageManager);
|
|
476
|
+
const cliSpecifier = getWpTypiaCliSpecifier();
|
|
477
|
+
return createRetrofitPlan({
|
|
478
|
+
blockTargets: [],
|
|
479
|
+
commandMode: "preview-only",
|
|
480
|
+
detectedLayout: {
|
|
481
|
+
blockNames: [],
|
|
482
|
+
description: "Already an official wp-typia workspace.",
|
|
483
|
+
kind: "official-workspace"
|
|
484
|
+
},
|
|
485
|
+
generatedArtifacts: [],
|
|
486
|
+
nextSteps: [
|
|
487
|
+
"Use `wp-typia add <kind> <name>` to extend the official workspace instead of rerunning init.",
|
|
488
|
+
formatRunScript(workspacePackageManager, "sync"),
|
|
489
|
+
formatPackageExecCommand(workspacePackageManager, cliSpecifier, "doctor")
|
|
490
|
+
],
|
|
491
|
+
notes: [
|
|
492
|
+
"The official workspace template already owns inventory, doctor, and add-command workflows."
|
|
493
|
+
],
|
|
494
|
+
packageChanges: {
|
|
495
|
+
addDevDependencies: [],
|
|
496
|
+
scripts: []
|
|
497
|
+
},
|
|
498
|
+
packageManager: workspacePackageManager,
|
|
499
|
+
plannedFiles: [],
|
|
500
|
+
projectDir: workspace.projectDir,
|
|
501
|
+
projectName: workspace.packageName,
|
|
502
|
+
status: "already-initialized"
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
const projectName = typeof packageJson?.name === "string" && packageJson.name.length > 0 ? packageJson.name : path2.basename(resolvedProjectDir);
|
|
506
|
+
const layout = buildInitLayoutDetails(resolvedProjectDir);
|
|
507
|
+
const dependencyChanges = buildDependencyChanges(packageJson);
|
|
508
|
+
const scriptChanges = buildScriptChanges(packageJson, packageManager);
|
|
509
|
+
const packageManagerFieldChange = buildPackageManagerFieldChange(packageJson, packageManager, {
|
|
510
|
+
persistExplicitOverride: typeof options.packageManager === "string"
|
|
511
|
+
});
|
|
512
|
+
const rawPlannedFiles = layout.kind === "generated-project" || layout.kind === "official-workspace" ? [] : buildPlannedFiles(resolvedProjectDir, layout.kind);
|
|
513
|
+
const hasExistingSurface = hasExistingWpTypiaProjectSurface(resolvedProjectDir, packageJson);
|
|
514
|
+
const status = hasExistingSurface && dependencyChanges.length === 0 && scriptChanges.length === 0 && packageManagerFieldChange === undefined ? "already-initialized" : "preview";
|
|
515
|
+
const plannedFiles = status === "already-initialized" ? [] : rawPlannedFiles;
|
|
516
|
+
const detectedLayout = status === "already-initialized" && hasExistingSurface ? {
|
|
517
|
+
blockNames: layout.blockNames,
|
|
518
|
+
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"}.`,
|
|
519
|
+
kind: "generated-project"
|
|
520
|
+
} : {
|
|
521
|
+
blockNames: layout.blockNames,
|
|
522
|
+
description: layout.description,
|
|
523
|
+
kind: layout.kind
|
|
524
|
+
};
|
|
525
|
+
return createRetrofitPlan({
|
|
526
|
+
blockTargets: layout.blockTargets,
|
|
527
|
+
commandMode: "preview-only",
|
|
528
|
+
detectedLayout,
|
|
529
|
+
generatedArtifacts: status === "already-initialized" && detectedLayout.kind === "generated-project" ? [] : layout.generatedArtifacts,
|
|
530
|
+
notes: Array.from(new Set([
|
|
531
|
+
"Preview only: `wp-typia init` does not write files yet.",
|
|
532
|
+
RETROFIT_APPLY_PREVIEW_NOTE,
|
|
533
|
+
...layout.notes
|
|
534
|
+
])),
|
|
535
|
+
packageChanges: {
|
|
536
|
+
addDevDependencies: dependencyChanges,
|
|
537
|
+
...packageManagerFieldChange ? { packageManagerField: packageManagerFieldChange } : {},
|
|
538
|
+
scripts: scriptChanges
|
|
539
|
+
},
|
|
540
|
+
packageManager,
|
|
541
|
+
plannedFiles,
|
|
542
|
+
projectDir: resolvedProjectDir,
|
|
543
|
+
projectName,
|
|
544
|
+
status
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
// ../wp-typia-project-tools/src/runtime/cli-init-templates.ts
|
|
549
|
+
import path3 from "path";
|
|
550
|
+
function buildRetrofitBlockConfigEntry(target) {
|
|
551
|
+
return [
|
|
552
|
+
"\t{",
|
|
553
|
+
` slug: ${quoteTsString(target.slug)},`,
|
|
554
|
+
` attributeTypeName: ${quoteTsString(target.attributeTypeName)},`,
|
|
555
|
+
` blockJsonFile: ${quoteTsString(target.blockJsonFile)},`,
|
|
556
|
+
` manifestFile: ${quoteTsString(target.manifestFile)},`,
|
|
557
|
+
` typesFile: ${quoteTsString(target.typesFile)},`,
|
|
558
|
+
"\t},"
|
|
559
|
+
].join(`
|
|
560
|
+
`);
|
|
561
|
+
}
|
|
562
|
+
function buildRetrofitBlockConfigSource(targets) {
|
|
563
|
+
const blockEntries = targets.map(buildRetrofitBlockConfigEntry).join(`
|
|
564
|
+
`);
|
|
565
|
+
const baseSource = `export interface WorkspaceBlockConfig {
|
|
566
|
+
attributeTypeName: string;
|
|
567
|
+
apiTypesFile?: string;
|
|
568
|
+
blockJsonFile?: string;
|
|
569
|
+
manifestFile?: string;
|
|
570
|
+
openApiFile?: string;
|
|
571
|
+
restManifest?: ReturnType<
|
|
572
|
+
typeof import( '@wp-typia/block-runtime/metadata-core' ).defineEndpointManifest
|
|
573
|
+
>;
|
|
574
|
+
slug: string;
|
|
575
|
+
typesFile: string;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
export const BLOCKS: WorkspaceBlockConfig[] = [
|
|
579
|
+
${blockEntries}
|
|
580
|
+
];
|
|
581
|
+
`;
|
|
582
|
+
return `${updateWorkspaceInventorySource(baseSource)}
|
|
583
|
+
`;
|
|
584
|
+
}
|
|
585
|
+
function buildRetrofitSyncTypesScriptSource() {
|
|
586
|
+
return `/* eslint-disable no-console */
|
|
587
|
+
import path from 'node:path';
|
|
588
|
+
|
|
589
|
+
import { syncBlockMetadata } from '@wp-typia/block-runtime/metadata-core';
|
|
590
|
+
|
|
591
|
+
import { BLOCKS } from './block-config';
|
|
592
|
+
|
|
593
|
+
function parseCliOptions( argv: string[] ) {
|
|
594
|
+
const options = {
|
|
595
|
+
check: false,
|
|
596
|
+
};
|
|
597
|
+
|
|
598
|
+
for ( const argument of argv ) {
|
|
599
|
+
if ( argument === '--check' ) {
|
|
600
|
+
options.check = true;
|
|
601
|
+
continue;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
throw new Error( \`Unknown sync-types flag: \${ argument }\` );
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
return options;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
async function main() {
|
|
611
|
+
const options = parseCliOptions( process.argv.slice( 2 ) );
|
|
612
|
+
|
|
293
613
|
if ( BLOCKS.length === 0 ) {
|
|
294
614
|
console.log(
|
|
295
615
|
options.check
|
|
@@ -442,241 +762,18 @@ main().catch( ( error ) => {
|
|
|
442
762
|
} );
|
|
443
763
|
`;
|
|
444
764
|
}
|
|
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
765
|
function buildRetrofitHelperFiles(blockTargets) {
|
|
671
766
|
return {
|
|
672
|
-
[
|
|
673
|
-
[
|
|
674
|
-
[
|
|
767
|
+
[path3.join("scripts", "block-config.ts")]: buildRetrofitBlockConfigSource(blockTargets),
|
|
768
|
+
[path3.join("scripts", "sync-project.ts")]: buildRetrofitSyncProjectScriptSource(),
|
|
769
|
+
[path3.join("scripts", "sync-types-to-block-json.ts")]: buildRetrofitSyncTypesScriptSource()
|
|
675
770
|
};
|
|
676
771
|
}
|
|
772
|
+
|
|
773
|
+
// ../wp-typia-project-tools/src/runtime/cli-init-apply.ts
|
|
677
774
|
async function createRetrofitMutationSnapshot(projectDir, filePaths) {
|
|
678
|
-
const scriptsDir =
|
|
679
|
-
const scriptsDirExisted =
|
|
775
|
+
const scriptsDir = path4.join(projectDir, "scripts");
|
|
776
|
+
const scriptsDirExisted = fs3.existsSync(scriptsDir);
|
|
680
777
|
const fileSources = await snapshotWorkspaceFiles(filePaths);
|
|
681
778
|
const targetPaths = fileSources.filter((entry) => entry.source === null).map((entry) => entry.filePath);
|
|
682
779
|
if (!scriptsDirExisted) {
|
|
@@ -690,95 +787,22 @@ async function createRetrofitMutationSnapshot(projectDir, filePaths) {
|
|
|
690
787
|
}
|
|
691
788
|
async function writeRetrofitFiles(options) {
|
|
692
789
|
const helperFiles = buildRetrofitHelperFiles(options.blockTargets);
|
|
693
|
-
const scriptsDir =
|
|
790
|
+
const scriptsDir = path4.join(options.projectDir, "scripts");
|
|
694
791
|
await fsp.mkdir(scriptsDir, { recursive: true });
|
|
695
|
-
await fsp.writeFile(
|
|
792
|
+
await fsp.writeFile(path4.join(options.projectDir, "package.json"), buildProjectPackageJsonSource(options.packageJson), "utf8");
|
|
696
793
|
for (const [relativePath, source] of Object.entries(helperFiles)) {
|
|
697
|
-
await fsp.writeFile(
|
|
794
|
+
await fsp.writeFile(path4.join(options.projectDir, relativePath), source, "utf8");
|
|
698
795
|
}
|
|
699
796
|
}
|
|
700
797
|
function buildApplyFailureError(error) {
|
|
701
798
|
const message = error instanceof Error ? error.message : String(error);
|
|
702
799
|
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
800
|
}
|
|
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
|
-
});
|
|
801
|
+
function toApplyNotes(previewNotes) {
|
|
802
|
+
return Array.from(new Set([
|
|
803
|
+
...previewNotes.filter((note) => note !== "Preview only: `wp-typia init` does not write files yet." && note !== RETROFIT_APPLY_PREVIEW_NOTE),
|
|
804
|
+
RETROFIT_ROLLBACK_NOTE
|
|
805
|
+
]));
|
|
782
806
|
}
|
|
783
807
|
async function applyInitPlan(projectDir, options = {}) {
|
|
784
808
|
const previewPlan = getInitPlan(projectDir, options);
|
|
@@ -789,10 +813,7 @@ async function applyInitPlan(projectDir, options = {}) {
|
|
|
789
813
|
return createRetrofitPlan({
|
|
790
814
|
...previewPlan,
|
|
791
815
|
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
|
-
])),
|
|
816
|
+
notes: toApplyNotes(previewPlan.notes),
|
|
796
817
|
status: "already-initialized"
|
|
797
818
|
});
|
|
798
819
|
}
|
|
@@ -804,8 +825,8 @@ async function applyInitPlan(projectDir, options = {}) {
|
|
|
804
825
|
});
|
|
805
826
|
const helperFiles = buildRetrofitHelperFiles(previewPlan.blockTargets);
|
|
806
827
|
const filePaths = [
|
|
807
|
-
|
|
808
|
-
...Object.keys(helperFiles).map((relativePath) =>
|
|
828
|
+
path4.join(previewPlan.projectDir, "package.json"),
|
|
829
|
+
...Object.keys(helperFiles).map((relativePath) => path4.join(previewPlan.projectDir, relativePath))
|
|
809
830
|
];
|
|
810
831
|
const mutationSnapshot = await createRetrofitMutationSnapshot(previewPlan.projectDir, filePaths);
|
|
811
832
|
try {
|
|
@@ -821,13 +842,12 @@ async function applyInitPlan(projectDir, options = {}) {
|
|
|
821
842
|
return createRetrofitPlan({
|
|
822
843
|
...previewPlan,
|
|
823
844
|
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
|
-
])),
|
|
845
|
+
notes: toApplyNotes(previewPlan.notes),
|
|
828
846
|
status: "applied"
|
|
829
847
|
});
|
|
830
848
|
}
|
|
849
|
+
|
|
850
|
+
// ../wp-typia-project-tools/src/runtime/cli-init.ts
|
|
831
851
|
async function runInitCommand(options) {
|
|
832
852
|
return options.apply ? applyInitPlan(options.projectDir, {
|
|
833
853
|
packageManager: options.packageManager
|
|
@@ -841,4 +861,4 @@ export {
|
|
|
841
861
|
applyInitPlan
|
|
842
862
|
};
|
|
843
863
|
|
|
844
|
-
//# debugId=
|
|
864
|
+
//# debugId=9445E5AD8C9D8E6964756E2164756E21
|