wp-typia 0.22.2 → 0.22.3

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.
@@ -36308,93 +36308,192 @@ function getMutableBlockHooks(blockJson, blockJsonRelativePath) {
36308
36308
  }
36309
36309
  return blockHooks;
36310
36310
  }
36311
- function assertVariationDoesNotExist(projectDir, blockSlug, variationSlug, inventory) {
36312
- const variationPath = path12.join(projectDir, "src", "blocks", blockSlug, "variations", `${variationSlug}.ts`);
36313
- if (fs8.existsSync(variationPath)) {
36314
- throw new Error(`A variation already exists at ${path12.relative(projectDir, variationPath)}. Choose a different name.`);
36311
+ function assertScaffoldDoesNotExist(options) {
36312
+ for (const collision of options.filesystemCollisions) {
36313
+ const targetPath = path12.join(options.projectDir, collision.relativePath);
36314
+ if (fs8.existsSync(targetPath)) {
36315
+ throw new Error(`${collision.label} already exists at ${path12.relative(options.projectDir, targetPath)}. Choose a different name.`);
36316
+ }
36315
36317
  }
36316
- if (inventory.variations.some((entry) => entry.block === blockSlug && entry.slug === variationSlug)) {
36317
- throw new Error(`A variation inventory entry already exists for ${blockSlug}/${variationSlug}. Choose a different name.`);
36318
+ if (options.inventoryCollision && options.inventoryCollision.entries.some(options.inventoryCollision.exists)) {
36319
+ throw new Error(options.inventoryCollision.message);
36318
36320
  }
36319
36321
  }
36322
+ function assertVariationDoesNotExist(projectDir, blockSlug, variationSlug, inventory) {
36323
+ assertScaffoldDoesNotExist({
36324
+ filesystemCollisions: [
36325
+ {
36326
+ label: "A variation",
36327
+ relativePath: path12.join("src", "blocks", blockSlug, "variations", `${variationSlug}.ts`)
36328
+ }
36329
+ ],
36330
+ inventoryCollision: {
36331
+ entries: inventory.variations,
36332
+ exists: (entry) => entry.block === blockSlug && entry.slug === variationSlug,
36333
+ message: `A variation inventory entry already exists for ${blockSlug}/${variationSlug}. Choose a different name.`
36334
+ },
36335
+ projectDir
36336
+ });
36337
+ }
36338
+ function assertBlockStyleDoesNotExist(projectDir, blockSlug, styleSlug, inventory) {
36339
+ assertScaffoldDoesNotExist({
36340
+ filesystemCollisions: [
36341
+ {
36342
+ label: "A block style",
36343
+ relativePath: path12.join("src", "blocks", blockSlug, "styles", `${styleSlug}.ts`)
36344
+ }
36345
+ ],
36346
+ inventoryCollision: {
36347
+ entries: inventory.blockStyles,
36348
+ exists: (entry) => entry.block === blockSlug && entry.slug === styleSlug,
36349
+ message: `A block style inventory entry already exists for ${blockSlug}/${styleSlug}. Choose a different name.`
36350
+ },
36351
+ projectDir
36352
+ });
36353
+ }
36354
+ function assertBlockTransformDoesNotExist(projectDir, blockSlug, transformSlug, inventory) {
36355
+ assertScaffoldDoesNotExist({
36356
+ filesystemCollisions: [
36357
+ {
36358
+ label: "A block transform",
36359
+ relativePath: path12.join("src", "blocks", blockSlug, "transforms", `${transformSlug}.ts`)
36360
+ }
36361
+ ],
36362
+ inventoryCollision: {
36363
+ entries: inventory.blockTransforms,
36364
+ exists: (entry) => entry.block === blockSlug && entry.slug === transformSlug,
36365
+ message: `A block transform inventory entry already exists for ${blockSlug}/${transformSlug}. Choose a different name.`
36366
+ },
36367
+ projectDir
36368
+ });
36369
+ }
36320
36370
  function assertPatternDoesNotExist(projectDir, patternSlug, inventory) {
36321
- const patternPath = path12.join(projectDir, "src", "patterns", `${patternSlug}.php`);
36322
- if (fs8.existsSync(patternPath)) {
36323
- throw new Error(`A pattern already exists at ${path12.relative(projectDir, patternPath)}. Choose a different name.`);
36324
- }
36325
- if (inventory.patterns.some((entry) => entry.slug === patternSlug)) {
36326
- throw new Error(`A pattern inventory entry already exists for ${patternSlug}. Choose a different name.`);
36327
- }
36371
+ assertScaffoldDoesNotExist({
36372
+ filesystemCollisions: [
36373
+ {
36374
+ label: "A pattern",
36375
+ relativePath: path12.join("src", "patterns", `${patternSlug}.php`)
36376
+ }
36377
+ ],
36378
+ inventoryCollision: {
36379
+ entries: inventory.patterns,
36380
+ exists: (entry) => entry.slug === patternSlug,
36381
+ message: `A pattern inventory entry already exists for ${patternSlug}. Choose a different name.`
36382
+ },
36383
+ projectDir
36384
+ });
36328
36385
  }
36329
36386
  function assertBindingSourceDoesNotExist(projectDir, bindingSourceSlug, inventory) {
36330
- const bindingSourceDir = path12.join(projectDir, "src", "bindings", bindingSourceSlug);
36331
- if (fs8.existsSync(bindingSourceDir)) {
36332
- throw new Error(`A binding source already exists at ${path12.relative(projectDir, bindingSourceDir)}. Choose a different name.`);
36333
- }
36334
- if (inventory.bindingSources.some((entry) => entry.slug === bindingSourceSlug)) {
36335
- throw new Error(`A binding source inventory entry already exists for ${bindingSourceSlug}. Choose a different name.`);
36336
- }
36387
+ assertScaffoldDoesNotExist({
36388
+ filesystemCollisions: [
36389
+ {
36390
+ label: "A binding source",
36391
+ relativePath: path12.join("src", "bindings", bindingSourceSlug)
36392
+ }
36393
+ ],
36394
+ inventoryCollision: {
36395
+ entries: inventory.bindingSources,
36396
+ exists: (entry) => entry.slug === bindingSourceSlug,
36397
+ message: `A binding source inventory entry already exists for ${bindingSourceSlug}. Choose a different name.`
36398
+ },
36399
+ projectDir
36400
+ });
36337
36401
  }
36338
36402
  function assertRestResourceDoesNotExist(projectDir, restResourceSlug, inventory) {
36339
- const restResourceDir = path12.join(projectDir, "src", "rest", restResourceSlug);
36340
- const restResourcePhpPath = path12.join(projectDir, "inc", "rest", `${restResourceSlug}.php`);
36341
- if (fs8.existsSync(restResourceDir)) {
36342
- throw new Error(`A REST resource already exists at ${path12.relative(projectDir, restResourceDir)}. Choose a different name.`);
36343
- }
36344
- if (fs8.existsSync(restResourcePhpPath)) {
36345
- throw new Error(`A REST resource bootstrap already exists at ${path12.relative(projectDir, restResourcePhpPath)}. Choose a different name.`);
36346
- }
36347
- if (inventory.restResources.some((entry) => entry.slug === restResourceSlug)) {
36348
- throw new Error(`A REST resource inventory entry already exists for ${restResourceSlug}. Choose a different name.`);
36349
- }
36403
+ assertScaffoldDoesNotExist({
36404
+ filesystemCollisions: [
36405
+ {
36406
+ label: "A REST resource",
36407
+ relativePath: path12.join("src", "rest", restResourceSlug)
36408
+ },
36409
+ {
36410
+ label: "A REST resource bootstrap",
36411
+ relativePath: path12.join("inc", "rest", `${restResourceSlug}.php`)
36412
+ }
36413
+ ],
36414
+ inventoryCollision: {
36415
+ entries: inventory.restResources,
36416
+ exists: (entry) => entry.slug === restResourceSlug,
36417
+ message: `A REST resource inventory entry already exists for ${restResourceSlug}. Choose a different name.`
36418
+ },
36419
+ projectDir
36420
+ });
36350
36421
  }
36351
36422
  function assertAdminViewDoesNotExist(projectDir, adminViewSlug, inventory) {
36352
- const adminViewDir = path12.join(projectDir, "src", "admin-views", adminViewSlug);
36353
- const adminViewPhpPath = path12.join(projectDir, "inc", "admin-views", `${adminViewSlug}.php`);
36354
- if (fs8.existsSync(adminViewDir)) {
36355
- throw new Error(`An admin view already exists at ${path12.relative(projectDir, adminViewDir)}. Choose a different name.`);
36356
- }
36357
- if (fs8.existsSync(adminViewPhpPath)) {
36358
- throw new Error(`An admin view bootstrap already exists at ${path12.relative(projectDir, adminViewPhpPath)}. Choose a different name.`);
36359
- }
36360
- if (inventory.adminViews.some((entry) => entry.slug === adminViewSlug)) {
36361
- throw new Error(`An admin view inventory entry already exists for ${adminViewSlug}. Choose a different name.`);
36362
- }
36423
+ assertScaffoldDoesNotExist({
36424
+ filesystemCollisions: [
36425
+ {
36426
+ label: "An admin view",
36427
+ relativePath: path12.join("src", "admin-views", adminViewSlug)
36428
+ },
36429
+ {
36430
+ label: "An admin view bootstrap",
36431
+ relativePath: path12.join("inc", "admin-views", `${adminViewSlug}.php`)
36432
+ }
36433
+ ],
36434
+ inventoryCollision: {
36435
+ entries: inventory.adminViews,
36436
+ exists: (entry) => entry.slug === adminViewSlug,
36437
+ message: `An admin view inventory entry already exists for ${adminViewSlug}. Choose a different name.`
36438
+ },
36439
+ projectDir
36440
+ });
36363
36441
  }
36364
36442
  function assertAbilityDoesNotExist(projectDir, abilitySlug, inventory) {
36365
- const abilityDir = path12.join(projectDir, "src", "abilities", abilitySlug);
36366
- const abilityPhpPath = path12.join(projectDir, "inc", "abilities", `${abilitySlug}.php`);
36367
- if (fs8.existsSync(abilityDir)) {
36368
- throw new Error(`An ability scaffold already exists at ${path12.relative(projectDir, abilityDir)}. Choose a different name.`);
36369
- }
36370
- if (fs8.existsSync(abilityPhpPath)) {
36371
- throw new Error(`An ability bootstrap already exists at ${path12.relative(projectDir, abilityPhpPath)}. Choose a different name.`);
36372
- }
36373
- if (inventory.abilities.some((entry) => entry.slug === abilitySlug)) {
36374
- throw new Error(`An ability inventory entry already exists for ${abilitySlug}. Choose a different name.`);
36375
- }
36443
+ assertScaffoldDoesNotExist({
36444
+ filesystemCollisions: [
36445
+ {
36446
+ label: "An ability scaffold",
36447
+ relativePath: path12.join("src", "abilities", abilitySlug)
36448
+ },
36449
+ {
36450
+ label: "An ability bootstrap",
36451
+ relativePath: path12.join("inc", "abilities", `${abilitySlug}.php`)
36452
+ }
36453
+ ],
36454
+ inventoryCollision: {
36455
+ entries: inventory.abilities,
36456
+ exists: (entry) => entry.slug === abilitySlug,
36457
+ message: `An ability inventory entry already exists for ${abilitySlug}. Choose a different name.`
36458
+ },
36459
+ projectDir
36460
+ });
36376
36461
  }
36377
36462
  function assertAiFeatureDoesNotExist(projectDir, aiFeatureSlug, inventory) {
36378
- const aiFeatureDir = path12.join(projectDir, "src", "ai-features", aiFeatureSlug);
36379
- const aiFeaturePhpPath = path12.join(projectDir, "inc", "ai-features", `${aiFeatureSlug}.php`);
36380
- if (fs8.existsSync(aiFeatureDir)) {
36381
- throw new Error(`An AI feature already exists at ${path12.relative(projectDir, aiFeatureDir)}. Choose a different name.`);
36382
- }
36383
- if (fs8.existsSync(aiFeaturePhpPath)) {
36384
- throw new Error(`An AI feature bootstrap already exists at ${path12.relative(projectDir, aiFeaturePhpPath)}. Choose a different name.`);
36385
- }
36386
- if (inventory.aiFeatures.some((entry) => entry.slug === aiFeatureSlug)) {
36387
- throw new Error(`An AI feature inventory entry already exists for ${aiFeatureSlug}. Choose a different name.`);
36388
- }
36463
+ assertScaffoldDoesNotExist({
36464
+ filesystemCollisions: [
36465
+ {
36466
+ label: "An AI feature",
36467
+ relativePath: path12.join("src", "ai-features", aiFeatureSlug)
36468
+ },
36469
+ {
36470
+ label: "An AI feature bootstrap",
36471
+ relativePath: path12.join("inc", "ai-features", `${aiFeatureSlug}.php`)
36472
+ }
36473
+ ],
36474
+ inventoryCollision: {
36475
+ entries: inventory.aiFeatures,
36476
+ exists: (entry) => entry.slug === aiFeatureSlug,
36477
+ message: `An AI feature inventory entry already exists for ${aiFeatureSlug}. Choose a different name.`
36478
+ },
36479
+ projectDir
36480
+ });
36389
36481
  }
36390
36482
  function assertEditorPluginDoesNotExist(projectDir, editorPluginSlug, inventory) {
36391
- const editorPluginDir = path12.join(projectDir, "src", "editor-plugins", editorPluginSlug);
36392
- if (fs8.existsSync(editorPluginDir)) {
36393
- throw new Error(`An editor plugin already exists at ${path12.relative(projectDir, editorPluginDir)}. Choose a different name.`);
36394
- }
36395
- if (inventory.editorPlugins.some((entry) => entry.slug === editorPluginSlug)) {
36396
- throw new Error(`An editor plugin inventory entry already exists for ${editorPluginSlug}. Choose a different name.`);
36397
- }
36483
+ assertScaffoldDoesNotExist({
36484
+ filesystemCollisions: [
36485
+ {
36486
+ label: "An editor plugin",
36487
+ relativePath: path12.join("src", "editor-plugins", editorPluginSlug)
36488
+ }
36489
+ ],
36490
+ inventoryCollision: {
36491
+ entries: inventory.editorPlugins,
36492
+ exists: (entry) => entry.slug === editorPluginSlug,
36493
+ message: `An editor plugin inventory entry already exists for ${editorPluginSlug}. Choose a different name.`
36494
+ },
36495
+ projectDir
36496
+ });
36398
36497
  }
36399
36498
  function formatAddHelpText() {
36400
36499
  return `Usage:
@@ -226909,7 +227008,9 @@ type InteractivityActionShape = object;
226909
227008
  type InteractivityCallbackShape = object;
226910
227009
  type InteractivityContextShape = object;
226911
227010
  type InteractivityStateShape = object;
226912
- type InteractivityCallable = CallableFunction;
227011
+ type InteractivityCallable =
227012
+ | ((...args: unknown[]) => unknown)
227013
+ | ReturnType<typeof import('@wordpress/interactivity').withSyncEvent>;
226913
227014
  type InteractivityKey<T extends object> = Extract<keyof T, string>;
226914
227015
  type InteractivityMethodKey<T extends object> = {
226915
227016
  [Key in InteractivityKey<T>]: T[Key] extends InteractivityCallable ? Key : never;
@@ -227012,7 +227113,7 @@ export function defineInteractivityStore<
227012
227113
  };
227013
227114
  }
227014
227115
 
227015
- type InteractivityActionHandler = CallableFunction;
227116
+ type InteractivityActionHandler = InteractivityCallable;
227016
227117
 
227017
227118
  export interface {{pascalCase}}StoreActions {
227018
227119
  handleClick: InteractivityActionHandler;
@@ -232343,8 +232444,10 @@ registerBlockBindingsSource( {
232343
232444
  `;
232344
232445
  }
232345
232446
  function resolveBindingTarget(options, namespace) {
232346
- const hasBlock = options.blockName !== undefined && options.blockName.trim().length > 0;
232347
- const hasAttribute = options.attributeName !== undefined && options.attributeName.trim().length > 0;
232447
+ const blockName = normalizeOptionalCliString(options.blockName);
232448
+ const attributeName = normalizeOptionalCliString(options.attributeName);
232449
+ const hasBlock = blockName !== undefined;
232450
+ const hasAttribute = attributeName !== undefined;
232348
232451
  if (!hasBlock && !hasAttribute) {
232349
232452
  return;
232350
232453
  }
@@ -232352,8 +232455,8 @@ function resolveBindingTarget(options, namespace) {
232352
232455
  throw new Error("`wp-typia add binding-source` requires --block and --attribute to be provided together.");
232353
232456
  }
232354
232457
  return {
232355
- attributeName: assertValidBindingAttributeName(options.attributeName ?? ""),
232356
- blockSlug: resolveBindingTargetBlockSlug(options.blockName ?? "", namespace)
232458
+ attributeName: assertValidBindingAttributeName(attributeName ?? ""),
232459
+ blockSlug: resolveBindingTargetBlockSlug(blockName ?? "", namespace)
232357
232460
  };
232358
232461
  }
232359
232462
  function formatBindingAttributeTypeMember(attributeName) {
@@ -233109,6 +233212,7 @@ var init_cli_add_workspace_assets = __esm(() => {
233109
233212
  init_workspace_project();
233110
233213
  init_workspace_inventory();
233111
233214
  init_cli_add_shared();
233215
+ init_cli_validation();
233112
233216
  import_typescript2 = __toESM(require_typescript(), 1);
233113
233217
  BINDING_ATTRIBUTE_NAME_PATTERN = /^[A-Za-z][A-Za-z0-9_-]*$/u;
233114
233218
  });
@@ -234358,22 +234462,10 @@ var init_cli_add_workspace_rest = __esm(() => {
234358
234462
  init_workspace_project();
234359
234463
  });
234360
234464
 
234361
- // ../wp-typia-project-tools/src/runtime/cli-add-workspace-ability.ts
234362
- import fs44 from "fs";
234363
- import { promises as fsp21 } from "fs";
234364
- import path57 from "path";
234365
- import { syncTypeSchemas as syncTypeSchemas3 } from "@wp-typia/block-runtime/metadata-core";
234366
- function resolveManagedDependencyVersion(existingVersion, requiredVersion) {
234367
- if (!existingVersion) {
234368
- return requiredVersion;
234369
- }
234370
- const existingMinimum = import_semver2.default.minVersion(existingVersion);
234371
- const requiredMinimum = import_semver2.default.minVersion(requiredVersion);
234372
- if (!existingMinimum || !requiredMinimum) {
234373
- return requiredVersion;
234374
- }
234375
- return import_semver2.default.gte(existingMinimum, requiredMinimum) ? existingVersion : requiredVersion;
234376
- }
234465
+ // ../wp-typia-project-tools/src/runtime/cli-add-workspace-ability-types.ts
234466
+ var ABILITY_SERVER_GLOB = "/inc/abilities/*.php", ABILITY_EDITOR_SCRIPT = "build/abilities/index.js", ABILITY_EDITOR_ASSET = "build/abilities/index.asset.php", ABILITY_REGISTRY_END_MARKER = "// wp-typia add ability entries end", ABILITY_REGISTRY_START_MARKER = "// wp-typia add ability entries start", WP_ABILITIES_SCRIPT_MODULE_ID = "@wordpress/abilities", WP_CORE_ABILITIES_SCRIPT_MODULE_ID = "@wordpress/core-abilities";
234467
+
234468
+ // ../wp-typia-project-tools/src/runtime/cli-add-workspace-ability-templates.ts
234377
234469
  function toAbilityCategorySlug(workspaceNamespace) {
234378
234470
  const normalizedNamespace = workspaceNamespace.replace(/[^a-z0-9-]+/gu, "-").replace(/-{2,}/gu, "-").replace(/^-|-$/gu, "");
234379
234471
  return `${normalizedNamespace || "workspace"}-workflows`;
@@ -234838,6 +234930,27 @@ function buildAbilityRegistrySource(abilitySlugs) {
234838
234930
  `).concat(`
234839
234931
  `);
234840
234932
  }
234933
+ var init_cli_add_workspace_ability_templates = __esm(() => {
234934
+ init_scaffold_compatibility();
234935
+ init_cli_add_shared();
234936
+ });
234937
+
234938
+ // ../wp-typia-project-tools/src/runtime/cli-add-workspace-ability-scaffold.ts
234939
+ import fs44 from "fs";
234940
+ import { promises as fsp21 } from "fs";
234941
+ import path57 from "path";
234942
+ import { syncTypeSchemas as syncTypeSchemas3 } from "@wp-typia/block-runtime/metadata-core";
234943
+ function resolveManagedDependencyVersion(existingVersion, requiredVersion) {
234944
+ if (!existingVersion) {
234945
+ return requiredVersion;
234946
+ }
234947
+ const existingMinimum = import_semver2.default.minVersion(existingVersion);
234948
+ const requiredMinimum = import_semver2.default.minVersion(requiredVersion);
234949
+ if (!existingMinimum || !requiredMinimum) {
234950
+ return requiredVersion;
234951
+ }
234952
+ return import_semver2.default.gte(existingMinimum, requiredMinimum) ? existingVersion : requiredVersion;
234953
+ }
234841
234954
  function resolveAbilityRegistryPath(projectDir) {
234842
234955
  const abilitiesDir = path57.join(projectDir, "src", "abilities");
234843
234956
  return [path57.join(abilitiesDir, "index.ts"), path57.join(abilitiesDir, "index.js")].find((candidatePath) => fs44.existsSync(candidatePath)) ?? path57.join(abilitiesDir, "index.ts");
@@ -235049,21 +235162,29 @@ async function ensureAbilityBuildScriptAnchors(workspace) {
235049
235162
  }
235050
235163
  const sharedEntriesPattern = /(for\s*\(\s*const\s+relativePath\s+of\s+\[)([\s\S]*?)(\]\s*\)\s*\{)/u;
235051
235164
  const match3 = nextSource.match(sharedEntriesPattern);
235052
- if (!match3 || !match3[2].includes("src/bindings/index.ts") || !match3[2].includes("src/editor-plugins/index.ts")) {
235165
+ if (!match3 || !/['"]src\/bindings\/index\.(?:ts|js)['"]/u.test(match3[2]) || !/['"]src\/editor-plugins\/index\.(?:tsx|ts|js)['"]/u.test(match3[2])) {
235053
235166
  throw new Error([
235054
235167
  `ensureAbilityBuildScriptAnchors could not patch ${path57.basename(buildScriptPath)}.`,
235055
235168
  "Missing the expected shared editor entries array in scripts/build-workspace.mjs.",
235056
235169
  "Restore the generated template or wire abilities/index manually before retrying."
235057
235170
  ].join(" "));
235058
235171
  }
235059
- nextSource = nextSource.replace(sharedEntriesPattern, `$1
235060
- 'src/bindings/index.ts',
235061
- 'src/bindings/index.js',
235062
- 'src/editor-plugins/index.ts',
235063
- 'src/editor-plugins/index.js',
235064
- 'src/abilities/index.ts',
235065
- 'src/abilities/index.js',
235066
- $3`);
235172
+ nextSource = nextSource.replace(sharedEntriesPattern, (fullMatch, sharedEntries) => {
235173
+ const missingAbilityEntries = [
235174
+ "'src/abilities/index.ts'",
235175
+ "'src/abilities/index.js'"
235176
+ ].filter((entry) => !sharedEntries.includes(entry));
235177
+ if (missingAbilityEntries.length === 0) {
235178
+ return fullMatch;
235179
+ }
235180
+ const itemIndent = sharedEntries.match(/\n([ \t]*)['"]/u)?.[1] ?? "\t\t";
235181
+ const trimmedEntries = sharedEntries.replace(/\s*$/u, "");
235182
+ const trailingWhitespace = sharedEntries.slice(trimmedEntries.length);
235183
+ const separator = trimmedEntries.trimEnd().endsWith(",") ? "" : ",";
235184
+ const nextEntries = `${trimmedEntries}${separator}` + missingAbilityEntries.map((entry) => `
235185
+ ${itemIndent}${entry},`).join("") + trailingWhitespace;
235186
+ return fullMatch.replace(sharedEntries, nextEntries);
235187
+ });
235067
235188
  return nextSource;
235068
235189
  });
235069
235190
  }
@@ -235092,8 +235213,7 @@ async function ensureAbilityWebpackAnchors(workspace) {
235092
235213
  entries.push( [ entryName, entryPath ] );
235093
235214
  break;
235094
235215
  }
235095
- }
235096
- $2`);
235216
+ }$2`);
235097
235217
  }
235098
235218
  const sharedEntriesPattern = /for\s*\(\s*const\s+\[\s*entryName\s*,\s*candidates\s*\]\s+of\s+\[([\s\S]*?)\]\s*\)\s*\{/u;
235099
235219
  const match3 = source.match(sharedEntriesPattern);
@@ -235104,31 +235224,33 @@ $2`);
235104
235224
  "Restore the generated template or wire abilities/index manually before retrying."
235105
235225
  ].join(" "));
235106
235226
  }
235107
- return source.replace(sharedEntriesPattern, `for ( const [ entryName, candidates ] of [
235108
- [
235109
- 'bindings/index',
235110
- [ 'src/bindings/index.ts', 'src/bindings/index.js' ],
235111
- ],
235112
- [
235113
- 'editor-plugins/index',
235114
- [ 'src/editor-plugins/index.ts', 'src/editor-plugins/index.js' ],
235115
- ],
235116
- [
235117
- 'abilities/index',
235118
- [ 'src/abilities/index.ts', 'src/abilities/index.js' ],
235119
- ],
235120
- ] ) {`);
235227
+ return source.replace(sharedEntriesPattern, (fullMatch, sharedEntries) => {
235228
+ if (/['"]abilities\/index['"]/u.test(sharedEntries)) {
235229
+ return fullMatch;
235230
+ }
235231
+ const tupleIndent = sharedEntries.match(/\n([ \t]*)\[/u)?.[1] ?? "\t\t";
235232
+ const nestedIndent = `${tupleIndent} `;
235233
+ const trimmedEntries = sharedEntries.replace(/\s*$/u, "");
235234
+ const trailingWhitespace = sharedEntries.slice(trimmedEntries.length);
235235
+ const separator = trimmedEntries.trimEnd().endsWith(",") ? "" : ",";
235236
+ const abilityTuple = [
235237
+ `${tupleIndent}[`,
235238
+ `${nestedIndent}'abilities/index',`,
235239
+ `${nestedIndent}[ 'src/abilities/index.ts', 'src/abilities/index.js' ],`,
235240
+ `${tupleIndent}],`
235241
+ ].join(`
235242
+ `);
235243
+ const nextEntries = `${trimmedEntries}${separator}
235244
+ ${abilityTuple}` + trailingWhitespace;
235245
+ return fullMatch.replace(sharedEntries, nextEntries);
235246
+ });
235121
235247
  });
235122
235248
  }
235123
- async function runAddAbilityCommand({
235124
- abilityName,
235125
- cwd = process.cwd()
235249
+ async function scaffoldAbilityWorkspace({
235250
+ abilitySlug,
235251
+ compatibilityPolicy,
235252
+ workspace
235126
235253
  }) {
235127
- const workspace = resolveWorkspaceProject(cwd);
235128
- const abilitySlug = assertValidGeneratedSlug("Ability name", normalizeBlockSlug(abilityName), "wp-typia add ability <name>");
235129
- const inventory = readWorkspaceInventory(workspace.projectDir);
235130
- assertAbilityDoesNotExist(workspace.projectDir, abilitySlug, inventory);
235131
- const compatibilityPolicy = resolveScaffoldCompatibilityPolicy(REQUIRED_WORKSPACE_ABILITY_COMPATIBILITY);
235132
235254
  const blockConfigPath = path57.join(workspace.projectDir, "scripts", "block-config.ts");
235133
235255
  const bootstrapPath = getWorkspaceBootstrapPath(workspace);
235134
235256
  const buildScriptPath = path57.join(workspace.projectDir, "scripts", "build-workspace.mjs");
@@ -235187,27 +235309,53 @@ async function runAddAbilityCommand({
235187
235309
  });
235188
235310
  await writeAbilityRegistry(workspace.projectDir, abilitySlug);
235189
235311
  await appendWorkspaceInventoryEntries(workspace.projectDir, {
235190
- abilityEntries: [buildAbilityConfigEntry(abilitySlug, compatibilityPolicy)]
235312
+ abilityEntries: [
235313
+ buildAbilityConfigEntry(abilitySlug, compatibilityPolicy)
235314
+ ]
235191
235315
  });
235192
- return {
235193
- abilitySlug,
235194
- projectDir: workspace.projectDir
235195
- };
235196
235316
  } catch (error48) {
235197
235317
  await rollbackWorkspaceMutation(mutationSnapshot);
235198
235318
  throw error48;
235199
235319
  }
235200
235320
  }
235201
- var import_semver2, ABILITY_SERVER_GLOB = "/inc/abilities/*.php", ABILITY_EDITOR_SCRIPT = "build/abilities/index.js", ABILITY_EDITOR_ASSET = "build/abilities/index.asset.php", ABILITY_REGISTRY_END_MARKER = "// wp-typia add ability entries end", ABILITY_REGISTRY_START_MARKER = "// wp-typia add ability entries start", WP_ABILITIES_SCRIPT_MODULE_ID = "@wordpress/abilities", WP_CORE_ABILITIES_SCRIPT_MODULE_ID = "@wordpress/core-abilities";
235202
- var init_cli_add_workspace_ability = __esm(() => {
235321
+ var import_semver2;
235322
+ var init_cli_add_workspace_ability_scaffold = __esm(() => {
235203
235323
  init_workspace_inventory();
235204
- init_workspace_project();
235324
+ init_cli_add_workspace_ability_templates();
235205
235325
  init_cli_add_shared();
235206
235326
  init_scaffold_compatibility();
235207
235327
  init_package_versions();
235208
235328
  import_semver2 = __toESM(require_semver2(), 1);
235209
235329
  });
235210
235330
 
235331
+ // ../wp-typia-project-tools/src/runtime/cli-add-workspace-ability.ts
235332
+ async function runAddAbilityCommand({
235333
+ abilityName,
235334
+ cwd = process.cwd()
235335
+ }) {
235336
+ const workspace = resolveWorkspaceProject(cwd);
235337
+ const abilitySlug = assertValidGeneratedSlug("Ability name", normalizeBlockSlug(abilityName), "wp-typia add ability <name>");
235338
+ const inventory = readWorkspaceInventory(workspace.projectDir);
235339
+ assertAbilityDoesNotExist(workspace.projectDir, abilitySlug, inventory);
235340
+ const compatibilityPolicy = resolveScaffoldCompatibilityPolicy(REQUIRED_WORKSPACE_ABILITY_COMPATIBILITY);
235341
+ await scaffoldAbilityWorkspace({
235342
+ abilitySlug,
235343
+ compatibilityPolicy,
235344
+ workspace
235345
+ });
235346
+ return {
235347
+ abilitySlug,
235348
+ projectDir: workspace.projectDir
235349
+ };
235350
+ }
235351
+ var init_cli_add_workspace_ability = __esm(() => {
235352
+ init_cli_add_shared();
235353
+ init_cli_add_workspace_ability_scaffold();
235354
+ init_workspace_inventory();
235355
+ init_workspace_project();
235356
+ init_scaffold_compatibility();
235357
+ });
235358
+
235211
235359
  // ../wp-typia-project-tools/src/runtime/schema-core.ts
235212
235360
  var exports_schema_core = {};
235213
235361
  import"@wp-typia/block-runtime/schema-core";
@@ -236087,9 +236235,7 @@ var init_cli_add_workspace_ai_anchors = __esm(() => {
236087
236235
  init_cli_add_shared();
236088
236236
  });
236089
236237
 
236090
- // ../wp-typia-project-tools/src/runtime/cli-add-workspace-ai.ts
236091
- import { promises as fsp23 } from "fs";
236092
- import path60 from "path";
236238
+ // ../wp-typia-project-tools/src/runtime/cli-add-workspace-ai-templates.ts
236093
236239
  function buildAiFeaturePhpSource(aiFeatureSlug, namespace, phpPrefix, textDomain) {
236094
236240
  const aiFeatureTitle = toTitleCase(aiFeatureSlug);
236095
236241
  const aiFeaturePhpId = aiFeatureSlug.replace(/-/g, "_");
@@ -236690,17 +236836,17 @@ add_action( 'admin_notices', '${adminNoticeFunctionName}' );
236690
236836
  add_action( 'rest_api_init', '${registerRoutesFunctionName}' );
236691
236837
  `;
236692
236838
  }
236693
- async function runAddAiFeatureCommand({
236694
- aiFeatureName,
236695
- cwd = process.cwd(),
236696
- namespace
236839
+ var init_cli_add_workspace_ai_templates = () => {};
236840
+
236841
+ // ../wp-typia-project-tools/src/runtime/cli-add-workspace-ai-scaffold.ts
236842
+ import { promises as fsp23 } from "fs";
236843
+ import path60 from "path";
236844
+ async function scaffoldAiFeatureWorkspace({
236845
+ aiFeatureSlug,
236846
+ compatibilityPolicy,
236847
+ namespace,
236848
+ workspace
236697
236849
  }) {
236698
- const workspace = resolveWorkspaceProject(cwd);
236699
- const aiFeatureSlug = assertValidGeneratedSlug("AI feature name", normalizeBlockSlug(aiFeatureName), "wp-typia add ai-feature <name> [--namespace <vendor/v1>]");
236700
- const resolvedNamespace = resolveRestResourceNamespace(workspace.workspace.namespace, namespace);
236701
- const compatibilityPolicy = resolveScaffoldCompatibilityPolicy(OPTIONAL_WORDPRESS_AI_CLIENT_COMPATIBILITY);
236702
- const inventory = readWorkspaceInventory(workspace.projectDir);
236703
- assertAiFeatureDoesNotExist(workspace.projectDir, aiFeatureSlug, inventory);
236704
236850
  const blockConfigPath = path60.join(workspace.projectDir, "scripts", "block-config.ts");
236705
236851
  const bootstrapPath = getWorkspaceBootstrapPath(workspace);
236706
236852
  const packageJsonPath = path60.join(workspace.projectDir, "package.json");
@@ -236738,7 +236884,7 @@ async function runAddAiFeatureCommand({
236738
236884
  await fsp23.writeFile(validatorsFilePath, buildAiFeatureValidatorsSource(aiFeatureSlug), "utf8");
236739
236885
  await fsp23.writeFile(apiFilePath, buildAiFeatureApiSource(aiFeatureSlug), "utf8");
236740
236886
  await fsp23.writeFile(dataFilePath, buildAiFeatureDataSource(aiFeatureSlug), "utf8");
236741
- await fsp23.writeFile(phpFilePath, buildAiFeaturePhpSource(aiFeatureSlug, resolvedNamespace, workspace.workspace.phpPrefix, workspace.workspace.textDomain), "utf8");
236887
+ await fsp23.writeFile(phpFilePath, buildAiFeaturePhpSource(aiFeatureSlug, namespace, workspace.workspace.phpPrefix, workspace.workspace.textDomain), "utf8");
236742
236888
  const pascalCase = toPascalCase(aiFeatureSlug);
236743
236889
  await syncAiFeatureRestArtifacts({
236744
236890
  clientFile: `src/ai-features/${aiFeatureSlug}/api-client.ts`,
@@ -236747,7 +236893,7 @@ async function runAddAiFeatureCommand({
236747
236893
  typesFile: `src/ai-features/${aiFeatureSlug}/api-types.ts`,
236748
236894
  validatorsFile: `src/ai-features/${aiFeatureSlug}/api-validators.ts`,
236749
236895
  variables: {
236750
- namespace: resolvedNamespace,
236896
+ namespace,
236751
236897
  pascalCase,
236752
236898
  slugKebabCase: aiFeatureSlug,
236753
236899
  title: toTitleCase(aiFeatureSlug)
@@ -236760,14 +236906,11 @@ async function runAddAiFeatureCommand({
236760
236906
  });
236761
236907
  await appendWorkspaceInventoryEntries(workspace.projectDir, {
236762
236908
  aiFeatureEntries: [
236763
- buildAiFeatureConfigEntry(aiFeatureSlug, resolvedNamespace)
236909
+ buildAiFeatureConfigEntry(aiFeatureSlug, namespace)
236764
236910
  ],
236765
236911
  transformSource: ensureBlockConfigCanAddRestManifests
236766
236912
  });
236767
236913
  return {
236768
- aiFeatureSlug,
236769
- namespace: resolvedNamespace,
236770
- projectDir: workspace.projectDir,
236771
236914
  warnings: packageScriptChanges.addedProjectToolsDependency ? [
236772
236915
  "Added `@wp-typia/project-tools` to devDependencies for `sync-ai`. If this workspace was already installed, rerun your package manager install command before the first `wp-typia sync ai`."
236773
236916
  ] : []
@@ -236777,12 +236920,45 @@ async function runAddAiFeatureCommand({
236777
236920
  throw error48;
236778
236921
  }
236779
236922
  }
236780
- var init_cli_add_workspace_ai = __esm(() => {
236781
- init_cli_add_shared();
236923
+ var init_cli_add_workspace_ai_scaffold = __esm(() => {
236782
236924
  init_cli_add_block_legacy_validator();
236783
236925
  init_cli_add_workspace_ai_source_emitters();
236784
236926
  init_cli_add_workspace_ai_anchors();
236927
+ init_cli_add_workspace_ai_templates();
236928
+ init_workspace_inventory();
236929
+ init_cli_add_shared();
236930
+ init_scaffold_compatibility();
236785
236931
  init_ai_feature_artifacts();
236932
+ });
236933
+
236934
+ // ../wp-typia-project-tools/src/runtime/cli-add-workspace-ai.ts
236935
+ async function runAddAiFeatureCommand({
236936
+ aiFeatureName,
236937
+ cwd = process.cwd(),
236938
+ namespace
236939
+ }) {
236940
+ const workspace = resolveWorkspaceProject(cwd);
236941
+ const aiFeatureSlug = assertValidGeneratedSlug("AI feature name", normalizeBlockSlug(aiFeatureName), "wp-typia add ai-feature <name> [--namespace <vendor/v1>]");
236942
+ const resolvedNamespace = resolveRestResourceNamespace(workspace.workspace.namespace, namespace);
236943
+ const compatibilityPolicy = resolveScaffoldCompatibilityPolicy(OPTIONAL_WORDPRESS_AI_CLIENT_COMPATIBILITY);
236944
+ const inventory = readWorkspaceInventory(workspace.projectDir);
236945
+ assertAiFeatureDoesNotExist(workspace.projectDir, aiFeatureSlug, inventory);
236946
+ const scaffoldResult = await scaffoldAiFeatureWorkspace({
236947
+ aiFeatureSlug,
236948
+ compatibilityPolicy,
236949
+ namespace: resolvedNamespace,
236950
+ workspace
236951
+ });
236952
+ return {
236953
+ aiFeatureSlug,
236954
+ namespace: resolvedNamespace,
236955
+ projectDir: workspace.projectDir,
236956
+ warnings: scaffoldResult.warnings
236957
+ };
236958
+ }
236959
+ var init_cli_add_workspace_ai = __esm(() => {
236960
+ init_cli_add_shared();
236961
+ init_cli_add_workspace_ai_scaffold();
236786
236962
  init_workspace_inventory();
236787
236963
  init_workspace_project();
236788
236964
  init_scaffold_compatibility();
@@ -237258,24 +237434,6 @@ async function writeBlockTransformRegistry(projectDir, blockSlug, transformSlug)
237258
237434
  const nextTransformSlugs = Array.from(new Set([...existingTransformSlugs, transformSlug])).sort();
237259
237435
  await fsp24.writeFile(transformsIndexPath, buildBlockTransformIndexSource(nextTransformSlugs), "utf8");
237260
237436
  }
237261
- function assertBlockStyleDoesNotExist(projectDir, blockSlug, styleSlug, inventory) {
237262
- const stylePath = path61.join(projectDir, "src", "blocks", blockSlug, "styles", `${styleSlug}.ts`);
237263
- if (fs45.existsSync(stylePath)) {
237264
- throw new Error(`A block style already exists at ${path61.relative(projectDir, stylePath)}. Choose a different name.`);
237265
- }
237266
- if (inventory.blockStyles.some((entry) => entry.block === blockSlug && entry.slug === styleSlug)) {
237267
- throw new Error(`A block style inventory entry already exists for ${blockSlug}/${styleSlug}. Choose a different name.`);
237268
- }
237269
- }
237270
- function assertBlockTransformDoesNotExist(projectDir, blockSlug, transformSlug, inventory) {
237271
- const transformPath = path61.join(projectDir, "src", "blocks", blockSlug, "transforms", `${transformSlug}.ts`);
237272
- if (fs45.existsSync(transformPath)) {
237273
- throw new Error(`A block transform already exists at ${path61.relative(projectDir, transformPath)}. Choose a different name.`);
237274
- }
237275
- if (inventory.blockTransforms.some((entry) => entry.block === blockSlug && entry.slug === transformSlug)) {
237276
- throw new Error(`A block transform inventory entry already exists for ${blockSlug}/${transformSlug}. Choose a different name.`);
237277
- }
237278
- }
237279
237437
  function assertFullBlockName(blockName, flagName) {
237280
237438
  const trimmed = blockName.trim();
237281
237439
  if (!trimmed) {
@@ -237651,16 +237809,153 @@ var init_cli_doctor_environment = __esm(() => {
237651
237809
  init_template_registry();
237652
237810
  });
237653
237811
 
237654
- // ../wp-typia-project-tools/src/runtime/cli-doctor-workspace.ts
237812
+ // ../wp-typia-project-tools/src/runtime/cli-doctor-workspace-shared.ts
237655
237813
  import fs47 from "fs";
237656
237814
  import path63 from "path";
237657
- import { parseScaffoldBlockMetadata as parseScaffoldBlockMetadata2 } from "@wp-typia/block-runtime/blocks";
237658
237815
  function createDoctorCheck2(label, status, detail, code) {
237659
237816
  return code ? { code, detail, label, status } : { detail, label, status };
237660
237817
  }
237661
237818
  function createDoctorScopeCheck(status, detail) {
237662
237819
  return createDoctorCheck2("Doctor scope", status, detail);
237663
237820
  }
237821
+ function getWorkspaceBootstrapRelativePath(packageName) {
237822
+ return `${packageName.split("/").pop() ?? packageName}.php`;
237823
+ }
237824
+ function checkExistingFiles(projectDir, label, filePaths) {
237825
+ const missing = filePaths.filter((filePath) => typeof filePath === "string").filter((filePath) => !fs47.existsSync(path63.join(projectDir, filePath)));
237826
+ return createDoctorCheck2(label, missing.length === 0 ? "pass" : "fail", missing.length === 0 ? "All referenced files exist" : `Missing: ${missing.join(", ")}`);
237827
+ }
237828
+ var WORKSPACE_BINDING_SERVER_GLOB = "/src/bindings/*/server.php", WORKSPACE_BINDING_EDITOR_SCRIPT = "build/bindings/index.js", WORKSPACE_BINDING_EDITOR_ASSET = "build/bindings/index.asset.php", WORKSPACE_REST_RESOURCE_GLOB = "/inc/rest/*.php", WORKSPACE_ABILITY_GLOB = "/inc/abilities/*.php", WORKSPACE_ABILITY_EDITOR_SCRIPT = "build/abilities/index.js", WORKSPACE_ABILITY_EDITOR_ASSET = "build/abilities/index.asset.php", WORKSPACE_AI_FEATURE_GLOB = "/inc/ai-features/*.php", WORKSPACE_ADMIN_VIEW_GLOB = "/inc/admin-views/*.php", WORKSPACE_ADMIN_VIEW_SCRIPT = "build/admin-views/index.js", WORKSPACE_ADMIN_VIEW_ASSET = "build/admin-views/index.asset.php", WORKSPACE_ADMIN_VIEW_STYLE = "build/admin-views/style-index.css", WORKSPACE_EDITOR_PLUGIN_EDITOR_SCRIPT = "build/editor-plugins/index.js", WORKSPACE_EDITOR_PLUGIN_EDITOR_ASSET = "build/editor-plugins/index.asset.php", WORKSPACE_EDITOR_PLUGIN_EDITOR_STYLE = "build/editor-plugins/style-index.css", WORKSPACE_GENERATED_BLOCK_ARTIFACTS, WORKSPACE_FULL_BLOCK_NAME_PATTERN;
237829
+ var init_cli_doctor_workspace_shared = __esm(() => {
237830
+ WORKSPACE_GENERATED_BLOCK_ARTIFACTS = [
237831
+ "block.json",
237832
+ "typia.manifest.json",
237833
+ "typia.schema.json",
237834
+ "typia-validator.php",
237835
+ "typia.openapi.json"
237836
+ ];
237837
+ WORKSPACE_FULL_BLOCK_NAME_PATTERN = /^[a-z0-9-]+\/[a-z0-9-]+$/u;
237838
+ });
237839
+
237840
+ // ../wp-typia-project-tools/src/runtime/cli-doctor-workspace-bindings.ts
237841
+ import fs48 from "fs";
237842
+ import path64 from "path";
237843
+ import { parseScaffoldBlockMetadata as parseScaffoldBlockMetadata2 } from "@wp-typia/block-runtime/blocks";
237844
+ function checkWorkspaceBindingBootstrap(projectDir, packageName) {
237845
+ const packageBaseName = packageName.split("/").pop() ?? packageName;
237846
+ const bootstrapPath = path64.join(projectDir, `${packageBaseName}.php`);
237847
+ if (!fs48.existsSync(bootstrapPath)) {
237848
+ return createDoctorCheck2("Binding bootstrap", "fail", `Missing ${path64.basename(bootstrapPath)}`);
237849
+ }
237850
+ const source = fs48.readFileSync(bootstrapPath, "utf8");
237851
+ const hasServerGlob = source.includes(WORKSPACE_BINDING_SERVER_GLOB);
237852
+ const hasEditorEnqueueHook = source.includes("enqueue_block_editor_assets");
237853
+ const hasEditorScript = source.includes(WORKSPACE_BINDING_EDITOR_SCRIPT);
237854
+ const hasEditorAsset = source.includes(WORKSPACE_BINDING_EDITOR_ASSET);
237855
+ return createDoctorCheck2("Binding bootstrap", hasServerGlob && hasEditorEnqueueHook && hasEditorScript && hasEditorAsset ? "pass" : "fail", hasServerGlob && hasEditorEnqueueHook && hasEditorScript && hasEditorAsset ? "Binding source PHP and editor bootstrap hooks are present" : "Missing binding source PHP require glob or editor enqueue hook");
237856
+ }
237857
+ function checkWorkspaceBindingSourcesIndex(projectDir, bindingSources) {
237858
+ const indexRelativePath = [path64.join("src", "bindings", "index.ts"), path64.join("src", "bindings", "index.js")].find((relativePath) => fs48.existsSync(path64.join(projectDir, relativePath)));
237859
+ if (!indexRelativePath) {
237860
+ return createDoctorCheck2("Binding sources index", "fail", "Missing src/bindings/index.ts or src/bindings/index.js");
237861
+ }
237862
+ const indexPath = path64.join(projectDir, indexRelativePath);
237863
+ const source = fs48.readFileSync(indexPath, "utf8");
237864
+ const missingImports = bindingSources.filter((bindingSource) => !source.includes(`./${bindingSource.slug}/editor`));
237865
+ return createDoctorCheck2("Binding sources index", missingImports.length === 0 ? "pass" : "fail", missingImports.length === 0 ? "Binding source editor registrations are aggregated" : `Missing editor imports for: ${missingImports.map((entry) => entry.slug).join(", ")}`);
237866
+ }
237867
+ function checkWorkspaceBindingTarget(projectDir, workspace, registeredBlockSlugs, bindingSource) {
237868
+ const hasBlock = bindingSource.block !== undefined;
237869
+ const hasAttribute = bindingSource.attribute !== undefined;
237870
+ if (!hasBlock && !hasAttribute) {
237871
+ return;
237872
+ }
237873
+ if (!bindingSource.block || !bindingSource.attribute) {
237874
+ return createDoctorCheck2(`Binding target ${bindingSource.slug}`, "fail", "Binding target entries must include both block and attribute.");
237875
+ }
237876
+ if (!registeredBlockSlugs.has(bindingSource.block)) {
237877
+ return createDoctorCheck2(`Binding target ${bindingSource.slug}`, "fail", `Binding target references unknown block "${bindingSource.block}".`);
237878
+ }
237879
+ const blockJsonRelativePath = path64.join("src", "blocks", bindingSource.block, "block.json");
237880
+ const blockJsonPath = path64.join(projectDir, blockJsonRelativePath);
237881
+ const issues = [];
237882
+ try {
237883
+ const blockJson = parseScaffoldBlockMetadata2(JSON.parse(fs48.readFileSync(blockJsonPath, "utf8")));
237884
+ const attributes = blockJson.attributes;
237885
+ if (!attributes || typeof attributes !== "object" || Array.isArray(attributes)) {
237886
+ issues.push(`${blockJsonRelativePath} must define an attributes object`);
237887
+ } else {
237888
+ const attributeConfig = attributes[bindingSource.attribute];
237889
+ if (!attributeConfig || typeof attributeConfig !== "object" || Array.isArray(attributeConfig)) {
237890
+ issues.push(`${blockJsonRelativePath} must declare attribute "${bindingSource.attribute}"`);
237891
+ }
237892
+ }
237893
+ } catch (error48) {
237894
+ issues.push(error48 instanceof Error ? `Unable to read ${blockJsonRelativePath}: ${error48.message}` : `Unable to read ${blockJsonRelativePath}.`);
237895
+ }
237896
+ const serverPath = path64.join(projectDir, bindingSource.serverFile);
237897
+ if (fs48.existsSync(serverPath)) {
237898
+ const serverSource = fs48.readFileSync(serverPath, "utf8");
237899
+ const supportedAttributesFilter = `block_bindings_supported_attributes_${workspace.workspace.namespace}/${bindingSource.block}`;
237900
+ if (!serverSource.includes(supportedAttributesFilter)) {
237901
+ issues.push(`${bindingSource.serverFile} must register ${supportedAttributesFilter}`);
237902
+ }
237903
+ if (!new RegExp(`(['"])${escapeRegex2(bindingSource.attribute)}\\1`, "u").test(serverSource)) {
237904
+ issues.push(`${bindingSource.serverFile} must expose attribute "${bindingSource.attribute}"`);
237905
+ }
237906
+ } else {
237907
+ issues.push(`Missing ${bindingSource.serverFile}`);
237908
+ }
237909
+ const editorPath = path64.join(projectDir, bindingSource.editorFile);
237910
+ if (fs48.existsSync(editorPath)) {
237911
+ const editorSource = fs48.readFileSync(editorPath, "utf8");
237912
+ const blockName = `${workspace.workspace.namespace}/${bindingSource.block}`;
237913
+ const bindingSourceTargetMatch = editorSource.match(/export\s+const\s+BINDING_SOURCE_TARGET\s*=\s*\{([\s\S]*?)\}\s+as\s+const\s*;/u);
237914
+ if (!bindingSourceTargetMatch) {
237915
+ issues.push(`${bindingSource.editorFile} must export BINDING_SOURCE_TARGET`);
237916
+ } else {
237917
+ const targetSource = bindingSourceTargetMatch[1] ?? "";
237918
+ const attributePattern = new RegExp(`\\battribute\\s*:\\s*["']${escapeRegex2(bindingSource.attribute)}["']`, "u");
237919
+ const blockPattern = new RegExp(`\\bblock\\s*:\\s*["']${escapeRegex2(blockName)}["']`, "u");
237920
+ if (!attributePattern.test(targetSource)) {
237921
+ issues.push(`${bindingSource.editorFile} must document target attribute "${bindingSource.attribute}"`);
237922
+ }
237923
+ if (!blockPattern.test(targetSource)) {
237924
+ issues.push(`${bindingSource.editorFile} must document target block "${blockName}"`);
237925
+ }
237926
+ }
237927
+ } else {
237928
+ issues.push(`Missing ${bindingSource.editorFile}`);
237929
+ }
237930
+ return createDoctorCheck2(`Binding target ${bindingSource.slug}`, issues.length === 0 ? "pass" : "fail", issues.length === 0 ? `${bindingSource.block}.${bindingSource.attribute} is declared and supported` : issues.join("; "));
237931
+ }
237932
+ function getWorkspaceBindingDoctorChecks(workspace, inventory) {
237933
+ const checks3 = [];
237934
+ if (inventory.bindingSources.length > 0) {
237935
+ checks3.push(checkWorkspaceBindingBootstrap(workspace.projectDir, workspace.packageName));
237936
+ checks3.push(checkWorkspaceBindingSourcesIndex(workspace.projectDir, inventory.bindingSources));
237937
+ }
237938
+ const registeredBlockSlugs = new Set(inventory.blocks.map((block) => block.slug));
237939
+ for (const bindingSource of inventory.bindingSources) {
237940
+ checks3.push(checkExistingFiles(workspace.projectDir, `Binding source ${bindingSource.slug}`, [
237941
+ bindingSource.serverFile,
237942
+ bindingSource.editorFile
237943
+ ]));
237944
+ const bindingTargetCheck = checkWorkspaceBindingTarget(workspace.projectDir, workspace, registeredBlockSlugs, bindingSource);
237945
+ if (bindingTargetCheck) {
237946
+ checks3.push(bindingTargetCheck);
237947
+ }
237948
+ }
237949
+ return checks3;
237950
+ }
237951
+ var init_cli_doctor_workspace_bindings = __esm(() => {
237952
+ init_cli_doctor_workspace_shared();
237953
+ });
237954
+
237955
+ // ../wp-typia-project-tools/src/runtime/cli-doctor-workspace-blocks.ts
237956
+ import fs49 from "fs";
237957
+ import path65 from "path";
237958
+ import { parseScaffoldBlockMetadata as parseScaffoldBlockMetadata3 } from "@wp-typia/block-runtime/blocks";
237664
237959
  function maskSourceSegment2(segment) {
237665
237960
  return segment.replace(/[^\n\r]/gu, " ");
237666
237961
  }
@@ -237723,7 +238018,7 @@ function hasExecutablePattern2(source, pattern) {
237723
238018
  return pattern.test(maskTypeScriptCommentsAndLiterals2(source));
237724
238019
  }
237725
238020
  function normalizePathSeparators(relativePath) {
237726
- return relativePath.split(path63.sep).join("/");
238021
+ return relativePath.split(path65.sep).join("/");
237727
238022
  }
237728
238023
  function hasRegisteredBlockAsset(value2) {
237729
238024
  if (typeof value2 === "string") {
@@ -237735,25 +238030,19 @@ function hasRegisteredBlockAsset(value2) {
237735
238030
  return false;
237736
238031
  }
237737
238032
  function readWorkspaceBlockIframeMetadata(projectDir, blockSlug) {
237738
- const blockJsonRelativePath = path63.join("src", "blocks", blockSlug, "block.json");
237739
- const blockJsonPath = path63.join(projectDir, blockJsonRelativePath);
237740
- if (!fs47.existsSync(blockJsonPath)) {
238033
+ const blockJsonRelativePath = path65.join("src", "blocks", blockSlug, "block.json");
238034
+ const blockJsonPath = path65.join(projectDir, blockJsonRelativePath);
238035
+ if (!fs49.existsSync(blockJsonPath)) {
237741
238036
  return {
237742
238037
  blockJsonRelativePath,
237743
238038
  error: `Missing ${blockJsonRelativePath}`
237744
238039
  };
237745
238040
  }
237746
238041
  try {
237747
- const parsed = JSON.parse(fs47.readFileSync(blockJsonPath, "utf8"));
237748
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
237749
- return {
237750
- blockJsonRelativePath,
237751
- error: `${blockJsonRelativePath} must contain a JSON object`
237752
- };
237753
- }
238042
+ const document2 = parseScaffoldBlockMetadata3(JSON.parse(fs49.readFileSync(blockJsonPath, "utf8")));
237754
238043
  return {
237755
238044
  blockJsonRelativePath,
237756
- document: parsed
238045
+ document: document2
237757
238046
  };
237758
238047
  } catch (error48) {
237759
238048
  return {
@@ -237763,156 +238052,126 @@ function readWorkspaceBlockIframeMetadata(projectDir, blockSlug) {
237763
238052
  }
237764
238053
  }
237765
238054
  function isWorkspaceBlockEditorSource(relativePath) {
237766
- const normalizedPath = normalizePathSeparators(relativePath);
237767
- const normalizedLowerPath = normalizedPath.toLowerCase();
237768
- if (!WORKSPACE_BLOCK_EDITOR_SOURCE_FILE_PATTERN.test(normalizedLowerPath) || /\.d\.[cm]?[jt]s$/u.test(normalizedLowerPath)) {
238055
+ if (!WORKSPACE_BLOCK_EDITOR_SOURCE_FILE_PATTERN.test(relativePath)) {
237769
238056
  return false;
237770
238057
  }
237771
- const segments = normalizedLowerPath.split("/");
237772
- const fileName = segments[segments.length - 1] ?? "";
237773
- const baseName = fileName.replace(/\.[^.]+$/u, "");
237774
- if (WORKSPACE_BLOCK_EDITOR_SOURCE_BASENAMES.has(baseName)) {
238058
+ const normalizedRelativePath = normalizePathSeparators(relativePath);
238059
+ const normalizedDirName = path65.posix.dirname(normalizedRelativePath);
238060
+ const normalizedBaseName = path65.posix.basename(normalizedRelativePath, path65.posix.extname(normalizedRelativePath));
238061
+ if (WORKSPACE_BLOCK_EDITOR_SOURCE_BASENAMES.has(normalizedBaseName)) {
237775
238062
  return true;
237776
238063
  }
237777
- return segments.slice(0, -1).some((segment) => WORKSPACE_BLOCK_EDITOR_SOURCE_DIRECTORIES.has(segment));
238064
+ const pathSegments = normalizedDirName.split("/");
238065
+ return pathSegments.some((segment) => WORKSPACE_BLOCK_EDITOR_SOURCE_DIRECTORIES.has(segment));
237778
238066
  }
237779
238067
  function isWorkspaceBlockSaveSource(relativePath) {
237780
- const fileName = normalizePathSeparators(relativePath).split("/").pop() ?? "";
237781
- return fileName.replace(/\.[^.]+$/u, "").toLowerCase() === "save";
238068
+ const normalizedBaseName = path65.basename(relativePath, path65.extname(relativePath));
238069
+ return normalizedBaseName === "save";
237782
238070
  }
237783
238071
  function collectWorkspaceBlockEditorSources(projectDir, blockSlug) {
237784
- const blockDir = path63.join(projectDir, "src", "blocks", blockSlug);
237785
- if (!fs47.existsSync(blockDir)) {
238072
+ const blockDir = path65.join(projectDir, "src", "blocks", blockSlug);
238073
+ if (!fs49.existsSync(blockDir)) {
237786
238074
  return [];
237787
238075
  }
237788
- const sources = [];
237789
- const visitDirectory = (directory) => {
237790
- for (const entry of fs47.readdirSync(directory, { withFileTypes: true })) {
237791
- const entryPath = path63.join(directory, entry.name);
238076
+ const collected = [];
238077
+ const queue = [blockDir];
238078
+ while (queue.length > 0) {
238079
+ const currentDir = queue.pop();
238080
+ if (!currentDir) {
238081
+ continue;
238082
+ }
238083
+ for (const entry of fs49.readdirSync(currentDir, { withFileTypes: true })) {
238084
+ const absolutePath = path65.join(currentDir, entry.name);
237792
238085
  if (entry.isDirectory()) {
237793
- visitDirectory(entryPath);
238086
+ queue.push(absolutePath);
237794
238087
  continue;
237795
238088
  }
237796
238089
  if (!entry.isFile()) {
237797
238090
  continue;
237798
238091
  }
237799
- const relativePath = normalizePathSeparators(path63.relative(projectDir, entryPath));
237800
- const blockRelativePath = path63.relative(blockDir, entryPath);
237801
- if (!isWorkspaceBlockEditorSource(blockRelativePath)) {
238092
+ const relativePath = path65.relative(projectDir, absolutePath);
238093
+ if (!isWorkspaceBlockEditorSource(relativePath)) {
237802
238094
  continue;
237803
238095
  }
237804
- sources.push({
237805
- relativePath,
237806
- source: fs47.readFileSync(entryPath, "utf8")
238096
+ collected.push({
238097
+ relativePath: normalizePathSeparators(relativePath),
238098
+ source: fs49.readFileSync(absolutePath, "utf8")
237807
238099
  });
237808
238100
  }
237809
- };
237810
- visitDirectory(blockDir);
237811
- return sources;
238101
+ }
238102
+ return collected.sort((left, right) => left.relativePath.localeCompare(right.relativePath));
237812
238103
  }
237813
238104
  function getSourceLineNumber(source, index) {
237814
- let lineNumber = 1;
238105
+ let line = 1;
237815
238106
  for (let cursor = 0;cursor < index; cursor += 1) {
237816
238107
  if (source[cursor] === `
237817
238108
  `) {
237818
- lineNumber += 1;
238109
+ line += 1;
237819
238110
  }
237820
238111
  }
237821
- return lineNumber;
238112
+ return line;
237822
238113
  }
237823
- function isGlobalDomAccessCandidate(maskedSource, index, token) {
237824
- if (token === "document" || token === "window") {
237825
- return true;
238114
+ function isGlobalDomAccessCandidate(source, index, identifier) {
238115
+ const lineStart = source.lastIndexOf(`
238116
+ `, index - 1) + 1;
238117
+ const lineEndCandidate = source.indexOf(`
238118
+ `, index);
238119
+ const lineEnd = lineEndCandidate === -1 ? source.length : lineEndCandidate;
238120
+ const lineSource = source.slice(lineStart, lineEnd);
238121
+ const trimmedLine = lineSource.trimStart();
238122
+ if (trimmedLine.startsWith("import ")) {
238123
+ return false;
237826
238124
  }
237827
- const before = maskedSource.slice(0, index);
237828
- const after = maskedSource.slice(index + token.length);
237829
- const previousNonWhitespace = before.match(/\S(?=\s*$)/u)?.[0] ?? "";
237830
- const nextNonWhitespace = after.match(/^\s*(\S)/u)?.[1] ?? "";
237831
- if (previousNonWhitespace === "." || previousNonWhitespace === "{" || previousNonWhitespace === ",") {
238125
+ if (trimmedLine.startsWith("const ") || trimmedLine.startsWith("let ") || trimmedLine.startsWith("var ")) {
237832
238126
  return false;
237833
238127
  }
237834
- if (nextNonWhitespace === ":") {
238128
+ if (trimmedLine.startsWith("function ") || trimmedLine.startsWith("class ")) {
237835
238129
  return false;
237836
238130
  }
237837
- if (/\b(?:const|function|let|var)\s+$/u.test(before)) {
238131
+ const precedingCharacter = index > 0 ? source[index - 1] : "";
238132
+ if (precedingCharacter === "." || precedingCharacter === "'" || precedingCharacter === '"') {
237838
238133
  return false;
237839
238134
  }
237840
- return true;
238135
+ return identifier === "document" || identifier === "window" || identifier === "parent" || identifier === "top";
237841
238136
  }
237842
- function findWorkspaceBlockGlobalDomAccesses(sources) {
237843
- const findings = [];
237844
- for (const { relativePath, source } of sources) {
238137
+ function findWorkspaceBlockGlobalDomAccesses(editorSources) {
238138
+ return editorSources.flatMap(({ relativePath, source }) => {
237845
238139
  const maskedSource = maskTypeScriptCommentsAndLiterals2(source);
237846
238140
  const matches = maskedSource.matchAll(WORKSPACE_BLOCK_IFRAME_GLOBAL_DOM_PATTERN);
238141
+ const findings = [];
237847
238142
  for (const match3 of matches) {
237848
- const index = match3.index ?? 0;
237849
- const matchedToken = match3[0].replace(/\W+/gu, "");
237850
- if (!isGlobalDomAccessCandidate(maskedSource, index, matchedToken)) {
238143
+ const identifier = match3[0];
238144
+ const matchIndex = match3.index ?? -1;
238145
+ if (matchIndex < 0) {
237851
238146
  continue;
237852
238147
  }
237853
- findings.push(`${relativePath}:${getSourceLineNumber(source, index)} (${matchedToken})`);
237854
- if (findings.length >= 5) {
237855
- return findings;
238148
+ if (!isGlobalDomAccessCandidate(source, matchIndex, identifier)) {
238149
+ continue;
237856
238150
  }
238151
+ findings.push(`${relativePath}:${getSourceLineNumber(source, matchIndex)}`);
237857
238152
  }
237858
- }
237859
- return findings;
237860
- }
237861
- function getWorkspaceBootstrapRelativePath(packageName) {
237862
- const packageBaseName = packageName.split("/").pop() ?? packageName;
237863
- return `${packageBaseName}.php`;
237864
- }
237865
- function checkExistingFiles(projectDir, label, filePaths) {
237866
- const missing = filePaths.filter((filePath) => typeof filePath === "string").filter((filePath) => !fs47.existsSync(path63.join(projectDir, filePath)));
237867
- return createDoctorCheck2(label, missing.length === 0 ? "pass" : "fail", missing.length === 0 ? "All referenced files exist" : `Missing: ${missing.join(", ")}`);
237868
- }
237869
- function checkWorkspacePackageMetadata(workspace, packageJson) {
237870
- const issues = [];
237871
- const packageName = packageJson.name;
237872
- const bootstrapRelativePath = getWorkspaceBootstrapRelativePath(typeof packageName === "string" && packageName.length > 0 ? packageName : workspace.packageName);
237873
- const wpTypia = packageJson.wpTypia;
237874
- if (typeof packageName !== "string" || packageName.length === 0) {
237875
- issues.push("package.json must define a string name for workspace bootstrap resolution");
237876
- }
237877
- if (wpTypia?.projectType !== "workspace") {
237878
- issues.push('wpTypia.projectType must be "workspace"');
237879
- }
237880
- if (wpTypia?.templatePackage !== WORKSPACE_TEMPLATE_PACKAGE) {
237881
- issues.push(`wpTypia.templatePackage must be "${WORKSPACE_TEMPLATE_PACKAGE}"`);
237882
- }
237883
- if (wpTypia?.namespace !== workspace.workspace.namespace) {
237884
- issues.push(`wpTypia.namespace must equal "${workspace.workspace.namespace}"`);
237885
- }
237886
- if (wpTypia?.textDomain !== workspace.workspace.textDomain) {
237887
- issues.push(`wpTypia.textDomain must equal "${workspace.workspace.textDomain}"`);
237888
- }
237889
- if (wpTypia?.phpPrefix !== workspace.workspace.phpPrefix) {
237890
- issues.push(`wpTypia.phpPrefix must equal "${workspace.workspace.phpPrefix}"`);
237891
- }
237892
- if (!fs47.existsSync(path63.join(workspace.projectDir, bootstrapRelativePath))) {
237893
- issues.push(`Missing bootstrap file ${bootstrapRelativePath}`);
237894
- }
237895
- return createDoctorCheck2("Workspace package metadata", issues.length === 0 ? "pass" : "fail", issues.length === 0 ? `package.json metadata aligns with ${workspace.packageName} and ${bootstrapRelativePath}` : issues.join("; "));
238153
+ return findings;
238154
+ });
237896
238155
  }
237897
238156
  function getWorkspaceBlockRequiredFiles(block) {
237898
- const blockDir = path63.join("src", "blocks", block.slug);
238157
+ const blockDir = path65.join("src", "blocks", block.slug);
237899
238158
  return Array.from(new Set([
237900
238159
  block.typesFile,
237901
238160
  block.apiTypesFile,
237902
238161
  block.openApiFile,
237903
- path63.join(blockDir, "index.tsx"),
237904
- ...WORKSPACE_GENERATED_BLOCK_ARTIFACTS.map((fileName) => path63.join(blockDir, fileName))
238162
+ path65.join(blockDir, "index.tsx"),
238163
+ ...WORKSPACE_GENERATED_BLOCK_ARTIFACTS.map((fileName) => path65.join(blockDir, fileName))
237905
238164
  ].filter((filePath) => typeof filePath === "string")));
237906
238165
  }
237907
238166
  function checkWorkspaceBlockMetadata(projectDir, workspace, block) {
237908
- const blockJsonRelativePath = path63.join("src", "blocks", block.slug, "block.json");
237909
- const blockJsonPath = path63.join(projectDir, blockJsonRelativePath);
237910
- if (!fs47.existsSync(blockJsonPath)) {
238167
+ const blockJsonRelativePath = path65.join("src", "blocks", block.slug, "block.json");
238168
+ const blockJsonPath = path65.join(projectDir, blockJsonRelativePath);
238169
+ if (!fs49.existsSync(blockJsonPath)) {
237911
238170
  return createDoctorCheck2(`Block metadata ${block.slug}`, "fail", `Missing ${blockJsonRelativePath}`);
237912
238171
  }
237913
238172
  let blockJson;
237914
238173
  try {
237915
- blockJson = parseScaffoldBlockMetadata2(JSON.parse(fs47.readFileSync(blockJsonPath, "utf8")));
238174
+ blockJson = parseScaffoldBlockMetadata3(JSON.parse(fs49.readFileSync(blockJsonPath, "utf8")));
237916
238175
  } catch (error48) {
237917
238176
  return createDoctorCheck2(`Block metadata ${block.slug}`, "fail", error48 instanceof Error ? error48.message : String(error48));
237918
238177
  }
@@ -237927,14 +238186,14 @@ function checkWorkspaceBlockMetadata(projectDir, workspace, block) {
237927
238186
  return createDoctorCheck2(`Block metadata ${block.slug}`, issues.length === 0 ? "pass" : "fail", issues.length === 0 ? `block.json matches ${expectedName} and ${workspace.workspace.textDomain}` : issues.join("; "));
237928
238187
  }
237929
238188
  function checkWorkspaceBlockHooks(projectDir, blockSlug) {
237930
- const blockJsonRelativePath = path63.join("src", "blocks", blockSlug, "block.json");
237931
- const blockJsonPath = path63.join(projectDir, blockJsonRelativePath);
237932
- if (!fs47.existsSync(blockJsonPath)) {
238189
+ const blockJsonRelativePath = path65.join("src", "blocks", blockSlug, "block.json");
238190
+ const blockJsonPath = path65.join(projectDir, blockJsonRelativePath);
238191
+ if (!fs49.existsSync(blockJsonPath)) {
237933
238192
  return createDoctorCheck2(`Block hooks ${blockSlug}`, "fail", `Missing ${blockJsonRelativePath}`);
237934
238193
  }
237935
238194
  let blockJson;
237936
238195
  try {
237937
- blockJson = parseScaffoldBlockMetadata2(JSON.parse(fs47.readFileSync(blockJsonPath, "utf8")));
238196
+ blockJson = parseScaffoldBlockMetadata3(JSON.parse(fs49.readFileSync(blockJsonPath, "utf8")));
237938
238197
  } catch (error48) {
237939
238198
  return createDoctorCheck2(`Block hooks ${blockSlug}`, "fail", error48 instanceof Error ? error48.message : String(error48));
237940
238199
  }
@@ -237950,12 +238209,12 @@ function checkWorkspaceBlockHooks(projectDir, blockSlug) {
237950
238209
  return createDoctorCheck2(`Block hooks ${blockSlug}`, invalidEntries.length === 0 ? "pass" : "fail", invalidEntries.length === 0 ? `blockHooks metadata is valid${Object.keys(blockHooks).length > 0 ? ` (${Object.keys(blockHooks).join(", ")})` : ""}` : `Invalid blockHooks entries: ${invalidEntries.map(([anchor, position]) => `${anchor || "<empty>"} => ${String(position)}`).join(", ")}`);
237951
238210
  }
237952
238211
  function checkWorkspaceBlockCollectionImport(projectDir, blockSlug) {
237953
- const entryRelativePath = path63.join("src", "blocks", blockSlug, "index.tsx");
237954
- const entryPath = path63.join(projectDir, entryRelativePath);
237955
- if (!fs47.existsSync(entryPath)) {
238212
+ const entryRelativePath = path65.join("src", "blocks", blockSlug, "index.tsx");
238213
+ const entryPath = path65.join(projectDir, entryRelativePath);
238214
+ if (!fs49.existsSync(entryPath)) {
237956
238215
  return createDoctorCheck2(`Block collection ${blockSlug}`, "fail", `Missing ${entryRelativePath}`);
237957
238216
  }
237958
- const source = fs47.readFileSync(entryPath, "utf8");
238217
+ const source = fs49.readFileSync(entryPath, "utf8");
237959
238218
  const hasCollectionImport = WORKSPACE_COLLECTION_IMPORT_PATTERN.test(source);
237960
238219
  return createDoctorCheck2(`Block collection ${blockSlug}`, hasCollectionImport ? "pass" : "fail", hasCollectionImport ? "Shared block collection import is present" : `Missing a shared collection import like ${WORKSPACE_COLLECTION_IMPORT_LINE}`);
237961
238220
  }
@@ -237968,8 +238227,8 @@ function checkWorkspaceBlockIframeCompatibility(projectDir, blockSlug) {
237968
238227
  }
237969
238228
  const blockJson = metadataResult.document;
237970
238229
  const apiVersion = typeof blockJson.apiVersion === "number" && Number.isFinite(blockJson.apiVersion) ? blockJson.apiVersion : null;
237971
- const blockDir = path63.join(projectDir, "src", "blocks", blockSlug);
237972
- const localStyleFiles = WORKSPACE_BLOCK_LOCAL_STYLE_FILES.filter((fileName) => fs47.existsSync(path63.join(blockDir, fileName))).map((fileName) => normalizePathSeparators(path63.join("src", "blocks", blockSlug, fileName)));
238230
+ const blockDir = path65.join(projectDir, "src", "blocks", blockSlug);
238231
+ const localStyleFiles = WORKSPACE_BLOCK_LOCAL_STYLE_FILES.filter((fileName) => fs49.existsSync(path65.join(blockDir, fileName))).map((fileName) => normalizePathSeparators(path65.join("src", "blocks", blockSlug, fileName)));
237973
238232
  const hasRegisteredEditorStyles = hasRegisteredBlockAsset(blockJson.style) || hasRegisteredBlockAsset(blockJson.editorStyle);
237974
238233
  const editorSources = collectWorkspaceBlockEditorSources(projectDir, blockSlug);
237975
238234
  const editorWrapperSources = editorSources.filter((source) => !isWorkspaceBlockSaveSource(source.relativePath));
@@ -237987,103 +238246,162 @@ function checkWorkspaceBlockIframeCompatibility(projectDir, blockSlug) {
237987
238246
  }
237988
238247
  function checkWorkspacePatternBootstrap(projectDir, packageName) {
237989
238248
  const packageBaseName = packageName.split("/").pop() ?? packageName;
237990
- const bootstrapPath = path63.join(projectDir, `${packageBaseName}.php`);
237991
- if (!fs47.existsSync(bootstrapPath)) {
237992
- return createDoctorCheck2("Pattern bootstrap", "fail", `Missing ${path63.basename(bootstrapPath)}`);
238249
+ const bootstrapPath = path65.join(projectDir, `${packageBaseName}.php`);
238250
+ if (!fs49.existsSync(bootstrapPath)) {
238251
+ return createDoctorCheck2("Pattern bootstrap", "fail", `Missing ${path65.basename(bootstrapPath)}`);
237993
238252
  }
237994
- const source = fs47.readFileSync(bootstrapPath, "utf8");
238253
+ const source = fs49.readFileSync(bootstrapPath, "utf8");
237995
238254
  const hasCategoryAnchor = source.includes("register_block_pattern_category");
237996
238255
  const hasPatternGlob = source.includes("/src/patterns/*.php");
237997
238256
  return createDoctorCheck2("Pattern bootstrap", hasCategoryAnchor && hasPatternGlob ? "pass" : "fail", hasCategoryAnchor && hasPatternGlob ? "Pattern category and loader hooks are present" : "Missing pattern category registration or src/patterns loader hook");
237998
238257
  }
237999
- function checkWorkspaceBindingBootstrap(projectDir, packageName) {
238000
- const packageBaseName = packageName.split("/").pop() ?? packageName;
238001
- const bootstrapPath = path63.join(projectDir, `${packageBaseName}.php`);
238002
- if (!fs47.existsSync(bootstrapPath)) {
238003
- return createDoctorCheck2("Binding bootstrap", "fail", `Missing ${path63.basename(bootstrapPath)}`);
238258
+ function checkVariationEntrypoint(projectDir, blockSlug) {
238259
+ const entryPath = path65.join(projectDir, "src", "blocks", blockSlug, "index.tsx");
238260
+ if (!fs49.existsSync(entryPath)) {
238261
+ return createDoctorCheck2(`Variation entrypoint ${blockSlug}`, "fail", `Missing ${path65.relative(projectDir, entryPath)}`);
238004
238262
  }
238005
- const source = fs47.readFileSync(bootstrapPath, "utf8");
238006
- const hasServerGlob = source.includes(WORKSPACE_BINDING_SERVER_GLOB);
238007
- const hasEditorEnqueueHook = source.includes("enqueue_block_editor_assets");
238008
- const hasEditorScript = source.includes(WORKSPACE_BINDING_EDITOR_SCRIPT);
238009
- const hasEditorAsset = source.includes(WORKSPACE_BINDING_EDITOR_ASSET);
238010
- return createDoctorCheck2("Binding bootstrap", hasServerGlob && hasEditorEnqueueHook && hasEditorScript && hasEditorAsset ? "pass" : "fail", hasServerGlob && hasEditorEnqueueHook && hasEditorScript && hasEditorAsset ? "Binding source PHP and editor bootstrap hooks are present" : "Missing binding source PHP require glob or editor enqueue hook");
238263
+ const source = fs49.readFileSync(entryPath, "utf8");
238264
+ const hasImport = hasUncommentedPattern2(source, WORKSPACE_VARIATIONS_IMPORT_PATTERN);
238265
+ const hasCall = hasExecutablePattern2(source, WORKSPACE_VARIATIONS_CALL_PATTERN);
238266
+ return createDoctorCheck2(`Variation entrypoint ${blockSlug}`, hasImport && hasCall ? "pass" : "fail", hasImport && hasCall ? "Variations registration hook is present" : "Missing ./variations import or registerWorkspaceVariations() call");
238011
238267
  }
238012
- function checkWorkspaceBindingSourcesIndex(projectDir, bindingSources) {
238013
- const indexRelativePath = [path63.join("src", "bindings", "index.ts"), path63.join("src", "bindings", "index.js")].find((relativePath) => fs47.existsSync(path63.join(projectDir, relativePath)));
238014
- if (!indexRelativePath) {
238015
- return createDoctorCheck2("Binding sources index", "fail", "Missing src/bindings/index.ts or src/bindings/index.js");
238268
+ function checkBlockStyleEntrypoint(projectDir, blockSlug) {
238269
+ const entryPath = path65.join(projectDir, "src", "blocks", blockSlug, "index.tsx");
238270
+ if (!fs49.existsSync(entryPath)) {
238271
+ return createDoctorCheck2(`Block style entrypoint ${blockSlug}`, "fail", `Missing ${path65.relative(projectDir, entryPath)}`);
238016
238272
  }
238017
- const indexPath = path63.join(projectDir, indexRelativePath);
238018
- const source = fs47.readFileSync(indexPath, "utf8");
238019
- const missingImports = bindingSources.filter((bindingSource) => !source.includes(`./${bindingSource.slug}/editor`));
238020
- return createDoctorCheck2("Binding sources index", missingImports.length === 0 ? "pass" : "fail", missingImports.length === 0 ? "Binding source editor registrations are aggregated" : `Missing editor imports for: ${missingImports.map((entry) => entry.slug).join(", ")}`);
238273
+ const source = fs49.readFileSync(entryPath, "utf8");
238274
+ const hasImport = hasUncommentedPattern2(source, WORKSPACE_BLOCK_STYLES_IMPORT_PATTERN);
238275
+ const hasCall = hasExecutablePattern2(source, WORKSPACE_BLOCK_STYLES_CALL_PATTERN);
238276
+ return createDoctorCheck2(`Block style entrypoint ${blockSlug}`, hasImport && hasCall ? "pass" : "fail", hasImport && hasCall ? "Block style registration hook is present" : "Missing ./styles import or registerWorkspaceBlockStyles() call");
238021
238277
  }
238022
- function checkWorkspaceBindingTarget(projectDir, workspace, registeredBlockSlugs, bindingSource) {
238023
- const hasBlock = bindingSource.block !== undefined;
238024
- const hasAttribute = bindingSource.attribute !== undefined;
238025
- if (!hasBlock && !hasAttribute) {
238026
- return;
238278
+ function checkBlockTransformEntrypoint(projectDir, blockSlug) {
238279
+ const entryPath = path65.join(projectDir, "src", "blocks", blockSlug, "index.tsx");
238280
+ if (!fs49.existsSync(entryPath)) {
238281
+ return createDoctorCheck2(`Block transform entrypoint ${blockSlug}`, "fail", `Missing ${path65.relative(projectDir, entryPath)}`);
238027
238282
  }
238028
- if (!bindingSource.block || !bindingSource.attribute) {
238029
- return createDoctorCheck2(`Binding target ${bindingSource.slug}`, "fail", "Binding target entries must include both block and attribute.");
238283
+ const source = fs49.readFileSync(entryPath, "utf8");
238284
+ const hasImport = hasUncommentedPattern2(source, WORKSPACE_BLOCK_TRANSFORMS_IMPORT_PATTERN);
238285
+ const hasCall = hasExecutablePattern2(source, WORKSPACE_BLOCK_TRANSFORMS_CALL_PATTERN);
238286
+ return createDoctorCheck2(`Block transform entrypoint ${blockSlug}`, hasImport && hasCall ? "pass" : "fail", hasImport && hasCall ? "Block transform registration hook is present" : "Missing ./transforms import or applyWorkspaceBlockTransforms(registration.settings) call");
238287
+ }
238288
+ function checkBlockTransformConfig(workspace, transform2) {
238289
+ const expectedTo = `${workspace.workspace.namespace}/${transform2.block}`;
238290
+ const issues = [];
238291
+ if (!WORKSPACE_FULL_BLOCK_NAME_PATTERN.test(transform2.from)) {
238292
+ issues.push("from must use full namespace/block format");
238030
238293
  }
238031
- if (!registeredBlockSlugs.has(bindingSource.block)) {
238032
- return createDoctorCheck2(`Binding target ${bindingSource.slug}`, "fail", `Binding target references unknown block "${bindingSource.block}".`);
238294
+ if (transform2.to !== expectedTo) {
238295
+ issues.push(`to must equal "${expectedTo}" for workspace block "${transform2.block}"`);
238033
238296
  }
238034
- const blockJsonRelativePath = path63.join("src", "blocks", bindingSource.block, "block.json");
238035
- const blockJsonPath = path63.join(projectDir, blockJsonRelativePath);
238036
- const issues = [];
238037
- try {
238038
- const blockJson = parseScaffoldBlockMetadata2(JSON.parse(fs47.readFileSync(blockJsonPath, "utf8")));
238039
- const attributes = blockJson.attributes;
238040
- if (!attributes || typeof attributes !== "object" || Array.isArray(attributes)) {
238041
- issues.push(`${blockJsonRelativePath} must define an attributes object`);
238042
- } else {
238043
- const attributeConfig = attributes[bindingSource.attribute];
238044
- if (!attributeConfig || typeof attributeConfig !== "object" || Array.isArray(attributeConfig)) {
238045
- issues.push(`${blockJsonRelativePath} must declare attribute "${bindingSource.attribute}"`);
238046
- }
238297
+ return createDoctorCheck2(`Block transform config ${transform2.block}/${transform2.slug}`, issues.length === 0 ? "pass" : "fail", issues.length === 0 ? `${transform2.from} transforms into ${transform2.to}` : issues.join("; "));
238298
+ }
238299
+ function getWorkspaceBlockDoctorChecks(workspace, inventory) {
238300
+ const checks3 = [];
238301
+ for (const block of inventory.blocks) {
238302
+ checks3.push(checkExistingFiles(workspace.projectDir, `Block ${block.slug}`, getWorkspaceBlockRequiredFiles(block)));
238303
+ checks3.push(checkWorkspaceBlockMetadata(workspace.projectDir, workspace, block));
238304
+ checks3.push(checkWorkspaceBlockHooks(workspace.projectDir, block.slug));
238305
+ checks3.push(checkWorkspaceBlockCollectionImport(workspace.projectDir, block.slug));
238306
+ checks3.push(...checkWorkspaceBlockIframeCompatibility(workspace.projectDir, block.slug));
238307
+ }
238308
+ const registeredBlockSlugs = new Set(inventory.blocks.map((block) => block.slug));
238309
+ const variationTargetBlocks = new Set;
238310
+ for (const variation of inventory.variations) {
238311
+ if (!registeredBlockSlugs.has(variation.block)) {
238312
+ checks3.push(createDoctorCheck2(`Variation ${variation.block}/${variation.slug}`, "fail", `Variation references unknown block "${variation.block}"`));
238313
+ continue;
238047
238314
  }
238048
- } catch (error48) {
238049
- issues.push(error48 instanceof Error ? `Unable to read ${blockJsonRelativePath}: ${error48.message}` : `Unable to read ${blockJsonRelativePath}.`);
238315
+ variationTargetBlocks.add(variation.block);
238316
+ checks3.push(checkExistingFiles(workspace.projectDir, `Variation ${variation.block}/${variation.slug}`, [variation.file]));
238050
238317
  }
238051
- const serverPath = path63.join(projectDir, bindingSource.serverFile);
238052
- if (fs47.existsSync(serverPath)) {
238053
- const serverSource = fs47.readFileSync(serverPath, "utf8");
238054
- const supportedAttributesFilter = `block_bindings_supported_attributes_${workspace.workspace.namespace}/${bindingSource.block}`;
238055
- if (!serverSource.includes(supportedAttributesFilter)) {
238056
- issues.push(`${bindingSource.serverFile} must register ${supportedAttributesFilter}`);
238057
- }
238058
- if (!new RegExp(`'${escapeRegex2(bindingSource.attribute)}'`, "u").test(serverSource)) {
238059
- issues.push(`${bindingSource.serverFile} must expose attribute "${bindingSource.attribute}"`);
238318
+ for (const blockSlug of variationTargetBlocks) {
238319
+ checks3.push(checkVariationEntrypoint(workspace.projectDir, blockSlug));
238320
+ }
238321
+ const blockStyleTargetBlocks = new Set;
238322
+ for (const blockStyle of inventory.blockStyles) {
238323
+ if (!registeredBlockSlugs.has(blockStyle.block)) {
238324
+ checks3.push(createDoctorCheck2(`Block style ${blockStyle.block}/${blockStyle.slug}`, "fail", `Block style references unknown block "${blockStyle.block}"`));
238325
+ continue;
238060
238326
  }
238061
- } else {
238062
- issues.push(`Missing ${bindingSource.serverFile}`);
238327
+ blockStyleTargetBlocks.add(blockStyle.block);
238328
+ checks3.push(checkExistingFiles(workspace.projectDir, `Block style ${blockStyle.block}/${blockStyle.slug}`, [blockStyle.file]));
238063
238329
  }
238064
- const editorPath = path63.join(projectDir, bindingSource.editorFile);
238065
- if (fs47.existsSync(editorPath)) {
238066
- const editorSource = fs47.readFileSync(editorPath, "utf8");
238067
- const blockName = `${workspace.workspace.namespace}/${bindingSource.block}`;
238068
- const bindingSourceTargetMatch = editorSource.match(/export\s+const\s+BINDING_SOURCE_TARGET\s*=\s*\{([\s\S]*?)\}\s+as\s+const\s*;/u);
238069
- if (!bindingSourceTargetMatch) {
238070
- issues.push(`${bindingSource.editorFile} must export BINDING_SOURCE_TARGET`);
238071
- } else {
238072
- const targetSource = bindingSourceTargetMatch[1] ?? "";
238073
- const attributePattern = new RegExp(`\\battribute\\s*:\\s*["']${escapeRegex2(bindingSource.attribute)}["']`, "u");
238074
- const blockPattern = new RegExp(`\\bblock\\s*:\\s*["']${escapeRegex2(blockName)}["']`, "u");
238075
- if (!attributePattern.test(targetSource)) {
238076
- issues.push(`${bindingSource.editorFile} must document target attribute "${bindingSource.attribute}"`);
238077
- }
238078
- if (!blockPattern.test(targetSource)) {
238079
- issues.push(`${bindingSource.editorFile} must document target block "${blockName}"`);
238080
- }
238330
+ for (const blockSlug of blockStyleTargetBlocks) {
238331
+ checks3.push(checkExistingFiles(workspace.projectDir, `Block style registry ${blockSlug}`, [
238332
+ path65.join("src", "blocks", blockSlug, "styles", "index.ts")
238333
+ ]));
238334
+ checks3.push(checkBlockStyleEntrypoint(workspace.projectDir, blockSlug));
238335
+ }
238336
+ const blockTransformTargetBlocks = new Set;
238337
+ for (const blockTransform of inventory.blockTransforms) {
238338
+ if (!registeredBlockSlugs.has(blockTransform.block)) {
238339
+ checks3.push(createDoctorCheck2(`Block transform ${blockTransform.block}/${blockTransform.slug}`, "fail", `Block transform references unknown block "${blockTransform.block}"`));
238340
+ continue;
238081
238341
  }
238082
- } else {
238083
- issues.push(`Missing ${bindingSource.editorFile}`);
238342
+ blockTransformTargetBlocks.add(blockTransform.block);
238343
+ checks3.push(checkBlockTransformConfig(workspace, blockTransform));
238344
+ checks3.push(checkExistingFiles(workspace.projectDir, `Block transform ${blockTransform.block}/${blockTransform.slug}`, [blockTransform.file]));
238084
238345
  }
238085
- return createDoctorCheck2(`Binding target ${bindingSource.slug}`, issues.length === 0 ? "pass" : "fail", issues.length === 0 ? `${bindingSource.block}.${bindingSource.attribute} is declared and supported` : issues.join("; "));
238346
+ for (const blockSlug of blockTransformTargetBlocks) {
238347
+ checks3.push(checkExistingFiles(workspace.projectDir, `Block transform registry ${blockSlug}`, [
238348
+ path65.join("src", "blocks", blockSlug, "transforms", "index.ts")
238349
+ ]));
238350
+ checks3.push(checkBlockTransformEntrypoint(workspace.projectDir, blockSlug));
238351
+ }
238352
+ const shouldCheckPatternBootstrap = inventory.patterns.length > 0 || fs49.existsSync(path65.join(workspace.projectDir, "src", "patterns"));
238353
+ if (shouldCheckPatternBootstrap) {
238354
+ checks3.push(checkWorkspacePatternBootstrap(workspace.projectDir, workspace.packageName));
238355
+ }
238356
+ for (const pattern of inventory.patterns) {
238357
+ checks3.push(checkExistingFiles(workspace.projectDir, `Pattern ${pattern.slug}`, [pattern.file]));
238358
+ }
238359
+ return checks3;
238086
238360
  }
238361
+ var WORKSPACE_COLLECTION_IMPORT_LINE = "import '../../collection';", WORKSPACE_COLLECTION_IMPORT_PATTERN, WORKSPACE_VARIATIONS_IMPORT_PATTERN, WORKSPACE_VARIATIONS_CALL_PATTERN, WORKSPACE_BLOCK_STYLES_IMPORT_PATTERN, WORKSPACE_BLOCK_STYLES_CALL_PATTERN, WORKSPACE_BLOCK_TRANSFORMS_IMPORT_PATTERN, WORKSPACE_BLOCK_TRANSFORMS_CALL_PATTERN, WORKSPACE_BLOCK_IFRAME_COMPATIBILITY_DOC_URL = "https://developer.wordpress.org/block-editor/reference-guides/block-api/block-api-versions/block-migration-for-iframe-editor-compatibility/", WORKSPACE_BLOCK_IFRAME_DIAGNOSTIC_CODES, WORKSPACE_BLOCK_EDITOR_SOURCE_FILE_PATTERN, WORKSPACE_BLOCK_EDITOR_SOURCE_BASENAMES, WORKSPACE_BLOCK_EDITOR_SOURCE_DIRECTORIES, WORKSPACE_BLOCK_LOCAL_STYLE_FILES, WORKSPACE_BLOCK_IFRAME_GLOBAL_DOM_PATTERN, WORKSPACE_BLOCK_PROPS_PATTERN;
238362
+ var init_cli_doctor_workspace_blocks = __esm(() => {
238363
+ init_cli_doctor_workspace_shared();
238364
+ init_hooked_blocks();
238365
+ WORKSPACE_COLLECTION_IMPORT_PATTERN = /^\s*import\s+["']\.\.\/\.\.\/collection["']\s*;?\s*$/m;
238366
+ WORKSPACE_VARIATIONS_IMPORT_PATTERN = /^\s*import\s*\{\s*registerWorkspaceVariations\s*\}\s*from\s*["']\.\/variations["']\s*;?\s*$/mu;
238367
+ WORKSPACE_VARIATIONS_CALL_PATTERN = /registerWorkspaceVariations\s*\(\s*\)\s*;?/u;
238368
+ WORKSPACE_BLOCK_STYLES_IMPORT_PATTERN = /^\s*import\s*\{\s*registerWorkspaceBlockStyles\s*\}\s*from\s*["']\.\/styles["']\s*;?\s*$/mu;
238369
+ WORKSPACE_BLOCK_STYLES_CALL_PATTERN = /registerWorkspaceBlockStyles\s*\(\s*\)\s*;?/u;
238370
+ WORKSPACE_BLOCK_TRANSFORMS_IMPORT_PATTERN = /^\s*import\s*\{\s*applyWorkspaceBlockTransforms\s*\}\s*from\s*["']\.\/transforms["']\s*;?\s*$/mu;
238371
+ WORKSPACE_BLOCK_TRANSFORMS_CALL_PATTERN = /applyWorkspaceBlockTransforms\s*\(\s*registration\s*\.\s*settings\s*\)\s*;?/u;
238372
+ WORKSPACE_BLOCK_IFRAME_DIAGNOSTIC_CODES = {
238373
+ API_VERSION: "wp-typia.workspace.block.iframe.api-version",
238374
+ BLOCK_PROPS: "wp-typia.workspace.block.iframe.block-props",
238375
+ EDITOR_GLOBALS: "wp-typia.workspace.block.iframe.editor-globals",
238376
+ EDITOR_STYLES: "wp-typia.workspace.block.iframe.editor-styles"
238377
+ };
238378
+ WORKSPACE_BLOCK_EDITOR_SOURCE_FILE_PATTERN = /\.[cm]?[jt]sx?$/u;
238379
+ WORKSPACE_BLOCK_EDITOR_SOURCE_BASENAMES = new Set([
238380
+ "edit",
238381
+ "editor",
238382
+ "index",
238383
+ "save"
238384
+ ]);
238385
+ WORKSPACE_BLOCK_EDITOR_SOURCE_DIRECTORIES = new Set([
238386
+ "components",
238387
+ "controls",
238388
+ "editor",
238389
+ "inspector"
238390
+ ]);
238391
+ WORKSPACE_BLOCK_LOCAL_STYLE_FILES = [
238392
+ "editor.css",
238393
+ "editor.scss",
238394
+ "index.css",
238395
+ "style.css",
238396
+ "style.scss"
238397
+ ];
238398
+ WORKSPACE_BLOCK_IFRAME_GLOBAL_DOM_PATTERN = /\b(?:document|window)\b|\b(?:parent|top)\b(?!\s*:)/gu;
238399
+ WORKSPACE_BLOCK_PROPS_PATTERN = /\buse(?:Block|InnerBlocks)Props(?:\.save)?\s*\(/u;
238400
+ });
238401
+
238402
+ // ../wp-typia-project-tools/src/runtime/cli-doctor-workspace-features.ts
238403
+ import fs50 from "fs";
238404
+ import path66 from "path";
238087
238405
  function getWorkspaceRestResourceRequiredFiles(restResource) {
238088
238406
  const schemaNames = new Set;
238089
238407
  if (restResource.methods.includes("list")) {
@@ -238109,7 +238427,7 @@ function getWorkspaceRestResourceRequiredFiles(restResource) {
238109
238427
  }
238110
238428
  return Array.from(new Set([
238111
238429
  restResource.apiFile,
238112
- ...Array.from(schemaNames, (schemaName) => path63.join(path63.dirname(restResource.typesFile), "api-schemas", `${schemaName}.schema.json`)),
238430
+ ...Array.from(schemaNames, (schemaName) => path66.join(path66.dirname(restResource.typesFile), "api-schemas", `${schemaName}.schema.json`)),
238113
238431
  restResource.clientFile,
238114
238432
  restResource.dataFile,
238115
238433
  restResource.openApiFile,
@@ -238125,11 +238443,11 @@ function checkWorkspaceRestResourceConfig(restResource) {
238125
238443
  }
238126
238444
  function checkWorkspaceRestResourceBootstrap(projectDir, packageName, phpPrefix) {
238127
238445
  const packageBaseName = packageName.split("/").pop() ?? packageName;
238128
- const bootstrapPath = path63.join(projectDir, `${packageBaseName}.php`);
238129
- if (!fs47.existsSync(bootstrapPath)) {
238130
- return createDoctorCheck2("REST resource bootstrap", "fail", `Missing ${path63.basename(bootstrapPath)}`);
238446
+ const bootstrapPath = path66.join(projectDir, `${packageBaseName}.php`);
238447
+ if (!fs50.existsSync(bootstrapPath)) {
238448
+ return createDoctorCheck2("REST resource bootstrap", "fail", `Missing ${path66.basename(bootstrapPath)}`);
238131
238449
  }
238132
- const source = fs47.readFileSync(bootstrapPath, "utf8");
238450
+ const source = fs50.readFileSync(bootstrapPath, "utf8");
238133
238451
  const registerFunctionName = `${phpPrefix}_register_rest_resources`;
238134
238452
  const registerHook = `add_action( 'init', '${registerFunctionName}', 20 );`;
238135
238453
  const hasServerGlob = source.includes(WORKSPACE_REST_RESOURCE_GLOB);
@@ -238148,12 +238466,12 @@ function getWorkspaceAbilityRequiredFiles(ability) {
238148
238466
  ]));
238149
238467
  }
238150
238468
  function checkWorkspaceAbilityConfig(projectDir, ability) {
238151
- const configPath = path63.join(projectDir, ability.configFile);
238152
- if (!fs47.existsSync(configPath)) {
238469
+ const configPath = path66.join(projectDir, ability.configFile);
238470
+ if (!fs50.existsSync(configPath)) {
238153
238471
  return createDoctorCheck2(`Ability config ${ability.slug}`, "fail", `Missing ${ability.configFile}`);
238154
238472
  }
238155
238473
  try {
238156
- const config2 = JSON.parse(fs47.readFileSync(configPath, "utf8"));
238474
+ const config2 = JSON.parse(fs50.readFileSync(configPath, "utf8"));
238157
238475
  const abilityId = typeof config2.abilityId === "string" ? config2.abilityId.trim() : "";
238158
238476
  const categorySlug = typeof config2.category?.slug === "string" ? config2.category.slug.trim() : "";
238159
238477
  const hasValidAbilityId = /^[a-z0-9-]+\/[a-z0-9-]+$/u.test(abilityId);
@@ -238165,11 +238483,11 @@ function checkWorkspaceAbilityConfig(projectDir, ability) {
238165
238483
  }
238166
238484
  function checkWorkspaceAbilityBootstrap(projectDir, packageName, phpPrefix) {
238167
238485
  const packageBaseName = packageName.split("/").pop() ?? packageName;
238168
- const bootstrapPath = path63.join(projectDir, `${packageBaseName}.php`);
238169
- if (!fs47.existsSync(bootstrapPath)) {
238170
- return createDoctorCheck2("Ability bootstrap", "fail", `Missing ${path63.basename(bootstrapPath)}`);
238486
+ const bootstrapPath = path66.join(projectDir, `${packageBaseName}.php`);
238487
+ if (!fs50.existsSync(bootstrapPath)) {
238488
+ return createDoctorCheck2("Ability bootstrap", "fail", `Missing ${path66.basename(bootstrapPath)}`);
238171
238489
  }
238172
- const source = fs47.readFileSync(bootstrapPath, "utf8");
238490
+ const source = fs50.readFileSync(bootstrapPath, "utf8");
238173
238491
  const loadFunctionName = `${phpPrefix}_load_workflow_abilities`;
238174
238492
  const enqueueFunctionName = `${phpPrefix}_enqueue_workflow_abilities`;
238175
238493
  const loadHook = `add_action( 'plugins_loaded', '${loadFunctionName}' );`;
@@ -238186,14 +238504,14 @@ function checkWorkspaceAbilityBootstrap(projectDir, packageName, phpPrefix) {
238186
238504
  }
238187
238505
  function checkWorkspaceAbilityIndex(projectDir, abilities) {
238188
238506
  const indexRelativePath = [
238189
- path63.join("src", "abilities", "index.ts"),
238190
- path63.join("src", "abilities", "index.js")
238191
- ].find((relativePath) => fs47.existsSync(path63.join(projectDir, relativePath)));
238507
+ path66.join("src", "abilities", "index.ts"),
238508
+ path66.join("src", "abilities", "index.js")
238509
+ ].find((relativePath) => fs50.existsSync(path66.join(projectDir, relativePath)));
238192
238510
  if (!indexRelativePath) {
238193
238511
  return createDoctorCheck2("Abilities index", "fail", "Missing src/abilities/index.ts or src/abilities/index.js");
238194
238512
  }
238195
- const indexPath = path63.join(projectDir, indexRelativePath);
238196
- const source = fs47.readFileSync(indexPath, "utf8");
238513
+ const indexPath = path66.join(projectDir, indexRelativePath);
238514
+ const source = fs50.readFileSync(indexPath, "utf8");
238197
238515
  const missingExports = abilities.filter((ability) => {
238198
238516
  const exportPattern = new RegExp(`^\\s*export\\s+(?:\\*\\s+from|\\{[^}]+\\}\\s+from)\\s+['"\`]\\./${escapeRegex2(ability.slug)}\\/client['"\`]`, "mu");
238199
238517
  return !exportPattern.test(source);
@@ -238204,9 +238522,9 @@ function getWorkspaceAiFeatureRequiredFiles(aiFeature) {
238204
238522
  return Array.from(new Set([
238205
238523
  aiFeature.aiSchemaFile,
238206
238524
  aiFeature.apiFile,
238207
- path63.join(path63.dirname(aiFeature.typesFile), "api-schemas", "feature-request.schema.json"),
238208
- path63.join(path63.dirname(aiFeature.typesFile), "api-schemas", "feature-response.schema.json"),
238209
- path63.join(path63.dirname(aiFeature.typesFile), "api-schemas", "feature-result.schema.json"),
238525
+ path66.join(path66.dirname(aiFeature.typesFile), "api-schemas", "feature-request.schema.json"),
238526
+ path66.join(path66.dirname(aiFeature.typesFile), "api-schemas", "feature-response.schema.json"),
238527
+ path66.join(path66.dirname(aiFeature.typesFile), "api-schemas", "feature-result.schema.json"),
238210
238528
  aiFeature.clientFile,
238211
238529
  aiFeature.dataFile,
238212
238530
  aiFeature.openApiFile,
@@ -238221,11 +238539,11 @@ function checkWorkspaceAiFeatureConfig(aiFeature) {
238221
238539
  }
238222
238540
  function checkWorkspaceAiFeatureBootstrap(projectDir, packageName, phpPrefix) {
238223
238541
  const packageBaseName = packageName.split("/").pop() ?? packageName;
238224
- const bootstrapPath = path63.join(projectDir, `${packageBaseName}.php`);
238225
- if (!fs47.existsSync(bootstrapPath)) {
238226
- return createDoctorCheck2("AI feature bootstrap", "fail", `Missing ${path63.basename(bootstrapPath)}`);
238542
+ const bootstrapPath = path66.join(projectDir, `${packageBaseName}.php`);
238543
+ if (!fs50.existsSync(bootstrapPath)) {
238544
+ return createDoctorCheck2("AI feature bootstrap", "fail", `Missing ${path66.basename(bootstrapPath)}`);
238227
238545
  }
238228
- const source = fs47.readFileSync(bootstrapPath, "utf8");
238546
+ const source = fs50.readFileSync(bootstrapPath, "utf8");
238229
238547
  const registerFunctionName = `${phpPrefix}_register_ai_features`;
238230
238548
  const registerHook = `add_action( 'init', '${registerFunctionName}', 20 );`;
238231
238549
  const hasServerGlob = source.includes(WORKSPACE_AI_FEATURE_GLOB);
@@ -238233,14 +238551,14 @@ function checkWorkspaceAiFeatureBootstrap(projectDir, packageName, phpPrefix) {
238233
238551
  return createDoctorCheck2("AI feature bootstrap", hasServerGlob && hasRegisterHook ? "pass" : "fail", hasServerGlob && hasRegisterHook ? "AI feature PHP loader hook is present" : "Missing AI feature PHP require glob or init hook");
238234
238552
  }
238235
238553
  function getWorkspaceEditorPluginRequiredFiles(editorPlugin) {
238236
- const editorPluginDir = path63.join("src", "editor-plugins", editorPlugin.slug);
238237
- const surfaceFile = editorPlugin.slot === "PluginSidebar" ? path63.join(editorPluginDir, "Sidebar.tsx") : path63.join(editorPluginDir, "Surface.tsx");
238554
+ const editorPluginDir = path66.join("src", "editor-plugins", editorPlugin.slug);
238555
+ const surfaceFile = editorPlugin.slot === "PluginSidebar" ? path66.join(editorPluginDir, "Sidebar.tsx") : path66.join(editorPluginDir, "Surface.tsx");
238238
238556
  return Array.from(new Set([
238239
238557
  editorPlugin.file,
238240
238558
  surfaceFile,
238241
- path63.join(editorPluginDir, "data.ts"),
238242
- path63.join(editorPluginDir, "types.ts"),
238243
- path63.join(editorPluginDir, "style.scss")
238559
+ path66.join(editorPluginDir, "data.ts"),
238560
+ path66.join(editorPluginDir, "types.ts"),
238561
+ path66.join(editorPluginDir, "style.scss")
238244
238562
  ]));
238245
238563
  }
238246
238564
  function checkWorkspaceEditorPluginConfig(editorPlugin) {
@@ -238250,11 +238568,11 @@ function checkWorkspaceEditorPluginConfig(editorPlugin) {
238250
238568
  }
238251
238569
  function checkWorkspaceEditorPluginBootstrap(projectDir, packageName, phpPrefix) {
238252
238570
  const packageBaseName = packageName.split("/").pop() ?? packageName;
238253
- const bootstrapPath = path63.join(projectDir, `${packageBaseName}.php`);
238254
- if (!fs47.existsSync(bootstrapPath)) {
238255
- return createDoctorCheck2("Editor plugin bootstrap", "fail", `Missing ${path63.basename(bootstrapPath)}`);
238571
+ const bootstrapPath = path66.join(projectDir, `${packageBaseName}.php`);
238572
+ if (!fs50.existsSync(bootstrapPath)) {
238573
+ return createDoctorCheck2("Editor plugin bootstrap", "fail", `Missing ${path66.basename(bootstrapPath)}`);
238256
238574
  }
238257
- const source = fs47.readFileSync(bootstrapPath, "utf8");
238575
+ const source = fs50.readFileSync(bootstrapPath, "utf8");
238258
238576
  const enqueueFunctionName = `${phpPrefix}_enqueue_editor_plugins_editor`;
238259
238577
  const enqueueHook = `add_action( 'enqueue_block_editor_assets', '${enqueueFunctionName}' );`;
238260
238578
  const hasEditorEnqueueHook = source.includes(enqueueHook);
@@ -238265,14 +238583,14 @@ function checkWorkspaceEditorPluginBootstrap(projectDir, packageName, phpPrefix)
238265
238583
  }
238266
238584
  function checkWorkspaceEditorPluginIndex(projectDir, editorPlugins) {
238267
238585
  const indexRelativePath = [
238268
- path63.join("src", "editor-plugins", "index.ts"),
238269
- path63.join("src", "editor-plugins", "index.js")
238270
- ].find((relativePath) => fs47.existsSync(path63.join(projectDir, relativePath)));
238586
+ path66.join("src", "editor-plugins", "index.ts"),
238587
+ path66.join("src", "editor-plugins", "index.js")
238588
+ ].find((relativePath) => fs50.existsSync(path66.join(projectDir, relativePath)));
238271
238589
  if (!indexRelativePath) {
238272
238590
  return createDoctorCheck2("Editor plugins index", "fail", "Missing src/editor-plugins/index.ts or src/editor-plugins/index.js");
238273
238591
  }
238274
- const indexPath = path63.join(projectDir, indexRelativePath);
238275
- const source = fs47.readFileSync(indexPath, "utf8");
238592
+ const indexPath = path66.join(projectDir, indexRelativePath);
238593
+ const source = fs50.readFileSync(indexPath, "utf8");
238276
238594
  const missingImports = editorPlugins.filter((editorPlugin) => {
238277
238595
  const importPattern = new RegExp(`['"\`]\\./${escapeRegex2(editorPlugin.slug)}(?:/[^'"\`]*)?['"\`]`, "u");
238278
238596
  return !importPattern.test(source);
@@ -238280,15 +238598,15 @@ function checkWorkspaceEditorPluginIndex(projectDir, editorPlugins) {
238280
238598
  return createDoctorCheck2("Editor plugins index", missingImports.length === 0 ? "pass" : "fail", missingImports.length === 0 ? "Editor plugin registrations are aggregated" : `Missing editor plugin imports for: ${missingImports.map((entry) => entry.slug).join(", ")}`);
238281
238599
  }
238282
238600
  function getWorkspaceAdminViewRequiredFiles(adminView) {
238283
- const adminViewDir = path63.join("src", "admin-views", adminView.slug);
238601
+ const adminViewDir = path66.join("src", "admin-views", adminView.slug);
238284
238602
  return Array.from(new Set([
238285
238603
  adminView.file,
238286
238604
  adminView.phpFile,
238287
- path63.join(adminViewDir, "Screen.tsx"),
238288
- path63.join(adminViewDir, "config.ts"),
238289
- path63.join(adminViewDir, "data.ts"),
238290
- path63.join(adminViewDir, "style.scss"),
238291
- path63.join(adminViewDir, "types.ts")
238605
+ path66.join(adminViewDir, "Screen.tsx"),
238606
+ path66.join(adminViewDir, "config.ts"),
238607
+ path66.join(adminViewDir, "data.ts"),
238608
+ path66.join(adminViewDir, "style.scss"),
238609
+ path66.join(adminViewDir, "types.ts")
238292
238610
  ]));
238293
238611
  }
238294
238612
  function checkWorkspaceAdminViewConfig(adminView, inventory) {
@@ -238305,11 +238623,11 @@ function checkWorkspaceAdminViewConfig(adminView, inventory) {
238305
238623
  }
238306
238624
  function checkWorkspaceAdminViewBootstrap(projectDir, packageName, phpPrefix) {
238307
238625
  const packageBaseName = packageName.split("/").pop() ?? packageName;
238308
- const bootstrapPath = path63.join(projectDir, `${packageBaseName}.php`);
238309
- if (!fs47.existsSync(bootstrapPath)) {
238310
- return createDoctorCheck2("Admin view bootstrap", "fail", `Missing ${path63.basename(bootstrapPath)}`);
238626
+ const bootstrapPath = path66.join(projectDir, `${packageBaseName}.php`);
238627
+ if (!fs50.existsSync(bootstrapPath)) {
238628
+ return createDoctorCheck2("Admin view bootstrap", "fail", `Missing ${path66.basename(bootstrapPath)}`);
238311
238629
  }
238312
- const source = fs47.readFileSync(bootstrapPath, "utf8");
238630
+ const source = fs50.readFileSync(bootstrapPath, "utf8");
238313
238631
  const loadFunctionName = `${phpPrefix}_load_admin_views`;
238314
238632
  const loadHook = `add_action( 'plugins_loaded', '${loadFunctionName}' );`;
238315
238633
  const hasLoaderHook = source.includes(loadHook);
@@ -238318,14 +238636,14 @@ function checkWorkspaceAdminViewBootstrap(projectDir, packageName, phpPrefix) {
238318
238636
  }
238319
238637
  function checkWorkspaceAdminViewIndex(projectDir, adminViews) {
238320
238638
  const indexRelativePath = [
238321
- path63.join("src", "admin-views", "index.ts"),
238322
- path63.join("src", "admin-views", "index.js")
238323
- ].find((relativePath) => fs47.existsSync(path63.join(projectDir, relativePath)));
238639
+ path66.join("src", "admin-views", "index.ts"),
238640
+ path66.join("src", "admin-views", "index.js")
238641
+ ].find((relativePath) => fs50.existsSync(path66.join(projectDir, relativePath)));
238324
238642
  if (!indexRelativePath) {
238325
238643
  return createDoctorCheck2("Admin views index", "fail", "Missing src/admin-views/index.ts or src/admin-views/index.js");
238326
238644
  }
238327
- const indexPath = path63.join(projectDir, indexRelativePath);
238328
- const source = fs47.readFileSync(indexPath, "utf8");
238645
+ const indexPath = path66.join(projectDir, indexRelativePath);
238646
+ const source = fs50.readFileSync(indexPath, "utf8");
238329
238647
  const missingImports = adminViews.filter((adminView) => {
238330
238648
  const importPattern = new RegExp(`['"\`]\\./${escapeRegex2(adminView.slug)}(?:/[^'"\`]*)?['"\`]`, "u");
238331
238649
  return !importPattern.test(source);
@@ -238333,11 +238651,11 @@ function checkWorkspaceAdminViewIndex(projectDir, adminViews) {
238333
238651
  return createDoctorCheck2("Admin views index", missingImports.length === 0 ? "pass" : "fail", missingImports.length === 0 ? "Admin view registrations are aggregated" : `Missing admin view imports for: ${missingImports.map((entry) => entry.slug).join(", ")}`);
238334
238652
  }
238335
238653
  function checkWorkspaceAdminViewPhp(projectDir, adminView) {
238336
- const phpPath = path63.join(projectDir, adminView.phpFile);
238337
- if (!fs47.existsSync(phpPath)) {
238654
+ const phpPath = path66.join(projectDir, adminView.phpFile);
238655
+ if (!fs50.existsSync(phpPath)) {
238338
238656
  return createDoctorCheck2(`Admin view PHP ${adminView.slug}`, "fail", `Missing ${adminView.phpFile}`);
238339
238657
  }
238340
- const source = fs47.readFileSync(phpPath, "utf8");
238658
+ const source = fs50.readFileSync(phpPath, "utf8");
238341
238659
  const hasAdminMenu = source.includes("add_submenu_page");
238342
238660
  const hasAdminEnqueue = source.includes("admin_enqueue_scripts");
238343
238661
  const hasScript = source.includes(WORKSPACE_ADMIN_VIEW_SCRIPT);
@@ -238346,56 +238664,115 @@ function checkWorkspaceAdminViewPhp(projectDir, adminView) {
238346
238664
  const hasComponentsStyleDependency = source.includes("'wp-components'");
238347
238665
  return createDoctorCheck2(`Admin view PHP ${adminView.slug}`, hasAdminMenu && hasAdminEnqueue && hasScript && hasAsset && hasStyle && hasComponentsStyleDependency ? "pass" : "fail", hasAdminMenu && hasAdminEnqueue && hasScript && hasAsset && hasStyle && hasComponentsStyleDependency ? "Admin menu, script, style, and wp-components style dependency are wired" : "Missing admin menu, enqueue hook, build/admin-views asset reference, or wp-components style dependency");
238348
238666
  }
238349
- function checkVariationEntrypoint(projectDir, blockSlug) {
238350
- const entryPath = path63.join(projectDir, "src", "blocks", blockSlug, "index.tsx");
238351
- if (!fs47.existsSync(entryPath)) {
238352
- return createDoctorCheck2(`Variation entrypoint ${blockSlug}`, "fail", `Missing ${path63.relative(projectDir, entryPath)}`);
238667
+ function getWorkspaceFeatureDoctorChecks(workspace, inventory) {
238668
+ const checks3 = [];
238669
+ if (inventory.restResources.length > 0) {
238670
+ checks3.push(checkWorkspaceRestResourceBootstrap(workspace.projectDir, workspace.packageName, workspace.workspace.phpPrefix));
238353
238671
  }
238354
- const source = fs47.readFileSync(entryPath, "utf8");
238355
- const hasImport = hasUncommentedPattern2(source, WORKSPACE_VARIATIONS_IMPORT_PATTERN);
238356
- const hasCall = hasExecutablePattern2(source, WORKSPACE_VARIATIONS_CALL_PATTERN);
238357
- return createDoctorCheck2(`Variation entrypoint ${blockSlug}`, hasImport && hasCall ? "pass" : "fail", hasImport && hasCall ? "Variations registration hook is present" : "Missing ./variations import or registerWorkspaceVariations() call");
238358
- }
238359
- function checkBlockStyleEntrypoint(projectDir, blockSlug) {
238360
- const entryPath = path63.join(projectDir, "src", "blocks", blockSlug, "index.tsx");
238361
- if (!fs47.existsSync(entryPath)) {
238362
- return createDoctorCheck2(`Block style entrypoint ${blockSlug}`, "fail", `Missing ${path63.relative(projectDir, entryPath)}`);
238672
+ for (const restResource of inventory.restResources) {
238673
+ checks3.push(checkWorkspaceRestResourceConfig(restResource));
238674
+ checks3.push(checkExistingFiles(workspace.projectDir, `REST resource ${restResource.slug}`, getWorkspaceRestResourceRequiredFiles(restResource)));
238363
238675
  }
238364
- const source = fs47.readFileSync(entryPath, "utf8");
238365
- const hasImport = hasUncommentedPattern2(source, WORKSPACE_BLOCK_STYLES_IMPORT_PATTERN);
238366
- const hasCall = hasExecutablePattern2(source, WORKSPACE_BLOCK_STYLES_CALL_PATTERN);
238367
- return createDoctorCheck2(`Block style entrypoint ${blockSlug}`, hasImport && hasCall ? "pass" : "fail", hasImport && hasCall ? "Block style registration hook is present" : "Missing ./styles import or registerWorkspaceBlockStyles() call");
238368
- }
238369
- function checkBlockTransformEntrypoint(projectDir, blockSlug) {
238370
- const entryPath = path63.join(projectDir, "src", "blocks", blockSlug, "index.tsx");
238371
- if (!fs47.existsSync(entryPath)) {
238372
- return createDoctorCheck2(`Block transform entrypoint ${blockSlug}`, "fail", `Missing ${path63.relative(projectDir, entryPath)}`);
238676
+ if (inventory.abilities.length > 0) {
238677
+ checks3.push(checkWorkspaceAbilityBootstrap(workspace.projectDir, workspace.packageName, workspace.workspace.phpPrefix));
238678
+ checks3.push(checkWorkspaceAbilityIndex(workspace.projectDir, inventory.abilities));
238373
238679
  }
238374
- const source = fs47.readFileSync(entryPath, "utf8");
238375
- const hasImport = hasUncommentedPattern2(source, WORKSPACE_BLOCK_TRANSFORMS_IMPORT_PATTERN);
238376
- const hasCall = hasExecutablePattern2(source, WORKSPACE_BLOCK_TRANSFORMS_CALL_PATTERN);
238377
- return createDoctorCheck2(`Block transform entrypoint ${blockSlug}`, hasImport && hasCall ? "pass" : "fail", hasImport && hasCall ? "Block transform registration hook is present" : "Missing ./transforms import or applyWorkspaceBlockTransforms(registration.settings) call");
238680
+ for (const ability of inventory.abilities) {
238681
+ checks3.push(checkWorkspaceAbilityConfig(workspace.projectDir, ability));
238682
+ checks3.push(checkExistingFiles(workspace.projectDir, `Ability ${ability.slug}`, getWorkspaceAbilityRequiredFiles(ability)));
238683
+ }
238684
+ if (inventory.aiFeatures.length > 0) {
238685
+ checks3.push(checkWorkspaceAiFeatureBootstrap(workspace.projectDir, workspace.packageName, workspace.workspace.phpPrefix));
238686
+ }
238687
+ for (const aiFeature of inventory.aiFeatures) {
238688
+ checks3.push(checkWorkspaceAiFeatureConfig(aiFeature));
238689
+ checks3.push(checkExistingFiles(workspace.projectDir, `AI feature ${aiFeature.slug}`, getWorkspaceAiFeatureRequiredFiles(aiFeature)));
238690
+ }
238691
+ if (inventory.editorPlugins.length > 0) {
238692
+ checks3.push(checkWorkspaceEditorPluginBootstrap(workspace.projectDir, workspace.packageName, workspace.workspace.phpPrefix));
238693
+ checks3.push(checkWorkspaceEditorPluginIndex(workspace.projectDir, inventory.editorPlugins));
238694
+ }
238695
+ for (const editorPlugin of inventory.editorPlugins) {
238696
+ checks3.push(checkExistingFiles(workspace.projectDir, `Editor plugin ${editorPlugin.slug}`, getWorkspaceEditorPluginRequiredFiles(editorPlugin)));
238697
+ checks3.push(checkWorkspaceEditorPluginConfig(editorPlugin));
238698
+ }
238699
+ if (inventory.adminViews.length > 0) {
238700
+ checks3.push(checkWorkspaceAdminViewBootstrap(workspace.projectDir, workspace.packageName, workspace.workspace.phpPrefix));
238701
+ checks3.push(checkWorkspaceAdminViewIndex(workspace.projectDir, inventory.adminViews));
238702
+ }
238703
+ for (const adminView of inventory.adminViews) {
238704
+ checks3.push(checkWorkspaceAdminViewConfig(adminView, inventory));
238705
+ checks3.push(checkExistingFiles(workspace.projectDir, `Admin view ${adminView.slug}`, getWorkspaceAdminViewRequiredFiles(adminView)));
238706
+ checks3.push(checkWorkspaceAdminViewPhp(workspace.projectDir, adminView));
238707
+ }
238708
+ return checks3;
238378
238709
  }
238379
- function checkBlockTransformConfig(workspace, transform2) {
238380
- const expectedTo = `${workspace.workspace.namespace}/${transform2.block}`;
238710
+ var init_cli_doctor_workspace_features = __esm(() => {
238711
+ init_cli_add_shared();
238712
+ init_cli_doctor_workspace_shared();
238713
+ });
238714
+
238715
+ // ../wp-typia-project-tools/src/runtime/cli-doctor-workspace-package.ts
238716
+ import fs51 from "fs";
238717
+ import path67 from "path";
238718
+ function getWorkspacePackageMetadataCheck(workspace, packageJson) {
238381
238719
  const issues = [];
238382
- if (!WORKSPACE_FULL_BLOCK_NAME_PATTERN.test(transform2.from)) {
238383
- issues.push("from must use full namespace/block format");
238720
+ const packageName = packageJson.name;
238721
+ const bootstrapRelativePath = getWorkspaceBootstrapRelativePath(typeof packageName === "string" && packageName.length > 0 ? packageName : workspace.packageName);
238722
+ const wpTypia = packageJson.wpTypia;
238723
+ if (typeof packageName !== "string" || packageName.length === 0) {
238724
+ issues.push("package.json must define a string name for workspace bootstrap resolution");
238384
238725
  }
238385
- if (transform2.to !== expectedTo) {
238386
- issues.push(`to must equal "${expectedTo}" for workspace block "${transform2.block}"`);
238726
+ if (wpTypia?.projectType !== "workspace") {
238727
+ issues.push('wpTypia.projectType must be "workspace"');
238387
238728
  }
238388
- return createDoctorCheck2(`Block transform config ${transform2.block}/${transform2.slug}`, issues.length === 0 ? "pass" : "fail", issues.length === 0 ? `${transform2.from} transforms into ${transform2.to}` : issues.join("; "));
238729
+ if (wpTypia?.templatePackage !== WORKSPACE_TEMPLATE_PACKAGE) {
238730
+ issues.push(`wpTypia.templatePackage must be "${WORKSPACE_TEMPLATE_PACKAGE}"`);
238731
+ }
238732
+ if (wpTypia?.namespace !== workspace.workspace.namespace) {
238733
+ issues.push(`wpTypia.namespace must equal "${workspace.workspace.namespace}"`);
238734
+ }
238735
+ if (wpTypia?.textDomain !== workspace.workspace.textDomain) {
238736
+ issues.push(`wpTypia.textDomain must equal "${workspace.workspace.textDomain}"`);
238737
+ }
238738
+ if (wpTypia?.phpPrefix !== workspace.workspace.phpPrefix) {
238739
+ issues.push(`wpTypia.phpPrefix must equal "${workspace.workspace.phpPrefix}"`);
238740
+ }
238741
+ if (!fs51.existsSync(path67.join(workspace.projectDir, bootstrapRelativePath))) {
238742
+ issues.push(`Missing bootstrap file ${bootstrapRelativePath}`);
238743
+ }
238744
+ return createDoctorCheck2("Workspace package metadata", issues.length === 0 ? "pass" : "fail", issues.length === 0 ? `package.json metadata aligns with ${workspace.packageName} and ${bootstrapRelativePath}` : issues.join("; "));
238389
238745
  }
238390
- function checkMigrationWorkspaceHint(workspace, packageJson) {
238746
+ function getMigrationWorkspaceHintCheck(workspace, packageJson) {
238391
238747
  const hasMigrationScript = typeof packageJson.scripts?.["migration:doctor"] === "string";
238392
- const migrationConfigRelativePath = path63.join("src", "migrations", "config.ts");
238393
- const hasMigrationConfig = fs47.existsSync(path63.join(workspace.projectDir, migrationConfigRelativePath));
238748
+ const migrationConfigRelativePath = path67.join("src", "migrations", "config.ts");
238749
+ const hasMigrationConfig = fs51.existsSync(path67.join(workspace.projectDir, migrationConfigRelativePath));
238394
238750
  if (!hasMigrationScript && !hasMigrationConfig) {
238395
238751
  return null;
238396
238752
  }
238397
238753
  return createDoctorCheck2("Migration workspace", hasMigrationConfig ? "pass" : "fail", hasMigrationConfig ? "Run `wp-typia migrate doctor --all` for migration target, snapshot, fixture, and generated artifact checks" : `Missing ${migrationConfigRelativePath} for the configured migration workspace`);
238398
238754
  }
238755
+ var init_cli_doctor_workspace_package = __esm(() => {
238756
+ init_cli_doctor_workspace_shared();
238757
+ init_workspace_project();
238758
+ });
238759
+
238760
+ // ../wp-typia-project-tools/src/runtime/cli-doctor-workspace.ts
238761
+ function formatWorkspaceInventorySummary(inventory) {
238762
+ return [
238763
+ `${inventory.blocks.length} block(s)`,
238764
+ `${inventory.variations.length} variation(s)`,
238765
+ `${inventory.blockStyles.length} block style(s)`,
238766
+ `${inventory.blockTransforms.length} block transform(s)`,
238767
+ `${inventory.patterns.length} pattern(s)`,
238768
+ `${inventory.bindingSources.length} binding source(s)`,
238769
+ `${inventory.restResources.length} REST resource(s)`,
238770
+ `${inventory.abilities.length} ability scaffold(s)`,
238771
+ `${inventory.aiFeatures.length} AI feature(s)`,
238772
+ `${inventory.editorPlugins.length} editor plugin(s)`,
238773
+ `${inventory.adminViews.length} admin view(s)`
238774
+ ].join(", ");
238775
+ }
238399
238776
  function getWorkspaceDoctorChecks(cwd) {
238400
238777
  const checks3 = [];
238401
238778
  let workspace = null;
@@ -238425,122 +238802,14 @@ function getWorkspaceDoctorChecks(cwd) {
238425
238802
  checks3.push(createDoctorCheck2("Workspace package metadata", "fail", error48 instanceof Error ? error48.message : String(error48)));
238426
238803
  return checks3;
238427
238804
  }
238428
- checks3.push(checkWorkspacePackageMetadata(workspace, workspacePackageJson));
238805
+ checks3.push(getWorkspacePackageMetadataCheck(workspace, workspacePackageJson));
238429
238806
  try {
238430
238807
  const inventory = readWorkspaceInventory(workspace.projectDir);
238431
- checks3.push(createDoctorCheck2("Workspace inventory", "pass", `${inventory.blocks.length} block(s), ${inventory.variations.length} variation(s), ${inventory.blockStyles.length} block style(s), ${inventory.blockTransforms.length} block transform(s), ${inventory.patterns.length} pattern(s), ${inventory.bindingSources.length} binding source(s), ${inventory.restResources.length} REST resource(s), ${inventory.abilities.length} ability scaffold(s), ${inventory.aiFeatures.length} AI feature(s), ${inventory.editorPlugins.length} editor plugin(s), ${inventory.adminViews.length} admin view(s)`));
238432
- for (const block of inventory.blocks) {
238433
- checks3.push(checkExistingFiles(workspace.projectDir, `Block ${block.slug}`, getWorkspaceBlockRequiredFiles(block)));
238434
- checks3.push(checkWorkspaceBlockMetadata(workspace.projectDir, workspace, block));
238435
- checks3.push(checkWorkspaceBlockHooks(workspace.projectDir, block.slug));
238436
- checks3.push(checkWorkspaceBlockCollectionImport(workspace.projectDir, block.slug));
238437
- checks3.push(...checkWorkspaceBlockIframeCompatibility(workspace.projectDir, block.slug));
238438
- }
238439
- const registeredBlockSlugs = new Set(inventory.blocks.map((block) => block.slug));
238440
- const variationTargetBlocks = new Set;
238441
- for (const variation of inventory.variations) {
238442
- if (!registeredBlockSlugs.has(variation.block)) {
238443
- checks3.push(createDoctorCheck2(`Variation ${variation.block}/${variation.slug}`, "fail", `Variation references unknown block "${variation.block}"`));
238444
- continue;
238445
- }
238446
- variationTargetBlocks.add(variation.block);
238447
- checks3.push(checkExistingFiles(workspace.projectDir, `Variation ${variation.block}/${variation.slug}`, [variation.file]));
238448
- }
238449
- for (const blockSlug of variationTargetBlocks) {
238450
- checks3.push(checkVariationEntrypoint(workspace.projectDir, blockSlug));
238451
- }
238452
- const blockStyleTargetBlocks = new Set;
238453
- for (const blockStyle of inventory.blockStyles) {
238454
- if (!registeredBlockSlugs.has(blockStyle.block)) {
238455
- checks3.push(createDoctorCheck2(`Block style ${blockStyle.block}/${blockStyle.slug}`, "fail", `Block style references unknown block "${blockStyle.block}"`));
238456
- continue;
238457
- }
238458
- blockStyleTargetBlocks.add(blockStyle.block);
238459
- checks3.push(checkExistingFiles(workspace.projectDir, `Block style ${blockStyle.block}/${blockStyle.slug}`, [blockStyle.file]));
238460
- }
238461
- for (const blockSlug of blockStyleTargetBlocks) {
238462
- checks3.push(checkExistingFiles(workspace.projectDir, `Block style registry ${blockSlug}`, [
238463
- path63.join("src", "blocks", blockSlug, "styles", "index.ts")
238464
- ]));
238465
- checks3.push(checkBlockStyleEntrypoint(workspace.projectDir, blockSlug));
238466
- }
238467
- const blockTransformTargetBlocks = new Set;
238468
- for (const blockTransform of inventory.blockTransforms) {
238469
- if (!registeredBlockSlugs.has(blockTransform.block)) {
238470
- checks3.push(createDoctorCheck2(`Block transform ${blockTransform.block}/${blockTransform.slug}`, "fail", `Block transform references unknown block "${blockTransform.block}"`));
238471
- continue;
238472
- }
238473
- blockTransformTargetBlocks.add(blockTransform.block);
238474
- checks3.push(checkBlockTransformConfig(workspace, blockTransform));
238475
- checks3.push(checkExistingFiles(workspace.projectDir, `Block transform ${blockTransform.block}/${blockTransform.slug}`, [blockTransform.file]));
238476
- }
238477
- for (const blockSlug of blockTransformTargetBlocks) {
238478
- checks3.push(checkExistingFiles(workspace.projectDir, `Block transform registry ${blockSlug}`, [
238479
- path63.join("src", "blocks", blockSlug, "transforms", "index.ts")
238480
- ]));
238481
- checks3.push(checkBlockTransformEntrypoint(workspace.projectDir, blockSlug));
238482
- }
238483
- const shouldCheckPatternBootstrap = inventory.patterns.length > 0 || fs47.existsSync(path63.join(workspace.projectDir, "src", "patterns"));
238484
- if (shouldCheckPatternBootstrap) {
238485
- checks3.push(checkWorkspacePatternBootstrap(workspace.projectDir, workspace.packageName));
238486
- }
238487
- for (const pattern of inventory.patterns) {
238488
- checks3.push(checkExistingFiles(workspace.projectDir, `Pattern ${pattern.slug}`, [pattern.file]));
238489
- }
238490
- if (inventory.bindingSources.length > 0) {
238491
- checks3.push(checkWorkspaceBindingBootstrap(workspace.projectDir, workspace.packageName));
238492
- checks3.push(checkWorkspaceBindingSourcesIndex(workspace.projectDir, inventory.bindingSources));
238493
- }
238494
- for (const bindingSource of inventory.bindingSources) {
238495
- checks3.push(checkExistingFiles(workspace.projectDir, `Binding source ${bindingSource.slug}`, [
238496
- bindingSource.serverFile,
238497
- bindingSource.editorFile
238498
- ]));
238499
- const bindingTargetCheck = checkWorkspaceBindingTarget(workspace.projectDir, workspace, registeredBlockSlugs, bindingSource);
238500
- if (bindingTargetCheck) {
238501
- checks3.push(bindingTargetCheck);
238502
- }
238503
- }
238504
- if (inventory.restResources.length > 0) {
238505
- checks3.push(checkWorkspaceRestResourceBootstrap(workspace.projectDir, workspace.packageName, workspace.workspace.phpPrefix));
238506
- }
238507
- for (const restResource of inventory.restResources) {
238508
- checks3.push(checkWorkspaceRestResourceConfig(restResource));
238509
- checks3.push(checkExistingFiles(workspace.projectDir, `REST resource ${restResource.slug}`, getWorkspaceRestResourceRequiredFiles(restResource)));
238510
- }
238511
- if (inventory.abilities.length > 0) {
238512
- checks3.push(checkWorkspaceAbilityBootstrap(workspace.projectDir, workspace.packageName, workspace.workspace.phpPrefix));
238513
- checks3.push(checkWorkspaceAbilityIndex(workspace.projectDir, inventory.abilities));
238514
- }
238515
- for (const ability of inventory.abilities) {
238516
- checks3.push(checkWorkspaceAbilityConfig(workspace.projectDir, ability));
238517
- checks3.push(checkExistingFiles(workspace.projectDir, `Ability ${ability.slug}`, getWorkspaceAbilityRequiredFiles(ability)));
238518
- }
238519
- if (inventory.aiFeatures.length > 0) {
238520
- checks3.push(checkWorkspaceAiFeatureBootstrap(workspace.projectDir, workspace.packageName, workspace.workspace.phpPrefix));
238521
- }
238522
- for (const aiFeature of inventory.aiFeatures) {
238523
- checks3.push(checkWorkspaceAiFeatureConfig(aiFeature));
238524
- checks3.push(checkExistingFiles(workspace.projectDir, `AI feature ${aiFeature.slug}`, getWorkspaceAiFeatureRequiredFiles(aiFeature)));
238525
- }
238526
- if (inventory.editorPlugins.length > 0) {
238527
- checks3.push(checkWorkspaceEditorPluginBootstrap(workspace.projectDir, workspace.packageName, workspace.workspace.phpPrefix));
238528
- checks3.push(checkWorkspaceEditorPluginIndex(workspace.projectDir, inventory.editorPlugins));
238529
- }
238530
- for (const editorPlugin of inventory.editorPlugins) {
238531
- checks3.push(checkExistingFiles(workspace.projectDir, `Editor plugin ${editorPlugin.slug}`, getWorkspaceEditorPluginRequiredFiles(editorPlugin)));
238532
- checks3.push(checkWorkspaceEditorPluginConfig(editorPlugin));
238533
- }
238534
- if (inventory.adminViews.length > 0) {
238535
- checks3.push(checkWorkspaceAdminViewBootstrap(workspace.projectDir, workspace.packageName, workspace.workspace.phpPrefix));
238536
- checks3.push(checkWorkspaceAdminViewIndex(workspace.projectDir, inventory.adminViews));
238537
- }
238538
- for (const adminView of inventory.adminViews) {
238539
- checks3.push(checkWorkspaceAdminViewConfig(adminView, inventory));
238540
- checks3.push(checkExistingFiles(workspace.projectDir, `Admin view ${adminView.slug}`, getWorkspaceAdminViewRequiredFiles(adminView)));
238541
- checks3.push(checkWorkspaceAdminViewPhp(workspace.projectDir, adminView));
238542
- }
238543
- const migrationWorkspaceCheck = checkMigrationWorkspaceHint(workspace, workspacePackageJson);
238808
+ checks3.push(createDoctorCheck2("Workspace inventory", "pass", formatWorkspaceInventorySummary(inventory)));
238809
+ checks3.push(...getWorkspaceBlockDoctorChecks(workspace, inventory));
238810
+ checks3.push(...getWorkspaceBindingDoctorChecks(workspace, inventory));
238811
+ checks3.push(...getWorkspaceFeatureDoctorChecks(workspace, inventory));
238812
+ const migrationWorkspaceCheck = getMigrationWorkspaceHintCheck(workspace, workspacePackageJson);
238544
238813
  if (migrationWorkspaceCheck) {
238545
238814
  checks3.push(migrationWorkspaceCheck);
238546
238815
  }
@@ -238549,55 +238818,14 @@ function getWorkspaceDoctorChecks(cwd) {
238549
238818
  }
238550
238819
  return checks3;
238551
238820
  }
238552
- var WORKSPACE_COLLECTION_IMPORT_LINE = "import '../../collection';", WORKSPACE_COLLECTION_IMPORT_PATTERN, WORKSPACE_BINDING_SERVER_GLOB = "/src/bindings/*/server.php", WORKSPACE_BINDING_EDITOR_SCRIPT = "build/bindings/index.js", WORKSPACE_BINDING_EDITOR_ASSET = "build/bindings/index.asset.php", WORKSPACE_REST_RESOURCE_GLOB = "/inc/rest/*.php", WORKSPACE_ABILITY_GLOB = "/inc/abilities/*.php", WORKSPACE_ABILITY_EDITOR_SCRIPT = "build/abilities/index.js", WORKSPACE_ABILITY_EDITOR_ASSET = "build/abilities/index.asset.php", WORKSPACE_AI_FEATURE_GLOB = "/inc/ai-features/*.php", WORKSPACE_ADMIN_VIEW_GLOB = "/inc/admin-views/*.php", WORKSPACE_ADMIN_VIEW_SCRIPT = "build/admin-views/index.js", WORKSPACE_ADMIN_VIEW_ASSET = "build/admin-views/index.asset.php", WORKSPACE_ADMIN_VIEW_STYLE = "build/admin-views/style-index.css", WORKSPACE_EDITOR_PLUGIN_EDITOR_SCRIPT = "build/editor-plugins/index.js", WORKSPACE_EDITOR_PLUGIN_EDITOR_ASSET = "build/editor-plugins/index.asset.php", WORKSPACE_EDITOR_PLUGIN_EDITOR_STYLE = "build/editor-plugins/style-index.css", WORKSPACE_GENERATED_BLOCK_ARTIFACTS, WORKSPACE_FULL_BLOCK_NAME_PATTERN, WORKSPACE_VARIATIONS_IMPORT_PATTERN, WORKSPACE_VARIATIONS_CALL_PATTERN, WORKSPACE_BLOCK_STYLES_IMPORT_PATTERN, WORKSPACE_BLOCK_STYLES_CALL_PATTERN, WORKSPACE_BLOCK_TRANSFORMS_IMPORT_PATTERN, WORKSPACE_BLOCK_TRANSFORMS_CALL_PATTERN, WORKSPACE_BLOCK_IFRAME_COMPATIBILITY_DOC_URL = "https://developer.wordpress.org/block-editor/reference-guides/block-api/block-api-versions/block-migration-for-iframe-editor-compatibility/", WORKSPACE_BLOCK_IFRAME_DIAGNOSTIC_CODES, WORKSPACE_BLOCK_EDITOR_SOURCE_FILE_PATTERN, WORKSPACE_BLOCK_EDITOR_SOURCE_BASENAMES, WORKSPACE_BLOCK_EDITOR_SOURCE_DIRECTORIES, WORKSPACE_BLOCK_LOCAL_STYLE_FILES, WORKSPACE_BLOCK_IFRAME_GLOBAL_DOM_PATTERN, WORKSPACE_BLOCK_PROPS_PATTERN;
238553
238821
  var init_cli_doctor_workspace = __esm(() => {
238554
- init_cli_add_shared();
238555
- init_hooked_blocks();
238822
+ init_cli_doctor_workspace_bindings();
238823
+ init_cli_doctor_workspace_blocks();
238824
+ init_cli_doctor_workspace_features();
238825
+ init_cli_doctor_workspace_package();
238826
+ init_cli_doctor_workspace_shared();
238556
238827
  init_workspace_inventory();
238557
238828
  init_workspace_project();
238558
- WORKSPACE_COLLECTION_IMPORT_PATTERN = /^\s*import\s+["']\.\.\/\.\.\/collection["']\s*;?\s*$/m;
238559
- WORKSPACE_GENERATED_BLOCK_ARTIFACTS = [
238560
- "block.json",
238561
- "typia.manifest.json",
238562
- "typia.schema.json",
238563
- "typia-validator.php",
238564
- "typia.openapi.json"
238565
- ];
238566
- WORKSPACE_FULL_BLOCK_NAME_PATTERN = /^[a-z0-9-]+\/[a-z0-9-]+$/u;
238567
- WORKSPACE_VARIATIONS_IMPORT_PATTERN = /^\s*import\s*\{\s*registerWorkspaceVariations\s*\}\s*from\s*["']\.\/variations["']\s*;?\s*$/mu;
238568
- WORKSPACE_VARIATIONS_CALL_PATTERN = /registerWorkspaceVariations\s*\(\s*\)\s*;?/u;
238569
- WORKSPACE_BLOCK_STYLES_IMPORT_PATTERN = /^\s*import\s*\{\s*registerWorkspaceBlockStyles\s*\}\s*from\s*["']\.\/styles["']\s*;?\s*$/mu;
238570
- WORKSPACE_BLOCK_STYLES_CALL_PATTERN = /registerWorkspaceBlockStyles\s*\(\s*\)\s*;?/u;
238571
- WORKSPACE_BLOCK_TRANSFORMS_IMPORT_PATTERN = /^\s*import\s*\{\s*applyWorkspaceBlockTransforms\s*\}\s*from\s*["']\.\/transforms["']\s*;?\s*$/mu;
238572
- WORKSPACE_BLOCK_TRANSFORMS_CALL_PATTERN = /applyWorkspaceBlockTransforms\s*\(\s*registration\s*\.\s*settings\s*\)\s*;?/u;
238573
- WORKSPACE_BLOCK_IFRAME_DIAGNOSTIC_CODES = {
238574
- API_VERSION: "wp-typia.workspace.block.iframe.api-version",
238575
- BLOCK_PROPS: "wp-typia.workspace.block.iframe.block-props",
238576
- EDITOR_GLOBALS: "wp-typia.workspace.block.iframe.editor-globals",
238577
- EDITOR_STYLES: "wp-typia.workspace.block.iframe.editor-styles"
238578
- };
238579
- WORKSPACE_BLOCK_EDITOR_SOURCE_FILE_PATTERN = /\.[cm]?[jt]sx?$/u;
238580
- WORKSPACE_BLOCK_EDITOR_SOURCE_BASENAMES = new Set([
238581
- "edit",
238582
- "editor",
238583
- "index",
238584
- "save"
238585
- ]);
238586
- WORKSPACE_BLOCK_EDITOR_SOURCE_DIRECTORIES = new Set([
238587
- "components",
238588
- "controls",
238589
- "editor",
238590
- "inspector"
238591
- ]);
238592
- WORKSPACE_BLOCK_LOCAL_STYLE_FILES = [
238593
- "editor.css",
238594
- "editor.scss",
238595
- "index.css",
238596
- "style.css",
238597
- "style.scss"
238598
- ];
238599
- WORKSPACE_BLOCK_IFRAME_GLOBAL_DOM_PATTERN = /\b(?:document|window)\b|\b(?:parent|top)\b(?!\s*:)/gu;
238600
- WORKSPACE_BLOCK_PROPS_PATTERN = /\buse(?:Block|InnerBlocks)Props(?:\.save)?\s*\(/u;
238601
238829
  });
238602
238830
 
238603
238831
  // ../wp-typia-project-tools/src/runtime/cli-doctor.ts
@@ -238646,19 +238874,19 @@ __export(exports_cli_init, {
238646
238874
  getInitPlan: () => getInitPlan,
238647
238875
  applyInitPlan: () => applyInitPlan
238648
238876
  });
238649
- import fs48 from "fs";
238877
+ import fs52 from "fs";
238650
238878
  import { promises as fsp25 } from "fs";
238651
- import path64 from "path";
238879
+ import path68 from "path";
238652
238880
  import { analyzeSourceTypes } from "@wp-typia/block-runtime/metadata-parser";
238653
238881
  function normalizeRelativePath2(value2) {
238654
238882
  return value2.replace(/\\/gu, "/");
238655
238883
  }
238656
238884
  function readProjectPackageJson(projectDir) {
238657
- const packageJsonPath = path64.join(projectDir, "package.json");
238658
- if (!fs48.existsSync(packageJsonPath)) {
238885
+ const packageJsonPath = path68.join(projectDir, "package.json");
238886
+ if (!fs52.existsSync(packageJsonPath)) {
238659
238887
  return null;
238660
238888
  }
238661
- const source = fs48.readFileSync(packageJsonPath, "utf8");
238889
+ const source = fs52.readFileSync(packageJsonPath, "utf8");
238662
238890
  try {
238663
238891
  return JSON.parse(source);
238664
238892
  } catch (error48) {
@@ -238670,13 +238898,13 @@ function inferInitPackageManager(projectDir, packageJson) {
238670
238898
  if (packageJson?.packageManager) {
238671
238899
  return parseWorkspacePackageManagerId(packageJson.packageManager);
238672
238900
  }
238673
- if (fs48.existsSync(path64.join(projectDir, "bun.lock")) || fs48.existsSync(path64.join(projectDir, "bun.lockb"))) {
238901
+ if (fs52.existsSync(path68.join(projectDir, "bun.lock")) || fs52.existsSync(path68.join(projectDir, "bun.lockb"))) {
238674
238902
  return "bun";
238675
238903
  }
238676
- if (fs48.existsSync(path64.join(projectDir, "pnpm-lock.yaml"))) {
238904
+ if (fs52.existsSync(path68.join(projectDir, "pnpm-lock.yaml"))) {
238677
238905
  return "pnpm";
238678
238906
  }
238679
- if (fs48.existsSync(path64.join(projectDir, "yarn.lock")) || fs48.existsSync(path64.join(projectDir, ".yarnrc.yml"))) {
238907
+ if (fs52.existsSync(path68.join(projectDir, "yarn.lock")) || fs52.existsSync(path68.join(projectDir, ".yarnrc.yml"))) {
238680
238908
  return "yarn";
238681
238909
  }
238682
238910
  return "npm";
@@ -238760,13 +238988,13 @@ function buildPackageManagerFieldChange(packageJson, packageManager, options = {
238760
238988
  };
238761
238989
  }
238762
238990
  function buildGeneratedArtifactPaths(blockJsonFile, manifestFile) {
238763
- const manifestDir = path64.dirname(manifestFile);
238991
+ const manifestDir = path68.dirname(manifestFile);
238764
238992
  const artifactPaths = [
238765
238993
  blockJsonFile,
238766
238994
  manifestFile,
238767
- path64.join(manifestDir, "typia.schema.json"),
238768
- path64.join(manifestDir, "typia-validator.php"),
238769
- path64.join(manifestDir, "typia.openapi.json")
238995
+ path68.join(manifestDir, "typia.schema.json"),
238996
+ path68.join(manifestDir, "typia-validator.php"),
238997
+ path68.join(manifestDir, "typia.openapi.json")
238770
238998
  ];
238771
238999
  return Array.from(new Set(artifactPaths.map((filePath) => normalizeRelativePath2(filePath))));
238772
239000
  }
@@ -238787,8 +239015,8 @@ function isObjectLikeSourceType(projectDir, typesFile, sourceTypeName) {
238787
239015
  return analyzedTypes[sourceTypeName]?.kind === "object";
238788
239016
  }
238789
239017
  function inferRetrofitAttributeTypeName(projectDir, block) {
238790
- const typesPath = path64.join(projectDir, block.typesFile);
238791
- const typesSource = fs48.readFileSync(typesPath, "utf8");
239018
+ const typesPath = path68.join(projectDir, block.typesFile);
239019
+ const typesSource = fs52.readFileSync(typesPath, "utf8");
238792
239020
  const blockNameSegments = block.blockName.split("/");
238793
239021
  const slug = blockNameSegments[blockNameSegments.length - 1] ?? block.key;
238794
239022
  const candidateNames = collectNamedSourceTypeCandidates(typesSource);
@@ -239093,10 +239321,10 @@ function hasExistingWpTypiaProjectSurface(projectDir, packageJson) {
239093
239321
  const scripts = packageJson?.scripts ?? {};
239094
239322
  const hasSyncSurface = typeof scripts.sync === "string" || typeof scripts["sync-types"] === "string";
239095
239323
  const hasHelperFiles = [
239096
- path64.join("scripts", "block-config.ts"),
239097
- path64.join("scripts", "sync-project.ts"),
239098
- path64.join("scripts", "sync-types-to-block-json.ts")
239099
- ].every((relativePath) => fs48.existsSync(path64.join(projectDir, relativePath)));
239324
+ path68.join("scripts", "block-config.ts"),
239325
+ path68.join("scripts", "sync-project.ts"),
239326
+ path68.join("scripts", "sync-types-to-block-json.ts")
239327
+ ].every((relativePath) => fs52.existsSync(path68.join(projectDir, relativePath)));
239100
239328
  const hasRuntimeDeps = typeof getExistingDependencyVersion(packageJson, "@wp-typia/block-runtime") === "string" && typeof getExistingDependencyVersion(packageJson, "@wp-typia/block-types") === "string";
239101
239329
  return hasSyncSurface && hasHelperFiles && hasRuntimeDeps;
239102
239330
  }
@@ -239106,17 +239334,17 @@ function buildPlannedFiles(projectDir, layoutKind) {
239106
239334
  }
239107
239335
  return [
239108
239336
  {
239109
- action: fs48.existsSync(path64.join(projectDir, "scripts", "block-config.ts")) ? "update" : "add",
239337
+ action: fs52.existsSync(path68.join(projectDir, "scripts", "block-config.ts")) ? "update" : "add",
239110
239338
  path: "scripts/block-config.ts",
239111
239339
  purpose: "Declare the current retrofit block targets so sync-types can regenerate metadata from the existing TypeScript source of truth."
239112
239340
  },
239113
239341
  {
239114
- action: fs48.existsSync(path64.join(projectDir, "scripts", "sync-types-to-block-json.ts")) ? "update" : "add",
239342
+ action: fs52.existsSync(path68.join(projectDir, "scripts", "sync-types-to-block-json.ts")) ? "update" : "add",
239115
239343
  path: "scripts/sync-types-to-block-json.ts",
239116
239344
  purpose: "Generate block.json and Typia metadata artifacts from the current TypeScript source of truth."
239117
239345
  },
239118
239346
  {
239119
- action: fs48.existsSync(path64.join(projectDir, "scripts", "sync-project.ts")) ? "update" : "add",
239347
+ action: fs52.existsSync(path68.join(projectDir, "scripts", "sync-project.ts")) ? "update" : "add",
239120
239348
  path: "scripts/sync-project.ts",
239121
239349
  purpose: "Provide one shared sync entrypoint that can grow into sync-rest or workspace-aware refresh steps later."
239122
239350
  }
@@ -239264,14 +239492,14 @@ function buildProjectPackageJsonSource(packageJson) {
239264
239492
  }
239265
239493
  function buildRetrofitHelperFiles(blockTargets) {
239266
239494
  return {
239267
- [path64.join("scripts", "block-config.ts")]: buildRetrofitBlockConfigSource(blockTargets),
239268
- [path64.join("scripts", "sync-project.ts")]: buildRetrofitSyncProjectScriptSource(),
239269
- [path64.join("scripts", "sync-types-to-block-json.ts")]: buildRetrofitSyncTypesScriptSource()
239495
+ [path68.join("scripts", "block-config.ts")]: buildRetrofitBlockConfigSource(blockTargets),
239496
+ [path68.join("scripts", "sync-project.ts")]: buildRetrofitSyncProjectScriptSource(),
239497
+ [path68.join("scripts", "sync-types-to-block-json.ts")]: buildRetrofitSyncTypesScriptSource()
239270
239498
  };
239271
239499
  }
239272
239500
  async function createRetrofitMutationSnapshot(projectDir, filePaths) {
239273
- const scriptsDir = path64.join(projectDir, "scripts");
239274
- const scriptsDirExisted = fs48.existsSync(scriptsDir);
239501
+ const scriptsDir = path68.join(projectDir, "scripts");
239502
+ const scriptsDirExisted = fs52.existsSync(scriptsDir);
239275
239503
  const fileSources = await snapshotWorkspaceFiles(filePaths);
239276
239504
  const targetPaths = fileSources.filter((entry) => entry.source === null).map((entry) => entry.filePath);
239277
239505
  if (!scriptsDirExisted) {
@@ -239285,11 +239513,11 @@ async function createRetrofitMutationSnapshot(projectDir, filePaths) {
239285
239513
  }
239286
239514
  async function writeRetrofitFiles(options) {
239287
239515
  const helperFiles = buildRetrofitHelperFiles(options.blockTargets);
239288
- const scriptsDir = path64.join(options.projectDir, "scripts");
239516
+ const scriptsDir = path68.join(options.projectDir, "scripts");
239289
239517
  await fsp25.mkdir(scriptsDir, { recursive: true });
239290
- await fsp25.writeFile(path64.join(options.projectDir, "package.json"), buildProjectPackageJsonSource(options.packageJson), "utf8");
239518
+ await fsp25.writeFile(path68.join(options.projectDir, "package.json"), buildProjectPackageJsonSource(options.packageJson), "utf8");
239291
239519
  for (const [relativePath, source] of Object.entries(helperFiles)) {
239292
- await fsp25.writeFile(path64.join(options.projectDir, relativePath), source, "utf8");
239520
+ await fsp25.writeFile(path68.join(options.projectDir, relativePath), source, "utf8");
239293
239521
  }
239294
239522
  }
239295
239523
  function buildApplyFailureError(error48) {
@@ -239297,7 +239525,7 @@ function buildApplyFailureError(error48) {
239297
239525
  return createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.INVALID_ARGUMENT, `Unable to apply the retrofit init plan safely. The command restored the previous package.json/helper-file snapshot. ${message}`, error48 instanceof Error ? { cause: error48 } : undefined);
239298
239526
  }
239299
239527
  function getInitPlan(projectDir, options = {}) {
239300
- const resolvedProjectDir = path64.resolve(projectDir);
239528
+ const resolvedProjectDir = path68.resolve(projectDir);
239301
239529
  const packageJson = readProjectPackageJson(resolvedProjectDir);
239302
239530
  const packageManager = resolveInitPackageManager(resolvedProjectDir, packageJson, options.packageManager);
239303
239531
  const workspace = tryResolveWorkspaceProject(resolvedProjectDir);
@@ -239333,7 +239561,7 @@ function getInitPlan(projectDir, options = {}) {
239333
239561
  status: "already-initialized"
239334
239562
  });
239335
239563
  }
239336
- const projectName = typeof packageJson?.name === "string" && packageJson.name.length > 0 ? packageJson.name : path64.basename(resolvedProjectDir);
239564
+ const projectName = typeof packageJson?.name === "string" && packageJson.name.length > 0 ? packageJson.name : path68.basename(resolvedProjectDir);
239337
239565
  const layout = buildLayoutDetails(resolvedProjectDir);
239338
239566
  const dependencyChanges = buildDependencyChanges(packageJson);
239339
239567
  const scriptChanges = buildScriptChanges(packageJson, packageManager);
@@ -239399,8 +239627,8 @@ async function applyInitPlan(projectDir, options = {}) {
239399
239627
  });
239400
239628
  const helperFiles = buildRetrofitHelperFiles(previewPlan.blockTargets);
239401
239629
  const filePaths = [
239402
- path64.join(previewPlan.projectDir, "package.json"),
239403
- ...Object.keys(helperFiles).map((relativePath) => path64.join(previewPlan.projectDir, relativePath))
239630
+ path68.join(previewPlan.projectDir, "package.json"),
239631
+ ...Object.keys(helperFiles).map((relativePath) => path68.join(previewPlan.projectDir, relativePath))
239404
239632
  ];
239405
239633
  const mutationSnapshot = await createRetrofitMutationSnapshot(previewPlan.projectDir, filePaths);
239406
239634
  try {
@@ -239462,27 +239690,27 @@ __export(exports_cli_scaffold, {
239462
239690
  getOptionalOnboarding: () => getOptionalOnboarding,
239463
239691
  getNextSteps: () => getNextSteps
239464
239692
  });
239465
- import fs49 from "fs";
239693
+ import fs53 from "fs";
239466
239694
  import { promises as fsp26 } from "fs";
239467
- import path65 from "path";
239695
+ import path69 from "path";
239468
239696
  async function listRelativeProjectFiles(rootDir) {
239469
239697
  const relativeFiles = [];
239470
239698
  async function visit2(currentDir) {
239471
239699
  const entries = await fsp26.readdir(currentDir, { withFileTypes: true });
239472
239700
  for (const entry of entries) {
239473
- const absolutePath = path65.join(currentDir, entry.name);
239701
+ const absolutePath = path69.join(currentDir, entry.name);
239474
239702
  if (entry.isDirectory()) {
239475
239703
  await visit2(absolutePath);
239476
239704
  continue;
239477
239705
  }
239478
- relativeFiles.push(path65.relative(rootDir, absolutePath).replace(path65.sep === "\\" ? /\\/gu : /\//gu, "/"));
239706
+ relativeFiles.push(path69.relative(rootDir, absolutePath).replace(path69.sep === "\\" ? /\\/gu : /\//gu, "/"));
239479
239707
  }
239480
239708
  }
239481
239709
  await visit2(rootDir);
239482
239710
  return relativeFiles.sort((left, right) => left.localeCompare(right));
239483
239711
  }
239484
239712
  async function assertDryRunTargetDirectoryReady(projectDir, allowExistingDir) {
239485
- if (!fs49.existsSync(projectDir) || allowExistingDir) {
239713
+ if (!fs53.existsSync(projectDir) || allowExistingDir) {
239486
239714
  return;
239487
239715
  }
239488
239716
  const entries = await fsp26.readdir(projectDir);
@@ -239513,7 +239741,7 @@ async function buildScaffoldDryRunPlan({
239513
239741
  }) {
239514
239742
  await assertDryRunTargetDirectoryReady(projectDir, allowExistingDir);
239515
239743
  const { path: tempRoot, cleanup } = await createManagedTempRoot("wp-typia-scaffold-plan-");
239516
- const previewProjectDir = path65.join(tempRoot, "preview-project");
239744
+ const previewProjectDir = path69.join(tempRoot, "preview-project");
239517
239745
  try {
239518
239746
  const result = await scaffoldProject({
239519
239747
  allowExistingDir: false,
@@ -239553,14 +239781,14 @@ function validateCreateProjectInput(projectInput) {
239553
239781
  if (normalizedProjectInput.length === 0) {
239554
239782
  throw new Error("Project directory is required. Usage: wp-typia create <project-dir> (or wp-typia <project-dir> when <project-dir> is the only positional argument).");
239555
239783
  }
239556
- const normalizedProjectPath = path65.normalize(normalizedProjectInput).replace(/[\\/]+$/u, "") || path65.normalize(normalizedProjectInput);
239784
+ const normalizedProjectPath = path69.normalize(normalizedProjectInput).replace(/[\\/]+$/u, "") || path69.normalize(normalizedProjectInput);
239557
239785
  if (normalizedProjectPath === "." || normalizedProjectPath === "..") {
239558
239786
  throw new Error("`wp-typia create` requires a new project directory. Use an explicit child directory instead of `.` or `..`.");
239559
239787
  }
239560
239788
  }
239561
239789
  function collectProjectDirectoryWarnings(projectDir) {
239562
239790
  const warnings = [];
239563
- const projectName = path65.basename(projectDir);
239791
+ const projectName = path69.basename(projectDir);
239564
239792
  if (/\s/u.test(projectName)) {
239565
239793
  warnings.push(`Project directory "${projectName}" contains spaces. The generated next-step commands will be quoted, but a simple kebab-case directory name is usually easier to use with shells and downstream tooling.`);
239566
239794
  }
@@ -239715,7 +239943,7 @@ function getNextSteps({
239715
239943
  noInstall,
239716
239944
  templateId
239717
239945
  }) {
239718
- const cdTarget = path65.isAbsolute(projectInput) ? projectDir : projectInput;
239946
+ const cdTarget = path69.isAbsolute(projectInput) ? projectDir : projectInput;
239719
239947
  const steps = [`cd ${quoteShellValue(cdTarget)}`];
239720
239948
  if (noInstall) {
239721
239949
  steps.push(formatInstallCommand(packageManager));
@@ -239863,8 +240091,8 @@ async function runScaffoldFlow({
239863
240091
  select: selectWithMigrationUi,
239864
240092
  yes
239865
240093
  });
239866
- const projectDir = path65.resolve(cwd, projectInput);
239867
- const projectName = path65.basename(projectDir);
240094
+ const projectDir = path69.resolve(cwd, projectInput);
240095
+ const projectName = path69.basename(projectDir);
239868
240096
  const answers = await collectScaffoldAnswers({
239869
240097
  dataStorageMode: resolvedDataStorage,
239870
240098
  namespace,
@@ -239927,7 +240155,7 @@ async function runScaffoldFlow({
239927
240155
  let availableScripts;
239928
240156
  if (!dryRun) {
239929
240157
  try {
239930
- const parsedPackageJson = JSON.parse(fs49.readFileSync(path65.join(projectDir, "package.json"), "utf8"));
240158
+ const parsedPackageJson = JSON.parse(fs53.readFileSync(path69.join(projectDir, "package.json"), "utf8"));
239931
240159
  const scripts = parsedPackageJson.scripts && typeof parsedPackageJson.scripts === "object" && !Array.isArray(parsedPackageJson.scripts) ? parsedPackageJson.scripts : {};
239932
240160
  availableScripts = Object.entries(scripts).filter(([, value2]) => typeof value2 === "string").map(([scriptName]) => scriptName);
239933
240161
  } catch {
@@ -293050,6 +293278,63 @@ var ADD_KIND_IDS = [
293050
293278
  "editor-plugin"
293051
293279
  ];
293052
293280
 
293281
+ // src/cli-string-flags.ts
293282
+ init_cli_diagnostics();
293283
+ function readOptionalCliStringFlagValue(flags2, name2, mode) {
293284
+ const value2 = flags2[name2];
293285
+ if (value2 === undefined || value2 === null) {
293286
+ return;
293287
+ }
293288
+ if (typeof value2 !== "string") {
293289
+ throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, `\`--${name2}\` requires a value.`);
293290
+ }
293291
+ const trimmed = value2.trim();
293292
+ if (trimmed.length === 0) {
293293
+ if (mode === "strict") {
293294
+ throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, `\`--${name2}\` requires a value.`);
293295
+ }
293296
+ return;
293297
+ }
293298
+ return mode === "strict" ? value2 : trimmed;
293299
+ }
293300
+ function readOptionalLooseStringFlag(flags2, name2) {
293301
+ return readOptionalCliStringFlagValue(flags2, name2, "loose");
293302
+ }
293303
+ function readOptionalStrictStringFlag(flags2, name2) {
293304
+ return readOptionalCliStringFlagValue(flags2, name2, "strict");
293305
+ }
293306
+ function requireStrictStringFlag(flags2, name2, message) {
293307
+ const value2 = readOptionalStrictStringFlag(flags2, name2);
293308
+ if (!value2) {
293309
+ throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, message);
293310
+ }
293311
+ return value2;
293312
+ }
293313
+ function readOptionalPairedStrictStringFlags(flags2, leftName, rightName, message) {
293314
+ const leftValue = readOptionalStrictStringFlag(flags2, leftName);
293315
+ const rightValue = readOptionalStrictStringFlag(flags2, rightName);
293316
+ if (Boolean(leftValue) !== Boolean(rightValue)) {
293317
+ throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, message);
293318
+ }
293319
+ return [leftValue, rightValue];
293320
+ }
293321
+
293322
+ // src/external-layer-prompt-options.ts
293323
+ function formatExternalLayerSelectHint(option3) {
293324
+ const details = [
293325
+ option3.description,
293326
+ option3.extends.length > 0 ? `extends ${option3.extends.join(", ")}` : undefined
293327
+ ].filter((value2) => typeof value2 === "string" && value2.length > 0);
293328
+ return details.length > 0 ? details.join(" \xB7 ") : undefined;
293329
+ }
293330
+ function toExternalLayerPromptOptions(options) {
293331
+ return options.map((option3) => ({
293332
+ hint: formatExternalLayerSelectHint(option3),
293333
+ label: option3.id,
293334
+ value: option3.id
293335
+ }));
293336
+ }
293337
+
293053
293338
  // src/add-kind-registry.ts
293054
293339
  var BLOCK_VISIBLE_FIELD_ORDER = [
293055
293340
  "kind",
@@ -293108,51 +293393,12 @@ var NAME_NAMESPACE_VISIBLE_FIELDS = [
293108
293393
  "name",
293109
293394
  "namespace"
293110
293395
  ];
293111
- function readOptionalStringFlag(flags2, name2) {
293112
- const value2 = flags2[name2];
293113
- if (value2 === undefined || value2 === null) {
293114
- return;
293115
- }
293116
- if (typeof value2 !== "string" || value2.trim().length === 0) {
293117
- throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, `\`--${name2}\` requires a value.`);
293118
- }
293119
- return value2;
293120
- }
293121
- function requireStringFlag(flags2, name2, message) {
293122
- const value2 = readOptionalStringFlag(flags2, name2);
293123
- if (!value2) {
293124
- throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, message);
293125
- }
293126
- return value2;
293127
- }
293128
- function readOptionalPairedStringFlags(flags2, leftName, rightName, message) {
293129
- const leftValue = readOptionalStringFlag(flags2, leftName);
293130
- const rightValue = readOptionalStringFlag(flags2, rightName);
293131
- if (Boolean(leftValue) !== Boolean(rightValue)) {
293132
- throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, message);
293133
- }
293134
- return [leftValue, rightValue];
293135
- }
293136
293396
  function requireAddKindName(context, message) {
293137
293397
  if (!context.name) {
293138
293398
  throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, message);
293139
293399
  }
293140
293400
  return context.name;
293141
293401
  }
293142
- function formatExternalLayerSelectHint(option3) {
293143
- const details = [
293144
- option3.description,
293145
- option3.extends.length > 0 ? `extends ${option3.extends.join(", ")}` : undefined
293146
- ].filter((value2) => typeof value2 === "string" && value2.length > 0);
293147
- return details.length > 0 ? details.join(" \xB7 ") : undefined;
293148
- }
293149
- function toExternalLayerPromptOptions(options) {
293150
- return options.map((option3) => ({
293151
- hint: formatExternalLayerSelectHint(option3),
293152
- label: option3.id,
293153
- value: option3.id
293154
- }));
293155
- }
293156
293402
  function defineAddKindRegistryEntry(entry) {
293157
293403
  return entry;
293158
293404
  }
@@ -293186,7 +293432,7 @@ var ADD_KIND_REGISTRY = {
293186
293432
  nameLabel: "Admin view name",
293187
293433
  async prepareExecution(context) {
293188
293434
  const name2 = requireAddKindName(context, "`wp-typia add admin-view` requires <name>. Usage: wp-typia add admin-view <name> [--source <rest-resource:slug|core-data:kind/name>].");
293189
- const source = readOptionalStringFlag(context.flags, "source");
293435
+ const source = readOptionalStrictStringFlag(context.flags, "source");
293190
293436
  return createNamedExecutionPlan(context, {
293191
293437
  execute: ({ cwd, name: name3 }) => context.addRuntime.runAddAdminViewCommand({
293192
293438
  adminViewName: name3,
@@ -293226,7 +293472,7 @@ var ADD_KIND_REGISTRY = {
293226
293472
  nameLabel: "Binding source name",
293227
293473
  async prepareExecution(context) {
293228
293474
  const name2 = requireAddKindName(context, "`wp-typia add binding-source` requires <name>. Usage: wp-typia add binding-source <name> [--block <block-slug|namespace/block-slug> --attribute <attribute>].");
293229
- const [blockName, attributeName] = readOptionalPairedStringFlags(context.flags, "block", "attribute", "`wp-typia add binding-source` requires --block and --attribute to be provided together.");
293475
+ const [blockName, attributeName] = readOptionalPairedStrictStringFlags(context.flags, "block", "attribute", "`wp-typia add binding-source` requires --block and --attribute to be provided together.");
293230
293476
  return createNamedExecutionPlan(context, {
293231
293477
  execute: ({ cwd, name: name3 }) => context.addRuntime.runAddBindingSourceCommand({
293232
293478
  attributeName,
@@ -293266,15 +293512,15 @@ var ADD_KIND_REGISTRY = {
293266
293512
  nameLabel: "Block name",
293267
293513
  async prepareExecution(context) {
293268
293514
  const name2 = requireAddKindName(context, "`wp-typia add block` requires <name>. Usage: wp-typia add block <name> [--template <basic|interactivity|persistence|compound>]");
293269
- const externalLayerId = readOptionalStringFlag(context.flags, "external-layer-id");
293270
- const externalLayerSource = readOptionalStringFlag(context.flags, "external-layer-source");
293515
+ const externalLayerId = readOptionalStrictStringFlag(context.flags, "external-layer-id");
293516
+ const externalLayerSource = readOptionalStrictStringFlag(context.flags, "external-layer-source");
293271
293517
  const shouldPromptForLayerSelection = Boolean(externalLayerSource) && !Boolean(externalLayerId) && context.isInteractiveSession;
293272
293518
  const selectPrompt = shouldPromptForLayerSelection ? await context.getOrCreatePrompt() : undefined;
293273
- const alternateRenderTargets = readOptionalStringFlag(context.flags, "alternate-render-targets");
293274
- const dataStorageMode = readOptionalStringFlag(context.flags, "data-storage");
293275
- const innerBlocksPreset = readOptionalStringFlag(context.flags, "inner-blocks-preset");
293276
- const persistencePolicy = readOptionalStringFlag(context.flags, "persistence-policy");
293277
- let resolvedTemplateId = readOptionalStringFlag(context.flags, "template");
293519
+ const alternateRenderTargets = readOptionalStrictStringFlag(context.flags, "alternate-render-targets");
293520
+ const dataStorageMode = readOptionalStrictStringFlag(context.flags, "data-storage");
293521
+ const innerBlocksPreset = readOptionalStrictStringFlag(context.flags, "inner-blocks-preset");
293522
+ const persistencePolicy = readOptionalStrictStringFlag(context.flags, "persistence-policy");
293523
+ let resolvedTemplateId = readOptionalStrictStringFlag(context.flags, "template");
293278
293524
  if (!resolvedTemplateId && context.isInteractiveSession) {
293279
293525
  const templatePrompt = await context.getOrCreatePrompt();
293280
293526
  resolvedTemplateId = await templatePrompt.select("Select a block template", context.addRuntime.ADD_BLOCK_TEMPLATE_IDS.map((templateId) => ({
@@ -293371,7 +293617,7 @@ var ADD_KIND_REGISTRY = {
293371
293617
  nameLabel: "Editor plugin name",
293372
293618
  async prepareExecution(context) {
293373
293619
  const name2 = requireAddKindName(context, "`wp-typia add editor-plugin` requires <name>. Usage: wp-typia add editor-plugin <name> [--slot <sidebar|document-setting-panel>].");
293374
- const slot = readOptionalStringFlag(context.flags, "slot");
293620
+ const slot = readOptionalStrictStringFlag(context.flags, "slot");
293375
293621
  return createNamedExecutionPlan(context, {
293376
293622
  execute: ({ cwd, name: name3 }) => context.addRuntime.runAddEditorPluginCommand({
293377
293623
  cwd,
@@ -293409,8 +293655,8 @@ var ADD_KIND_REGISTRY = {
293409
293655
  nameLabel: "Target block",
293410
293656
  async prepareExecution(context) {
293411
293657
  const name2 = requireAddKindName(context, "`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>.");
293412
- const anchorBlockName = requireStringFlag(context.flags, "anchor", "`wp-typia add hooked-block` requires --anchor <anchor-block-name>.");
293413
- const position = requireStringFlag(context.flags, "position", "`wp-typia add hooked-block` requires --position <before|after|firstChild|lastChild>.");
293658
+ const anchorBlockName = requireStrictStringFlag(context.flags, "anchor", "`wp-typia add hooked-block` requires --anchor <anchor-block-name>.");
293659
+ const position = requireStrictStringFlag(context.flags, "position", "`wp-typia add hooked-block` requires --position <before|after|firstChild|lastChild>.");
293414
293660
  return createNamedExecutionPlan(context, {
293415
293661
  execute: ({ cwd, name: name3 }) => context.addRuntime.runAddHookedBlockCommand({
293416
293662
  anchorBlockName,
@@ -293480,7 +293726,7 @@ var ADD_KIND_REGISTRY = {
293480
293726
  nameLabel: "Style name",
293481
293727
  async prepareExecution(context) {
293482
293728
  const name2 = requireAddKindName(context, "`wp-typia add style` requires <name>. Usage: wp-typia add style <name> --block <block-slug>.");
293483
- const blockSlug = requireStringFlag(context.flags, "block", "`wp-typia add style` requires --block <block-slug>.");
293729
+ const blockSlug = requireStrictStringFlag(context.flags, "block", "`wp-typia add style` requires --block <block-slug>.");
293484
293730
  return createNamedExecutionPlan(context, {
293485
293731
  execute: ({ cwd, name: name3 }) => context.addRuntime.runAddBlockStyleCommand({
293486
293732
  blockName: blockSlug,
@@ -293518,8 +293764,8 @@ var ADD_KIND_REGISTRY = {
293518
293764
  nameLabel: "Transform name",
293519
293765
  async prepareExecution(context) {
293520
293766
  const name2 = requireAddKindName(context, "`wp-typia add transform` requires <name>. Usage: wp-typia add transform <name> --from <namespace/block> --to <block-slug|namespace/block-slug>.");
293521
- const fromBlockName = requireStringFlag(context.flags, "from", "`wp-typia add transform` requires --from <namespace/block>.");
293522
- const toBlockName = requireStringFlag(context.flags, "to", "`wp-typia add transform` requires --to <block-slug|namespace/block-slug>.");
293767
+ const fromBlockName = requireStrictStringFlag(context.flags, "from", "`wp-typia add transform` requires --from <namespace/block>.");
293768
+ const toBlockName = requireStrictStringFlag(context.flags, "to", "`wp-typia add transform` requires --to <block-slug|namespace/block-slug>.");
293523
293769
  return createNamedExecutionPlan(context, {
293524
293770
  execute: ({ cwd, name: name3 }) => context.addRuntime.runAddBlockTransformCommand({
293525
293771
  cwd,
@@ -293560,8 +293806,8 @@ var ADD_KIND_REGISTRY = {
293560
293806
  nameLabel: "REST resource name",
293561
293807
  async prepareExecution(context) {
293562
293808
  const name2 = requireAddKindName(context, "`wp-typia add rest-resource` requires <name>. Usage: wp-typia add rest-resource <name> [--namespace <vendor/v1>] [--methods <list,read,create>].");
293563
- const methods = readOptionalStringFlag(context.flags, "methods");
293564
- const namespace = readOptionalStringFlag(context.flags, "namespace");
293809
+ const methods = readOptionalStrictStringFlag(context.flags, "methods");
293810
+ const namespace = readOptionalStrictStringFlag(context.flags, "namespace");
293565
293811
  return createNamedExecutionPlan(context, {
293566
293812
  execute: ({ cwd, name: name3 }) => context.addRuntime.runAddRestResourceCommand({
293567
293813
  cwd,
@@ -293600,7 +293846,7 @@ var ADD_KIND_REGISTRY = {
293600
293846
  nameLabel: "AI feature name",
293601
293847
  async prepareExecution(context) {
293602
293848
  const name2 = requireAddKindName(context, "`wp-typia add ai-feature` requires <name>. Usage: wp-typia add ai-feature <name> [--namespace <vendor/v1>].");
293603
- const namespace = readOptionalStringFlag(context.flags, "namespace");
293849
+ const namespace = readOptionalStrictStringFlag(context.flags, "namespace");
293604
293850
  return createNamedExecutionPlan(context, {
293605
293851
  execute: ({ cwd, name: name3 }) => context.addRuntime.runAddAiFeatureCommand({
293606
293852
  aiFeatureName: name3,
@@ -293639,7 +293885,7 @@ var ADD_KIND_REGISTRY = {
293639
293885
  nameLabel: "Variation name",
293640
293886
  async prepareExecution(context) {
293641
293887
  const name2 = requireAddKindName(context, "`wp-typia add variation` requires <name>. Usage: wp-typia add variation <name> --block <block-slug>");
293642
- const blockSlug = requireStringFlag(context.flags, "block", "`wp-typia add variation` requires --block <block-slug>.");
293888
+ const blockSlug = requireStrictStringFlag(context.flags, "block", "`wp-typia add variation` requires --block <block-slug>.");
293643
293889
  return createNamedExecutionPlan(context, {
293644
293890
  execute: ({ cwd, name: name3 }) => context.addRuntime.runAddVariationCommand({
293645
293891
  blockName: blockSlug,
@@ -293817,7 +294063,7 @@ import path10 from "path";
293817
294063
  // package.json
293818
294064
  var package_default2 = {
293819
294065
  name: "wp-typia",
293820
- version: "0.22.2",
294066
+ version: "0.22.3",
293821
294067
  description: "Canonical CLI package for wp-typia scaffolding and project workflows",
293822
294068
  packageManager: "bun@1.3.11",
293823
294069
  type: "module",
@@ -293887,7 +294133,7 @@ var package_default2 = {
293887
294133
  "@bunli/tui": "0.6.0",
293888
294134
  "@bunli/utils": "0.6.0",
293889
294135
  "@wp-typia/api-client": "^0.4.5",
293890
- "@wp-typia/project-tools": "0.22.2",
294136
+ "@wp-typia/project-tools": "0.22.3",
293891
294137
  "better-result": "^2.7.0",
293892
294138
  react: "^19.2.5",
293893
294139
  "react-dom": "^19.2.5",
@@ -294242,20 +294488,6 @@ function printBlock(lines, printLine) {
294242
294488
  printLine(line);
294243
294489
  }
294244
294490
  }
294245
- function formatExternalLayerSelectHint2(option3) {
294246
- const details = [
294247
- option3.description,
294248
- option3.extends.length > 0 ? `extends ${option3.extends.join(", ")}` : undefined
294249
- ].filter((value2) => typeof value2 === "string" && value2.length > 0);
294250
- return details.length > 0 ? details.join(" \xB7 ") : undefined;
294251
- }
294252
- function toExternalLayerPromptOptions2(options) {
294253
- return options.map((option3) => ({
294254
- hint: formatExternalLayerSelectHint2(option3),
294255
- label: option3.id,
294256
- value: option3.id
294257
- }));
294258
- }
294259
294491
 
294260
294492
  // src/runtime-capabilities.ts
294261
294493
  function isInteractiveTerminal({
@@ -294539,17 +294771,6 @@ function shouldWrapCliCommandError(options) {
294539
294771
  }
294540
294772
  return true;
294541
294773
  }
294542
- function readOptionalLooseStringFlag(flags2, name2) {
294543
- const value2 = flags2[name2];
294544
- if (value2 === undefined || value2 === null) {
294545
- return;
294546
- }
294547
- if (typeof value2 !== "string") {
294548
- throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, `\`--${name2}\` requires a value.`);
294549
- }
294550
- const trimmed = value2.trim();
294551
- return trimmed.length > 0 ? trimmed : undefined;
294552
- }
294553
294774
  function pushFlag(argv, name2, value2) {
294554
294775
  if (value2 === undefined || value2 === null || value2 === false) {
294555
294776
  return;
@@ -294691,7 +294912,7 @@ async function executeCreateCommand({
294691
294912
  promptText: activePrompt ? (message, defaultValue, validate) => activePrompt.text(message, defaultValue, validate) : undefined,
294692
294913
  queryPostType: readOptionalLooseStringFlag(flags2, "query-post-type"),
294693
294914
  selectDataStorage: activePrompt ? () => activePrompt.select("Select a data storage mode", [...DATA_STORAGE_PROMPT_OPTIONS], 1) : undefined,
294694
- selectExternalLayerId: shouldPromptForExternalLayerSelection && activePrompt ? (options) => activePrompt.select("Select an external layer", toExternalLayerPromptOptions2(options), 1) : undefined,
294915
+ selectExternalLayerId: shouldPromptForExternalLayerSelection && activePrompt ? (options) => activePrompt.select("Select an external layer", toExternalLayerPromptOptions(options), 1) : undefined,
294695
294916
  selectPackageManager: activePrompt ? () => activePrompt.select("Select a package manager", [...PACKAGE_MANAGER_PROMPT_OPTIONS], 1) : undefined,
294696
294917
  selectPersistencePolicy: activePrompt ? () => activePrompt.select("Select a persistence policy", [...PERSISTENCE_POLICY_PROMPT_OPTIONS], 1) : undefined,
294697
294918
  selectTemplate: activePrompt ? () => activePrompt.select("Select a template", getTemplateSelectOptions2(), 1) : undefined,
@@ -295551,8 +295772,8 @@ var init_default = initCommand;
295551
295772
  init_cli_diagnostics();
295552
295773
 
295553
295774
  // src/mcp.ts
295554
- import fs50 from "fs/promises";
295555
- import path66 from "path";
295775
+ import fs54 from "fs/promises";
295776
+ import path70 from "path";
295556
295777
 
295557
295778
  // ../../node_modules/.bun/@bunli+plugin-mcp@0.2.5+ef72ce197b058209/node_modules/@bunli/plugin-mcp/src/errors.ts
295558
295779
  class SchemaConversionError extends TaggedError("SchemaConversionError")() {
@@ -296080,8 +296301,8 @@ function isToolGroup(value2) {
296080
296301
  return isObject3(value2) && typeof value2.namespace === "string" && Array.isArray(value2.tools) && value2.tools.every(isTool);
296081
296302
  }
296082
296303
  async function readSchemaSource(cwd, source) {
296083
- const schemaPath = path66.resolve(cwd, source.path);
296084
- const raw = await fs50.readFile(schemaPath, "utf8");
296304
+ const schemaPath = path70.resolve(cwd, source.path);
296305
+ const raw = await fs54.readFile(schemaPath, "utf8");
296085
296306
  const parsed = JSON.parse(raw);
296086
296307
  if (isToolGroup(parsed)) {
296087
296308
  return parsed;
@@ -296097,7 +296318,7 @@ async function readSchemaSource(cwd, source) {
296097
296318
  async function loadMcpToolGroups(cwd, schemaSources) {
296098
296319
  return Promise.all(schemaSources.map((source) => readSchemaSource(cwd, source)));
296099
296320
  }
296100
- async function syncMcpSchemas(cwd, schemaSources, outputDir = path66.join(cwd, ".bunli", "mcp")) {
296321
+ async function syncMcpSchemas(cwd, schemaSources, outputDir = path70.join(cwd, ".bunli", "mcp")) {
296101
296322
  const groups = await loadMcpToolGroups(cwd, schemaSources);
296102
296323
  const result = await generateMCPTypes({
296103
296324
  outputDir,
@@ -296119,8 +296340,8 @@ async function syncMcpSchemas(cwd, schemaSources, outputDir = path66.join(cwd, "
296119
296340
  throw convert.error;
296120
296341
  }
296121
296342
  }
296122
- await fs50.mkdir(outputDir, { recursive: true });
296123
- await fs50.writeFile(path66.join(outputDir, "registry.json"), `${JSON.stringify(registry2, null, 2)}
296343
+ await fs54.mkdir(outputDir, { recursive: true });
296344
+ await fs54.writeFile(path70.join(outputDir, "registry.json"), `${JSON.stringify(registry2, null, 2)}
296124
296345
  `, "utf8");
296125
296346
  return {
296126
296347
  commandCount: registry2.reduce((count, group) => count + group.tools.length, 0),
@@ -296439,4 +296660,4 @@ export {
296439
296660
  cli
296440
296661
  };
296441
296662
 
296442
- //# debugId=95E6742032974D4764756E2164756E21
296663
+ //# debugId=EB85DB51484D012864756E2164756E21