@wp-typia/create-workspace-template 0.14.0 → 0.16.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.
- package/README.md +5 -0
- package/README.md.mustache +5 -1
- package/package.json +1 -1
- package/package.json.mustache +4 -2
- package/scripts/block-config.ts.mustache +65 -0
- package/scripts/build-workspace.mjs.mustache +8 -1
- package/scripts/sync-rest-contracts.ts.mustache +80 -6
- package/src/editor-plugins/.gitkeep +1 -0
- package/webpack.config.js.mustache +22 -7
- package/{{slugKebabCase}}.php.mustache +37 -0
package/README.md
CHANGED
|
@@ -12,6 +12,11 @@ The generated project starts with an empty `src/blocks/*` workspace shell and is
|
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
14
|
wp-typia add block my-block --template basic
|
|
15
|
+
wp-typia add style callout-emphasis --block my-block
|
|
16
|
+
wp-typia add transform quote-to-block --from core/quote --to my-block
|
|
15
17
|
wp-typia add binding-source hero-data
|
|
18
|
+
wp-typia add binding-source hero-data --block my-block --attribute headline
|
|
19
|
+
wp-typia add editor-plugin review-workflow --slot sidebar
|
|
20
|
+
wp-typia add editor-plugin seo-notes --slot document-setting-panel
|
|
16
21
|
wp-typia add hooked-block my-block --anchor core/post-content --position after
|
|
17
22
|
```
|
package/README.md.mustache
CHANGED
|
@@ -20,11 +20,15 @@ wp-typia add block counter-card --template persistence --data-storage custom-tab
|
|
|
20
20
|
wp-typia add block faq-stack --template compound --data-storage custom-table --persistence-policy public
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
Variations
|
|
23
|
+
Variations, block styles, transforms, patterns, and REST resources can also be
|
|
24
|
+
added after the first block exists:
|
|
24
25
|
|
|
25
26
|
```bash
|
|
26
27
|
wp-typia add variation hero-card --block counter-card
|
|
28
|
+
wp-typia add style callout-emphasis --block counter-card
|
|
29
|
+
wp-typia add transform quote-to-counter --from core/quote --to counter-card
|
|
27
30
|
wp-typia add pattern hero-layout
|
|
31
|
+
wp-typia add rest-resource snapshots --namespace {{namespace}}/v1 --methods list,read,create
|
|
28
32
|
```
|
|
29
33
|
|
|
30
34
|
## Development
|
package/package.json
CHANGED
package/package.json.mustache
CHANGED
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
"@wp-typia/api-client": "{{apiClientPackageVersion}}",
|
|
30
30
|
"@wp-typia/block-runtime": "{{blockRuntimePackageVersion}}",
|
|
31
31
|
"@wp-typia/block-types": "{{blockTypesPackageVersion}}",
|
|
32
|
+
"@wp-typia/project-tools": "{{projectToolsPackageVersion}}",
|
|
32
33
|
"@wp-typia/rest": "{{restPackageVersion}}",
|
|
33
34
|
"@typia/unplugin": "^12.0.1",
|
|
34
35
|
"@types/node": "^24.5.2",
|
|
@@ -36,7 +37,6 @@
|
|
|
36
37
|
"@types/wordpress__blocks": "^12.5.18",
|
|
37
38
|
"@wordpress/browserslist-config": "^6.42.0",
|
|
38
39
|
"@wordpress/scripts": "^30.22.0",
|
|
39
|
-
"ajv": "^8.18.0",
|
|
40
40
|
"eslint-plugin-jsx-a11y": "^6.10.2",
|
|
41
41
|
"tsx": "^4.20.5",
|
|
42
42
|
"typescript": "^5.9.2",
|
|
@@ -47,8 +47,10 @@
|
|
|
47
47
|
"@wordpress/block-editor": "^15.2.0",
|
|
48
48
|
"@wordpress/blocks": "^15.2.0",
|
|
49
49
|
"@wordpress/components": "^30.2.0",
|
|
50
|
+
"@wordpress/editor": "^14.44.0",
|
|
50
51
|
"@wordpress/element": "^6.29.0",
|
|
51
52
|
"@wordpress/i18n": "^6.2.0",
|
|
52
|
-
"@wordpress/interactivity": "^6.29.0"
|
|
53
|
+
"@wordpress/interactivity": "^6.29.0",
|
|
54
|
+
"@wordpress/plugins": "^7.44.0"
|
|
53
55
|
}
|
|
54
56
|
}
|
|
@@ -15,17 +15,62 @@ export interface WorkspaceVariationConfig {
|
|
|
15
15
|
slug: string;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
export interface WorkspaceBlockStyleConfig {
|
|
19
|
+
block: string;
|
|
20
|
+
file: string;
|
|
21
|
+
slug: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface WorkspaceBlockTransformConfig {
|
|
25
|
+
block: string;
|
|
26
|
+
file: string;
|
|
27
|
+
from: string;
|
|
28
|
+
slug: string;
|
|
29
|
+
to: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
18
32
|
export interface WorkspacePatternConfig {
|
|
19
33
|
file: string;
|
|
20
34
|
slug: string;
|
|
21
35
|
}
|
|
22
36
|
|
|
23
37
|
export interface WorkspaceBindingSourceConfig {
|
|
38
|
+
attribute?: string;
|
|
39
|
+
block?: string;
|
|
24
40
|
editorFile: string;
|
|
25
41
|
serverFile: string;
|
|
26
42
|
slug: string;
|
|
27
43
|
}
|
|
28
44
|
|
|
45
|
+
export interface WorkspaceRestResourceConfig {
|
|
46
|
+
apiFile: string;
|
|
47
|
+
clientFile: string;
|
|
48
|
+
dataFile: string;
|
|
49
|
+
methods: Array< 'list' | 'read' | 'create' | 'update' | 'delete' >;
|
|
50
|
+
namespace: string;
|
|
51
|
+
openApiFile: string;
|
|
52
|
+
phpFile: string;
|
|
53
|
+
restManifest?: ReturnType<
|
|
54
|
+
typeof import( '@wp-typia/block-runtime/metadata-core' ).defineEndpointManifest
|
|
55
|
+
>;
|
|
56
|
+
slug: string;
|
|
57
|
+
typesFile: string;
|
|
58
|
+
validatorsFile: string;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface WorkspaceEditorPluginConfig {
|
|
62
|
+
file: string;
|
|
63
|
+
slug: string;
|
|
64
|
+
slot: string;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface WorkspaceAdminViewConfig {
|
|
68
|
+
file: string;
|
|
69
|
+
phpFile: string;
|
|
70
|
+
slug: string;
|
|
71
|
+
source?: string;
|
|
72
|
+
}
|
|
73
|
+
|
|
29
74
|
export const BLOCKS: WorkspaceBlockConfig[] = [
|
|
30
75
|
// wp-typia add block entries
|
|
31
76
|
];
|
|
@@ -34,6 +79,14 @@ export const VARIATIONS: WorkspaceVariationConfig[] = [
|
|
|
34
79
|
// wp-typia add variation entries
|
|
35
80
|
];
|
|
36
81
|
|
|
82
|
+
export const BLOCK_STYLES: WorkspaceBlockStyleConfig[] = [
|
|
83
|
+
// wp-typia add style entries
|
|
84
|
+
];
|
|
85
|
+
|
|
86
|
+
export const BLOCK_TRANSFORMS: WorkspaceBlockTransformConfig[] = [
|
|
87
|
+
// wp-typia add transform entries
|
|
88
|
+
];
|
|
89
|
+
|
|
37
90
|
export const PATTERNS: WorkspacePatternConfig[] = [
|
|
38
91
|
// wp-typia add pattern entries
|
|
39
92
|
];
|
|
@@ -41,3 +94,15 @@ export const PATTERNS: WorkspacePatternConfig[] = [
|
|
|
41
94
|
export const BINDING_SOURCES: WorkspaceBindingSourceConfig[] = [
|
|
42
95
|
// wp-typia add binding-source entries
|
|
43
96
|
];
|
|
97
|
+
|
|
98
|
+
export const REST_RESOURCES: WorkspaceRestResourceConfig[] = [
|
|
99
|
+
// wp-typia add rest-resource entries
|
|
100
|
+
];
|
|
101
|
+
|
|
102
|
+
export const EDITOR_PLUGINS: WorkspaceEditorPluginConfig[] = [
|
|
103
|
+
// wp-typia add editor-plugin entries
|
|
104
|
+
];
|
|
105
|
+
|
|
106
|
+
export const ADMIN_VIEWS: WorkspaceAdminViewConfig[] = [
|
|
107
|
+
// wp-typia add admin-view entries
|
|
108
|
+
];
|
|
@@ -22,7 +22,14 @@ function getBlockSlugs() {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
function hasSharedEditorEntries() {
|
|
25
|
-
for ( const relativePath of [
|
|
25
|
+
for ( const relativePath of [
|
|
26
|
+
'src/bindings/index.ts',
|
|
27
|
+
'src/bindings/index.js',
|
|
28
|
+
'src/editor-plugins/index.ts',
|
|
29
|
+
'src/editor-plugins/index.js',
|
|
30
|
+
'src/admin-views/index.ts',
|
|
31
|
+
'src/admin-views/index.js',
|
|
32
|
+
] ) {
|
|
26
33
|
if ( fs.existsSync( path.join( process.cwd(), relativePath ) ) ) {
|
|
27
34
|
return true;
|
|
28
35
|
}
|
|
@@ -8,7 +8,12 @@ import {
|
|
|
8
8
|
syncTypeSchemas,
|
|
9
9
|
} from '@wp-typia/block-runtime/metadata-core';
|
|
10
10
|
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
BLOCKS,
|
|
13
|
+
REST_RESOURCES,
|
|
14
|
+
type WorkspaceBlockConfig,
|
|
15
|
+
type WorkspaceRestResourceConfig,
|
|
16
|
+
} from './block-config';
|
|
12
17
|
|
|
13
18
|
function parseCliOptions( argv: string[] ) {
|
|
14
19
|
const options = {
|
|
@@ -42,6 +47,25 @@ function isRestEnabledBlock(
|
|
|
42
47
|
);
|
|
43
48
|
}
|
|
44
49
|
|
|
50
|
+
function isWorkspaceRestResource(
|
|
51
|
+
resource: WorkspaceRestResourceConfig
|
|
52
|
+
): resource is WorkspaceRestResourceConfig & {
|
|
53
|
+
clientFile: string;
|
|
54
|
+
openApiFile: string;
|
|
55
|
+
restManifest: NonNullable< WorkspaceRestResourceConfig[ 'restManifest' ] >;
|
|
56
|
+
typesFile: string;
|
|
57
|
+
validatorsFile: string;
|
|
58
|
+
} {
|
|
59
|
+
return (
|
|
60
|
+
typeof resource.clientFile === 'string' &&
|
|
61
|
+
typeof resource.openApiFile === 'string' &&
|
|
62
|
+
typeof resource.typesFile === 'string' &&
|
|
63
|
+
typeof resource.validatorsFile === 'string' &&
|
|
64
|
+
typeof resource.restManifest === 'object' &&
|
|
65
|
+
resource.restManifest !== null
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
45
69
|
async function assertTypeArtifactsCurrent( block: WorkspaceBlockConfig ) {
|
|
46
70
|
const report = await runSyncBlockMetadata(
|
|
47
71
|
{
|
|
@@ -73,12 +97,13 @@ async function assertTypeArtifactsCurrent( block: WorkspaceBlockConfig ) {
|
|
|
73
97
|
async function main() {
|
|
74
98
|
const options = parseCliOptions( process.argv.slice( 2 ) );
|
|
75
99
|
const restBlocks = BLOCKS.filter( isRestEnabledBlock );
|
|
100
|
+
const restResources = REST_RESOURCES.filter( isWorkspaceRestResource );
|
|
76
101
|
|
|
77
|
-
if ( restBlocks.length === 0 ) {
|
|
102
|
+
if ( restBlocks.length === 0 && restResources.length === 0 ) {
|
|
78
103
|
console.log(
|
|
79
104
|
options.check
|
|
80
|
-
? 'ℹ️ No REST-enabled workspace blocks are registered yet. `sync-rest --check` is already clean.'
|
|
81
|
-
: 'ℹ️ No REST-enabled workspace blocks are registered yet.'
|
|
105
|
+
? 'ℹ️ No REST-enabled workspace blocks or plugin-level REST resources are registered yet. `sync-rest --check` is already clean.'
|
|
106
|
+
: 'ℹ️ No REST-enabled workspace blocks or plugin-level REST resources are registered yet.'
|
|
82
107
|
);
|
|
83
108
|
return;
|
|
84
109
|
}
|
|
@@ -142,10 +167,59 @@ async function main() {
|
|
|
142
167
|
);
|
|
143
168
|
}
|
|
144
169
|
|
|
170
|
+
for ( const resource of restResources ) {
|
|
171
|
+
const contracts = resource.restManifest.contracts;
|
|
172
|
+
|
|
173
|
+
for ( const [ baseName, contract ] of Object.entries( contracts ) ) {
|
|
174
|
+
await syncTypeSchemas(
|
|
175
|
+
{
|
|
176
|
+
jsonSchemaFile: path.join(
|
|
177
|
+
path.dirname( resource.typesFile ),
|
|
178
|
+
'api-schemas',
|
|
179
|
+
`${ baseName }.schema.json`
|
|
180
|
+
),
|
|
181
|
+
openApiFile: path.join(
|
|
182
|
+
path.dirname( resource.typesFile ),
|
|
183
|
+
'api-schemas',
|
|
184
|
+
`${ baseName }.openapi.json`
|
|
185
|
+
),
|
|
186
|
+
sourceTypeName: contract.sourceTypeName,
|
|
187
|
+
typesFile: resource.typesFile,
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
check: options.check,
|
|
191
|
+
}
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
await syncRestOpenApi(
|
|
196
|
+
{
|
|
197
|
+
manifest: resource.restManifest,
|
|
198
|
+
openApiFile: resource.openApiFile,
|
|
199
|
+
typesFile: resource.typesFile,
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
check: options.check,
|
|
203
|
+
}
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
await syncEndpointClient(
|
|
207
|
+
{
|
|
208
|
+
clientFile: resource.clientFile,
|
|
209
|
+
manifest: resource.restManifest,
|
|
210
|
+
typesFile: resource.typesFile,
|
|
211
|
+
validatorsFile: resource.validatorsFile,
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
check: options.check,
|
|
215
|
+
}
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
|
|
145
219
|
console.log(
|
|
146
220
|
options.check
|
|
147
|
-
? '✅ REST contract schemas, portable API clients, and endpoint-aware OpenAPI documents are already up to date
|
|
148
|
-
: '✅ REST contract schemas, portable API clients, and endpoint-aware OpenAPI documents generated
|
|
221
|
+
? '✅ REST contract schemas, portable API clients, and endpoint-aware OpenAPI documents are already up to date for workspace blocks and plugin-level resources!'
|
|
222
|
+
: '✅ REST contract schemas, portable API clients, and endpoint-aware OpenAPI documents generated for workspace blocks and plugin-level resources!'
|
|
149
223
|
);
|
|
150
224
|
}
|
|
151
225
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -189,14 +189,29 @@ function getEditorEntries() {
|
|
|
189
189
|
function getSharedEditorEntries() {
|
|
190
190
|
const entries = [];
|
|
191
191
|
|
|
192
|
-
for ( const
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
192
|
+
for ( const [ entryName, candidates ] of [
|
|
193
|
+
[
|
|
194
|
+
'bindings/index',
|
|
195
|
+
[ 'src/bindings/index.ts', 'src/bindings/index.js' ],
|
|
196
|
+
],
|
|
197
|
+
[
|
|
198
|
+
'editor-plugins/index',
|
|
199
|
+
[ 'src/editor-plugins/index.ts', 'src/editor-plugins/index.js' ],
|
|
200
|
+
],
|
|
201
|
+
[
|
|
202
|
+
'admin-views/index',
|
|
203
|
+
[ 'src/admin-views/index.ts', 'src/admin-views/index.js' ],
|
|
204
|
+
],
|
|
205
|
+
] ) {
|
|
206
|
+
for ( const relativePath of candidates ) {
|
|
207
|
+
const entryPath = path.resolve( process.cwd(), relativePath );
|
|
208
|
+
if ( ! fs.existsSync( entryPath ) ) {
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
197
211
|
|
|
198
|
-
|
|
199
|
-
|
|
212
|
+
entries.push( [ entryName, entryPath ] );
|
|
213
|
+
break;
|
|
214
|
+
}
|
|
200
215
|
}
|
|
201
216
|
|
|
202
217
|
return Object.fromEntries( entries );
|
|
@@ -117,6 +117,42 @@ function {{phpPrefix}}_enqueue_binding_sources_editor() {
|
|
|
117
117
|
);
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
+
function {{phpPrefix}}_enqueue_editor_plugins_editor() {
|
|
121
|
+
$script_path = __DIR__ . '/build/editor-plugins/index.js';
|
|
122
|
+
$asset_path = __DIR__ . '/build/editor-plugins/index.asset.php';
|
|
123
|
+
$style_path = __DIR__ . '/build/editor-plugins/style-index.css';
|
|
124
|
+
$style_rtl_path = __DIR__ . '/build/editor-plugins/style-index-rtl.css';
|
|
125
|
+
|
|
126
|
+
if ( ! file_exists( $script_path ) || ! file_exists( $asset_path ) ) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
$asset = require $asset_path;
|
|
131
|
+
if ( ! is_array( $asset ) ) {
|
|
132
|
+
$asset = array();
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
wp_enqueue_script(
|
|
136
|
+
'{{slugKebabCase}}-editor-plugins',
|
|
137
|
+
plugins_url( 'build/editor-plugins/index.js', __FILE__ ),
|
|
138
|
+
isset( $asset['dependencies'] ) && is_array( $asset['dependencies'] ) ? $asset['dependencies'] : array(),
|
|
139
|
+
isset( $asset['version'] ) ? $asset['version'] : filemtime( $script_path ),
|
|
140
|
+
true
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
if ( file_exists( $style_path ) ) {
|
|
144
|
+
wp_enqueue_style(
|
|
145
|
+
'{{slugKebabCase}}-editor-plugins',
|
|
146
|
+
plugins_url( 'build/editor-plugins/style-index.css', __FILE__ ),
|
|
147
|
+
array(),
|
|
148
|
+
isset( $asset['version'] ) ? $asset['version'] : filemtime( $style_path )
|
|
149
|
+
);
|
|
150
|
+
if ( file_exists( $style_rtl_path ) ) {
|
|
151
|
+
wp_style_add_data( '{{slugKebabCase}}-editor-plugins', 'rtl', 'replace' );
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
120
156
|
function {{phpPrefix}}_register_pattern_category() {
|
|
121
157
|
if ( function_exists( 'register_block_pattern_category' ) ) {
|
|
122
158
|
register_block_pattern_category(
|
|
@@ -143,3 +179,4 @@ add_action( 'init', '{{phpPrefix}}_register_binding_sources', 20 );
|
|
|
143
179
|
add_action( 'init', '{{phpPrefix}}_register_pattern_category' );
|
|
144
180
|
add_action( 'init', '{{phpPrefix}}_register_patterns', 20 );
|
|
145
181
|
add_action( 'enqueue_block_editor_assets', '{{phpPrefix}}_enqueue_binding_sources_editor' );
|
|
182
|
+
add_action( 'enqueue_block_editor_assets', '{{phpPrefix}}_enqueue_editor_plugins_editor' );
|