@wp-typia/project-tools 0.16.14 → 0.18.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/block-generator-service-core.d.ts +1 -1
- package/dist/runtime/block-generator-service-core.js +2 -1
- package/dist/runtime/block-generator-service-spec.d.ts +8 -1
- package/dist/runtime/block-generator-service-spec.js +27 -0
- package/dist/runtime/built-in-block-artifacts.js +1 -0
- package/dist/runtime/built-in-block-code-artifacts.js +14 -1
- package/dist/runtime/built-in-block-code-templates/compound-child.d.ts +2 -2
- package/dist/runtime/built-in-block-code-templates/compound-child.js +30 -2
- package/dist/runtime/built-in-block-code-templates/compound-parent.d.ts +1 -1
- package/dist/runtime/built-in-block-code-templates/compound-parent.js +139 -19
- package/dist/runtime/built-in-block-code-templates/query-loop.d.ts +1 -0
- package/dist/runtime/built-in-block-code-templates/query-loop.js +70 -0
- package/dist/runtime/built-in-block-code-templates.d.ts +1 -0
- package/dist/runtime/built-in-block-code-templates.js +1 -0
- package/dist/runtime/built-in-block-non-ts-artifacts.js +2 -0
- package/dist/runtime/cli-add-block.d.ts +2 -1
- package/dist/runtime/cli-add-block.js +19 -1
- package/dist/runtime/cli-add-shared.d.ts +55 -1
- package/dist/runtime/cli-add-shared.js +101 -2
- package/dist/runtime/cli-add-workspace-assets.d.ts +21 -1
- package/dist/runtime/cli-add-workspace-assets.js +417 -1
- package/dist/runtime/cli-add-workspace-rest.d.ts +14 -0
- package/dist/runtime/cli-add-workspace-rest.js +1060 -0
- package/dist/runtime/cli-add-workspace.d.ts +10 -1
- package/dist/runtime/cli-add-workspace.js +10 -1
- package/dist/runtime/cli-add.d.ts +3 -3
- package/dist/runtime/cli-add.js +2 -2
- package/dist/runtime/cli-core.d.ts +3 -1
- package/dist/runtime/cli-core.js +2 -1
- package/dist/runtime/cli-doctor-workspace.js +135 -1
- package/dist/runtime/cli-help.js +10 -5
- package/dist/runtime/cli-scaffold.d.ts +11 -2
- package/dist/runtime/cli-scaffold.js +137 -36
- package/dist/runtime/cli-templates.d.ts +4 -4
- package/dist/runtime/cli-templates.js +79 -39
- package/dist/runtime/index.d.ts +4 -3
- package/dist/runtime/index.js +3 -2
- package/dist/runtime/local-dev-presets.js +27 -12
- package/dist/runtime/rest-resource-artifacts.d.ts +35 -0
- package/dist/runtime/rest-resource-artifacts.js +158 -0
- package/dist/runtime/scaffold-answer-resolution.d.ts +1 -1
- package/dist/runtime/scaffold-answer-resolution.js +94 -3
- package/dist/runtime/scaffold-apply-utils.d.ts +4 -3
- package/dist/runtime/scaffold-apply-utils.js +34 -17
- package/dist/runtime/scaffold-bootstrap.d.ts +15 -0
- package/dist/runtime/scaffold-bootstrap.js +29 -7
- package/dist/runtime/scaffold-documents.js +9 -9
- package/dist/runtime/scaffold-onboarding.js +17 -1
- package/dist/runtime/scaffold-package-manager-files.js +6 -1
- package/dist/runtime/scaffold-template-variables.js +6 -0
- package/dist/runtime/scaffold.d.ts +15 -1
- package/dist/runtime/scaffold.js +50 -8
- package/dist/runtime/template-defaults.d.ts +7 -0
- package/dist/runtime/template-defaults.js +4 -0
- package/dist/runtime/template-registry.d.ts +1 -1
- package/dist/runtime/template-registry.js +14 -1
- package/dist/runtime/template-render.d.ts +5 -2
- package/dist/runtime/template-render.js +9 -3
- package/dist/runtime/template-source-contracts.d.ts +11 -0
- package/dist/runtime/template-source-external.d.ts +1 -1
- package/dist/runtime/template-source-external.js +45 -13
- package/dist/runtime/template-source-normalization.d.ts +1 -1
- package/dist/runtime/template-source-normalization.js +5 -1
- package/dist/runtime/template-source-remote.d.ts +5 -0
- package/dist/runtime/template-source-remote.js +33 -0
- package/dist/runtime/template-source.js +30 -1
- package/dist/runtime/workspace-inventory.d.ts +43 -1
- package/dist/runtime/workspace-inventory.js +132 -1
- package/dist/runtime/workspace-project.d.ts +1 -1
- package/dist/runtime/workspace-project.js +2 -2
- package/package.json +3 -3
- package/templates/_shared/compound/core/scripts/add-compound-child.ts.mustache +428 -49
- package/templates/query-loop/inc/query-runtime.php.mustache +85 -0
- package/templates/query-loop/package.json.mustache +32 -0
- package/templates/query-loop/src/patterns/grid.php.mustache +49 -0
- package/templates/query-loop/src/patterns/list.php.mustache +48 -0
- package/templates/query-loop/src/query-extension.ts.mustache +41 -0
- package/templates/query-loop/webpack.config.js.mustache +16 -0
- package/templates/query-loop/{{slugKebabCase}}.php.mustache +84 -0
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import type { HookedBlockPositionId } from "./hooked-blocks.js";
|
|
2
2
|
import { type RunAddHookedBlockCommandOptions, type RunAddVariationCommandOptions } from "./cli-add-shared.js";
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Re-export focused workspace asset scaffold commands from the companion
|
|
5
|
+
* `cli-add-workspace-assets` module.
|
|
6
|
+
*/
|
|
7
|
+
export { runAddEditorPluginCommand, runAddBindingSourceCommand, runAddPatternCommand, } from "./cli-add-workspace-assets.js";
|
|
8
|
+
/**
|
|
9
|
+
* Re-export the plugin-level REST resource scaffold workflow from the focused
|
|
10
|
+
* rest-resource runtime helper module.
|
|
11
|
+
*/
|
|
12
|
+
export { runAddRestResourceCommand } from "./cli-add-workspace-rest.js";
|
|
4
13
|
/**
|
|
5
14
|
* Add one variation entry to an existing workspace block.
|
|
6
15
|
*
|
|
@@ -119,7 +119,16 @@ async function writeVariationRegistry(projectDir, blockSlug, variationSlug) {
|
|
|
119
119
|
const nextVariationSlugs = Array.from(new Set([...existingVariationSlugs, variationSlug])).sort();
|
|
120
120
|
await fsp.writeFile(variationsIndexPath, buildVariationIndexSource(nextVariationSlugs), "utf8");
|
|
121
121
|
}
|
|
122
|
-
|
|
122
|
+
/**
|
|
123
|
+
* Re-export focused workspace asset scaffold commands from the companion
|
|
124
|
+
* `cli-add-workspace-assets` module.
|
|
125
|
+
*/
|
|
126
|
+
export { runAddEditorPluginCommand, runAddBindingSourceCommand, runAddPatternCommand, } from "./cli-add-workspace-assets.js";
|
|
127
|
+
/**
|
|
128
|
+
* Re-export the plugin-level REST resource scaffold workflow from the focused
|
|
129
|
+
* rest-resource runtime helper module.
|
|
130
|
+
*/
|
|
131
|
+
export { runAddRestResourceCommand } from "./cli-add-workspace-rest.js";
|
|
123
132
|
/**
|
|
124
133
|
* Add one variation entry to an existing workspace block.
|
|
125
134
|
*
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
* - `cli-add-block` for built-in block scaffolding
|
|
8
8
|
* - `cli-add-workspace` for workspace mutation commands
|
|
9
9
|
*/
|
|
10
|
-
export { ADD_BLOCK_TEMPLATE_IDS, ADD_KIND_IDS, formatAddHelpText, } from "./cli-add-shared.js";
|
|
11
|
-
export type { AddBlockTemplateId, AddKindId, } from "./cli-add-shared.js";
|
|
10
|
+
export { ADD_BLOCK_TEMPLATE_IDS, ADD_KIND_IDS, EDITOR_PLUGIN_SLOT_IDS, formatAddHelpText, } from "./cli-add-shared.js";
|
|
11
|
+
export type { AddBlockTemplateId, AddKindId, EditorPluginSlotId, } from "./cli-add-shared.js";
|
|
12
12
|
export { runAddBlockCommand, seedWorkspaceMigrationProject, } from "./cli-add-block.js";
|
|
13
|
-
export { runAddBindingSourceCommand, runAddHookedBlockCommand, runAddPatternCommand, runAddVariationCommand, } from "./cli-add-workspace.js";
|
|
13
|
+
export { runAddBindingSourceCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddPatternCommand, runAddRestResourceCommand, runAddVariationCommand, } from "./cli-add-workspace.js";
|
|
14
14
|
export { getWorkspaceBlockSelectOptions } from "./workspace-inventory.js";
|
package/dist/runtime/cli-add.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* - `cli-add-block` for built-in block scaffolding
|
|
8
8
|
* - `cli-add-workspace` for workspace mutation commands
|
|
9
9
|
*/
|
|
10
|
-
export { ADD_BLOCK_TEMPLATE_IDS, ADD_KIND_IDS, formatAddHelpText, } from "./cli-add-shared.js";
|
|
10
|
+
export { ADD_BLOCK_TEMPLATE_IDS, ADD_KIND_IDS, EDITOR_PLUGIN_SLOT_IDS, formatAddHelpText, } from "./cli-add-shared.js";
|
|
11
11
|
export { runAddBlockCommand, seedWorkspaceMigrationProject, } from "./cli-add-block.js";
|
|
12
|
-
export { runAddBindingSourceCommand, runAddHookedBlockCommand, runAddPatternCommand, runAddVariationCommand, } from "./cli-add-workspace.js";
|
|
12
|
+
export { runAddBindingSourceCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddPatternCommand, runAddRestResourceCommand, runAddVariationCommand, } from "./cli-add-workspace.js";
|
|
13
13
|
export { getWorkspaceBlockSelectOptions } from "./workspace-inventory.js";
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* and `HOOKED_BLOCK_POSITION_IDS`,
|
|
12
12
|
* `getWorkspaceBlockSelectOptions`, and `seedWorkspaceMigrationProject` for
|
|
13
13
|
* explicit `wp-typia add` flows,
|
|
14
|
+
* `runAddRestResourceCommand` for plugin-level REST resource scaffolds,
|
|
14
15
|
* `getDoctorChecks`, `runDoctor`, and `DoctorCheck` for diagnostics,
|
|
15
16
|
* `createCliCommandError` and `formatCliDiagnosticError` for shared
|
|
16
17
|
* non-interactive failure rendering,
|
|
@@ -25,8 +26,9 @@
|
|
|
25
26
|
export { getDoctorChecks, runDoctor, type DoctorCheck } from "./cli-doctor.js";
|
|
26
27
|
export { createCliCommandError, CliDiagnosticError, formatCliDiagnosticError, formatDoctorCheckLine, formatDoctorSummaryLine, getDoctorFailureDetailLines, getFailingDoctorChecks, isCliDiagnosticError, } from "./cli-diagnostics.js";
|
|
27
28
|
export type { CliDiagnosticMessage } from "./cli-diagnostics.js";
|
|
28
|
-
export { formatAddHelpText, getWorkspaceBlockSelectOptions, runAddBindingSourceCommand, runAddBlockCommand, runAddHookedBlockCommand, runAddPatternCommand, runAddVariationCommand, seedWorkspaceMigrationProject, } from "./cli-add.js";
|
|
29
|
+
export { EDITOR_PLUGIN_SLOT_IDS, formatAddHelpText, getWorkspaceBlockSelectOptions, runAddBindingSourceCommand, runAddBlockCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddPatternCommand, runAddRestResourceCommand, runAddVariationCommand, seedWorkspaceMigrationProject, } from "./cli-add.js";
|
|
29
30
|
export { HOOKED_BLOCK_POSITION_IDS } from "./hooked-blocks.js";
|
|
31
|
+
export type { EditorPluginSlotId } from "./cli-add.js";
|
|
30
32
|
export type { HookedBlockPositionId } from "./hooked-blocks.js";
|
|
31
33
|
export { formatHelpText } from "./cli-help.js";
|
|
32
34
|
export { getNextSteps, getOptionalOnboarding, runScaffoldFlow, } from "./cli-scaffold.js";
|
package/dist/runtime/cli-core.js
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* and `HOOKED_BLOCK_POSITION_IDS`,
|
|
12
12
|
* `getWorkspaceBlockSelectOptions`, and `seedWorkspaceMigrationProject` for
|
|
13
13
|
* explicit `wp-typia add` flows,
|
|
14
|
+
* `runAddRestResourceCommand` for plugin-level REST resource scaffolds,
|
|
14
15
|
* `getDoctorChecks`, `runDoctor`, and `DoctorCheck` for diagnostics,
|
|
15
16
|
* `createCliCommandError` and `formatCliDiagnosticError` for shared
|
|
16
17
|
* non-interactive failure rendering,
|
|
@@ -24,7 +25,7 @@
|
|
|
24
25
|
*/
|
|
25
26
|
export { getDoctorChecks, runDoctor } from "./cli-doctor.js";
|
|
26
27
|
export { createCliCommandError, CliDiagnosticError, formatCliDiagnosticError, formatDoctorCheckLine, formatDoctorSummaryLine, getDoctorFailureDetailLines, getFailingDoctorChecks, isCliDiagnosticError, } from "./cli-diagnostics.js";
|
|
27
|
-
export { formatAddHelpText, getWorkspaceBlockSelectOptions, runAddBindingSourceCommand, runAddBlockCommand, runAddHookedBlockCommand, runAddPatternCommand, runAddVariationCommand, seedWorkspaceMigrationProject, } from "./cli-add.js";
|
|
28
|
+
export { EDITOR_PLUGIN_SLOT_IDS, formatAddHelpText, getWorkspaceBlockSelectOptions, runAddBindingSourceCommand, runAddBlockCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddPatternCommand, runAddRestResourceCommand, runAddVariationCommand, seedWorkspaceMigrationProject, } from "./cli-add.js";
|
|
28
29
|
export { HOOKED_BLOCK_POSITION_IDS } from "./hooked-blocks.js";
|
|
29
30
|
export { formatHelpText } from "./cli-help.js";
|
|
30
31
|
export { getNextSteps, getOptionalOnboarding, runScaffoldFlow, } from "./cli-scaffold.js";
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { parseScaffoldBlockMetadata } from "@wp-typia/block-runtime/blocks";
|
|
4
|
+
import { EDITOR_PLUGIN_SLOT_IDS, REST_RESOURCE_METHOD_IDS, REST_RESOURCE_NAMESPACE_PATTERN, } from "./cli-add-shared.js";
|
|
4
5
|
import { HOOKED_BLOCK_ANCHOR_PATTERN, HOOKED_BLOCK_POSITION_SET, } from "./hooked-blocks.js";
|
|
5
6
|
import { readWorkspaceInventory } from "./workspace-inventory.js";
|
|
6
7
|
import { getInvalidWorkspaceProjectReason, parseWorkspacePackageJson, WORKSPACE_TEMPLATE_PACKAGE, tryResolveWorkspaceProject, } from "./workspace-project.js";
|
|
@@ -9,6 +10,10 @@ const WORKSPACE_COLLECTION_IMPORT_PATTERN = /^\s*import\s+["']\.\.\/\.\.\/collec
|
|
|
9
10
|
const WORKSPACE_BINDING_SERVER_GLOB = "/src/bindings/*/server.php";
|
|
10
11
|
const WORKSPACE_BINDING_EDITOR_SCRIPT = "build/bindings/index.js";
|
|
11
12
|
const WORKSPACE_BINDING_EDITOR_ASSET = "build/bindings/index.asset.php";
|
|
13
|
+
const WORKSPACE_REST_RESOURCE_GLOB = "/inc/rest/*.php";
|
|
14
|
+
const WORKSPACE_EDITOR_PLUGIN_EDITOR_SCRIPT = "build/editor-plugins/index.js";
|
|
15
|
+
const WORKSPACE_EDITOR_PLUGIN_EDITOR_ASSET = "build/editor-plugins/index.asset.php";
|
|
16
|
+
const WORKSPACE_EDITOR_PLUGIN_EDITOR_STYLE = "build/editor-plugins/style-index.css";
|
|
12
17
|
const WORKSPACE_GENERATED_BLOCK_ARTIFACTS = [
|
|
13
18
|
"block.json",
|
|
14
19
|
"typia.manifest.json",
|
|
@@ -22,6 +27,9 @@ function createDoctorCheck(label, status, detail) {
|
|
|
22
27
|
function createDoctorScopeCheck(status, detail) {
|
|
23
28
|
return createDoctorCheck("Doctor scope", status, detail);
|
|
24
29
|
}
|
|
30
|
+
function escapeRegex(value) {
|
|
31
|
+
return value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
32
|
+
}
|
|
25
33
|
function getWorkspaceBootstrapRelativePath(packageName) {
|
|
26
34
|
const packageBaseName = packageName.split("/").pop() ?? packageName;
|
|
27
35
|
return `${packageBaseName}.php`;
|
|
@@ -184,6 +192,117 @@ function checkWorkspaceBindingSourcesIndex(projectDir, bindingSources) {
|
|
|
184
192
|
? "Binding source editor registrations are aggregated"
|
|
185
193
|
: `Missing editor imports for: ${missingImports.map((entry) => entry.slug).join(", ")}`);
|
|
186
194
|
}
|
|
195
|
+
function getWorkspaceRestResourceRequiredFiles(restResource) {
|
|
196
|
+
const schemaNames = new Set();
|
|
197
|
+
if (restResource.methods.includes("list")) {
|
|
198
|
+
schemaNames.add("list-query");
|
|
199
|
+
schemaNames.add("list-response");
|
|
200
|
+
}
|
|
201
|
+
if (restResource.methods.includes("read")) {
|
|
202
|
+
schemaNames.add("read-query");
|
|
203
|
+
schemaNames.add("read-response");
|
|
204
|
+
}
|
|
205
|
+
if (restResource.methods.includes("create")) {
|
|
206
|
+
schemaNames.add("create-request");
|
|
207
|
+
schemaNames.add("create-response");
|
|
208
|
+
}
|
|
209
|
+
if (restResource.methods.includes("update")) {
|
|
210
|
+
schemaNames.add("update-query");
|
|
211
|
+
schemaNames.add("update-request");
|
|
212
|
+
schemaNames.add("update-response");
|
|
213
|
+
}
|
|
214
|
+
if (restResource.methods.includes("delete")) {
|
|
215
|
+
schemaNames.add("delete-query");
|
|
216
|
+
schemaNames.add("delete-response");
|
|
217
|
+
}
|
|
218
|
+
return Array.from(new Set([
|
|
219
|
+
restResource.apiFile,
|
|
220
|
+
...Array.from(schemaNames, (schemaName) => path.join(path.dirname(restResource.typesFile), "api-schemas", `${schemaName}.schema.json`)),
|
|
221
|
+
restResource.clientFile,
|
|
222
|
+
restResource.dataFile,
|
|
223
|
+
restResource.openApiFile,
|
|
224
|
+
restResource.phpFile,
|
|
225
|
+
restResource.typesFile,
|
|
226
|
+
restResource.validatorsFile,
|
|
227
|
+
]));
|
|
228
|
+
}
|
|
229
|
+
function checkWorkspaceRestResourceConfig(restResource) {
|
|
230
|
+
const hasNamespace = REST_RESOURCE_NAMESPACE_PATTERN.test(restResource.namespace);
|
|
231
|
+
const hasMethods = restResource.methods.length > 0 &&
|
|
232
|
+
restResource.methods.every((method) => REST_RESOURCE_METHOD_IDS.includes(method));
|
|
233
|
+
return createDoctorCheck(`REST resource config ${restResource.slug}`, hasNamespace && hasMethods ? "pass" : "fail", hasNamespace && hasMethods
|
|
234
|
+
? `REST resource namespace ${restResource.namespace} with methods ${restResource.methods.join(", ")}`
|
|
235
|
+
: "REST resource namespace or methods are invalid");
|
|
236
|
+
}
|
|
237
|
+
function checkWorkspaceRestResourceBootstrap(projectDir, packageName, phpPrefix) {
|
|
238
|
+
const packageBaseName = packageName.split("/").pop() ?? packageName;
|
|
239
|
+
const bootstrapPath = path.join(projectDir, `${packageBaseName}.php`);
|
|
240
|
+
if (!fs.existsSync(bootstrapPath)) {
|
|
241
|
+
return createDoctorCheck("REST resource bootstrap", "fail", `Missing ${path.basename(bootstrapPath)}`);
|
|
242
|
+
}
|
|
243
|
+
const source = fs.readFileSync(bootstrapPath, "utf8");
|
|
244
|
+
const registerFunctionName = `${phpPrefix}_register_rest_resources`;
|
|
245
|
+
const registerHook = `add_action( 'init', '${registerFunctionName}', 20 );`;
|
|
246
|
+
const hasServerGlob = source.includes(WORKSPACE_REST_RESOURCE_GLOB);
|
|
247
|
+
const hasRegisterHook = source.includes(registerHook);
|
|
248
|
+
return createDoctorCheck("REST resource bootstrap", hasServerGlob && hasRegisterHook ? "pass" : "fail", hasServerGlob && hasRegisterHook
|
|
249
|
+
? "REST resource PHP loader hook is present"
|
|
250
|
+
: "Missing REST resource PHP require glob or init hook");
|
|
251
|
+
}
|
|
252
|
+
function getWorkspaceEditorPluginRequiredFiles(editorPlugin) {
|
|
253
|
+
const editorPluginDir = path.join("src", "editor-plugins", editorPlugin.slug);
|
|
254
|
+
return Array.from(new Set([
|
|
255
|
+
editorPlugin.file,
|
|
256
|
+
path.join(editorPluginDir, "Sidebar.tsx"),
|
|
257
|
+
path.join(editorPluginDir, "data.ts"),
|
|
258
|
+
path.join(editorPluginDir, "types.ts"),
|
|
259
|
+
path.join(editorPluginDir, "style.scss"),
|
|
260
|
+
]));
|
|
261
|
+
}
|
|
262
|
+
function checkWorkspaceEditorPluginConfig(editorPlugin) {
|
|
263
|
+
const validSlots = new Set(EDITOR_PLUGIN_SLOT_IDS);
|
|
264
|
+
const isValidSlot = validSlots.has(editorPlugin.slot);
|
|
265
|
+
return createDoctorCheck(`Editor plugin config ${editorPlugin.slug}`, isValidSlot ? "pass" : "fail", isValidSlot
|
|
266
|
+
? `Editor plugin slot ${editorPlugin.slot} is supported`
|
|
267
|
+
: `Unsupported editor plugin slot "${editorPlugin.slot}". Expected one of: ${EDITOR_PLUGIN_SLOT_IDS.join(", ")}`);
|
|
268
|
+
}
|
|
269
|
+
function checkWorkspaceEditorPluginBootstrap(projectDir, packageName, phpPrefix) {
|
|
270
|
+
const packageBaseName = packageName.split("/").pop() ?? packageName;
|
|
271
|
+
const bootstrapPath = path.join(projectDir, `${packageBaseName}.php`);
|
|
272
|
+
if (!fs.existsSync(bootstrapPath)) {
|
|
273
|
+
return createDoctorCheck("Editor plugin bootstrap", "fail", `Missing ${path.basename(bootstrapPath)}`);
|
|
274
|
+
}
|
|
275
|
+
const source = fs.readFileSync(bootstrapPath, "utf8");
|
|
276
|
+
const enqueueFunctionName = `${phpPrefix}_enqueue_editor_plugins_editor`;
|
|
277
|
+
const enqueueHook = `add_action( 'enqueue_block_editor_assets', '${enqueueFunctionName}' );`;
|
|
278
|
+
const hasEditorEnqueueHook = source.includes(enqueueHook);
|
|
279
|
+
const hasEditorScript = source.includes(WORKSPACE_EDITOR_PLUGIN_EDITOR_SCRIPT);
|
|
280
|
+
const hasEditorAsset = source.includes(WORKSPACE_EDITOR_PLUGIN_EDITOR_ASSET);
|
|
281
|
+
const hasEditorStyle = source.includes(WORKSPACE_EDITOR_PLUGIN_EDITOR_STYLE);
|
|
282
|
+
return createDoctorCheck("Editor plugin bootstrap", hasEditorEnqueueHook && hasEditorScript && hasEditorAsset && hasEditorStyle ? "pass" : "fail", hasEditorEnqueueHook && hasEditorScript && hasEditorAsset && hasEditorStyle
|
|
283
|
+
? "Editor plugin enqueue hook is present"
|
|
284
|
+
: "Missing editor plugin enqueue hook or build/editor-plugins script/style asset references");
|
|
285
|
+
}
|
|
286
|
+
function checkWorkspaceEditorPluginIndex(projectDir, editorPlugins) {
|
|
287
|
+
const indexRelativePath = [
|
|
288
|
+
path.join("src", "editor-plugins", "index.ts"),
|
|
289
|
+
path.join("src", "editor-plugins", "index.js"),
|
|
290
|
+
].find((relativePath) => fs.existsSync(path.join(projectDir, relativePath)));
|
|
291
|
+
if (!indexRelativePath) {
|
|
292
|
+
return createDoctorCheck("Editor plugins index", "fail", "Missing src/editor-plugins/index.ts or src/editor-plugins/index.js");
|
|
293
|
+
}
|
|
294
|
+
const indexPath = path.join(projectDir, indexRelativePath);
|
|
295
|
+
const source = fs.readFileSync(indexPath, "utf8");
|
|
296
|
+
const missingImports = editorPlugins.filter((editorPlugin) => {
|
|
297
|
+
const importPattern = new RegExp(`['"\`]\\./${escapeRegex(editorPlugin.slug)}(?:/[^'"\`]*)?['"\`]`, "u");
|
|
298
|
+
return !importPattern.test(source);
|
|
299
|
+
});
|
|
300
|
+
return createDoctorCheck("Editor plugins index", missingImports.length === 0 ? "pass" : "fail", missingImports.length === 0
|
|
301
|
+
? "Editor plugin registrations are aggregated"
|
|
302
|
+
: `Missing editor plugin imports for: ${missingImports
|
|
303
|
+
.map((entry) => entry.slug)
|
|
304
|
+
.join(", ")}`);
|
|
305
|
+
}
|
|
187
306
|
function checkVariationEntrypoint(projectDir, blockSlug) {
|
|
188
307
|
const entryPath = path.join(projectDir, "src", "blocks", blockSlug, "index.tsx");
|
|
189
308
|
if (!fs.existsSync(entryPath)) {
|
|
@@ -258,7 +377,7 @@ export function getWorkspaceDoctorChecks(cwd) {
|
|
|
258
377
|
checks.push(checkWorkspacePackageMetadata(workspace, workspacePackageJson));
|
|
259
378
|
try {
|
|
260
379
|
const inventory = readWorkspaceInventory(workspace.projectDir);
|
|
261
|
-
checks.push(createDoctorCheck("Workspace inventory", "pass", `${inventory.blocks.length} block(s), ${inventory.variations.length} variation(s), ${inventory.patterns.length} pattern(s), ${inventory.bindingSources.length} binding source(s)`));
|
|
380
|
+
checks.push(createDoctorCheck("Workspace inventory", "pass", `${inventory.blocks.length} block(s), ${inventory.variations.length} variation(s), ${inventory.patterns.length} pattern(s), ${inventory.bindingSources.length} binding source(s), ${inventory.restResources.length} REST resource(s), ${inventory.editorPlugins.length} editor plugin(s)`));
|
|
262
381
|
for (const block of inventory.blocks) {
|
|
263
382
|
checks.push(checkExistingFiles(workspace.projectDir, `Block ${block.slug}`, getWorkspaceBlockRequiredFiles(block)));
|
|
264
383
|
checks.push(checkWorkspaceBlockMetadata(workspace.projectDir, workspace, block));
|
|
@@ -296,6 +415,21 @@ export function getWorkspaceDoctorChecks(cwd) {
|
|
|
296
415
|
bindingSource.editorFile,
|
|
297
416
|
]));
|
|
298
417
|
}
|
|
418
|
+
if (inventory.restResources.length > 0) {
|
|
419
|
+
checks.push(checkWorkspaceRestResourceBootstrap(workspace.projectDir, workspace.packageName, workspace.workspace.phpPrefix));
|
|
420
|
+
}
|
|
421
|
+
for (const restResource of inventory.restResources) {
|
|
422
|
+
checks.push(checkWorkspaceRestResourceConfig(restResource));
|
|
423
|
+
checks.push(checkExistingFiles(workspace.projectDir, `REST resource ${restResource.slug}`, getWorkspaceRestResourceRequiredFiles(restResource)));
|
|
424
|
+
}
|
|
425
|
+
if (inventory.editorPlugins.length > 0) {
|
|
426
|
+
checks.push(checkWorkspaceEditorPluginBootstrap(workspace.projectDir, workspace.packageName, workspace.workspace.phpPrefix));
|
|
427
|
+
checks.push(checkWorkspaceEditorPluginIndex(workspace.projectDir, inventory.editorPlugins));
|
|
428
|
+
}
|
|
429
|
+
for (const editorPlugin of inventory.editorPlugins) {
|
|
430
|
+
checks.push(checkExistingFiles(workspace.projectDir, `Editor plugin ${editorPlugin.slug}`, getWorkspaceEditorPluginRequiredFiles(editorPlugin)));
|
|
431
|
+
checks.push(checkWorkspaceEditorPluginConfig(editorPlugin));
|
|
432
|
+
}
|
|
299
433
|
const migrationWorkspaceCheck = checkMigrationWorkspaceHint(workspace, workspacePackageJson);
|
|
300
434
|
if (migrationWorkspaceCheck) {
|
|
301
435
|
checks.push(migrationWorkspaceCheck);
|
package/dist/runtime/cli-help.js
CHANGED
|
@@ -10,16 +10,19 @@ import { TEMPLATE_IDS } from "./template-registry.js";
|
|
|
10
10
|
*/
|
|
11
11
|
export function formatHelpText() {
|
|
12
12
|
return `Usage:
|
|
13
|
-
wp-typia create <project-dir> [--template <basic|interactivity>] [--external-layer-source <./path|github:owner/repo/path[#ref]|npm-package>] [--external-layer-id <layer-id>] [--namespace <value>] [--text-domain <value>] [--php-prefix <value>] [--with-migration-ui] [--with-wp-env] [--with-test-preset] [--yes] [--no-install] [--package-manager <id>]
|
|
14
|
-
wp-typia create <project-dir> [--template <./path|github:owner/repo/path[#ref]>] [--
|
|
15
|
-
wp-typia create <project-dir> [--template
|
|
16
|
-
wp-typia create <project-dir> [--template
|
|
17
|
-
wp-typia create <project-dir> [--template
|
|
13
|
+
wp-typia create <project-dir> [--template <basic|interactivity>] [--external-layer-source <./path|github:owner/repo/path[#ref]|npm-package>] [--external-layer-id <layer-id>] [--namespace <value>] [--text-domain <value>] [--php-prefix <value>] [--with-migration-ui] [--with-wp-env] [--with-test-preset] [--yes] [--dry-run] [--no-install] [--package-manager <id>]
|
|
14
|
+
wp-typia create <project-dir> [--template query-loop] [--external-layer-source <./path|github:owner/repo/path[#ref]|npm-package>] [--external-layer-id <layer-id>] [--query-post-type <post-type>] [--namespace <value>] [--text-domain <value>] [--php-prefix <value>] [--with-migration-ui] [--with-wp-env] [--with-test-preset] [--yes] [--dry-run] [--no-install] [--package-manager <id>]
|
|
15
|
+
wp-typia create <project-dir> [--template <./path|github:owner/repo/path[#ref]>] [--variant <name>] [--namespace <value>] [--text-domain <value>] [--php-prefix <value>] [--with-wp-env] [--with-test-preset] [--yes] [--dry-run] [--no-install] [--package-manager <id>]
|
|
16
|
+
wp-typia create <project-dir> [--template <npm-package>] [--variant <name>] [--namespace <value>] [--text-domain <value>] [--php-prefix <value>] [--with-wp-env] [--with-test-preset] [--yes] [--dry-run] [--no-install] [--package-manager <id>]
|
|
17
|
+
wp-typia create <project-dir> [--template persistence] [--external-layer-source <./path|github:owner/repo/path[#ref]|npm-package>] [--external-layer-id <layer-id>] [--data-storage <post-meta|custom-table>] [--persistence-policy <authenticated|public>] [--namespace <value>] [--text-domain <value>] [--php-prefix <value>] [--with-migration-ui] [--with-wp-env] [--with-test-preset] [--yes] [--dry-run] [--no-install] [--package-manager <id>]
|
|
18
|
+
wp-typia create <project-dir> [--template compound] [--external-layer-source <./path|github:owner/repo/path[#ref]|npm-package>] [--external-layer-id <layer-id>] [--data-storage <post-meta|custom-table>] [--persistence-policy <authenticated|public>] [--namespace <value>] [--text-domain <value>] [--php-prefix <value>] [--with-migration-ui] [--with-wp-env] [--with-test-preset] [--yes] [--dry-run] [--no-install] [--package-manager <id>]
|
|
18
19
|
wp-typia <project-dir> [create flags...]
|
|
19
20
|
wp-typia add block <name> --template <basic|interactivity|persistence|compound> [--external-layer-source <./path|github:owner/repo/path[#ref]|npm-package>] [--external-layer-id <layer-id>] [--data-storage <post-meta|custom-table>] [--persistence-policy <authenticated|public>]
|
|
20
21
|
wp-typia add variation <name> --block <block-slug>
|
|
21
22
|
wp-typia add pattern <name>
|
|
22
23
|
wp-typia add binding-source <name>
|
|
24
|
+
wp-typia add rest-resource <name> [--namespace <vendor/v1>] [--methods <method[,method...]>]
|
|
25
|
+
wp-typia add editor-plugin <name> [--slot <PluginSidebar>]
|
|
23
26
|
wp-typia add hooked-block <block-slug> --anchor <anchor-block-name> --position <before|after|firstChild|lastChild>
|
|
24
27
|
wp-typia migrate <init|snapshot|diff|scaffold|verify|doctor|fixtures|fuzz> [...]
|
|
25
28
|
wp-typia templates list
|
|
@@ -38,6 +41,8 @@ Notes:
|
|
|
38
41
|
\`add variation\` uses an existing workspace block from \`scripts/block-config.ts\`.
|
|
39
42
|
\`add pattern\` scaffolds a namespaced PHP pattern shell under \`src/patterns/\`.
|
|
40
43
|
\`add binding-source\` scaffolds shared PHP and editor registration under \`src/bindings/\`.
|
|
44
|
+
\`add rest-resource\` scaffolds plugin-level TypeScript REST contracts under \`src/rest/\` and PHP route glue under \`inc/rest/\`.
|
|
45
|
+
\`add editor-plugin\` scaffolds a document-level editor extension under \`src/editor-plugins/\`.
|
|
41
46
|
\`add hooked-block\` patches an existing workspace block's \`block.json\` \`blockHooks\` metadata.
|
|
42
47
|
\`wp-typia doctor\` always checks environment readiness and reports when it only ran environment-level diagnostics; official workspace roots also get inventory and source-tree drift checks.
|
|
43
48
|
\`wp-typia migrate doctor --all\` checks migration target alignment, snapshots, fixtures, and generated migration artifacts.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { collectScaffoldAnswers, scaffoldProject } from "./scaffold.js";
|
|
2
|
-
import type { DataStorageMode, PersistencePolicy } from "./scaffold.js";
|
|
2
|
+
import type { DataStorageMode, PersistencePolicy, ScaffoldProgressEvent } from "./scaffold.js";
|
|
3
3
|
import type { PackageManagerId } from "./package-managers.js";
|
|
4
4
|
import { type ExternalLayerSelectionOption } from "./external-layer-selection.js";
|
|
5
5
|
import type { TemplateDefinition } from "./template-registry.js";
|
|
@@ -20,20 +20,27 @@ interface OptionalOnboardingGuidance {
|
|
|
20
20
|
note: string;
|
|
21
21
|
steps: string[];
|
|
22
22
|
}
|
|
23
|
+
export interface ScaffoldDryRunPlan {
|
|
24
|
+
dependencyInstall: "skipped-by-flag" | "would-install";
|
|
25
|
+
files: string[];
|
|
26
|
+
}
|
|
23
27
|
interface RunScaffoldFlowOptions {
|
|
24
28
|
allowExistingDir?: boolean;
|
|
25
29
|
cwd?: string;
|
|
26
30
|
dataStorageMode?: string;
|
|
31
|
+
dryRun?: boolean;
|
|
27
32
|
externalLayerId?: string;
|
|
28
33
|
externalLayerSource?: string;
|
|
29
34
|
installDependencies?: Parameters<typeof scaffoldProject>[0]["installDependencies"];
|
|
30
35
|
isInteractive?: boolean;
|
|
31
36
|
namespace?: string;
|
|
32
37
|
noInstall?: boolean;
|
|
38
|
+
onProgress?: ((event: ScaffoldProgressEvent) => void | Promise<void>) | undefined;
|
|
33
39
|
packageManager?: string;
|
|
34
40
|
phpPrefix?: string;
|
|
35
41
|
projectInput: string;
|
|
36
42
|
promptText?: Parameters<typeof collectScaffoldAnswers>[0]["promptText"];
|
|
43
|
+
queryPostType?: string;
|
|
37
44
|
selectDataStorage?: () => Promise<DataStorageMode>;
|
|
38
45
|
selectExternalLayerId?: (options: ExternalLayerSelectionOption[]) => Promise<string>;
|
|
39
46
|
selectPackageManager?: () => Promise<PackageManagerId>;
|
|
@@ -73,8 +80,10 @@ export declare function getOptionalOnboarding({ availableScripts, packageManager
|
|
|
73
80
|
* project.
|
|
74
81
|
* @returns The scaffold result together with next-step guidance.
|
|
75
82
|
*/
|
|
76
|
-
export declare function runScaffoldFlow({ projectInput, cwd, templateId, dataStorageMode, externalLayerId, externalLayerSource, persistencePolicy, packageManager, namespace, textDomain, phpPrefix, yes, noInstall, isInteractive, allowExistingDir, selectTemplate, selectDataStorage, selectExternalLayerId, selectPersistencePolicy, selectPackageManager, promptText, installDependencies, variant, selectWithTestPreset, selectWithWpEnv, selectWithMigrationUi, withMigrationUi, withTestPreset, withWpEnv, }: RunScaffoldFlowOptions): Promise<{
|
|
83
|
+
export declare function runScaffoldFlow({ projectInput, cwd, templateId, dataStorageMode, dryRun, externalLayerId, externalLayerSource, persistencePolicy, packageManager, namespace, textDomain, phpPrefix, queryPostType, yes, noInstall, onProgress, isInteractive, allowExistingDir, selectTemplate, selectDataStorage, selectExternalLayerId, selectPersistencePolicy, selectPackageManager, promptText, installDependencies, variant, selectWithTestPreset, selectWithWpEnv, selectWithMigrationUi, withMigrationUi, withTestPreset, withWpEnv, }: RunScaffoldFlowOptions): Promise<{
|
|
84
|
+
dryRun: boolean;
|
|
77
85
|
optionalOnboarding: OptionalOnboardingGuidance;
|
|
86
|
+
plan: ScaffoldDryRunPlan | undefined;
|
|
78
87
|
projectDir: string;
|
|
79
88
|
projectInput: string;
|
|
80
89
|
packageManager: PackageManagerId;
|
|
@@ -1,11 +1,79 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
|
+
import { promises as fsp } from "node:fs";
|
|
3
|
+
import os from "node:os";
|
|
2
4
|
import path from "node:path";
|
|
3
5
|
import { collectScaffoldAnswers, DATA_STORAGE_MODES, PERSISTENCE_POLICIES, isDataStorageMode, isPersistencePolicy, resolvePackageManagerId, resolveTemplateId, scaffoldProject, } from "./scaffold.js";
|
|
4
6
|
import { formatInstallCommand, formatRunScript, } from "./package-managers.js";
|
|
5
7
|
import { getPrimaryDevelopmentScript } from "./local-dev-presets.js";
|
|
6
8
|
import { getOptionalOnboardingNote, getOptionalOnboardingSteps, } from "./scaffold-onboarding.js";
|
|
9
|
+
import { formatNonEmptyTargetDirectoryError } from "./scaffold-bootstrap.js";
|
|
7
10
|
import { OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE, isBuiltInTemplateId, } from "./template-registry.js";
|
|
8
11
|
import { resolveOptionalInteractiveExternalLayerId, } from "./external-layer-selection.js";
|
|
12
|
+
async function listRelativeProjectFiles(rootDir) {
|
|
13
|
+
const relativeFiles = [];
|
|
14
|
+
async function visit(currentDir) {
|
|
15
|
+
const entries = await fsp.readdir(currentDir, { withFileTypes: true });
|
|
16
|
+
for (const entry of entries) {
|
|
17
|
+
const absolutePath = path.join(currentDir, entry.name);
|
|
18
|
+
if (entry.isDirectory()) {
|
|
19
|
+
await visit(absolutePath);
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
relativeFiles.push(path
|
|
23
|
+
.relative(rootDir, absolutePath)
|
|
24
|
+
.replace(path.sep === "\\" ? /\\/gu : /\//gu, "/"));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
await visit(rootDir);
|
|
28
|
+
return relativeFiles.sort((left, right) => left.localeCompare(right));
|
|
29
|
+
}
|
|
30
|
+
async function assertDryRunTargetDirectoryReady(projectDir, allowExistingDir) {
|
|
31
|
+
if (!fs.existsSync(projectDir) || allowExistingDir) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const entries = await fsp.readdir(projectDir);
|
|
35
|
+
if (entries.length > 0) {
|
|
36
|
+
throw new Error(formatNonEmptyTargetDirectoryError(projectDir));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async function buildScaffoldDryRunPlan({ allowExistingDir, answers, cwd, dataStorageMode, externalLayerId, externalLayerSource, externalLayerSourceLabel, installDependencies, noInstall, onProgress, packageManager, persistencePolicy, projectDir, templateId, variant, withMigrationUi, withTestPreset, withWpEnv, }) {
|
|
40
|
+
await assertDryRunTargetDirectoryReady(projectDir, allowExistingDir);
|
|
41
|
+
const tempRoot = await fsp.mkdtemp(path.join(os.tmpdir(), "wp-typia-scaffold-plan-"));
|
|
42
|
+
const previewProjectDir = path.join(tempRoot, "preview-project");
|
|
43
|
+
try {
|
|
44
|
+
const result = await scaffoldProject({
|
|
45
|
+
allowExistingDir: false,
|
|
46
|
+
answers,
|
|
47
|
+
cwd,
|
|
48
|
+
dataStorageMode,
|
|
49
|
+
externalLayerId,
|
|
50
|
+
externalLayerSource,
|
|
51
|
+
externalLayerSourceLabel,
|
|
52
|
+
installDependencies,
|
|
53
|
+
noInstall: true,
|
|
54
|
+
onProgress,
|
|
55
|
+
packageManager,
|
|
56
|
+
persistencePolicy,
|
|
57
|
+
projectDir: previewProjectDir,
|
|
58
|
+
templateId,
|
|
59
|
+
variant,
|
|
60
|
+
withMigrationUi,
|
|
61
|
+
withTestPreset,
|
|
62
|
+
withWpEnv,
|
|
63
|
+
});
|
|
64
|
+
const files = await listRelativeProjectFiles(previewProjectDir);
|
|
65
|
+
return {
|
|
66
|
+
plan: {
|
|
67
|
+
dependencyInstall: noInstall ? "skipped-by-flag" : "would-install",
|
|
68
|
+
files,
|
|
69
|
+
},
|
|
70
|
+
result,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
await fsp.rm(tempRoot, { force: true, recursive: true });
|
|
75
|
+
}
|
|
76
|
+
}
|
|
9
77
|
function validateCreateProjectInput(projectInput) {
|
|
10
78
|
const normalizedProjectInput = projectInput.trim();
|
|
11
79
|
if (normalizedProjectInput.length === 0) {
|
|
@@ -135,7 +203,7 @@ export function getOptionalOnboarding({ availableScripts, packageManager, templa
|
|
|
135
203
|
* project.
|
|
136
204
|
* @returns The scaffold result together with next-step guidance.
|
|
137
205
|
*/
|
|
138
|
-
export async function runScaffoldFlow({ projectInput, cwd = process.cwd(), templateId, dataStorageMode, externalLayerId, externalLayerSource, persistencePolicy, packageManager, namespace, textDomain, phpPrefix, yes = false, noInstall = false, isInteractive = false, allowExistingDir = false, selectTemplate, selectDataStorage, selectExternalLayerId, selectPersistencePolicy, selectPackageManager, promptText, installDependencies = undefined, variant, selectWithTestPreset, selectWithWpEnv, selectWithMigrationUi, withMigrationUi, withTestPreset, withWpEnv, }) {
|
|
206
|
+
export async function runScaffoldFlow({ projectInput, cwd = process.cwd(), templateId, dataStorageMode, dryRun = false, externalLayerId, externalLayerSource, persistencePolicy, packageManager, namespace, textDomain, phpPrefix, queryPostType, yes = false, noInstall = false, onProgress, isInteractive = false, allowExistingDir = false, selectTemplate, selectDataStorage, selectExternalLayerId, selectPersistencePolicy, selectPackageManager, promptText, installDependencies = undefined, variant, selectWithTestPreset, selectWithWpEnv, selectWithMigrationUi, withMigrationUi, withTestPreset, withWpEnv, }) {
|
|
139
207
|
const normalizedExternalLayerId = typeof externalLayerId === "string" && externalLayerId.trim().length > 0
|
|
140
208
|
? externalLayerId.trim()
|
|
141
209
|
: undefined;
|
|
@@ -228,52 +296,82 @@ export async function runScaffoldFlow({ projectInput, cwd = process.cwd(), templ
|
|
|
228
296
|
persistencePolicy: resolvedPersistencePolicy,
|
|
229
297
|
phpPrefix,
|
|
230
298
|
projectName,
|
|
299
|
+
queryPostType,
|
|
231
300
|
templateId: resolvedTemplateId,
|
|
232
301
|
textDomain,
|
|
233
302
|
yes,
|
|
234
303
|
promptText,
|
|
235
304
|
});
|
|
236
|
-
const
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
305
|
+
const resolvedResult = dryRun
|
|
306
|
+
? await buildScaffoldDryRunPlan({
|
|
307
|
+
allowExistingDir,
|
|
308
|
+
answers,
|
|
309
|
+
cwd,
|
|
310
|
+
dataStorageMode: resolvedDataStorage,
|
|
311
|
+
externalLayerId: resolvedExternalLayerSelection.externalLayerId,
|
|
312
|
+
externalLayerSource: resolvedExternalLayerSelection.externalLayerSource,
|
|
313
|
+
externalLayerSourceLabel: normalizedExternalLayerSource,
|
|
314
|
+
installDependencies,
|
|
315
|
+
noInstall,
|
|
316
|
+
onProgress,
|
|
317
|
+
packageManager: resolvedPackageManager,
|
|
318
|
+
persistencePolicy: resolvedPersistencePolicy,
|
|
319
|
+
projectDir,
|
|
320
|
+
templateId: resolvedTemplateId,
|
|
321
|
+
variant,
|
|
322
|
+
withMigrationUi: resolvedWithMigrationUi,
|
|
323
|
+
withTestPreset: resolvedWithTestPreset,
|
|
324
|
+
withWpEnv: resolvedWithWpEnv,
|
|
325
|
+
})
|
|
326
|
+
: {
|
|
327
|
+
plan: undefined,
|
|
328
|
+
result: await scaffoldProject({
|
|
329
|
+
answers,
|
|
330
|
+
allowExistingDir,
|
|
331
|
+
cwd,
|
|
332
|
+
dataStorageMode: resolvedDataStorage,
|
|
333
|
+
externalLayerId: resolvedExternalLayerSelection.externalLayerId,
|
|
334
|
+
externalLayerSource: resolvedExternalLayerSelection.externalLayerSource,
|
|
335
|
+
externalLayerSourceLabel: normalizedExternalLayerSource,
|
|
336
|
+
installDependencies,
|
|
337
|
+
noInstall,
|
|
338
|
+
onProgress,
|
|
339
|
+
packageManager: resolvedPackageManager,
|
|
340
|
+
persistencePolicy: resolvedPersistencePolicy,
|
|
341
|
+
projectDir,
|
|
342
|
+
templateId: resolvedTemplateId,
|
|
343
|
+
variant,
|
|
344
|
+
withMigrationUi: resolvedWithMigrationUi,
|
|
345
|
+
withTestPreset: resolvedWithTestPreset,
|
|
346
|
+
withWpEnv: resolvedWithWpEnv,
|
|
347
|
+
}),
|
|
348
|
+
};
|
|
255
349
|
let availableScripts;
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
.
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
350
|
+
if (!dryRun) {
|
|
351
|
+
try {
|
|
352
|
+
const parsedPackageJson = JSON.parse(fs.readFileSync(path.join(projectDir, "package.json"), "utf8"));
|
|
353
|
+
const scripts = parsedPackageJson.scripts &&
|
|
354
|
+
typeof parsedPackageJson.scripts === "object" &&
|
|
355
|
+
!Array.isArray(parsedPackageJson.scripts)
|
|
356
|
+
? parsedPackageJson.scripts
|
|
357
|
+
: {};
|
|
358
|
+
availableScripts = Object.entries(scripts)
|
|
359
|
+
.filter(([, value]) => typeof value === "string")
|
|
360
|
+
.map(([scriptName]) => scriptName);
|
|
361
|
+
}
|
|
362
|
+
catch {
|
|
363
|
+
availableScripts = undefined;
|
|
364
|
+
}
|
|
269
365
|
}
|
|
270
366
|
return {
|
|
367
|
+
dryRun,
|
|
271
368
|
optionalOnboarding: getOptionalOnboarding({
|
|
272
369
|
availableScripts,
|
|
273
370
|
packageManager: resolvedPackageManager,
|
|
274
371
|
templateId: resolvedTemplateId,
|
|
275
|
-
compoundPersistenceEnabled: result.variables.compoundPersistenceEnabled === "true",
|
|
372
|
+
compoundPersistenceEnabled: resolvedResult.result.variables.compoundPersistenceEnabled === "true",
|
|
276
373
|
}),
|
|
374
|
+
plan: resolvedResult.plan,
|
|
277
375
|
projectDir,
|
|
278
376
|
projectInput,
|
|
279
377
|
packageManager: resolvedPackageManager,
|
|
@@ -285,8 +383,11 @@ export async function runScaffoldFlow({ projectInput, cwd = process.cwd(), templ
|
|
|
285
383
|
templateId: resolvedTemplateId,
|
|
286
384
|
}),
|
|
287
385
|
result: {
|
|
288
|
-
...result,
|
|
289
|
-
warnings: [
|
|
386
|
+
...resolvedResult.result,
|
|
387
|
+
warnings: [
|
|
388
|
+
...resolvedResult.result.warnings,
|
|
389
|
+
...collectProjectDirectoryWarnings(projectDir),
|
|
390
|
+
],
|
|
290
391
|
},
|
|
291
392
|
};
|
|
292
393
|
}
|
|
@@ -8,18 +8,18 @@ import type { TemplateDefinition } from "./template-registry.js";
|
|
|
8
8
|
*/
|
|
9
9
|
export declare function formatTemplateSummary(template: TemplateDefinition): string;
|
|
10
10
|
/**
|
|
11
|
-
* Format the feature hint
|
|
11
|
+
* Format the feature and capability hint lines shown under a template summary.
|
|
12
12
|
*
|
|
13
13
|
* @param template Template metadata including the `features` list.
|
|
14
|
-
* @returns Indented feature text for CLI list output.
|
|
14
|
+
* @returns Indented feature and capability text for CLI list output.
|
|
15
15
|
*/
|
|
16
16
|
export declare function formatTemplateFeatures(template: TemplateDefinition): string;
|
|
17
17
|
/**
|
|
18
18
|
* Format the detailed template description for `templates inspect`.
|
|
19
19
|
*
|
|
20
20
|
* This expands special layer combinations for the `persistence` and `compound`
|
|
21
|
-
* templates and returns a multi-line block
|
|
22
|
-
*
|
|
21
|
+
* templates and returns a multi-line block centered on human-facing identity,
|
|
22
|
+
* capabilities, and logical layer composition.
|
|
23
23
|
*
|
|
24
24
|
* @param template Template metadata including `id`, `defaultCategory`,
|
|
25
25
|
* `templateDir`, and `features`.
|