@wp-typia/project-tools 0.18.0 → 0.19.1
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 +248 -2
- package/dist/runtime/built-in-block-artifacts.js +3 -1
- package/dist/runtime/built-in-block-code-artifacts.js +3 -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 +66 -31
- 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-diagnostics.d.ts +26 -0
- package/dist/runtime/cli-diagnostics.js +107 -0
- package/dist/runtime/cli-doctor-workspace.js +4 -4
- package/dist/runtime/cli-help.js +4 -3
- package/dist/runtime/cli-scaffold.d.ts +3 -1
- package/dist/runtime/cli-scaffold.js +91 -15
- 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 +5 -1
- package/dist/runtime/index.js +3 -1
- 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-bootstrap.js +5 -1
- package/dist/runtime/scaffold-documents.js +29 -6
- 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-variable-groups.d.ts +154 -0
- package/dist/runtime/scaffold-template-variable-groups.js +13 -0
- package/dist/runtime/scaffold-template-variables.js +80 -1
- package/dist/runtime/scaffold.d.ts +21 -2
- package/dist/runtime/scaffold.js +12 -5
- package/dist/runtime/temp-roots.d.ts +44 -0
- package/dist/runtime/temp-roots.js +129 -0
- package/dist/runtime/template-builtins.js +4 -6
- package/dist/runtime/template-registry.d.ts +8 -0
- package/dist/runtime/template-registry.js +34 -1
- package/dist/runtime/template-source-external.d.ts +1 -0
- package/dist/runtime/template-source-external.js +4 -7
- package/dist/runtime/template-source-remote.js +44 -23
- package/dist/runtime/template-source-seeds.js +3 -9
- package/dist/runtime/template-source.d.ts +2 -3
- package/dist/runtime/template-source.js +13 -5
- package/dist/runtime/workspace-project.js +1 -1
- package/package.json +12 -2
- package/templates/_shared/compound/core/scripts/add-compound-child.ts.mustache +318 -18
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const ALTERNATE_RENDER_TARGET_IDS: readonly ["email", "mjml", "plain-text"];
|
|
2
|
+
export type AlternateRenderTargetId = (typeof ALTERNATE_RENDER_TARGET_IDS)[number];
|
|
3
|
+
export declare function isAlternateRenderTargetId(value: string): value is AlternateRenderTargetId;
|
|
4
|
+
export declare function parseAlternateRenderTargets(value?: string): AlternateRenderTargetId[];
|
|
5
|
+
export declare function formatAlternateRenderTargets(targets: readonly AlternateRenderTargetId[]): string;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export const ALTERNATE_RENDER_TARGET_IDS = [
|
|
2
|
+
"email",
|
|
3
|
+
"mjml",
|
|
4
|
+
"plain-text",
|
|
5
|
+
];
|
|
6
|
+
export function isAlternateRenderTargetId(value) {
|
|
7
|
+
return ALTERNATE_RENDER_TARGET_IDS.includes(value);
|
|
8
|
+
}
|
|
9
|
+
export function parseAlternateRenderTargets(value) {
|
|
10
|
+
if (typeof value !== "string") {
|
|
11
|
+
return [];
|
|
12
|
+
}
|
|
13
|
+
const normalized = value
|
|
14
|
+
.split(",")
|
|
15
|
+
.map((entry) => entry.trim().toLowerCase())
|
|
16
|
+
.filter(Boolean);
|
|
17
|
+
if (normalized.length === 0) {
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
const deduped = Array.from(new Set(normalized));
|
|
21
|
+
const invalid = deduped.filter((entry) => !isAlternateRenderTargetId(entry));
|
|
22
|
+
if (invalid.length > 0) {
|
|
23
|
+
throw new Error(`Unsupported alternate render target${invalid.length > 1 ? "s" : ""} "${invalid.join(", ")}". Expected one of: ${ALTERNATE_RENDER_TARGET_IDS.join(", ")}.`);
|
|
24
|
+
}
|
|
25
|
+
return deduped;
|
|
26
|
+
}
|
|
27
|
+
export function formatAlternateRenderTargets(targets) {
|
|
28
|
+
return targets.join(", ");
|
|
29
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type ApplyBlockInput, type PlanBlockInput, type PlanBlockResult, type RenderBlockInput, type RenderBlockResult, type ValidateBlockInput, type ValidateBlockResult } from "./block-generator-service-spec.js";
|
|
2
2
|
import type { ScaffoldProjectResult } from "./scaffold.js";
|
|
3
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>;
|
|
4
|
+
plan({ allowExistingDir, alternateRenderTargets, answers, cwd, dataStorageMode, externalLayerId, externalLayerSource, externalLayerSourceLabel, noInstall, packageManager, persistencePolicy, projectDir, repositoryReference, templateId, variant, withMigrationUi, withTestPreset, withWpEnv, }: PlanBlockInput): Promise<PlanBlockResult>;
|
|
5
5
|
validate({ plan }: ValidateBlockInput): Promise<ValidateBlockResult>;
|
|
6
6
|
render({ validated }: RenderBlockInput): Promise<RenderBlockResult>;
|
|
7
7
|
apply({ rendered, installDependencies, onProgress, }: ApplyBlockInput): Promise<ScaffoldProjectResult>;
|
|
@@ -7,6 +7,7 @@ import { resolveTemplateSeed, parseTemplateLocator } from "./template-source.js"
|
|
|
7
7
|
import { assertExternalTemplateLayersDoNotWriteProtectedOutputs, resolveExternalTemplateLayers, } from "./template-layers.js";
|
|
8
8
|
import { getBuiltInTemplateOverlayDir, getBuiltInTemplateSharedLayerDirs, resolveBuiltInTemplateSource, resolveBuiltInTemplateSourceFromLayerDirs, } from "./template-builtins.js";
|
|
9
9
|
import { buildTemplateVariablesFromBlockSpec, createBuiltInBlockSpec, } from "./block-generator-service-spec.js";
|
|
10
|
+
import { assertBuiltInTemplateVariantAllowed, assertExternalLayerCompositionOptions, } from "./cli-validation.js";
|
|
10
11
|
const renderedArtifactCache = new WeakMap();
|
|
11
12
|
function createVariablesFingerprint(variables) {
|
|
12
13
|
return stableJsonStringify(variables);
|
|
@@ -82,9 +83,10 @@ async function runCleanupGroup(label, cleanups) {
|
|
|
82
83
|
}
|
|
83
84
|
}
|
|
84
85
|
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
|
+
async plan({ allowExistingDir = false, alternateRenderTargets, answers, cwd = process.cwd(), dataStorageMode, externalLayerId, externalLayerSource, externalLayerSourceLabel, noInstall = false, packageManager, persistencePolicy, projectDir, repositoryReference, templateId, variant, withMigrationUi = false, withTestPreset = false, withWpEnv = false, }) {
|
|
86
87
|
return {
|
|
87
88
|
spec: createBuiltInBlockSpec({
|
|
89
|
+
alternateRenderTargets,
|
|
88
90
|
answers,
|
|
89
91
|
dataStorageMode,
|
|
90
92
|
persistencePolicy,
|
|
@@ -108,12 +110,14 @@ export class BlockGeneratorService {
|
|
|
108
110
|
};
|
|
109
111
|
}
|
|
110
112
|
async validate({ plan }) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
113
|
+
assertExternalLayerCompositionOptions({
|
|
114
|
+
externalLayerId: plan.target.externalLayerId,
|
|
115
|
+
externalLayerSource: plan.target.externalLayerSource,
|
|
116
|
+
});
|
|
117
|
+
assertBuiltInTemplateVariantAllowed({
|
|
118
|
+
templateId: plan.spec.template.family,
|
|
119
|
+
variant: plan.target.variant,
|
|
120
|
+
});
|
|
117
121
|
return plan;
|
|
118
122
|
}
|
|
119
123
|
async render({ validated }) {
|
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
import type { PackageManagerId } from "./package-managers.js";
|
|
2
|
+
import { type AlternateRenderTargetId } from "./alternate-render-targets.js";
|
|
3
|
+
import { type CompoundInnerBlocksPresetId } from "./compound-inner-blocks.js";
|
|
2
4
|
import { type BuiltInTemplateId } from "./template-registry.js";
|
|
3
5
|
import type { InstallDependenciesOptions } from "./scaffold-apply-utils.js";
|
|
4
6
|
import type { DataStorageMode, PersistencePolicy, ScaffoldAnswers, ScaffoldProgressEvent, ScaffoldTemplateVariables } from "./scaffold.js";
|
|
5
7
|
export interface BlockSpec {
|
|
8
|
+
alternateRenderTargets: readonly AlternateRenderTargetId[];
|
|
6
9
|
block: {
|
|
7
10
|
namespace: string;
|
|
8
11
|
phpPrefix: string;
|
|
9
12
|
slug: string;
|
|
10
13
|
textDomain: string;
|
|
11
14
|
};
|
|
15
|
+
compound: {
|
|
16
|
+
innerBlocksPreset: CompoundInnerBlocksPresetId;
|
|
17
|
+
};
|
|
12
18
|
metadata: {
|
|
13
19
|
category: string;
|
|
14
20
|
description: string;
|
|
@@ -57,6 +63,7 @@ export interface BlockGenerationTarget {
|
|
|
57
63
|
}
|
|
58
64
|
export interface PlanBlockInput {
|
|
59
65
|
allowExistingDir?: boolean;
|
|
66
|
+
alternateRenderTargets?: string;
|
|
60
67
|
answers: ScaffoldAnswers;
|
|
61
68
|
cwd?: string;
|
|
62
69
|
dataStorageMode?: DataStorageMode;
|
|
@@ -107,5 +114,5 @@ export interface ApplyBlockInput {
|
|
|
107
114
|
installDependencies?: ((options: InstallDependenciesOptions) => Promise<void>) | undefined;
|
|
108
115
|
onProgress?: ((event: ScaffoldProgressEvent) => void | Promise<void>) | undefined;
|
|
109
116
|
}
|
|
110
|
-
export declare function createBuiltInBlockSpec({ answers, dataStorageMode, persistencePolicy, templateId, withMigrationUi, withTestPreset, withWpEnv, }: Omit<PlanBlockInput, "allowExistingDir" | "cwd" | "noInstall" | "packageManager" | "projectDir" | "variant">): BlockSpec;
|
|
117
|
+
export declare function createBuiltInBlockSpec({ alternateRenderTargets, answers, dataStorageMode, persistencePolicy, templateId, withMigrationUi, withTestPreset, withWpEnv, }: Omit<PlanBlockInput, "allowExistingDir" | "cwd" | "noInstall" | "packageManager" | "projectDir" | "variant">): BlockSpec;
|
|
111
118
|
export declare function buildTemplateVariablesFromBlockSpec(spec: BlockSpec): ScaffoldTemplateVariables;
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { getPackageVersions } from "./package-versions.js";
|
|
2
2
|
import { BUILTIN_BLOCK_METADATA_VERSION, COMPOUND_CHILD_BLOCK_METADATA_DEFAULTS, getBuiltInTemplateMetadataDefaults, } from "./template-defaults.js";
|
|
3
|
+
import { formatAlternateRenderTargets, parseAlternateRenderTargets, } from "./alternate-render-targets.js";
|
|
4
|
+
import { DEFAULT_COMPOUND_INNER_BLOCKS_PRESET_ID, getCompoundInnerBlocksPresetDefinition, } from "./compound-inner-blocks.js";
|
|
3
5
|
import { getTemplateById, } from "./template-registry.js";
|
|
4
6
|
import { toPascalCase, toSnakeCase, } from "./string-case.js";
|
|
5
7
|
import { buildBlockCssClassName, buildFrontendCssClassName, resolveScaffoldIdentifiers, } from "./scaffold-identifiers.js";
|
|
8
|
+
import { attachScaffoldTemplateVariableGroups } from "./scaffold-template-variable-groups.js";
|
|
6
9
|
function getBuiltInPersistenceSpec({ templateId, dataStorageMode, persistencePolicy, }) {
|
|
7
10
|
if (templateId === "persistence") {
|
|
8
11
|
return {
|
|
@@ -33,7 +36,7 @@ const DEFAULT_QUERY_LOOP_ALLOWED_CONTROLS = [
|
|
|
33
36
|
"author",
|
|
34
37
|
"search",
|
|
35
38
|
];
|
|
36
|
-
export function createBuiltInBlockSpec({ answers, dataStorageMode, persistencePolicy, templateId, withMigrationUi = false, withTestPreset = false, withWpEnv = false, }) {
|
|
39
|
+
export function createBuiltInBlockSpec({ alternateRenderTargets, answers, dataStorageMode, persistencePolicy, templateId, withMigrationUi = false, withTestPreset = false, withWpEnv = false, }) {
|
|
37
40
|
const template = getTemplateById(templateId);
|
|
38
41
|
const metadataDefaults = getBuiltInTemplateMetadataDefaults(templateId);
|
|
39
42
|
const identifiers = resolveScaffoldIdentifiers({
|
|
@@ -44,8 +47,17 @@ export function createBuiltInBlockSpec({ answers, dataStorageMode, persistencePo
|
|
|
44
47
|
});
|
|
45
48
|
const resolvedDataStorageMode = dataStorageMode ?? answers.dataStorageMode;
|
|
46
49
|
const resolvedPersistencePolicy = persistencePolicy ?? answers.persistencePolicy;
|
|
50
|
+
const parsedAlternateRenderTargets = parseAlternateRenderTargets(alternateRenderTargets);
|
|
51
|
+
const innerBlocksPreset = templateId === "compound"
|
|
52
|
+
? (answers.compoundInnerBlocksPreset ??
|
|
53
|
+
DEFAULT_COMPOUND_INNER_BLOCKS_PRESET_ID)
|
|
54
|
+
: DEFAULT_COMPOUND_INNER_BLOCKS_PRESET_ID;
|
|
47
55
|
return {
|
|
56
|
+
alternateRenderTargets: parsedAlternateRenderTargets,
|
|
48
57
|
block: identifiers,
|
|
58
|
+
compound: {
|
|
59
|
+
innerBlocksPreset,
|
|
60
|
+
},
|
|
49
61
|
metadata: {
|
|
50
62
|
category: metadataDefaults.category,
|
|
51
63
|
description: answers.description.trim(),
|
|
@@ -94,16 +106,25 @@ export function buildTemplateVariablesFromBlockSpec(spec) {
|
|
|
94
106
|
const textDomain = spec.block.textDomain;
|
|
95
107
|
const phpPrefix = spec.block.phpPrefix;
|
|
96
108
|
const phpPrefixUpper = phpPrefix.toUpperCase();
|
|
109
|
+
const alternateRenderTargets = [...spec.alternateRenderTargets];
|
|
110
|
+
const hasAlternateEmailRenderTarget = alternateRenderTargets.includes("email");
|
|
111
|
+
const hasAlternateMjmlRenderTarget = alternateRenderTargets.includes("mjml");
|
|
112
|
+
const hasAlternatePlainTextRenderTarget = alternateRenderTargets.includes("plain-text");
|
|
97
113
|
const compoundChildTitle = `${title} Item`;
|
|
98
114
|
const cssClassName = buildBlockCssClassName(namespace, slug);
|
|
99
115
|
const compoundChildCssClassName = buildBlockCssClassName(namespace, `${slug}-item`);
|
|
116
|
+
const compoundInnerBlocksPreset = spec.compound.innerBlocksPreset;
|
|
117
|
+
const compoundInnerBlocksPresetDefinition = getCompoundInnerBlocksPresetDefinition(compoundInnerBlocksPreset);
|
|
118
|
+
const compoundInnerBlocksOrientation = compoundInnerBlocksPresetDefinition.orientation ?? "";
|
|
100
119
|
const persistenceEnabled = spec.persistence.enabled;
|
|
101
120
|
const dataStorageMode = persistenceEnabled ? spec.persistence.dataStorageMode : "custom-table";
|
|
102
121
|
const persistencePolicy = persistenceEnabled
|
|
103
122
|
? spec.persistence.persistencePolicy
|
|
104
123
|
: "authenticated";
|
|
105
124
|
const queryVariationNamespace = `${namespace}/${slug}`;
|
|
106
|
-
|
|
125
|
+
const flatVariables = {
|
|
126
|
+
alternateRenderTargetsCsv: formatAlternateRenderTargets(alternateRenderTargets),
|
|
127
|
+
alternateRenderTargetsJson: JSON.stringify(alternateRenderTargets),
|
|
107
128
|
apiClientPackageVersion,
|
|
108
129
|
author: spec.project.author,
|
|
109
130
|
blockRuntimePackageVersion,
|
|
@@ -117,6 +138,29 @@ export function buildTemplateVariablesFromBlockSpec(spec) {
|
|
|
117
138
|
compoundChildIcon: COMPOUND_CHILD_BLOCK_METADATA_DEFAULTS.icon,
|
|
118
139
|
compoundChildTitleJson: JSON.stringify(compoundChildTitle),
|
|
119
140
|
compoundPersistenceEnabled: spec.template.family === "compound" && persistenceEnabled ? "true" : "false",
|
|
141
|
+
compoundInnerBlocksDirectInsert: compoundInnerBlocksPresetDefinition.directInsert ? "true" : "false",
|
|
142
|
+
compoundInnerBlocksOrientation: compoundInnerBlocksOrientation,
|
|
143
|
+
compoundInnerBlocksOrientationExpression: compoundInnerBlocksPresetDefinition.orientation
|
|
144
|
+
? `'${compoundInnerBlocksPresetDefinition.orientation}'`
|
|
145
|
+
: "undefined",
|
|
146
|
+
compoundInnerBlocksPreset,
|
|
147
|
+
compoundInnerBlocksPresetDescription: compoundInnerBlocksPresetDefinition.description,
|
|
148
|
+
compoundInnerBlocksPresetLabel: compoundInnerBlocksPresetDefinition.label,
|
|
149
|
+
compoundInnerBlocksTemplateLockExpression: compoundInnerBlocksPresetDefinition.templateLock === false
|
|
150
|
+
? "false"
|
|
151
|
+
: `'${compoundInnerBlocksPresetDefinition.templateLock}'`,
|
|
152
|
+
hasAlternateEmailRenderTarget: hasAlternateEmailRenderTarget
|
|
153
|
+
? "true"
|
|
154
|
+
: "false",
|
|
155
|
+
hasAlternateMjmlRenderTarget: hasAlternateMjmlRenderTarget
|
|
156
|
+
? "true"
|
|
157
|
+
: "false",
|
|
158
|
+
hasAlternatePlainTextRenderTarget: hasAlternatePlainTextRenderTarget
|
|
159
|
+
? "true"
|
|
160
|
+
: "false",
|
|
161
|
+
hasAlternateRenderTargets: alternateRenderTargets.length > 0
|
|
162
|
+
? "true"
|
|
163
|
+
: "false",
|
|
120
164
|
projectToolsPackageVersion,
|
|
121
165
|
cssClassName,
|
|
122
166
|
dashCase: slug,
|
|
@@ -163,4 +207,206 @@ export function buildTemplateVariablesFromBlockSpec(spec) {
|
|
|
163
207
|
titleCase: pascalCase,
|
|
164
208
|
persistencePolicy,
|
|
165
209
|
};
|
|
210
|
+
const shared = {
|
|
211
|
+
author: spec.project.author,
|
|
212
|
+
blockMetadataVersion: BUILTIN_BLOCK_METADATA_VERSION,
|
|
213
|
+
category: spec.metadata.category,
|
|
214
|
+
cssClassName,
|
|
215
|
+
description: spec.metadata.description,
|
|
216
|
+
descriptionJson: flatVariables.descriptionJson,
|
|
217
|
+
frontendCssClassName: flatVariables.frontendCssClassName,
|
|
218
|
+
icon: spec.metadata.icon,
|
|
219
|
+
keyword: spec.metadata.keyword,
|
|
220
|
+
namespace,
|
|
221
|
+
pascalCase,
|
|
222
|
+
phpPrefix,
|
|
223
|
+
phpPrefixUpper,
|
|
224
|
+
slug,
|
|
225
|
+
slugCamelCase: flatVariables.slugCamelCase,
|
|
226
|
+
slugKebabCase: slug,
|
|
227
|
+
slugSnakeCase,
|
|
228
|
+
textDomain,
|
|
229
|
+
title,
|
|
230
|
+
titleCase: pascalCase,
|
|
231
|
+
titleJson: flatVariables.titleJson,
|
|
232
|
+
versions: {
|
|
233
|
+
apiClient: apiClientPackageVersion,
|
|
234
|
+
blockRuntime: blockRuntimePackageVersion,
|
|
235
|
+
blockTypes: blockTypesPackageVersion,
|
|
236
|
+
projectTools: projectToolsPackageVersion,
|
|
237
|
+
rest: restPackageVersion,
|
|
238
|
+
},
|
|
239
|
+
};
|
|
240
|
+
const alternateRenderTargetsGroup = {
|
|
241
|
+
csv: flatVariables.alternateRenderTargetsCsv,
|
|
242
|
+
enabled: alternateRenderTargets.length > 0,
|
|
243
|
+
hasEmail: hasAlternateEmailRenderTarget,
|
|
244
|
+
hasMjml: hasAlternateMjmlRenderTarget,
|
|
245
|
+
hasPlainText: hasAlternatePlainTextRenderTarget,
|
|
246
|
+
json: flatVariables.alternateRenderTargetsJson,
|
|
247
|
+
targets: alternateRenderTargets,
|
|
248
|
+
};
|
|
249
|
+
const compoundGroup = {
|
|
250
|
+
child: {
|
|
251
|
+
category: COMPOUND_CHILD_BLOCK_METADATA_DEFAULTS.category,
|
|
252
|
+
cssClassName: compoundChildCssClassName,
|
|
253
|
+
icon: COMPOUND_CHILD_BLOCK_METADATA_DEFAULTS.icon,
|
|
254
|
+
title: compoundChildTitle,
|
|
255
|
+
titleJson: JSON.stringify(compoundChildTitle),
|
|
256
|
+
},
|
|
257
|
+
enabled: true,
|
|
258
|
+
innerBlocks: {
|
|
259
|
+
description: compoundInnerBlocksPresetDefinition.description,
|
|
260
|
+
directInsert: compoundInnerBlocksPresetDefinition.directInsert,
|
|
261
|
+
label: compoundInnerBlocksPresetDefinition.label,
|
|
262
|
+
orientation: compoundInnerBlocksOrientation,
|
|
263
|
+
orientationExpression: compoundInnerBlocksPresetDefinition.orientation
|
|
264
|
+
? `'${compoundInnerBlocksPresetDefinition.orientation}'`
|
|
265
|
+
: "undefined",
|
|
266
|
+
preset: compoundInnerBlocksPreset,
|
|
267
|
+
templateLockExpression: compoundInnerBlocksPresetDefinition.templateLock === false
|
|
268
|
+
? "false"
|
|
269
|
+
: `'${compoundInnerBlocksPresetDefinition.templateLock}'`,
|
|
270
|
+
},
|
|
271
|
+
persistenceEnabled: persistenceEnabled,
|
|
272
|
+
};
|
|
273
|
+
const persistenceGroup = persistenceEnabled
|
|
274
|
+
? {
|
|
275
|
+
auth: {
|
|
276
|
+
bootstrapCredentialDeclarations: flatVariables.bootstrapCredentialDeclarations,
|
|
277
|
+
descriptionJson: flatVariables.persistencePolicyDescriptionJson,
|
|
278
|
+
intent: flatVariables.restWriteAuthIntent,
|
|
279
|
+
isAuthenticated: persistencePolicy === "authenticated",
|
|
280
|
+
isPublic: persistencePolicy === "public",
|
|
281
|
+
mechanism: flatVariables.restWriteAuthMechanism,
|
|
282
|
+
mode: flatVariables.restWriteAuthMode,
|
|
283
|
+
publicWriteRequestIdDeclaration: flatVariables.publicWriteRequestIdDeclaration,
|
|
284
|
+
},
|
|
285
|
+
dataStorageMode,
|
|
286
|
+
enabled: true,
|
|
287
|
+
policy: persistencePolicy,
|
|
288
|
+
scope: spec.persistence.scope,
|
|
289
|
+
}
|
|
290
|
+
: null;
|
|
291
|
+
const queryLoopGroup = {
|
|
292
|
+
allowedControls: spec.queryLoop.allowedControls,
|
|
293
|
+
allowedControlsJson: flatVariables.queryAllowedControlsJson,
|
|
294
|
+
enabled: true,
|
|
295
|
+
postType: spec.queryLoop.postType,
|
|
296
|
+
postTypeJson: flatVariables.queryPostTypeJson,
|
|
297
|
+
variationNamespace: queryVariationNamespace,
|
|
298
|
+
variationNamespaceJson: flatVariables.queryVariationNamespaceJson,
|
|
299
|
+
};
|
|
300
|
+
switch (spec.template.family) {
|
|
301
|
+
case "basic":
|
|
302
|
+
return attachScaffoldTemplateVariableGroups(flatVariables, {
|
|
303
|
+
alternateRenderTargets: alternateRenderTargetsGroup,
|
|
304
|
+
compound: {
|
|
305
|
+
enabled: false,
|
|
306
|
+
persistenceEnabled: false,
|
|
307
|
+
},
|
|
308
|
+
persistence: {
|
|
309
|
+
enabled: false,
|
|
310
|
+
scope: "none",
|
|
311
|
+
},
|
|
312
|
+
queryLoop: {
|
|
313
|
+
enabled: false,
|
|
314
|
+
},
|
|
315
|
+
shared,
|
|
316
|
+
template: {
|
|
317
|
+
description: spec.template.description,
|
|
318
|
+
},
|
|
319
|
+
templateFamily: "basic",
|
|
320
|
+
});
|
|
321
|
+
case "interactivity":
|
|
322
|
+
return attachScaffoldTemplateVariableGroups(flatVariables, {
|
|
323
|
+
alternateRenderTargets: alternateRenderTargetsGroup,
|
|
324
|
+
compound: {
|
|
325
|
+
enabled: false,
|
|
326
|
+
persistenceEnabled: false,
|
|
327
|
+
},
|
|
328
|
+
persistence: {
|
|
329
|
+
enabled: false,
|
|
330
|
+
scope: "none",
|
|
331
|
+
},
|
|
332
|
+
queryLoop: {
|
|
333
|
+
enabled: false,
|
|
334
|
+
},
|
|
335
|
+
shared,
|
|
336
|
+
template: {
|
|
337
|
+
description: spec.template.description,
|
|
338
|
+
},
|
|
339
|
+
templateFamily: "interactivity",
|
|
340
|
+
});
|
|
341
|
+
case "persistence": {
|
|
342
|
+
if (persistenceGroup === null) {
|
|
343
|
+
throw new Error("Persistence scaffolds must provide persistence template variables.");
|
|
344
|
+
}
|
|
345
|
+
return attachScaffoldTemplateVariableGroups(flatVariables, {
|
|
346
|
+
alternateRenderTargets: alternateRenderTargetsGroup,
|
|
347
|
+
compound: {
|
|
348
|
+
enabled: false,
|
|
349
|
+
persistenceEnabled: false,
|
|
350
|
+
},
|
|
351
|
+
persistence: {
|
|
352
|
+
...persistenceGroup,
|
|
353
|
+
scope: "single",
|
|
354
|
+
},
|
|
355
|
+
queryLoop: {
|
|
356
|
+
enabled: false,
|
|
357
|
+
},
|
|
358
|
+
shared,
|
|
359
|
+
template: {
|
|
360
|
+
description: spec.template.description,
|
|
361
|
+
},
|
|
362
|
+
templateFamily: "persistence",
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
case "compound": {
|
|
366
|
+
const compoundPersistenceGroup = persistenceGroup === null
|
|
367
|
+
? {
|
|
368
|
+
enabled: false,
|
|
369
|
+
scope: "none",
|
|
370
|
+
}
|
|
371
|
+
: {
|
|
372
|
+
...persistenceGroup,
|
|
373
|
+
scope: "compound-parent",
|
|
374
|
+
};
|
|
375
|
+
return attachScaffoldTemplateVariableGroups(flatVariables, {
|
|
376
|
+
alternateRenderTargets: alternateRenderTargetsGroup,
|
|
377
|
+
compound: compoundGroup,
|
|
378
|
+
persistence: compoundPersistenceGroup,
|
|
379
|
+
queryLoop: {
|
|
380
|
+
enabled: false,
|
|
381
|
+
},
|
|
382
|
+
shared,
|
|
383
|
+
template: {
|
|
384
|
+
description: spec.template.description,
|
|
385
|
+
},
|
|
386
|
+
templateFamily: "compound",
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
case "query-loop":
|
|
390
|
+
return attachScaffoldTemplateVariableGroups(flatVariables, {
|
|
391
|
+
alternateRenderTargets: alternateRenderTargetsGroup,
|
|
392
|
+
compound: {
|
|
393
|
+
enabled: false,
|
|
394
|
+
persistenceEnabled: false,
|
|
395
|
+
},
|
|
396
|
+
persistence: {
|
|
397
|
+
enabled: false,
|
|
398
|
+
scope: "none",
|
|
399
|
+
},
|
|
400
|
+
queryLoop: queryLoopGroup,
|
|
401
|
+
shared,
|
|
402
|
+
template: {
|
|
403
|
+
description: spec.template.description,
|
|
404
|
+
},
|
|
405
|
+
templateFamily: "query-loop",
|
|
406
|
+
});
|
|
407
|
+
default: {
|
|
408
|
+
const unreachableTemplateFamily = spec.template.family;
|
|
409
|
+
throw new Error(`Unhandled scaffold template family: ${unreachableTemplateFamily}`);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
166
412
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { buildBasicAttributes, buildBlockJsonAttributes, buildCompoundChildAttributes, buildCompoundParentAttributes, buildInteractivityAttributes, buildManifestDocument, buildPersistenceAttributes, DEFAULT_COMPOUND_CHILD_BODY_PLACEHOLDER, } from "./built-in-block-artifact-documents.js";
|
|
2
2
|
import { buildBasicTypesSource, buildCompoundChildTypesSource, buildCompoundTypesSource, buildInteractivityTypesSource, buildPersistenceTypesSource, } from "./built-in-block-artifact-types.js";
|
|
3
|
+
import { getScaffoldTemplateVariableGroups } from "./scaffold-template-variable-groups.js";
|
|
3
4
|
function stringifyBlockJsonDocument(document) {
|
|
4
5
|
return `${JSON.stringify(document, null, "\t")}\n`;
|
|
5
6
|
}
|
|
@@ -103,7 +104,8 @@ function buildPersistenceArtifact(variables) {
|
|
|
103
104
|
}
|
|
104
105
|
function buildCompoundParentArtifact(variables) {
|
|
105
106
|
const attributes = buildCompoundParentAttributes(variables);
|
|
106
|
-
const
|
|
107
|
+
const compoundGroup = getScaffoldTemplateVariableGroups(variables).compound;
|
|
108
|
+
const persistenceEnabled = compoundGroup.enabled && compoundGroup.persistenceEnabled;
|
|
107
109
|
return {
|
|
108
110
|
blockJsonDocument: {
|
|
109
111
|
$schema: "https://schemas.wp.org/trunk/block.json",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { buildBuiltInNonTsArtifacts } from "./built-in-block-non-ts-artifacts.js";
|
|
2
2
|
import { BASIC_EDIT_TEMPLATE, BASIC_INDEX_TEMPLATE, BASIC_SAVE_TEMPLATE, BASIC_VALIDATORS_TEMPLATE, BLOCK_METADATA_WRAPPER_TEMPLATE, COMPOUND_CHILD_EDIT_TEMPLATE, COMPOUND_CHILD_INDEX_TEMPLATE, COMPOUND_CHILD_SAVE_TEMPLATE, COMPOUND_CHILD_VALIDATORS_TEMPLATE, COMPOUND_CHILDREN_TEMPLATE, COMPOUND_LOCAL_HOOKS_TEMPLATE, COMPOUND_PARENT_EDIT_TEMPLATE, COMPOUND_PARENT_INDEX_TEMPLATE, COMPOUND_PARENT_SAVE_TEMPLATE, COMPOUND_PARENT_VALIDATORS_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_EDIT_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_INTERACTIVITY_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_SAVE_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_VALIDATORS_TEMPLATE, INTERACTIVITY_EDIT_TEMPLATE, INTERACTIVITY_INDEX_TEMPLATE, INTERACTIVITY_SAVE_TEMPLATE, INTERACTIVITY_SCRIPT_TEMPLATE, INTERACTIVITY_VALIDATORS_TEMPLATE, MANIFEST_DEFAULTS_DOCUMENT_WRAPPER_TEMPLATE, MANIFEST_DOCUMENT_WRAPPER_TEMPLATE, PERSISTENCE_EDIT_TEMPLATE, PERSISTENCE_INDEX_TEMPLATE, PERSISTENCE_INTERACTIVITY_TEMPLATE, PERSISTENCE_SAVE_TEMPLATE, PERSISTENCE_VALIDATORS_TEMPLATE, QUERY_LOOP_INDEX_TEMPLATE, SHARED_HOOKS_TEMPLATE, } from "./built-in-block-code-templates.js";
|
|
3
|
+
import { getScaffoldTemplateVariableGroups } from "./scaffold-template-variable-groups.js";
|
|
3
4
|
import { renderMustacheTemplateString } from "./template-render.js";
|
|
4
5
|
function renderCodeTemplate(template, variables) {
|
|
5
6
|
const rendered = renderMustacheTemplateString(template, variables);
|
|
@@ -98,7 +99,8 @@ function buildInteractivityCodeArtifacts(variables) {
|
|
|
98
99
|
function buildCompoundCodeArtifacts(variables) {
|
|
99
100
|
const parentBasePath = `src/blocks/${variables.slugKebabCase}`;
|
|
100
101
|
const childBasePath = `src/blocks/${variables.slugKebabCase}-item`;
|
|
101
|
-
const
|
|
102
|
+
const compoundGroup = getScaffoldTemplateVariableGroups(variables).compound;
|
|
103
|
+
const compoundPersistenceEnabled = compoundGroup.enabled && compoundGroup.persistenceEnabled;
|
|
102
104
|
return ensureUniqueArtifactPaths([
|
|
103
105
|
createCodeArtifact("src/hooks.ts", SHARED_HOOKS_TEMPLATE, variables),
|
|
104
106
|
...createTypedJsonWrapperArtifacts(parentBasePath, variables),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const COMPOUND_CHILD_EDIT_TEMPLATE = "import type { BlockEditProps } from '@wp-typia/block-types/blocks/registration';\nimport { InnerBlocks, RichText, useBlockProps } from '@wordpress/block-editor';\nimport { Notice } from '@wordpress/components';\nimport { __ } from '@wordpress/i18n';\n\nimport metadata from './block-metadata';\nimport {\n\
|
|
1
|
+
export declare const COMPOUND_CHILD_EDIT_TEMPLATE = "import type { BlockEditProps } from '@wp-typia/block-types/blocks/registration';\nimport { InnerBlocks, RichText, useBlockProps } from '@wordpress/block-editor';\nimport { Notice } from '@wordpress/components';\nimport { __ } from '@wordpress/i18n';\n\nimport metadata from './block-metadata';\nimport {\n\tgetChildInnerBlocksPropsOptions,\n\thasNestedChildBlocks,\n} from '../{{slugKebabCase}}/children';\nimport { useTypiaValidation } from './hooks';\nimport type { {{pascalCase}}ItemAttributes } from './types';\nimport {\n\tcreateAttributeUpdater,\n\tvalidate{{pascalCase}}ItemAttributes,\n} from './validators';\n\ntype EditProps = BlockEditProps< {{pascalCase}}ItemAttributes >;\ntype CompoundInnerBlocksProps = Parameters< typeof InnerBlocks >[ 0 ] & {\n\tdefaultBlock?: [ string, Record< string, unknown > ];\n\tdirectInsert?: boolean;\n};\n\nconst TypedInnerBlocks = InnerBlocks as unknown as (\n\tprops: CompoundInnerBlocksProps\n) => ReturnType< typeof InnerBlocks >;\n\nexport default function Edit( {\n\tattributes,\n\tsetAttributes,\n}: EditProps ) {\n\tconst updateAttribute = createAttributeUpdater( attributes, setAttributes );\n\tconst { errorMessages, isValid } = useTypiaValidation(\n\t\tattributes,\n\t\tvalidate{{pascalCase}}ItemAttributes\n\t);\n\tconst nestedInnerBlocksPropsOptions = getChildInnerBlocksPropsOptions(\n\t\tmetadata.name\n\t);\n\tconst showsNestedChildren = hasNestedChildBlocks( metadata.name );\n\n\treturn (\n\t\t<div { ...useBlockProps( { className: '{{compoundChildCssClassName}}' } ) }>\n\t\t\t<RichText\n\t\t\t\ttagName=\"h4\"\n\t\t\t\tclassName=\"{{compoundChildCssClassName}}__title\"\n\t\t\t\tvalue={ attributes.title ?? '' }\n\t\t\t\tonChange={ ( title ) => updateAttribute( 'title', title ) }\n\t\t\t\tplaceholder={ __( {{compoundChildTitleJson}}, '{{textDomain}}' ) }\n\t\t\t/>\n\t\t\t<RichText\n\t\t\t\ttagName=\"p\"\n\t\t\t\tclassName=\"{{compoundChildCssClassName}}__body\"\n\t\t\t\tvalue={ attributes.body ?? '' }\n\t\t\t\tonChange={ ( body ) => updateAttribute( 'body', body ) }\n\t\t\t\tplaceholder={ __( 'Add supporting details for this internal item.', '{{textDomain}}' ) }\n\t\t\t/>\n\t\t\t{ ! isValid && (\n\t\t\t\t<Notice status=\"error\" isDismissible={ false }>\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t{ errorMessages.map( ( error, index ) => <li key={ index }>{ error }</li> ) }\n\t\t\t\t\t</ul>\n\t\t\t\t</Notice>\n\t\t\t) }\n\t\t\t{ showsNestedChildren && (\n\t\t\t\t<div className=\"{{compoundChildCssClassName}}__children\">\n\t\t\t\t\t<TypedInnerBlocks\n\t\t\t\t\t\t{ ...( nestedInnerBlocksPropsOptions ?? {} ) }\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t) }\n\t\t</div>\n\t);\n}\n";
|
|
2
2
|
export declare const COMPOUND_CHILD_SAVE_TEMPLATE = "import { InnerBlocks, RichText, useBlockProps } from '@wordpress/block-editor';\n\nimport metadata from './block-metadata';\nimport { hasNestedChildBlocks } from '../{{slugKebabCase}}/children';\nimport type { {{pascalCase}}ItemAttributes } from './types';\n\nexport default function Save( {\n\tattributes,\n}: {\n\tattributes: {{pascalCase}}ItemAttributes;\n} ) {\n\tconst showsNestedChildren = hasNestedChildBlocks( metadata.name );\n\n\treturn (\n\t\t<div { ...useBlockProps.save( { className: '{{compoundChildCssClassName}}' } ) }>\n\t\t\t<RichText.Content\n\t\t\t\ttagName=\"h4\"\n\t\t\t\tclassName=\"{{compoundChildCssClassName}}__title\"\n\t\t\t\tvalue={ attributes.title }\n\t\t\t/>\n\t\t\t<RichText.Content\n\t\t\t\ttagName=\"p\"\n\t\t\t\tclassName=\"{{compoundChildCssClassName}}__body\"\n\t\t\t\tvalue={ attributes.body }\n\t\t\t/>\n\t\t\t{ showsNestedChildren && (\n\t\t\t\t<div className=\"{{compoundChildCssClassName}}__children\">\n\t\t\t\t\t<InnerBlocks.Content />\n\t\t\t\t</div>\n\t\t\t) }\n\t\t</div>\n\t);\n}\n";
|
|
3
3
|
export declare const COMPOUND_CHILD_INDEX_TEMPLATE = "import {\n\tregisterScaffoldBlockType,\n\ttype BlockConfiguration,\n} from '@wp-typia/block-types/blocks/registration';\nimport {\n\tbuildScaffoldBlockRegistration,\n\tparseScaffoldBlockMetadata,\n} from '@wp-typia/block-runtime/blocks';\n\nimport Edit from './edit';\nimport Save from './save';\nimport metadata from './block-metadata';\nimport '../{{slugKebabCase}}/style.scss';\n\nimport type { {{pascalCase}}ItemAttributes } from './types';\n\nconst registration = buildScaffoldBlockRegistration(\n\tparseScaffoldBlockMetadata<BlockConfiguration< {{pascalCase}}ItemAttributes >>( metadata ),\n\t{\n\t\tedit: Edit,\n\t\tsave: Save,\n\t}\n);\n\nregisterScaffoldBlockType(registration.name, registration.settings);\n";
|
|
4
4
|
export declare const COMPOUND_CHILD_VALIDATORS_TEMPLATE = "import typia from 'typia';\nimport currentManifest from './manifest-defaults-document';\nimport type {\n\t{{pascalCase}}ItemAttributes,\n\t{{pascalCase}}ItemValidationResult,\n} from './types';\nimport { createTemplateValidatorToolkit } from '../../validator-toolkit';\n\nconst scaffoldValidators = createTemplateValidatorToolkit< {{pascalCase}}ItemAttributes >( {\n\tassert: typia.createAssert< {{pascalCase}}ItemAttributes >(),\n\tclone: typia.misc.createClone< {{pascalCase}}ItemAttributes >() as (\n\t\tvalue: {{pascalCase}}ItemAttributes,\n\t) => {{pascalCase}}ItemAttributes,\n\tis: typia.createIs< {{pascalCase}}ItemAttributes >(),\n\tmanifest: currentManifest,\n\tprune: typia.misc.createPrune< {{pascalCase}}ItemAttributes >(),\n\trandom: typia.createRandom< {{pascalCase}}ItemAttributes >() as (\n\t\t...args: unknown[]\n\t) => {{pascalCase}}ItemAttributes,\n\tvalidate: typia.createValidate< {{pascalCase}}ItemAttributes >(),\n} );\n\nexport const validate{{pascalCase}}ItemAttributes =\n\tscaffoldValidators.validateAttributes as (\n\t\tattributes: unknown\n\t) => {{pascalCase}}ItemValidationResult;\n\nexport const validators = scaffoldValidators.validators;\n\nexport const sanitize{{pascalCase}}ItemAttributes =\n\tscaffoldValidators.sanitizeAttributes as (\n\t\tattributes: Partial< {{pascalCase}}ItemAttributes >\n\t) => {{pascalCase}}ItemAttributes;\n\nexport const createAttributeUpdater = scaffoldValidators.createAttributeUpdater;\n";
|
|
@@ -5,8 +5,7 @@ import { __ } from '@wordpress/i18n';
|
|
|
5
5
|
|
|
6
6
|
import metadata from './block-metadata';
|
|
7
7
|
import {
|
|
8
|
-
\
|
|
9
|
-
\tgetChildTemplate,
|
|
8
|
+
\tgetChildInnerBlocksPropsOptions,
|
|
10
9
|
\thasNestedChildBlocks,
|
|
11
10
|
} from '../{{slugKebabCase}}/children';
|
|
12
11
|
import { useTypiaValidation } from './hooks';
|
|
@@ -17,6 +16,14 @@ import {
|
|
|
17
16
|
} from './validators';
|
|
18
17
|
|
|
19
18
|
type EditProps = BlockEditProps< {{pascalCase}}ItemAttributes >;
|
|
19
|
+
type CompoundInnerBlocksProps = Parameters< typeof InnerBlocks >[ 0 ] & {
|
|
20
|
+
\tdefaultBlock?: [ string, Record< string, unknown > ];
|
|
21
|
+
\tdirectInsert?: boolean;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const TypedInnerBlocks = InnerBlocks as unknown as (
|
|
25
|
+
\tprops: CompoundInnerBlocksProps
|
|
26
|
+
) => ReturnType< typeof InnerBlocks >;
|
|
20
27
|
|
|
21
28
|
export default function Edit( {
|
|
22
29
|
\tattributes,
|
|
@@ -27,8 +34,9 @@ export default function Edit( {
|
|
|
27
34
|
\t\tattributes,
|
|
28
35
|
\t\tvalidate{{pascalCase}}ItemAttributes
|
|
29
36
|
\t);
|
|
30
|
-
\tconst
|
|
31
|
-
\
|
|
37
|
+
\tconst nestedInnerBlocksPropsOptions = getChildInnerBlocksPropsOptions(
|
|
38
|
+
\t\tmetadata.name
|
|
39
|
+
\t);
|
|
32
40
|
\tconst showsNestedChildren = hasNestedChildBlocks( metadata.name );
|
|
33
41
|
|
|
34
42
|
\treturn (
|
|
@@ -56,11 +64,8 @@ export default function Edit( {
|
|
|
56
64
|
\t\t\t) }
|
|
57
65
|
\t\t\t{ showsNestedChildren && (
|
|
58
66
|
\t\t\t\t<div className="{{compoundChildCssClassName}}__children">
|
|
59
|
-
\t\t\t\t\t<
|
|
60
|
-
\t\t\t\t\t\
|
|
61
|
-
\t\t\t\t\t\trenderAppender={ InnerBlocks.ButtonBlockAppender }
|
|
62
|
-
\t\t\t\t\t\ttemplate={ nestedTemplate }
|
|
63
|
-
\t\t\t\t\t\ttemplateLock={ false }
|
|
67
|
+
\t\t\t\t\t<TypedInnerBlocks
|
|
68
|
+
\t\t\t\t\t\t{ ...( nestedInnerBlocksPropsOptions ?? {} ) }
|
|
64
69
|
\t\t\t\t\t/>
|
|
65
70
|
\t\t\t\t</div>
|
|
66
71
|
\t\t\t) }
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export declare const COMPOUND_PARENT_EDIT_TEMPLATE = "import type { BlockEditProps } from '@wp-typia/block-types/blocks/registration';\nimport { __ } from '@wordpress/i18n';\nimport {\n\tInspectorControls,\n\tInnerBlocks,\n\tRichText,\n\tuseBlockProps,\n} from '@wordpress/block-editor';\nimport { Notice, PanelBody, ToggleControl } from '@wordpress/components';\n\nimport {\n\
|
|
1
|
+
export declare const COMPOUND_PARENT_EDIT_TEMPLATE = "import type { BlockEditProps } from '@wp-typia/block-types/blocks/registration';\nimport { __ } from '@wordpress/i18n';\nimport {\n\tInspectorControls,\n\tInnerBlocks,\n\tRichText,\n\tuseBlockProps,\n} from '@wordpress/block-editor';\nimport { Notice, PanelBody, ToggleControl } from '@wordpress/components';\n\nimport {\n\tgetRootInnerBlocksPropsOptions,\n} from './children';\nimport { useTypiaValidation } from './hooks';\nimport type { {{pascalCase}}Attributes } from './types';\nimport {\n\tcreateAttributeUpdater,\n\tvalidate{{pascalCase}}Attributes,\n} from './validators';\n\ntype EditProps = BlockEditProps< {{pascalCase}}Attributes >;\ntype CompoundInnerBlocksProps = Parameters< typeof InnerBlocks >[ 0 ] & {\n\tdefaultBlock?: [ string, Record< string, unknown > ];\n\tdirectInsert?: boolean;\n};\n\nconst TypedInnerBlocks = InnerBlocks as unknown as (\n\tprops: CompoundInnerBlocksProps\n) => ReturnType< typeof InnerBlocks >;\n\nexport default function Edit( {\n\tattributes,\n\tsetAttributes,\n}: EditProps ) {\n\tconst { errorMessages, isValid } = useTypiaValidation(\n\t\tattributes,\n\t\tvalidate{{pascalCase}}Attributes\n\t);\n\tconst updateAttribute = createAttributeUpdater( attributes, setAttributes );\n\tconst blockProps = useBlockProps( {\n\t\tclassName: '{{cssClassName}}',\n\t} );\n\tconst rootInnerBlocksPropsOptions = getRootInnerBlocksPropsOptions();\n\n\treturn (\n\t\t<>\n\t\t\t<InspectorControls>\n\t\t\t\t<PanelBody title={ __( 'Compound Settings', '{{textDomain}}' ) }>\n\t\t\t\t\t<ToggleControl\n\t\t\t\t\t\tlabel={ __( 'Show dividers between items', '{{textDomain}}' ) }\n\t\t\t\t\t\tchecked={ attributes.showDividers ?? true }\n\t\t\t\t\t\tonChange={ ( value ) => updateAttribute( 'showDividers', value ) }\n\t\t\t\t\t/>\n\t\t\t\t</PanelBody>\n\t\t\t\t{ ! isValid && (\n\t\t\t\t\t<PanelBody title={ __( 'Validation Errors', '{{textDomain}}' ) } initialOpen>\n\t\t\t\t\t\t{ errorMessages.map( ( error, index ) => (\n\t\t\t\t\t\t\t<Notice key={ index } status=\"error\" isDismissible={ false }>\n\t\t\t\t\t\t\t\t{ error }\n\t\t\t\t\t\t\t</Notice>\n\t\t\t\t\t\t) ) }\n\t\t\t\t\t</PanelBody>\n\t\t\t\t) }\n\t\t\t</InspectorControls>\n\t\t\t<div { ...blockProps }>\n\t\t\t\t<RichText\n\t\t\t\t\ttagName=\"h3\"\n\t\t\t\t\tclassName=\"{{cssClassName}}__heading\"\n\t\t\t\t\tvalue={ attributes.heading }\n\t\t\t\t\tonChange={ ( heading ) => updateAttribute( 'heading', heading ) }\n\t\t\t\t\tplaceholder={ __( {{titleJson}}, '{{textDomain}}' ) }\n\t\t\t\t/>\n\t\t\t\t<RichText\n\t\t\t\t\ttagName=\"p\"\n\t\t\t\t\tclassName=\"{{cssClassName}}__intro\"\n\t\t\t\t\tvalue={ attributes.intro ?? '' }\n\t\t\t\t\tonChange={ ( intro ) => updateAttribute( 'intro', intro ) }\n\t\t\t\t\tplaceholder={ __(\n\t\t\t\t\t\t'Add and reorder internal items inside this compound block.',\n\t\t\t\t\t\t'{{textDomain}}'\n\t\t\t\t\t) }\n\t\t\t\t/>\n\t\t\t\t{ ! isValid && (\n\t\t\t\t\t<Notice status=\"error\" isDismissible={ false }>\n\t\t\t\t\t\t<ul>\n\t\t\t\t\t\t\t{ errorMessages.map( ( error, index ) => <li key={ index }>{ error }</li> ) }\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</Notice>\n\t\t\t\t) }\n\t\t\t\t<div className=\"{{cssClassName}}__items\">\n\t\t\t\t\t<TypedInnerBlocks { ...rootInnerBlocksPropsOptions } />\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</>\n\t);\n}\n";
|
|
2
2
|
export declare const COMPOUND_PARENT_SAVE_TEMPLATE = "import { InnerBlocks, RichText, useBlockProps } from '@wordpress/block-editor';\n\nimport type { {{pascalCase}}Attributes } from './types';\n\nexport default function Save( {\n\tattributes,\n}: {\n\tattributes: {{pascalCase}}Attributes;\n} ) {\n\treturn (\n\t\t<div\n\t\t\t{ ...useBlockProps.save( {\n\t\t\t\tclassName: '{{cssClassName}}',\n\t\t\t\t'data-show-dividers': ( attributes.showDividers ?? true ) ? 'true' : 'false',\n\t\t\t} ) }\n\t\t>\n\t\t\t<RichText.Content\n\t\t\t\ttagName=\"h3\"\n\t\t\t\tclassName=\"{{cssClassName}}__heading\"\n\t\t\t\tvalue={ attributes.heading }\n\t\t\t/>\n\t\t\t<RichText.Content\n\t\t\t\ttagName=\"p\"\n\t\t\t\tclassName=\"{{cssClassName}}__intro\"\n\t\t\t\tvalue={ attributes.intro ?? '' }\n\t\t\t/>\n\t\t\t<div className=\"{{cssClassName}}__items\">\n\t\t\t\t<InnerBlocks.Content />\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n";
|
|
3
3
|
export declare const COMPOUND_PARENT_INDEX_TEMPLATE = "import {\n\tregisterScaffoldBlockType,\n\ttype BlockConfiguration,\n} from '@wp-typia/block-types/blocks/registration';\nimport {\n\tbuildScaffoldBlockRegistration,\n\tparseScaffoldBlockMetadata,\n} from '@wp-typia/block-runtime/blocks';\n\nimport Edit from './edit';\nimport Save from './save';\nimport metadata from './block-metadata';\nimport './style.scss';\n\nimport type { {{pascalCase}}Attributes } from './types';\n\nconst registration = buildScaffoldBlockRegistration(\n\tparseScaffoldBlockMetadata<BlockConfiguration< {{pascalCase}}Attributes >>( metadata ),\n\t{\n\t\tedit: Edit,\n\t\tsave: Save,\n\t}\n);\n\nregisterScaffoldBlockType(registration.name, registration.settings);\n";
|
|
4
4
|
export declare const COMPOUND_LOCAL_HOOKS_TEMPLATE = "export {\n\tformatValidationError,\n\tformatValidationErrors,\n\tuseTypiaValidation,\n} from '../../hooks';\n\nexport type {\n\tTypiaValidationError,\n\tValidationResult,\n\tValidationState,\n} from '../../hooks';\n";
|
|
5
5
|
export declare const COMPOUND_PARENT_VALIDATORS_TEMPLATE = "import typia from 'typia';\nimport currentManifest from './manifest-defaults-document';\nimport type {\n\t{{pascalCase}}Attributes,\n\t{{pascalCase}}ValidationResult,\n} from './types';\nimport { createTemplateValidatorToolkit } from '../../validator-toolkit';\n\nconst scaffoldValidators = createTemplateValidatorToolkit< {{pascalCase}}Attributes >( {\n\tassert: typia.createAssert< {{pascalCase}}Attributes >(),\n\tclone: typia.misc.createClone< {{pascalCase}}Attributes >() as (\n\t\tvalue: {{pascalCase}}Attributes,\n\t) => {{pascalCase}}Attributes,\n\tis: typia.createIs< {{pascalCase}}Attributes >(),\n\tmanifest: currentManifest,\n\tprune: typia.misc.createPrune< {{pascalCase}}Attributes >(),\n\trandom: typia.createRandom< {{pascalCase}}Attributes >() as (\n\t\t...args: unknown[]\n\t) => {{pascalCase}}Attributes,\n\tvalidate: typia.createValidate< {{pascalCase}}Attributes >(),\n} );\n\nexport const validate{{pascalCase}}Attributes =\n\tscaffoldValidators.validateAttributes as (\n\t\tattributes: unknown\n\t) => {{pascalCase}}ValidationResult;\n\nexport const validators = scaffoldValidators.validators;\n\nexport const sanitize{{pascalCase}}Attributes =\n\tscaffoldValidators.sanitizeAttributes as (\n\t\tattributes: Partial< {{pascalCase}}Attributes >\n\t) => {{pascalCase}}Attributes;\n\nexport const createAttributeUpdater = scaffoldValidators.createAttributeUpdater;\n";
|
|
6
|
-
export declare const COMPOUND_CHILDREN_TEMPLATE = "import type { BlockTemplate } from '@wp-typia/block-types/blocks/registration';\n\nexport const DEFAULT_CHILD_BLOCK_NAME = '{{namespace}}/{{slugKebabCase}}-item';\n\nexport interface CompoundChildSpec {\n\tancestorKeys: string[];\n\tblockName: string;\n\tbodyPlaceholder: string;\n\tcontainer: boolean;\n\tfolderSlug: string;\n\tkey: string;\n\tplacement: 'nested' | 'root';\n\tsupportsInserter: boolean;\n\ttemplateInstances: Array< Record< string, unknown > >;\n\ttitle: string;\n}\n\nconst ROOT_BLOCK_NAME = '{{namespace}}/{{slugKebabCase}}';\n\nexport const COMPOUND_CHILD_SPECS: CompoundChildSpec[] = [\n\t{\n\t\tancestorKeys: [],\n\t\tblockName: DEFAULT_CHILD_BLOCK_NAME,\n\t\tbodyPlaceholder: 'Add supporting details for this internal item.',\n\t\tcontainer: false,\n\t\tfolderSlug: '{{slugKebabCase}}-item',\n\t\tkey: 'item',\n\t\tplacement: 'root',\n\t\tsupportsInserter: false,\n\t\ttemplateInstances: [\n\t\t\t{\n\t\t\t\tbody: 'Add supporting details for the first internal item.',\n\t\t\t\ttitle: 'First Item',\n\t\t\t},\n\t\t\t{\n\t\t\t\tbody: 'Add supporting details for the second internal item.',\n\t\t\t\ttitle: 'Second Item',\n\t\t\t},\n\t\t],\n\t\ttitle: '{{compoundChildTitle}}',\n\t},\n\t// add-child: insert new child specs here\n];\n\nfunction
|
|
6
|
+
export declare const COMPOUND_CHILDREN_TEMPLATE = "import type { BlockTemplate } from '@wp-typia/block-types/blocks/registration';\nimport { InnerBlocks } from '@wordpress/block-editor';\n\nexport const DEFAULT_CHILD_BLOCK_NAME = '{{namespace}}/{{slugKebabCase}}-item';\n\nexport interface CompoundChildSpec {\n\tancestorKeys: string[];\n\tblockName: string;\n\tbodyPlaceholder: string;\n\tcontainer: boolean;\n\tfolderSlug: string;\n\tkey: string;\n\tplacement: 'nested' | 'root';\n\tsupportsInserter: boolean;\n\ttemplateInstances: Array< Record< string, unknown > >;\n\ttitle: string;\n}\n\nexport interface CompoundInnerBlocksConfig {\n\tdefaultBlock?: [ string, Record< string, unknown > ];\n\tdirectInsert: boolean;\n\torientation?: 'horizontal' | 'vertical';\n\ttemplate?: BlockTemplate;\n\ttemplateLock: false | 'insert' | 'all';\n}\n\nexport type CompoundInnerBlocksPropsOptions = CompoundInnerBlocksConfig & {\n\trenderAppender?: typeof InnerBlocks.ButtonBlockAppender;\n};\n\nexport const ROOT_INNER_BLOCKS_PRESET_ID = '{{compoundInnerBlocksPreset}}';\nexport const ROOT_INNER_BLOCKS_PRESET_DESCRIPTION =\n\t'{{compoundInnerBlocksPresetDescription}}';\n\nconst BASE_INNER_BLOCKS_CONFIG: Omit<\n\tCompoundInnerBlocksConfig,\n\t'defaultBlock' | 'template'\n> = {\n\tdirectInsert: {{compoundInnerBlocksDirectInsert}},\n\torientation: {{compoundInnerBlocksOrientationExpression}},\n\ttemplateLock: {{compoundInnerBlocksTemplateLockExpression}},\n};\n\nconst ROOT_BLOCK_NAME = '{{namespace}}/{{slugKebabCase}}';\n\nexport const COMPOUND_CHILD_SPECS: CompoundChildSpec[] = [\n\t{\n\t\tancestorKeys: [],\n\t\tblockName: DEFAULT_CHILD_BLOCK_NAME,\n\t\tbodyPlaceholder: 'Add supporting details for this internal item.',\n\t\tcontainer: false,\n\t\tfolderSlug: '{{slugKebabCase}}-item',\n\t\tkey: 'item',\n\t\tplacement: 'root',\n\t\tsupportsInserter: false,\n\t\ttemplateInstances: [\n\t\t\t{\n\t\t\t\tbody: 'Add supporting details for the first internal item.',\n\t\t\t\ttitle: 'First Item',\n\t\t\t},\n\t\t\t{\n\t\t\t\tbody: 'Add supporting details for the second internal item.',\n\t\t\t\ttitle: 'Second Item',\n\t\t\t},\n\t\t],\n\t\ttitle: '{{compoundChildTitle}}',\n\t},\n\t// add-child: insert new child specs here\n];\n\nfunction buildTemplateEntriesForSpec( spec: CompoundChildSpec ): BlockTemplate {\n\tconst nestedTemplate = buildNestedTemplateForKey( spec.key );\n\n\treturn spec.templateInstances.map( ( attributes ) =>\n\t\tnestedTemplate.length > 0\n\t\t\t? [ spec.blockName, attributes, nestedTemplate ]\n\t\t\t: [ spec.blockName, attributes ]\n\t);\n}\n\nfunction buildNestedTemplateForKey( key: string ): BlockTemplate {\n\treturn COMPOUND_CHILD_SPECS.filter(\n\t\t( spec ) =>\n\t\t\tspec.placement === 'nested' &&\n\t\t\tspec.ancestorKeys[ spec.ancestorKeys.length - 1 ] === key\n\t).flatMap( ( spec ) => buildTemplateEntriesForSpec( spec ) );\n}\n\nexport const DEFAULT_CHILD_TEMPLATE: BlockTemplate =\n\tCOMPOUND_CHILD_SPECS.filter( ( spec ) => spec.placement === 'root' ).flatMap(\n\t\t( spec ) => buildTemplateEntriesForSpec( spec )\n\t);\n\nfunction buildDefaultBlockEntry(\n\ttemplate?: BlockTemplate\n): [ string, Record< string, unknown > ] | undefined {\n\tif (\n\t\t! BASE_INNER_BLOCKS_CONFIG.directInsert ||\n\t\t! Array.isArray( template ) ||\n\t\ttemplate.length === 0 ||\n\t\ttypeof template[ 0 ]?.[ 0 ] !== 'string'\n\t) {\n\t\treturn undefined;\n\t}\n\n\treturn [ template[ 0 ][ 0 ], {} ];\n}\n\nfunction buildInnerBlocksPropsOptions(\n\tconfig: CompoundInnerBlocksConfig\n): CompoundInnerBlocksPropsOptions {\n\treturn {\n\t\t...config,\n\t\trenderAppender:\n\t\t\tconfig.templateLock === 'all'\n\t\t\t\t? undefined\n\t\t\t\t: InnerBlocks.ButtonBlockAppender,\n\t};\n}\n\nexport function getRootInnerBlocksConfig(): CompoundInnerBlocksConfig {\n\treturn {\n\t\t...BASE_INNER_BLOCKS_CONFIG,\n\t\tdefaultBlock: buildDefaultBlockEntry( DEFAULT_CHILD_TEMPLATE ),\n\t\ttemplate: DEFAULT_CHILD_TEMPLATE,\n\t};\n}\n\nexport function getRootInnerBlocksPropsOptions(): CompoundInnerBlocksPropsOptions {\n\treturn buildInnerBlocksPropsOptions( getRootInnerBlocksConfig() );\n}\n\nexport function getChildSpec( blockName: string ): CompoundChildSpec | undefined {\n\treturn COMPOUND_CHILD_SPECS.find( ( spec ) => spec.blockName === blockName );\n}\n\nexport function getChildTemplate(\n\tblockName: string\n): BlockTemplate | undefined {\n\tconst childSpec = getChildSpec( blockName );\n\tif ( ! childSpec ) {\n\t\treturn undefined;\n\t}\n\n\tconst nestedTemplate = buildNestedTemplateForKey( childSpec.key );\n\tif ( nestedTemplate.length > 0 ) {\n\t\treturn nestedTemplate;\n\t}\n\n\treturn childSpec.container ? [] : undefined;\n}\n\nexport function getChildInnerBlocksConfig(\n\tblockName: string\n): CompoundInnerBlocksConfig | undefined {\n\tconst childSpec = getChildSpec( blockName );\n\tif ( ! childSpec ) {\n\t\treturn undefined;\n\t}\n\n\tconst template = getChildTemplate( blockName );\n\n\tif ( ! childSpec.container && ! template ) {\n\t\treturn undefined;\n\t}\n\n\treturn {\n\t\t...BASE_INNER_BLOCKS_CONFIG,\n\t\tdefaultBlock: buildDefaultBlockEntry( template ),\n\t\ttemplate,\n\t};\n}\n\nexport function getChildInnerBlocksPropsOptions(\n\tblockName: string\n): CompoundInnerBlocksPropsOptions | undefined {\n\tconst config = getChildInnerBlocksConfig( blockName );\n\tif ( ! config ) {\n\t\treturn undefined;\n\t}\n\n\treturn buildInnerBlocksPropsOptions( config );\n}\n\nexport function hasNestedChildBlocks( blockName: string ): boolean {\n\tconst childSpec = getChildSpec( blockName );\n\tif ( ! childSpec ) {\n\t\treturn false;\n\t}\n\n\treturn childSpec.container || buildNestedTemplateForKey( childSpec.key ).length > 0;\n}\n\nexport function isRootCompoundChildBlock( blockName: string ): boolean {\n\tconst childSpec = getChildSpec( blockName );\n\treturn childSpec?.placement === 'root';\n}\n\nexport { ROOT_BLOCK_NAME };\n";
|