@wp-typia/project-tools 0.16.1 → 0.16.4
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/README.md +17 -0
- package/dist/runtime/block-generator-service.d.ts +102 -0
- package/dist/runtime/block-generator-service.js +268 -0
- package/dist/runtime/built-in-block-artifacts.d.ts +37 -0
- package/dist/runtime/built-in-block-artifacts.js +1203 -0
- package/dist/runtime/built-in-block-code-artifacts.d.ts +30 -0
- package/dist/runtime/built-in-block-code-artifacts.js +122 -0
- package/dist/runtime/index.d.ts +2 -0
- package/dist/runtime/index.js +1 -0
- package/dist/runtime/package-versions.js +7 -2
- package/dist/runtime/scaffold-apply-utils.d.ts +47 -0
- package/dist/runtime/scaffold-apply-utils.js +405 -0
- package/dist/runtime/scaffold-identifiers.d.ts +34 -0
- package/dist/runtime/scaffold-identifiers.js +82 -0
- package/dist/runtime/scaffold.js +33 -0
- package/dist/runtime/schema-core.d.ts +5 -266
- package/dist/runtime/schema-core.js +5 -775
- package/dist/runtime/starter-manifests.d.ts +3 -2
- package/dist/runtime/starter-manifests.js +15 -365
- package/dist/runtime/template-render.d.ts +5 -0
- package/dist/runtime/template-render.js +13 -3
- package/package.json +56 -3
- package/templates/_shared/compound/persistence/scripts/block-config.ts.mustache +4 -4
- package/templates/_shared/persistence/core/scripts/sync-rest-contracts.ts.mustache +4 -4
- package/templates/_shared/base/src/hooks.ts.mustache +0 -19
- package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/block.json.mustache +0 -52
- package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/edit.tsx.mustache +0 -123
- package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/hooks.ts.mustache +0 -11
- package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/interactivity.ts.mustache +0 -305
- package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/save.tsx.mustache +0 -3
- package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/types.ts.mustache +0 -61
- package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/validators.ts.mustache +0 -43
- package/templates/_shared/persistence/core/src/index.tsx.mustache +0 -25
- package/templates/_shared/persistence/core/src/interactivity.ts.mustache +0 -308
- package/templates/_shared/persistence/core/src/save.tsx.mustache +0 -5
- package/templates/_shared/persistence/core/src/validators.ts.mustache +0 -43
- package/templates/basic/src/block.json.mustache +0 -51
- package/templates/basic/src/edit.tsx.mustache +0 -128
- package/templates/basic/src/index.tsx.mustache +0 -45
- package/templates/basic/src/save.tsx.mustache +0 -30
- package/templates/basic/src/types.ts.mustache +0 -56
- package/templates/basic/src/validators.ts.mustache +0 -37
- package/templates/compound/src/blocks/{{slugKebabCase}}/block.json.mustache +0 -37
- package/templates/compound/src/blocks/{{slugKebabCase}}/children.ts.mustache +0 -25
- package/templates/compound/src/blocks/{{slugKebabCase}}/edit.tsx.mustache +0 -93
- package/templates/compound/src/blocks/{{slugKebabCase}}/hooks.ts.mustache +0 -11
- package/templates/compound/src/blocks/{{slugKebabCase}}/index.tsx.mustache +0 -25
- package/templates/compound/src/blocks/{{slugKebabCase}}/save.tsx.mustache +0 -32
- package/templates/compound/src/blocks/{{slugKebabCase}}/types.ts.mustache +0 -18
- package/templates/compound/src/blocks/{{slugKebabCase}}/validators.ts.mustache +0 -35
- package/templates/compound/src/blocks/{{slugKebabCase}}-item/block.json.mustache +0 -35
- package/templates/compound/src/blocks/{{slugKebabCase}}-item/edit.tsx.mustache +0 -50
- package/templates/compound/src/blocks/{{slugKebabCase}}-item/hooks.ts.mustache +0 -11
- package/templates/compound/src/blocks/{{slugKebabCase}}-item/index.tsx.mustache +0 -25
- package/templates/compound/src/blocks/{{slugKebabCase}}-item/save.tsx.mustache +0 -24
- package/templates/compound/src/blocks/{{slugKebabCase}}-item/types.ts.mustache +0 -17
- package/templates/compound/src/blocks/{{slugKebabCase}}-item/validators.ts.mustache +0 -35
- package/templates/interactivity/src/block.json.mustache +0 -74
- package/templates/interactivity/src/edit.tsx.mustache +0 -270
- package/templates/interactivity/src/index.tsx.mustache +0 -33
- package/templates/interactivity/src/interactivity.ts.mustache +0 -152
- package/templates/interactivity/src/save.tsx.mustache +0 -101
- package/templates/interactivity/src/types.ts.mustache +0 -32
- package/templates/interactivity/src/validators.ts.mustache +0 -47
- package/templates/persistence/src/block.json.mustache +0 -52
- package/templates/persistence/src/edit.tsx.mustache +0 -165
- package/templates/persistence/src/types.ts.mustache +0 -59
package/README.md
CHANGED
|
@@ -6,6 +6,9 @@ Package roles:
|
|
|
6
6
|
|
|
7
7
|
- `wp-typia` owns the CLI, help, TUI, completions, skills, MCP, and bin entry.
|
|
8
8
|
- `@wp-typia/project-tools` owns scaffold, add-block, migrate, template, doctor, and schema project helpers.
|
|
9
|
+
It also owns the typed generator boundary via `BlockSpec` and `BlockGeneratorService`,
|
|
10
|
+
plus the emitter-owned built-in structural/code path where built-in
|
|
11
|
+
templates no longer ship structural or TS/TSX Mustache files.
|
|
9
12
|
- `@wp-typia/block-runtime/*` owns generated-project runtime helpers.
|
|
10
13
|
- `@wp-typia/create` is the deprecated legacy package shell.
|
|
11
14
|
|
|
@@ -14,10 +17,17 @@ Supported public imports:
|
|
|
14
17
|
- `@wp-typia/project-tools`
|
|
15
18
|
- `@wp-typia/project-tools/schema-core`
|
|
16
19
|
|
|
20
|
+
Implementation note:
|
|
21
|
+
|
|
22
|
+
- `@wp-typia/project-tools/schema-core` remains the preferred project-tooling
|
|
23
|
+
import path.
|
|
24
|
+
- The shared implementation now lives in `@wp-typia/block-runtime/schema-core`.
|
|
25
|
+
|
|
17
26
|
Example:
|
|
18
27
|
|
|
19
28
|
```ts
|
|
20
29
|
import {
|
|
30
|
+
BlockGeneratorService,
|
|
21
31
|
getTemplateById,
|
|
22
32
|
parseMigrationArgs,
|
|
23
33
|
projectJsonSchemaDocument,
|
|
@@ -29,4 +39,11 @@ import {
|
|
|
29
39
|
import { normalizeEndpointAuthDefinition } from "@wp-typia/project-tools/schema-core";
|
|
30
40
|
```
|
|
31
41
|
|
|
42
|
+
`BlockGeneratorService` is the additive typed orchestration boundary for built-in
|
|
43
|
+
block scaffolds. Built-in templates no longer ship structural or TS/TSX
|
|
44
|
+
Mustache files for built-in `types.ts`, `block.json`, or generated scaffold
|
|
45
|
+
bodies; those files and starter `typia.manifest.json` now come from the emitter
|
|
46
|
+
path, while styles, PHP, and the remaining non-TS scaffold files still come
|
|
47
|
+
from Mustache-backed template copy.
|
|
48
|
+
|
|
32
49
|
If you need metadata sync, editor helpers, validation helpers, or other generated-project runtime utilities, import them directly from `@wp-typia/block-runtime/*`.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import type { PackageManagerId } from "./package-managers.js";
|
|
2
|
+
import { type BuiltInTemplateId } from "./template-registry.js";
|
|
3
|
+
import { type InstallDependenciesOptions } from "./scaffold-apply-utils.js";
|
|
4
|
+
import type { DataStorageMode, PersistencePolicy, ScaffoldAnswers, ScaffoldProjectResult, ScaffoldTemplateVariables } from "./scaffold.js";
|
|
5
|
+
export interface BlockSpec {
|
|
6
|
+
block: {
|
|
7
|
+
namespace: string;
|
|
8
|
+
phpPrefix: string;
|
|
9
|
+
slug: string;
|
|
10
|
+
textDomain: string;
|
|
11
|
+
};
|
|
12
|
+
metadata: {
|
|
13
|
+
category: string;
|
|
14
|
+
description: string;
|
|
15
|
+
icon: string;
|
|
16
|
+
keyword: string;
|
|
17
|
+
title: string;
|
|
18
|
+
};
|
|
19
|
+
persistence: {
|
|
20
|
+
enabled: false;
|
|
21
|
+
} | {
|
|
22
|
+
dataStorageMode: DataStorageMode;
|
|
23
|
+
enabled: true;
|
|
24
|
+
persistencePolicy: PersistencePolicy;
|
|
25
|
+
scope: "compound-parent" | "single";
|
|
26
|
+
};
|
|
27
|
+
project: {
|
|
28
|
+
author: string;
|
|
29
|
+
};
|
|
30
|
+
runtime: {
|
|
31
|
+
withMigrationUi: boolean;
|
|
32
|
+
withTestPreset: boolean;
|
|
33
|
+
withWpEnv: boolean;
|
|
34
|
+
};
|
|
35
|
+
template: {
|
|
36
|
+
description: string;
|
|
37
|
+
family: BuiltInTemplateId;
|
|
38
|
+
features: string[];
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export interface BlockGenerationTarget {
|
|
42
|
+
allowExistingDir: boolean;
|
|
43
|
+
cwd: string;
|
|
44
|
+
noInstall: boolean;
|
|
45
|
+
packageManager: PackageManagerId;
|
|
46
|
+
projectDir: string;
|
|
47
|
+
variant?: string;
|
|
48
|
+
}
|
|
49
|
+
export interface PlanBlockInput {
|
|
50
|
+
allowExistingDir?: boolean;
|
|
51
|
+
answers: ScaffoldAnswers;
|
|
52
|
+
cwd?: string;
|
|
53
|
+
dataStorageMode?: DataStorageMode;
|
|
54
|
+
noInstall?: boolean;
|
|
55
|
+
packageManager: PackageManagerId;
|
|
56
|
+
persistencePolicy?: PersistencePolicy;
|
|
57
|
+
projectDir: string;
|
|
58
|
+
templateId: BuiltInTemplateId;
|
|
59
|
+
variant?: string;
|
|
60
|
+
withMigrationUi?: boolean;
|
|
61
|
+
withTestPreset?: boolean;
|
|
62
|
+
withWpEnv?: boolean;
|
|
63
|
+
}
|
|
64
|
+
export interface PlanBlockResult {
|
|
65
|
+
spec: BlockSpec;
|
|
66
|
+
target: BlockGenerationTarget;
|
|
67
|
+
}
|
|
68
|
+
export interface ValidateBlockInput {
|
|
69
|
+
plan: PlanBlockResult;
|
|
70
|
+
}
|
|
71
|
+
export interface ValidateBlockResult extends PlanBlockResult {
|
|
72
|
+
}
|
|
73
|
+
export interface RenderBlockInput {
|
|
74
|
+
validated: ValidateBlockResult;
|
|
75
|
+
}
|
|
76
|
+
export interface RenderBlockResult extends ValidateBlockResult {
|
|
77
|
+
cleanup?: () => Promise<void>;
|
|
78
|
+
gitignoreContent: string;
|
|
79
|
+
postRender: {
|
|
80
|
+
applyLocalDevPresets: boolean;
|
|
81
|
+
applyMigrationUiCapability: boolean;
|
|
82
|
+
seedPersistenceArtifacts: boolean;
|
|
83
|
+
seedStarterManifestFiles: boolean;
|
|
84
|
+
};
|
|
85
|
+
readmeContent: string;
|
|
86
|
+
selectedVariant: null;
|
|
87
|
+
templateDir: string;
|
|
88
|
+
variables: ScaffoldTemplateVariables;
|
|
89
|
+
warnings: string[];
|
|
90
|
+
}
|
|
91
|
+
export interface ApplyBlockInput {
|
|
92
|
+
rendered: RenderBlockResult;
|
|
93
|
+
installDependencies?: ((options: InstallDependenciesOptions) => Promise<void>) | undefined;
|
|
94
|
+
}
|
|
95
|
+
export declare function createBuiltInBlockSpec({ answers, dataStorageMode, persistencePolicy, templateId, withMigrationUi, withTestPreset, withWpEnv, }: Omit<PlanBlockInput, "allowExistingDir" | "cwd" | "noInstall" | "packageManager" | "projectDir" | "variant">): BlockSpec;
|
|
96
|
+
export declare function buildTemplateVariablesFromBlockSpec(spec: BlockSpec): ScaffoldTemplateVariables;
|
|
97
|
+
export declare class BlockGeneratorService {
|
|
98
|
+
plan({ allowExistingDir, answers, cwd, dataStorageMode, noInstall, packageManager, persistencePolicy, projectDir, templateId, variant, withMigrationUi, withTestPreset, withWpEnv, }: PlanBlockInput): Promise<PlanBlockResult>;
|
|
99
|
+
validate({ plan }: ValidateBlockInput): Promise<ValidateBlockResult>;
|
|
100
|
+
render({ validated }: RenderBlockInput): Promise<RenderBlockResult>;
|
|
101
|
+
apply({ rendered, installDependencies, }: ApplyBlockInput): Promise<ScaffoldProjectResult>;
|
|
102
|
+
}
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import { getPackageVersions } from "./package-versions.js";
|
|
2
|
+
import { BUILTIN_BLOCK_METADATA_VERSION, COMPOUND_CHILD_BLOCK_METADATA_DEFAULTS, getBuiltInTemplateMetadataDefaults, } from "./template-defaults.js";
|
|
3
|
+
import { getTemplateById, } from "./template-registry.js";
|
|
4
|
+
import { resolveBuiltInTemplateSource } from "./template-builtins.js";
|
|
5
|
+
import { toPascalCase, toSnakeCase, } from "./string-case.js";
|
|
6
|
+
import { applyBuiltInScaffoldProjectFiles, buildGitignore, buildReadme, } from "./scaffold-apply-utils.js";
|
|
7
|
+
import { buildBlockCssClassName, buildFrontendCssClassName, resolveScaffoldIdentifiers, } from "./scaffold-identifiers.js";
|
|
8
|
+
import { buildBuiltInBlockArtifacts, } from "./built-in-block-artifacts.js";
|
|
9
|
+
import { buildBuiltInCodeArtifacts, } from "./built-in-block-code-artifacts.js";
|
|
10
|
+
const renderedArtifactCache = new WeakMap();
|
|
11
|
+
function createVariablesFingerprint(variables) {
|
|
12
|
+
return JSON.stringify(variables);
|
|
13
|
+
}
|
|
14
|
+
function getBuiltInPersistenceSpec({ templateId, dataStorageMode, persistencePolicy, }) {
|
|
15
|
+
if (templateId === "persistence") {
|
|
16
|
+
return {
|
|
17
|
+
dataStorageMode: dataStorageMode ?? "custom-table",
|
|
18
|
+
enabled: true,
|
|
19
|
+
persistencePolicy: persistencePolicy ?? "authenticated",
|
|
20
|
+
scope: "single",
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
if (templateId === "compound" && (dataStorageMode || persistencePolicy)) {
|
|
24
|
+
return {
|
|
25
|
+
dataStorageMode: dataStorageMode ?? "custom-table",
|
|
26
|
+
enabled: true,
|
|
27
|
+
persistencePolicy: persistencePolicy ?? "authenticated",
|
|
28
|
+
scope: "compound-parent",
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
enabled: false,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export function createBuiltInBlockSpec({ answers, dataStorageMode, persistencePolicy, templateId, withMigrationUi = false, withTestPreset = false, withWpEnv = false, }) {
|
|
36
|
+
const template = getTemplateById(templateId);
|
|
37
|
+
const metadataDefaults = getBuiltInTemplateMetadataDefaults(templateId);
|
|
38
|
+
const identifiers = resolveScaffoldIdentifiers({
|
|
39
|
+
namespace: answers.namespace,
|
|
40
|
+
phpPrefix: answers.phpPrefix,
|
|
41
|
+
slug: answers.slug,
|
|
42
|
+
textDomain: answers.textDomain,
|
|
43
|
+
});
|
|
44
|
+
const resolvedDataStorageMode = dataStorageMode ?? answers.dataStorageMode;
|
|
45
|
+
const resolvedPersistencePolicy = persistencePolicy ?? answers.persistencePolicy;
|
|
46
|
+
return {
|
|
47
|
+
block: identifiers,
|
|
48
|
+
metadata: {
|
|
49
|
+
category: metadataDefaults.category,
|
|
50
|
+
description: answers.description.trim(),
|
|
51
|
+
icon: metadataDefaults.icon,
|
|
52
|
+
keyword: identifiers.slug.replace(/-/g, " "),
|
|
53
|
+
title: answers.title.trim(),
|
|
54
|
+
},
|
|
55
|
+
persistence: getBuiltInPersistenceSpec({
|
|
56
|
+
dataStorageMode: resolvedDataStorageMode,
|
|
57
|
+
persistencePolicy: resolvedPersistencePolicy,
|
|
58
|
+
templateId,
|
|
59
|
+
}),
|
|
60
|
+
project: {
|
|
61
|
+
author: answers.author.trim(),
|
|
62
|
+
},
|
|
63
|
+
runtime: {
|
|
64
|
+
withMigrationUi,
|
|
65
|
+
withTestPreset,
|
|
66
|
+
withWpEnv,
|
|
67
|
+
},
|
|
68
|
+
template: {
|
|
69
|
+
description: template.description,
|
|
70
|
+
family: templateId,
|
|
71
|
+
features: [...template.features],
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
export function buildTemplateVariablesFromBlockSpec(spec) {
|
|
76
|
+
const { apiClientPackageVersion, blockRuntimePackageVersion, blockTypesPackageVersion, projectToolsPackageVersion, restPackageVersion, } = getPackageVersions();
|
|
77
|
+
const slug = spec.block.slug;
|
|
78
|
+
const slugSnakeCase = toSnakeCase(slug);
|
|
79
|
+
const pascalCase = toPascalCase(slug);
|
|
80
|
+
const title = spec.metadata.title;
|
|
81
|
+
const namespace = spec.block.namespace;
|
|
82
|
+
const textDomain = spec.block.textDomain;
|
|
83
|
+
const phpPrefix = spec.block.phpPrefix;
|
|
84
|
+
const phpPrefixUpper = phpPrefix.toUpperCase();
|
|
85
|
+
const compoundChildTitle = `${title} Item`;
|
|
86
|
+
const cssClassName = buildBlockCssClassName(namespace, slug);
|
|
87
|
+
const compoundChildCssClassName = buildBlockCssClassName(namespace, `${slug}-item`);
|
|
88
|
+
const persistenceEnabled = spec.persistence.enabled;
|
|
89
|
+
const dataStorageMode = persistenceEnabled ? spec.persistence.dataStorageMode : "custom-table";
|
|
90
|
+
const persistencePolicy = persistenceEnabled
|
|
91
|
+
? spec.persistence.persistencePolicy
|
|
92
|
+
: "authenticated";
|
|
93
|
+
return {
|
|
94
|
+
apiClientPackageVersion,
|
|
95
|
+
author: spec.project.author,
|
|
96
|
+
blockRuntimePackageVersion,
|
|
97
|
+
blockMetadataVersion: BUILTIN_BLOCK_METADATA_VERSION,
|
|
98
|
+
blockTypesPackageVersion,
|
|
99
|
+
category: spec.metadata.category,
|
|
100
|
+
icon: spec.metadata.icon,
|
|
101
|
+
compoundChildTitle,
|
|
102
|
+
compoundChildCategory: COMPOUND_CHILD_BLOCK_METADATA_DEFAULTS.category,
|
|
103
|
+
compoundChildCssClassName,
|
|
104
|
+
compoundChildIcon: COMPOUND_CHILD_BLOCK_METADATA_DEFAULTS.icon,
|
|
105
|
+
compoundChildTitleJson: JSON.stringify(compoundChildTitle),
|
|
106
|
+
compoundPersistenceEnabled: spec.template.family === "compound" && persistenceEnabled ? "true" : "false",
|
|
107
|
+
projectToolsPackageVersion,
|
|
108
|
+
cssClassName,
|
|
109
|
+
dashCase: slug,
|
|
110
|
+
dataStorageMode,
|
|
111
|
+
description: spec.metadata.description,
|
|
112
|
+
frontendCssClassName: buildFrontendCssClassName(cssClassName),
|
|
113
|
+
isAuthenticatedPersistencePolicy: persistencePolicy === "authenticated" ? "true" : "false",
|
|
114
|
+
isPublicPersistencePolicy: persistencePolicy === "public" ? "true" : "false",
|
|
115
|
+
bootstrapCredentialDeclarations: persistencePolicy === "public"
|
|
116
|
+
? "publicWriteExpiresAt?: number & tags.Type< 'uint32' >;\n\tpublicWriteToken?: string & tags.MinLength< 1 > & tags.MaxLength< 512 >;"
|
|
117
|
+
: "restNonce?: string & tags.MinLength< 1 > & tags.MaxLength< 128 >;",
|
|
118
|
+
persistencePolicyDescriptionJson: JSON.stringify(persistencePolicy === "authenticated"
|
|
119
|
+
? "Writes require a logged-in user and a valid REST nonce."
|
|
120
|
+
: "Anonymous writes use signed short-lived public tokens, per-request ids, and coarse rate limiting."),
|
|
121
|
+
keyword: spec.metadata.keyword,
|
|
122
|
+
namespace,
|
|
123
|
+
needsMigration: "{{needsMigration}}",
|
|
124
|
+
pascalCase,
|
|
125
|
+
phpPrefix,
|
|
126
|
+
phpPrefixUpper,
|
|
127
|
+
restPackageVersion,
|
|
128
|
+
publicWriteRequestIdDeclaration: persistencePolicy === "public"
|
|
129
|
+
? "publicWriteRequestId: string & tags.MinLength< 1 > & tags.MaxLength< 128 >;"
|
|
130
|
+
: "publicWriteRequestId?: string & tags.MinLength< 1 > & tags.MaxLength< 128 >;",
|
|
131
|
+
restWriteAuthIntent: persistencePolicy === "public"
|
|
132
|
+
? "public-write-protected"
|
|
133
|
+
: "authenticated",
|
|
134
|
+
restWriteAuthMechanism: persistencePolicy === "public" ? "public-signed-token" : "rest-nonce",
|
|
135
|
+
restWriteAuthMode: persistencePolicy === "public" ? "public-signed-token" : "authenticated-rest-nonce",
|
|
136
|
+
slug,
|
|
137
|
+
slugCamelCase: pascalCase.charAt(0).toLowerCase() + pascalCase.slice(1),
|
|
138
|
+
slugKebabCase: slug,
|
|
139
|
+
slugSnakeCase,
|
|
140
|
+
textDomain,
|
|
141
|
+
textdomain: textDomain,
|
|
142
|
+
title,
|
|
143
|
+
titleJson: JSON.stringify(title),
|
|
144
|
+
titleCase: pascalCase,
|
|
145
|
+
persistencePolicy,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
export class BlockGeneratorService {
|
|
149
|
+
async plan({ allowExistingDir = false, answers, cwd = process.cwd(), dataStorageMode, noInstall = false, packageManager, persistencePolicy, projectDir, templateId, variant, withMigrationUi = false, withTestPreset = false, withWpEnv = false, }) {
|
|
150
|
+
return {
|
|
151
|
+
spec: createBuiltInBlockSpec({
|
|
152
|
+
answers,
|
|
153
|
+
dataStorageMode,
|
|
154
|
+
persistencePolicy,
|
|
155
|
+
templateId,
|
|
156
|
+
withMigrationUi,
|
|
157
|
+
withTestPreset,
|
|
158
|
+
withWpEnv,
|
|
159
|
+
}),
|
|
160
|
+
target: {
|
|
161
|
+
allowExistingDir,
|
|
162
|
+
cwd,
|
|
163
|
+
noInstall,
|
|
164
|
+
packageManager,
|
|
165
|
+
projectDir,
|
|
166
|
+
variant,
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
async validate({ plan }) {
|
|
171
|
+
if (plan.target.variant) {
|
|
172
|
+
throw new Error(`--variant is only supported for official external template configs. Received variant "${plan.target.variant}" for built-in template "${plan.spec.template.family}".`);
|
|
173
|
+
}
|
|
174
|
+
return plan;
|
|
175
|
+
}
|
|
176
|
+
async render({ validated }) {
|
|
177
|
+
const templateSource = await resolveBuiltInTemplateSource(validated.spec.template.family, {
|
|
178
|
+
persistenceEnabled: validated.spec.persistence.enabled,
|
|
179
|
+
persistencePolicy: validated.spec.persistence.enabled &&
|
|
180
|
+
validated.spec.persistence.persistencePolicy === "public"
|
|
181
|
+
? "public"
|
|
182
|
+
: "authenticated",
|
|
183
|
+
});
|
|
184
|
+
const variables = buildTemplateVariablesFromBlockSpec(validated.spec);
|
|
185
|
+
const persistenceEnabled = validated.spec.persistence.enabled;
|
|
186
|
+
const rendered = {
|
|
187
|
+
...validated,
|
|
188
|
+
cleanup: templateSource.cleanup,
|
|
189
|
+
gitignoreContent: buildGitignore(),
|
|
190
|
+
postRender: {
|
|
191
|
+
applyLocalDevPresets: true,
|
|
192
|
+
applyMigrationUiCapability: validated.spec.runtime.withMigrationUi,
|
|
193
|
+
seedPersistenceArtifacts: validated.spec.template.family === "persistence" ||
|
|
194
|
+
(validated.spec.template.family === "compound" && persistenceEnabled),
|
|
195
|
+
seedStarterManifestFiles: true,
|
|
196
|
+
},
|
|
197
|
+
readmeContent: buildReadme(validated.spec.template.family, variables, validated.target.packageManager, {
|
|
198
|
+
withMigrationUi: validated.spec.runtime.withMigrationUi,
|
|
199
|
+
withTestPreset: validated.spec.runtime.withTestPreset,
|
|
200
|
+
withWpEnv: validated.spec.runtime.withWpEnv,
|
|
201
|
+
}),
|
|
202
|
+
selectedVariant: null,
|
|
203
|
+
templateDir: templateSource.templateDir,
|
|
204
|
+
variables,
|
|
205
|
+
warnings: templateSource.warnings ?? [],
|
|
206
|
+
};
|
|
207
|
+
renderedArtifactCache.set(rendered, {
|
|
208
|
+
artifacts: buildBuiltInBlockArtifacts({
|
|
209
|
+
templateId: validated.spec.template.family,
|
|
210
|
+
variables,
|
|
211
|
+
}),
|
|
212
|
+
codeArtifacts: buildBuiltInCodeArtifacts({
|
|
213
|
+
templateId: validated.spec.template.family,
|
|
214
|
+
variables,
|
|
215
|
+
}),
|
|
216
|
+
variablesFingerprint: createVariablesFingerprint(variables),
|
|
217
|
+
});
|
|
218
|
+
return rendered;
|
|
219
|
+
}
|
|
220
|
+
async apply({ rendered, installDependencies, }) {
|
|
221
|
+
const cachedArtifacts = renderedArtifactCache.get(rendered);
|
|
222
|
+
const currentVariablesFingerprint = createVariablesFingerprint(rendered.variables);
|
|
223
|
+
const artifacts = cachedArtifacts &&
|
|
224
|
+
cachedArtifacts.variablesFingerprint === currentVariablesFingerprint
|
|
225
|
+
? cachedArtifacts.artifacts
|
|
226
|
+
: buildBuiltInBlockArtifacts({
|
|
227
|
+
templateId: rendered.spec.template.family,
|
|
228
|
+
variables: rendered.variables,
|
|
229
|
+
});
|
|
230
|
+
const codeArtifacts = cachedArtifacts &&
|
|
231
|
+
cachedArtifacts.variablesFingerprint === currentVariablesFingerprint
|
|
232
|
+
? cachedArtifacts.codeArtifacts
|
|
233
|
+
: buildBuiltInCodeArtifacts({
|
|
234
|
+
templateId: rendered.spec.template.family,
|
|
235
|
+
variables: rendered.variables,
|
|
236
|
+
});
|
|
237
|
+
try {
|
|
238
|
+
await applyBuiltInScaffoldProjectFiles({
|
|
239
|
+
allowExistingDir: rendered.target.allowExistingDir,
|
|
240
|
+
artifacts,
|
|
241
|
+
codeArtifacts,
|
|
242
|
+
installDependencies,
|
|
243
|
+
noInstall: rendered.target.noInstall,
|
|
244
|
+
packageManager: rendered.target.packageManager,
|
|
245
|
+
projectDir: rendered.target.projectDir,
|
|
246
|
+
gitignoreContent: rendered.gitignoreContent,
|
|
247
|
+
readmeContent: rendered.readmeContent,
|
|
248
|
+
templateDir: rendered.templateDir,
|
|
249
|
+
templateId: rendered.spec.template.family,
|
|
250
|
+
variables: rendered.variables,
|
|
251
|
+
withMigrationUi: rendered.spec.runtime.withMigrationUi,
|
|
252
|
+
withTestPreset: rendered.spec.runtime.withTestPreset,
|
|
253
|
+
withWpEnv: rendered.spec.runtime.withWpEnv,
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
finally {
|
|
257
|
+
await rendered.cleanup?.();
|
|
258
|
+
}
|
|
259
|
+
return {
|
|
260
|
+
packageManager: rendered.target.packageManager,
|
|
261
|
+
projectDir: rendered.target.projectDir,
|
|
262
|
+
selectedVariant: rendered.selectedVariant,
|
|
263
|
+
templateId: rendered.spec.template.family,
|
|
264
|
+
variables: rendered.variables,
|
|
265
|
+
warnings: rendered.warnings,
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { ManifestDocument } from "./migration-types.js";
|
|
2
|
+
import type { ScaffoldTemplateVariables } from "./scaffold.js";
|
|
3
|
+
import type { BuiltInTemplateId } from "./template-registry.js";
|
|
4
|
+
export interface BuiltInBlockArtifact {
|
|
5
|
+
blockJsonDocument: Record<string, unknown>;
|
|
6
|
+
manifestDocument: ManifestDocument;
|
|
7
|
+
relativeDir: string;
|
|
8
|
+
typesSource: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Builds a starter manifest document for a generated compound child block.
|
|
12
|
+
*
|
|
13
|
+
* @param childTypeName TypeScript source type name for the child manifest.
|
|
14
|
+
* @param childTitle Default title used by the child block.
|
|
15
|
+
* @param bodyPlaceholder Optional placeholder used for the child body field.
|
|
16
|
+
* @returns Starter manifest metadata for the compound child block.
|
|
17
|
+
*/
|
|
18
|
+
export declare function buildCompoundChildStarterManifestDocument(childTypeName: string, childTitle: string, bodyPlaceholder?: string): ManifestDocument;
|
|
19
|
+
/**
|
|
20
|
+
* Generates typed structural artifacts for a built-in block scaffold.
|
|
21
|
+
*
|
|
22
|
+
* @param options.templateId Built-in template family to emit.
|
|
23
|
+
* @param options.variables Resolved scaffold template variables.
|
|
24
|
+
* @returns Structural artifacts for the built-in block, including compound
|
|
25
|
+
* parent and child outputs when applicable.
|
|
26
|
+
*/
|
|
27
|
+
export declare function buildBuiltInBlockArtifacts({ templateId, variables, }: {
|
|
28
|
+
templateId: BuiltInTemplateId;
|
|
29
|
+
variables: ScaffoldTemplateVariables;
|
|
30
|
+
}): BuiltInBlockArtifact[];
|
|
31
|
+
/**
|
|
32
|
+
* Serializes a generated `block.json` document using scaffold formatting.
|
|
33
|
+
*
|
|
34
|
+
* @param document Structured `block.json` document.
|
|
35
|
+
* @returns Pretty-printed JSON with a trailing newline.
|
|
36
|
+
*/
|
|
37
|
+
export declare function stringifyBuiltInBlockJsonDocument(document: Record<string, unknown>): string;
|