@wp-typia/project-tools 0.16.12 → 0.16.13

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.
@@ -0,0 +1,8 @@
1
+ import { type ApplyBlockInput, type PlanBlockInput, type PlanBlockResult, type RenderBlockInput, type RenderBlockResult, type ValidateBlockInput, type ValidateBlockResult } from "./block-generator-service-spec.js";
2
+ import type { ScaffoldProjectResult } from "./scaffold.js";
3
+ export declare class BlockGeneratorService {
4
+ plan({ allowExistingDir, answers, cwd, dataStorageMode, externalLayerId, externalLayerSource, externalLayerSourceLabel, noInstall, packageManager, persistencePolicy, projectDir, repositoryReference, templateId, variant, withMigrationUi, withTestPreset, withWpEnv, }: PlanBlockInput): Promise<PlanBlockResult>;
5
+ validate({ plan }: ValidateBlockInput): Promise<ValidateBlockResult>;
6
+ render({ validated }: RenderBlockInput): Promise<RenderBlockResult>;
7
+ apply({ rendered, installDependencies, }: ApplyBlockInput): Promise<ScaffoldProjectResult>;
8
+ }
@@ -0,0 +1,274 @@
1
+ import { applyBuiltInScaffoldProjectFiles, buildGitignore, buildReadme, } from "./scaffold-apply-utils.js";
2
+ import { buildBuiltInBlockArtifacts, } from "./built-in-block-artifacts.js";
3
+ import { buildBuiltInCodeArtifacts, } from "./built-in-block-code-artifacts.js";
4
+ import { stableJsonStringify } from "./object-utils.js";
5
+ import { getStarterManifestFiles } from "./starter-manifests.js";
6
+ import { resolveTemplateSeed, parseTemplateLocator } from "./template-source.js";
7
+ import { assertExternalTemplateLayersDoNotWriteProtectedOutputs, resolveExternalTemplateLayers, } from "./template-layers.js";
8
+ import { getBuiltInTemplateOverlayDir, getBuiltInTemplateSharedLayerDirs, resolveBuiltInTemplateSource, resolveBuiltInTemplateSourceFromLayerDirs, } from "./template-builtins.js";
9
+ import { buildTemplateVariablesFromBlockSpec, createBuiltInBlockSpec, } from "./block-generator-service-spec.js";
10
+ const renderedArtifactCache = new WeakMap();
11
+ function createVariablesFingerprint(variables) {
12
+ return stableJsonStringify(variables);
13
+ }
14
+ function buildProtectedTemplateOutputPaths({ codeArtifacts, spec, variables, artifacts, }) {
15
+ const protectedOutputs = new Set([
16
+ ".gitignore",
17
+ "package.json",
18
+ "scripts/add-compound-child.ts",
19
+ "scripts/block-config.ts",
20
+ "scripts/sync-project.ts",
21
+ "scripts/sync-rest-contracts.ts",
22
+ "scripts/sync-types-to-block-json.ts",
23
+ "tsconfig.json",
24
+ "webpack.config.js",
25
+ `${variables.slugKebabCase}.php`,
26
+ ]);
27
+ for (const artifact of codeArtifacts) {
28
+ protectedOutputs.add(artifact.relativePath);
29
+ }
30
+ for (const artifact of artifacts) {
31
+ protectedOutputs.add(`${artifact.relativeDir}/block.json`);
32
+ protectedOutputs.add(`${artifact.relativeDir}/types.ts`);
33
+ }
34
+ for (const manifest of getStarterManifestFiles(spec.template.family, variables)) {
35
+ protectedOutputs.add(manifest.relativePath);
36
+ }
37
+ return protectedOutputs;
38
+ }
39
+ function buildCombinedTemplateLayerDirs({ baseLayerDirs, externalEntries, templateId, }) {
40
+ const orderedLayerDirs = [];
41
+ const seenLayerDirs = new Set();
42
+ for (const layerDir of baseLayerDirs) {
43
+ if (seenLayerDirs.has(layerDir)) {
44
+ continue;
45
+ }
46
+ orderedLayerDirs.push(layerDir);
47
+ seenLayerDirs.add(layerDir);
48
+ }
49
+ for (const entry of externalEntries) {
50
+ if (seenLayerDirs.has(entry.dir)) {
51
+ continue;
52
+ }
53
+ orderedLayerDirs.push(entry.dir);
54
+ seenLayerDirs.add(entry.dir);
55
+ }
56
+ const overlayDir = getBuiltInTemplateOverlayDir(templateId);
57
+ if (!seenLayerDirs.has(overlayDir)) {
58
+ orderedLayerDirs.push(overlayDir);
59
+ }
60
+ return orderedLayerDirs;
61
+ }
62
+ async function runCleanupGroup(label, cleanups) {
63
+ const cleanupErrors = [];
64
+ const seen = new Set();
65
+ for (const cleanup of cleanups) {
66
+ if (!cleanup || seen.has(cleanup)) {
67
+ continue;
68
+ }
69
+ seen.add(cleanup);
70
+ try {
71
+ await cleanup();
72
+ }
73
+ catch (error) {
74
+ cleanupErrors.push(error instanceof Error ? error : new Error(String(error)));
75
+ }
76
+ }
77
+ if (cleanupErrors.length > 0) {
78
+ throw new Error([
79
+ label,
80
+ ...cleanupErrors.map((error) => `- ${error.message}`),
81
+ ].join("\n"));
82
+ }
83
+ }
84
+ export class BlockGeneratorService {
85
+ async plan({ allowExistingDir = false, answers, cwd = process.cwd(), dataStorageMode, externalLayerId, externalLayerSource, externalLayerSourceLabel, noInstall = false, packageManager, persistencePolicy, projectDir, repositoryReference, templateId, variant, withMigrationUi = false, withTestPreset = false, withWpEnv = false, }) {
86
+ return {
87
+ spec: createBuiltInBlockSpec({
88
+ answers,
89
+ dataStorageMode,
90
+ persistencePolicy,
91
+ templateId,
92
+ withMigrationUi,
93
+ withTestPreset,
94
+ withWpEnv,
95
+ }),
96
+ target: {
97
+ allowExistingDir,
98
+ cwd,
99
+ externalLayerId,
100
+ externalLayerSource,
101
+ externalLayerSourceLabel,
102
+ noInstall,
103
+ packageManager,
104
+ projectDir,
105
+ repositoryReference,
106
+ variant,
107
+ },
108
+ };
109
+ }
110
+ async validate({ plan }) {
111
+ if (plan.target.externalLayerId && !plan.target.externalLayerSource) {
112
+ throw new Error("externalLayerId requires externalLayerSource when composing built-in template layers.");
113
+ }
114
+ if (plan.target.variant) {
115
+ 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}".`);
116
+ }
117
+ return plan;
118
+ }
119
+ async render({ validated }) {
120
+ const variables = buildTemplateVariablesFromBlockSpec(validated.spec);
121
+ const persistenceEnabled = validated.spec.persistence.enabled;
122
+ const artifacts = buildBuiltInBlockArtifacts({
123
+ templateId: validated.spec.template.family,
124
+ variables,
125
+ });
126
+ const codeArtifacts = buildBuiltInCodeArtifacts({
127
+ templateId: validated.spec.template.family,
128
+ variables,
129
+ });
130
+ const templateVariantOptions = {
131
+ persistenceEnabled,
132
+ persistencePolicy: validated.spec.persistence.enabled &&
133
+ validated.spec.persistence.persistencePolicy === "public"
134
+ ? "public"
135
+ : "authenticated",
136
+ };
137
+ let templateSource = await resolveBuiltInTemplateSource(validated.spec.template.family, templateVariantOptions);
138
+ const warnings = [...(templateSource.warnings ?? [])];
139
+ if (validated.target.externalLayerSource) {
140
+ let layerSeed;
141
+ let pendingLayerCleanup;
142
+ let pendingTemplateCleanup;
143
+ let composedCleanup;
144
+ try {
145
+ layerSeed = await resolveTemplateSeed(parseTemplateLocator(validated.target.externalLayerSource), validated.target.cwd);
146
+ pendingLayerCleanup = layerSeed.cleanup;
147
+ const resolvedLayers = await resolveExternalTemplateLayers({
148
+ externalLayerId: validated.target.externalLayerId,
149
+ sourceRoot: layerSeed.rootDir,
150
+ });
151
+ const baseLayerDirs = getBuiltInTemplateSharedLayerDirs(validated.spec.template.family, templateVariantOptions);
152
+ await assertExternalTemplateLayersDoNotWriteProtectedOutputs({
153
+ externalEntries: resolvedLayers.entries,
154
+ protectedOutputPaths: buildProtectedTemplateOutputPaths({
155
+ artifacts,
156
+ codeArtifacts,
157
+ spec: validated.spec,
158
+ variables,
159
+ }),
160
+ view: variables,
161
+ });
162
+ const previousTemplateCleanup = templateSource.cleanup;
163
+ const nextTemplateSource = await resolveBuiltInTemplateSourceFromLayerDirs(validated.spec.template.family, buildCombinedTemplateLayerDirs({
164
+ baseLayerDirs,
165
+ externalEntries: resolvedLayers.entries,
166
+ templateId: validated.spec.template.family,
167
+ }));
168
+ pendingTemplateCleanup = nextTemplateSource.cleanup;
169
+ await previousTemplateCleanup?.();
170
+ templateSource = nextTemplateSource;
171
+ composedCleanup = async () => runCleanupGroup("Failed to cleanup composed template sources.", [
172
+ pendingTemplateCleanup,
173
+ pendingLayerCleanup,
174
+ ]);
175
+ templateSource.cleanup = composedCleanup;
176
+ warnings.push(`Applied external layer "${resolvedLayers.selectedLayerId}" from "${validated.target.externalLayerSourceLabel ?? validated.target.externalLayerSource}".`);
177
+ }
178
+ catch (error) {
179
+ try {
180
+ if (composedCleanup) {
181
+ await composedCleanup();
182
+ }
183
+ else {
184
+ await runCleanupGroup("Failed to cleanup partially composed template sources.", [
185
+ templateSource.cleanup,
186
+ pendingTemplateCleanup,
187
+ pendingLayerCleanup,
188
+ ]);
189
+ }
190
+ }
191
+ catch {
192
+ // Preserve the original compose failure instead of masking it with cleanup errors.
193
+ }
194
+ throw error;
195
+ }
196
+ }
197
+ const rendered = {
198
+ ...validated,
199
+ cleanup: templateSource.cleanup,
200
+ gitignoreContent: buildGitignore(),
201
+ postRender: {
202
+ applyLocalDevPresets: true,
203
+ applyMigrationUiCapability: validated.spec.runtime.withMigrationUi,
204
+ seedPersistenceArtifacts: validated.spec.template.family === "persistence" ||
205
+ (validated.spec.template.family === "compound" && persistenceEnabled),
206
+ seedStarterManifestFiles: true,
207
+ },
208
+ readmeContent: buildReadme(validated.spec.template.family, variables, validated.target.packageManager, {
209
+ withMigrationUi: validated.spec.runtime.withMigrationUi,
210
+ withTestPreset: validated.spec.runtime.withTestPreset,
211
+ withWpEnv: validated.spec.runtime.withWpEnv,
212
+ }),
213
+ selectedVariant: null,
214
+ templateDir: templateSource.templateDir,
215
+ variables,
216
+ warnings,
217
+ };
218
+ renderedArtifactCache.set(rendered, {
219
+ artifacts,
220
+ codeArtifacts,
221
+ variablesFingerprint: createVariablesFingerprint(variables),
222
+ });
223
+ return rendered;
224
+ }
225
+ async apply({ rendered, installDependencies, }) {
226
+ const cachedArtifacts = renderedArtifactCache.get(rendered);
227
+ const currentVariablesFingerprint = createVariablesFingerprint(rendered.variables);
228
+ const artifacts = cachedArtifacts &&
229
+ cachedArtifacts.variablesFingerprint === currentVariablesFingerprint
230
+ ? cachedArtifacts.artifacts
231
+ : buildBuiltInBlockArtifacts({
232
+ templateId: rendered.spec.template.family,
233
+ variables: rendered.variables,
234
+ });
235
+ const codeArtifacts = cachedArtifacts &&
236
+ cachedArtifacts.variablesFingerprint === currentVariablesFingerprint
237
+ ? cachedArtifacts.codeArtifacts
238
+ : buildBuiltInCodeArtifacts({
239
+ templateId: rendered.spec.template.family,
240
+ variables: rendered.variables,
241
+ });
242
+ try {
243
+ await applyBuiltInScaffoldProjectFiles({
244
+ allowExistingDir: rendered.target.allowExistingDir,
245
+ artifacts,
246
+ codeArtifacts,
247
+ installDependencies,
248
+ noInstall: rendered.target.noInstall,
249
+ packageManager: rendered.target.packageManager,
250
+ projectDir: rendered.target.projectDir,
251
+ repositoryReference: rendered.target.repositoryReference,
252
+ gitignoreContent: rendered.gitignoreContent,
253
+ readmeContent: rendered.readmeContent,
254
+ templateDir: rendered.templateDir,
255
+ templateId: rendered.spec.template.family,
256
+ variables: rendered.variables,
257
+ withMigrationUi: rendered.spec.runtime.withMigrationUi,
258
+ withTestPreset: rendered.spec.runtime.withTestPreset,
259
+ withWpEnv: rendered.spec.runtime.withWpEnv,
260
+ });
261
+ }
262
+ finally {
263
+ await rendered.cleanup?.();
264
+ }
265
+ return {
266
+ packageManager: rendered.target.packageManager,
267
+ projectDir: rendered.target.projectDir,
268
+ selectedVariant: rendered.selectedVariant,
269
+ templateId: rendered.spec.template.family,
270
+ variables: rendered.variables,
271
+ warnings: rendered.warnings,
272
+ };
273
+ }
274
+ }
@@ -0,0 +1,104 @@
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, 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
+ externalLayerId?: string;
45
+ externalLayerSource?: string;
46
+ externalLayerSourceLabel?: string;
47
+ noInstall: boolean;
48
+ packageManager: PackageManagerId;
49
+ projectDir: string;
50
+ repositoryReference?: string;
51
+ variant?: string;
52
+ }
53
+ export interface PlanBlockInput {
54
+ allowExistingDir?: boolean;
55
+ answers: ScaffoldAnswers;
56
+ cwd?: string;
57
+ dataStorageMode?: DataStorageMode;
58
+ externalLayerId?: string;
59
+ externalLayerSource?: string;
60
+ externalLayerSourceLabel?: string;
61
+ noInstall?: boolean;
62
+ packageManager: PackageManagerId;
63
+ persistencePolicy?: PersistencePolicy;
64
+ projectDir: string;
65
+ repositoryReference?: string;
66
+ templateId: BuiltInTemplateId;
67
+ variant?: string;
68
+ withMigrationUi?: boolean;
69
+ withTestPreset?: boolean;
70
+ withWpEnv?: boolean;
71
+ }
72
+ export interface PlanBlockResult {
73
+ spec: BlockSpec;
74
+ target: BlockGenerationTarget;
75
+ }
76
+ export interface ValidateBlockInput {
77
+ plan: PlanBlockResult;
78
+ }
79
+ export interface ValidateBlockResult extends PlanBlockResult {
80
+ }
81
+ export interface RenderBlockInput {
82
+ validated: ValidateBlockResult;
83
+ }
84
+ export interface RenderBlockResult extends ValidateBlockResult {
85
+ cleanup?: () => Promise<void>;
86
+ gitignoreContent: string;
87
+ postRender: {
88
+ applyLocalDevPresets: boolean;
89
+ applyMigrationUiCapability: boolean;
90
+ seedPersistenceArtifacts: boolean;
91
+ seedStarterManifestFiles: boolean;
92
+ };
93
+ readmeContent: string;
94
+ selectedVariant: null;
95
+ templateDir: string;
96
+ variables: ScaffoldTemplateVariables;
97
+ warnings: string[];
98
+ }
99
+ export interface ApplyBlockInput {
100
+ rendered: RenderBlockResult;
101
+ installDependencies?: ((options: InstallDependenciesOptions) => Promise<void>) | undefined;
102
+ }
103
+ export declare function createBuiltInBlockSpec({ answers, dataStorageMode, persistencePolicy, templateId, withMigrationUi, withTestPreset, withWpEnv, }: Omit<PlanBlockInput, "allowExistingDir" | "cwd" | "noInstall" | "packageManager" | "projectDir" | "variant">): BlockSpec;
104
+ export declare function buildTemplateVariablesFromBlockSpec(spec: BlockSpec): ScaffoldTemplateVariables;
@@ -0,0 +1,139 @@
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 { toPascalCase, toSnakeCase, } from "./string-case.js";
5
+ import { buildBlockCssClassName, buildFrontendCssClassName, resolveScaffoldIdentifiers, } from "./scaffold-identifiers.js";
6
+ function getBuiltInPersistenceSpec({ templateId, dataStorageMode, persistencePolicy, }) {
7
+ if (templateId === "persistence") {
8
+ return {
9
+ dataStorageMode: dataStorageMode ?? "custom-table",
10
+ enabled: true,
11
+ persistencePolicy: persistencePolicy ?? "authenticated",
12
+ scope: "single",
13
+ };
14
+ }
15
+ if (templateId === "compound" && (dataStorageMode || persistencePolicy)) {
16
+ return {
17
+ dataStorageMode: dataStorageMode ?? "custom-table",
18
+ enabled: true,
19
+ persistencePolicy: persistencePolicy ?? "authenticated",
20
+ scope: "compound-parent",
21
+ };
22
+ }
23
+ return {
24
+ enabled: false,
25
+ };
26
+ }
27
+ export function createBuiltInBlockSpec({ answers, dataStorageMode, persistencePolicy, templateId, withMigrationUi = false, withTestPreset = false, withWpEnv = false, }) {
28
+ const template = getTemplateById(templateId);
29
+ const metadataDefaults = getBuiltInTemplateMetadataDefaults(templateId);
30
+ const identifiers = resolveScaffoldIdentifiers({
31
+ namespace: answers.namespace,
32
+ phpPrefix: answers.phpPrefix,
33
+ slug: answers.slug,
34
+ textDomain: answers.textDomain,
35
+ });
36
+ const resolvedDataStorageMode = dataStorageMode ?? answers.dataStorageMode;
37
+ const resolvedPersistencePolicy = persistencePolicy ?? answers.persistencePolicy;
38
+ return {
39
+ block: identifiers,
40
+ metadata: {
41
+ category: metadataDefaults.category,
42
+ description: answers.description.trim(),
43
+ icon: metadataDefaults.icon,
44
+ keyword: identifiers.slug.replace(/-/g, " "),
45
+ title: answers.title.trim(),
46
+ },
47
+ persistence: getBuiltInPersistenceSpec({
48
+ dataStorageMode: resolvedDataStorageMode,
49
+ persistencePolicy: resolvedPersistencePolicy,
50
+ templateId,
51
+ }),
52
+ project: {
53
+ author: answers.author.trim(),
54
+ },
55
+ runtime: {
56
+ withMigrationUi,
57
+ withTestPreset,
58
+ withWpEnv,
59
+ },
60
+ template: {
61
+ description: template.description,
62
+ family: templateId,
63
+ features: [...template.features],
64
+ },
65
+ };
66
+ }
67
+ export function buildTemplateVariablesFromBlockSpec(spec) {
68
+ const { apiClientPackageVersion, blockRuntimePackageVersion, blockTypesPackageVersion, projectToolsPackageVersion, restPackageVersion, } = getPackageVersions();
69
+ const slug = spec.block.slug;
70
+ const slugSnakeCase = toSnakeCase(slug);
71
+ const pascalCase = toPascalCase(slug);
72
+ const title = spec.metadata.title;
73
+ const namespace = spec.block.namespace;
74
+ const textDomain = spec.block.textDomain;
75
+ const phpPrefix = spec.block.phpPrefix;
76
+ const phpPrefixUpper = phpPrefix.toUpperCase();
77
+ const compoundChildTitle = `${title} Item`;
78
+ const cssClassName = buildBlockCssClassName(namespace, slug);
79
+ const compoundChildCssClassName = buildBlockCssClassName(namespace, `${slug}-item`);
80
+ const persistenceEnabled = spec.persistence.enabled;
81
+ const dataStorageMode = persistenceEnabled ? spec.persistence.dataStorageMode : "custom-table";
82
+ const persistencePolicy = persistenceEnabled
83
+ ? spec.persistence.persistencePolicy
84
+ : "authenticated";
85
+ return {
86
+ apiClientPackageVersion,
87
+ author: spec.project.author,
88
+ blockRuntimePackageVersion,
89
+ blockMetadataVersion: BUILTIN_BLOCK_METADATA_VERSION,
90
+ blockTypesPackageVersion,
91
+ category: spec.metadata.category,
92
+ icon: spec.metadata.icon,
93
+ compoundChildTitle,
94
+ compoundChildCategory: COMPOUND_CHILD_BLOCK_METADATA_DEFAULTS.category,
95
+ compoundChildCssClassName,
96
+ compoundChildIcon: COMPOUND_CHILD_BLOCK_METADATA_DEFAULTS.icon,
97
+ compoundChildTitleJson: JSON.stringify(compoundChildTitle),
98
+ compoundPersistenceEnabled: spec.template.family === "compound" && persistenceEnabled ? "true" : "false",
99
+ projectToolsPackageVersion,
100
+ cssClassName,
101
+ dashCase: slug,
102
+ dataStorageMode,
103
+ description: spec.metadata.description,
104
+ frontendCssClassName: buildFrontendCssClassName(cssClassName),
105
+ isAuthenticatedPersistencePolicy: persistencePolicy === "authenticated" ? "true" : "false",
106
+ isPublicPersistencePolicy: persistencePolicy === "public" ? "true" : "false",
107
+ bootstrapCredentialDeclarations: persistencePolicy === "public"
108
+ ? "publicWriteExpiresAt?: number & tags.Type< 'uint32' >;\n\tpublicWriteToken?: string & tags.MinLength< 1 > & tags.MaxLength< 512 >;"
109
+ : "restNonce?: string & tags.MinLength< 1 > & tags.MaxLength< 128 >;",
110
+ persistencePolicyDescriptionJson: JSON.stringify(persistencePolicy === "authenticated"
111
+ ? "Writes require a logged-in user and a valid REST nonce."
112
+ : "Anonymous writes use signed short-lived public tokens, per-request ids, and coarse rate limiting."),
113
+ keyword: spec.metadata.keyword,
114
+ namespace,
115
+ needsMigration: "{{needsMigration}}",
116
+ pascalCase,
117
+ phpPrefix,
118
+ phpPrefixUpper,
119
+ restPackageVersion,
120
+ publicWriteRequestIdDeclaration: persistencePolicy === "public"
121
+ ? "publicWriteRequestId: string & tags.MinLength< 1 > & tags.MaxLength< 128 >;"
122
+ : "publicWriteRequestId?: string & tags.MinLength< 1 > & tags.MaxLength< 128 >;",
123
+ restWriteAuthIntent: persistencePolicy === "public"
124
+ ? "public-write-protected"
125
+ : "authenticated",
126
+ restWriteAuthMechanism: persistencePolicy === "public" ? "public-signed-token" : "rest-nonce",
127
+ restWriteAuthMode: persistencePolicy === "public" ? "public-signed-token" : "authenticated-rest-nonce",
128
+ slug,
129
+ slugCamelCase: pascalCase.charAt(0).toLowerCase() + pascalCase.slice(1),
130
+ slugKebabCase: slug,
131
+ slugSnakeCase,
132
+ textDomain,
133
+ textdomain: textDomain,
134
+ title,
135
+ titleJson: JSON.stringify(title),
136
+ titleCase: pascalCase,
137
+ persistencePolicy,
138
+ };
139
+ }
@@ -1,110 +1,2 @@
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
- externalLayerId?: string;
45
- externalLayerSource?: string;
46
- externalLayerSourceLabel?: string;
47
- noInstall: boolean;
48
- packageManager: PackageManagerId;
49
- projectDir: string;
50
- repositoryReference?: string;
51
- variant?: string;
52
- }
53
- export interface PlanBlockInput {
54
- allowExistingDir?: boolean;
55
- answers: ScaffoldAnswers;
56
- cwd?: string;
57
- dataStorageMode?: DataStorageMode;
58
- externalLayerId?: string;
59
- externalLayerSource?: string;
60
- externalLayerSourceLabel?: string;
61
- noInstall?: boolean;
62
- packageManager: PackageManagerId;
63
- persistencePolicy?: PersistencePolicy;
64
- projectDir: string;
65
- repositoryReference?: string;
66
- templateId: BuiltInTemplateId;
67
- variant?: string;
68
- withMigrationUi?: boolean;
69
- withTestPreset?: boolean;
70
- withWpEnv?: boolean;
71
- }
72
- export interface PlanBlockResult {
73
- spec: BlockSpec;
74
- target: BlockGenerationTarget;
75
- }
76
- export interface ValidateBlockInput {
77
- plan: PlanBlockResult;
78
- }
79
- export interface ValidateBlockResult extends PlanBlockResult {
80
- }
81
- export interface RenderBlockInput {
82
- validated: ValidateBlockResult;
83
- }
84
- export interface RenderBlockResult extends ValidateBlockResult {
85
- cleanup?: () => Promise<void>;
86
- gitignoreContent: string;
87
- postRender: {
88
- applyLocalDevPresets: boolean;
89
- applyMigrationUiCapability: boolean;
90
- seedPersistenceArtifacts: boolean;
91
- seedStarterManifestFiles: boolean;
92
- };
93
- readmeContent: string;
94
- selectedVariant: null;
95
- templateDir: string;
96
- variables: ScaffoldTemplateVariables;
97
- warnings: string[];
98
- }
99
- export interface ApplyBlockInput {
100
- rendered: RenderBlockResult;
101
- installDependencies?: ((options: InstallDependenciesOptions) => Promise<void>) | undefined;
102
- }
103
- export declare function createBuiltInBlockSpec({ answers, dataStorageMode, persistencePolicy, templateId, withMigrationUi, withTestPreset, withWpEnv, }: Omit<PlanBlockInput, "allowExistingDir" | "cwd" | "noInstall" | "packageManager" | "projectDir" | "variant">): BlockSpec;
104
- export declare function buildTemplateVariablesFromBlockSpec(spec: BlockSpec): ScaffoldTemplateVariables;
105
- export declare class BlockGeneratorService {
106
- plan({ allowExistingDir, answers, cwd, dataStorageMode, externalLayerId, externalLayerSource, externalLayerSourceLabel, noInstall, packageManager, persistencePolicy, projectDir, repositoryReference, templateId, variant, withMigrationUi, withTestPreset, withWpEnv, }: PlanBlockInput): Promise<PlanBlockResult>;
107
- validate({ plan }: ValidateBlockInput): Promise<ValidateBlockResult>;
108
- render({ validated }: RenderBlockInput): Promise<RenderBlockResult>;
109
- apply({ rendered, installDependencies, }: ApplyBlockInput): Promise<ScaffoldProjectResult>;
110
- }
1
+ export * from "./block-generator-service-spec.js";
2
+ export * from "./block-generator-service-core.js";