@avocadostudio-ai/shared 0.1.0 → 0.2.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.
@@ -41,6 +41,9 @@
41
41
  },
42
42
  "ogImage": {
43
43
  "type": "string"
44
+ },
45
+ "path": {
46
+ "type": "string"
44
47
  }
45
48
  },
46
49
  "additionalProperties": false
@@ -1,12 +1,261 @@
1
1
  import { z } from "zod";
2
2
  import type { FieldMeta, ListFieldMeta } from "./blocks/_registry.ts";
3
3
  export declare const jsonSchemaLikeSchema: z.ZodType<Record<string, unknown>>;
4
+ /**
5
+ * Field metadata a site may declare alongside the JSON schema.
6
+ *
7
+ * JSON Schema describes what a value *is*; this describes how a person edits
8
+ * it, and the two are not the same question. A one-word headline and a six
9
+ * sentence body are both `{"type":"string"}`, so a manifest carrying only the
10
+ * schema gives them the same one-line input — which is exactly what happened to
11
+ * every integration with a real prose field. `kind` and `multiline` have no
12
+ * JSON Schema spelling, so they have to travel beside it.
13
+ */
14
+ export declare const fieldMetaSchema: z.ZodObject<{
15
+ kind: z.ZodEnum<{
16
+ number: "number";
17
+ boolean: "boolean";
18
+ enum: "enum";
19
+ text: "text";
20
+ richtext: "richtext";
21
+ url: "url";
22
+ image: "image";
23
+ imageAlt: "imageAlt";
24
+ color: "color";
25
+ headingLevel: "headingLevel";
26
+ }>;
27
+ label: z.ZodOptional<z.ZodString>;
28
+ inlineEditable: z.ZodOptional<z.ZodBoolean>;
29
+ options: z.ZodOptional<z.ZodArray<z.ZodString>>;
30
+ imageSpec: z.ZodOptional<z.ZodObject<{
31
+ aspectRatio: z.ZodEnum<{
32
+ landscape: "landscape";
33
+ square: "square";
34
+ portrait: "portrait";
35
+ }>;
36
+ width: z.ZodNumber;
37
+ height: z.ZodNumber;
38
+ format: z.ZodOptional<z.ZodEnum<{
39
+ png: "png";
40
+ webp: "webp";
41
+ jpeg: "jpeg";
42
+ }>>;
43
+ }, z.core.$strip>>;
44
+ multiline: z.ZodOptional<z.ZodBoolean>;
45
+ inline: z.ZodOptional<z.ZodBoolean>;
46
+ decorators: z.ZodOptional<z.ZodArray<z.ZodObject<{
47
+ name: z.ZodString;
48
+ title: z.ZodOptional<z.ZodString>;
49
+ }, z.core.$strip>>>;
50
+ required: z.ZodOptional<z.ZodBoolean>;
51
+ }, z.core.$strip>;
52
+ export declare const listFieldMetaSchema: z.ZodObject<{
53
+ label: z.ZodOptional<z.ZodString>;
54
+ itemFields: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
55
+ kind: z.ZodEnum<{
56
+ number: "number";
57
+ boolean: "boolean";
58
+ enum: "enum";
59
+ text: "text";
60
+ richtext: "richtext";
61
+ url: "url";
62
+ image: "image";
63
+ imageAlt: "imageAlt";
64
+ color: "color";
65
+ headingLevel: "headingLevel";
66
+ }>;
67
+ label: z.ZodOptional<z.ZodString>;
68
+ inlineEditable: z.ZodOptional<z.ZodBoolean>;
69
+ options: z.ZodOptional<z.ZodArray<z.ZodString>>;
70
+ imageSpec: z.ZodOptional<z.ZodObject<{
71
+ aspectRatio: z.ZodEnum<{
72
+ landscape: "landscape";
73
+ square: "square";
74
+ portrait: "portrait";
75
+ }>;
76
+ width: z.ZodNumber;
77
+ height: z.ZodNumber;
78
+ format: z.ZodOptional<z.ZodEnum<{
79
+ png: "png";
80
+ webp: "webp";
81
+ jpeg: "jpeg";
82
+ }>>;
83
+ }, z.core.$strip>>;
84
+ multiline: z.ZodOptional<z.ZodBoolean>;
85
+ inline: z.ZodOptional<z.ZodBoolean>;
86
+ decorators: z.ZodOptional<z.ZodArray<z.ZodObject<{
87
+ name: z.ZodString;
88
+ title: z.ZodOptional<z.ZodString>;
89
+ }, z.core.$strip>>>;
90
+ required: z.ZodOptional<z.ZodBoolean>;
91
+ }, z.core.$strip>>>;
92
+ discriminator: z.ZodOptional<z.ZodString>;
93
+ itemFieldsByType: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodObject<{
94
+ kind: z.ZodEnum<{
95
+ number: "number";
96
+ boolean: "boolean";
97
+ enum: "enum";
98
+ text: "text";
99
+ richtext: "richtext";
100
+ url: "url";
101
+ image: "image";
102
+ imageAlt: "imageAlt";
103
+ color: "color";
104
+ headingLevel: "headingLevel";
105
+ }>;
106
+ label: z.ZodOptional<z.ZodString>;
107
+ inlineEditable: z.ZodOptional<z.ZodBoolean>;
108
+ options: z.ZodOptional<z.ZodArray<z.ZodString>>;
109
+ imageSpec: z.ZodOptional<z.ZodObject<{
110
+ aspectRatio: z.ZodEnum<{
111
+ landscape: "landscape";
112
+ square: "square";
113
+ portrait: "portrait";
114
+ }>;
115
+ width: z.ZodNumber;
116
+ height: z.ZodNumber;
117
+ format: z.ZodOptional<z.ZodEnum<{
118
+ png: "png";
119
+ webp: "webp";
120
+ jpeg: "jpeg";
121
+ }>>;
122
+ }, z.core.$strip>>;
123
+ multiline: z.ZodOptional<z.ZodBoolean>;
124
+ inline: z.ZodOptional<z.ZodBoolean>;
125
+ decorators: z.ZodOptional<z.ZodArray<z.ZodObject<{
126
+ name: z.ZodString;
127
+ title: z.ZodOptional<z.ZodString>;
128
+ }, z.core.$strip>>>;
129
+ required: z.ZodOptional<z.ZodBoolean>;
130
+ }, z.core.$strip>>>>;
131
+ }, z.core.$strip>;
4
132
  export declare const blockDefinitionSchema: z.ZodObject<{
5
133
  type: z.ZodString;
6
134
  displayName: z.ZodOptional<z.ZodString>;
7
135
  editablePaths: z.ZodOptional<z.ZodArray<z.ZodString>>;
8
136
  propsSchema: z.ZodType<Record<string, unknown>, unknown, z.core.$ZodTypeInternals<Record<string, unknown>, unknown>>;
9
137
  defaultProps: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
138
+ fields: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
139
+ kind: z.ZodEnum<{
140
+ number: "number";
141
+ boolean: "boolean";
142
+ enum: "enum";
143
+ text: "text";
144
+ richtext: "richtext";
145
+ url: "url";
146
+ image: "image";
147
+ imageAlt: "imageAlt";
148
+ color: "color";
149
+ headingLevel: "headingLevel";
150
+ }>;
151
+ label: z.ZodOptional<z.ZodString>;
152
+ inlineEditable: z.ZodOptional<z.ZodBoolean>;
153
+ options: z.ZodOptional<z.ZodArray<z.ZodString>>;
154
+ imageSpec: z.ZodOptional<z.ZodObject<{
155
+ aspectRatio: z.ZodEnum<{
156
+ landscape: "landscape";
157
+ square: "square";
158
+ portrait: "portrait";
159
+ }>;
160
+ width: z.ZodNumber;
161
+ height: z.ZodNumber;
162
+ format: z.ZodOptional<z.ZodEnum<{
163
+ png: "png";
164
+ webp: "webp";
165
+ jpeg: "jpeg";
166
+ }>>;
167
+ }, z.core.$strip>>;
168
+ multiline: z.ZodOptional<z.ZodBoolean>;
169
+ inline: z.ZodOptional<z.ZodBoolean>;
170
+ decorators: z.ZodOptional<z.ZodArray<z.ZodObject<{
171
+ name: z.ZodString;
172
+ title: z.ZodOptional<z.ZodString>;
173
+ }, z.core.$strip>>>;
174
+ required: z.ZodOptional<z.ZodBoolean>;
175
+ }, z.core.$strip>>>;
176
+ listFields: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
177
+ label: z.ZodOptional<z.ZodString>;
178
+ itemFields: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
179
+ kind: z.ZodEnum<{
180
+ number: "number";
181
+ boolean: "boolean";
182
+ enum: "enum";
183
+ text: "text";
184
+ richtext: "richtext";
185
+ url: "url";
186
+ image: "image";
187
+ imageAlt: "imageAlt";
188
+ color: "color";
189
+ headingLevel: "headingLevel";
190
+ }>;
191
+ label: z.ZodOptional<z.ZodString>;
192
+ inlineEditable: z.ZodOptional<z.ZodBoolean>;
193
+ options: z.ZodOptional<z.ZodArray<z.ZodString>>;
194
+ imageSpec: z.ZodOptional<z.ZodObject<{
195
+ aspectRatio: z.ZodEnum<{
196
+ landscape: "landscape";
197
+ square: "square";
198
+ portrait: "portrait";
199
+ }>;
200
+ width: z.ZodNumber;
201
+ height: z.ZodNumber;
202
+ format: z.ZodOptional<z.ZodEnum<{
203
+ png: "png";
204
+ webp: "webp";
205
+ jpeg: "jpeg";
206
+ }>>;
207
+ }, z.core.$strip>>;
208
+ multiline: z.ZodOptional<z.ZodBoolean>;
209
+ inline: z.ZodOptional<z.ZodBoolean>;
210
+ decorators: z.ZodOptional<z.ZodArray<z.ZodObject<{
211
+ name: z.ZodString;
212
+ title: z.ZodOptional<z.ZodString>;
213
+ }, z.core.$strip>>>;
214
+ required: z.ZodOptional<z.ZodBoolean>;
215
+ }, z.core.$strip>>>;
216
+ discriminator: z.ZodOptional<z.ZodString>;
217
+ itemFieldsByType: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodObject<{
218
+ kind: z.ZodEnum<{
219
+ number: "number";
220
+ boolean: "boolean";
221
+ enum: "enum";
222
+ text: "text";
223
+ richtext: "richtext";
224
+ url: "url";
225
+ image: "image";
226
+ imageAlt: "imageAlt";
227
+ color: "color";
228
+ headingLevel: "headingLevel";
229
+ }>;
230
+ label: z.ZodOptional<z.ZodString>;
231
+ inlineEditable: z.ZodOptional<z.ZodBoolean>;
232
+ options: z.ZodOptional<z.ZodArray<z.ZodString>>;
233
+ imageSpec: z.ZodOptional<z.ZodObject<{
234
+ aspectRatio: z.ZodEnum<{
235
+ landscape: "landscape";
236
+ square: "square";
237
+ portrait: "portrait";
238
+ }>;
239
+ width: z.ZodNumber;
240
+ height: z.ZodNumber;
241
+ format: z.ZodOptional<z.ZodEnum<{
242
+ png: "png";
243
+ webp: "webp";
244
+ jpeg: "jpeg";
245
+ }>>;
246
+ }, z.core.$strip>>;
247
+ multiline: z.ZodOptional<z.ZodBoolean>;
248
+ inline: z.ZodOptional<z.ZodBoolean>;
249
+ decorators: z.ZodOptional<z.ZodArray<z.ZodObject<{
250
+ name: z.ZodString;
251
+ title: z.ZodOptional<z.ZodString>;
252
+ }, z.core.$strip>>>;
253
+ required: z.ZodOptional<z.ZodBoolean>;
254
+ }, z.core.$strip>>>>;
255
+ }, z.core.$strip>>>;
256
+ category: z.ZodOptional<z.ZodString>;
257
+ description: z.ZodOptional<z.ZodString>;
258
+ chrome: z.ZodOptional<z.ZodBoolean>;
10
259
  }, z.core.$strip>;
11
260
  export declare const blockManifestSchema: z.ZodObject<{
12
261
  version: z.ZodNumber;
@@ -16,13 +265,207 @@ export declare const blockManifestSchema: z.ZodObject<{
16
265
  editablePaths: z.ZodOptional<z.ZodArray<z.ZodString>>;
17
266
  propsSchema: z.ZodType<Record<string, unknown>, unknown, z.core.$ZodTypeInternals<Record<string, unknown>, unknown>>;
18
267
  defaultProps: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
268
+ fields: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
269
+ kind: z.ZodEnum<{
270
+ number: "number";
271
+ boolean: "boolean";
272
+ enum: "enum";
273
+ text: "text";
274
+ richtext: "richtext";
275
+ url: "url";
276
+ image: "image";
277
+ imageAlt: "imageAlt";
278
+ color: "color";
279
+ headingLevel: "headingLevel";
280
+ }>;
281
+ label: z.ZodOptional<z.ZodString>;
282
+ inlineEditable: z.ZodOptional<z.ZodBoolean>;
283
+ options: z.ZodOptional<z.ZodArray<z.ZodString>>;
284
+ imageSpec: z.ZodOptional<z.ZodObject<{
285
+ aspectRatio: z.ZodEnum<{
286
+ landscape: "landscape";
287
+ square: "square";
288
+ portrait: "portrait";
289
+ }>;
290
+ width: z.ZodNumber;
291
+ height: z.ZodNumber;
292
+ format: z.ZodOptional<z.ZodEnum<{
293
+ png: "png";
294
+ webp: "webp";
295
+ jpeg: "jpeg";
296
+ }>>;
297
+ }, z.core.$strip>>;
298
+ multiline: z.ZodOptional<z.ZodBoolean>;
299
+ inline: z.ZodOptional<z.ZodBoolean>;
300
+ decorators: z.ZodOptional<z.ZodArray<z.ZodObject<{
301
+ name: z.ZodString;
302
+ title: z.ZodOptional<z.ZodString>;
303
+ }, z.core.$strip>>>;
304
+ required: z.ZodOptional<z.ZodBoolean>;
305
+ }, z.core.$strip>>>;
306
+ listFields: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
307
+ label: z.ZodOptional<z.ZodString>;
308
+ itemFields: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
309
+ kind: z.ZodEnum<{
310
+ number: "number";
311
+ boolean: "boolean";
312
+ enum: "enum";
313
+ text: "text";
314
+ richtext: "richtext";
315
+ url: "url";
316
+ image: "image";
317
+ imageAlt: "imageAlt";
318
+ color: "color";
319
+ headingLevel: "headingLevel";
320
+ }>;
321
+ label: z.ZodOptional<z.ZodString>;
322
+ inlineEditable: z.ZodOptional<z.ZodBoolean>;
323
+ options: z.ZodOptional<z.ZodArray<z.ZodString>>;
324
+ imageSpec: z.ZodOptional<z.ZodObject<{
325
+ aspectRatio: z.ZodEnum<{
326
+ landscape: "landscape";
327
+ square: "square";
328
+ portrait: "portrait";
329
+ }>;
330
+ width: z.ZodNumber;
331
+ height: z.ZodNumber;
332
+ format: z.ZodOptional<z.ZodEnum<{
333
+ png: "png";
334
+ webp: "webp";
335
+ jpeg: "jpeg";
336
+ }>>;
337
+ }, z.core.$strip>>;
338
+ multiline: z.ZodOptional<z.ZodBoolean>;
339
+ inline: z.ZodOptional<z.ZodBoolean>;
340
+ decorators: z.ZodOptional<z.ZodArray<z.ZodObject<{
341
+ name: z.ZodString;
342
+ title: z.ZodOptional<z.ZodString>;
343
+ }, z.core.$strip>>>;
344
+ required: z.ZodOptional<z.ZodBoolean>;
345
+ }, z.core.$strip>>>;
346
+ discriminator: z.ZodOptional<z.ZodString>;
347
+ itemFieldsByType: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodObject<{
348
+ kind: z.ZodEnum<{
349
+ number: "number";
350
+ boolean: "boolean";
351
+ enum: "enum";
352
+ text: "text";
353
+ richtext: "richtext";
354
+ url: "url";
355
+ image: "image";
356
+ imageAlt: "imageAlt";
357
+ color: "color";
358
+ headingLevel: "headingLevel";
359
+ }>;
360
+ label: z.ZodOptional<z.ZodString>;
361
+ inlineEditable: z.ZodOptional<z.ZodBoolean>;
362
+ options: z.ZodOptional<z.ZodArray<z.ZodString>>;
363
+ imageSpec: z.ZodOptional<z.ZodObject<{
364
+ aspectRatio: z.ZodEnum<{
365
+ landscape: "landscape";
366
+ square: "square";
367
+ portrait: "portrait";
368
+ }>;
369
+ width: z.ZodNumber;
370
+ height: z.ZodNumber;
371
+ format: z.ZodOptional<z.ZodEnum<{
372
+ png: "png";
373
+ webp: "webp";
374
+ jpeg: "jpeg";
375
+ }>>;
376
+ }, z.core.$strip>>;
377
+ multiline: z.ZodOptional<z.ZodBoolean>;
378
+ inline: z.ZodOptional<z.ZodBoolean>;
379
+ decorators: z.ZodOptional<z.ZodArray<z.ZodObject<{
380
+ name: z.ZodString;
381
+ title: z.ZodOptional<z.ZodString>;
382
+ }, z.core.$strip>>>;
383
+ required: z.ZodOptional<z.ZodBoolean>;
384
+ }, z.core.$strip>>>>;
385
+ }, z.core.$strip>>>;
386
+ category: z.ZodOptional<z.ZodString>;
387
+ description: z.ZodOptional<z.ZodString>;
388
+ chrome: z.ZodOptional<z.ZodBoolean>;
19
389
  }, z.core.$strip>>;
20
390
  }, z.core.$strip>;
21
391
  export type BlockDefinition = z.infer<typeof blockDefinitionSchema>;
22
392
  export type BlockManifest = z.infer<typeof blockManifestSchema>;
393
+ /** Where a value stopped matching its schema, and why. */
394
+ export type ManifestSchemaIssue = {
395
+ path: string;
396
+ message: string;
397
+ };
398
+ /**
399
+ * Validate, and say what went wrong.
400
+ *
401
+ * The boolean form below could only report "does not match block manifest
402
+ * schema" — which is what an integrator saw when a plan wrote one prop of the
403
+ * wrong type, on a block with a dozen of them. The same failing patch reported
404
+ * through the registered-schema path said "bullets: expected string, received
405
+ * array". Two validators, one useless message, and the useful one was the path
406
+ * NOT taken when a manifest was supplied — so custom blocks, the case that
407
+ * needs the detail most, got the least.
408
+ *
409
+ * Returns the first issue found, or null when the value matches. It reports on
410
+ * exactly the constraints the boolean form enforced, with one deliberate
411
+ * loosening since — a key holding `undefined` counts as absent, see below.
412
+ * Note that `enum` and `const` are among the constraints it does not enforce —
413
+ * a value outside a declared enum still passes here.
414
+ */
415
+ export declare function findManifestSchemaIssue(schema: Record<string, unknown>, value: unknown, path?: string): ManifestSchemaIssue | null;
23
416
  export declare function validateByJsonSchemaLike(schema: Record<string, unknown>, value: unknown): boolean;
417
+ /**
418
+ * A ProseMirror/Tiptap richtext document self-identifies: it is an object whose
419
+ * `type` is pinned to the literal `"doc"`. We key off that signature (rather
420
+ * than a CMS-specific annotation) so any block declaring a `{type:"doc",content}`
421
+ * field gets the richtext editor — and the underlying document is edited as-is,
422
+ * not flattened to a string.
423
+ */
424
+ export declare function isProseMirrorDocSchema(schema: unknown): boolean;
24
425
  export declare function deriveFieldMetaFromSchema(propsSchema: Record<string, unknown>): {
25
426
  fields: Record<string, FieldMeta>;
26
427
  listFields: Record<string, ListFieldMeta>;
27
428
  };
28
429
  export declare function validateManifestDefaultProps(blocks: BlockDefinition[]): string | null;
430
+ /**
431
+ * The field metadata a manifest block should actually be edited with.
432
+ *
433
+ * Derived from the JSON schema, then refined by whatever the definition
434
+ * declared. Every surface that renders a manifest block — the property panel,
435
+ * the Puck adapter, the planner's block contracts, an integration's own
436
+ * boundary code — has to agree on this, so it lives here rather than being
437
+ * re-derived four times with four sets of assumptions.
438
+ *
439
+ * Two rules:
440
+ *
441
+ * - `propsSchema` decides *which* props exist. A declared entry for a key the
442
+ * schema does not expose is ignored, not added — otherwise a stale manifest
443
+ * would put a control on a prop the block cannot store.
444
+ * - A declared entry is merged *over* the derived one, key by key, so a site
445
+ * can supply just `multiline` and keep the label and options that were
446
+ * inferred for it.
447
+ */
448
+ export declare function resolveManifestFieldMeta(definition: {
449
+ propsSchema: Record<string, unknown>;
450
+ fields?: Record<string, unknown>;
451
+ listFields?: Record<string, unknown>;
452
+ }): {
453
+ fields: Record<string, FieldMeta>;
454
+ listFields: Record<string, ListFieldMeta>;
455
+ };
456
+ /**
457
+ * Build a manifest describing every block type registered in THIS process.
458
+ *
459
+ * Built fresh on every call rather than memoised, because the registry is not
460
+ * fixed at module load: a site's custom blocks call `registerBlock()` from its
461
+ * own `blocks/register.ts`, which may run after this module was first imported.
462
+ * A cached manifest is a manifest missing exactly the blocks the caller most
463
+ * needs to know about.
464
+ *
465
+ * This lives in `shared`, not in the SDK, because two very different consumers
466
+ * need the same answer. The editor asks the *site* for it over
467
+ * `/api/editor/blocks`; an MCP agent asks the *orchestrator*, which in library
468
+ * mode is mounted in that same site process and so shares its registry. Keeping
469
+ * one builder is what makes those two answers the same answer.
470
+ */
471
+ export declare function buildBlockManifest(): BlockManifest;