@wp-typia/project-tools 0.23.0 → 0.23.1

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.
Files changed (109) hide show
  1. package/dist/runtime/ai-feature-artifacts.js +4 -1
  2. package/dist/runtime/block-generator-service-spec.js +2 -1
  3. package/dist/runtime/cli-add-block-json.js +5 -1
  4. package/dist/runtime/cli-add-help.js +4 -3
  5. package/dist/runtime/cli-add-types.d.ts +18 -6
  6. package/dist/runtime/cli-add-validation.d.ts +7 -0
  7. package/dist/runtime/cli-add-validation.js +9 -0
  8. package/dist/runtime/cli-add-workspace-ability-scaffold.js +4 -1
  9. package/dist/runtime/cli-add-workspace-admin-view-scaffold.js +5 -1
  10. package/dist/runtime/cli-add-workspace-admin-view-templates-core-data.d.ts +34 -0
  11. package/dist/runtime/cli-add-workspace-admin-view-templates-core-data.js +483 -0
  12. package/dist/runtime/cli-add-workspace-admin-view-templates-default.d.ts +30 -0
  13. package/dist/runtime/cli-add-workspace-admin-view-templates-default.js +310 -0
  14. package/dist/runtime/cli-add-workspace-admin-view-templates-rest.d.ts +25 -0
  15. package/dist/runtime/cli-add-workspace-admin-view-templates-rest.js +124 -0
  16. package/dist/runtime/cli-add-workspace-admin-view-templates-settings.d.ts +34 -0
  17. package/dist/runtime/cli-add-workspace-admin-view-templates-settings.js +370 -0
  18. package/dist/runtime/cli-add-workspace-admin-view-templates-shared.d.ts +49 -0
  19. package/dist/runtime/cli-add-workspace-admin-view-templates-shared.js +259 -0
  20. package/dist/runtime/cli-add-workspace-admin-view-templates.d.ts +18 -27
  21. package/dist/runtime/cli-add-workspace-admin-view-templates.js +30 -1326
  22. package/dist/runtime/cli-add-workspace-ai-anchors.js +4 -1
  23. package/dist/runtime/cli-add-workspace-ai-source-emitters.js +17 -1
  24. package/dist/runtime/cli-add-workspace-integration-env.d.ts +3 -1
  25. package/dist/runtime/cli-add-workspace-integration-env.js +42 -5
  26. package/dist/runtime/cli-add-workspace-rest-anchors.d.ts +8 -0
  27. package/dist/runtime/cli-add-workspace-rest-anchors.js +41 -0
  28. package/dist/runtime/cli-add-workspace-rest-generated.d.ts +9 -0
  29. package/dist/runtime/cli-add-workspace-rest-generated.js +158 -0
  30. package/dist/runtime/cli-add-workspace-rest-manual.d.ts +8 -0
  31. package/dist/runtime/cli-add-workspace-rest-manual.js +279 -0
  32. package/dist/runtime/cli-add-workspace-rest-php-templates.d.ts +24 -0
  33. package/dist/runtime/cli-add-workspace-rest-php-templates.js +678 -0
  34. package/dist/runtime/cli-add-workspace-rest-source-emitters.d.ts +8 -0
  35. package/dist/runtime/cli-add-workspace-rest-source-emitters.js +25 -4
  36. package/dist/runtime/cli-add-workspace-rest-types.d.ts +108 -0
  37. package/dist/runtime/cli-add-workspace-rest-types.js +1 -0
  38. package/dist/runtime/cli-add-workspace-rest.d.ts +3 -20
  39. package/dist/runtime/cli-add-workspace-rest.js +33 -788
  40. package/dist/runtime/cli-core.d.ts +1 -1
  41. package/dist/runtime/cli-core.js +1 -1
  42. package/dist/runtime/cli-diagnostics.d.ts +3 -1
  43. package/dist/runtime/cli-diagnostics.js +17 -5
  44. package/dist/runtime/cli-doctor-workspace-bindings.js +4 -1
  45. package/dist/runtime/cli-doctor-workspace-block-addons.d.ts +12 -0
  46. package/dist/runtime/cli-doctor-workspace-block-addons.js +134 -0
  47. package/dist/runtime/cli-doctor-workspace-block-iframe.d.ts +9 -0
  48. package/dist/runtime/cli-doctor-workspace-block-iframe.js +228 -0
  49. package/dist/runtime/cli-doctor-workspace-block-metadata.d.ts +11 -0
  50. package/dist/runtime/cli-doctor-workspace-block-metadata.js +111 -0
  51. package/dist/runtime/cli-doctor-workspace-blocks.js +6 -424
  52. package/dist/runtime/cli-doctor-workspace-features-abilities.d.ts +11 -0
  53. package/dist/runtime/cli-doctor-workspace-features-abilities.js +112 -0
  54. package/dist/runtime/cli-doctor-workspace-features-admin-views.d.ts +11 -0
  55. package/dist/runtime/cli-doctor-workspace-features-admin-views.js +128 -0
  56. package/dist/runtime/cli-doctor-workspace-features-ai.d.ts +11 -0
  57. package/dist/runtime/cli-doctor-workspace-features-ai.js +57 -0
  58. package/dist/runtime/cli-doctor-workspace-features-editor-plugins.d.ts +11 -0
  59. package/dist/runtime/cli-doctor-workspace-features-editor-plugins.js +80 -0
  60. package/dist/runtime/cli-doctor-workspace-features-post-meta.d.ts +11 -0
  61. package/dist/runtime/cli-doctor-workspace-features-post-meta.js +77 -0
  62. package/dist/runtime/cli-doctor-workspace-features-rest.d.ts +11 -0
  63. package/dist/runtime/cli-doctor-workspace-features-rest.js +120 -0
  64. package/dist/runtime/cli-doctor-workspace-features.js +14 -487
  65. package/dist/runtime/cli-doctor.d.ts +52 -3
  66. package/dist/runtime/cli-doctor.js +79 -8
  67. package/dist/runtime/cli-help.js +6 -3
  68. package/dist/runtime/cli-init-package-json.js +4 -2
  69. package/dist/runtime/cli-prompt.d.ts +16 -2
  70. package/dist/runtime/cli-prompt.js +29 -12
  71. package/dist/runtime/cli-scaffold.d.ts +2 -1
  72. package/dist/runtime/cli-scaffold.js +19 -10
  73. package/dist/runtime/external-template-guards.js +4 -6
  74. package/dist/runtime/index.d.ts +2 -2
  75. package/dist/runtime/index.js +1 -1
  76. package/dist/runtime/json-utils.d.ts +62 -4
  77. package/dist/runtime/json-utils.js +78 -4
  78. package/dist/runtime/local-dev-presets.js +4 -1
  79. package/dist/runtime/migration-ui-capability.js +4 -1
  80. package/dist/runtime/migration-utils.js +4 -1
  81. package/dist/runtime/package-managers.js +6 -1
  82. package/dist/runtime/package-versions.js +6 -1
  83. package/dist/runtime/scaffold-bootstrap.js +7 -2
  84. package/dist/runtime/scaffold-package-manager-files.js +5 -1
  85. package/dist/runtime/scaffold-repository-reference.js +4 -2
  86. package/dist/runtime/scaffold-template-variables.js +2 -1
  87. package/dist/runtime/scaffold.d.ts +18 -1
  88. package/dist/runtime/scaffold.js +55 -2
  89. package/dist/runtime/temp-roots.js +4 -1
  90. package/dist/runtime/template-layers.js +4 -1
  91. package/dist/runtime/template-registry.js +9 -3
  92. package/dist/runtime/template-source-contracts.d.ts +2 -0
  93. package/dist/runtime/template-source-normalization.js +2 -1
  94. package/dist/runtime/template-source-remote.js +18 -5
  95. package/dist/runtime/template-source-seeds.js +10 -3
  96. package/dist/runtime/workspace-inventory-mutations.js +2 -1
  97. package/dist/runtime/workspace-inventory-parser-entries.d.ts +17 -0
  98. package/dist/runtime/workspace-inventory-parser-entries.js +157 -0
  99. package/dist/runtime/workspace-inventory-parser-validation.d.ts +104 -0
  100. package/dist/runtime/workspace-inventory-parser-validation.js +34 -0
  101. package/dist/runtime/workspace-inventory-parser.d.ts +3 -45
  102. package/dist/runtime/workspace-inventory-parser.js +3 -581
  103. package/dist/runtime/workspace-inventory-section-descriptors.d.ts +19 -0
  104. package/dist/runtime/workspace-inventory-section-descriptors.js +435 -0
  105. package/dist/runtime/workspace-inventory-templates.d.ts +1 -1
  106. package/dist/runtime/workspace-inventory-templates.js +1 -0
  107. package/dist/runtime/workspace-inventory-types.d.ts +1 -0
  108. package/dist/runtime/workspace-project.js +4 -6
  109. package/package.json +2 -2
@@ -0,0 +1,279 @@
1
+ import { promises as fsp } from "node:fs";
2
+ import path from "node:path";
3
+ import { ensureBlockConfigCanAddRestManifests } from "./cli-add-block-legacy-validator.js";
4
+ import { assertValidManualRestContractAuth, assertValidManualRestContractHttpMethod, assertValidTypeScriptIdentifier, collectRestRouteNamedCaptureNames, resolveOptionalPhpCallbackReference, resolveOptionalPhpClassReference, resolveManualRestContractPathPattern, rollbackWorkspaceMutation, snapshotWorkspaceFiles, } from "./cli-add-shared.js";
5
+ import { ensureRestResourceSyncScriptAnchors } from "./cli-add-workspace-rest-anchors.js";
6
+ import { buildManualRestContractApiSource, buildManualRestContractConfigEntry, buildManualRestContractTypesSource, buildManualRestContractValidatorsSource, } from "./cli-add-workspace-rest-source-emitters.js";
7
+ import { syncManualRestContractArtifacts } from "./rest-resource-artifacts.js";
8
+ import { toPascalCase, toTitleCase } from "./string-case.js";
9
+ import { appendWorkspaceInventoryEntries } from "./workspace-inventory.js";
10
+ const MANUAL_REST_REQUEST_BODY_FIELD_NAMES = new Set(["payload", "comment"]);
11
+ const MANUAL_REST_RESPONSE_FIELD_NAMES = new Set([
12
+ "id",
13
+ "status",
14
+ "message",
15
+ "updatedAt",
16
+ ]);
17
+ function resolveManualRestSecretPreserveOnEmpty(value) {
18
+ if (value === undefined) {
19
+ return true;
20
+ }
21
+ if (typeof value === "boolean") {
22
+ return value;
23
+ }
24
+ const normalized = value.trim().toLowerCase();
25
+ if (["1", "true", "yes"].includes(normalized)) {
26
+ return true;
27
+ }
28
+ if (["0", "false", "no"].includes(normalized)) {
29
+ return false;
30
+ }
31
+ throw new Error("Manual REST contract --secret-preserve-on-empty must be true or false.");
32
+ }
33
+ function resolveManualRestSecretStateFieldCandidate(options) {
34
+ const candidates = [
35
+ options.secretStateFieldName,
36
+ options.secretHasValueFieldName,
37
+ options.secretMaskedResponseFieldName,
38
+ ].filter((value) => typeof value === "string");
39
+ const distinct = Array.from(new Set(candidates));
40
+ if (distinct.length > 1) {
41
+ throw new Error("Manual REST contract secret state, has-value, and masked response field flags must match when combined.");
42
+ }
43
+ return distinct[0];
44
+ }
45
+ function resolveManualRestRoutePathPattern(options) {
46
+ const trimmedPathPattern = typeof options.pathPattern === "string"
47
+ ? options.pathPattern.trim()
48
+ : undefined;
49
+ const trimmedRoutePattern = typeof options.routePattern === "string"
50
+ ? options.routePattern.trim()
51
+ : undefined;
52
+ if (trimmedPathPattern &&
53
+ trimmedRoutePattern &&
54
+ trimmedPathPattern !== trimmedRoutePattern) {
55
+ throw new Error("Manual REST contract --path and --route-pattern must match when both are provided. Use one route pattern flag for provider routes.");
56
+ }
57
+ return resolveManualRestContractPathPattern(options.restResourceSlug, options.pathPattern ?? options.routePattern);
58
+ }
59
+ /**
60
+ * Scaffold a type-only external REST contract for workspace consumers.
61
+ *
62
+ * @param options Resolved workspace and raw manual-mode command options.
63
+ * @returns Resolved scaffold metadata for the manual REST contract.
64
+ */
65
+ export async function scaffoldManualRestContract({ auth, bodyTypeName, controllerClass, controllerExtends, method, namespace, pathPattern, permissionCallback, queryTypeName, responseTypeName, restResourceSlug, routePattern, secretFieldName, secretHasValueFieldName, secretMaskedResponseFieldName, secretPreserveOnEmpty, secretStateFieldName, workspace, }) {
66
+ const blockConfigPath = path.join(workspace.projectDir, "scripts", "block-config.ts");
67
+ const syncRestScriptPath = path.join(workspace.projectDir, "scripts", "sync-rest-contracts.ts");
68
+ const restResourceDir = path.join(workspace.projectDir, "src", "rest", restResourceSlug);
69
+ const typesFilePath = path.join(restResourceDir, "api-types.ts");
70
+ const validatorsFilePath = path.join(restResourceDir, "api-validators.ts");
71
+ const apiFilePath = path.join(restResourceDir, "api.ts");
72
+ const pascalCase = toPascalCase(restResourceSlug);
73
+ const resolvedAuth = assertValidManualRestContractAuth(auth);
74
+ const resolvedMethod = assertValidManualRestContractHttpMethod(method);
75
+ const resolvedPathPattern = resolveManualRestRoutePathPattern({
76
+ pathPattern,
77
+ restResourceSlug,
78
+ routePattern,
79
+ });
80
+ const pathParameterNames = collectRestRouteNamedCaptureNames(resolvedPathPattern);
81
+ const resolvedPermissionCallback = resolveOptionalPhpCallbackReference("Manual REST contract permission callback", permissionCallback);
82
+ const resolvedControllerClass = resolveOptionalPhpClassReference("Manual REST contract controller class", controllerClass);
83
+ const resolvedControllerExtends = resolveOptionalPhpClassReference("Manual REST contract controller base class", controllerExtends);
84
+ if (resolvedControllerExtends && !resolvedControllerClass) {
85
+ throw new Error("Manual REST contract controller base class requires --controller-class.");
86
+ }
87
+ const resolvedQueryTypeName = assertValidTypeScriptIdentifier("Manual REST contract query type", queryTypeName ?? `${pascalCase}Query`, "wp-typia add rest-resource <name> --manual [--query-type <ExportedQueryType>]");
88
+ const resolvedResponseTypeName = assertValidTypeScriptIdentifier("Manual REST contract response type", responseTypeName ?? `${pascalCase}Response`, "wp-typia add rest-resource <name> --manual [--response-type <ExportedResponseType>]");
89
+ const defaultsToBody = bodyTypeName == null && ["PATCH", "POST", "PUT"].includes(resolvedMethod);
90
+ const resolvedBodyTypeName = bodyTypeName != null || defaultsToBody
91
+ ? assertValidTypeScriptIdentifier("Manual REST contract body type", bodyTypeName ?? `${pascalCase}Request`, "wp-typia add rest-resource <name> --manual [--body-type <ExportedBodyType>]")
92
+ : undefined;
93
+ if (resolvedMethod === "GET" && resolvedBodyTypeName) {
94
+ throw new Error("Manual REST contract GET routes cannot define a body type. Remove --body-type or use POST, PUT, or PATCH.");
95
+ }
96
+ const secretStateFieldCandidate = resolveManualRestSecretStateFieldCandidate({
97
+ secretHasValueFieldName,
98
+ secretMaskedResponseFieldName,
99
+ secretStateFieldName,
100
+ });
101
+ if (secretPreserveOnEmpty !== undefined && !secretFieldName) {
102
+ throw new Error("Manual REST contract --secret-preserve-on-empty requires --secret-field.");
103
+ }
104
+ if (secretStateFieldCandidate !== undefined && !secretFieldName) {
105
+ throw new Error("Manual REST contract secret state, has-value, and masked response field flags require --secret-field.");
106
+ }
107
+ if (secretFieldName && !resolvedBodyTypeName) {
108
+ throw new Error("Manual REST contract secret fields require a request body. Use POST, PUT, or PATCH so a request body is generated.");
109
+ }
110
+ const resolvedSecretFieldName = secretFieldName
111
+ ? assertValidTypeScriptIdentifier("Manual REST contract secret field", secretFieldName, "wp-typia add rest-resource <name> --manual --method POST --secret-field <field>")
112
+ : undefined;
113
+ const resolvedSecretPreserveOnEmpty = resolvedSecretFieldName
114
+ ? resolveManualRestSecretPreserveOnEmpty(secretPreserveOnEmpty)
115
+ : undefined;
116
+ const resolvedSecretStateFieldName = resolvedSecretFieldName
117
+ ? assertValidTypeScriptIdentifier("Manual REST contract secret state field", secretStateFieldCandidate ??
118
+ `has${toPascalCase(resolvedSecretFieldName)}`, "wp-typia add rest-resource <name> --manual --method POST --secret-state-field <field>")
119
+ : undefined;
120
+ if (resolvedSecretFieldName &&
121
+ MANUAL_REST_REQUEST_BODY_FIELD_NAMES.has(resolvedSecretFieldName)) {
122
+ throw new Error(`Manual REST contract secret field must not reuse scaffolded request body fields: ${Array.from(MANUAL_REST_REQUEST_BODY_FIELD_NAMES).join(", ")}.`);
123
+ }
124
+ if (resolvedSecretStateFieldName &&
125
+ MANUAL_REST_RESPONSE_FIELD_NAMES.has(resolvedSecretStateFieldName)) {
126
+ throw new Error(`Manual REST contract secret state field must not reuse scaffolded response fields: ${Array.from(MANUAL_REST_RESPONSE_FIELD_NAMES).join(", ")}.`);
127
+ }
128
+ if (resolvedSecretFieldName &&
129
+ resolvedSecretStateFieldName &&
130
+ resolvedSecretFieldName === resolvedSecretStateFieldName) {
131
+ throw new Error("Manual REST contract secret state field must be different from the raw secret field.");
132
+ }
133
+ const manualTypeNames = [
134
+ resolvedQueryTypeName,
135
+ resolvedResponseTypeName,
136
+ resolvedBodyTypeName,
137
+ ].filter((value) => value != null);
138
+ const duplicateManualTypeNames = manualTypeNames.filter((name, index) => manualTypeNames.indexOf(name) !== index);
139
+ if (duplicateManualTypeNames.length > 0) {
140
+ throw new Error(`Manual REST contract type names must be unique: ${Array.from(new Set(duplicateManualTypeNames)).join(", ")}. Use distinct --query-type, --body-type, and --response-type values.`);
141
+ }
142
+ const mutationSnapshot = {
143
+ fileSources: await snapshotWorkspaceFiles([
144
+ blockConfigPath,
145
+ syncRestScriptPath,
146
+ ]),
147
+ snapshotDirs: [],
148
+ targetPaths: [restResourceDir],
149
+ };
150
+ try {
151
+ await fsp.mkdir(restResourceDir, { recursive: true });
152
+ await ensureRestResourceSyncScriptAnchors(workspace);
153
+ await fsp.writeFile(typesFilePath, buildManualRestContractTypesSource({
154
+ ...(resolvedBodyTypeName
155
+ ? { bodyTypeName: resolvedBodyTypeName }
156
+ : {}),
157
+ pathParameterNames,
158
+ queryTypeName: resolvedQueryTypeName,
159
+ responseTypeName: resolvedResponseTypeName,
160
+ restResourceSlug,
161
+ ...(resolvedSecretFieldName
162
+ ? { secretFieldName: resolvedSecretFieldName }
163
+ : {}),
164
+ ...(resolvedSecretPreserveOnEmpty !== undefined
165
+ ? { secretPreserveOnEmpty: resolvedSecretPreserveOnEmpty }
166
+ : {}),
167
+ ...(resolvedSecretStateFieldName
168
+ ? { secretStateFieldName: resolvedSecretStateFieldName }
169
+ : {}),
170
+ }), "utf8");
171
+ await fsp.writeFile(validatorsFilePath, buildManualRestContractValidatorsSource({
172
+ ...(resolvedBodyTypeName
173
+ ? { bodyTypeName: resolvedBodyTypeName }
174
+ : {}),
175
+ queryTypeName: resolvedQueryTypeName,
176
+ responseTypeName: resolvedResponseTypeName,
177
+ }), "utf8");
178
+ await fsp.writeFile(apiFilePath, buildManualRestContractApiSource({
179
+ ...(resolvedBodyTypeName
180
+ ? { bodyTypeName: resolvedBodyTypeName }
181
+ : {}),
182
+ queryTypeName: resolvedQueryTypeName,
183
+ restResourceSlug,
184
+ }), "utf8");
185
+ await syncManualRestContractArtifacts({
186
+ clientFile: `src/rest/${restResourceSlug}/api-client.ts`,
187
+ outputDir: restResourceDir,
188
+ projectDir: workspace.projectDir,
189
+ typesFile: `src/rest/${restResourceSlug}/api-types.ts`,
190
+ validatorsFile: `src/rest/${restResourceSlug}/api-validators.ts`,
191
+ variables: {
192
+ auth: resolvedAuth,
193
+ ...(resolvedBodyTypeName
194
+ ? { bodyTypeName: resolvedBodyTypeName }
195
+ : {}),
196
+ method: resolvedMethod,
197
+ namespace,
198
+ pascalCase,
199
+ pathPattern: resolvedPathPattern,
200
+ queryTypeName: resolvedQueryTypeName,
201
+ responseTypeName: resolvedResponseTypeName,
202
+ slugKebabCase: restResourceSlug,
203
+ title: toTitleCase(restResourceSlug),
204
+ },
205
+ });
206
+ await appendWorkspaceInventoryEntries(workspace.projectDir, {
207
+ restResourceEntries: [
208
+ buildManualRestContractConfigEntry({
209
+ auth: resolvedAuth,
210
+ ...(resolvedBodyTypeName
211
+ ? { bodyTypeName: resolvedBodyTypeName }
212
+ : {}),
213
+ ...(resolvedControllerClass
214
+ ? { controllerClass: resolvedControllerClass }
215
+ : {}),
216
+ ...(resolvedControllerExtends
217
+ ? { controllerExtends: resolvedControllerExtends }
218
+ : {}),
219
+ method: resolvedMethod,
220
+ namespace,
221
+ pathPattern: resolvedPathPattern,
222
+ ...(resolvedPermissionCallback
223
+ ? { permissionCallback: resolvedPermissionCallback }
224
+ : {}),
225
+ queryTypeName: resolvedQueryTypeName,
226
+ responseTypeName: resolvedResponseTypeName,
227
+ restResourceSlug,
228
+ ...(resolvedSecretFieldName
229
+ ? { secretFieldName: resolvedSecretFieldName }
230
+ : {}),
231
+ ...(resolvedSecretPreserveOnEmpty !== undefined
232
+ ? { secretPreserveOnEmpty: resolvedSecretPreserveOnEmpty }
233
+ : {}),
234
+ ...(resolvedSecretStateFieldName
235
+ ? { secretStateFieldName: resolvedSecretStateFieldName }
236
+ : {}),
237
+ }),
238
+ ],
239
+ transformSource: ensureBlockConfigCanAddRestManifests,
240
+ });
241
+ return {
242
+ auth: resolvedAuth,
243
+ ...(resolvedBodyTypeName
244
+ ? { bodyTypeName: resolvedBodyTypeName }
245
+ : {}),
246
+ ...(resolvedControllerClass
247
+ ? { controllerClass: resolvedControllerClass }
248
+ : {}),
249
+ ...(resolvedControllerExtends
250
+ ? { controllerExtends: resolvedControllerExtends }
251
+ : {}),
252
+ method: resolvedMethod,
253
+ methods: [],
254
+ mode: "manual",
255
+ namespace,
256
+ pathPattern: resolvedPathPattern,
257
+ ...(resolvedPermissionCallback
258
+ ? { permissionCallback: resolvedPermissionCallback }
259
+ : {}),
260
+ projectDir: workspace.projectDir,
261
+ queryTypeName: resolvedQueryTypeName,
262
+ restResourceSlug,
263
+ responseTypeName: resolvedResponseTypeName,
264
+ ...(resolvedSecretFieldName
265
+ ? { secretFieldName: resolvedSecretFieldName }
266
+ : {}),
267
+ ...(resolvedSecretPreserveOnEmpty !== undefined
268
+ ? { secretPreserveOnEmpty: resolvedSecretPreserveOnEmpty }
269
+ : {}),
270
+ ...(resolvedSecretStateFieldName
271
+ ? { secretStateFieldName: resolvedSecretStateFieldName }
272
+ : {}),
273
+ };
274
+ }
275
+ catch (error) {
276
+ await rollbackWorkspaceMutation(mutationSnapshot);
277
+ throw error;
278
+ }
279
+ }
@@ -0,0 +1,24 @@
1
+ import { type RestResourceMethodId } from "./cli-add-shared.js";
2
+ /**
3
+ * Build the PHP route/controller glue for generated workspace REST resources.
4
+ *
5
+ * @param restResourceSlug Normalized REST resource slug.
6
+ * @param namespace WordPress REST namespace, such as `vendor/v1`.
7
+ * @param phpPrefix Plugin PHP function prefix.
8
+ * @param methods REST operations to expose.
9
+ * @param options Optional generated route and controller customizations.
10
+ * @returns A complete PHP source file for the generated REST resource.
11
+ */
12
+ export declare function buildRestResourcePhpSource(restResourceSlug: string, namespace: string, phpPrefix: string, methods: RestResourceMethodId[], options: {
13
+ controllerClass?: string;
14
+ controllerExtends?: string;
15
+ permissionCallback?: string;
16
+ routePattern: string;
17
+ }): string;
18
+ /**
19
+ * Build the shared PHP helper loaded by workspace bootstraps for generated REST schemas.
20
+ *
21
+ * @param phpPrefix Plugin-scoped PHP function prefix.
22
+ * @returns PHP source for `inc/rest-schema.php`.
23
+ */
24
+ export declare function buildWorkspaceRestSchemaHelperPhpSource(phpPrefix: string): string;