@digital-gravy/etch-public-api 0.7.1 → 0.7.3

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 (3) hide show
  1. package/dist/index.d.cts +290 -202
  2. package/dist/index.d.ts +290 -202
  3. package/package.json +1 -1
package/dist/index.d.cts CHANGED
@@ -1,6 +1,208 @@
1
+ /**
2
+ * Loop definitions, WordPress query argument shapes, and the `etch.loops` API
3
+ * surface.
4
+ */
5
+ /**
6
+ * A loop parameter reference, e.g. `$count`. Resolved to a concrete value
7
+ * before the query runs.
8
+ */
9
+ type LoopParamRef = `$${string}`;
10
+ /**
11
+ * A numeric query value, or a loop-parameter expression that resolves to one:
12
+ * a bare reference (`$count`) or a reference with a numeric fallback
13
+ * (`$count ?? 10`). Plain numeric strings (e.g. `"10"`) are not accepted —
14
+ * pass the number itself.
15
+ */
16
+ type NumericParam = number | LoopParamRef | `$${string} ?? ${number}`;
17
+ /**
18
+ * A boolean query value, or a loop-parameter expression that resolves to one:
19
+ * a bare reference (`$sticky`) or a reference with a boolean fallback
20
+ * (`$sticky ?? false`). WordPress also accepts its integer-boolean convention
21
+ * (`0`/`1`) for these args.
22
+ */
23
+ type BooleanParam = boolean | 0 | 1 | LoopParamRef | `$${string} ?? ${boolean}`;
24
+ /**
25
+ * A `WP_Query` meta-query clause. Extensible — additional keys are allowed.
26
+ * @see https://developer.wordpress.org/reference/classes/wp_query/#custom-field-post-meta-parameters
27
+ */
28
+ interface MetaQueryItem {
29
+ /** The custom field (meta) key to compare. */
30
+ key: string;
31
+ /** The value(s) to compare against. */
32
+ value: string | number | Array<string | number>;
33
+ /** Comparison operator (defaults to `=`). */
34
+ compare?: '=' | '!=' | '>' | '>=' | '<' | '<=' | 'LIKE' | 'NOT LIKE' | 'IN' | 'NOT IN' | 'BETWEEN' | 'NOT BETWEEN' | 'EXISTS' | 'NOT EXISTS';
35
+ /** SQL type the value is cast to before comparison. */
36
+ type?: 'NUMERIC' | 'BINARY' | 'CHAR' | 'DATE' | 'DATETIME' | 'DECIMAL' | 'SIGNED' | 'TIME' | 'UNSIGNED';
37
+ [key: string]: unknown;
38
+ }
39
+ /**
40
+ * A `WP_Query` taxonomy-query clause. Extensible — additional keys are allowed.
41
+ * @see https://developer.wordpress.org/reference/classes/wp_query/#taxonomy-parameters
42
+ */
43
+ interface TaxQueryItem {
44
+ /** The taxonomy to query (e.g. `category`, `post_tag`). */
45
+ taxonomy: string;
46
+ /** Which term field `terms` refers to. */
47
+ field: 'term_id' | 'slug' | 'name';
48
+ /** The term(s) to match. */
49
+ terms: string | number | Array<string | number>;
50
+ /** How to match the terms (defaults to `IN`). */
51
+ operator?: 'IN' | 'NOT IN' | 'AND';
52
+ /** Whether to include child terms of a hierarchical taxonomy. */
53
+ include_children?: boolean;
54
+ [key: string]: unknown;
55
+ }
56
+ /**
57
+ * WordPress query arguments. Values may be static or a loop parameter
58
+ * expression (`"$param"` or `"$param ?? fallback"`). Extensible — any
59
+ * additional `WP_Query` argument is allowed.
60
+ */
61
+ interface WpQueryArgs {
62
+ /** Post type(s) to query. */
63
+ post_type?: string | string[];
64
+ /** Number of posts per page (`-1` for all). */
65
+ posts_per_page?: NumericParam;
66
+ /** Number of posts to skip. */
67
+ offset?: NumericParam;
68
+ /** Page of results to return. */
69
+ paged?: NumericParam;
70
+ /** Alias of `paged` used in some contexts. */
71
+ page?: NumericParam;
72
+ /** Field to order results by. */
73
+ orderby?: 'date' | 'title' | 'menu_order' | 'rand' | 'ID' | 'author' | 'name' | 'modified' | 'parent' | 'comment_count' | (string & {});
74
+ /** Sort direction. */
75
+ order?: 'ASC' | 'DESC' | (string & {});
76
+ /** Post status to include. */
77
+ post_status?: 'publish' | 'pending' | 'draft' | 'auto-draft' | 'future' | 'private' | 'inherit' | 'trash' | (string & {});
78
+ /** Whether to ignore sticky posts. */
79
+ ignore_sticky_posts?: BooleanParam;
80
+ /** Author id (number) or username (string). */
81
+ author?: number | string;
82
+ /** Author by `user_nicename`. */
83
+ author_name?: string;
84
+ /** Category id (number) or slug (string). */
85
+ category?: number | string;
86
+ /** Category by slug. */
87
+ category_name?: string;
88
+ /** Tag slug. */
89
+ tag?: string;
90
+ /** Taxonomy query clauses. */
91
+ tax_query?: TaxQueryItem[];
92
+ /** Meta (custom field) query clauses. */
93
+ meta_query?: MetaQueryItem[];
94
+ /** Search keyword. */
95
+ s?: string;
96
+ [key: string]: unknown;
97
+ }
98
+ /** WordPress taxonomy-term query arguments (extensible). */
99
+ interface WpTermsArgs {
100
+ /** Taxonomy to fetch terms from. */
101
+ taxonomy?: string;
102
+ /** Field to order terms by. */
103
+ orderby?: 'name' | 'slug' | 'term_group' | 'term_id' | 'description' | 'count' | (string & {});
104
+ /** Sort direction. */
105
+ order?: 'ASC' | 'DESC' | (string & {});
106
+ [key: string]: unknown;
107
+ }
108
+ /** WordPress user query arguments (extensible). */
109
+ interface WpUsersArgs {
110
+ /** Role(s) users must have. */
111
+ role?: string | string[];
112
+ /** User ids to include. */
113
+ include?: number[] | string;
114
+ /** User ids to exclude. */
115
+ exclude?: number[] | string;
116
+ /** Search keyword. */
117
+ search?: string;
118
+ /** Columns the `search` keyword is matched against. */
119
+ search_columns?: string[] | string;
120
+ /** Field to order users by. */
121
+ orderby?: 'ID' | 'display_name' | 'name' | 'user_login' | 'user_email' | 'user_registered' | 'post_count' | 'meta_value' | 'meta_value_num' | (string & {});
122
+ /** Sort direction. */
123
+ order?: 'ASC' | 'DESC' | (string & {});
124
+ /** Number of users to return. */
125
+ number?: NumericParam;
126
+ /** Number of users to skip. */
127
+ offset?: NumericParam;
128
+ /** Page of results to return. */
129
+ paged?: NumericParam;
130
+ [key: string]: unknown;
131
+ }
132
+ /** Type-specific configuration of an {@link EtchLoop}, discriminated by `type`. */
133
+ type EtchLoopConfig = {
134
+ type: 'wp-query';
135
+ args: WpQueryArgs;
136
+ } | {
137
+ type: 'wp-terms';
138
+ args: WpTermsArgs;
139
+ } | {
140
+ type: 'wp-users';
141
+ args: WpUsersArgs;
142
+ } | {
143
+ type: 'main-query';
144
+ args: WpQueryArgs;
145
+ } | {
146
+ type: 'json';
147
+ data: unknown[];
148
+ };
149
+ /** A loop definition (extensible). */
150
+ interface EtchLoop {
151
+ /** Stable, human-authored key used to reference the loop. */
152
+ key: string;
153
+ /** Display name shown in the loop manager. */
154
+ name: string;
155
+ /** Whether the loop is global (reusable across pages) or local to a document. */
156
+ global: boolean;
157
+ /** The loop's data source and arguments. */
158
+ config: EtchLoopConfig;
159
+ [key: string]: unknown;
160
+ }
161
+ /** All loops keyed by id. */
162
+ type EtchLoopObj = Record<string, EtchLoop>;
163
+ /** Partial loop binding applied to an `etch/loop` block by `loops.setForBlock()`. */
164
+ interface BlockLoopBinding {
165
+ /** Id of the loop to bind. */
166
+ loopId?: string;
167
+ /** What the block iterates over (e.g. the loop's items). */
168
+ target?: string;
169
+ /** Variable name bound to the current item inside the loop. */
170
+ itemId?: string;
171
+ /** Variable name bound to the current index inside the loop. */
172
+ indexId?: string;
173
+ /**
174
+ * Values for the loop's parameters. Every key must be a `$`-prefixed
175
+ * parameter reference (e.g. `$count`), matching the `$param` expressions
176
+ * used in the loop's query args.
177
+ */
178
+ loopParams?: Record<LoopParamRef, unknown>;
179
+ }
180
+ /** Loop definitions and binding loops to blocks. */
181
+ interface EtchLoopsApi {
182
+ /** All loops keyed by id. */
183
+ getAll(): EtchLoopObj;
184
+ /** Add a new loop; returns its generated id. */
185
+ add(loop: EtchLoop): string;
186
+ /** Replace an existing loop's definition. */
187
+ update(loopId: string, loop: EtchLoop): void;
188
+ /** Delete a loop by id. */
189
+ delete(loopId: string): void;
190
+ /**
191
+ * Fuzzy-search loops by `name` or `key`, ranked best-first. Each hit is the
192
+ * loop plus its `id` (the value `setForBlock`/`update`/`delete` expect).
193
+ * Returns an empty array for a blank query or when nothing matches.
194
+ */
195
+ findLoop(query: string): (EtchLoop & {
196
+ id: string;
197
+ })[];
198
+ /** Bind (or update the binding of) a loop on an `etch/loop` block. */
199
+ setForBlock(blockId: string, loop: BlockLoopBinding): void;
200
+ }
201
+
1
202
  /**
2
203
  * Block JSON shapes (read and write) and the `etch.blocks` API surface.
3
204
  */
205
+
4
206
  /** A block type identifier, always namespaced under `etch/` (e.g. `etch/text`). */
5
207
  type EtchBlockType = `etch/${string}`;
6
208
  /** Editor-facing metadata stored on every block. */
@@ -144,8 +346,11 @@ interface EtchLoopBlockJson extends EtchBlockCommon {
144
346
  indexId?: string;
145
347
  /** Id of a registered loop definition this block is bound to. */
146
348
  loopId?: string;
147
- /** Values for the bound loop's parameters. */
148
- loopParams?: Record<string, unknown>;
349
+ /**
350
+ * Values for the bound loop's parameters. Every key must be a `$`-prefixed
351
+ * parameter reference (e.g. `$count`).
352
+ */
353
+ loopParams?: Record<LoopParamRef, unknown>;
149
354
  }
150
355
  /** A conditional block (`etch/condition`); renders its children when the expression holds. */
151
356
  interface EtchConditionBlockJson extends EtchBlockCommon {
@@ -265,6 +470,50 @@ interface BlockPatch {
265
470
  /** Replace the text content. Only valid on text blocks. */
266
471
  text?: string;
267
472
  }
473
+ /**
474
+ * A portable, JSON-serializable snapshot of a block subtree produced by
475
+ * {@link EtchBlocksApi.copy} and consumed by {@link EtchBlocksApi.pasteAsync}.
476
+ *
477
+ * Treat it as an **opaque token**: store it, send it over the wire, or hand it
478
+ * straight back to `pasteAsync()`. The fields below are documented so you can
479
+ * inspect a payload, but the bundled `styles` / `loops` / `components` /
480
+ * `customMediaDefinitions` are Etch-internal definitions that `pasteAsync()`
481
+ * re-creates and re-maps to fresh ids — don't depend on their internal shape or
482
+ * mutate them.
483
+ *
484
+ * Unlike the builder's Cmd-C / Cmd-V shortcuts, `copy()` / `pasteAsync()` never
485
+ * touch the system clipboard, so they work for fully programmatic flows (no
486
+ * user gesture or clipboard permission required).
487
+ */
488
+ interface CopyObject {
489
+ /** Payload kind. Currently always `"block"`. */
490
+ type: 'block';
491
+ /**
492
+ * Payload schema version, derived from the features the copied block uses.
493
+ * `paste()` migrates older payloads forward, so pass it back unchanged.
494
+ */
495
+ version: number;
496
+ /** The copied block subtree in Gutenberg block grammar. */
497
+ gutenbergBlock: GutenbergBlock;
498
+ /** Global styles referenced by the block, keyed by style id (opaque). */
499
+ styles?: {
500
+ [styleId: string]: unknown;
501
+ };
502
+ /** Loop definitions referenced by the block, keyed by loop id (opaque). */
503
+ loops?: {
504
+ [loopId: string]: unknown;
505
+ };
506
+ /** Component definitions referenced by the block, keyed by component id (opaque). */
507
+ components?: {
508
+ [componentId: number]: unknown;
509
+ };
510
+ /** `@custom-media` definitions referenced by the block's styles (opaque). */
511
+ customMediaDefinitions?: {
512
+ [name: string]: unknown;
513
+ };
514
+ /** ISO 8601 timestamp of when the copy was produced. */
515
+ timestamp?: string;
516
+ }
268
517
  /** Block selection, reading, structure and property edits. */
269
518
  interface EtchBlocksApi {
270
519
  /** Select a block in the canvas by id. */
@@ -281,9 +530,13 @@ interface EtchBlocksApi {
281
530
  find(predicate: FindBlocksPredicate): string[];
282
531
  /**
283
532
  * Build a block from JSON and insert it; returns the new block id.
284
- * `parentId` defaults to the document root, `index` to the end of the parent.
533
+ * `parentId` defaults to the document root (`null` is treated the same as
534
+ * omitting it, matching {@link move}), `index` to the end of the parent.
535
+ *
536
+ * Throws `WRONG_BLOCK_TYPE` when `parentId` names a block that cannot contain
537
+ * the new block (e.g. a text or void element).
285
538
  */
286
- create(json: EtchBlockJson, parentId?: string, index?: number): string;
539
+ create(json: EtchBlockJson, parentId?: string | null, index?: number): string;
287
540
  /** Remove a block and its entire subtree. */
288
541
  delete(blockId: string): void;
289
542
  /** Deep-copy a block next to the original; returns the new block's id. */
@@ -291,12 +544,44 @@ interface EtchBlocksApi {
291
544
  /**
292
545
  * Re-parent a block. `newParentId` of `null` moves it to the document root;
293
546
  * `index` defaults to the end of the new parent.
547
+ *
548
+ * Throws `WRONG_BLOCK_TYPE` when `newParentId` cannot contain the block; the
549
+ * block is left in its original position.
294
550
  */
295
551
  move(blockId: string, newParentId: string | null, index?: number): void;
296
552
  /** Replace a block with a new one built from JSON; returns the new block id. */
297
553
  replace(blockId: string, json: EtchBlockJson): string;
298
554
  /** Patch a block's common editable properties in place (keeps id/children). */
299
555
  update(blockId: string, patch: BlockPatch): void;
556
+ /**
557
+ * Serialize a block and its subtree — along with the global styles, loops and
558
+ * components it references — into a portable {@link CopyObject}. The result is
559
+ * plain JSON: hold it, persist it, or pass it to {@link pasteAsync}. Unlike the
560
+ * Cmd-C shortcut this does **not** write to the system clipboard. Throws
561
+ * `BLOCK_NOT_FOUND` for an unknown id.
562
+ */
563
+ copy(blockId: string): CopyObject;
564
+ /**
565
+ * Insert a block previously produced by {@link copy}. Any styles, loops and
566
+ * components it carries are re-created and re-mapped to fresh ids. Resolves to
567
+ * the id of the newly inserted block. Throws `INVALID_ARGUMENT` for a
568
+ * malformed payload and `BLOCK_NOT_FOUND` for an unknown `targetId`.
569
+ *
570
+ * Placement (mirrors {@link create}):
571
+ * - **No `targetId`** (omitted or `null`) — appended to the document root, or
572
+ * inserted there at `index` when given.
573
+ * - **`targetId` + `index`** — inserted as a child of the target at `index`.
574
+ * Throws `WRONG_BLOCK_TYPE` when the target cannot contain the block: an
575
+ * explicit `index` is a deliberate "place it here as a child" request, so
576
+ * an impossible target is an error rather than a silent miss.
577
+ * - **`targetId`, no `index`** — inserted into the target when it accepts
578
+ * children, otherwise immediately after it (handy for "paste near this
579
+ * block").
580
+ *
581
+ * `index` is clamped to the valid range; a negative `index` counts from the
582
+ * end (`-1` appends).
583
+ */
584
+ pasteAsync(payload: CopyObject, targetId?: string | null, index?: number): Promise<string>;
300
585
  /** Set the text content of a text block. */
301
586
  setText(blockId: string, text: string): void;
302
587
  /** Rename a block (sets its label / display name). */
@@ -357,203 +642,6 @@ interface EtchBlocksApi {
357
642
  saveComponentEditModeAsync(): Promise<void>;
358
643
  }
359
644
 
360
- /**
361
- * Loop definitions, WordPress query argument shapes, and the `etch.loops` API
362
- * surface.
363
- */
364
- /**
365
- * A loop parameter reference, e.g. `$count`. Resolved to a concrete value
366
- * before the query runs.
367
- */
368
- type LoopParamRef = `$${string}`;
369
- /**
370
- * A numeric query value, or a loop-parameter expression that resolves to one:
371
- * a bare reference (`$count`) or a reference with a numeric fallback
372
- * (`$count ?? 10`). Plain numeric strings (e.g. `"10"`) are not accepted —
373
- * pass the number itself.
374
- */
375
- type NumericParam = number | LoopParamRef | `$${string} ?? ${number}`;
376
- /**
377
- * A boolean query value, or a loop-parameter expression that resolves to one:
378
- * a bare reference (`$sticky`) or a reference with a boolean fallback
379
- * (`$sticky ?? false`). WordPress also accepts its integer-boolean convention
380
- * (`0`/`1`) for these args.
381
- */
382
- type BooleanParam = boolean | 0 | 1 | LoopParamRef | `$${string} ?? ${boolean}`;
383
- /**
384
- * A `WP_Query` meta-query clause. Extensible — additional keys are allowed.
385
- * @see https://developer.wordpress.org/reference/classes/wp_query/#custom-field-post-meta-parameters
386
- */
387
- interface MetaQueryItem {
388
- /** The custom field (meta) key to compare. */
389
- key: string;
390
- /** The value(s) to compare against. */
391
- value: string | number | Array<string | number>;
392
- /** Comparison operator (defaults to `=`). */
393
- compare?: '=' | '!=' | '>' | '>=' | '<' | '<=' | 'LIKE' | 'NOT LIKE' | 'IN' | 'NOT IN' | 'BETWEEN' | 'NOT BETWEEN' | 'EXISTS' | 'NOT EXISTS';
394
- /** SQL type the value is cast to before comparison. */
395
- type?: 'NUMERIC' | 'BINARY' | 'CHAR' | 'DATE' | 'DATETIME' | 'DECIMAL' | 'SIGNED' | 'TIME' | 'UNSIGNED';
396
- [key: string]: unknown;
397
- }
398
- /**
399
- * A `WP_Query` taxonomy-query clause. Extensible — additional keys are allowed.
400
- * @see https://developer.wordpress.org/reference/classes/wp_query/#taxonomy-parameters
401
- */
402
- interface TaxQueryItem {
403
- /** The taxonomy to query (e.g. `category`, `post_tag`). */
404
- taxonomy: string;
405
- /** Which term field `terms` refers to. */
406
- field: 'term_id' | 'slug' | 'name';
407
- /** The term(s) to match. */
408
- terms: string | number | Array<string | number>;
409
- /** How to match the terms (defaults to `IN`). */
410
- operator?: 'IN' | 'NOT IN' | 'AND';
411
- /** Whether to include child terms of a hierarchical taxonomy. */
412
- include_children?: boolean;
413
- [key: string]: unknown;
414
- }
415
- /**
416
- * WordPress query arguments. Values may be static or a loop parameter
417
- * expression (`"$param"` or `"$param ?? fallback"`). Extensible — any
418
- * additional `WP_Query` argument is allowed.
419
- */
420
- interface WpQueryArgs {
421
- /** Post type(s) to query. */
422
- post_type?: string | string[];
423
- /** Number of posts per page (`-1` for all). */
424
- posts_per_page?: NumericParam;
425
- /** Number of posts to skip. */
426
- offset?: NumericParam;
427
- /** Page of results to return. */
428
- paged?: NumericParam;
429
- /** Alias of `paged` used in some contexts. */
430
- page?: NumericParam;
431
- /** Field to order results by. */
432
- orderby?: 'date' | 'title' | 'menu_order' | 'rand' | 'ID' | 'author' | 'name' | 'modified' | 'parent' | 'comment_count' | (string & {});
433
- /** Sort direction. */
434
- order?: 'ASC' | 'DESC' | (string & {});
435
- /** Post status to include. */
436
- post_status?: 'publish' | 'pending' | 'draft' | 'auto-draft' | 'future' | 'private' | 'inherit' | 'trash' | (string & {});
437
- /** Whether to ignore sticky posts. */
438
- ignore_sticky_posts?: BooleanParam;
439
- /** Author id (number) or username (string). */
440
- author?: number | string;
441
- /** Author by `user_nicename`. */
442
- author_name?: string;
443
- /** Category id (number) or slug (string). */
444
- category?: number | string;
445
- /** Category by slug. */
446
- category_name?: string;
447
- /** Tag slug. */
448
- tag?: string;
449
- /** Taxonomy query clauses. */
450
- tax_query?: TaxQueryItem[];
451
- /** Meta (custom field) query clauses. */
452
- meta_query?: MetaQueryItem[];
453
- /** Search keyword. */
454
- s?: string;
455
- [key: string]: unknown;
456
- }
457
- /** WordPress taxonomy-term query arguments (extensible). */
458
- interface WpTermsArgs {
459
- /** Taxonomy to fetch terms from. */
460
- taxonomy?: string;
461
- /** Field to order terms by. */
462
- orderby?: 'name' | 'slug' | 'term_group' | 'term_id' | 'description' | 'count' | (string & {});
463
- /** Sort direction. */
464
- order?: 'ASC' | 'DESC' | (string & {});
465
- [key: string]: unknown;
466
- }
467
- /** WordPress user query arguments (extensible). */
468
- interface WpUsersArgs {
469
- /** Role(s) users must have. */
470
- role?: string | string[];
471
- /** User ids to include. */
472
- include?: number[] | string;
473
- /** User ids to exclude. */
474
- exclude?: number[] | string;
475
- /** Search keyword. */
476
- search?: string;
477
- /** Columns the `search` keyword is matched against. */
478
- search_columns?: string[] | string;
479
- /** Field to order users by. */
480
- orderby?: 'ID' | 'display_name' | 'name' | 'user_login' | 'user_email' | 'user_registered' | 'post_count' | 'meta_value' | 'meta_value_num' | (string & {});
481
- /** Sort direction. */
482
- order?: 'ASC' | 'DESC' | (string & {});
483
- /** Number of users to return. */
484
- number?: NumericParam;
485
- /** Number of users to skip. */
486
- offset?: NumericParam;
487
- /** Page of results to return. */
488
- paged?: NumericParam;
489
- [key: string]: unknown;
490
- }
491
- /** Type-specific configuration of an {@link EtchLoop}, discriminated by `type`. */
492
- type EtchLoopConfig = {
493
- type: 'wp-query';
494
- args: WpQueryArgs;
495
- } | {
496
- type: 'wp-terms';
497
- args: WpTermsArgs;
498
- } | {
499
- type: 'wp-users';
500
- args: WpUsersArgs;
501
- } | {
502
- type: 'main-query';
503
- args: WpQueryArgs;
504
- } | {
505
- type: 'json';
506
- data: unknown[];
507
- };
508
- /** A loop definition (extensible). */
509
- interface EtchLoop {
510
- /** Stable, human-authored key used to reference the loop. */
511
- key: string;
512
- /** Display name shown in the loop manager. */
513
- name: string;
514
- /** Whether the loop is global (reusable across pages) or local to a document. */
515
- global: boolean;
516
- /** The loop's data source and arguments. */
517
- config: EtchLoopConfig;
518
- [key: string]: unknown;
519
- }
520
- /** All loops keyed by id. */
521
- type EtchLoopObj = Record<string, EtchLoop>;
522
- /** Partial loop binding applied to an `etch/loop` block by `loops.setForBlock()`. */
523
- interface BlockLoopBinding {
524
- /** Id of the loop to bind. */
525
- loopId?: string;
526
- /** What the block iterates over (e.g. the loop's items). */
527
- target?: string;
528
- /** Variable name bound to the current item inside the loop. */
529
- itemId?: string;
530
- /** Variable name bound to the current index inside the loop. */
531
- indexId?: string;
532
- /** Values for the loop's parameters (used by `$param` expressions). */
533
- loopParams?: Record<string, unknown>;
534
- }
535
- /** Loop definitions and binding loops to blocks. */
536
- interface EtchLoopsApi {
537
- /** All loops keyed by id. */
538
- getAll(): EtchLoopObj;
539
- /** Add a new loop; returns its generated id. */
540
- add(loop: EtchLoop): string;
541
- /** Replace an existing loop's definition. */
542
- update(loopId: string, loop: EtchLoop): void;
543
- /** Delete a loop by id. */
544
- delete(loopId: string): void;
545
- /**
546
- * Fuzzy-search loops by `name` or `key`, ranked best-first. Each hit is the
547
- * loop plus its `id` (the value `setForBlock`/`update`/`delete` expect).
548
- * Returns an empty array for a blank query or when nothing matches.
549
- */
550
- findLoop(query: string): (EtchLoop & {
551
- id: string;
552
- })[];
553
- /** Bind (or update the binding of) a loop on an `etch/loop` block. */
554
- setForBlock(blockId: string, loop: BlockLoopBinding): void;
555
- }
556
-
557
645
  /**
558
646
  * Global style (CSS rule) shapes and the `etch.styles` API surface.
559
647
  */
@@ -1352,4 +1440,4 @@ declare function isEtchApiError(value: unknown): value is EtchApiError;
1352
1440
  */
1353
1441
  declare const ETCH_API_VERSION = "0.x";
1354
1442
 
1355
- export { type ArrayComponentProperty, type BlockLoopBinding, type BlockPatch, type BooleanComponentProperty, type BooleanParam, type BridgeConnectOptions, type ClassComponentProperty, type ColorScheme, type ComponentPatch, type ComponentProperty, type ComponentPropertyBase, type ConditionComponentProperty, type ConnectOptions, type CustomField, type CustomFieldAssignment, type CustomFieldGroup, type CustomFieldType, ETCH_API_VERSION, type Etch, EtchApiError, type EtchApiErrorCode, type EtchBlockCommon, type EtchBlockContext, type EtchBlockJson, type EtchBlockOptions, type EtchBlockScript, type EtchBlockType, type EtchBlockTypeName, type EtchBlocksApi, type EtchBridgeConnection, type EtchComponentBlockJson, type EtchComponentsApi, type EtchConditionBlockJson, type EtchDynamicElementBlockJson, type EtchDynamicImageBlockJson, type EtchElementBlockJson, type EtchFieldsApi, type EtchHistoryApi, type EtchHtmlAttributes, type EtchLoop, type EtchLoopBlockJson, type EtchLoopConfig, type EtchLoopObj, type EtchLoopsApi, type EtchNavigationApi, type EtchPassthroughBlockJson, type EtchPostContentBlockJson, type EtchRawHtmlBlockJson, type EtchSlotContentBlockJson, type EtchSlotPlaceholderBlockJson, type EtchStylesApi, type EtchStylesheetsApi, type EtchSvgBlockJson, type EtchTextBlockJson, type EtchUiApi, type FindBlocksPredicate, type GroupComponentProperty, type GutenbergBlock, type LoopParamRef, type MetaQueryItem, type NavigationPlace, type NumberComponentProperty, type NumericParam, type ObjectComponentProperty, type PostCustomFieldGroupEntry, type PostCustomFieldValueEntry, type PostCustomFieldValueResponse, type PostCustomFieldValuesResponse, type PostSummary, type PublicBlockJson, type PublicComponentJson, type PublicComponentSummary, type RepeaterComponentProperty, type ResolvedCustomField, type SelectOptionsString, type StringComponentProperty, type StyleListFilter, type StylePatch, type StyleSelectorType, type StyleSummary, type StylesheetInput, type StylesheetPatch, type StylesheetSummary, type StylesheetType, type TaxQueryItem, type TemplateSummary, type WpQueryArgs, type WpTermsArgs, type WpUsersArgs, getEtch, isEtchApiError, isEtchAvailable };
1443
+ export { type ArrayComponentProperty, type BlockLoopBinding, type BlockPatch, type BooleanComponentProperty, type BooleanParam, type BridgeConnectOptions, type ClassComponentProperty, type ColorScheme, type ComponentPatch, type ComponentProperty, type ComponentPropertyBase, type ConditionComponentProperty, type ConnectOptions, type CopyObject, type CustomField, type CustomFieldAssignment, type CustomFieldGroup, type CustomFieldType, ETCH_API_VERSION, type Etch, EtchApiError, type EtchApiErrorCode, type EtchBlockCommon, type EtchBlockContext, type EtchBlockJson, type EtchBlockOptions, type EtchBlockScript, type EtchBlockType, type EtchBlockTypeName, type EtchBlocksApi, type EtchBridgeConnection, type EtchComponentBlockJson, type EtchComponentsApi, type EtchConditionBlockJson, type EtchDynamicElementBlockJson, type EtchDynamicImageBlockJson, type EtchElementBlockJson, type EtchFieldsApi, type EtchHistoryApi, type EtchHtmlAttributes, type EtchLoop, type EtchLoopBlockJson, type EtchLoopConfig, type EtchLoopObj, type EtchLoopsApi, type EtchNavigationApi, type EtchPassthroughBlockJson, type EtchPostContentBlockJson, type EtchRawHtmlBlockJson, type EtchSlotContentBlockJson, type EtchSlotPlaceholderBlockJson, type EtchStylesApi, type EtchStylesheetsApi, type EtchSvgBlockJson, type EtchTextBlockJson, type EtchUiApi, type FindBlocksPredicate, type GroupComponentProperty, type GutenbergBlock, type LoopParamRef, type MetaQueryItem, type NavigationPlace, type NumberComponentProperty, type NumericParam, type ObjectComponentProperty, type PostCustomFieldGroupEntry, type PostCustomFieldValueEntry, type PostCustomFieldValueResponse, type PostCustomFieldValuesResponse, type PostSummary, type PublicBlockJson, type PublicComponentJson, type PublicComponentSummary, type RepeaterComponentProperty, type ResolvedCustomField, type SelectOptionsString, type StringComponentProperty, type StyleListFilter, type StylePatch, type StyleSelectorType, type StyleSummary, type StylesheetInput, type StylesheetPatch, type StylesheetSummary, type StylesheetType, type TaxQueryItem, type TemplateSummary, type WpQueryArgs, type WpTermsArgs, type WpUsersArgs, getEtch, isEtchApiError, isEtchAvailable };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,208 @@
1
+ /**
2
+ * Loop definitions, WordPress query argument shapes, and the `etch.loops` API
3
+ * surface.
4
+ */
5
+ /**
6
+ * A loop parameter reference, e.g. `$count`. Resolved to a concrete value
7
+ * before the query runs.
8
+ */
9
+ type LoopParamRef = `$${string}`;
10
+ /**
11
+ * A numeric query value, or a loop-parameter expression that resolves to one:
12
+ * a bare reference (`$count`) or a reference with a numeric fallback
13
+ * (`$count ?? 10`). Plain numeric strings (e.g. `"10"`) are not accepted —
14
+ * pass the number itself.
15
+ */
16
+ type NumericParam = number | LoopParamRef | `$${string} ?? ${number}`;
17
+ /**
18
+ * A boolean query value, or a loop-parameter expression that resolves to one:
19
+ * a bare reference (`$sticky`) or a reference with a boolean fallback
20
+ * (`$sticky ?? false`). WordPress also accepts its integer-boolean convention
21
+ * (`0`/`1`) for these args.
22
+ */
23
+ type BooleanParam = boolean | 0 | 1 | LoopParamRef | `$${string} ?? ${boolean}`;
24
+ /**
25
+ * A `WP_Query` meta-query clause. Extensible — additional keys are allowed.
26
+ * @see https://developer.wordpress.org/reference/classes/wp_query/#custom-field-post-meta-parameters
27
+ */
28
+ interface MetaQueryItem {
29
+ /** The custom field (meta) key to compare. */
30
+ key: string;
31
+ /** The value(s) to compare against. */
32
+ value: string | number | Array<string | number>;
33
+ /** Comparison operator (defaults to `=`). */
34
+ compare?: '=' | '!=' | '>' | '>=' | '<' | '<=' | 'LIKE' | 'NOT LIKE' | 'IN' | 'NOT IN' | 'BETWEEN' | 'NOT BETWEEN' | 'EXISTS' | 'NOT EXISTS';
35
+ /** SQL type the value is cast to before comparison. */
36
+ type?: 'NUMERIC' | 'BINARY' | 'CHAR' | 'DATE' | 'DATETIME' | 'DECIMAL' | 'SIGNED' | 'TIME' | 'UNSIGNED';
37
+ [key: string]: unknown;
38
+ }
39
+ /**
40
+ * A `WP_Query` taxonomy-query clause. Extensible — additional keys are allowed.
41
+ * @see https://developer.wordpress.org/reference/classes/wp_query/#taxonomy-parameters
42
+ */
43
+ interface TaxQueryItem {
44
+ /** The taxonomy to query (e.g. `category`, `post_tag`). */
45
+ taxonomy: string;
46
+ /** Which term field `terms` refers to. */
47
+ field: 'term_id' | 'slug' | 'name';
48
+ /** The term(s) to match. */
49
+ terms: string | number | Array<string | number>;
50
+ /** How to match the terms (defaults to `IN`). */
51
+ operator?: 'IN' | 'NOT IN' | 'AND';
52
+ /** Whether to include child terms of a hierarchical taxonomy. */
53
+ include_children?: boolean;
54
+ [key: string]: unknown;
55
+ }
56
+ /**
57
+ * WordPress query arguments. Values may be static or a loop parameter
58
+ * expression (`"$param"` or `"$param ?? fallback"`). Extensible — any
59
+ * additional `WP_Query` argument is allowed.
60
+ */
61
+ interface WpQueryArgs {
62
+ /** Post type(s) to query. */
63
+ post_type?: string | string[];
64
+ /** Number of posts per page (`-1` for all). */
65
+ posts_per_page?: NumericParam;
66
+ /** Number of posts to skip. */
67
+ offset?: NumericParam;
68
+ /** Page of results to return. */
69
+ paged?: NumericParam;
70
+ /** Alias of `paged` used in some contexts. */
71
+ page?: NumericParam;
72
+ /** Field to order results by. */
73
+ orderby?: 'date' | 'title' | 'menu_order' | 'rand' | 'ID' | 'author' | 'name' | 'modified' | 'parent' | 'comment_count' | (string & {});
74
+ /** Sort direction. */
75
+ order?: 'ASC' | 'DESC' | (string & {});
76
+ /** Post status to include. */
77
+ post_status?: 'publish' | 'pending' | 'draft' | 'auto-draft' | 'future' | 'private' | 'inherit' | 'trash' | (string & {});
78
+ /** Whether to ignore sticky posts. */
79
+ ignore_sticky_posts?: BooleanParam;
80
+ /** Author id (number) or username (string). */
81
+ author?: number | string;
82
+ /** Author by `user_nicename`. */
83
+ author_name?: string;
84
+ /** Category id (number) or slug (string). */
85
+ category?: number | string;
86
+ /** Category by slug. */
87
+ category_name?: string;
88
+ /** Tag slug. */
89
+ tag?: string;
90
+ /** Taxonomy query clauses. */
91
+ tax_query?: TaxQueryItem[];
92
+ /** Meta (custom field) query clauses. */
93
+ meta_query?: MetaQueryItem[];
94
+ /** Search keyword. */
95
+ s?: string;
96
+ [key: string]: unknown;
97
+ }
98
+ /** WordPress taxonomy-term query arguments (extensible). */
99
+ interface WpTermsArgs {
100
+ /** Taxonomy to fetch terms from. */
101
+ taxonomy?: string;
102
+ /** Field to order terms by. */
103
+ orderby?: 'name' | 'slug' | 'term_group' | 'term_id' | 'description' | 'count' | (string & {});
104
+ /** Sort direction. */
105
+ order?: 'ASC' | 'DESC' | (string & {});
106
+ [key: string]: unknown;
107
+ }
108
+ /** WordPress user query arguments (extensible). */
109
+ interface WpUsersArgs {
110
+ /** Role(s) users must have. */
111
+ role?: string | string[];
112
+ /** User ids to include. */
113
+ include?: number[] | string;
114
+ /** User ids to exclude. */
115
+ exclude?: number[] | string;
116
+ /** Search keyword. */
117
+ search?: string;
118
+ /** Columns the `search` keyword is matched against. */
119
+ search_columns?: string[] | string;
120
+ /** Field to order users by. */
121
+ orderby?: 'ID' | 'display_name' | 'name' | 'user_login' | 'user_email' | 'user_registered' | 'post_count' | 'meta_value' | 'meta_value_num' | (string & {});
122
+ /** Sort direction. */
123
+ order?: 'ASC' | 'DESC' | (string & {});
124
+ /** Number of users to return. */
125
+ number?: NumericParam;
126
+ /** Number of users to skip. */
127
+ offset?: NumericParam;
128
+ /** Page of results to return. */
129
+ paged?: NumericParam;
130
+ [key: string]: unknown;
131
+ }
132
+ /** Type-specific configuration of an {@link EtchLoop}, discriminated by `type`. */
133
+ type EtchLoopConfig = {
134
+ type: 'wp-query';
135
+ args: WpQueryArgs;
136
+ } | {
137
+ type: 'wp-terms';
138
+ args: WpTermsArgs;
139
+ } | {
140
+ type: 'wp-users';
141
+ args: WpUsersArgs;
142
+ } | {
143
+ type: 'main-query';
144
+ args: WpQueryArgs;
145
+ } | {
146
+ type: 'json';
147
+ data: unknown[];
148
+ };
149
+ /** A loop definition (extensible). */
150
+ interface EtchLoop {
151
+ /** Stable, human-authored key used to reference the loop. */
152
+ key: string;
153
+ /** Display name shown in the loop manager. */
154
+ name: string;
155
+ /** Whether the loop is global (reusable across pages) or local to a document. */
156
+ global: boolean;
157
+ /** The loop's data source and arguments. */
158
+ config: EtchLoopConfig;
159
+ [key: string]: unknown;
160
+ }
161
+ /** All loops keyed by id. */
162
+ type EtchLoopObj = Record<string, EtchLoop>;
163
+ /** Partial loop binding applied to an `etch/loop` block by `loops.setForBlock()`. */
164
+ interface BlockLoopBinding {
165
+ /** Id of the loop to bind. */
166
+ loopId?: string;
167
+ /** What the block iterates over (e.g. the loop's items). */
168
+ target?: string;
169
+ /** Variable name bound to the current item inside the loop. */
170
+ itemId?: string;
171
+ /** Variable name bound to the current index inside the loop. */
172
+ indexId?: string;
173
+ /**
174
+ * Values for the loop's parameters. Every key must be a `$`-prefixed
175
+ * parameter reference (e.g. `$count`), matching the `$param` expressions
176
+ * used in the loop's query args.
177
+ */
178
+ loopParams?: Record<LoopParamRef, unknown>;
179
+ }
180
+ /** Loop definitions and binding loops to blocks. */
181
+ interface EtchLoopsApi {
182
+ /** All loops keyed by id. */
183
+ getAll(): EtchLoopObj;
184
+ /** Add a new loop; returns its generated id. */
185
+ add(loop: EtchLoop): string;
186
+ /** Replace an existing loop's definition. */
187
+ update(loopId: string, loop: EtchLoop): void;
188
+ /** Delete a loop by id. */
189
+ delete(loopId: string): void;
190
+ /**
191
+ * Fuzzy-search loops by `name` or `key`, ranked best-first. Each hit is the
192
+ * loop plus its `id` (the value `setForBlock`/`update`/`delete` expect).
193
+ * Returns an empty array for a blank query or when nothing matches.
194
+ */
195
+ findLoop(query: string): (EtchLoop & {
196
+ id: string;
197
+ })[];
198
+ /** Bind (or update the binding of) a loop on an `etch/loop` block. */
199
+ setForBlock(blockId: string, loop: BlockLoopBinding): void;
200
+ }
201
+
1
202
  /**
2
203
  * Block JSON shapes (read and write) and the `etch.blocks` API surface.
3
204
  */
205
+
4
206
  /** A block type identifier, always namespaced under `etch/` (e.g. `etch/text`). */
5
207
  type EtchBlockType = `etch/${string}`;
6
208
  /** Editor-facing metadata stored on every block. */
@@ -144,8 +346,11 @@ interface EtchLoopBlockJson extends EtchBlockCommon {
144
346
  indexId?: string;
145
347
  /** Id of a registered loop definition this block is bound to. */
146
348
  loopId?: string;
147
- /** Values for the bound loop's parameters. */
148
- loopParams?: Record<string, unknown>;
349
+ /**
350
+ * Values for the bound loop's parameters. Every key must be a `$`-prefixed
351
+ * parameter reference (e.g. `$count`).
352
+ */
353
+ loopParams?: Record<LoopParamRef, unknown>;
149
354
  }
150
355
  /** A conditional block (`etch/condition`); renders its children when the expression holds. */
151
356
  interface EtchConditionBlockJson extends EtchBlockCommon {
@@ -265,6 +470,50 @@ interface BlockPatch {
265
470
  /** Replace the text content. Only valid on text blocks. */
266
471
  text?: string;
267
472
  }
473
+ /**
474
+ * A portable, JSON-serializable snapshot of a block subtree produced by
475
+ * {@link EtchBlocksApi.copy} and consumed by {@link EtchBlocksApi.pasteAsync}.
476
+ *
477
+ * Treat it as an **opaque token**: store it, send it over the wire, or hand it
478
+ * straight back to `pasteAsync()`. The fields below are documented so you can
479
+ * inspect a payload, but the bundled `styles` / `loops` / `components` /
480
+ * `customMediaDefinitions` are Etch-internal definitions that `pasteAsync()`
481
+ * re-creates and re-maps to fresh ids — don't depend on their internal shape or
482
+ * mutate them.
483
+ *
484
+ * Unlike the builder's Cmd-C / Cmd-V shortcuts, `copy()` / `pasteAsync()` never
485
+ * touch the system clipboard, so they work for fully programmatic flows (no
486
+ * user gesture or clipboard permission required).
487
+ */
488
+ interface CopyObject {
489
+ /** Payload kind. Currently always `"block"`. */
490
+ type: 'block';
491
+ /**
492
+ * Payload schema version, derived from the features the copied block uses.
493
+ * `paste()` migrates older payloads forward, so pass it back unchanged.
494
+ */
495
+ version: number;
496
+ /** The copied block subtree in Gutenberg block grammar. */
497
+ gutenbergBlock: GutenbergBlock;
498
+ /** Global styles referenced by the block, keyed by style id (opaque). */
499
+ styles?: {
500
+ [styleId: string]: unknown;
501
+ };
502
+ /** Loop definitions referenced by the block, keyed by loop id (opaque). */
503
+ loops?: {
504
+ [loopId: string]: unknown;
505
+ };
506
+ /** Component definitions referenced by the block, keyed by component id (opaque). */
507
+ components?: {
508
+ [componentId: number]: unknown;
509
+ };
510
+ /** `@custom-media` definitions referenced by the block's styles (opaque). */
511
+ customMediaDefinitions?: {
512
+ [name: string]: unknown;
513
+ };
514
+ /** ISO 8601 timestamp of when the copy was produced. */
515
+ timestamp?: string;
516
+ }
268
517
  /** Block selection, reading, structure and property edits. */
269
518
  interface EtchBlocksApi {
270
519
  /** Select a block in the canvas by id. */
@@ -281,9 +530,13 @@ interface EtchBlocksApi {
281
530
  find(predicate: FindBlocksPredicate): string[];
282
531
  /**
283
532
  * Build a block from JSON and insert it; returns the new block id.
284
- * `parentId` defaults to the document root, `index` to the end of the parent.
533
+ * `parentId` defaults to the document root (`null` is treated the same as
534
+ * omitting it, matching {@link move}), `index` to the end of the parent.
535
+ *
536
+ * Throws `WRONG_BLOCK_TYPE` when `parentId` names a block that cannot contain
537
+ * the new block (e.g. a text or void element).
285
538
  */
286
- create(json: EtchBlockJson, parentId?: string, index?: number): string;
539
+ create(json: EtchBlockJson, parentId?: string | null, index?: number): string;
287
540
  /** Remove a block and its entire subtree. */
288
541
  delete(blockId: string): void;
289
542
  /** Deep-copy a block next to the original; returns the new block's id. */
@@ -291,12 +544,44 @@ interface EtchBlocksApi {
291
544
  /**
292
545
  * Re-parent a block. `newParentId` of `null` moves it to the document root;
293
546
  * `index` defaults to the end of the new parent.
547
+ *
548
+ * Throws `WRONG_BLOCK_TYPE` when `newParentId` cannot contain the block; the
549
+ * block is left in its original position.
294
550
  */
295
551
  move(blockId: string, newParentId: string | null, index?: number): void;
296
552
  /** Replace a block with a new one built from JSON; returns the new block id. */
297
553
  replace(blockId: string, json: EtchBlockJson): string;
298
554
  /** Patch a block's common editable properties in place (keeps id/children). */
299
555
  update(blockId: string, patch: BlockPatch): void;
556
+ /**
557
+ * Serialize a block and its subtree — along with the global styles, loops and
558
+ * components it references — into a portable {@link CopyObject}. The result is
559
+ * plain JSON: hold it, persist it, or pass it to {@link pasteAsync}. Unlike the
560
+ * Cmd-C shortcut this does **not** write to the system clipboard. Throws
561
+ * `BLOCK_NOT_FOUND` for an unknown id.
562
+ */
563
+ copy(blockId: string): CopyObject;
564
+ /**
565
+ * Insert a block previously produced by {@link copy}. Any styles, loops and
566
+ * components it carries are re-created and re-mapped to fresh ids. Resolves to
567
+ * the id of the newly inserted block. Throws `INVALID_ARGUMENT` for a
568
+ * malformed payload and `BLOCK_NOT_FOUND` for an unknown `targetId`.
569
+ *
570
+ * Placement (mirrors {@link create}):
571
+ * - **No `targetId`** (omitted or `null`) — appended to the document root, or
572
+ * inserted there at `index` when given.
573
+ * - **`targetId` + `index`** — inserted as a child of the target at `index`.
574
+ * Throws `WRONG_BLOCK_TYPE` when the target cannot contain the block: an
575
+ * explicit `index` is a deliberate "place it here as a child" request, so
576
+ * an impossible target is an error rather than a silent miss.
577
+ * - **`targetId`, no `index`** — inserted into the target when it accepts
578
+ * children, otherwise immediately after it (handy for "paste near this
579
+ * block").
580
+ *
581
+ * `index` is clamped to the valid range; a negative `index` counts from the
582
+ * end (`-1` appends).
583
+ */
584
+ pasteAsync(payload: CopyObject, targetId?: string | null, index?: number): Promise<string>;
300
585
  /** Set the text content of a text block. */
301
586
  setText(blockId: string, text: string): void;
302
587
  /** Rename a block (sets its label / display name). */
@@ -357,203 +642,6 @@ interface EtchBlocksApi {
357
642
  saveComponentEditModeAsync(): Promise<void>;
358
643
  }
359
644
 
360
- /**
361
- * Loop definitions, WordPress query argument shapes, and the `etch.loops` API
362
- * surface.
363
- */
364
- /**
365
- * A loop parameter reference, e.g. `$count`. Resolved to a concrete value
366
- * before the query runs.
367
- */
368
- type LoopParamRef = `$${string}`;
369
- /**
370
- * A numeric query value, or a loop-parameter expression that resolves to one:
371
- * a bare reference (`$count`) or a reference with a numeric fallback
372
- * (`$count ?? 10`). Plain numeric strings (e.g. `"10"`) are not accepted —
373
- * pass the number itself.
374
- */
375
- type NumericParam = number | LoopParamRef | `$${string} ?? ${number}`;
376
- /**
377
- * A boolean query value, or a loop-parameter expression that resolves to one:
378
- * a bare reference (`$sticky`) or a reference with a boolean fallback
379
- * (`$sticky ?? false`). WordPress also accepts its integer-boolean convention
380
- * (`0`/`1`) for these args.
381
- */
382
- type BooleanParam = boolean | 0 | 1 | LoopParamRef | `$${string} ?? ${boolean}`;
383
- /**
384
- * A `WP_Query` meta-query clause. Extensible — additional keys are allowed.
385
- * @see https://developer.wordpress.org/reference/classes/wp_query/#custom-field-post-meta-parameters
386
- */
387
- interface MetaQueryItem {
388
- /** The custom field (meta) key to compare. */
389
- key: string;
390
- /** The value(s) to compare against. */
391
- value: string | number | Array<string | number>;
392
- /** Comparison operator (defaults to `=`). */
393
- compare?: '=' | '!=' | '>' | '>=' | '<' | '<=' | 'LIKE' | 'NOT LIKE' | 'IN' | 'NOT IN' | 'BETWEEN' | 'NOT BETWEEN' | 'EXISTS' | 'NOT EXISTS';
394
- /** SQL type the value is cast to before comparison. */
395
- type?: 'NUMERIC' | 'BINARY' | 'CHAR' | 'DATE' | 'DATETIME' | 'DECIMAL' | 'SIGNED' | 'TIME' | 'UNSIGNED';
396
- [key: string]: unknown;
397
- }
398
- /**
399
- * A `WP_Query` taxonomy-query clause. Extensible — additional keys are allowed.
400
- * @see https://developer.wordpress.org/reference/classes/wp_query/#taxonomy-parameters
401
- */
402
- interface TaxQueryItem {
403
- /** The taxonomy to query (e.g. `category`, `post_tag`). */
404
- taxonomy: string;
405
- /** Which term field `terms` refers to. */
406
- field: 'term_id' | 'slug' | 'name';
407
- /** The term(s) to match. */
408
- terms: string | number | Array<string | number>;
409
- /** How to match the terms (defaults to `IN`). */
410
- operator?: 'IN' | 'NOT IN' | 'AND';
411
- /** Whether to include child terms of a hierarchical taxonomy. */
412
- include_children?: boolean;
413
- [key: string]: unknown;
414
- }
415
- /**
416
- * WordPress query arguments. Values may be static or a loop parameter
417
- * expression (`"$param"` or `"$param ?? fallback"`). Extensible — any
418
- * additional `WP_Query` argument is allowed.
419
- */
420
- interface WpQueryArgs {
421
- /** Post type(s) to query. */
422
- post_type?: string | string[];
423
- /** Number of posts per page (`-1` for all). */
424
- posts_per_page?: NumericParam;
425
- /** Number of posts to skip. */
426
- offset?: NumericParam;
427
- /** Page of results to return. */
428
- paged?: NumericParam;
429
- /** Alias of `paged` used in some contexts. */
430
- page?: NumericParam;
431
- /** Field to order results by. */
432
- orderby?: 'date' | 'title' | 'menu_order' | 'rand' | 'ID' | 'author' | 'name' | 'modified' | 'parent' | 'comment_count' | (string & {});
433
- /** Sort direction. */
434
- order?: 'ASC' | 'DESC' | (string & {});
435
- /** Post status to include. */
436
- post_status?: 'publish' | 'pending' | 'draft' | 'auto-draft' | 'future' | 'private' | 'inherit' | 'trash' | (string & {});
437
- /** Whether to ignore sticky posts. */
438
- ignore_sticky_posts?: BooleanParam;
439
- /** Author id (number) or username (string). */
440
- author?: number | string;
441
- /** Author by `user_nicename`. */
442
- author_name?: string;
443
- /** Category id (number) or slug (string). */
444
- category?: number | string;
445
- /** Category by slug. */
446
- category_name?: string;
447
- /** Tag slug. */
448
- tag?: string;
449
- /** Taxonomy query clauses. */
450
- tax_query?: TaxQueryItem[];
451
- /** Meta (custom field) query clauses. */
452
- meta_query?: MetaQueryItem[];
453
- /** Search keyword. */
454
- s?: string;
455
- [key: string]: unknown;
456
- }
457
- /** WordPress taxonomy-term query arguments (extensible). */
458
- interface WpTermsArgs {
459
- /** Taxonomy to fetch terms from. */
460
- taxonomy?: string;
461
- /** Field to order terms by. */
462
- orderby?: 'name' | 'slug' | 'term_group' | 'term_id' | 'description' | 'count' | (string & {});
463
- /** Sort direction. */
464
- order?: 'ASC' | 'DESC' | (string & {});
465
- [key: string]: unknown;
466
- }
467
- /** WordPress user query arguments (extensible). */
468
- interface WpUsersArgs {
469
- /** Role(s) users must have. */
470
- role?: string | string[];
471
- /** User ids to include. */
472
- include?: number[] | string;
473
- /** User ids to exclude. */
474
- exclude?: number[] | string;
475
- /** Search keyword. */
476
- search?: string;
477
- /** Columns the `search` keyword is matched against. */
478
- search_columns?: string[] | string;
479
- /** Field to order users by. */
480
- orderby?: 'ID' | 'display_name' | 'name' | 'user_login' | 'user_email' | 'user_registered' | 'post_count' | 'meta_value' | 'meta_value_num' | (string & {});
481
- /** Sort direction. */
482
- order?: 'ASC' | 'DESC' | (string & {});
483
- /** Number of users to return. */
484
- number?: NumericParam;
485
- /** Number of users to skip. */
486
- offset?: NumericParam;
487
- /** Page of results to return. */
488
- paged?: NumericParam;
489
- [key: string]: unknown;
490
- }
491
- /** Type-specific configuration of an {@link EtchLoop}, discriminated by `type`. */
492
- type EtchLoopConfig = {
493
- type: 'wp-query';
494
- args: WpQueryArgs;
495
- } | {
496
- type: 'wp-terms';
497
- args: WpTermsArgs;
498
- } | {
499
- type: 'wp-users';
500
- args: WpUsersArgs;
501
- } | {
502
- type: 'main-query';
503
- args: WpQueryArgs;
504
- } | {
505
- type: 'json';
506
- data: unknown[];
507
- };
508
- /** A loop definition (extensible). */
509
- interface EtchLoop {
510
- /** Stable, human-authored key used to reference the loop. */
511
- key: string;
512
- /** Display name shown in the loop manager. */
513
- name: string;
514
- /** Whether the loop is global (reusable across pages) or local to a document. */
515
- global: boolean;
516
- /** The loop's data source and arguments. */
517
- config: EtchLoopConfig;
518
- [key: string]: unknown;
519
- }
520
- /** All loops keyed by id. */
521
- type EtchLoopObj = Record<string, EtchLoop>;
522
- /** Partial loop binding applied to an `etch/loop` block by `loops.setForBlock()`. */
523
- interface BlockLoopBinding {
524
- /** Id of the loop to bind. */
525
- loopId?: string;
526
- /** What the block iterates over (e.g. the loop's items). */
527
- target?: string;
528
- /** Variable name bound to the current item inside the loop. */
529
- itemId?: string;
530
- /** Variable name bound to the current index inside the loop. */
531
- indexId?: string;
532
- /** Values for the loop's parameters (used by `$param` expressions). */
533
- loopParams?: Record<string, unknown>;
534
- }
535
- /** Loop definitions and binding loops to blocks. */
536
- interface EtchLoopsApi {
537
- /** All loops keyed by id. */
538
- getAll(): EtchLoopObj;
539
- /** Add a new loop; returns its generated id. */
540
- add(loop: EtchLoop): string;
541
- /** Replace an existing loop's definition. */
542
- update(loopId: string, loop: EtchLoop): void;
543
- /** Delete a loop by id. */
544
- delete(loopId: string): void;
545
- /**
546
- * Fuzzy-search loops by `name` or `key`, ranked best-first. Each hit is the
547
- * loop plus its `id` (the value `setForBlock`/`update`/`delete` expect).
548
- * Returns an empty array for a blank query or when nothing matches.
549
- */
550
- findLoop(query: string): (EtchLoop & {
551
- id: string;
552
- })[];
553
- /** Bind (or update the binding of) a loop on an `etch/loop` block. */
554
- setForBlock(blockId: string, loop: BlockLoopBinding): void;
555
- }
556
-
557
645
  /**
558
646
  * Global style (CSS rule) shapes and the `etch.styles` API surface.
559
647
  */
@@ -1352,4 +1440,4 @@ declare function isEtchApiError(value: unknown): value is EtchApiError;
1352
1440
  */
1353
1441
  declare const ETCH_API_VERSION = "0.x";
1354
1442
 
1355
- export { type ArrayComponentProperty, type BlockLoopBinding, type BlockPatch, type BooleanComponentProperty, type BooleanParam, type BridgeConnectOptions, type ClassComponentProperty, type ColorScheme, type ComponentPatch, type ComponentProperty, type ComponentPropertyBase, type ConditionComponentProperty, type ConnectOptions, type CustomField, type CustomFieldAssignment, type CustomFieldGroup, type CustomFieldType, ETCH_API_VERSION, type Etch, EtchApiError, type EtchApiErrorCode, type EtchBlockCommon, type EtchBlockContext, type EtchBlockJson, type EtchBlockOptions, type EtchBlockScript, type EtchBlockType, type EtchBlockTypeName, type EtchBlocksApi, type EtchBridgeConnection, type EtchComponentBlockJson, type EtchComponentsApi, type EtchConditionBlockJson, type EtchDynamicElementBlockJson, type EtchDynamicImageBlockJson, type EtchElementBlockJson, type EtchFieldsApi, type EtchHistoryApi, type EtchHtmlAttributes, type EtchLoop, type EtchLoopBlockJson, type EtchLoopConfig, type EtchLoopObj, type EtchLoopsApi, type EtchNavigationApi, type EtchPassthroughBlockJson, type EtchPostContentBlockJson, type EtchRawHtmlBlockJson, type EtchSlotContentBlockJson, type EtchSlotPlaceholderBlockJson, type EtchStylesApi, type EtchStylesheetsApi, type EtchSvgBlockJson, type EtchTextBlockJson, type EtchUiApi, type FindBlocksPredicate, type GroupComponentProperty, type GutenbergBlock, type LoopParamRef, type MetaQueryItem, type NavigationPlace, type NumberComponentProperty, type NumericParam, type ObjectComponentProperty, type PostCustomFieldGroupEntry, type PostCustomFieldValueEntry, type PostCustomFieldValueResponse, type PostCustomFieldValuesResponse, type PostSummary, type PublicBlockJson, type PublicComponentJson, type PublicComponentSummary, type RepeaterComponentProperty, type ResolvedCustomField, type SelectOptionsString, type StringComponentProperty, type StyleListFilter, type StylePatch, type StyleSelectorType, type StyleSummary, type StylesheetInput, type StylesheetPatch, type StylesheetSummary, type StylesheetType, type TaxQueryItem, type TemplateSummary, type WpQueryArgs, type WpTermsArgs, type WpUsersArgs, getEtch, isEtchApiError, isEtchAvailable };
1443
+ export { type ArrayComponentProperty, type BlockLoopBinding, type BlockPatch, type BooleanComponentProperty, type BooleanParam, type BridgeConnectOptions, type ClassComponentProperty, type ColorScheme, type ComponentPatch, type ComponentProperty, type ComponentPropertyBase, type ConditionComponentProperty, type ConnectOptions, type CopyObject, type CustomField, type CustomFieldAssignment, type CustomFieldGroup, type CustomFieldType, ETCH_API_VERSION, type Etch, EtchApiError, type EtchApiErrorCode, type EtchBlockCommon, type EtchBlockContext, type EtchBlockJson, type EtchBlockOptions, type EtchBlockScript, type EtchBlockType, type EtchBlockTypeName, type EtchBlocksApi, type EtchBridgeConnection, type EtchComponentBlockJson, type EtchComponentsApi, type EtchConditionBlockJson, type EtchDynamicElementBlockJson, type EtchDynamicImageBlockJson, type EtchElementBlockJson, type EtchFieldsApi, type EtchHistoryApi, type EtchHtmlAttributes, type EtchLoop, type EtchLoopBlockJson, type EtchLoopConfig, type EtchLoopObj, type EtchLoopsApi, type EtchNavigationApi, type EtchPassthroughBlockJson, type EtchPostContentBlockJson, type EtchRawHtmlBlockJson, type EtchSlotContentBlockJson, type EtchSlotPlaceholderBlockJson, type EtchStylesApi, type EtchStylesheetsApi, type EtchSvgBlockJson, type EtchTextBlockJson, type EtchUiApi, type FindBlocksPredicate, type GroupComponentProperty, type GutenbergBlock, type LoopParamRef, type MetaQueryItem, type NavigationPlace, type NumberComponentProperty, type NumericParam, type ObjectComponentProperty, type PostCustomFieldGroupEntry, type PostCustomFieldValueEntry, type PostCustomFieldValueResponse, type PostCustomFieldValuesResponse, type PostSummary, type PublicBlockJson, type PublicComponentJson, type PublicComponentSummary, type RepeaterComponentProperty, type ResolvedCustomField, type SelectOptionsString, type StringComponentProperty, type StyleListFilter, type StylePatch, type StyleSelectorType, type StyleSummary, type StylesheetInput, type StylesheetPatch, type StylesheetSummary, type StylesheetType, type TaxQueryItem, type TemplateSummary, type WpQueryArgs, type WpTermsArgs, type WpUsersArgs, getEtch, isEtchApiError, isEtchAvailable };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digital-gravy/etch-public-api",
3
- "version": "0.7.1",
3
+ "version": "0.7.3",
4
4
  "description": "MIT-licensed typed client and contract for the Etch builder scripting API (window.etch). Etch itself is a separate proprietary product governed by its own commercial terms.",
5
5
  "license": "MIT",
6
6
  "repository": {