wp-typia 0.24.4 → 0.24.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.
Files changed (58) hide show
  1. package/README.md +8 -6
  2. package/bin/wp-typia.js +24 -103
  3. package/{dist-bunli/node-cli.js → dist/cli.js} +5086 -3693
  4. package/package.json +9 -36
  5. package/bin/routing-metadata.generated.d.ts +0 -8
  6. package/bin/routing-metadata.generated.js +0 -93
  7. package/bin/runtime-routing.d.ts +0 -34
  8. package/bin/runtime-routing.js +0 -124
  9. package/dist-bunli/.bunli/commands.gen.js +0 -304441
  10. package/dist-bunli/.bunli/highlights-eq9cgrbb.scm +0 -604
  11. package/dist-bunli/.bunli/highlights-ghv9g403.scm +0 -205
  12. package/dist-bunli/.bunli/highlights-hk7bwhj4.scm +0 -284
  13. package/dist-bunli/.bunli/highlights-r812a2qc.scm +0 -150
  14. package/dist-bunli/.bunli/highlights-x6tmsnaa.scm +0 -115
  15. package/dist-bunli/.bunli/injections-73j83es3.scm +0 -27
  16. package/dist-bunli/.bunli/tree-sitter-javascript-nd0q4pe9.wasm +0 -0
  17. package/dist-bunli/.bunli/tree-sitter-markdown-411r6y9b.wasm +0 -0
  18. package/dist-bunli/.bunli/tree-sitter-markdown_inline-j5349f42.wasm +0 -0
  19. package/dist-bunli/.bunli/tree-sitter-typescript-zxjzwt75.wasm +0 -0
  20. package/dist-bunli/.bunli/tree-sitter-zig-e78zbjpm.wasm +0 -0
  21. package/dist-bunli/agents-91fpdyyt.js +0 -12
  22. package/dist-bunli/chunk-bdqvmfwv-f5qmzmxg.js +0 -16825
  23. package/dist-bunli/cli-03j0axbt.js +0 -163
  24. package/dist-bunli/cli-1170yyve.js +0 -106
  25. package/dist-bunli/cli-368d4cgy.js +0 -1235
  26. package/dist-bunli/cli-377p86mf.js +0 -191
  27. package/dist-bunli/cli-6v0pcxw6.js +0 -314
  28. package/dist-bunli/cli-84c7wff4.js +0 -198
  29. package/dist-bunli/cli-8hxf9qw6.js +0 -198
  30. package/dist-bunli/cli-9fx0qgb7.js +0 -3680
  31. package/dist-bunli/cli-ac2ebaf8.js +0 -3
  32. package/dist-bunli/cli-add-qjd3ba8j.js +0 -10671
  33. package/dist-bunli/cli-am5x7tb4.js +0 -192
  34. package/dist-bunli/cli-bajwv85z.js +0 -24
  35. package/dist-bunli/cli-ccax7s0s.js +0 -34
  36. package/dist-bunli/cli-cvxvcw7c.js +0 -46
  37. package/dist-bunli/cli-diagnostics-10drxh34.js +0 -34
  38. package/dist-bunli/cli-doctor-6fyxq940.js +0 -1446
  39. package/dist-bunli/cli-e4bwd81c.js +0 -1260
  40. package/dist-bunli/cli-fv4h3ydt.js +0 -173823
  41. package/dist-bunli/cli-hv2yedw2.js +0 -74591
  42. package/dist-bunli/cli-init-7avk42dh.js +0 -880
  43. package/dist-bunli/cli-kfm9mm68.js +0 -14679
  44. package/dist-bunli/cli-prompt-ncyg68rn.js +0 -12
  45. package/dist-bunli/cli-rdcga1bd.js +0 -135
  46. package/dist-bunli/cli-scaffold-0bb6pr3w.js +0 -538
  47. package/dist-bunli/cli-t73q5aqz.js +0 -103
  48. package/dist-bunli/cli-templates-g8t4fm11.js +0 -167
  49. package/dist-bunli/cli-tj7ajdvf.js +0 -2612
  50. package/dist-bunli/cli-tq730sqt.js +0 -344
  51. package/dist-bunli/cli-xnn9xjcy.js +0 -68
  52. package/dist-bunli/cli-z48frc8t.js +0 -229
  53. package/dist-bunli/cli.js +0 -2523
  54. package/dist-bunli/command-list-y3g7e9rb.js +0 -4013
  55. package/dist-bunli/create-template-validation-4fr851vg.js +0 -16
  56. package/dist-bunli/migrations-3vngdy51.js +0 -47
  57. package/dist-bunli/sync-k2k8svyc.js +0 -13
  58. package/dist-bunli/workspace-project-gmv2a71z.js +0 -22
@@ -1,880 +0,0 @@
1
- // @bun
2
- import {
3
- getPackageVersions
4
- } from "./cli-84c7wff4.js";
5
- import"./cli-8hxf9qw6.js";
6
- import {
7
- discoverMigrationInitLayout
8
- } from "./cli-e4bwd81c.js";
9
- import {
10
- quoteTsString,
11
- require_typescript,
12
- rollbackWorkspaceMutation,
13
- snapshotWorkspaceFiles,
14
- toPascalCase,
15
- updateWorkspaceInventorySource
16
- } from "./cli-fv4h3ydt.js";
17
- import"./cli-cvxvcw7c.js";
18
- import"./cli-bajwv85z.js";
19
- import {
20
- CLI_DIAGNOSTIC_CODES,
21
- createCliDiagnosticCodeError
22
- } from "./cli-tq730sqt.js";
23
- import {
24
- parseWorkspacePackageManagerId,
25
- tryResolveWorkspaceProject
26
- } from "./cli-1170yyve.js";
27
- import {
28
- formatAddDevDependenciesCommand,
29
- formatPackageExecCommand,
30
- formatRunScript,
31
- getPackageManager,
32
- transformPackageManagerText
33
- } from "./cli-am5x7tb4.js";
34
- import {
35
- readJsonFileSync
36
- } from "./cli-ccax7s0s.js";
37
- import {
38
- __toESM
39
- } from "./cli-xnn9xjcy.js";
40
-
41
- // ../wp-typia-project-tools/src/runtime/cli-init-apply.ts
42
- import fs3 from "fs";
43
- import { promises as fsp } from "fs";
44
- import path4 from "path";
45
-
46
- // ../wp-typia-project-tools/src/runtime/cli-init-package-json.ts
47
- import fs from "fs";
48
- import path from "path";
49
- var BASE_RETROFIT_SCRIPTS = {
50
- sync: "tsx scripts/sync-project.ts",
51
- "sync-types": "tsx scripts/sync-types-to-block-json.ts",
52
- typecheck: "bun run sync --check && tsc --noEmit"
53
- };
54
- var BASE_RETROFIT_DEV_DEPENDENCIES = [
55
- "@typia/unplugin",
56
- "@wp-typia/block-runtime",
57
- "@wp-typia/block-types",
58
- "tsx",
59
- "typescript",
60
- "typia"
61
- ];
62
- function readProjectPackageJson(projectDir) {
63
- const packageJsonPath = path.join(projectDir, "package.json");
64
- if (!fs.existsSync(packageJsonPath)) {
65
- return null;
66
- }
67
- try {
68
- return readJsonFileSync(packageJsonPath, {
69
- context: "project package manifest"
70
- });
71
- } catch (error) {
72
- const message = error instanceof Error ? error.message : String(error);
73
- throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.INVALID_ARGUMENT, `Unable to parse ${packageJsonPath}: ${message}`, error instanceof Error ? { cause: error } : undefined);
74
- }
75
- }
76
- function inferInitPackageManager(projectDir, packageJson) {
77
- if (packageJson?.packageManager) {
78
- return parseWorkspacePackageManagerId(packageJson.packageManager);
79
- }
80
- if (fs.existsSync(path.join(projectDir, "bun.lock")) || fs.existsSync(path.join(projectDir, "bun.lockb"))) {
81
- return "bun";
82
- }
83
- if (fs.existsSync(path.join(projectDir, "pnpm-lock.yaml"))) {
84
- return "pnpm";
85
- }
86
- if (fs.existsSync(path.join(projectDir, "yarn.lock")) || fs.existsSync(path.join(projectDir, ".yarnrc.yml"))) {
87
- return "yarn";
88
- }
89
- return "npm";
90
- }
91
- function resolveInitPackageManager(projectDir, packageJson, override) {
92
- if (!override) {
93
- return inferInitPackageManager(projectDir, packageJson);
94
- }
95
- if (override !== "bun" && override !== "npm" && override !== "pnpm" && override !== "yarn") {
96
- throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.INVALID_ARGUMENT, `Unknown package manager "${override}". Expected one of: bun, npm, pnpm, yarn.`);
97
- }
98
- return override;
99
- }
100
- function getWpTypiaCliSpecifier() {
101
- const versions = getPackageVersions();
102
- return versions.wpTypiaPackageExactVersion === "0.0.0" ? "wp-typia" : `wp-typia@${versions.wpTypiaPackageExactVersion}`;
103
- }
104
- function buildRequiredDevDependencyMap() {
105
- const versions = getPackageVersions();
106
- return {
107
- "@typia/unplugin": versions.typiaUnpluginPackageVersion,
108
- "@wp-typia/block-runtime": versions.blockRuntimePackageVersion,
109
- "@wp-typia/block-types": versions.blockTypesPackageVersion,
110
- tsx: versions.tsxPackageVersion,
111
- typescript: versions.typescriptPackageVersion,
112
- typia: versions.typiaPackageVersion
113
- };
114
- }
115
- function getExistingDependencyVersion(packageJson, name) {
116
- return packageJson?.devDependencies?.[name] ?? packageJson?.dependencies?.[name];
117
- }
118
- function buildDependencyChanges(packageJson) {
119
- const requiredDependencies = buildRequiredDevDependencyMap();
120
- return BASE_RETROFIT_DEV_DEPENDENCIES.flatMap((name) => {
121
- const requiredValue = requiredDependencies[name];
122
- const currentValue = getExistingDependencyVersion(packageJson, name);
123
- if (currentValue === requiredValue) {
124
- return [];
125
- }
126
- return [
127
- {
128
- action: currentValue ? "update" : "add",
129
- ...currentValue ? { currentValue } : {},
130
- name,
131
- requiredValue
132
- }
133
- ];
134
- });
135
- }
136
- function buildScriptChanges(packageJson, packageManager) {
137
- const scripts = packageJson?.scripts ?? {};
138
- return Object.entries(BASE_RETROFIT_SCRIPTS).flatMap(([name, commandSource]) => {
139
- const requiredValue = transformPackageManagerText(commandSource, packageManager);
140
- const currentValue = scripts[name];
141
- if (currentValue === requiredValue) {
142
- return [];
143
- }
144
- return [
145
- {
146
- action: typeof currentValue === "string" ? "update" : "add",
147
- ...typeof currentValue === "string" ? { currentValue } : {},
148
- name,
149
- requiredValue
150
- }
151
- ];
152
- });
153
- }
154
- function buildPackageManagerFieldChange(packageJson, packageManager, options = {}) {
155
- if (!options.persistExplicitOverride && packageManager === "npm") {
156
- return;
157
- }
158
- const requiredValue = getPackageManager(packageManager).packageManagerField;
159
- const currentValue = packageJson?.packageManager;
160
- if (currentValue === requiredValue) {
161
- return;
162
- }
163
- return {
164
- action: typeof currentValue === "string" ? "update" : "add",
165
- ...typeof currentValue === "string" ? { currentValue } : {},
166
- requiredValue
167
- };
168
- }
169
- function hasExistingWpTypiaProjectSurface(projectDir, packageJson) {
170
- const scripts = packageJson?.scripts ?? {};
171
- const hasSyncSurface = typeof scripts.sync === "string" || typeof scripts["sync-types"] === "string";
172
- const hasHelperFiles = [
173
- path.join("scripts", "block-config.ts"),
174
- path.join("scripts", "sync-project.ts"),
175
- path.join("scripts", "sync-types-to-block-json.ts")
176
- ].every((relativePath) => fs.existsSync(path.join(projectDir, relativePath)));
177
- const hasRuntimeDeps = typeof getExistingDependencyVersion(packageJson, "@wp-typia/block-runtime") === "string" && typeof getExistingDependencyVersion(packageJson, "@wp-typia/block-types") === "string";
178
- return hasSyncSurface && hasHelperFiles && hasRuntimeDeps;
179
- }
180
- function buildRequiredDevDependencyMapEntries() {
181
- return Object.entries(buildRequiredDevDependencyMap()).map(([name, version]) => `${name}@${version.replace(/^workspace:/u, "")}`);
182
- }
183
- function setDependencyVersion(packageJson, name, requiredValue) {
184
- if (packageJson.devDependencies?.[name] !== undefined) {
185
- packageJson.devDependencies[name] = requiredValue;
186
- return;
187
- }
188
- if (packageJson.dependencies?.[name] !== undefined) {
189
- packageJson.dependencies[name] = requiredValue;
190
- return;
191
- }
192
- packageJson.devDependencies ??= {};
193
- packageJson.devDependencies[name] = requiredValue;
194
- }
195
- function buildNextProjectPackageJson(options) {
196
- const nextPackageJson = options.packageJson ? JSON.parse(JSON.stringify(options.packageJson)) : {
197
- name: options.projectName,
198
- private: true
199
- };
200
- nextPackageJson.devDependencies ??= {};
201
- nextPackageJson.scripts ??= {};
202
- for (const dependencyChange of options.packageChanges.addDevDependencies) {
203
- setDependencyVersion(nextPackageJson, dependencyChange.name, dependencyChange.requiredValue);
204
- }
205
- if (options.packageChanges.packageManagerField) {
206
- nextPackageJson.packageManager = options.packageChanges.packageManagerField.requiredValue;
207
- } else if (!nextPackageJson.packageManager && options.packageManager !== "npm") {
208
- nextPackageJson.packageManager = getPackageManager(options.packageManager).packageManagerField;
209
- }
210
- for (const scriptChange of options.packageChanges.scripts) {
211
- nextPackageJson.scripts[scriptChange.name] = scriptChange.requiredValue;
212
- }
213
- return nextPackageJson;
214
- }
215
- function buildProjectPackageJsonSource(packageJson) {
216
- return `${JSON.stringify(packageJson, null, 2)}
217
- `;
218
- }
219
-
220
- // ../wp-typia-project-tools/src/runtime/cli-init-plan.ts
221
- var import_typescript = __toESM(require_typescript(), 1);
222
- import fs2 from "fs";
223
- import path2 from "path";
224
- import { analyzeSourceTypes } from "@wp-typia/block-runtime/metadata-parser";
225
-
226
- // ../wp-typia-project-tools/src/runtime/cli-init-plan-presentation.ts
227
- function buildInitPlanChangeSummary(changes, options) {
228
- const lines = [];
229
- for (const dependencyChange of changes.packageChanges.addDevDependencies) {
230
- lines.push(`devDependency ${dependencyChange.action} ${dependencyChange.name} -> ${dependencyChange.requiredValue}`);
231
- }
232
- if (changes.packageChanges.packageManagerField) {
233
- lines.push(`packageManager ${changes.packageChanges.packageManagerField.action} -> ${changes.packageChanges.packageManagerField.requiredValue}`);
234
- }
235
- for (const scriptChange of changes.packageChanges.scripts) {
236
- lines.push(`script ${scriptChange.action} ${scriptChange.name} -> ${scriptChange.requiredValue}`);
237
- }
238
- for (const filePlan of changes.plannedFiles) {
239
- lines.push(`file ${filePlan.action} ${filePlan.path} (${filePlan.purpose})`);
240
- }
241
- if (options.includeGeneratedArtifacts) {
242
- for (const artifactPath of changes.generatedArtifacts) {
243
- lines.push(`generated artifact ${artifactPath}`);
244
- }
245
- }
246
- return lines;
247
- }
248
- function buildInitPlanNextSteps(options) {
249
- const cliSpecifier = getWpTypiaCliSpecifier();
250
- const syncTypesRun = formatRunScript(options.packageManager, "sync-types");
251
- const syncRun = formatRunScript(options.packageManager, "sync");
252
- const doctorRun = formatPackageExecCommand(options.packageManager, cliSpecifier, "doctor");
253
- const migrationInitRun = formatPackageExecCommand(options.packageManager, cliSpecifier, "migrate init --current-migration-version v1");
254
- const dependencyInstallCommand = formatAddDevDependenciesCommand(options.packageManager, buildRequiredDevDependencyMapEntries());
255
- if (options.layoutKind === "unsupported") {
256
- return [
257
- "Align the project to one of the supported retrofit layouts listed below, then rerun `wp-typia init`.",
258
- dependencyInstallCommand,
259
- syncTypesRun,
260
- doctorRun
261
- ];
262
- }
263
- if (options.commandMode === "apply") {
264
- return [
265
- ...options.dependencyChangeCount > 0 ? [
266
- "Install or reinstall project dependencies so the retrofit sync scripts and metadata generators are available locally.",
267
- dependencyInstallCommand
268
- ] : [],
269
- syncRun,
270
- doctorRun,
271
- `Optional migration bootstrap: ${migrationInitRun}`
272
- ];
273
- }
274
- return [
275
- ...options.hasPlannedChanges ? [
276
- "Re-run `wp-typia init --apply` to write the planned package.json changes and helper files automatically.",
277
- ...options.dependencyChangeCount > 0 ? [dependencyInstallCommand] : []
278
- ] : [],
279
- syncRun,
280
- doctorRun,
281
- `Optional migration bootstrap: ${migrationInitRun}`
282
- ];
283
- }
284
- function buildRetrofitPlanSummary(options) {
285
- if (options.status === "already-initialized") {
286
- 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.";
287
- }
288
- if (options.commandMode === "apply") {
289
- return "Applied the minimum wp-typia retrofit surface so package.json and helper scripts are ready for the next install and sync run.";
290
- }
291
- return "This command previews the minimum wp-typia adoption layer for the current project without rewriting it into a full scaffold.";
292
- }
293
-
294
- // ../wp-typia-project-tools/src/runtime/cli-init-types.ts
295
- 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.";
296
- 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.";
297
- var RETROFIT_ROLLBACK_NOTE = "Apply mode writes package.json and generated helper files with rollback-on-failure protection.";
298
-
299
- // ../wp-typia-project-tools/src/runtime/cli-init-plan.ts
300
- function normalizeRelativePath(value) {
301
- return value.replace(/\\/gu, "/");
302
- }
303
- function buildGeneratedArtifactPaths(blockJsonFile, manifestFile) {
304
- const manifestDir = path2.dirname(manifestFile);
305
- const artifactPaths = [
306
- blockJsonFile,
307
- manifestFile,
308
- path2.join(manifestDir, "typia.schema.json"),
309
- path2.join(manifestDir, "typia-validator.php"),
310
- path2.join(manifestDir, "typia.openapi.json")
311
- ];
312
- return Array.from(new Set(artifactPaths.map((filePath) => normalizeRelativePath(filePath))));
313
- }
314
- function collectNamedSourceTypeCandidates(typesSource) {
315
- const sourceFile = import_typescript.default.createSourceFile("types.ts", typesSource, import_typescript.default.ScriptTarget.Latest, true, import_typescript.default.ScriptKind.TS);
316
- return sourceFile.statements.flatMap((statement) => {
317
- if (import_typescript.default.isInterfaceDeclaration(statement) || import_typescript.default.isTypeAliasDeclaration(statement)) {
318
- return [statement.name.text];
319
- }
320
- return [];
321
- });
322
- }
323
- function isObjectLikeSourceType(projectDir, typesFile, sourceTypeName) {
324
- const analyzedTypes = analyzeSourceTypes({
325
- projectRoot: projectDir,
326
- typesFile
327
- }, [sourceTypeName]);
328
- return analyzedTypes[sourceTypeName]?.kind === "object";
329
- }
330
- function inferRetrofitAttributeTypeName(projectDir, block) {
331
- const typesPath = path2.join(projectDir, block.typesFile);
332
- const typesSource = fs2.readFileSync(typesPath, "utf8");
333
- const blockNameSegments = block.blockName.split("/");
334
- const slug = blockNameSegments[blockNameSegments.length - 1] ?? block.key;
335
- const candidateNames = collectNamedSourceTypeCandidates(typesSource);
336
- const validCandidates = candidateNames.filter((candidateName) => isObjectLikeSourceType(projectDir, block.typesFile, candidateName));
337
- const preferredName = `${toPascalCase(slug)}Attributes`;
338
- if (validCandidates.includes(preferredName)) {
339
- return preferredName;
340
- }
341
- const attributeCandidates = validCandidates.filter((candidateName) => candidateName.endsWith("Attributes"));
342
- if (attributeCandidates.length === 1) {
343
- return attributeCandidates[0];
344
- }
345
- if (validCandidates.length === 1) {
346
- return validCandidates[0];
347
- }
348
- if (validCandidates.length === 0) {
349
- throw new Error(`Unable to infer an object-like source type from ${block.typesFile}. Add one interface or type alias such as ${preferredName} before rerunning \`wp-typia init\`.`);
350
- }
351
- throw new Error(`Unable to infer a unique source type from ${block.typesFile}. Candidate object-like exports: ${validCandidates.join(", ")}. Rename one to ${preferredName} or leave a single object-like attributes type before rerunning \`wp-typia init\`.`);
352
- }
353
- function buildRetrofitBlockTarget(projectDir, block) {
354
- const blockNameSegments = block.blockName.split("/");
355
- const slug = blockNameSegments[blockNameSegments.length - 1] ?? block.key;
356
- return {
357
- attributeTypeName: inferRetrofitAttributeTypeName(projectDir, block),
358
- blockJsonFile: block.blockJsonFile,
359
- blockName: block.blockName,
360
- manifestFile: block.manifestFile,
361
- saveFile: block.saveFile,
362
- slug,
363
- typesFile: block.typesFile
364
- };
365
- }
366
- function buildInitLayoutDetails(projectDir) {
367
- try {
368
- const discoveredLayout = discoverMigrationInitLayout(projectDir);
369
- const discoveredBlocks = discoveredLayout.mode === "multi" ? discoveredLayout.blocks : [discoveredLayout.block];
370
- let blockTargets;
371
- try {
372
- blockTargets = discoveredBlocks.map((block) => buildRetrofitBlockTarget(projectDir, block));
373
- } catch (error) {
374
- const message = error instanceof Error ? error.message : String(error);
375
- return {
376
- blockNames: discoveredBlocks.map((block) => block.blockName),
377
- blockTargets: [],
378
- description: "Detected supported block files, but could not infer retrofit block-config metadata automatically yet.",
379
- generatedArtifacts: [],
380
- kind: "unsupported",
381
- notes: [message, SUPPORTED_RETROFIT_LAYOUT_NOTE]
382
- };
383
- }
384
- if (discoveredLayout.mode === "multi") {
385
- return {
386
- blockNames: discoveredBlocks.map((block) => block.blockName),
387
- blockTargets,
388
- description: `Detected a supported multi-block retrofit candidate (${discoveredBlocks.length} targets).`,
389
- generatedArtifacts: discoveredBlocks.flatMap((block) => buildGeneratedArtifactPaths(block.blockJsonFile, block.manifestFile)),
390
- kind: "multi-block",
391
- notes: [
392
- "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."
393
- ]
394
- };
395
- }
396
- return {
397
- blockNames: [discoveredLayout.block.blockName],
398
- blockTargets,
399
- description: "Detected a supported single-block retrofit candidate.",
400
- generatedArtifacts: buildGeneratedArtifactPaths(discoveredLayout.block.blockJsonFile, discoveredLayout.block.manifestFile),
401
- kind: "single-block",
402
- notes: discoveredLayout.block.blockJsonFile === "block.json" ? [
403
- "Legacy root `block.json` layouts are still supported for retrofit planning, but newer scaffolds keep generated block metadata under `src/`."
404
- ] : []
405
- };
406
- } catch (error) {
407
- const message = error instanceof Error ? error.message : String(error);
408
- return {
409
- blockNames: [],
410
- blockTargets: [],
411
- description: "No supported retrofit layout was auto-detected yet.",
412
- generatedArtifacts: [],
413
- kind: "unsupported",
414
- notes: [message, SUPPORTED_RETROFIT_LAYOUT_NOTE]
415
- };
416
- }
417
- }
418
- function buildPlannedFiles(projectDir, layoutKind) {
419
- if (layoutKind === "unsupported") {
420
- return [];
421
- }
422
- return [
423
- {
424
- action: fs2.existsSync(path2.join(projectDir, "scripts", "block-config.ts")) ? "update" : "add",
425
- path: "scripts/block-config.ts",
426
- purpose: "Declare the current retrofit block targets so sync-types can regenerate metadata from the existing TypeScript source of truth."
427
- },
428
- {
429
- action: fs2.existsSync(path2.join(projectDir, "scripts", "sync-types-to-block-json.ts")) ? "update" : "add",
430
- path: "scripts/sync-types-to-block-json.ts",
431
- purpose: "Generate block.json and Typia metadata artifacts from the current TypeScript source of truth."
432
- },
433
- {
434
- action: fs2.existsSync(path2.join(projectDir, "scripts", "sync-project.ts")) ? "update" : "add",
435
- path: "scripts/sync-project.ts",
436
- purpose: "Provide one shared sync entrypoint that can grow into sync-rest or workspace-aware refresh steps later."
437
- }
438
- ];
439
- }
440
- function createRetrofitPlan(options) {
441
- const includeGeneratedArtifacts = options.commandMode === "preview-only";
442
- const plannedChanges = buildInitPlanChangeSummary({
443
- generatedArtifacts: options.generatedArtifacts,
444
- packageChanges: options.packageChanges,
445
- plannedFiles: options.plannedFiles
446
- }, {
447
- includeGeneratedArtifacts
448
- });
449
- return {
450
- blockTargets: options.blockTargets,
451
- commandMode: options.commandMode,
452
- detectedLayout: options.detectedLayout,
453
- generatedArtifacts: options.generatedArtifacts,
454
- nextSteps: options.nextSteps ?? buildInitPlanNextSteps({
455
- commandMode: options.commandMode,
456
- dependencyChangeCount: options.packageChanges.addDevDependencies.length,
457
- hasPlannedChanges: plannedChanges.length > 0,
458
- layoutKind: options.detectedLayout.kind,
459
- packageManager: options.packageManager
460
- }),
461
- notes: options.notes,
462
- packageChanges: options.packageChanges,
463
- plannedFiles: options.plannedFiles,
464
- packageManager: options.packageManager,
465
- projectDir: options.projectDir,
466
- projectName: options.projectName,
467
- status: options.status,
468
- summary: buildRetrofitPlanSummary({
469
- commandMode: options.commandMode,
470
- status: options.status
471
- })
472
- };
473
- }
474
- function getInitPlan(projectDir, options = {}) {
475
- const resolvedProjectDir = path2.resolve(projectDir);
476
- const packageJson = readProjectPackageJson(resolvedProjectDir);
477
- const packageManager = resolveInitPackageManager(resolvedProjectDir, packageJson, options.packageManager);
478
- const workspace = tryResolveWorkspaceProject(resolvedProjectDir);
479
- if (workspace) {
480
- const workspacePackageJson = readProjectPackageJson(workspace.projectDir);
481
- const workspacePackageManager = resolveInitPackageManager(workspace.projectDir, workspacePackageJson, options.packageManager);
482
- const cliSpecifier = getWpTypiaCliSpecifier();
483
- return createRetrofitPlan({
484
- blockTargets: [],
485
- commandMode: "preview-only",
486
- detectedLayout: {
487
- blockNames: [],
488
- description: "Already an official wp-typia workspace.",
489
- kind: "official-workspace"
490
- },
491
- generatedArtifacts: [],
492
- nextSteps: [
493
- "Use `wp-typia add <kind> <name>` to extend the official workspace instead of rerunning init.",
494
- formatRunScript(workspacePackageManager, "sync"),
495
- formatPackageExecCommand(workspacePackageManager, cliSpecifier, "doctor")
496
- ],
497
- notes: [
498
- "The official workspace template already owns inventory, doctor, and add-command workflows."
499
- ],
500
- packageChanges: {
501
- addDevDependencies: [],
502
- scripts: []
503
- },
504
- packageManager: workspacePackageManager,
505
- plannedFiles: [],
506
- projectDir: workspace.projectDir,
507
- projectName: workspace.packageName,
508
- status: "already-initialized"
509
- });
510
- }
511
- const projectName = typeof packageJson?.name === "string" && packageJson.name.length > 0 ? packageJson.name : path2.basename(resolvedProjectDir);
512
- const layout = buildInitLayoutDetails(resolvedProjectDir);
513
- const dependencyChanges = buildDependencyChanges(packageJson);
514
- const scriptChanges = buildScriptChanges(packageJson, packageManager);
515
- const packageManagerFieldChange = buildPackageManagerFieldChange(packageJson, packageManager, {
516
- persistExplicitOverride: typeof options.packageManager === "string"
517
- });
518
- const rawPlannedFiles = layout.kind === "generated-project" || layout.kind === "official-workspace" ? [] : buildPlannedFiles(resolvedProjectDir, layout.kind);
519
- const hasExistingSurface = hasExistingWpTypiaProjectSurface(resolvedProjectDir, packageJson);
520
- const status = hasExistingSurface && dependencyChanges.length === 0 && scriptChanges.length === 0 && packageManagerFieldChange === undefined ? "already-initialized" : "preview";
521
- const plannedFiles = status === "already-initialized" ? [] : rawPlannedFiles;
522
- const detectedLayout = status === "already-initialized" && hasExistingSurface ? {
523
- blockNames: layout.blockNames,
524
- 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"}.`,
525
- kind: "generated-project"
526
- } : {
527
- blockNames: layout.blockNames,
528
- description: layout.description,
529
- kind: layout.kind
530
- };
531
- return createRetrofitPlan({
532
- blockTargets: layout.blockTargets,
533
- commandMode: "preview-only",
534
- detectedLayout,
535
- generatedArtifacts: status === "already-initialized" && detectedLayout.kind === "generated-project" ? [] : layout.generatedArtifacts,
536
- notes: Array.from(new Set([
537
- "Preview only: `wp-typia init` does not write files yet.",
538
- RETROFIT_APPLY_PREVIEW_NOTE,
539
- ...layout.notes
540
- ])),
541
- packageChanges: {
542
- addDevDependencies: dependencyChanges,
543
- ...packageManagerFieldChange ? { packageManagerField: packageManagerFieldChange } : {},
544
- scripts: scriptChanges
545
- },
546
- packageManager,
547
- plannedFiles,
548
- projectDir: resolvedProjectDir,
549
- projectName,
550
- status
551
- });
552
- }
553
-
554
- // ../wp-typia-project-tools/src/runtime/cli-init-templates.ts
555
- import path3 from "path";
556
- function buildRetrofitBlockConfigEntry(target) {
557
- return [
558
- "\t{",
559
- ` slug: ${quoteTsString(target.slug)},`,
560
- ` attributeTypeName: ${quoteTsString(target.attributeTypeName)},`,
561
- ` blockJsonFile: ${quoteTsString(target.blockJsonFile)},`,
562
- ` manifestFile: ${quoteTsString(target.manifestFile)},`,
563
- ` typesFile: ${quoteTsString(target.typesFile)},`,
564
- "\t},"
565
- ].join(`
566
- `);
567
- }
568
- function buildRetrofitBlockConfigSource(targets) {
569
- const blockEntries = targets.map(buildRetrofitBlockConfigEntry).join(`
570
- `);
571
- const baseSource = `export interface WorkspaceBlockConfig {
572
- attributeTypeName: string;
573
- apiTypesFile?: string;
574
- blockJsonFile?: string;
575
- manifestFile?: string;
576
- openApiFile?: string;
577
- restManifest?: ReturnType<
578
- typeof import( '@wp-typia/block-runtime/metadata-core' ).defineEndpointManifest
579
- >;
580
- slug: string;
581
- typesFile: string;
582
- }
583
-
584
- export const BLOCKS: WorkspaceBlockConfig[] = [
585
- ${blockEntries}
586
- ];
587
- `;
588
- return `${updateWorkspaceInventorySource(baseSource)}
589
- `;
590
- }
591
- function buildRetrofitSyncTypesScriptSource() {
592
- return `/* eslint-disable no-console */
593
- import path from 'node:path';
594
-
595
- import { syncBlockMetadata } from '@wp-typia/block-runtime/metadata-core';
596
-
597
- import { BLOCKS } from './block-config';
598
-
599
- function parseCliOptions( argv: string[] ) {
600
- const options = {
601
- check: false,
602
- };
603
-
604
- for ( const argument of argv ) {
605
- if ( argument === '--check' ) {
606
- options.check = true;
607
- continue;
608
- }
609
-
610
- throw new Error( \`Unknown sync-types flag: \${ argument }\` );
611
- }
612
-
613
- return options;
614
- }
615
-
616
- async function main() {
617
- const options = parseCliOptions( process.argv.slice( 2 ) );
618
-
619
- if ( BLOCKS.length === 0 ) {
620
- console.log(
621
- options.check
622
- ? '\u2139\uFE0F No retrofit blocks are registered yet. \`sync-types --check\` is already clean.'
623
- : '\u2139\uFE0F No retrofit blocks are registered yet. Add one block target to scripts/block-config.ts before rerunning sync-types.'
624
- );
625
- return;
626
- }
627
-
628
- for ( const block of BLOCKS ) {
629
- const blockDir = path.dirname( block.typesFile );
630
- const blockJsonFile =
631
- block.blockJsonFile ?? path.join( blockDir, 'block.json' );
632
- const manifestFile =
633
- block.manifestFile ?? path.join( blockDir, 'typia.manifest.json' );
634
- const manifestDir = path.dirname( manifestFile );
635
- const result = await syncBlockMetadata(
636
- {
637
- blockJsonFile,
638
- jsonSchemaFile: path.join( manifestDir, 'typia.schema.json' ),
639
- manifestFile,
640
- openApiFile: path.join( manifestDir, 'typia.openapi.json' ),
641
- sourceTypeName: block.attributeTypeName,
642
- typesFile: block.typesFile,
643
- },
644
- {
645
- check: options.check,
646
- }
647
- );
648
- for ( const warning of result.lossyProjectionWarnings ) {
649
- console.warn( \`\u26A0\uFE0F \${ block.slug }: \${ warning }\` );
650
- }
651
- for ( const warning of result.phpGenerationWarnings ) {
652
- console.warn( \`\u26A0\uFE0F \${ block.slug }: \${ warning }\` );
653
- }
654
-
655
- console.log(
656
- options.check
657
- ? \`\u2705 \${ block.slug }: block.json, typia.manifest.json, typia-validator.php, typia.schema.json, and typia.openapi.json are already up to date with the TypeScript types!\`
658
- : \`\u2705 \${ block.slug }: block.json, typia.manifest.json, typia-validator.php, typia.schema.json, and typia.openapi.json were generated from TypeScript types!\`
659
- );
660
- console.log( '\uD83D\uDCDD Generated attributes:', result.attributeNames );
661
- }
662
- }
663
-
664
- main().catch( ( error ) => {
665
- console.error( '\u274C Type sync failed:', error );
666
- process.exit( 1 );
667
- } );
668
- `;
669
- }
670
- function buildRetrofitSyncProjectScriptSource() {
671
- return `/* eslint-disable no-console */
672
- import { spawnSync } from 'node:child_process';
673
- import fs from 'node:fs';
674
- import path from 'node:path';
675
-
676
- interface SyncCliOptions {
677
- check: boolean;
678
- }
679
-
680
- function parseCliOptions( argv: string[] ): SyncCliOptions {
681
- const options: SyncCliOptions = {
682
- check: false,
683
- };
684
-
685
- for ( const argument of argv ) {
686
- if ( argument === '--check' ) {
687
- options.check = true;
688
- continue;
689
- }
690
-
691
- throw new Error( \`Unknown sync flag: \${ argument }\` );
692
- }
693
-
694
- return options;
695
- }
696
-
697
- function getSyncScriptEnv() {
698
- const binaryDirectory = path.join( process.cwd(), 'node_modules', '.bin' );
699
- const inheritedPath =
700
- process.env.PATH ??
701
- process.env.Path ??
702
- Object.entries( process.env ).find(
703
- ( [ key ] ) => key.toLowerCase() === 'path'
704
- )?.[ 1 ] ??
705
- '';
706
- const nextPath = fs.existsSync( binaryDirectory )
707
- ? \`\${ binaryDirectory }\${ path.delimiter }\${ inheritedPath }\`
708
- : inheritedPath;
709
- const env: NodeJS.ProcessEnv = {
710
- ...process.env,
711
- };
712
-
713
- for ( const key of Object.keys( env ) ) {
714
- if ( key.toLowerCase() === 'path' ) {
715
- delete env[ key ];
716
- }
717
- }
718
-
719
- env.PATH = nextPath;
720
-
721
- return env;
722
- }
723
-
724
- function getOptionalNodeErrorCode( error: unknown ): string | undefined {
725
- return typeof error === 'object' && error !== null && 'code' in error
726
- ? String( ( error as { code: unknown } ).code )
727
- : undefined;
728
- }
729
-
730
- function isFileNotFoundError( error: unknown ): boolean {
731
- return getOptionalNodeErrorCode( error ) === 'ENOENT';
732
- }
733
-
734
- function runSyncScript( scriptPath: string, options: SyncCliOptions ) {
735
- const args = [ scriptPath ];
736
- if ( options.check ) {
737
- args.push( '--check' );
738
- }
739
-
740
- const result = spawnSync( 'tsx', args, {
741
- cwd: process.cwd(),
742
- env: getSyncScriptEnv(),
743
- shell: process.platform === 'win32',
744
- stdio: 'inherit',
745
- } );
746
-
747
- if ( result.error ) {
748
- if ( isFileNotFoundError( result.error ) ) {
749
- throw new Error(
750
- 'Unable to resolve \`tsx\` for project sync. Install project dependencies or rerun the command through your package manager.'
751
- );
752
- }
753
-
754
- throw result.error;
755
- }
756
-
757
- if ( result.status !== 0 ) {
758
- throw new Error( \`Sync script failed: \${ scriptPath }\` );
759
- }
760
- }
761
-
762
- async function main() {
763
- const options = parseCliOptions( process.argv.slice( 2 ) );
764
- const syncTypesScriptPath = path.join( 'scripts', 'sync-types-to-block-json.ts' );
765
-
766
- runSyncScript( syncTypesScriptPath, options );
767
-
768
- console.log(
769
- options.check
770
- ? '\u2705 Generated project metadata is already synchronized.'
771
- : '\u2705 Generated project metadata was synchronized.'
772
- );
773
- }
774
-
775
- main().catch( ( error ) => {
776
- console.error( '\u274C Project sync failed:', error );
777
- process.exit( 1 );
778
- } );
779
- `;
780
- }
781
- function buildRetrofitHelperFiles(blockTargets) {
782
- return {
783
- [path3.join("scripts", "block-config.ts")]: buildRetrofitBlockConfigSource(blockTargets),
784
- [path3.join("scripts", "sync-project.ts")]: buildRetrofitSyncProjectScriptSource(),
785
- [path3.join("scripts", "sync-types-to-block-json.ts")]: buildRetrofitSyncTypesScriptSource()
786
- };
787
- }
788
-
789
- // ../wp-typia-project-tools/src/runtime/cli-init-apply.ts
790
- async function createRetrofitMutationSnapshot(projectDir, filePaths) {
791
- const scriptsDir = path4.join(projectDir, "scripts");
792
- const scriptsDirExisted = fs3.existsSync(scriptsDir);
793
- const fileSources = await snapshotWorkspaceFiles(filePaths);
794
- const targetPaths = fileSources.filter((entry) => entry.source === null).map((entry) => entry.filePath);
795
- if (!scriptsDirExisted) {
796
- targetPaths.push(scriptsDir);
797
- }
798
- return {
799
- fileSources,
800
- snapshotDirs: [],
801
- targetPaths
802
- };
803
- }
804
- async function writeRetrofitFiles(options) {
805
- const helperFiles = buildRetrofitHelperFiles(options.blockTargets);
806
- const scriptsDir = path4.join(options.projectDir, "scripts");
807
- await fsp.mkdir(scriptsDir, { recursive: true });
808
- await fsp.writeFile(path4.join(options.projectDir, "package.json"), buildProjectPackageJsonSource(options.packageJson), "utf8");
809
- for (const [relativePath, source] of Object.entries(helperFiles)) {
810
- await fsp.writeFile(path4.join(options.projectDir, relativePath), source, "utf8");
811
- }
812
- }
813
- function buildApplyFailureError(error) {
814
- const message = error instanceof Error ? error.message : String(error);
815
- 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);
816
- }
817
- function toApplyNotes(previewNotes) {
818
- return Array.from(new Set([
819
- ...previewNotes.filter((note) => note !== "Preview only: `wp-typia init` does not write files yet." && note !== RETROFIT_APPLY_PREVIEW_NOTE),
820
- RETROFIT_ROLLBACK_NOTE
821
- ]));
822
- }
823
- async function applyInitPlan(projectDir, options = {}) {
824
- const previewPlan = getInitPlan(projectDir, options);
825
- if (previewPlan.detectedLayout.kind === "unsupported") {
826
- throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.INVALID_ARGUMENT, "`wp-typia init --apply` requires a supported retrofit layout. Run `wp-typia init` first to inspect the preview plan and any blocking notes.");
827
- }
828
- if (previewPlan.status === "already-initialized") {
829
- return createRetrofitPlan({
830
- ...previewPlan,
831
- commandMode: "apply",
832
- notes: toApplyNotes(previewPlan.notes),
833
- status: "already-initialized"
834
- });
835
- }
836
- const nextPackageJson = buildNextProjectPackageJson({
837
- packageChanges: previewPlan.packageChanges,
838
- packageJson: readProjectPackageJson(previewPlan.projectDir),
839
- packageManager: previewPlan.packageManager,
840
- projectName: previewPlan.projectName
841
- });
842
- const helperFiles = buildRetrofitHelperFiles(previewPlan.blockTargets);
843
- const filePaths = [
844
- path4.join(previewPlan.projectDir, "package.json"),
845
- ...Object.keys(helperFiles).map((relativePath) => path4.join(previewPlan.projectDir, relativePath))
846
- ];
847
- const mutationSnapshot = await createRetrofitMutationSnapshot(previewPlan.projectDir, filePaths);
848
- try {
849
- await writeRetrofitFiles({
850
- blockTargets: previewPlan.blockTargets,
851
- packageJson: nextPackageJson,
852
- projectDir: previewPlan.projectDir
853
- });
854
- } catch (error) {
855
- await rollbackWorkspaceMutation(mutationSnapshot);
856
- throw buildApplyFailureError(error);
857
- }
858
- return createRetrofitPlan({
859
- ...previewPlan,
860
- commandMode: "apply",
861
- notes: toApplyNotes(previewPlan.notes),
862
- status: "applied"
863
- });
864
- }
865
-
866
- // ../wp-typia-project-tools/src/runtime/cli-init.ts
867
- async function runInitCommand(options) {
868
- return options.apply ? applyInitPlan(options.projectDir, {
869
- packageManager: options.packageManager
870
- }) : getInitPlan(options.projectDir, {
871
- packageManager: options.packageManager
872
- });
873
- }
874
- export {
875
- runInitCommand,
876
- getInitPlan,
877
- applyInitPlan
878
- };
879
-
880
- //# debugId=DC4EACE5C620361164756E2164756E21