@wp-typia/project-tools 0.22.10 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/runtime/cli-add-collision.d.ts +25 -0
- package/dist/runtime/cli-add-collision.js +76 -0
- 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 +26 -0
- 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 +2 -0
- package/dist/runtime/cli-doctor-workspace.js +8 -3
- 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/index.d.ts +1 -1
- package/dist/runtime/index.js +1 -1
- package/dist/runtime/rest-resource-artifacts.d.ts +57 -1
- package/dist/runtime/rest-resource-artifacts.js +97 -1
- 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/workspace-inventory-mutations.js +52 -3
- package/dist/runtime/workspace-inventory-parser.d.ts +3 -2
- package/dist/runtime/workspace-inventory-parser.js +126 -5
- package/dist/runtime/workspace-inventory-read.d.ts +9 -2
- package/dist/runtime/workspace-inventory-read.js +9 -2
- package/dist/runtime/workspace-inventory-templates.d.ts +16 -1
- package/dist/runtime/workspace-inventory-templates.js +74 -4
- package/dist/runtime/workspace-inventory-types.d.ts +51 -2
- package/dist/runtime/workspace-inventory.d.ts +2 -2
- package/dist/runtime/workspace-inventory.js +1 -1
- package/package.json +2 -2
|
@@ -50,23 +50,296 @@ function replaceRequiredSyncRestSource(nextSource, target, anchor, replacement,
|
|
|
50
50
|
assertSyncRestAnchor(nextSource, target, anchorDescription, hasAnchor, syncRestScriptPath);
|
|
51
51
|
return nextSource.replace(anchor, replacement);
|
|
52
52
|
}
|
|
53
|
+
function getSyncRestPatchErrorMessage(functionName, syncRestScriptPath, anchorDescription, subject) {
|
|
54
|
+
return [
|
|
55
|
+
`${functionName} could not patch ${path.basename(syncRestScriptPath)}.`,
|
|
56
|
+
`Missing expected ${anchorDescription} anchor in scripts/sync-rest-contracts.ts.`,
|
|
57
|
+
`Restore the generated template or add the ${subject} wiring manually before retrying.`,
|
|
58
|
+
].join(" ");
|
|
59
|
+
}
|
|
60
|
+
function replaceBlockConfigImportForContracts(nextSource, syncRestScriptPath) {
|
|
61
|
+
const importPatterns = [
|
|
62
|
+
/^import\s*\{\n(?:\t[^\n]*\n)+\} from ["']\.\/block-config["'];?$/mu,
|
|
63
|
+
/^import\s*\{[^\n]*\}\s*from\s*["']\.\/block-config["'];?$/mu,
|
|
64
|
+
];
|
|
65
|
+
const importMatch = importPatterns.map((pattern) => pattern.exec(nextSource)).find(Boolean) ??
|
|
66
|
+
null;
|
|
67
|
+
if (!importMatch) {
|
|
68
|
+
throw new Error(getSyncRestPatchErrorMessage("ensureContractSyncScriptAnchors", syncRestScriptPath, "block-config import", "CONTRACTS"));
|
|
69
|
+
}
|
|
70
|
+
const importSource = importMatch[0];
|
|
71
|
+
if (importSource.includes("CONTRACTS") &&
|
|
72
|
+
importSource.includes("WorkspaceContractConfig")) {
|
|
73
|
+
return nextSource;
|
|
74
|
+
}
|
|
75
|
+
if (!importSource.includes("BLOCKS") ||
|
|
76
|
+
!importSource.includes("WorkspaceBlockConfig")) {
|
|
77
|
+
throw new Error(getSyncRestPatchErrorMessage("ensureContractSyncScriptAnchors", syncRestScriptPath, "BLOCKS import", "CONTRACTS"));
|
|
78
|
+
}
|
|
79
|
+
const hasAiFeatures = importSource.includes("AI_FEATURES");
|
|
80
|
+
const hasAiFeatureConfig = importSource.includes("WorkspaceAiFeatureConfig");
|
|
81
|
+
const hasRestResources = importSource.includes("REST_RESOURCES");
|
|
82
|
+
const hasRestResourceConfig = importSource.includes("WorkspaceRestResourceConfig");
|
|
83
|
+
const hasPostMeta = importSource.includes("POST_META");
|
|
84
|
+
const hasPostMetaConfig = importSource.includes("WorkspacePostMetaConfig");
|
|
85
|
+
const replacement = [
|
|
86
|
+
"import {",
|
|
87
|
+
...(hasAiFeatures ? ["\tAI_FEATURES,"] : []),
|
|
88
|
+
"\tBLOCKS,",
|
|
89
|
+
"\tCONTRACTS,",
|
|
90
|
+
...(hasPostMeta ? ["\tPOST_META,"] : []),
|
|
91
|
+
...(hasRestResources ? ["\tREST_RESOURCES,"] : []),
|
|
92
|
+
...(hasAiFeatureConfig ? ["\ttype WorkspaceAiFeatureConfig,"] : []),
|
|
93
|
+
"\ttype WorkspaceBlockConfig,",
|
|
94
|
+
"\ttype WorkspaceContractConfig,",
|
|
95
|
+
...(hasPostMetaConfig ? ["\ttype WorkspacePostMetaConfig,"] : []),
|
|
96
|
+
...(hasRestResourceConfig ? ["\ttype WorkspaceRestResourceConfig,"] : []),
|
|
97
|
+
"} from './block-config';",
|
|
98
|
+
].join("\n");
|
|
99
|
+
return nextSource.replace(importSource, replacement);
|
|
100
|
+
}
|
|
101
|
+
function replaceBlockConfigImportForRestResources(nextSource, syncRestScriptPath) {
|
|
102
|
+
const importPatterns = [
|
|
103
|
+
/^import\s*\{\n(?:\t[^\n]*\n)+\} from ["']\.\/block-config["'];?$/mu,
|
|
104
|
+
/^import\s*\{[^\n]*\}\s*from\s*["']\.\/block-config["'];?$/mu,
|
|
105
|
+
];
|
|
106
|
+
const importMatch = importPatterns.map((pattern) => pattern.exec(nextSource)).find(Boolean) ??
|
|
107
|
+
null;
|
|
108
|
+
if (!importMatch) {
|
|
109
|
+
throw new Error(getSyncRestPatchErrorMessage("ensureRestResourceSyncScriptAnchors", syncRestScriptPath, "block-config import", "REST_RESOURCES"));
|
|
110
|
+
}
|
|
111
|
+
const importSource = importMatch[0];
|
|
112
|
+
if (importSource.includes("REST_RESOURCES") &&
|
|
113
|
+
importSource.includes("WorkspaceRestResourceConfig")) {
|
|
114
|
+
return nextSource;
|
|
115
|
+
}
|
|
116
|
+
if (!importSource.includes("BLOCKS") ||
|
|
117
|
+
!importSource.includes("WorkspaceBlockConfig")) {
|
|
118
|
+
throw new Error(getSyncRestPatchErrorMessage("ensureRestResourceSyncScriptAnchors", syncRestScriptPath, "BLOCKS import", "REST_RESOURCES"));
|
|
119
|
+
}
|
|
120
|
+
const hasAiFeatures = importSource.includes("AI_FEATURES");
|
|
121
|
+
const hasAiFeatureConfig = importSource.includes("WorkspaceAiFeatureConfig");
|
|
122
|
+
const hasContracts = importSource.includes("CONTRACTS");
|
|
123
|
+
const hasContractConfig = importSource.includes("WorkspaceContractConfig");
|
|
124
|
+
const hasPostMeta = importSource.includes("POST_META");
|
|
125
|
+
const hasPostMetaConfig = importSource.includes("WorkspacePostMetaConfig");
|
|
126
|
+
const replacement = [
|
|
127
|
+
"import {",
|
|
128
|
+
...(hasAiFeatures ? ["\tAI_FEATURES,"] : []),
|
|
129
|
+
"\tBLOCKS,",
|
|
130
|
+
...(hasContracts ? ["\tCONTRACTS,"] : []),
|
|
131
|
+
...(hasPostMeta ? ["\tPOST_META,"] : []),
|
|
132
|
+
"\tREST_RESOURCES,",
|
|
133
|
+
...(hasAiFeatureConfig ? ["\ttype WorkspaceAiFeatureConfig,"] : []),
|
|
134
|
+
"\ttype WorkspaceBlockConfig,",
|
|
135
|
+
...(hasContractConfig ? ["\ttype WorkspaceContractConfig,"] : []),
|
|
136
|
+
...(hasPostMetaConfig ? ["\ttype WorkspacePostMetaConfig,"] : []),
|
|
137
|
+
"\ttype WorkspaceRestResourceConfig,",
|
|
138
|
+
"} from './block-config';",
|
|
139
|
+
].join("\n");
|
|
140
|
+
return nextSource.replace(importSource, replacement);
|
|
141
|
+
}
|
|
142
|
+
function replaceRequiredContractSyncRestSource(nextSource, target, anchor, replacement, anchorDescription, syncRestScriptPath) {
|
|
143
|
+
if (nextSource.includes(target)) {
|
|
144
|
+
return nextSource;
|
|
145
|
+
}
|
|
146
|
+
const hasAnchor = typeof anchor === "string" ? nextSource.includes(anchor) : anchor.test(nextSource);
|
|
147
|
+
if (!hasAnchor) {
|
|
148
|
+
throw new Error(getSyncRestPatchErrorMessage("ensureContractSyncScriptAnchors", syncRestScriptPath, anchorDescription, "CONTRACTS"));
|
|
149
|
+
}
|
|
150
|
+
return nextSource.replace(anchor, replacement);
|
|
151
|
+
}
|
|
152
|
+
function formatNoResourcesSubject(subjects) {
|
|
153
|
+
if (subjects.length <= 2) {
|
|
154
|
+
return subjects.join(" or ");
|
|
155
|
+
}
|
|
156
|
+
const lastSubject = subjects[subjects.length - 1];
|
|
157
|
+
return `${subjects.slice(0, -1).join(", ")}, or ${lastSubject}`;
|
|
158
|
+
}
|
|
159
|
+
function buildContractNoResourcesGuard({ hasAiFeatures, hasPostMeta, hasRestResources, }) {
|
|
160
|
+
const condition = ["restBlocks.length === 0 &&", "standaloneContracts.length === 0"];
|
|
161
|
+
if (hasPostMeta) {
|
|
162
|
+
condition[condition.length - 1] = `${condition[condition.length - 1]} &&`;
|
|
163
|
+
condition.push("postMetaContracts.length === 0");
|
|
164
|
+
}
|
|
165
|
+
if (hasRestResources) {
|
|
166
|
+
condition[condition.length - 1] = `${condition[condition.length - 1]} &&`;
|
|
167
|
+
condition.push("restResources.length === 0");
|
|
168
|
+
}
|
|
169
|
+
if (hasAiFeatures) {
|
|
170
|
+
condition[condition.length - 1] = `${condition[condition.length - 1]} &&`;
|
|
171
|
+
condition.push("aiFeatures.length === 0");
|
|
172
|
+
}
|
|
173
|
+
const noResourcesSubject = formatNoResourcesSubject([
|
|
174
|
+
"REST-enabled workspace blocks",
|
|
175
|
+
"standalone contracts",
|
|
176
|
+
...(hasPostMeta ? ["post meta contracts"] : []),
|
|
177
|
+
...(hasRestResources ? ["plugin-level REST resources"] : []),
|
|
178
|
+
...(hasAiFeatures ? ["AI features"] : []),
|
|
179
|
+
]);
|
|
180
|
+
return [
|
|
181
|
+
"if (",
|
|
182
|
+
...condition.map((line) => `\t\t${line}`),
|
|
183
|
+
"\t) {",
|
|
184
|
+
"\t\tconsole.log(",
|
|
185
|
+
"\t\t\toptions.check",
|
|
186
|
+
`\t\t\t\t? 'ℹ️ No ${noResourcesSubject} are registered yet. \`sync-rest --check\` is already clean.'`,
|
|
187
|
+
`\t\t\t\t: 'ℹ️ No ${noResourcesSubject} are registered yet.'`,
|
|
188
|
+
"\t\t);",
|
|
189
|
+
"\t\treturn;",
|
|
190
|
+
"\t}",
|
|
191
|
+
].join("\n");
|
|
192
|
+
}
|
|
193
|
+
const NO_RESOURCES_GUARD_PATTERN = /if \(\s*restBlocks\.length === 0(?:\s*&&\s*standaloneContracts\.length === 0)?(?:\s*&&\s*postMetaContracts\.length === 0)?(?:\s*&&\s*restResources\.length === 0)?(?:\s*&&\s*aiFeatures\.length === 0)?\s*\) \{[\s\S]*?\n\t\treturn;\n\t\}/u;
|
|
194
|
+
function replaceNoResourcesGuard(nextSource, replacement, functionName, syncRestScriptPath, subject) {
|
|
195
|
+
if (!NO_RESOURCES_GUARD_PATTERN.test(nextSource)) {
|
|
196
|
+
throw new Error(getSyncRestPatchErrorMessage(functionName, syncRestScriptPath, "no-resources guard", subject));
|
|
197
|
+
}
|
|
198
|
+
return nextSource.replace(NO_RESOURCES_GUARD_PATTERN, replacement);
|
|
199
|
+
}
|
|
200
|
+
function insertStandaloneContractFilter(nextSource, syncRestScriptPath) {
|
|
201
|
+
if (nextSource.includes("const standaloneContracts = CONTRACTS.filter")) {
|
|
202
|
+
return nextSource;
|
|
203
|
+
}
|
|
204
|
+
const restResourcesFilter = "const restResources = REST_RESOURCES.filter( isWorkspaceRestResource );";
|
|
205
|
+
if (nextSource.includes(restResourcesFilter)) {
|
|
206
|
+
return nextSource.replace(restResourcesFilter, [
|
|
207
|
+
"const standaloneContracts = CONTRACTS.filter( isWorkspaceStandaloneContract );",
|
|
208
|
+
restResourcesFilter,
|
|
209
|
+
].join("\n\t"));
|
|
210
|
+
}
|
|
211
|
+
const restBlocksFilter = "const restBlocks = BLOCKS.filter( isRestEnabledBlock );";
|
|
212
|
+
return replaceRequiredContractSyncRestSource(nextSource, "const standaloneContracts = CONTRACTS.filter", restBlocksFilter, [
|
|
213
|
+
restBlocksFilter,
|
|
214
|
+
"const standaloneContracts = CONTRACTS.filter( isWorkspaceStandaloneContract );",
|
|
215
|
+
].join("\n\t"), "restBlocks filter", syncRestScriptPath);
|
|
216
|
+
}
|
|
217
|
+
function insertStandaloneContractNoResourcesGuard(nextSource, syncRestScriptPath) {
|
|
218
|
+
const hasRestResources = nextSource.includes("const restResources = REST_RESOURCES.filter( isWorkspaceRestResource );");
|
|
219
|
+
const hasAiFeatures = nextSource.includes("const aiFeatures = AI_FEATURES.filter( isWorkspaceAiFeature );");
|
|
220
|
+
const hasPostMeta = nextSource.includes("const postMetaContracts = POST_META.filter( isWorkspacePostMetaContract );");
|
|
221
|
+
return replaceNoResourcesGuard(nextSource, buildContractNoResourcesGuard({
|
|
222
|
+
hasAiFeatures,
|
|
223
|
+
hasPostMeta,
|
|
224
|
+
hasRestResources,
|
|
225
|
+
}), "ensureContractSyncScriptAnchors", syncRestScriptPath, "CONTRACTS");
|
|
226
|
+
}
|
|
227
|
+
function buildRestResourceNoResourcesGuard({ hasAiFeatures, hasPostMeta, hasStandaloneContracts, }) {
|
|
228
|
+
const condition = ["restBlocks.length === 0"];
|
|
229
|
+
if (hasStandaloneContracts) {
|
|
230
|
+
condition[condition.length - 1] = `${condition[condition.length - 1]} &&`;
|
|
231
|
+
condition.push("standaloneContracts.length === 0");
|
|
232
|
+
}
|
|
233
|
+
if (hasPostMeta) {
|
|
234
|
+
condition[condition.length - 1] = `${condition[condition.length - 1]} &&`;
|
|
235
|
+
condition.push("postMetaContracts.length === 0");
|
|
236
|
+
}
|
|
237
|
+
condition[condition.length - 1] = `${condition[condition.length - 1]} &&`;
|
|
238
|
+
condition.push("restResources.length === 0");
|
|
239
|
+
if (hasAiFeatures) {
|
|
240
|
+
condition[condition.length - 1] = `${condition[condition.length - 1]} &&`;
|
|
241
|
+
condition.push("aiFeatures.length === 0");
|
|
242
|
+
}
|
|
243
|
+
const noResourcesSubject = formatNoResourcesSubject([
|
|
244
|
+
"REST-enabled workspace blocks",
|
|
245
|
+
...(hasStandaloneContracts ? ["standalone contracts"] : []),
|
|
246
|
+
...(hasPostMeta ? ["post meta contracts"] : []),
|
|
247
|
+
"plugin-level REST resources",
|
|
248
|
+
...(hasAiFeatures ? ["AI features"] : []),
|
|
249
|
+
]);
|
|
250
|
+
return [
|
|
251
|
+
"if (",
|
|
252
|
+
...condition.map((line) => `\t\t${line}`),
|
|
253
|
+
"\t) {",
|
|
254
|
+
"\t\tconsole.log(",
|
|
255
|
+
"\t\t\toptions.check",
|
|
256
|
+
`\t\t\t\t? 'ℹ️ No ${noResourcesSubject} are registered yet. \`sync-rest --check\` is already clean.'`,
|
|
257
|
+
`\t\t\t\t: 'ℹ️ No ${noResourcesSubject} are registered yet.'`,
|
|
258
|
+
"\t\t);",
|
|
259
|
+
"\t\treturn;",
|
|
260
|
+
"\t}",
|
|
261
|
+
].join("\n");
|
|
262
|
+
}
|
|
263
|
+
function insertRestResourceNoResourcesGuard(nextSource, syncRestScriptPath) {
|
|
264
|
+
const hasStandaloneContracts = nextSource.includes("const standaloneContracts = CONTRACTS.filter( isWorkspaceStandaloneContract );");
|
|
265
|
+
const hasAiFeatures = nextSource.includes("const aiFeatures = AI_FEATURES.filter( isWorkspaceAiFeature );");
|
|
266
|
+
const hasPostMeta = nextSource.includes("const postMetaContracts = POST_META.filter( isWorkspacePostMetaContract );");
|
|
267
|
+
return replaceNoResourcesGuard(nextSource, buildRestResourceNoResourcesGuard({
|
|
268
|
+
hasAiFeatures,
|
|
269
|
+
hasPostMeta,
|
|
270
|
+
hasStandaloneContracts,
|
|
271
|
+
}), "ensureRestResourceSyncScriptAnchors", syncRestScriptPath, "REST_RESOURCES");
|
|
272
|
+
}
|
|
273
|
+
function insertStandaloneContractSyncLoop(nextSource, syncRestScriptPath) {
|
|
274
|
+
if (nextSource.includes("for ( const contract of standaloneContracts )")) {
|
|
275
|
+
return nextSource;
|
|
276
|
+
}
|
|
277
|
+
const loopSource = [
|
|
278
|
+
"\tfor ( const contract of standaloneContracts ) {",
|
|
279
|
+
"\t\tawait syncTypeSchemas(",
|
|
280
|
+
"\t\t\t{",
|
|
281
|
+
"\t\t\t\tjsonSchemaFile: contract.schemaFile,",
|
|
282
|
+
"\t\t\t\tsourceTypeName: contract.sourceTypeName,",
|
|
283
|
+
"\t\t\t\ttypesFile: contract.typesFile,",
|
|
284
|
+
"\t\t\t},",
|
|
285
|
+
"\t\t\t{",
|
|
286
|
+
"\t\t\t\tcheck: options.check,",
|
|
287
|
+
"\t\t\t}",
|
|
288
|
+
"\t\t);",
|
|
289
|
+
"\t}",
|
|
290
|
+
].join("\n");
|
|
291
|
+
const resourceLoopAnchor = "\n\tfor ( const resource of restResources ) {";
|
|
292
|
+
if (nextSource.includes(resourceLoopAnchor)) {
|
|
293
|
+
return nextSource.replace(resourceLoopAnchor, `\n${loopSource}\n${resourceLoopAnchor}`);
|
|
294
|
+
}
|
|
295
|
+
const consoleLogPattern = /\n\tconsole\.log\(\n\t\toptions\.check/u;
|
|
296
|
+
return replaceRequiredContractSyncRestSource(nextSource, "for ( const contract of standaloneContracts )", consoleLogPattern, [
|
|
297
|
+
"",
|
|
298
|
+
loopSource,
|
|
299
|
+
"",
|
|
300
|
+
"\tconsole.log(",
|
|
301
|
+
"\t\toptions.check",
|
|
302
|
+
].join("\n"), "success log insertion point", syncRestScriptPath);
|
|
303
|
+
}
|
|
304
|
+
export async function ensureContractSyncScriptAnchors(workspace) {
|
|
305
|
+
const syncRestScriptPath = path.join(workspace.projectDir, "scripts", "sync-rest-contracts.ts");
|
|
306
|
+
await patchFile(syncRestScriptPath, (source) => {
|
|
307
|
+
let nextSource = replaceBlockConfigImportForContracts(source, syncRestScriptPath);
|
|
308
|
+
const helperInsertionAnchor = "async function assertTypeArtifactsCurrent";
|
|
309
|
+
nextSource = replaceRequiredContractSyncRestSource(nextSource, "function isWorkspaceStandaloneContract(", helperInsertionAnchor, [
|
|
310
|
+
"function isWorkspaceStandaloneContract(",
|
|
311
|
+
"\tcontract: WorkspaceContractConfig",
|
|
312
|
+
"): contract is WorkspaceContractConfig & {",
|
|
313
|
+
"\tschemaFile: string;",
|
|
314
|
+
"\tsourceTypeName: string;",
|
|
315
|
+
"\ttypesFile: string;",
|
|
316
|
+
"} {",
|
|
317
|
+
"\treturn (",
|
|
318
|
+
"\t\ttypeof contract.schemaFile === 'string' &&",
|
|
319
|
+
"\t\ttypeof contract.sourceTypeName === 'string' &&",
|
|
320
|
+
"\t\ttypeof contract.typesFile === 'string'",
|
|
321
|
+
"\t);",
|
|
322
|
+
"}",
|
|
323
|
+
"",
|
|
324
|
+
"async function assertTypeArtifactsCurrent",
|
|
325
|
+
].join("\n"), "type artifact assertion helper", syncRestScriptPath);
|
|
326
|
+
nextSource = insertStandaloneContractFilter(nextSource, syncRestScriptPath);
|
|
327
|
+
nextSource = insertStandaloneContractNoResourcesGuard(nextSource, syncRestScriptPath);
|
|
328
|
+
nextSource = insertStandaloneContractSyncLoop(nextSource, syncRestScriptPath);
|
|
329
|
+
nextSource = nextSource.replace("✅ REST contract schemas, portable API clients, and endpoint-aware OpenAPI documents are already up to date for workspace blocks and plugin-level resources!", "✅ REST contract schemas, standalone schemas, portable API clients, and endpoint-aware OpenAPI documents are already up to date for workspace blocks, standalone contracts, and plugin-level resources!");
|
|
330
|
+
nextSource = nextSource.replace("✅ REST contract schemas, portable API clients, and endpoint-aware OpenAPI documents generated for workspace blocks and plugin-level resources!", "✅ REST contract schemas, standalone schemas, portable API clients, and endpoint-aware OpenAPI documents generated for workspace blocks, standalone contracts, and plugin-level resources!");
|
|
331
|
+
nextSource = nextSource.replace("✅ REST contract schemas, portable API clients, and endpoint-aware OpenAPI documents are already up to date with the TypeScript types!", "✅ REST contract schemas, standalone schemas, portable API clients, and endpoint-aware OpenAPI documents are already up to date with the TypeScript types!");
|
|
332
|
+
nextSource = nextSource.replace("✅ REST contract schemas, portable API clients, and endpoint-aware OpenAPI documents generated from TypeScript types!", "✅ REST contract schemas, standalone schemas, portable API clients, and endpoint-aware OpenAPI documents generated from TypeScript types!");
|
|
333
|
+
return nextSource;
|
|
334
|
+
});
|
|
335
|
+
}
|
|
53
336
|
export async function ensureRestResourceSyncScriptAnchors(workspace) {
|
|
54
337
|
const syncRestScriptPath = path.join(workspace.projectDir, "scripts", "sync-rest-contracts.ts");
|
|
55
338
|
await patchFile(syncRestScriptPath, (source) => {
|
|
56
|
-
let nextSource = source;
|
|
57
|
-
const importAnchor = "import { BLOCKS, type WorkspaceBlockConfig } from './block-config';";
|
|
339
|
+
let nextSource = replaceBlockConfigImportForRestResources(source, syncRestScriptPath);
|
|
58
340
|
const helperInsertionAnchor = "async function assertTypeArtifactsCurrent";
|
|
59
341
|
const restBlocksAnchor = "const restBlocks = BLOCKS.filter( isRestEnabledBlock );";
|
|
60
|
-
const noResourcesPattern = /if \( restBlocks.length === 0 \) \{[\s\S]*?\n\t\treturn;\n\t\}/u;
|
|
61
342
|
const consoleLogPattern = /\n\tconsole\.log\(\n\t\toptions\.check/u;
|
|
62
|
-
nextSource = replaceRequiredSyncRestSource(nextSource, "REST_RESOURCES", importAnchor, [
|
|
63
|
-
"import {",
|
|
64
|
-
"\tBLOCKS,",
|
|
65
|
-
"\tREST_RESOURCES,",
|
|
66
|
-
"\ttype WorkspaceBlockConfig,",
|
|
67
|
-
"\ttype WorkspaceRestResourceConfig,",
|
|
68
|
-
"} from './block-config';",
|
|
69
|
-
].join("\n"), "BLOCKS import", syncRestScriptPath);
|
|
70
343
|
nextSource = replaceRequiredSyncRestSource(nextSource, "function isWorkspaceRestResource(", helperInsertionAnchor, [
|
|
71
344
|
"function isWorkspaceRestResource(",
|
|
72
345
|
"\tresource: WorkspaceRestResourceConfig",
|
|
@@ -93,16 +366,7 @@ export async function ensureRestResourceSyncScriptAnchors(workspace) {
|
|
|
93
366
|
"const restBlocks = BLOCKS.filter( isRestEnabledBlock );",
|
|
94
367
|
"const restResources = REST_RESOURCES.filter( isWorkspaceRestResource );",
|
|
95
368
|
].join("\n"), "restBlocks filter", syncRestScriptPath);
|
|
96
|
-
nextSource =
|
|
97
|
-
"if ( restBlocks.length === 0 && restResources.length === 0 ) {",
|
|
98
|
-
"\t\tconsole.log(",
|
|
99
|
-
"\t\t\toptions.check",
|
|
100
|
-
"\t\t\t\t? 'ℹ️ No REST-enabled workspace blocks or plugin-level REST resources are registered yet. `sync-rest --check` is already clean.'",
|
|
101
|
-
"\t\t\t\t: 'ℹ️ No REST-enabled workspace blocks or plugin-level REST resources are registered yet.'",
|
|
102
|
-
"\t\t);",
|
|
103
|
-
"\t\treturn;",
|
|
104
|
-
"\t}",
|
|
105
|
-
].join("\n"), "no-resources guard", syncRestScriptPath);
|
|
369
|
+
nextSource = insertRestResourceNoResourcesGuard(nextSource, syncRestScriptPath);
|
|
106
370
|
nextSource = replaceRequiredSyncRestSource(nextSource, "for ( const resource of restResources ) {", consoleLogPattern, [
|
|
107
371
|
"",
|
|
108
372
|
"\tfor ( const resource of restResources ) {",
|
|
@@ -1,5 +1,93 @@
|
|
|
1
|
-
import { type RestResourceMethodId } from "./cli-add-shared.js";
|
|
2
|
-
|
|
1
|
+
import { type ManualRestContractAuthId, type ManualRestContractHttpMethodId, type RestResourceMethodId } from "./cli-add-shared.js";
|
|
2
|
+
/**
|
|
3
|
+
* Build a generated REST resource config entry for `scripts/block-config.ts`.
|
|
4
|
+
*
|
|
5
|
+
* @param options REST resource metadata. `restResourceSlug`, `namespace`, and
|
|
6
|
+
* `methods` are required; `controllerClass`, `controllerExtends`,
|
|
7
|
+
* `permissionCallback`, and `routePattern` opt into generated controller,
|
|
8
|
+
* permission, and item-route escape hatches.
|
|
9
|
+
* @returns TypeScript object literal source for one generated REST resource entry.
|
|
10
|
+
*/
|
|
11
|
+
export declare function buildRestResourceConfigEntry(options: {
|
|
12
|
+
controllerClass?: string;
|
|
13
|
+
controllerExtends?: string;
|
|
14
|
+
methods: RestResourceMethodId[];
|
|
15
|
+
namespace: string;
|
|
16
|
+
permissionCallback?: string;
|
|
17
|
+
restResourceSlug: string;
|
|
18
|
+
routePattern?: string;
|
|
19
|
+
}): string;
|
|
20
|
+
/**
|
|
21
|
+
* Build the `REST_RESOURCES` config entry appended for a manual REST contract.
|
|
22
|
+
*
|
|
23
|
+
* @param options Manual contract file, route, type, and auth metadata.
|
|
24
|
+
* @param options.auth Auth intent stored in the endpoint manifest.
|
|
25
|
+
* @param options.bodyTypeName Optional exported body type name.
|
|
26
|
+
* @param options.method Uppercase HTTP method for the external route.
|
|
27
|
+
* @param options.namespace REST namespace such as `vendor/v1`.
|
|
28
|
+
* @param options.pathPattern Route pattern relative to the namespace.
|
|
29
|
+
* @param options.queryTypeName Exported query type name.
|
|
30
|
+
* @param options.responseTypeName Exported response type name.
|
|
31
|
+
* @param options.restResourceSlug Normalized workspace REST contract slug.
|
|
32
|
+
* @returns A TypeScript object literal string for `scripts/block-config.ts`.
|
|
33
|
+
*/
|
|
34
|
+
export declare function buildManualRestContractConfigEntry(options: {
|
|
35
|
+
auth: ManualRestContractAuthId;
|
|
36
|
+
bodyTypeName?: string;
|
|
37
|
+
method: ManualRestContractHttpMethodId;
|
|
38
|
+
namespace: string;
|
|
39
|
+
pathPattern: string;
|
|
40
|
+
queryTypeName: string;
|
|
41
|
+
responseTypeName: string;
|
|
42
|
+
restResourceSlug: string;
|
|
43
|
+
secretFieldName?: string;
|
|
44
|
+
secretStateFieldName?: string;
|
|
45
|
+
}): string;
|
|
46
|
+
/**
|
|
47
|
+
* Build the editable TypeScript type source for a manual REST contract.
|
|
48
|
+
*
|
|
49
|
+
* @param options Manual contract type naming metadata.
|
|
50
|
+
* @param options.bodyTypeName Optional exported body type name.
|
|
51
|
+
* @param options.queryTypeName Exported query type name.
|
|
52
|
+
* @param options.responseTypeName Exported response type name.
|
|
53
|
+
* @param options.restResourceSlug Normalized workspace REST contract slug.
|
|
54
|
+
* @param options.secretFieldName Optional raw secret field included only in the request body.
|
|
55
|
+
* @param options.secretStateFieldName Optional masked response boolean field.
|
|
56
|
+
* @returns TypeScript source for `api-types.ts`.
|
|
57
|
+
*/
|
|
58
|
+
export declare function buildManualRestContractTypesSource(options: {
|
|
59
|
+
bodyTypeName?: string;
|
|
60
|
+
queryTypeName: string;
|
|
61
|
+
responseTypeName: string;
|
|
62
|
+
restResourceSlug: string;
|
|
63
|
+
secretFieldName?: string;
|
|
64
|
+
secretStateFieldName?: string;
|
|
65
|
+
}): string;
|
|
66
|
+
/**
|
|
67
|
+
* Build Typia validator source for a manual REST contract.
|
|
68
|
+
*
|
|
69
|
+
* @param options Manual contract type names to validate.
|
|
70
|
+
* @param options.bodyTypeName Optional exported body type name.
|
|
71
|
+
* @param options.queryTypeName Exported query type name.
|
|
72
|
+
* @param options.responseTypeName Exported response type name.
|
|
73
|
+
* @returns TypeScript source for `api-validators.ts`.
|
|
74
|
+
*/
|
|
75
|
+
export declare function buildManualRestContractValidatorsSource(options: {
|
|
76
|
+
bodyTypeName?: string;
|
|
77
|
+
queryTypeName: string;
|
|
78
|
+
responseTypeName: string;
|
|
79
|
+
}): string;
|
|
80
|
+
/**
|
|
81
|
+
* Build the public API shim for a manual REST contract.
|
|
82
|
+
*
|
|
83
|
+
* @param options Manual REST contract operation and request type metadata.
|
|
84
|
+
* @returns TypeScript source that re-exports the generated endpoint client.
|
|
85
|
+
*/
|
|
86
|
+
export declare function buildManualRestContractApiSource(options: {
|
|
87
|
+
bodyTypeName?: string;
|
|
88
|
+
queryTypeName: string;
|
|
89
|
+
restResourceSlug: string;
|
|
90
|
+
}): string;
|
|
3
91
|
export declare function buildRestResourceTypesSource(restResourceSlug: string, methods: RestResourceMethodId[]): string;
|
|
4
92
|
export declare function buildRestResourceValidatorsSource(restResourceSlug: string, methods: RestResourceMethodId[]): string;
|
|
5
93
|
export declare function buildRestResourceApiSource(restResourceSlug: string, methods: RestResourceMethodId[]): string;
|