wp-typia 0.22.10 → 0.23.0

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.
@@ -170926,6 +170926,18 @@ var REST_RESOURCE_METHOD_IDS = [
170926
170926
  "update",
170927
170927
  "delete"
170928
170928
  ];
170929
+ var MANUAL_REST_CONTRACT_HTTP_METHOD_IDS = [
170930
+ "DELETE",
170931
+ "GET",
170932
+ "PATCH",
170933
+ "POST",
170934
+ "PUT"
170935
+ ];
170936
+ var MANUAL_REST_CONTRACT_AUTH_IDS = [
170937
+ "authenticated",
170938
+ "public",
170939
+ "public-write-protected"
170940
+ ];
170929
170941
  var EDITOR_PLUGIN_SLOT_IDS = ["sidebar", "document-setting-panel"];
170930
170942
  var EDITOR_PLUGIN_SLOT_ALIASES = {
170931
170943
  PluginDocumentSettingPanel: "document-setting-panel",
@@ -170940,6 +170952,10 @@ function resolveEditorPluginSlotAlias(slot) {
170940
170952
  }
170941
170953
  return EDITOR_PLUGIN_SLOT_ALIASES[trimmed];
170942
170954
  }
170955
+ var INTEGRATION_ENV_SERVICE_IDS = [
170956
+ "none",
170957
+ "docker-compose"
170958
+ ];
170943
170959
  var ADD_BLOCK_TEMPLATE_IDS = [
170944
170960
  "basic",
170945
170961
  "interactivity",
@@ -171038,7 +171054,97 @@ function toTitleCase(input) {
171038
171054
 
171039
171055
  // ../wp-typia-project-tools/src/runtime/cli-add-validation.ts
171040
171056
  var WORKSPACE_GENERATED_SLUG_PATTERN = /^[a-z][a-z0-9-]*$/;
171057
+ var WORDPRESS_POST_TYPE_PATTERN = /^[a-z0-9_][a-z0-9_-]*$/u;
171058
+ var TYPESCRIPT_IDENTIFIER_PATTERN = /^[A-Za-z_$][A-Za-z0-9_$]*$/u;
171059
+ var TYPESCRIPT_RESERVED_IDENTIFIERS = new Set([
171060
+ "abstract",
171061
+ "any",
171062
+ "as",
171063
+ "asserts",
171064
+ "async",
171065
+ "await",
171066
+ "bigint",
171067
+ "boolean",
171068
+ "break",
171069
+ "case",
171070
+ "catch",
171071
+ "class",
171072
+ "const",
171073
+ "constructor",
171074
+ "continue",
171075
+ "debugger",
171076
+ "declare",
171077
+ "default",
171078
+ "delete",
171079
+ "do",
171080
+ "else",
171081
+ "enum",
171082
+ "export",
171083
+ "extends",
171084
+ "false",
171085
+ "finally",
171086
+ "for",
171087
+ "from",
171088
+ "function",
171089
+ "get",
171090
+ "global",
171091
+ "if",
171092
+ "implements",
171093
+ "import",
171094
+ "in",
171095
+ "infer",
171096
+ "instanceof",
171097
+ "interface",
171098
+ "intrinsic",
171099
+ "is",
171100
+ "keyof",
171101
+ "let",
171102
+ "module",
171103
+ "namespace",
171104
+ "never",
171105
+ "new",
171106
+ "null",
171107
+ "number",
171108
+ "object",
171109
+ "of",
171110
+ "out",
171111
+ "override",
171112
+ "package",
171113
+ "private",
171114
+ "protected",
171115
+ "public",
171116
+ "readonly",
171117
+ "require",
171118
+ "return",
171119
+ "satisfies",
171120
+ "set",
171121
+ "static",
171122
+ "string",
171123
+ "super",
171124
+ "switch",
171125
+ "symbol",
171126
+ "this",
171127
+ "throw",
171128
+ "true",
171129
+ "try",
171130
+ "type",
171131
+ "typeof",
171132
+ "undefined",
171133
+ "unique",
171134
+ "unknown",
171135
+ "using",
171136
+ "var",
171137
+ "void",
171138
+ "while",
171139
+ "with",
171140
+ "yield"
171141
+ ]);
171041
171142
  var REST_RESOURCE_NAMESPACE_PATTERN = /^[a-z][a-z0-9-]*(?:\/[a-z0-9-]+)+$/u;
171143
+ var PHP_IDENTIFIER_PATTERN = "[A-Za-z_][A-Za-z0-9_]*";
171144
+ var PHP_QUALIFIED_NAME_PATTERN = new RegExp(`^\\\\?${PHP_IDENTIFIER_PATTERN}(?:\\\\${PHP_IDENTIFIER_PATTERN})*$`, "u");
171145
+ var PHP_CALLBACK_REFERENCE_PATTERN = new RegExp(`^\\\\?${PHP_IDENTIFIER_PATTERN}(?:\\\\${PHP_IDENTIFIER_PATTERN})*(?:::${PHP_IDENTIFIER_PATTERN})?$`, "u");
171146
+ var REST_ROUTE_NAMED_CAPTURE_PATTERN = /\(\?P<([A-Za-z_][A-Za-z0-9_]*)>/gu;
171147
+ var REST_ROUTE_UNSUPPORTED_CAPTURE_PATTERN = /\((?!\?(?:P<[A-Za-z_][A-Za-z0-9_]*>|:))/u;
171042
171148
  function assertValidGeneratedSlug(label, slug, usage) {
171043
171149
  if (!slug) {
171044
171150
  throw new Error(`${label} is required. Use \`${usage}\`.`);
@@ -171048,6 +171154,19 @@ function assertValidGeneratedSlug(label, slug, usage) {
171048
171154
  }
171049
171155
  return slug;
171050
171156
  }
171157
+ function assertValidTypeScriptIdentifier(label, value, usage) {
171158
+ const trimmed = value.trim();
171159
+ if (!trimmed) {
171160
+ throw new Error(`${label} is required. Use \`${usage}\`.`);
171161
+ }
171162
+ if (!TYPESCRIPT_IDENTIFIER_PATTERN.test(trimmed)) {
171163
+ throw new Error(`${label} must be a valid TypeScript identifier, such as ExternalRetrieveResponse.`);
171164
+ }
171165
+ if (TYPESCRIPT_RESERVED_IDENTIFIERS.has(trimmed)) {
171166
+ throw new Error(`${label} must not be a reserved TypeScript keyword, such as ${trimmed}.`);
171167
+ }
171168
+ return trimmed;
171169
+ }
171051
171170
  function assertValidRestResourceNamespace(namespace) {
171052
171171
  const trimmed = namespace.trim();
171053
171172
  if (!trimmed) {
@@ -171061,6 +171180,34 @@ function assertValidRestResourceNamespace(namespace) {
171061
171180
  function resolveRestResourceNamespace(workspaceNamespace, namespace) {
171062
171181
  return assertValidRestResourceNamespace(namespace ?? `${workspaceNamespace}/v1`);
171063
171182
  }
171183
+ function assertValidPostMetaPostType(postType) {
171184
+ const trimmed = postType.trim();
171185
+ if (!trimmed) {
171186
+ throw new Error("`wp-typia add post-meta` requires --post-type <post-type>.");
171187
+ }
171188
+ if (trimmed.length > 20) {
171189
+ throw new Error("Post meta post type must be 20 characters or fewer.");
171190
+ }
171191
+ if (!WORDPRESS_POST_TYPE_PATTERN.test(trimmed)) {
171192
+ throw new Error("Post meta post type must use a WordPress post type key such as `post` or `example_post_type`.");
171193
+ }
171194
+ return trimmed;
171195
+ }
171196
+ function resolvePostMetaKey({
171197
+ metaKey,
171198
+ phpPrefix,
171199
+ slug
171200
+ }) {
171201
+ const resolvedMetaKey = metaKey ?? `_${toSnakeCase(`${phpPrefix}_${slug}`)}`;
171202
+ const trimmed = resolvedMetaKey.trim();
171203
+ if (!trimmed) {
171204
+ throw new Error("Post meta key cannot be empty.");
171205
+ }
171206
+ if (/[\p{Cc}\s]/u.test(trimmed)) {
171207
+ throw new Error("Post meta key must not contain whitespace or control characters.");
171208
+ }
171209
+ return trimmed;
171210
+ }
171064
171211
  function assertValidRestResourceMethods(methods) {
171065
171212
  const rawMethods = typeof methods === "string" && methods.trim().length > 0 ? methods.split(",").map((value) => value.trim()).filter(Boolean) : ["list", "read", "create"];
171066
171213
  const normalizedMethods = Array.from(new Set(rawMethods));
@@ -171073,6 +171220,91 @@ function assertValidRestResourceMethods(methods) {
171073
171220
  }
171074
171221
  return normalizedMethods;
171075
171222
  }
171223
+ function resolveOptionalPhpCallbackReference(label, callback) {
171224
+ if (callback == null) {
171225
+ return;
171226
+ }
171227
+ const trimmed = callback.trim();
171228
+ if (!trimmed) {
171229
+ throw new Error(`${label} cannot be empty.`);
171230
+ }
171231
+ if (!PHP_CALLBACK_REFERENCE_PATTERN.test(trimmed)) {
171232
+ throw new Error(`${label} must be a PHP function reference or ClassName::method callback.`);
171233
+ }
171234
+ return trimmed;
171235
+ }
171236
+ function resolveOptionalPhpClassReference(label, classReference) {
171237
+ if (classReference == null) {
171238
+ return;
171239
+ }
171240
+ const trimmed = classReference.trim();
171241
+ if (!trimmed) {
171242
+ throw new Error(`${label} cannot be empty.`);
171243
+ }
171244
+ if (!PHP_QUALIFIED_NAME_PATTERN.test(trimmed)) {
171245
+ throw new Error(`${label} must be a PHP class reference such as Demo_Rest_Controller or Vendor\\Plugin\\Controller.`);
171246
+ }
171247
+ return trimmed;
171248
+ }
171249
+ function assertValidManualRestContractHttpMethod(method = "GET") {
171250
+ const normalized = method.trim().toUpperCase();
171251
+ if (MANUAL_REST_CONTRACT_HTTP_METHOD_IDS.includes(normalized)) {
171252
+ return normalized;
171253
+ }
171254
+ throw new Error(`Manual REST contract method must be one of: ${MANUAL_REST_CONTRACT_HTTP_METHOD_IDS.join(", ")}.`);
171255
+ }
171256
+ function assertValidManualRestContractAuth(auth = "public") {
171257
+ const normalized = auth.trim().toLowerCase();
171258
+ if (MANUAL_REST_CONTRACT_AUTH_IDS.includes(normalized)) {
171259
+ return normalized;
171260
+ }
171261
+ throw new Error(`Manual REST contract auth must be one of: ${MANUAL_REST_CONTRACT_AUTH_IDS.join(", ")}.`);
171262
+ }
171263
+ function resolveRestRoutePathPattern(options) {
171264
+ const explicitPath = typeof options.pathPattern === "string" ? options.pathPattern.trim() : undefined;
171265
+ if (explicitPath === "") {
171266
+ throw new Error(options.emptyMessage);
171267
+ }
171268
+ const trimmed = explicitPath ?? options.defaultPath;
171269
+ if (/^https?:\/\//iu.test(trimmed)) {
171270
+ throw new Error(`${options.label} must be a route pattern relative to the namespace, not an absolute URL.`);
171271
+ }
171272
+ const withLeadingSlash = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
171273
+ if (!withLeadingSlash || withLeadingSlash === "/") {
171274
+ throw new Error(options.emptyMessage);
171275
+ }
171276
+ if (/\s/u.test(withLeadingSlash)) {
171277
+ throw new Error(`${options.label} must not contain whitespace.`);
171278
+ }
171279
+ return withLeadingSlash;
171280
+ }
171281
+ function isGeneratedRestResourceRoutePatternCompatible(routePattern) {
171282
+ const namedCaptures = Array.from(routePattern.matchAll(REST_ROUTE_NAMED_CAPTURE_PATTERN), (match) => match[1]);
171283
+ const hasRegexGroup = routePattern.includes("(");
171284
+ const hasUnsupportedCapture = REST_ROUTE_UNSUPPORTED_CAPTURE_PATTERN.test(routePattern);
171285
+ return !hasUnsupportedCapture && (!hasRegexGroup || namedCaptures.length === 1 && namedCaptures[0] === "id");
171286
+ }
171287
+ function resolveManualRestContractPathPattern(slug, pathPattern) {
171288
+ return resolveRestRoutePathPattern({
171289
+ defaultPath: `/${slug}`,
171290
+ emptyMessage: "Manual REST contract path is required. Use `--path <route-pattern>` such as `/external-record/(?P<id>[\\d]+)`.",
171291
+ label: "Manual REST contract path",
171292
+ pathPattern
171293
+ });
171294
+ }
171295
+ function resolveGeneratedRestResourceRoutePattern(slug, routePattern) {
171296
+ const resolvedRoutePattern = resolveRestRoutePathPattern({
171297
+ defaultPath: `/${slug}/item`,
171298
+ emptyMessage: "Generated REST resource route pattern is required. Use `--route-pattern <route-pattern>` such as `/records/(?P<id>[\\d]+)`.",
171299
+ label: "Generated REST resource route pattern",
171300
+ pathPattern: routePattern
171301
+ });
171302
+ const hasExplicitRoutePattern = typeof routePattern === "string" && routePattern.trim().length > 0;
171303
+ if (hasExplicitRoutePattern && !isGeneratedRestResourceRoutePatternCompatible(resolvedRoutePattern)) {
171304
+ throw new Error("Generated REST resource route pattern must use only an `(?P<id>...)` named capture when using regex groups.");
171305
+ }
171306
+ return resolvedRoutePattern;
171307
+ }
171076
171308
  function assertValidHookedBlockPosition(position) {
171077
171309
  if (HOOKED_BLOCK_POSITION_IDS.includes(position)) {
171078
171310
  return position;
@@ -171105,6 +171337,13 @@ function assertValidEditorPluginSlot(slot = "sidebar") {
171105
171337
  }
171106
171338
  throw new Error(`Editor plugin slot must be one of: ${EDITOR_PLUGIN_SLOT_IDS.join(", ")}. Legacy aliases: PluginSidebar, PluginDocumentSettingPanel.`);
171107
171339
  }
171340
+ function assertValidIntegrationEnvService(service = "none") {
171341
+ const trimmed = service.trim();
171342
+ if (INTEGRATION_ENV_SERVICE_IDS.includes(trimmed)) {
171343
+ return trimmed;
171344
+ }
171345
+ throw new Error(`Integration environment service must be one of: ${INTEGRATION_ENV_SERVICE_IDS.join(", ")}.`);
171346
+ }
171108
171347
 
171109
171348
  // ../wp-typia-project-tools/src/runtime/fs-async.ts
171110
171349
  import { promises as fsp } from "fs";
@@ -171141,12 +171380,16 @@ function formatAddHelpText() {
171141
171380
  return `Usage:
171142
171381
  wp-typia add admin-view <name> [--source <rest-resource:slug|core-data:kind/name>] [--dry-run]
171143
171382
  wp-typia add block <name> [--template <${ADD_BLOCK_TEMPLATE_IDS.join("|")}>] [--external-layer-source <./path|github:owner/repo/path[#ref]|npm-package>] [--external-layer-id <layer-id>] [--inner-blocks-preset <freeform|ordered|horizontal|locked-structure>] [--alternate-render-targets <email,mjml,plain-text>] [--data-storage <post-meta|custom-table>] [--persistence-policy <authenticated|public>] [--dry-run]
171383
+ wp-typia add integration-env <name> [--wp-env] [--service <none|docker-compose>] [--dry-run]
171144
171384
  wp-typia add variation <name> --block <block-slug> [--dry-run]
171145
171385
  wp-typia add style <name> --block <block-slug> [--dry-run]
171146
171386
  wp-typia add transform <name> --from <namespace/block> --to <block-slug|namespace/block-slug> [--dry-run]
171147
171387
  wp-typia add pattern <name> [--dry-run]
171148
171388
  wp-typia add binding-source <name> [--block <block-slug|namespace/block-slug> --attribute <attribute>] [--dry-run]
171149
- wp-typia add rest-resource <name> [--namespace <vendor/v1>] [--methods <${REST_RESOURCE_METHOD_IDS.join(",")}>] [--dry-run]
171389
+ wp-typia add contract <name> [--type <ExportedTypeName>] [--dry-run]
171390
+ wp-typia add rest-resource <name> [--namespace <vendor/v1>] [--methods <${REST_RESOURCE_METHOD_IDS.join(",")}>] [--route-pattern <route-pattern>] [--permission-callback <callback>] [--controller-class <ClassName>] [--controller-extends <BaseClass>] [--dry-run]
171391
+ wp-typia add rest-resource <name> --manual [--namespace <vendor/v1>] [--method <GET|POST|PUT|PATCH|DELETE>] [--auth <public|authenticated|public-write-protected>] [--path <route-pattern>] [--query-type <Type>] [--body-type <Type>] [--response-type <Type>] [--dry-run]
171392
+ wp-typia add post-meta <name> --post-type <post-type> [--type <ExportedTypeName>] [--meta-key <meta-key>] [--hide-from-rest] [--dry-run]
171150
171393
  wp-typia add ability <name> [--dry-run]
171151
171394
  wp-typia add ai-feature <name> [--namespace <vendor/v1>] [--dry-run]
171152
171395
  wp-typia add hooked-block <block-slug> --anchor <anchor-block-name> --position <${HOOKED_BLOCK_POSITION_IDS.join("|")}> [--dry-run]
@@ -171160,13 +171403,18 @@ Notes:
171160
171403
  Pass \`--source rest-resource:<slug>\` to reuse a list-capable REST resource.
171161
171404
  Pass \`--source core-data:postType/post\` or \`--source core-data:taxonomy/category\` to bind a WordPress-owned entity collection.
171162
171405
  Generated admin-view workspaces add \`@wp-typia/dataviews\` and the needed WordPress DataViews packages as opt-in dependencies.
171406
+ \`add integration-env\` generates an opt-in local smoke starter under \`scripts/integration-smoke/\`, updates \`.env.example\`, and can add \`@wordpress/env\` plus \`.wp-env.json\` when \`--wp-env\` is passed.
171407
+ Pass \`--service docker-compose\` to include a placeholder local service stack that can be adapted to project-specific dependencies.
171163
171408
  \`query-loop\` is a create-time scaffold family. Use \`wp-typia create <project-dir> --template query-loop\` instead of \`wp-typia add block\`.
171164
171409
  \`add variation\` targets an existing block slug from \`scripts/block-config.ts\`.
171165
171410
  \`add style\` registers a Block Styles option for an existing generated block.
171166
171411
  \`add transform\` adds a block-to-block transform into an existing generated block.
171167
171412
  \`add pattern\` scaffolds a namespaced PHP pattern shell under \`src/patterns/\`.
171168
171413
  \`add binding-source\` scaffolds shared PHP and editor registration under \`src/bindings/\`; pass \`--block\` and \`--attribute\` together to declare an end-to-end bindable attribute on an existing generated block.
171169
- \`add rest-resource\` scaffolds plugin-level TypeScript REST contracts under \`src/rest/\` and PHP route glue under \`inc/rest/\`.
171414
+ \`add contract\` registers a standalone TypeScript wire contract under \`src/contracts/\` and generates a stable JSON Schema artifact without creating PHP route glue.
171415
+ \`add rest-resource\` scaffolds plugin-level TypeScript REST contracts under \`src/rest/\` and PHP route glue under \`inc/rest/\`. Use \`--route-pattern\`, \`--permission-callback\`, \`--controller-class\`, and \`--controller-extends\` when an existing WordPress controller or permission model needs to own part of the generated route surface.
171416
+ Pass \`--manual\` with \`add rest-resource\` to track an external REST route with typed schemas, OpenAPI, clients, and drift checks without generating PHP route/controller files.
171417
+ \`add post-meta\` scaffolds a typed post meta contract under \`src/post-meta/\`, generates a schema artifact, and wires \`register_post_meta()\` helpers under \`inc/post-meta/\`.
171170
171418
  \`add ability\` scaffolds typed workflow abilities under \`src/abilities/\` and server registration under \`inc/abilities/\`.
171171
171419
  \`add ai-feature\` scaffolds server-owned AI feature endpoints under \`src/ai-features/\` and PHP route glue under \`inc/ai-features/\`.
171172
171420
  \`add hooked-block\` patches an existing workspace block's \`block.json\` \`blockHooks\` metadata.
@@ -171443,6 +171691,40 @@ var REST_RESOURCE_COLLISION_DESCRIPTOR = {
171443
171691
  message: ({ slug }) => `A REST resource inventory entry already exists for ${slug}. Choose a different name.`
171444
171692
  }
171445
171693
  };
171694
+ var POST_META_COLLISION_DESCRIPTOR = {
171695
+ filesystemCollisions: [
171696
+ {
171697
+ label: "A post meta contract",
171698
+ relativePath: ({ slug }) => path3.join("src", "post-meta", slug)
171699
+ },
171700
+ {
171701
+ label: "A post meta bootstrap",
171702
+ relativePath: ({ slug }) => path3.join("inc", "post-meta", `${slug}.php`)
171703
+ }
171704
+ ],
171705
+ inventoryCollision: {
171706
+ entries: (inventory) => inventory.postMeta,
171707
+ exists: (entry, { slug }) => entry.slug === slug,
171708
+ message: ({ slug }) => `A post meta inventory entry already exists for ${slug}. Choose a different name.`
171709
+ }
171710
+ };
171711
+ var CONTRACT_COLLISION_DESCRIPTOR = {
171712
+ filesystemCollisions: [
171713
+ {
171714
+ label: "A standalone contract",
171715
+ relativePath: ({ slug }) => path3.join("src", "contracts", `${slug}.ts`)
171716
+ },
171717
+ {
171718
+ label: "A standalone contract schema",
171719
+ relativePath: ({ slug }) => path3.join("src", "contracts", `${slug}.schema.json`)
171720
+ }
171721
+ ],
171722
+ inventoryCollision: {
171723
+ entries: (inventory) => inventory.contracts,
171724
+ exists: (entry, { slug }) => entry.slug === slug,
171725
+ message: ({ slug }) => `A standalone contract inventory entry already exists for ${slug}. Choose a different name.`
171726
+ }
171727
+ };
171446
171728
  var ADMIN_VIEW_COLLISION_DESCRIPTOR = {
171447
171729
  filesystemCollisions: [
171448
171730
  {
@@ -171555,6 +171837,25 @@ function assertRestResourceDoesNotExist(projectDir, restResourceSlug, inventory)
171555
171837
  projectDir
171556
171838
  });
171557
171839
  }
171840
+ function assertPostMetaDoesNotExist(projectDir, postMetaSlug, postType, metaKey, inventory) {
171841
+ assertAddKindScaffoldDoesNotExist({
171842
+ context: { metaKey, postType, slug: postMetaSlug },
171843
+ descriptor: POST_META_COLLISION_DESCRIPTOR,
171844
+ inventory,
171845
+ projectDir
171846
+ });
171847
+ if (inventory.postMeta.some((entry) => entry.postType === postType && entry.metaKey === metaKey)) {
171848
+ throw new Error(`A post meta inventory entry already registers ${metaKey} for ${postType}. Choose a different meta key or post type.`);
171849
+ }
171850
+ }
171851
+ function assertContractDoesNotExist(projectDir, contractSlug, inventory) {
171852
+ assertAddKindScaffoldDoesNotExist({
171853
+ context: { slug: contractSlug },
171854
+ descriptor: CONTRACT_COLLISION_DESCRIPTOR,
171855
+ inventory,
171856
+ projectDir
171857
+ });
171858
+ }
171558
171859
  function assertAdminViewDoesNotExist(projectDir, adminViewSlug, inventory) {
171559
171860
  assertAddKindScaffoldDoesNotExist({
171560
171861
  context: { slug: adminViewSlug },
@@ -171611,7 +171912,9 @@ var BLOCK_STYLE_CONFIG_ENTRY_MARKER = "\t// wp-typia add style entries";
171611
171912
  var BLOCK_TRANSFORM_CONFIG_ENTRY_MARKER = "\t// wp-typia add transform entries";
171612
171913
  var PATTERN_CONFIG_ENTRY_MARKER = "\t// wp-typia add pattern entries";
171613
171914
  var BINDING_SOURCE_CONFIG_ENTRY_MARKER = "\t// wp-typia add binding-source entries";
171915
+ var CONTRACT_CONFIG_ENTRY_MARKER = "\t// wp-typia add contract entries";
171614
171916
  var REST_RESOURCE_CONFIG_ENTRY_MARKER = "\t// wp-typia add rest-resource entries";
171917
+ var POST_META_CONFIG_ENTRY_MARKER = "\t// wp-typia add post-meta entries";
171615
171918
  var ABILITY_CONFIG_ENTRY_MARKER = "\t// wp-typia add ability entries";
171616
171919
  var AI_FEATURE_CONFIG_ENTRY_MARKER = "\t// wp-typia add ai-feature entries";
171617
171920
  var ADMIN_VIEW_CONFIG_ENTRY_MARKER = "\t// wp-typia add admin-view entries";
@@ -171689,23 +171992,63 @@ export const BINDING_SOURCES: WorkspaceBindingSourceConfig[] = [
171689
171992
  // wp-typia add binding-source entries
171690
171993
  ];
171691
171994
  `;
171995
+ var CONTRACTS_INTERFACE_SECTION = `
171996
+
171997
+ export interface WorkspaceContractConfig {
171998
+ schemaFile: string;
171999
+ slug: string;
172000
+ sourceTypeName: string;
172001
+ typesFile: string;
172002
+ }
172003
+ `;
172004
+ var CONTRACTS_CONST_SECTION = `
172005
+
172006
+ export const CONTRACTS: WorkspaceContractConfig[] = [
172007
+ // wp-typia add contract entries
172008
+ ];
172009
+ `;
171692
172010
  var REST_RESOURCES_INTERFACE_SECTION = `
171693
172011
 
171694
- export interface WorkspaceRestResourceConfig {
172012
+ export interface WorkspaceRestResourceBaseConfig {
171695
172013
  apiFile: string;
172014
+ auth?: 'authenticated' | 'public' | 'public-write-protected';
172015
+ bodyTypeName?: string;
171696
172016
  clientFile: string;
171697
- dataFile: string;
171698
- methods: Array< 'list' | 'read' | 'create' | 'update' | 'delete' >;
172017
+ controllerClass?: string;
172018
+ controllerExtends?: string;
171699
172019
  namespace: string;
171700
172020
  openApiFile: string;
171701
- phpFile: string;
172021
+ permissionCallback?: string;
171702
172022
  restManifest?: ReturnType<
171703
172023
  typeof import( '@wp-typia/block-runtime/metadata-core' ).defineEndpointManifest
171704
172024
  >;
172025
+ secretFieldName?: string;
172026
+ secretStateFieldName?: string;
171705
172027
  slug: string;
171706
172028
  typesFile: string;
171707
172029
  validatorsFile: string;
171708
172030
  }
172031
+
172032
+ export interface GeneratedWorkspaceRestResourceConfig extends WorkspaceRestResourceBaseConfig {
172033
+ dataFile: string;
172034
+ methods: Array< 'list' | 'read' | 'create' | 'update' | 'delete' >;
172035
+ mode?: 'generated';
172036
+ phpFile: string;
172037
+ routePattern?: string;
172038
+ }
172039
+
172040
+ export interface ManualWorkspaceRestResourceConfig extends WorkspaceRestResourceBaseConfig {
172041
+ method: 'DELETE' | 'GET' | 'PATCH' | 'POST' | 'PUT';
172042
+ methods: [];
172043
+ mode: 'manual';
172044
+ pathPattern: string;
172045
+ queryTypeName: string;
172046
+ responseTypeName: string;
172047
+ }
172048
+
172049
+ export type WorkspaceRestResourceConfig =
172050
+ | GeneratedWorkspaceRestResourceConfig
172051
+ | ManualWorkspaceRestResourceConfig;
171709
172052
  `;
171710
172053
  var REST_RESOURCES_CONST_SECTION = `
171711
172054
 
@@ -171713,6 +172056,25 @@ export const REST_RESOURCES: WorkspaceRestResourceConfig[] = [
171713
172056
  // wp-typia add rest-resource entries
171714
172057
  ];
171715
172058
  `;
172059
+ var POST_META_INTERFACE_SECTION = `
172060
+
172061
+ export interface WorkspacePostMetaConfig {
172062
+ metaKey: string;
172063
+ phpFile: string;
172064
+ postType: string;
172065
+ schemaFile: string;
172066
+ showInRest: boolean;
172067
+ slug: string;
172068
+ sourceTypeName: string;
172069
+ typesFile: string;
172070
+ }
172071
+ `;
172072
+ var POST_META_CONST_SECTION = `
172073
+
172074
+ export const POST_META: WorkspacePostMetaConfig[] = [
172075
+ // wp-typia add post-meta entries
172076
+ ];
172077
+ `;
171716
172078
  var WORKSPACE_COMPATIBILITY_CONFIG_FIELD = ` compatibility?: {
171717
172079
  hardMinimums: {
171718
172080
  php?: string;
@@ -171960,6 +172322,33 @@ var INVENTORY_SECTIONS = [
171960
172322
  section: BINDING_SOURCES_CONST_SECTION
171961
172323
  }
171962
172324
  },
172325
+ {
172326
+ append: {
172327
+ marker: CONTRACT_CONFIG_ENTRY_MARKER,
172328
+ optionKey: "contractEntries"
172329
+ },
172330
+ interface: {
172331
+ name: "WorkspaceContractConfig",
172332
+ section: CONTRACTS_INTERFACE_SECTION
172333
+ },
172334
+ parse: {
172335
+ entriesKey: "contracts",
172336
+ entry: defineInventoryEntryParser()({
172337
+ entryName: "CONTRACTS",
172338
+ fields: [
172339
+ { key: "schemaFile", required: true },
172340
+ { key: "slug", required: true },
172341
+ { key: "sourceTypeName", required: true },
172342
+ { key: "typesFile", required: true }
172343
+ ]
172344
+ }),
172345
+ hasSectionKey: "hasContractsSection"
172346
+ },
172347
+ value: {
172348
+ name: "CONTRACTS",
172349
+ section: CONTRACTS_CONST_SECTION
172350
+ }
172351
+ },
171963
172352
  {
171964
172353
  append: {
171965
172354
  marker: REST_RESOURCE_CONFIG_ENTRY_MARKER,
@@ -171975,8 +172364,27 @@ var INVENTORY_SECTIONS = [
171975
172364
  entryName: "REST_RESOURCES",
171976
172365
  fields: [
171977
172366
  { key: "apiFile", required: true },
172367
+ {
172368
+ key: "auth",
172369
+ validate: (value, context) => {
172370
+ if (typeof value === "string" && !MANUAL_REST_CONTRACT_AUTH_IDS.includes(value)) {
172371
+ throw new Error(`${context.entryName}[${context.elementIndex}].${context.key} must be one of: ${MANUAL_REST_CONTRACT_AUTH_IDS.join(", ")}.`);
172372
+ }
172373
+ }
172374
+ },
172375
+ { key: "bodyTypeName" },
171978
172376
  { key: "clientFile", required: true },
171979
- { key: "dataFile", required: true },
172377
+ { key: "controllerClass" },
172378
+ { key: "controllerExtends" },
172379
+ { key: "dataFile" },
172380
+ {
172381
+ key: "method",
172382
+ validate: (value, context) => {
172383
+ if (typeof value === "string" && !MANUAL_REST_CONTRACT_HTTP_METHOD_IDS.includes(value)) {
172384
+ throw new Error(`${context.entryName}[${context.elementIndex}].${context.key} must be one of: ${MANUAL_REST_CONTRACT_HTTP_METHOD_IDS.join(", ")}.`);
172385
+ }
172386
+ }
172387
+ },
171980
172388
  {
171981
172389
  key: "methods",
171982
172390
  kind: "stringArray",
@@ -171989,9 +172397,24 @@ var INVENTORY_SECTIONS = [
171989
172397
  }
171990
172398
  }
171991
172399
  },
172400
+ {
172401
+ key: "mode",
172402
+ validate: (value, context) => {
172403
+ if (typeof value === "string" && value !== "generated" && value !== "manual") {
172404
+ throw new Error(`${context.entryName}[${context.elementIndex}].${context.key} must be generated or manual.`);
172405
+ }
172406
+ }
172407
+ },
171992
172408
  { key: "namespace", required: true },
171993
172409
  { key: "openApiFile", required: true },
171994
- { key: "phpFile", required: true },
172410
+ { key: "pathPattern" },
172411
+ { key: "permissionCallback" },
172412
+ { key: "phpFile" },
172413
+ { key: "queryTypeName" },
172414
+ { key: "responseTypeName" },
172415
+ { key: "routePattern" },
172416
+ { key: "secretFieldName" },
172417
+ { key: "secretStateFieldName" },
171995
172418
  { key: "slug", required: true },
171996
172419
  { key: "typesFile", required: true },
171997
172420
  { key: "validatorsFile", required: true }
@@ -172004,6 +172427,37 @@ var INVENTORY_SECTIONS = [
172004
172427
  section: REST_RESOURCES_CONST_SECTION
172005
172428
  }
172006
172429
  },
172430
+ {
172431
+ append: {
172432
+ marker: POST_META_CONFIG_ENTRY_MARKER,
172433
+ optionKey: "postMetaEntries"
172434
+ },
172435
+ interface: {
172436
+ name: "WorkspacePostMetaConfig",
172437
+ section: POST_META_INTERFACE_SECTION
172438
+ },
172439
+ parse: {
172440
+ entriesKey: "postMeta",
172441
+ entry: defineInventoryEntryParser()({
172442
+ entryName: "POST_META",
172443
+ fields: [
172444
+ { key: "metaKey", required: true },
172445
+ { key: "phpFile", required: true },
172446
+ { key: "postType", required: true },
172447
+ { key: "schemaFile", required: true },
172448
+ { key: "showInRest", kind: "boolean", required: true },
172449
+ { key: "slug", required: true },
172450
+ { key: "sourceTypeName", required: true },
172451
+ { key: "typesFile", required: true }
172452
+ ]
172453
+ }),
172454
+ hasSectionKey: "hasPostMetaSection"
172455
+ },
172456
+ value: {
172457
+ name: "POST_META",
172458
+ section: POST_META_CONST_SECTION
172459
+ }
172460
+ },
172007
172461
  {
172008
172462
  append: {
172009
172463
  marker: ABILITY_CONFIG_ENTRY_MARKER,
@@ -172190,6 +172644,25 @@ function getOptionalStringArrayProperty(entryName, elementIndex, objectLiteral,
172190
172644
  }
172191
172645
  return;
172192
172646
  }
172647
+ function getOptionalBooleanProperty(entryName, elementIndex, objectLiteral, key) {
172648
+ for (const property of objectLiteral.properties) {
172649
+ if (!import_typescript2.default.isPropertyAssignment(property)) {
172650
+ continue;
172651
+ }
172652
+ const propertyName = getPropertyNameText(property.name);
172653
+ if (propertyName !== key) {
172654
+ continue;
172655
+ }
172656
+ if (property.initializer.kind === import_typescript2.default.SyntaxKind.TrueKeyword) {
172657
+ return true;
172658
+ }
172659
+ if (property.initializer.kind === import_typescript2.default.SyntaxKind.FalseKeyword) {
172660
+ return false;
172661
+ }
172662
+ throw new Error(`${entryName}[${elementIndex}] must use a boolean literal for "${key}" in scripts/block-config.ts.`);
172663
+ }
172664
+ return;
172665
+ }
172193
172666
  function isMissingRequiredInventoryValue(value) {
172194
172667
  return value === undefined || typeof value === "string" && value.length === 0;
172195
172668
  }
@@ -172210,7 +172683,7 @@ function parseInventoryEntries(arrayLiteral, descriptor) {
172210
172683
  const entry = {};
172211
172684
  for (const field of descriptor.fields) {
172212
172685
  const kind = field.kind ?? "string";
172213
- const value = kind === "stringArray" ? getOptionalStringArrayProperty(descriptor.entryName, elementIndex, element, field.key) : getOptionalStringProperty(descriptor.entryName, elementIndex, element, field.key);
172686
+ const value = kind === "stringArray" ? getOptionalStringArrayProperty(descriptor.entryName, elementIndex, element, field.key) : kind === "boolean" ? getOptionalBooleanProperty(descriptor.entryName, elementIndex, element, field.key) : getOptionalStringProperty(descriptor.entryName, elementIndex, element, field.key);
172214
172687
  field.validate?.(value, {
172215
172688
  elementIndex,
172216
172689
  entryName: descriptor.entryName,
@@ -172264,6 +172737,7 @@ function parseWorkspaceInventorySource(source) {
172264
172737
  blockStyles: [],
172265
172738
  blockTransforms: [],
172266
172739
  blocks: parseInventorySection(sourceFile, BLOCK_INVENTORY_SECTION).entries,
172740
+ contracts: [],
172267
172741
  editorPlugins: [],
172268
172742
  hasAbilitiesSection: false,
172269
172743
  hasAdminViewsSection: false,
@@ -172271,11 +172745,14 @@ function parseWorkspaceInventorySource(source) {
172271
172745
  hasBindingSourcesSection: false,
172272
172746
  hasBlockStylesSection: false,
172273
172747
  hasBlockTransformsSection: false,
172748
+ hasContractsSection: false,
172274
172749
  hasEditorPluginsSection: false,
172275
172750
  hasPatternsSection: false,
172751
+ hasPostMetaSection: false,
172276
172752
  hasRestResourcesSection: false,
172277
172753
  hasVariationsSection: false,
172278
172754
  patterns: [],
172755
+ postMeta: [],
172279
172756
  restResources: [],
172280
172757
  source,
172281
172758
  variations: []
@@ -172717,7 +173194,7 @@ function replacePhpFunctionDefinition(source, functionName, replacement, options
172717
173194
  function ensureWorkspaceInventorySections(source) {
172718
173195
  let nextSource = source.trimEnd();
172719
173196
  for (const section of INVENTORY_SECTIONS) {
172720
- if (section.interface && !hasExportedInterface(nextSource, section.interface.name)) {
173197
+ if (section.interface && !hasExportedTypeDeclaration(nextSource, section.interface.name)) {
172721
173198
  nextSource += section.interface.section;
172722
173199
  }
172723
173200
  if (section.value && !hasExportedConst(nextSource, section.value.name)) {
@@ -172727,8 +173204,8 @@ function ensureWorkspaceInventorySections(source) {
172727
173204
  return `${nextSource}
172728
173205
  `;
172729
173206
  }
172730
- function hasExportedInterface(source, interfaceName) {
172731
- return new RegExp(`export\\s+interface\\s+${escapeRegex(interfaceName)}\\b`, "u").test(source);
173207
+ function hasExportedTypeDeclaration(source, interfaceName) {
173208
+ return new RegExp(`export\\s+(?:interface|type)\\s+${escapeRegex(interfaceName)}\\b`, "u").test(source);
172732
173209
  }
172733
173210
  function hasExportedConst(source, constName) {
172734
173211
  return new RegExp(`export\\s+const\\s+${escapeRegex(constName)}\\b`, "u").test(source);
@@ -172781,6 +173258,37 @@ function ensureInterfaceField(source, interfaceName, fieldName, fieldSource) {
172781
173258
  return `${start}${body}${body.length > 0 && !body.endsWith(lineEnding) ? lineEnding : ""}${formattedFieldSource}${end}`;
172782
173259
  });
172783
173260
  }
173261
+ function upsertInterfaceField(source, interfaceName, fieldName, fieldSource) {
173262
+ const interfacePattern = new RegExp(`(export\\s+interface\\s+${escapeRegex(interfaceName)}\\s*\\{\\r?\\n)([\\s\\S]*?)(\\r?\\n\\})`, "u");
173263
+ return source.replace(interfacePattern, (match, start, body, end) => {
173264
+ const lineEnding = start.endsWith(`\r
173265
+ `) ? `\r
173266
+ ` : `
173267
+ `;
173268
+ const formattedFieldSource = `${fieldSource.replace(/\r?\n$/u, "").split(`
173269
+ `).join(lineEnding)}${lineEnding}`;
173270
+ const existingFieldPattern = new RegExp(`(^[ \\t]*${escapeRegex(fieldName)}\\??:\\s*[^;\\r\\n]+;?\\r?\\n?)`, "mu");
173271
+ const existingFieldMatch = existingFieldPattern.exec(body);
173272
+ if (existingFieldMatch?.[0]) {
173273
+ if (existingFieldMatch[0].trim() === fieldSource.trim()) {
173274
+ return match;
173275
+ }
173276
+ return `${start}${body.slice(0, existingFieldMatch.index)}${formattedFieldSource}${body.slice(existingFieldMatch.index + existingFieldMatch[0].length)}${end}`;
173277
+ }
173278
+ const memberPattern = /^[ \t]*([A-Za-z_$][\w$]*)\??:/gmu;
173279
+ for (const member of body.matchAll(memberPattern)) {
173280
+ const memberIndex = member.index;
173281
+ const memberName = member[1];
173282
+ if (memberIndex === undefined || !memberName) {
173283
+ continue;
173284
+ }
173285
+ if (memberName.localeCompare(fieldName) > 0) {
173286
+ return `${start}${body.slice(0, memberIndex)}${formattedFieldSource}${body.slice(memberIndex)}${end}`;
173287
+ }
173288
+ }
173289
+ return `${start}${body}${body.length > 0 && !body.endsWith(lineEnding) ? lineEnding : ""}${formattedFieldSource}${end}`;
173290
+ });
173291
+ }
172784
173292
  function normalizeInterfaceFieldBlock(source, interfaceName, fieldName, fieldSource, requiredFragments) {
172785
173293
  const interfacePattern = new RegExp(`(export\\s+interface\\s+${escapeRegex(interfaceName)}\\s*\\{\\r?\\n)([\\s\\S]*?)(\\r?\\n\\})`, "u");
172786
173294
  return source.replace(interfacePattern, (match, start, body, end) => {
@@ -172814,6 +173322,25 @@ function updateWorkspaceInventorySource(source, options = {}) {
172814
173322
  nextSource = normalizeInterfaceFieldBlock(nextSource, "WorkspaceAbilityConfig", "compatibility", WORKSPACE_COMPATIBILITY_CONFIG_FIELD, ["optionalFeatureIds: string[];", "requiredFeatureIds: string[];"]);
172815
173323
  nextSource = ensureInterfaceField(nextSource, "WorkspaceAiFeatureConfig", "compatibility", WORKSPACE_COMPATIBILITY_CONFIG_FIELD);
172816
173324
  nextSource = normalizeInterfaceFieldBlock(nextSource, "WorkspaceAiFeatureConfig", "compatibility", WORKSPACE_COMPATIBILITY_CONFIG_FIELD, ["optionalFeatureIds: string[];", "requiredFeatureIds: string[];"]);
173325
+ for (const [fieldName, fieldSource] of [
173326
+ ["auth", "\tauth?: 'authenticated' | 'public' | 'public-write-protected';"],
173327
+ ["bodyTypeName", "\tbodyTypeName?: string;"],
173328
+ ["controllerClass", "\tcontrollerClass?: string;"],
173329
+ ["controllerExtends", "\tcontrollerExtends?: string;"],
173330
+ ["dataFile", "\tdataFile?: string;"],
173331
+ ["method", "\tmethod?: 'DELETE' | 'GET' | 'PATCH' | 'POST' | 'PUT';"],
173332
+ ["mode", "\tmode?: 'generated' | 'manual';"],
173333
+ ["pathPattern", "\tpathPattern?: string;"],
173334
+ ["permissionCallback", "\tpermissionCallback?: string;"],
173335
+ ["phpFile", "\tphpFile?: string;"],
173336
+ ["queryTypeName", "\tqueryTypeName?: string;"],
173337
+ ["responseTypeName", "\tresponseTypeName?: string;"],
173338
+ ["routePattern", "\troutePattern?: string;"],
173339
+ ["secretFieldName", "\tsecretFieldName?: string;"],
173340
+ ["secretStateFieldName", "\tsecretStateFieldName?: string;"]
173341
+ ]) {
173342
+ nextSource = upsertInterfaceField(nextSource, "WorkspaceRestResourceConfig", fieldName, fieldSource);
173343
+ }
172817
173344
  return nextSource;
172818
173345
  }
172819
173346
  async function appendWorkspaceInventoryEntries(projectDir, options) {
@@ -172824,6 +173351,6 @@ async function appendWorkspaceInventoryEntries(projectDir, options) {
172824
173351
  await writeFile(blockConfigPath, nextSource, "utf8");
172825
173352
  }
172826
173353
  }
172827
- export { toKebabCase, toSnakeCase, toPascalCase, toCamelCase, toSegmentPascalCase, toTitleCase, validateBlockSlug, validateNamespace, normalizeBlockSlug, resolveNonEmptyNormalizedBlockSlug, buildBlockCssClassName, buildFrontendCssClassName, resolveScaffoldIdentifiers, REST_RESOURCE_METHOD_IDS, EDITOR_PLUGIN_SLOT_IDS, resolveEditorPluginSlotAlias, ADD_BLOCK_TEMPLATE_IDS, suggestAddBlockTemplateId, HOOKED_BLOCK_POSITION_SET, HOOKED_BLOCK_ANCHOR_PATTERN, REST_RESOURCE_NAMESPACE_PATTERN, assertValidGeneratedSlug, resolveRestResourceNamespace, assertValidRestResourceMethods, assertValidHookedBlockPosition, buildWorkspacePhpPrefix, isAddBlockTemplateId, quoteTsString, assertValidHookAnchor, assertValidEditorPluginSlot, pathExists, readOptionalUtf8File, getNodeErrorCode, getOptionalNodeErrorCode, isFileNotFoundError, getWorkspaceBootstrapPath, patchFile, readOptionalFile, snapshotWorkspaceFiles, rollbackWorkspaceMutation, resolveWorkspaceBlock, readWorkspaceBlockJson, getMutableBlockHooks, assertVariationDoesNotExist, assertBlockStyleDoesNotExist, assertBlockTransformDoesNotExist, assertPatternDoesNotExist, assertBindingSourceDoesNotExist, assertRestResourceDoesNotExist, assertAdminViewDoesNotExist, assertAbilityDoesNotExist, assertAiFeatureDoesNotExist, assertEditorPluginDoesNotExist, formatAddHelpText, require_typescript, getPropertyNameText, readWorkspaceInventory, readWorkspaceInventoryAsync, getWorkspaceBlockSelectOptions, getWorkspaceBlockSelectOptionsAsync, escapeRegex, quotePhpString, hasPhpFunctionDefinition, hasPhpFunctionCall, findPhpFunctionRange, replacePhpFunctionDefinition, updateWorkspaceInventorySource, appendWorkspaceInventoryEntries };
173354
+ export { toKebabCase, toSnakeCase, toPascalCase, toCamelCase, toSegmentPascalCase, toTitleCase, validateBlockSlug, validateNamespace, normalizeBlockSlug, resolveNonEmptyNormalizedBlockSlug, buildBlockCssClassName, buildFrontendCssClassName, resolveScaffoldIdentifiers, REST_RESOURCE_METHOD_IDS, MANUAL_REST_CONTRACT_HTTP_METHOD_IDS, MANUAL_REST_CONTRACT_AUTH_IDS, EDITOR_PLUGIN_SLOT_IDS, resolveEditorPluginSlotAlias, ADD_BLOCK_TEMPLATE_IDS, suggestAddBlockTemplateId, HOOKED_BLOCK_POSITION_SET, HOOKED_BLOCK_ANCHOR_PATTERN, REST_RESOURCE_NAMESPACE_PATTERN, assertValidGeneratedSlug, assertValidTypeScriptIdentifier, resolveRestResourceNamespace, assertValidPostMetaPostType, resolvePostMetaKey, assertValidRestResourceMethods, resolveOptionalPhpCallbackReference, resolveOptionalPhpClassReference, assertValidManualRestContractHttpMethod, assertValidManualRestContractAuth, isGeneratedRestResourceRoutePatternCompatible, resolveManualRestContractPathPattern, resolveGeneratedRestResourceRoutePattern, assertValidHookedBlockPosition, buildWorkspacePhpPrefix, isAddBlockTemplateId, quoteTsString, assertValidHookAnchor, assertValidEditorPluginSlot, assertValidIntegrationEnvService, pathExists, readOptionalUtf8File, getNodeErrorCode, getOptionalNodeErrorCode, isFileNotFoundError, getWorkspaceBootstrapPath, patchFile, readOptionalFile, snapshotWorkspaceFiles, rollbackWorkspaceMutation, resolveWorkspaceBlock, readWorkspaceBlockJson, getMutableBlockHooks, assertVariationDoesNotExist, assertBlockStyleDoesNotExist, assertBlockTransformDoesNotExist, assertPatternDoesNotExist, assertBindingSourceDoesNotExist, assertRestResourceDoesNotExist, assertPostMetaDoesNotExist, assertContractDoesNotExist, assertAdminViewDoesNotExist, assertAbilityDoesNotExist, assertAiFeatureDoesNotExist, assertEditorPluginDoesNotExist, formatAddHelpText, require_typescript, getPropertyNameText, readWorkspaceInventory, readWorkspaceInventoryAsync, getWorkspaceBlockSelectOptions, getWorkspaceBlockSelectOptionsAsync, escapeRegex, quotePhpString, hasPhpFunctionDefinition, hasPhpFunctionCall, findPhpFunctionRange, replacePhpFunctionDefinition, updateWorkspaceInventorySource, appendWorkspaceInventoryEntries };
172828
173355
 
172829
- //# debugId=10B8DF3957EF445164756E2164756E21
173356
+ //# debugId=E79B1182F12A2D7664756E2164756E21