@abraca/schema 2.3.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.
Files changed (92) hide show
  1. package/dist/abracadabra-schema.cjs +853 -0
  2. package/dist/abracadabra-schema.cjs.map +1 -0
  3. package/dist/abracadabra-schema.esm.js +781 -0
  4. package/dist/abracadabra-schema.esm.js.map +1 -0
  5. package/dist/index.d.ts +2538 -0
  6. package/package.json +41 -0
  7. package/src/crdt.ts +63 -0
  8. package/src/generated/calendar.ts +35 -0
  9. package/src/generated/chart.ts +35 -0
  10. package/src/generated/checklist.ts +35 -0
  11. package/src/generated/dashboard.ts +35 -0
  12. package/src/generated/doc.ts +35 -0
  13. package/src/generated/gallery.ts +35 -0
  14. package/src/generated/graph.ts +35 -0
  15. package/src/generated/json-schema/calendar.json +140 -0
  16. package/src/generated/json-schema/chart.json +164 -0
  17. package/src/generated/json-schema/checklist.json +138 -0
  18. package/src/generated/json-schema/dashboard.json +122 -0
  19. package/src/generated/json-schema/doc.json +122 -0
  20. package/src/generated/json-schema/gallery.json +157 -0
  21. package/src/generated/json-schema/graph.json +125 -0
  22. package/src/generated/json-schema/kanban.json +145 -0
  23. package/src/generated/json-schema/map.json +125 -0
  24. package/src/generated/json-schema/outline.json +122 -0
  25. package/src/generated/json-schema/overview.json +122 -0
  26. package/src/generated/json-schema/plugin-manifest.json +221 -0
  27. package/src/generated/json-schema/prose.json +122 -0
  28. package/src/generated/json-schema/sheets.json +135 -0
  29. package/src/generated/json-schema/slides.json +129 -0
  30. package/src/generated/json-schema/table.json +136 -0
  31. package/src/generated/json-schema/timeline.json +122 -0
  32. package/src/generated/kanban.ts +35 -0
  33. package/src/generated/map.ts +35 -0
  34. package/src/generated/markdown/calendar.md +59 -0
  35. package/src/generated/markdown/chart.md +62 -0
  36. package/src/generated/markdown/checklist.md +58 -0
  37. package/src/generated/markdown/dashboard.md +56 -0
  38. package/src/generated/markdown/doc.md +56 -0
  39. package/src/generated/markdown/gallery.md +61 -0
  40. package/src/generated/markdown/graph.md +57 -0
  41. package/src/generated/markdown/kanban.md +62 -0
  42. package/src/generated/markdown/map.md +57 -0
  43. package/src/generated/markdown/outline.md +56 -0
  44. package/src/generated/markdown/overview.md +56 -0
  45. package/src/generated/markdown/prose.md +56 -0
  46. package/src/generated/markdown/sheets.md +59 -0
  47. package/src/generated/markdown/slides.md +57 -0
  48. package/src/generated/markdown/table.md +58 -0
  49. package/src/generated/markdown/timeline.md +56 -0
  50. package/src/generated/outline.ts +35 -0
  51. package/src/generated/overview.ts +35 -0
  52. package/src/generated/prose.ts +35 -0
  53. package/src/generated/rust/calendar.rs +125 -0
  54. package/src/generated/rust/chart.rs +151 -0
  55. package/src/generated/rust/checklist.rs +123 -0
  56. package/src/generated/rust/dashboard.rs +101 -0
  57. package/src/generated/rust/doc.rs +101 -0
  58. package/src/generated/rust/gallery.rs +146 -0
  59. package/src/generated/rust/graph.rs +104 -0
  60. package/src/generated/rust/kanban.rs +127 -0
  61. package/src/generated/rust/map.rs +104 -0
  62. package/src/generated/rust/outline.rs +101 -0
  63. package/src/generated/rust/overview.rs +101 -0
  64. package/src/generated/rust/prose.rs +101 -0
  65. package/src/generated/rust/sheets.rs +110 -0
  66. package/src/generated/rust/slides.rs +111 -0
  67. package/src/generated/rust/table.rs +121 -0
  68. package/src/generated/rust/timeline.rs +101 -0
  69. package/src/generated/sheets.ts +35 -0
  70. package/src/generated/slides.ts +35 -0
  71. package/src/generated/table.ts +35 -0
  72. package/src/generated/timeline.ts +35 -0
  73. package/src/index.ts +389 -0
  74. package/src/manifest/plugin-manifest.ts +212 -0
  75. package/src/query.ts +150 -0
  76. package/src/types/calendar.ts +23 -0
  77. package/src/types/chart.ts +36 -0
  78. package/src/types/checklist.ts +22 -0
  79. package/src/types/dashboard.ts +18 -0
  80. package/src/types/doc.ts +19 -0
  81. package/src/types/gallery.ts +24 -0
  82. package/src/types/graph.ts +21 -0
  83. package/src/types/kanban.ts +27 -0
  84. package/src/types/map.ts +21 -0
  85. package/src/types/outline.ts +17 -0
  86. package/src/types/overview.ts +17 -0
  87. package/src/types/prose.ts +19 -0
  88. package/src/types/sheets.ts +24 -0
  89. package/src/types/slides.ts +22 -0
  90. package/src/types/table.ts +22 -0
  91. package/src/types/timeline.ts +18 -0
  92. package/src/types/universal.ts +59 -0
@@ -0,0 +1,853 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ let zod = require("zod");
3
+
4
+ //#region packages/schema/src/crdt.ts
5
+ /** Y.Text marker. Reads as opaque CRDT — schema does not validate the contents. */
6
+ function ytext() {
7
+ return zod.z.custom(() => true).meta({ crdt: "ytext" });
8
+ }
9
+ /** Y.Array<T> marker. Element schema is preserved in metadata for codegen. */
10
+ function yarray(element) {
11
+ return zod.z.custom(() => true).meta({
12
+ crdt: "yarray",
13
+ element
14
+ });
15
+ }
16
+ /** Y.Map<T> marker. Value schema is preserved in metadata for codegen. */
17
+ function ymap(value) {
18
+ return zod.z.custom(() => true).meta({
19
+ crdt: "ymap",
20
+ element: value
21
+ });
22
+ }
23
+ /** Inspect a Zod schema for a CRDT marker. Returns undefined for non-CRDT schemas. */
24
+ function crdtMetaOf(schema) {
25
+ const meta = schema.meta();
26
+ if (meta && typeof meta.crdt === "string") return meta;
27
+ }
28
+
29
+ //#endregion
30
+ //#region packages/schema/src/types/universal.ts
31
+ /**
32
+ * Universal meta keys that may appear on any typed root.
33
+ *
34
+ * Mirrors the canonical list in `page-type-guidelines.md` §4.5 plus the
35
+ * three cross-cutting cover keys (`coverUploadId`/`coverDocId`/
36
+ * `coverMimeType`). Every key is optional. Per-type schemas merge this
37
+ * object via `UniversalMeta.extend({ ... })`.
38
+ *
39
+ * Descendant-only keys (cell formatting, geo, dashboard layout, spatial
40
+ * transforms, EXIF media metadata, etc.) are deliberately excluded —
41
+ * descendants are untyped and unvalidated by the registry, so those
42
+ * keys flow through the untyped meta path without per-type constraints.
43
+ */
44
+ const hexColor = zod.z.string().regex(/^#[0-9a-fA-F]{6}$/);
45
+ const hhmm = zod.z.string().regex(/^[0-2]\d:[0-5]\d$/);
46
+ const UniversalMeta = zod.z.strictObject({
47
+ color: hexColor.optional(),
48
+ icon: zod.z.string().optional(),
49
+ datetimeStart: zod.z.iso.datetime().optional(),
50
+ datetimeEnd: zod.z.iso.datetime().optional(),
51
+ allDay: zod.z.boolean().optional(),
52
+ dateStart: zod.z.iso.date().optional(),
53
+ dateEnd: zod.z.iso.date().optional(),
54
+ timeStart: hhmm.optional(),
55
+ timeEnd: hhmm.optional(),
56
+ tags: zod.z.array(zod.z.string()).optional(),
57
+ checked: zod.z.boolean().optional(),
58
+ priority: zod.z.number().int().min(0).max(4).optional(),
59
+ status: zod.z.string().optional(),
60
+ rating: zod.z.number().min(0).max(5).optional(),
61
+ url: zod.z.string().optional(),
62
+ email: zod.z.string().optional(),
63
+ phone: zod.z.string().optional(),
64
+ number: zod.z.number().optional(),
65
+ unit: zod.z.string().optional(),
66
+ subtitle: zod.z.string().optional(),
67
+ note: zod.z.string().optional(),
68
+ taskProgress: zod.z.number().min(0).max(100).optional(),
69
+ assignedTo: zod.z.string().optional(),
70
+ coverUploadId: zod.z.string().optional(),
71
+ coverDocId: zod.z.string().optional(),
72
+ coverMimeType: zod.z.string().optional(),
73
+ __schemaVersion: zod.z.number().int().min(1).optional()
74
+ });
75
+
76
+ //#endregion
77
+ //#region packages/schema/src/query.ts
78
+ /**
79
+ * V2 query layer — predicate AST.
80
+ *
81
+ * Mirrors InstantDB / Prisma `where` shapes: column → predicate pairs
82
+ * composed with boolean AND/OR/NOT. The Rust compiler at
83
+ * `crates/abracadabra/src/query.rs` walks the same shape and emits
84
+ * indexed SQL against `doc_meta_index`.
85
+ *
86
+ * Columns are restricted to the universal-meta projection: `priority`,
87
+ * `dateStart`, `dateEnd`, `tags`, `status`, `assignedTo`. Anything else
88
+ * is rejected. Adding a column requires both:
89
+ * 1. A new column on `doc_meta_index` (migration in `abracadabra-rs`)
90
+ * 2. A new entry in `META_COLUMNS` below
91
+ *
92
+ * The schema is intentionally narrow — only the operators the v2 query
93
+ * layer can actually execute against indexed columns are accepted. New
94
+ * operators require server changes; the schema is the contract.
95
+ */
96
+ /**
97
+ * Whitelisted indexed columns on `doc_meta_index`. Adding to this list
98
+ * requires a parallel migration on the server. Order is the canonical
99
+ * documentation order — not enforced.
100
+ */
101
+ const META_COLUMNS = [
102
+ "priority",
103
+ "dateStart",
104
+ "dateEnd",
105
+ "tags",
106
+ "status",
107
+ "assignedTo"
108
+ ];
109
+ zod.z.enum(META_COLUMNS);
110
+ const ScalarValue = zod.z.union([
111
+ zod.z.string(),
112
+ zod.z.number(),
113
+ zod.z.boolean(),
114
+ zod.z.null()
115
+ ]);
116
+ /**
117
+ * Numeric / lexicographic comparison operators. Apply to integer
118
+ * (`priority`), date (`dateStart`, `dateEnd`), and string
119
+ * (`status`, `assignedTo`) columns. Strings compare lexicographically
120
+ * — useful for date filtering on the SQLite path where dates are TEXT.
121
+ */
122
+ const RangeOps = zod.z.strictObject({
123
+ eq: ScalarValue.optional(),
124
+ neq: ScalarValue.optional(),
125
+ gt: ScalarValue.optional(),
126
+ gte: ScalarValue.optional(),
127
+ lt: ScalarValue.optional(),
128
+ lte: ScalarValue.optional(),
129
+ in: zod.z.array(ScalarValue).optional(),
130
+ between: zod.z.tuple([ScalarValue, ScalarValue]).optional()
131
+ });
132
+ /**
133
+ * Operators for the `tags` column. `tags` is a JSON array.
134
+ * `contains: "x"` matches when the array includes the string `x`.
135
+ * `containsAll: ["x","y"]` requires all listed tags to be present.
136
+ * `containsAny: ["x","y"]` requires at least one.
137
+ */
138
+ const TagOps = zod.z.strictObject({
139
+ contains: zod.z.string().optional(),
140
+ containsAll: zod.z.array(zod.z.string()).optional(),
141
+ containsAny: zod.z.array(zod.z.string()).optional(),
142
+ isEmpty: zod.z.boolean().optional()
143
+ });
144
+ /** Per-column predicate. `null` => column IS NULL. */
145
+ const ColumnPredicate = zod.z.union([
146
+ ScalarValue,
147
+ RangeOps,
148
+ TagOps
149
+ ]);
150
+ const WhereClauseSchema = zod.z.lazy(() => zod.z.strictObject({
151
+ AND: zod.z.array(WhereClauseSchema).optional(),
152
+ OR: zod.z.array(WhereClauseSchema).optional(),
153
+ NOT: WhereClauseSchema.optional(),
154
+ priority: ColumnPredicate.optional(),
155
+ dateStart: ColumnPredicate.optional(),
156
+ dateEnd: ColumnPredicate.optional(),
157
+ tags: ColumnPredicate.optional(),
158
+ status: ColumnPredicate.optional(),
159
+ assignedTo: ColumnPredicate.optional()
160
+ }));
161
+ /**
162
+ * Parse + normalise a raw `where` object. Returns a discriminated
163
+ * result so call sites can render server-friendly error messages on
164
+ * the wire.
165
+ */
166
+ function parseWhereClause(raw) {
167
+ const parsed = WhereClauseSchema.safeParse(raw);
168
+ if (parsed.success) return {
169
+ ok: true,
170
+ value: parsed.data
171
+ };
172
+ return {
173
+ ok: false,
174
+ errors: parsed.error.issues.map((i) => ({
175
+ path: i.path,
176
+ message: i.message
177
+ }))
178
+ };
179
+ }
180
+
181
+ //#endregion
182
+ //#region packages/schema/src/types/doc.ts
183
+ /**
184
+ * `doc` — the default rich-text page type. Body is a TipTap-backed
185
+ * `Y.Text`; descendants are untyped tree entries.
186
+ */
187
+ const DocMeta = UniversalMeta;
188
+ const Doc = defineDocType({
189
+ name: "doc",
190
+ version: 1,
191
+ meta: DocMeta,
192
+ body: ytext()
193
+ });
194
+ const docSchema = defineSchema({ types: [Doc] });
195
+
196
+ //#endregion
197
+ //#region packages/schema/src/types/prose.ts
198
+ /**
199
+ * `prose` — long-form prose with serif typography. Same body shape as
200
+ * `doc` (Y.Text TipTap content); descendants are untyped.
201
+ */
202
+ const ProseMeta = UniversalMeta;
203
+ const Prose = defineDocType({
204
+ name: "prose",
205
+ version: 1,
206
+ meta: ProseMeta,
207
+ body: ytext()
208
+ });
209
+ const proseSchema = defineSchema({ types: [Prose] });
210
+
211
+ //#endregion
212
+ //#region packages/schema/src/types/kanban.ts
213
+ /**
214
+ * `kanban` — drag-and-drop board. Direct children are columns;
215
+ * grandchildren are cards. Both descendants are untyped tree entries
216
+ * — only the board itself carries `type: "kanban"` and the per-board
217
+ * view-config keys below.
218
+ */
219
+ const KanbanMeta = UniversalMeta.extend({
220
+ kanbanColumnWidth: zod.z.enum([
221
+ "narrow",
222
+ "default",
223
+ "wide"
224
+ ]).optional(),
225
+ kanbanShowIcon: zod.z.boolean().optional(),
226
+ kanbanShowTags: zod.z.boolean().optional(),
227
+ kanbanShowPriority: zod.z.boolean().optional(),
228
+ kanbanShowDueDate: zod.z.boolean().optional(),
229
+ kanbanShowCover: zod.z.boolean().optional()
230
+ });
231
+ const Kanban = defineDocType({
232
+ name: "kanban",
233
+ version: 1,
234
+ meta: KanbanMeta
235
+ });
236
+ const kanbanSchema = defineSchema({ types: [Kanban] });
237
+
238
+ //#endregion
239
+ //#region packages/schema/src/types/gallery.ts
240
+ /**
241
+ * `gallery` — visual grid of items with rich content. Direct children
242
+ * are items (untyped tree entries).
243
+ */
244
+ const GalleryMeta = UniversalMeta.extend({
245
+ galleryColumns: zod.z.number().int().min(1).max(6).optional(),
246
+ galleryAspect: zod.z.enum([
247
+ "square",
248
+ "4:3",
249
+ "3:2",
250
+ "16:9",
251
+ "free"
252
+ ]).optional(),
253
+ galleryCardStyle: zod.z.enum([
254
+ "default",
255
+ "compact",
256
+ "detailed"
257
+ ]).optional(),
258
+ galleryShowLabels: zod.z.boolean().optional(),
259
+ gallerySortBy: zod.z.enum([
260
+ "manual",
261
+ "date",
262
+ "name",
263
+ "rating"
264
+ ]).optional()
265
+ });
266
+ const Gallery = defineDocType({
267
+ name: "gallery",
268
+ version: 1,
269
+ meta: GalleryMeta
270
+ });
271
+ const gallerySchema = defineSchema({ types: [Gallery] });
272
+
273
+ //#endregion
274
+ //#region packages/schema/src/types/table.ts
275
+ /**
276
+ * `table` — collaborative spreadsheet. Direct children are columns;
277
+ * grandchildren are positional cells (row N = Nth child of each
278
+ * column). Descendants are untyped.
279
+ */
280
+ const TableMeta = UniversalMeta.extend({
281
+ tableMode: zod.z.enum(["hierarchy", "flat"]).optional(),
282
+ tableSortDir: zod.z.enum(["asc", "desc"]).optional()
283
+ });
284
+ const Table = defineDocType({
285
+ name: "table",
286
+ version: 1,
287
+ meta: TableMeta
288
+ });
289
+ const tableSchema = defineSchema({ types: [Table] });
290
+
291
+ //#endregion
292
+ //#region packages/schema/src/types/outline.ts
293
+ /**
294
+ * `outline` — hierarchical outline with keyboard navigation. Unlimited
295
+ * descendant nesting; all descendants are untyped.
296
+ */
297
+ const OutlineMeta = UniversalMeta;
298
+ const Outline = defineDocType({
299
+ name: "outline",
300
+ version: 1,
301
+ meta: OutlineMeta
302
+ });
303
+ const outlineSchema = defineSchema({ types: [Outline] });
304
+
305
+ //#endregion
306
+ //#region packages/schema/src/types/checklist.ts
307
+ /**
308
+ * `checklist` — collaborative checklist with sub-tasks and due dates.
309
+ * Unlimited descendant nesting; all descendants are untyped (per-task
310
+ * `checked` / `priority` / `dateEnd` flow through universal keys).
311
+ */
312
+ const ChecklistMeta = UniversalMeta.extend({
313
+ checklistFilter: zod.z.enum([
314
+ "all",
315
+ "active",
316
+ "completed"
317
+ ]).optional(),
318
+ checklistSort: zod.z.enum([
319
+ "manual",
320
+ "priority",
321
+ "due"
322
+ ]).optional()
323
+ });
324
+ const Checklist = defineDocType({
325
+ name: "checklist",
326
+ version: 1,
327
+ meta: ChecklistMeta
328
+ });
329
+ const checklistSchema = defineSchema({ types: [Checklist] });
330
+
331
+ //#endregion
332
+ //#region packages/schema/src/types/graph.ts
333
+ /**
334
+ * `graph` — force-directed knowledge graph rendering. Descendants are
335
+ * untyped (per-node `graphX` / `graphY` / `graphPinned` are written to
336
+ * descendant meta but not validated by the registry).
337
+ */
338
+ const GraphMeta = UniversalMeta.extend({ showRefEdges: zod.z.boolean().optional() });
339
+ const Graph = defineDocType({
340
+ name: "graph",
341
+ version: 1,
342
+ meta: GraphMeta
343
+ });
344
+ const graphSchema = defineSchema({ types: [Graph] });
345
+
346
+ //#endregion
347
+ //#region packages/schema/src/types/timeline.ts
348
+ /**
349
+ * `timeline` — Gantt-style project timeline. Direct children are epics;
350
+ * grandchildren are tasks (both untyped). Per-bar `dateStart` /
351
+ * `dateEnd` / `taskProgress` / `color` use universal keys.
352
+ */
353
+ const TimelineMeta = UniversalMeta;
354
+ const Timeline = defineDocType({
355
+ name: "timeline",
356
+ version: 1,
357
+ meta: TimelineMeta
358
+ });
359
+ const timelineSchema = defineSchema({ types: [Timeline] });
360
+
361
+ //#endregion
362
+ //#region packages/schema/src/types/calendar.ts
363
+ /**
364
+ * `calendar` — event calendar with month/week/day views. Direct
365
+ * children are events (untyped); per-event `datetimeStart` /
366
+ * `datetimeEnd` / `allDay` / `color` use universal keys.
367
+ */
368
+ const CalendarMeta = UniversalMeta.extend({
369
+ calendarWeekStart: zod.z.enum(["sun", "mon"]).optional(),
370
+ calendarView: zod.z.enum([
371
+ "month",
372
+ "week",
373
+ "day"
374
+ ]).optional(),
375
+ calendarShowWeekNumbers: zod.z.boolean().optional()
376
+ });
377
+ const Calendar = defineDocType({
378
+ name: "calendar",
379
+ version: 1,
380
+ meta: CalendarMeta
381
+ });
382
+ const calendarSchema = defineSchema({ types: [Calendar] });
383
+
384
+ //#endregion
385
+ //#region packages/schema/src/types/map.ts
386
+ /**
387
+ * `map` — collaborative world map. Direct children are markers / lines
388
+ * / measure entries (untyped, distinguished by descendant `geoType`
389
+ * key flowing through the untyped meta path).
390
+ */
391
+ const MapMeta = UniversalMeta.extend({ mapShowLabels: zod.z.boolean().optional() });
392
+ const MapDocType = defineDocType({
393
+ name: "map",
394
+ version: 1,
395
+ meta: MapMeta
396
+ });
397
+ const mapSchema = defineSchema({ types: [MapDocType] });
398
+
399
+ //#endregion
400
+ //#region packages/schema/src/types/dashboard.ts
401
+ /**
402
+ * `dashboard` — arranges documents as draggable icons / widgets.
403
+ * Descendants are untyped; per-item `desk*` layout keys flow through
404
+ * the untyped meta path.
405
+ */
406
+ const DashboardMeta = UniversalMeta;
407
+ const Dashboard = defineDocType({
408
+ name: "dashboard",
409
+ version: 1,
410
+ meta: DashboardMeta
411
+ });
412
+ const dashboardSchema = defineSchema({ types: [Dashboard] });
413
+
414
+ //#endregion
415
+ //#region packages/schema/src/types/chart.ts
416
+ /**
417
+ * `chart` — manual data points or aggregation over document trees.
418
+ * Direct children are data points (untyped); per-point `number` /
419
+ * `color` / `tags` use universal keys.
420
+ */
421
+ const ChartMeta = UniversalMeta.extend({
422
+ chartType: zod.z.enum([
423
+ "bar",
424
+ "stacked bar",
425
+ "line",
426
+ "donut",
427
+ "treemap"
428
+ ]).optional(),
429
+ chartMetric: zod.z.enum([
430
+ "value",
431
+ "type",
432
+ "tag",
433
+ "status",
434
+ "priority",
435
+ "activity",
436
+ "completion"
437
+ ]).optional(),
438
+ chartColorScheme: zod.z.enum([
439
+ "default",
440
+ "warm",
441
+ "cool",
442
+ "mono"
443
+ ]).optional(),
444
+ chartLimit: zod.z.number().int().min(3).max(30).optional(),
445
+ chartShowLegend: zod.z.boolean().optional(),
446
+ chartShowValues: zod.z.boolean().optional()
447
+ });
448
+ const Chart = defineDocType({
449
+ name: "chart",
450
+ version: 1,
451
+ meta: ChartMeta
452
+ });
453
+ const chartSchema = defineSchema({ types: [Chart] });
454
+
455
+ //#endregion
456
+ //#region packages/schema/src/types/sheets.ts
457
+ /**
458
+ * `sheets` — spreadsheet with formulas + formatting. Direct children
459
+ * are columns; grandchildren are positional cells (both untyped).
460
+ * Per-cell `formula` / `bold` / `bgColor` / `numberFormat` etc. flow
461
+ * through the untyped meta path.
462
+ */
463
+ const SheetsMeta = UniversalMeta.extend({
464
+ sheetsDefaultColWidth: zod.z.number().min(40).max(500).optional(),
465
+ sheetsDefaultRowHeight: zod.z.number().min(20).max(100).optional(),
466
+ sheetsShowGridlines: zod.z.boolean().optional()
467
+ });
468
+ const Sheets = defineDocType({
469
+ name: "sheets",
470
+ version: 1,
471
+ meta: SheetsMeta
472
+ });
473
+ const sheetsSchema = defineSchema({ types: [Sheets] });
474
+
475
+ //#endregion
476
+ //#region packages/schema/src/types/slides.ts
477
+ /**
478
+ * `slides` — two-axis presentation. Direct children are slides;
479
+ * grandchildren are sub-slides (both untyped); per-slide
480
+ * `slidesTransition` / `color` flow through the universal/untyped
481
+ * paths.
482
+ */
483
+ const SlidesMeta = UniversalMeta.extend({ slidesTheme: zod.z.enum(["dark", "light"]).optional() });
484
+ const Slides = defineDocType({
485
+ name: "slides",
486
+ version: 1,
487
+ meta: SlidesMeta
488
+ });
489
+ const slidesSchema = defineSchema({ types: [Slides] });
490
+
491
+ //#endregion
492
+ //#region packages/schema/src/types/overview.ts
493
+ /**
494
+ * `overview` — space home: activity, people, stats. Descendants are
495
+ * regular pages; no overview-specific config keys today.
496
+ */
497
+ const OverviewMeta = UniversalMeta;
498
+ const Overview = defineDocType({
499
+ name: "overview",
500
+ version: 1,
501
+ meta: OverviewMeta
502
+ });
503
+ const overviewSchema = defineSchema({ types: [Overview] });
504
+
505
+ //#endregion
506
+ //#region packages/schema/src/manifest/plugin-manifest.ts
507
+ /**
508
+ * Runtime validation schema for plugin manifests (manifest v1).
509
+ *
510
+ * The TypeScript types live in `@abraca/plugin/src/manifest.ts` and stay
511
+ * pure — `@abraca/plugin` itself ships zero schemas per `feedback_schema_free_core`.
512
+ * This file is the opt-in Zod validator used by:
513
+ *
514
+ * - the registry server's submission pipeline (verifies submitted manifests
515
+ * before storing the artifact)
516
+ * - the `@abraca/plugin-cli` `validate` command (local pre-submit linting)
517
+ * - hosts (`cou-shell`, `@abraca/nuxt`) before instantiating an external
518
+ * plugin, when they want runtime validation in addition to the
519
+ * compile-time `PluginManifest` typing.
520
+ *
521
+ * The inferred shape is asserted to be structurally identical to
522
+ * `PluginManifest` from `@abraca/plugin` via `_check` type aliases below —
523
+ * if either side drifts, the typecheck fails.
524
+ */
525
+ /**
526
+ * Capabilities with no dynamic suffix. Anything outside this set and the two
527
+ * prefix families (`network[:*]`, `page-type:<slug>`) is rejected.
528
+ *
529
+ * Encoded as a regex pattern (not a `.refine()` callback) so the
530
+ * Zod-to-JSON-Schema codegen captures it — otherwise the registry server's
531
+ * Rust validator would have to re-implement the vocabulary in parallel.
532
+ */
533
+ const CAPABILITY_PATTERN = "^(fs:read|fs:write|clipboard:read|clipboard:write|doc-read|doc-write|awareness|server-runner|command-palette|toolbar|bubble-menu|slash-command|drag-handle|chat:send|chat:read|notifications:show|network|network:\\S+|page-type:[a-z][a-z0-9-]*)$";
534
+ const PluginCapabilitySchema = zod.z.string().regex(new RegExp(CAPABILITY_PATTERN), { message: "unknown plugin capability — see PluginCapability in @abraca/plugin" }).transform((s) => s);
535
+ /** Lowercase-kebab slug. Starts with a letter; no consecutive dashes; no trailing dash. */
536
+ const PluginIdSchema = zod.z.string().regex(/^[a-z][a-z0-9]*(-[a-z0-9]+)*$/, "id must be lowercase-kebab (e.g. 'spatial', 'plugin-coder', 'my-2nd-plugin')");
537
+ /**
538
+ * Strict semver `MAJOR.MINOR.PATCH` with optional pre-release / build metadata.
539
+ * Reference: https://semver.org/spec/v2.0.0.html#backusnaur-form-grammar-for-valid-semver-versions
540
+ */
541
+ const SemverSchema = zod.z.string().regex(/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/, "version must be valid semver (e.g. '1.2.3', '0.1.0-alpha.1')");
542
+ /**
543
+ * Loose semver range — accepts `^1.2.3`, `~1.2`, `>=1.0 <2`, `1.x`, etc.
544
+ * Not parsed here; the registry server runs `semver.validRange` for strict
545
+ * validation. We just guard against obvious junk.
546
+ */
547
+ const SemverRangeSchema = zod.z.string().min(1).max(80).regex(/^[\d.xX*~^<>=|\s&,a-zA-Z+-]+$/, "invalid semver range");
548
+ /** `sha256-<64 hex chars>`. */
549
+ const IntegritySchema = zod.z.string().regex(/^sha256-[0-9a-f]{64}$/, "integrity must be 'sha256-' + 64 lowercase hex chars");
550
+ /** Relative POSIX path. No `..` segments, no absolute, no protocols. */
551
+ const RelativePathSchema = zod.z.string().min(1).max(256).refine((p) => !p.startsWith("/") && !/^[a-z]+:\/\//i.test(p) && !p.split("/").includes(".."), "must be a relative path with no '..' segments");
552
+ const PluginManifestAuthorSchema = zod.z.object({
553
+ github: zod.z.string().min(1).max(64).optional(),
554
+ name: zod.z.string().min(1).max(120).optional(),
555
+ url: zod.z.string().url().max(512).optional(),
556
+ email: zod.z.string().email().max(254).optional()
557
+ });
558
+ const PluginPricingSchema = zod.z.enum([
559
+ "free",
560
+ "optional",
561
+ "paid"
562
+ ]);
563
+ const PluginVersionStatusSchema = zod.z.enum([
564
+ "live",
565
+ "pending",
566
+ "rejected",
567
+ "superseded"
568
+ ]);
569
+ const PluginManifestContributesSchema = zod.z.object({
570
+ pageTypes: zod.z.array(zod.z.string().min(1)).readonly().optional(),
571
+ extensions: zod.z.array(zod.z.string().min(1)).readonly().optional(),
572
+ awarenessFields: zod.z.array(zod.z.string().min(1)).readonly().optional(),
573
+ serverRunners: zod.z.array(zod.z.string().min(1)).readonly().optional(),
574
+ commands: zod.z.array(zod.z.string().min(1)).readonly().optional(),
575
+ settingsPanels: zod.z.array(zod.z.string().min(1)).readonly().optional()
576
+ });
577
+ const PluginManifestSchema = zod.z.object({
578
+ manifestVersion: zod.z.literal(1),
579
+ id: PluginIdSchema,
580
+ name: zod.z.string().min(1).max(80).optional(),
581
+ version: SemverSchema,
582
+ author: PluginManifestAuthorSchema,
583
+ license: zod.z.string().min(1).max(80),
584
+ description: zod.z.string().min(1).max(280),
585
+ readme: zod.z.string().max(1e5).optional(),
586
+ homepage: zod.z.string().url().max(512).optional(),
587
+ repository: zod.z.string().min(3).max(512).optional(),
588
+ minAbracadabraVersion: SemverRangeSchema.optional(),
589
+ entry: RelativePathSchema,
590
+ integrity: IntegritySchema,
591
+ pricing: PluginPricingSchema.optional(),
592
+ screenshots: zod.z.array(RelativePathSchema).max(20).readonly().optional(),
593
+ categories: zod.z.array(zod.z.string().min(1).max(40)).max(10).readonly().optional(),
594
+ capabilities: zod.z.object({
595
+ required: zod.z.array(PluginCapabilitySchema).readonly(),
596
+ optional: zod.z.array(PluginCapabilitySchema).readonly().optional()
597
+ }),
598
+ contributes: PluginManifestContributesSchema.optional(),
599
+ peerDeps: zod.z.record(zod.z.string(), SemverRangeSchema).optional()
600
+ });
601
+ /**
602
+ * Parse and validate a manifest. Always returns a result object — never
603
+ * throws. Useful for surface UIs (the registry submission flow, the CLI's
604
+ * `validate` command) that want to render every issue at once.
605
+ */
606
+ function validatePluginManifest(value) {
607
+ const parsed = PluginManifestSchema.safeParse(value);
608
+ if (parsed.success) return {
609
+ ok: true,
610
+ value: parsed.data
611
+ };
612
+ return {
613
+ ok: false,
614
+ errors: parsed.error.issues.map((i) => ({
615
+ path: i.path,
616
+ message: i.message,
617
+ code: i.code
618
+ }))
619
+ };
620
+ }
621
+
622
+ //#endregion
623
+ //#region packages/schema/src/index.ts
624
+ /**
625
+ * Declare a doc-type. The returned value carries enough type information for
626
+ * downstream codegen and is a `DocType` once registered.
627
+ */
628
+ function defineDocType(spec) {
629
+ return {
630
+ ...spec,
631
+ __resolved: true
632
+ };
633
+ }
634
+ /** Reference another doc-type by name. Resolution happens in {@link defineSchema}. */
635
+ function ref(name) {
636
+ return { __ref: name };
637
+ }
638
+ /**
639
+ * Build a registry from a list of doc-types. Validates that all `ref(...)`
640
+ * targets exist; throws on dangling references.
641
+ *
642
+ * The returned registry carries a phantom `__metaMap` witness inferred from
643
+ * `spec`, so call sites like `provider.docs(schema).get("kanban", id)`
644
+ * see fully-typed meta even though the registry's runtime shape is generic.
645
+ */
646
+ function defineSchema(spec) {
647
+ const types = /* @__PURE__ */ new Map();
648
+ for (const t of spec.types) {
649
+ if (types.has(t.name)) throw new Error(`Duplicate doc-type name: ${t.name}`);
650
+ types.set(t.name, t);
651
+ }
652
+ for (const t of spec.types) for (const child of t.children ?? []) if (!types.has(child.__ref)) throw new Error(`Doc-type "${t.name}" references unknown child doc-type "${child.__ref}"`);
653
+ return {
654
+ types,
655
+ get(name) {
656
+ return types.get(name);
657
+ },
658
+ validateChildType(parent, child) {
659
+ if (!types.has(child)) return {
660
+ ok: false,
661
+ errors: [{
662
+ path: [],
663
+ message: `Unknown doc-type: ${child}`
664
+ }]
665
+ };
666
+ if (parent === null) return {
667
+ ok: false,
668
+ errors: [{
669
+ path: [],
670
+ message: `Doc-type "${child}" cannot be a root document — root-eligibility is reserved for Phase 2`
671
+ }]
672
+ };
673
+ const parentType = types.get(parent);
674
+ if (!parentType) return {
675
+ ok: false,
676
+ errors: [{
677
+ path: [],
678
+ message: `Unknown parent doc-type: ${parent}`
679
+ }]
680
+ };
681
+ if ((parentType.children ?? []).some((c) => c.__ref === child)) return {
682
+ ok: true,
683
+ value: void 0
684
+ };
685
+ return {
686
+ ok: false,
687
+ errors: [{
688
+ path: [],
689
+ message: `Doc-type "${child}" is not an allowed child of "${parent}"`
690
+ }]
691
+ };
692
+ },
693
+ validateMeta(name, value) {
694
+ const t = types.get(name);
695
+ if (!t) return {
696
+ ok: true,
697
+ value
698
+ };
699
+ const parsed = t.meta.safeParse(value);
700
+ if (parsed.success) return {
701
+ ok: true,
702
+ value: parsed.data
703
+ };
704
+ return {
705
+ ok: false,
706
+ errors: parsed.error.issues.map((i) => ({
707
+ path: i.path,
708
+ message: i.message,
709
+ code: i.code
710
+ }))
711
+ };
712
+ }
713
+ };
714
+ }
715
+ /**
716
+ * Apply forward migrations to a meta object.
717
+ *
718
+ * Reads `meta.__schemaVersion` (defaults to `1` if absent) and applies
719
+ * each `migrations[v]` from there up to the schema's declared `version`.
720
+ * Each migration function receives the previous version's meta and
721
+ * returns the next version's meta. The final value carries
722
+ * `__schemaVersion = <highest version reached>`.
723
+ *
724
+ * Behaviour:
725
+ * - **Unknown doc-type**: returns `meta` unchanged. Rule 4 — registries
726
+ * only constrain the types they declare.
727
+ * - **No migrations declared**: returns `meta` unchanged. Useful for
728
+ * freshly-introduced doc-types still at v1.
729
+ * - **Missing migration entry mid-chain**: stops at the highest
730
+ * reachable version. Caller can detect by inspecting
731
+ * `result.__schemaVersion` against `schema.get(typeName)?.version`.
732
+ * - **Non-object meta** (null, undefined, primitives): returns
733
+ * unchanged. Migrations only operate on object meta.
734
+ *
735
+ * Migrations are pure: they receive a meta value and return a new
736
+ * one. They MUST NOT mutate the input (callers may pass shared
737
+ * references).
738
+ *
739
+ * @example
740
+ * // v2 of kanban introduces a new required-shape `boardLayout` key.
741
+ * const Kanban = defineDocType({
742
+ * name: "kanban",
743
+ * version: 2,
744
+ * meta: KanbanMetaV2,
745
+ * migrations: {
746
+ * 1: (oldMeta) => ({ ...oldMeta, boardLayout: "default" }),
747
+ * },
748
+ * });
749
+ * const fresh = runMigrations(kanbanSchema, "kanban", { kanbanShowIcon: true });
750
+ * // fresh.boardLayout === "default"
751
+ * // fresh.__schemaVersion === 2
752
+ */
753
+ function runMigrations(registry, typeName, meta) {
754
+ if (meta === null || typeof meta !== "object") return meta;
755
+ const t = registry.get(typeName);
756
+ if (!t) return meta;
757
+ const target = t.version;
758
+ const migrations = t.migrations;
759
+ const m = meta;
760
+ let currentVersion = typeof m.__schemaVersion === "number" && m.__schemaVersion >= 1 ? m.__schemaVersion : 1;
761
+ if (currentVersion >= target) return meta;
762
+ if (!migrations) return meta;
763
+ let working = meta;
764
+ let migrated = false;
765
+ while (currentVersion < target) {
766
+ const fn = migrations[currentVersion];
767
+ if (typeof fn !== "function") break;
768
+ working = fn(working);
769
+ currentVersion += 1;
770
+ migrated = true;
771
+ }
772
+ if (!migrated) return meta;
773
+ if (working === null || typeof working !== "object") return working;
774
+ return {
775
+ ...working,
776
+ __schemaVersion: currentVersion
777
+ };
778
+ }
779
+
780
+ //#endregion
781
+ exports.Calendar = Calendar;
782
+ exports.CalendarMeta = CalendarMeta;
783
+ exports.Chart = Chart;
784
+ exports.ChartMeta = ChartMeta;
785
+ exports.Checklist = Checklist;
786
+ exports.ChecklistMeta = ChecklistMeta;
787
+ exports.Dashboard = Dashboard;
788
+ exports.DashboardMeta = DashboardMeta;
789
+ exports.Doc = Doc;
790
+ exports.DocMeta = DocMeta;
791
+ exports.Gallery = Gallery;
792
+ exports.GalleryMeta = GalleryMeta;
793
+ exports.Graph = Graph;
794
+ exports.GraphMeta = GraphMeta;
795
+ exports.IntegritySchema = IntegritySchema;
796
+ exports.Kanban = Kanban;
797
+ exports.KanbanMeta = KanbanMeta;
798
+ exports.META_COLUMNS = META_COLUMNS;
799
+ exports.MapDocType = MapDocType;
800
+ exports.MapMeta = MapMeta;
801
+ exports.Outline = Outline;
802
+ exports.OutlineMeta = OutlineMeta;
803
+ exports.Overview = Overview;
804
+ exports.OverviewMeta = OverviewMeta;
805
+ exports.PluginCapabilitySchema = PluginCapabilitySchema;
806
+ exports.PluginIdSchema = PluginIdSchema;
807
+ exports.PluginManifestAuthorSchema = PluginManifestAuthorSchema;
808
+ exports.PluginManifestContributesSchema = PluginManifestContributesSchema;
809
+ exports.PluginManifestSchema = PluginManifestSchema;
810
+ exports.PluginPricingSchema = PluginPricingSchema;
811
+ exports.PluginVersionStatusSchema = PluginVersionStatusSchema;
812
+ exports.Prose = Prose;
813
+ exports.ProseMeta = ProseMeta;
814
+ exports.RelativePathSchema = RelativePathSchema;
815
+ exports.SemverRangeSchema = SemverRangeSchema;
816
+ exports.SemverSchema = SemverSchema;
817
+ exports.Sheets = Sheets;
818
+ exports.SheetsMeta = SheetsMeta;
819
+ exports.Slides = Slides;
820
+ exports.SlidesMeta = SlidesMeta;
821
+ exports.Table = Table;
822
+ exports.TableMeta = TableMeta;
823
+ exports.Timeline = Timeline;
824
+ exports.TimelineMeta = TimelineMeta;
825
+ exports.UniversalMeta = UniversalMeta;
826
+ exports.WhereClauseSchema = WhereClauseSchema;
827
+ exports.calendarSchema = calendarSchema;
828
+ exports.chartSchema = chartSchema;
829
+ exports.checklistSchema = checklistSchema;
830
+ exports.crdtMetaOf = crdtMetaOf;
831
+ exports.dashboardSchema = dashboardSchema;
832
+ exports.defineDocType = defineDocType;
833
+ exports.defineSchema = defineSchema;
834
+ exports.docSchema = docSchema;
835
+ exports.gallerySchema = gallerySchema;
836
+ exports.graphSchema = graphSchema;
837
+ exports.kanbanSchema = kanbanSchema;
838
+ exports.mapSchema = mapSchema;
839
+ exports.outlineSchema = outlineSchema;
840
+ exports.overviewSchema = overviewSchema;
841
+ exports.parseWhereClause = parseWhereClause;
842
+ exports.proseSchema = proseSchema;
843
+ exports.ref = ref;
844
+ exports.runMigrations = runMigrations;
845
+ exports.sheetsSchema = sheetsSchema;
846
+ exports.slidesSchema = slidesSchema;
847
+ exports.tableSchema = tableSchema;
848
+ exports.timelineSchema = timelineSchema;
849
+ exports.validatePluginManifest = validatePluginManifest;
850
+ exports.yarray = yarray;
851
+ exports.ymap = ymap;
852
+ exports.ytext = ytext;
853
+ //# sourceMappingURL=abracadabra-schema.cjs.map