@wp-typia/project-tools 0.18.0 → 0.19.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/alternate-render-targets.d.ts +5 -0
- package/dist/runtime/alternate-render-targets.js +29 -0
- package/dist/runtime/block-generator-service-core.d.ts +1 -1
- package/dist/runtime/block-generator-service-core.js +11 -7
- package/dist/runtime/block-generator-service-spec.d.ts +8 -1
- package/dist/runtime/block-generator-service-spec.js +43 -1
- package/dist/runtime/built-in-block-code-templates/compound-child.d.ts +1 -1
- package/dist/runtime/built-in-block-code-templates/compound-child.js +14 -9
- package/dist/runtime/built-in-block-code-templates/compound-parent.d.ts +2 -2
- package/dist/runtime/built-in-block-code-templates/compound-parent.js +100 -43
- package/dist/runtime/built-in-block-code-templates/compound-persistence.d.ts +1 -1
- package/dist/runtime/built-in-block-code-templates/compound-persistence.js +11 -8
- package/dist/runtime/built-in-block-non-ts-artifacts.js +505 -2
- package/dist/runtime/cli-add-block.d.ts +4 -1
- package/dist/runtime/cli-add-block.js +55 -26
- package/dist/runtime/cli-add-shared.d.ts +3 -1
- package/dist/runtime/cli-add-shared.js +12 -12
- package/dist/runtime/cli-core.d.ts +2 -0
- package/dist/runtime/cli-core.js +1 -0
- package/dist/runtime/cli-help.js +4 -3
- package/dist/runtime/cli-scaffold.d.ts +3 -1
- package/dist/runtime/cli-scaffold.js +88 -12
- package/dist/runtime/cli-templates.js +26 -1
- package/dist/runtime/cli-validation.d.ts +66 -0
- package/dist/runtime/cli-validation.js +92 -0
- package/dist/runtime/compound-inner-blocks.d.ts +78 -0
- package/dist/runtime/compound-inner-blocks.js +88 -0
- package/dist/runtime/index.d.ts +2 -0
- package/dist/runtime/index.js +1 -0
- package/dist/runtime/migration-command-surface.js +2 -0
- package/dist/runtime/package-versions.d.ts +1 -0
- package/dist/runtime/package-versions.js +12 -0
- package/dist/runtime/scaffold-answer-resolution.js +10 -6
- package/dist/runtime/scaffold-documents.js +22 -2
- package/dist/runtime/scaffold-identifiers.d.ts +17 -0
- package/dist/runtime/scaffold-identifiers.js +22 -0
- package/dist/runtime/scaffold-onboarding.js +21 -13
- package/dist/runtime/scaffold-template-variables.js +22 -0
- package/dist/runtime/scaffold.d.ts +16 -1
- package/dist/runtime/scaffold.js +7 -4
- package/dist/runtime/template-source.js +5 -3
- package/dist/runtime/workspace-project.js +1 -1
- package/package.json +7 -2
- package/templates/_shared/compound/core/scripts/add-compound-child.ts.mustache +318 -18
|
@@ -10,13 +10,17 @@ import { getDefaultAnswers, scaffoldProject } from "./scaffold.js";
|
|
|
10
10
|
import { copyInterpolatedDirectory, listInterpolatedDirectoryOutputs, } from "./template-render.js";
|
|
11
11
|
import { appendWorkspaceInventoryEntries, } from "./workspace-inventory.js";
|
|
12
12
|
import { resolveWorkspaceProject, } from "./workspace-project.js";
|
|
13
|
-
import { ADD_BLOCK_TEMPLATE_IDS, buildWorkspacePhpPrefix, isAddBlockTemplateId,
|
|
13
|
+
import { ADD_BLOCK_TEMPLATE_IDS, buildWorkspacePhpPrefix, isAddBlockTemplateId, patchFile, readOptionalFile, rollbackWorkspaceMutation, snapshotWorkspaceFiles, } from "./cli-add-shared.js";
|
|
14
|
+
import { resolveNonEmptyNormalizedBlockSlug, } from "./scaffold-identifiers.js";
|
|
14
15
|
import { buildConfigEntries, buildMigrationBlocks, buildServerTemplateRoot, } from "./cli-add-block-config.js";
|
|
15
16
|
import { COMPOUND_SHARED_SUPPORT_FILES, collectLegacyCompoundValidatorPaths, ensureBlockConfigCanAddRestManifests, ensureCompoundWorkspaceSupportFiles, } from "./cli-add-block-legacy-validator.js";
|
|
16
17
|
import { parseTemplateLocator, resolveTemplateSeed, } from "./template-source.js";
|
|
17
18
|
import { resolveExternalTemplateLayers, } from "./template-layers.js";
|
|
18
19
|
import { formatInstallCommand, } from "./package-managers.js";
|
|
20
|
+
import { parseCompoundInnerBlocksPreset } from "./compound-inner-blocks.js";
|
|
19
21
|
import { resolveOptionalInteractiveExternalLayerId, } from "./external-layer-selection.js";
|
|
22
|
+
import { parseAlternateRenderTargets } from "./alternate-render-targets.js";
|
|
23
|
+
import { assertExternalLayerCompositionOptions, normalizeOptionalCliString, resolveLocalCliPathOption, } from "./cli-validation.js";
|
|
20
24
|
const COLLECTION_IMPORT_LINE = "import '../../collection';";
|
|
21
25
|
// This is a lightweight preflight heuristic for the common install layouts:
|
|
22
26
|
// node_modules for npm/pnpm/bun/yarn-classic and Yarn PnP marker files.
|
|
@@ -61,21 +65,6 @@ async function renderWorkspacePersistenceServerModule(projectDir, variables) {
|
|
|
61
65
|
const templateDir = buildServerTemplateRoot(variables.persistencePolicy);
|
|
62
66
|
await copyInterpolatedDirectory(templateDir, targetDir, variables);
|
|
63
67
|
}
|
|
64
|
-
function normalizeExternalLayerOption(value) {
|
|
65
|
-
if (typeof value !== "string") {
|
|
66
|
-
return undefined;
|
|
67
|
-
}
|
|
68
|
-
const trimmed = value.trim();
|
|
69
|
-
return trimmed.length > 0 ? trimmed : undefined;
|
|
70
|
-
}
|
|
71
|
-
function resolveExternalLayerSourceFromCaller(source, callerCwd) {
|
|
72
|
-
if (typeof source !== "string" ||
|
|
73
|
-
source.length === 0 ||
|
|
74
|
-
!(path.isAbsolute(source) || source.startsWith("./") || source.startsWith("../"))) {
|
|
75
|
-
return source;
|
|
76
|
-
}
|
|
77
|
-
return path.resolve(callerCwd, source);
|
|
78
|
-
}
|
|
79
68
|
function hasInstalledWorkspaceDependencies(projectDir) {
|
|
80
69
|
return WORKSPACE_INSTALL_MARKERS.some((marker) => fs.existsSync(path.join(projectDir, marker)));
|
|
81
70
|
}
|
|
@@ -207,12 +196,14 @@ async function syncWorkspaceAddedBlockArtifacts(projectDir, templateId, variable
|
|
|
207
196
|
}
|
|
208
197
|
}
|
|
209
198
|
function assertPersistenceFlagsAllowed(templateId, options) {
|
|
210
|
-
const hasPersistenceFlags = typeof options.
|
|
199
|
+
const hasPersistenceFlags = typeof options.alternateRenderTargets === "string" ||
|
|
200
|
+
typeof options.dataStorageMode === "string" ||
|
|
211
201
|
typeof options.persistencePolicy === "string";
|
|
212
202
|
if (!hasPersistenceFlags) {
|
|
213
203
|
return;
|
|
214
204
|
}
|
|
215
205
|
if (templateId === "persistence" || templateId === "compound") {
|
|
206
|
+
parseAlternateRenderTargets(options.alternateRenderTargets);
|
|
216
207
|
if (typeof options.dataStorageMode === "string" &&
|
|
217
208
|
options.dataStorageMode !== "custom-table" &&
|
|
218
209
|
options.dataStorageMode !== "post-meta") {
|
|
@@ -223,9 +214,24 @@ function assertPersistenceFlagsAllowed(templateId, options) {
|
|
|
223
214
|
options.persistencePolicy !== "public") {
|
|
224
215
|
throw new Error(`Unsupported persistence policy "${options.persistencePolicy}". Expected one of: authenticated, public.`);
|
|
225
216
|
}
|
|
217
|
+
if (templateId === "compound" &&
|
|
218
|
+
typeof options.alternateRenderTargets === "string" &&
|
|
219
|
+
!options.dataStorageMode &&
|
|
220
|
+
!options.persistencePolicy) {
|
|
221
|
+
throw new Error("`--alternate-render-targets` on `wp-typia add block --template compound` requires the persistence-enabled server render path. Add `--data-storage <post-meta|custom-table>` or `--persistence-policy <authenticated|public>` first.");
|
|
222
|
+
}
|
|
226
223
|
return;
|
|
227
224
|
}
|
|
228
|
-
throw new Error(`--data-storage
|
|
225
|
+
throw new Error(`--data-storage, --persistence-policy, and --alternate-render-targets are supported only for \`wp-typia add block --template persistence\` or persistence-enabled \`--template compound\`.`);
|
|
226
|
+
}
|
|
227
|
+
function assertCompoundInnerBlocksPresetAllowed(templateId, innerBlocksPreset) {
|
|
228
|
+
if (!innerBlocksPreset) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
if (templateId !== "compound") {
|
|
232
|
+
throw new Error("`--inner-blocks-preset` is supported only for `wp-typia add block --template compound`.");
|
|
233
|
+
}
|
|
234
|
+
parseCompoundInnerBlocksPreset(innerBlocksPreset);
|
|
229
235
|
}
|
|
230
236
|
/**
|
|
231
237
|
* Seeds an empty official workspace migration project before any blocks are added.
|
|
@@ -255,6 +261,9 @@ export async function seedWorkspaceMigrationProject(projectDir, currentMigration
|
|
|
255
261
|
* workspace. Defaults to `process.cwd()`.
|
|
256
262
|
* @param options.dataStorageMode Optional storage mode for persistence-capable
|
|
257
263
|
* templates.
|
|
264
|
+
* @param options.innerBlocksPreset Optional compound-only InnerBlocks preset
|
|
265
|
+
* (`freeform`, `ordered`, `horizontal`, or `locked-structure`) that controls
|
|
266
|
+
* the generated authoring defaults for nested compound containers.
|
|
258
267
|
* @param options.persistencePolicy Optional persistence policy for
|
|
259
268
|
* persistence-capable templates.
|
|
260
269
|
* @param options.templateId Built-in block family to scaffold. Defaults to
|
|
@@ -267,16 +276,33 @@ export async function seedWorkspaceMigrationProject(projectDir, currentMigration
|
|
|
267
276
|
* workspace dependencies have not been installed yet, or target block paths
|
|
268
277
|
* already exist.
|
|
269
278
|
*/
|
|
270
|
-
export async function runAddBlockCommand({ blockName, cwd = process.cwd(), dataStorageMode, externalLayerId, externalLayerSource, persistencePolicy, selectExternalLayerId, templateId = "basic", }) {
|
|
279
|
+
export async function runAddBlockCommand({ alternateRenderTargets, blockName, cwd = process.cwd(), dataStorageMode, externalLayerId, externalLayerSource, innerBlocksPreset, persistencePolicy, selectExternalLayerId, templateId = "basic", }) {
|
|
280
|
+
if (templateId === "query-loop") {
|
|
281
|
+
throw new Error("`wp-typia add block --template query-loop` is not supported. Query Loop is a create-time `core/query` variation scaffold, so use `wp-typia create <project-dir> --template query-loop` instead.");
|
|
282
|
+
}
|
|
271
283
|
if (!isAddBlockTemplateId(templateId)) {
|
|
272
284
|
throw new Error(`Unknown add-block template "${templateId}". Expected one of: ${ADD_BLOCK_TEMPLATE_IDS.join(", ")}`);
|
|
273
285
|
}
|
|
274
286
|
const resolvedTemplateId = templateId;
|
|
275
|
-
assertPersistenceFlagsAllowed(resolvedTemplateId, {
|
|
287
|
+
assertPersistenceFlagsAllowed(resolvedTemplateId, {
|
|
288
|
+
alternateRenderTargets,
|
|
289
|
+
dataStorageMode,
|
|
290
|
+
persistencePolicy,
|
|
291
|
+
});
|
|
292
|
+
assertCompoundInnerBlocksPresetAllowed(resolvedTemplateId, innerBlocksPreset);
|
|
293
|
+
const resolvedInnerBlocksPreset = parseCompoundInnerBlocksPreset(innerBlocksPreset);
|
|
276
294
|
const workspace = resolveWorkspaceProject(cwd);
|
|
277
295
|
assertWorkspaceDependenciesInstalled(workspace);
|
|
278
|
-
const normalizedExternalLayerId =
|
|
279
|
-
const normalizedExternalLayerSource =
|
|
296
|
+
const normalizedExternalLayerId = normalizeOptionalCliString(externalLayerId);
|
|
297
|
+
const normalizedExternalLayerSource = resolveLocalCliPathOption({
|
|
298
|
+
cwd,
|
|
299
|
+
label: "--external-layer-source",
|
|
300
|
+
value: externalLayerSource,
|
|
301
|
+
});
|
|
302
|
+
assertExternalLayerCompositionOptions({
|
|
303
|
+
externalLayerId: normalizedExternalLayerId,
|
|
304
|
+
externalLayerSource: normalizedExternalLayerSource,
|
|
305
|
+
});
|
|
280
306
|
const resolvedExternalLayerSelection = await resolveOptionalInteractiveExternalLayerId({
|
|
281
307
|
callerCwd: cwd,
|
|
282
308
|
externalLayerId: normalizedExternalLayerId,
|
|
@@ -285,10 +311,11 @@ export async function runAddBlockCommand({ blockName, cwd = process.cwd(), dataS
|
|
|
285
311
|
});
|
|
286
312
|
let tempRoot = "";
|
|
287
313
|
try {
|
|
288
|
-
const normalizedSlug =
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
314
|
+
const normalizedSlug = resolveNonEmptyNormalizedBlockSlug({
|
|
315
|
+
input: blockName,
|
|
316
|
+
label: "Block name",
|
|
317
|
+
usage: "wp-typia add block <name> --template <family>",
|
|
318
|
+
});
|
|
292
319
|
const defaults = getDefaultAnswers(normalizedSlug, resolvedTemplateId);
|
|
293
320
|
tempRoot = await fsp.mkdtemp(path.join(os.tmpdir(), "wp-typia-add-block-"));
|
|
294
321
|
const tempProjectDir = path.join(tempRoot, normalizedSlug);
|
|
@@ -305,9 +332,11 @@ export async function runAddBlockCommand({ blockName, cwd = process.cwd(), dataS
|
|
|
305
332
|
: [];
|
|
306
333
|
const result = await (async () => {
|
|
307
334
|
const scaffoldResult = await scaffoldProject({
|
|
335
|
+
alternateRenderTargets,
|
|
308
336
|
answers: {
|
|
309
337
|
...defaults,
|
|
310
338
|
author: workspace.author,
|
|
339
|
+
compoundInnerBlocksPreset: resolvedInnerBlocksPreset,
|
|
311
340
|
namespace: workspace.workspace.namespace,
|
|
312
341
|
phpPrefix: blockPhpPrefix,
|
|
313
342
|
slug: normalizedSlug,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type HookedBlockPositionId } from "./hooked-blocks.js";
|
|
2
2
|
import { type WorkspaceInventory } from "./workspace-inventory.js";
|
|
3
3
|
import { type WorkspaceProject } from "./workspace-project.js";
|
|
4
|
+
export { normalizeBlockSlug, } from "./scaffold-identifiers.js";
|
|
4
5
|
/**
|
|
5
6
|
* Supported top-level `wp-typia add` kinds exposed by the canonical CLI.
|
|
6
7
|
*/
|
|
@@ -63,11 +64,13 @@ export interface RunAddEditorPluginCommandOptions {
|
|
|
63
64
|
slot?: string;
|
|
64
65
|
}
|
|
65
66
|
export interface RunAddBlockCommandOptions {
|
|
67
|
+
alternateRenderTargets?: string;
|
|
66
68
|
blockName: string;
|
|
67
69
|
cwd?: string;
|
|
68
70
|
dataStorageMode?: string;
|
|
69
71
|
externalLayerId?: string;
|
|
70
72
|
externalLayerSource?: string;
|
|
73
|
+
innerBlocksPreset?: string;
|
|
71
74
|
persistencePolicy?: string;
|
|
72
75
|
selectExternalLayerId?: (options: Array<{
|
|
73
76
|
description?: string;
|
|
@@ -89,7 +92,6 @@ export interface WorkspaceMutationSnapshot {
|
|
|
89
92
|
/** Files or directories created by the mutation that should be removed on rollback. */
|
|
90
93
|
targetPaths: string[];
|
|
91
94
|
}
|
|
92
|
-
export declare function normalizeBlockSlug(input: string): string;
|
|
93
95
|
export declare function assertValidGeneratedSlug(label: string, slug: string, usage: string): string;
|
|
94
96
|
export declare function assertValidRestResourceNamespace(namespace: string): string;
|
|
95
97
|
export declare function resolveRestResourceNamespace(workspaceNamespace: string, namespace?: string): string;
|
|
@@ -3,8 +3,9 @@ import { promises as fsp } from "node:fs";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { parseScaffoldBlockMetadata } from "@wp-typia/block-runtime/blocks";
|
|
5
5
|
import { HOOKED_BLOCK_ANCHOR_PATTERN, HOOKED_BLOCK_POSITION_IDS, } from "./hooked-blocks.js";
|
|
6
|
-
import {
|
|
6
|
+
import { toSnakeCase, } from "./string-case.js";
|
|
7
7
|
import { WORKSPACE_TEMPLATE_PACKAGE, } from "./workspace-project.js";
|
|
8
|
+
export { normalizeBlockSlug, } from "./scaffold-identifiers.js";
|
|
8
9
|
/**
|
|
9
10
|
* Supported top-level `wp-typia add` kinds exposed by the canonical CLI.
|
|
10
11
|
*/
|
|
@@ -43,9 +44,6 @@ export const ADD_BLOCK_TEMPLATE_IDS = [
|
|
|
43
44
|
];
|
|
44
45
|
const WORKSPACE_GENERATED_SLUG_PATTERN = /^[a-z][a-z0-9-]*$/;
|
|
45
46
|
export const REST_RESOURCE_NAMESPACE_PATTERN = /^[a-z][a-z0-9-]*(?:\/[a-z0-9-]+)+$/u;
|
|
46
|
-
export function normalizeBlockSlug(input) {
|
|
47
|
-
return toKebabCase(input);
|
|
48
|
-
}
|
|
49
47
|
export function assertValidGeneratedSlug(label, slug, usage) {
|
|
50
48
|
if (!slug) {
|
|
51
49
|
throw new Error(`${label} is required. Use \`${usage}\`.`);
|
|
@@ -279,16 +277,18 @@ export function assertEditorPluginDoesNotExist(projectDir, editorPluginSlug, inv
|
|
|
279
277
|
*/
|
|
280
278
|
export function formatAddHelpText() {
|
|
281
279
|
return `Usage:
|
|
282
|
-
wp-typia add block <name> --template <${ADD_BLOCK_TEMPLATE_IDS.join("|")}> [--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>]
|
|
283
|
-
wp-typia add variation <name> --block <block-slug>
|
|
284
|
-
wp-typia add pattern <name>
|
|
285
|
-
wp-typia add binding-source <name>
|
|
286
|
-
wp-typia add rest-resource <name> [--namespace <vendor/v1>] [--methods <list,read,create,update,delete>]
|
|
287
|
-
wp-typia add hooked-block <block-slug> --anchor <anchor-block-name> --position <${HOOKED_BLOCK_POSITION_IDS.join("|")}>
|
|
288
|
-
wp-typia add editor-plugin <name> [--slot <${EDITOR_PLUGIN_SLOT_IDS.join("|")}>]
|
|
280
|
+
wp-typia add block <name> --template <${ADD_BLOCK_TEMPLATE_IDS.join("|")}> [--external-layer-source <./path|github:owner/repo/path[#ref]|npm-package>] [--external-layer-id <layer-id>] [--inner-blocks-preset <freeform|ordered|horizontal|locked-structure>] [--alternate-render-targets <email,mjml,plain-text>] [--data-storage <post-meta|custom-table>] [--persistence-policy <authenticated|public>] [--dry-run]
|
|
281
|
+
wp-typia add variation <name> --block <block-slug> [--dry-run]
|
|
282
|
+
wp-typia add pattern <name> [--dry-run]
|
|
283
|
+
wp-typia add binding-source <name> [--dry-run]
|
|
284
|
+
wp-typia add rest-resource <name> [--namespace <vendor/v1>] [--methods <list,read,create,update,delete>] [--dry-run]
|
|
285
|
+
wp-typia add hooked-block <block-slug> --anchor <anchor-block-name> --position <${HOOKED_BLOCK_POSITION_IDS.join("|")}> [--dry-run]
|
|
286
|
+
wp-typia add editor-plugin <name> [--slot <${EDITOR_PLUGIN_SLOT_IDS.join("|")}>] [--dry-run]
|
|
289
287
|
|
|
290
288
|
Notes:
|
|
291
|
-
\`wp-typia add\` runs only inside official ${WORKSPACE_TEMPLATE_PACKAGE} workspaces
|
|
289
|
+
\`wp-typia add\` runs only inside official ${WORKSPACE_TEMPLATE_PACKAGE} workspaces scaffolded via \`wp-typia create <project-dir> --template workspace\`.
|
|
290
|
+
Pass \`--dry-run\` to preview the workspace files that would change without writing them.
|
|
291
|
+
\`query-loop\` is a create-time scaffold family. Use \`wp-typia create <project-dir> --template query-loop\` instead of \`wp-typia add block\`.
|
|
292
292
|
\`add variation\` targets an existing block slug from \`scripts/block-config.ts\`.
|
|
293
293
|
\`add pattern\` scaffolds a namespaced PHP pattern shell under \`src/patterns/\`.
|
|
294
294
|
\`add binding-source\` scaffolds shared PHP and editor registration under \`src/bindings/\`.
|
|
@@ -27,6 +27,8 @@ export { getDoctorChecks, runDoctor, type DoctorCheck } from "./cli-doctor.js";
|
|
|
27
27
|
export { createCliCommandError, CliDiagnosticError, formatCliDiagnosticError, formatDoctorCheckLine, formatDoctorSummaryLine, getDoctorFailureDetailLines, getFailingDoctorChecks, isCliDiagnosticError, } from "./cli-diagnostics.js";
|
|
28
28
|
export type { CliDiagnosticMessage } from "./cli-diagnostics.js";
|
|
29
29
|
export { EDITOR_PLUGIN_SLOT_IDS, formatAddHelpText, getWorkspaceBlockSelectOptions, runAddBindingSourceCommand, runAddBlockCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddPatternCommand, runAddRestResourceCommand, runAddVariationCommand, seedWorkspaceMigrationProject, } from "./cli-add.js";
|
|
30
|
+
export { COMPOUND_INNER_BLOCKS_PRESET_IDS, getCompoundInnerBlocksPresetDefinition, } from "./compound-inner-blocks.js";
|
|
31
|
+
export type { CompoundInnerBlocksPresetId } from "./compound-inner-blocks.js";
|
|
30
32
|
export { HOOKED_BLOCK_POSITION_IDS } from "./hooked-blocks.js";
|
|
31
33
|
export type { EditorPluginSlotId } from "./cli-add.js";
|
|
32
34
|
export type { HookedBlockPositionId } from "./hooked-blocks.js";
|
package/dist/runtime/cli-core.js
CHANGED
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
export { getDoctorChecks, runDoctor } from "./cli-doctor.js";
|
|
27
27
|
export { createCliCommandError, CliDiagnosticError, formatCliDiagnosticError, formatDoctorCheckLine, formatDoctorSummaryLine, getDoctorFailureDetailLines, getFailingDoctorChecks, isCliDiagnosticError, } from "./cli-diagnostics.js";
|
|
28
28
|
export { EDITOR_PLUGIN_SLOT_IDS, formatAddHelpText, getWorkspaceBlockSelectOptions, runAddBindingSourceCommand, runAddBlockCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddPatternCommand, runAddRestResourceCommand, runAddVariationCommand, seedWorkspaceMigrationProject, } from "./cli-add.js";
|
|
29
|
+
export { COMPOUND_INNER_BLOCKS_PRESET_IDS, getCompoundInnerBlocksPresetDefinition, } from "./compound-inner-blocks.js";
|
|
29
30
|
export { HOOKED_BLOCK_POSITION_IDS } from "./hooked-blocks.js";
|
|
30
31
|
export { formatHelpText } from "./cli-help.js";
|
|
31
32
|
export { getNextSteps, getOptionalOnboarding, runScaffoldFlow, } from "./cli-scaffold.js";
|
package/dist/runtime/cli-help.js
CHANGED
|
@@ -14,10 +14,10 @@ export function formatHelpText() {
|
|
|
14
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
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
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>]
|
|
17
|
+
wp-typia create <project-dir> [--template persistence] [--external-layer-source <./path|github:owner/repo/path[#ref]|npm-package>] [--external-layer-id <layer-id>] [--alternate-render-targets <email,mjml,plain-text>] [--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>] [--inner-blocks-preset <freeform|ordered|horizontal|locked-structure>] [--alternate-render-targets <email,mjml,plain-text>] [--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>]
|
|
19
19
|
wp-typia <project-dir> [create flags...]
|
|
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
|
+
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>] [--inner-blocks-preset <freeform|ordered|horizontal|locked-structure>] [--alternate-render-targets <email,mjml,plain-text>] [--data-storage <post-meta|custom-table>] [--persistence-policy <authenticated|public>]
|
|
21
21
|
wp-typia add variation <name> --block <block-slug>
|
|
22
22
|
wp-typia add pattern <name>
|
|
23
23
|
wp-typia add binding-source <name>
|
|
@@ -38,6 +38,7 @@ Notes:
|
|
|
38
38
|
\`wp-typia create\` is the canonical scaffold command.
|
|
39
39
|
\`wp-typia <project-dir>\` remains a backward-compatible alias to \`create\` when \`<project-dir>\` is the only positional argument.
|
|
40
40
|
Use \`--template workspace\` as shorthand for \`@wp-typia/create-workspace-template\`, the official empty workspace scaffold behind \`wp-typia add ...\`.
|
|
41
|
+
\`query-loop\` is create-only. Use \`wp-typia create <project-dir> --template query-loop\`; \`wp-typia add block\` accepts only basic, interactivity, persistence, and compound families.
|
|
41
42
|
\`add variation\` uses an existing workspace block from \`scripts/block-config.ts\`.
|
|
42
43
|
\`add pattern\` scaffolds a namespaced PHP pattern shell under \`src/patterns/\`.
|
|
43
44
|
\`add binding-source\` scaffolds shared PHP and editor registration under \`src/bindings/\`.
|
|
@@ -26,12 +26,14 @@ export interface ScaffoldDryRunPlan {
|
|
|
26
26
|
}
|
|
27
27
|
interface RunScaffoldFlowOptions {
|
|
28
28
|
allowExistingDir?: boolean;
|
|
29
|
+
alternateRenderTargets?: string;
|
|
29
30
|
cwd?: string;
|
|
30
31
|
dataStorageMode?: string;
|
|
31
32
|
dryRun?: boolean;
|
|
32
33
|
externalLayerId?: string;
|
|
33
34
|
externalLayerSource?: string;
|
|
34
35
|
installDependencies?: Parameters<typeof scaffoldProject>[0]["installDependencies"];
|
|
36
|
+
innerBlocksPreset?: string;
|
|
35
37
|
isInteractive?: boolean;
|
|
36
38
|
namespace?: string;
|
|
37
39
|
noInstall?: boolean;
|
|
@@ -80,7 +82,7 @@ export declare function getOptionalOnboarding({ availableScripts, packageManager
|
|
|
80
82
|
* project.
|
|
81
83
|
* @returns The scaffold result together with next-step guidance.
|
|
82
84
|
*/
|
|
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<{
|
|
85
|
+
export declare function runScaffoldFlow({ projectInput, cwd, templateId, alternateRenderTargets, dataStorageMode, dryRun, externalLayerId, externalLayerSource, innerBlocksPreset, 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
86
|
dryRun: boolean;
|
|
85
87
|
optionalOnboarding: OptionalOnboardingGuidance;
|
|
86
88
|
plan: ScaffoldDryRunPlan | undefined;
|
|
@@ -3,12 +3,15 @@ import { promises as fsp } from "node:fs";
|
|
|
3
3
|
import os from "node:os";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { collectScaffoldAnswers, DATA_STORAGE_MODES, PERSISTENCE_POLICIES, isDataStorageMode, isPersistencePolicy, resolvePackageManagerId, resolveTemplateId, scaffoldProject, } from "./scaffold.js";
|
|
6
|
+
import { parseAlternateRenderTargets } from "./alternate-render-targets.js";
|
|
7
|
+
import { parseCompoundInnerBlocksPreset } from "./compound-inner-blocks.js";
|
|
6
8
|
import { formatInstallCommand, formatRunScript, } from "./package-managers.js";
|
|
7
9
|
import { getPrimaryDevelopmentScript } from "./local-dev-presets.js";
|
|
8
10
|
import { getOptionalOnboardingNote, getOptionalOnboardingSteps, } from "./scaffold-onboarding.js";
|
|
9
11
|
import { formatNonEmptyTargetDirectoryError } from "./scaffold-bootstrap.js";
|
|
10
12
|
import { OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE, isBuiltInTemplateId, } from "./template-registry.js";
|
|
11
13
|
import { resolveOptionalInteractiveExternalLayerId, } from "./external-layer-selection.js";
|
|
14
|
+
import { assertBuiltInTemplateVariantAllowed, resolveLocalCliPathOption, normalizeOptionalCliString, } from "./cli-validation.js";
|
|
12
15
|
async function listRelativeProjectFiles(rootDir) {
|
|
13
16
|
const relativeFiles = [];
|
|
14
17
|
async function visit(currentDir) {
|
|
@@ -36,13 +39,14 @@ async function assertDryRunTargetDirectoryReady(projectDir, allowExistingDir) {
|
|
|
36
39
|
throw new Error(formatNonEmptyTargetDirectoryError(projectDir));
|
|
37
40
|
}
|
|
38
41
|
}
|
|
39
|
-
async function buildScaffoldDryRunPlan({ allowExistingDir, answers, cwd, dataStorageMode, externalLayerId, externalLayerSource, externalLayerSourceLabel, installDependencies, noInstall, onProgress, packageManager, persistencePolicy, projectDir, templateId, variant, withMigrationUi, withTestPreset, withWpEnv, }) {
|
|
42
|
+
async function buildScaffoldDryRunPlan({ allowExistingDir, alternateRenderTargets, answers, cwd, dataStorageMode, externalLayerId, externalLayerSource, externalLayerSourceLabel, installDependencies, noInstall, onProgress, packageManager, persistencePolicy, projectDir, templateId, variant, withMigrationUi, withTestPreset, withWpEnv, }) {
|
|
40
43
|
await assertDryRunTargetDirectoryReady(projectDir, allowExistingDir);
|
|
41
44
|
const tempRoot = await fsp.mkdtemp(path.join(os.tmpdir(), "wp-typia-scaffold-plan-"));
|
|
42
45
|
const previewProjectDir = path.join(tempRoot, "preview-project");
|
|
43
46
|
try {
|
|
44
47
|
const result = await scaffoldProject({
|
|
45
48
|
allowExistingDir: false,
|
|
49
|
+
alternateRenderTargets,
|
|
46
50
|
answers,
|
|
47
51
|
cwd,
|
|
48
52
|
dataStorageMode,
|
|
@@ -109,14 +113,74 @@ function templateUsesPersistenceSettings(templateId, options) {
|
|
|
109
113
|
function templateSupportsPersistenceFlags(templateId) {
|
|
110
114
|
return templateId === "persistence" || templateId === "compound";
|
|
111
115
|
}
|
|
116
|
+
function templateSupportsCompoundInnerBlocksPreset(templateId) {
|
|
117
|
+
return templateId === "compound";
|
|
118
|
+
}
|
|
119
|
+
function createTemplateLabel(templateId) {
|
|
120
|
+
return templateId === OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE
|
|
121
|
+
? "`--template workspace`"
|
|
122
|
+
: `"${templateId}"`;
|
|
123
|
+
}
|
|
124
|
+
function collectTemplateCapabilityWarnings(options) {
|
|
125
|
+
const warnings = [];
|
|
126
|
+
const trimmedQueryPostType = options.queryPostType?.trim();
|
|
127
|
+
if (trimmedQueryPostType &&
|
|
128
|
+
options.templateId !== "query-loop" &&
|
|
129
|
+
(isBuiltInTemplateId(options.templateId) ||
|
|
130
|
+
options.templateId === OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE)) {
|
|
131
|
+
warnings.push(`\`--query-post-type\` only applies to \`wp-typia create --template query-loop\`, which scaffolds a create-time \`core/query\` variation instead of a standalone block. ${createTemplateLabel(options.templateId)} will ignore "${trimmedQueryPostType}".`);
|
|
132
|
+
}
|
|
133
|
+
if (options.withMigrationUi === true &&
|
|
134
|
+
!isBuiltInTemplateId(options.templateId) &&
|
|
135
|
+
options.templateId !== OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE) {
|
|
136
|
+
warnings.push(`\`--with-migration-ui\` was ignored for ${createTemplateLabel(options.templateId)}. Migration UI currently scaffolds built-in templates and the official \`--template workspace\` flow; external templates still need to opt into that surface explicitly.`);
|
|
137
|
+
}
|
|
138
|
+
return warnings;
|
|
139
|
+
}
|
|
140
|
+
function templateSupportsAlternateRenderTargets(options) {
|
|
141
|
+
if (!options.alternateRenderTargets) {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
if (options.templateId === "persistence") {
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
if (options.templateId !== "compound") {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
return templateUsesPersistenceSettings(options.templateId, {
|
|
151
|
+
dataStorageMode: options.dataStorageMode,
|
|
152
|
+
persistencePolicy: options.persistencePolicy,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
112
155
|
function validateCreateFlagContract(options) {
|
|
113
|
-
const { dataStorageMode, persistencePolicy, templateId, variant } = options;
|
|
156
|
+
const { alternateRenderTargets, dataStorageMode, innerBlocksPreset, persistencePolicy, templateId, variant, } = options;
|
|
114
157
|
if ((dataStorageMode || persistencePolicy) &&
|
|
115
158
|
!templateSupportsPersistenceFlags(templateId)) {
|
|
116
159
|
throw new Error("`--data-storage` and `--persistence-policy` are supported only for `wp-typia create --template persistence` or `--template compound`.");
|
|
117
160
|
}
|
|
118
|
-
if (
|
|
119
|
-
|
|
161
|
+
if (alternateRenderTargets &&
|
|
162
|
+
!templateSupportsAlternateRenderTargets({
|
|
163
|
+
alternateRenderTargets,
|
|
164
|
+
dataStorageMode,
|
|
165
|
+
persistencePolicy,
|
|
166
|
+
templateId,
|
|
167
|
+
})) {
|
|
168
|
+
if (templateId === "compound") {
|
|
169
|
+
throw new Error("`--alternate-render-targets` on `wp-typia create --template compound` requires the persistence-enabled server render path. Add `--data-storage <post-meta|custom-table>` or `--persistence-policy <authenticated|public>` first.");
|
|
170
|
+
}
|
|
171
|
+
throw new Error("`--alternate-render-targets` is supported only for `wp-typia create --template persistence` or persistence-enabled `--template compound` scaffolds.");
|
|
172
|
+
}
|
|
173
|
+
parseAlternateRenderTargets(alternateRenderTargets);
|
|
174
|
+
if (innerBlocksPreset &&
|
|
175
|
+
!templateSupportsCompoundInnerBlocksPreset(templateId)) {
|
|
176
|
+
throw new Error("`--inner-blocks-preset` is supported only for `wp-typia create --template compound`.");
|
|
177
|
+
}
|
|
178
|
+
parseCompoundInnerBlocksPreset(innerBlocksPreset);
|
|
179
|
+
if (isBuiltInTemplateId(templateId)) {
|
|
180
|
+
assertBuiltInTemplateVariantAllowed({
|
|
181
|
+
templateId,
|
|
182
|
+
variant,
|
|
183
|
+
});
|
|
120
184
|
}
|
|
121
185
|
}
|
|
122
186
|
function parseSelectableValue(label, value, isValue, allowedValues) {
|
|
@@ -203,14 +267,13 @@ export function getOptionalOnboarding({ availableScripts, packageManager, templa
|
|
|
203
267
|
* project.
|
|
204
268
|
* @returns The scaffold result together with next-step guidance.
|
|
205
269
|
*/
|
|
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, }) {
|
|
207
|
-
const normalizedExternalLayerId =
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
externalLayerSource
|
|
212
|
-
|
|
213
|
-
: undefined;
|
|
270
|
+
export async function runScaffoldFlow({ projectInput, cwd = process.cwd(), templateId, alternateRenderTargets, dataStorageMode, dryRun = false, externalLayerId, externalLayerSource, innerBlocksPreset, 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, }) {
|
|
271
|
+
const normalizedExternalLayerId = normalizeOptionalCliString(externalLayerId);
|
|
272
|
+
const normalizedExternalLayerSource = resolveLocalCliPathOption({
|
|
273
|
+
cwd,
|
|
274
|
+
label: "--external-layer-source",
|
|
275
|
+
value: externalLayerSource,
|
|
276
|
+
});
|
|
214
277
|
validateCreateProjectInput(projectInput);
|
|
215
278
|
const resolvedTemplateId = await resolveTemplateId({
|
|
216
279
|
templateId,
|
|
@@ -219,11 +282,14 @@ export async function runScaffoldFlow({ projectInput, cwd = process.cwd(), templ
|
|
|
219
282
|
selectTemplate,
|
|
220
283
|
});
|
|
221
284
|
validateCreateFlagContract({
|
|
285
|
+
alternateRenderTargets,
|
|
222
286
|
dataStorageMode,
|
|
287
|
+
innerBlocksPreset,
|
|
223
288
|
persistencePolicy,
|
|
224
289
|
templateId: resolvedTemplateId,
|
|
225
290
|
variant,
|
|
226
291
|
});
|
|
292
|
+
const resolvedInnerBlocksPreset = parseCompoundInnerBlocksPreset(innerBlocksPreset);
|
|
227
293
|
const resolvedExternalLayerSelection = isBuiltInTemplateId(resolvedTemplateId) && isInteractive
|
|
228
294
|
? await resolveOptionalInteractiveExternalLayerId({
|
|
229
295
|
callerCwd: cwd,
|
|
@@ -302,9 +368,13 @@ export async function runScaffoldFlow({ projectInput, cwd = process.cwd(), templ
|
|
|
302
368
|
yes,
|
|
303
369
|
promptText,
|
|
304
370
|
});
|
|
371
|
+
if (resolvedTemplateId === "compound" && resolvedInnerBlocksPreset) {
|
|
372
|
+
answers.compoundInnerBlocksPreset = resolvedInnerBlocksPreset;
|
|
373
|
+
}
|
|
305
374
|
const resolvedResult = dryRun
|
|
306
375
|
? await buildScaffoldDryRunPlan({
|
|
307
376
|
allowExistingDir,
|
|
377
|
+
alternateRenderTargets,
|
|
308
378
|
answers,
|
|
309
379
|
cwd,
|
|
310
380
|
dataStorageMode: resolvedDataStorage,
|
|
@@ -326,6 +396,7 @@ export async function runScaffoldFlow({ projectInput, cwd = process.cwd(), templ
|
|
|
326
396
|
: {
|
|
327
397
|
plan: undefined,
|
|
328
398
|
result: await scaffoldProject({
|
|
399
|
+
alternateRenderTargets,
|
|
329
400
|
answers,
|
|
330
401
|
allowExistingDir,
|
|
331
402
|
cwd,
|
|
@@ -386,6 +457,11 @@ export async function runScaffoldFlow({ projectInput, cwd = process.cwd(), templ
|
|
|
386
457
|
...resolvedResult.result,
|
|
387
458
|
warnings: [
|
|
388
459
|
...resolvedResult.result.warnings,
|
|
460
|
+
...collectTemplateCapabilityWarnings({
|
|
461
|
+
queryPostType,
|
|
462
|
+
templateId: resolvedTemplateId,
|
|
463
|
+
withMigrationUi,
|
|
464
|
+
}),
|
|
389
465
|
...collectProjectDirectoryWarnings(projectDir),
|
|
390
466
|
],
|
|
391
467
|
},
|
|
@@ -21,6 +21,10 @@ export function formatTemplateFeatures(template) {
|
|
|
21
21
|
if (capabilityHints.length > 0) {
|
|
22
22
|
lines.push(` Supports: ${capabilityHints.join(" • ")}`);
|
|
23
23
|
}
|
|
24
|
+
const specialNotes = getTemplateSpecialNotes(template);
|
|
25
|
+
if (specialNotes.length > 0) {
|
|
26
|
+
lines.push(` Notes: ${specialNotes.join(" • ")}`);
|
|
27
|
+
}
|
|
24
28
|
if (template.id === OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE) {
|
|
25
29
|
lines.push(` Alias: ${WORKSPACE_TEMPLATE_ALIAS} (\`--template ${WORKSPACE_TEMPLATE_ALIAS}\`)`);
|
|
26
30
|
}
|
|
@@ -51,6 +55,13 @@ export function formatTemplateDetails(template) {
|
|
|
51
55
|
detailLines.push(` - ${capabilityHint}`);
|
|
52
56
|
}
|
|
53
57
|
}
|
|
58
|
+
const specialNotes = getTemplateSpecialNotes(template);
|
|
59
|
+
if (specialNotes.length > 0) {
|
|
60
|
+
detailLines.push("Notes:");
|
|
61
|
+
for (const specialNote of specialNotes) {
|
|
62
|
+
detailLines.push(` - ${specialNote}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
54
65
|
detailLines.push("Logical layers:");
|
|
55
66
|
for (const logicalLayer of getTemplateLogicalLayerSummaries(template)) {
|
|
56
67
|
detailLines.push(` - ${logicalLayer}`);
|
|
@@ -60,7 +71,12 @@ export function formatTemplateDetails(template) {
|
|
|
60
71
|
}
|
|
61
72
|
function getTemplateCapabilityHints(template) {
|
|
62
73
|
if (template.id === "persistence" || template.id === "compound") {
|
|
63
|
-
return [
|
|
74
|
+
return [
|
|
75
|
+
"--alternate-render-targets",
|
|
76
|
+
"--data-storage",
|
|
77
|
+
"--persistence-policy",
|
|
78
|
+
"external layers",
|
|
79
|
+
];
|
|
64
80
|
}
|
|
65
81
|
if (template.id === "query-loop") {
|
|
66
82
|
return ["--query-post-type", "external layers"];
|
|
@@ -70,6 +86,15 @@ function getTemplateCapabilityHints(template) {
|
|
|
70
86
|
}
|
|
71
87
|
return [];
|
|
72
88
|
}
|
|
89
|
+
function getTemplateSpecialNotes(template) {
|
|
90
|
+
if (template.id === "query-loop") {
|
|
91
|
+
return [
|
|
92
|
+
"Create-time variation scaffold only; use `wp-typia create <project-dir> --template query-loop` instead of `wp-typia add block`.",
|
|
93
|
+
"Owns a `core/query` variation, so it does not generate `src/types.ts`, `block.json`, or Typia manifests.",
|
|
94
|
+
];
|
|
95
|
+
}
|
|
96
|
+
return [];
|
|
97
|
+
}
|
|
73
98
|
function getTemplateIdentityLines(template) {
|
|
74
99
|
if (template.id === OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE) {
|
|
75
100
|
return [
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalize one optional CLI string flag by trimming whitespace and collapsing
|
|
3
|
+
* empty strings to `undefined`.
|
|
4
|
+
*
|
|
5
|
+
* @param value Raw CLI value before normalization.
|
|
6
|
+
* @returns The trimmed string when present, otherwise `undefined`.
|
|
7
|
+
*/
|
|
8
|
+
export declare function normalizeOptionalCliString(value?: string): string | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Resolve one CLI path flag relative to the caller when it is expressed as a
|
|
11
|
+
* local filesystem path.
|
|
12
|
+
*
|
|
13
|
+
* Non-local values such as npm package specs or `github:` locators pass
|
|
14
|
+
* through unchanged. Local relative and absolute paths are resolved against the
|
|
15
|
+
* provided `cwd` and must exist on disk.
|
|
16
|
+
*
|
|
17
|
+
* @param options Path resolution inputs for one CLI flag.
|
|
18
|
+
* @param options.cwd Caller working directory used for relative path
|
|
19
|
+
* resolution.
|
|
20
|
+
* @param options.label Human-readable option label used in thrown errors.
|
|
21
|
+
* @param options.value Raw CLI value before trimming and path resolution.
|
|
22
|
+
* @returns The normalized string, or `undefined` when the option was omitted.
|
|
23
|
+
* @throws When a local-looking path resolves to a missing filesystem entry.
|
|
24
|
+
*/
|
|
25
|
+
export declare function resolveLocalCliPathOption(options: {
|
|
26
|
+
cwd: string;
|
|
27
|
+
label: string;
|
|
28
|
+
value?: string;
|
|
29
|
+
}): string | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* Validate the built-in template composition rule for external layers.
|
|
32
|
+
*
|
|
33
|
+
* @param options External layer CLI options after normalization.
|
|
34
|
+
* @param options.externalLayerId Optional selected layer id.
|
|
35
|
+
* @param options.externalLayerSource Optional layer source locator or path.
|
|
36
|
+
* @throws When `externalLayerId` is provided without `externalLayerSource`.
|
|
37
|
+
*/
|
|
38
|
+
export declare function assertExternalLayerCompositionOptions(options: {
|
|
39
|
+
externalLayerId?: string;
|
|
40
|
+
externalLayerSource?: string;
|
|
41
|
+
}): void;
|
|
42
|
+
/**
|
|
43
|
+
* Build the shared error message used when a built-in template receives a
|
|
44
|
+
* `--variant` override.
|
|
45
|
+
*
|
|
46
|
+
* @param options Built-in template context.
|
|
47
|
+
* @param options.templateId Built-in template id that rejected the variant.
|
|
48
|
+
* @param options.variant User-supplied variant override.
|
|
49
|
+
* @returns The canonical user-facing error message.
|
|
50
|
+
*/
|
|
51
|
+
export declare function createBuiltInVariantErrorMessage(options: {
|
|
52
|
+
templateId: string;
|
|
53
|
+
variant: string;
|
|
54
|
+
}): string;
|
|
55
|
+
/**
|
|
56
|
+
* Reject unsupported `--variant` usage for built-in templates.
|
|
57
|
+
*
|
|
58
|
+
* @param options Built-in template validation context.
|
|
59
|
+
* @param options.templateId Built-in template id being scaffolded.
|
|
60
|
+
* @param options.variant Optional variant override from CLI flags.
|
|
61
|
+
* @throws When a built-in template receives any explicit `--variant` value.
|
|
62
|
+
*/
|
|
63
|
+
export declare function assertBuiltInTemplateVariantAllowed(options: {
|
|
64
|
+
templateId: string;
|
|
65
|
+
variant?: string;
|
|
66
|
+
}): void;
|