@wp-typia/project-tools 0.22.9 → 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.
- package/dist/runtime/ai-artifacts.js +3 -4
- package/dist/runtime/ai-feature-artifacts.js +2 -4
- package/dist/runtime/cli-add-collision.d.ts +25 -0
- package/dist/runtime/cli-add-collision.js +76 -0
- package/dist/runtime/cli-add-filesystem.js +2 -15
- package/dist/runtime/cli-add-help.js +11 -2
- package/dist/runtime/cli-add-kind-ids.d.ts +1 -1
- package/dist/runtime/cli-add-kind-ids.js +3 -0
- package/dist/runtime/cli-add-types.d.ts +117 -0
- package/dist/runtime/cli-add-types.js +29 -1
- package/dist/runtime/cli-add-validation.d.ts +90 -1
- package/dist/runtime/cli-add-validation.js +304 -1
- package/dist/runtime/cli-add-workspace-admin-view-scaffold.js +74 -19
- package/dist/runtime/cli-add-workspace-admin-view-source.js +11 -2
- package/dist/runtime/cli-add-workspace-admin-view-templates.d.ts +20 -2
- package/dist/runtime/cli-add-workspace-admin-view-templates.js +359 -3
- package/dist/runtime/cli-add-workspace-admin-view-types.d.ts +21 -0
- package/dist/runtime/cli-add-workspace-admin-view-types.js +22 -0
- package/dist/runtime/cli-add-workspace-ai-anchors.js +121 -31
- package/dist/runtime/cli-add-workspace-contract-source-emitters.d.ts +15 -0
- package/dist/runtime/cli-add-workspace-contract-source-emitters.js +42 -0
- package/dist/runtime/cli-add-workspace-contract.d.ts +15 -0
- package/dist/runtime/cli-add-workspace-contract.js +65 -0
- package/dist/runtime/cli-add-workspace-integration-env.d.ts +24 -0
- package/dist/runtime/cli-add-workspace-integration-env.js +391 -0
- package/dist/runtime/cli-add-workspace-post-meta-anchors.d.ts +23 -0
- package/dist/runtime/cli-add-workspace-post-meta-anchors.js +244 -0
- package/dist/runtime/cli-add-workspace-post-meta-source-emitters.d.ts +63 -0
- package/dist/runtime/cli-add-workspace-post-meta-source-emitters.js +179 -0
- package/dist/runtime/cli-add-workspace-post-meta.d.ts +15 -0
- package/dist/runtime/cli-add-workspace-post-meta.js +107 -0
- package/dist/runtime/cli-add-workspace-rest-anchors.d.ts +1 -0
- package/dist/runtime/cli-add-workspace-rest-anchors.js +285 -21
- package/dist/runtime/cli-add-workspace-rest-source-emitters.d.ts +90 -2
- package/dist/runtime/cli-add-workspace-rest-source-emitters.js +302 -29
- package/dist/runtime/cli-add-workspace-rest.d.ts +15 -2
- package/dist/runtime/cli-add-workspace-rest.js +329 -21
- package/dist/runtime/cli-add-workspace.d.ts +15 -0
- package/dist/runtime/cli-add-workspace.js +15 -0
- package/dist/runtime/cli-add.d.ts +1 -1
- package/dist/runtime/cli-add.js +1 -1
- package/dist/runtime/cli-core.d.ts +2 -1
- package/dist/runtime/cli-core.js +2 -1
- package/dist/runtime/cli-doctor-environment.js +1 -3
- package/dist/runtime/cli-doctor-workspace-features.js +128 -10
- package/dist/runtime/cli-doctor-workspace-package.d.ts +25 -3
- package/dist/runtime/cli-doctor-workspace-package.js +35 -13
- package/dist/runtime/cli-doctor-workspace-shared.d.ts +2 -0
- package/dist/runtime/cli-doctor-workspace-shared.js +5 -0
- package/dist/runtime/cli-doctor-workspace.d.ts +1 -1
- package/dist/runtime/cli-doctor-workspace.js +16 -8
- package/dist/runtime/cli-doctor.js +1 -1
- package/dist/runtime/cli-help.js +7 -0
- package/dist/runtime/cli-init-templates.js +11 -1
- package/dist/runtime/contract-artifacts.d.ts +14 -0
- package/dist/runtime/contract-artifacts.js +15 -0
- package/dist/runtime/fs-async.d.ts +7 -0
- package/dist/runtime/fs-async.js +11 -2
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.js +1 -1
- package/dist/runtime/migration-maintenance-verify.js +3 -0
- package/dist/runtime/migration-render-generated.js +4 -0
- package/dist/runtime/package-versions.js +3 -7
- package/dist/runtime/rest-resource-artifacts.d.ts +57 -1
- package/dist/runtime/rest-resource-artifacts.js +97 -1
- package/dist/runtime/scaffold-repository-reference.js +3 -7
- package/dist/runtime/template-render.d.ts +1 -1
- package/dist/runtime/template-render.js +1 -1
- package/dist/runtime/template-source-cache-markers.d.ts +37 -0
- package/dist/runtime/template-source-cache-markers.js +125 -0
- package/dist/runtime/template-source-cache.d.ts +1 -4
- package/dist/runtime/template-source-cache.js +16 -122
- package/dist/runtime/template-source-external.d.ts +4 -2
- package/dist/runtime/template-source-external.js +4 -2
- package/dist/runtime/template-source-remote.d.ts +8 -4
- package/dist/runtime/template-source-remote.js +8 -4
- package/dist/runtime/typia-llm.js +3 -4
- package/dist/runtime/workspace-inventory-mutations.d.ts +24 -0
- package/dist/runtime/workspace-inventory-mutations.js +181 -0
- package/dist/runtime/workspace-inventory-parser.d.ts +53 -0
- package/dist/runtime/workspace-inventory-parser.js +632 -0
- package/dist/runtime/workspace-inventory-read.d.ts +51 -0
- package/dist/runtime/workspace-inventory-read.js +98 -0
- package/dist/runtime/workspace-inventory-templates.d.ts +50 -0
- package/dist/runtime/workspace-inventory-templates.js +268 -0
- package/dist/runtime/workspace-inventory-types.d.ts +220 -0
- package/dist/runtime/workspace-inventory-types.js +1 -0
- package/dist/runtime/workspace-inventory.d.ts +5 -252
- package/dist/runtime/workspace-inventory.js +4 -928
- package/package.json +2 -2
|
@@ -1,928 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import { REST_RESOURCE_METHOD_IDS } from "./cli-add-shared.js";
|
|
6
|
-
import { escapeRegex } from "./php-utils.js";
|
|
7
|
-
import { getPropertyNameText } from "./ts-property-names.js";
|
|
8
|
-
function defineInventoryEntryParser() {
|
|
9
|
-
return (descriptor) => descriptor;
|
|
10
|
-
}
|
|
11
|
-
export const BLOCK_CONFIG_ENTRY_MARKER = "\t// wp-typia add block entries";
|
|
12
|
-
export const VARIATION_CONFIG_ENTRY_MARKER = "\t// wp-typia add variation entries";
|
|
13
|
-
export const BLOCK_STYLE_CONFIG_ENTRY_MARKER = "\t// wp-typia add style entries";
|
|
14
|
-
export const BLOCK_TRANSFORM_CONFIG_ENTRY_MARKER = "\t// wp-typia add transform entries";
|
|
15
|
-
export const PATTERN_CONFIG_ENTRY_MARKER = "\t// wp-typia add pattern entries";
|
|
16
|
-
export const BINDING_SOURCE_CONFIG_ENTRY_MARKER = "\t// wp-typia add binding-source entries";
|
|
17
|
-
export const REST_RESOURCE_CONFIG_ENTRY_MARKER = "\t// wp-typia add rest-resource entries";
|
|
18
|
-
export const ABILITY_CONFIG_ENTRY_MARKER = "\t// wp-typia add ability entries";
|
|
19
|
-
export const AI_FEATURE_CONFIG_ENTRY_MARKER = "\t// wp-typia add ai-feature entries";
|
|
20
|
-
export const ADMIN_VIEW_CONFIG_ENTRY_MARKER = "\t// wp-typia add admin-view entries";
|
|
21
|
-
/**
|
|
22
|
-
* Marker used to append generated editor-plugin entries into `EDITOR_PLUGINS`.
|
|
23
|
-
*/
|
|
24
|
-
export const EDITOR_PLUGIN_CONFIG_ENTRY_MARKER = "\t// wp-typia add editor-plugin entries";
|
|
25
|
-
const VARIATIONS_INTERFACE_SECTION = `
|
|
26
|
-
|
|
27
|
-
export interface WorkspaceVariationConfig {
|
|
28
|
-
\tblock: string;
|
|
29
|
-
\tfile: string;
|
|
30
|
-
\tslug: string;
|
|
31
|
-
}
|
|
32
|
-
`;
|
|
33
|
-
const VARIATIONS_CONST_SECTION = `
|
|
34
|
-
|
|
35
|
-
export const VARIATIONS: WorkspaceVariationConfig[] = [
|
|
36
|
-
\t// wp-typia add variation entries
|
|
37
|
-
];
|
|
38
|
-
`;
|
|
39
|
-
const BLOCK_STYLES_INTERFACE_SECTION = `
|
|
40
|
-
|
|
41
|
-
export interface WorkspaceBlockStyleConfig {
|
|
42
|
-
\tblock: string;
|
|
43
|
-
\tfile: string;
|
|
44
|
-
\tslug: string;
|
|
45
|
-
}
|
|
46
|
-
`;
|
|
47
|
-
const BLOCK_STYLES_CONST_SECTION = `
|
|
48
|
-
|
|
49
|
-
export const BLOCK_STYLES: WorkspaceBlockStyleConfig[] = [
|
|
50
|
-
\t// wp-typia add style entries
|
|
51
|
-
];
|
|
52
|
-
`;
|
|
53
|
-
const BLOCK_TRANSFORMS_INTERFACE_SECTION = `
|
|
54
|
-
|
|
55
|
-
export interface WorkspaceBlockTransformConfig {
|
|
56
|
-
\tblock: string;
|
|
57
|
-
\tfile: string;
|
|
58
|
-
\tfrom: string;
|
|
59
|
-
\tslug: string;
|
|
60
|
-
\tto: string;
|
|
61
|
-
}
|
|
62
|
-
`;
|
|
63
|
-
const BLOCK_TRANSFORMS_CONST_SECTION = `
|
|
64
|
-
|
|
65
|
-
export const BLOCK_TRANSFORMS: WorkspaceBlockTransformConfig[] = [
|
|
66
|
-
\t// wp-typia add transform entries
|
|
67
|
-
];
|
|
68
|
-
`;
|
|
69
|
-
const PATTERNS_INTERFACE_SECTION = `
|
|
70
|
-
|
|
71
|
-
export interface WorkspacePatternConfig {
|
|
72
|
-
\tfile: string;
|
|
73
|
-
\tslug: string;
|
|
74
|
-
}
|
|
75
|
-
`;
|
|
76
|
-
const PATTERNS_CONST_SECTION = `
|
|
77
|
-
|
|
78
|
-
export const PATTERNS: WorkspacePatternConfig[] = [
|
|
79
|
-
\t// wp-typia add pattern entries
|
|
80
|
-
];
|
|
81
|
-
`;
|
|
82
|
-
const BINDING_SOURCES_INTERFACE_SECTION = `
|
|
83
|
-
|
|
84
|
-
export interface WorkspaceBindingSourceConfig {
|
|
85
|
-
\tattribute?: string;
|
|
86
|
-
\tblock?: string;
|
|
87
|
-
\teditorFile: string;
|
|
88
|
-
\tserverFile: string;
|
|
89
|
-
\tslug: string;
|
|
90
|
-
}
|
|
91
|
-
`;
|
|
92
|
-
const BINDING_SOURCES_CONST_SECTION = `
|
|
93
|
-
|
|
94
|
-
export const BINDING_SOURCES: WorkspaceBindingSourceConfig[] = [
|
|
95
|
-
\t// wp-typia add binding-source entries
|
|
96
|
-
];
|
|
97
|
-
`;
|
|
98
|
-
const REST_RESOURCES_INTERFACE_SECTION = `
|
|
99
|
-
|
|
100
|
-
export interface WorkspaceRestResourceConfig {
|
|
101
|
-
\tapiFile: string;
|
|
102
|
-
\tclientFile: string;
|
|
103
|
-
\tdataFile: string;
|
|
104
|
-
\tmethods: Array< 'list' | 'read' | 'create' | 'update' | 'delete' >;
|
|
105
|
-
\tnamespace: string;
|
|
106
|
-
\topenApiFile: string;
|
|
107
|
-
\tphpFile: string;
|
|
108
|
-
\trestManifest?: ReturnType<
|
|
109
|
-
\t\ttypeof import( '@wp-typia/block-runtime/metadata-core' ).defineEndpointManifest
|
|
110
|
-
\t>;
|
|
111
|
-
\tslug: string;
|
|
112
|
-
\ttypesFile: string;
|
|
113
|
-
\tvalidatorsFile: string;
|
|
114
|
-
}
|
|
115
|
-
`;
|
|
116
|
-
const REST_RESOURCES_CONST_SECTION = `
|
|
117
|
-
|
|
118
|
-
export const REST_RESOURCES: WorkspaceRestResourceConfig[] = [
|
|
119
|
-
\t// wp-typia add rest-resource entries
|
|
120
|
-
];
|
|
121
|
-
`;
|
|
122
|
-
const WORKSPACE_COMPATIBILITY_CONFIG_FIELD = `\tcompatibility?: {
|
|
123
|
-
\t\thardMinimums: {
|
|
124
|
-
\t\t\tphp?: string;
|
|
125
|
-
\t\t\twordpress?: string;
|
|
126
|
-
\t\t};
|
|
127
|
-
\t\tmode: 'baseline' | 'optional' | 'required';
|
|
128
|
-
\t\toptionalFeatureIds: string[];
|
|
129
|
-
\t\toptionalFeatures: string[];
|
|
130
|
-
\t\trequiredFeatureIds: string[];
|
|
131
|
-
\t\trequiredFeatures: string[];
|
|
132
|
-
\t\truntimeGates: string[];
|
|
133
|
-
\t};
|
|
134
|
-
`;
|
|
135
|
-
const ABILITIES_INTERFACE_SECTION = `
|
|
136
|
-
|
|
137
|
-
export interface WorkspaceAbilityConfig {
|
|
138
|
-
\tclientFile: string;
|
|
139
|
-
${WORKSPACE_COMPATIBILITY_CONFIG_FIELD}\tconfigFile: string;
|
|
140
|
-
\tdataFile: string;
|
|
141
|
-
\tinputSchemaFile: string;
|
|
142
|
-
\tinputTypeName: string;
|
|
143
|
-
\toutputSchemaFile: string;
|
|
144
|
-
\toutputTypeName: string;
|
|
145
|
-
\tphpFile: string;
|
|
146
|
-
\tslug: string;
|
|
147
|
-
\ttypesFile: string;
|
|
148
|
-
}
|
|
149
|
-
`;
|
|
150
|
-
const ABILITIES_CONST_SECTION = `
|
|
151
|
-
|
|
152
|
-
export const ABILITIES: WorkspaceAbilityConfig[] = [
|
|
153
|
-
\t// wp-typia add ability entries
|
|
154
|
-
];
|
|
155
|
-
`;
|
|
156
|
-
const AI_FEATURES_INTERFACE_SECTION = `
|
|
157
|
-
|
|
158
|
-
export interface WorkspaceAiFeatureConfig {
|
|
159
|
-
\taiSchemaFile: string;
|
|
160
|
-
\tapiFile: string;
|
|
161
|
-
\tclientFile: string;
|
|
162
|
-
${WORKSPACE_COMPATIBILITY_CONFIG_FIELD}\tdataFile: string;
|
|
163
|
-
\tnamespace: string;
|
|
164
|
-
\topenApiFile: string;
|
|
165
|
-
\tphpFile: string;
|
|
166
|
-
\trestManifest?: ReturnType<
|
|
167
|
-
\t\ttypeof import( '@wp-typia/block-runtime/metadata-core' ).defineEndpointManifest
|
|
168
|
-
\t>;
|
|
169
|
-
\tslug: string;
|
|
170
|
-
\ttypesFile: string;
|
|
171
|
-
\tvalidatorsFile: string;
|
|
172
|
-
}
|
|
173
|
-
`;
|
|
174
|
-
const AI_FEATURES_CONST_SECTION = `
|
|
175
|
-
|
|
176
|
-
export const AI_FEATURES: WorkspaceAiFeatureConfig[] = [
|
|
177
|
-
\t// wp-typia add ai-feature entries
|
|
178
|
-
];
|
|
179
|
-
`;
|
|
180
|
-
const ADMIN_VIEWS_INTERFACE_SECTION = `
|
|
181
|
-
|
|
182
|
-
export interface WorkspaceAdminViewConfig {
|
|
183
|
-
\tfile: string;
|
|
184
|
-
\tphpFile: string;
|
|
185
|
-
\tslug: string;
|
|
186
|
-
\tsource?: string;
|
|
187
|
-
}
|
|
188
|
-
`;
|
|
189
|
-
const ADMIN_VIEWS_CONST_SECTION = `
|
|
190
|
-
|
|
191
|
-
export const ADMIN_VIEWS: WorkspaceAdminViewConfig[] = [
|
|
192
|
-
\t// wp-typia add admin-view entries
|
|
193
|
-
];
|
|
194
|
-
`;
|
|
195
|
-
const EDITOR_PLUGINS_INTERFACE_SECTION = `
|
|
196
|
-
|
|
197
|
-
export interface WorkspaceEditorPluginConfig {
|
|
198
|
-
\tfile: string;
|
|
199
|
-
\tslug: string;
|
|
200
|
-
\tslot: string;
|
|
201
|
-
}
|
|
202
|
-
`;
|
|
203
|
-
const EDITOR_PLUGINS_CONST_SECTION = `
|
|
204
|
-
|
|
205
|
-
export const EDITOR_PLUGINS: WorkspaceEditorPluginConfig[] = [
|
|
206
|
-
\t// wp-typia add editor-plugin entries
|
|
207
|
-
];
|
|
208
|
-
`;
|
|
209
|
-
const BLOCK_INVENTORY_SECTION = {
|
|
210
|
-
append: {
|
|
211
|
-
marker: BLOCK_CONFIG_ENTRY_MARKER,
|
|
212
|
-
optionKey: "blockEntries",
|
|
213
|
-
},
|
|
214
|
-
parse: {
|
|
215
|
-
entriesKey: "blocks",
|
|
216
|
-
entry: defineInventoryEntryParser()({
|
|
217
|
-
entryName: "BLOCKS",
|
|
218
|
-
fields: [
|
|
219
|
-
{ key: "apiTypesFile" },
|
|
220
|
-
{ key: "attributeTypeName" },
|
|
221
|
-
{ key: "openApiFile" },
|
|
222
|
-
{ key: "slug", required: true },
|
|
223
|
-
{ key: "typesFile", required: true },
|
|
224
|
-
],
|
|
225
|
-
}),
|
|
226
|
-
exportName: "BLOCKS",
|
|
227
|
-
required: true,
|
|
228
|
-
},
|
|
229
|
-
};
|
|
230
|
-
const INVENTORY_SECTIONS = [
|
|
231
|
-
{
|
|
232
|
-
append: {
|
|
233
|
-
marker: VARIATION_CONFIG_ENTRY_MARKER,
|
|
234
|
-
optionKey: "variationEntries",
|
|
235
|
-
},
|
|
236
|
-
interface: {
|
|
237
|
-
name: "WorkspaceVariationConfig",
|
|
238
|
-
section: VARIATIONS_INTERFACE_SECTION,
|
|
239
|
-
},
|
|
240
|
-
parse: {
|
|
241
|
-
entriesKey: "variations",
|
|
242
|
-
entry: defineInventoryEntryParser()({
|
|
243
|
-
entryName: "VARIATIONS",
|
|
244
|
-
fields: [
|
|
245
|
-
{ key: "block", required: true },
|
|
246
|
-
{ key: "file", required: true },
|
|
247
|
-
{ key: "slug", required: true },
|
|
248
|
-
],
|
|
249
|
-
}),
|
|
250
|
-
hasSectionKey: "hasVariationsSection",
|
|
251
|
-
},
|
|
252
|
-
value: {
|
|
253
|
-
name: "VARIATIONS",
|
|
254
|
-
section: VARIATIONS_CONST_SECTION,
|
|
255
|
-
},
|
|
256
|
-
},
|
|
257
|
-
{
|
|
258
|
-
append: {
|
|
259
|
-
marker: BLOCK_STYLE_CONFIG_ENTRY_MARKER,
|
|
260
|
-
optionKey: "blockStyleEntries",
|
|
261
|
-
},
|
|
262
|
-
interface: {
|
|
263
|
-
name: "WorkspaceBlockStyleConfig",
|
|
264
|
-
section: BLOCK_STYLES_INTERFACE_SECTION,
|
|
265
|
-
},
|
|
266
|
-
parse: {
|
|
267
|
-
entriesKey: "blockStyles",
|
|
268
|
-
entry: defineInventoryEntryParser()({
|
|
269
|
-
entryName: "BLOCK_STYLES",
|
|
270
|
-
fields: [
|
|
271
|
-
{ key: "block", required: true },
|
|
272
|
-
{ key: "file", required: true },
|
|
273
|
-
{ key: "slug", required: true },
|
|
274
|
-
],
|
|
275
|
-
}),
|
|
276
|
-
hasSectionKey: "hasBlockStylesSection",
|
|
277
|
-
},
|
|
278
|
-
value: {
|
|
279
|
-
name: "BLOCK_STYLES",
|
|
280
|
-
section: BLOCK_STYLES_CONST_SECTION,
|
|
281
|
-
},
|
|
282
|
-
},
|
|
283
|
-
{
|
|
284
|
-
append: {
|
|
285
|
-
marker: BLOCK_TRANSFORM_CONFIG_ENTRY_MARKER,
|
|
286
|
-
optionKey: "blockTransformEntries",
|
|
287
|
-
},
|
|
288
|
-
interface: {
|
|
289
|
-
name: "WorkspaceBlockTransformConfig",
|
|
290
|
-
section: BLOCK_TRANSFORMS_INTERFACE_SECTION,
|
|
291
|
-
},
|
|
292
|
-
parse: {
|
|
293
|
-
entriesKey: "blockTransforms",
|
|
294
|
-
entry: defineInventoryEntryParser()({
|
|
295
|
-
entryName: "BLOCK_TRANSFORMS",
|
|
296
|
-
fields: [
|
|
297
|
-
{ key: "block", required: true },
|
|
298
|
-
{ key: "file", required: true },
|
|
299
|
-
{ key: "from", required: true },
|
|
300
|
-
{ key: "slug", required: true },
|
|
301
|
-
{ key: "to", required: true },
|
|
302
|
-
],
|
|
303
|
-
}),
|
|
304
|
-
hasSectionKey: "hasBlockTransformsSection",
|
|
305
|
-
},
|
|
306
|
-
value: {
|
|
307
|
-
name: "BLOCK_TRANSFORMS",
|
|
308
|
-
section: BLOCK_TRANSFORMS_CONST_SECTION,
|
|
309
|
-
},
|
|
310
|
-
},
|
|
311
|
-
{
|
|
312
|
-
append: {
|
|
313
|
-
marker: PATTERN_CONFIG_ENTRY_MARKER,
|
|
314
|
-
optionKey: "patternEntries",
|
|
315
|
-
},
|
|
316
|
-
interface: {
|
|
317
|
-
name: "WorkspacePatternConfig",
|
|
318
|
-
section: PATTERNS_INTERFACE_SECTION,
|
|
319
|
-
},
|
|
320
|
-
parse: {
|
|
321
|
-
entriesKey: "patterns",
|
|
322
|
-
entry: defineInventoryEntryParser()({
|
|
323
|
-
entryName: "PATTERNS",
|
|
324
|
-
fields: [
|
|
325
|
-
{ key: "file", required: true },
|
|
326
|
-
{ key: "slug", required: true },
|
|
327
|
-
],
|
|
328
|
-
}),
|
|
329
|
-
hasSectionKey: "hasPatternsSection",
|
|
330
|
-
},
|
|
331
|
-
value: {
|
|
332
|
-
name: "PATTERNS",
|
|
333
|
-
section: PATTERNS_CONST_SECTION,
|
|
334
|
-
},
|
|
335
|
-
},
|
|
336
|
-
{
|
|
337
|
-
append: {
|
|
338
|
-
marker: BINDING_SOURCE_CONFIG_ENTRY_MARKER,
|
|
339
|
-
optionKey: "bindingSourceEntries",
|
|
340
|
-
},
|
|
341
|
-
interface: {
|
|
342
|
-
name: "WorkspaceBindingSourceConfig",
|
|
343
|
-
section: BINDING_SOURCES_INTERFACE_SECTION,
|
|
344
|
-
},
|
|
345
|
-
parse: {
|
|
346
|
-
entriesKey: "bindingSources",
|
|
347
|
-
entry: defineInventoryEntryParser()({
|
|
348
|
-
entryName: "BINDING_SOURCES",
|
|
349
|
-
fields: [
|
|
350
|
-
{ key: "attribute" },
|
|
351
|
-
{ key: "block" },
|
|
352
|
-
{ key: "editorFile", required: true },
|
|
353
|
-
{ key: "serverFile", required: true },
|
|
354
|
-
{ key: "slug", required: true },
|
|
355
|
-
],
|
|
356
|
-
}),
|
|
357
|
-
hasSectionKey: "hasBindingSourcesSection",
|
|
358
|
-
},
|
|
359
|
-
value: {
|
|
360
|
-
name: "BINDING_SOURCES",
|
|
361
|
-
section: BINDING_SOURCES_CONST_SECTION,
|
|
362
|
-
},
|
|
363
|
-
},
|
|
364
|
-
{
|
|
365
|
-
append: {
|
|
366
|
-
marker: REST_RESOURCE_CONFIG_ENTRY_MARKER,
|
|
367
|
-
optionKey: "restResourceEntries",
|
|
368
|
-
},
|
|
369
|
-
interface: {
|
|
370
|
-
name: "WorkspaceRestResourceConfig",
|
|
371
|
-
section: REST_RESOURCES_INTERFACE_SECTION,
|
|
372
|
-
},
|
|
373
|
-
parse: {
|
|
374
|
-
entriesKey: "restResources",
|
|
375
|
-
entry: defineInventoryEntryParser()({
|
|
376
|
-
entryName: "REST_RESOURCES",
|
|
377
|
-
fields: [
|
|
378
|
-
{ key: "apiFile", required: true },
|
|
379
|
-
{ key: "clientFile", required: true },
|
|
380
|
-
{ key: "dataFile", required: true },
|
|
381
|
-
{
|
|
382
|
-
key: "methods",
|
|
383
|
-
kind: "stringArray",
|
|
384
|
-
required: true,
|
|
385
|
-
validate: (value, context) => {
|
|
386
|
-
const methods = Array.isArray(value) ? value : [];
|
|
387
|
-
const invalidMethods = methods.filter((method) => !REST_RESOURCE_METHOD_IDS.includes(method));
|
|
388
|
-
if (invalidMethods.length > 0) {
|
|
389
|
-
throw new Error(`${context.entryName}[${context.elementIndex}].${context.key} includes unsupported values: ${invalidMethods.join(", ")}.`);
|
|
390
|
-
}
|
|
391
|
-
},
|
|
392
|
-
},
|
|
393
|
-
{ key: "namespace", required: true },
|
|
394
|
-
{ key: "openApiFile", required: true },
|
|
395
|
-
{ key: "phpFile", required: true },
|
|
396
|
-
{ key: "slug", required: true },
|
|
397
|
-
{ key: "typesFile", required: true },
|
|
398
|
-
{ key: "validatorsFile", required: true },
|
|
399
|
-
],
|
|
400
|
-
}),
|
|
401
|
-
hasSectionKey: "hasRestResourcesSection",
|
|
402
|
-
},
|
|
403
|
-
value: {
|
|
404
|
-
name: "REST_RESOURCES",
|
|
405
|
-
section: REST_RESOURCES_CONST_SECTION,
|
|
406
|
-
},
|
|
407
|
-
},
|
|
408
|
-
{
|
|
409
|
-
append: {
|
|
410
|
-
marker: ABILITY_CONFIG_ENTRY_MARKER,
|
|
411
|
-
optionKey: "abilityEntries",
|
|
412
|
-
},
|
|
413
|
-
interface: {
|
|
414
|
-
name: "WorkspaceAbilityConfig",
|
|
415
|
-
section: ABILITIES_INTERFACE_SECTION,
|
|
416
|
-
},
|
|
417
|
-
parse: {
|
|
418
|
-
entriesKey: "abilities",
|
|
419
|
-
entry: defineInventoryEntryParser()({
|
|
420
|
-
entryName: "ABILITIES",
|
|
421
|
-
fields: [
|
|
422
|
-
{ key: "clientFile", required: true },
|
|
423
|
-
{ key: "configFile", required: true },
|
|
424
|
-
{ key: "dataFile", required: true },
|
|
425
|
-
{ key: "inputSchemaFile", required: true },
|
|
426
|
-
{ key: "inputTypeName", required: true },
|
|
427
|
-
{ key: "outputSchemaFile", required: true },
|
|
428
|
-
{ key: "outputTypeName", required: true },
|
|
429
|
-
{ key: "phpFile", required: true },
|
|
430
|
-
{ key: "slug", required: true },
|
|
431
|
-
{ key: "typesFile", required: true },
|
|
432
|
-
],
|
|
433
|
-
}),
|
|
434
|
-
hasSectionKey: "hasAbilitiesSection",
|
|
435
|
-
},
|
|
436
|
-
value: {
|
|
437
|
-
name: "ABILITIES",
|
|
438
|
-
section: ABILITIES_CONST_SECTION,
|
|
439
|
-
},
|
|
440
|
-
},
|
|
441
|
-
{
|
|
442
|
-
append: {
|
|
443
|
-
marker: AI_FEATURE_CONFIG_ENTRY_MARKER,
|
|
444
|
-
optionKey: "aiFeatureEntries",
|
|
445
|
-
},
|
|
446
|
-
interface: {
|
|
447
|
-
name: "WorkspaceAiFeatureConfig",
|
|
448
|
-
section: AI_FEATURES_INTERFACE_SECTION,
|
|
449
|
-
},
|
|
450
|
-
parse: {
|
|
451
|
-
entriesKey: "aiFeatures",
|
|
452
|
-
entry: defineInventoryEntryParser()({
|
|
453
|
-
entryName: "AI_FEATURES",
|
|
454
|
-
fields: [
|
|
455
|
-
{ key: "aiSchemaFile", required: true },
|
|
456
|
-
{ key: "apiFile", required: true },
|
|
457
|
-
{ key: "clientFile", required: true },
|
|
458
|
-
{ key: "dataFile", required: true },
|
|
459
|
-
{ key: "namespace", required: true },
|
|
460
|
-
{ key: "openApiFile", required: true },
|
|
461
|
-
{ key: "phpFile", required: true },
|
|
462
|
-
{ key: "slug", required: true },
|
|
463
|
-
{ key: "typesFile", required: true },
|
|
464
|
-
{ key: "validatorsFile", required: true },
|
|
465
|
-
],
|
|
466
|
-
}),
|
|
467
|
-
hasSectionKey: "hasAiFeaturesSection",
|
|
468
|
-
},
|
|
469
|
-
value: {
|
|
470
|
-
name: "AI_FEATURES",
|
|
471
|
-
section: AI_FEATURES_CONST_SECTION,
|
|
472
|
-
},
|
|
473
|
-
},
|
|
474
|
-
{
|
|
475
|
-
append: {
|
|
476
|
-
marker: ADMIN_VIEW_CONFIG_ENTRY_MARKER,
|
|
477
|
-
optionKey: "adminViewEntries",
|
|
478
|
-
},
|
|
479
|
-
interface: {
|
|
480
|
-
name: "WorkspaceAdminViewConfig",
|
|
481
|
-
section: ADMIN_VIEWS_INTERFACE_SECTION,
|
|
482
|
-
},
|
|
483
|
-
parse: {
|
|
484
|
-
entriesKey: "adminViews",
|
|
485
|
-
entry: defineInventoryEntryParser()({
|
|
486
|
-
entryName: "ADMIN_VIEWS",
|
|
487
|
-
fields: [
|
|
488
|
-
{ key: "file", required: true },
|
|
489
|
-
{ key: "phpFile", required: true },
|
|
490
|
-
{ key: "slug", required: true },
|
|
491
|
-
{ key: "source" },
|
|
492
|
-
],
|
|
493
|
-
}),
|
|
494
|
-
hasSectionKey: "hasAdminViewsSection",
|
|
495
|
-
},
|
|
496
|
-
value: {
|
|
497
|
-
name: "ADMIN_VIEWS",
|
|
498
|
-
section: ADMIN_VIEWS_CONST_SECTION,
|
|
499
|
-
},
|
|
500
|
-
},
|
|
501
|
-
{
|
|
502
|
-
append: {
|
|
503
|
-
marker: EDITOR_PLUGIN_CONFIG_ENTRY_MARKER,
|
|
504
|
-
optionKey: "editorPluginEntries",
|
|
505
|
-
},
|
|
506
|
-
interface: {
|
|
507
|
-
name: "WorkspaceEditorPluginConfig",
|
|
508
|
-
section: EDITOR_PLUGINS_INTERFACE_SECTION,
|
|
509
|
-
},
|
|
510
|
-
parse: {
|
|
511
|
-
entriesKey: "editorPlugins",
|
|
512
|
-
entry: defineInventoryEntryParser()({
|
|
513
|
-
entryName: "EDITOR_PLUGINS",
|
|
514
|
-
fields: [
|
|
515
|
-
{ key: "file", required: true },
|
|
516
|
-
{ key: "slug", required: true },
|
|
517
|
-
{ key: "slot", required: true },
|
|
518
|
-
],
|
|
519
|
-
}),
|
|
520
|
-
hasSectionKey: "hasEditorPluginsSection",
|
|
521
|
-
},
|
|
522
|
-
value: {
|
|
523
|
-
name: "EDITOR_PLUGINS",
|
|
524
|
-
section: EDITOR_PLUGINS_CONST_SECTION,
|
|
525
|
-
},
|
|
526
|
-
},
|
|
527
|
-
];
|
|
528
|
-
function findExportedArrayLiteral(sourceFile, exportName) {
|
|
529
|
-
for (const statement of sourceFile.statements) {
|
|
530
|
-
if (!ts.isVariableStatement(statement)) {
|
|
531
|
-
continue;
|
|
532
|
-
}
|
|
533
|
-
if (!statement.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword)) {
|
|
534
|
-
continue;
|
|
535
|
-
}
|
|
536
|
-
for (const declaration of statement.declarationList.declarations) {
|
|
537
|
-
if (!ts.isIdentifier(declaration.name) || declaration.name.text !== exportName) {
|
|
538
|
-
continue;
|
|
539
|
-
}
|
|
540
|
-
if (declaration.initializer && ts.isArrayLiteralExpression(declaration.initializer)) {
|
|
541
|
-
return {
|
|
542
|
-
array: declaration.initializer,
|
|
543
|
-
found: true,
|
|
544
|
-
};
|
|
545
|
-
}
|
|
546
|
-
return {
|
|
547
|
-
array: null,
|
|
548
|
-
found: true,
|
|
549
|
-
};
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
return {
|
|
553
|
-
array: null,
|
|
554
|
-
found: false,
|
|
555
|
-
};
|
|
556
|
-
}
|
|
557
|
-
function getOptionalStringProperty(entryName, elementIndex, objectLiteral, key) {
|
|
558
|
-
for (const property of objectLiteral.properties) {
|
|
559
|
-
if (!ts.isPropertyAssignment(property)) {
|
|
560
|
-
continue;
|
|
561
|
-
}
|
|
562
|
-
const propertyName = getPropertyNameText(property.name);
|
|
563
|
-
if (propertyName !== key) {
|
|
564
|
-
continue;
|
|
565
|
-
}
|
|
566
|
-
if (ts.isStringLiteralLike(property.initializer)) {
|
|
567
|
-
return property.initializer.text;
|
|
568
|
-
}
|
|
569
|
-
throw new Error(`${entryName}[${elementIndex}] must use a string literal for "${key}" in scripts/block-config.ts.`);
|
|
570
|
-
}
|
|
571
|
-
return undefined;
|
|
572
|
-
}
|
|
573
|
-
function getOptionalStringArrayProperty(entryName, elementIndex, objectLiteral, key) {
|
|
574
|
-
for (const property of objectLiteral.properties) {
|
|
575
|
-
if (!ts.isPropertyAssignment(property)) {
|
|
576
|
-
continue;
|
|
577
|
-
}
|
|
578
|
-
const propertyName = getPropertyNameText(property.name);
|
|
579
|
-
if (propertyName !== key) {
|
|
580
|
-
continue;
|
|
581
|
-
}
|
|
582
|
-
if (!ts.isArrayLiteralExpression(property.initializer)) {
|
|
583
|
-
throw new Error(`${entryName}[${elementIndex}] must use an array literal for "${key}" in scripts/block-config.ts.`);
|
|
584
|
-
}
|
|
585
|
-
return property.initializer.elements.map((element, itemIndex) => {
|
|
586
|
-
if (!ts.isStringLiteralLike(element)) {
|
|
587
|
-
throw new Error(`${entryName}[${elementIndex}].${key}[${itemIndex}] must use a string literal in scripts/block-config.ts.`);
|
|
588
|
-
}
|
|
589
|
-
return element.text;
|
|
590
|
-
});
|
|
591
|
-
}
|
|
592
|
-
return undefined;
|
|
593
|
-
}
|
|
594
|
-
function isMissingRequiredInventoryValue(value) {
|
|
595
|
-
return value === undefined || (typeof value === "string" && value.length === 0);
|
|
596
|
-
}
|
|
597
|
-
function formatMissingRequiredInventoryFields(keys) {
|
|
598
|
-
return keys.length === 1
|
|
599
|
-
? `required "${keys[0]}"`
|
|
600
|
-
: `required fields ${keys.map((key) => `"${key}"`).join(", ")}`;
|
|
601
|
-
}
|
|
602
|
-
function assertParsedInventoryEntry(entry, descriptor, elementIndex) {
|
|
603
|
-
const missingRequiredKeys = descriptor.fields
|
|
604
|
-
.filter((field) => field.required === true &&
|
|
605
|
-
isMissingRequiredInventoryValue(entry[field.key]))
|
|
606
|
-
.map((field) => field.key);
|
|
607
|
-
if (missingRequiredKeys.length > 0) {
|
|
608
|
-
throw new Error(`${descriptor.entryName}[${elementIndex}] is missing ${formatMissingRequiredInventoryFields(missingRequiredKeys)} in scripts/block-config.ts.`);
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
function parseInventoryEntries(arrayLiteral, descriptor) {
|
|
612
|
-
return arrayLiteral.elements.map((element, elementIndex) => {
|
|
613
|
-
if (!ts.isObjectLiteralExpression(element)) {
|
|
614
|
-
throw new Error(`${descriptor.entryName}[${elementIndex}] must be an object literal in scripts/block-config.ts.`);
|
|
615
|
-
}
|
|
616
|
-
const entry = {};
|
|
617
|
-
for (const field of descriptor.fields) {
|
|
618
|
-
const kind = field.kind ?? "string";
|
|
619
|
-
const value = kind === "stringArray"
|
|
620
|
-
? getOptionalStringArrayProperty(descriptor.entryName, elementIndex, element, field.key)
|
|
621
|
-
: getOptionalStringProperty(descriptor.entryName, elementIndex, element, field.key);
|
|
622
|
-
field.validate?.(value, {
|
|
623
|
-
elementIndex,
|
|
624
|
-
entryName: descriptor.entryName,
|
|
625
|
-
key: field.key,
|
|
626
|
-
});
|
|
627
|
-
entry[field.key] = value;
|
|
628
|
-
}
|
|
629
|
-
assertParsedInventoryEntry(entry, descriptor, elementIndex);
|
|
630
|
-
return entry;
|
|
631
|
-
});
|
|
632
|
-
}
|
|
633
|
-
function parseInventorySection(sourceFile, descriptor) {
|
|
634
|
-
if (!descriptor.parse) {
|
|
635
|
-
return {
|
|
636
|
-
entries: [],
|
|
637
|
-
found: false,
|
|
638
|
-
};
|
|
639
|
-
}
|
|
640
|
-
const exportName = descriptor.parse.exportName ?? descriptor.value?.name;
|
|
641
|
-
if (!exportName) {
|
|
642
|
-
throw new Error("Inventory parser descriptor is missing an export name.");
|
|
643
|
-
}
|
|
644
|
-
const exportedArray = findExportedArrayLiteral(sourceFile, exportName);
|
|
645
|
-
if (!exportedArray.found) {
|
|
646
|
-
if (descriptor.parse.required) {
|
|
647
|
-
throw new Error(`scripts/block-config.ts must export a ${exportName} array.`);
|
|
648
|
-
}
|
|
649
|
-
return {
|
|
650
|
-
entries: [],
|
|
651
|
-
found: false,
|
|
652
|
-
};
|
|
653
|
-
}
|
|
654
|
-
if (!exportedArray.array) {
|
|
655
|
-
if (descriptor.parse.required) {
|
|
656
|
-
throw new Error(`scripts/block-config.ts must export a ${exportName} array.`);
|
|
657
|
-
}
|
|
658
|
-
throw new Error(`scripts/block-config.ts must export ${exportName} as an array literal.`);
|
|
659
|
-
}
|
|
660
|
-
return {
|
|
661
|
-
entries: parseInventoryEntries(exportedArray.array, descriptor.parse.entry),
|
|
662
|
-
found: true,
|
|
663
|
-
};
|
|
664
|
-
}
|
|
665
|
-
/**
|
|
666
|
-
* Parse workspace inventory entries from the source of `scripts/block-config.ts`.
|
|
667
|
-
*
|
|
668
|
-
* @param source Raw TypeScript source from `scripts/block-config.ts`.
|
|
669
|
-
* @returns Parsed inventory sections without the resolved `blockConfigPath`.
|
|
670
|
-
* @throws {Error} When `BLOCKS` is missing or any inventory entry is malformed.
|
|
671
|
-
*/
|
|
672
|
-
export function parseWorkspaceInventorySource(source) {
|
|
673
|
-
const sourceFile = ts.createSourceFile("block-config.ts", source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
674
|
-
const parsedInventory = {
|
|
675
|
-
abilities: [],
|
|
676
|
-
adminViews: [],
|
|
677
|
-
aiFeatures: [],
|
|
678
|
-
bindingSources: [],
|
|
679
|
-
blockStyles: [],
|
|
680
|
-
blockTransforms: [],
|
|
681
|
-
blocks: parseInventorySection(sourceFile, BLOCK_INVENTORY_SECTION).entries,
|
|
682
|
-
editorPlugins: [],
|
|
683
|
-
hasAbilitiesSection: false,
|
|
684
|
-
hasAdminViewsSection: false,
|
|
685
|
-
hasAiFeaturesSection: false,
|
|
686
|
-
hasBindingSourcesSection: false,
|
|
687
|
-
hasBlockStylesSection: false,
|
|
688
|
-
hasBlockTransformsSection: false,
|
|
689
|
-
hasEditorPluginsSection: false,
|
|
690
|
-
hasPatternsSection: false,
|
|
691
|
-
hasRestResourcesSection: false,
|
|
692
|
-
hasVariationsSection: false,
|
|
693
|
-
patterns: [],
|
|
694
|
-
restResources: [],
|
|
695
|
-
source,
|
|
696
|
-
variations: [],
|
|
697
|
-
};
|
|
698
|
-
const mutableInventory = parsedInventory;
|
|
699
|
-
for (const section of INVENTORY_SECTIONS) {
|
|
700
|
-
if (!section.parse) {
|
|
701
|
-
continue;
|
|
702
|
-
}
|
|
703
|
-
const parsedSection = parseInventorySection(sourceFile, section);
|
|
704
|
-
mutableInventory[section.parse.entriesKey] = parsedSection.entries;
|
|
705
|
-
if (section.parse.hasSectionKey) {
|
|
706
|
-
mutableInventory[section.parse.hasSectionKey] = parsedSection.found;
|
|
707
|
-
}
|
|
708
|
-
}
|
|
709
|
-
return parsedInventory;
|
|
710
|
-
}
|
|
711
|
-
/**
|
|
712
|
-
* Synchronously read and parse the canonical workspace inventory file.
|
|
713
|
-
*
|
|
714
|
-
* This compatibility helper is intentionally sync-only for callers that expose
|
|
715
|
-
* synchronous APIs. Prefer `readWorkspaceInventoryAsync()` from async command
|
|
716
|
-
* paths so workspace reads do not block the event loop.
|
|
717
|
-
*
|
|
718
|
-
* @param projectDir Workspace root directory.
|
|
719
|
-
* @returns Parsed `WorkspaceInventory` including the resolved `blockConfigPath`.
|
|
720
|
-
* @throws {Error} When `scripts/block-config.ts` is missing or invalid.
|
|
721
|
-
*/
|
|
722
|
-
export function readWorkspaceInventory(projectDir) {
|
|
723
|
-
const blockConfigPath = path.join(projectDir, "scripts", "block-config.ts");
|
|
724
|
-
let source;
|
|
725
|
-
try {
|
|
726
|
-
source = readFileSync(blockConfigPath, "utf8");
|
|
727
|
-
}
|
|
728
|
-
catch (error) {
|
|
729
|
-
if (typeof error === "object" &&
|
|
730
|
-
error !== null &&
|
|
731
|
-
"code" in error &&
|
|
732
|
-
error.code === "ENOENT") {
|
|
733
|
-
throw new Error(`Workspace inventory file is missing at ${blockConfigPath}. Expected scripts/block-config.ts to exist.`);
|
|
734
|
-
}
|
|
735
|
-
throw error;
|
|
736
|
-
}
|
|
737
|
-
return {
|
|
738
|
-
blockConfigPath,
|
|
739
|
-
...parseWorkspaceInventorySource(source),
|
|
740
|
-
};
|
|
741
|
-
}
|
|
742
|
-
/**
|
|
743
|
-
* Asynchronously read and parse the canonical workspace inventory file.
|
|
744
|
-
*
|
|
745
|
-
* @param projectDir Workspace root directory.
|
|
746
|
-
* @returns Parsed `WorkspaceInventory` including the resolved `blockConfigPath`.
|
|
747
|
-
* @throws {Error} When `scripts/block-config.ts` is missing or invalid.
|
|
748
|
-
*/
|
|
749
|
-
export async function readWorkspaceInventoryAsync(projectDir) {
|
|
750
|
-
const blockConfigPath = path.join(projectDir, "scripts", "block-config.ts");
|
|
751
|
-
let source;
|
|
752
|
-
try {
|
|
753
|
-
source = await readFile(blockConfigPath, "utf8");
|
|
754
|
-
}
|
|
755
|
-
catch (error) {
|
|
756
|
-
if (typeof error === "object" &&
|
|
757
|
-
error !== null &&
|
|
758
|
-
"code" in error &&
|
|
759
|
-
error.code === "ENOENT") {
|
|
760
|
-
throw new Error(`Workspace inventory file is missing at ${blockConfigPath}. Expected scripts/block-config.ts to exist.`);
|
|
761
|
-
}
|
|
762
|
-
throw error;
|
|
763
|
-
}
|
|
764
|
-
return {
|
|
765
|
-
blockConfigPath,
|
|
766
|
-
...parseWorkspaceInventorySource(source),
|
|
767
|
-
};
|
|
768
|
-
}
|
|
769
|
-
function toWorkspaceBlockSelectOptions(blocks) {
|
|
770
|
-
return blocks.map((block) => ({
|
|
771
|
-
description: block.typesFile,
|
|
772
|
-
name: block.slug,
|
|
773
|
-
value: block.slug,
|
|
774
|
-
}));
|
|
775
|
-
}
|
|
776
|
-
/**
|
|
777
|
-
* Synchronously return select options for the current workspace block inventory.
|
|
778
|
-
*
|
|
779
|
-
* The `description` field mirrors `block.typesFile`, while `name` and `value`
|
|
780
|
-
* both map to the block slug for use in interactive add flows.
|
|
781
|
-
*
|
|
782
|
-
* @deprecated Use `getWorkspaceBlockSelectOptionsAsync()` from async command
|
|
783
|
-
* paths. This helper intentionally remains sync-only for compatibility callers.
|
|
784
|
-
*
|
|
785
|
-
* @param projectDir Workspace root directory.
|
|
786
|
-
* @returns Block options for variation-target selection.
|
|
787
|
-
*/
|
|
788
|
-
export function getWorkspaceBlockSelectOptions(projectDir) {
|
|
789
|
-
return toWorkspaceBlockSelectOptions(readWorkspaceInventory(projectDir).blocks);
|
|
790
|
-
}
|
|
791
|
-
/**
|
|
792
|
-
* Asynchronously return select options for the current workspace block inventory.
|
|
793
|
-
*
|
|
794
|
-
* The returned option shape matches `getWorkspaceBlockSelectOptions()` while
|
|
795
|
-
* avoiding synchronous inventory reads in interactive or async command paths.
|
|
796
|
-
*
|
|
797
|
-
* @param projectDir Workspace root directory.
|
|
798
|
-
* @returns Block options for variation-target selection.
|
|
799
|
-
*/
|
|
800
|
-
export async function getWorkspaceBlockSelectOptionsAsync(projectDir) {
|
|
801
|
-
return toWorkspaceBlockSelectOptions((await readWorkspaceInventoryAsync(projectDir)).blocks);
|
|
802
|
-
}
|
|
803
|
-
function ensureWorkspaceInventorySections(source) {
|
|
804
|
-
let nextSource = source.trimEnd();
|
|
805
|
-
for (const section of INVENTORY_SECTIONS) {
|
|
806
|
-
if (section.interface &&
|
|
807
|
-
!hasExportedInterface(nextSource, section.interface.name)) {
|
|
808
|
-
nextSource += section.interface.section;
|
|
809
|
-
}
|
|
810
|
-
if (section.value && !hasExportedConst(nextSource, section.value.name)) {
|
|
811
|
-
nextSource += section.value.section;
|
|
812
|
-
}
|
|
813
|
-
}
|
|
814
|
-
return `${nextSource}\n`;
|
|
815
|
-
}
|
|
816
|
-
function hasExportedInterface(source, interfaceName) {
|
|
817
|
-
return new RegExp(`export\\s+interface\\s+${escapeRegex(interfaceName)}\\b`, "u").test(source);
|
|
818
|
-
}
|
|
819
|
-
function hasExportedConst(source, constName) {
|
|
820
|
-
return new RegExp(`export\\s+const\\s+${escapeRegex(constName)}\\b`, "u").test(source);
|
|
821
|
-
}
|
|
822
|
-
function appendEntriesAtMarker(source, marker, entries) {
|
|
823
|
-
if (entries.length === 0) {
|
|
824
|
-
return source;
|
|
825
|
-
}
|
|
826
|
-
if (!source.includes(marker)) {
|
|
827
|
-
throw new Error(`Workspace inventory marker "${marker}" is missing in scripts/block-config.ts.`);
|
|
828
|
-
}
|
|
829
|
-
return source.replace(marker, `${entries.join("\n")}\n${marker}`);
|
|
830
|
-
}
|
|
831
|
-
function appendInventorySectionEntries(source, options) {
|
|
832
|
-
let nextSource = source;
|
|
833
|
-
for (const section of [BLOCK_INVENTORY_SECTION, ...INVENTORY_SECTIONS]) {
|
|
834
|
-
if (!section.append) {
|
|
835
|
-
continue;
|
|
836
|
-
}
|
|
837
|
-
nextSource = appendEntriesAtMarker(nextSource, section.append.marker, options[section.append.optionKey] ?? []);
|
|
838
|
-
}
|
|
839
|
-
return nextSource;
|
|
840
|
-
}
|
|
841
|
-
function ensureInterfaceField(source, interfaceName, fieldName, fieldSource) {
|
|
842
|
-
const interfacePattern = new RegExp(`(export\\s+interface\\s+${escapeRegex(interfaceName)}\\s*\\{\\r?\\n)([\\s\\S]*?)(\\r?\\n\\})`, "u");
|
|
843
|
-
return source.replace(interfacePattern, (match, start, body, end) => {
|
|
844
|
-
if (new RegExp(`^[ \t]*${escapeRegex(fieldName)}\\??:`, "mu").test(body)) {
|
|
845
|
-
return match;
|
|
846
|
-
}
|
|
847
|
-
const lineEnding = start.endsWith("\r\n") ? "\r\n" : "\n";
|
|
848
|
-
const formattedFieldSource = `${fieldSource
|
|
849
|
-
.replace(/\r?\n$/u, "")
|
|
850
|
-
.split("\n")
|
|
851
|
-
.join(lineEnding)}${lineEnding}`;
|
|
852
|
-
const memberPattern = /^[ \t]*([A-Za-z_$][\w$]*)\??:/gmu;
|
|
853
|
-
for (const member of body.matchAll(memberPattern)) {
|
|
854
|
-
const memberIndex = member.index;
|
|
855
|
-
const memberName = member[1];
|
|
856
|
-
if (memberIndex === undefined || !memberName) {
|
|
857
|
-
continue;
|
|
858
|
-
}
|
|
859
|
-
if (memberName.localeCompare(fieldName) > 0) {
|
|
860
|
-
return `${start}${body.slice(0, memberIndex)}${formattedFieldSource}${body.slice(memberIndex)}${end}`;
|
|
861
|
-
}
|
|
862
|
-
}
|
|
863
|
-
return `${start}${body}${body.length > 0 && !body.endsWith(lineEnding) ? lineEnding : ""}${formattedFieldSource}${end}`;
|
|
864
|
-
});
|
|
865
|
-
}
|
|
866
|
-
function normalizeInterfaceFieldBlock(source, interfaceName, fieldName, fieldSource, requiredFragments) {
|
|
867
|
-
const interfacePattern = new RegExp(`(export\\s+interface\\s+${escapeRegex(interfaceName)}\\s*\\{\\r?\\n)([\\s\\S]*?)(\\r?\\n\\})`, "u");
|
|
868
|
-
return source.replace(interfacePattern, (match, start, body, end) => {
|
|
869
|
-
const fieldPattern = new RegExp(`(^([ \\t]*)${escapeRegex(fieldName)}\\??:\\s*\\{[ \\t]*\\r?\\n)([\\s\\S]*?)(^\\2\\};\\r?\\n?)`, "mu");
|
|
870
|
-
const fieldMatch = fieldPattern.exec(body);
|
|
871
|
-
if (!fieldMatch) {
|
|
872
|
-
return match;
|
|
873
|
-
}
|
|
874
|
-
const existingFieldSource = fieldMatch[0];
|
|
875
|
-
if (requiredFragments.every((fragment) => existingFieldSource.includes(fragment))) {
|
|
876
|
-
return match;
|
|
877
|
-
}
|
|
878
|
-
const lineEnding = start.endsWith("\r\n") ? "\r\n" : "\n";
|
|
879
|
-
const formattedFieldSource = `${fieldSource
|
|
880
|
-
.replace(/\r?\n$/u, "")
|
|
881
|
-
.split("\n")
|
|
882
|
-
.join(lineEnding)}${lineEnding}`;
|
|
883
|
-
return `${start}${body.slice(0, fieldMatch.index)}${formattedFieldSource}${body.slice(fieldMatch.index + existingFieldSource.length)}${end}`;
|
|
884
|
-
});
|
|
885
|
-
}
|
|
886
|
-
/**
|
|
887
|
-
* Update `scripts/block-config.ts` source text with additional inventory entries.
|
|
888
|
-
*
|
|
889
|
-
* Missing inventory sections for variations, patterns, binding sources, REST
|
|
890
|
-
* resources, workflow abilities, AI features, editor plugins, block styles, and
|
|
891
|
-
* block transforms are created
|
|
892
|
-
* automatically before new entries are appended at their marker comments.
|
|
893
|
-
* When provided, `transformSource` runs before any entries are inserted.
|
|
894
|
-
*
|
|
895
|
-
* @param source Existing `scripts/block-config.ts` source.
|
|
896
|
-
* @param options Entry lists plus an optional source transformer.
|
|
897
|
-
* @returns Updated source text with all requested inventory entries appended.
|
|
898
|
-
*/
|
|
899
|
-
export function updateWorkspaceInventorySource(source, options = {}) {
|
|
900
|
-
let nextSource = ensureWorkspaceInventorySections(source);
|
|
901
|
-
if (options.transformSource) {
|
|
902
|
-
nextSource = options.transformSource(nextSource);
|
|
903
|
-
}
|
|
904
|
-
nextSource = appendInventorySectionEntries(nextSource, options);
|
|
905
|
-
nextSource = ensureInterfaceField(nextSource, "WorkspaceBindingSourceConfig", "attribute", "\tattribute?: string;");
|
|
906
|
-
nextSource = ensureInterfaceField(nextSource, "WorkspaceBindingSourceConfig", "block", "\tblock?: string;");
|
|
907
|
-
nextSource = ensureInterfaceField(nextSource, "WorkspaceAbilityConfig", "compatibility", WORKSPACE_COMPATIBILITY_CONFIG_FIELD);
|
|
908
|
-
nextSource = normalizeInterfaceFieldBlock(nextSource, "WorkspaceAbilityConfig", "compatibility", WORKSPACE_COMPATIBILITY_CONFIG_FIELD, ["optionalFeatureIds: string[];", "requiredFeatureIds: string[];"]);
|
|
909
|
-
nextSource = ensureInterfaceField(nextSource, "WorkspaceAiFeatureConfig", "compatibility", WORKSPACE_COMPATIBILITY_CONFIG_FIELD);
|
|
910
|
-
nextSource = normalizeInterfaceFieldBlock(nextSource, "WorkspaceAiFeatureConfig", "compatibility", WORKSPACE_COMPATIBILITY_CONFIG_FIELD, ["optionalFeatureIds: string[];", "requiredFeatureIds: string[];"]);
|
|
911
|
-
return nextSource;
|
|
912
|
-
}
|
|
913
|
-
/**
|
|
914
|
-
* Append new entries to the canonical workspace inventory file on disk.
|
|
915
|
-
*
|
|
916
|
-
* @param projectDir Workspace root directory.
|
|
917
|
-
* @param options Entry lists and optional source transform passed through to
|
|
918
|
-
* `updateWorkspaceInventorySource`.
|
|
919
|
-
* @returns Resolves once `scripts/block-config.ts` has been updated if needed.
|
|
920
|
-
*/
|
|
921
|
-
export async function appendWorkspaceInventoryEntries(projectDir, options) {
|
|
922
|
-
const blockConfigPath = path.join(projectDir, "scripts", "block-config.ts");
|
|
923
|
-
const source = await readFile(blockConfigPath, "utf8");
|
|
924
|
-
const nextSource = updateWorkspaceInventorySource(source, options);
|
|
925
|
-
if (nextSource !== source) {
|
|
926
|
-
await writeFile(blockConfigPath, nextSource, "utf8");
|
|
927
|
-
}
|
|
928
|
-
}
|
|
1
|
+
export { ABILITY_CONFIG_ENTRY_MARKER, ADMIN_VIEW_CONFIG_ENTRY_MARKER, AI_FEATURE_CONFIG_ENTRY_MARKER, BINDING_SOURCE_CONFIG_ENTRY_MARKER, BLOCK_CONFIG_ENTRY_MARKER, BLOCK_STYLE_CONFIG_ENTRY_MARKER, BLOCK_TRANSFORM_CONFIG_ENTRY_MARKER, CONTRACT_CONFIG_ENTRY_MARKER, EDITOR_PLUGIN_CONFIG_ENTRY_MARKER, PATTERN_CONFIG_ENTRY_MARKER, POST_META_CONFIG_ENTRY_MARKER, REST_RESOURCE_CONFIG_ENTRY_MARKER, VARIATION_CONFIG_ENTRY_MARKER, } from "./workspace-inventory-templates.js";
|
|
2
|
+
export { parseWorkspaceInventorySource } from "./workspace-inventory-parser.js";
|
|
3
|
+
export { getWorkspaceBlockSelectOptions, getWorkspaceBlockSelectOptionsAsync, readWorkspaceInventory, readWorkspaceInventoryAsync, } from "./workspace-inventory-read.js";
|
|
4
|
+
export { appendWorkspaceInventoryEntries, updateWorkspaceInventorySource, } from "./workspace-inventory-mutations.js";
|