@wp-typia/project-tools 0.16.2 → 0.16.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/dist/runtime/block-generator-service.d.ts +102 -0
- package/dist/runtime/block-generator-service.js +268 -0
- package/dist/runtime/built-in-block-artifacts.d.ts +37 -0
- package/dist/runtime/built-in-block-artifacts.js +1203 -0
- package/dist/runtime/built-in-block-code-artifacts.d.ts +30 -0
- package/dist/runtime/built-in-block-code-artifacts.js +122 -0
- package/dist/runtime/index.d.ts +2 -0
- package/dist/runtime/index.js +1 -0
- package/dist/runtime/scaffold-apply-utils.d.ts +47 -0
- package/dist/runtime/scaffold-apply-utils.js +405 -0
- package/dist/runtime/scaffold-identifiers.d.ts +34 -0
- package/dist/runtime/scaffold-identifiers.js +82 -0
- package/dist/runtime/scaffold.js +33 -0
- package/dist/runtime/starter-manifests.d.ts +3 -2
- package/dist/runtime/starter-manifests.js +15 -365
- package/dist/runtime/template-render.d.ts +5 -0
- package/dist/runtime/template-render.js +13 -3
- package/package.json +2 -2
- package/templates/_shared/compound/persistence/scripts/block-config.ts.mustache +4 -4
- package/templates/_shared/persistence/core/scripts/sync-rest-contracts.ts.mustache +4 -4
- package/templates/_shared/base/src/hooks.ts.mustache +0 -19
- package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/block.json.mustache +0 -52
- package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/edit.tsx.mustache +0 -123
- package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/hooks.ts.mustache +0 -11
- package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/interactivity.ts.mustache +0 -305
- package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/save.tsx.mustache +0 -3
- package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/types.ts.mustache +0 -61
- package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/validators.ts.mustache +0 -43
- package/templates/_shared/persistence/core/src/index.tsx.mustache +0 -25
- package/templates/_shared/persistence/core/src/interactivity.ts.mustache +0 -308
- package/templates/_shared/persistence/core/src/save.tsx.mustache +0 -5
- package/templates/_shared/persistence/core/src/validators.ts.mustache +0 -43
- package/templates/basic/src/block.json.mustache +0 -51
- package/templates/basic/src/edit.tsx.mustache +0 -128
- package/templates/basic/src/index.tsx.mustache +0 -45
- package/templates/basic/src/save.tsx.mustache +0 -30
- package/templates/basic/src/types.ts.mustache +0 -56
- package/templates/basic/src/validators.ts.mustache +0 -37
- package/templates/compound/src/blocks/{{slugKebabCase}}/block.json.mustache +0 -37
- package/templates/compound/src/blocks/{{slugKebabCase}}/children.ts.mustache +0 -25
- package/templates/compound/src/blocks/{{slugKebabCase}}/edit.tsx.mustache +0 -93
- package/templates/compound/src/blocks/{{slugKebabCase}}/hooks.ts.mustache +0 -11
- package/templates/compound/src/blocks/{{slugKebabCase}}/index.tsx.mustache +0 -25
- package/templates/compound/src/blocks/{{slugKebabCase}}/save.tsx.mustache +0 -32
- package/templates/compound/src/blocks/{{slugKebabCase}}/types.ts.mustache +0 -18
- package/templates/compound/src/blocks/{{slugKebabCase}}/validators.ts.mustache +0 -35
- package/templates/compound/src/blocks/{{slugKebabCase}}-item/block.json.mustache +0 -35
- package/templates/compound/src/blocks/{{slugKebabCase}}-item/edit.tsx.mustache +0 -50
- package/templates/compound/src/blocks/{{slugKebabCase}}-item/hooks.ts.mustache +0 -11
- package/templates/compound/src/blocks/{{slugKebabCase}}-item/index.tsx.mustache +0 -25
- package/templates/compound/src/blocks/{{slugKebabCase}}-item/save.tsx.mustache +0 -24
- package/templates/compound/src/blocks/{{slugKebabCase}}-item/types.ts.mustache +0 -17
- package/templates/compound/src/blocks/{{slugKebabCase}}-item/validators.ts.mustache +0 -35
- package/templates/interactivity/src/block.json.mustache +0 -74
- package/templates/interactivity/src/edit.tsx.mustache +0 -270
- package/templates/interactivity/src/index.tsx.mustache +0 -33
- package/templates/interactivity/src/interactivity.ts.mustache +0 -152
- package/templates/interactivity/src/save.tsx.mustache +0 -101
- package/templates/interactivity/src/types.ts.mustache +0 -32
- package/templates/interactivity/src/validators.ts.mustache +0 -47
- package/templates/persistence/src/block.json.mustache +0 -52
- package/templates/persistence/src/edit.tsx.mustache +0 -165
- package/templates/persistence/src/types.ts.mustache +0 -59
package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/edit.tsx.mustache
DELETED
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import { __ } from '@wordpress/i18n';
|
|
2
|
-
import {
|
|
3
|
-
InspectorControls,
|
|
4
|
-
InnerBlocks,
|
|
5
|
-
RichText,
|
|
6
|
-
useBlockProps,
|
|
7
|
-
} from '@wordpress/block-editor';
|
|
8
|
-
import {
|
|
9
|
-
Notice,
|
|
10
|
-
PanelBody,
|
|
11
|
-
TextControl,
|
|
12
|
-
ToggleControl,
|
|
13
|
-
} from '@wordpress/components';
|
|
14
|
-
|
|
15
|
-
import {
|
|
16
|
-
ALLOWED_CHILD_BLOCKS,
|
|
17
|
-
DEFAULT_CHILD_TEMPLATE,
|
|
18
|
-
} from './children';
|
|
19
|
-
import { useTypiaValidation } from './hooks';
|
|
20
|
-
import type { {{pascalCase}}Attributes } from './types';
|
|
21
|
-
import {
|
|
22
|
-
createAttributeUpdater,
|
|
23
|
-
validate{{pascalCase}}Attributes,
|
|
24
|
-
} from './validators';
|
|
25
|
-
|
|
26
|
-
export default function Edit( {
|
|
27
|
-
attributes,
|
|
28
|
-
setAttributes,
|
|
29
|
-
}: {
|
|
30
|
-
attributes: {{pascalCase}}Attributes;
|
|
31
|
-
setAttributes: ( attrs: Partial< {{pascalCase}}Attributes > ) => void;
|
|
32
|
-
} ) {
|
|
33
|
-
const { errorMessages, isValid } = useTypiaValidation(
|
|
34
|
-
attributes,
|
|
35
|
-
validate{{pascalCase}}Attributes
|
|
36
|
-
);
|
|
37
|
-
const updateAttribute = createAttributeUpdater( attributes, setAttributes );
|
|
38
|
-
const blockProps = useBlockProps( {
|
|
39
|
-
className: '{{cssClassName}}',
|
|
40
|
-
} );
|
|
41
|
-
|
|
42
|
-
return (
|
|
43
|
-
<>
|
|
44
|
-
<InspectorControls>
|
|
45
|
-
<PanelBody title={ __( 'Compound Settings', '{{textDomain}}' ) }>
|
|
46
|
-
<ToggleControl
|
|
47
|
-
label={ __( 'Show dividers between items', '{{textDomain}}' ) }
|
|
48
|
-
checked={ attributes.showDividers ?? true }
|
|
49
|
-
onChange={ ( value ) => updateAttribute( 'showDividers', value ) }
|
|
50
|
-
/>
|
|
51
|
-
<ToggleControl
|
|
52
|
-
label={ __( 'Show persisted count', '{{textDomain}}' ) }
|
|
53
|
-
checked={ attributes.showCount ?? true }
|
|
54
|
-
onChange={ ( value ) => updateAttribute( 'showCount', value ) }
|
|
55
|
-
/>
|
|
56
|
-
<TextControl
|
|
57
|
-
label={ __( 'Button label', '{{textDomain}}' ) }
|
|
58
|
-
value={ attributes.buttonLabel ?? 'Persist Count' }
|
|
59
|
-
onChange={ ( buttonLabel ) => updateAttribute( 'buttonLabel', buttonLabel ) }
|
|
60
|
-
/>
|
|
61
|
-
<TextControl
|
|
62
|
-
label={ __( 'Resource key', '{{textDomain}}' ) }
|
|
63
|
-
value={ attributes.resourceKey ?? '' }
|
|
64
|
-
onChange={ ( resourceKey ) => updateAttribute( 'resourceKey', resourceKey ) }
|
|
65
|
-
help={ __( 'Stable key used by the persisted counter endpoint.', '{{textDomain}}' ) }
|
|
66
|
-
/>
|
|
67
|
-
<Notice status="info" isDismissible={ false }>
|
|
68
|
-
{ __( 'Storage mode: {{dataStorageMode}}', '{{textDomain}}' ) }
|
|
69
|
-
</Notice>
|
|
70
|
-
<Notice status="info" isDismissible={ false }>
|
|
71
|
-
{ __( 'Persistence policy: {{persistencePolicy}}', '{{textDomain}}' ) }
|
|
72
|
-
</Notice>
|
|
73
|
-
</PanelBody>
|
|
74
|
-
{ ! isValid && (
|
|
75
|
-
<PanelBody title={ __( 'Validation Errors', '{{textDomain}}' ) } initialOpen>
|
|
76
|
-
{ errorMessages.map( ( error, index ) => (
|
|
77
|
-
<Notice key={ index } status="error" isDismissible={ false }>
|
|
78
|
-
{ error }
|
|
79
|
-
</Notice>
|
|
80
|
-
) ) }
|
|
81
|
-
</PanelBody>
|
|
82
|
-
) }
|
|
83
|
-
</InspectorControls>
|
|
84
|
-
<div { ...blockProps }>
|
|
85
|
-
<RichText
|
|
86
|
-
tagName="h3"
|
|
87
|
-
className="{{cssClassName}}__heading"
|
|
88
|
-
value={ attributes.heading }
|
|
89
|
-
onChange={ ( heading ) => updateAttribute( 'heading', heading ) }
|
|
90
|
-
placeholder={ __( {{titleJson}}, '{{textDomain}}' ) }
|
|
91
|
-
/>
|
|
92
|
-
<RichText
|
|
93
|
-
tagName="p"
|
|
94
|
-
className="{{cssClassName}}__intro"
|
|
95
|
-
value={ attributes.intro ?? '' }
|
|
96
|
-
onChange={ ( intro ) => updateAttribute( 'intro', intro ) }
|
|
97
|
-
placeholder={ __(
|
|
98
|
-
'Add and reorder internal items inside this compound block.',
|
|
99
|
-
'{{textDomain}}'
|
|
100
|
-
) }
|
|
101
|
-
/>
|
|
102
|
-
{ ! isValid && (
|
|
103
|
-
<Notice status="error" isDismissible={ false }>
|
|
104
|
-
<ul>
|
|
105
|
-
{ errorMessages.map( ( error, index ) => <li key={ index }>{ error }</li> ) }
|
|
106
|
-
</ul>
|
|
107
|
-
</Notice>
|
|
108
|
-
) }
|
|
109
|
-
<p className="{{cssClassName}}__meta">
|
|
110
|
-
{ __( 'Resource key:', '{{textDomain}}' ) } { attributes.resourceKey || '—' }
|
|
111
|
-
</p>
|
|
112
|
-
<div className="{{cssClassName}}__items">
|
|
113
|
-
<InnerBlocks
|
|
114
|
-
allowedBlocks={ ALLOWED_CHILD_BLOCKS }
|
|
115
|
-
renderAppender={ InnerBlocks.ButtonBlockAppender }
|
|
116
|
-
template={ DEFAULT_CHILD_TEMPLATE }
|
|
117
|
-
templateLock={ false }
|
|
118
|
-
/>
|
|
119
|
-
</div>
|
|
120
|
-
</div>
|
|
121
|
-
</>
|
|
122
|
-
);
|
|
123
|
-
}
|
|
@@ -1,305 +0,0 @@
|
|
|
1
|
-
import { getContext, store } from '@wordpress/interactivity';
|
|
2
|
-
import { generatePublicWriteRequestId } from '@wp-typia/block-runtime/identifiers';
|
|
3
|
-
|
|
4
|
-
import { fetchBootstrap, fetchState, writeState } from './api';
|
|
5
|
-
import type {
|
|
6
|
-
{{pascalCase}}ClientState,
|
|
7
|
-
{{pascalCase}}Context,
|
|
8
|
-
{{pascalCase}}State,
|
|
9
|
-
} from './types';
|
|
10
|
-
|
|
11
|
-
function hasExpiredPublicWriteToken(
|
|
12
|
-
expiresAt?: number
|
|
13
|
-
): boolean {
|
|
14
|
-
return (
|
|
15
|
-
typeof expiresAt === 'number' &&
|
|
16
|
-
expiresAt > 0 &&
|
|
17
|
-
Date.now() >= expiresAt * 1000
|
|
18
|
-
);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function getWriteBlockedMessage(
|
|
22
|
-
context: {{pascalCase}}Context
|
|
23
|
-
): string {
|
|
24
|
-
return context.persistencePolicy === 'authenticated'
|
|
25
|
-
? 'Sign in to persist this counter.'
|
|
26
|
-
: 'Public writes are temporarily unavailable.';
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const BOOTSTRAP_MAX_ATTEMPTS = 3;
|
|
30
|
-
const BOOTSTRAP_RETRY_DELAYS_MS = [ 250, 500 ];
|
|
31
|
-
|
|
32
|
-
async function waitForBootstrapRetry( delayMs: number ): Promise< void > {
|
|
33
|
-
await new Promise( ( resolve ) => {
|
|
34
|
-
setTimeout( resolve, delayMs );
|
|
35
|
-
} );
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function getClientState(
|
|
39
|
-
context: {{pascalCase}}Context
|
|
40
|
-
): {{pascalCase}}ClientState {
|
|
41
|
-
if ( context.client ) {
|
|
42
|
-
return context.client;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
context.client = {
|
|
46
|
-
bootstrapError: '',
|
|
47
|
-
writeExpiry: 0,
|
|
48
|
-
writeNonce: '',
|
|
49
|
-
writeToken: '',
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
return context.client;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function clearBootstrapError(
|
|
56
|
-
context: {{pascalCase}}Context,
|
|
57
|
-
clientState: {{pascalCase}}ClientState
|
|
58
|
-
): void {
|
|
59
|
-
if ( context.error === clientState.bootstrapError ) {
|
|
60
|
-
context.error = '';
|
|
61
|
-
}
|
|
62
|
-
clientState.bootstrapError = '';
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function setBootstrapError(
|
|
66
|
-
context: {{pascalCase}}Context,
|
|
67
|
-
clientState: {{pascalCase}}ClientState,
|
|
68
|
-
message: string
|
|
69
|
-
): void {
|
|
70
|
-
clientState.bootstrapError = message;
|
|
71
|
-
context.error = message;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const { actions, state } = store( '{{slugKebabCase}}', {
|
|
75
|
-
state: {
|
|
76
|
-
isHydrated: false,
|
|
77
|
-
} as {{pascalCase}}State,
|
|
78
|
-
|
|
79
|
-
actions: {
|
|
80
|
-
async loadState() {
|
|
81
|
-
const context = getContext< {{pascalCase}}Context >();
|
|
82
|
-
if ( context.postId <= 0 || ! context.resourceKey ) {
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
context.isLoading = true;
|
|
87
|
-
context.error = '';
|
|
88
|
-
|
|
89
|
-
try {
|
|
90
|
-
const result = await fetchState( {
|
|
91
|
-
postId: context.postId,
|
|
92
|
-
resourceKey: context.resourceKey,
|
|
93
|
-
}, {
|
|
94
|
-
transportTarget: 'frontend',
|
|
95
|
-
} );
|
|
96
|
-
if ( ! result.isValid || ! result.data ) {
|
|
97
|
-
context.error = result.errors[ 0 ]?.expected ?? 'Unable to load counter';
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
context.count = result.data.count;
|
|
101
|
-
} catch ( error ) {
|
|
102
|
-
context.error =
|
|
103
|
-
error instanceof Error ? error.message : 'Unknown loading error';
|
|
104
|
-
} finally {
|
|
105
|
-
context.isLoading = false;
|
|
106
|
-
}
|
|
107
|
-
},
|
|
108
|
-
async loadBootstrap() {
|
|
109
|
-
const context = getContext< {{pascalCase}}Context >();
|
|
110
|
-
const clientState = getClientState( context );
|
|
111
|
-
if ( context.postId <= 0 || ! context.resourceKey ) {
|
|
112
|
-
context.bootstrapReady = true;
|
|
113
|
-
context.canWrite = false;
|
|
114
|
-
clientState.bootstrapError = '';
|
|
115
|
-
clientState.writeExpiry = 0;
|
|
116
|
-
clientState.writeNonce = '';
|
|
117
|
-
clientState.writeToken = '';
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
context.isBootstrapping = true;
|
|
122
|
-
|
|
123
|
-
let bootstrapSucceeded = false;
|
|
124
|
-
let lastBootstrapError =
|
|
125
|
-
'Unable to initialize write access';
|
|
126
|
-
const includePublicWriteCredentials = {{isPublicPersistencePolicy}};
|
|
127
|
-
const includeRestNonce = {{isAuthenticatedPersistencePolicy}};
|
|
128
|
-
|
|
129
|
-
for ( let attempt = 1; attempt <= BOOTSTRAP_MAX_ATTEMPTS; attempt += 1 ) {
|
|
130
|
-
try {
|
|
131
|
-
const result = await fetchBootstrap( {
|
|
132
|
-
postId: context.postId,
|
|
133
|
-
resourceKey: context.resourceKey,
|
|
134
|
-
}, {
|
|
135
|
-
transportTarget: 'frontend',
|
|
136
|
-
} );
|
|
137
|
-
if ( ! result.isValid || ! result.data ) {
|
|
138
|
-
lastBootstrapError =
|
|
139
|
-
result.errors[ 0 ]?.expected ??
|
|
140
|
-
'Unable to initialize write access';
|
|
141
|
-
if ( attempt < BOOTSTRAP_MAX_ATTEMPTS ) {
|
|
142
|
-
await waitForBootstrapRetry(
|
|
143
|
-
BOOTSTRAP_RETRY_DELAYS_MS[ attempt - 1 ] ?? 750
|
|
144
|
-
);
|
|
145
|
-
continue;
|
|
146
|
-
}
|
|
147
|
-
break;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
clientState.writeExpiry =
|
|
151
|
-
includePublicWriteCredentials &&
|
|
152
|
-
'publicWriteExpiresAt' in result.data &&
|
|
153
|
-
typeof result.data.publicWriteExpiresAt === 'number' &&
|
|
154
|
-
result.data.publicWriteExpiresAt > 0
|
|
155
|
-
? result.data.publicWriteExpiresAt
|
|
156
|
-
: 0;
|
|
157
|
-
clientState.writeToken =
|
|
158
|
-
includePublicWriteCredentials &&
|
|
159
|
-
'publicWriteToken' in result.data &&
|
|
160
|
-
typeof result.data.publicWriteToken === 'string' &&
|
|
161
|
-
result.data.publicWriteToken.length > 0
|
|
162
|
-
? result.data.publicWriteToken
|
|
163
|
-
: '';
|
|
164
|
-
clientState.writeNonce =
|
|
165
|
-
includeRestNonce &&
|
|
166
|
-
'restNonce' in result.data &&
|
|
167
|
-
typeof result.data.restNonce === 'string' &&
|
|
168
|
-
result.data.restNonce.length > 0
|
|
169
|
-
? result.data.restNonce
|
|
170
|
-
: '';
|
|
171
|
-
context.bootstrapReady = true;
|
|
172
|
-
context.canWrite =
|
|
173
|
-
result.data.canWrite === true &&
|
|
174
|
-
(
|
|
175
|
-
context.persistencePolicy === 'authenticated'
|
|
176
|
-
? clientState.writeNonce.length > 0
|
|
177
|
-
: clientState.writeToken.length > 0 &&
|
|
178
|
-
! hasExpiredPublicWriteToken( clientState.writeExpiry )
|
|
179
|
-
);
|
|
180
|
-
clearBootstrapError( context, clientState );
|
|
181
|
-
bootstrapSucceeded = true;
|
|
182
|
-
break;
|
|
183
|
-
} catch ( error ) {
|
|
184
|
-
lastBootstrapError =
|
|
185
|
-
error instanceof Error ? error.message : 'Unknown bootstrap error';
|
|
186
|
-
if ( attempt < BOOTSTRAP_MAX_ATTEMPTS ) {
|
|
187
|
-
await waitForBootstrapRetry(
|
|
188
|
-
BOOTSTRAP_RETRY_DELAYS_MS[ attempt - 1 ] ?? 750
|
|
189
|
-
);
|
|
190
|
-
continue;
|
|
191
|
-
}
|
|
192
|
-
break;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
if ( ! bootstrapSucceeded ) {
|
|
197
|
-
context.bootstrapReady = false;
|
|
198
|
-
context.canWrite = false;
|
|
199
|
-
clientState.writeExpiry = 0;
|
|
200
|
-
clientState.writeNonce = '';
|
|
201
|
-
clientState.writeToken = '';
|
|
202
|
-
setBootstrapError( context, clientState, lastBootstrapError );
|
|
203
|
-
}
|
|
204
|
-
context.isBootstrapping = false;
|
|
205
|
-
},
|
|
206
|
-
async increment() {
|
|
207
|
-
const context = getContext< {{pascalCase}}Context >();
|
|
208
|
-
const clientState = getClientState( context );
|
|
209
|
-
if ( context.postId <= 0 || ! context.resourceKey ) {
|
|
210
|
-
return;
|
|
211
|
-
}
|
|
212
|
-
if ( ! context.bootstrapReady ) {
|
|
213
|
-
await actions.loadBootstrap();
|
|
214
|
-
}
|
|
215
|
-
if ( ! context.bootstrapReady ) {
|
|
216
|
-
context.error = 'Write access is still initializing.';
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
if (
|
|
220
|
-
context.persistencePolicy === 'public' &&
|
|
221
|
-
hasExpiredPublicWriteToken( clientState.writeExpiry )
|
|
222
|
-
) {
|
|
223
|
-
await actions.loadBootstrap();
|
|
224
|
-
}
|
|
225
|
-
if (
|
|
226
|
-
context.persistencePolicy === 'public' &&
|
|
227
|
-
hasExpiredPublicWriteToken( clientState.writeExpiry )
|
|
228
|
-
) {
|
|
229
|
-
context.canWrite = false;
|
|
230
|
-
context.error = getWriteBlockedMessage( context );
|
|
231
|
-
return;
|
|
232
|
-
}
|
|
233
|
-
if ( ! context.canWrite ) {
|
|
234
|
-
context.error = getWriteBlockedMessage( context );
|
|
235
|
-
return;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
context.isSaving = true;
|
|
239
|
-
context.error = '';
|
|
240
|
-
|
|
241
|
-
try {
|
|
242
|
-
const result = await writeState( {
|
|
243
|
-
delta: 1,
|
|
244
|
-
postId: context.postId,
|
|
245
|
-
publicWriteRequestId:
|
|
246
|
-
context.persistencePolicy === 'public'
|
|
247
|
-
? generatePublicWriteRequestId()
|
|
248
|
-
: undefined,
|
|
249
|
-
publicWriteToken:
|
|
250
|
-
context.persistencePolicy === 'public' &&
|
|
251
|
-
clientState.writeToken.length > 0
|
|
252
|
-
? clientState.writeToken
|
|
253
|
-
: undefined,
|
|
254
|
-
resourceKey: context.resourceKey,
|
|
255
|
-
}, {
|
|
256
|
-
restNonce:
|
|
257
|
-
clientState.writeNonce.length > 0
|
|
258
|
-
? clientState.writeNonce
|
|
259
|
-
: undefined,
|
|
260
|
-
transportTarget: 'frontend',
|
|
261
|
-
} );
|
|
262
|
-
if ( ! result.isValid || ! result.data ) {
|
|
263
|
-
context.error = result.errors[ 0 ]?.expected ?? 'Unable to update counter';
|
|
264
|
-
return;
|
|
265
|
-
}
|
|
266
|
-
context.count = result.data.count;
|
|
267
|
-
context.storage = result.data.storage;
|
|
268
|
-
} catch ( error ) {
|
|
269
|
-
context.error =
|
|
270
|
-
error instanceof Error ? error.message : 'Unknown update error';
|
|
271
|
-
} finally {
|
|
272
|
-
context.isSaving = false;
|
|
273
|
-
}
|
|
274
|
-
},
|
|
275
|
-
},
|
|
276
|
-
|
|
277
|
-
callbacks: {
|
|
278
|
-
init() {
|
|
279
|
-
const context = getContext< {{pascalCase}}Context >();
|
|
280
|
-
context.client = {
|
|
281
|
-
bootstrapError: '',
|
|
282
|
-
writeExpiry: 0,
|
|
283
|
-
writeNonce: '',
|
|
284
|
-
writeToken: '',
|
|
285
|
-
};
|
|
286
|
-
context.bootstrapReady = false;
|
|
287
|
-
context.canWrite = false;
|
|
288
|
-
context.count = 0;
|
|
289
|
-
context.error = '';
|
|
290
|
-
context.isBootstrapping = false;
|
|
291
|
-
context.isLoading = false;
|
|
292
|
-
context.isSaving = false;
|
|
293
|
-
},
|
|
294
|
-
mounted() {
|
|
295
|
-
state.isHydrated = true;
|
|
296
|
-
if ( typeof document !== 'undefined' ) {
|
|
297
|
-
document.documentElement.dataset[ '{{slugCamelCase}}Hydrated' ] = 'true';
|
|
298
|
-
}
|
|
299
|
-
void Promise.allSettled( [
|
|
300
|
-
actions.loadState(),
|
|
301
|
-
actions.loadBootstrap(),
|
|
302
|
-
] );
|
|
303
|
-
},
|
|
304
|
-
},
|
|
305
|
-
} );
|
package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/types.ts.mustache
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
TypiaValidationError,
|
|
3
|
-
ValidationResult,
|
|
4
|
-
} from '@wp-typia/block-runtime/validation';
|
|
5
|
-
import { tags } from 'typia';
|
|
6
|
-
|
|
7
|
-
export type {
|
|
8
|
-
TypiaValidationError,
|
|
9
|
-
ValidationResult,
|
|
10
|
-
} from '@wp-typia/block-runtime/validation';
|
|
11
|
-
|
|
12
|
-
export interface {{pascalCase}}Attributes {
|
|
13
|
-
heading: string &
|
|
14
|
-
tags.MinLength< 1 > &
|
|
15
|
-
tags.MaxLength< 80 > &
|
|
16
|
-
tags.Default< {{titleJson}} >;
|
|
17
|
-
intro?: string &
|
|
18
|
-
tags.MinLength< 1 > &
|
|
19
|
-
tags.MaxLength< 180 > &
|
|
20
|
-
tags.Default< 'Add and reorder internal items inside this compound block.' >;
|
|
21
|
-
showDividers?: boolean & tags.Default< true >;
|
|
22
|
-
showCount?: boolean & tags.Default< true >;
|
|
23
|
-
buttonLabel?: string &
|
|
24
|
-
tags.MinLength< 1 > &
|
|
25
|
-
tags.MaxLength< 40 > &
|
|
26
|
-
tags.Default< 'Persist Count' >;
|
|
27
|
-
resourceKey?: string &
|
|
28
|
-
tags.MinLength< 1 > &
|
|
29
|
-
tags.MaxLength< 100 > &
|
|
30
|
-
tags.Default< 'primary' >;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export interface {{pascalCase}}Context {
|
|
34
|
-
buttonLabel: string;
|
|
35
|
-
bootstrapReady: boolean;
|
|
36
|
-
canWrite: boolean;
|
|
37
|
-
count: number;
|
|
38
|
-
error: string;
|
|
39
|
-
isBootstrapping: boolean;
|
|
40
|
-
isLoading: boolean;
|
|
41
|
-
isSaving: boolean;
|
|
42
|
-
persistencePolicy: 'authenticated' | 'public';
|
|
43
|
-
postId: number;
|
|
44
|
-
resourceKey: string;
|
|
45
|
-
showCount: boolean;
|
|
46
|
-
storage: 'post-meta' | 'custom-table';
|
|
47
|
-
client?: {{pascalCase}}ClientState;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export interface {{pascalCase}}State {
|
|
51
|
-
isHydrated: boolean;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export interface {{pascalCase}}ClientState {
|
|
55
|
-
bootstrapError: string;
|
|
56
|
-
writeExpiry: number;
|
|
57
|
-
writeNonce: string;
|
|
58
|
-
writeToken: string;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export type {{pascalCase}}ValidationResult = ValidationResult< {{pascalCase}}Attributes >;
|
package/templates/_shared/compound/persistence/src/blocks/{{slugKebabCase}}/validators.ts.mustache
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import typia from 'typia';
|
|
2
|
-
import currentManifest from './typia.manifest.json';
|
|
3
|
-
import type {
|
|
4
|
-
{{pascalCase}}Attributes,
|
|
5
|
-
{{pascalCase}}ValidationResult,
|
|
6
|
-
} from './types';
|
|
7
|
-
import { generateResourceKey } from '@wp-typia/block-runtime/identifiers';
|
|
8
|
-
import { createTemplateValidatorToolkit } from '../../validator-toolkit';
|
|
9
|
-
|
|
10
|
-
const scaffoldValidators = createTemplateValidatorToolkit< {{pascalCase}}Attributes >( {
|
|
11
|
-
assert: typia.createAssert< {{pascalCase}}Attributes >(),
|
|
12
|
-
clone: typia.misc.createClone< {{pascalCase}}Attributes >() as (
|
|
13
|
-
value: {{pascalCase}}Attributes,
|
|
14
|
-
) => {{pascalCase}}Attributes,
|
|
15
|
-
is: typia.createIs< {{pascalCase}}Attributes >(),
|
|
16
|
-
manifest: currentManifest,
|
|
17
|
-
prune: typia.misc.createPrune< {{pascalCase}}Attributes >(),
|
|
18
|
-
random: typia.createRandom< {{pascalCase}}Attributes >() as (
|
|
19
|
-
...args: unknown[]
|
|
20
|
-
) => {{pascalCase}}Attributes,
|
|
21
|
-
finalize: ( normalized ) => ( {
|
|
22
|
-
...normalized,
|
|
23
|
-
resourceKey:
|
|
24
|
-
normalized.resourceKey && normalized.resourceKey.length > 0
|
|
25
|
-
? normalized.resourceKey
|
|
26
|
-
: generateResourceKey( '{{slugKebabCase}}' ),
|
|
27
|
-
} ),
|
|
28
|
-
validate: typia.createValidate< {{pascalCase}}Attributes >(),
|
|
29
|
-
} );
|
|
30
|
-
|
|
31
|
-
export const validators = scaffoldValidators.validators;
|
|
32
|
-
|
|
33
|
-
export const validate{{pascalCase}}Attributes =
|
|
34
|
-
scaffoldValidators.validateAttributes as (
|
|
35
|
-
attributes: unknown
|
|
36
|
-
) => {{pascalCase}}ValidationResult;
|
|
37
|
-
|
|
38
|
-
export const sanitize{{pascalCase}}Attributes =
|
|
39
|
-
scaffoldValidators.sanitizeAttributes as (
|
|
40
|
-
attributes: Partial< {{pascalCase}}Attributes >
|
|
41
|
-
) => {{pascalCase}}Attributes;
|
|
42
|
-
|
|
43
|
-
export const createAttributeUpdater = scaffoldValidators.createAttributeUpdater;
|
|
@@ -1,25 +0,0 @@
|
|
|
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
|
-
);
|