@digital-gravy/etch-public-api 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +110 -0
- package/dist/index.cjs +61 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +884 -0
- package/dist/index.d.ts +884 -0
- package/dist/index.js +55 -0
- package/dist/index.js.map +1 -0
- package/package.json +43 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,884 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The public, dependency-free contract for the Etch builder scripting API.
|
|
3
|
+
*
|
|
4
|
+
* Every type here is self-contained (no imports from the Etch source), so this
|
|
5
|
+
* file can ship as the published `.d.ts` and be the single artifact that is
|
|
6
|
+
* versioned deliberately. It mirrors the runtime exposed on `window.etch`.
|
|
7
|
+
*
|
|
8
|
+
* Method signatures take/return plain serializable values (block ids and JSON),
|
|
9
|
+
* never internal reactive class instances. Loose internal shapes (block JSON,
|
|
10
|
+
* loop query args, custom-field definitions) are modelled as **extensible**
|
|
11
|
+
* objects with an index signature, matching the runtime's permissive parsing.
|
|
12
|
+
*
|
|
13
|
+
* Several string fields use the `'literal' | (string & {})` idiom: the known
|
|
14
|
+
* values appear in autocomplete while any other string is still accepted (for
|
|
15
|
+
* loop parameter expressions, plugin-added values, etc.).
|
|
16
|
+
*/
|
|
17
|
+
/** A block type identifier, always namespaced under `etch/` (e.g. `etch/text`). */
|
|
18
|
+
type EtchBlockType = `etch/${string}`;
|
|
19
|
+
/** Editor-facing metadata stored on every block. */
|
|
20
|
+
interface EtchBlockContext {
|
|
21
|
+
/** The block's display label in the structure panel. */
|
|
22
|
+
name?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Whether the block is expanded or collapsed in the builder's structure
|
|
25
|
+
* panel. This is editor UI state, not document data — most scripts can
|
|
26
|
+
* ignore it.
|
|
27
|
+
*/
|
|
28
|
+
structureState?: "open" | "closed";
|
|
29
|
+
/** Whether the block is hidden (not rendered) on the canvas. */
|
|
30
|
+
hidden?: boolean;
|
|
31
|
+
}
|
|
32
|
+
/** Inline script attached to a block. */
|
|
33
|
+
interface EtchBlockScript {
|
|
34
|
+
/** The JavaScript source associated with the block. */
|
|
35
|
+
code: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Block-type-specific options. The set of keys depends on the block type (e.g.
|
|
39
|
+
* a video block carries `youtubeUrl`, an image block `srcUrl`), so this is an
|
|
40
|
+
* open bag rather than a fixed shape.
|
|
41
|
+
*/
|
|
42
|
+
interface EtchBlockOptions {
|
|
43
|
+
[key: string]: unknown;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* A block as plain, structured-clone-safe JSON — the shape accepted by
|
|
47
|
+
* `blocks.create()` / `blocks.replace()`. Concrete block types add their own
|
|
48
|
+
* fields, so the shape is intentionally extensible.
|
|
49
|
+
*/
|
|
50
|
+
interface EtchBlockJson {
|
|
51
|
+
/** The block type, e.g. `etch/text` or `etch/div`. */
|
|
52
|
+
type: EtchBlockType;
|
|
53
|
+
/** Schema version of this block type. */
|
|
54
|
+
version: number;
|
|
55
|
+
/** Editor-facing metadata (label, hidden, structure state). */
|
|
56
|
+
context: EtchBlockContext;
|
|
57
|
+
/** Optional inline script attached to the block. */
|
|
58
|
+
script?: EtchBlockScript;
|
|
59
|
+
/** Optional block-type-specific options. */
|
|
60
|
+
options?: EtchBlockOptions;
|
|
61
|
+
/** Child blocks, each itself an `EtchBlockJson`. */
|
|
62
|
+
children: EtchBlockJson[];
|
|
63
|
+
/** Block-type-specific fields beyond the common ones above. */
|
|
64
|
+
[key: string]: unknown;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* A block serialized for reading: {@link EtchBlockJson} plus its `id` and
|
|
68
|
+
* `parentId` (`null` at the document root). `id`/`parentId` are attached
|
|
69
|
+
* recursively, so every node in `children` is itself a `PublicBlockJson`.
|
|
70
|
+
*/
|
|
71
|
+
interface PublicBlockJson {
|
|
72
|
+
/** Stable id of this block. */
|
|
73
|
+
id: string;
|
|
74
|
+
/** Id of the parent block, or `null` when the block sits at the document root. */
|
|
75
|
+
parentId: string | null;
|
|
76
|
+
/** The block type, e.g. `etch/text` or `etch/div`. */
|
|
77
|
+
type: EtchBlockType;
|
|
78
|
+
/** Schema version of this block type. */
|
|
79
|
+
version: number;
|
|
80
|
+
/** Editor-facing metadata (label, hidden, structure state). */
|
|
81
|
+
context: EtchBlockContext;
|
|
82
|
+
/** Optional inline script attached to the block. */
|
|
83
|
+
script?: EtchBlockScript;
|
|
84
|
+
/** Optional block-type-specific options. */
|
|
85
|
+
options?: EtchBlockOptions;
|
|
86
|
+
/** Child blocks, each itself a `PublicBlockJson` with its own id/parentId. */
|
|
87
|
+
children: PublicBlockJson[];
|
|
88
|
+
/** Block-type-specific fields beyond the common ones above. */
|
|
89
|
+
[key: string]: unknown;
|
|
90
|
+
}
|
|
91
|
+
/** Predicate accepted by `blocks.find()`. All provided fields must match (AND). */
|
|
92
|
+
interface FindBlocksPredicate {
|
|
93
|
+
/** Match blocks of this exact type (e.g. `etch/text`). */
|
|
94
|
+
type?: string;
|
|
95
|
+
/** Match blocks carrying this CSS class. */
|
|
96
|
+
class?: string;
|
|
97
|
+
/** Match blocks that have this HTML attribute set. */
|
|
98
|
+
attribute?: string;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Patch accepted by `blocks.update()`. Only the provided fields are changed; the
|
|
102
|
+
* block keeps its id and children.
|
|
103
|
+
*/
|
|
104
|
+
interface BlockPatch {
|
|
105
|
+
/** Rename the block (its structure-panel label). */
|
|
106
|
+
name?: string;
|
|
107
|
+
/** Hide or show the block on the canvas. */
|
|
108
|
+
hidden?: boolean;
|
|
109
|
+
/**
|
|
110
|
+
* Merge HTML attributes — a key set to `undefined` removes that attribute.
|
|
111
|
+
* Only valid on HTML blocks.
|
|
112
|
+
*/
|
|
113
|
+
attributes?: Record<string, string | undefined>;
|
|
114
|
+
/** Replace the text content. Only valid on text blocks. */
|
|
115
|
+
text?: string;
|
|
116
|
+
}
|
|
117
|
+
/** Block selection, reading, structure and property edits. */
|
|
118
|
+
interface EtchBlocksApi {
|
|
119
|
+
/** Select a block in the canvas by id. */
|
|
120
|
+
select(blockId: string): void;
|
|
121
|
+
/** Clear the current selection. */
|
|
122
|
+
deselect(): void;
|
|
123
|
+
/** Id of the currently selected block, or `null` when nothing is selected. */
|
|
124
|
+
getSelectedId(): string | null;
|
|
125
|
+
/** The block (and its subtree) as serializable JSON, with `id`/`parentId` attached. */
|
|
126
|
+
getJson(blockId: string): PublicBlockJson;
|
|
127
|
+
/** The whole document as a forest of top-level blocks with nested children. */
|
|
128
|
+
getTree(): PublicBlockJson[];
|
|
129
|
+
/** Ids of every block matching the predicate (all provided fields AND-matched). */
|
|
130
|
+
find(predicate: FindBlocksPredicate): string[];
|
|
131
|
+
/**
|
|
132
|
+
* Build a block from JSON and insert it; returns the new block id.
|
|
133
|
+
* `parentId` defaults to the document root, `index` to the end of the parent.
|
|
134
|
+
*/
|
|
135
|
+
create(json: EtchBlockJson, parentId?: string, index?: number): string;
|
|
136
|
+
/** Remove a block and its entire subtree. */
|
|
137
|
+
delete(blockId: string): void;
|
|
138
|
+
/** Deep-copy a block next to the original; returns the new block's id. */
|
|
139
|
+
duplicate(blockId: string): string;
|
|
140
|
+
/**
|
|
141
|
+
* Re-parent a block. `newParentId` of `null` moves it to the document root;
|
|
142
|
+
* `index` defaults to the end of the new parent.
|
|
143
|
+
*/
|
|
144
|
+
move(blockId: string, newParentId: string | null, index?: number): void;
|
|
145
|
+
/** Replace a block with a new one built from JSON; returns the new block id. */
|
|
146
|
+
replace(blockId: string, json: EtchBlockJson): string;
|
|
147
|
+
/** Patch a block's common editable properties in place (keeps id/children). */
|
|
148
|
+
update(blockId: string, patch: BlockPatch): void;
|
|
149
|
+
/** Set the text content of a text block. */
|
|
150
|
+
setText(blockId: string, text: string): void;
|
|
151
|
+
/** Rename a block (sets its label / display name). */
|
|
152
|
+
rename(blockId: string, name: string): void;
|
|
153
|
+
/** Read an HTML attribute, or `undefined` when it is not set. */
|
|
154
|
+
getAttribute(blockId: string, key: string): string | undefined;
|
|
155
|
+
/** Set an HTML attribute; omit `value` for a valueless (boolean) attribute. */
|
|
156
|
+
setAttribute(blockId: string, key: string, value?: string): void;
|
|
157
|
+
/** Remove an HTML attribute. */
|
|
158
|
+
removeAttribute(blockId: string, key: string): void;
|
|
159
|
+
/** Add a CSS class to the block. */
|
|
160
|
+
addClass(blockId: string, className: string): void;
|
|
161
|
+
/** Remove a CSS class from the block. */
|
|
162
|
+
removeClass(blockId: string, className: string): void;
|
|
163
|
+
/** Whether the block currently has the given CSS class. */
|
|
164
|
+
hasClass(blockId: string, className: string): boolean;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* A `WP_Query` meta-query clause. Extensible — additional keys are allowed.
|
|
168
|
+
* @see https://developer.wordpress.org/reference/classes/wp_query/#custom-field-post-meta-parameters
|
|
169
|
+
*/
|
|
170
|
+
interface MetaQueryItem {
|
|
171
|
+
/** The custom field (meta) key to compare. */
|
|
172
|
+
key: string;
|
|
173
|
+
/** The value(s) to compare against. */
|
|
174
|
+
value: string | number | Array<string | number>;
|
|
175
|
+
/** Comparison operator (defaults to `=`). */
|
|
176
|
+
compare?: "=" | "!=" | ">" | ">=" | "<" | "<=" | "LIKE" | "NOT LIKE" | "IN" | "NOT IN" | "BETWEEN" | "NOT BETWEEN" | "EXISTS" | "NOT EXISTS";
|
|
177
|
+
/** SQL type the value is cast to before comparison. */
|
|
178
|
+
type?: "NUMERIC" | "BINARY" | "CHAR" | "DATE" | "DATETIME" | "DECIMAL" | "SIGNED" | "TIME" | "UNSIGNED";
|
|
179
|
+
[key: string]: unknown;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* A `WP_Query` taxonomy-query clause. Extensible — additional keys are allowed.
|
|
183
|
+
* @see https://developer.wordpress.org/reference/classes/wp_query/#taxonomy-parameters
|
|
184
|
+
*/
|
|
185
|
+
interface TaxQueryItem {
|
|
186
|
+
/** The taxonomy to query (e.g. `category`, `post_tag`). */
|
|
187
|
+
taxonomy: string;
|
|
188
|
+
/** Which term field `terms` refers to. */
|
|
189
|
+
field: "term_id" | "slug" | "name";
|
|
190
|
+
/** The term(s) to match. */
|
|
191
|
+
terms: string | number | Array<string | number>;
|
|
192
|
+
/** How to match the terms (defaults to `IN`). */
|
|
193
|
+
operator?: "IN" | "NOT IN" | "AND";
|
|
194
|
+
/** Whether to include child terms of a hierarchical taxonomy. */
|
|
195
|
+
include_children?: boolean;
|
|
196
|
+
[key: string]: unknown;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* WordPress query arguments. Values may be static or a loop parameter
|
|
200
|
+
* expression (`"$param"` or `"$param ?? fallback"`). Extensible — any
|
|
201
|
+
* additional `WP_Query` argument is allowed.
|
|
202
|
+
*/
|
|
203
|
+
interface WpQueryArgs {
|
|
204
|
+
/** Post type(s) to query. */
|
|
205
|
+
post_type?: string | string[];
|
|
206
|
+
/** Number of posts per page (`-1` for all). */
|
|
207
|
+
posts_per_page?: number | string;
|
|
208
|
+
/** Number of posts to skip. */
|
|
209
|
+
offset?: number | string;
|
|
210
|
+
/** Page of results to return. */
|
|
211
|
+
paged?: number | string;
|
|
212
|
+
/** Alias of `paged` used in some contexts. */
|
|
213
|
+
page?: number | string;
|
|
214
|
+
/** Field to order results by. */
|
|
215
|
+
orderby?: "date" | "title" | "menu_order" | "rand" | "ID" | "author" | "name" | "modified" | "parent" | "comment_count" | (string & {});
|
|
216
|
+
/** Sort direction. */
|
|
217
|
+
order?: "ASC" | "DESC" | (string & {});
|
|
218
|
+
/** Post status to include. */
|
|
219
|
+
post_status?: "publish" | "pending" | "draft" | "auto-draft" | "future" | "private" | "inherit" | "trash" | (string & {});
|
|
220
|
+
/** Whether to ignore sticky posts. */
|
|
221
|
+
ignore_sticky_posts?: boolean | 0 | 1 | (string & {});
|
|
222
|
+
/** Author id (number) or username (string). */
|
|
223
|
+
author?: number | string;
|
|
224
|
+
/** Author by `user_nicename`. */
|
|
225
|
+
author_name?: string;
|
|
226
|
+
/** Category id (number) or slug (string). */
|
|
227
|
+
category?: number | string;
|
|
228
|
+
/** Category by slug. */
|
|
229
|
+
category_name?: string;
|
|
230
|
+
/** Tag slug. */
|
|
231
|
+
tag?: string;
|
|
232
|
+
/** Taxonomy query clauses. */
|
|
233
|
+
tax_query?: TaxQueryItem[];
|
|
234
|
+
/** Meta (custom field) query clauses. */
|
|
235
|
+
meta_query?: MetaQueryItem[];
|
|
236
|
+
/** Search keyword. */
|
|
237
|
+
s?: string;
|
|
238
|
+
[key: string]: unknown;
|
|
239
|
+
}
|
|
240
|
+
/** WordPress taxonomy-term query arguments (extensible). */
|
|
241
|
+
interface WpTermsArgs {
|
|
242
|
+
/** Taxonomy to fetch terms from. */
|
|
243
|
+
taxonomy?: string;
|
|
244
|
+
/** Field to order terms by. */
|
|
245
|
+
orderby?: "name" | "slug" | "term_group" | "term_id" | "description" | "count" | (string & {});
|
|
246
|
+
/** Sort direction. */
|
|
247
|
+
order?: "ASC" | "DESC" | (string & {});
|
|
248
|
+
[key: string]: unknown;
|
|
249
|
+
}
|
|
250
|
+
/** WordPress user query arguments (extensible). */
|
|
251
|
+
interface WpUsersArgs {
|
|
252
|
+
/** Role(s) users must have. */
|
|
253
|
+
role?: string | string[];
|
|
254
|
+
/** User ids to include. */
|
|
255
|
+
include?: number[] | string;
|
|
256
|
+
/** User ids to exclude. */
|
|
257
|
+
exclude?: number[] | string;
|
|
258
|
+
/** Search keyword. */
|
|
259
|
+
search?: string;
|
|
260
|
+
/** Columns the `search` keyword is matched against. */
|
|
261
|
+
search_columns?: string[] | string;
|
|
262
|
+
/** Field to order users by. */
|
|
263
|
+
orderby?: "ID" | "display_name" | "name" | "user_login" | "user_email" | "user_registered" | "post_count" | "meta_value" | "meta_value_num" | (string & {});
|
|
264
|
+
/** Sort direction. */
|
|
265
|
+
order?: "ASC" | "DESC" | (string & {});
|
|
266
|
+
/** Number of users to return. */
|
|
267
|
+
number?: number | string;
|
|
268
|
+
/** Number of users to skip. */
|
|
269
|
+
offset?: number | string;
|
|
270
|
+
/** Page of results to return. */
|
|
271
|
+
paged?: number | string;
|
|
272
|
+
[key: string]: unknown;
|
|
273
|
+
}
|
|
274
|
+
/** Type-specific configuration of an {@link EtchLoop}, discriminated by `type`. */
|
|
275
|
+
type EtchLoopConfig = {
|
|
276
|
+
type: "wp-query";
|
|
277
|
+
args: WpQueryArgs;
|
|
278
|
+
} | {
|
|
279
|
+
type: "wp-terms";
|
|
280
|
+
args: WpTermsArgs;
|
|
281
|
+
} | {
|
|
282
|
+
type: "wp-users";
|
|
283
|
+
args: WpUsersArgs;
|
|
284
|
+
} | {
|
|
285
|
+
type: "main-query";
|
|
286
|
+
args: WpQueryArgs;
|
|
287
|
+
} | {
|
|
288
|
+
type: "json";
|
|
289
|
+
data: unknown[];
|
|
290
|
+
};
|
|
291
|
+
/** A loop definition (extensible). */
|
|
292
|
+
interface EtchLoop {
|
|
293
|
+
/** Stable, human-authored key used to reference the loop. */
|
|
294
|
+
key: string;
|
|
295
|
+
/** Display name shown in the loop manager. */
|
|
296
|
+
name: string;
|
|
297
|
+
/** Whether the loop is global (reusable across pages) or local to a document. */
|
|
298
|
+
global: boolean;
|
|
299
|
+
/** The loop's data source and arguments. */
|
|
300
|
+
config: EtchLoopConfig;
|
|
301
|
+
[key: string]: unknown;
|
|
302
|
+
}
|
|
303
|
+
/** All loops keyed by id. */
|
|
304
|
+
type EtchLoopObj = Record<string, EtchLoop>;
|
|
305
|
+
/** Partial loop binding applied to an `etch/loop` block by `loops.setForBlock()`. */
|
|
306
|
+
interface BlockLoopBinding {
|
|
307
|
+
/** Id of the loop to bind. */
|
|
308
|
+
loopId?: string;
|
|
309
|
+
/** What the block iterates over (e.g. the loop's items). */
|
|
310
|
+
target?: string;
|
|
311
|
+
/** Variable name bound to the current item inside the loop. */
|
|
312
|
+
itemId?: string;
|
|
313
|
+
/** Variable name bound to the current index inside the loop. */
|
|
314
|
+
indexId?: string;
|
|
315
|
+
/** Values for the loop's parameters (used by `$param` expressions). */
|
|
316
|
+
loopParams?: Record<string, unknown>;
|
|
317
|
+
}
|
|
318
|
+
/** Loop definitions and binding loops to blocks. */
|
|
319
|
+
interface EtchLoopsApi {
|
|
320
|
+
/** All loops keyed by id. */
|
|
321
|
+
getAll(): EtchLoopObj;
|
|
322
|
+
/** Add a new loop; returns its generated id. */
|
|
323
|
+
add(loop: EtchLoop): string;
|
|
324
|
+
/** Replace an existing loop's definition. */
|
|
325
|
+
update(loopId: string, loop: EtchLoop): void;
|
|
326
|
+
/** Delete a loop by id. */
|
|
327
|
+
delete(loopId: string): void;
|
|
328
|
+
/**
|
|
329
|
+
* Fuzzy-search loops by `name` or `key`, ranked best-first. Each hit is the
|
|
330
|
+
* loop plus its `id` (the value `setForBlock`/`update`/`delete` expect).
|
|
331
|
+
* Returns an empty array for a blank query or when nothing matches.
|
|
332
|
+
*/
|
|
333
|
+
findLoop(query: string): (EtchLoop & {
|
|
334
|
+
id: string;
|
|
335
|
+
})[];
|
|
336
|
+
/** Bind (or update the binding of) a loop on an `etch/loop` block. */
|
|
337
|
+
setForBlock(blockId: string, loop: BlockLoopBinding): void;
|
|
338
|
+
}
|
|
339
|
+
/** Patch accepted by `styles.update()`. Omitted fields keep their current value. */
|
|
340
|
+
interface StylePatch {
|
|
341
|
+
/** The CSS selector the rule targets. */
|
|
342
|
+
selector?: string;
|
|
343
|
+
/** The CSS declarations (rule body). */
|
|
344
|
+
css?: string;
|
|
345
|
+
/** The collection/folder the style belongs to. */
|
|
346
|
+
collection?: string;
|
|
347
|
+
}
|
|
348
|
+
/** Global style (CSS) definitions, including `:root` global CSS variables. */
|
|
349
|
+
interface EtchStylesApi {
|
|
350
|
+
/** Create a style rule for `selector`; returns its id. */
|
|
351
|
+
create(selector: string, css?: string, collection?: string): string;
|
|
352
|
+
/** Patch a style rule's selector, css, or collection. */
|
|
353
|
+
update(styleId: string, patch: StylePatch): void;
|
|
354
|
+
/** Delete a style rule by id. */
|
|
355
|
+
delete(styleId: string): void;
|
|
356
|
+
/** All global CSS custom properties as a `name -> value` record. */
|
|
357
|
+
listVariables(collection?: string): Record<string, string>;
|
|
358
|
+
/** Read one global CSS custom property, or `undefined` when unset. */
|
|
359
|
+
getVariable(name: string, collection?: string): string | undefined;
|
|
360
|
+
/** Set a global CSS custom property (e.g. `('--brand', '#0af')`). */
|
|
361
|
+
setVariable(name: string, value: string, collection?: string): void;
|
|
362
|
+
/** Remove a global CSS custom property. */
|
|
363
|
+
removeVariable(name: string, collection?: string): void;
|
|
364
|
+
}
|
|
365
|
+
/** Type of a global stylesheet. */
|
|
366
|
+
type StylesheetType = "default" | "@custom-media";
|
|
367
|
+
/** A global stylesheet entry. */
|
|
368
|
+
interface StylesheetSummary {
|
|
369
|
+
/** Stable id of the stylesheet. */
|
|
370
|
+
id: string;
|
|
371
|
+
/** Display name. */
|
|
372
|
+
name: string;
|
|
373
|
+
/** The full CSS contents. */
|
|
374
|
+
css: string;
|
|
375
|
+
/** Whether this is a regular stylesheet or a `@custom-media` definition set. */
|
|
376
|
+
type: StylesheetType;
|
|
377
|
+
}
|
|
378
|
+
/** Input for `stylesheets.create()`. */
|
|
379
|
+
interface StylesheetInput {
|
|
380
|
+
/** Display name. */
|
|
381
|
+
name: string;
|
|
382
|
+
/** Initial CSS contents. */
|
|
383
|
+
css: string;
|
|
384
|
+
/** Stylesheet type (defaults to `default`). */
|
|
385
|
+
type?: StylesheetType;
|
|
386
|
+
}
|
|
387
|
+
/** Patch for `stylesheets.update()`. Omitted fields keep their current value. */
|
|
388
|
+
interface StylesheetPatch {
|
|
389
|
+
/** New display name. */
|
|
390
|
+
name?: string;
|
|
391
|
+
/** Replacement CSS contents. */
|
|
392
|
+
css?: string;
|
|
393
|
+
/** New stylesheet type. */
|
|
394
|
+
type?: StylesheetType;
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Global stylesheets and `@custom-media` definitions.
|
|
398
|
+
*
|
|
399
|
+
* Note: every method persists to the backend immediately (they do not wait for
|
|
400
|
+
* {@link Etch.saveAsync}).
|
|
401
|
+
*/
|
|
402
|
+
interface EtchStylesheetsApi {
|
|
403
|
+
/** All global stylesheets as plain summaries. */
|
|
404
|
+
list(): StylesheetSummary[];
|
|
405
|
+
/** One stylesheet by id. */
|
|
406
|
+
get(stylesheetId: string): StylesheetSummary;
|
|
407
|
+
/** Create a stylesheet; resolves to its new id. */
|
|
408
|
+
createAsync(input: StylesheetInput): Promise<string>;
|
|
409
|
+
/** Patch a stylesheet's name, css, or type. */
|
|
410
|
+
updateAsync(stylesheetId: string, patch: StylesheetPatch): Promise<void>;
|
|
411
|
+
/** Append CSS to a stylesheet (a newline is inserted before it). */
|
|
412
|
+
appendAsync(stylesheetId: string, css: string): Promise<void>;
|
|
413
|
+
/** Delete a stylesheet by id. */
|
|
414
|
+
deleteAsync(stylesheetId: string): Promise<void>;
|
|
415
|
+
/** All `@custom-media` definitions as a `name -> query` record. */
|
|
416
|
+
listCustomMedia(): Record<string, string>;
|
|
417
|
+
/** Add (or look up) a `@custom-media` definition, e.g. `('--sm', '(max-width: 600px)')`. */
|
|
418
|
+
addCustomMediaAsync(name: string, query: string): Promise<void>;
|
|
419
|
+
}
|
|
420
|
+
/** Fields shared by every component property. */
|
|
421
|
+
interface ComponentPropertyBase {
|
|
422
|
+
/** Display name of the property. */
|
|
423
|
+
name: string;
|
|
424
|
+
/** Stable key used to reference the property in markup. */
|
|
425
|
+
key: string;
|
|
426
|
+
/** Optional human-readable description. */
|
|
427
|
+
description?: string;
|
|
428
|
+
}
|
|
429
|
+
/** A string property, optionally specialized (color picker, image, select, …). */
|
|
430
|
+
interface StringComponentProperty {
|
|
431
|
+
type: {
|
|
432
|
+
primitive: "string";
|
|
433
|
+
specialized?: "color" | "url" | "image" | "select" | "array" | "wpMediaId";
|
|
434
|
+
};
|
|
435
|
+
/** Default value. */
|
|
436
|
+
default?: string;
|
|
437
|
+
/** Allowed values when `specialized` is `select`. */
|
|
438
|
+
options?: string[];
|
|
439
|
+
}
|
|
440
|
+
/** A numeric property. */
|
|
441
|
+
interface NumberComponentProperty {
|
|
442
|
+
type: {
|
|
443
|
+
primitive: "number";
|
|
444
|
+
};
|
|
445
|
+
/** Default value. */
|
|
446
|
+
default?: number;
|
|
447
|
+
/** Allowed values, when constrained to a set. */
|
|
448
|
+
options?: number[];
|
|
449
|
+
}
|
|
450
|
+
/** A boolean property. */
|
|
451
|
+
interface BooleanComponentProperty {
|
|
452
|
+
type: {
|
|
453
|
+
primitive: "boolean";
|
|
454
|
+
};
|
|
455
|
+
/** Default value (a string is allowed for expression-driven defaults). */
|
|
456
|
+
default?: boolean | string;
|
|
457
|
+
}
|
|
458
|
+
/** An object property carrying structured data. */
|
|
459
|
+
interface ObjectComponentProperty {
|
|
460
|
+
type: {
|
|
461
|
+
primitive: "object";
|
|
462
|
+
specialized?: string;
|
|
463
|
+
};
|
|
464
|
+
/** Default value. */
|
|
465
|
+
default?: Record<string, unknown> | unknown[];
|
|
466
|
+
}
|
|
467
|
+
/** An array property carrying a list of values. */
|
|
468
|
+
interface ArrayComponentProperty {
|
|
469
|
+
type: {
|
|
470
|
+
primitive: "array";
|
|
471
|
+
specialized?: string;
|
|
472
|
+
};
|
|
473
|
+
/** Default value. */
|
|
474
|
+
default?: unknown[];
|
|
475
|
+
}
|
|
476
|
+
/** A property holding a list of CSS class names. */
|
|
477
|
+
interface ClassComponentProperty {
|
|
478
|
+
type: {
|
|
479
|
+
primitive: "array";
|
|
480
|
+
specialized: "class";
|
|
481
|
+
};
|
|
482
|
+
/** Default value. */
|
|
483
|
+
default?: string[];
|
|
484
|
+
}
|
|
485
|
+
/** A group of nested properties (no default of its own). */
|
|
486
|
+
interface GroupComponentProperty {
|
|
487
|
+
type: {
|
|
488
|
+
primitive: "object";
|
|
489
|
+
specialized: "group";
|
|
490
|
+
};
|
|
491
|
+
/** The nested properties in this group. */
|
|
492
|
+
properties: ComponentProperty[];
|
|
493
|
+
}
|
|
494
|
+
/** A repeatable group of nested properties (no default of its own). */
|
|
495
|
+
interface RepeaterComponentProperty {
|
|
496
|
+
type: {
|
|
497
|
+
primitive: "array";
|
|
498
|
+
specialized: "repeater";
|
|
499
|
+
};
|
|
500
|
+
/** The nested properties repeated per row. */
|
|
501
|
+
properties: ComponentProperty[];
|
|
502
|
+
}
|
|
503
|
+
/** A conditional group gated by an expression. */
|
|
504
|
+
interface ConditionComponentProperty {
|
|
505
|
+
type: {
|
|
506
|
+
primitive: "string";
|
|
507
|
+
specialized: "condition";
|
|
508
|
+
};
|
|
509
|
+
/** The nested properties shown when the condition holds. */
|
|
510
|
+
properties: ComponentProperty[];
|
|
511
|
+
/** The condition expression. */
|
|
512
|
+
default?: string;
|
|
513
|
+
}
|
|
514
|
+
/** A single configurable property of a component. */
|
|
515
|
+
type ComponentProperty = ComponentPropertyBase & (StringComponentProperty | NumberComponentProperty | BooleanComponentProperty | ObjectComponentProperty | ArrayComponentProperty | ClassComponentProperty | GroupComponentProperty | RepeaterComponentProperty | ConditionComponentProperty);
|
|
516
|
+
/** Component metadata without its block tree (returned by `components.list()`). */
|
|
517
|
+
interface PublicComponentSummary {
|
|
518
|
+
/** Numeric id of the component. */
|
|
519
|
+
id: number;
|
|
520
|
+
/** Display name. */
|
|
521
|
+
name: string;
|
|
522
|
+
/** Stable key used to reference the component in markup. */
|
|
523
|
+
key: string;
|
|
524
|
+
/** Optional human-readable description. */
|
|
525
|
+
description?: string;
|
|
526
|
+
/** The component's configurable properties. */
|
|
527
|
+
properties: ComponentProperty[];
|
|
528
|
+
}
|
|
529
|
+
/** Full component definition including its block tree as serializable JSON. */
|
|
530
|
+
interface PublicComponentJson extends PublicComponentSummary {
|
|
531
|
+
/** The component's block tree as serializable JSON. */
|
|
532
|
+
blocks: PublicBlockJson[];
|
|
533
|
+
}
|
|
534
|
+
/** Patch accepted by `components.update()`. Omitted fields keep their current value. */
|
|
535
|
+
interface ComponentPatch {
|
|
536
|
+
/** New display name. */
|
|
537
|
+
name?: string;
|
|
538
|
+
/** New reference key. */
|
|
539
|
+
key?: string;
|
|
540
|
+
/** New description. */
|
|
541
|
+
description?: string;
|
|
542
|
+
/** Replacement set of configurable properties. */
|
|
543
|
+
properties?: ComponentProperty[];
|
|
544
|
+
/** Replacement block tree as JSON. */
|
|
545
|
+
blocks?: EtchBlockJson[];
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* Reusable Etch component definitions.
|
|
549
|
+
*
|
|
550
|
+
* Note: `createAsync`/`updateAsync`/`deleteAsync` persist to the backend immediately (they do
|
|
551
|
+
* not wait for {@link Etch.saveAsync}).
|
|
552
|
+
*/
|
|
553
|
+
interface EtchComponentsApi {
|
|
554
|
+
/** All components as summaries (without their block trees). */
|
|
555
|
+
list(): PublicComponentSummary[];
|
|
556
|
+
/** One component including its block tree, by id. */
|
|
557
|
+
getJson(componentId: number): PublicComponentJson;
|
|
558
|
+
/** Create an empty component with the given name; resolves to its new id. */
|
|
559
|
+
createAsync(name: string): Promise<number>;
|
|
560
|
+
/** Patch a component's metadata, properties, or block tree. */
|
|
561
|
+
updateAsync(componentId: number, patch: ComponentPatch): Promise<void>;
|
|
562
|
+
/** Delete a component by id. */
|
|
563
|
+
deleteAsync(componentId: number): Promise<void>;
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* A navigable area of the builder UI:
|
|
567
|
+
* - `builder` — the canvas/editor
|
|
568
|
+
* - `templates` — the template switcher
|
|
569
|
+
* - `content-hub` — the pages/posts browser
|
|
570
|
+
* - `style-manager` — the global style manager
|
|
571
|
+
* - `loop-manager` — the loop manager
|
|
572
|
+
*/
|
|
573
|
+
type NavigationPlace = "builder" | "templates" | "style-manager" | "content-hub" | "loop-manager";
|
|
574
|
+
/** Lightweight post entry returned by `navigation.listPostsAsync()`. */
|
|
575
|
+
interface PostSummary {
|
|
576
|
+
/** Post id. */
|
|
577
|
+
id: number;
|
|
578
|
+
/** Post title. */
|
|
579
|
+
title: string;
|
|
580
|
+
/** URL slug. */
|
|
581
|
+
slug: string;
|
|
582
|
+
/** Post status (e.g. `publish`, `draft`). */
|
|
583
|
+
status: string;
|
|
584
|
+
/** Post type (e.g. `page`, `post`, or a custom type). */
|
|
585
|
+
postType: string;
|
|
586
|
+
}
|
|
587
|
+
/** Lightweight template entry returned by `navigation.listTemplatesAsync()`. */
|
|
588
|
+
interface TemplateSummary {
|
|
589
|
+
/** Template id. */
|
|
590
|
+
id: number;
|
|
591
|
+
/** Template title. */
|
|
592
|
+
title: string;
|
|
593
|
+
/** Template slug. */
|
|
594
|
+
slug: string;
|
|
595
|
+
}
|
|
596
|
+
/** Switching the active post/template and navigating between builder UI areas. */
|
|
597
|
+
interface EtchNavigationApi {
|
|
598
|
+
/** Navigate to a builder UI area (e.g. the loop manager). */
|
|
599
|
+
goTo(place: NavigationPlace): void;
|
|
600
|
+
/** The currently active builder UI area. */
|
|
601
|
+
getCurrentPlace(): NavigationPlace;
|
|
602
|
+
/** All builder UI areas that `goTo` accepts. */
|
|
603
|
+
getPlaces(): NavigationPlace[];
|
|
604
|
+
/** Switch the canvas to a post (page/post/CPT) by id, returning to the builder view. */
|
|
605
|
+
openPostAsync(postId: number): Promise<void>;
|
|
606
|
+
/** Switch the canvas to a template by id, returning to the builder view. */
|
|
607
|
+
openTemplateAsync(templateId: number): Promise<void>;
|
|
608
|
+
/** Id of the post/template currently open in the canvas (`null` if none). */
|
|
609
|
+
getActivePostId(): number | null;
|
|
610
|
+
/** Whether the canvas is currently editing a template. */
|
|
611
|
+
isEditingTemplate(): boolean;
|
|
612
|
+
/** List available posts, optionally filtered to one post type. */
|
|
613
|
+
listPostsAsync(postType?: string): Promise<PostSummary[]>;
|
|
614
|
+
/** List available templates. */
|
|
615
|
+
listTemplatesAsync(): Promise<TemplateSummary[]>;
|
|
616
|
+
}
|
|
617
|
+
/** Custom field type. Open-ended for future field types. */
|
|
618
|
+
type CustomFieldType = "text" | "textarea" | "number" | "boolean" | (string & {});
|
|
619
|
+
/** A custom field definition (extensible). */
|
|
620
|
+
interface CustomField {
|
|
621
|
+
/** Display label. */
|
|
622
|
+
label: string;
|
|
623
|
+
/** Stable key used to read/write the field's value. */
|
|
624
|
+
key: string;
|
|
625
|
+
/** The field's data type. */
|
|
626
|
+
type: CustomFieldType;
|
|
627
|
+
/** Optional help text. */
|
|
628
|
+
description?: string;
|
|
629
|
+
/** Whether a value is required. */
|
|
630
|
+
required?: boolean;
|
|
631
|
+
[key: string]: unknown;
|
|
632
|
+
}
|
|
633
|
+
/** Where a custom field group is assigned. */
|
|
634
|
+
type CustomFieldAssignment = {
|
|
635
|
+
post_types: string[];
|
|
636
|
+
op: "isIn" | "isNotIn";
|
|
637
|
+
} | {
|
|
638
|
+
post_ids: number[];
|
|
639
|
+
op: "isIn" | "isNotIn";
|
|
640
|
+
} | {
|
|
641
|
+
taxonomies: string[];
|
|
642
|
+
op: "isIn" | "isNotIn";
|
|
643
|
+
};
|
|
644
|
+
/** A custom field group definition (extensible). */
|
|
645
|
+
interface CustomFieldGroup {
|
|
646
|
+
/** Display label of the group. */
|
|
647
|
+
label: string;
|
|
648
|
+
/** Optional description. */
|
|
649
|
+
description?: string;
|
|
650
|
+
/** The fields in this group. */
|
|
651
|
+
fields: CustomField[];
|
|
652
|
+
/** Which posts/taxonomies this group is assigned to. */
|
|
653
|
+
assigned_to: CustomFieldAssignment;
|
|
654
|
+
[key: string]: unknown;
|
|
655
|
+
}
|
|
656
|
+
/** A resolved field returned by the single field-value endpoints. */
|
|
657
|
+
interface ResolvedCustomField {
|
|
658
|
+
/** The field's key. */
|
|
659
|
+
key: string;
|
|
660
|
+
/** The field's label. */
|
|
661
|
+
label: string;
|
|
662
|
+
/** The field's data type. */
|
|
663
|
+
type: CustomFieldType;
|
|
664
|
+
/** The resolved value; varies per field type, `null` when unset. */
|
|
665
|
+
value: unknown;
|
|
666
|
+
}
|
|
667
|
+
/** Response from `fields.getValueAsync()` — the resolved field plus its group/post. */
|
|
668
|
+
interface PostCustomFieldValueResponse {
|
|
669
|
+
/** Id of the post the value belongs to. */
|
|
670
|
+
post_id: number;
|
|
671
|
+
/** Id of the group the field was resolved from. */
|
|
672
|
+
group_id: string;
|
|
673
|
+
/** The resolved field and its value. */
|
|
674
|
+
field: ResolvedCustomField;
|
|
675
|
+
}
|
|
676
|
+
/** Per-field entry inside a bulk field-values response (keyed by field key). */
|
|
677
|
+
interface PostCustomFieldValueEntry {
|
|
678
|
+
/** The field's label. */
|
|
679
|
+
label: string;
|
|
680
|
+
/** The field's data type. */
|
|
681
|
+
type: CustomFieldType;
|
|
682
|
+
/** The resolved value; varies per field type, `null` when unset. */
|
|
683
|
+
value: unknown;
|
|
684
|
+
}
|
|
685
|
+
/** Per-group entry inside a bulk field-values response. */
|
|
686
|
+
interface PostCustomFieldGroupEntry {
|
|
687
|
+
/** The group's label. */
|
|
688
|
+
label: string;
|
|
689
|
+
/** The group's resolved field values, keyed by field key. */
|
|
690
|
+
fields: Record<string, PostCustomFieldValueEntry>;
|
|
691
|
+
}
|
|
692
|
+
/** Response from `fields.getValuesAsync()` — every group assigned to the post. */
|
|
693
|
+
interface PostCustomFieldValuesResponse {
|
|
694
|
+
/** Id of the post. */
|
|
695
|
+
post_id: number;
|
|
696
|
+
/** Every assigned group with its resolved field values, keyed by group id. */
|
|
697
|
+
groups: Record<string, PostCustomFieldGroupEntry>;
|
|
698
|
+
}
|
|
699
|
+
/**
|
|
700
|
+
* Custom field groups, their fields, and per-post field values.
|
|
701
|
+
*
|
|
702
|
+
* Note: every method persists to the backend immediately (they do not wait for
|
|
703
|
+
* {@link Etch.saveAsync}).
|
|
704
|
+
*/
|
|
705
|
+
interface EtchFieldsApi {
|
|
706
|
+
/** All custom field groups, keyed by group id. */
|
|
707
|
+
listGroupsAsync(): Promise<Record<string, CustomFieldGroup>>;
|
|
708
|
+
/** One custom field group by id. */
|
|
709
|
+
getGroupAsync(groupId: string): Promise<CustomFieldGroup>;
|
|
710
|
+
/** Create a custom field group; resolves to its new id. */
|
|
711
|
+
createGroupAsync(definition: CustomFieldGroup): Promise<string>;
|
|
712
|
+
/** Replace a custom field group's definition. */
|
|
713
|
+
updateGroupAsync(groupId: string, definition: CustomFieldGroup): Promise<void>;
|
|
714
|
+
/** Delete a custom field group by id. */
|
|
715
|
+
deleteGroupAsync(groupId: string): Promise<void>;
|
|
716
|
+
/** Add a field to a group. */
|
|
717
|
+
addFieldAsync(groupId: string, field: CustomField): Promise<void>;
|
|
718
|
+
/** Replace a field within a group. */
|
|
719
|
+
updateFieldAsync(groupId: string, fieldKey: string, field: CustomField): Promise<void>;
|
|
720
|
+
/** Remove a field from a group. */
|
|
721
|
+
removeFieldAsync(groupId: string, fieldKey: string): Promise<void>;
|
|
722
|
+
/** All resolved field values for a post, grouped. */
|
|
723
|
+
getValuesAsync(postId: number): Promise<PostCustomFieldValuesResponse>;
|
|
724
|
+
/** One resolved field value for a post. */
|
|
725
|
+
getValueAsync(postId: number, fieldKey: string): Promise<PostCustomFieldValueResponse>;
|
|
726
|
+
/** Set one field value on a post; resolves to the updated resolved field. */
|
|
727
|
+
setValueAsync(postId: number, fieldKey: string, value: unknown): Promise<PostCustomFieldValueResponse>;
|
|
728
|
+
/** Set several field values on a post at once. */
|
|
729
|
+
setValuesAsync(postId: number, values: Record<string, unknown>): Promise<void>;
|
|
730
|
+
/** Clear one field value on a post. */
|
|
731
|
+
deleteValueAsync(postId: number, fieldKey: string): Promise<void>;
|
|
732
|
+
}
|
|
733
|
+
/** Canvas color scheme. */
|
|
734
|
+
type ColorScheme = "light" | "dark";
|
|
735
|
+
/** Builder app/chrome controls: color scheme, interface visibility, exit. */
|
|
736
|
+
interface EtchUiApi {
|
|
737
|
+
/** The current canvas color scheme. */
|
|
738
|
+
getColorScheme(): ColorScheme;
|
|
739
|
+
/** Set the canvas color scheme (persisted locally, per active page). */
|
|
740
|
+
setColorScheme(scheme: ColorScheme): void;
|
|
741
|
+
/** Toggle between light and dark canvas color schemes. */
|
|
742
|
+
toggleColorScheme(): void;
|
|
743
|
+
/** Whether the builder chrome (panels/toolbars) is currently hidden. */
|
|
744
|
+
isInterfaceHidden(): boolean;
|
|
745
|
+
/** Show or hide the builder chrome. */
|
|
746
|
+
setInterfaceHidden(hidden: boolean): void;
|
|
747
|
+
/** Toggle the builder chrome visibility. */
|
|
748
|
+
toggleInterface(): void;
|
|
749
|
+
/** Leave the builder and return to the WordPress admin dashboard. */
|
|
750
|
+
exitToWordPress(): void;
|
|
751
|
+
}
|
|
752
|
+
/** Undo/redo of builder mutations. */
|
|
753
|
+
interface EtchHistoryApi {
|
|
754
|
+
/** Undo the last builder mutation. */
|
|
755
|
+
undo(): void;
|
|
756
|
+
/** Redo the last undone mutation. */
|
|
757
|
+
redo(): void;
|
|
758
|
+
/** Whether there is a mutation to undo. */
|
|
759
|
+
canUndo(): boolean;
|
|
760
|
+
/** Whether there is a mutation to redo. */
|
|
761
|
+
canRedo(): boolean;
|
|
762
|
+
}
|
|
763
|
+
/** Options for negotiating an API instance (see the runtime `connect`). */
|
|
764
|
+
interface ConnectOptions {
|
|
765
|
+
/**
|
|
766
|
+
* The contract version this consumer targets, e.g. `"^1.0"`. Reserved for
|
|
767
|
+
* the stable (`1.x`) runtime; ignored by `0.x` runtimes that have no
|
|
768
|
+
* `connect()`.
|
|
769
|
+
*/
|
|
770
|
+
apiVersion?: string;
|
|
771
|
+
/** A stable identifier for the calling plugin (for telemetry / guards). */
|
|
772
|
+
id?: string;
|
|
773
|
+
}
|
|
774
|
+
/**
|
|
775
|
+
* Public, scriptable builder API exposed on `window.etch`.
|
|
776
|
+
*
|
|
777
|
+
* Intended for AI assistants and third-party plugins. Every method takes/returns
|
|
778
|
+
* plain serializable values (block ids and JSON), never internal reactive class
|
|
779
|
+
* instances. Mutations route through the same guarded paths the UI uses, so
|
|
780
|
+
* `readonly` checks, child-acceptance rules and undo/redo history all keep
|
|
781
|
+
* working.
|
|
782
|
+
*
|
|
783
|
+
* Methods throw `EtchApiError` (with a `code`) on failure.
|
|
784
|
+
*/
|
|
785
|
+
interface Etch {
|
|
786
|
+
/** Block selection, reading, structure and property edits. */
|
|
787
|
+
blocks: EtchBlocksApi;
|
|
788
|
+
/** Loop definitions and binding loops to blocks. */
|
|
789
|
+
loops: EtchLoopsApi;
|
|
790
|
+
/** Global style (CSS) definitions and CSS variables. */
|
|
791
|
+
styles: EtchStylesApi;
|
|
792
|
+
/** Global stylesheets and `@custom-media` definitions. */
|
|
793
|
+
stylesheets: EtchStylesheetsApi;
|
|
794
|
+
/** Reusable component definitions. */
|
|
795
|
+
components: EtchComponentsApi;
|
|
796
|
+
/** Switching the active post/template and navigating the builder UI. */
|
|
797
|
+
navigation: EtchNavigationApi;
|
|
798
|
+
/** Custom field groups, fields, and per-post values. */
|
|
799
|
+
fields: EtchFieldsApi;
|
|
800
|
+
/** Builder chrome controls (color scheme, interface visibility, exit). */
|
|
801
|
+
ui: EtchUiApi;
|
|
802
|
+
/** Undo/redo of builder mutations. */
|
|
803
|
+
history: EtchHistoryApi;
|
|
804
|
+
/** Persist everything (blocks, loops, styles, UI). */
|
|
805
|
+
saveAsync(): Promise<void>;
|
|
806
|
+
/**
|
|
807
|
+
* Negotiate a version-pinned API instance. **Reserved** — not implemented by
|
|
808
|
+
* `0.x` runtimes. When present on a future stable runtime, it returns an
|
|
809
|
+
* adapter pinned to the requested {@link ConnectOptions.apiVersion}.
|
|
810
|
+
*/
|
|
811
|
+
connect?(options?: ConnectOptions): Etch;
|
|
812
|
+
/**
|
|
813
|
+
* Version of the scripting contract exposed on `window.etch`, independent of
|
|
814
|
+
* the product {@link Etch.version}. `0.x` while experimental. Prefer feature
|
|
815
|
+
* detection over comparing this value.
|
|
816
|
+
*/
|
|
817
|
+
readonly apiVersion: string;
|
|
818
|
+
/** The Etch builder (product) version, for capability checks. */
|
|
819
|
+
readonly version: string;
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
declare global {
|
|
823
|
+
interface Window {
|
|
824
|
+
/** The Etch scripting API, present once the builder has loaded. */
|
|
825
|
+
etch?: Etch;
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
/**
|
|
829
|
+
* Whether the Etch scripting API is present on the page. Use this to guard code
|
|
830
|
+
* that should no-op when not running inside the builder.
|
|
831
|
+
*/
|
|
832
|
+
declare function isEtchAvailable(): boolean;
|
|
833
|
+
/**
|
|
834
|
+
* Acquire the Etch scripting API from the page.
|
|
835
|
+
*
|
|
836
|
+
* The runtime lives on `window.etch` (injected by the builder); this returns it
|
|
837
|
+
* typed. When the page exposes a future stable runtime with a native
|
|
838
|
+
* `connect()`, version negotiation is delegated to it. On today's `0.x`
|
|
839
|
+
* runtime, the global is returned directly after a best-effort version check.
|
|
840
|
+
*
|
|
841
|
+
* @throws {EtchApiError} `NOT_AVAILABLE` when the builder is not present.
|
|
842
|
+
*
|
|
843
|
+
* @example
|
|
844
|
+
* ```ts
|
|
845
|
+
* import { getEtch } from '@etchwp/public-api';
|
|
846
|
+
*
|
|
847
|
+
* const etch = getEtch();
|
|
848
|
+
* const ids = etch.blocks.find({ type: 'text' });
|
|
849
|
+
* etch.blocks.setText(ids[0], 'Hello');
|
|
850
|
+
* await etch.saveAsync();
|
|
851
|
+
* ```
|
|
852
|
+
*/
|
|
853
|
+
declare function getEtch(options?: ConnectOptions): Etch;
|
|
854
|
+
|
|
855
|
+
/**
|
|
856
|
+
* Error codes thrown by the public `window.etch` API.
|
|
857
|
+
*
|
|
858
|
+
* The API throws typed errors (rather than returning sentinels) so that AI
|
|
859
|
+
* assistants and plugin authors can `try`/`catch` and react to a precise cause.
|
|
860
|
+
*
|
|
861
|
+
* The union ends with `(string & {})` so that codes added by newer Etch
|
|
862
|
+
* runtimes still type-check as `EtchApiErrorCode` while keeping autocomplete for
|
|
863
|
+
* the known values.
|
|
864
|
+
*/
|
|
865
|
+
type EtchApiErrorCode = 'BLOCK_NOT_FOUND' | 'WRONG_BLOCK_TYPE' | 'READONLY' | 'INVALID_ARGUMENT' | 'LOOP_NOT_FOUND' | 'STYLE_NOT_FOUND' | 'STYLESHEET_NOT_FOUND' | 'COMPONENT_NOT_FOUND' | 'POST_NOT_FOUND' | 'OPERATION_FAILED' | 'NOT_AVAILABLE' | (string & {});
|
|
866
|
+
/** Error thrown by the public Etch API (and by this client). */
|
|
867
|
+
declare class EtchApiError extends Error {
|
|
868
|
+
readonly code: EtchApiErrorCode;
|
|
869
|
+
constructor(code: EtchApiErrorCode, message: string);
|
|
870
|
+
}
|
|
871
|
+
/** Narrow an unknown caught value to an {@link EtchApiError}. */
|
|
872
|
+
declare function isEtchApiError(value: unknown): value is EtchApiError;
|
|
873
|
+
|
|
874
|
+
/**
|
|
875
|
+
* Version of the Etch scripting **contract** this package targets, independent
|
|
876
|
+
* of the Etch product version and of this package's own npm version.
|
|
877
|
+
*
|
|
878
|
+
* `0.x` signals the surface is **experimental** and may change without a major
|
|
879
|
+
* bump until it stabilizes. It matches the value returned by the runtime's
|
|
880
|
+
* {@link Etch.apiVersion} getter on `window.etch`.
|
|
881
|
+
*/
|
|
882
|
+
declare const ETCH_API_VERSION = "0.x";
|
|
883
|
+
|
|
884
|
+
export { type ArrayComponentProperty, type BlockLoopBinding, type BlockPatch, type BooleanComponentProperty, 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 EtchBlockContext, type EtchBlockJson, type EtchBlockOptions, type EtchBlockScript, type EtchBlockType, type EtchBlocksApi, type EtchComponentsApi, type EtchFieldsApi, type EtchHistoryApi, type EtchLoop, type EtchLoopConfig, type EtchLoopObj, type EtchLoopsApi, type EtchNavigationApi, type EtchStylesApi, type EtchStylesheetsApi, type EtchUiApi, type FindBlocksPredicate, type GroupComponentProperty, type MetaQueryItem, type NavigationPlace, type NumberComponentProperty, type ObjectComponentProperty, type PostCustomFieldGroupEntry, type PostCustomFieldValueEntry, type PostCustomFieldValueResponse, type PostCustomFieldValuesResponse, type PostSummary, type PublicBlockJson, type PublicComponentJson, type PublicComponentSummary, type RepeaterComponentProperty, type ResolvedCustomField, type StringComponentProperty, type StylePatch, type StylesheetInput, type StylesheetPatch, type StylesheetSummary, type StylesheetType, type TaxQueryItem, type TemplateSummary, type WpQueryArgs, type WpTermsArgs, type WpUsersArgs, getEtch, isEtchApiError, isEtchAvailable };
|