wp-typia 0.22.8 → 0.22.10
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/dist-bunli/.bunli/commands.gen.js +3522 -3250
- package/dist-bunli/{cli-pnjx2e2h.js → cli-1k61xyn2.js} +14 -9
- package/dist-bunli/{cli-arz4rcye.js → cli-2mswafd6.js} +6 -6
- package/dist-bunli/{cli-fa7g1aqm.js → cli-2x49egkd.js} +52 -58
- package/dist-bunli/{cli-bbj0kn1e.js → cli-3fzqhpx9.js} +477 -455
- package/dist-bunli/{cli-mzvzbpnz.js → cli-8reep89s.js} +5 -27
- package/dist-bunli/{cli-add-1xvw17yg.js → cli-add-8rvmezy0.js} +37 -21
- package/dist-bunli/cli-cvxvcw7c.js +46 -0
- package/dist-bunli/{cli-doctor-bjv6z74k.js → cli-doctor-5m6xyx9q.js} +8 -7
- package/dist-bunli/{cli-init-zdfrmp3y.js → cli-init-qv3zxmvc.js} +5 -4
- package/dist-bunli/{cli-scaffold-pbb67zxg.js → cli-scaffold-b1ex2y80.js} +14 -12
- package/dist-bunli/{cli-e7n7hbvr.js → cli-spdrcg8k.js} +117 -99
- package/dist-bunli/{cli-bwwssctv.js → cli-tjf0070f.js} +9 -5
- package/dist-bunli/cli.js +2 -2
- package/dist-bunli/{command-list-hbcv3bz6.js → command-list-h96cft88.js} +1188 -1005
- package/dist-bunli/{create-template-validation-7k2752mz.js → create-template-validation-rtec5sng.js} +3 -2
- package/dist-bunli/{migrations-ads3j14z.js → migrations-7g9rag5d.js} +5 -4
- package/dist-bunli/node-cli.js +1337 -1123
- package/package.json +2 -2
|
@@ -11,13 +11,15 @@ import {
|
|
|
11
11
|
WP_TYPIA_TOP_LEVEL_COMMAND_NAMES,
|
|
12
12
|
buildCommandOptions,
|
|
13
13
|
emitCliDiagnosticFailure,
|
|
14
|
+
formatAddKindList,
|
|
15
|
+
formatAddKindUsagePlaceholder,
|
|
14
16
|
getAddBlockDefaults,
|
|
15
17
|
getCreateDefaults,
|
|
16
18
|
getMcpSchemaSources,
|
|
17
19
|
package_default,
|
|
18
20
|
prefersStructuredCliOutput,
|
|
19
21
|
resolveCommandOptionValues
|
|
20
|
-
} from "./cli-
|
|
22
|
+
} from "./cli-spdrcg8k.js";
|
|
21
23
|
import {
|
|
22
24
|
Result,
|
|
23
25
|
TaggedError,
|
|
@@ -42,10 +44,12 @@ import {
|
|
|
42
44
|
createCliDiagnosticCodeError
|
|
43
45
|
} from "./cli-p95wr1q8.js";
|
|
44
46
|
import {
|
|
47
|
+
PACKAGE_MANAGER_IDS,
|
|
45
48
|
formatInstallCommand,
|
|
46
49
|
formatPackageExecCommand,
|
|
47
50
|
formatRunScript,
|
|
48
|
-
inferPackageManagerId
|
|
51
|
+
inferPackageManagerId,
|
|
52
|
+
parsePackageManagerField
|
|
49
53
|
} from "./cli-52ke0ptp.js";
|
|
50
54
|
import {
|
|
51
55
|
__require,
|
|
@@ -67,7 +71,7 @@ function resolveBundledModuleHref(baseUrl, candidates, options = {}) {
|
|
|
67
71
|
}
|
|
68
72
|
const missingCandidates = candidates.map((candidate) => fileURLToPath(new URL(candidate, baseUrl)));
|
|
69
73
|
const label = options.moduleLabel ?? "bundled wp-typia runtime module";
|
|
70
|
-
throw
|
|
74
|
+
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_BUILD_ARTIFACT, [
|
|
71
75
|
`Missing bundled build artifacts for ${label}.`,
|
|
72
76
|
"None of the expected files were found:",
|
|
73
77
|
...missingCandidates.map((candidatePath) => `- ${candidatePath}`),
|
|
@@ -76,63 +80,7 @@ function resolveBundledModuleHref(baseUrl, candidates, options = {}) {
|
|
|
76
80
|
`));
|
|
77
81
|
}
|
|
78
82
|
|
|
79
|
-
// src/
|
|
80
|
-
function readOptionalCliStringFlagValue(flags, name, mode) {
|
|
81
|
-
const value = flags[name];
|
|
82
|
-
if (value === undefined || value === null) {
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
if (typeof value !== "string") {
|
|
86
|
-
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, `\`--${name}\` requires a value.`);
|
|
87
|
-
}
|
|
88
|
-
const trimmed = value.trim();
|
|
89
|
-
if (trimmed.length === 0) {
|
|
90
|
-
if (mode === "strict") {
|
|
91
|
-
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, `\`--${name}\` requires a value.`);
|
|
92
|
-
}
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
return mode === "strict" ? value : trimmed;
|
|
96
|
-
}
|
|
97
|
-
function readOptionalLooseStringFlag(flags, name) {
|
|
98
|
-
return readOptionalCliStringFlagValue(flags, name, "loose");
|
|
99
|
-
}
|
|
100
|
-
function readOptionalStrictStringFlag(flags, name) {
|
|
101
|
-
return readOptionalCliStringFlagValue(flags, name, "strict");
|
|
102
|
-
}
|
|
103
|
-
function requireStrictStringFlag(flags, name, message) {
|
|
104
|
-
const value = readOptionalStrictStringFlag(flags, name);
|
|
105
|
-
if (!value) {
|
|
106
|
-
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, message);
|
|
107
|
-
}
|
|
108
|
-
return value;
|
|
109
|
-
}
|
|
110
|
-
function readOptionalPairedStrictStringFlags(flags, leftName, rightName, message) {
|
|
111
|
-
const leftValue = readOptionalStrictStringFlag(flags, leftName);
|
|
112
|
-
const rightValue = readOptionalStrictStringFlag(flags, rightName);
|
|
113
|
-
if (Boolean(leftValue) !== Boolean(rightValue)) {
|
|
114
|
-
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, message);
|
|
115
|
-
}
|
|
116
|
-
return [leftValue, rightValue];
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// src/external-layer-prompt-options.ts
|
|
120
|
-
function formatExternalLayerSelectHint(option2) {
|
|
121
|
-
const details = [
|
|
122
|
-
option2.description,
|
|
123
|
-
option2.extends.length > 0 ? `extends ${option2.extends.join(", ")}` : undefined
|
|
124
|
-
].filter((value) => typeof value === "string" && value.length > 0);
|
|
125
|
-
return details.length > 0 ? details.join(" \xB7 ") : undefined;
|
|
126
|
-
}
|
|
127
|
-
function toExternalLayerPromptOptions(options) {
|
|
128
|
-
return options.map((option2) => ({
|
|
129
|
-
hint: formatExternalLayerSelectHint(option2),
|
|
130
|
-
label: option2.id,
|
|
131
|
-
value: option2.id
|
|
132
|
-
}));
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// src/add-kind-registry.ts
|
|
83
|
+
// src/add-kind-registry-shared.ts
|
|
136
84
|
var BLOCK_VISIBLE_FIELD_ORDER = [
|
|
137
85
|
"kind",
|
|
138
86
|
"name",
|
|
@@ -214,509 +162,627 @@ function isAddPersistenceTemplate(template) {
|
|
|
214
162
|
function formatAddBlockTemplateIds(addRuntime) {
|
|
215
163
|
return addRuntime.ADD_BLOCK_TEMPLATE_IDS.join(", ");
|
|
216
164
|
}
|
|
165
|
+
function getMistypedAddBlockTemplateMessage(addRuntime, templateId) {
|
|
166
|
+
const suggestion = addRuntime.suggestAddBlockTemplateId(templateId);
|
|
167
|
+
if (!suggestion) {
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
return `Unknown add-block template "${templateId}". Did you mean "${suggestion}"? Use \`--template ${suggestion}\`, or run \`wp-typia templates list\` to inspect available templates.`;
|
|
171
|
+
}
|
|
217
172
|
function assertAddBlockTemplateId(context, templateId) {
|
|
173
|
+
if (templateId === "query-loop") {
|
|
174
|
+
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.INVALID_ARGUMENT, "`wp-typia add block --template query-loop` is not supported. Query Loop is a create-time `core/query` variation scaffold, so use `wp-typia create <project-dir> --template query-loop` instead.");
|
|
175
|
+
}
|
|
218
176
|
if (context.addRuntime.isAddBlockTemplateId(templateId)) {
|
|
219
177
|
return templateId;
|
|
220
178
|
}
|
|
221
|
-
|
|
222
|
-
|
|
179
|
+
const mistypedAddBlockTemplateMessage = getMistypedAddBlockTemplateMessage(context.addRuntime, templateId);
|
|
180
|
+
if (mistypedAddBlockTemplateMessage) {
|
|
181
|
+
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.UNKNOWN_TEMPLATE, mistypedAddBlockTemplateMessage);
|
|
223
182
|
}
|
|
224
183
|
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.UNKNOWN_TEMPLATE, `Unknown add-block template "${templateId}". Expected one of: ${formatAddBlockTemplateIds(context.addRuntime)}. Run \`wp-typia templates list\` to inspect available templates.`);
|
|
225
184
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
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
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
})
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
})
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
visibleFieldNames: () => NAME_ONLY_VISIBLE_FIELDS
|
|
523
|
-
}),
|
|
524
|
-
style: defineAddKindRegistryEntry({
|
|
525
|
-
completion: {
|
|
526
|
-
nextSteps: (values) => [
|
|
527
|
-
`Review src/blocks/${values.blockSlug}/styles/${values.styleSlug}.ts.`,
|
|
528
|
-
"Run your workspace build or dev command to verify the new block style registration."
|
|
529
|
-
],
|
|
530
|
-
summaryLines: (values, projectDir) => [
|
|
531
|
-
`Block style: ${values.styleSlug}`,
|
|
532
|
-
`Target block: ${values.blockSlug}`,
|
|
533
|
-
`Project directory: ${projectDir}`
|
|
534
|
-
],
|
|
535
|
-
title: "Added block style"
|
|
536
|
-
},
|
|
537
|
-
description: "Add a Block Styles registration to an existing block",
|
|
538
|
-
nameLabel: "Style name",
|
|
539
|
-
async prepareExecution(context) {
|
|
540
|
-
const name = requireAddKindName(context, "`wp-typia add style` requires <name>. Usage: wp-typia add style <name> --block <block-slug>.");
|
|
541
|
-
const blockSlug = requireStrictStringFlag(context.flags, "block", "`wp-typia add style` requires --block <block-slug>.");
|
|
542
|
-
return createNamedExecutionPlan(context, {
|
|
543
|
-
execute: ({ cwd, name: name2 }) => context.addRuntime.runAddBlockStyleCommand({
|
|
544
|
-
blockName: blockSlug,
|
|
545
|
-
cwd,
|
|
546
|
-
styleName: name2
|
|
547
|
-
}),
|
|
548
|
-
getValues: (result) => ({
|
|
549
|
-
blockSlug: result.blockSlug,
|
|
550
|
-
styleSlug: result.styleSlug
|
|
551
|
-
}),
|
|
552
|
-
missingNameMessage: "`wp-typia add style` requires <name>. Usage: wp-typia add style <name> --block <block-slug>.",
|
|
553
|
-
name
|
|
554
|
-
});
|
|
555
|
-
},
|
|
556
|
-
sortOrder: 40,
|
|
557
|
-
supportsDryRun: true,
|
|
558
|
-
usage: "wp-typia add style <name> --block <block-slug> [--dry-run]",
|
|
559
|
-
visibleFieldNames: () => NAME_BLOCK_VISIBLE_FIELDS
|
|
560
|
-
}),
|
|
561
|
-
transform: defineAddKindRegistryEntry({
|
|
562
|
-
completion: {
|
|
563
|
-
nextSteps: (values) => [
|
|
564
|
-
`Review src/blocks/${values.blockSlug}/transforms/${values.transformSlug}.ts.`,
|
|
565
|
-
"Run your workspace build or dev command to verify the new block transform registration."
|
|
566
|
-
],
|
|
567
|
-
summaryLines: (values, projectDir) => [
|
|
568
|
-
`Block transform: ${values.transformSlug}`,
|
|
569
|
-
`From: ${values.fromBlockName}`,
|
|
570
|
-
`To: ${values.toBlockName}`,
|
|
571
|
-
`Project directory: ${projectDir}`
|
|
572
|
-
],
|
|
573
|
-
title: "Added block transform"
|
|
574
|
-
},
|
|
575
|
-
description: "Add a block-to-block transform into a workspace block",
|
|
576
|
-
nameLabel: "Transform name",
|
|
577
|
-
async prepareExecution(context) {
|
|
578
|
-
const name = requireAddKindName(context, "`wp-typia add transform` requires <name>. Usage: wp-typia add transform <name> --from <namespace/block> --to <block-slug|namespace/block-slug>.");
|
|
579
|
-
const fromBlockName = requireStrictStringFlag(context.flags, "from", "`wp-typia add transform` requires --from <namespace/block>.");
|
|
580
|
-
const toBlockName = requireStrictStringFlag(context.flags, "to", "`wp-typia add transform` requires --to <block-slug|namespace/block-slug>.");
|
|
581
|
-
return createNamedExecutionPlan(context, {
|
|
582
|
-
execute: ({ cwd, name: name2 }) => context.addRuntime.runAddBlockTransformCommand({
|
|
583
|
-
cwd,
|
|
584
|
-
fromBlockName,
|
|
585
|
-
toBlockName,
|
|
586
|
-
transformName: name2
|
|
587
|
-
}),
|
|
588
|
-
getValues: (result) => ({
|
|
589
|
-
blockSlug: result.blockSlug,
|
|
590
|
-
fromBlockName: result.fromBlockName,
|
|
591
|
-
toBlockName: result.toBlockName,
|
|
592
|
-
transformSlug: result.transformSlug
|
|
593
|
-
}),
|
|
594
|
-
missingNameMessage: "`wp-typia add transform` requires <name>. Usage: wp-typia add transform <name> --from <namespace/block> --to <block-slug|namespace/block-slug>.",
|
|
595
|
-
name
|
|
596
|
-
});
|
|
597
|
-
},
|
|
598
|
-
sortOrder: 50,
|
|
599
|
-
supportsDryRun: true,
|
|
600
|
-
usage: "wp-typia add transform <name> --from <namespace/block> --to <block-slug|namespace/block-slug> [--dry-run]",
|
|
601
|
-
visibleFieldNames: () => NAME_FROM_TO_VISIBLE_FIELDS
|
|
602
|
-
}),
|
|
603
|
-
"rest-resource": defineAddKindRegistryEntry({
|
|
604
|
-
completion: {
|
|
605
|
-
nextSteps: (values) => [
|
|
606
|
-
`Review src/rest/${values.restResourceSlug}/ and inc/rest/${values.restResourceSlug}.php.`,
|
|
607
|
-
"Run your workspace build or dev command to verify the generated REST resource contract."
|
|
608
|
-
],
|
|
609
|
-
summaryLines: (values, projectDir) => [
|
|
610
|
-
`REST resource: ${values.restResourceSlug}`,
|
|
611
|
-
`Namespace: ${values.namespace}`,
|
|
612
|
-
`Methods: ${values.methods}`,
|
|
613
|
-
`Project directory: ${projectDir}`
|
|
614
|
-
],
|
|
615
|
-
title: "Added plugin-level REST resource"
|
|
616
|
-
},
|
|
617
|
-
description: "Add a plugin-level typed REST resource",
|
|
618
|
-
nameLabel: "REST resource name",
|
|
619
|
-
async prepareExecution(context) {
|
|
620
|
-
const name = requireAddKindName(context, "`wp-typia add rest-resource` requires <name>. Usage: wp-typia add rest-resource <name> [--namespace <vendor/v1>] [--methods <list,read,create>].");
|
|
621
|
-
const methods = readOptionalStrictStringFlag(context.flags, "methods");
|
|
622
|
-
const namespace = readOptionalStrictStringFlag(context.flags, "namespace");
|
|
623
|
-
return createNamedExecutionPlan(context, {
|
|
624
|
-
execute: ({ cwd, name: name2 }) => context.addRuntime.runAddRestResourceCommand({
|
|
625
|
-
cwd,
|
|
626
|
-
methods,
|
|
627
|
-
namespace,
|
|
628
|
-
restResourceName: name2
|
|
629
|
-
}),
|
|
630
|
-
getValues: (result) => ({
|
|
631
|
-
methods: result.methods.join(", "),
|
|
632
|
-
namespace: result.namespace,
|
|
633
|
-
restResourceSlug: result.restResourceSlug
|
|
634
|
-
}),
|
|
635
|
-
missingNameMessage: "`wp-typia add rest-resource` requires <name>. Usage: wp-typia add rest-resource <name> [--namespace <vendor/v1>] [--methods <list,read,create>].",
|
|
636
|
-
name
|
|
637
|
-
});
|
|
638
|
-
},
|
|
639
|
-
sortOrder: 80,
|
|
640
|
-
supportsDryRun: true,
|
|
641
|
-
usage: "wp-typia add rest-resource <name> [--namespace <vendor/v1>] [--methods <list,read,create,update,delete>] [--dry-run]",
|
|
642
|
-
visibleFieldNames: () => NAME_NAMESPACE_METHODS_VISIBLE_FIELDS
|
|
643
|
-
}),
|
|
644
|
-
"ai-feature": defineAddKindRegistryEntry({
|
|
645
|
-
completion: {
|
|
646
|
-
nextSteps: (values) => [
|
|
647
|
-
`Review src/ai-features/${values.aiFeatureSlug}/ and inc/ai-features/${values.aiFeatureSlug}.php.`,
|
|
648
|
-
"Run `wp-typia sync-rest` and `wp-typia sync ai` or your workspace build/dev command to verify the generated REST artifacts and AI schema."
|
|
649
|
-
],
|
|
650
|
-
summaryLines: (values, projectDir) => [
|
|
651
|
-
`AI feature: ${values.aiFeatureSlug}`,
|
|
652
|
-
`Namespace: ${values.namespace}`,
|
|
653
|
-
`Project directory: ${projectDir}`
|
|
654
|
-
],
|
|
655
|
-
title: "Added server-only AI feature"
|
|
656
|
-
},
|
|
657
|
-
description: "Add a server-owned WordPress AI feature endpoint",
|
|
658
|
-
nameLabel: "AI feature name",
|
|
659
|
-
async prepareExecution(context) {
|
|
660
|
-
const name = requireAddKindName(context, "`wp-typia add ai-feature` requires <name>. Usage: wp-typia add ai-feature <name> [--namespace <vendor/v1>].");
|
|
661
|
-
const namespace = readOptionalStrictStringFlag(context.flags, "namespace");
|
|
662
|
-
return createNamedExecutionPlan(context, {
|
|
663
|
-
execute: ({ cwd, name: name2 }) => context.addRuntime.runAddAiFeatureCommand({
|
|
664
|
-
aiFeatureName: name2,
|
|
665
|
-
cwd,
|
|
666
|
-
namespace
|
|
667
|
-
}),
|
|
668
|
-
getValues: (result) => ({
|
|
669
|
-
aiFeatureSlug: result.aiFeatureSlug,
|
|
670
|
-
namespace: result.namespace
|
|
671
|
-
}),
|
|
672
|
-
getWarnings: (result) => result.warnings,
|
|
673
|
-
missingNameMessage: "`wp-typia add ai-feature` requires <name>. Usage: wp-typia add ai-feature <name> [--namespace <vendor/v1>].",
|
|
674
|
-
name,
|
|
675
|
-
warnLine: context.warnLine
|
|
676
|
-
});
|
|
677
|
-
},
|
|
678
|
-
sortOrder: 100,
|
|
679
|
-
supportsDryRun: true,
|
|
680
|
-
usage: "wp-typia add ai-feature <name> [--namespace <vendor/v1>] [--dry-run]",
|
|
681
|
-
visibleFieldNames: () => NAME_NAMESPACE_VISIBLE_FIELDS
|
|
682
|
-
}),
|
|
683
|
-
variation: defineAddKindRegistryEntry({
|
|
684
|
-
completion: {
|
|
685
|
-
nextSteps: (values) => [
|
|
686
|
-
`Review src/blocks/${values.blockSlug}/variations/${values.variationSlug}.ts.`,
|
|
687
|
-
"Run your workspace build or dev command to pick up the new variation."
|
|
688
|
-
],
|
|
689
|
-
summaryLines: (values, projectDir) => [
|
|
690
|
-
`Variation: ${values.variationSlug}`,
|
|
691
|
-
`Target block: ${values.blockSlug}`,
|
|
692
|
-
`Project directory: ${projectDir}`
|
|
693
|
-
],
|
|
694
|
-
title: "Added workspace variation"
|
|
695
|
-
},
|
|
696
|
-
description: "Add a variation to an existing block",
|
|
697
|
-
nameLabel: "Variation name",
|
|
698
|
-
async prepareExecution(context) {
|
|
699
|
-
const name = requireAddKindName(context, "`wp-typia add variation` requires <name>. Usage: wp-typia add variation <name> --block <block-slug>");
|
|
700
|
-
const blockSlug = requireStrictStringFlag(context.flags, "block", "`wp-typia add variation` requires --block <block-slug>.");
|
|
701
|
-
return createNamedExecutionPlan(context, {
|
|
702
|
-
execute: ({ cwd, name: name2 }) => context.addRuntime.runAddVariationCommand({
|
|
703
|
-
blockName: blockSlug,
|
|
704
|
-
cwd,
|
|
705
|
-
variationName: name2
|
|
706
|
-
}),
|
|
707
|
-
getValues: (result) => ({
|
|
708
|
-
blockSlug: result.blockSlug,
|
|
709
|
-
variationSlug: result.variationSlug
|
|
710
|
-
}),
|
|
711
|
-
missingNameMessage: "`wp-typia add variation` requires <name>. Usage: wp-typia add variation <name> --block <block-slug>",
|
|
712
|
-
name
|
|
713
|
-
});
|
|
714
|
-
},
|
|
715
|
-
sortOrder: 30,
|
|
716
|
-
supportsDryRun: true,
|
|
717
|
-
usage: "wp-typia add variation <name> --block <block-slug> [--dry-run]",
|
|
718
|
-
visibleFieldNames: () => NAME_BLOCK_VISIBLE_FIELDS
|
|
185
|
+
|
|
186
|
+
// src/add-kinds/ability.ts
|
|
187
|
+
var ABILITY_MISSING_NAME_MESSAGE = "`wp-typia add ability` requires <name>. Usage: wp-typia add ability <name>.";
|
|
188
|
+
var abilityAddKindEntry = defineAddKindRegistryEntry({
|
|
189
|
+
completion: {
|
|
190
|
+
nextSteps: (values) => [
|
|
191
|
+
`Review src/abilities/${values.abilitySlug}/ and inc/abilities/${values.abilitySlug}.php.`,
|
|
192
|
+
"Run `wp-typia sync` or `npm run sync-abilities -- --check` and then your workspace build/dev command to verify the generated workflow ability."
|
|
193
|
+
],
|
|
194
|
+
summaryLines: (values, projectDir) => [
|
|
195
|
+
`Ability: ${values.abilitySlug}`,
|
|
196
|
+
`Project directory: ${projectDir}`
|
|
197
|
+
],
|
|
198
|
+
title: "Added workflow ability"
|
|
199
|
+
},
|
|
200
|
+
description: "Add a typed server/client workflow ability scaffold",
|
|
201
|
+
nameLabel: "Ability name",
|
|
202
|
+
async prepareExecution(context) {
|
|
203
|
+
return createNamedExecutionPlan(context, {
|
|
204
|
+
execute: ({ cwd, name }) => context.addRuntime.runAddAbilityCommand({
|
|
205
|
+
abilityName: name,
|
|
206
|
+
cwd
|
|
207
|
+
}),
|
|
208
|
+
getValues: (result) => ({
|
|
209
|
+
abilitySlug: result.abilitySlug
|
|
210
|
+
}),
|
|
211
|
+
getWarnings: (result) => result.warnings,
|
|
212
|
+
missingNameMessage: ABILITY_MISSING_NAME_MESSAGE,
|
|
213
|
+
warnLine: context.warnLine
|
|
214
|
+
});
|
|
215
|
+
},
|
|
216
|
+
sortOrder: 90,
|
|
217
|
+
supportsDryRun: true,
|
|
218
|
+
usage: "wp-typia add ability <name> [--dry-run]",
|
|
219
|
+
visibleFieldNames: () => NAME_ONLY_VISIBLE_FIELDS
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
// src/cli-string-flags.ts
|
|
223
|
+
function readOptionalCliStringFlagValue(flags, name, mode) {
|
|
224
|
+
const value = flags[name];
|
|
225
|
+
if (value === undefined || value === null) {
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
if (typeof value !== "string") {
|
|
229
|
+
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, `\`--${name}\` requires a value.`);
|
|
230
|
+
}
|
|
231
|
+
const trimmed = value.trim();
|
|
232
|
+
if (trimmed.length === 0) {
|
|
233
|
+
if (mode === "strict") {
|
|
234
|
+
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, `\`--${name}\` requires a value.`);
|
|
235
|
+
}
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
return mode === "strict" ? value : trimmed;
|
|
239
|
+
}
|
|
240
|
+
function readOptionalLooseStringFlag(flags, name) {
|
|
241
|
+
return readOptionalCliStringFlagValue(flags, name, "loose");
|
|
242
|
+
}
|
|
243
|
+
function readOptionalStrictStringFlag(flags, name) {
|
|
244
|
+
return readOptionalCliStringFlagValue(flags, name, "strict");
|
|
245
|
+
}
|
|
246
|
+
function requireStrictStringFlag(flags, name, message) {
|
|
247
|
+
const value = readOptionalStrictStringFlag(flags, name);
|
|
248
|
+
if (!value) {
|
|
249
|
+
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, message);
|
|
250
|
+
}
|
|
251
|
+
return value;
|
|
252
|
+
}
|
|
253
|
+
function readOptionalPairedStrictStringFlags(flags, leftName, rightName, message) {
|
|
254
|
+
const leftValue = readOptionalStrictStringFlag(flags, leftName);
|
|
255
|
+
const rightValue = readOptionalStrictStringFlag(flags, rightName);
|
|
256
|
+
if (Boolean(leftValue) !== Boolean(rightValue)) {
|
|
257
|
+
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, message);
|
|
258
|
+
}
|
|
259
|
+
return [leftValue, rightValue];
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// src/add-kinds/admin-view.ts
|
|
263
|
+
var ADMIN_VIEW_MISSING_NAME_MESSAGE = "`wp-typia add admin-view` requires <name>. Usage: wp-typia add admin-view <name> [--source <rest-resource:slug|core-data:kind/name>].";
|
|
264
|
+
var adminViewAddKindEntry = defineAddKindRegistryEntry({
|
|
265
|
+
completion: {
|
|
266
|
+
nextSteps: (values) => [
|
|
267
|
+
`Review src/admin-views/${values.adminViewSlug}/ and inc/admin-views/${values.adminViewSlug}.php.`,
|
|
268
|
+
"Run your workspace build or dev command to verify the generated DataViews admin screen."
|
|
269
|
+
],
|
|
270
|
+
summaryLines: (values, projectDir) => [
|
|
271
|
+
`Admin view: ${values.adminViewSlug}`,
|
|
272
|
+
...values.source ? [`Source: ${values.source}`] : [],
|
|
273
|
+
`Project directory: ${projectDir}`
|
|
274
|
+
],
|
|
275
|
+
title: "Added DataViews admin screen"
|
|
276
|
+
},
|
|
277
|
+
description: "Add an opt-in DataViews-powered admin screen",
|
|
278
|
+
nameLabel: "Admin view name",
|
|
279
|
+
async prepareExecution(context) {
|
|
280
|
+
const name = requireAddKindName(context, ADMIN_VIEW_MISSING_NAME_MESSAGE);
|
|
281
|
+
const source = readOptionalStrictStringFlag(context.flags, "source");
|
|
282
|
+
return createNamedExecutionPlan(context, {
|
|
283
|
+
execute: ({ cwd, name: name2 }) => context.addRuntime.runAddAdminViewCommand({
|
|
284
|
+
adminViewName: name2,
|
|
285
|
+
cwd,
|
|
286
|
+
source
|
|
287
|
+
}),
|
|
288
|
+
getValues: (result) => ({
|
|
289
|
+
adminViewSlug: result.adminViewSlug,
|
|
290
|
+
...result.source ? { source: result.source } : {}
|
|
291
|
+
}),
|
|
292
|
+
missingNameMessage: ADMIN_VIEW_MISSING_NAME_MESSAGE,
|
|
293
|
+
name
|
|
294
|
+
});
|
|
295
|
+
},
|
|
296
|
+
sortOrder: 10,
|
|
297
|
+
supportsDryRun: true,
|
|
298
|
+
usage: "wp-typia add admin-view <name> [--source <rest-resource:slug|core-data:kind/name>] [--dry-run]",
|
|
299
|
+
visibleFieldNames: () => NAME_SOURCE_VISIBLE_FIELDS
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
// src/add-kinds/ai-feature.ts
|
|
303
|
+
var AI_FEATURE_MISSING_NAME_MESSAGE = "`wp-typia add ai-feature` requires <name>. Usage: wp-typia add ai-feature <name> [--namespace <vendor/v1>].";
|
|
304
|
+
var aiFeatureAddKindEntry = defineAddKindRegistryEntry({
|
|
305
|
+
completion: {
|
|
306
|
+
nextSteps: (values) => [
|
|
307
|
+
`Review src/ai-features/${values.aiFeatureSlug}/ and inc/ai-features/${values.aiFeatureSlug}.php.`,
|
|
308
|
+
"Run `wp-typia sync-rest` and `wp-typia sync ai` or your workspace build/dev command to verify the generated REST artifacts and AI schema."
|
|
309
|
+
],
|
|
310
|
+
summaryLines: (values, projectDir) => [
|
|
311
|
+
`AI feature: ${values.aiFeatureSlug}`,
|
|
312
|
+
`Namespace: ${values.namespace}`,
|
|
313
|
+
`Project directory: ${projectDir}`
|
|
314
|
+
],
|
|
315
|
+
title: "Added server-only AI feature"
|
|
316
|
+
},
|
|
317
|
+
description: "Add a server-owned WordPress AI feature endpoint",
|
|
318
|
+
nameLabel: "AI feature name",
|
|
319
|
+
async prepareExecution(context) {
|
|
320
|
+
const name = requireAddKindName(context, AI_FEATURE_MISSING_NAME_MESSAGE);
|
|
321
|
+
const namespace = readOptionalStrictStringFlag(context.flags, "namespace");
|
|
322
|
+
return createNamedExecutionPlan(context, {
|
|
323
|
+
execute: ({ cwd, name: name2 }) => context.addRuntime.runAddAiFeatureCommand({
|
|
324
|
+
aiFeatureName: name2,
|
|
325
|
+
cwd,
|
|
326
|
+
namespace
|
|
327
|
+
}),
|
|
328
|
+
getValues: (result) => ({
|
|
329
|
+
aiFeatureSlug: result.aiFeatureSlug,
|
|
330
|
+
namespace: result.namespace
|
|
331
|
+
}),
|
|
332
|
+
getWarnings: (result) => result.warnings,
|
|
333
|
+
missingNameMessage: AI_FEATURE_MISSING_NAME_MESSAGE,
|
|
334
|
+
name,
|
|
335
|
+
warnLine: context.warnLine
|
|
336
|
+
});
|
|
337
|
+
},
|
|
338
|
+
sortOrder: 100,
|
|
339
|
+
supportsDryRun: true,
|
|
340
|
+
usage: "wp-typia add ai-feature <name> [--namespace <vendor/v1>] [--dry-run]",
|
|
341
|
+
visibleFieldNames: () => NAME_NAMESPACE_VISIBLE_FIELDS
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
// src/add-kinds/binding-source.ts
|
|
345
|
+
var BINDING_SOURCE_MISSING_NAME_MESSAGE = "`wp-typia add binding-source` requires <name>. Usage: wp-typia add binding-source <name> [--block <block-slug|namespace/block-slug> --attribute <attribute>].";
|
|
346
|
+
var bindingSourceAddKindEntry = defineAddKindRegistryEntry({
|
|
347
|
+
completion: {
|
|
348
|
+
nextSteps: (values) => [
|
|
349
|
+
`Review src/bindings/${values.bindingSourceSlug}/server.php and src/bindings/${values.bindingSourceSlug}/editor.ts.`,
|
|
350
|
+
...values.blockSlug && values.attributeName ? [
|
|
351
|
+
`Review src/blocks/${values.blockSlug}/block.json for the ${values.attributeName} bindable attribute.`
|
|
352
|
+
] : [],
|
|
353
|
+
"Run your workspace build or dev command to verify the binding source hooks and editor registration."
|
|
354
|
+
],
|
|
355
|
+
summaryLines: (values, projectDir) => [
|
|
356
|
+
`Binding source: ${values.bindingSourceSlug}`,
|
|
357
|
+
...values.blockSlug && values.attributeName ? [`Target: ${values.blockSlug}.${values.attributeName}`] : [],
|
|
358
|
+
`Project directory: ${projectDir}`
|
|
359
|
+
],
|
|
360
|
+
title: "Added binding source"
|
|
361
|
+
},
|
|
362
|
+
description: "Add a shared block bindings source",
|
|
363
|
+
nameLabel: "Binding source name",
|
|
364
|
+
async prepareExecution(context) {
|
|
365
|
+
const name = requireAddKindName(context, BINDING_SOURCE_MISSING_NAME_MESSAGE);
|
|
366
|
+
const [blockName, attributeName] = readOptionalPairedStrictStringFlags(context.flags, "block", "attribute", "`wp-typia add binding-source` requires --block and --attribute to be provided together.");
|
|
367
|
+
return createNamedExecutionPlan(context, {
|
|
368
|
+
execute: ({ cwd, name: name2 }) => context.addRuntime.runAddBindingSourceCommand({
|
|
369
|
+
attributeName,
|
|
370
|
+
bindingSourceName: name2,
|
|
371
|
+
blockName,
|
|
372
|
+
cwd
|
|
373
|
+
}),
|
|
374
|
+
getValues: (result) => ({
|
|
375
|
+
...result.attributeName ? { attributeName: result.attributeName } : {},
|
|
376
|
+
...result.blockSlug ? { blockSlug: result.blockSlug } : {},
|
|
377
|
+
bindingSourceSlug: result.bindingSourceSlug
|
|
378
|
+
}),
|
|
379
|
+
missingNameMessage: BINDING_SOURCE_MISSING_NAME_MESSAGE,
|
|
380
|
+
name
|
|
381
|
+
});
|
|
382
|
+
},
|
|
383
|
+
sortOrder: 70,
|
|
384
|
+
supportsDryRun: true,
|
|
385
|
+
usage: "wp-typia add binding-source <name> [--block <block-slug|namespace/block-slug> --attribute <attribute>] [--dry-run]",
|
|
386
|
+
visibleFieldNames: () => NAME_BLOCK_ATTRIBUTE_VISIBLE_FIELDS
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
// src/external-layer-prompt-options.ts
|
|
390
|
+
function formatExternalLayerSelectHint(option2) {
|
|
391
|
+
const details = [
|
|
392
|
+
option2.description,
|
|
393
|
+
option2.extends.length > 0 ? `extends ${option2.extends.join(", ")}` : undefined
|
|
394
|
+
].filter((value) => typeof value === "string" && value.length > 0);
|
|
395
|
+
return details.length > 0 ? details.join(" \xB7 ") : undefined;
|
|
396
|
+
}
|
|
397
|
+
function toExternalLayerPromptOptions(options) {
|
|
398
|
+
return options.map((option2) => ({
|
|
399
|
+
hint: formatExternalLayerSelectHint(option2),
|
|
400
|
+
label: option2.id,
|
|
401
|
+
value: option2.id
|
|
402
|
+
}));
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// src/add-kinds/block.ts
|
|
406
|
+
var BLOCK_MISSING_NAME_MESSAGE = "`wp-typia add block` requires <name>. Usage: wp-typia add block <name> [--template <basic|interactivity|persistence|compound>]";
|
|
407
|
+
var blockAddKindEntry = defineAddKindRegistryEntry({
|
|
408
|
+
completion: {
|
|
409
|
+
nextSteps: () => [
|
|
410
|
+
"Review the generated sources under src/blocks/ and the updated scripts/block-config.ts entry.",
|
|
411
|
+
"Run your workspace build or dev command to verify the new scaffolded block family."
|
|
412
|
+
],
|
|
413
|
+
summaryLines: (values, projectDir) => [
|
|
414
|
+
`Blocks: ${values.blockSlugs}`,
|
|
415
|
+
`Template family: ${values.templateId}`,
|
|
416
|
+
`Project directory: ${projectDir}`
|
|
417
|
+
],
|
|
418
|
+
title: "Added workspace block"
|
|
419
|
+
},
|
|
420
|
+
description: "Add a real block slice",
|
|
421
|
+
hiddenStringSubmitFields: ["external-layer-id", "external-layer-source"],
|
|
422
|
+
nameLabel: "Block name",
|
|
423
|
+
async prepareExecution(context) {
|
|
424
|
+
const name = requireAddKindName(context, BLOCK_MISSING_NAME_MESSAGE);
|
|
425
|
+
const externalLayerId = readOptionalStrictStringFlag(context.flags, "external-layer-id");
|
|
426
|
+
const externalLayerSource = readOptionalStrictStringFlag(context.flags, "external-layer-source");
|
|
427
|
+
const shouldPromptForLayerSelection = Boolean(externalLayerSource) && !Boolean(externalLayerId) && context.isInteractiveSession;
|
|
428
|
+
const selectPrompt = shouldPromptForLayerSelection ? await context.getOrCreatePrompt() : undefined;
|
|
429
|
+
const alternateRenderTargets = readOptionalStrictStringFlag(context.flags, "alternate-render-targets");
|
|
430
|
+
const dataStorageMode = readOptionalStrictStringFlag(context.flags, "data-storage");
|
|
431
|
+
const innerBlocksPreset = readOptionalStrictStringFlag(context.flags, "inner-blocks-preset");
|
|
432
|
+
const persistencePolicy = readOptionalStrictStringFlag(context.flags, "persistence-policy");
|
|
433
|
+
const requestedTemplateId = readOptionalStrictStringFlag(context.flags, "template");
|
|
434
|
+
let resolvedTemplateId = requestedTemplateId ? assertAddBlockTemplateId(context, requestedTemplateId) : undefined;
|
|
435
|
+
if (!resolvedTemplateId && context.isInteractiveSession) {
|
|
436
|
+
const templatePrompt = await context.getOrCreatePrompt();
|
|
437
|
+
resolvedTemplateId = await templatePrompt.select("Select a block template", context.addRuntime.ADD_BLOCK_TEMPLATE_IDS.map((templateId) => ({
|
|
438
|
+
hint: `Scaffold the ${templateId} block family`,
|
|
439
|
+
label: templateId,
|
|
440
|
+
value: templateId
|
|
441
|
+
})), 1);
|
|
442
|
+
}
|
|
443
|
+
resolvedTemplateId ??= "basic";
|
|
444
|
+
return createNamedExecutionPlan(context, {
|
|
445
|
+
execute: ({ cwd, name: name2 }) => context.addRuntime.runAddBlockCommand({
|
|
446
|
+
alternateRenderTargets,
|
|
447
|
+
blockName: name2,
|
|
448
|
+
cwd,
|
|
449
|
+
dataStorageMode,
|
|
450
|
+
externalLayerId,
|
|
451
|
+
externalLayerSource,
|
|
452
|
+
innerBlocksPreset,
|
|
453
|
+
persistencePolicy,
|
|
454
|
+
selectExternalLayerId: selectPrompt ? (options) => selectPrompt.select("Select an external layer", toExternalLayerPromptOptions(options), 1) : undefined,
|
|
455
|
+
templateId: resolvedTemplateId
|
|
456
|
+
}),
|
|
457
|
+
getValues: (result) => ({
|
|
458
|
+
blockSlugs: result.blockSlugs.join(", "),
|
|
459
|
+
templateId: result.templateId
|
|
460
|
+
}),
|
|
461
|
+
getWarnings: (result) => result.warnings,
|
|
462
|
+
missingNameMessage: BLOCK_MISSING_NAME_MESSAGE,
|
|
463
|
+
name,
|
|
464
|
+
warnLine: context.warnLine
|
|
465
|
+
});
|
|
466
|
+
},
|
|
467
|
+
sortOrder: 20,
|
|
468
|
+
supportsDryRun: true,
|
|
469
|
+
usage: "wp-typia add block <name> [--template <basic|interactivity|persistence|compound>] [--external-layer-source <./path|github:owner/repo/path[#ref]|npm-package>] [--external-layer-id <layer-id>] [--inner-blocks-preset <freeform|ordered|horizontal|locked-structure>] [--alternate-render-targets <email,mjml,plain-text>] [--data-storage <post-meta|custom-table>] [--persistence-policy <authenticated|public>] [--dry-run]",
|
|
470
|
+
visibleFieldNames: ({ template }) => BLOCK_VISIBLE_FIELD_ORDER.filter((fieldName) => {
|
|
471
|
+
if (fieldName === "alternate-render-targets") {
|
|
472
|
+
return isAddPersistenceTemplate(template);
|
|
473
|
+
}
|
|
474
|
+
if (fieldName === "inner-blocks-preset") {
|
|
475
|
+
return template === "compound";
|
|
476
|
+
}
|
|
477
|
+
if (fieldName === "data-storage" || fieldName === "persistence-policy") {
|
|
478
|
+
return isAddPersistenceTemplate(template);
|
|
479
|
+
}
|
|
480
|
+
return true;
|
|
719
481
|
})
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
// src/add-kinds/editor-plugin.ts
|
|
485
|
+
var EDITOR_PLUGIN_MISSING_NAME_MESSAGE = "`wp-typia add editor-plugin` requires <name>. Usage: wp-typia add editor-plugin <name> [--slot <sidebar|document-setting-panel>].";
|
|
486
|
+
var editorPluginAddKindEntry = defineAddKindRegistryEntry({
|
|
487
|
+
completion: {
|
|
488
|
+
nextSteps: (values) => [
|
|
489
|
+
`Review src/editor-plugins/${values.editorPluginSlug}/.`,
|
|
490
|
+
"Run your workspace build or dev command to verify the new editor plugin registration."
|
|
491
|
+
],
|
|
492
|
+
summaryLines: (values, projectDir) => [
|
|
493
|
+
`Editor plugin: ${values.editorPluginSlug}`,
|
|
494
|
+
`Slot: ${values.slot}`,
|
|
495
|
+
`Project directory: ${projectDir}`
|
|
496
|
+
],
|
|
497
|
+
title: "Added editor plugin"
|
|
498
|
+
},
|
|
499
|
+
description: "Add a slot-aware document editor extension shell",
|
|
500
|
+
nameLabel: "Editor plugin name",
|
|
501
|
+
async prepareExecution(context) {
|
|
502
|
+
const name = requireAddKindName(context, EDITOR_PLUGIN_MISSING_NAME_MESSAGE);
|
|
503
|
+
const slot = readOptionalStrictStringFlag(context.flags, "slot");
|
|
504
|
+
return createNamedExecutionPlan(context, {
|
|
505
|
+
execute: ({ cwd, name: name2 }) => context.addRuntime.runAddEditorPluginCommand({
|
|
506
|
+
cwd,
|
|
507
|
+
editorPluginName: name2,
|
|
508
|
+
slot
|
|
509
|
+
}),
|
|
510
|
+
getValues: (result) => ({
|
|
511
|
+
editorPluginSlug: result.editorPluginSlug,
|
|
512
|
+
slot: result.slot
|
|
513
|
+
}),
|
|
514
|
+
missingNameMessage: EDITOR_PLUGIN_MISSING_NAME_MESSAGE,
|
|
515
|
+
name
|
|
516
|
+
});
|
|
517
|
+
},
|
|
518
|
+
sortOrder: 120,
|
|
519
|
+
supportsDryRun: true,
|
|
520
|
+
usage: "wp-typia add editor-plugin <name> [--slot <sidebar|document-setting-panel>] [--dry-run]",
|
|
521
|
+
visibleFieldNames: () => NAME_SLOT_VISIBLE_FIELDS
|
|
522
|
+
});
|
|
523
|
+
|
|
524
|
+
// src/add-kinds/hooked-block.ts
|
|
525
|
+
var HOOKED_BLOCK_MISSING_NAME_MESSAGE = "`wp-typia add hooked-block` requires <block-slug>. Usage: wp-typia add hooked-block <block-slug> --anchor <anchor-block-name> --position <before|after|firstChild|lastChild>.";
|
|
526
|
+
var hookedBlockAddKindEntry = defineAddKindRegistryEntry({
|
|
527
|
+
completion: {
|
|
528
|
+
nextSteps: (values) => [
|
|
529
|
+
`Review src/blocks/${values.blockSlug}/block.json for the new blockHooks entry.`,
|
|
530
|
+
"Run your workspace build or dev command to verify the updated hooked-block metadata."
|
|
531
|
+
],
|
|
532
|
+
summaryLines: (values, projectDir) => [
|
|
533
|
+
`Block: ${values.blockSlug}`,
|
|
534
|
+
`Anchor: ${values.anchorBlockName}`,
|
|
535
|
+
`Position: ${values.position}`,
|
|
536
|
+
`Project directory: ${projectDir}`
|
|
537
|
+
],
|
|
538
|
+
title: "Added blockHooks metadata"
|
|
539
|
+
},
|
|
540
|
+
description: "Add block.json hook metadata to an existing block",
|
|
541
|
+
nameLabel: "Target block",
|
|
542
|
+
async prepareExecution(context) {
|
|
543
|
+
const name = requireAddKindName(context, HOOKED_BLOCK_MISSING_NAME_MESSAGE);
|
|
544
|
+
const anchorBlockName = requireStrictStringFlag(context.flags, "anchor", "`wp-typia add hooked-block` requires --anchor <anchor-block-name>.");
|
|
545
|
+
const position = requireStrictStringFlag(context.flags, "position", "`wp-typia add hooked-block` requires --position <before|after|firstChild|lastChild>.");
|
|
546
|
+
return createNamedExecutionPlan(context, {
|
|
547
|
+
execute: ({ cwd, name: name2 }) => context.addRuntime.runAddHookedBlockCommand({
|
|
548
|
+
anchorBlockName,
|
|
549
|
+
blockName: name2,
|
|
550
|
+
cwd,
|
|
551
|
+
position
|
|
552
|
+
}),
|
|
553
|
+
getValues: (result) => ({
|
|
554
|
+
anchorBlockName: result.anchorBlockName,
|
|
555
|
+
blockSlug: result.blockSlug,
|
|
556
|
+
position: result.position
|
|
557
|
+
}),
|
|
558
|
+
missingNameMessage: HOOKED_BLOCK_MISSING_NAME_MESSAGE,
|
|
559
|
+
name
|
|
560
|
+
});
|
|
561
|
+
},
|
|
562
|
+
sortOrder: 110,
|
|
563
|
+
supportsDryRun: true,
|
|
564
|
+
usage: "wp-typia add hooked-block <block-slug> --anchor <anchor-block-name> --position <before|after|firstChild|lastChild> [--dry-run]",
|
|
565
|
+
visibleFieldNames: () => NAME_ANCHOR_POSITION_VISIBLE_FIELDS
|
|
566
|
+
});
|
|
567
|
+
|
|
568
|
+
// src/add-kinds/pattern.ts
|
|
569
|
+
var PATTERN_MISSING_NAME_MESSAGE = "`wp-typia add pattern` requires <name>. Usage: wp-typia add pattern <name>.";
|
|
570
|
+
var patternAddKindEntry = defineAddKindRegistryEntry({
|
|
571
|
+
completion: {
|
|
572
|
+
nextSteps: (values) => [
|
|
573
|
+
`Review src/patterns/${values.patternSlug}.php.`,
|
|
574
|
+
"Run your workspace build or dev command to verify the new pattern registration."
|
|
575
|
+
],
|
|
576
|
+
summaryLines: (values, projectDir) => [
|
|
577
|
+
`Pattern: ${values.patternSlug}`,
|
|
578
|
+
`Project directory: ${projectDir}`
|
|
579
|
+
],
|
|
580
|
+
title: "Added workspace pattern"
|
|
581
|
+
},
|
|
582
|
+
description: "Add a PHP block pattern shell",
|
|
583
|
+
nameLabel: "Pattern name",
|
|
584
|
+
async prepareExecution(context) {
|
|
585
|
+
return createNamedExecutionPlan(context, {
|
|
586
|
+
execute: ({ cwd, name }) => context.addRuntime.runAddPatternCommand({
|
|
587
|
+
cwd,
|
|
588
|
+
patternName: name
|
|
589
|
+
}),
|
|
590
|
+
getValues: (result) => ({
|
|
591
|
+
patternSlug: result.patternSlug
|
|
592
|
+
}),
|
|
593
|
+
missingNameMessage: PATTERN_MISSING_NAME_MESSAGE,
|
|
594
|
+
warnLine: context.warnLine
|
|
595
|
+
});
|
|
596
|
+
},
|
|
597
|
+
sortOrder: 60,
|
|
598
|
+
supportsDryRun: true,
|
|
599
|
+
usage: "wp-typia add pattern <name> [--dry-run]",
|
|
600
|
+
visibleFieldNames: () => NAME_ONLY_VISIBLE_FIELDS
|
|
601
|
+
});
|
|
602
|
+
|
|
603
|
+
// src/add-kinds/rest-resource.ts
|
|
604
|
+
var REST_RESOURCE_MISSING_NAME_MESSAGE = "`wp-typia add rest-resource` requires <name>. Usage: wp-typia add rest-resource <name> [--namespace <vendor/v1>] [--methods <list,read,create,update,delete>].";
|
|
605
|
+
var restResourceAddKindEntry = defineAddKindRegistryEntry({
|
|
606
|
+
completion: {
|
|
607
|
+
nextSteps: (values) => [
|
|
608
|
+
`Review src/rest/${values.restResourceSlug}/ and inc/rest/${values.restResourceSlug}.php.`,
|
|
609
|
+
"Run your workspace build or dev command to verify the generated REST resource contract."
|
|
610
|
+
],
|
|
611
|
+
summaryLines: (values, projectDir) => [
|
|
612
|
+
`REST resource: ${values.restResourceSlug}`,
|
|
613
|
+
`Namespace: ${values.namespace}`,
|
|
614
|
+
`Methods: ${values.methods}`,
|
|
615
|
+
`Project directory: ${projectDir}`
|
|
616
|
+
],
|
|
617
|
+
title: "Added plugin-level REST resource"
|
|
618
|
+
},
|
|
619
|
+
description: "Add a plugin-level typed REST resource",
|
|
620
|
+
nameLabel: "REST resource name",
|
|
621
|
+
async prepareExecution(context) {
|
|
622
|
+
const name = requireAddKindName(context, REST_RESOURCE_MISSING_NAME_MESSAGE);
|
|
623
|
+
const methods = readOptionalStrictStringFlag(context.flags, "methods");
|
|
624
|
+
const namespace = readOptionalStrictStringFlag(context.flags, "namespace");
|
|
625
|
+
return createNamedExecutionPlan(context, {
|
|
626
|
+
execute: ({ cwd, name: name2 }) => context.addRuntime.runAddRestResourceCommand({
|
|
627
|
+
cwd,
|
|
628
|
+
methods,
|
|
629
|
+
namespace,
|
|
630
|
+
restResourceName: name2
|
|
631
|
+
}),
|
|
632
|
+
getValues: (result) => ({
|
|
633
|
+
methods: result.methods.join(", "),
|
|
634
|
+
namespace: result.namespace,
|
|
635
|
+
restResourceSlug: result.restResourceSlug
|
|
636
|
+
}),
|
|
637
|
+
missingNameMessage: REST_RESOURCE_MISSING_NAME_MESSAGE,
|
|
638
|
+
name
|
|
639
|
+
});
|
|
640
|
+
},
|
|
641
|
+
sortOrder: 80,
|
|
642
|
+
supportsDryRun: true,
|
|
643
|
+
usage: "wp-typia add rest-resource <name> [--namespace <vendor/v1>] [--methods <list,read,create,update,delete>] [--dry-run]",
|
|
644
|
+
visibleFieldNames: () => NAME_NAMESPACE_METHODS_VISIBLE_FIELDS
|
|
645
|
+
});
|
|
646
|
+
|
|
647
|
+
// src/add-kinds/style.ts
|
|
648
|
+
var STYLE_MISSING_NAME_MESSAGE = "`wp-typia add style` requires <name>. Usage: wp-typia add style <name> --block <block-slug>.";
|
|
649
|
+
var styleAddKindEntry = defineAddKindRegistryEntry({
|
|
650
|
+
completion: {
|
|
651
|
+
nextSteps: (values) => [
|
|
652
|
+
`Review src/blocks/${values.blockSlug}/styles/${values.styleSlug}.ts.`,
|
|
653
|
+
"Run your workspace build or dev command to verify the new block style registration."
|
|
654
|
+
],
|
|
655
|
+
summaryLines: (values, projectDir) => [
|
|
656
|
+
`Block style: ${values.styleSlug}`,
|
|
657
|
+
`Target block: ${values.blockSlug}`,
|
|
658
|
+
`Project directory: ${projectDir}`
|
|
659
|
+
],
|
|
660
|
+
title: "Added block style"
|
|
661
|
+
},
|
|
662
|
+
description: "Add a Block Styles registration to an existing block",
|
|
663
|
+
nameLabel: "Style name",
|
|
664
|
+
async prepareExecution(context) {
|
|
665
|
+
const name = requireAddKindName(context, STYLE_MISSING_NAME_MESSAGE);
|
|
666
|
+
const blockSlug = requireStrictStringFlag(context.flags, "block", "`wp-typia add style` requires --block <block-slug>.");
|
|
667
|
+
return createNamedExecutionPlan(context, {
|
|
668
|
+
execute: ({ cwd, name: name2 }) => context.addRuntime.runAddBlockStyleCommand({
|
|
669
|
+
blockName: blockSlug,
|
|
670
|
+
cwd,
|
|
671
|
+
styleName: name2
|
|
672
|
+
}),
|
|
673
|
+
getValues: (result) => ({
|
|
674
|
+
blockSlug: result.blockSlug,
|
|
675
|
+
styleSlug: result.styleSlug
|
|
676
|
+
}),
|
|
677
|
+
missingNameMessage: STYLE_MISSING_NAME_MESSAGE,
|
|
678
|
+
name
|
|
679
|
+
});
|
|
680
|
+
},
|
|
681
|
+
sortOrder: 40,
|
|
682
|
+
supportsDryRun: true,
|
|
683
|
+
usage: "wp-typia add style <name> --block <block-slug> [--dry-run]",
|
|
684
|
+
visibleFieldNames: () => NAME_BLOCK_VISIBLE_FIELDS
|
|
685
|
+
});
|
|
686
|
+
|
|
687
|
+
// src/add-kinds/transform.ts
|
|
688
|
+
var TRANSFORM_MISSING_NAME_MESSAGE = "`wp-typia add transform` requires <name>. Usage: wp-typia add transform <name> --from <namespace/block> --to <block-slug|namespace/block-slug>.";
|
|
689
|
+
var transformAddKindEntry = defineAddKindRegistryEntry({
|
|
690
|
+
completion: {
|
|
691
|
+
nextSteps: (values) => [
|
|
692
|
+
`Review src/blocks/${values.blockSlug}/transforms/${values.transformSlug}.ts.`,
|
|
693
|
+
"Run your workspace build or dev command to verify the new block transform registration."
|
|
694
|
+
],
|
|
695
|
+
summaryLines: (values, projectDir) => [
|
|
696
|
+
`Block transform: ${values.transformSlug}`,
|
|
697
|
+
`From: ${values.fromBlockName}`,
|
|
698
|
+
`To: ${values.toBlockName}`,
|
|
699
|
+
`Project directory: ${projectDir}`
|
|
700
|
+
],
|
|
701
|
+
title: "Added block transform"
|
|
702
|
+
},
|
|
703
|
+
description: "Add a block-to-block transform into a workspace block",
|
|
704
|
+
nameLabel: "Transform name",
|
|
705
|
+
async prepareExecution(context) {
|
|
706
|
+
const name = requireAddKindName(context, TRANSFORM_MISSING_NAME_MESSAGE);
|
|
707
|
+
const fromBlockName = requireStrictStringFlag(context.flags, "from", "`wp-typia add transform` requires --from <namespace/block>.");
|
|
708
|
+
const toBlockName = requireStrictStringFlag(context.flags, "to", "`wp-typia add transform` requires --to <block-slug|namespace/block-slug>.");
|
|
709
|
+
return createNamedExecutionPlan(context, {
|
|
710
|
+
execute: ({ cwd, name: name2 }) => context.addRuntime.runAddBlockTransformCommand({
|
|
711
|
+
cwd,
|
|
712
|
+
fromBlockName,
|
|
713
|
+
toBlockName,
|
|
714
|
+
transformName: name2
|
|
715
|
+
}),
|
|
716
|
+
getValues: (result) => ({
|
|
717
|
+
blockSlug: result.blockSlug,
|
|
718
|
+
fromBlockName: result.fromBlockName,
|
|
719
|
+
toBlockName: result.toBlockName,
|
|
720
|
+
transformSlug: result.transformSlug
|
|
721
|
+
}),
|
|
722
|
+
missingNameMessage: TRANSFORM_MISSING_NAME_MESSAGE,
|
|
723
|
+
name
|
|
724
|
+
});
|
|
725
|
+
},
|
|
726
|
+
sortOrder: 50,
|
|
727
|
+
supportsDryRun: true,
|
|
728
|
+
usage: "wp-typia add transform <name> --from <namespace/block> --to <block-slug|namespace/block-slug> [--dry-run]",
|
|
729
|
+
visibleFieldNames: () => NAME_FROM_TO_VISIBLE_FIELDS
|
|
730
|
+
});
|
|
731
|
+
|
|
732
|
+
// src/add-kinds/variation.ts
|
|
733
|
+
var VARIATION_MISSING_NAME_MESSAGE = "`wp-typia add variation` requires <name>. Usage: wp-typia add variation <name> --block <block-slug>";
|
|
734
|
+
var variationAddKindEntry = defineAddKindRegistryEntry({
|
|
735
|
+
completion: {
|
|
736
|
+
nextSteps: (values) => [
|
|
737
|
+
`Review src/blocks/${values.blockSlug}/variations/${values.variationSlug}.ts.`,
|
|
738
|
+
"Run your workspace build or dev command to pick up the new variation."
|
|
739
|
+
],
|
|
740
|
+
summaryLines: (values, projectDir) => [
|
|
741
|
+
`Variation: ${values.variationSlug}`,
|
|
742
|
+
`Target block: ${values.blockSlug}`,
|
|
743
|
+
`Project directory: ${projectDir}`
|
|
744
|
+
],
|
|
745
|
+
title: "Added workspace variation"
|
|
746
|
+
},
|
|
747
|
+
description: "Add a variation to an existing block",
|
|
748
|
+
nameLabel: "Variation name",
|
|
749
|
+
async prepareExecution(context) {
|
|
750
|
+
const name = requireAddKindName(context, VARIATION_MISSING_NAME_MESSAGE);
|
|
751
|
+
const blockSlug = requireStrictStringFlag(context.flags, "block", "`wp-typia add variation` requires --block <block-slug>.");
|
|
752
|
+
return createNamedExecutionPlan(context, {
|
|
753
|
+
execute: ({ cwd, name: name2 }) => context.addRuntime.runAddVariationCommand({
|
|
754
|
+
blockName: blockSlug,
|
|
755
|
+
cwd,
|
|
756
|
+
variationName: name2
|
|
757
|
+
}),
|
|
758
|
+
getValues: (result) => ({
|
|
759
|
+
blockSlug: result.blockSlug,
|
|
760
|
+
variationSlug: result.variationSlug
|
|
761
|
+
}),
|
|
762
|
+
missingNameMessage: VARIATION_MISSING_NAME_MESSAGE,
|
|
763
|
+
name
|
|
764
|
+
});
|
|
765
|
+
},
|
|
766
|
+
sortOrder: 30,
|
|
767
|
+
supportsDryRun: true,
|
|
768
|
+
usage: "wp-typia add variation <name> --block <block-slug> [--dry-run]",
|
|
769
|
+
visibleFieldNames: () => NAME_BLOCK_VISIBLE_FIELDS
|
|
770
|
+
});
|
|
771
|
+
|
|
772
|
+
// src/add-kind-registry.ts
|
|
773
|
+
var ADD_KIND_REGISTRY = {
|
|
774
|
+
"admin-view": adminViewAddKindEntry,
|
|
775
|
+
block: blockAddKindEntry,
|
|
776
|
+
variation: variationAddKindEntry,
|
|
777
|
+
style: styleAddKindEntry,
|
|
778
|
+
transform: transformAddKindEntry,
|
|
779
|
+
pattern: patternAddKindEntry,
|
|
780
|
+
"binding-source": bindingSourceAddKindEntry,
|
|
781
|
+
"rest-resource": restResourceAddKindEntry,
|
|
782
|
+
ability: abilityAddKindEntry,
|
|
783
|
+
"ai-feature": aiFeatureAddKindEntry,
|
|
784
|
+
"hooked-block": hookedBlockAddKindEntry,
|
|
785
|
+
"editor-plugin": editorPluginAddKindEntry
|
|
720
786
|
};
|
|
721
787
|
function isAddKindId(value) {
|
|
722
788
|
return typeof value === "string" && ADD_KIND_IDS.includes(value);
|
|
@@ -732,16 +798,28 @@ function buildAddKindCompletionDetails(kind, options) {
|
|
|
732
798
|
title: descriptor.title
|
|
733
799
|
};
|
|
734
800
|
}
|
|
735
|
-
function formatAddKindList() {
|
|
736
|
-
return ADD_KIND_IDS.join(", ");
|
|
737
|
-
}
|
|
738
|
-
function formatAddKindUsagePlaceholder() {
|
|
739
|
-
return `<${ADD_KIND_IDS.join("|")}>`;
|
|
740
|
-
}
|
|
741
801
|
function supportsAddKindDryRun(kind) {
|
|
742
802
|
return ADD_KIND_REGISTRY[kind].supportsDryRun;
|
|
743
803
|
}
|
|
744
804
|
|
|
805
|
+
// src/cli-error-messages.ts
|
|
806
|
+
var MISSING_CREATE_PROJECT_DIR_DETAIL_LINES = [
|
|
807
|
+
"`wp-typia create` requires <project-dir>.",
|
|
808
|
+
"`--dry-run` still needs a logical project directory name because wp-typia derives slugs, package names, and planned file paths from it."
|
|
809
|
+
];
|
|
810
|
+
function formatMissingAddKindDetailLine() {
|
|
811
|
+
return `\`wp-typia add\` requires <kind>. Usage: wp-typia add ${formatAddKindUsagePlaceholder()} ...`;
|
|
812
|
+
}
|
|
813
|
+
function shouldPrintMissingAddKindHelp(options) {
|
|
814
|
+
if (typeof options.emitOutput === "boolean") {
|
|
815
|
+
return options.emitOutput;
|
|
816
|
+
}
|
|
817
|
+
return options.format !== "json";
|
|
818
|
+
}
|
|
819
|
+
function buildMissingCreateProjectDirDetailLines() {
|
|
820
|
+
return [...MISSING_CREATE_PROJECT_DIR_DETAIL_LINES];
|
|
821
|
+
}
|
|
822
|
+
|
|
745
823
|
// src/runtime-bridge-add-dry-run.ts
|
|
746
824
|
import fs2 from "fs";
|
|
747
825
|
import { promises as fsp } from "fs";
|
|
@@ -766,6 +844,55 @@ async function copyWorkspaceProject(sourceDir, targetDir) {
|
|
|
766
844
|
recursive: true
|
|
767
845
|
});
|
|
768
846
|
}
|
|
847
|
+
function formatInstallMarkerError(error) {
|
|
848
|
+
if (error instanceof Error) {
|
|
849
|
+
return error.message;
|
|
850
|
+
}
|
|
851
|
+
return String(error);
|
|
852
|
+
}
|
|
853
|
+
function formatInstallMarkerFailures(failures) {
|
|
854
|
+
return failures.map((failure) => `${failure.operation}: ${failure.reason}`).join("; ");
|
|
855
|
+
}
|
|
856
|
+
function ensureWorkspaceInstallMarker({
|
|
857
|
+
fsAdapter = fs2,
|
|
858
|
+
sourceMarker,
|
|
859
|
+
targetMarker
|
|
860
|
+
}) {
|
|
861
|
+
const failures = [];
|
|
862
|
+
try {
|
|
863
|
+
fsAdapter.symlinkSync(sourceMarker, targetMarker);
|
|
864
|
+
return;
|
|
865
|
+
} catch (error) {
|
|
866
|
+
failures.push({
|
|
867
|
+
operation: "symlink",
|
|
868
|
+
reason: formatInstallMarkerError(error)
|
|
869
|
+
});
|
|
870
|
+
}
|
|
871
|
+
try {
|
|
872
|
+
fsAdapter.linkSync(sourceMarker, targetMarker);
|
|
873
|
+
return;
|
|
874
|
+
} catch (error) {
|
|
875
|
+
failures.push({
|
|
876
|
+
operation: "hard link",
|
|
877
|
+
reason: formatInstallMarkerError(error)
|
|
878
|
+
});
|
|
879
|
+
}
|
|
880
|
+
try {
|
|
881
|
+
fsAdapter.copyFileSync(sourceMarker, targetMarker);
|
|
882
|
+
return;
|
|
883
|
+
} catch (error) {
|
|
884
|
+
failures.push({
|
|
885
|
+
operation: "copy",
|
|
886
|
+
reason: formatInstallMarkerError(error)
|
|
887
|
+
});
|
|
888
|
+
}
|
|
889
|
+
throw new Error([
|
|
890
|
+
"Failed to prepare dry-run install marker.",
|
|
891
|
+
`Source: ${sourceMarker}`,
|
|
892
|
+
`Target: ${targetMarker}`,
|
|
893
|
+
`Fallback failures: ${formatInstallMarkerFailures(failures)}`
|
|
894
|
+
].join(" "));
|
|
895
|
+
}
|
|
769
896
|
function ensureWorkspaceInstallMarkers(sourceDir, targetDir) {
|
|
770
897
|
const sourceNodeModules = path.join(sourceDir, "node_modules");
|
|
771
898
|
if (fs2.existsSync(sourceNodeModules)) {
|
|
@@ -777,15 +904,7 @@ function ensureWorkspaceInstallMarkers(sourceDir, targetDir) {
|
|
|
777
904
|
continue;
|
|
778
905
|
}
|
|
779
906
|
const targetMarker = path.join(targetDir, marker);
|
|
780
|
-
|
|
781
|
-
fs2.symlinkSync(sourceMarker, targetMarker);
|
|
782
|
-
} catch {
|
|
783
|
-
try {
|
|
784
|
-
fs2.linkSync(sourceMarker, targetMarker);
|
|
785
|
-
} catch {
|
|
786
|
-
fs2.copyFileSync(sourceMarker, targetMarker);
|
|
787
|
-
}
|
|
788
|
-
}
|
|
907
|
+
ensureWorkspaceInstallMarker({ sourceMarker, targetMarker });
|
|
789
908
|
}
|
|
790
909
|
}
|
|
791
910
|
async function listWorkspaceFiles(rootDir) {
|
|
@@ -946,40 +1065,38 @@ function stripLeadingOutputMarker(text, kind) {
|
|
|
946
1065
|
return text.replace(new RegExp(`^(?:${markerPattern})\\s*`, "u"), "");
|
|
947
1066
|
}
|
|
948
1067
|
|
|
949
|
-
// src/runtime-
|
|
950
|
-
function
|
|
951
|
-
const
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
const
|
|
961
|
-
|
|
962
|
-
${
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
}
|
|
979
|
-
if (payload.optionalNote) {
|
|
980
|
-
printLine(`Note: ${payload.optionalNote}`);
|
|
981
|
-
}
|
|
1068
|
+
// src/runtime-output/init.ts
|
|
1069
|
+
function buildInitCompletionPayload(plan, markerOptions) {
|
|
1070
|
+
const changeLines = [
|
|
1071
|
+
...plan.packageChanges.addDevDependencies.map((dependency) => `devDependency ${dependency.action} ${dependency.name} -> ${dependency.requiredValue}`),
|
|
1072
|
+
...plan.packageChanges.packageManagerField ? [
|
|
1073
|
+
`packageManager ${plan.packageChanges.packageManagerField.action} -> ${plan.packageChanges.packageManagerField.requiredValue}`
|
|
1074
|
+
] : [],
|
|
1075
|
+
...plan.packageChanges.scripts.map((script) => `script ${script.action} ${script.name} -> ${script.requiredValue}`),
|
|
1076
|
+
...plan.plannedFiles.map((filePlan) => `file ${filePlan.action} ${filePlan.path} (${filePlan.purpose})`),
|
|
1077
|
+
...plan.commandMode === "preview-only" ? plan.generatedArtifacts.map((artifactPath) => `generated artifact ${artifactPath}`) : []
|
|
1078
|
+
];
|
|
1079
|
+
const modeLine = plan.commandMode === "apply" ? plan.status === "already-initialized" ? "Mode: apply requested; no files were written because the retrofit surface already existed." : "Mode: apply; package.json and retrofit helper files were written." : "Mode: preview only; no files were written.";
|
|
1080
|
+
const optionalTitle = plan.commandMode === "apply" ? `Applied adoption changes (${changeLines.length}):` : `Planned adoption changes (${changeLines.length}):`;
|
|
1081
|
+
const title = plan.status === "already-initialized" ? formatOutputMarker("success", `wp-typia init: ${plan.projectName} is already initialized`, markerOptions) : plan.commandMode === "apply" ? formatOutputMarker("success", `Applied retrofit init for ${plan.projectName}`, markerOptions) : formatOutputMarker("dryRun", `Retrofit init plan for ${plan.projectName}`, markerOptions);
|
|
1082
|
+
return {
|
|
1083
|
+
nextSteps: plan.nextSteps,
|
|
1084
|
+
optionalLines: changeLines,
|
|
1085
|
+
optionalNote: plan.summary,
|
|
1086
|
+
optionalTitle,
|
|
1087
|
+
summaryLines: [
|
|
1088
|
+
`Project directory: ${plan.projectDir}`,
|
|
1089
|
+
`Detected layout: ${plan.detectedLayout.description}`,
|
|
1090
|
+
...plan.detectedLayout.blockNames.length > 0 ? [`Block targets: ${plan.detectedLayout.blockNames.join(", ")}`] : [],
|
|
1091
|
+
`Package manager: ${plan.packageManager}`,
|
|
1092
|
+
modeLine
|
|
1093
|
+
],
|
|
1094
|
+
title,
|
|
1095
|
+
warningLines: plan.notes
|
|
1096
|
+
};
|
|
982
1097
|
}
|
|
1098
|
+
|
|
1099
|
+
// src/runtime-output/structured.ts
|
|
983
1100
|
function toNonEmptyArray(values) {
|
|
984
1101
|
return values && values.length > 0 ? values : undefined;
|
|
985
1102
|
}
|
|
@@ -1040,12 +1157,35 @@ function buildStructuredInitSuccessPayload(plan) {
|
|
|
1040
1157
|
}
|
|
1041
1158
|
};
|
|
1042
1159
|
}
|
|
1160
|
+
// src/runtime-output/create.ts
|
|
1161
|
+
function escapeRegExp2(source) {
|
|
1162
|
+
return source.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
1163
|
+
}
|
|
1164
|
+
var LOOSE_CREATE_COMPLETION_PACKAGE_MANAGER_PATTERN = new RegExp(`^(?:corepack\\s+)?(${PACKAGE_MANAGER_IDS.map(escapeRegExp2).join("|")})(?=$|[@:/+\\s])`, "iu");
|
|
1165
|
+
function parseCreateCompletionPackageManager(packageManager) {
|
|
1166
|
+
const normalizedPackageManager = packageManager.trim();
|
|
1167
|
+
const parsedPackageManager = parsePackageManagerField(normalizedPackageManager);
|
|
1168
|
+
if (parsedPackageManager) {
|
|
1169
|
+
return parsedPackageManager;
|
|
1170
|
+
}
|
|
1171
|
+
const looseMatch = LOOSE_CREATE_COMPLETION_PACKAGE_MANAGER_PATTERN.exec(normalizedPackageManager);
|
|
1172
|
+
const loosePackageManager = looseMatch?.[1]?.toLowerCase();
|
|
1173
|
+
return PACKAGE_MANAGER_IDS.includes(loosePackageManager) ? loosePackageManager : null;
|
|
1174
|
+
}
|
|
1175
|
+
function resolveCreateCompletionPackageManager(packageManager) {
|
|
1176
|
+
const parsedPackageManager = parseCreateCompletionPackageManager(packageManager);
|
|
1177
|
+
if (parsedPackageManager) {
|
|
1178
|
+
return parsedPackageManager;
|
|
1179
|
+
}
|
|
1180
|
+
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.INVALID_ARGUMENT, `Unsupported package manager "${packageManager}" in create completion payload. Expected one of: ${PACKAGE_MANAGER_IDS.join(", ")}.`);
|
|
1181
|
+
}
|
|
1043
1182
|
function formatCreateProgressLine(payload, markerOptions) {
|
|
1044
1183
|
return formatOutputMarker("progress", `${payload.title}: ${payload.detail}`, markerOptions);
|
|
1045
1184
|
}
|
|
1046
1185
|
function buildCreateCompletionPayload(flow, markerOptions) {
|
|
1186
|
+
const packageManager = resolveCreateCompletionPackageManager(flow.packageManager);
|
|
1047
1187
|
const verificationSteps = [
|
|
1048
|
-
formatPackageExecCommand(
|
|
1188
|
+
formatPackageExecCommand(packageManager, `wp-typia@${package_default.version}`, "doctor"),
|
|
1049
1189
|
...flow.optionalOnboarding.steps
|
|
1050
1190
|
];
|
|
1051
1191
|
return {
|
|
@@ -1084,42 +1224,7 @@ function buildCreateDryRunPayload(flow, markerOptions) {
|
|
|
1084
1224
|
warningLines: flow.result.warnings
|
|
1085
1225
|
};
|
|
1086
1226
|
}
|
|
1087
|
-
|
|
1088
|
-
const changeLines = [
|
|
1089
|
-
...plan.packageChanges.addDevDependencies.map((dependency) => `devDependency ${dependency.action} ${dependency.name} -> ${dependency.requiredValue}`),
|
|
1090
|
-
...plan.packageChanges.packageManagerField ? [
|
|
1091
|
-
`packageManager ${plan.packageChanges.packageManagerField.action} -> ${plan.packageChanges.packageManagerField.requiredValue}`
|
|
1092
|
-
] : [],
|
|
1093
|
-
...plan.packageChanges.scripts.map((script) => `script ${script.action} ${script.name} -> ${script.requiredValue}`),
|
|
1094
|
-
...plan.plannedFiles.map((filePlan) => `file ${filePlan.action} ${filePlan.path} (${filePlan.purpose})`),
|
|
1095
|
-
...plan.commandMode === "preview-only" ? plan.generatedArtifacts.map((artifactPath) => `generated artifact ${artifactPath}`) : []
|
|
1096
|
-
];
|
|
1097
|
-
const modeLine = plan.commandMode === "apply" ? plan.status === "already-initialized" ? "Mode: apply requested; no files were written because the retrofit surface already existed." : "Mode: apply; package.json and retrofit helper files were written." : "Mode: preview only; no files were written.";
|
|
1098
|
-
const optionalTitle = plan.commandMode === "apply" ? `Applied adoption changes (${changeLines.length}):` : `Planned adoption changes (${changeLines.length}):`;
|
|
1099
|
-
const title = plan.status === "already-initialized" ? formatOutputMarker("success", `wp-typia init: ${plan.projectName} is already initialized`, markerOptions) : plan.commandMode === "apply" ? formatOutputMarker("success", `Applied retrofit init for ${plan.projectName}`, markerOptions) : formatOutputMarker("dryRun", `Retrofit init plan for ${plan.projectName}`, markerOptions);
|
|
1100
|
-
return {
|
|
1101
|
-
nextSteps: plan.nextSteps,
|
|
1102
|
-
optionalLines: changeLines,
|
|
1103
|
-
optionalNote: plan.summary,
|
|
1104
|
-
optionalTitle,
|
|
1105
|
-
summaryLines: [
|
|
1106
|
-
`Project directory: ${plan.projectDir}`,
|
|
1107
|
-
`Detected layout: ${plan.detectedLayout.description}`,
|
|
1108
|
-
...plan.detectedLayout.blockNames.length > 0 ? [`Block targets: ${plan.detectedLayout.blockNames.join(", ")}`] : [],
|
|
1109
|
-
`Package manager: ${plan.packageManager}`,
|
|
1110
|
-
modeLine
|
|
1111
|
-
],
|
|
1112
|
-
title,
|
|
1113
|
-
warningLines: plan.notes
|
|
1114
|
-
};
|
|
1115
|
-
}
|
|
1116
|
-
function buildMigrationCompletionPayload(options, markerOptions) {
|
|
1117
|
-
const summaryLines = options.lines.filter((line) => line.trim().length > 0);
|
|
1118
|
-
return {
|
|
1119
|
-
summaryLines,
|
|
1120
|
-
title: formatOutputMarker("success", `Completed wp-typia migrate ${options.command}`, markerOptions)
|
|
1121
|
-
};
|
|
1122
|
-
}
|
|
1227
|
+
// src/runtime-output/add.ts
|
|
1123
1228
|
function buildAddCompletionPayload(options, markerOptions) {
|
|
1124
1229
|
const verificationLines = [
|
|
1125
1230
|
formatPackageExecCommand(options.packageManager ?? inferPackageManagerId(options.projectDir), `wp-typia@${package_default.version}`, "doctor")
|
|
@@ -1151,6 +1256,15 @@ function buildAddDryRunPayload(options, markerOptions) {
|
|
|
1151
1256
|
warningLines: options.completion.warningLines
|
|
1152
1257
|
};
|
|
1153
1258
|
}
|
|
1259
|
+
// src/runtime-output/migrate.ts
|
|
1260
|
+
function buildMigrationCompletionPayload(options, markerOptions) {
|
|
1261
|
+
const summaryLines = options.lines.filter((line) => line.trim().length > 0);
|
|
1262
|
+
return {
|
|
1263
|
+
summaryLines,
|
|
1264
|
+
title: formatOutputMarker("success", `Completed wp-typia migrate ${options.command}`, markerOptions)
|
|
1265
|
+
};
|
|
1266
|
+
}
|
|
1267
|
+
// src/runtime-output/sync.ts
|
|
1154
1268
|
function buildSyncDryRunPayload(options, markerOptions) {
|
|
1155
1269
|
const targetSuffix = options.target === "ai" ? " ai" : "";
|
|
1156
1270
|
const targetSummary = options.target === "ai" ? "Sync target: AI artifacts only." : options.target === "default" ? "Sync target: generated project defaults." : undefined;
|
|
@@ -1167,232 +1281,62 @@ function buildSyncDryRunPayload(options, markerOptions) {
|
|
|
1167
1281
|
title: formatOutputMarker("dryRun", `Dry run for wp-typia sync${targetSuffix}`, markerOptions)
|
|
1168
1282
|
};
|
|
1169
1283
|
}
|
|
1170
|
-
|
|
1284
|
+
// src/print-block.ts
|
|
1285
|
+
function printBlock(printLine, lines) {
|
|
1171
1286
|
for (const line of lines) {
|
|
1172
1287
|
printLine(line);
|
|
1173
1288
|
}
|
|
1174
1289
|
}
|
|
1175
1290
|
|
|
1176
|
-
// src/runtime-
|
|
1177
|
-
function
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
return Boolean(stdin?.isTTY) && Boolean(stdout?.isTTY) && term !== "dumb";
|
|
1183
|
-
}
|
|
1184
|
-
function supportsInteractiveTui(options = {}) {
|
|
1185
|
-
const hasBunRuntime = options.hasBunRuntime ?? typeof Bun !== "undefined";
|
|
1186
|
-
return hasBunRuntime && isInteractiveTerminal(options);
|
|
1187
|
-
}
|
|
1188
|
-
// src/runtime-bridge-sync.ts
|
|
1189
|
-
import { spawnSync } from "child_process";
|
|
1190
|
-
import fs3 from "fs";
|
|
1191
|
-
import path2 from "path";
|
|
1192
|
-
var SYNC_INSTALL_MARKERS = [
|
|
1193
|
-
"node_modules",
|
|
1194
|
-
".pnp.cjs",
|
|
1195
|
-
".pnp.loader.mjs"
|
|
1196
|
-
];
|
|
1197
|
-
var LOCAL_SYNC_TOOL_PATTERN = /(^|[\s;&|()])(?:tsx|wp-scripts)(?=($|[\s;&|()]))/u;
|
|
1198
|
-
var CAPTURED_SYNC_OUTPUT_MAX_BUFFER = 16 * 1024 * 1024;
|
|
1199
|
-
function resolveSyncExecutionTarget(subcommand) {
|
|
1200
|
-
if (!subcommand) {
|
|
1201
|
-
return "default";
|
|
1202
|
-
}
|
|
1203
|
-
if (subcommand === "ai") {
|
|
1204
|
-
return "ai";
|
|
1205
|
-
}
|
|
1206
|
-
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.INVALID_COMMAND, `Unknown sync subcommand "${subcommand}". Expected one of: "ai".`);
|
|
1207
|
-
}
|
|
1208
|
-
function getSyncRootError(cwd) {
|
|
1209
|
-
return createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.OUTSIDE_PROJECT_ROOT, `No generated wp-typia project root was found at ${cwd}. Run \`wp-typia sync\` from a scaffolded project or official workspace root that already contains generated sync scripts. If you expected this directory to work, cd into the scaffold root first or rerun the scaffold before syncing.`);
|
|
1210
|
-
}
|
|
1211
|
-
function resolveSyncProjectContext(cwd) {
|
|
1212
|
-
const packageJsonPath = path2.join(cwd, "package.json");
|
|
1213
|
-
if (!fs3.existsSync(packageJsonPath)) {
|
|
1214
|
-
throw getSyncRootError(cwd);
|
|
1215
|
-
}
|
|
1216
|
-
const packageJson = JSON.parse(fs3.readFileSync(packageJsonPath, "utf8"));
|
|
1217
|
-
const scripts = packageJson.scripts ?? {};
|
|
1218
|
-
const syncScripts = {
|
|
1219
|
-
sync: typeof scripts.sync === "string" ? {
|
|
1220
|
-
command: scripts.sync,
|
|
1221
|
-
scriptName: "sync"
|
|
1222
|
-
} : undefined,
|
|
1223
|
-
"sync-ai": typeof scripts["sync-ai"] === "string" ? {
|
|
1224
|
-
command: scripts["sync-ai"],
|
|
1225
|
-
scriptName: "sync-ai"
|
|
1226
|
-
} : typeof scripts["sync-wordpress-ai"] === "string" ? {
|
|
1227
|
-
command: scripts["sync-wordpress-ai"],
|
|
1228
|
-
scriptName: "sync-wordpress-ai"
|
|
1229
|
-
} : undefined,
|
|
1230
|
-
"sync-rest": typeof scripts["sync-rest"] === "string" ? {
|
|
1231
|
-
command: scripts["sync-rest"],
|
|
1232
|
-
scriptName: "sync-rest"
|
|
1233
|
-
} : undefined,
|
|
1234
|
-
"sync-types": typeof scripts["sync-types"] === "string" ? {
|
|
1235
|
-
command: scripts["sync-types"],
|
|
1236
|
-
scriptName: "sync-types"
|
|
1237
|
-
} : undefined
|
|
1238
|
-
};
|
|
1239
|
-
return {
|
|
1240
|
-
cwd,
|
|
1241
|
-
packageJsonPath,
|
|
1242
|
-
packageManager: inferPackageManagerId(cwd, packageJson.packageManager),
|
|
1243
|
-
scripts: syncScripts
|
|
1244
|
-
};
|
|
1245
|
-
}
|
|
1246
|
-
function findInstalledDependencyMarkerDir(projectDir) {
|
|
1247
|
-
let currentDir = path2.resolve(projectDir);
|
|
1248
|
-
while (true) {
|
|
1249
|
-
if (SYNC_INSTALL_MARKERS.some((marker) => fs3.existsSync(path2.join(currentDir, marker)))) {
|
|
1250
|
-
return currentDir;
|
|
1251
|
-
}
|
|
1252
|
-
const parentDir = path2.dirname(currentDir);
|
|
1253
|
-
if (parentDir === currentDir) {
|
|
1254
|
-
return null;
|
|
1255
|
-
}
|
|
1256
|
-
currentDir = parentDir;
|
|
1257
|
-
}
|
|
1258
|
-
}
|
|
1259
|
-
function scriptsLikelyNeedInstalledDependencies(project, target) {
|
|
1260
|
-
const candidateScripts = target === "ai" ? [project.scripts["sync-ai"]] : project.scripts.sync ? [project.scripts.sync] : [
|
|
1261
|
-
project.scripts["sync-types"],
|
|
1262
|
-
project.scripts["sync-rest"],
|
|
1263
|
-
project.scripts["sync-ai"]
|
|
1264
|
-
];
|
|
1265
|
-
return candidateScripts.some((script) => script !== undefined && LOCAL_SYNC_TOOL_PATTERN.test(script.command));
|
|
1266
|
-
}
|
|
1267
|
-
function assertSyncDependenciesInstalled(project, target) {
|
|
1268
|
-
if (!scriptsLikelyNeedInstalledDependencies(project, target)) {
|
|
1269
|
-
return;
|
|
1270
|
-
}
|
|
1271
|
-
const markerDir = findInstalledDependencyMarkerDir(project.cwd);
|
|
1272
|
-
if (markerDir) {
|
|
1273
|
-
return;
|
|
1274
|
-
}
|
|
1275
|
-
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.DEPENDENCIES_NOT_INSTALLED, `Project dependencies have not been installed yet. Run \`${formatInstallCommand(project.packageManager)}\` from the project root before \`wp-typia sync\`. The generated sync scripts rely on local tools such as \`tsx\`.`);
|
|
1276
|
-
}
|
|
1277
|
-
function getPackageManagerRunInvocation(packageManager, scriptName, extraArgs) {
|
|
1278
|
-
switch (packageManager) {
|
|
1279
|
-
case "bun":
|
|
1280
|
-
return { args: ["run", scriptName, ...extraArgs], command: "bun" };
|
|
1281
|
-
case "npm":
|
|
1282
|
-
return {
|
|
1283
|
-
args: [
|
|
1284
|
-
"run",
|
|
1285
|
-
scriptName,
|
|
1286
|
-
...extraArgs.length > 0 ? ["--", ...extraArgs] : []
|
|
1287
|
-
],
|
|
1288
|
-
command: "npm"
|
|
1289
|
-
};
|
|
1290
|
-
case "pnpm":
|
|
1291
|
-
return { args: ["run", scriptName, ...extraArgs], command: "pnpm" };
|
|
1292
|
-
case "yarn":
|
|
1293
|
-
return { args: ["run", scriptName, ...extraArgs], command: "yarn" };
|
|
1294
|
-
}
|
|
1295
|
-
}
|
|
1296
|
-
function createSyncPlannedCommand(project, scriptName, extraArgs) {
|
|
1297
|
-
const script = project.scripts[scriptName];
|
|
1298
|
-
if (!script) {
|
|
1299
|
-
return null;
|
|
1300
|
-
}
|
|
1301
|
-
const invocation = getPackageManagerRunInvocation(project.packageManager, script.scriptName, extraArgs);
|
|
1302
|
-
return {
|
|
1303
|
-
args: invocation.args,
|
|
1304
|
-
command: invocation.command,
|
|
1305
|
-
displayCommand: formatRunScript(project.packageManager, script.scriptName, extraArgs.join(" ")),
|
|
1306
|
-
scriptName: script.scriptName
|
|
1307
|
-
};
|
|
1308
|
-
}
|
|
1309
|
-
function buildSyncPlannedCommands(project, extraArgs, target) {
|
|
1310
|
-
if (target === "ai") {
|
|
1311
|
-
const syncAiCommand2 = createSyncPlannedCommand(project, "sync-ai", extraArgs);
|
|
1312
|
-
if (!syncAiCommand2) {
|
|
1313
|
-
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.CONFIGURATION_MISSING, `Expected ${project.packageJsonPath} to define a \`sync-ai\` script for \`wp-typia sync ai\`.`);
|
|
1314
|
-
}
|
|
1315
|
-
return [syncAiCommand2];
|
|
1291
|
+
// src/runtime-output/print.ts
|
|
1292
|
+
function printCompletionPayload(payload, options = {}) {
|
|
1293
|
+
const printLine = options.printLine ?? console.log;
|
|
1294
|
+
const warnLine = options.warnLine ?? printLine;
|
|
1295
|
+
for (const line of payload.preambleLines ?? []) {
|
|
1296
|
+
printLine(line);
|
|
1316
1297
|
}
|
|
1317
|
-
|
|
1318
|
-
|
|
1298
|
+
for (const warning of payload.warningLines ?? []) {
|
|
1299
|
+
warnLine(formatOutputMarker("warning", warning, options.markerOptions));
|
|
1319
1300
|
}
|
|
1320
|
-
const
|
|
1321
|
-
|
|
1322
|
-
|
|
1301
|
+
const hasDetails = (payload.summaryLines?.length ?? 0) > 0 || (payload.nextSteps?.length ?? 0) > 0 || (payload.optionalLines?.length ?? 0) > 0 || Boolean(payload.optionalNote);
|
|
1302
|
+
const hasLeadingContext = (payload.preambleLines?.length ?? 0) > 0 || (payload.warningLines?.length ?? 0) > 0;
|
|
1303
|
+
printLine(hasLeadingContext && hasDetails ? `
|
|
1304
|
+
${payload.title}` : payload.title);
|
|
1305
|
+
for (const line of payload.summaryLines ?? []) {
|
|
1306
|
+
printLine(line);
|
|
1323
1307
|
}
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1308
|
+
if ((payload.nextSteps?.length ?? 0) > 0) {
|
|
1309
|
+
printLine("Next steps:");
|
|
1310
|
+
for (const step of payload.nextSteps ?? []) {
|
|
1311
|
+
printLine(` ${step}`);
|
|
1312
|
+
}
|
|
1328
1313
|
}
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1314
|
+
if ((payload.optionalLines?.length ?? 0) > 0) {
|
|
1315
|
+
printLine(`
|
|
1316
|
+
${payload.optionalTitle ?? "Optional:"}`);
|
|
1317
|
+
for (const step of payload.optionalLines ?? []) {
|
|
1318
|
+
printLine(` ${step}`);
|
|
1319
|
+
}
|
|
1332
1320
|
}
|
|
1333
|
-
|
|
1334
|
-
}
|
|
1335
|
-
function runProjectScript(project, plannedCommand, options) {
|
|
1336
|
-
const result = spawnSync(plannedCommand.command, plannedCommand.args, {
|
|
1337
|
-
cwd: project.cwd,
|
|
1338
|
-
encoding: options.captureOutput ? "utf8" : undefined,
|
|
1339
|
-
...options.captureOutput ? { maxBuffer: CAPTURED_SYNC_OUTPUT_MAX_BUFFER } : {},
|
|
1340
|
-
shell: process.platform === "win32",
|
|
1341
|
-
stdio: options.captureOutput ? "pipe" : "inherit"
|
|
1342
|
-
});
|
|
1343
|
-
const stderr = options.captureOutput && typeof result.stderr === "string" ? result.stderr : undefined;
|
|
1344
|
-
const stdout = options.captureOutput && typeof result.stdout === "string" ? result.stdout : undefined;
|
|
1345
|
-
if (result.error || result.status !== 0) {
|
|
1346
|
-
throw new Error(`\`${plannedCommand.displayCommand}\` failed.`, {
|
|
1347
|
-
cause: result.error ?? (stderr ? new Error(stderr.trim()) : undefined)
|
|
1348
|
-
});
|
|
1321
|
+
if (payload.optionalNote) {
|
|
1322
|
+
printLine(`Note: ${payload.optionalNote}`);
|
|
1349
1323
|
}
|
|
1350
|
-
return {
|
|
1351
|
-
...plannedCommand,
|
|
1352
|
-
exitCode: result.status ?? 0,
|
|
1353
|
-
...stderr !== undefined ? { stderr } : {},
|
|
1354
|
-
...stdout !== undefined ? { stdout } : {}
|
|
1355
|
-
};
|
|
1356
1324
|
}
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
const
|
|
1367
|
-
|
|
1368
|
-
check,
|
|
1369
|
-
dryRun,
|
|
1370
|
-
packageJsonPath: project.packageJsonPath,
|
|
1371
|
-
packageManager: project.packageManager,
|
|
1372
|
-
plannedCommands,
|
|
1373
|
-
projectDir: project.cwd,
|
|
1374
|
-
target
|
|
1375
|
-
};
|
|
1376
|
-
if (dryRun) {
|
|
1377
|
-
return result;
|
|
1378
|
-
}
|
|
1379
|
-
assertSyncDependenciesInstalled(project, target);
|
|
1380
|
-
result.executedCommands = plannedCommands.map((plannedCommand) => runProjectScript(project, plannedCommand, {
|
|
1381
|
-
captureOutput
|
|
1382
|
-
}));
|
|
1383
|
-
return result;
|
|
1325
|
+
// src/runtime-capabilities.ts
|
|
1326
|
+
function isInteractiveTerminal({
|
|
1327
|
+
stdin = process.stdin,
|
|
1328
|
+
stdout = process.stdout,
|
|
1329
|
+
term = process.env.TERM
|
|
1330
|
+
} = {}) {
|
|
1331
|
+
return Boolean(stdin?.isTTY) && Boolean(stdout?.isTTY) && term !== "dumb";
|
|
1332
|
+
}
|
|
1333
|
+
function supportsInteractiveTui(options = {}) {
|
|
1334
|
+
const hasBunRuntime = options.hasBunRuntime ?? typeof Bun !== "undefined";
|
|
1335
|
+
return hasBunRuntime && isInteractiveTerminal(options);
|
|
1384
1336
|
}
|
|
1385
1337
|
|
|
1386
|
-
// src/runtime-bridge.ts
|
|
1387
|
-
var loadCliAddRuntime = () => import("./cli-add-1xvw17yg.js");
|
|
1338
|
+
// src/runtime-bridge-shared.ts
|
|
1388
1339
|
var loadCliDiagnosticsRuntime = () => import("./cli-diagnostics-5dvztm7q.js");
|
|
1389
|
-
var loadCliDoctorRuntime = () => import("./cli-doctor-bjv6z74k.js");
|
|
1390
|
-
var loadCliInitRuntime = () => import("./cli-init-zdfrmp3y.js");
|
|
1391
|
-
var loadCliPromptRuntime = () => import("./cli-prompt-614tq57c.js");
|
|
1392
|
-
var loadCliScaffoldRuntime = () => import("./cli-scaffold-pbb67zxg.js");
|
|
1393
|
-
var loadCliTemplatesRuntime = () => import("./cli-templates-hc71dfc2.js");
|
|
1394
|
-
var loadCreateTemplateValidationRuntime = () => import("./create-template-validation-7k2752mz.js");
|
|
1395
|
-
var loadMigrationsRuntime = () => import("./migrations-ads3j14z.js");
|
|
1396
1340
|
async function wrapCliCommandError(command, error) {
|
|
1397
1341
|
const { createCliCommandError } = await loadCliDiagnosticsRuntime();
|
|
1398
1342
|
return createCliCommandError({ command, error });
|
|
@@ -1406,6 +1350,15 @@ function shouldWrapCliCommandError(options) {
|
|
|
1406
1350
|
}
|
|
1407
1351
|
return true;
|
|
1408
1352
|
}
|
|
1353
|
+
function emitCompletion(payload, options) {
|
|
1354
|
+
if (options.emitOutput) {
|
|
1355
|
+
printCompletionPayload(payload, {
|
|
1356
|
+
printLine: options.printLine,
|
|
1357
|
+
warnLine: options.warnLine
|
|
1358
|
+
});
|
|
1359
|
+
}
|
|
1360
|
+
return payload;
|
|
1361
|
+
}
|
|
1409
1362
|
function pushFlag(argv, name, value) {
|
|
1410
1363
|
if (value === undefined || value === null || value === false) {
|
|
1411
1364
|
return;
|
|
@@ -1416,6 +1369,10 @@ function pushFlag(argv, name, value) {
|
|
|
1416
1369
|
}
|
|
1417
1370
|
argv.push(`--${name}`, String(value));
|
|
1418
1371
|
}
|
|
1372
|
+
|
|
1373
|
+
// src/runtime-bridge-add.ts
|
|
1374
|
+
var loadCliAddRuntime = () => import("./cli-add-8rvmezy0.js");
|
|
1375
|
+
var loadCliPromptRuntime = () => import("./cli-prompt-614tq57c.js");
|
|
1419
1376
|
async function executeWorkspaceAddWithOptionalDryRun(options) {
|
|
1420
1377
|
const simulated = options.dryRun ? await simulateWorkspaceAddDryRun({
|
|
1421
1378
|
cwd: options.cwd,
|
|
@@ -1459,6 +1416,72 @@ async function executePlannedAddKind(kind, executionContext, context) {
|
|
|
1459
1416
|
const plan = await getAddKindExecutionPlan(kind, executionContext);
|
|
1460
1417
|
return executePreparedAddKind(kind, context, plan);
|
|
1461
1418
|
}
|
|
1419
|
+
async function executeAddCommand({
|
|
1420
|
+
cwd,
|
|
1421
|
+
emitOutput = true,
|
|
1422
|
+
flags,
|
|
1423
|
+
interactive,
|
|
1424
|
+
kind,
|
|
1425
|
+
name,
|
|
1426
|
+
printLine = console.log,
|
|
1427
|
+
prompt,
|
|
1428
|
+
warnLine = console.warn
|
|
1429
|
+
}) {
|
|
1430
|
+
let activePrompt;
|
|
1431
|
+
const dryRun = Boolean(flags["dry-run"]);
|
|
1432
|
+
try {
|
|
1433
|
+
const addRuntime = await loadCliAddRuntime();
|
|
1434
|
+
const isInteractiveSession = interactive ?? isInteractiveTerminal();
|
|
1435
|
+
if (!kind) {
|
|
1436
|
+
if (shouldPrintMissingAddKindHelp({ emitOutput })) {
|
|
1437
|
+
printLine(addRuntime.formatAddHelpText());
|
|
1438
|
+
}
|
|
1439
|
+
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, formatMissingAddKindDetailLine());
|
|
1440
|
+
}
|
|
1441
|
+
if (!isAddKindId(kind)) {
|
|
1442
|
+
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.INVALID_COMMAND, `Unknown add kind "${kind}". Expected one of: ${formatAddKindList()}.`);
|
|
1443
|
+
}
|
|
1444
|
+
if (dryRun && !supportsAddKindDryRun(kind)) {
|
|
1445
|
+
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.INVALID_ARGUMENT, `\`wp-typia add ${kind}\` does not support \`--dry-run\` yet.`);
|
|
1446
|
+
}
|
|
1447
|
+
const executionContext = {
|
|
1448
|
+
addRuntime,
|
|
1449
|
+
cwd,
|
|
1450
|
+
flags,
|
|
1451
|
+
getOrCreatePrompt: async () => {
|
|
1452
|
+
if (activePrompt) {
|
|
1453
|
+
return activePrompt;
|
|
1454
|
+
}
|
|
1455
|
+
const { createReadlinePrompt } = await loadCliPromptRuntime();
|
|
1456
|
+
activePrompt = prompt ?? createReadlinePrompt();
|
|
1457
|
+
return activePrompt;
|
|
1458
|
+
},
|
|
1459
|
+
isInteractiveSession,
|
|
1460
|
+
name,
|
|
1461
|
+
warnLine
|
|
1462
|
+
};
|
|
1463
|
+
return await executePlannedAddKind(kind, executionContext, {
|
|
1464
|
+
cwd,
|
|
1465
|
+
dryRun,
|
|
1466
|
+
emitOutput,
|
|
1467
|
+
printLine
|
|
1468
|
+
});
|
|
1469
|
+
} catch (error) {
|
|
1470
|
+
if (!shouldWrapCliCommandError({ emitOutput })) {
|
|
1471
|
+
throw error;
|
|
1472
|
+
}
|
|
1473
|
+
throw await wrapCliCommandError("add", error);
|
|
1474
|
+
} finally {
|
|
1475
|
+
if (activePrompt && activePrompt !== prompt) {
|
|
1476
|
+
activePrompt.close();
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1480
|
+
// src/runtime-bridge-create.ts
|
|
1481
|
+
var loadCliPromptRuntime2 = () => import("./cli-prompt-614tq57c.js");
|
|
1482
|
+
var loadCliScaffoldRuntime = () => import("./cli-scaffold-b1ex2y80.js");
|
|
1483
|
+
var loadCliTemplatesRuntime = () => import("./cli-templates-hc71dfc2.js");
|
|
1484
|
+
var loadCreateTemplateValidationRuntime = () => import("./create-template-validation-rtec5sng.js");
|
|
1462
1485
|
var PACKAGE_MANAGER_PROMPT_OPTIONS = [
|
|
1463
1486
|
{ label: "npm", value: "npm", hint: "Use npm" },
|
|
1464
1487
|
{ label: "pnpm", value: "pnpm", hint: "Use pnpm" },
|
|
@@ -1485,15 +1508,6 @@ var BOOLEAN_PROMPT_OPTIONS = [
|
|
|
1485
1508
|
{ label: "Yes", value: "yes", hint: "Enable this option" },
|
|
1486
1509
|
{ label: "No", value: "no", hint: "Keep the default disabled state" }
|
|
1487
1510
|
];
|
|
1488
|
-
function emitCompletion(payload, options) {
|
|
1489
|
-
if (options.emitOutput) {
|
|
1490
|
-
printCompletionPayload(payload, {
|
|
1491
|
-
printLine: options.printLine,
|
|
1492
|
-
warnLine: options.warnLine
|
|
1493
|
-
});
|
|
1494
|
-
}
|
|
1495
|
-
return payload;
|
|
1496
|
-
}
|
|
1497
1511
|
async function executeCreateCommand({
|
|
1498
1512
|
projectDir,
|
|
1499
1513
|
cwd,
|
|
@@ -1514,7 +1528,7 @@ async function executeCreateCommand({
|
|
|
1514
1528
|
{ runScaffoldFlow },
|
|
1515
1529
|
{ getTemplateSelectOptions }
|
|
1516
1530
|
] = await Promise.all([
|
|
1517
|
-
|
|
1531
|
+
loadCliPromptRuntime2(),
|
|
1518
1532
|
loadCliScaffoldRuntime(),
|
|
1519
1533
|
loadCliTemplatesRuntime()
|
|
1520
1534
|
]);
|
|
@@ -1583,100 +1597,24 @@ async function executeCreateCommand({
|
|
|
1583
1597
|
activePrompt.close();
|
|
1584
1598
|
}
|
|
1585
1599
|
}
|
|
1586
|
-
}
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
prompt,
|
|
1596
|
-
warnLine = console.warn
|
|
1597
|
-
}) {
|
|
1598
|
-
let activePrompt;
|
|
1599
|
-
const dryRun = Boolean(flags["dry-run"]);
|
|
1600
|
-
try {
|
|
1601
|
-
const addRuntime = await loadCliAddRuntime();
|
|
1602
|
-
const isInteractiveSession = interactive ?? isInteractiveTerminal();
|
|
1603
|
-
if (!kind) {
|
|
1604
|
-
if (emitOutput) {
|
|
1605
|
-
printLine(addRuntime.formatAddHelpText());
|
|
1606
|
-
}
|
|
1607
|
-
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, `\`wp-typia add\` requires <kind>. Usage: wp-typia add ${formatAddKindUsagePlaceholder()} ...`);
|
|
1608
|
-
}
|
|
1609
|
-
if (!isAddKindId(kind)) {
|
|
1610
|
-
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.INVALID_COMMAND, `Unknown add kind "${kind}". Expected one of: ${formatAddKindList()}.`);
|
|
1611
|
-
}
|
|
1612
|
-
if (dryRun && !supportsAddKindDryRun(kind)) {
|
|
1613
|
-
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.INVALID_ARGUMENT, `\`wp-typia add ${kind}\` does not support \`--dry-run\` yet.`);
|
|
1614
|
-
}
|
|
1615
|
-
const executionContext = {
|
|
1616
|
-
addRuntime,
|
|
1617
|
-
cwd,
|
|
1618
|
-
flags,
|
|
1619
|
-
getOrCreatePrompt: async () => {
|
|
1620
|
-
if (activePrompt) {
|
|
1621
|
-
return activePrompt;
|
|
1622
|
-
}
|
|
1623
|
-
const { createReadlinePrompt } = await loadCliPromptRuntime();
|
|
1624
|
-
activePrompt = prompt ?? createReadlinePrompt();
|
|
1625
|
-
return activePrompt;
|
|
1626
|
-
},
|
|
1627
|
-
isInteractiveSession,
|
|
1628
|
-
name,
|
|
1629
|
-
warnLine
|
|
1630
|
-
};
|
|
1631
|
-
return await executePlannedAddKind(kind, executionContext, {
|
|
1632
|
-
cwd,
|
|
1633
|
-
dryRun,
|
|
1634
|
-
emitOutput,
|
|
1635
|
-
printLine
|
|
1636
|
-
});
|
|
1637
|
-
} catch (error) {
|
|
1638
|
-
if (!shouldWrapCliCommandError({ emitOutput })) {
|
|
1639
|
-
throw error;
|
|
1640
|
-
}
|
|
1641
|
-
throw await wrapCliCommandError("add", error);
|
|
1642
|
-
} finally {
|
|
1643
|
-
if (activePrompt && activePrompt !== prompt) {
|
|
1644
|
-
activePrompt.close();
|
|
1645
|
-
}
|
|
1646
|
-
}
|
|
1647
|
-
}
|
|
1648
|
-
async function executeTemplatesCommand({ flags }, printLine = console.log) {
|
|
1649
|
-
const {
|
|
1650
|
-
formatTemplateDetails,
|
|
1651
|
-
formatTemplateFeatures,
|
|
1652
|
-
formatTemplateSummary,
|
|
1653
|
-
getTemplateById,
|
|
1654
|
-
listTemplates
|
|
1655
|
-
} = await loadCliTemplatesRuntime();
|
|
1656
|
-
const subcommand = flags.subcommand ?? "list";
|
|
1657
|
-
if (subcommand === "list") {
|
|
1658
|
-
for (const template of listTemplates()) {
|
|
1659
|
-
printBlock([formatTemplateSummary(template), formatTemplateFeatures(template)], printLine);
|
|
1660
|
-
}
|
|
1661
|
-
return;
|
|
1662
|
-
}
|
|
1663
|
-
if (subcommand === "inspect") {
|
|
1664
|
-
if (!flags.id) {
|
|
1665
|
-
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, "`wp-typia templates inspect` requires <template-id>.");
|
|
1666
|
-
}
|
|
1667
|
-
const template = getTemplateById(flags.id);
|
|
1668
|
-
if (!template) {
|
|
1669
|
-
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.INVALID_ARGUMENT, `Unknown template "${flags.id}".`);
|
|
1670
|
-
}
|
|
1671
|
-
printBlock([formatTemplateDetails(template)], printLine);
|
|
1672
|
-
return;
|
|
1600
|
+
}
|
|
1601
|
+
// src/runtime-bridge-doctor.ts
|
|
1602
|
+
var loadCliDoctorRuntime = () => import("./cli-doctor-5m6xyx9q.js");
|
|
1603
|
+
async function executeDoctorCommand(cwd) {
|
|
1604
|
+
try {
|
|
1605
|
+
const { runDoctor } = await loadCliDoctorRuntime();
|
|
1606
|
+
await runDoctor(cwd);
|
|
1607
|
+
} catch (error) {
|
|
1608
|
+
throw await wrapCliCommandError("doctor", error);
|
|
1673
1609
|
}
|
|
1674
|
-
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.INVALID_COMMAND, `Unknown templates subcommand "${subcommand}". Expected list or inspect.`);
|
|
1675
1610
|
}
|
|
1611
|
+
// src/runtime-bridge-init.ts
|
|
1612
|
+
import path2 from "path";
|
|
1613
|
+
var loadCliInitRuntime = () => import("./cli-init-qv3zxmvc.js");
|
|
1676
1614
|
async function executeInitCommand({ apply, cwd, packageManager, projectDir }, options = {}) {
|
|
1677
1615
|
try {
|
|
1678
1616
|
const { runInitCommand } = await loadCliInitRuntime();
|
|
1679
|
-
const resolvedProjectDir = projectDir ?
|
|
1617
|
+
const resolvedProjectDir = projectDir ? path2.resolve(cwd, projectDir) : cwd;
|
|
1680
1618
|
const plan = await runInitCommand({
|
|
1681
1619
|
apply,
|
|
1682
1620
|
packageManager,
|
|
@@ -1697,14 +1635,8 @@ async function executeInitCommand({ apply, cwd, packageManager, projectDir }, op
|
|
|
1697
1635
|
throw await wrapCliCommandError("init", error);
|
|
1698
1636
|
}
|
|
1699
1637
|
}
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
const { runDoctor } = await loadCliDoctorRuntime();
|
|
1703
|
-
await runDoctor(cwd);
|
|
1704
|
-
} catch (error) {
|
|
1705
|
-
throw await wrapCliCommandError("doctor", error);
|
|
1706
|
-
}
|
|
1707
|
-
}
|
|
1638
|
+
// src/runtime-bridge-migrate.ts
|
|
1639
|
+
var loadMigrationsRuntime = () => import("./migrations-7g9rag5d.js");
|
|
1708
1640
|
async function executeMigrateCommand({
|
|
1709
1641
|
command,
|
|
1710
1642
|
cwd,
|
|
@@ -1712,12 +1644,17 @@ async function executeMigrateCommand({
|
|
|
1712
1644
|
prompt,
|
|
1713
1645
|
renderLine
|
|
1714
1646
|
}) {
|
|
1715
|
-
const { formatMigrationHelpText, parseMigrationArgs, runMigrationCommand } = await loadMigrationsRuntime();
|
|
1716
|
-
if (!command) {
|
|
1717
|
-
console.log(formatMigrationHelpText());
|
|
1718
|
-
return;
|
|
1719
|
-
}
|
|
1720
1647
|
try {
|
|
1648
|
+
const { formatMigrationHelpText, parseMigrationArgs, runMigrationCommand } = await loadMigrationsRuntime();
|
|
1649
|
+
if (!command) {
|
|
1650
|
+
const helpText = formatMigrationHelpText();
|
|
1651
|
+
if (renderLine) {
|
|
1652
|
+
renderLine(helpText);
|
|
1653
|
+
} else {
|
|
1654
|
+
console.log(helpText);
|
|
1655
|
+
}
|
|
1656
|
+
return;
|
|
1657
|
+
}
|
|
1721
1658
|
const argv = [command];
|
|
1722
1659
|
pushFlag(argv, "all", flags.all);
|
|
1723
1660
|
pushFlag(argv, "force", flags.force);
|
|
@@ -1757,11 +1694,246 @@ async function executeMigrateCommand({
|
|
|
1757
1694
|
throw await wrapCliCommandError("migrate", error);
|
|
1758
1695
|
}
|
|
1759
1696
|
}
|
|
1697
|
+
// src/runtime-bridge-templates.ts
|
|
1698
|
+
var loadCliTemplatesRuntime2 = () => import("./cli-templates-hc71dfc2.js");
|
|
1699
|
+
async function executeTemplatesCommand({ flags }, printLine = console.log) {
|
|
1700
|
+
const {
|
|
1701
|
+
formatTemplateDetails,
|
|
1702
|
+
formatTemplateFeatures,
|
|
1703
|
+
formatTemplateSummary,
|
|
1704
|
+
getTemplateById,
|
|
1705
|
+
listTemplates
|
|
1706
|
+
} = await loadCliTemplatesRuntime2();
|
|
1707
|
+
const subcommand = flags.subcommand ?? "list";
|
|
1708
|
+
if (subcommand === "list") {
|
|
1709
|
+
for (const template of listTemplates()) {
|
|
1710
|
+
printBlock(printLine, [formatTemplateSummary(template), formatTemplateFeatures(template)]);
|
|
1711
|
+
}
|
|
1712
|
+
return;
|
|
1713
|
+
}
|
|
1714
|
+
if (subcommand === "inspect") {
|
|
1715
|
+
if (!flags.id) {
|
|
1716
|
+
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, "`wp-typia templates inspect` requires <template-id>.");
|
|
1717
|
+
}
|
|
1718
|
+
const template = getTemplateById(flags.id);
|
|
1719
|
+
if (!template) {
|
|
1720
|
+
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.INVALID_ARGUMENT, `Unknown template "${flags.id}".`);
|
|
1721
|
+
}
|
|
1722
|
+
printBlock(printLine, [formatTemplateDetails(template)]);
|
|
1723
|
+
return;
|
|
1724
|
+
}
|
|
1725
|
+
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.INVALID_COMMAND, `Unknown templates subcommand "${subcommand}". Expected list or inspect.`);
|
|
1726
|
+
}
|
|
1760
1727
|
async function listTemplatesForRuntime() {
|
|
1761
|
-
const { listTemplates } = await
|
|
1728
|
+
const { listTemplates } = await loadCliTemplatesRuntime2();
|
|
1762
1729
|
return listTemplates();
|
|
1763
1730
|
}
|
|
1764
|
-
|
|
1731
|
+
// src/runtime-bridge-sync.ts
|
|
1732
|
+
import { spawnSync } from "child_process";
|
|
1733
|
+
import fs3 from "fs";
|
|
1734
|
+
import path3 from "path";
|
|
1735
|
+
var SYNC_INSTALL_MARKERS = [
|
|
1736
|
+
"node_modules",
|
|
1737
|
+
".pnp.cjs",
|
|
1738
|
+
".pnp.loader.mjs"
|
|
1739
|
+
];
|
|
1740
|
+
var LOCAL_SYNC_TOOL_PATTERN = /(^|[\s;&|()])(?:tsx|wp-scripts)(?=($|[\s;&|()]))/u;
|
|
1741
|
+
var CAPTURED_SYNC_OUTPUT_MAX_BUFFER = 16 * 1024 * 1024;
|
|
1742
|
+
function resolveSyncExecutionTarget(subcommand) {
|
|
1743
|
+
if (!subcommand) {
|
|
1744
|
+
return "default";
|
|
1745
|
+
}
|
|
1746
|
+
if (subcommand === "ai") {
|
|
1747
|
+
return "ai";
|
|
1748
|
+
}
|
|
1749
|
+
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.INVALID_COMMAND, `Unknown sync subcommand "${subcommand}". Expected one of: "ai".`);
|
|
1750
|
+
}
|
|
1751
|
+
function getSyncRootError(cwd) {
|
|
1752
|
+
return createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.OUTSIDE_PROJECT_ROOT, `No generated wp-typia project root was found at ${cwd}. Run \`wp-typia sync\` from a scaffolded project or official workspace root that already contains generated sync scripts. If you expected this directory to work, cd into the scaffold root first or rerun the scaffold before syncing.`);
|
|
1753
|
+
}
|
|
1754
|
+
function readSyncPackageJson(packageJsonPath) {
|
|
1755
|
+
const source = fs3.readFileSync(packageJsonPath, "utf8");
|
|
1756
|
+
try {
|
|
1757
|
+
return JSON.parse(source);
|
|
1758
|
+
} catch (error) {
|
|
1759
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1760
|
+
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.INVALID_ARGUMENT, `Unable to parse ${packageJsonPath}: ${message}`, error instanceof Error ? { cause: error } : undefined);
|
|
1761
|
+
}
|
|
1762
|
+
}
|
|
1763
|
+
function resolveSyncProjectContext(cwd) {
|
|
1764
|
+
const packageJsonPath = path3.join(cwd, "package.json");
|
|
1765
|
+
if (!fs3.existsSync(packageJsonPath)) {
|
|
1766
|
+
throw getSyncRootError(cwd);
|
|
1767
|
+
}
|
|
1768
|
+
const packageJson = readSyncPackageJson(packageJsonPath);
|
|
1769
|
+
const scripts = packageJson.scripts ?? {};
|
|
1770
|
+
const syncScripts = {
|
|
1771
|
+
sync: typeof scripts.sync === "string" ? {
|
|
1772
|
+
command: scripts.sync,
|
|
1773
|
+
scriptName: "sync"
|
|
1774
|
+
} : undefined,
|
|
1775
|
+
"sync-ai": typeof scripts["sync-ai"] === "string" ? {
|
|
1776
|
+
command: scripts["sync-ai"],
|
|
1777
|
+
scriptName: "sync-ai"
|
|
1778
|
+
} : typeof scripts["sync-wordpress-ai"] === "string" ? {
|
|
1779
|
+
command: scripts["sync-wordpress-ai"],
|
|
1780
|
+
scriptName: "sync-wordpress-ai"
|
|
1781
|
+
} : undefined,
|
|
1782
|
+
"sync-rest": typeof scripts["sync-rest"] === "string" ? {
|
|
1783
|
+
command: scripts["sync-rest"],
|
|
1784
|
+
scriptName: "sync-rest"
|
|
1785
|
+
} : undefined,
|
|
1786
|
+
"sync-types": typeof scripts["sync-types"] === "string" ? {
|
|
1787
|
+
command: scripts["sync-types"],
|
|
1788
|
+
scriptName: "sync-types"
|
|
1789
|
+
} : undefined
|
|
1790
|
+
};
|
|
1791
|
+
return {
|
|
1792
|
+
cwd,
|
|
1793
|
+
packageJsonPath,
|
|
1794
|
+
packageManager: inferPackageManagerId(cwd, packageJson.packageManager),
|
|
1795
|
+
scripts: syncScripts
|
|
1796
|
+
};
|
|
1797
|
+
}
|
|
1798
|
+
function findInstalledDependencyMarkerDir(projectDir) {
|
|
1799
|
+
let currentDir = path3.resolve(projectDir);
|
|
1800
|
+
while (true) {
|
|
1801
|
+
if (SYNC_INSTALL_MARKERS.some((marker) => fs3.existsSync(path3.join(currentDir, marker)))) {
|
|
1802
|
+
return currentDir;
|
|
1803
|
+
}
|
|
1804
|
+
const parentDir = path3.dirname(currentDir);
|
|
1805
|
+
if (parentDir === currentDir) {
|
|
1806
|
+
return null;
|
|
1807
|
+
}
|
|
1808
|
+
currentDir = parentDir;
|
|
1809
|
+
}
|
|
1810
|
+
}
|
|
1811
|
+
function scriptsLikelyNeedInstalledDependencies(project, target) {
|
|
1812
|
+
const candidateScripts = target === "ai" ? [project.scripts["sync-ai"]] : project.scripts.sync ? [project.scripts.sync] : [
|
|
1813
|
+
project.scripts["sync-types"],
|
|
1814
|
+
project.scripts["sync-rest"],
|
|
1815
|
+
project.scripts["sync-ai"]
|
|
1816
|
+
];
|
|
1817
|
+
return candidateScripts.some((script) => script !== undefined && LOCAL_SYNC_TOOL_PATTERN.test(script.command));
|
|
1818
|
+
}
|
|
1819
|
+
function assertSyncDependenciesInstalled(project, target) {
|
|
1820
|
+
if (!scriptsLikelyNeedInstalledDependencies(project, target)) {
|
|
1821
|
+
return;
|
|
1822
|
+
}
|
|
1823
|
+
const markerDir = findInstalledDependencyMarkerDir(project.cwd);
|
|
1824
|
+
if (markerDir) {
|
|
1825
|
+
return;
|
|
1826
|
+
}
|
|
1827
|
+
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.DEPENDENCIES_NOT_INSTALLED, `Project dependencies have not been installed yet. Run \`${formatInstallCommand(project.packageManager)}\` from the project root before \`wp-typia sync\`. The generated sync scripts rely on local tools such as \`tsx\`.`);
|
|
1828
|
+
}
|
|
1829
|
+
function getPackageManagerRunInvocation(packageManager, scriptName, extraArgs) {
|
|
1830
|
+
switch (packageManager) {
|
|
1831
|
+
case "bun":
|
|
1832
|
+
return { args: ["run", scriptName, ...extraArgs], command: "bun" };
|
|
1833
|
+
case "npm":
|
|
1834
|
+
return {
|
|
1835
|
+
args: [
|
|
1836
|
+
"run",
|
|
1837
|
+
scriptName,
|
|
1838
|
+
...extraArgs.length > 0 ? ["--", ...extraArgs] : []
|
|
1839
|
+
],
|
|
1840
|
+
command: "npm"
|
|
1841
|
+
};
|
|
1842
|
+
case "pnpm":
|
|
1843
|
+
return { args: ["run", scriptName, ...extraArgs], command: "pnpm" };
|
|
1844
|
+
case "yarn":
|
|
1845
|
+
return { args: ["run", scriptName, ...extraArgs], command: "yarn" };
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
function createSyncPlannedCommand(project, scriptName, extraArgs) {
|
|
1849
|
+
const script = project.scripts[scriptName];
|
|
1850
|
+
if (!script) {
|
|
1851
|
+
return null;
|
|
1852
|
+
}
|
|
1853
|
+
const invocation = getPackageManagerRunInvocation(project.packageManager, script.scriptName, extraArgs);
|
|
1854
|
+
return {
|
|
1855
|
+
args: invocation.args,
|
|
1856
|
+
command: invocation.command,
|
|
1857
|
+
displayCommand: formatRunScript(project.packageManager, script.scriptName, extraArgs.join(" ")),
|
|
1858
|
+
scriptName: script.scriptName
|
|
1859
|
+
};
|
|
1860
|
+
}
|
|
1861
|
+
function buildSyncPlannedCommands(project, extraArgs, target) {
|
|
1862
|
+
if (target === "ai") {
|
|
1863
|
+
const syncAiCommand2 = createSyncPlannedCommand(project, "sync-ai", extraArgs);
|
|
1864
|
+
if (!syncAiCommand2) {
|
|
1865
|
+
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.CONFIGURATION_MISSING, `Expected ${project.packageJsonPath} to define a \`sync-ai\` script for \`wp-typia sync ai\`.`);
|
|
1866
|
+
}
|
|
1867
|
+
return [syncAiCommand2];
|
|
1868
|
+
}
|
|
1869
|
+
if (project.scripts.sync) {
|
|
1870
|
+
return [createSyncPlannedCommand(project, "sync", extraArgs)];
|
|
1871
|
+
}
|
|
1872
|
+
const syncTypesCommand = createSyncPlannedCommand(project, "sync-types", extraArgs);
|
|
1873
|
+
if (!syncTypesCommand) {
|
|
1874
|
+
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.CONFIGURATION_MISSING, `Expected ${project.packageJsonPath} to define either a \`sync\` or \`sync-types\` script.`);
|
|
1875
|
+
}
|
|
1876
|
+
const plannedCommands = [syncTypesCommand];
|
|
1877
|
+
const syncRestCommand = createSyncPlannedCommand(project, "sync-rest", extraArgs);
|
|
1878
|
+
if (syncRestCommand) {
|
|
1879
|
+
plannedCommands.push(syncRestCommand);
|
|
1880
|
+
}
|
|
1881
|
+
const syncAiCommand = createSyncPlannedCommand(project, "sync-ai", extraArgs);
|
|
1882
|
+
if (syncAiCommand) {
|
|
1883
|
+
plannedCommands.push(syncAiCommand);
|
|
1884
|
+
}
|
|
1885
|
+
return plannedCommands;
|
|
1886
|
+
}
|
|
1887
|
+
function runProjectScript(project, plannedCommand, options) {
|
|
1888
|
+
const result = spawnSync(plannedCommand.command, plannedCommand.args, {
|
|
1889
|
+
cwd: project.cwd,
|
|
1890
|
+
encoding: options.captureOutput ? "utf8" : undefined,
|
|
1891
|
+
...options.captureOutput ? { maxBuffer: CAPTURED_SYNC_OUTPUT_MAX_BUFFER } : {},
|
|
1892
|
+
shell: process.platform === "win32",
|
|
1893
|
+
stdio: options.captureOutput ? "pipe" : "inherit"
|
|
1894
|
+
});
|
|
1895
|
+
const stderr = options.captureOutput && typeof result.stderr === "string" ? result.stderr : undefined;
|
|
1896
|
+
const stdout = options.captureOutput && typeof result.stdout === "string" ? result.stdout : undefined;
|
|
1897
|
+
if (result.error || result.status !== 0) {
|
|
1898
|
+
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.COMMAND_EXECUTION, `\`${plannedCommand.displayCommand}\` failed.`, {
|
|
1899
|
+
cause: result.error ?? (stderr ? new Error(stderr.trim()) : undefined)
|
|
1900
|
+
});
|
|
1901
|
+
}
|
|
1902
|
+
return {
|
|
1903
|
+
...plannedCommand,
|
|
1904
|
+
exitCode: result.status ?? 0,
|
|
1905
|
+
...stderr !== undefined ? { stderr } : {},
|
|
1906
|
+
...stdout !== undefined ? { stdout } : {}
|
|
1907
|
+
};
|
|
1908
|
+
}
|
|
1909
|
+
async function executeSyncCommand({
|
|
1910
|
+
captureOutput = false,
|
|
1911
|
+
check = false,
|
|
1912
|
+
cwd,
|
|
1913
|
+
dryRun = false,
|
|
1914
|
+
target = "default"
|
|
1915
|
+
}) {
|
|
1916
|
+
const project = resolveSyncProjectContext(cwd);
|
|
1917
|
+
const extraArgs = check ? ["--check"] : [];
|
|
1918
|
+
const plannedCommands = buildSyncPlannedCommands(project, extraArgs, target);
|
|
1919
|
+
const result = {
|
|
1920
|
+
check,
|
|
1921
|
+
dryRun,
|
|
1922
|
+
packageJsonPath: project.packageJsonPath,
|
|
1923
|
+
packageManager: project.packageManager,
|
|
1924
|
+
plannedCommands,
|
|
1925
|
+
projectDir: project.cwd,
|
|
1926
|
+
target
|
|
1927
|
+
};
|
|
1928
|
+
if (dryRun) {
|
|
1929
|
+
return result;
|
|
1930
|
+
}
|
|
1931
|
+
assertSyncDependenciesInstalled(project, target);
|
|
1932
|
+
result.executedCommands = plannedCommands.map((plannedCommand) => runProjectScript(project, plannedCommand, {
|
|
1933
|
+
captureOutput
|
|
1934
|
+
}));
|
|
1935
|
+
return result;
|
|
1936
|
+
}
|
|
1765
1937
|
// src/ui/lazy-flow.tsx
|
|
1766
1938
|
var import_react33 = __toESM(require_react(), 1);
|
|
1767
1939
|
|
|
@@ -2279,10 +2451,7 @@ var createCommand = defineCommand({
|
|
|
2279
2451
|
emitCliDiagnosticFailure(args, {
|
|
2280
2452
|
code: CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT,
|
|
2281
2453
|
command: "create",
|
|
2282
|
-
detailLines:
|
|
2283
|
-
"`wp-typia create` requires <project-dir>.",
|
|
2284
|
-
"`--dry-run` still needs a logical project directory name because wp-typia derives slugs, package names, and planned file paths from it."
|
|
2285
|
-
]
|
|
2454
|
+
detailLines: buildMissingCreateProjectDirDetailLines()
|
|
2286
2455
|
});
|
|
2287
2456
|
return;
|
|
2288
2457
|
}
|
|
@@ -2344,7 +2513,7 @@ var doctorCommand = defineCommand({
|
|
|
2344
2513
|
const prefersStructuredOutput = prefersStructuredCliOutput(args);
|
|
2345
2514
|
if (prefersStructuredOutput) {
|
|
2346
2515
|
const [{ getDoctorChecks }, { getDoctorFailureDetailLines }] = await Promise.all([
|
|
2347
|
-
import("./cli-doctor-
|
|
2516
|
+
import("./cli-doctor-5m6xyx9q.js"),
|
|
2348
2517
|
import("./cli-diagnostics-5dvztm7q.js")
|
|
2349
2518
|
]);
|
|
2350
2519
|
const checks = await getDoctorChecks(args.cwd);
|
|
@@ -2403,7 +2572,7 @@ var initCommand = defineCommand({
|
|
|
2403
2572
|
|
|
2404
2573
|
// src/mcp.ts
|
|
2405
2574
|
import fs4 from "fs/promises";
|
|
2406
|
-
import
|
|
2575
|
+
import path4 from "path";
|
|
2407
2576
|
|
|
2408
2577
|
// ../../node_modules/.bun/@bunli+plugin-mcp@0.2.5+ef72ce197b058209/node_modules/@bunli/plugin-mcp/src/errors.ts
|
|
2409
2578
|
class SchemaConversionError extends TaggedError("SchemaConversionError")() {
|
|
@@ -2422,7 +2591,7 @@ class McpToolsProviderError extends TaggedError("McpToolsProviderError")() {
|
|
|
2422
2591
|
function jsonSchemaToZodSchema(schema, options = {}) {
|
|
2423
2592
|
return convertSchema(schema, options, "$");
|
|
2424
2593
|
}
|
|
2425
|
-
function convertSchema(schema, options,
|
|
2594
|
+
function convertSchema(schema, options, path4) {
|
|
2426
2595
|
const { coerce = true } = options;
|
|
2427
2596
|
if (!schema || typeof schema !== "object") {
|
|
2428
2597
|
return Result.ok(exports_external.unknown());
|
|
@@ -2437,49 +2606,49 @@ function convertSchema(schema, options, path3) {
|
|
|
2437
2606
|
return Result.ok(exports_external.enum(enumValues));
|
|
2438
2607
|
}
|
|
2439
2608
|
const literals = enumValues.map((v) => exports_external.literal(v));
|
|
2440
|
-
return unionFromSchemas(literals,
|
|
2609
|
+
return unionFromSchemas(literals, path4);
|
|
2441
2610
|
}
|
|
2442
2611
|
}
|
|
2443
2612
|
if (schema.anyOf && schema.anyOf.length > 0) {
|
|
2444
|
-
const schemas = mapSchemas(schema.anyOf, options, `${
|
|
2613
|
+
const schemas = mapSchemas(schema.anyOf, options, `${path4}.anyOf`);
|
|
2445
2614
|
if (Result.isError(schemas)) {
|
|
2446
2615
|
return schemas;
|
|
2447
2616
|
}
|
|
2448
|
-
return unionFromSchemas(schemas.value, `${
|
|
2617
|
+
return unionFromSchemas(schemas.value, `${path4}.anyOf`);
|
|
2449
2618
|
}
|
|
2450
2619
|
if (schema.oneOf && schema.oneOf.length > 0) {
|
|
2451
|
-
const schemas = mapSchemas(schema.oneOf, options, `${
|
|
2620
|
+
const schemas = mapSchemas(schema.oneOf, options, `${path4}.oneOf`);
|
|
2452
2621
|
if (Result.isError(schemas)) {
|
|
2453
2622
|
return schemas;
|
|
2454
2623
|
}
|
|
2455
|
-
return unionFromSchemas(schemas.value, `${
|
|
2624
|
+
return unionFromSchemas(schemas.value, `${path4}.oneOf`);
|
|
2456
2625
|
}
|
|
2457
2626
|
const schemaType = Array.isArray(schema.type) ? schema.type[0] : schema.type;
|
|
2458
2627
|
switch (schemaType) {
|
|
2459
2628
|
case "string":
|
|
2460
|
-
return buildStringSchema(schema,
|
|
2629
|
+
return buildStringSchema(schema, path4);
|
|
2461
2630
|
case "number":
|
|
2462
2631
|
case "integer":
|
|
2463
2632
|
return Result.ok(buildNumberSchema(schema, coerce));
|
|
2464
2633
|
case "boolean":
|
|
2465
2634
|
return Result.ok(buildBooleanSchema());
|
|
2466
2635
|
case "array":
|
|
2467
|
-
return buildArraySchema(schema, options,
|
|
2636
|
+
return buildArraySchema(schema, options, path4);
|
|
2468
2637
|
case "object":
|
|
2469
|
-
return buildObjectSchema(schema, options,
|
|
2638
|
+
return buildObjectSchema(schema, options, path4);
|
|
2470
2639
|
case "null":
|
|
2471
2640
|
return Result.ok(exports_external.null());
|
|
2472
2641
|
default:
|
|
2473
2642
|
if (schema.properties) {
|
|
2474
|
-
return buildObjectSchema(schema, options,
|
|
2643
|
+
return buildObjectSchema(schema, options, path4);
|
|
2475
2644
|
}
|
|
2476
2645
|
if (schema.items) {
|
|
2477
|
-
return buildArraySchema(schema, options,
|
|
2646
|
+
return buildArraySchema(schema, options, path4);
|
|
2478
2647
|
}
|
|
2479
2648
|
return Result.ok(exports_external.unknown());
|
|
2480
2649
|
}
|
|
2481
2650
|
}
|
|
2482
|
-
function buildStringSchema(schema,
|
|
2651
|
+
function buildStringSchema(schema, path4) {
|
|
2483
2652
|
let zodSchema = exports_external.string();
|
|
2484
2653
|
if (schema.minLength !== undefined) {
|
|
2485
2654
|
zodSchema = zodSchema.min(schema.minLength);
|
|
@@ -2492,7 +2661,7 @@ function buildStringSchema(schema, path3) {
|
|
|
2492
2661
|
const regexResult = Result.try({
|
|
2493
2662
|
try: () => new RegExp(pattern),
|
|
2494
2663
|
catch: (cause) => new SchemaConversionError({
|
|
2495
|
-
path:
|
|
2664
|
+
path: path4,
|
|
2496
2665
|
message: `Invalid regex pattern "${pattern}"`,
|
|
2497
2666
|
cause
|
|
2498
2667
|
})
|
|
@@ -2549,19 +2718,19 @@ function buildNumberSchema(schema, coerce) {
|
|
|
2549
2718
|
function buildBooleanSchema() {
|
|
2550
2719
|
return exports_external.boolean();
|
|
2551
2720
|
}
|
|
2552
|
-
function buildArraySchema(schema, options,
|
|
2721
|
+
function buildArraySchema(schema, options, path4) {
|
|
2553
2722
|
let itemSchema = exports_external.unknown();
|
|
2554
2723
|
if (schema.items) {
|
|
2555
2724
|
if (Array.isArray(schema.items)) {
|
|
2556
2725
|
if (schema.items.length > 0) {
|
|
2557
|
-
const itemResult = convertSchema(schema.items[0], options, `${
|
|
2726
|
+
const itemResult = convertSchema(schema.items[0], options, `${path4}.items[0]`);
|
|
2558
2727
|
if (Result.isError(itemResult)) {
|
|
2559
2728
|
return itemResult;
|
|
2560
2729
|
}
|
|
2561
2730
|
itemSchema = itemResult.value;
|
|
2562
2731
|
}
|
|
2563
2732
|
} else {
|
|
2564
|
-
const itemResult = convertSchema(schema.items, options, `${
|
|
2733
|
+
const itemResult = convertSchema(schema.items, options, `${path4}.items`);
|
|
2565
2734
|
if (Result.isError(itemResult)) {
|
|
2566
2735
|
return itemResult;
|
|
2567
2736
|
}
|
|
@@ -2577,14 +2746,14 @@ function buildArraySchema(schema, options, path3) {
|
|
|
2577
2746
|
}
|
|
2578
2747
|
return Result.ok(zodSchema);
|
|
2579
2748
|
}
|
|
2580
|
-
function buildObjectSchema(schema, options,
|
|
2749
|
+
function buildObjectSchema(schema, options, path4) {
|
|
2581
2750
|
if (!schema.properties) {
|
|
2582
2751
|
return Result.ok(exports_external.record(exports_external.string(), exports_external.unknown()));
|
|
2583
2752
|
}
|
|
2584
2753
|
const shape = {};
|
|
2585
2754
|
const requiredFields = new Set(schema.required || []);
|
|
2586
2755
|
for (const [propName, propSchema] of Object.entries(schema.properties)) {
|
|
2587
|
-
const propResult = convertSchema(propSchema, options, `${
|
|
2756
|
+
const propResult = convertSchema(propSchema, options, `${path4}.properties.${propName}`);
|
|
2588
2757
|
if (Result.isError(propResult)) {
|
|
2589
2758
|
return propResult;
|
|
2590
2759
|
}
|
|
@@ -2599,10 +2768,10 @@ function buildObjectSchema(schema, options, path3) {
|
|
|
2599
2768
|
}
|
|
2600
2769
|
return Result.ok(exports_external.object(shape));
|
|
2601
2770
|
}
|
|
2602
|
-
function mapSchemas(schemas, options,
|
|
2771
|
+
function mapSchemas(schemas, options, path4) {
|
|
2603
2772
|
const zodSchemas = [];
|
|
2604
2773
|
for (let index = 0;index < schemas.length; index += 1) {
|
|
2605
|
-
const converted = convertSchema(schemas[index], options, `${
|
|
2774
|
+
const converted = convertSchema(schemas[index], options, `${path4}[${index}]`);
|
|
2606
2775
|
if (Result.isError(converted)) {
|
|
2607
2776
|
return converted;
|
|
2608
2777
|
}
|
|
@@ -2610,11 +2779,11 @@ function mapSchemas(schemas, options, path3) {
|
|
|
2610
2779
|
}
|
|
2611
2780
|
return Result.ok(zodSchemas);
|
|
2612
2781
|
}
|
|
2613
|
-
function unionFromSchemas(schemas,
|
|
2782
|
+
function unionFromSchemas(schemas, path4) {
|
|
2614
2783
|
if (schemas.length === 0) {
|
|
2615
2784
|
return Result.err(new SchemaConversionError({
|
|
2616
|
-
path:
|
|
2617
|
-
message: `Cannot create union from an empty schema set at ${
|
|
2785
|
+
path: path4,
|
|
2786
|
+
message: `Cannot create union from an empty schema set at ${path4}`,
|
|
2618
2787
|
cause: new Error("Empty schema union")
|
|
2619
2788
|
}));
|
|
2620
2789
|
}
|
|
@@ -2937,7 +3106,7 @@ function getErrorCauseOptions(error) {
|
|
|
2937
3106
|
return error instanceof Error ? { cause: error } : undefined;
|
|
2938
3107
|
}
|
|
2939
3108
|
async function readSchemaSource(cwd, source) {
|
|
2940
|
-
const schemaPath =
|
|
3109
|
+
const schemaPath = path4.resolve(cwd, source.path);
|
|
2941
3110
|
const raw = await fs4.readFile(schemaPath, "utf8");
|
|
2942
3111
|
let parsed;
|
|
2943
3112
|
try {
|
|
@@ -2959,7 +3128,7 @@ async function readSchemaSource(cwd, source) {
|
|
|
2959
3128
|
async function loadMcpToolGroups(cwd, schemaSources) {
|
|
2960
3129
|
return Promise.all(schemaSources.map((source) => readSchemaSource(cwd, source)));
|
|
2961
3130
|
}
|
|
2962
|
-
async function syncMcpSchemas(cwd, schemaSources, outputDir =
|
|
3131
|
+
async function syncMcpSchemas(cwd, schemaSources, outputDir = path4.join(cwd, ".bunli", "mcp")) {
|
|
2963
3132
|
const groups = await loadMcpToolGroups(cwd, schemaSources);
|
|
2964
3133
|
const result = await generateMCPTypes({
|
|
2965
3134
|
outputDir,
|
|
@@ -2982,7 +3151,7 @@ async function syncMcpSchemas(cwd, schemaSources, outputDir = path3.join(cwd, ".
|
|
|
2982
3151
|
}
|
|
2983
3152
|
}
|
|
2984
3153
|
await fs4.mkdir(outputDir, { recursive: true });
|
|
2985
|
-
await fs4.writeFile(
|
|
3154
|
+
await fs4.writeFile(path4.join(outputDir, "registry.json"), `${JSON.stringify(registry, null, 2)}
|
|
2986
3155
|
`, "utf8");
|
|
2987
3156
|
return {
|
|
2988
3157
|
commandCount: registry.reduce((count, group) => count + group.tools.length, 0),
|
|
@@ -2992,12 +3161,31 @@ async function syncMcpSchemas(cwd, schemaSources, outputDir = path3.join(cwd, ".
|
|
|
2992
3161
|
}
|
|
2993
3162
|
|
|
2994
3163
|
// src/commands/mcp.ts
|
|
3164
|
+
var defaultPrintLine = (line) => {
|
|
3165
|
+
process.stdout.write(`${line}
|
|
3166
|
+
`);
|
|
3167
|
+
};
|
|
3168
|
+
function resolveMcpPrintLine(args) {
|
|
3169
|
+
return args.printLine ?? defaultPrintLine;
|
|
3170
|
+
}
|
|
3171
|
+
function printMcpToolGroupSummary(summary, printLine) {
|
|
3172
|
+
for (const group of summary) {
|
|
3173
|
+
printLine(`${group.namespace} (${group.toolCount})`);
|
|
3174
|
+
for (const tool of group.tools) {
|
|
3175
|
+
printLine(` - ${tool}`);
|
|
3176
|
+
}
|
|
3177
|
+
}
|
|
3178
|
+
}
|
|
3179
|
+
function printMcpSyncSummary(result, printLine) {
|
|
3180
|
+
printLine(`Synced ${result.commandCount} MCP tools across ${result.groups.length} namespaces into ${result.outputDir}.`);
|
|
3181
|
+
}
|
|
2995
3182
|
var mcpCommand = defineCommand({
|
|
2996
3183
|
defaultFormat: "json",
|
|
2997
3184
|
description: "Inspect or sync schema-driven MCP metadata for wp-typia.",
|
|
2998
3185
|
handler: async (args) => {
|
|
2999
3186
|
const subcommand = args.positional[0] ?? "list";
|
|
3000
3187
|
const prefersStructuredOutput = prefersStructuredCliOutput(args);
|
|
3188
|
+
const printLine = resolveMcpPrintLine(args);
|
|
3001
3189
|
const userConfig = args.context?.store?.wpTypiaUserConfig && typeof args.context.store.wpTypiaUserConfig === "object" ? args.context.store.wpTypiaUserConfig : {};
|
|
3002
3190
|
const schemaSources = getMcpSchemaSources(userConfig);
|
|
3003
3191
|
if (schemaSources.length === 0) {
|
|
@@ -3022,12 +3210,7 @@ var mcpCommand = defineCommand({
|
|
|
3022
3210
|
args.output({ groups: summary });
|
|
3023
3211
|
return;
|
|
3024
3212
|
}
|
|
3025
|
-
|
|
3026
|
-
console.log(`${group.namespace} (${group.toolCount})`);
|
|
3027
|
-
for (const tool of group.tools) {
|
|
3028
|
-
console.log(` - ${tool}`);
|
|
3029
|
-
}
|
|
3030
|
-
}
|
|
3213
|
+
printMcpToolGroupSummary(summary, printLine);
|
|
3031
3214
|
return;
|
|
3032
3215
|
}
|
|
3033
3216
|
if (subcommand === "sync") {
|
|
@@ -3037,7 +3220,7 @@ var mcpCommand = defineCommand({
|
|
|
3037
3220
|
args.output({ sync: result });
|
|
3038
3221
|
return;
|
|
3039
3222
|
}
|
|
3040
|
-
|
|
3223
|
+
printMcpSyncSummary(result, printLine);
|
|
3041
3224
|
return;
|
|
3042
3225
|
}
|
|
3043
3226
|
emitCliDiagnosticFailure(args, {
|
|
@@ -3221,4 +3404,4 @@ export {
|
|
|
3221
3404
|
wpTypiaCommands
|
|
3222
3405
|
};
|
|
3223
3406
|
|
|
3224
|
-
//# debugId=
|
|
3407
|
+
//# debugId=8B3272B9527B417864756E2164756E21
|