@wp-typia/project-tools 0.16.1 → 0.16.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/README.md +17 -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 +30 -0
  7. package/dist/runtime/built-in-block-code-artifacts.js +122 -0
  8. package/dist/runtime/index.d.ts +2 -0
  9. package/dist/runtime/index.js +1 -0
  10. package/dist/runtime/package-versions.js +7 -2
  11. package/dist/runtime/scaffold-apply-utils.d.ts +47 -0
  12. package/dist/runtime/scaffold-apply-utils.js +405 -0
  13. package/dist/runtime/scaffold-identifiers.d.ts +34 -0
  14. package/dist/runtime/scaffold-identifiers.js +82 -0
  15. package/dist/runtime/scaffold.js +33 -0
  16. package/dist/runtime/schema-core.d.ts +5 -266
  17. package/dist/runtime/schema-core.js +5 -775
  18. package/dist/runtime/starter-manifests.d.ts +3 -2
  19. package/dist/runtime/starter-manifests.js +15 -365
  20. package/dist/runtime/template-render.d.ts +5 -0
  21. package/dist/runtime/template-render.js +13 -3
  22. package/package.json +56 -3
  23. package/templates/_shared/compound/persistence/scripts/block-config.ts.mustache +4 -4
  24. package/templates/_shared/persistence/core/scripts/sync-rest-contracts.ts.mustache +4 -4
  25. package/templates/_shared/base/src/hooks.ts.mustache +0 -19
  26. package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/block.json.mustache +0 -52
  27. package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/edit.tsx.mustache +0 -123
  28. package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/hooks.ts.mustache +0 -11
  29. package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/interactivity.ts.mustache +0 -305
  30. package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/save.tsx.mustache +0 -3
  31. package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/types.ts.mustache +0 -61
  32. package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/validators.ts.mustache +0 -43
  33. package/templates/_shared/persistence/core/src/index.tsx.mustache +0 -25
  34. package/templates/_shared/persistence/core/src/interactivity.ts.mustache +0 -308
  35. package/templates/_shared/persistence/core/src/save.tsx.mustache +0 -5
  36. package/templates/_shared/persistence/core/src/validators.ts.mustache +0 -43
  37. package/templates/basic/src/block.json.mustache +0 -51
  38. package/templates/basic/src/edit.tsx.mustache +0 -128
  39. package/templates/basic/src/index.tsx.mustache +0 -45
  40. package/templates/basic/src/save.tsx.mustache +0 -30
  41. package/templates/basic/src/types.ts.mustache +0 -56
  42. package/templates/basic/src/validators.ts.mustache +0 -37
  43. package/templates/compound/src/blocks/{{slugKebabCase}}/block.json.mustache +0 -37
  44. package/templates/compound/src/blocks/{{slugKebabCase}}/children.ts.mustache +0 -25
  45. package/templates/compound/src/blocks/{{slugKebabCase}}/edit.tsx.mustache +0 -93
  46. package/templates/compound/src/blocks/{{slugKebabCase}}/hooks.ts.mustache +0 -11
  47. package/templates/compound/src/blocks/{{slugKebabCase}}/index.tsx.mustache +0 -25
  48. package/templates/compound/src/blocks/{{slugKebabCase}}/save.tsx.mustache +0 -32
  49. package/templates/compound/src/blocks/{{slugKebabCase}}/types.ts.mustache +0 -18
  50. package/templates/compound/src/blocks/{{slugKebabCase}}/validators.ts.mustache +0 -35
  51. package/templates/compound/src/blocks/{{slugKebabCase}}-item/block.json.mustache +0 -35
  52. package/templates/compound/src/blocks/{{slugKebabCase}}-item/edit.tsx.mustache +0 -50
  53. package/templates/compound/src/blocks/{{slugKebabCase}}-item/hooks.ts.mustache +0 -11
  54. package/templates/compound/src/blocks/{{slugKebabCase}}-item/index.tsx.mustache +0 -25
  55. package/templates/compound/src/blocks/{{slugKebabCase}}-item/save.tsx.mustache +0 -24
  56. package/templates/compound/src/blocks/{{slugKebabCase}}-item/types.ts.mustache +0 -17
  57. package/templates/compound/src/blocks/{{slugKebabCase}}-item/validators.ts.mustache +0 -35
  58. package/templates/interactivity/src/block.json.mustache +0 -74
  59. package/templates/interactivity/src/edit.tsx.mustache +0 -270
  60. package/templates/interactivity/src/index.tsx.mustache +0 -33
  61. package/templates/interactivity/src/interactivity.ts.mustache +0 -152
  62. package/templates/interactivity/src/save.tsx.mustache +0 -101
  63. package/templates/interactivity/src/types.ts.mustache +0 -32
  64. package/templates/interactivity/src/validators.ts.mustache +0 -47
  65. package/templates/persistence/src/block.json.mustache +0 -52
  66. package/templates/persistence/src/edit.tsx.mustache +0 -165
  67. package/templates/persistence/src/types.ts.mustache +0 -59
@@ -0,0 +1,1203 @@
1
+ const ALIGNMENT_VALUES = ["left", "center", "right"];
2
+ const BASIC_ALIGNMENT_VALUES = ["left", "center", "right", "justify"];
3
+ const INTERACTIVE_MODE_VALUES = ["click", "hover"];
4
+ const ANIMATION_VALUES = ["none", "bounce", "pulse", "shake", "flip"];
5
+ const DEFAULT_COMPOUND_CHILD_BODY_PLACEHOLDER = "Add supporting details for this internal item.";
6
+ function createConstraints(overrides = {}) {
7
+ return {
8
+ exclusiveMaximum: null,
9
+ exclusiveMinimum: null,
10
+ format: null,
11
+ maxLength: null,
12
+ maxItems: null,
13
+ maximum: null,
14
+ minLength: null,
15
+ minItems: null,
16
+ minimum: null,
17
+ multipleOf: null,
18
+ pattern: null,
19
+ typeTag: null,
20
+ ...overrides,
21
+ };
22
+ }
23
+ function createManifestAttribute({ constraints, defaultValue, enumValues = null, kind, required, selector = null, source = null, sourceType, }) {
24
+ const hasDefault = defaultValue !== undefined;
25
+ return {
26
+ ts: {
27
+ items: null,
28
+ kind,
29
+ properties: null,
30
+ required,
31
+ union: null,
32
+ },
33
+ typia: {
34
+ constraints: createConstraints(constraints),
35
+ defaultValue: hasDefault ? defaultValue : null,
36
+ hasDefault,
37
+ },
38
+ wp: {
39
+ defaultValue: hasDefault ? defaultValue : null,
40
+ enum: enumValues,
41
+ hasDefault,
42
+ ...(selector ? { selector } : {}),
43
+ ...(source ? { source } : {}),
44
+ type: sourceType,
45
+ },
46
+ };
47
+ }
48
+ function createBlockJsonAttribute({ defaultValue, enumValues = null, selector, source, type, }) {
49
+ const attribute = {
50
+ type,
51
+ };
52
+ if (defaultValue !== undefined) {
53
+ attribute.default = defaultValue;
54
+ }
55
+ if (enumValues !== null && enumValues.length > 0) {
56
+ attribute.enum = enumValues;
57
+ }
58
+ if (source) {
59
+ attribute.source = source;
60
+ }
61
+ if (selector) {
62
+ attribute.selector = selector;
63
+ }
64
+ return attribute;
65
+ }
66
+ function createAttributeDefinition({ blockJson, description, manifest, name, optional, typeExpression, }) {
67
+ return {
68
+ blockJson,
69
+ description,
70
+ manifest,
71
+ name,
72
+ optional,
73
+ typeExpression,
74
+ };
75
+ }
76
+ function buildManifestDocument(sourceType, attributes) {
77
+ return {
78
+ attributes: Object.fromEntries(attributes.map((attribute) => [
79
+ attribute.name,
80
+ createManifestAttribute(attribute.manifest),
81
+ ])),
82
+ manifestVersion: 2,
83
+ sourceType,
84
+ };
85
+ }
86
+ function buildBlockJsonAttributes(attributes) {
87
+ return Object.fromEntries(attributes.map((attribute) => [
88
+ attribute.name,
89
+ createBlockJsonAttribute(attribute.blockJson),
90
+ ]));
91
+ }
92
+ function quote(value) {
93
+ return JSON.stringify(value);
94
+ }
95
+ function emitDocComment(description, indent = "") {
96
+ if (!description) {
97
+ return [];
98
+ }
99
+ return [
100
+ `${indent}/**`,
101
+ ...description.lines.map((line) => line.length === 0 ? `${indent} *` : `${indent} * ${line}`),
102
+ `${indent} */`,
103
+ ];
104
+ }
105
+ function emitInterface(definition) {
106
+ const lines = [
107
+ ...emitDocComment(definition.description),
108
+ `export interface ${definition.name} {`,
109
+ ];
110
+ for (const member of definition.members) {
111
+ lines.push(...emitDocComment(member.description, "\t"));
112
+ lines.push(`\t${member.name}${member.optional ? "?" : ""}: ${member.typeExpression};`);
113
+ }
114
+ lines.push("}");
115
+ return lines;
116
+ }
117
+ function emitTypesModule({ preambleLines, interfaces, typeAliases, }) {
118
+ const sections = [];
119
+ if (preambleLines.length > 0) {
120
+ sections.push(preambleLines.join("\n"));
121
+ }
122
+ for (const definition of interfaces) {
123
+ sections.push(emitInterface(definition).join("\n"));
124
+ }
125
+ if (typeAliases.length > 0) {
126
+ sections.push(typeAliases
127
+ .map((alias) => `export type ${alias.name} = ${alias.value};`)
128
+ .join("\n"));
129
+ }
130
+ return `${sections.join("\n\n")}\n`;
131
+ }
132
+ function stringifyBlockJsonDocument(document) {
133
+ return `${JSON.stringify(document, null, "\t")}\n`;
134
+ }
135
+ function buildBasicAttributes() {
136
+ return [
137
+ createAttributeDefinition({
138
+ blockJson: {
139
+ defaultValue: "",
140
+ type: "string",
141
+ },
142
+ description: {
143
+ lines: ["Main block content"],
144
+ },
145
+ manifest: {
146
+ constraints: {
147
+ maxLength: 1000,
148
+ },
149
+ defaultValue: "",
150
+ kind: "string",
151
+ required: true,
152
+ sourceType: "string",
153
+ },
154
+ name: "content",
155
+ optional: false,
156
+ typeExpression: 'string & tags.MaxLength<1000> & tags.Default<"">',
157
+ }),
158
+ createAttributeDefinition({
159
+ blockJson: {
160
+ defaultValue: "left",
161
+ enumValues: [...BASIC_ALIGNMENT_VALUES],
162
+ type: "string",
163
+ },
164
+ description: {
165
+ lines: ["Alignment"],
166
+ },
167
+ manifest: {
168
+ defaultValue: "left",
169
+ enumValues: [...BASIC_ALIGNMENT_VALUES],
170
+ kind: "string",
171
+ required: false,
172
+ sourceType: "string",
173
+ },
174
+ name: "alignment",
175
+ optional: true,
176
+ typeExpression: 'TextAlignment & tags.Default<"left">',
177
+ }),
178
+ createAttributeDefinition({
179
+ blockJson: {
180
+ defaultValue: true,
181
+ type: "boolean",
182
+ },
183
+ description: {
184
+ lines: ["Visibility toggle"],
185
+ },
186
+ manifest: {
187
+ defaultValue: true,
188
+ kind: "boolean",
189
+ required: false,
190
+ sourceType: "boolean",
191
+ },
192
+ name: "isVisible",
193
+ optional: true,
194
+ typeExpression: "boolean & tags.Default<true>",
195
+ }),
196
+ createAttributeDefinition({
197
+ blockJson: {
198
+ defaultValue: "",
199
+ type: "string",
200
+ },
201
+ description: {
202
+ lines: ["Custom CSS class"],
203
+ },
204
+ manifest: {
205
+ constraints: {
206
+ maxLength: 100,
207
+ },
208
+ defaultValue: "",
209
+ kind: "string",
210
+ required: false,
211
+ sourceType: "string",
212
+ },
213
+ name: "className",
214
+ optional: true,
215
+ typeExpression: 'string & tags.MaxLength<100> & tags.Default<"">',
216
+ }),
217
+ createAttributeDefinition({
218
+ blockJson: {
219
+ type: "string",
220
+ },
221
+ description: {
222
+ lines: ["Generated runtime ID"],
223
+ },
224
+ manifest: {
225
+ constraints: {
226
+ format: "uuid",
227
+ },
228
+ kind: "string",
229
+ required: false,
230
+ sourceType: "string",
231
+ },
232
+ name: "id",
233
+ optional: true,
234
+ typeExpression: 'string & tags.Format<"uuid">',
235
+ }),
236
+ createAttributeDefinition({
237
+ blockJson: {
238
+ defaultValue: 1,
239
+ type: "number",
240
+ },
241
+ description: {
242
+ lines: ["Block version for migrations"],
243
+ },
244
+ manifest: {
245
+ constraints: {
246
+ typeTag: "uint32",
247
+ },
248
+ defaultValue: 1,
249
+ kind: "number",
250
+ required: false,
251
+ sourceType: "number",
252
+ },
253
+ name: "schemaVersion",
254
+ optional: true,
255
+ typeExpression: 'number & tags.Type<"uint32"> & tags.Default<1>',
256
+ }),
257
+ ];
258
+ }
259
+ function buildInteractivityAttributes(variables) {
260
+ return [
261
+ createAttributeDefinition({
262
+ blockJson: {
263
+ defaultValue: "",
264
+ selector: `.${variables.cssClassName}__content`,
265
+ source: "html",
266
+ type: "string",
267
+ },
268
+ manifest: {
269
+ constraints: {
270
+ maxLength: 1000,
271
+ },
272
+ defaultValue: "",
273
+ kind: "string",
274
+ required: true,
275
+ selector: `.${variables.cssClassName}__content`,
276
+ source: "html",
277
+ sourceType: "string",
278
+ },
279
+ name: "content",
280
+ optional: false,
281
+ typeExpression: 'string & tags.MaxLength<1000> & tags.Default<"">',
282
+ }),
283
+ createAttributeDefinition({
284
+ blockJson: {
285
+ defaultValue: "left",
286
+ enumValues: [...ALIGNMENT_VALUES],
287
+ type: "string",
288
+ },
289
+ manifest: {
290
+ defaultValue: "left",
291
+ enumValues: [...ALIGNMENT_VALUES],
292
+ kind: "string",
293
+ required: false,
294
+ sourceType: "string",
295
+ },
296
+ name: "alignment",
297
+ optional: true,
298
+ typeExpression: 'TextAlignment & tags.Default<"left">',
299
+ }),
300
+ createAttributeDefinition({
301
+ blockJson: {
302
+ defaultValue: true,
303
+ type: "boolean",
304
+ },
305
+ manifest: {
306
+ defaultValue: true,
307
+ kind: "boolean",
308
+ required: false,
309
+ sourceType: "boolean",
310
+ },
311
+ name: "isVisible",
312
+ optional: true,
313
+ typeExpression: "boolean & tags.Default<true>",
314
+ }),
315
+ createAttributeDefinition({
316
+ blockJson: {
317
+ defaultValue: "click",
318
+ enumValues: [...INTERACTIVE_MODE_VALUES],
319
+ type: "string",
320
+ },
321
+ manifest: {
322
+ defaultValue: "click",
323
+ enumValues: [...INTERACTIVE_MODE_VALUES],
324
+ kind: "string",
325
+ required: false,
326
+ sourceType: "string",
327
+ },
328
+ name: "interactiveMode",
329
+ optional: true,
330
+ typeExpression: '("click" | "hover") & tags.Default<"click">',
331
+ }),
332
+ createAttributeDefinition({
333
+ blockJson: {
334
+ defaultValue: "none",
335
+ enumValues: [...ANIMATION_VALUES],
336
+ type: "string",
337
+ },
338
+ manifest: {
339
+ defaultValue: "none",
340
+ enumValues: [...ANIMATION_VALUES],
341
+ kind: "string",
342
+ required: false,
343
+ sourceType: "string",
344
+ },
345
+ name: "animation",
346
+ optional: true,
347
+ typeExpression: '("none" | "bounce" | "pulse" | "shake" | "flip") & tags.Default<"none">',
348
+ }),
349
+ createAttributeDefinition({
350
+ blockJson: {
351
+ defaultValue: 0,
352
+ type: "number",
353
+ },
354
+ manifest: {
355
+ constraints: {
356
+ minimum: 0,
357
+ typeTag: "uint32",
358
+ },
359
+ defaultValue: 0,
360
+ kind: "number",
361
+ required: false,
362
+ sourceType: "number",
363
+ },
364
+ name: "clickCount",
365
+ optional: true,
366
+ typeExpression: 'number & tags.Minimum<0> & tags.Type<"uint32"> & tags.Default<0>',
367
+ }),
368
+ createAttributeDefinition({
369
+ blockJson: {
370
+ defaultValue: false,
371
+ type: "boolean",
372
+ },
373
+ manifest: {
374
+ defaultValue: false,
375
+ kind: "boolean",
376
+ required: false,
377
+ sourceType: "boolean",
378
+ },
379
+ name: "isAnimating",
380
+ optional: true,
381
+ typeExpression: "boolean & tags.Default<false>",
382
+ }),
383
+ createAttributeDefinition({
384
+ blockJson: {
385
+ defaultValue: true,
386
+ type: "boolean",
387
+ },
388
+ manifest: {
389
+ defaultValue: true,
390
+ kind: "boolean",
391
+ required: false,
392
+ sourceType: "boolean",
393
+ },
394
+ name: "showCounter",
395
+ optional: true,
396
+ typeExpression: "boolean & tags.Default<true>",
397
+ }),
398
+ createAttributeDefinition({
399
+ blockJson: {
400
+ defaultValue: 10,
401
+ type: "number",
402
+ },
403
+ manifest: {
404
+ constraints: {
405
+ minimum: 0,
406
+ typeTag: "uint32",
407
+ },
408
+ defaultValue: 10,
409
+ kind: "number",
410
+ required: false,
411
+ sourceType: "number",
412
+ },
413
+ name: "maxClicks",
414
+ optional: true,
415
+ typeExpression: 'number & tags.Minimum<0> & tags.Type<"uint32"> & tags.Default<10>',
416
+ }),
417
+ ];
418
+ }
419
+ function buildPersistenceAttributes(variables) {
420
+ return [
421
+ createAttributeDefinition({
422
+ blockJson: {
423
+ defaultValue: `${variables.title} persistence block`,
424
+ selector: `.${variables.cssClassName}__content`,
425
+ source: "html",
426
+ type: "string",
427
+ },
428
+ manifest: {
429
+ constraints: {
430
+ maxLength: 250,
431
+ minLength: 1,
432
+ },
433
+ defaultValue: `${variables.title} persistence block`,
434
+ kind: "string",
435
+ required: true,
436
+ selector: `.${variables.cssClassName}__content`,
437
+ source: "html",
438
+ sourceType: "string",
439
+ },
440
+ name: "content",
441
+ optional: false,
442
+ typeExpression: `string & tags.MinLength<1> & tags.MaxLength<250> & tags.Default<${quote(`${variables.title} persistence block`)}>`,
443
+ }),
444
+ createAttributeDefinition({
445
+ blockJson: {
446
+ defaultValue: "left",
447
+ enumValues: [...ALIGNMENT_VALUES],
448
+ type: "string",
449
+ },
450
+ manifest: {
451
+ defaultValue: "left",
452
+ enumValues: [...ALIGNMENT_VALUES],
453
+ kind: "string",
454
+ required: false,
455
+ sourceType: "string",
456
+ },
457
+ name: "alignment",
458
+ optional: true,
459
+ typeExpression: 'TextAlignment & tags.Default<"left">',
460
+ }),
461
+ createAttributeDefinition({
462
+ blockJson: {
463
+ defaultValue: true,
464
+ type: "boolean",
465
+ },
466
+ manifest: {
467
+ defaultValue: true,
468
+ kind: "boolean",
469
+ required: false,
470
+ sourceType: "boolean",
471
+ },
472
+ name: "isVisible",
473
+ optional: true,
474
+ typeExpression: "boolean & tags.Default<true>",
475
+ }),
476
+ createAttributeDefinition({
477
+ blockJson: {
478
+ defaultValue: true,
479
+ type: "boolean",
480
+ },
481
+ manifest: {
482
+ defaultValue: true,
483
+ kind: "boolean",
484
+ required: false,
485
+ sourceType: "boolean",
486
+ },
487
+ name: "showCount",
488
+ optional: true,
489
+ typeExpression: "boolean & tags.Default<true>",
490
+ }),
491
+ createAttributeDefinition({
492
+ blockJson: {
493
+ defaultValue: "Persist Count",
494
+ type: "string",
495
+ },
496
+ manifest: {
497
+ constraints: {
498
+ maxLength: 40,
499
+ minLength: 1,
500
+ },
501
+ defaultValue: "Persist Count",
502
+ kind: "string",
503
+ required: false,
504
+ sourceType: "string",
505
+ },
506
+ name: "buttonLabel",
507
+ optional: true,
508
+ typeExpression: 'string & tags.MinLength<1> & tags.MaxLength<40> & tags.Default<"Persist Count">',
509
+ }),
510
+ createAttributeDefinition({
511
+ blockJson: {
512
+ defaultValue: "",
513
+ type: "string",
514
+ },
515
+ manifest: {
516
+ constraints: {
517
+ maxLength: 100,
518
+ minLength: 1,
519
+ },
520
+ defaultValue: "primary",
521
+ kind: "string",
522
+ required: false,
523
+ sourceType: "string",
524
+ },
525
+ name: "resourceKey",
526
+ optional: true,
527
+ typeExpression: 'string & tags.MinLength<1> & tags.MaxLength<100> & tags.Default<"primary">',
528
+ }),
529
+ ];
530
+ }
531
+ function buildCompoundParentAttributes(variables) {
532
+ const attributes = [
533
+ createAttributeDefinition({
534
+ blockJson: {
535
+ defaultValue: variables.title,
536
+ selector: `.${variables.cssClassName}__heading`,
537
+ source: "html",
538
+ type: "string",
539
+ },
540
+ manifest: {
541
+ constraints: {
542
+ maxLength: 80,
543
+ minLength: 1,
544
+ },
545
+ defaultValue: variables.title,
546
+ kind: "string",
547
+ required: true,
548
+ selector: `.${variables.cssClassName}__heading`,
549
+ source: "html",
550
+ sourceType: "string",
551
+ },
552
+ name: "heading",
553
+ optional: false,
554
+ typeExpression: `string & tags.MinLength<1> & tags.MaxLength<80> & tags.Default<${quote(variables.title)}>`,
555
+ }),
556
+ createAttributeDefinition({
557
+ blockJson: {
558
+ defaultValue: "Add and reorder internal items inside this compound block.",
559
+ selector: `.${variables.cssClassName}__intro`,
560
+ source: "html",
561
+ type: "string",
562
+ },
563
+ manifest: {
564
+ constraints: {
565
+ maxLength: 180,
566
+ minLength: 1,
567
+ },
568
+ defaultValue: "Add and reorder internal items inside this compound block.",
569
+ kind: "string",
570
+ required: false,
571
+ selector: `.${variables.cssClassName}__intro`,
572
+ source: "html",
573
+ sourceType: "string",
574
+ },
575
+ name: "intro",
576
+ optional: true,
577
+ typeExpression: 'string & tags.MinLength<1> & tags.MaxLength<180> & tags.Default<"Add and reorder internal items inside this compound block.">',
578
+ }),
579
+ createAttributeDefinition({
580
+ blockJson: {
581
+ defaultValue: true,
582
+ type: "boolean",
583
+ },
584
+ manifest: {
585
+ defaultValue: true,
586
+ kind: "boolean",
587
+ required: false,
588
+ sourceType: "boolean",
589
+ },
590
+ name: "showDividers",
591
+ optional: true,
592
+ typeExpression: "boolean & tags.Default<true>",
593
+ }),
594
+ ];
595
+ if (variables.compoundPersistenceEnabled === "true") {
596
+ attributes.push(createAttributeDefinition({
597
+ blockJson: {
598
+ defaultValue: true,
599
+ type: "boolean",
600
+ },
601
+ manifest: {
602
+ defaultValue: true,
603
+ kind: "boolean",
604
+ required: false,
605
+ sourceType: "boolean",
606
+ },
607
+ name: "showCount",
608
+ optional: true,
609
+ typeExpression: "boolean & tags.Default<true>",
610
+ }), createAttributeDefinition({
611
+ blockJson: {
612
+ defaultValue: "Persist Count",
613
+ type: "string",
614
+ },
615
+ manifest: {
616
+ constraints: {
617
+ maxLength: 40,
618
+ minLength: 1,
619
+ },
620
+ defaultValue: "Persist Count",
621
+ kind: "string",
622
+ required: false,
623
+ sourceType: "string",
624
+ },
625
+ name: "buttonLabel",
626
+ optional: true,
627
+ typeExpression: 'string & tags.MinLength<1> & tags.MaxLength<40> & tags.Default<"Persist Count">',
628
+ }), createAttributeDefinition({
629
+ blockJson: {
630
+ defaultValue: "",
631
+ type: "string",
632
+ },
633
+ manifest: {
634
+ constraints: {
635
+ maxLength: 100,
636
+ minLength: 1,
637
+ },
638
+ defaultValue: "primary",
639
+ kind: "string",
640
+ required: false,
641
+ sourceType: "string",
642
+ },
643
+ name: "resourceKey",
644
+ optional: true,
645
+ typeExpression: 'string & tags.MinLength<1> & tags.MaxLength<100> & tags.Default<"primary">',
646
+ }));
647
+ }
648
+ return attributes;
649
+ }
650
+ function buildCompoundChildAttributes(bodyPlaceholder = DEFAULT_COMPOUND_CHILD_BODY_PLACEHOLDER, childTitle, childCssClassName) {
651
+ const titleSelector = childCssClassName
652
+ ? `.${childCssClassName}__title`
653
+ : null;
654
+ const bodySelector = childCssClassName
655
+ ? `.${childCssClassName}__body`
656
+ : null;
657
+ return [
658
+ createAttributeDefinition({
659
+ blockJson: {
660
+ defaultValue: childTitle,
661
+ ...(titleSelector
662
+ ? {
663
+ selector: titleSelector,
664
+ source: "html",
665
+ }
666
+ : {}),
667
+ type: "string",
668
+ },
669
+ manifest: {
670
+ constraints: {
671
+ maxLength: 80,
672
+ minLength: 1,
673
+ },
674
+ defaultValue: childTitle,
675
+ kind: "string",
676
+ required: true,
677
+ selector: titleSelector,
678
+ source: titleSelector ? "html" : null,
679
+ sourceType: "string",
680
+ },
681
+ name: "title",
682
+ optional: false,
683
+ typeExpression: `string & tags.MinLength<1> & tags.MaxLength<80> & tags.Default<${quote(childTitle)}>`,
684
+ }),
685
+ createAttributeDefinition({
686
+ blockJson: {
687
+ defaultValue: bodyPlaceholder,
688
+ ...(bodySelector
689
+ ? {
690
+ selector: bodySelector,
691
+ source: "html",
692
+ }
693
+ : {}),
694
+ type: "string",
695
+ },
696
+ manifest: {
697
+ constraints: {
698
+ maxLength: 280,
699
+ minLength: 1,
700
+ },
701
+ defaultValue: bodyPlaceholder,
702
+ kind: "string",
703
+ required: true,
704
+ selector: bodySelector,
705
+ source: bodySelector ? "html" : null,
706
+ sourceType: "string",
707
+ },
708
+ name: "body",
709
+ optional: false,
710
+ typeExpression: `string & tags.MinLength<1> & tags.MaxLength<280> & tags.Default<${quote(bodyPlaceholder)}>`,
711
+ }),
712
+ ];
713
+ }
714
+ function buildBasicTypesSource(variables, attributes) {
715
+ return emitTypesModule({
716
+ preambleLines: [
717
+ 'import type { TextAlignment } from "@wp-typia/block-types/block-editor/alignment";',
718
+ "import type {",
719
+ "\tTypiaValidationError,",
720
+ "\tValidationResult,",
721
+ '} from "@wp-typia/block-runtime/validation";',
722
+ 'import { tags } from "typia";',
723
+ "",
724
+ 'export type { TypiaValidationError, ValidationResult } from "@wp-typia/block-runtime/validation";',
725
+ ],
726
+ interfaces: [
727
+ {
728
+ description: {
729
+ lines: [
730
+ "Block attributes interface",
731
+ "Typia tags define runtime validation rules",
732
+ ],
733
+ },
734
+ members: attributes.map((attribute) => ({
735
+ description: attribute.description,
736
+ name: attribute.name,
737
+ optional: attribute.optional,
738
+ typeExpression: attribute.typeExpression,
739
+ })),
740
+ name: `${variables.pascalCase}Attributes`,
741
+ },
742
+ ],
743
+ typeAliases: [
744
+ {
745
+ name: `${variables.pascalCase}ValidationResult`,
746
+ value: `ValidationResult<${variables.pascalCase}Attributes>`,
747
+ },
748
+ ],
749
+ });
750
+ }
751
+ function buildInteractivityTypesSource(variables, attributes) {
752
+ return emitTypesModule({
753
+ preambleLines: [
754
+ 'import type { TextAlignment } from "@wp-typia/block-types/block-editor/alignment";',
755
+ "import type {",
756
+ "\tTypiaValidationError,",
757
+ "\tValidationResult,",
758
+ '} from "@wp-typia/block-runtime/validation";',
759
+ 'import { tags } from "typia";',
760
+ "",
761
+ 'export type { TypiaValidationError, ValidationResult } from "@wp-typia/block-runtime/validation";',
762
+ ],
763
+ interfaces: [
764
+ {
765
+ members: attributes.map((attribute) => ({
766
+ name: attribute.name,
767
+ optional: attribute.optional,
768
+ typeExpression: attribute.typeExpression,
769
+ })),
770
+ name: `${variables.pascalCase}Attributes`,
771
+ },
772
+ {
773
+ members: [
774
+ {
775
+ name: "clicks",
776
+ typeExpression: "number",
777
+ },
778
+ {
779
+ name: "isAnimating",
780
+ typeExpression: "boolean",
781
+ },
782
+ {
783
+ name: "isVisible",
784
+ typeExpression: "boolean",
785
+ },
786
+ {
787
+ name: "animation",
788
+ typeExpression: '"none" | "bounce" | "pulse" | "shake" | "flip"',
789
+ },
790
+ {
791
+ name: "maxClicks",
792
+ typeExpression: "number",
793
+ },
794
+ ],
795
+ name: `${variables.pascalCase}Context`,
796
+ },
797
+ ],
798
+ typeAliases: [
799
+ {
800
+ name: `${variables.pascalCase}ValidationResult`,
801
+ value: `ValidationResult<${variables.pascalCase}Attributes>`,
802
+ },
803
+ ],
804
+ });
805
+ }
806
+ function buildPersistenceTypesSource(variables, attributes) {
807
+ return emitTypesModule({
808
+ preambleLines: [
809
+ 'import type { TextAlignment } from "@wp-typia/block-types/block-editor/alignment";',
810
+ "import type {",
811
+ "\tTypiaValidationError,",
812
+ "\tValidationResult,",
813
+ '} from "@wp-typia/block-runtime/validation";',
814
+ 'import { tags } from "typia";',
815
+ "",
816
+ 'export type { TypiaValidationError, ValidationResult } from "@wp-typia/block-runtime/validation";',
817
+ ],
818
+ interfaces: [
819
+ {
820
+ members: attributes.map((attribute) => ({
821
+ name: attribute.name,
822
+ optional: attribute.optional,
823
+ typeExpression: attribute.typeExpression,
824
+ })),
825
+ name: `${variables.pascalCase}Attributes`,
826
+ },
827
+ {
828
+ members: [
829
+ { name: "buttonLabel", typeExpression: "string" },
830
+ { name: "bootstrapReady", typeExpression: "boolean" },
831
+ { name: "canWrite", typeExpression: "boolean" },
832
+ { name: "count", typeExpression: "number" },
833
+ { name: "error", typeExpression: "string" },
834
+ { name: "isBootstrapping", typeExpression: "boolean" },
835
+ { name: "isLoading", typeExpression: "boolean" },
836
+ { name: "isSaving", typeExpression: "boolean" },
837
+ {
838
+ name: "persistencePolicy",
839
+ typeExpression: '"authenticated" | "public"',
840
+ },
841
+ { name: "postId", typeExpression: "number" },
842
+ { name: "resourceKey", typeExpression: "string" },
843
+ {
844
+ name: "storage",
845
+ typeExpression: '"post-meta" | "custom-table"',
846
+ },
847
+ { name: "isVisible", typeExpression: "boolean" },
848
+ {
849
+ name: "client",
850
+ optional: true,
851
+ typeExpression: `${variables.pascalCase}ClientState`,
852
+ },
853
+ ],
854
+ name: `${variables.pascalCase}Context`,
855
+ },
856
+ {
857
+ members: [
858
+ { name: "isHydrated", typeExpression: "boolean" },
859
+ ],
860
+ name: `${variables.pascalCase}State`,
861
+ },
862
+ {
863
+ members: [
864
+ { name: "bootstrapError", typeExpression: "string" },
865
+ { name: "writeExpiry", typeExpression: "number" },
866
+ { name: "writeNonce", typeExpression: "string" },
867
+ { name: "writeToken", typeExpression: "string" },
868
+ ],
869
+ name: `${variables.pascalCase}ClientState`,
870
+ },
871
+ ],
872
+ typeAliases: [
873
+ {
874
+ name: `${variables.pascalCase}ValidationResult`,
875
+ value: `ValidationResult<${variables.pascalCase}Attributes>`,
876
+ },
877
+ ],
878
+ });
879
+ }
880
+ function buildCompoundTypesSource(variables, attributes) {
881
+ const persistenceEnabled = variables.compoundPersistenceEnabled === "true";
882
+ return emitTypesModule({
883
+ preambleLines: persistenceEnabled
884
+ ? [
885
+ "import type {",
886
+ "\tTypiaValidationError,",
887
+ "\tValidationResult,",
888
+ '} from "@wp-typia/block-runtime/validation";',
889
+ 'import { tags } from "typia";',
890
+ "",
891
+ 'export type { TypiaValidationError, ValidationResult } from "@wp-typia/block-runtime/validation";',
892
+ ]
893
+ : [
894
+ 'import type { ValidationResult } from "@wp-typia/block-runtime/validation";',
895
+ 'import { tags } from "typia";',
896
+ "",
897
+ 'export type { ValidationResult } from "@wp-typia/block-runtime/validation";',
898
+ ],
899
+ interfaces: [
900
+ {
901
+ members: attributes.map((attribute) => ({
902
+ name: attribute.name,
903
+ optional: attribute.optional,
904
+ typeExpression: attribute.typeExpression,
905
+ })),
906
+ name: `${variables.pascalCase}Attributes`,
907
+ },
908
+ ...(persistenceEnabled
909
+ ? [
910
+ {
911
+ members: [
912
+ { name: "buttonLabel", typeExpression: "string" },
913
+ { name: "bootstrapReady", typeExpression: "boolean" },
914
+ { name: "canWrite", typeExpression: "boolean" },
915
+ { name: "count", typeExpression: "number" },
916
+ { name: "error", typeExpression: "string" },
917
+ { name: "isBootstrapping", typeExpression: "boolean" },
918
+ { name: "isLoading", typeExpression: "boolean" },
919
+ { name: "isSaving", typeExpression: "boolean" },
920
+ {
921
+ name: "persistencePolicy",
922
+ typeExpression: '"authenticated" | "public"',
923
+ },
924
+ { name: "postId", typeExpression: "number" },
925
+ { name: "resourceKey", typeExpression: "string" },
926
+ { name: "showCount", typeExpression: "boolean" },
927
+ {
928
+ name: "storage",
929
+ typeExpression: '"post-meta" | "custom-table"',
930
+ },
931
+ {
932
+ name: "client",
933
+ optional: true,
934
+ typeExpression: `${variables.pascalCase}ClientState`,
935
+ },
936
+ ],
937
+ name: `${variables.pascalCase}Context`,
938
+ },
939
+ {
940
+ members: [{ name: "isHydrated", typeExpression: "boolean" }],
941
+ name: `${variables.pascalCase}State`,
942
+ },
943
+ {
944
+ members: [
945
+ { name: "bootstrapError", typeExpression: "string" },
946
+ { name: "writeExpiry", typeExpression: "number" },
947
+ { name: "writeNonce", typeExpression: "string" },
948
+ { name: "writeToken", typeExpression: "string" },
949
+ ],
950
+ name: `${variables.pascalCase}ClientState`,
951
+ },
952
+ ]
953
+ : []),
954
+ ],
955
+ typeAliases: [
956
+ {
957
+ name: `${variables.pascalCase}ValidationResult`,
958
+ value: `ValidationResult<${variables.pascalCase}Attributes>`,
959
+ },
960
+ ],
961
+ });
962
+ }
963
+ function buildCompoundChildTypesSource(variables, attributes) {
964
+ return emitTypesModule({
965
+ preambleLines: [
966
+ 'import type { ValidationResult } from "@wp-typia/block-runtime/validation";',
967
+ 'import { tags } from "typia";',
968
+ "",
969
+ 'export type { ValidationResult } from "@wp-typia/block-runtime/validation";',
970
+ ],
971
+ interfaces: [
972
+ {
973
+ members: attributes.map((attribute) => ({
974
+ name: attribute.name,
975
+ optional: attribute.optional,
976
+ typeExpression: attribute.typeExpression,
977
+ })),
978
+ name: `${variables.pascalCase}ItemAttributes`,
979
+ },
980
+ ],
981
+ typeAliases: [
982
+ {
983
+ name: `${variables.pascalCase}ItemValidationResult`,
984
+ value: `ValidationResult<${variables.pascalCase}ItemAttributes>`,
985
+ },
986
+ ],
987
+ });
988
+ }
989
+ function buildBasicArtifact(variables) {
990
+ const attributes = buildBasicAttributes();
991
+ return {
992
+ blockJsonDocument: {
993
+ $schema: "https://schemas.wp.org/trunk/block.json",
994
+ apiVersion: 3,
995
+ name: `${variables.namespace}/${variables.slug}`,
996
+ version: variables.blockMetadataVersion,
997
+ title: variables.title,
998
+ category: variables.category,
999
+ icon: variables.icon,
1000
+ description: variables.description,
1001
+ keywords: [variables.keyword, "typia", "block"],
1002
+ example: {
1003
+ attributes: {
1004
+ content: "Example content",
1005
+ alignment: "center",
1006
+ isVisible: true,
1007
+ },
1008
+ },
1009
+ supports: {
1010
+ html: false,
1011
+ },
1012
+ textdomain: variables.textDomain,
1013
+ editorScript: "file:./index.js",
1014
+ editorStyle: "file:./index.css",
1015
+ style: "file:./style-index.css",
1016
+ attributes: buildBlockJsonAttributes(attributes),
1017
+ },
1018
+ manifestDocument: buildManifestDocument(`${variables.pascalCase}Attributes`, attributes),
1019
+ relativeDir: "src",
1020
+ typesSource: buildBasicTypesSource(variables, attributes),
1021
+ };
1022
+ }
1023
+ function buildInteractivityArtifact(variables) {
1024
+ const attributes = buildInteractivityAttributes(variables);
1025
+ return {
1026
+ blockJsonDocument: {
1027
+ $schema: "https://schemas.wp.org/trunk/block.json",
1028
+ apiVersion: 3,
1029
+ name: `${variables.namespace}/${variables.slugKebabCase}`,
1030
+ version: variables.blockMetadataVersion,
1031
+ title: variables.title,
1032
+ category: variables.category,
1033
+ icon: variables.icon,
1034
+ description: variables.description,
1035
+ example: {},
1036
+ supports: {
1037
+ html: false,
1038
+ align: true,
1039
+ anchor: true,
1040
+ className: true,
1041
+ interactivity: true,
1042
+ },
1043
+ attributes: buildBlockJsonAttributes(attributes),
1044
+ textdomain: variables.textDomain,
1045
+ editorScript: "file:./index.js",
1046
+ editorStyle: "file:./index.css",
1047
+ style: "file:./style-index.css",
1048
+ viewScriptModule: "file:./interactivity.js",
1049
+ },
1050
+ manifestDocument: buildManifestDocument(`${variables.pascalCase}Attributes`, attributes),
1051
+ relativeDir: "src",
1052
+ typesSource: buildInteractivityTypesSource(variables, attributes),
1053
+ };
1054
+ }
1055
+ function buildPersistenceArtifact(variables) {
1056
+ const attributes = buildPersistenceAttributes(variables);
1057
+ return {
1058
+ blockJsonDocument: {
1059
+ $schema: "https://schemas.wp.org/trunk/block.json",
1060
+ apiVersion: 3,
1061
+ name: `${variables.namespace}/${variables.slugKebabCase}`,
1062
+ version: variables.blockMetadataVersion,
1063
+ title: variables.title,
1064
+ category: variables.category,
1065
+ icon: variables.icon,
1066
+ description: variables.description,
1067
+ example: {},
1068
+ supports: {
1069
+ html: false,
1070
+ align: true,
1071
+ anchor: true,
1072
+ className: true,
1073
+ interactivity: true,
1074
+ },
1075
+ attributes: buildBlockJsonAttributes(attributes),
1076
+ textdomain: variables.textDomain,
1077
+ editorScript: "file:./index.js",
1078
+ style: "file:./style-index.css",
1079
+ viewScriptModule: "file:./interactivity.js",
1080
+ render: "file:./render.php",
1081
+ },
1082
+ manifestDocument: buildManifestDocument(`${variables.pascalCase}Attributes`, attributes),
1083
+ relativeDir: "src",
1084
+ typesSource: buildPersistenceTypesSource(variables, attributes),
1085
+ };
1086
+ }
1087
+ function buildCompoundParentArtifact(variables) {
1088
+ const attributes = buildCompoundParentAttributes(variables);
1089
+ const persistenceEnabled = variables.compoundPersistenceEnabled === "true";
1090
+ return {
1091
+ blockJsonDocument: {
1092
+ $schema: "https://schemas.wp.org/trunk/block.json",
1093
+ apiVersion: 3,
1094
+ name: `${variables.namespace}/${variables.slugKebabCase}`,
1095
+ version: variables.blockMetadataVersion,
1096
+ title: variables.title,
1097
+ category: variables.category,
1098
+ icon: variables.icon,
1099
+ description: variables.description,
1100
+ example: {},
1101
+ supports: persistenceEnabled
1102
+ ? {
1103
+ html: false,
1104
+ anchor: true,
1105
+ className: true,
1106
+ interactivity: true,
1107
+ }
1108
+ : {
1109
+ html: false,
1110
+ anchor: true,
1111
+ className: true,
1112
+ },
1113
+ attributes: buildBlockJsonAttributes(attributes),
1114
+ textdomain: variables.textDomain,
1115
+ editorScript: "file:./index.js",
1116
+ style: "file:./style-index.css",
1117
+ ...(persistenceEnabled
1118
+ ? {
1119
+ viewScriptModule: "file:./interactivity.js",
1120
+ render: "file:./render.php",
1121
+ }
1122
+ : {}),
1123
+ },
1124
+ manifestDocument: buildManifestDocument(`${variables.pascalCase}Attributes`, attributes),
1125
+ relativeDir: `src/blocks/${variables.slugKebabCase}`,
1126
+ typesSource: buildCompoundTypesSource(variables, attributes),
1127
+ };
1128
+ }
1129
+ function buildCompoundChildArtifact(variables, bodyPlaceholder = DEFAULT_COMPOUND_CHILD_BODY_PLACEHOLDER) {
1130
+ const attributes = buildCompoundChildAttributes(bodyPlaceholder, variables.compoundChildTitle, variables.compoundChildCssClassName);
1131
+ return {
1132
+ blockJsonDocument: {
1133
+ $schema: "https://schemas.wp.org/trunk/block.json",
1134
+ apiVersion: 3,
1135
+ name: `${variables.namespace}/${variables.slugKebabCase}-item`,
1136
+ version: variables.blockMetadataVersion,
1137
+ title: variables.compoundChildTitle,
1138
+ category: variables.compoundChildCategory,
1139
+ icon: variables.compoundChildIcon,
1140
+ description: `Internal item block used by ${variables.title}.`,
1141
+ parent: [`${variables.namespace}/${variables.slugKebabCase}`],
1142
+ example: {},
1143
+ supports: {
1144
+ html: false,
1145
+ inserter: false,
1146
+ reusable: false,
1147
+ },
1148
+ attributes: buildBlockJsonAttributes(attributes),
1149
+ textdomain: variables.textDomain,
1150
+ editorScript: "file:./index.js",
1151
+ },
1152
+ manifestDocument: buildManifestDocument(`${variables.pascalCase}ItemAttributes`, attributes),
1153
+ relativeDir: `src/blocks/${variables.slugKebabCase}-item`,
1154
+ typesSource: buildCompoundChildTypesSource(variables, attributes),
1155
+ };
1156
+ }
1157
+ /**
1158
+ * Builds a starter manifest document for a generated compound child block.
1159
+ *
1160
+ * @param childTypeName TypeScript source type name for the child manifest.
1161
+ * @param childTitle Default title used by the child block.
1162
+ * @param bodyPlaceholder Optional placeholder used for the child body field.
1163
+ * @returns Starter manifest metadata for the compound child block.
1164
+ */
1165
+ export function buildCompoundChildStarterManifestDocument(childTypeName, childTitle, bodyPlaceholder = DEFAULT_COMPOUND_CHILD_BODY_PLACEHOLDER) {
1166
+ const attributes = buildCompoundChildAttributes(bodyPlaceholder, childTitle, null);
1167
+ return buildManifestDocument(childTypeName, attributes);
1168
+ }
1169
+ /**
1170
+ * Generates typed structural artifacts for a built-in block scaffold.
1171
+ *
1172
+ * @param options.templateId Built-in template family to emit.
1173
+ * @param options.variables Resolved scaffold template variables.
1174
+ * @returns Structural artifacts for the built-in block, including compound
1175
+ * parent and child outputs when applicable.
1176
+ */
1177
+ export function buildBuiltInBlockArtifacts({ templateId, variables, }) {
1178
+ if (templateId === "basic") {
1179
+ return [buildBasicArtifact(variables)];
1180
+ }
1181
+ if (templateId === "interactivity") {
1182
+ return [buildInteractivityArtifact(variables)];
1183
+ }
1184
+ if (templateId === "persistence") {
1185
+ return [buildPersistenceArtifact(variables)];
1186
+ }
1187
+ if (templateId === "compound") {
1188
+ return [
1189
+ buildCompoundParentArtifact(variables),
1190
+ buildCompoundChildArtifact(variables),
1191
+ ];
1192
+ }
1193
+ return [];
1194
+ }
1195
+ /**
1196
+ * Serializes a generated `block.json` document using scaffold formatting.
1197
+ *
1198
+ * @param document Structured `block.json` document.
1199
+ * @returns Pretty-printed JSON with a trailing newline.
1200
+ */
1201
+ export function stringifyBuiltInBlockJsonDocument(document) {
1202
+ return stringifyBlockJsonDocument(document);
1203
+ }