wp-typia 0.22.9 → 0.22.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -170947,7 +170947,9 @@ var ADD_BLOCK_TEMPLATE_IDS = [
170947
170947
  "compound"
170948
170948
  ];
170949
170949
  function suggestAddBlockTemplateId(templateId) {
170950
- return suggestCloseId(templateId, ADD_BLOCK_TEMPLATE_IDS);
170950
+ return suggestCloseId(templateId, ADD_BLOCK_TEMPLATE_IDS, {
170951
+ maxDistance: 3
170952
+ });
170951
170953
  }
170952
170954
 
170953
170955
  // ../wp-typia-project-tools/src/runtime/hooked-blocks.ts
@@ -171125,10 +171127,13 @@ async function readOptionalUtf8File(filePath) {
171125
171127
  }
171126
171128
  }
171127
171129
  function getNodeErrorCode(error) {
171128
- return typeof error === "object" && error !== null && "code" in error ? String(error.code) : "";
171130
+ return getOptionalNodeErrorCode(error) ?? "";
171131
+ }
171132
+ function getOptionalNodeErrorCode(error) {
171133
+ return typeof error === "object" && error !== null && "code" in error ? String(error.code) : undefined;
171129
171134
  }
171130
171135
  function isFileNotFoundError(error) {
171131
- return getNodeErrorCode(error) === "ENOENT";
171136
+ return getOptionalNodeErrorCode(error) === "ENOENT";
171132
171137
  }
171133
171138
 
171134
171139
  // ../wp-typia-project-tools/src/runtime/cli-add-help.ts
@@ -171260,14 +171265,7 @@ async function patchFile(filePath, transform) {
171260
171265
  }
171261
171266
  }
171262
171267
  async function readOptionalFile(filePath) {
171263
- try {
171264
- return await fsp2.readFile(filePath, "utf8");
171265
- } catch (error) {
171266
- if (isFileNotFoundError2(error)) {
171267
- return null;
171268
- }
171269
- throw error;
171270
- }
171268
+ return readOptionalUtf8File(filePath);
171271
171269
  }
171272
171270
  async function restoreOptionalFile(filePath, source) {
171273
171271
  if (source === null) {
@@ -171295,9 +171293,6 @@ async function rollbackWorkspaceMutation(snapshot) {
171295
171293
  await restoreOptionalFile(filePath, source);
171296
171294
  }
171297
171295
  }
171298
- function isFileNotFoundError2(error) {
171299
- return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
171300
- }
171301
171296
  // ../wp-typia-project-tools/src/runtime/cli-add-block-json.ts
171302
171297
  import path2 from "path";
171303
171298
  import { parseScaffoldBlockMetadata } from "@wp-typia/block-runtime/blocks";
@@ -171592,1122 +171587,1133 @@ function assertEditorPluginDoesNotExist(projectDir, editorPluginSlug, inventory)
171592
171587
  projectDir
171593
171588
  });
171594
171589
  }
171595
- // ../wp-typia-project-tools/src/runtime/workspace-inventory.ts
171596
- var import_typescript2 = __toESM(require_typescript(), 1);
171590
+ // ../wp-typia-project-tools/src/runtime/workspace-inventory-read.ts
171597
171591
  import { readFileSync } from "fs";
171598
171592
  import path4 from "path";
171599
- import { readFile, writeFile } from "fs/promises";
171593
+ import { readFile } from "fs/promises";
171600
171594
 
171601
- // ../wp-typia-project-tools/src/runtime/php-utils.ts
171602
- function escapeRegex(value) {
171603
- return value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
171595
+ // ../wp-typia-project-tools/src/runtime/workspace-inventory-parser.ts
171596
+ var import_typescript2 = __toESM(require_typescript(), 1);
171597
+
171598
+ // ../wp-typia-project-tools/src/runtime/ts-property-names.ts
171599
+ var import_typescript = __toESM(require_typescript(), 1);
171600
+ function getPropertyNameText(name) {
171601
+ if (import_typescript.default.isIdentifier(name) || import_typescript.default.isStringLiteral(name) || import_typescript.default.isNumericLiteral(name)) {
171602
+ return name.text;
171603
+ }
171604
+ return null;
171604
171605
  }
171605
- function quotePhpString(value) {
171606
- return `'${value.replace(/\\/gu, "\\\\").replace(/'/gu, "\\'")}'`;
171606
+
171607
+ // ../wp-typia-project-tools/src/runtime/workspace-inventory-templates.ts
171608
+ var BLOCK_CONFIG_ENTRY_MARKER = "\t// wp-typia add block entries";
171609
+ var VARIATION_CONFIG_ENTRY_MARKER = "\t// wp-typia add variation entries";
171610
+ var BLOCK_STYLE_CONFIG_ENTRY_MARKER = "\t// wp-typia add style entries";
171611
+ var BLOCK_TRANSFORM_CONFIG_ENTRY_MARKER = "\t// wp-typia add transform entries";
171612
+ var PATTERN_CONFIG_ENTRY_MARKER = "\t// wp-typia add pattern entries";
171613
+ var BINDING_SOURCE_CONFIG_ENTRY_MARKER = "\t// wp-typia add binding-source entries";
171614
+ var REST_RESOURCE_CONFIG_ENTRY_MARKER = "\t// wp-typia add rest-resource entries";
171615
+ var ABILITY_CONFIG_ENTRY_MARKER = "\t// wp-typia add ability entries";
171616
+ var AI_FEATURE_CONFIG_ENTRY_MARKER = "\t// wp-typia add ai-feature entries";
171617
+ var ADMIN_VIEW_CONFIG_ENTRY_MARKER = "\t// wp-typia add admin-view entries";
171618
+ var EDITOR_PLUGIN_CONFIG_ENTRY_MARKER = "\t// wp-typia add editor-plugin entries";
171619
+ var VARIATIONS_INTERFACE_SECTION = `
171620
+
171621
+ export interface WorkspaceVariationConfig {
171622
+ block: string;
171623
+ file: string;
171624
+ slug: string;
171607
171625
  }
171608
- function hasPhpFunctionDefinition(source, functionName) {
171609
- return new RegExp(`function\\s+${escapeRegex(functionName)}\\s*\\(`, "u").test(source);
171626
+ `;
171627
+ var VARIATIONS_CONST_SECTION = `
171628
+
171629
+ export const VARIATIONS: WorkspaceVariationConfig[] = [
171630
+ // wp-typia add variation entries
171631
+ ];
171632
+ `;
171633
+ var BLOCK_STYLES_INTERFACE_SECTION = `
171634
+
171635
+ export interface WorkspaceBlockStyleConfig {
171636
+ block: string;
171637
+ file: string;
171638
+ slug: string;
171610
171639
  }
171611
- function isPhpIdentifierStart(character) {
171612
- return /^[A-Za-z_]$/u.test(character ?? "");
171640
+ `;
171641
+ var BLOCK_STYLES_CONST_SECTION = `
171642
+
171643
+ export const BLOCK_STYLES: WorkspaceBlockStyleConfig[] = [
171644
+ // wp-typia add style entries
171645
+ ];
171646
+ `;
171647
+ var BLOCK_TRANSFORMS_INTERFACE_SECTION = `
171648
+
171649
+ export interface WorkspaceBlockTransformConfig {
171650
+ block: string;
171651
+ file: string;
171652
+ from: string;
171653
+ slug: string;
171654
+ to: string;
171613
171655
  }
171614
- function isPhpIdentifierPart(character) {
171615
- return /^[A-Za-z0-9_]$/u.test(character ?? "");
171656
+ `;
171657
+ var BLOCK_TRANSFORMS_CONST_SECTION = `
171658
+
171659
+ export const BLOCK_TRANSFORMS: WorkspaceBlockTransformConfig[] = [
171660
+ // wp-typia add transform entries
171661
+ ];
171662
+ `;
171663
+ var PATTERNS_INTERFACE_SECTION = `
171664
+
171665
+ export interface WorkspacePatternConfig {
171666
+ file: string;
171667
+ slug: string;
171616
171668
  }
171617
- function isPhpLineStart(source, index) {
171618
- return index === 0 || source[index - 1] === `
171619
171669
  `;
171670
+ var PATTERNS_CONST_SECTION = `
171671
+
171672
+ export const PATTERNS: WorkspacePatternConfig[] = [
171673
+ // wp-typia add pattern entries
171674
+ ];
171675
+ `;
171676
+ var BINDING_SOURCES_INTERFACE_SECTION = `
171677
+
171678
+ export interface WorkspaceBindingSourceConfig {
171679
+ attribute?: string;
171680
+ block?: string;
171681
+ editorFile: string;
171682
+ serverFile: string;
171683
+ slug: string;
171620
171684
  }
171621
- function isPhpHorizontalWhitespace(character) {
171622
- return character === " " || character === "\t";
171685
+ `;
171686
+ var BINDING_SOURCES_CONST_SECTION = `
171687
+
171688
+ export const BINDING_SOURCES: WorkspaceBindingSourceConfig[] = [
171689
+ // wp-typia add binding-source entries
171690
+ ];
171691
+ `;
171692
+ var REST_RESOURCES_INTERFACE_SECTION = `
171693
+
171694
+ export interface WorkspaceRestResourceConfig {
171695
+ apiFile: string;
171696
+ clientFile: string;
171697
+ dataFile: string;
171698
+ methods: Array< 'list' | 'read' | 'create' | 'update' | 'delete' >;
171699
+ namespace: string;
171700
+ openApiFile: string;
171701
+ phpFile: string;
171702
+ restManifest?: ReturnType<
171703
+ typeof import( '@wp-typia/block-runtime/metadata-core' ).defineEndpointManifest
171704
+ >;
171705
+ slug: string;
171706
+ typesFile: string;
171707
+ validatorsFile: string;
171623
171708
  }
171624
- function isPhpWhitespace(character) {
171625
- return typeof character === "string" && /\s/u.test(character);
171709
+ `;
171710
+ var REST_RESOURCES_CONST_SECTION = `
171711
+
171712
+ export const REST_RESOURCES: WorkspaceRestResourceConfig[] = [
171713
+ // wp-typia add rest-resource entries
171714
+ ];
171715
+ `;
171716
+ var WORKSPACE_COMPATIBILITY_CONFIG_FIELD = ` compatibility?: {
171717
+ hardMinimums: {
171718
+ php?: string;
171719
+ wordpress?: string;
171720
+ };
171721
+ mode: 'baseline' | 'optional' | 'required';
171722
+ optionalFeatureIds: string[];
171723
+ optionalFeatures: string[];
171724
+ requiredFeatureIds: string[];
171725
+ requiredFeatures: string[];
171726
+ runtimeGates: string[];
171727
+ };
171728
+ `;
171729
+ var ABILITIES_INTERFACE_SECTION = `
171730
+
171731
+ export interface WorkspaceAbilityConfig {
171732
+ clientFile: string;
171733
+ ${WORKSPACE_COMPATIBILITY_CONFIG_FIELD} configFile: string;
171734
+ dataFile: string;
171735
+ inputSchemaFile: string;
171736
+ inputTypeName: string;
171737
+ outputSchemaFile: string;
171738
+ outputTypeName: string;
171739
+ phpFile: string;
171740
+ slug: string;
171741
+ typesFile: string;
171626
171742
  }
171627
- function findPhpLineBoundary(source, index) {
171628
- const newlineIndex = source.indexOf(`
171629
- `, index);
171630
- if (newlineIndex === -1) {
171631
- return {
171632
- contentEnd: source.endsWith("\r") ? source.length - 1 : source.length,
171633
- nextStart: source.length
171634
- };
171635
- }
171636
- return {
171637
- contentEnd: source[newlineIndex - 1] === "\r" ? newlineIndex - 1 : newlineIndex,
171638
- nextStart: newlineIndex + 1
171639
- };
171743
+ `;
171744
+ var ABILITIES_CONST_SECTION = `
171745
+
171746
+ export const ABILITIES: WorkspaceAbilityConfig[] = [
171747
+ // wp-typia add ability entries
171748
+ ];
171749
+ `;
171750
+ var AI_FEATURES_INTERFACE_SECTION = `
171751
+
171752
+ export interface WorkspaceAiFeatureConfig {
171753
+ aiSchemaFile: string;
171754
+ apiFile: string;
171755
+ clientFile: string;
171756
+ ${WORKSPACE_COMPATIBILITY_CONFIG_FIELD} dataFile: string;
171757
+ namespace: string;
171758
+ openApiFile: string;
171759
+ phpFile: string;
171760
+ restManifest?: ReturnType<
171761
+ typeof import( '@wp-typia/block-runtime/metadata-core' ).defineEndpointManifest
171762
+ >;
171763
+ slug: string;
171764
+ typesFile: string;
171765
+ validatorsFile: string;
171640
171766
  }
171641
- function parsePhpHeredocStart(source, index) {
171642
- if (!source.startsWith("<<<", index)) {
171643
- return null;
171644
- }
171645
- let cursor = index + 3;
171646
- while (isPhpHorizontalWhitespace(source[cursor])) {
171647
- cursor += 1;
171648
- }
171649
- const quote = source[cursor] === "'" || source[cursor] === '"' ? source[cursor] : "";
171650
- if (quote) {
171651
- cursor += 1;
171652
- }
171653
- if (!isPhpIdentifierStart(source[cursor])) {
171654
- return null;
171655
- }
171656
- const delimiterStart = cursor;
171657
- cursor += 1;
171658
- while (isPhpIdentifierPart(source[cursor])) {
171659
- cursor += 1;
171660
- }
171661
- const delimiter = source.slice(delimiterStart, cursor);
171662
- if (quote) {
171663
- if (source[cursor] !== quote) {
171664
- return null;
171665
- }
171666
- cursor += 1;
171667
- }
171668
- const lineBoundary = findPhpLineBoundary(source, cursor);
171669
- if (source.slice(cursor, lineBoundary.contentEnd).trim() !== "") {
171670
- return null;
171671
- }
171672
- return {
171673
- contentStart: lineBoundary.nextStart,
171674
- delimiter
171675
- };
171767
+ `;
171768
+ var AI_FEATURES_CONST_SECTION = `
171769
+
171770
+ export const AI_FEATURES: WorkspaceAiFeatureConfig[] = [
171771
+ // wp-typia add ai-feature entries
171772
+ ];
171773
+ `;
171774
+ var ADMIN_VIEWS_INTERFACE_SECTION = `
171775
+
171776
+ export interface WorkspaceAdminViewConfig {
171777
+ file: string;
171778
+ phpFile: string;
171779
+ slug: string;
171780
+ source?: string;
171676
171781
  }
171677
- function findPhpHeredocClosingEnd(source, index, delimiter) {
171678
- if (!isPhpLineStart(source, index)) {
171679
- return null;
171680
- }
171681
- let cursor = index;
171682
- while (isPhpHorizontalWhitespace(source[cursor])) {
171683
- cursor += 1;
171684
- }
171685
- if (!source.startsWith(delimiter, cursor)) {
171686
- return null;
171687
- }
171688
- cursor += delimiter.length;
171689
- if (isPhpIdentifierPart(source[cursor])) {
171690
- return null;
171691
- }
171692
- let continuationCursor = cursor;
171693
- while (isPhpHorizontalWhitespace(source[continuationCursor])) {
171694
- continuationCursor += 1;
171695
- }
171696
- const continuation = source[continuationCursor];
171697
- if (continuationCursor >= source.length || continuation === "\r" || continuation === `
171698
- ` || !isPhpIdentifierPart(continuation)) {
171699
- return cursor;
171700
- }
171701
- return null;
171702
- }
171703
- function skipPhpCallTrivia(source, index) {
171704
- let cursor = index;
171705
- while (cursor < source.length) {
171706
- while (isPhpWhitespace(source[cursor])) {
171707
- cursor += 1;
171708
- }
171709
- if (source[cursor] === "/" && source[cursor + 1] === "*") {
171710
- const commentEnd = source.indexOf("*/", cursor + 2);
171711
- if (commentEnd === -1) {
171712
- return null;
171713
- }
171714
- cursor = commentEnd + 2;
171715
- continue;
171716
- }
171717
- if (source[cursor] === "/" && source[cursor + 1] === "/") {
171718
- cursor = findPhpLineBoundary(source, cursor + 2).nextStart;
171719
- continue;
171720
- }
171721
- if (source[cursor] === "#" && source[cursor + 1] !== "[") {
171722
- cursor = findPhpLineBoundary(source, cursor + 1).nextStart;
171723
- continue;
171724
- }
171725
- return cursor;
171726
- }
171727
- return cursor;
171728
- }
171729
- function matchesPhpFunctionCallAt(source, index, functionName) {
171730
- if (!source.startsWith(functionName, index)) {
171731
- return false;
171732
- }
171733
- if (isPhpIdentifierPart(source[index - 1])) {
171734
- return false;
171735
- }
171736
- const cursor = index + functionName.length;
171737
- if (isPhpIdentifierPart(source[cursor])) {
171738
- return false;
171739
- }
171740
- const callStart = skipPhpCallTrivia(source, cursor);
171741
- return callStart !== null && source[callStart] === "(";
171782
+ `;
171783
+ var ADMIN_VIEWS_CONST_SECTION = `
171784
+
171785
+ export const ADMIN_VIEWS: WorkspaceAdminViewConfig[] = [
171786
+ // wp-typia add admin-view entries
171787
+ ];
171788
+ `;
171789
+ var EDITOR_PLUGINS_INTERFACE_SECTION = `
171790
+
171791
+ export interface WorkspaceEditorPluginConfig {
171792
+ file: string;
171793
+ slug: string;
171794
+ slot: string;
171742
171795
  }
171743
- function createPhpScannerState() {
171744
- return {
171745
- heredocDelimiter: "",
171746
- interpolationComment: "",
171747
- interpolationDepth: 0,
171748
- interpolationQuote: "",
171749
- mode: "code"
171750
- };
171796
+ `;
171797
+ var EDITOR_PLUGINS_CONST_SECTION = `
171798
+
171799
+ export const EDITOR_PLUGINS: WorkspaceEditorPluginConfig[] = [
171800
+ // wp-typia add editor-plugin entries
171801
+ ];
171802
+ `;
171803
+
171804
+ // ../wp-typia-project-tools/src/runtime/workspace-inventory-parser.ts
171805
+ function defineInventoryEntryParser() {
171806
+ return (descriptor) => descriptor;
171751
171807
  }
171752
- function advancePhpScanner(source, index, state) {
171753
- const character = source[index];
171754
- if (state.mode === "heredoc") {
171755
- const closingEnd = findPhpHeredocClosingEnd(source, index, state.heredocDelimiter);
171756
- if (closingEnd !== null) {
171757
- state.mode = "code";
171758
- state.heredocDelimiter = "";
171759
- return { ambiguous: false, inCode: false, index: closingEnd };
171760
- }
171761
- const nextLineStart = findPhpLineBoundary(source, index).nextStart;
171762
- if (nextLineStart <= index) {
171763
- return { ambiguous: true, inCode: false, index };
171764
- }
171765
- return { ambiguous: false, inCode: false, index: nextLineStart };
171808
+ var BLOCK_INVENTORY_SECTION = {
171809
+ append: {
171810
+ marker: BLOCK_CONFIG_ENTRY_MARKER,
171811
+ optionKey: "blockEntries"
171812
+ },
171813
+ parse: {
171814
+ entriesKey: "blocks",
171815
+ entry: defineInventoryEntryParser()({
171816
+ entryName: "BLOCKS",
171817
+ fields: [
171818
+ { key: "apiTypesFile" },
171819
+ { key: "attributeTypeName" },
171820
+ { key: "openApiFile" },
171821
+ { key: "slug", required: true },
171822
+ { key: "typesFile", required: true }
171823
+ ]
171824
+ }),
171825
+ exportName: "BLOCKS",
171826
+ required: true
171766
171827
  }
171767
- if (state.mode === "single-quoted" || state.mode === "double-quoted") {
171768
- const quote = state.mode === "single-quoted" ? "'" : '"';
171769
- if (character === "\\") {
171770
- return { ambiguous: false, inCode: false, index: index + 2 };
171771
- }
171772
- if (state.mode === "double-quoted" && character === "{" && source[index + 1] === "$") {
171773
- state.mode = "double-quoted-interpolation";
171774
- state.interpolationComment = "";
171775
- state.interpolationDepth = 1;
171776
- state.interpolationQuote = "";
171777
- return { ambiguous: false, inCode: false, index: index + 2 };
171828
+ };
171829
+ var INVENTORY_SECTIONS = [
171830
+ {
171831
+ append: {
171832
+ marker: VARIATION_CONFIG_ENTRY_MARKER,
171833
+ optionKey: "variationEntries"
171834
+ },
171835
+ interface: {
171836
+ name: "WorkspaceVariationConfig",
171837
+ section: VARIATIONS_INTERFACE_SECTION
171838
+ },
171839
+ parse: {
171840
+ entriesKey: "variations",
171841
+ entry: defineInventoryEntryParser()({
171842
+ entryName: "VARIATIONS",
171843
+ fields: [
171844
+ { key: "block", required: true },
171845
+ { key: "file", required: true },
171846
+ { key: "slug", required: true }
171847
+ ]
171848
+ }),
171849
+ hasSectionKey: "hasVariationsSection"
171850
+ },
171851
+ value: {
171852
+ name: "VARIATIONS",
171853
+ section: VARIATIONS_CONST_SECTION
171778
171854
  }
171779
- if (character === quote) {
171780
- state.mode = "code";
171855
+ },
171856
+ {
171857
+ append: {
171858
+ marker: BLOCK_STYLE_CONFIG_ENTRY_MARKER,
171859
+ optionKey: "blockStyleEntries"
171860
+ },
171861
+ interface: {
171862
+ name: "WorkspaceBlockStyleConfig",
171863
+ section: BLOCK_STYLES_INTERFACE_SECTION
171864
+ },
171865
+ parse: {
171866
+ entriesKey: "blockStyles",
171867
+ entry: defineInventoryEntryParser()({
171868
+ entryName: "BLOCK_STYLES",
171869
+ fields: [
171870
+ { key: "block", required: true },
171871
+ { key: "file", required: true },
171872
+ { key: "slug", required: true }
171873
+ ]
171874
+ }),
171875
+ hasSectionKey: "hasBlockStylesSection"
171876
+ },
171877
+ value: {
171878
+ name: "BLOCK_STYLES",
171879
+ section: BLOCK_STYLES_CONST_SECTION
171781
171880
  }
171782
- return { ambiguous: false, inCode: false, index: index + 1 };
171783
- }
171784
- if (state.mode === "double-quoted-interpolation") {
171785
- if (state.interpolationQuote) {
171786
- if (character === "\\") {
171787
- return { ambiguous: false, inCode: false, index: index + 2 };
171788
- }
171789
- if (character === state.interpolationQuote) {
171790
- state.interpolationQuote = "";
171791
- }
171792
- return { ambiguous: false, inCode: false, index: index + 1 };
171881
+ },
171882
+ {
171883
+ append: {
171884
+ marker: BLOCK_TRANSFORM_CONFIG_ENTRY_MARKER,
171885
+ optionKey: "blockTransformEntries"
171886
+ },
171887
+ interface: {
171888
+ name: "WorkspaceBlockTransformConfig",
171889
+ section: BLOCK_TRANSFORMS_INTERFACE_SECTION
171890
+ },
171891
+ parse: {
171892
+ entriesKey: "blockTransforms",
171893
+ entry: defineInventoryEntryParser()({
171894
+ entryName: "BLOCK_TRANSFORMS",
171895
+ fields: [
171896
+ { key: "block", required: true },
171897
+ { key: "file", required: true },
171898
+ { key: "from", required: true },
171899
+ { key: "slug", required: true },
171900
+ { key: "to", required: true }
171901
+ ]
171902
+ }),
171903
+ hasSectionKey: "hasBlockTransformsSection"
171904
+ },
171905
+ value: {
171906
+ name: "BLOCK_TRANSFORMS",
171907
+ section: BLOCK_TRANSFORMS_CONST_SECTION
171793
171908
  }
171794
- if (state.interpolationComment === "line") {
171795
- if (character === "\r" || character === `
171796
- `) {
171797
- state.interpolationComment = "";
171798
- }
171799
- return { ambiguous: false, inCode: false, index: index + 1 };
171909
+ },
171910
+ {
171911
+ append: {
171912
+ marker: PATTERN_CONFIG_ENTRY_MARKER,
171913
+ optionKey: "patternEntries"
171914
+ },
171915
+ interface: {
171916
+ name: "WorkspacePatternConfig",
171917
+ section: PATTERNS_INTERFACE_SECTION
171918
+ },
171919
+ parse: {
171920
+ entriesKey: "patterns",
171921
+ entry: defineInventoryEntryParser()({
171922
+ entryName: "PATTERNS",
171923
+ fields: [
171924
+ { key: "file", required: true },
171925
+ { key: "slug", required: true }
171926
+ ]
171927
+ }),
171928
+ hasSectionKey: "hasPatternsSection"
171929
+ },
171930
+ value: {
171931
+ name: "PATTERNS",
171932
+ section: PATTERNS_CONST_SECTION
171800
171933
  }
171801
- if (state.interpolationComment === "block") {
171802
- if (character === "*" && source[index + 1] === "/") {
171803
- state.interpolationComment = "";
171804
- return { ambiguous: false, inCode: false, index: index + 2 };
171805
- }
171806
- return { ambiguous: false, inCode: false, index: index + 1 };
171807
- }
171808
- if (character === "/" && source[index + 1] === "/") {
171809
- state.interpolationComment = "line";
171810
- return { ambiguous: false, inCode: false, index: index + 2 };
171934
+ },
171935
+ {
171936
+ append: {
171937
+ marker: BINDING_SOURCE_CONFIG_ENTRY_MARKER,
171938
+ optionKey: "bindingSourceEntries"
171939
+ },
171940
+ interface: {
171941
+ name: "WorkspaceBindingSourceConfig",
171942
+ section: BINDING_SOURCES_INTERFACE_SECTION
171943
+ },
171944
+ parse: {
171945
+ entriesKey: "bindingSources",
171946
+ entry: defineInventoryEntryParser()({
171947
+ entryName: "BINDING_SOURCES",
171948
+ fields: [
171949
+ { key: "attribute" },
171950
+ { key: "block" },
171951
+ { key: "editorFile", required: true },
171952
+ { key: "serverFile", required: true },
171953
+ { key: "slug", required: true }
171954
+ ]
171955
+ }),
171956
+ hasSectionKey: "hasBindingSourcesSection"
171957
+ },
171958
+ value: {
171959
+ name: "BINDING_SOURCES",
171960
+ section: BINDING_SOURCES_CONST_SECTION
171811
171961
  }
171812
- if (character === "#" && source[index + 1] !== "[") {
171813
- state.interpolationComment = "line";
171814
- return { ambiguous: false, inCode: false, index: index + 1 };
171962
+ },
171963
+ {
171964
+ append: {
171965
+ marker: REST_RESOURCE_CONFIG_ENTRY_MARKER,
171966
+ optionKey: "restResourceEntries"
171967
+ },
171968
+ interface: {
171969
+ name: "WorkspaceRestResourceConfig",
171970
+ section: REST_RESOURCES_INTERFACE_SECTION
171971
+ },
171972
+ parse: {
171973
+ entriesKey: "restResources",
171974
+ entry: defineInventoryEntryParser()({
171975
+ entryName: "REST_RESOURCES",
171976
+ fields: [
171977
+ { key: "apiFile", required: true },
171978
+ { key: "clientFile", required: true },
171979
+ { key: "dataFile", required: true },
171980
+ {
171981
+ key: "methods",
171982
+ kind: "stringArray",
171983
+ required: true,
171984
+ validate: (value, context) => {
171985
+ const methods = Array.isArray(value) ? value : [];
171986
+ const invalidMethods = methods.filter((method) => !REST_RESOURCE_METHOD_IDS.includes(method));
171987
+ if (invalidMethods.length > 0) {
171988
+ throw new Error(`${context.entryName}[${context.elementIndex}].${context.key} includes unsupported values: ${invalidMethods.join(", ")}.`);
171989
+ }
171990
+ }
171991
+ },
171992
+ { key: "namespace", required: true },
171993
+ { key: "openApiFile", required: true },
171994
+ { key: "phpFile", required: true },
171995
+ { key: "slug", required: true },
171996
+ { key: "typesFile", required: true },
171997
+ { key: "validatorsFile", required: true }
171998
+ ]
171999
+ }),
172000
+ hasSectionKey: "hasRestResourcesSection"
172001
+ },
172002
+ value: {
172003
+ name: "REST_RESOURCES",
172004
+ section: REST_RESOURCES_CONST_SECTION
171815
172005
  }
171816
- if (character === "/" && source[index + 1] === "*") {
171817
- state.interpolationComment = "block";
171818
- return { ambiguous: false, inCode: false, index: index + 2 };
172006
+ },
172007
+ {
172008
+ append: {
172009
+ marker: ABILITY_CONFIG_ENTRY_MARKER,
172010
+ optionKey: "abilityEntries"
172011
+ },
172012
+ interface: {
172013
+ name: "WorkspaceAbilityConfig",
172014
+ section: ABILITIES_INTERFACE_SECTION
172015
+ },
172016
+ parse: {
172017
+ entriesKey: "abilities",
172018
+ entry: defineInventoryEntryParser()({
172019
+ entryName: "ABILITIES",
172020
+ fields: [
172021
+ { key: "clientFile", required: true },
172022
+ { key: "configFile", required: true },
172023
+ { key: "dataFile", required: true },
172024
+ { key: "inputSchemaFile", required: true },
172025
+ { key: "inputTypeName", required: true },
172026
+ { key: "outputSchemaFile", required: true },
172027
+ { key: "outputTypeName", required: true },
172028
+ { key: "phpFile", required: true },
172029
+ { key: "slug", required: true },
172030
+ { key: "typesFile", required: true }
172031
+ ]
172032
+ }),
172033
+ hasSectionKey: "hasAbilitiesSection"
172034
+ },
172035
+ value: {
172036
+ name: "ABILITIES",
172037
+ section: ABILITIES_CONST_SECTION
171819
172038
  }
171820
- if (character === "'" || character === '"') {
171821
- state.interpolationQuote = character;
171822
- return { ambiguous: false, inCode: false, index: index + 1 };
172039
+ },
172040
+ {
172041
+ append: {
172042
+ marker: AI_FEATURE_CONFIG_ENTRY_MARKER,
172043
+ optionKey: "aiFeatureEntries"
172044
+ },
172045
+ interface: {
172046
+ name: "WorkspaceAiFeatureConfig",
172047
+ section: AI_FEATURES_INTERFACE_SECTION
172048
+ },
172049
+ parse: {
172050
+ entriesKey: "aiFeatures",
172051
+ entry: defineInventoryEntryParser()({
172052
+ entryName: "AI_FEATURES",
172053
+ fields: [
172054
+ { key: "aiSchemaFile", required: true },
172055
+ { key: "apiFile", required: true },
172056
+ { key: "clientFile", required: true },
172057
+ { key: "dataFile", required: true },
172058
+ { key: "namespace", required: true },
172059
+ { key: "openApiFile", required: true },
172060
+ { key: "phpFile", required: true },
172061
+ { key: "slug", required: true },
172062
+ { key: "typesFile", required: true },
172063
+ { key: "validatorsFile", required: true }
172064
+ ]
172065
+ }),
172066
+ hasSectionKey: "hasAiFeaturesSection"
172067
+ },
172068
+ value: {
172069
+ name: "AI_FEATURES",
172070
+ section: AI_FEATURES_CONST_SECTION
171823
172071
  }
171824
- if (character === "{") {
171825
- state.interpolationDepth += 1;
171826
- return { ambiguous: false, inCode: false, index: index + 1 };
172072
+ },
172073
+ {
172074
+ append: {
172075
+ marker: ADMIN_VIEW_CONFIG_ENTRY_MARKER,
172076
+ optionKey: "adminViewEntries"
172077
+ },
172078
+ interface: {
172079
+ name: "WorkspaceAdminViewConfig",
172080
+ section: ADMIN_VIEWS_INTERFACE_SECTION
172081
+ },
172082
+ parse: {
172083
+ entriesKey: "adminViews",
172084
+ entry: defineInventoryEntryParser()({
172085
+ entryName: "ADMIN_VIEWS",
172086
+ fields: [
172087
+ { key: "file", required: true },
172088
+ { key: "phpFile", required: true },
172089
+ { key: "slug", required: true },
172090
+ { key: "source" }
172091
+ ]
172092
+ }),
172093
+ hasSectionKey: "hasAdminViewsSection"
172094
+ },
172095
+ value: {
172096
+ name: "ADMIN_VIEWS",
172097
+ section: ADMIN_VIEWS_CONST_SECTION
171827
172098
  }
171828
- if (character === "}") {
171829
- state.interpolationDepth -= 1;
171830
- if (state.interpolationDepth <= 0) {
171831
- state.interpolationComment = "";
171832
- state.interpolationDepth = 0;
171833
- state.mode = "double-quoted";
171834
- }
171835
- return { ambiguous: false, inCode: false, index: index + 1 };
172099
+ },
172100
+ {
172101
+ append: {
172102
+ marker: EDITOR_PLUGIN_CONFIG_ENTRY_MARKER,
172103
+ optionKey: "editorPluginEntries"
172104
+ },
172105
+ interface: {
172106
+ name: "WorkspaceEditorPluginConfig",
172107
+ section: EDITOR_PLUGINS_INTERFACE_SECTION
172108
+ },
172109
+ parse: {
172110
+ entriesKey: "editorPlugins",
172111
+ entry: defineInventoryEntryParser()({
172112
+ entryName: "EDITOR_PLUGINS",
172113
+ fields: [
172114
+ { key: "file", required: true },
172115
+ { key: "slug", required: true },
172116
+ { key: "slot", required: true }
172117
+ ]
172118
+ }),
172119
+ hasSectionKey: "hasEditorPluginsSection"
172120
+ },
172121
+ value: {
172122
+ name: "EDITOR_PLUGINS",
172123
+ section: EDITOR_PLUGINS_CONST_SECTION
171836
172124
  }
171837
- return { ambiguous: false, inCode: false, index: index + 1 };
171838
172125
  }
171839
- if (state.mode === "line-comment") {
171840
- if (character === "\r" || character === `
171841
- `) {
171842
- state.mode = "code";
172126
+ ];
172127
+ function findExportedArrayLiteral(sourceFile, exportName) {
172128
+ for (const statement of sourceFile.statements) {
172129
+ if (!import_typescript2.default.isVariableStatement(statement)) {
172130
+ continue;
171843
172131
  }
171844
- return { ambiguous: false, inCode: false, index: index + 1 };
171845
- }
171846
- if (state.mode === "block-comment") {
171847
- if (character === "*" && source[index + 1] === "/") {
171848
- state.mode = "code";
171849
- return { ambiguous: false, inCode: false, index: index + 2 };
172132
+ if (!statement.modifiers?.some((modifier) => modifier.kind === import_typescript2.default.SyntaxKind.ExportKeyword)) {
172133
+ continue;
172134
+ }
172135
+ for (const declaration of statement.declarationList.declarations) {
172136
+ if (!import_typescript2.default.isIdentifier(declaration.name) || declaration.name.text !== exportName) {
172137
+ continue;
172138
+ }
172139
+ if (declaration.initializer && import_typescript2.default.isArrayLiteralExpression(declaration.initializer)) {
172140
+ return {
172141
+ array: declaration.initializer,
172142
+ found: true
172143
+ };
172144
+ }
172145
+ return {
172146
+ array: null,
172147
+ found: true
172148
+ };
171850
172149
  }
171851
- return { ambiguous: false, inCode: false, index: index + 1 };
171852
- }
171853
- if (character === "'") {
171854
- state.mode = "single-quoted";
171855
- return { ambiguous: false, inCode: false, index: index + 1 };
171856
- }
171857
- if (character === '"') {
171858
- state.mode = "double-quoted";
171859
- return { ambiguous: false, inCode: false, index: index + 1 };
171860
172150
  }
171861
- if (character === "/" && source[index + 1] === "/") {
171862
- state.mode = "line-comment";
171863
- return { ambiguous: false, inCode: false, index: index + 2 };
171864
- }
171865
- if (character === "#" && source[index + 1] !== "[") {
171866
- state.mode = "line-comment";
171867
- return { ambiguous: false, inCode: false, index: index + 1 };
171868
- }
171869
- if (character === "/" && source[index + 1] === "*") {
171870
- state.mode = "block-comment";
171871
- return { ambiguous: false, inCode: false, index: index + 2 };
171872
- }
171873
- if (character === "<") {
171874
- const heredocStart = parsePhpHeredocStart(source, index);
171875
- if (heredocStart) {
171876
- state.mode = "heredoc";
171877
- state.heredocDelimiter = heredocStart.delimiter;
171878
- return {
171879
- ambiguous: false,
171880
- inCode: false,
171881
- index: heredocStart.contentStart
171882
- };
171883
- }
171884
- }
171885
- return { ambiguous: false, inCode: true, index };
172151
+ return {
172152
+ array: null,
172153
+ found: false
172154
+ };
171886
172155
  }
171887
- function hasPhpFunctionCall(source, functionName) {
171888
- const scanner = createPhpScannerState();
171889
- let index = 0;
171890
- while (index < source.length) {
171891
- const scan = advancePhpScanner(source, index, scanner);
171892
- if (scan.ambiguous) {
171893
- return false;
172156
+ function getOptionalStringProperty(entryName, elementIndex, objectLiteral, key) {
172157
+ for (const property of objectLiteral.properties) {
172158
+ if (!import_typescript2.default.isPropertyAssignment(property)) {
172159
+ continue;
171894
172160
  }
171895
- if (!scan.inCode) {
171896
- index = scan.index;
172161
+ const propertyName = getPropertyNameText(property.name);
172162
+ if (propertyName !== key) {
171897
172163
  continue;
171898
172164
  }
171899
- if (matchesPhpFunctionCallAt(source, index, functionName)) {
171900
- return true;
172165
+ if (import_typescript2.default.isStringLiteralLike(property.initializer)) {
172166
+ return property.initializer.text;
171901
172167
  }
171902
- index += 1;
172168
+ throw new Error(`${entryName}[${elementIndex}] must use a string literal for "${key}" in scripts/block-config.ts.`);
171903
172169
  }
171904
- return false;
172170
+ return;
171905
172171
  }
171906
- function findPhpFunctionRange(source, functionName, options = {}) {
171907
- const signaturePattern = new RegExp(`function\\s+${escapeRegex(functionName)}\\s*\\([^)]*\\)\\s*(?::\\s*[^{};]+)?\\s*\\{`, "u");
171908
- const signatureMatch = signaturePattern.exec(source);
171909
- if (!signatureMatch) {
171910
- return null;
171911
- }
171912
- const functionStart = signatureMatch.index;
171913
- const openBraceOffset = signatureMatch[0].lastIndexOf("{");
171914
- if (openBraceOffset === -1) {
171915
- return null;
171916
- }
171917
- const openBraceIndex = functionStart + openBraceOffset;
171918
- let depth = 0;
171919
- const scanner = createPhpScannerState();
171920
- let index = openBraceIndex;
171921
- while (index < source.length) {
171922
- const scan = advancePhpScanner(source, index, scanner);
171923
- if (scan.ambiguous) {
171924
- return null;
171925
- }
171926
- if (!scan.inCode) {
171927
- index = scan.index;
172172
+ function getOptionalStringArrayProperty(entryName, elementIndex, objectLiteral, key) {
172173
+ for (const property of objectLiteral.properties) {
172174
+ if (!import_typescript2.default.isPropertyAssignment(property)) {
171928
172175
  continue;
171929
172176
  }
171930
- const character = source[index];
171931
- if (character === "{") {
171932
- depth += 1;
171933
- index += 1;
172177
+ const propertyName = getPropertyNameText(property.name);
172178
+ if (propertyName !== key) {
171934
172179
  continue;
171935
172180
  }
171936
- if (character !== "}") {
171937
- index += 1;
171938
- continue;
172181
+ if (!import_typescript2.default.isArrayLiteralExpression(property.initializer)) {
172182
+ throw new Error(`${entryName}[${elementIndex}] must use an array literal for "${key}" in scripts/block-config.ts.`);
171939
172183
  }
171940
- depth -= 1;
171941
- if (depth === 0) {
171942
- let end = index + 1;
171943
- if (options.includeTrailingNewlines ?? true) {
171944
- while (end < source.length && /[\r\n]/u.test(source[end] ?? "")) {
171945
- end += 1;
171946
- }
172184
+ return property.initializer.elements.map((element, itemIndex) => {
172185
+ if (!import_typescript2.default.isStringLiteralLike(element)) {
172186
+ throw new Error(`${entryName}[${elementIndex}].${key}[${itemIndex}] must use a string literal in scripts/block-config.ts.`);
171947
172187
  }
171948
- return {
171949
- end,
171950
- source: source.slice(functionStart, end),
171951
- start: functionStart
171952
- };
171953
- }
171954
- index += 1;
172188
+ return element.text;
172189
+ });
171955
172190
  }
171956
- return null;
172191
+ return;
171957
172192
  }
171958
- function replacePhpFunctionDefinition(source, functionName, replacement, options = {}) {
171959
- const functionRange = findPhpFunctionRange(source, functionName, options);
171960
- if (!functionRange) {
171961
- return null;
172193
+ function isMissingRequiredInventoryValue(value) {
172194
+ return value === undefined || typeof value === "string" && value.length === 0;
172195
+ }
172196
+ function formatMissingRequiredInventoryFields(keys) {
172197
+ return keys.length === 1 ? `required "${keys[0]}"` : `required fields ${keys.map((key) => `"${key}"`).join(", ")}`;
172198
+ }
172199
+ function assertParsedInventoryEntry(entry, descriptor, elementIndex) {
172200
+ const missingRequiredKeys = descriptor.fields.filter((field) => field.required === true && isMissingRequiredInventoryValue(entry[field.key])).map((field) => field.key);
172201
+ if (missingRequiredKeys.length > 0) {
172202
+ throw new Error(`${descriptor.entryName}[${elementIndex}] is missing ${formatMissingRequiredInventoryFields(missingRequiredKeys)} in scripts/block-config.ts.`);
171962
172203
  }
171963
- return [
171964
- source.slice(0, functionRange.start),
171965
- options.trimReplacementStart ? replacement.trimStart() : replacement,
171966
- source.slice(functionRange.end)
171967
- ].join("");
171968
172204
  }
171969
-
171970
- // ../wp-typia-project-tools/src/runtime/ts-property-names.ts
171971
- var import_typescript = __toESM(require_typescript(), 1);
171972
- function getPropertyNameText(name) {
171973
- if (import_typescript.default.isIdentifier(name) || import_typescript.default.isStringLiteral(name) || import_typescript.default.isNumericLiteral(name)) {
171974
- return name.text;
172205
+ function parseInventoryEntries(arrayLiteral, descriptor) {
172206
+ return arrayLiteral.elements.map((element, elementIndex) => {
172207
+ if (!import_typescript2.default.isObjectLiteralExpression(element)) {
172208
+ throw new Error(`${descriptor.entryName}[${elementIndex}] must be an object literal in scripts/block-config.ts.`);
172209
+ }
172210
+ const entry = {};
172211
+ for (const field of descriptor.fields) {
172212
+ const kind = field.kind ?? "string";
172213
+ const value = kind === "stringArray" ? getOptionalStringArrayProperty(descriptor.entryName, elementIndex, element, field.key) : getOptionalStringProperty(descriptor.entryName, elementIndex, element, field.key);
172214
+ field.validate?.(value, {
172215
+ elementIndex,
172216
+ entryName: descriptor.entryName,
172217
+ key: field.key
172218
+ });
172219
+ entry[field.key] = value;
172220
+ }
172221
+ assertParsedInventoryEntry(entry, descriptor, elementIndex);
172222
+ return entry;
172223
+ });
172224
+ }
172225
+ function parseInventorySection(sourceFile, descriptor) {
172226
+ if (!descriptor.parse) {
172227
+ return {
172228
+ entries: [],
172229
+ found: false
172230
+ };
171975
172231
  }
171976
- return null;
172232
+ const exportName = descriptor.parse.exportName ?? descriptor.value?.name;
172233
+ if (!exportName) {
172234
+ throw new Error("Inventory parser descriptor is missing an export name.");
172235
+ }
172236
+ const exportedArray = findExportedArrayLiteral(sourceFile, exportName);
172237
+ if (!exportedArray.found) {
172238
+ if (descriptor.parse.required) {
172239
+ throw new Error(`scripts/block-config.ts must export a ${exportName} array.`);
172240
+ }
172241
+ return {
172242
+ entries: [],
172243
+ found: false
172244
+ };
172245
+ }
172246
+ if (!exportedArray.array) {
172247
+ if (descriptor.parse.required) {
172248
+ throw new Error(`scripts/block-config.ts must export a ${exportName} array.`);
172249
+ }
172250
+ throw new Error(`scripts/block-config.ts must export ${exportName} as an array literal.`);
172251
+ }
172252
+ return {
172253
+ entries: parseInventoryEntries(exportedArray.array, descriptor.parse.entry),
172254
+ found: true
172255
+ };
171977
172256
  }
171978
-
171979
- // ../wp-typia-project-tools/src/runtime/workspace-inventory.ts
171980
- function defineInventoryEntryParser() {
171981
- return (descriptor) => descriptor;
172257
+ function parseWorkspaceInventorySource(source) {
172258
+ const sourceFile = import_typescript2.default.createSourceFile("block-config.ts", source, import_typescript2.default.ScriptTarget.Latest, true, import_typescript2.default.ScriptKind.TS);
172259
+ const parsedInventory = {
172260
+ abilities: [],
172261
+ adminViews: [],
172262
+ aiFeatures: [],
172263
+ bindingSources: [],
172264
+ blockStyles: [],
172265
+ blockTransforms: [],
172266
+ blocks: parseInventorySection(sourceFile, BLOCK_INVENTORY_SECTION).entries,
172267
+ editorPlugins: [],
172268
+ hasAbilitiesSection: false,
172269
+ hasAdminViewsSection: false,
172270
+ hasAiFeaturesSection: false,
172271
+ hasBindingSourcesSection: false,
172272
+ hasBlockStylesSection: false,
172273
+ hasBlockTransformsSection: false,
172274
+ hasEditorPluginsSection: false,
172275
+ hasPatternsSection: false,
172276
+ hasRestResourcesSection: false,
172277
+ hasVariationsSection: false,
172278
+ patterns: [],
172279
+ restResources: [],
172280
+ source,
172281
+ variations: []
172282
+ };
172283
+ const mutableInventory = parsedInventory;
172284
+ for (const section of INVENTORY_SECTIONS) {
172285
+ if (!section.parse) {
172286
+ continue;
172287
+ }
172288
+ const parsedSection = parseInventorySection(sourceFile, section);
172289
+ mutableInventory[section.parse.entriesKey] = parsedSection.entries;
172290
+ if (section.parse.hasSectionKey) {
172291
+ mutableInventory[section.parse.hasSectionKey] = parsedSection.found;
172292
+ }
172293
+ }
172294
+ return parsedInventory;
171982
172295
  }
171983
- var BLOCK_CONFIG_ENTRY_MARKER = "\t// wp-typia add block entries";
171984
- var VARIATION_CONFIG_ENTRY_MARKER = "\t// wp-typia add variation entries";
171985
- var BLOCK_STYLE_CONFIG_ENTRY_MARKER = "\t// wp-typia add style entries";
171986
- var BLOCK_TRANSFORM_CONFIG_ENTRY_MARKER = "\t// wp-typia add transform entries";
171987
- var PATTERN_CONFIG_ENTRY_MARKER = "\t// wp-typia add pattern entries";
171988
- var BINDING_SOURCE_CONFIG_ENTRY_MARKER = "\t// wp-typia add binding-source entries";
171989
- var REST_RESOURCE_CONFIG_ENTRY_MARKER = "\t// wp-typia add rest-resource entries";
171990
- var ABILITY_CONFIG_ENTRY_MARKER = "\t// wp-typia add ability entries";
171991
- var AI_FEATURE_CONFIG_ENTRY_MARKER = "\t// wp-typia add ai-feature entries";
171992
- var ADMIN_VIEW_CONFIG_ENTRY_MARKER = "\t// wp-typia add admin-view entries";
171993
- var EDITOR_PLUGIN_CONFIG_ENTRY_MARKER = "\t// wp-typia add editor-plugin entries";
171994
- var VARIATIONS_INTERFACE_SECTION = `
171995
172296
 
171996
- export interface WorkspaceVariationConfig {
171997
- block: string;
171998
- file: string;
171999
- slug: string;
172297
+ // ../wp-typia-project-tools/src/runtime/workspace-inventory-read.ts
172298
+ function readWorkspaceInventory(projectDir) {
172299
+ const blockConfigPath = path4.join(projectDir, "scripts", "block-config.ts");
172300
+ let source;
172301
+ try {
172302
+ source = readFileSync(blockConfigPath, "utf8");
172303
+ } catch (error) {
172304
+ if (isFileNotFoundError(error)) {
172305
+ throw new Error(`Workspace inventory file is missing at ${blockConfigPath}. Expected scripts/block-config.ts to exist.`);
172306
+ }
172307
+ throw error;
172308
+ }
172309
+ return {
172310
+ blockConfigPath,
172311
+ ...parseWorkspaceInventorySource(source)
172312
+ };
172000
172313
  }
172001
- `;
172002
- var VARIATIONS_CONST_SECTION = `
172003
-
172004
- export const VARIATIONS: WorkspaceVariationConfig[] = [
172005
- // wp-typia add variation entries
172006
- ];
172007
- `;
172008
- var BLOCK_STYLES_INTERFACE_SECTION = `
172009
-
172010
- export interface WorkspaceBlockStyleConfig {
172011
- block: string;
172012
- file: string;
172013
- slug: string;
172314
+ async function readWorkspaceInventoryAsync(projectDir) {
172315
+ const blockConfigPath = path4.join(projectDir, "scripts", "block-config.ts");
172316
+ let source;
172317
+ try {
172318
+ source = await readFile(blockConfigPath, "utf8");
172319
+ } catch (error) {
172320
+ if (isFileNotFoundError(error)) {
172321
+ throw new Error(`Workspace inventory file is missing at ${blockConfigPath}. Expected scripts/block-config.ts to exist.`);
172322
+ }
172323
+ throw error;
172324
+ }
172325
+ return {
172326
+ blockConfigPath,
172327
+ ...parseWorkspaceInventorySource(source)
172328
+ };
172014
172329
  }
172015
- `;
172016
- var BLOCK_STYLES_CONST_SECTION = `
172017
-
172018
- export const BLOCK_STYLES: WorkspaceBlockStyleConfig[] = [
172019
- // wp-typia add style entries
172020
- ];
172021
- `;
172022
- var BLOCK_TRANSFORMS_INTERFACE_SECTION = `
172023
-
172024
- export interface WorkspaceBlockTransformConfig {
172025
- block: string;
172026
- file: string;
172027
- from: string;
172028
- slug: string;
172029
- to: string;
172330
+ function toWorkspaceBlockSelectOptions(blocks) {
172331
+ return blocks.map((block) => ({
172332
+ description: block.typesFile,
172333
+ name: block.slug,
172334
+ value: block.slug
172335
+ }));
172030
172336
  }
172031
- `;
172032
- var BLOCK_TRANSFORMS_CONST_SECTION = `
172033
-
172034
- export const BLOCK_TRANSFORMS: WorkspaceBlockTransformConfig[] = [
172035
- // wp-typia add transform entries
172036
- ];
172037
- `;
172038
- var PATTERNS_INTERFACE_SECTION = `
172039
-
172040
- export interface WorkspacePatternConfig {
172041
- file: string;
172042
- slug: string;
172337
+ function getWorkspaceBlockSelectOptions(projectDir) {
172338
+ return toWorkspaceBlockSelectOptions(readWorkspaceInventory(projectDir).blocks);
172043
172339
  }
172044
- `;
172045
- var PATTERNS_CONST_SECTION = `
172046
-
172047
- export const PATTERNS: WorkspacePatternConfig[] = [
172048
- // wp-typia add pattern entries
172049
- ];
172050
- `;
172051
- var BINDING_SOURCES_INTERFACE_SECTION = `
172052
-
172053
- export interface WorkspaceBindingSourceConfig {
172054
- attribute?: string;
172055
- block?: string;
172056
- editorFile: string;
172057
- serverFile: string;
172058
- slug: string;
172340
+ async function getWorkspaceBlockSelectOptionsAsync(projectDir) {
172341
+ return toWorkspaceBlockSelectOptions((await readWorkspaceInventoryAsync(projectDir)).blocks);
172059
172342
  }
172060
- `;
172061
- var BINDING_SOURCES_CONST_SECTION = `
172343
+ // ../wp-typia-project-tools/src/runtime/workspace-inventory-mutations.ts
172344
+ import path5 from "path";
172345
+ import { readFile as readFile2, writeFile } from "fs/promises";
172062
172346
 
172063
- export const BINDING_SOURCES: WorkspaceBindingSourceConfig[] = [
172064
- // wp-typia add binding-source entries
172065
- ];
172066
- `;
172067
- var REST_RESOURCES_INTERFACE_SECTION = `
172068
-
172069
- export interface WorkspaceRestResourceConfig {
172070
- apiFile: string;
172071
- clientFile: string;
172072
- dataFile: string;
172073
- methods: Array< 'list' | 'read' | 'create' | 'update' | 'delete' >;
172074
- namespace: string;
172075
- openApiFile: string;
172076
- phpFile: string;
172077
- restManifest?: ReturnType<
172078
- typeof import( '@wp-typia/block-runtime/metadata-core' ).defineEndpointManifest
172079
- >;
172080
- slug: string;
172081
- typesFile: string;
172082
- validatorsFile: string;
172347
+ // ../wp-typia-project-tools/src/runtime/php-utils.ts
172348
+ function escapeRegex(value) {
172349
+ return value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
172083
172350
  }
172084
- `;
172085
- var REST_RESOURCES_CONST_SECTION = `
172086
-
172087
- export const REST_RESOURCES: WorkspaceRestResourceConfig[] = [
172088
- // wp-typia add rest-resource entries
172089
- ];
172090
- `;
172091
- var WORKSPACE_COMPATIBILITY_CONFIG_FIELD = ` compatibility?: {
172092
- hardMinimums: {
172093
- php?: string;
172094
- wordpress?: string;
172095
- };
172096
- mode: 'baseline' | 'optional' | 'required';
172097
- optionalFeatureIds: string[];
172098
- optionalFeatures: string[];
172099
- requiredFeatureIds: string[];
172100
- requiredFeatures: string[];
172101
- runtimeGates: string[];
172102
- };
172103
- `;
172104
- var ABILITIES_INTERFACE_SECTION = `
172105
-
172106
- export interface WorkspaceAbilityConfig {
172107
- clientFile: string;
172108
- ${WORKSPACE_COMPATIBILITY_CONFIG_FIELD} configFile: string;
172109
- dataFile: string;
172110
- inputSchemaFile: string;
172111
- inputTypeName: string;
172112
- outputSchemaFile: string;
172113
- outputTypeName: string;
172114
- phpFile: string;
172115
- slug: string;
172116
- typesFile: string;
172351
+ function quotePhpString(value) {
172352
+ return `'${value.replace(/\\/gu, "\\\\").replace(/'/gu, "\\'")}'`;
172117
172353
  }
172118
- `;
172119
- var ABILITIES_CONST_SECTION = `
172120
-
172121
- export const ABILITIES: WorkspaceAbilityConfig[] = [
172122
- // wp-typia add ability entries
172123
- ];
172124
- `;
172125
- var AI_FEATURES_INTERFACE_SECTION = `
172126
-
172127
- export interface WorkspaceAiFeatureConfig {
172128
- aiSchemaFile: string;
172129
- apiFile: string;
172130
- clientFile: string;
172131
- ${WORKSPACE_COMPATIBILITY_CONFIG_FIELD} dataFile: string;
172132
- namespace: string;
172133
- openApiFile: string;
172134
- phpFile: string;
172135
- restManifest?: ReturnType<
172136
- typeof import( '@wp-typia/block-runtime/metadata-core' ).defineEndpointManifest
172137
- >;
172138
- slug: string;
172139
- typesFile: string;
172140
- validatorsFile: string;
172354
+ function hasPhpFunctionDefinition(source, functionName) {
172355
+ return new RegExp(`function\\s+${escapeRegex(functionName)}\\s*\\(`, "u").test(source);
172141
172356
  }
172142
- `;
172143
- var AI_FEATURES_CONST_SECTION = `
172144
-
172145
- export const AI_FEATURES: WorkspaceAiFeatureConfig[] = [
172146
- // wp-typia add ai-feature entries
172147
- ];
172148
- `;
172149
- var ADMIN_VIEWS_INTERFACE_SECTION = `
172150
-
172151
- export interface WorkspaceAdminViewConfig {
172152
- file: string;
172153
- phpFile: string;
172154
- slug: string;
172155
- source?: string;
172357
+ function isPhpIdentifierStart(character) {
172358
+ return /^[A-Za-z_]$/u.test(character ?? "");
172156
172359
  }
172157
- `;
172158
- var ADMIN_VIEWS_CONST_SECTION = `
172159
-
172160
- export const ADMIN_VIEWS: WorkspaceAdminViewConfig[] = [
172161
- // wp-typia add admin-view entries
172162
- ];
172163
- `;
172164
- var EDITOR_PLUGINS_INTERFACE_SECTION = `
172165
-
172166
- export interface WorkspaceEditorPluginConfig {
172167
- file: string;
172168
- slug: string;
172169
- slot: string;
172360
+ function isPhpIdentifierPart(character) {
172361
+ return /^[A-Za-z0-9_]$/u.test(character ?? "");
172170
172362
  }
172363
+ function isPhpLineStart(source, index) {
172364
+ return index === 0 || source[index - 1] === `
172171
172365
  `;
172172
- var EDITOR_PLUGINS_CONST_SECTION = `
172173
-
172174
- export const EDITOR_PLUGINS: WorkspaceEditorPluginConfig[] = [
172175
- // wp-typia add editor-plugin entries
172176
- ];
172177
- `;
172178
- var BLOCK_INVENTORY_SECTION = {
172179
- append: {
172180
- marker: BLOCK_CONFIG_ENTRY_MARKER,
172181
- optionKey: "blockEntries"
172182
- },
172183
- parse: {
172184
- entriesKey: "blocks",
172185
- entry: defineInventoryEntryParser()({
172186
- entryName: "BLOCKS",
172187
- fields: [
172188
- { key: "apiTypesFile" },
172189
- { key: "attributeTypeName" },
172190
- { key: "openApiFile" },
172191
- { key: "slug", required: true },
172192
- { key: "typesFile", required: true }
172193
- ]
172194
- }),
172195
- exportName: "BLOCKS",
172196
- required: true
172366
+ }
172367
+ function isPhpHorizontalWhitespace(character) {
172368
+ return character === " " || character === "\t";
172369
+ }
172370
+ function isPhpWhitespace(character) {
172371
+ return typeof character === "string" && /\s/u.test(character);
172372
+ }
172373
+ function findPhpLineBoundary(source, index) {
172374
+ const newlineIndex = source.indexOf(`
172375
+ `, index);
172376
+ if (newlineIndex === -1) {
172377
+ return {
172378
+ contentEnd: source.endsWith("\r") ? source.length - 1 : source.length,
172379
+ nextStart: source.length
172380
+ };
172197
172381
  }
172198
- };
172199
- var INVENTORY_SECTIONS = [
172200
- {
172201
- append: {
172202
- marker: VARIATION_CONFIG_ENTRY_MARKER,
172203
- optionKey: "variationEntries"
172204
- },
172205
- interface: {
172206
- name: "WorkspaceVariationConfig",
172207
- section: VARIATIONS_INTERFACE_SECTION
172208
- },
172209
- parse: {
172210
- entriesKey: "variations",
172211
- entry: defineInventoryEntryParser()({
172212
- entryName: "VARIATIONS",
172213
- fields: [
172214
- { key: "block", required: true },
172215
- { key: "file", required: true },
172216
- { key: "slug", required: true }
172217
- ]
172218
- }),
172219
- hasSectionKey: "hasVariationsSection"
172220
- },
172221
- value: {
172222
- name: "VARIATIONS",
172223
- section: VARIATIONS_CONST_SECTION
172382
+ return {
172383
+ contentEnd: source[newlineIndex - 1] === "\r" ? newlineIndex - 1 : newlineIndex,
172384
+ nextStart: newlineIndex + 1
172385
+ };
172386
+ }
172387
+ function parsePhpHeredocStart(source, index) {
172388
+ if (!source.startsWith("<<<", index)) {
172389
+ return null;
172390
+ }
172391
+ let cursor = index + 3;
172392
+ while (isPhpHorizontalWhitespace(source[cursor])) {
172393
+ cursor += 1;
172394
+ }
172395
+ const quote = source[cursor] === "'" || source[cursor] === '"' ? source[cursor] : "";
172396
+ if (quote) {
172397
+ cursor += 1;
172398
+ }
172399
+ if (!isPhpIdentifierStart(source[cursor])) {
172400
+ return null;
172401
+ }
172402
+ const delimiterStart = cursor;
172403
+ cursor += 1;
172404
+ while (isPhpIdentifierPart(source[cursor])) {
172405
+ cursor += 1;
172406
+ }
172407
+ const delimiter = source.slice(delimiterStart, cursor);
172408
+ if (quote) {
172409
+ if (source[cursor] !== quote) {
172410
+ return null;
172224
172411
  }
172225
- },
172226
- {
172227
- append: {
172228
- marker: BLOCK_STYLE_CONFIG_ENTRY_MARKER,
172229
- optionKey: "blockStyleEntries"
172230
- },
172231
- interface: {
172232
- name: "WorkspaceBlockStyleConfig",
172233
- section: BLOCK_STYLES_INTERFACE_SECTION
172234
- },
172235
- parse: {
172236
- entriesKey: "blockStyles",
172237
- entry: defineInventoryEntryParser()({
172238
- entryName: "BLOCK_STYLES",
172239
- fields: [
172240
- { key: "block", required: true },
172241
- { key: "file", required: true },
172242
- { key: "slug", required: true }
172243
- ]
172244
- }),
172245
- hasSectionKey: "hasBlockStylesSection"
172246
- },
172247
- value: {
172248
- name: "BLOCK_STYLES",
172249
- section: BLOCK_STYLES_CONST_SECTION
172412
+ cursor += 1;
172413
+ }
172414
+ const lineBoundary = findPhpLineBoundary(source, cursor);
172415
+ if (source.slice(cursor, lineBoundary.contentEnd).trim() !== "") {
172416
+ return null;
172417
+ }
172418
+ return {
172419
+ contentStart: lineBoundary.nextStart,
172420
+ delimiter
172421
+ };
172422
+ }
172423
+ function findPhpHeredocClosingEnd(source, index, delimiter) {
172424
+ if (!isPhpLineStart(source, index)) {
172425
+ return null;
172426
+ }
172427
+ let cursor = index;
172428
+ while (isPhpHorizontalWhitespace(source[cursor])) {
172429
+ cursor += 1;
172430
+ }
172431
+ if (!source.startsWith(delimiter, cursor)) {
172432
+ return null;
172433
+ }
172434
+ cursor += delimiter.length;
172435
+ if (isPhpIdentifierPart(source[cursor])) {
172436
+ return null;
172437
+ }
172438
+ let continuationCursor = cursor;
172439
+ while (isPhpHorizontalWhitespace(source[continuationCursor])) {
172440
+ continuationCursor += 1;
172441
+ }
172442
+ const continuation = source[continuationCursor];
172443
+ if (continuationCursor >= source.length || continuation === "\r" || continuation === `
172444
+ ` || !isPhpIdentifierPart(continuation)) {
172445
+ return cursor;
172446
+ }
172447
+ return null;
172448
+ }
172449
+ function skipPhpCallTrivia(source, index) {
172450
+ let cursor = index;
172451
+ while (cursor < source.length) {
172452
+ while (isPhpWhitespace(source[cursor])) {
172453
+ cursor += 1;
172250
172454
  }
172251
- },
172252
- {
172253
- append: {
172254
- marker: BLOCK_TRANSFORM_CONFIG_ENTRY_MARKER,
172255
- optionKey: "blockTransformEntries"
172256
- },
172257
- interface: {
172258
- name: "WorkspaceBlockTransformConfig",
172259
- section: BLOCK_TRANSFORMS_INTERFACE_SECTION
172260
- },
172261
- parse: {
172262
- entriesKey: "blockTransforms",
172263
- entry: defineInventoryEntryParser()({
172264
- entryName: "BLOCK_TRANSFORMS",
172265
- fields: [
172266
- { key: "block", required: true },
172267
- { key: "file", required: true },
172268
- { key: "from", required: true },
172269
- { key: "slug", required: true },
172270
- { key: "to", required: true }
172271
- ]
172272
- }),
172273
- hasSectionKey: "hasBlockTransformsSection"
172274
- },
172275
- value: {
172276
- name: "BLOCK_TRANSFORMS",
172277
- section: BLOCK_TRANSFORMS_CONST_SECTION
172455
+ if (source[cursor] === "/" && source[cursor + 1] === "*") {
172456
+ const commentEnd = source.indexOf("*/", cursor + 2);
172457
+ if (commentEnd === -1) {
172458
+ return null;
172459
+ }
172460
+ cursor = commentEnd + 2;
172461
+ continue;
172278
172462
  }
172279
- },
172280
- {
172281
- append: {
172282
- marker: PATTERN_CONFIG_ENTRY_MARKER,
172283
- optionKey: "patternEntries"
172284
- },
172285
- interface: {
172286
- name: "WorkspacePatternConfig",
172287
- section: PATTERNS_INTERFACE_SECTION
172288
- },
172289
- parse: {
172290
- entriesKey: "patterns",
172291
- entry: defineInventoryEntryParser()({
172292
- entryName: "PATTERNS",
172293
- fields: [
172294
- { key: "file", required: true },
172295
- { key: "slug", required: true }
172296
- ]
172297
- }),
172298
- hasSectionKey: "hasPatternsSection"
172299
- },
172300
- value: {
172301
- name: "PATTERNS",
172302
- section: PATTERNS_CONST_SECTION
172463
+ if (source[cursor] === "/" && source[cursor + 1] === "/") {
172464
+ cursor = findPhpLineBoundary(source, cursor + 2).nextStart;
172465
+ continue;
172303
172466
  }
172304
- },
172305
- {
172306
- append: {
172307
- marker: BINDING_SOURCE_CONFIG_ENTRY_MARKER,
172308
- optionKey: "bindingSourceEntries"
172309
- },
172310
- interface: {
172311
- name: "WorkspaceBindingSourceConfig",
172312
- section: BINDING_SOURCES_INTERFACE_SECTION
172313
- },
172314
- parse: {
172315
- entriesKey: "bindingSources",
172316
- entry: defineInventoryEntryParser()({
172317
- entryName: "BINDING_SOURCES",
172318
- fields: [
172319
- { key: "attribute" },
172320
- { key: "block" },
172321
- { key: "editorFile", required: true },
172322
- { key: "serverFile", required: true },
172323
- { key: "slug", required: true }
172324
- ]
172325
- }),
172326
- hasSectionKey: "hasBindingSourcesSection"
172327
- },
172328
- value: {
172329
- name: "BINDING_SOURCES",
172330
- section: BINDING_SOURCES_CONST_SECTION
172467
+ if (source[cursor] === "#" && source[cursor + 1] !== "[") {
172468
+ cursor = findPhpLineBoundary(source, cursor + 1).nextStart;
172469
+ continue;
172331
172470
  }
172332
- },
172333
- {
172334
- append: {
172335
- marker: REST_RESOURCE_CONFIG_ENTRY_MARKER,
172336
- optionKey: "restResourceEntries"
172337
- },
172338
- interface: {
172339
- name: "WorkspaceRestResourceConfig",
172340
- section: REST_RESOURCES_INTERFACE_SECTION
172341
- },
172342
- parse: {
172343
- entriesKey: "restResources",
172344
- entry: defineInventoryEntryParser()({
172345
- entryName: "REST_RESOURCES",
172346
- fields: [
172347
- { key: "apiFile", required: true },
172348
- { key: "clientFile", required: true },
172349
- { key: "dataFile", required: true },
172350
- {
172351
- key: "methods",
172352
- kind: "stringArray",
172353
- required: true,
172354
- validate: (value, context) => {
172355
- const methods = Array.isArray(value) ? value : [];
172356
- const invalidMethods = methods.filter((method) => !REST_RESOURCE_METHOD_IDS.includes(method));
172357
- if (invalidMethods.length > 0) {
172358
- throw new Error(`${context.entryName}[${context.elementIndex}].${context.key} includes unsupported values: ${invalidMethods.join(", ")}.`);
172359
- }
172360
- }
172361
- },
172362
- { key: "namespace", required: true },
172363
- { key: "openApiFile", required: true },
172364
- { key: "phpFile", required: true },
172365
- { key: "slug", required: true },
172366
- { key: "typesFile", required: true },
172367
- { key: "validatorsFile", required: true }
172368
- ]
172369
- }),
172370
- hasSectionKey: "hasRestResourcesSection"
172371
- },
172372
- value: {
172373
- name: "REST_RESOURCES",
172374
- section: REST_RESOURCES_CONST_SECTION
172471
+ return cursor;
172472
+ }
172473
+ return cursor;
172474
+ }
172475
+ function matchesPhpFunctionCallAt(source, index, functionName) {
172476
+ if (!source.startsWith(functionName, index)) {
172477
+ return false;
172478
+ }
172479
+ if (isPhpIdentifierPart(source[index - 1])) {
172480
+ return false;
172481
+ }
172482
+ const cursor = index + functionName.length;
172483
+ if (isPhpIdentifierPart(source[cursor])) {
172484
+ return false;
172485
+ }
172486
+ const callStart = skipPhpCallTrivia(source, cursor);
172487
+ return callStart !== null && source[callStart] === "(";
172488
+ }
172489
+ function createPhpScannerState() {
172490
+ return {
172491
+ heredocDelimiter: "",
172492
+ interpolationComment: "",
172493
+ interpolationDepth: 0,
172494
+ interpolationQuote: "",
172495
+ mode: "code"
172496
+ };
172497
+ }
172498
+ function advancePhpScanner(source, index, state) {
172499
+ const character = source[index];
172500
+ if (state.mode === "heredoc") {
172501
+ const closingEnd = findPhpHeredocClosingEnd(source, index, state.heredocDelimiter);
172502
+ if (closingEnd !== null) {
172503
+ state.mode = "code";
172504
+ state.heredocDelimiter = "";
172505
+ return { ambiguous: false, inCode: false, index: closingEnd };
172375
172506
  }
172376
- },
172377
- {
172378
- append: {
172379
- marker: ABILITY_CONFIG_ENTRY_MARKER,
172380
- optionKey: "abilityEntries"
172381
- },
172382
- interface: {
172383
- name: "WorkspaceAbilityConfig",
172384
- section: ABILITIES_INTERFACE_SECTION
172385
- },
172386
- parse: {
172387
- entriesKey: "abilities",
172388
- entry: defineInventoryEntryParser()({
172389
- entryName: "ABILITIES",
172390
- fields: [
172391
- { key: "clientFile", required: true },
172392
- { key: "configFile", required: true },
172393
- { key: "dataFile", required: true },
172394
- { key: "inputSchemaFile", required: true },
172395
- { key: "inputTypeName", required: true },
172396
- { key: "outputSchemaFile", required: true },
172397
- { key: "outputTypeName", required: true },
172398
- { key: "phpFile", required: true },
172399
- { key: "slug", required: true },
172400
- { key: "typesFile", required: true }
172401
- ]
172402
- }),
172403
- hasSectionKey: "hasAbilitiesSection"
172404
- },
172405
- value: {
172406
- name: "ABILITIES",
172407
- section: ABILITIES_CONST_SECTION
172507
+ const nextLineStart = findPhpLineBoundary(source, index).nextStart;
172508
+ if (nextLineStart <= index) {
172509
+ return { ambiguous: true, inCode: false, index };
172408
172510
  }
172409
- },
172410
- {
172411
- append: {
172412
- marker: AI_FEATURE_CONFIG_ENTRY_MARKER,
172413
- optionKey: "aiFeatureEntries"
172414
- },
172415
- interface: {
172416
- name: "WorkspaceAiFeatureConfig",
172417
- section: AI_FEATURES_INTERFACE_SECTION
172418
- },
172419
- parse: {
172420
- entriesKey: "aiFeatures",
172421
- entry: defineInventoryEntryParser()({
172422
- entryName: "AI_FEATURES",
172423
- fields: [
172424
- { key: "aiSchemaFile", required: true },
172425
- { key: "apiFile", required: true },
172426
- { key: "clientFile", required: true },
172427
- { key: "dataFile", required: true },
172428
- { key: "namespace", required: true },
172429
- { key: "openApiFile", required: true },
172430
- { key: "phpFile", required: true },
172431
- { key: "slug", required: true },
172432
- { key: "typesFile", required: true },
172433
- { key: "validatorsFile", required: true }
172434
- ]
172435
- }),
172436
- hasSectionKey: "hasAiFeaturesSection"
172437
- },
172438
- value: {
172439
- name: "AI_FEATURES",
172440
- section: AI_FEATURES_CONST_SECTION
172511
+ return { ambiguous: false, inCode: false, index: nextLineStart };
172512
+ }
172513
+ if (state.mode === "single-quoted" || state.mode === "double-quoted") {
172514
+ const quote = state.mode === "single-quoted" ? "'" : '"';
172515
+ if (character === "\\") {
172516
+ return { ambiguous: false, inCode: false, index: index + 2 };
172441
172517
  }
172442
- },
172443
- {
172444
- append: {
172445
- marker: ADMIN_VIEW_CONFIG_ENTRY_MARKER,
172446
- optionKey: "adminViewEntries"
172447
- },
172448
- interface: {
172449
- name: "WorkspaceAdminViewConfig",
172450
- section: ADMIN_VIEWS_INTERFACE_SECTION
172451
- },
172452
- parse: {
172453
- entriesKey: "adminViews",
172454
- entry: defineInventoryEntryParser()({
172455
- entryName: "ADMIN_VIEWS",
172456
- fields: [
172457
- { key: "file", required: true },
172458
- { key: "phpFile", required: true },
172459
- { key: "slug", required: true },
172460
- { key: "source" }
172461
- ]
172462
- }),
172463
- hasSectionKey: "hasAdminViewsSection"
172464
- },
172465
- value: {
172466
- name: "ADMIN_VIEWS",
172467
- section: ADMIN_VIEWS_CONST_SECTION
172518
+ if (state.mode === "double-quoted" && character === "{" && source[index + 1] === "$") {
172519
+ state.mode = "double-quoted-interpolation";
172520
+ state.interpolationComment = "";
172521
+ state.interpolationDepth = 1;
172522
+ state.interpolationQuote = "";
172523
+ return { ambiguous: false, inCode: false, index: index + 2 };
172468
172524
  }
172469
- },
172470
- {
172471
- append: {
172472
- marker: EDITOR_PLUGIN_CONFIG_ENTRY_MARKER,
172473
- optionKey: "editorPluginEntries"
172474
- },
172475
- interface: {
172476
- name: "WorkspaceEditorPluginConfig",
172477
- section: EDITOR_PLUGINS_INTERFACE_SECTION
172478
- },
172479
- parse: {
172480
- entriesKey: "editorPlugins",
172481
- entry: defineInventoryEntryParser()({
172482
- entryName: "EDITOR_PLUGINS",
172483
- fields: [
172484
- { key: "file", required: true },
172485
- { key: "slug", required: true },
172486
- { key: "slot", required: true }
172487
- ]
172488
- }),
172489
- hasSectionKey: "hasEditorPluginsSection"
172490
- },
172491
- value: {
172492
- name: "EDITOR_PLUGINS",
172493
- section: EDITOR_PLUGINS_CONST_SECTION
172525
+ if (character === quote) {
172526
+ state.mode = "code";
172494
172527
  }
172528
+ return { ambiguous: false, inCode: false, index: index + 1 };
172495
172529
  }
172496
- ];
172497
- function findExportedArrayLiteral(sourceFile, exportName) {
172498
- for (const statement of sourceFile.statements) {
172499
- if (!import_typescript2.default.isVariableStatement(statement)) {
172500
- continue;
172530
+ if (state.mode === "double-quoted-interpolation") {
172531
+ if (state.interpolationQuote) {
172532
+ if (character === "\\") {
172533
+ return { ambiguous: false, inCode: false, index: index + 2 };
172534
+ }
172535
+ if (character === state.interpolationQuote) {
172536
+ state.interpolationQuote = "";
172537
+ }
172538
+ return { ambiguous: false, inCode: false, index: index + 1 };
172501
172539
  }
172502
- if (!statement.modifiers?.some((modifier) => modifier.kind === import_typescript2.default.SyntaxKind.ExportKeyword)) {
172503
- continue;
172540
+ if (state.interpolationComment === "line") {
172541
+ if (character === "\r" || character === `
172542
+ `) {
172543
+ state.interpolationComment = "";
172544
+ }
172545
+ return { ambiguous: false, inCode: false, index: index + 1 };
172504
172546
  }
172505
- for (const declaration of statement.declarationList.declarations) {
172506
- if (!import_typescript2.default.isIdentifier(declaration.name) || declaration.name.text !== exportName) {
172507
- continue;
172547
+ if (state.interpolationComment === "block") {
172548
+ if (character === "*" && source[index + 1] === "/") {
172549
+ state.interpolationComment = "";
172550
+ return { ambiguous: false, inCode: false, index: index + 2 };
172508
172551
  }
172509
- if (declaration.initializer && import_typescript2.default.isArrayLiteralExpression(declaration.initializer)) {
172510
- return {
172511
- array: declaration.initializer,
172512
- found: true
172513
- };
172552
+ return { ambiguous: false, inCode: false, index: index + 1 };
172553
+ }
172554
+ if (character === "/" && source[index + 1] === "/") {
172555
+ state.interpolationComment = "line";
172556
+ return { ambiguous: false, inCode: false, index: index + 2 };
172557
+ }
172558
+ if (character === "#" && source[index + 1] !== "[") {
172559
+ state.interpolationComment = "line";
172560
+ return { ambiguous: false, inCode: false, index: index + 1 };
172561
+ }
172562
+ if (character === "/" && source[index + 1] === "*") {
172563
+ state.interpolationComment = "block";
172564
+ return { ambiguous: false, inCode: false, index: index + 2 };
172565
+ }
172566
+ if (character === "'" || character === '"') {
172567
+ state.interpolationQuote = character;
172568
+ return { ambiguous: false, inCode: false, index: index + 1 };
172569
+ }
172570
+ if (character === "{") {
172571
+ state.interpolationDepth += 1;
172572
+ return { ambiguous: false, inCode: false, index: index + 1 };
172573
+ }
172574
+ if (character === "}") {
172575
+ state.interpolationDepth -= 1;
172576
+ if (state.interpolationDepth <= 0) {
172577
+ state.interpolationComment = "";
172578
+ state.interpolationDepth = 0;
172579
+ state.mode = "double-quoted";
172514
172580
  }
172581
+ return { ambiguous: false, inCode: false, index: index + 1 };
172582
+ }
172583
+ return { ambiguous: false, inCode: false, index: index + 1 };
172584
+ }
172585
+ if (state.mode === "line-comment") {
172586
+ if (character === "\r" || character === `
172587
+ `) {
172588
+ state.mode = "code";
172589
+ }
172590
+ return { ambiguous: false, inCode: false, index: index + 1 };
172591
+ }
172592
+ if (state.mode === "block-comment") {
172593
+ if (character === "*" && source[index + 1] === "/") {
172594
+ state.mode = "code";
172595
+ return { ambiguous: false, inCode: false, index: index + 2 };
172596
+ }
172597
+ return { ambiguous: false, inCode: false, index: index + 1 };
172598
+ }
172599
+ if (character === "'") {
172600
+ state.mode = "single-quoted";
172601
+ return { ambiguous: false, inCode: false, index: index + 1 };
172602
+ }
172603
+ if (character === '"') {
172604
+ state.mode = "double-quoted";
172605
+ return { ambiguous: false, inCode: false, index: index + 1 };
172606
+ }
172607
+ if (character === "/" && source[index + 1] === "/") {
172608
+ state.mode = "line-comment";
172609
+ return { ambiguous: false, inCode: false, index: index + 2 };
172610
+ }
172611
+ if (character === "#" && source[index + 1] !== "[") {
172612
+ state.mode = "line-comment";
172613
+ return { ambiguous: false, inCode: false, index: index + 1 };
172614
+ }
172615
+ if (character === "/" && source[index + 1] === "*") {
172616
+ state.mode = "block-comment";
172617
+ return { ambiguous: false, inCode: false, index: index + 2 };
172618
+ }
172619
+ if (character === "<") {
172620
+ const heredocStart = parsePhpHeredocStart(source, index);
172621
+ if (heredocStart) {
172622
+ state.mode = "heredoc";
172623
+ state.heredocDelimiter = heredocStart.delimiter;
172515
172624
  return {
172516
- array: null,
172517
- found: true
172625
+ ambiguous: false,
172626
+ inCode: false,
172627
+ index: heredocStart.contentStart
172518
172628
  };
172519
172629
  }
172520
172630
  }
172521
- return {
172522
- array: null,
172523
- found: false
172524
- };
172525
- }
172526
- function getOptionalStringProperty(entryName, elementIndex, objectLiteral, key) {
172527
- for (const property of objectLiteral.properties) {
172528
- if (!import_typescript2.default.isPropertyAssignment(property)) {
172529
- continue;
172530
- }
172531
- const propertyName = getPropertyNameText(property.name);
172532
- if (propertyName !== key) {
172533
- continue;
172534
- }
172535
- if (import_typescript2.default.isStringLiteralLike(property.initializer)) {
172536
- return property.initializer.text;
172537
- }
172538
- throw new Error(`${entryName}[${elementIndex}] must use a string literal for "${key}" in scripts/block-config.ts.`);
172539
- }
172540
- return;
172631
+ return { ambiguous: false, inCode: true, index };
172541
172632
  }
172542
- function getOptionalStringArrayProperty(entryName, elementIndex, objectLiteral, key) {
172543
- for (const property of objectLiteral.properties) {
172544
- if (!import_typescript2.default.isPropertyAssignment(property)) {
172545
- continue;
172633
+ function hasPhpFunctionCall(source, functionName) {
172634
+ const scanner = createPhpScannerState();
172635
+ let index = 0;
172636
+ while (index < source.length) {
172637
+ const scan = advancePhpScanner(source, index, scanner);
172638
+ if (scan.ambiguous) {
172639
+ return false;
172546
172640
  }
172547
- const propertyName = getPropertyNameText(property.name);
172548
- if (propertyName !== key) {
172641
+ if (!scan.inCode) {
172642
+ index = scan.index;
172549
172643
  continue;
172550
172644
  }
172551
- if (!import_typescript2.default.isArrayLiteralExpression(property.initializer)) {
172552
- throw new Error(`${entryName}[${elementIndex}] must use an array literal for "${key}" in scripts/block-config.ts.`);
172645
+ if (matchesPhpFunctionCallAt(source, index, functionName)) {
172646
+ return true;
172553
172647
  }
172554
- return property.initializer.elements.map((element, itemIndex) => {
172555
- if (!import_typescript2.default.isStringLiteralLike(element)) {
172556
- throw new Error(`${entryName}[${elementIndex}].${key}[${itemIndex}] must use a string literal in scripts/block-config.ts.`);
172557
- }
172558
- return element.text;
172559
- });
172560
- }
172561
- return;
172562
- }
172563
- function isMissingRequiredInventoryValue(value) {
172564
- return value === undefined || typeof value === "string" && value.length === 0;
172565
- }
172566
- function formatMissingRequiredInventoryFields(keys) {
172567
- return keys.length === 1 ? `required "${keys[0]}"` : `required fields ${keys.map((key) => `"${key}"`).join(", ")}`;
172568
- }
172569
- function assertParsedInventoryEntry(entry, descriptor, elementIndex) {
172570
- const missingRequiredKeys = descriptor.fields.filter((field) => field.required === true && isMissingRequiredInventoryValue(entry[field.key])).map((field) => field.key);
172571
- if (missingRequiredKeys.length > 0) {
172572
- throw new Error(`${descriptor.entryName}[${elementIndex}] is missing ${formatMissingRequiredInventoryFields(missingRequiredKeys)} in scripts/block-config.ts.`);
172648
+ index += 1;
172573
172649
  }
172650
+ return false;
172574
172651
  }
172575
- function parseInventoryEntries(arrayLiteral, descriptor) {
172576
- return arrayLiteral.elements.map((element, elementIndex) => {
172577
- if (!import_typescript2.default.isObjectLiteralExpression(element)) {
172578
- throw new Error(`${descriptor.entryName}[${elementIndex}] must be an object literal in scripts/block-config.ts.`);
172579
- }
172580
- const entry = {};
172581
- for (const field of descriptor.fields) {
172582
- const kind = field.kind ?? "string";
172583
- const value = kind === "stringArray" ? getOptionalStringArrayProperty(descriptor.entryName, elementIndex, element, field.key) : getOptionalStringProperty(descriptor.entryName, elementIndex, element, field.key);
172584
- field.validate?.(value, {
172585
- elementIndex,
172586
- entryName: descriptor.entryName,
172587
- key: field.key
172588
- });
172589
- entry[field.key] = value;
172590
- }
172591
- assertParsedInventoryEntry(entry, descriptor, elementIndex);
172592
- return entry;
172593
- });
172594
- }
172595
- function parseInventorySection(sourceFile, descriptor) {
172596
- if (!descriptor.parse) {
172597
- return {
172598
- entries: [],
172599
- found: false
172600
- };
172652
+ function findPhpFunctionRange(source, functionName, options = {}) {
172653
+ const signaturePattern = new RegExp(`function\\s+${escapeRegex(functionName)}\\s*\\([^)]*\\)\\s*(?::\\s*[^{};]+)?\\s*\\{`, "u");
172654
+ const signatureMatch = signaturePattern.exec(source);
172655
+ if (!signatureMatch) {
172656
+ return null;
172601
172657
  }
172602
- const exportName = descriptor.parse.exportName ?? descriptor.value?.name;
172603
- if (!exportName) {
172604
- throw new Error("Inventory parser descriptor is missing an export name.");
172658
+ const functionStart = signatureMatch.index;
172659
+ const openBraceOffset = signatureMatch[0].lastIndexOf("{");
172660
+ if (openBraceOffset === -1) {
172661
+ return null;
172605
172662
  }
172606
- const exportedArray = findExportedArrayLiteral(sourceFile, exportName);
172607
- if (!exportedArray.found) {
172608
- if (descriptor.parse.required) {
172609
- throw new Error(`scripts/block-config.ts must export a ${exportName} array.`);
172663
+ const openBraceIndex = functionStart + openBraceOffset;
172664
+ let depth = 0;
172665
+ const scanner = createPhpScannerState();
172666
+ let index = openBraceIndex;
172667
+ while (index < source.length) {
172668
+ const scan = advancePhpScanner(source, index, scanner);
172669
+ if (scan.ambiguous) {
172670
+ return null;
172610
172671
  }
172611
- return {
172612
- entries: [],
172613
- found: false
172614
- };
172615
- }
172616
- if (!exportedArray.array) {
172617
- if (descriptor.parse.required) {
172618
- throw new Error(`scripts/block-config.ts must export a ${exportName} array.`);
172672
+ if (!scan.inCode) {
172673
+ index = scan.index;
172674
+ continue;
172619
172675
  }
172620
- throw new Error(`scripts/block-config.ts must export ${exportName} as an array literal.`);
172621
- }
172622
- return {
172623
- entries: parseInventoryEntries(exportedArray.array, descriptor.parse.entry),
172624
- found: true
172625
- };
172626
- }
172627
- function parseWorkspaceInventorySource(source) {
172628
- const sourceFile = import_typescript2.default.createSourceFile("block-config.ts", source, import_typescript2.default.ScriptTarget.Latest, true, import_typescript2.default.ScriptKind.TS);
172629
- const parsedInventory = {
172630
- abilities: [],
172631
- adminViews: [],
172632
- aiFeatures: [],
172633
- bindingSources: [],
172634
- blockStyles: [],
172635
- blockTransforms: [],
172636
- blocks: parseInventorySection(sourceFile, BLOCK_INVENTORY_SECTION).entries,
172637
- editorPlugins: [],
172638
- hasAbilitiesSection: false,
172639
- hasAdminViewsSection: false,
172640
- hasAiFeaturesSection: false,
172641
- hasBindingSourcesSection: false,
172642
- hasBlockStylesSection: false,
172643
- hasBlockTransformsSection: false,
172644
- hasEditorPluginsSection: false,
172645
- hasPatternsSection: false,
172646
- hasRestResourcesSection: false,
172647
- hasVariationsSection: false,
172648
- patterns: [],
172649
- restResources: [],
172650
- source,
172651
- variations: []
172652
- };
172653
- const mutableInventory = parsedInventory;
172654
- for (const section of INVENTORY_SECTIONS) {
172655
- if (!section.parse) {
172676
+ const character = source[index];
172677
+ if (character === "{") {
172678
+ depth += 1;
172679
+ index += 1;
172656
172680
  continue;
172657
172681
  }
172658
- const parsedSection = parseInventorySection(sourceFile, section);
172659
- mutableInventory[section.parse.entriesKey] = parsedSection.entries;
172660
- if (section.parse.hasSectionKey) {
172661
- mutableInventory[section.parse.hasSectionKey] = parsedSection.found;
172682
+ if (character !== "}") {
172683
+ index += 1;
172684
+ continue;
172662
172685
  }
172663
- }
172664
- return parsedInventory;
172665
- }
172666
- function readWorkspaceInventory(projectDir) {
172667
- const blockConfigPath = path4.join(projectDir, "scripts", "block-config.ts");
172668
- let source;
172669
- try {
172670
- source = readFileSync(blockConfigPath, "utf8");
172671
- } catch (error) {
172672
- if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") {
172673
- throw new Error(`Workspace inventory file is missing at ${blockConfigPath}. Expected scripts/block-config.ts to exist.`);
172686
+ depth -= 1;
172687
+ if (depth === 0) {
172688
+ let end = index + 1;
172689
+ if (options.includeTrailingNewlines ?? true) {
172690
+ while (end < source.length && /[\r\n]/u.test(source[end] ?? "")) {
172691
+ end += 1;
172692
+ }
172693
+ }
172694
+ return {
172695
+ end,
172696
+ source: source.slice(functionStart, end),
172697
+ start: functionStart
172698
+ };
172674
172699
  }
172675
- throw error;
172700
+ index += 1;
172676
172701
  }
172677
- return {
172678
- blockConfigPath,
172679
- ...parseWorkspaceInventorySource(source)
172680
- };
172702
+ return null;
172681
172703
  }
172682
- async function readWorkspaceInventoryAsync(projectDir) {
172683
- const blockConfigPath = path4.join(projectDir, "scripts", "block-config.ts");
172684
- let source;
172685
- try {
172686
- source = await readFile(blockConfigPath, "utf8");
172687
- } catch (error) {
172688
- if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") {
172689
- throw new Error(`Workspace inventory file is missing at ${blockConfigPath}. Expected scripts/block-config.ts to exist.`);
172690
- }
172691
- throw error;
172704
+ function replacePhpFunctionDefinition(source, functionName, replacement, options = {}) {
172705
+ const functionRange = findPhpFunctionRange(source, functionName, options);
172706
+ if (!functionRange) {
172707
+ return null;
172692
172708
  }
172693
- return {
172694
- blockConfigPath,
172695
- ...parseWorkspaceInventorySource(source)
172696
- };
172697
- }
172698
- function toWorkspaceBlockSelectOptions(blocks) {
172699
- return blocks.map((block) => ({
172700
- description: block.typesFile,
172701
- name: block.slug,
172702
- value: block.slug
172703
- }));
172704
- }
172705
- function getWorkspaceBlockSelectOptions(projectDir) {
172706
- return toWorkspaceBlockSelectOptions(readWorkspaceInventory(projectDir).blocks);
172707
- }
172708
- async function getWorkspaceBlockSelectOptionsAsync(projectDir) {
172709
- return toWorkspaceBlockSelectOptions((await readWorkspaceInventoryAsync(projectDir)).blocks);
172709
+ return [
172710
+ source.slice(0, functionRange.start),
172711
+ options.trimReplacementStart ? replacement.trimStart() : replacement,
172712
+ source.slice(functionRange.end)
172713
+ ].join("");
172710
172714
  }
172715
+
172716
+ // ../wp-typia-project-tools/src/runtime/workspace-inventory-mutations.ts
172711
172717
  function ensureWorkspaceInventorySections(source) {
172712
172718
  let nextSource = source.trimEnd();
172713
172719
  for (const section of INVENTORY_SECTIONS) {
@@ -172734,9 +172740,10 @@ function appendEntriesAtMarker(source, marker, entries) {
172734
172740
  if (!source.includes(marker)) {
172735
172741
  throw new Error(`Workspace inventory marker "${marker}" is missing in scripts/block-config.ts.`);
172736
172742
  }
172737
- return source.replace(marker, `${entries.join(`
172743
+ const replacement = `${entries.join(`
172738
172744
  `)}
172739
- ${marker}`);
172745
+ ${marker}`;
172746
+ return source.replace(marker, () => replacement);
172740
172747
  }
172741
172748
  function appendInventorySectionEntries(source, options) {
172742
172749
  let nextSource = source;
@@ -172810,14 +172817,13 @@ function updateWorkspaceInventorySource(source, options = {}) {
172810
172817
  return nextSource;
172811
172818
  }
172812
172819
  async function appendWorkspaceInventoryEntries(projectDir, options) {
172813
- const blockConfigPath = path4.join(projectDir, "scripts", "block-config.ts");
172814
- const source = await readFile(blockConfigPath, "utf8");
172820
+ const blockConfigPath = path5.join(projectDir, "scripts", "block-config.ts");
172821
+ const source = await readFile2(blockConfigPath, "utf8");
172815
172822
  const nextSource = updateWorkspaceInventorySource(source, options);
172816
172823
  if (nextSource !== source) {
172817
172824
  await writeFile(blockConfigPath, nextSource, "utf8");
172818
172825
  }
172819
172826
  }
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 };
172820
172828
 
172821
- 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, getWorkspaceBootstrapPath, patchFile, readOptionalFile, snapshotWorkspaceFiles, rollbackWorkspaceMutation, pathExists, readOptionalUtf8File, getNodeErrorCode, resolveWorkspaceBlock, readWorkspaceBlockJson, getMutableBlockHooks, assertVariationDoesNotExist, assertBlockStyleDoesNotExist, assertBlockTransformDoesNotExist, assertPatternDoesNotExist, assertBindingSourceDoesNotExist, assertRestResourceDoesNotExist, assertAdminViewDoesNotExist, assertAbilityDoesNotExist, assertAiFeatureDoesNotExist, assertEditorPluginDoesNotExist, formatAddHelpText, require_typescript, escapeRegex, quotePhpString, hasPhpFunctionDefinition, hasPhpFunctionCall, findPhpFunctionRange, replacePhpFunctionDefinition, getPropertyNameText, readWorkspaceInventory, readWorkspaceInventoryAsync, getWorkspaceBlockSelectOptions, getWorkspaceBlockSelectOptionsAsync, updateWorkspaceInventorySource, appendWorkspaceInventoryEntries };
172822
-
172823
- //# debugId=3C14848EF1DAC47E64756E2164756E21
172829
+ //# debugId=10B8DF3957EF445164756E2164756E21