@wp-typia/project-tools 0.21.0 → 0.22.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 (34) hide show
  1. package/dist/runtime/ai-feature-capability.js +2 -33
  2. package/dist/runtime/built-in-block-artifact-types.js +11 -0
  3. package/dist/runtime/built-in-block-code-artifacts.js +5 -1
  4. package/dist/runtime/built-in-block-code-templates/interactivity.d.ts +4 -3
  5. package/dist/runtime/built-in-block-code-templates/interactivity.js +259 -100
  6. package/dist/runtime/built-in-block-code-templates.d.ts +1 -1
  7. package/dist/runtime/built-in-block-code-templates.js +1 -1
  8. package/dist/runtime/cli-add-shared.d.ts +4 -3
  9. package/dist/runtime/cli-add-shared.js +5 -2
  10. package/dist/runtime/cli-add-workspace-ability.js +3 -4
  11. package/dist/runtime/cli-add-workspace-admin-view-scaffold.d.ts +9 -0
  12. package/dist/runtime/cli-add-workspace-admin-view-scaffold.js +257 -0
  13. package/dist/runtime/cli-add-workspace-admin-view-source.d.ts +5 -0
  14. package/dist/runtime/cli-add-workspace-admin-view-source.js +86 -0
  15. package/dist/runtime/cli-add-workspace-admin-view-templates.d.ts +23 -0
  16. package/dist/runtime/cli-add-workspace-admin-view-templates.js +991 -0
  17. package/dist/runtime/cli-add-workspace-admin-view-types.d.ts +29 -0
  18. package/dist/runtime/cli-add-workspace-admin-view-types.js +29 -0
  19. package/dist/runtime/cli-add-workspace-admin-view.d.ts +1 -14
  20. package/dist/runtime/cli-add-workspace-admin-view.js +23 -860
  21. package/dist/runtime/cli-doctor-workspace.js +5 -4
  22. package/dist/runtime/cli-help.js +5 -2
  23. package/dist/runtime/external-layer-selection.d.ts +8 -2
  24. package/dist/runtime/external-layer-selection.js +3 -4
  25. package/dist/runtime/package-versions.d.ts +28 -0
  26. package/dist/runtime/package-versions.js +79 -36
  27. package/dist/runtime/scaffold-compatibility.d.ts +2 -2
  28. package/dist/runtime/scaffold-compatibility.js +22 -48
  29. package/dist/runtime/string-case.d.ts +7 -0
  30. package/dist/runtime/string-case.js +21 -11
  31. package/dist/runtime/version-floor.d.ts +26 -0
  32. package/dist/runtime/version-floor.js +56 -0
  33. package/dist/runtime/workspace-inventory.d.ts +2 -1
  34. package/package.json +3 -2
@@ -4,6 +4,7 @@ import { useBlockProps, InspectorControls, RichText, BlockControls, AlignmentToo
4
4
  import { PanelBody, RangeControl, Button, Notice } from '@wordpress/components';
5
5
  import { useState } from '@wordpress/element';
6
6
  import currentManifest from './manifest-document';
7
+ import { {{slugCamelCase}}Store } from './interactivity-store';
7
8
  import {
8
9
  InspectorFromManifest,
9
10
  useEditorFields,
@@ -84,17 +85,22 @@ export default function Edit({ attributes, setAttributes, isSelected }: EditProp
84
85
 
85
86
  const blockProps = useBlockProps({
86
87
  className: \`{{cssClassName}} {{cssClassName}}--\${interactiveMode}\`,
87
- 'data-wp-interactive': '{{slugKebabCase}}',
88
- 'data-wp-context': JSON.stringify({
89
- clicks: clickCount,
90
- isAnimating,
91
- isVisible,
92
- animation,
93
- maxClicks,
94
- })
88
+ 'data-wp-interactive': {{slugCamelCase}}Store.directive.interactive,
89
+ 'data-wp-context': JSON.stringify(
90
+ {{slugCamelCase}}Store.createContext({
91
+ clicks: clickCount,
92
+ isAnimating,
93
+ isVisible,
94
+ animation,
95
+ maxClicks,
96
+ })
97
+ )
95
98
  });
96
99
  const previewContentStyle = { textAlign: alignmentValue };
97
100
  const progressBarStyle = { width: \`\${(clickCount / maxClicks) * 100}%\` };
101
+ const clicksDirective = {{slugCamelCase}}Store.directive.state('clicks');
102
+ const isAnimatingDirective = {{slugCamelCase}}Store.directive.state('isAnimating');
103
+ const progressDirective = {{slugCamelCase}}Store.directive.state('progress') + " + '%'";
98
104
 
99
105
  const resetCounter = () => {
100
106
  updateField('clickCount', 0);
@@ -191,9 +197,9 @@ export default function Edit({ attributes, setAttributes, isSelected }: EditProp
191
197
  <div
192
198
  className={\`{{cssClassName}}__content \${isAnimating ? 'is-animating' : ''}\`}
193
199
  style={previewContentStyle}
194
- data-wp-on--click={isPreviewing ? 'actions.handleClick' : undefined}
195
- data-wp-on--mouseenter={isPreviewing && interactiveMode === 'hover' ? 'actions.handleMouseEnter' : undefined}
196
- data-wp-on--mouseleave={isPreviewing && interactiveMode === 'hover' ? 'actions.handleMouseLeave' : undefined}
200
+ data-wp-on--click={isPreviewing ? {{slugCamelCase}}Store.directive.action('handleClick') : undefined}
201
+ data-wp-on--mouseenter={isPreviewing && interactiveMode === 'hover' ? {{slugCamelCase}}Store.directive.action('handleMouseEnter') : undefined}
202
+ data-wp-on--mouseleave={isPreviewing && interactiveMode === 'hover' ? {{slugCamelCase}}Store.directive.action('handleMouseLeave') : undefined}
197
203
  >
198
204
  <RichText
199
205
  tagName="p"
@@ -222,7 +228,7 @@ export default function Edit({ attributes, setAttributes, isSelected }: EditProp
222
228
  </span>
223
229
  <span
224
230
  className="{{cssClassName}}__counter-value"
225
- data-wp-text="state.clicks"
231
+ data-wp-text={clicksDirective}
226
232
  >
227
233
  {clickCount}
228
234
  </span>
@@ -234,7 +240,7 @@ export default function Edit({ attributes, setAttributes, isSelected }: EditProp
234
240
  <div
235
241
  className="{{cssClassName}}__progress-bar"
236
242
  style={progressBarStyle}
237
- data-wp-style--width="state.progress + '%'"
243
+ data-wp-style--width={progressDirective}
238
244
  />
239
245
  </div>
240
246
  )}
@@ -242,7 +248,7 @@ export default function Edit({ attributes, setAttributes, isSelected }: EditProp
242
248
  {animation !== 'none' && (
243
249
  <div
244
250
  className={\`{{cssClassName}}__animation \${isAnimating ? 'is-active' : ''}\`}
245
- data-wp-class--is-active="state.isAnimating"
251
+ data-wp-class--is-active={isAnimatingDirective}
246
252
  >
247
253
  {animation}
248
254
  </div>
@@ -255,6 +261,7 @@ export default function Edit({ attributes, setAttributes, isSelected }: EditProp
255
261
  `;
256
262
  export const INTERACTIVITY_SAVE_TEMPLATE = `import { useBlockProps, RichText } from '@wordpress/block-editor';
257
263
  import { __ } from '@wordpress/i18n';
264
+ import { {{slugCamelCase}}Store } from './interactivity-store';
258
265
  import type { {{pascalCase}}Attributes } from './types';
259
266
 
260
267
  export default function Save({ attributes }: { attributes: {{pascalCase}}Attributes }) {
@@ -266,27 +273,41 @@ export default function Save({ attributes }: { attributes: {{pascalCase}}Attribu
266
273
  const maxClicks = attributes.maxClicks ?? 0;
267
274
  const showCounter = attributes.showCounter ?? true;
268
275
  const contentStyle = { textAlign: attributes.alignment };
276
+ const clickActionDirective = {{slugCamelCase}}Store.directive.action('handleClick');
277
+ const visibilityHiddenDirective = {{slugCamelCase}}Store.directive.negate(
278
+ {{slugCamelCase}}Store.directive.state('isVisible')
279
+ );
280
+ const clicksDirective = {{slugCamelCase}}Store.directive.state('clicks');
281
+ const clampedClicksDirective = {{slugCamelCase}}Store.directive.state('clampedClicks');
282
+ const isAnimatingDirective = {{slugCamelCase}}Store.directive.state('isAnimating');
283
+ const completionHiddenDirective = {{slugCamelCase}}Store.directive.negate(
284
+ {{slugCamelCase}}Store.directive.state('isComplete')
285
+ );
286
+ const resetActionDirective = {{slugCamelCase}}Store.directive.action('reset');
269
287
  const blockProps = useBlockProps.save({
270
288
  className: \`{{cssClassName}} {{cssClassName}}--\${interactiveMode}\`,
271
- 'data-wp-interactive': '{{slugKebabCase}}',
272
- 'data-wp-context': JSON.stringify({
273
- clicks: clickCount,
274
- isAnimating,
275
- isVisible,
276
- animation,
277
- maxClicks,
278
- })
289
+ 'data-wp-interactive': {{slugCamelCase}}Store.directive.interactive,
290
+ 'data-wp-context': JSON.stringify(
291
+ {{slugCamelCase}}Store.createContext({
292
+ clicks: clickCount,
293
+ isAnimating,
294
+ isVisible,
295
+ animation,
296
+ maxClicks,
297
+ })
298
+ )
279
299
  });
300
+ const progressDirective = {{slugCamelCase}}Store.directive.state('progress') + " + '%'";
280
301
 
281
302
  return (
282
303
  <div {...blockProps}>
283
304
  <div
284
305
  className={\`{{cssClassName}}__content \${isAnimating ? 'is-animating' : ''}\`}
285
306
  style={contentStyle}
286
- data-wp-on--click="actions.handleClick"
287
- data-wp-on--mouseenter={interactiveMode === 'hover' ? 'actions.handleMouseEnter' : undefined}
288
- data-wp-on--mouseleave={interactiveMode === 'hover' ? 'actions.handleMouseLeave' : undefined}
289
- data-wp-bind--hidden="!state.isVisible"
307
+ data-wp-on--click={clickActionDirective}
308
+ data-wp-on--mouseenter={interactiveMode === 'hover' ? {{slugCamelCase}}Store.directive.action('handleMouseEnter') : undefined}
309
+ data-wp-on--mouseleave={interactiveMode === 'hover' ? {{slugCamelCase}}Store.directive.action('handleMouseLeave') : undefined}
310
+ data-wp-bind--hidden={visibilityHiddenDirective}
290
311
  >
291
312
  <RichText.Content
292
313
  tagName="p"
@@ -306,7 +327,7 @@ export default function Save({ attributes }: { attributes: {{pascalCase}}Attribu
306
327
  </span>
307
328
  <span
308
329
  className="{{cssClassName}}__counter-value"
309
- data-wp-text="state.clicks"
330
+ data-wp-text={clicksDirective}
310
331
  >
311
332
  {clickCount}
312
333
  </span>
@@ -322,8 +343,8 @@ export default function Save({ attributes }: { attributes: {{pascalCase}}Attribu
322
343
  aria-valuemin={0}
323
344
  aria-valuemax={maxClicks}
324
345
  aria-valuenow={Math.min(clickCount, maxClicks)}
325
- data-wp-bind--aria-valuenow="state.clampedClicks"
326
- data-wp-style--width="state.progress + '%'"
346
+ data-wp-bind--aria-valuenow={clampedClicksDirective}
347
+ data-wp-style--width={progressDirective}
327
348
  />
328
349
  </div>
329
350
  )}
@@ -331,7 +352,7 @@ export default function Save({ attributes }: { attributes: {{pascalCase}}Attribu
331
352
  <div
332
353
  className={\`{{cssClassName}}__animation \${animation}\`}
333
354
  aria-hidden="true"
334
- data-wp-class--is-active="state.isAnimating"
355
+ data-wp-class--is-active={isAnimatingDirective}
335
356
  />
336
357
 
337
358
  {maxClicks > 0 && (
@@ -340,7 +361,7 @@ export default function Save({ attributes }: { attributes: {{pascalCase}}Attribu
340
361
  role="status"
341
362
  aria-live="polite"
342
363
  aria-atomic="true"
343
- data-wp-bind--hidden="!state.isComplete"
364
+ data-wp-bind--hidden={completionHiddenDirective}
344
365
  >
345
366
  { __( '🎉 Complete!', '{{textDomain}}' ) }
346
367
  </div>
@@ -348,7 +369,7 @@ export default function Save({ attributes }: { attributes: {{pascalCase}}Attribu
348
369
 
349
370
  <button
350
371
  className="{{cssClassName}}__reset"
351
- data-wp-on--click="actions.reset"
372
+ data-wp-on--click={resetActionDirective}
352
373
  aria-label={ __( 'Reset counter', '{{textDomain}}' ) }
353
374
  >
354
375
  <span aria-hidden="true">↻</span>
@@ -398,20 +419,214 @@ const registration = buildScaffoldBlockRegistration(
398
419
 
399
420
  registerScaffoldBlockType(registration.name, registration.settings);
400
421
  `;
422
+ export const INTERACTIVITY_STORE_TEMPLATE = `import type {
423
+ {{pascalCase}}Context,
424
+ {{pascalCase}}State,
425
+ } from './types';
426
+
427
+ type InteractivityActionShape = object;
428
+ type InteractivityCallbackShape = object;
429
+ type InteractivityContextShape = object;
430
+ type InteractivityStateShape = object;
431
+ type InteractivityCallable = CallableFunction;
432
+ type InteractivityKey<T extends object> = Extract<keyof T, string>;
433
+ type InteractivityMethodKey<T extends object> = {
434
+ [Key in InteractivityKey<T>]: T[Key] extends InteractivityCallable ? Key : never;
435
+ }[InteractivityKey<T>];
436
+
437
+ type InteractivityDirectivePath<
438
+ Root extends string,
439
+ Key extends string,
440
+ > = \`\${Root}.\${Key}\`;
441
+
442
+ type NegatedInteractivityDirectivePath<Path extends string> = \`!\${Path}\`;
443
+
444
+ export interface TypedInteractivityDirectiveHelpers<
445
+ State extends InteractivityStateShape,
446
+ Context extends InteractivityContextShape,
447
+ Actions extends InteractivityActionShape,
448
+ Callbacks extends InteractivityCallbackShape,
449
+ Namespace extends string,
450
+ > {
451
+ readonly interactive: Namespace;
452
+ action<Key extends InteractivityMethodKey<Actions>>(
453
+ key: Key,
454
+ ): InteractivityDirectivePath<'actions', Key>;
455
+ callback<Key extends InteractivityMethodKey<Callbacks>>(
456
+ key: Key,
457
+ ): InteractivityDirectivePath<'callbacks', Key>;
458
+ state<Key extends InteractivityKey<State>>(
459
+ key: Key,
460
+ ): InteractivityDirectivePath<'state', Key>;
461
+ context<Key extends InteractivityKey<Context>>(
462
+ key: Key,
463
+ ): InteractivityDirectivePath<'context', Key>;
464
+ negate<Path extends string>(
465
+ path: Path,
466
+ ): NegatedInteractivityDirectivePath<Path>;
467
+ }
468
+
469
+ export interface TypedInteractivityStore<
470
+ Namespace extends string,
471
+ State extends InteractivityStateShape,
472
+ Context extends InteractivityContextShape,
473
+ Actions extends InteractivityActionShape,
474
+ Callbacks extends InteractivityCallbackShape,
475
+ > {
476
+ readonly namespace: Namespace;
477
+ readonly state: State;
478
+ readonly context: Context;
479
+ readonly actions: Actions;
480
+ readonly callbacks: Callbacks;
481
+ readonly directive: TypedInteractivityDirectiveHelpers<
482
+ State,
483
+ Context,
484
+ Actions,
485
+ Callbacks,
486
+ Namespace
487
+ >;
488
+ createContext(value: Context): Context;
489
+ }
490
+
491
+ export function defineInteractivityStore<
492
+ Namespace extends string,
493
+ State extends InteractivityStateShape,
494
+ Context extends InteractivityContextShape,
495
+ Actions extends InteractivityActionShape,
496
+ Callbacks extends InteractivityCallbackShape,
497
+ >(config: {
498
+ readonly namespace: Namespace;
499
+ readonly state: State;
500
+ readonly context: Context;
501
+ readonly actions: Actions;
502
+ readonly callbacks: Callbacks;
503
+ }): TypedInteractivityStore<Namespace, State, Context, Actions, Callbacks> {
504
+ return {
505
+ namespace: config.namespace,
506
+ state: config.state,
507
+ context: config.context,
508
+ actions: config.actions,
509
+ callbacks: config.callbacks,
510
+ directive: {
511
+ interactive: config.namespace,
512
+ action<Key extends InteractivityMethodKey<Actions>>(key: Key) {
513
+ return \`actions.\${key}\` as InteractivityDirectivePath<'actions', Key>;
514
+ },
515
+ callback<Key extends InteractivityMethodKey<Callbacks>>(key: Key) {
516
+ return \`callbacks.\${key}\` as InteractivityDirectivePath<'callbacks', Key>;
517
+ },
518
+ state<Key extends InteractivityKey<State>>(key: Key) {
519
+ return \`state.\${key}\` as InteractivityDirectivePath<'state', Key>;
520
+ },
521
+ context<Key extends InteractivityKey<Context>>(key: Key) {
522
+ return \`context.\${key}\` as InteractivityDirectivePath<'context', Key>;
523
+ },
524
+ negate<Path extends string>(path: Path) {
525
+ return \`!\${path}\` as NegatedInteractivityDirectivePath<Path>;
526
+ },
527
+ },
528
+ createContext(value) {
529
+ return value;
530
+ },
531
+ };
532
+ }
533
+
534
+ type InteractivityActionHandler = CallableFunction;
535
+
536
+ export interface {{pascalCase}}StoreActions {
537
+ handleClick: InteractivityActionHandler;
538
+ handleMouseEnter: InteractivityActionHandler;
539
+ handleMouseLeave: InteractivityActionHandler;
540
+ reset: InteractivityActionHandler;
541
+ }
542
+
543
+ export interface {{pascalCase}}StoreCallbacks {}
544
+
545
+ export const {{slugCamelCase}}Store = defineInteractivityStore({
546
+ namespace: '{{slugKebabCase}}',
547
+ state: {} as {{pascalCase}}State,
548
+ context: {} as {{pascalCase}}Context,
549
+ actions: {} as {{pascalCase}}StoreActions,
550
+ callbacks: {} as {{pascalCase}}StoreCallbacks,
551
+ });
552
+ `;
401
553
  export const INTERACTIVITY_SCRIPT_TEMPLATE = `/**
402
554
  * WordPress Interactivity API implementation for {{title}} block
403
555
  */
404
556
  import { store, getContext, getElement, withSyncEvent } from '@wordpress/interactivity';
405
- import type { {{pascalCase}}Context } from './types';
557
+ import {
558
+ {{slugCamelCase}}Store,
559
+ type {{pascalCase}}StoreActions,
560
+ } from './interactivity-store';
561
+ import type { {{pascalCase}}Context, {{pascalCase}}State } from './types';
406
562
 
407
563
  function getBlockContext() {
408
564
  return getContext<{{pascalCase}}Context>();
409
565
  }
410
566
 
411
- // Store configuration
412
- store('{{slugKebabCase}}', {
413
- // State - reactive data that updates the UI
414
- state: {
567
+ const actions: {{pascalCase}}StoreActions = {
568
+ // Handle block click
569
+ handleClick: () => {
570
+ const context = getBlockContext();
571
+ const { ref } = getElement();
572
+
573
+ if (!ref) {
574
+ return;
575
+ }
576
+
577
+ if (context.maxClicks > 0 && context.clicks >= context.maxClicks) {
578
+ return;
579
+ }
580
+
581
+ const previousClicks = context.clicks;
582
+
583
+ // Increment click counter
584
+ context.clicks += 1;
585
+
586
+ // Trigger animation
587
+ if (context.animation !== 'none') {
588
+ context.isAnimating = true;
589
+ setTimeout(() => {
590
+ context.isAnimating = false;
591
+ }, 1000);
592
+ }
593
+
594
+ // Emit custom event
595
+ ref.dispatchEvent(new CustomEvent('{{slugKebabCase}}:click', {
596
+ detail: { clicks: context.clicks }
597
+ }));
598
+
599
+ // Check if max clicks reached
600
+ if (context.maxClicks > 0 && previousClicks < context.maxClicks && context.clicks === context.maxClicks) {
601
+ ref.dispatchEvent(new CustomEvent('{{slugKebabCase}}:complete', {
602
+ detail: { totalClicks: context.clicks }
603
+ }));
604
+ }
605
+ },
606
+
607
+ // Handle hover events
608
+ handleMouseEnter: () => {
609
+ const context = getBlockContext();
610
+ if (context.animation === 'none') return;
611
+ context.isAnimating = true;
612
+ },
613
+
614
+ handleMouseLeave: () => {
615
+ const context = getBlockContext();
616
+ if (context.animation === 'none') return;
617
+ context.isAnimating = false;
618
+ },
619
+
620
+ // Reset counter
621
+ reset: withSyncEvent((event: Event) => {
622
+ event.stopPropagation();
623
+ const context = getBlockContext();
624
+ context.clicks = 0;
625
+ context.isAnimating = false;
626
+ })
627
+ };
628
+
629
+ const state = {
415
630
  get clicks() {
416
631
  return getBlockContext().clicks;
417
632
  },
@@ -439,70 +654,14 @@ store('{{slugKebabCase}}', {
439
654
  const context = getBlockContext();
440
655
  return context.clicks >= context.maxClicks && context.maxClicks > 0;
441
656
  }
442
- },
443
-
444
- // Actions - user interactions
445
- actions: {
446
- // Handle block click
447
- handleClick: () => {
448
- const context = getBlockContext();
449
- const { ref } = getElement();
450
-
451
- if (!ref) {
452
- return;
453
- }
454
-
455
- if (context.maxClicks > 0 && context.clicks >= context.maxClicks) {
456
- return;
457
- }
458
-
459
- const previousClicks = context.clicks;
460
-
461
- // Increment click counter
462
- context.clicks += 1;
657
+ } satisfies {{pascalCase}}State;
463
658
 
464
- // Trigger animation
465
- if (context.animation !== 'none') {
466
- context.isAnimating = true;
467
- setTimeout(() => {
468
- context.isAnimating = false;
469
- }, 1000);
470
- }
471
-
472
- // Emit custom event
473
- ref.dispatchEvent(new CustomEvent('{{slugKebabCase}}:click', {
474
- detail: { clicks: context.clicks }
475
- }));
476
-
477
- // Check if max clicks reached
478
- if (context.maxClicks > 0 && previousClicks < context.maxClicks && context.clicks === context.maxClicks) {
479
- ref.dispatchEvent(new CustomEvent('{{slugKebabCase}}:complete', {
480
- detail: { totalClicks: context.clicks }
481
- }));
482
- }
483
- },
484
-
485
- // Handle hover events
486
- handleMouseEnter: () => {
487
- const context = getBlockContext();
488
- if (context.animation === 'none') return;
489
- context.isAnimating = true;
490
- },
491
-
492
- handleMouseLeave: () => {
493
- const context = getBlockContext();
494
- if (context.animation === 'none') return;
495
- context.isAnimating = false;
496
- },
497
-
498
- // Reset counter
499
- reset: withSyncEvent((event: Event) => {
500
- event.stopPropagation();
501
- const context = getBlockContext();
502
- context.clicks = 0;
503
- context.isAnimating = false;
504
- })
505
- }
659
+ // Store configuration
660
+ store({{slugCamelCase}}Store.namespace, {
661
+ // State - reactive data that updates the UI
662
+ state,
663
+ actions,
664
+ callbacks: {{slugCamelCase}}Store.callbacks,
506
665
  });
507
666
  `;
508
667
  export const INTERACTIVITY_VALIDATORS_TEMPLATE = `import typia from 'typia';
@@ -4,7 +4,7 @@
4
4
  */
5
5
  export { BLOCK_METADATA_WRAPPER_TEMPLATE, MANIFEST_DEFAULTS_DOCUMENT_WRAPPER_TEMPLATE, MANIFEST_DOCUMENT_WRAPPER_TEMPLATE, SHARED_HOOKS_TEMPLATE, } from "./built-in-block-code-templates/shared.js";
6
6
  export { BASIC_EDIT_TEMPLATE, BASIC_INDEX_TEMPLATE, BASIC_SAVE_TEMPLATE, BASIC_VALIDATORS_TEMPLATE, } from "./built-in-block-code-templates/basic.js";
7
- export { INTERACTIVITY_EDIT_TEMPLATE, INTERACTIVITY_INDEX_TEMPLATE, INTERACTIVITY_SAVE_TEMPLATE, INTERACTIVITY_SCRIPT_TEMPLATE, INTERACTIVITY_VALIDATORS_TEMPLATE, } from "./built-in-block-code-templates/interactivity.js";
7
+ export { INTERACTIVITY_EDIT_TEMPLATE, INTERACTIVITY_INDEX_TEMPLATE, INTERACTIVITY_SAVE_TEMPLATE, INTERACTIVITY_SCRIPT_TEMPLATE, INTERACTIVITY_STORE_TEMPLATE, INTERACTIVITY_VALIDATORS_TEMPLATE, } from "./built-in-block-code-templates/interactivity.js";
8
8
  export { PERSISTENCE_EDIT_TEMPLATE, PERSISTENCE_INDEX_TEMPLATE, PERSISTENCE_INTERACTIVITY_TEMPLATE, PERSISTENCE_SAVE_TEMPLATE, PERSISTENCE_VALIDATORS_TEMPLATE, } from "./built-in-block-code-templates/persistence.js";
9
9
  export { QUERY_LOOP_INDEX_TEMPLATE, } from "./built-in-block-code-templates/query-loop.js";
10
10
  export { COMPOUND_CHILD_EDIT_TEMPLATE, COMPOUND_CHILD_INDEX_TEMPLATE, COMPOUND_CHILDREN_TEMPLATE, COMPOUND_CHILD_SAVE_TEMPLATE, COMPOUND_CHILD_VALIDATORS_TEMPLATE, COMPOUND_LOCAL_HOOKS_TEMPLATE, COMPOUND_PARENT_EDIT_TEMPLATE, COMPOUND_PARENT_INDEX_TEMPLATE, COMPOUND_PARENT_SAVE_TEMPLATE, COMPOUND_PARENT_VALIDATORS_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_EDIT_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_INTERACTIVITY_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_SAVE_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_VALIDATORS_TEMPLATE, } from "./built-in-block-code-templates/compound.js";
@@ -4,7 +4,7 @@
4
4
  */
5
5
  export { BLOCK_METADATA_WRAPPER_TEMPLATE, MANIFEST_DEFAULTS_DOCUMENT_WRAPPER_TEMPLATE, MANIFEST_DOCUMENT_WRAPPER_TEMPLATE, SHARED_HOOKS_TEMPLATE, } from "./built-in-block-code-templates/shared.js";
6
6
  export { BASIC_EDIT_TEMPLATE, BASIC_INDEX_TEMPLATE, BASIC_SAVE_TEMPLATE, BASIC_VALIDATORS_TEMPLATE, } from "./built-in-block-code-templates/basic.js";
7
- export { INTERACTIVITY_EDIT_TEMPLATE, INTERACTIVITY_INDEX_TEMPLATE, INTERACTIVITY_SAVE_TEMPLATE, INTERACTIVITY_SCRIPT_TEMPLATE, INTERACTIVITY_VALIDATORS_TEMPLATE, } from "./built-in-block-code-templates/interactivity.js";
7
+ export { INTERACTIVITY_EDIT_TEMPLATE, INTERACTIVITY_INDEX_TEMPLATE, INTERACTIVITY_SAVE_TEMPLATE, INTERACTIVITY_SCRIPT_TEMPLATE, INTERACTIVITY_STORE_TEMPLATE, INTERACTIVITY_VALIDATORS_TEMPLATE, } from "./built-in-block-code-templates/interactivity.js";
8
8
  export { PERSISTENCE_EDIT_TEMPLATE, PERSISTENCE_INDEX_TEMPLATE, PERSISTENCE_INTERACTIVITY_TEMPLATE, PERSISTENCE_SAVE_TEMPLATE, PERSISTENCE_VALIDATORS_TEMPLATE, } from "./built-in-block-code-templates/persistence.js";
9
9
  export { QUERY_LOOP_INDEX_TEMPLATE, } from "./built-in-block-code-templates/query-loop.js";
10
10
  export { COMPOUND_CHILD_EDIT_TEMPLATE, COMPOUND_CHILD_INDEX_TEMPLATE, COMPOUND_CHILDREN_TEMPLATE, COMPOUND_CHILD_SAVE_TEMPLATE, COMPOUND_CHILD_VALIDATORS_TEMPLATE, COMPOUND_LOCAL_HOOKS_TEMPLATE, COMPOUND_PARENT_EDIT_TEMPLATE, COMPOUND_PARENT_INDEX_TEMPLATE, COMPOUND_PARENT_SAVE_TEMPLATE, COMPOUND_PARENT_VALIDATORS_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_EDIT_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_INTERACTIVITY_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_SAVE_TEMPLATE, COMPOUND_PERSISTENCE_PARENT_VALIDATORS_TEMPLATE, } from "./built-in-block-code-templates/compound.js";
@@ -92,9 +92,10 @@ export interface RunAddRestResourceCommandOptions {
92
92
  * normalized into the generated slug.
93
93
  * @property cwd Working directory used to resolve the nearest official workspace.
94
94
  * Defaults to `process.cwd()`.
95
- * @property source Optional data source locator. The first supported source is
96
- * `rest-resource:<slug>`, which wires the generated screen to an existing
97
- * list-capable REST resource.
95
+ * @property source Optional data source locator. `rest-resource:<slug>` wires
96
+ * the generated screen to an existing list-capable REST resource.
97
+ * `core-data:<kind>/<name>` binds the screen to a supported WordPress-owned
98
+ * entity collection such as `core-data:postType/post`.
98
99
  */
99
100
  export interface RunAddAdminViewCommandOptions {
100
101
  adminViewName: string;
@@ -357,7 +357,7 @@ export function assertEditorPluginDoesNotExist(projectDir, editorPluginSlug, inv
357
357
  */
358
358
  export function formatAddHelpText() {
359
359
  return `Usage:
360
- wp-typia add admin-view <name> [--source <rest-resource:slug>] [--dry-run]
360
+ wp-typia add admin-view <name> [--source <rest-resource:slug|core-data:kind/name>] [--dry-run]
361
361
  wp-typia add block <name> [--template <${ADD_BLOCK_TEMPLATE_IDS.join("|")}>] [--external-layer-source <./path|github:owner/repo/path[#ref]|npm-package>] [--external-layer-id <layer-id>] [--inner-blocks-preset <freeform|ordered|horizontal|locked-structure>] [--alternate-render-targets <email,mjml,plain-text>] [--data-storage <post-meta|custom-table>] [--persistence-policy <authenticated|public>] [--dry-run]
362
362
  wp-typia add variation <name> --block <block-slug> [--dry-run]
363
363
  wp-typia add style <name> --block <block-slug> [--dry-run]
@@ -374,7 +374,10 @@ Notes:
374
374
  \`wp-typia add\` runs only inside official ${WORKSPACE_TEMPLATE_PACKAGE} workspaces scaffolded via \`wp-typia create <project-dir> --template workspace\`.
375
375
  Pass \`--dry-run\` to preview the workspace files that would change without writing them.
376
376
  Interactive add flows let you choose a template when \`--template\` is omitted; non-interactive runs default to \`basic\`.
377
- \`add admin-view\` scaffolds an opt-in DataViews-powered WordPress admin screen under \`src/admin-views/\`; pass \`--source rest-resource:<slug>\` to reuse a list-capable REST resource.
377
+ \`add admin-view\` scaffolds an opt-in DataViews-powered WordPress admin screen under \`src/admin-views/\`.
378
+ Pass \`--source rest-resource:<slug>\` to reuse a list-capable REST resource.
379
+ Pass \`--source core-data:postType/post\` or \`--source core-data:taxonomy/category\` to bind a WordPress-owned entity collection.
380
+ Public installs currently gate this workflow until \`@wp-typia/dataviews\` is published to npm.
378
381
  \`query-loop\` is a create-time scaffold family. Use \`wp-typia create <project-dir> --template query-loop\` instead of \`wp-typia add block\`.
379
382
  \`add variation\` targets an existing block slug from \`scripts/block-config.ts\`.
380
383
  \`add style\` registers a Block Styles option for an existing generated block.
@@ -9,13 +9,12 @@ import { toPascalCase, toTitleCase } from "./string-case.js";
9
9
  import { escapeRegex, findPhpFunctionRange, hasPhpFunctionDefinition, quotePhpString, replacePhpFunctionDefinition, } from "./php-utils.js";
10
10
  import { assertAbilityDoesNotExist, assertValidGeneratedSlug, getWorkspaceBootstrapPath, normalizeBlockSlug, patchFile, quoteTsString, rollbackWorkspaceMutation, snapshotWorkspaceFiles, } from "./cli-add-shared.js";
11
11
  import { REQUIRED_WORKSPACE_ABILITY_COMPATIBILITY, renderScaffoldCompatibilityConfig, resolveScaffoldCompatibilityPolicy, updatePluginHeaderCompatibility, } from "./scaffold-compatibility.js";
12
+ import { DEFAULT_WORDPRESS_ABILITIES_VERSION, DEFAULT_WORDPRESS_CORE_ABILITIES_VERSION, } from "./package-versions.js";
12
13
  const ABILITY_SERVER_GLOB = "/inc/abilities/*.php";
13
14
  const ABILITY_EDITOR_SCRIPT = "build/abilities/index.js";
14
15
  const ABILITY_EDITOR_ASSET = "build/abilities/index.asset.php";
15
16
  const ABILITY_REGISTRY_END_MARKER = "// wp-typia add ability entries end";
16
17
  const ABILITY_REGISTRY_START_MARKER = "// wp-typia add ability entries start";
17
- const WP_ABILITIES_PACKAGE_VERSION = "^0.10.0";
18
- const WP_CORE_ABILITIES_PACKAGE_VERSION = "^0.9.0";
19
18
  const WP_ABILITIES_SCRIPT_MODULE_ID = "@wordpress/abilities";
20
19
  const WP_CORE_ABILITIES_SCRIPT_MODULE_ID = "@wordpress/core-abilities";
21
20
  function resolveManagedDependencyVersion(existingVersion, requiredVersion) {
@@ -654,8 +653,8 @@ async function ensureAbilityPackageScripts(workspace) {
654
653
  };
655
654
  const nextDependencies = {
656
655
  ...(packageJson.dependencies ?? {}),
657
- [WP_ABILITIES_SCRIPT_MODULE_ID]: resolveManagedDependencyVersion(packageJson.dependencies?.[WP_ABILITIES_SCRIPT_MODULE_ID], WP_ABILITIES_PACKAGE_VERSION),
658
- [WP_CORE_ABILITIES_SCRIPT_MODULE_ID]: resolveManagedDependencyVersion(packageJson.dependencies?.[WP_CORE_ABILITIES_SCRIPT_MODULE_ID], WP_CORE_ABILITIES_PACKAGE_VERSION),
656
+ [WP_ABILITIES_SCRIPT_MODULE_ID]: resolveManagedDependencyVersion(packageJson.dependencies?.[WP_ABILITIES_SCRIPT_MODULE_ID], DEFAULT_WORDPRESS_ABILITIES_VERSION),
657
+ [WP_CORE_ABILITIES_SCRIPT_MODULE_ID]: resolveManagedDependencyVersion(packageJson.dependencies?.[WP_CORE_ABILITIES_SCRIPT_MODULE_ID], DEFAULT_WORDPRESS_CORE_ABILITIES_VERSION),
659
658
  };
660
659
  if (JSON.stringify(nextScripts) === JSON.stringify(packageJson.scripts ?? {}) &&
661
660
  JSON.stringify(nextDependencies) === JSON.stringify(packageJson.dependencies ?? {})) {
@@ -0,0 +1,9 @@
1
+ import type { WorkspaceProject } from './workspace-project.js';
2
+ import { type AdminViewCoreDataSource, type AdminViewRestResource, type AdminViewSource } from './cli-add-workspace-admin-view-types.js';
3
+ export declare function scaffoldAdminViewWorkspace(options: {
4
+ adminViewSlug: string;
5
+ coreDataSource?: AdminViewCoreDataSource;
6
+ parsedSource?: AdminViewSource;
7
+ restResource?: AdminViewRestResource;
8
+ workspace: WorkspaceProject;
9
+ }): Promise<void>;