@wp-typia/project-tools 0.16.2 → 0.16.5

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.
Files changed (80) hide show
  1. package/README.md +13 -0
  2. package/dist/runtime/block-generator-service.d.ts +102 -0
  3. package/dist/runtime/block-generator-service.js +268 -0
  4. package/dist/runtime/built-in-block-artifacts.d.ts +37 -0
  5. package/dist/runtime/built-in-block-artifacts.js +1203 -0
  6. package/dist/runtime/built-in-block-code-artifacts.d.ts +31 -0
  7. package/dist/runtime/built-in-block-code-artifacts.js +137 -0
  8. package/dist/runtime/built-in-block-non-ts-artifacts.d.ts +18 -0
  9. package/dist/runtime/built-in-block-non-ts-artifacts.js +563 -0
  10. package/dist/runtime/cli-doctor.js +10 -5
  11. package/dist/runtime/index.d.ts +2 -0
  12. package/dist/runtime/index.js +1 -0
  13. package/dist/runtime/scaffold-apply-utils.d.ts +47 -0
  14. package/dist/runtime/scaffold-apply-utils.js +405 -0
  15. package/dist/runtime/scaffold-identifiers.d.ts +34 -0
  16. package/dist/runtime/scaffold-identifiers.js +82 -0
  17. package/dist/runtime/scaffold.js +33 -0
  18. package/dist/runtime/starter-manifests.d.ts +3 -2
  19. package/dist/runtime/starter-manifests.js +15 -365
  20. package/dist/runtime/template-builtins.d.ts +9 -0
  21. package/dist/runtime/template-builtins.js +31 -1
  22. package/dist/runtime/template-render.d.ts +5 -0
  23. package/dist/runtime/template-render.js +13 -3
  24. package/dist/runtime/template-source.js +9 -3
  25. package/package.json +2 -2
  26. package/templates/_shared/compound/persistence/scripts/block-config.ts.mustache +4 -4
  27. package/templates/_shared/persistence/core/scripts/sync-rest-contracts.ts.mustache +4 -4
  28. package/templates/_shared/base/src/hooks.ts.mustache +0 -19
  29. package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/block.json.mustache +0 -52
  30. package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/edit.tsx.mustache +0 -123
  31. package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/hooks.ts.mustache +0 -11
  32. package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/interactivity.ts.mustache +0 -305
  33. package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/render.php.mustache +0 -152
  34. package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/save.tsx.mustache +0 -3
  35. package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/types.ts.mustache +0 -61
  36. package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/validators.ts.mustache +0 -43
  37. package/templates/_shared/persistence/core/src/index.tsx.mustache +0 -25
  38. package/templates/_shared/persistence/core/src/interactivity.ts.mustache +0 -308
  39. package/templates/_shared/persistence/core/src/save.tsx.mustache +0 -5
  40. package/templates/_shared/persistence/core/src/validators.ts.mustache +0 -43
  41. package/templates/basic/src/block.json.mustache +0 -51
  42. package/templates/basic/src/edit.tsx.mustache +0 -128
  43. package/templates/basic/src/editor.scss.mustache +0 -8
  44. package/templates/basic/src/hooks.ts.mustache +0 -18
  45. package/templates/basic/src/index.tsx.mustache +0 -45
  46. package/templates/basic/src/render.php.mustache +0 -19
  47. package/templates/basic/src/save.tsx.mustache +0 -30
  48. package/templates/basic/src/style.scss.mustache +0 -40
  49. package/templates/basic/src/types.ts.mustache +0 -56
  50. package/templates/basic/src/validators.ts.mustache +0 -37
  51. package/templates/compound/src/blocks/{{slugKebabCase}}/block.json.mustache +0 -37
  52. package/templates/compound/src/blocks/{{slugKebabCase}}/children.ts.mustache +0 -25
  53. package/templates/compound/src/blocks/{{slugKebabCase}}/edit.tsx.mustache +0 -93
  54. package/templates/compound/src/blocks/{{slugKebabCase}}/hooks.ts.mustache +0 -11
  55. package/templates/compound/src/blocks/{{slugKebabCase}}/index.tsx.mustache +0 -25
  56. package/templates/compound/src/blocks/{{slugKebabCase}}/save.tsx.mustache +0 -32
  57. package/templates/compound/src/blocks/{{slugKebabCase}}/style.scss.mustache +0 -31
  58. package/templates/compound/src/blocks/{{slugKebabCase}}/types.ts.mustache +0 -18
  59. package/templates/compound/src/blocks/{{slugKebabCase}}/validators.ts.mustache +0 -35
  60. package/templates/compound/src/blocks/{{slugKebabCase}}-item/block.json.mustache +0 -35
  61. package/templates/compound/src/blocks/{{slugKebabCase}}-item/edit.tsx.mustache +0 -50
  62. package/templates/compound/src/blocks/{{slugKebabCase}}-item/hooks.ts.mustache +0 -11
  63. package/templates/compound/src/blocks/{{slugKebabCase}}-item/index.tsx.mustache +0 -25
  64. package/templates/compound/src/blocks/{{slugKebabCase}}-item/save.tsx.mustache +0 -24
  65. package/templates/compound/src/blocks/{{slugKebabCase}}-item/types.ts.mustache +0 -17
  66. package/templates/compound/src/blocks/{{slugKebabCase}}-item/validators.ts.mustache +0 -35
  67. package/templates/interactivity/src/block.json.mustache +0 -74
  68. package/templates/interactivity/src/edit.tsx.mustache +0 -270
  69. package/templates/interactivity/src/editor.scss.mustache +0 -8
  70. package/templates/interactivity/src/index.tsx.mustache +0 -33
  71. package/templates/interactivity/src/interactivity.ts.mustache +0 -152
  72. package/templates/interactivity/src/save.tsx.mustache +0 -101
  73. package/templates/interactivity/src/style.scss.mustache +0 -60
  74. package/templates/interactivity/src/types.ts.mustache +0 -32
  75. package/templates/interactivity/src/validators.ts.mustache +0 -47
  76. package/templates/persistence/src/block.json.mustache +0 -52
  77. package/templates/persistence/src/edit.tsx.mustache +0 -165
  78. package/templates/persistence/src/render.php.mustache +0 -120
  79. package/templates/persistence/src/style.scss.mustache +0 -46
  80. package/templates/persistence/src/types.ts.mustache +0 -59
@@ -1,378 +1,28 @@
1
- const ALIGNMENT_VALUES = ["left", "center", "right", "justify"];
2
- const INTERACTIVE_MODE_VALUES = ["click", "hover", "auto"];
3
- const ANIMATION_VALUES = ["none", "bounce", "pulse", "shake", "flip"];
4
- const DEFAULT_COMPOUND_CHILD_BODY_PLACEHOLDER = "Add supporting details for this internal item.";
5
- function createConstraints(overrides = {}) {
6
- return {
7
- exclusiveMaximum: null,
8
- exclusiveMinimum: null,
9
- format: null,
10
- maxLength: null,
11
- maxItems: null,
12
- maximum: null,
13
- minLength: null,
14
- minItems: null,
15
- minimum: null,
16
- multipleOf: null,
17
- pattern: null,
18
- typeTag: null,
19
- ...overrides,
20
- };
21
- }
22
- function createAttribute({ constraints, defaultValue, enumValues = null, kind, required, sourceType, }) {
23
- const hasDefault = defaultValue !== undefined;
24
- return {
25
- ts: {
26
- items: null,
27
- kind,
28
- properties: null,
29
- required,
30
- union: null,
31
- },
32
- typia: {
33
- constraints: createConstraints(constraints),
34
- defaultValue: hasDefault ? defaultValue : null,
35
- hasDefault,
36
- },
37
- wp: {
38
- defaultValue: hasDefault ? defaultValue : null,
39
- enum: enumValues,
40
- hasDefault,
41
- type: sourceType,
42
- },
43
- };
44
- }
45
- function createManifest(sourceType, attributes) {
46
- return {
47
- attributes,
48
- manifestVersion: 2,
49
- sourceType,
50
- };
51
- }
52
- function buildBasicStarterManifest(variables) {
53
- return createManifest(`${variables.pascalCase}Attributes`, {
54
- alignment: createAttribute({
55
- defaultValue: "left",
56
- enumValues: [...ALIGNMENT_VALUES],
57
- kind: "string",
58
- required: false,
59
- sourceType: "string",
60
- }),
61
- className: createAttribute({
62
- constraints: {
63
- maxLength: 100,
64
- },
65
- defaultValue: "",
66
- kind: "string",
67
- required: false,
68
- sourceType: "string",
69
- }),
70
- content: createAttribute({
71
- constraints: {
72
- maxLength: 1000,
73
- },
74
- defaultValue: "",
75
- kind: "string",
76
- required: true,
77
- sourceType: "string",
78
- }),
79
- id: createAttribute({
80
- constraints: {
81
- format: "uuid",
82
- },
83
- kind: "string",
84
- required: false,
85
- sourceType: "string",
86
- }),
87
- isVisible: createAttribute({
88
- defaultValue: true,
89
- kind: "boolean",
90
- required: false,
91
- sourceType: "boolean",
92
- }),
93
- schemaVersion: createAttribute({
94
- constraints: {
95
- typeTag: "uint32",
96
- },
97
- defaultValue: 1,
98
- kind: "number",
99
- required: false,
100
- sourceType: "number",
101
- }),
102
- });
103
- }
104
- function buildInteractivityStarterManifest(variables) {
105
- return createManifest(`${variables.pascalCase}Attributes`, {
106
- alignment: createAttribute({
107
- defaultValue: "left",
108
- enumValues: [...ALIGNMENT_VALUES],
109
- kind: "string",
110
- required: false,
111
- sourceType: "string",
112
- }),
113
- animation: createAttribute({
114
- defaultValue: "none",
115
- enumValues: [...ANIMATION_VALUES],
116
- kind: "string",
117
- required: false,
118
- sourceType: "string",
119
- }),
120
- autoPlayInterval: createAttribute({
121
- constraints: {
122
- minimum: 0,
123
- typeTag: "uint32",
124
- },
125
- defaultValue: 0,
126
- kind: "number",
127
- required: false,
128
- sourceType: "number",
129
- }),
130
- clickCount: createAttribute({
131
- constraints: {
132
- minimum: 0,
133
- typeTag: "uint32",
134
- },
135
- defaultValue: 0,
136
- kind: "number",
137
- required: false,
138
- sourceType: "number",
139
- }),
140
- content: createAttribute({
141
- constraints: {
142
- maxLength: 1000,
143
- },
144
- defaultValue: "",
145
- kind: "string",
146
- required: true,
147
- sourceType: "string",
148
- }),
149
- interactiveMode: createAttribute({
150
- defaultValue: "click",
151
- enumValues: [...INTERACTIVE_MODE_VALUES],
152
- kind: "string",
153
- required: false,
154
- sourceType: "string",
155
- }),
156
- isAnimating: createAttribute({
157
- defaultValue: false,
158
- kind: "boolean",
159
- required: false,
160
- sourceType: "boolean",
161
- }),
162
- isVisible: createAttribute({
163
- defaultValue: true,
164
- kind: "boolean",
165
- required: false,
166
- sourceType: "boolean",
167
- }),
168
- maxClicks: createAttribute({
169
- constraints: {
170
- minimum: 0,
171
- typeTag: "uint32",
172
- },
173
- defaultValue: 10,
174
- kind: "number",
175
- required: false,
176
- sourceType: "number",
177
- }),
178
- showCounter: createAttribute({
179
- defaultValue: true,
180
- kind: "boolean",
181
- required: false,
182
- sourceType: "boolean",
183
- }),
184
- uniqueId: createAttribute({
185
- defaultValue: "",
186
- kind: "string",
187
- required: false,
188
- sourceType: "string",
189
- }),
190
- });
191
- }
192
- function buildPersistenceStarterManifest(variables) {
193
- return createManifest(`${variables.pascalCase}Attributes`, {
194
- alignment: createAttribute({
195
- defaultValue: "left",
196
- enumValues: [...ALIGNMENT_VALUES],
197
- kind: "string",
198
- required: false,
199
- sourceType: "string",
200
- }),
201
- buttonLabel: createAttribute({
202
- constraints: {
203
- maxLength: 40,
204
- minLength: 1,
205
- },
206
- defaultValue: "Persist Count",
207
- kind: "string",
208
- required: false,
209
- sourceType: "string",
210
- }),
211
- content: createAttribute({
212
- constraints: {
213
- maxLength: 250,
214
- minLength: 1,
215
- },
216
- defaultValue: `${variables.title} persistence block`,
217
- kind: "string",
218
- required: true,
219
- sourceType: "string",
220
- }),
221
- isVisible: createAttribute({
222
- defaultValue: true,
223
- kind: "boolean",
224
- required: false,
225
- sourceType: "boolean",
226
- }),
227
- resourceKey: createAttribute({
228
- constraints: {
229
- maxLength: 100,
230
- minLength: 1,
231
- },
232
- defaultValue: "primary",
233
- kind: "string",
234
- required: false,
235
- sourceType: "string",
236
- }),
237
- showCount: createAttribute({
238
- defaultValue: true,
239
- kind: "boolean",
240
- required: false,
241
- sourceType: "boolean",
242
- }),
243
- });
244
- }
245
- function buildCompoundParentStarterManifest(variables) {
246
- const attributes = {
247
- heading: createAttribute({
248
- constraints: {
249
- maxLength: 80,
250
- minLength: 1,
251
- },
252
- defaultValue: variables.title,
253
- kind: "string",
254
- required: true,
255
- sourceType: "string",
256
- }),
257
- intro: createAttribute({
258
- constraints: {
259
- maxLength: 180,
260
- minLength: 1,
261
- },
262
- defaultValue: "Add and reorder internal items inside this compound block.",
263
- kind: "string",
264
- required: false,
265
- sourceType: "string",
266
- }),
267
- showDividers: createAttribute({
268
- defaultValue: true,
269
- kind: "boolean",
270
- required: false,
271
- sourceType: "boolean",
272
- }),
273
- };
274
- if (variables.compoundPersistenceEnabled === "true") {
275
- attributes.showCount = createAttribute({
276
- defaultValue: true,
277
- kind: "boolean",
278
- required: false,
279
- sourceType: "boolean",
280
- });
281
- attributes.buttonLabel = createAttribute({
282
- constraints: {
283
- maxLength: 40,
284
- minLength: 1,
285
- },
286
- defaultValue: "Persist Count",
287
- kind: "string",
288
- required: false,
289
- sourceType: "string",
290
- });
291
- attributes.resourceKey = createAttribute({
292
- constraints: {
293
- maxLength: 100,
294
- minLength: 1,
295
- },
296
- defaultValue: "primary",
297
- kind: "string",
298
- required: false,
299
- sourceType: "string",
300
- });
301
- }
302
- return createManifest(`${variables.pascalCase}Attributes`, attributes);
303
- }
304
- function buildCompoundChildStarterManifest(variables) {
305
- return buildCompoundChildStarterManifestDocument(`${variables.pascalCase}ItemAttributes`, variables.compoundChildTitle);
306
- }
1
+ import { buildBuiltInBlockArtifacts, buildCompoundChildStarterManifestDocument as buildCompoundChildStarterManifestFromArtifacts, } from "./built-in-block-artifacts.js";
307
2
  /**
308
3
  * Builds the starter manifest used by generated compound child blocks.
309
4
  */
310
- export function buildCompoundChildStarterManifestDocument(childTypeName, childTitle, bodyPlaceholder = DEFAULT_COMPOUND_CHILD_BODY_PLACEHOLDER) {
311
- return createManifest(childTypeName, {
312
- body: createAttribute({
313
- constraints: {
314
- maxLength: 280,
315
- minLength: 1,
316
- },
317
- defaultValue: bodyPlaceholder,
318
- kind: "string",
319
- required: true,
320
- sourceType: "string",
321
- }),
322
- title: createAttribute({
323
- constraints: {
324
- maxLength: 80,
325
- minLength: 1,
326
- },
327
- defaultValue: childTitle,
328
- kind: "string",
329
- required: true,
330
- sourceType: "string",
331
- }),
332
- });
5
+ export function buildCompoundChildStarterManifestDocument(childTypeName, childTitle, bodyPlaceholder) {
6
+ return buildCompoundChildStarterManifestFromArtifacts(childTypeName, childTitle, bodyPlaceholder);
333
7
  }
334
8
  /**
335
9
  * Returns the starter manifest files that should be seeded for a built-in
336
10
  * template before the first sync.
337
11
  */
338
12
  export function getStarterManifestFiles(templateId, variables) {
339
- if (templateId === "basic") {
340
- return [
341
- {
342
- document: buildBasicStarterManifest(variables),
343
- relativePath: "src/typia.manifest.json",
344
- },
345
- ];
346
- }
347
- if (templateId === "interactivity") {
348
- return [
349
- {
350
- document: buildInteractivityStarterManifest(variables),
351
- relativePath: "src/typia.manifest.json",
352
- },
353
- ];
354
- }
355
- if (templateId === "persistence") {
356
- return [
357
- {
358
- document: buildPersistenceStarterManifest(variables),
359
- relativePath: "src/typia.manifest.json",
360
- },
361
- ];
362
- }
363
- if (templateId === "compound") {
364
- return [
365
- {
366
- document: buildCompoundParentStarterManifest(variables),
367
- relativePath: `src/blocks/${variables.slugKebabCase}/typia.manifest.json`,
368
- },
369
- {
370
- document: buildCompoundChildStarterManifest(variables),
371
- relativePath: `src/blocks/${variables.slugKebabCase}-item/typia.manifest.json`,
372
- },
373
- ];
13
+ if (templateId !== "basic" &&
14
+ templateId !== "interactivity" &&
15
+ templateId !== "persistence" &&
16
+ templateId !== "compound") {
17
+ return [];
374
18
  }
375
- return [];
19
+ return buildBuiltInBlockArtifacts({
20
+ templateId,
21
+ variables,
22
+ }).map((artifact) => ({
23
+ document: artifact.manifestDocument,
24
+ relativePath: `${artifact.relativeDir}/typia.manifest.json`,
25
+ }));
376
26
  }
377
27
  /**
378
28
  * Serializes a starter manifest using the generated-project JSON formatting
@@ -27,6 +27,15 @@ export interface MaterializedBuiltInTemplateSource {
27
27
  * resolve to the shared base plus their own template directory.
28
28
  */
29
29
  export declare function getBuiltInTemplateLayerDirs(templateId: BuiltInTemplateId, { persistenceEnabled, persistencePolicy, }?: BuiltInTemplateVariantOptions): string[];
30
+ /**
31
+ * Returns whether a missing built-in overlay directory is expected because the
32
+ * template family no longer ships any Mustache assets in that layer.
33
+ *
34
+ * @param templateId Built-in template family being resolved.
35
+ * @param layerDir Candidate overlay directory for that family.
36
+ * @returns True when the missing layer can be skipped safely.
37
+ */
38
+ export declare function isOmittableBuiltInTemplateLayerDir(templateId: BuiltInTemplateId, layerDir: string): boolean;
30
39
  /**
31
40
  * Materializes a built-in template into a temporary directory by copying each
32
41
  * resolved layer in order.
@@ -1,7 +1,13 @@
1
+ import fs from "node:fs";
1
2
  import os from "node:os";
2
3
  import path from "node:path";
3
4
  import { promises as fsp } from "node:fs";
4
5
  import { getTemplateById, SHARED_BASE_TEMPLATE_ROOT, SHARED_COMPOUND_TEMPLATE_ROOT, SHARED_PERSISTENCE_TEMPLATE_ROOT, SHARED_REST_HELPER_TEMPLATE_ROOT, } from "./template-registry.js";
6
+ const OMITTABLE_BUILT_IN_OVERLAY_TEMPLATE_IDS = new Set([
7
+ "basic",
8
+ "persistence",
9
+ "compound",
10
+ ]);
5
11
  /**
6
12
  * Returns the ordered overlay directories for a built-in template.
7
13
  *
@@ -33,6 +39,29 @@ export function getBuiltInTemplateLayerDirs(templateId, { persistenceEnabled = f
33
39
  }
34
40
  return [SHARED_BASE_TEMPLATE_ROOT, getTemplateById(templateId).templateDir];
35
41
  }
42
+ /**
43
+ * Returns whether a missing built-in overlay directory is expected because the
44
+ * template family no longer ships any Mustache assets in that layer.
45
+ *
46
+ * @param templateId Built-in template family being resolved.
47
+ * @param layerDir Candidate overlay directory for that family.
48
+ * @returns True when the missing layer can be skipped safely.
49
+ */
50
+ export function isOmittableBuiltInTemplateLayerDir(templateId, layerDir) {
51
+ return (OMITTABLE_BUILT_IN_OVERLAY_TEMPLATE_IDS.has(templateId) &&
52
+ layerDir === getTemplateById(templateId).templateDir);
53
+ }
54
+ function resolveMaterializedBuiltInTemplateLayerDirs(templateId, options) {
55
+ return getBuiltInTemplateLayerDirs(templateId, options).flatMap((layerDir) => {
56
+ if (fs.existsSync(layerDir)) {
57
+ return [layerDir];
58
+ }
59
+ if (isOmittableBuiltInTemplateLayerDir(templateId, layerDir)) {
60
+ return [];
61
+ }
62
+ throw new Error(`Built-in template layer is missing: ${layerDir}`);
63
+ });
64
+ }
36
65
  /**
37
66
  * Materializes a built-in template into a temporary directory by copying each
38
67
  * resolved layer in order.
@@ -43,11 +72,12 @@ export function getBuiltInTemplateLayerDirs(templateId, { persistenceEnabled = f
43
72
  */
44
73
  export async function resolveBuiltInTemplateSource(templateId, options = {}) {
45
74
  const template = getTemplateById(templateId);
75
+ const layerDirs = resolveMaterializedBuiltInTemplateLayerDirs(templateId, options);
46
76
  const tempRoot = await fsp.mkdtemp(path.join(os.tmpdir(), "wp-typia-template-"));
47
77
  const templateDir = path.join(tempRoot, templateId);
48
78
  try {
49
79
  await fsp.mkdir(templateDir, { recursive: true });
50
- for (const layerDir of getBuiltInTemplateLayerDirs(templateId, options)) {
80
+ for (const layerDir of layerDirs) {
51
81
  await fsp.cp(layerDir, templateDir, {
52
82
  recursive: true,
53
83
  force: true,
@@ -15,6 +15,11 @@ export interface CopyRawDirectoryOptions {
15
15
  */
16
16
  filter?: (sourcePath: string, targetPath: string, entry: fs.Dirent) => boolean | Promise<boolean>;
17
17
  }
18
+ /**
19
+ * Render a Mustache template while keeping HTML escaping disabled only for the
20
+ * current render call.
21
+ */
22
+ export declare function renderMustacheTemplateString(template: string, view: TemplateRenderView): string;
18
23
  /**
19
24
  * Recursively copies a directory tree without rendering template contents.
20
25
  */
@@ -19,9 +19,19 @@ const BINARY_EXTENSIONS = new Set([
19
19
  ".woff",
20
20
  ".woff2",
21
21
  ]);
22
- Mustache.escape = (value) => value;
23
- function renderMustacheTemplateString(template, view) {
24
- return Mustache.render(template, view);
22
+ /**
23
+ * Render a Mustache template while keeping HTML escaping disabled only for the
24
+ * current render call.
25
+ */
26
+ export function renderMustacheTemplateString(template, view) {
27
+ const originalEscape = Mustache.escape;
28
+ Mustache.escape = (value) => value;
29
+ try {
30
+ return Mustache.render(template, view);
31
+ }
32
+ finally {
33
+ Mustache.escape = originalEscape;
34
+ }
25
35
  }
26
36
  function escapeRegExp(value) {
27
37
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -9,10 +9,10 @@ import { pathToFileURL } from "node:url";
9
9
  import npa from "npm-package-arg";
10
10
  import semver from "semver";
11
11
  import { x as extractTarball } from "tar";
12
- import { BUILTIN_TEMPLATE_IDS, PROJECT_TOOLS_PACKAGE_ROOT, SHARED_BASE_TEMPLATE_ROOT, TEMPLATE_ROOT, isBuiltInTemplateId, } from "./template-registry.js";
12
+ import { BUILTIN_TEMPLATE_IDS, PROJECT_TOOLS_PACKAGE_ROOT, isBuiltInTemplateId, } from "./template-registry.js";
13
13
  import { isPlainObject } from "./object-utils.js";
14
14
  import { getRemovedBuiltInTemplateMessage, isRemovedBuiltInTemplateId, } from "./template-defaults.js";
15
- import { resolveBuiltInTemplateSource } from "./template-builtins.js";
15
+ import { getBuiltInTemplateLayerDirs, isOmittableBuiltInTemplateLayerDir, resolveBuiltInTemplateSource, } from "./template-builtins.js";
16
16
  import { getPackageVersions } from "./package-versions.js";
17
17
  import { toSegmentPascalCase } from "./string-case.js";
18
18
  import { copyRawDirectory, copyRenderedDirectory } from "./template-render.js";
@@ -522,7 +522,13 @@ async function normalizeCreateBlockSubset(seed, context) {
522
522
  const blockJson = readRemoteBlockJson(seed.blockDir);
523
523
  const sourceRoot = getSeedSourceRoot(seed.blockDir);
524
524
  await fsp.mkdir(templateDir, { recursive: true });
525
- for (const layerDir of [SHARED_BASE_TEMPLATE_ROOT, path.join(TEMPLATE_ROOT, "basic")]) {
525
+ for (const layerDir of getBuiltInTemplateLayerDirs("basic")) {
526
+ if (!fs.existsSync(layerDir)) {
527
+ if (isOmittableBuiltInTemplateLayerDir("basic", layerDir)) {
528
+ continue;
529
+ }
530
+ throw new Error(`Built-in template layer is missing: ${layerDir}`);
531
+ }
526
532
  await fsp.cp(layerDir, templateDir, {
527
533
  recursive: true,
528
534
  force: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wp-typia/project-tools",
3
- "version": "0.16.2",
3
+ "version": "0.16.5",
4
4
  "description": "Project orchestration and programmatic tooling for wp-typia",
5
5
  "packageManager": "bun@1.3.11",
6
6
  "type": "module",
@@ -75,7 +75,7 @@
75
75
  "prepack": "bun run build && node ./scripts/publish-manifest.mjs prepare",
76
76
  "postpack": "node ./scripts/publish-manifest.mjs restore",
77
77
  "test": "bun run build && bun test tests/*.test.ts",
78
- "test:scaffold-core": "bun run build && bun test tests/scaffold-basic.test.ts tests/scaffold-persistence.test.ts tests/template-source.test.ts tests/cli-entry.test.ts tests/import-policy.test.ts",
78
+ "test:scaffold-core": "bun run build && bun test tests/block-generator-service.test.ts tests/built-in-block-artifacts.test.ts tests/scaffold-basic.test.ts tests/scaffold-persistence.test.ts tests/template-source.test.ts tests/cli-entry.test.ts tests/import-policy.test.ts",
79
79
  "test:workspace": "bun run build && bun test tests/workspace-add.test.ts tests/workspace-doctor.test.ts",
80
80
  "test:compound": "bun run build && bun test tests/scaffold-compound.test.ts",
81
81
  "test:migration-planning": "bun run build && bun test tests/migration-init.test.ts tests/migration-config.test.ts tests/migration-plan-wizard.test.ts",
@@ -31,7 +31,7 @@ export const BLOCKS = [
31
31
  queryContract: 'state-query',
32
32
  responseContract: 'state-response',
33
33
  summary: 'Read the current persisted state.',
34
- tags: [ '{{title}}' ],
34
+ tags: [ {{titleJson}} ],
35
35
  },
36
36
  {
37
37
  auth: '{{restWriteAuthIntent}}',
@@ -41,7 +41,7 @@ export const BLOCKS = [
41
41
  path: '/{{namespace}}/v1/{{slugKebabCase}}/state',
42
42
  responseContract: 'state-response',
43
43
  summary: 'Write the current persisted state.',
44
- tags: [ '{{title}}' ],
44
+ tags: [ {{titleJson}} ],
45
45
  wordpressAuth: {
46
46
  mechanism: '{{restWriteAuthMechanism}}',
47
47
  },
@@ -54,11 +54,11 @@ export const BLOCKS = [
54
54
  queryContract: 'bootstrap-query',
55
55
  responseContract: 'bootstrap-response',
56
56
  summary: 'Read fresh session bootstrap state for the current viewer.',
57
- tags: [ '{{title}}' ],
57
+ tags: [ {{titleJson}} ],
58
58
  },
59
59
  ],
60
60
  info: {
61
- title: '{{title}} REST API',
61
+ title: {{titleJson}} + ' REST API',
62
62
  version: '1.0.0',
63
63
  },
64
64
  } ),
@@ -76,7 +76,7 @@ const REST_ENDPOINT_MANIFEST = defineEndpointManifest( {
76
76
  queryContract: 'state-query',
77
77
  responseContract: 'state-response',
78
78
  summary: 'Read the current persisted state.',
79
- tags: [ '{{title}}' ],
79
+ tags: [ {{titleJson}} ],
80
80
  },
81
81
  {
82
82
  auth: '{{restWriteAuthIntent}}',
@@ -86,7 +86,7 @@ const REST_ENDPOINT_MANIFEST = defineEndpointManifest( {
86
86
  path: '/{{namespace}}/v1/{{slugKebabCase}}/state',
87
87
  responseContract: 'state-response',
88
88
  summary: 'Write the current persisted state.',
89
- tags: [ '{{title}}' ],
89
+ tags: [ {{titleJson}} ],
90
90
  wordpressAuth: {
91
91
  mechanism: '{{restWriteAuthMechanism}}',
92
92
  },
@@ -99,11 +99,11 @@ const REST_ENDPOINT_MANIFEST = defineEndpointManifest( {
99
99
  queryContract: 'bootstrap-query',
100
100
  responseContract: 'bootstrap-response',
101
101
  summary: 'Read fresh session bootstrap state for the current viewer.',
102
- tags: [ '{{title}}' ],
102
+ tags: [ {{titleJson}} ],
103
103
  },
104
104
  ],
105
105
  info: {
106
- title: '{{title}} REST API',
106
+ title: {{titleJson}} + ' REST API',
107
107
  version: '1.0.0',
108
108
  },
109
109
  } );
@@ -1,19 +0,0 @@
1
- import { useMemo } from '@wordpress/element';
2
-
3
- import {
4
- createUseTypiaValidationHook,
5
- formatValidationError,
6
- formatValidationErrors,
7
- } from '@wp-typia/block-runtime/validation';
8
-
9
- export {
10
- formatValidationError,
11
- formatValidationErrors,
12
- type TypiaValidationError,
13
- type ValidationResult,
14
- type ValidationState,
15
- } from '@wp-typia/block-runtime/validation';
16
-
17
- export const useTypiaValidation = createUseTypiaValidationHook( {
18
- useMemo,
19
- } );
@@ -1,52 +0,0 @@
1
- {
2
- "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 3,
4
- "name": "{{namespace}}/{{slugKebabCase}}",
5
- "version": "{{blockMetadataVersion}}",
6
- "title": {{titleJson}},
7
- "category": "{{category}}",
8
- "icon": "{{icon}}",
9
- "description": "{{description}}",
10
- "example": {},
11
- "supports": {
12
- "html": false,
13
- "anchor": true,
14
- "className": true,
15
- "interactivity": true
16
- },
17
- "attributes": {
18
- "heading": {
19
- "type": "string",
20
- "source": "html",
21
- "selector": ".{{cssClassName}}__heading",
22
- "default": {{titleJson}}
23
- },
24
- "intro": {
25
- "type": "string",
26
- "source": "html",
27
- "selector": ".{{cssClassName}}__intro",
28
- "default": "Add and reorder internal items inside this compound block."
29
- },
30
- "showDividers": {
31
- "type": "boolean",
32
- "default": true
33
- },
34
- "showCount": {
35
- "type": "boolean",
36
- "default": true
37
- },
38
- "buttonLabel": {
39
- "type": "string",
40
- "default": "Persist Count"
41
- },
42
- "resourceKey": {
43
- "type": "string",
44
- "default": ""
45
- }
46
- },
47
- "textdomain": "{{textDomain}}",
48
- "editorScript": "file:./index.js",
49
- "style": "file:./style-index.css",
50
- "viewScriptModule": "file:./interactivity.js",
51
- "render": "file:./render.php"
52
- }