wp-typia 0.20.3 → 0.20.5

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.
@@ -11,6 +11,7 @@ import {
11
11
  parseCompoundInnerBlocksPreset,
12
12
  parseTemplateLocator,
13
13
  renderScaffoldCompatibilityConfig,
14
+ require_semver,
14
15
  resolveExternalTemplateLayers,
15
16
  resolveLocalCliPathOption,
16
17
  resolveOptionalInteractiveExternalLayerId,
@@ -19,7 +20,7 @@ import {
19
20
  scaffoldProject,
20
21
  syncPersistenceRestArtifacts,
21
22
  updatePluginHeaderCompatibility
22
- } from "./cli-8rnhjvb8.js";
23
+ } from "./cli-j1tyw390.js";
23
24
  import {
24
25
  getPackageVersions
25
26
  } from "./cli-tesygdnr.js";
@@ -84,7 +85,8 @@ import {
84
85
  resolveWorkspaceProject
85
86
  } from "./cli-pd5pqgre.js";
86
87
  import {
87
- __reExport
88
+ __reExport,
89
+ __toESM
88
90
  } from "./cli-xnn9xjcy.js";
89
91
  // ../wp-typia-project-tools/src/runtime/cli-add-block.ts
90
92
  import fs2 from "fs";
@@ -639,7 +641,7 @@ async function runAddBlockCommand({
639
641
  throw new Error("`wp-typia add block --template query-loop` is not supported. Query Loop is a create-time `core/query` variation scaffold, so use `wp-typia create <project-dir> --template query-loop` instead.");
640
642
  }
641
643
  if (!isAddBlockTemplateId(templateId)) {
642
- throw new Error(`Unknown add-block template "${templateId}". Expected one of: ${ADD_BLOCK_TEMPLATE_IDS.join(", ")}`);
644
+ throw new Error(`Unknown add-block template "${templateId}". Expected one of: ${ADD_BLOCK_TEMPLATE_IDS.join(", ")}. Run \`wp-typia templates list\` to inspect available templates.`);
643
645
  }
644
646
  const resolvedTemplateId = templateId;
645
647
  assertPersistenceFlagsAllowed(resolvedTemplateId, {
@@ -2758,7 +2760,6 @@ async function runAddRestResourceCommand({
2758
2760
  const validatorsFilePath = path7.join(restResourceDir, "api-validators.ts");
2759
2761
  const apiFilePath = path7.join(restResourceDir, "api.ts");
2760
2762
  const dataFilePath = path7.join(restResourceDir, "data.ts");
2761
- const clientFilePath = path7.join(restResourceDir, "api-client.ts");
2762
2763
  const phpFilePath = path7.join(workspace.projectDir, "inc", "rest", `${restResourceSlug}.php`);
2763
2764
  const mutationSnapshot = {
2764
2765
  fileSources: await snapshotWorkspaceFiles([
@@ -2811,6 +2812,7 @@ async function runAddRestResourceCommand({
2811
2812
  }
2812
2813
  }
2813
2814
  // ../wp-typia-project-tools/src/runtime/cli-add-workspace-ability.ts
2815
+ var import_semver = __toESM(require_semver(), 1);
2814
2816
  import fs4 from "fs";
2815
2817
  import { promises as fsp5 } from "fs";
2816
2818
  import path8 from "path";
@@ -2820,14 +2822,60 @@ var ABILITY_EDITOR_SCRIPT = "build/abilities/index.js";
2820
2822
  var ABILITY_EDITOR_ASSET = "build/abilities/index.asset.php";
2821
2823
  var ABILITY_REGISTRY_END_MARKER = "// wp-typia add ability entries end";
2822
2824
  var ABILITY_REGISTRY_START_MARKER = "// wp-typia add ability entries start";
2823
- var WP_ABILITIES_SCRIPT_HANDLE = "wp-abilities";
2824
- var WP_CORE_ABILITIES_SCRIPT_HANDLE = "wp-core-abilities";
2825
+ var WP_ABILITIES_PACKAGE_VERSION = "^0.10.0";
2826
+ var WP_CORE_ABILITIES_PACKAGE_VERSION = "^0.9.0";
2827
+ var WP_ABILITIES_SCRIPT_MODULE_ID = "@wordpress/abilities";
2828
+ var WP_CORE_ABILITIES_SCRIPT_MODULE_ID = "@wordpress/core-abilities";
2825
2829
  function escapeRegex3(value) {
2826
2830
  return value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
2827
2831
  }
2828
2832
  function quotePhpString3(value) {
2829
2833
  return `'${value.replace(/\\/gu, "\\\\").replace(/'/gu, "\\'")}'`;
2830
2834
  }
2835
+ function findPhpFunctionRange2(source, functionName) {
2836
+ const functionPattern = new RegExp(`function\\s+${escapeRegex3(functionName)}\\s*\\([^)]*\\)\\s*\\{`, "u");
2837
+ const match = functionPattern.exec(source);
2838
+ if (!match) {
2839
+ return null;
2840
+ }
2841
+ const openingBraceIndex = match.index + match[0].length - 1;
2842
+ let depth = 0;
2843
+ for (let index = openingBraceIndex;index < source.length; index += 1) {
2844
+ const character = source[index];
2845
+ if (character === "{") {
2846
+ depth += 1;
2847
+ } else if (character === "}") {
2848
+ depth -= 1;
2849
+ if (depth === 0) {
2850
+ const end = index + 1;
2851
+ return {
2852
+ end,
2853
+ source: source.slice(match.index, end),
2854
+ start: match.index
2855
+ };
2856
+ }
2857
+ }
2858
+ }
2859
+ return null;
2860
+ }
2861
+ function replacePhpFunctionDefinition2(source, functionName, replacement) {
2862
+ const functionRange = findPhpFunctionRange2(source, functionName);
2863
+ if (!functionRange) {
2864
+ return source;
2865
+ }
2866
+ return `${source.slice(0, functionRange.start)}${replacement.trimStart()}${source.slice(functionRange.end)}`;
2867
+ }
2868
+ function resolveManagedDependencyVersion(existingVersion, requiredVersion) {
2869
+ if (!existingVersion) {
2870
+ return requiredVersion;
2871
+ }
2872
+ const existingMinimum = import_semver.default.minVersion(existingVersion);
2873
+ const requiredMinimum = import_semver.default.minVersion(requiredVersion);
2874
+ if (!existingMinimum || !requiredMinimum) {
2875
+ return requiredVersion;
2876
+ }
2877
+ return import_semver.default.gte(existingMinimum, requiredMinimum) ? existingVersion : requiredVersion;
2878
+ }
2831
2879
  function toPascalCaseFromAbilitySlug(abilitySlug) {
2832
2880
  return normalizeBlockSlug(abilitySlug).split("-").filter(Boolean).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1)).join("");
2833
2881
  }
@@ -2897,7 +2945,14 @@ export interface ${pascalCase}AbilityOutput {
2897
2945
  function buildAbilityDataSource(abilitySlug) {
2898
2946
  const pascalCase = toPascalCaseFromAbilitySlug(abilitySlug);
2899
2947
  const abilityConstBase = abilitySlug.toUpperCase().replace(/[^A-Z0-9]+/gu, "_").replace(/_{2,}/gu, "_").replace(/^_|_$/gu, "");
2900
- return `import abilityConfig from './ability.config.json';
2948
+ return `import {
2949
+ executeAbility,
2950
+ getAbilities,
2951
+ getAbility as getRegisteredAbility,
2952
+ } from '@wordpress/abilities';
2953
+ import '@wordpress/core-abilities';
2954
+
2955
+ import abilityConfig from './ability.config.json';
2901
2956
 
2902
2957
  import type { ${pascalCase}AbilityInput, ${pascalCase}AbilityOutput } from './types';
2903
2958
 
@@ -2909,55 +2964,56 @@ interface WordPressAbilityDefinition {
2909
2964
  name?: string;
2910
2965
  }
2911
2966
 
2912
- interface WordPressAbilitiesClient {
2913
- executeAbility( name: string, input?: unknown ): Promise< unknown >;
2914
- getAbilities( args?: { category?: string } ): WordPressAbilityDefinition[];
2915
- getAbility( name: string ): WordPressAbilityDefinition | undefined;
2916
- }
2917
-
2918
- const ABILITY_CLIENT_UNAVAILABLE_MESSAGE =
2919
- 'The WordPress abilities client is unavailable on this screen. Ensure the Abilities API and @wordpress/core-abilities integration are loaded before using this scaffold.';
2920
-
2921
2967
  export const ${abilityConstBase}_ABILITY = abilityConfig;
2922
2968
  export const ${abilityConstBase}_ABILITY_CATEGORY = abilityConfig.category;
2923
2969
  export const ${abilityConstBase}_ABILITY_ID = abilityConfig.abilityId;
2924
2970
  export const ${abilityConstBase}_ABILITY_META = abilityConfig.meta;
2971
+ const ABILITY_DISCOVERY_POLL_INTERVAL_MS = 50;
2972
+ const ABILITY_DISCOVERY_TIMEOUT_MS = 5000;
2925
2973
 
2926
2974
  export type {
2927
2975
  ${pascalCase}AbilityInput,
2928
2976
  ${pascalCase}AbilityOutput,
2929
2977
  };
2930
2978
 
2931
- function resolveAbilitiesClient(): WordPressAbilitiesClient {
2932
- const runtime = globalThis as typeof globalThis & {
2933
- window?: {
2934
- wp?: {
2935
- abilities?: WordPressAbilitiesClient;
2936
- };
2937
- };
2938
- };
2939
- const client = runtime.window?.wp?.abilities;
2940
- if ( ! client ) {
2941
- throw new Error( ABILITY_CLIENT_UNAVAILABLE_MESSAGE );
2942
- }
2979
+ function sleep( milliseconds: number ): Promise< void > {
2980
+ return new Promise( ( resolve ) => {
2981
+ setTimeout( resolve, milliseconds );
2982
+ } );
2983
+ }
2943
2984
 
2944
- return client;
2985
+ async function waitFor${pascalCase}AbilityRegistration(): Promise< void > {
2986
+ const deadline = Date.now() + ABILITY_DISCOVERY_TIMEOUT_MS;
2987
+ while ( ! getRegisteredAbility( ${abilityConstBase}_ABILITY_ID ) ) {
2988
+ if ( Date.now() >= deadline ) {
2989
+ return;
2990
+ }
2991
+
2992
+ await sleep( ABILITY_DISCOVERY_POLL_INTERVAL_MS );
2993
+ }
2945
2994
  }
2946
2995
 
2947
- export function list${pascalCase}CategoryAbilities(): WordPressAbilityDefinition[] {
2948
- return resolveAbilitiesClient().getAbilities( {
2996
+ export async function list${pascalCase}CategoryAbilities(): Promise< WordPressAbilityDefinition[] > {
2997
+ await waitFor${pascalCase}AbilityRegistration();
2998
+
2999
+ return getAbilities( {
2949
3000
  category: ${abilityConstBase}_ABILITY_CATEGORY.slug,
2950
- } );
3001
+ } ) as WordPressAbilityDefinition[];
2951
3002
  }
2952
3003
 
2953
- export function get${pascalCase}Ability():
3004
+ export async function get${pascalCase}Ability(): Promise<
2954
3005
  | WordPressAbilityDefinition
2955
- | undefined {
2956
- return resolveAbilitiesClient().getAbility( ${abilityConstBase}_ABILITY_ID );
3006
+ | undefined
3007
+ > {
3008
+ await waitFor${pascalCase}AbilityRegistration();
3009
+
3010
+ return getRegisteredAbility( ${abilityConstBase}_ABILITY_ID ) as
3011
+ | WordPressAbilityDefinition
3012
+ | undefined;
2957
3013
  }
2958
3014
 
2959
- export function require${pascalCase}Ability(): WordPressAbilityDefinition {
2960
- const ability = get${pascalCase}Ability();
3015
+ export async function require${pascalCase}Ability(): Promise< WordPressAbilityDefinition > {
3016
+ const ability = await get${pascalCase}Ability();
2961
3017
  if ( ability ) {
2962
3018
  return ability;
2963
3019
  }
@@ -2973,7 +3029,9 @@ export function require${pascalCase}Ability(): WordPressAbilityDefinition {
2973
3029
  export async function run${pascalCase}Ability(
2974
3030
  input: ${pascalCase}AbilityInput
2975
3031
  ): Promise< ${pascalCase}AbilityOutput > {
2976
- return ( await resolveAbilitiesClient().executeAbility(
3032
+ await waitFor${pascalCase}AbilityRegistration();
3033
+
3034
+ return ( await executeAbility(
2977
3035
  ${abilityConstBase}_ABILITY_ID,
2978
3036
  input
2979
3037
  ) ) as ${pascalCase}AbilityOutput;
@@ -2985,8 +3043,8 @@ function buildAbilityClientSource(abilitySlug) {
2985
3043
  return `/**
2986
3044
  * Re-export the typed ${pascalCase} ability client helpers.
2987
3045
  *
2988
- * The underlying WordPress abilities client is expected to have been hydrated
2989
- * by the site's admin/editor bootstrap before these helpers execute.
3046
+ * The helper methods load the WordPress core abilities integration and wait for
3047
+ * this server-registered ability before reading or executing it.
2990
3048
  */
2991
3049
  export * from './data';
2992
3050
  `;
@@ -3352,22 +3410,31 @@ function ${enqueueFunctionName}() {
3352
3410
  ? $asset['dependencies']
3353
3411
  : array();
3354
3412
 
3355
- foreach ( array( '${WP_CORE_ABILITIES_SCRIPT_HANDLE}', '${WP_ABILITIES_SCRIPT_HANDLE}' ) as $ability_dependency ) {
3356
- if (
3357
- function_exists( 'wp_script_is' ) &&
3358
- wp_script_is( $ability_dependency, 'registered' ) &&
3359
- ! in_array( $ability_dependency, $dependencies, true )
3360
- ) {
3413
+ foreach ( array( '${WP_CORE_ABILITIES_SCRIPT_MODULE_ID}', '${WP_ABILITIES_SCRIPT_MODULE_ID}' ) as $ability_dependency ) {
3414
+ $has_dependency = false;
3415
+ foreach ( $dependencies as $dependency ) {
3416
+ $dependency_id = is_array( $dependency ) && isset( $dependency['id'] )
3417
+ ? $dependency['id']
3418
+ : $dependency;
3419
+ if ( $dependency_id === $ability_dependency ) {
3420
+ $has_dependency = true;
3421
+ break;
3422
+ }
3423
+ }
3424
+ if ( ! $has_dependency ) {
3361
3425
  $dependencies[] = $ability_dependency;
3362
3426
  }
3363
3427
  }
3364
3428
 
3365
- wp_enqueue_script(
3429
+ if ( ! function_exists( 'wp_enqueue_script_module' ) ) {
3430
+ return;
3431
+ }
3432
+
3433
+ wp_enqueue_script_module(
3366
3434
  '${workspaceBaseName}-abilities',
3367
3435
  plugins_url( '${ABILITY_EDITOR_SCRIPT}', __FILE__ ),
3368
3436
  $dependencies,
3369
- isset( $asset['version'] ) ? $asset['version'] : filemtime( $script_path ),
3370
- true
3437
+ isset( $asset['version'] ) ? $asset['version'] : filemtime( $script_path )
3371
3438
  );
3372
3439
  }
3373
3440
  `;
@@ -3405,6 +3472,8 @@ ${snippet}
3405
3472
  }
3406
3473
  if (!hasPhpFunctionDefinition(enqueueFunctionName)) {
3407
3474
  insertPhpSnippet(enqueueFunction);
3475
+ } else if (!findPhpFunctionRange2(nextSource, enqueueFunctionName)?.source.includes("wp_enqueue_script_module")) {
3476
+ nextSource = replacePhpFunctionDefinition2(nextSource, enqueueFunctionName, enqueueFunction);
3408
3477
  }
3409
3478
  if (!nextSource.includes(loadHook)) {
3410
3479
  appendPhpSnippet(loadHook);
@@ -3425,10 +3494,16 @@ async function ensureAbilityPackageScripts(workspace) {
3425
3494
  ...packageJson.scripts ?? {},
3426
3495
  "sync-abilities": packageJson.scripts?.["sync-abilities"] ?? "tsx scripts/sync-abilities.ts"
3427
3496
  };
3428
- if (JSON.stringify(nextScripts) === JSON.stringify(packageJson.scripts ?? {})) {
3497
+ const nextDependencies = {
3498
+ ...packageJson.dependencies ?? {},
3499
+ [WP_ABILITIES_SCRIPT_MODULE_ID]: resolveManagedDependencyVersion(packageJson.dependencies?.[WP_ABILITIES_SCRIPT_MODULE_ID], WP_ABILITIES_PACKAGE_VERSION),
3500
+ [WP_CORE_ABILITIES_SCRIPT_MODULE_ID]: resolveManagedDependencyVersion(packageJson.dependencies?.[WP_CORE_ABILITIES_SCRIPT_MODULE_ID], WP_CORE_ABILITIES_PACKAGE_VERSION)
3501
+ };
3502
+ if (JSON.stringify(nextScripts) === JSON.stringify(packageJson.scripts ?? {}) && JSON.stringify(nextDependencies) === JSON.stringify(packageJson.dependencies ?? {})) {
3429
3503
  return;
3430
3504
  }
3431
3505
  packageJson.scripts = nextScripts;
3506
+ packageJson.dependencies = nextDependencies;
3432
3507
  await fsp5.writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, "\t")}
3433
3508
  `, "utf8");
3434
3509
  }
@@ -3504,6 +3579,28 @@ async function ensureAbilityWebpackAnchors(workspace) {
3504
3579
  if (/['"]abilities\/index['"]/u.test(source)) {
3505
3580
  return source;
3506
3581
  }
3582
+ const optionalModuleReturnPattern = /(function\s+getOptionalModuleEntries\s*\(\)\s*\{[\s\S]*?)(\n\treturn Object\.fromEntries\(\s*entries\s*\);\n\})/u;
3583
+ if (optionalModuleReturnPattern.test(source)) {
3584
+ return source.replace(optionalModuleReturnPattern, `$1
3585
+
3586
+ for ( const [ entryName, candidates ] of [
3587
+ [
3588
+ 'abilities/index',
3589
+ [ 'src/abilities/index.ts', 'src/abilities/index.js' ],
3590
+ ],
3591
+ ] ) {
3592
+ for ( const relativePath of candidates ) {
3593
+ const entryPath = path.resolve( process.cwd(), relativePath );
3594
+ if ( ! fs.existsSync( entryPath ) ) {
3595
+ continue;
3596
+ }
3597
+
3598
+ entries.push( [ entryName, entryPath ] );
3599
+ break;
3600
+ }
3601
+ }
3602
+ $2`);
3603
+ }
3507
3604
  const sharedEntriesPattern = /for\s*\(\s*const\s+\[\s*entryName\s*,\s*candidates\s*\]\s+of\s+\[([\s\S]*?)\]\s*\)\s*\{/u;
3508
3605
  const match = source.match(sharedEntriesPattern);
3509
3606
  if (!match || !match[1].includes("bindings/index") || !match[1].includes("editor-plugins/index")) {
@@ -5040,4 +5137,4 @@ export {
5040
5137
  ADD_BLOCK_TEMPLATE_IDS
5041
5138
  };
5042
5139
 
5043
- //# debugId=2B54B495F629D39264756E2164756E21
5140
+ //# debugId=497A4F5F67BAF4EF64756E2164756E21
@@ -10,7 +10,7 @@ import {
10
10
  getFailingDoctorChecks,
11
11
  isCliDiagnosticError,
12
12
  serializeCliDiagnosticError
13
- } from "./cli-jcd4wgam.js";
13
+ } from "./cli-xxzpb58s.js";
14
14
  import"./cli-xnn9xjcy.js";
15
15
  export {
16
16
  serializeCliDiagnosticError,
@@ -4,7 +4,7 @@ import {
4
4
  formatDoctorCheckLine,
5
5
  formatDoctorSummaryLine,
6
6
  getDoctorFailureDetailLines
7
- } from "./cli-jcd4wgam.js";
7
+ } from "./cli-xxzpb58s.js";
8
8
  import {
9
9
  getBuiltInTemplateLayerDirs,
10
10
  isOmittableBuiltInTemplateLayerDir
@@ -391,7 +391,8 @@ function checkWorkspaceAbilityBootstrap(projectDir, packageName, phpPrefix) {
391
391
  const hasServerGlob = source.includes(WORKSPACE_ABILITY_GLOB);
392
392
  const hasEditorScript = source.includes(WORKSPACE_ABILITY_EDITOR_SCRIPT);
393
393
  const hasEditorAsset = source.includes(WORKSPACE_ABILITY_EDITOR_ASSET);
394
- return createDoctorCheck2("Ability bootstrap", hasLoaderHook && hasAdminEnqueueHook && hasEditorEnqueueHook && hasServerGlob && hasEditorScript && hasEditorAsset ? "pass" : "fail", hasLoaderHook && hasAdminEnqueueHook && hasEditorEnqueueHook && hasServerGlob && hasEditorScript && hasEditorAsset ? "Ability loader and admin/editor client bootstrap hooks are present" : "Missing ability loader hook or build/abilities script asset references");
394
+ const hasScriptModuleEnqueue = source.includes("wp_enqueue_script_module");
395
+ return createDoctorCheck2("Ability bootstrap", hasLoaderHook && hasAdminEnqueueHook && hasEditorEnqueueHook && hasServerGlob && hasEditorScript && hasEditorAsset && hasScriptModuleEnqueue ? "pass" : "fail", hasLoaderHook && hasAdminEnqueueHook && hasEditorEnqueueHook && hasServerGlob && hasEditorScript && hasEditorAsset && hasScriptModuleEnqueue ? "Ability loader and admin/editor script-module bootstrap hooks are present" : "Missing ability loader hook, script-module enqueue, or build/abilities asset references");
395
396
  }
396
397
  function checkWorkspaceAbilityIndex(projectDir, abilities) {
397
398
  const indexRelativePath = [
@@ -647,4 +648,4 @@ export {
647
648
  getDoctorChecks
648
649
  };
649
650
 
650
- //# debugId=1F5A1F43481D5B9164756E2164756E21
651
+ //# debugId=DA7EC2F06C52A22464756E2164756E21