@wp-typia/project-tools 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/README.md +32 -0
  2. package/dist/runtime/cli-add.d.ts +38 -0
  3. package/dist/runtime/cli-add.js +561 -0
  4. package/dist/runtime/cli-core.d.ts +25 -0
  5. package/dist/runtime/cli-core.js +25 -0
  6. package/dist/runtime/cli-doctor.d.ts +34 -0
  7. package/dist/runtime/cli-doctor.js +131 -0
  8. package/dist/runtime/cli-help.d.ts +9 -0
  9. package/dist/runtime/cli-help.js +37 -0
  10. package/dist/runtime/cli-prompt.d.ts +21 -0
  11. package/dist/runtime/cli-prompt.js +53 -0
  12. package/dist/runtime/cli-scaffold.d.ts +79 -0
  13. package/dist/runtime/cli-scaffold.js +206 -0
  14. package/dist/runtime/cli-templates.d.ts +30 -0
  15. package/dist/runtime/cli-templates.js +61 -0
  16. package/dist/runtime/index.d.ts +9 -0
  17. package/dist/runtime/index.js +7 -0
  18. package/dist/runtime/json-utils.d.ts +10 -0
  19. package/dist/runtime/json-utils.js +12 -0
  20. package/dist/runtime/local-dev-presets.d.ts +26 -0
  21. package/dist/runtime/local-dev-presets.js +132 -0
  22. package/dist/runtime/metadata-analysis.d.ts +11 -0
  23. package/dist/runtime/metadata-analysis.js +285 -0
  24. package/dist/runtime/metadata-model.d.ts +84 -0
  25. package/dist/runtime/metadata-model.js +59 -0
  26. package/dist/runtime/metadata-parser.d.ts +53 -0
  27. package/dist/runtime/metadata-parser.js +794 -0
  28. package/dist/runtime/metadata-php-render.d.ts +29 -0
  29. package/dist/runtime/metadata-php-render.js +549 -0
  30. package/dist/runtime/metadata-projection.d.ts +7 -0
  31. package/dist/runtime/metadata-projection.js +233 -0
  32. package/dist/runtime/migration-constants.d.ts +15 -0
  33. package/dist/runtime/migration-constants.js +16 -0
  34. package/dist/runtime/migration-diff.d.ts +2 -0
  35. package/dist/runtime/migration-diff.js +537 -0
  36. package/dist/runtime/migration-fixtures.d.ts +8 -0
  37. package/dist/runtime/migration-fixtures.js +94 -0
  38. package/dist/runtime/migration-fuzz-plan.d.ts +2 -0
  39. package/dist/runtime/migration-fuzz-plan.js +50 -0
  40. package/dist/runtime/migration-manifest.d.ts +19 -0
  41. package/dist/runtime/migration-manifest.js +129 -0
  42. package/dist/runtime/migration-project.d.ts +94 -0
  43. package/dist/runtime/migration-project.js +1101 -0
  44. package/dist/runtime/migration-render.d.ts +11 -0
  45. package/dist/runtime/migration-render.js +741 -0
  46. package/dist/runtime/migration-risk.d.ts +4 -0
  47. package/dist/runtime/migration-risk.js +52 -0
  48. package/dist/runtime/migration-types.d.ts +249 -0
  49. package/dist/runtime/migration-types.js +1 -0
  50. package/dist/runtime/migration-ui-capability.d.ts +17 -0
  51. package/dist/runtime/migration-ui-capability.js +190 -0
  52. package/dist/runtime/migration-utils.d.ts +69 -0
  53. package/dist/runtime/migration-utils.js +246 -0
  54. package/dist/runtime/migrations.d.ts +249 -0
  55. package/dist/runtime/migrations.js +1061 -0
  56. package/dist/runtime/object-utils.d.ts +12 -0
  57. package/dist/runtime/object-utils.js +14 -0
  58. package/dist/runtime/package-managers.d.ts +28 -0
  59. package/dist/runtime/package-managers.js +156 -0
  60. package/dist/runtime/package-versions.d.ts +10 -0
  61. package/dist/runtime/package-versions.js +68 -0
  62. package/dist/runtime/scaffold-onboarding.d.ts +32 -0
  63. package/dist/runtime/scaffold-onboarding.js +99 -0
  64. package/dist/runtime/scaffold.d.ts +146 -0
  65. package/dist/runtime/scaffold.js +612 -0
  66. package/dist/runtime/schema-core.d.ts +267 -0
  67. package/dist/runtime/schema-core.js +597 -0
  68. package/dist/runtime/starter-manifests.d.ts +25 -0
  69. package/dist/runtime/starter-manifests.js +383 -0
  70. package/dist/runtime/string-case.d.ts +36 -0
  71. package/dist/runtime/string-case.js +69 -0
  72. package/dist/runtime/template-builtins.d.ts +38 -0
  73. package/dist/runtime/template-builtins.js +72 -0
  74. package/dist/runtime/template-defaults.d.ts +75 -0
  75. package/dist/runtime/template-defaults.js +65 -0
  76. package/dist/runtime/template-registry.d.ts +36 -0
  77. package/dist/runtime/template-registry.js +94 -0
  78. package/dist/runtime/template-render.d.ts +24 -0
  79. package/dist/runtime/template-render.js +113 -0
  80. package/dist/runtime/template-source.d.ts +71 -0
  81. package/dist/runtime/template-source.js +821 -0
  82. package/dist/runtime/typia-tags.d.ts +1 -0
  83. package/dist/runtime/typia-tags.js +1 -0
  84. package/package.json +79 -0
  85. package/templates/_shared/base/languages/.gitkeep +1 -0
  86. package/templates/_shared/base/package.json.mustache +41 -0
  87. package/templates/_shared/base/scripts/sync-types-to-block-json.ts.mustache +118 -0
  88. package/templates/_shared/base/src/hooks.ts.mustache +19 -0
  89. package/templates/_shared/base/src/validator-toolkit.ts.mustache +31 -0
  90. package/templates/_shared/base/tsconfig.json.mustache +21 -0
  91. package/templates/_shared/base/webpack.config.js.mustache +99 -0
  92. package/templates/_shared/base/{{slugKebabCase}}.php.mustache +53 -0
  93. package/templates/_shared/compound/core/package.json.mustache +45 -0
  94. package/templates/_shared/compound/core/scripts/add-compound-child.ts.mustache +559 -0
  95. package/templates/_shared/compound/core/scripts/block-config.ts.mustache +13 -0
  96. package/templates/_shared/compound/core/scripts/sync-types-to-block-json.ts.mustache +53 -0
  97. package/templates/_shared/compound/core/webpack.config.js.mustache +141 -0
  98. package/templates/_shared/compound/core/{{slugKebabCase}}.php.mustache +51 -0
  99. package/templates/_shared/compound/persistence/package.json.mustache +50 -0
  100. package/templates/_shared/compound/persistence/scripts/block-config.ts.mustache +59 -0
  101. package/templates/_shared/compound/persistence/scripts/sync-rest-contracts.ts.mustache +101 -0
  102. package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/api-types.ts.mustache +21 -0
  103. package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/api-validators.ts.mustache +32 -0
  104. package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/api.ts.mustache +68 -0
  105. package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/block.json.mustache +52 -0
  106. package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/data.ts.mustache +192 -0
  107. package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/edit.tsx.mustache +123 -0
  108. package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/hooks.ts.mustache +11 -0
  109. package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/interactivity.ts.mustache +132 -0
  110. package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/render.php.mustache +158 -0
  111. package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/save.tsx.mustache +3 -0
  112. package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/types.ts.mustache +56 -0
  113. package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/validators.ts.mustache +32 -0
  114. package/templates/_shared/compound/persistence-auth/{{slugKebabCase}}.php.mustache +294 -0
  115. package/templates/_shared/compound/persistence-public/{{slugKebabCase}}.php.mustache +312 -0
  116. package/templates/_shared/migration-ui/common/src/admin/migration-dashboard.tsx +394 -0
  117. package/templates/_shared/migration-ui/common/src/migration-detector.ts +9 -0
  118. package/templates/_shared/migration-ui/common/src/migrations/helpers.ts +490 -0
  119. package/templates/_shared/migration-ui/common/src/migrations/index.ts +886 -0
  120. package/templates/_shared/persistence/auth/{{slugKebabCase}}.php.mustache +290 -0
  121. package/templates/_shared/persistence/core/package.json.mustache +46 -0
  122. package/templates/_shared/persistence/core/scripts/sync-rest-contracts.ts.mustache +113 -0
  123. package/templates/_shared/persistence/core/scripts/sync-types-to-block-json.ts.mustache +125 -0
  124. package/templates/_shared/persistence/core/src/api-types.ts.mustache +21 -0
  125. package/templates/_shared/persistence/core/src/api-validators.ts.mustache +32 -0
  126. package/templates/_shared/persistence/core/src/api.ts.mustache +68 -0
  127. package/templates/_shared/persistence/core/src/data.ts.mustache +192 -0
  128. package/templates/_shared/persistence/core/src/index.tsx.mustache +25 -0
  129. package/templates/_shared/persistence/core/src/interactivity.ts.mustache +134 -0
  130. package/templates/_shared/persistence/core/src/save.tsx.mustache +5 -0
  131. package/templates/_shared/persistence/core/src/validators.ts.mustache +32 -0
  132. package/templates/_shared/persistence/core/{{slugKebabCase}}.php.mustache +336 -0
  133. package/templates/_shared/persistence/public/{{slugKebabCase}}.php.mustache +308 -0
  134. package/templates/_shared/presets/test-preset/.wp-env.test.json.mustache +16 -0
  135. package/templates/_shared/presets/test-preset/playwright.config.ts.mustache +22 -0
  136. package/templates/_shared/presets/test-preset/scripts/wait-for-wp-env.mjs.mustache +102 -0
  137. package/templates/_shared/presets/test-preset/scripts/wp-env-utils.cjs.mustache +32 -0
  138. package/templates/_shared/presets/test-preset/tests/e2e/smoke.spec.ts.mustache +34 -0
  139. package/templates/_shared/presets/wp-env/.wp-env.json.mustache +16 -0
  140. package/templates/_shared/rest-helpers/auth/inc/rest-auth.php.mustache +37 -0
  141. package/templates/_shared/rest-helpers/public/inc/rest-public.php.mustache +314 -0
  142. package/templates/_shared/rest-helpers/shared/inc/rest-shared.php.mustache +58 -0
  143. package/templates/_shared/workspace/persistence-auth/inc/rest-auth.php.mustache +36 -0
  144. package/templates/_shared/workspace/persistence-auth/inc/rest-shared.php.mustache +55 -0
  145. package/templates/_shared/workspace/persistence-auth/server.php.mustache +237 -0
  146. package/templates/_shared/workspace/persistence-public/inc/rest-public.php.mustache +273 -0
  147. package/templates/_shared/workspace/persistence-public/inc/rest-shared.php.mustache +55 -0
  148. package/templates/_shared/workspace/persistence-public/server.php.mustache +252 -0
  149. package/templates/basic/src/block.json.mustache +51 -0
  150. package/templates/basic/src/edit.tsx.mustache +128 -0
  151. package/templates/basic/src/editor.scss.mustache +8 -0
  152. package/templates/basic/src/hooks.ts.mustache +18 -0
  153. package/templates/basic/src/index.tsx.mustache +45 -0
  154. package/templates/basic/src/save.tsx.mustache +30 -0
  155. package/templates/basic/src/style.scss.mustache +40 -0
  156. package/templates/basic/src/types.ts.mustache +56 -0
  157. package/templates/basic/src/validators.ts.mustache +26 -0
  158. package/templates/compound/src/blocks/{{slugKebabCase}}/block.json.mustache +37 -0
  159. package/templates/compound/src/blocks/{{slugKebabCase}}/children.ts.mustache +25 -0
  160. package/templates/compound/src/blocks/{{slugKebabCase}}/edit.tsx.mustache +93 -0
  161. package/templates/compound/src/blocks/{{slugKebabCase}}/hooks.ts.mustache +11 -0
  162. package/templates/compound/src/blocks/{{slugKebabCase}}/index.tsx.mustache +25 -0
  163. package/templates/compound/src/blocks/{{slugKebabCase}}/save.tsx.mustache +32 -0
  164. package/templates/compound/src/blocks/{{slugKebabCase}}/style.scss.mustache +31 -0
  165. package/templates/compound/src/blocks/{{slugKebabCase}}/types.ts.mustache +13 -0
  166. package/templates/compound/src/blocks/{{slugKebabCase}}/validators.ts.mustache +17 -0
  167. package/templates/compound/src/blocks/{{slugKebabCase}}-item/block.json.mustache +35 -0
  168. package/templates/compound/src/blocks/{{slugKebabCase}}-item/edit.tsx.mustache +50 -0
  169. package/templates/compound/src/blocks/{{slugKebabCase}}-item/hooks.ts.mustache +11 -0
  170. package/templates/compound/src/blocks/{{slugKebabCase}}-item/index.tsx.mustache +25 -0
  171. package/templates/compound/src/blocks/{{slugKebabCase}}-item/save.tsx.mustache +24 -0
  172. package/templates/compound/src/blocks/{{slugKebabCase}}-item/types.ts.mustache +12 -0
  173. package/templates/compound/src/blocks/{{slugKebabCase}}-item/validators.ts.mustache +17 -0
  174. package/templates/interactivity/package.json.mustache +42 -0
  175. package/templates/interactivity/src/block.json.mustache +73 -0
  176. package/templates/interactivity/src/edit.tsx.mustache +270 -0
  177. package/templates/interactivity/src/index.tsx.mustache +32 -0
  178. package/templates/interactivity/src/interactivity.ts.mustache +152 -0
  179. package/templates/interactivity/src/save.tsx.mustache +101 -0
  180. package/templates/interactivity/src/style.scss.mustache +60 -0
  181. package/templates/interactivity/src/types.ts.mustache +32 -0
  182. package/templates/interactivity/src/validators.ts.mustache +36 -0
  183. package/templates/persistence/src/block.json.mustache +52 -0
  184. package/templates/persistence/src/edit.tsx.mustache +165 -0
  185. package/templates/persistence/src/render.php.mustache +126 -0
  186. package/templates/persistence/src/style.scss.mustache +46 -0
  187. package/templates/persistence/src/types.ts.mustache +55 -0
@@ -0,0 +1,25 @@
1
+ import type { Template } from '@wordpress/blocks';
2
+
3
+ export const DEFAULT_CHILD_BLOCK_NAME = '{{namespace}}/{{slugKebabCase}}-item';
4
+
5
+ export const ALLOWED_CHILD_BLOCKS = [
6
+ DEFAULT_CHILD_BLOCK_NAME,
7
+ // add-child: insert new allowed child block names here
8
+ ];
9
+
10
+ export const DEFAULT_CHILD_TEMPLATE: Template[] = [
11
+ [
12
+ DEFAULT_CHILD_BLOCK_NAME,
13
+ {
14
+ body: 'Add supporting details for the first internal item.',
15
+ title: 'First Item',
16
+ },
17
+ ],
18
+ [
19
+ DEFAULT_CHILD_BLOCK_NAME,
20
+ {
21
+ body: 'Add supporting details for the second internal item.',
22
+ title: 'Second Item',
23
+ },
24
+ ],
25
+ ];
@@ -0,0 +1,93 @@
1
+ import { __ } from '@wordpress/i18n';
2
+ import {
3
+ InspectorControls,
4
+ InnerBlocks,
5
+ RichText,
6
+ useBlockProps,
7
+ } from '@wordpress/block-editor';
8
+ import { Notice, PanelBody, ToggleControl } from '@wordpress/components';
9
+
10
+ import {
11
+ ALLOWED_CHILD_BLOCKS,
12
+ DEFAULT_CHILD_TEMPLATE,
13
+ } from './children';
14
+ import { useTypiaValidation } from './hooks';
15
+ import type { {{pascalCase}}Attributes } from './types';
16
+ import {
17
+ createAttributeUpdater,
18
+ validate{{pascalCase}}Attributes,
19
+ } from './validators';
20
+
21
+ export default function Edit( {
22
+ attributes,
23
+ setAttributes,
24
+ }: {
25
+ attributes: {{pascalCase}}Attributes;
26
+ setAttributes: ( attrs: Partial< {{pascalCase}}Attributes > ) => void;
27
+ } ) {
28
+ const { errorMessages, isValid } = useTypiaValidation(
29
+ attributes,
30
+ validate{{pascalCase}}Attributes
31
+ );
32
+ const updateAttribute = createAttributeUpdater( attributes, setAttributes );
33
+ const blockProps = useBlockProps( {
34
+ className: '{{cssClassName}}',
35
+ } );
36
+
37
+ return (
38
+ <>
39
+ <InspectorControls>
40
+ <PanelBody title={ __( 'Compound Settings', '{{textDomain}}' ) }>
41
+ <ToggleControl
42
+ label={ __( 'Show dividers between items', '{{textDomain}}' ) }
43
+ checked={ attributes.showDividers ?? true }
44
+ onChange={ ( value ) => updateAttribute( 'showDividers', value ) }
45
+ />
46
+ </PanelBody>
47
+ { ! isValid && (
48
+ <PanelBody title={ __( 'Validation Errors', '{{textDomain}}' ) } initialOpen>
49
+ { errorMessages.map( ( error, index ) => (
50
+ <Notice key={ index } status="error" isDismissible={ false }>
51
+ { error }
52
+ </Notice>
53
+ ) ) }
54
+ </PanelBody>
55
+ ) }
56
+ </InspectorControls>
57
+ <div { ...blockProps }>
58
+ <RichText
59
+ tagName="h3"
60
+ className="{{cssClassName}}__heading"
61
+ value={ attributes.heading }
62
+ onChange={ ( heading ) => updateAttribute( 'heading', heading ) }
63
+ placeholder={ __( {{titleJson}}, '{{textDomain}}' ) }
64
+ />
65
+ <RichText
66
+ tagName="p"
67
+ className="{{cssClassName}}__intro"
68
+ value={ attributes.intro ?? '' }
69
+ onChange={ ( intro ) => updateAttribute( 'intro', intro ) }
70
+ placeholder={ __(
71
+ 'Add and reorder internal items inside this compound block.',
72
+ '{{textDomain}}'
73
+ ) }
74
+ />
75
+ { ! isValid && (
76
+ <Notice status="error" isDismissible={ false }>
77
+ <ul>
78
+ { errorMessages.map( ( error, index ) => <li key={ index }>{ error }</li> ) }
79
+ </ul>
80
+ </Notice>
81
+ ) }
82
+ <div className="{{cssClassName}}__items">
83
+ <InnerBlocks
84
+ allowedBlocks={ ALLOWED_CHILD_BLOCKS }
85
+ renderAppender={ InnerBlocks.ButtonBlockAppender }
86
+ template={ DEFAULT_CHILD_TEMPLATE }
87
+ templateLock={ false }
88
+ />
89
+ </div>
90
+ </div>
91
+ </>
92
+ );
93
+ }
@@ -0,0 +1,11 @@
1
+ export {
2
+ formatValidationError,
3
+ formatValidationErrors,
4
+ useTypiaValidation,
5
+ } from '../../hooks';
6
+
7
+ export type {
8
+ TypiaValidationError,
9
+ ValidationResult,
10
+ ValidationState,
11
+ } from '../../hooks';
@@ -0,0 +1,25 @@
1
+ import { registerBlockType } from '@wordpress/blocks';
2
+ import type { BlockConfiguration } from '@wordpress/blocks';
3
+ import {
4
+ buildScaffoldBlockRegistration,
5
+ type ScaffoldBlockMetadata,
6
+ } from '@wp-typia/block-runtime/blocks';
7
+
8
+ import Edit from './edit';
9
+ import Save from './save';
10
+ import metadata from './block.json';
11
+ import './style.scss';
12
+
13
+ import type { {{pascalCase}}Attributes } from './types';
14
+
15
+ const registration = buildScaffoldBlockRegistration<
16
+ BlockConfiguration< {{pascalCase}}Attributes >
17
+ >( metadata as ScaffoldBlockMetadata, {
18
+ edit: Edit,
19
+ save: Save,
20
+ } );
21
+
22
+ registerBlockType< {{pascalCase}}Attributes >(
23
+ registration.name,
24
+ registration.settings
25
+ );
@@ -0,0 +1,32 @@
1
+ import { InnerBlocks, RichText, useBlockProps } from '@wordpress/block-editor';
2
+
3
+ import type { {{pascalCase}}Attributes } from './types';
4
+
5
+ export default function Save( {
6
+ attributes,
7
+ }: {
8
+ attributes: {{pascalCase}}Attributes;
9
+ } ) {
10
+ return (
11
+ <div
12
+ { ...useBlockProps.save( {
13
+ className: '{{cssClassName}}',
14
+ 'data-show-dividers': ( attributes.showDividers ?? true ) ? 'true' : 'false',
15
+ } ) }
16
+ >
17
+ <RichText.Content
18
+ tagName="h3"
19
+ className="{{cssClassName}}__heading"
20
+ value={ attributes.heading }
21
+ />
22
+ <RichText.Content
23
+ tagName="p"
24
+ className="{{cssClassName}}__intro"
25
+ value={ attributes.intro ?? '' }
26
+ />
27
+ <div className="{{cssClassName}}__items">
28
+ <InnerBlocks.Content />
29
+ </div>
30
+ </div>
31
+ );
32
+ }
@@ -0,0 +1,31 @@
1
+ .{{cssClassName}} {
2
+ border: 1px solid #dcdcde;
3
+ border-radius: 12px;
4
+ padding: 1.25rem;
5
+ background: #fff;
6
+ }
7
+
8
+ .{{cssClassName}}__heading {
9
+ margin: 0 0 0.5rem;
10
+ font-size: 1.2rem;
11
+ }
12
+
13
+ .{{cssClassName}}__intro {
14
+ margin: 0 0 1rem;
15
+ color: #50575e;
16
+ }
17
+
18
+ .{{cssClassName}}__items {
19
+ display: grid;
20
+ gap: 0.75rem;
21
+ }
22
+
23
+ .{{cssClassName}}[data-show-dividers='true'] .{{compoundChildCssClassName}} {
24
+ border-top: 1px solid #dcdcde;
25
+ padding-top: 0.75rem;
26
+ }
27
+
28
+ .{{cssClassName}}[data-show-dividers='true'] .{{compoundChildCssClassName}}:first-child {
29
+ border-top: 0;
30
+ padding-top: 0;
31
+ }
@@ -0,0 +1,13 @@
1
+ import { tags } from 'typia';
2
+
3
+ export interface {{pascalCase}}Attributes {
4
+ heading: string &
5
+ tags.MinLength< 1 > &
6
+ tags.MaxLength< 80 > &
7
+ tags.Default< {{titleJson}} >;
8
+ intro?: string &
9
+ tags.MinLength< 1 > &
10
+ tags.MaxLength< 180 > &
11
+ tags.Default< 'Add and reorder internal items inside this compound block.' >;
12
+ showDividers?: boolean & tags.Default< true >;
13
+ }
@@ -0,0 +1,17 @@
1
+ import currentManifest from './typia.manifest.json';
2
+ import type { {{pascalCase}}Attributes } from './types';
3
+ import { createTemplateValidatorToolkit } from '../../validator-toolkit';
4
+
5
+ const scaffoldValidators = createTemplateValidatorToolkit< {{pascalCase}}Attributes >( {
6
+ manifest: currentManifest,
7
+ } );
8
+
9
+ export const validate{{pascalCase}}Attributes =
10
+ scaffoldValidators.validateAttributes;
11
+
12
+ export const validators = scaffoldValidators.validators;
13
+
14
+ export const sanitize{{pascalCase}}Attributes =
15
+ scaffoldValidators.sanitizeAttributes;
16
+
17
+ export const createAttributeUpdater = scaffoldValidators.createAttributeUpdater;
@@ -0,0 +1,35 @@
1
+ {
2
+ "$schema": "https://schemas.wp.org/trunk/block.json",
3
+ "apiVersion": 3,
4
+ "name": "{{namespace}}/{{slugKebabCase}}-item",
5
+ "version": "{{blockMetadataVersion}}",
6
+ "title": {{compoundChildTitleJson}},
7
+ "category": "{{compoundChildCategory}}",
8
+ "icon": "{{compoundChildIcon}}",
9
+ "description": "Internal item block used by {{title}}.",
10
+ "parent": [
11
+ "{{namespace}}/{{slugKebabCase}}"
12
+ ],
13
+ "example": {},
14
+ "supports": {
15
+ "html": false,
16
+ "inserter": false,
17
+ "reusable": false
18
+ },
19
+ "attributes": {
20
+ "title": {
21
+ "type": "string",
22
+ "source": "html",
23
+ "selector": ".{{compoundChildCssClassName}}__title",
24
+ "default": {{compoundChildTitleJson}}
25
+ },
26
+ "body": {
27
+ "type": "string",
28
+ "source": "html",
29
+ "selector": ".{{compoundChildCssClassName}}__body",
30
+ "default": "Add supporting details for this internal item."
31
+ }
32
+ },
33
+ "textdomain": "{{textDomain}}",
34
+ "editorScript": "file:./index.js"
35
+ }
@@ -0,0 +1,50 @@
1
+ import { RichText, useBlockProps } from '@wordpress/block-editor';
2
+ import { Notice } from '@wordpress/components';
3
+ import { __ } from '@wordpress/i18n';
4
+
5
+ import { useTypiaValidation } from './hooks';
6
+ import type { {{pascalCase}}ItemAttributes } from './types';
7
+ import {
8
+ createAttributeUpdater,
9
+ validate{{pascalCase}}ItemAttributes,
10
+ } from './validators';
11
+
12
+ export default function Edit( {
13
+ attributes,
14
+ setAttributes,
15
+ }: {
16
+ attributes: {{pascalCase}}ItemAttributes;
17
+ setAttributes: ( attrs: Partial< {{pascalCase}}ItemAttributes > ) => void;
18
+ } ) {
19
+ const updateAttribute = createAttributeUpdater( attributes, setAttributes );
20
+ const { errorMessages, isValid } = useTypiaValidation(
21
+ attributes,
22
+ validate{{pascalCase}}ItemAttributes
23
+ );
24
+
25
+ return (
26
+ <div { ...useBlockProps( { className: '{{compoundChildCssClassName}}' } ) }>
27
+ <RichText
28
+ tagName="h4"
29
+ className="{{compoundChildCssClassName}}__title"
30
+ value={ attributes.title ?? '' }
31
+ onChange={ ( title ) => updateAttribute( 'title', title ) }
32
+ placeholder={ __( {{compoundChildTitleJson}}, '{{textDomain}}' ) }
33
+ />
34
+ <RichText
35
+ tagName="p"
36
+ className="{{compoundChildCssClassName}}__body"
37
+ value={ attributes.body ?? '' }
38
+ onChange={ ( body ) => updateAttribute( 'body', body ) }
39
+ placeholder={ __( 'Add supporting details for this internal item.', '{{textDomain}}' ) }
40
+ />
41
+ { ! isValid && (
42
+ <Notice status="error" isDismissible={ false }>
43
+ <ul>
44
+ { errorMessages.map( ( error, index ) => <li key={ index }>{ error }</li> ) }
45
+ </ul>
46
+ </Notice>
47
+ ) }
48
+ </div>
49
+ );
50
+ }
@@ -0,0 +1,11 @@
1
+ export {
2
+ formatValidationError,
3
+ formatValidationErrors,
4
+ useTypiaValidation,
5
+ } from '../../hooks';
6
+
7
+ export type {
8
+ TypiaValidationError,
9
+ ValidationResult,
10
+ ValidationState,
11
+ } from '../../hooks';
@@ -0,0 +1,25 @@
1
+ import { registerBlockType } from '@wordpress/blocks';
2
+ import type { BlockConfiguration } from '@wordpress/blocks';
3
+ import {
4
+ buildScaffoldBlockRegistration,
5
+ type ScaffoldBlockMetadata,
6
+ } from '@wp-typia/block-runtime/blocks';
7
+
8
+ import Edit from './edit';
9
+ import Save from './save';
10
+ import metadata from './block.json';
11
+ import '../{{slugKebabCase}}/style.scss';
12
+
13
+ import type { {{pascalCase}}ItemAttributes } from './types';
14
+
15
+ const registration = buildScaffoldBlockRegistration<
16
+ BlockConfiguration< {{pascalCase}}ItemAttributes >
17
+ >( metadata as ScaffoldBlockMetadata, {
18
+ edit: Edit,
19
+ save: Save,
20
+ } );
21
+
22
+ registerBlockType< {{pascalCase}}ItemAttributes >(
23
+ registration.name,
24
+ registration.settings
25
+ );
@@ -0,0 +1,24 @@
1
+ import { RichText, useBlockProps } from '@wordpress/block-editor';
2
+
3
+ import type { {{pascalCase}}ItemAttributes } from './types';
4
+
5
+ export default function Save( {
6
+ attributes,
7
+ }: {
8
+ attributes: {{pascalCase}}ItemAttributes;
9
+ } ) {
10
+ return (
11
+ <div { ...useBlockProps.save( { className: '{{compoundChildCssClassName}}' } ) }>
12
+ <RichText.Content
13
+ tagName="h4"
14
+ className="{{compoundChildCssClassName}}__title"
15
+ value={ attributes.title }
16
+ />
17
+ <RichText.Content
18
+ tagName="p"
19
+ className="{{compoundChildCssClassName}}__body"
20
+ value={ attributes.body }
21
+ />
22
+ </div>
23
+ );
24
+ }
@@ -0,0 +1,12 @@
1
+ import { tags } from 'typia';
2
+
3
+ export interface {{pascalCase}}ItemAttributes {
4
+ title: string &
5
+ tags.MinLength< 1 > &
6
+ tags.MaxLength< 80 > &
7
+ tags.Default< {{compoundChildTitleJson}} >;
8
+ body: string &
9
+ tags.MinLength< 1 > &
10
+ tags.MaxLength< 280 > &
11
+ tags.Default< 'Add supporting details for this internal item.' >;
12
+ }
@@ -0,0 +1,17 @@
1
+ import currentManifest from './typia.manifest.json';
2
+ import type { {{pascalCase}}ItemAttributes } from './types';
3
+ import { createTemplateValidatorToolkit } from '../../validator-toolkit';
4
+
5
+ const scaffoldValidators = createTemplateValidatorToolkit< {{pascalCase}}ItemAttributes >( {
6
+ manifest: currentManifest,
7
+ } );
8
+
9
+ export const validate{{pascalCase}}ItemAttributes =
10
+ scaffoldValidators.validateAttributes;
11
+
12
+ export const validators = scaffoldValidators.validators;
13
+
14
+ export const sanitize{{pascalCase}}ItemAttributes =
15
+ scaffoldValidators.sanitizeAttributes;
16
+
17
+ export const createAttributeUpdater = scaffoldValidators.createAttributeUpdater;
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "{{slug}}",
3
+ "version": "0.1.0",
4
+ "packageManager": "bun@1.3.10",
5
+ "description": "{{description}}",
6
+ "author": "{{author}}",
7
+ "license": "GPL-2.0-or-later",
8
+ "main": "build/index.js",
9
+ "scripts": {
10
+ "sync-types": "tsx scripts/sync-types-to-block-json.ts",
11
+ "build": "bun run sync-types --check && wp-scripts build --experimental-modules",
12
+ "start": "bun run sync-types && wp-scripts start --experimental-modules",
13
+ "dev": "bun run start",
14
+ "lint:js": "wp-scripts lint-js",
15
+ "lint:css": "wp-scripts lint-style",
16
+ "lint": "bun run lint:js && bun run lint:css",
17
+ "format": "wp-scripts format",
18
+ "typecheck": "bun run sync-types --check && tsc --noEmit"
19
+ },
20
+ "devDependencies": {
21
+ "@wp-typia/block-runtime": "{{blockRuntimePackageVersion}}",
22
+ "@wp-typia/block-types": "{{blockTypesPackageVersion}}",
23
+ "ajv": "^8.18.0",
24
+ "@types/wordpress__block-editor": "^11.5.17",
25
+ "@types/wordpress__blocks": "^12.5.18",
26
+ "@wordpress/browserslist-config": "^6.42.0",
27
+ "@wordpress/scripts": "^30.22.0",
28
+ "eslint-plugin-jsx-a11y": "^6.10.2",
29
+ "@typia/unplugin": "^12.0.1",
30
+ "tsx": "^4.20.5",
31
+ "typescript": "^5.9.2",
32
+ "typia": "^12.0.1"
33
+ },
34
+ "dependencies": {
35
+ "@wordpress/block-editor": "^15.2.0",
36
+ "@wordpress/blocks": "^15.2.0",
37
+ "@wordpress/components": "^30.2.0",
38
+ "@wordpress/element": "^6.29.0",
39
+ "@wordpress/i18n": "^6.2.0",
40
+ "@wordpress/interactivity": "^6.29.0"
41
+ }
42
+ }
@@ -0,0 +1,73 @@
1
+ {
2
+ "$schema": "https://schemas.wp.org/trunk/block.json",
3
+ "apiVersion": 3,
4
+ "name": "{{namespace}}/{{slugKebabCase}}",
5
+ "version": "{{blockMetadataVersion}}",
6
+ "title": "{{title}}",
7
+ "category": "{{category}}",
8
+ "icon": "{{icon}}",
9
+ "description": "{{description}}",
10
+ "example": {},
11
+ "supports": {
12
+ "html": false,
13
+ "align": true,
14
+ "anchor": true,
15
+ "className": true,
16
+ "interactivity": true
17
+ },
18
+ "attributes": {
19
+ "content": {
20
+ "type": "string",
21
+ "source": "html",
22
+ "selector": ".{{cssClassName}}__content",
23
+ "default": ""
24
+ },
25
+ "alignment": {
26
+ "type": "string",
27
+ "enum": ["left", "center", "right"],
28
+ "default": "left"
29
+ },
30
+ "isVisible": {
31
+ "type": "boolean",
32
+ "default": true
33
+ },
34
+ "interactiveMode": {
35
+ "type": "string",
36
+ "enum": ["click", "hover", "auto"],
37
+ "default": "click"
38
+ },
39
+ "animation": {
40
+ "type": "string",
41
+ "enum": ["none", "bounce", "pulse", "shake", "flip"],
42
+ "default": "none"
43
+ },
44
+ "clickCount": {
45
+ "type": "number",
46
+ "default": 0
47
+ },
48
+ "isAnimating": {
49
+ "type": "boolean",
50
+ "default": false
51
+ },
52
+ "showCounter": {
53
+ "type": "boolean",
54
+ "default": true
55
+ },
56
+ "maxClicks": {
57
+ "type": "number",
58
+ "default": 10
59
+ },
60
+ "autoPlayInterval": {
61
+ "type": "number",
62
+ "default": 0
63
+ },
64
+ "uniqueId": {
65
+ "type": "string",
66
+ "default": ""
67
+ }
68
+ },
69
+ "textdomain": "{{textDomain}}",
70
+ "editorScript": "file:./index.js",
71
+ "style": "file:./style-index.css",
72
+ "viewScriptModule": "file:./interactivity.js"
73
+ }