@wp-typia/project-tools 0.23.1 → 0.24.0

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 (152) hide show
  1. package/dist/runtime/built-in-block-non-ts-basic-artifacts.d.ts +9 -0
  2. package/dist/runtime/built-in-block-non-ts-basic-artifacts.js +84 -0
  3. package/dist/runtime/built-in-block-non-ts-compound-artifacts.d.ts +9 -0
  4. package/dist/runtime/built-in-block-non-ts-compound-artifacts.js +36 -0
  5. package/dist/runtime/built-in-block-non-ts-compound-templates.d.ts +23 -0
  6. package/dist/runtime/built-in-block-non-ts-compound-templates.js +453 -0
  7. package/dist/runtime/built-in-block-non-ts-family-artifacts.d.ts +8 -26
  8. package/dist/runtime/built-in-block-non-ts-family-artifacts.js +8 -1034
  9. package/dist/runtime/built-in-block-non-ts-interactivity-artifacts.d.ts +9 -0
  10. package/dist/runtime/built-in-block-non-ts-interactivity-artifacts.js +83 -0
  11. package/dist/runtime/built-in-block-non-ts-persistence-artifacts.d.ts +9 -0
  12. package/dist/runtime/built-in-block-non-ts-persistence-artifacts.js +33 -0
  13. package/dist/runtime/built-in-block-non-ts-persistence-templates.d.ts +23 -0
  14. package/dist/runtime/built-in-block-non-ts-persistence-templates.js +395 -0
  15. package/dist/runtime/cli-add-collision.js +8 -0
  16. package/dist/runtime/cli-add-help.js +10 -7
  17. package/dist/runtime/cli-add-kind-ids.d.ts +1 -1
  18. package/dist/runtime/cli-add-kind-ids.js +1 -0
  19. package/dist/runtime/cli-add-types.d.ts +28 -1
  20. package/dist/runtime/cli-add-types.js +2 -0
  21. package/dist/runtime/cli-add-workspace-ability-anchors.d.ts +24 -0
  22. package/dist/runtime/cli-add-workspace-ability-anchors.js +294 -0
  23. package/dist/runtime/cli-add-workspace-ability-registry.d.ts +10 -0
  24. package/dist/runtime/cli-add-workspace-ability-registry.js +51 -0
  25. package/dist/runtime/cli-add-workspace-ability-scaffold.d.ts +1 -1
  26. package/dist/runtime/cli-add-workspace-ability-scaffold.js +5 -311
  27. package/dist/runtime/cli-add-workspace-admin-view-scaffold.js +1 -1
  28. package/dist/runtime/cli-add-workspace-ai-anchors.d.ts +4 -4
  29. package/dist/runtime/cli-add-workspace-ai-anchors.js +4 -232
  30. package/dist/runtime/cli-add-workspace-ai-scaffold.js +4 -2
  31. package/dist/runtime/cli-add-workspace-ai-source-emitters.d.ts +1 -4
  32. package/dist/runtime/cli-add-workspace-ai-source-emitters.js +1 -145
  33. package/dist/runtime/cli-add-workspace-ai-sync-rest-anchors.d.ts +5 -0
  34. package/dist/runtime/cli-add-workspace-ai-sync-rest-anchors.js +236 -0
  35. package/dist/runtime/cli-add-workspace-ai-sync-script-source.d.ts +4 -0
  36. package/dist/runtime/cli-add-workspace-ai-sync-script-source.js +145 -0
  37. package/dist/runtime/cli-add-workspace-assets.d.ts +6 -63
  38. package/dist/runtime/cli-add-workspace-assets.js +6 -950
  39. package/dist/runtime/cli-add-workspace-binding-source-anchors.d.ts +23 -0
  40. package/dist/runtime/cli-add-workspace-binding-source-anchors.js +112 -0
  41. package/dist/runtime/cli-add-workspace-binding-source-source-emitters.d.ts +33 -0
  42. package/dist/runtime/cli-add-workspace-binding-source-source-emitters.js +436 -0
  43. package/dist/runtime/cli-add-workspace-binding-source-types.d.ts +20 -0
  44. package/dist/runtime/cli-add-workspace-binding-source-types.js +1 -0
  45. package/dist/runtime/cli-add-workspace-binding-source.d.ts +40 -0
  46. package/dist/runtime/cli-add-workspace-binding-source.js +275 -0
  47. package/dist/runtime/cli-add-workspace-block-style.d.ts +22 -0
  48. package/dist/runtime/cli-add-workspace-block-style.js +148 -0
  49. package/dist/runtime/cli-add-workspace-block-transform.d.ts +32 -0
  50. package/dist/runtime/cli-add-workspace-block-transform.js +197 -0
  51. package/dist/runtime/cli-add-workspace-contract.js +1 -1
  52. package/dist/runtime/cli-add-workspace-core-variation.d.ts +20 -0
  53. package/dist/runtime/cli-add-workspace-core-variation.js +322 -0
  54. package/dist/runtime/cli-add-workspace-editor-plugin-anchors.d.ts +37 -0
  55. package/dist/runtime/cli-add-workspace-editor-plugin-anchors.js +206 -0
  56. package/dist/runtime/cli-add-workspace-editor-plugin-source-emitters.d.ts +47 -0
  57. package/dist/runtime/cli-add-workspace-editor-plugin-source-emitters.js +219 -0
  58. package/dist/runtime/cli-add-workspace-editor-plugin.d.ts +22 -0
  59. package/dist/runtime/cli-add-workspace-editor-plugin.js +78 -0
  60. package/dist/runtime/cli-add-workspace-hooked-block.d.ts +23 -0
  61. package/dist/runtime/cli-add-workspace-hooked-block.js +57 -0
  62. package/dist/runtime/cli-add-workspace-integration-env-files.d.ts +33 -0
  63. package/dist/runtime/cli-add-workspace-integration-env-files.js +65 -0
  64. package/dist/runtime/cli-add-workspace-integration-env-package-json.d.ts +38 -0
  65. package/dist/runtime/cli-add-workspace-integration-env-package-json.js +122 -0
  66. package/dist/runtime/cli-add-workspace-integration-env-source-emitters.d.ts +44 -0
  67. package/dist/runtime/cli-add-workspace-integration-env-source-emitters.js +262 -0
  68. package/dist/runtime/cli-add-workspace-integration-env.js +5 -345
  69. package/dist/runtime/cli-add-workspace-pattern-anchors.d.ts +10 -0
  70. package/dist/runtime/cli-add-workspace-pattern-anchors.js +95 -0
  71. package/dist/runtime/cli-add-workspace-pattern-options.d.ts +20 -0
  72. package/dist/runtime/cli-add-workspace-pattern-options.js +113 -0
  73. package/dist/runtime/cli-add-workspace-pattern-source-emitters.d.ts +20 -0
  74. package/dist/runtime/cli-add-workspace-pattern-source-emitters.js +57 -0
  75. package/dist/runtime/cli-add-workspace-pattern.d.ts +42 -0
  76. package/dist/runtime/cli-add-workspace-pattern.js +99 -0
  77. package/dist/runtime/cli-add-workspace-post-meta.js +1 -1
  78. package/dist/runtime/cli-add-workspace-registration-hooks.d.ts +50 -0
  79. package/dist/runtime/cli-add-workspace-registration-hooks.js +162 -0
  80. package/dist/runtime/cli-add-workspace-rest-anchors.d.ts +6 -9
  81. package/dist/runtime/cli-add-workspace-rest-anchors.js +6 -466
  82. package/dist/runtime/cli-add-workspace-rest-bootstrap-anchors.d.ts +17 -0
  83. package/dist/runtime/cli-add-workspace-rest-bootstrap-anchors.js +108 -0
  84. package/dist/runtime/cli-add-workspace-rest-contract-sync-anchors.d.ts +9 -0
  85. package/dist/runtime/cli-add-workspace-rest-contract-sync-anchors.js +142 -0
  86. package/dist/runtime/cli-add-workspace-rest-generated-source-emitters.d.ts +51 -0
  87. package/dist/runtime/cli-add-workspace-rest-generated-source-emitters.js +415 -0
  88. package/dist/runtime/cli-add-workspace-rest-generated.js +5 -3
  89. package/dist/runtime/cli-add-workspace-rest-manual-source-emitters.d.ts +80 -0
  90. package/dist/runtime/cli-add-workspace-rest-manual-source-emitters.js +238 -0
  91. package/dist/runtime/cli-add-workspace-rest-manual.js +3 -16
  92. package/dist/runtime/cli-add-workspace-rest-php-templates.d.ts +1 -7
  93. package/dist/runtime/cli-add-workspace-rest-php-templates.js +3 -322
  94. package/dist/runtime/cli-add-workspace-rest-resource-php-routing-template.d.ts +33 -0
  95. package/dist/runtime/cli-add-workspace-rest-resource-php-routing-template.js +145 -0
  96. package/dist/runtime/cli-add-workspace-rest-resource-sync-anchors.d.ts +9 -0
  97. package/dist/runtime/cli-add-workspace-rest-resource-sync-anchors.js +162 -0
  98. package/dist/runtime/cli-add-workspace-rest-schema-helper-php-template.d.ts +7 -0
  99. package/dist/runtime/cli-add-workspace-rest-schema-helper-php-template.js +193 -0
  100. package/dist/runtime/cli-add-workspace-rest-source-emitters.d.ts +5 -99
  101. package/dist/runtime/cli-add-workspace-rest-source-emitters.js +5 -663
  102. package/dist/runtime/cli-add-workspace-rest-source-utils.d.ts +17 -0
  103. package/dist/runtime/cli-add-workspace-rest-source-utils.js +50 -0
  104. package/dist/runtime/cli-add-workspace-rest-sync-script-shared.d.ts +56 -0
  105. package/dist/runtime/cli-add-workspace-rest-sync-script-shared.js +122 -0
  106. package/dist/runtime/cli-add-workspace-rest-types.d.ts +3 -3
  107. package/dist/runtime/cli-add-workspace-variation.d.ts +22 -0
  108. package/dist/runtime/cli-add-workspace-variation.js +162 -0
  109. package/dist/runtime/cli-add-workspace.d.ts +42 -107
  110. package/dist/runtime/cli-add-workspace.js +42 -674
  111. package/dist/runtime/cli-add.d.ts +3 -3
  112. package/dist/runtime/cli-add.js +2 -2
  113. package/dist/runtime/cli-core.d.ts +2 -1
  114. package/dist/runtime/cli-core.js +1 -1
  115. package/dist/runtime/cli-doctor-workspace-bindings.js +59 -0
  116. package/dist/runtime/cli-doctor-workspace-block-addons.js +33 -5
  117. package/dist/runtime/cli-doctor.d.ts +2 -0
  118. package/dist/runtime/cli-doctor.js +13 -2
  119. package/dist/runtime/cli-help.js +6 -4
  120. package/dist/runtime/index.d.ts +5 -2
  121. package/dist/runtime/index.js +4 -2
  122. package/dist/runtime/local-dev-presets.js +2 -1
  123. package/dist/runtime/package-versions.d.ts +1 -0
  124. package/dist/runtime/package-versions.js +10 -2
  125. package/dist/runtime/pattern-catalog.d.ts +122 -0
  126. package/dist/runtime/pattern-catalog.js +471 -0
  127. package/dist/runtime/post-meta-binding-fields.d.ts +46 -0
  128. package/dist/runtime/post-meta-binding-fields.js +135 -0
  129. package/dist/runtime/typia-llm-json-schema.d.ts +24 -0
  130. package/dist/runtime/typia-llm-json-schema.js +33 -0
  131. package/dist/runtime/typia-llm-openapi-constraints.d.ts +20 -0
  132. package/dist/runtime/typia-llm-openapi-constraints.js +254 -0
  133. package/dist/runtime/typia-llm-projection.d.ts +25 -0
  134. package/dist/runtime/typia-llm-projection.js +58 -0
  135. package/dist/runtime/typia-llm-render.d.ts +21 -0
  136. package/dist/runtime/typia-llm-render.js +252 -0
  137. package/dist/runtime/typia-llm-sync.d.ts +10 -0
  138. package/dist/runtime/typia-llm-sync.js +63 -0
  139. package/dist/runtime/typia-llm-types.d.ts +197 -0
  140. package/dist/runtime/typia-llm-types.js +1 -0
  141. package/dist/runtime/typia-llm.d.ts +9 -255
  142. package/dist/runtime/typia-llm.js +5 -634
  143. package/dist/runtime/workspace-inventory-mutations.js +13 -0
  144. package/dist/runtime/workspace-inventory-section-descriptors.js +9 -1
  145. package/dist/runtime/workspace-inventory-templates.d.ts +2 -2
  146. package/dist/runtime/workspace-inventory-templates.js +9 -1
  147. package/dist/runtime/workspace-inventory-types.d.ts +9 -1
  148. package/package.json +8 -3
  149. package/templates/_shared/compound/core/scripts/block-config.ts.mustache +22 -0
  150. package/templates/_shared/compound/core/scripts/sync-types-to-block-json.ts.mustache +103 -2
  151. package/templates/_shared/compound/core/src/inner-blocks-templates.ts.mustache +13 -0
  152. package/templates/_shared/compound/persistence/scripts/block-config.ts.mustache +22 -1
@@ -1,1038 +1,12 @@
1
- import { buildAlternateRenderEntryArtifact, renderArtifact, toPhpSingleQuotedString, } from "./built-in-block-non-ts-render-utils.js";
2
- import { getScaffoldAlternateRenderTargets, isCompoundPersistenceEnabled, } from "./scaffold-template-variable-groups.js";
3
- const BASIC_STYLE_TEMPLATE = `/**
4
- * {{title}} Block Styles
5
- */
6
-
7
- .{{cssClassName}} {
8
- padding: 20px;
9
- border: 1px solid #ddd;
10
- border-radius: 4px;
11
- background-color: #fff;
12
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
13
-
14
- &.is-hidden {
15
- display: none;
16
- }
17
-
18
- &__content {
19
- font-size: 16px;
20
- line-height: 1.6;
21
- color: #333;
22
-
23
- // Alignment styles
24
- &[data-align="center"] {
25
- text-align: center;
26
- }
27
-
28
- &[data-align="right"] {
29
- text-align: right;
30
- }
31
-
32
- &[data-align="justify"] {
33
- text-align: justify;
34
- }
35
- }
36
-
37
- // Hover state
38
- &:hover {
39
- box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
40
- transition: box-shadow 0.2s ease;
41
- }
42
- }
43
- `;
44
- const BASIC_EDITOR_STYLE_TEMPLATE = `/**
45
- * {{title}} Block Editor Styles
46
- */
47
-
48
- .{{cssClassName}} {
49
- outline: 1px dashed #ddd;
50
- outline-offset: -1px;
51
- }
52
- `;
53
- const BASIC_RENDER_TEMPLATE = `<?php
54
- /**
55
- * Optional server render placeholder for {{title}}.
56
- *
57
- * The basic scaffold stays static by default. Keep \`src/save.tsx\` as the
58
- * canonical frontend output unless you intentionally convert this block into a
59
- * dynamic render path and add \`render\` to \`block.json\`.
60
- *
61
- * @package {{slug}}
62
- */
63
-
64
- if ( ! defined( 'ABSPATH' ) ) {
65
- exit;
66
- }
67
-
68
- ?>
69
- <div class="{{cssClassName}}__server-placeholder" hidden>
70
- <?php esc_html_e( 'Server render placeholder.', '{{textDomain}}' ); ?>
71
- </div>
72
- `;
73
- const INTERACTIVITY_STYLE_TEMPLATE = `.{{cssClassName}} {
74
- position: relative;
75
- padding: 1rem;
76
- border: 1px solid #dcdcde;
77
- border-radius: 0.75rem;
78
- background: #fff;
79
-
80
- &__content {
81
- display: grid;
82
- gap: 0.75rem;
83
- }
84
-
85
- &__counter {
86
- display: inline-flex;
87
- gap: 0.35rem;
88
- align-items: center;
89
- font-size: 0.9rem;
90
- font-weight: 600;
91
- }
92
-
93
- &__progress {
94
- width: 100%;
95
- height: 0.5rem;
96
- overflow: hidden;
97
- background: #f0f0f1;
98
- border-radius: 999px;
99
- }
100
-
101
- &__progress-bar {
102
- height: 100%;
103
- background: #3858e9;
104
- transition: width 0.2s ease;
105
- }
106
-
107
- &__animation {
108
- min-height: 1.5rem;
109
- font-size: 0.85rem;
110
- color: #3858e9;
111
- opacity: 0;
112
- transition: opacity 0.2s ease;
113
-
114
- &.is-active {
115
- opacity: 1;
116
- }
117
- }
118
-
119
- &__completion {
120
- font-weight: 700;
121
- color: #06752d;
122
- }
123
-
124
- &__reset {
125
- align-self: start;
126
- padding: 0.4rem 0.7rem;
127
- border: 1px solid #dcdcde;
128
- border-radius: 999px;
129
- background: transparent;
130
- cursor: pointer;
131
- }
132
- }
133
- `;
134
- const INTERACTIVITY_EDITOR_STYLE_TEMPLATE = `/**
135
- * {{title}} Block Editor Styles
136
- */
137
-
138
- .{{cssClassName}} {
139
- outline: 1px dashed #ddd;
140
- outline-offset: -1px;
141
- }
142
- `;
143
- const PERSISTENCE_STYLE_TEMPLATE = `.{{cssClassName}} {
144
- border: 1px solid #dcdcde;
145
- border-radius: 12px;
146
- padding: 16px;
147
- background: #fff;
148
-
149
- &__meta {
150
- color: #50575e;
151
- font-size: 13px;
152
- margin: 8px 0 0;
153
- }
154
- }
155
-
156
- .{{frontendCssClassName}} {
157
- display: grid;
158
- gap: 12px;
159
- border: 1px solid #dcdcde;
160
- border-radius: 12px;
161
- padding: 16px;
162
- background: #f6f7f7;
163
-
164
- &__count {
165
- display: inline-flex;
166
- min-width: 3rem;
167
- justify-content: center;
168
- font-weight: 700;
169
- }
170
-
171
- &__notice,
172
- &__error {
173
- margin: 0;
174
- font-size: 13px;
175
- }
176
-
177
- &__notice {
178
- color: #50575e;
179
- }
180
-
181
- &__error {
182
- color: #b32d2e;
183
- }
184
-
185
- button {
186
- width: fit-content;
187
- }
188
- }
189
- `;
190
- const PERSISTENCE_RENDER_TEMPLATE = `<?php
191
1
  /**
192
- * Dynamic render entry for the {{title}} block.
2
+ * Compatibility facade for non-TypeScript built-in block family artifact builders.
193
3
  *
194
- * @package {{pascalCase}}
195
- */
196
-
197
- if ( ! defined( 'ABSPATH' ) ) {
198
- exit;
199
- }
200
-
201
- $validator_path = __DIR__ . '/typia-validator.php';
202
- if ( ! file_exists( $validator_path ) ) {
203
- return '';
204
- }
205
-
206
- $validator = require $validator_path;
207
- if ( ! is_object( $validator ) || ! method_exists( $validator, 'apply_defaults' ) || ! method_exists( $validator, 'validate' ) ) {
208
- return '';
209
- }
210
-
211
- $normalized = $validator->apply_defaults( is_array( $attributes ) ? $attributes : array() );
212
- $validation = $validator->validate( $normalized );
213
- $resource_key = isset( $normalized['resourceKey'] ) ? (string) $normalized['resourceKey'] : '';
214
-
215
- if ( empty( $validation['valid'] ) || '' === $resource_key ) {
216
- return '';
217
- }
218
-
219
- $alignment = isset( $normalized['alignment'] ) ? (string) $normalized['alignment'] : 'left';
220
- $button_label = isset( $normalized['buttonLabel'] ) ? (string) $normalized['buttonLabel'] : 'Persist Count';
221
- $content = isset( $normalized['content'] ) ? (string) $normalized['content'] : '';
222
- $post_id = is_object( $block ) && isset( $block->context['postId'] )
223
- ? (int) $block->context['postId']
224
- : (int) get_queried_object_id();
225
- $storage_mode = '{{dataStorageMode}}';
226
- $persistence_policy = '{{persistencePolicy}}';
227
-
228
- {{phpPrefix}}_record_rendered_block_instance(
229
- (int) $post_id,
230
- '{{namespace}}/{{slugKebabCase}}',
231
- $resource_key
232
- );
233
-
234
- $notice_message = 'authenticated' === $persistence_policy
235
- ? __( 'Sign in to persist this counter.', '{{textDomain}}' )
236
- : __( 'Public writes are temporarily unavailable.', '{{textDomain}}' );
237
- $context = array(
238
- 'bootstrapReady' => false,
239
- 'buttonLabel' => $button_label,
240
- 'canWrite' => false,
241
- 'client' => array(
242
- 'writeExpiry' => 0,
243
- 'writeNonce' => '',
244
- 'writeToken' => '',
245
- ),
246
- 'count' => 0,
247
- 'error' => '',
248
- 'isBootstrapping' => false,
249
- 'isLoading' => false,
250
- 'isSaving' => false,
251
- 'isVisible' => ! empty( $normalized['isVisible'] ),
252
- 'persistencePolicy' => $persistence_policy,
253
- 'postId' => (int) $post_id,
254
- 'resourceKey' => $resource_key,
255
- 'storage' => $storage_mode,
256
- );
257
-
258
- $wrapper_attributes = get_block_wrapper_attributes(
259
- array(
260
- 'data-wp-context' => wp_json_encode( $context ),
261
- 'data-wp-interactive' => '{{slugKebabCase}}',
262
- 'data-wp-init' => 'callbacks.init',
263
- 'data-wp-run--mounted' => 'callbacks.mounted',
264
- )
265
- );
266
- ?>
267
-
268
- <div <?php echo $wrapper_attributes; ?>>
269
- <div class="{{frontendCssClassName}}">
270
- <p class="{{frontendCssClassName}}__content" style="<?php echo esc_attr( 'text-align:' . $alignment ); ?>">
271
- <?php echo esc_html( $content ); ?>
272
- </p>
273
- <p
274
- class="{{frontendCssClassName}}__notice"
275
- data-wp-bind--hidden="!context.bootstrapReady || context.canWrite"
276
- hidden
277
- >
278
- <?php echo esc_html( $notice_message ); ?>
279
- </p>
280
- <p
281
- class="{{frontendCssClassName}}__error"
282
- role="status"
283
- aria-live="polite"
284
- aria-atomic="true"
285
- data-wp-bind--hidden="!context.error"
286
- data-wp-text="context.error"
287
- hidden
288
- ></p>
289
- <?php if ( ! empty( $normalized['showCount'] ) ) : ?>
290
- <span
291
- class="{{frontendCssClassName}}__count"
292
- role="status"
293
- aria-live="polite"
294
- aria-atomic="true"
295
- data-wp-text="context.count"
296
- >
297
- 0
298
- </span>
299
- <?php endif; ?>
300
- <button
301
- type="button"
302
- disabled
303
- data-wp-bind--disabled="!context.canWrite"
304
- data-wp-on--click="actions.increment"
305
- >
306
- <?php echo esc_html( $button_label ); ?>
307
- </button>
308
- </div>
309
- </div>
310
- `;
311
- const PERSISTENCE_RENDER_TARGETS_TEMPLATE = `<?php
312
- /**
313
- * Alternate render target helpers for the {{title}} block.
314
- *
315
- * @package {{pascalCase}}
316
- */
317
-
318
- if ( ! defined( 'ABSPATH' ) ) {
319
- exit;
320
- }
321
-
322
- if ( ! function_exists( '{{phpPrefix}}_{{slugSnakeCase}}_build_render_context' ) ) {
323
- function {{phpPrefix}}_{{slugSnakeCase}}_build_render_context( $attributes, $content, $block ) {
324
- $validator_path = __DIR__ . '/typia-validator.php';
325
- if ( ! file_exists( $validator_path ) ) {
326
- return null;
327
- }
328
-
329
- $validator = require $validator_path;
330
- if ( ! is_object( $validator ) || ! method_exists( $validator, 'apply_defaults' ) || ! method_exists( $validator, 'validate' ) ) {
331
- return null;
332
- }
333
-
334
- $normalized = $validator->apply_defaults( is_array( $attributes ) ? $attributes : array() );
335
- $validation = $validator->validate( $normalized );
336
- $resource_key = isset( $normalized['resourceKey'] ) ? (string) $normalized['resourceKey'] : '';
337
-
338
- if ( empty( $validation['valid'] ) || '' === $resource_key ) {
339
- return null;
340
- }
341
-
342
- $alignment = isset( $normalized['alignment'] ) ? (string) $normalized['alignment'] : 'left';
343
- $button_label = isset( $normalized['buttonLabel'] ) ? (string) $normalized['buttonLabel'] : 'Persist Count';
344
- $rendered_content = isset( $normalized['content'] ) ? (string) $normalized['content'] : '';
345
- $post_id = is_object( $block ) && isset( $block->context['postId'] )
346
- ? (int) $block->context['postId']
347
- : (int) get_queried_object_id();
348
- $storage_mode = '{{dataStorageMode}}';
349
- $persistence_policy = '{{persistencePolicy}}';
350
-
351
- {{phpPrefix}}_record_rendered_block_instance(
352
- (int) $post_id,
353
- '{{namespace}}/{{slugKebabCase}}',
354
- $resource_key
355
- );
356
-
357
- $notice_message = 'authenticated' === $persistence_policy
358
- ? __( 'Sign in to persist this counter.', '{{textDomain}}' )
359
- : __( 'Public writes are temporarily unavailable.', '{{textDomain}}' );
360
- $web_context = array(
361
- 'bootstrapReady' => false,
362
- 'buttonLabel' => $button_label,
363
- 'canWrite' => false,
364
- 'client' => array(
365
- 'writeExpiry' => 0,
366
- 'writeNonce' => '',
367
- 'writeToken' => '',
368
- ),
369
- 'count' => 0,
370
- 'error' => '',
371
- 'isBootstrapping' => false,
372
- 'isLoading' => false,
373
- 'isSaving' => false,
374
- 'isVisible' => ! empty( $normalized['isVisible'] ),
375
- 'persistencePolicy' => $persistence_policy,
376
- 'postId' => (int) $post_id,
377
- 'resourceKey' => $resource_key,
378
- 'storage' => $storage_mode,
379
- );
380
-
381
- return array(
382
- 'alignment' => $alignment,
383
- 'buttonLabel' => $button_label,
384
- 'content' => $rendered_content,
385
- 'frontendClassName' => '{{frontendCssClassName}}',
386
- 'isVisible' => ! empty( $normalized['isVisible'] ),
387
- 'normalized' => $normalized,
388
- 'noticeMessage' => $notice_message,
389
- 'postId' => (int) $post_id,
390
- 'resourceKey' => $resource_key,
391
- 'showCount' => ! empty( $normalized['showCount'] ),
392
- 'title' => {{titleJson}},
393
- 'webContext' => $web_context,
394
- );
395
- }
396
- }
397
-
398
- if ( ! function_exists( '{{phpPrefix}}_{{slugSnakeCase}}_render_target' ) ) {
399
- function {{phpPrefix}}_{{slugSnakeCase}}_render_target( string $target, $attributes, $content = '', $block = null ): string {
400
- $context = {{phpPrefix}}_{{slugSnakeCase}}_build_render_context( $attributes, $content, $block );
401
- if ( null === $context || empty( $context['isVisible'] ) ) {
402
- return '';
403
- }
404
-
405
- $target_context = apply_filters(
406
- '{{phpPrefix}}_{{slugSnakeCase}}_render_target_context',
407
- $context,
408
- $target,
409
- $attributes,
410
- $block
411
- );
412
-
413
- $markup = '';
414
- switch ( $target ) {
415
- case 'email':
416
- $parts = array(
417
- '<div class="' . esc_attr( $target_context['frontendClassName'] ) . '-email">',
418
- '<p style="text-align:' . esc_attr( $target_context['alignment'] ) . ';">' . esc_html( $target_context['content'] ) . '</p>',
419
- );
420
- if ( ! empty( $target_context['showCount'] ) ) {
421
- $parts[] = '<p><strong>' . esc_html__( 'Count', '{{textDomain}}' ) . ':</strong> ' . esc_html( (string) $target_context['webContext']['count'] ) . '</p>';
422
- }
423
- $parts[] = '<p>' . esc_html( $target_context['noticeMessage'] ) . '</p>';
424
- $parts[] = '</div>';
425
- $markup = implode( '', $parts );
426
- break;
427
- case 'mjml':
428
- $markup = '<mjml><mj-body><mj-section><mj-column><mj-text align="' . esc_attr( $target_context['alignment'] ) . '">' . esc_html( $target_context['content'] ) . '</mj-text>';
429
- if ( ! empty( $target_context['showCount'] ) ) {
430
- $markup .= '<mj-text>' . esc_html__( 'Count', '{{textDomain}}' ) . ': ' . esc_html( (string) $target_context['webContext']['count'] ) . '</mj-text>';
431
- }
432
- $markup .= '<mj-text>' . esc_html( $target_context['noticeMessage'] ) . '</mj-text></mj-column></mj-section></mj-body></mjml>';
433
- break;
434
- case 'plain-text':
435
- $markup = implode(
436
- "\\n",
437
- array_filter(
438
- array(
439
- $target_context['title'],
440
- $target_context['content'],
441
- ! empty( $target_context['showCount'] )
442
- ? sprintf( '%s: %s', __( 'Count', '{{textDomain}}' ), (string) $target_context['webContext']['count'] )
443
- : null,
444
- $target_context['noticeMessage'],
445
- ),
446
- static fn( $value ) => is_string( $value ) && '' !== $value
447
- )
448
- );
449
- break;
450
- case 'web':
451
- default:
452
- $wrapper_attributes = get_block_wrapper_attributes(
453
- array(
454
- 'data-wp-context' => wp_json_encode( $target_context['webContext'] ),
455
- 'data-wp-interactive' => '{{slugKebabCase}}',
456
- 'data-wp-init' => 'callbacks.init',
457
- 'data-wp-run--mounted' => 'callbacks.mounted',
458
- )
459
- );
460
- ob_start();
461
- ?>
462
- <div <?php echo $wrapper_attributes; ?>>
463
- <div class="{{frontendCssClassName}}">
464
- <p class="{{frontendCssClassName}}__content" style="<?php echo esc_attr( 'text-align:' . $target_context['alignment'] ); ?>">
465
- <?php echo esc_html( $target_context['content'] ); ?>
466
- </p>
467
- <p
468
- class="{{frontendCssClassName}}__notice"
469
- data-wp-bind--hidden="!context.bootstrapReady || context.canWrite"
470
- hidden
471
- >
472
- <?php echo esc_html( $target_context['noticeMessage'] ); ?>
473
- </p>
474
- <p
475
- class="{{frontendCssClassName}}__error"
476
- role="status"
477
- aria-live="polite"
478
- aria-atomic="true"
479
- data-wp-bind--hidden="!context.error"
480
- data-wp-text="context.error"
481
- hidden
482
- ></p>
483
- <?php if ( ! empty( $target_context['showCount'] ) ) : ?>
484
- <span
485
- class="{{frontendCssClassName}}__count"
486
- role="status"
487
- aria-live="polite"
488
- aria-atomic="true"
489
- data-wp-text="context.count"
490
- >
491
- 0
492
- </span>
493
- <?php endif; ?>
494
- <button
495
- type="button"
496
- disabled
497
- data-wp-bind--disabled="!context.canWrite"
498
- data-wp-on--click="actions.increment"
499
- >
500
- <?php echo esc_html( $target_context['buttonLabel'] ); ?>
501
- </button>
502
- </div>
503
- </div>
504
- <?php
505
- $markup = (string) ob_get_clean();
506
- break;
507
- }
508
-
509
- return apply_filters(
510
- '{{phpPrefix}}_{{slugSnakeCase}}_render_target_markup',
511
- $markup,
512
- $target,
513
- $target_context
514
- );
515
- }
516
- }
517
- `;
518
- const COMPOUND_PERSISTENCE_RENDER_TARGETS_TEMPLATE = `<?php
519
- /**
520
- * Alternate render target helpers for the {{title}} compound parent block.
521
- *
522
- * @package {{pascalCase}}
523
- */
524
-
525
- if ( ! defined( 'ABSPATH' ) ) {
526
- exit;
527
- }
528
-
529
- if ( ! function_exists( '{{phpPrefix}}_{{slugSnakeCase}}_build_render_context' ) ) {
530
- function {{phpPrefix}}_{{slugSnakeCase}}_build_render_context( $attributes, $content, $block ) {
531
- $validator_path = __DIR__ . '/typia-validator.php';
532
- if ( ! file_exists( $validator_path ) ) {
533
- return null;
534
- }
535
-
536
- $validator = require $validator_path;
537
- if ( ! is_object( $validator ) || ! method_exists( $validator, 'apply_defaults' ) || ! method_exists( $validator, 'validate' ) ) {
538
- return null;
539
- }
540
-
541
- $normalized = $validator->apply_defaults( is_array( $attributes ) ? $attributes : array() );
542
- $validation = $validator->validate( $normalized );
543
- $resource_key = isset( $normalized['resourceKey'] ) ? (string) $normalized['resourceKey'] : '';
544
- $heading = isset( $normalized['heading'] ) ? (string) $normalized['heading'] : {{titlePhpLiteral}};
545
- $intro = isset( $normalized['intro'] ) ? (string) $normalized['intro'] : '';
546
- $button_label = isset( $normalized['buttonLabel'] ) ? (string) $normalized['buttonLabel'] : 'Persist Count';
547
- $show_count = ! empty( $normalized['showCount'] );
548
- $show_dividers = ! empty( $normalized['showDividers'] );
549
- $post_id = is_object( $block ) && isset( $block->context['postId'] )
550
- ? (int) $block->context['postId']
551
- : (int) get_queried_object_id();
552
- $storage_mode = '{{dataStorageMode}}';
553
- $persistence_policy = '{{persistencePolicy}}';
554
-
555
- $notice_message = 'authenticated' === $persistence_policy
556
- ? __( 'Sign in to persist this counter.', '{{textDomain}}' )
557
- : __( 'Public writes are temporarily unavailable.', '{{textDomain}}' );
558
-
559
- if ( empty( $validation['valid'] ) || '' === $resource_key ) {
560
- return null;
561
- }
562
-
563
- {{phpPrefix}}_record_rendered_block_instance(
564
- (int) $post_id,
565
- '{{namespace}}/{{slugKebabCase}}',
566
- $resource_key
567
- );
568
-
569
- $web_context = array(
570
- 'bootstrapReady' => false,
571
- 'buttonLabel' => $button_label,
572
- 'canWrite' => false,
573
- 'client' => array(
574
- 'writeExpiry' => 0,
575
- 'writeNonce' => '',
576
- 'writeToken' => '',
577
- ),
578
- 'count' => 0,
579
- 'error' => '',
580
- 'isBootstrapping' => false,
581
- 'isLoading' => false,
582
- 'isSaving' => false,
583
- 'persistencePolicy' => $persistence_policy,
584
- 'postId' => (int) $post_id,
585
- 'resourceKey' => $resource_key,
586
- 'showCount' => $show_count,
587
- 'storage' => $storage_mode,
588
- );
589
-
590
- $allowed_inner_html = wp_kses_allowed_html( 'post' );
591
-
592
- foreach ( $allowed_inner_html as &$allowed_attributes ) {
593
- if ( ! is_array( $allowed_attributes ) ) {
594
- continue;
595
- }
596
-
597
- $allowed_attributes['data-wp-bind--disabled'] = true;
598
- $allowed_attributes['data-wp-bind--hidden'] = true;
599
- $allowed_attributes['data-wp-bind--value'] = true;
600
- $allowed_attributes['data-wp-class'] = true;
601
- $allowed_attributes['data-wp-class--active'] = true;
602
- $allowed_attributes['data-wp-context'] = true;
603
- $allowed_attributes['data-wp-init'] = true;
604
- $allowed_attributes['data-wp-interactive'] = true;
605
- $allowed_attributes['data-wp-on--click'] = true;
606
- $allowed_attributes['data-wp-on--mouseenter'] = true;
607
- $allowed_attributes['data-wp-on--mouseleave'] = true;
608
- $allowed_attributes['data-wp-run--mounted'] = true;
609
- $allowed_attributes['data-wp-style--width'] = true;
610
- $allowed_attributes['data-wp-text'] = true;
611
- }
612
- unset( $allowed_attributes );
613
-
614
- return array(
615
- 'buttonLabel' => $button_label,
616
- 'frontendClassName' => '{{cssClassName}}',
617
- 'heading' => $heading,
618
- 'intro' => $intro,
619
- 'isVisible' => true,
620
- 'normalized' => $normalized,
621
- 'noticeMessage' => $notice_message,
622
- 'postId' => (int) $post_id,
623
- 'resourceKey' => $resource_key,
624
- 'sanitizedContent' => wp_kses( $content, $allowed_inner_html ),
625
- 'showCount' => $show_count,
626
- 'showDividers' => $show_dividers,
627
- 'title' => {{titleJson}},
628
- 'webContext' => $web_context,
629
- );
630
- }
631
- }
632
-
633
- if ( ! function_exists( '{{phpPrefix}}_{{slugSnakeCase}}_render_target' ) ) {
634
- function {{phpPrefix}}_{{slugSnakeCase}}_render_target( string $target, $attributes, $content = '', $block = null ): string {
635
- $context = {{phpPrefix}}_{{slugSnakeCase}}_build_render_context( $attributes, $content, $block );
636
- if ( null === $context ) {
637
- return '';
638
- }
639
-
640
- $target_context = apply_filters(
641
- '{{phpPrefix}}_{{slugSnakeCase}}_render_target_context',
642
- $context,
643
- $target,
644
- $attributes,
645
- $block
646
- );
647
-
648
- $markup = '';
649
- switch ( $target ) {
650
- case 'email':
651
- $parts = array(
652
- '<div class="' . esc_attr( $target_context['frontendClassName'] ) . '-email">',
653
- '<h3>' . esc_html( $target_context['heading'] ) . '</h3>',
654
- );
655
- if ( '' !== $target_context['intro'] ) {
656
- $parts[] = '<p>' . esc_html( $target_context['intro'] ) . '</p>';
657
- }
658
- if ( ! empty( $target_context['showCount'] ) ) {
659
- $parts[] = '<p><strong>' . esc_html__( 'Count', '{{textDomain}}' ) . ':</strong> ' . esc_html( (string) $target_context['webContext']['count'] ) . '</p>';
660
- }
661
- $parts[] = wp_kses_post( $target_context['sanitizedContent'] );
662
- $parts[] = '<p>' . esc_html( $target_context['noticeMessage'] ) . '</p>';
663
- $parts[] = '</div>';
664
- $markup = implode( '', $parts );
665
- break;
666
- case 'mjml':
667
- $markup = '<mjml><mj-body><mj-section><mj-column><mj-text font-weight="700">' . esc_html( $target_context['heading'] ) . '</mj-text>';
668
- if ( '' !== $target_context['intro'] ) {
669
- $markup .= '<mj-text>' . esc_html( $target_context['intro'] ) . '</mj-text>';
670
- }
671
- if ( ! empty( $target_context['showCount'] ) ) {
672
- $markup .= '<mj-text>' . esc_html__( 'Count', '{{textDomain}}' ) . ': ' . esc_html( (string) $target_context['webContext']['count'] ) . '</mj-text>';
673
- }
674
- $markup .= '<mj-text>' . esc_html( wp_strip_all_tags( $target_context['sanitizedContent'] ) ) . '</mj-text>';
675
- $markup .= '<mj-text>' . esc_html( $target_context['noticeMessage'] ) . '</mj-text></mj-column></mj-section></mj-body></mjml>';
676
- break;
677
- case 'plain-text':
678
- $markup = implode(
679
- "\\n",
680
- array_filter(
681
- array(
682
- $target_context['heading'],
683
- $target_context['intro'],
684
- wp_strip_all_tags( $target_context['sanitizedContent'] ),
685
- ! empty( $target_context['showCount'] )
686
- ? sprintf( '%s: %s', __( 'Count', '{{textDomain}}' ), (string) $target_context['webContext']['count'] )
687
- : null,
688
- $target_context['noticeMessage'],
689
- ),
690
- static fn( $value ) => is_string( $value ) && '' !== $value
691
- )
692
- );
693
- break;
694
- case 'web':
695
- default:
696
- $wrapper_attributes = get_block_wrapper_attributes(
697
- array(
698
- 'class' => '{{cssClassName}}',
699
- 'data-show-dividers' => $target_context['showDividers'] ? 'true' : 'false',
700
- 'data-wp-context' => wp_json_encode( $target_context['webContext'] ),
701
- 'data-wp-init' => 'callbacks.init',
702
- 'data-wp-interactive' => '{{slugKebabCase}}',
703
- 'data-wp-run--mounted' => 'callbacks.mounted',
704
- )
705
- );
706
- ob_start();
707
- ?>
708
- <div <?php echo $wrapper_attributes; ?>>
709
- <h3 class="{{cssClassName}}__heading"><?php echo esc_html( $target_context['heading'] ); ?></h3>
710
- <?php if ( '' !== $target_context['intro'] ) : ?>
711
- <p class="{{cssClassName}}__intro"><?php echo esc_html( $target_context['intro'] ); ?></p>
712
- <?php endif; ?>
713
- <p
714
- class="{{cssClassName}}__notice"
715
- data-wp-bind--hidden="!context.bootstrapReady || context.canWrite"
716
- hidden
717
- >
718
- <?php echo esc_html( $target_context['noticeMessage'] ); ?>
719
- </p>
720
- <p
721
- class="{{cssClassName}}__error"
722
- role="status"
723
- aria-live="polite"
724
- aria-atomic="true"
725
- data-wp-bind--hidden="!context.error"
726
- data-wp-text="context.error"
727
- hidden
728
- ></p>
729
- <?php if ( ! empty( $target_context['showCount'] ) ) : ?>
730
- <div class="{{cssClassName}}__counter">
731
- <span
732
- class="{{cssClassName}}__count"
733
- role="status"
734
- aria-live="polite"
735
- aria-atomic="true"
736
- data-wp-text="context.count"
737
- >0</span>
738
- <button
739
- type="button"
740
- disabled
741
- data-wp-bind--disabled="!context.canWrite"
742
- data-wp-on--click="actions.increment"
743
- >
744
- <?php echo esc_html( $target_context['buttonLabel'] ); ?>
745
- </button>
746
- </div>
747
- <?php endif; ?>
748
- <div class="{{cssClassName}}__items">
749
- <?php echo wp_kses_post( $target_context['sanitizedContent'] ); ?>
750
- </div>
751
- </div>
752
- <?php
753
- $markup = (string) ob_get_clean();
754
- break;
755
- }
756
-
757
- return apply_filters(
758
- '{{phpPrefix}}_{{slugSnakeCase}}_render_target_markup',
759
- $markup,
760
- $target,
761
- $target_context
762
- );
763
- }
764
- }
765
- `;
766
- const COMPOUND_STYLE_TEMPLATE = `.{{cssClassName}} {
767
- border: 1px solid #dcdcde;
768
- border-radius: 12px;
769
- padding: 1.25rem;
770
- background: #fff;
771
- }
772
-
773
- .{{cssClassName}}__heading {
774
- margin: 0 0 0.5rem;
775
- font-size: 1.2rem;
776
- }
777
-
778
- .{{cssClassName}}__intro {
779
- margin: 0 0 1rem;
780
- color: #50575e;
781
- }
782
-
783
- .{{cssClassName}}__items {
784
- display: grid;
785
- gap: 0.75rem;
786
- }
787
-
788
- .{{cssClassName}}[data-show-dividers='true'] .{{compoundChildCssClassName}} {
789
- border-top: 1px solid #dcdcde;
790
- padding-top: 0.75rem;
791
- }
792
-
793
- .{{cssClassName}}[data-show-dividers='true'] .{{compoundChildCssClassName}}:first-child {
794
- border-top: 0;
795
- padding-top: 0;
796
- }
797
- `;
798
- /**
799
- * Builds the basic family non-TypeScript scaffold artifacts.
800
- *
801
- * @param variables Scaffold template variables used to render the artifact set.
802
- * @returns The SCSS and PHP artifacts owned by the basic template family.
803
- */
804
- export function buildBasicArtifacts(variables) {
805
- return [
806
- renderArtifact("src/editor.scss", BASIC_EDITOR_STYLE_TEMPLATE, variables),
807
- renderArtifact("src/style.scss", BASIC_STYLE_TEMPLATE, variables),
808
- renderArtifact("src/render.php", BASIC_RENDER_TEMPLATE, variables),
809
- ];
810
- }
811
- /**
812
- * Builds the interactivity family non-TypeScript scaffold artifacts.
813
- *
814
- * @param variables Scaffold template variables used to render the artifact set.
815
- * @returns The SCSS artifacts owned by the interactivity template family.
816
- */
817
- export function buildInteractivityArtifacts(variables) {
818
- return [
819
- renderArtifact("src/editor.scss", INTERACTIVITY_EDITOR_STYLE_TEMPLATE, variables),
820
- renderArtifact("src/style.scss", INTERACTIVITY_STYLE_TEMPLATE, variables),
821
- ];
822
- }
823
- /**
824
- * Builds the persistence family non-TypeScript scaffold artifacts.
825
- *
826
- * @param variables Scaffold template variables used to render the artifact set.
827
- * @returns The persistence SCSS and PHP artifacts for the selected render targets.
828
- */
829
- export function buildPersistenceArtifacts(variables) {
830
- const alternateRenderTargets = getScaffoldAlternateRenderTargets(variables);
831
- if (!alternateRenderTargets.enabled) {
832
- return [
833
- renderArtifact("src/style.scss", PERSISTENCE_STYLE_TEMPLATE, variables),
834
- renderArtifact("src/render.php", PERSISTENCE_RENDER_TEMPLATE, variables),
835
- ];
836
- }
837
- const artifacts = [
838
- renderArtifact("src/style.scss", PERSISTENCE_STYLE_TEMPLATE, variables),
839
- renderArtifact("src/render-targets.php", PERSISTENCE_RENDER_TARGETS_TEMPLATE, variables),
840
- buildAlternateRenderEntryArtifact("src/render.php", "web", variables),
841
- ];
842
- if (alternateRenderTargets.hasEmail) {
843
- artifacts.push(buildAlternateRenderEntryArtifact("src/render-email.php", "email", variables));
844
- }
845
- if (alternateRenderTargets.hasMjml) {
846
- artifacts.push(buildAlternateRenderEntryArtifact("src/render-mjml.php", "mjml", variables));
847
- }
848
- if (alternateRenderTargets.hasPlainText) {
849
- artifacts.push(buildAlternateRenderEntryArtifact("src/render-text.php", "plain-text", variables));
850
- }
851
- return artifacts;
852
- }
853
- /**
854
- * Builds the compound family non-TypeScript scaffold artifacts.
855
- *
856
- * @param variables Scaffold template variables used to render the artifact set.
857
- * @returns The compound SCSS and PHP artifacts, including persistence variants when enabled.
858
- */
859
- export function buildCompoundArtifacts(variables) {
860
- const alternateRenderTargets = getScaffoldAlternateRenderTargets(variables);
861
- const artifacts = [
862
- renderArtifact(`src/blocks/${variables.slugKebabCase}/style.scss`, COMPOUND_STYLE_TEMPLATE, variables),
863
- ];
864
- if (isCompoundPersistenceEnabled(variables)) {
865
- const renderView = {
866
- ...variables,
867
- titlePhpLiteral: toPhpSingleQuotedString(variables.title),
868
- };
869
- if (alternateRenderTargets.enabled) {
870
- artifacts.push(renderArtifact(`src/blocks/${variables.slugKebabCase}/render-targets.php`, COMPOUND_PERSISTENCE_RENDER_TARGETS_TEMPLATE, renderView), buildAlternateRenderEntryArtifact(`src/blocks/${variables.slugKebabCase}/render.php`, "web", variables));
871
- if (alternateRenderTargets.hasEmail) {
872
- artifacts.push(buildAlternateRenderEntryArtifact(`src/blocks/${variables.slugKebabCase}/render-email.php`, "email", variables));
873
- }
874
- if (alternateRenderTargets.hasMjml) {
875
- artifacts.push(buildAlternateRenderEntryArtifact(`src/blocks/${variables.slugKebabCase}/render-mjml.php`, "mjml", variables));
876
- }
877
- if (alternateRenderTargets.hasPlainText) {
878
- artifacts.push(buildAlternateRenderEntryArtifact(`src/blocks/${variables.slugKebabCase}/render-text.php`, "plain-text", variables));
879
- }
880
- return artifacts;
881
- }
882
- const renderSource = `<?php
883
- /**
884
- * Dynamic render entry for the {{title}} compound parent block.
4
+ * Re-export these stable builder entrypoints when callers need to resolve a
5
+ * built-in family without depending on the focused implementation modules.
885
6
  *
886
- * @package {{pascalCase}}
7
+ * @since 0.0.0
887
8
  */
888
-
889
- if ( ! defined( 'ABSPATH' ) ) {
890
- exit;
891
- }
892
-
893
- $validator_path = __DIR__ . '/typia-validator.php';
894
- if ( ! file_exists( $validator_path ) ) {
895
- return '';
896
- }
897
-
898
- $validator = require $validator_path;
899
- if ( ! is_object( $validator ) || ! method_exists( $validator, 'apply_defaults' ) || ! method_exists( $validator, 'validate' ) ) {
900
- return '';
901
- }
902
-
903
- $normalized = $validator->apply_defaults( is_array( $attributes ) ? $attributes : array() );
904
- $validation = $validator->validate( $normalized );
905
- $resource_key = isset( $normalized['resourceKey'] ) ? (string) $normalized['resourceKey'] : '';
906
- $heading = isset( $normalized['heading'] ) ? (string) $normalized['heading'] : {{titlePhpLiteral}};
907
- $intro = isset( $normalized['intro'] ) ? (string) $normalized['intro'] : '';
908
- $button_label = isset( $normalized['buttonLabel'] ) ? (string) $normalized['buttonLabel'] : 'Persist Count';
909
- $show_count = ! empty( $normalized['showCount'] );
910
- $show_dividers = ! empty( $normalized['showDividers'] );
911
- $post_id = is_object( $block ) && isset( $block->context['postId'] )
912
- ? (int) $block->context['postId']
913
- : (int) get_queried_object_id();
914
- $storage_mode = '{{dataStorageMode}}';
915
- $persistence_policy = '{{persistencePolicy}}';
916
-
917
- $notice_message = 'authenticated' === $persistence_policy
918
- ? __( 'Sign in to persist this counter.', '{{textDomain}}' )
919
- : __( 'Public writes are temporarily unavailable.', '{{textDomain}}' );
920
-
921
- if ( empty( $validation['valid'] ) || '' === $resource_key ) {
922
- return '';
923
- }
924
-
925
- {{phpPrefix}}_record_rendered_block_instance(
926
- (int) $post_id,
927
- '{{namespace}}/{{slugKebabCase}}',
928
- $resource_key
929
- );
930
-
931
- $context = array(
932
- 'bootstrapReady' => false,
933
- 'buttonLabel' => $button_label,
934
- 'canWrite' => false,
935
- 'client' => array(
936
- 'writeExpiry' => 0,
937
- 'writeNonce' => '',
938
- 'writeToken' => '',
939
- ),
940
- 'count' => 0,
941
- 'error' => '',
942
- 'isBootstrapping' => false,
943
- 'isLoading' => false,
944
- 'isSaving' => false,
945
- 'persistencePolicy' => $persistence_policy,
946
- 'postId' => (int) $post_id,
947
- 'resourceKey' => $resource_key,
948
- 'showCount' => $show_count,
949
- 'storage' => $storage_mode,
950
- );
951
-
952
- $allowed_inner_html = wp_kses_allowed_html( 'post' );
953
-
954
- foreach ( $allowed_inner_html as &$allowed_attributes ) {
955
- if ( ! is_array( $allowed_attributes ) ) {
956
- continue;
957
- }
958
-
959
- $allowed_attributes['data-wp-bind--disabled'] = true;
960
- $allowed_attributes['data-wp-bind--hidden'] = true;
961
- $allowed_attributes['data-wp-bind--value'] = true;
962
- $allowed_attributes['data-wp-class'] = true;
963
- $allowed_attributes['data-wp-class--active'] = true;
964
- $allowed_attributes['data-wp-context'] = true;
965
- $allowed_attributes['data-wp-init'] = true;
966
- $allowed_attributes['data-wp-interactive'] = true;
967
- $allowed_attributes['data-wp-on--click'] = true;
968
- $allowed_attributes['data-wp-on--mouseenter'] = true;
969
- $allowed_attributes['data-wp-on--mouseleave'] = true;
970
- $allowed_attributes['data-wp-run--mounted'] = true;
971
- $allowed_attributes['data-wp-style--width'] = true;
972
- $allowed_attributes['data-wp-text'] = true;
973
- }
974
- unset( $allowed_attributes );
975
-
976
- $sanitized_content = wp_kses( $content, $allowed_inner_html );
977
-
978
- $wrapper_attributes = get_block_wrapper_attributes(
979
- array(
980
- 'class' => '{{cssClassName}}',
981
- 'data-show-dividers' => $show_dividers ? 'true' : 'false',
982
- 'data-wp-context' => wp_json_encode( $context ),
983
- 'data-wp-init' => 'callbacks.init',
984
- 'data-wp-interactive' => '{{slugKebabCase}}',
985
- 'data-wp-run--mounted' => 'callbacks.mounted',
986
- )
987
- );
988
- ?>
989
-
990
- <div <?php echo $wrapper_attributes; ?>>
991
- <h3 class="{{cssClassName}}__heading"><?php echo esc_html( $heading ); ?></h3>
992
- <?php if ( '' !== $intro ) : ?>
993
- <p class="{{cssClassName}}__intro"><?php echo esc_html( $intro ); ?></p>
994
- <?php endif; ?>
995
- <p
996
- class="{{cssClassName}}__notice"
997
- data-wp-bind--hidden="!context.bootstrapReady || context.canWrite"
998
- hidden
999
- >
1000
- <?php echo esc_html( $notice_message ); ?>
1001
- </p>
1002
- <p
1003
- class="{{cssClassName}}__error"
1004
- role="status"
1005
- aria-live="polite"
1006
- aria-atomic="true"
1007
- data-wp-bind--hidden="!context.error"
1008
- data-wp-text="context.error"
1009
- hidden
1010
- ></p>
1011
- <?php if ( $show_count ) : ?>
1012
- <div class="{{cssClassName}}__counter">
1013
- <span
1014
- class="{{cssClassName}}__count"
1015
- role="status"
1016
- aria-live="polite"
1017
- aria-atomic="true"
1018
- data-wp-text="context.count"
1019
- >0</span>
1020
- <button
1021
- type="button"
1022
- disabled
1023
- data-wp-bind--disabled="!context.canWrite"
1024
- data-wp-on--click="actions.increment"
1025
- >
1026
- <?php echo esc_html( $button_label ); ?>
1027
- </button>
1028
- </div>
1029
- <?php endif; ?>
1030
- <div class="{{cssClassName}}__items">
1031
- <?php echo $sanitized_content; ?>
1032
- </div>
1033
- </div>
1034
- `;
1035
- artifacts.push(renderArtifact(`src/blocks/${variables.slugKebabCase}/render.php`, renderSource, renderView));
1036
- }
1037
- return artifacts;
1038
- }
9
+ export { buildBasicArtifacts } from "./built-in-block-non-ts-basic-artifacts.js";
10
+ export { buildCompoundArtifacts } from "./built-in-block-non-ts-compound-artifacts.js";
11
+ export { buildInteractivityArtifacts } from "./built-in-block-non-ts-interactivity-artifacts.js";
12
+ export { buildPersistenceArtifacts } from "./built-in-block-non-ts-persistence-artifacts.js";