@velumo/core 0.1.0-beta.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 (53) hide show
  1. package/dist/background-validation.d.ts +3 -0
  2. package/dist/background-validation.d.ts.map +1 -0
  3. package/dist/background-validation.js +177 -0
  4. package/dist/background-validation.js.map +1 -0
  5. package/dist/builders.d.ts +134 -0
  6. package/dist/builders.d.ts.map +1 -0
  7. package/dist/builders.js +332 -0
  8. package/dist/builders.js.map +1 -0
  9. package/dist/capabilities.d.ts +7 -0
  10. package/dist/capabilities.d.ts.map +1 -0
  11. package/dist/capabilities.js +59 -0
  12. package/dist/capabilities.js.map +1 -0
  13. package/dist/index.d.ts +9 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +7 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/layout-validation.d.ts +4 -0
  18. package/dist/layout-validation.d.ts.map +1 -0
  19. package/dist/layout-validation.js +745 -0
  20. package/dist/layout-validation.js.map +1 -0
  21. package/dist/manifest-schema.d.ts +1328 -0
  22. package/dist/manifest-schema.d.ts.map +1 -0
  23. package/dist/manifest-schema.js +774 -0
  24. package/dist/manifest-schema.js.map +1 -0
  25. package/dist/theme-validation.d.ts +3 -0
  26. package/dist/theme-validation.d.ts.map +1 -0
  27. package/dist/theme-validation.js +239 -0
  28. package/dist/theme-validation.js.map +1 -0
  29. package/dist/tsconfig.tsbuildinfo +1 -0
  30. package/dist/types.d.ts +398 -0
  31. package/dist/types.d.ts.map +1 -0
  32. package/dist/types.js +2 -0
  33. package/dist/types.js.map +1 -0
  34. package/dist/validation-issue.d.ts +18 -0
  35. package/dist/validation-issue.d.ts.map +1 -0
  36. package/dist/validation-issue.js +30 -0
  37. package/dist/validation-issue.js.map +1 -0
  38. package/dist/validation.d.ts +4 -0
  39. package/dist/validation.d.ts.map +1 -0
  40. package/dist/validation.js +274 -0
  41. package/dist/validation.js.map +1 -0
  42. package/package.json +16 -0
  43. package/src/background-validation.ts +315 -0
  44. package/src/builders.ts +626 -0
  45. package/src/capabilities.ts +99 -0
  46. package/src/index.ts +147 -0
  47. package/src/layout-validation.ts +1385 -0
  48. package/src/manifest-schema.ts +823 -0
  49. package/src/theme-validation.ts +410 -0
  50. package/src/types.ts +560 -0
  51. package/src/validation-issue.ts +43 -0
  52. package/src/validation.ts +468 -0
  53. package/tsconfig.json +9 -0
@@ -0,0 +1,774 @@
1
+ /**
2
+ * JSON Schema (draft 2020-12) derived by hand from the `Manifest` TypeScript
3
+ * type in `types.ts`. This is the published, machine-readable form of the
4
+ * manifest contract — the artifact an agent or MCP server validates against.
5
+ *
6
+ * It is intentionally a richer, stricter mirror of the type than the
7
+ * lightweight runtime `validateManifest()`: it requires the `kind`
8
+ * discriminator on every slide and layout node, enforces every enum, and
9
+ * forbids unknown fields. The two are kept in sync by a drift test that runs a
10
+ * canonical manifest through both and asserts they agree.
11
+ *
12
+ * No schema library lives in `@velumo/core`: this is a plain, serializable
13
+ * object. JSON Schema execution (ajv) is confined to the test suite.
14
+ */
15
+ const jsonValue = {
16
+ $comment: "Any JSON value (string, number, boolean, null, object, array).",
17
+ };
18
+ const cameraVector = {
19
+ type: "object",
20
+ properties: {
21
+ x: { type: "number" },
22
+ y: { type: "number" },
23
+ z: { type: "number" },
24
+ },
25
+ additionalProperties: false,
26
+ };
27
+ const layoutMeta = {
28
+ type: "object",
29
+ properties: {
30
+ safeArea: { enum: ["default", "full-bleed", "title-safe"] },
31
+ depth: { type: "number" },
32
+ cameraHint: { enum: ["static", "push", "pan", "orbit"] },
33
+ },
34
+ additionalProperties: false,
35
+ };
36
+ const stringOrNumber = { type: ["string", "number"] };
37
+ const layoutChildren = {
38
+ type: "array",
39
+ items: { $ref: "#/$defs/layoutNode" },
40
+ };
41
+ export const manifestJsonSchema = {
42
+ $schema: "https://json-schema.org/draft/2020-12/schema",
43
+ $id: "https://velumo.dev/schemas/manifest.json",
44
+ title: "Velumo Manifest",
45
+ type: "object",
46
+ required: ["deck", "slides"],
47
+ additionalProperties: false,
48
+ properties: {
49
+ deck: { $ref: "#/$defs/deckMetadata" },
50
+ slides: { type: "array", items: { $ref: "#/$defs/slideEntry" } },
51
+ assets: { type: "array", items: { $ref: "#/$defs/asset" } },
52
+ plugins: { type: "array", items: { $ref: "#/$defs/plugin" } },
53
+ theme: { $ref: "#/$defs/theme" },
54
+ export: { $ref: "#/$defs/exportOptions" },
55
+ },
56
+ $defs: {
57
+ deckMetadata: {
58
+ type: "object",
59
+ required: ["title"],
60
+ properties: {
61
+ title: { type: "string", minLength: 1 },
62
+ description: { type: "string" },
63
+ author: { type: "string" },
64
+ watermark: { type: "string" },
65
+ },
66
+ additionalProperties: jsonValue,
67
+ },
68
+ slideEntry: {
69
+ oneOf: [{ $ref: "#/$defs/slide" }, { $ref: "#/$defs/scene" }],
70
+ },
71
+ slide: {
72
+ type: "object",
73
+ required: ["id", "kind"],
74
+ additionalProperties: false,
75
+ properties: {
76
+ id: { type: "string", minLength: 1 },
77
+ kind: { const: "slide" },
78
+ content: jsonValue,
79
+ layout: { $ref: "#/$defs/layoutNode" },
80
+ layers: { type: "array", items: { $ref: "#/$defs/layer" } },
81
+ fragments: { type: "array", items: { $ref: "#/$defs/fragment" } },
82
+ cues: { type: "array", items: { $ref: "#/$defs/cue" } },
83
+ notes: { type: "string" },
84
+ mood: { type: "string" },
85
+ transition: { type: "string" },
86
+ chrome: { type: "boolean" },
87
+ background: { $ref: "#/$defs/background" },
88
+ },
89
+ },
90
+ scene: {
91
+ type: "object",
92
+ required: ["id", "kind"],
93
+ additionalProperties: false,
94
+ properties: {
95
+ id: { type: "string", minLength: 1 },
96
+ kind: { const: "scene" },
97
+ duration: { type: "number" },
98
+ camera: { $ref: "#/$defs/camera" },
99
+ cameraPath: {
100
+ type: "array",
101
+ minItems: 1,
102
+ items: { $ref: "#/$defs/cameraStop" },
103
+ },
104
+ layout: { $ref: "#/$defs/layoutNode" },
105
+ layers: { type: "array", items: { $ref: "#/$defs/layer" } },
106
+ fragments: { type: "array", items: { $ref: "#/$defs/fragment" } },
107
+ cues: { type: "array", items: { $ref: "#/$defs/cue" } },
108
+ notes: { type: "string" },
109
+ mood: { type: "string" },
110
+ transition: { type: "string" },
111
+ chrome: { type: "boolean" },
112
+ background: { $ref: "#/$defs/background" },
113
+ },
114
+ },
115
+ camera: {
116
+ type: "object",
117
+ properties: {
118
+ from: cameraVector,
119
+ to: cameraVector,
120
+ zoom: { type: "number" },
121
+ },
122
+ additionalProperties: true,
123
+ },
124
+ cameraView: {
125
+ type: "object",
126
+ required: ["x", "y"],
127
+ additionalProperties: false,
128
+ properties: {
129
+ x: { type: "number", minimum: 0, maximum: 100 },
130
+ y: { type: "number", minimum: 0, maximum: 100 },
131
+ zoom: { type: "number", exclusiveMinimum: 0 },
132
+ },
133
+ },
134
+ cameraTransition: {
135
+ type: "object",
136
+ additionalProperties: false,
137
+ properties: {
138
+ duration: { type: "number", minimum: 0 },
139
+ easing: {
140
+ enum: ["linear", "ease", "ease-in", "ease-out", "ease-in-out"],
141
+ },
142
+ },
143
+ },
144
+ cameraStop: {
145
+ type: "object",
146
+ required: ["camera"],
147
+ additionalProperties: false,
148
+ properties: {
149
+ camera: { $ref: "#/$defs/cameraView" },
150
+ transition: { $ref: "#/$defs/cameraTransition" },
151
+ cues: { type: "array", items: { $ref: "#/$defs/cue" } },
152
+ hold: { type: "number", minimum: 0 },
153
+ },
154
+ },
155
+ layer: {
156
+ type: "object",
157
+ required: ["type"],
158
+ additionalProperties: false,
159
+ properties: {
160
+ id: { type: "string" },
161
+ type: { type: "string", minLength: 1 },
162
+ content: jsonValue,
163
+ props: { type: "object", additionalProperties: jsonValue },
164
+ timing: { type: "object", additionalProperties: jsonValue },
165
+ visible: { type: "boolean" },
166
+ },
167
+ },
168
+ fragment: {
169
+ type: "object",
170
+ required: ["id"],
171
+ additionalProperties: false,
172
+ properties: {
173
+ id: { type: "string", minLength: 1 },
174
+ layerId: { type: "string" },
175
+ transition: { type: "string" },
176
+ cues: { type: "array", items: { type: "string" } },
177
+ },
178
+ },
179
+ cue: {
180
+ type: "object",
181
+ required: ["time", "action"],
182
+ additionalProperties: false,
183
+ properties: {
184
+ time: { type: "number", minimum: 0 },
185
+ action: { $ref: "#/$defs/cueAction" },
186
+ },
187
+ },
188
+ cueAction: {
189
+ type: "object",
190
+ required: ["type"],
191
+ additionalProperties: false,
192
+ properties: {
193
+ type: { type: "string", minLength: 1 },
194
+ target: { type: "string" },
195
+ payload: jsonValue,
196
+ },
197
+ },
198
+ layoutNode: {
199
+ oneOf: [
200
+ { $ref: "#/$defs/stackLayout" },
201
+ { $ref: "#/$defs/gridLayout" },
202
+ { $ref: "#/$defs/splitLayout" },
203
+ { $ref: "#/$defs/heroLayout" },
204
+ { $ref: "#/$defs/frameLayout" },
205
+ { $ref: "#/$defs/canvasLayout" },
206
+ { $ref: "#/$defs/animateLayout" },
207
+ { $ref: "#/$defs/headingElement" },
208
+ { $ref: "#/$defs/textElement" },
209
+ { $ref: "#/$defs/mediaElement" },
210
+ { $ref: "#/$defs/calloutElement" },
211
+ { $ref: "#/$defs/codeElement" },
212
+ { $ref: "#/$defs/iconElement" },
213
+ { $ref: "#/$defs/tableLayout" },
214
+ { $ref: "#/$defs/connectorElement" },
215
+ { $ref: "#/$defs/badgeElement" },
216
+ { $ref: "#/$defs/ruleElement" },
217
+ ],
218
+ },
219
+ stackLayout: {
220
+ type: "object",
221
+ required: ["kind", "children"],
222
+ additionalProperties: false,
223
+ properties: {
224
+ kind: { const: "stack" },
225
+ children: layoutChildren,
226
+ direction: { enum: ["vertical", "horizontal"] },
227
+ align: { enum: ["start", "center", "end", "stretch"] },
228
+ gap: { type: "string" },
229
+ justify: { enum: ["start", "center", "between", "end"] },
230
+ meta: layoutMeta,
231
+ },
232
+ },
233
+ gridLayout: {
234
+ type: "object",
235
+ required: ["kind", "children"],
236
+ additionalProperties: false,
237
+ properties: {
238
+ kind: { const: "grid" },
239
+ children: layoutChildren,
240
+ columns: { type: "integer", minimum: 1 },
241
+ rows: { type: "integer", minimum: 1 },
242
+ meta: layoutMeta,
243
+ },
244
+ },
245
+ splitLayout: {
246
+ type: "object",
247
+ required: ["kind", "children"],
248
+ additionalProperties: false,
249
+ properties: {
250
+ kind: { const: "split" },
251
+ children: {
252
+ type: "array",
253
+ minItems: 2,
254
+ items: { $ref: "#/$defs/layoutNode" },
255
+ },
256
+ weights: {
257
+ type: "array",
258
+ items: { type: "number", exclusiveMinimum: 0 },
259
+ },
260
+ meta: layoutMeta,
261
+ },
262
+ },
263
+ heroLayout: {
264
+ type: "object",
265
+ required: ["kind", "children"],
266
+ additionalProperties: false,
267
+ properties: {
268
+ kind: { const: "hero" },
269
+ children: {
270
+ type: "array",
271
+ minItems: 1,
272
+ items: { $ref: "#/$defs/layoutNode" },
273
+ },
274
+ meta: layoutMeta,
275
+ },
276
+ },
277
+ frameLayout: {
278
+ type: "object",
279
+ required: ["kind", "children"],
280
+ additionalProperties: false,
281
+ properties: {
282
+ kind: { const: "frame" },
283
+ children: layoutChildren,
284
+ meta: layoutMeta,
285
+ tone: {
286
+ enum: [
287
+ "default",
288
+ "muted",
289
+ "accent",
290
+ "danger",
291
+ "magenta",
292
+ "cyan",
293
+ "purple",
294
+ "green",
295
+ ],
296
+ },
297
+ },
298
+ },
299
+ canvasLayout: {
300
+ type: "object",
301
+ required: ["kind", "items"],
302
+ additionalProperties: false,
303
+ properties: {
304
+ kind: { const: "canvas" },
305
+ items: { type: "array", items: { $ref: "#/$defs/canvasItem" } },
306
+ meta: layoutMeta,
307
+ },
308
+ },
309
+ canvasItem: {
310
+ type: "object",
311
+ required: ["x", "y", "child"],
312
+ additionalProperties: false,
313
+ properties: {
314
+ x: { type: "number", minimum: 0, maximum: 100 },
315
+ y: { type: "number", minimum: 0, maximum: 100 },
316
+ width: { type: "number", minimum: 0, maximum: 100 },
317
+ height: { type: "number", minimum: 0, maximum: 100 },
318
+ child: { $ref: "#/$defs/layoutNode" },
319
+ },
320
+ },
321
+ animateLayout: {
322
+ type: "object",
323
+ required: ["kind", "name", "child"],
324
+ additionalProperties: false,
325
+ properties: {
326
+ kind: { const: "animate" },
327
+ name: {
328
+ enum: [
329
+ "rise",
330
+ "fade",
331
+ "zoom",
332
+ "draw",
333
+ "in-left",
334
+ "in-right",
335
+ "glow",
336
+ "blink",
337
+ "pulse",
338
+ "sweep",
339
+ ],
340
+ },
341
+ delay: { type: "number", minimum: 0 },
342
+ duration: { type: "number", exclusiveMinimum: 0 },
343
+ easing: { type: "string", minLength: 1 },
344
+ child: { $ref: "#/$defs/layoutNode" },
345
+ },
346
+ },
347
+ headingElement: {
348
+ type: "object",
349
+ required: ["kind", "text"],
350
+ additionalProperties: false,
351
+ properties: {
352
+ kind: { const: "heading" },
353
+ text: { type: "string", minLength: 1 },
354
+ size: { enum: ["default", "display", "hero"] },
355
+ level: { type: "integer", minimum: 1, maximum: 6 },
356
+ transform: { enum: ["uppercase", "lowercase", "capitalize"] },
357
+ decoration: { enum: ["underline", "line-through"] },
358
+ glow: { type: "boolean" },
359
+ tone: {
360
+ enum: [
361
+ "default",
362
+ "muted",
363
+ "accent",
364
+ "danger",
365
+ "magenta",
366
+ "cyan",
367
+ "purple",
368
+ "green",
369
+ ],
370
+ },
371
+ },
372
+ },
373
+ textElement: {
374
+ type: "object",
375
+ required: ["kind", "text"],
376
+ additionalProperties: false,
377
+ properties: {
378
+ kind: { const: "text" },
379
+ text: { type: "string" },
380
+ variant: { enum: ["body", "lead", "caption"] },
381
+ transform: { enum: ["uppercase", "lowercase", "capitalize"] },
382
+ decoration: { enum: ["underline", "line-through"] },
383
+ glow: { type: "boolean" },
384
+ tone: {
385
+ enum: [
386
+ "default",
387
+ "muted",
388
+ "accent",
389
+ "danger",
390
+ "magenta",
391
+ "cyan",
392
+ "purple",
393
+ "green",
394
+ ],
395
+ },
396
+ },
397
+ },
398
+ mediaElement: {
399
+ type: "object",
400
+ required: ["kind", "src", "alt"],
401
+ additionalProperties: false,
402
+ properties: {
403
+ kind: { const: "media" },
404
+ src: { type: "string", minLength: 1 },
405
+ alt: { type: "string", minLength: 1 },
406
+ fit: { enum: ["contain", "cover", "fill"] },
407
+ },
408
+ },
409
+ calloutElement: {
410
+ type: "object",
411
+ required: ["kind", "children"],
412
+ additionalProperties: false,
413
+ properties: {
414
+ kind: { const: "callout" },
415
+ tone: { enum: ["info", "warning", "success", "danger", "quote"] },
416
+ children: layoutChildren,
417
+ },
418
+ },
419
+ codeElement: {
420
+ type: "object",
421
+ required: ["kind", "lines"],
422
+ additionalProperties: false,
423
+ properties: {
424
+ kind: { const: "code" },
425
+ lines: {
426
+ type: "array",
427
+ items: { type: "array", items: { $ref: "#/$defs/codeToken" } },
428
+ },
429
+ },
430
+ },
431
+ iconElement: {
432
+ type: "object",
433
+ required: ["kind", "name"],
434
+ additionalProperties: false,
435
+ properties: {
436
+ kind: { const: "icon" },
437
+ name: { enum: ["check", "cross", "dash", "ring", "dot", "arrow"] },
438
+ tone: {
439
+ enum: [
440
+ "default",
441
+ "muted",
442
+ "accent",
443
+ "danger",
444
+ "magenta",
445
+ "cyan",
446
+ "purple",
447
+ "green",
448
+ ],
449
+ },
450
+ label: { type: "string" },
451
+ },
452
+ },
453
+ badgeElement: {
454
+ type: "object",
455
+ required: ["kind", "text"],
456
+ additionalProperties: false,
457
+ properties: {
458
+ kind: { const: "badge" },
459
+ text: { type: "string" },
460
+ tone: {
461
+ enum: [
462
+ "default",
463
+ "muted",
464
+ "accent",
465
+ "danger",
466
+ "magenta",
467
+ "cyan",
468
+ "purple",
469
+ "green",
470
+ ],
471
+ },
472
+ variant: { enum: ["outline", "soft", "solid"] },
473
+ dot: {
474
+ enum: [
475
+ "default",
476
+ "muted",
477
+ "accent",
478
+ "danger",
479
+ "magenta",
480
+ "cyan",
481
+ "purple",
482
+ "green",
483
+ ],
484
+ },
485
+ mono: { type: "boolean" },
486
+ },
487
+ },
488
+ ruleElement: {
489
+ type: "object",
490
+ required: ["kind"],
491
+ additionalProperties: false,
492
+ properties: {
493
+ kind: { const: "rule" },
494
+ length: { type: ["string", "number"] },
495
+ thickness: { type: "number" },
496
+ tone: {
497
+ enum: [
498
+ "default",
499
+ "muted",
500
+ "accent",
501
+ "danger",
502
+ "magenta",
503
+ "cyan",
504
+ "purple",
505
+ "green",
506
+ ],
507
+ },
508
+ gradient: {
509
+ type: "array",
510
+ minItems: 2,
511
+ maxItems: 2,
512
+ items: {
513
+ enum: [
514
+ "default",
515
+ "muted",
516
+ "accent",
517
+ "danger",
518
+ "magenta",
519
+ "cyan",
520
+ "purple",
521
+ "green",
522
+ ],
523
+ },
524
+ },
525
+ radius: { type: "number" },
526
+ },
527
+ },
528
+ tableColumn: {
529
+ type: "object",
530
+ additionalProperties: false,
531
+ properties: {
532
+ header: { $ref: "#/$defs/layoutNode" },
533
+ weight: { type: "number", exclusiveMinimum: 0 },
534
+ align: { enum: ["start", "center", "end"] },
535
+ emphasis: { type: "boolean" },
536
+ },
537
+ },
538
+ tableLayout: {
539
+ type: "object",
540
+ required: ["kind", "columns", "rows"],
541
+ additionalProperties: false,
542
+ properties: {
543
+ kind: { const: "table" },
544
+ columns: {
545
+ type: "array",
546
+ minItems: 1,
547
+ items: { $ref: "#/$defs/tableColumn" },
548
+ },
549
+ rows: {
550
+ type: "array",
551
+ items: { type: "array", items: { $ref: "#/$defs/layoutNode" } },
552
+ },
553
+ meta: layoutMeta,
554
+ },
555
+ },
556
+ connectorPoint: {
557
+ type: "object",
558
+ required: ["x", "y"],
559
+ additionalProperties: false,
560
+ properties: {
561
+ x: { type: "number", minimum: 0, maximum: 100 },
562
+ y: { type: "number", minimum: 0, maximum: 100 },
563
+ },
564
+ },
565
+ connectorElement: {
566
+ type: "object",
567
+ required: ["kind", "from", "to"],
568
+ additionalProperties: false,
569
+ properties: {
570
+ kind: { const: "connector" },
571
+ from: { $ref: "#/$defs/connectorPoint" },
572
+ to: { $ref: "#/$defs/connectorPoint" },
573
+ control: { $ref: "#/$defs/connectorPoint" },
574
+ arrow: { enum: ["none", "end", "start", "both"] },
575
+ dashed: { type: "boolean" },
576
+ tone: {
577
+ enum: [
578
+ "default",
579
+ "muted",
580
+ "accent",
581
+ "danger",
582
+ "magenta",
583
+ "cyan",
584
+ "purple",
585
+ "green",
586
+ ],
587
+ },
588
+ },
589
+ },
590
+ codeToken: {
591
+ type: "object",
592
+ required: ["text"],
593
+ additionalProperties: false,
594
+ properties: {
595
+ text: { type: "string" },
596
+ kind: {
597
+ enum: [
598
+ "keyword",
599
+ "function",
600
+ "string",
601
+ "number",
602
+ "property",
603
+ "comment",
604
+ "punctuation",
605
+ "plain",
606
+ ],
607
+ },
608
+ },
609
+ },
610
+ asset: {
611
+ type: "object",
612
+ required: ["id", "type", "src"],
613
+ additionalProperties: false,
614
+ properties: {
615
+ id: { type: "string", minLength: 1 },
616
+ type: { type: "string", minLength: 1 },
617
+ src: { type: "string", minLength: 1 },
618
+ metadata: { type: "object", additionalProperties: jsonValue },
619
+ },
620
+ },
621
+ plugin: {
622
+ type: "object",
623
+ required: ["id"],
624
+ additionalProperties: false,
625
+ properties: {
626
+ id: { type: "string", minLength: 1 },
627
+ packageName: { type: "string" },
628
+ options: { type: "object", additionalProperties: jsonValue },
629
+ },
630
+ },
631
+ exportOptions: {
632
+ type: "object",
633
+ additionalProperties: false,
634
+ properties: {
635
+ formats: { type: "array", items: { type: "string" } },
636
+ metadata: { type: "object", additionalProperties: jsonValue },
637
+ },
638
+ },
639
+ theme: {
640
+ type: "object",
641
+ required: ["id"],
642
+ additionalProperties: false,
643
+ properties: {
644
+ id: { type: "string", minLength: 1 },
645
+ tokens: { $ref: "#/$defs/themeTokens" },
646
+ css: { type: "string" },
647
+ fonts: {
648
+ type: "array",
649
+ items: { $ref: "#/$defs/themeFontFace" },
650
+ },
651
+ },
652
+ },
653
+ themeFontFace: {
654
+ type: "object",
655
+ required: ["family", "source"],
656
+ additionalProperties: false,
657
+ properties: {
658
+ family: { type: "string", minLength: 1 },
659
+ source: { type: "string", minLength: 1 },
660
+ format: { type: "string" },
661
+ weight: stringOrNumber,
662
+ style: { type: "string" },
663
+ display: { type: "string" },
664
+ unicodeRange: { type: "string" },
665
+ stretch: { type: "string" },
666
+ },
667
+ },
668
+ themeTokens: {
669
+ type: "object",
670
+ additionalProperties: false,
671
+ properties: {
672
+ colors: { type: "object", additionalProperties: { type: "string" } },
673
+ typography: {
674
+ type: "object",
675
+ additionalProperties: { $ref: "#/$defs/typographyToken" },
676
+ },
677
+ spacing: { type: "object", additionalProperties: stringOrNumber },
678
+ radii: { type: "object", additionalProperties: stringOrNumber },
679
+ shadows: { type: "object", additionalProperties: { type: "string" } },
680
+ motion: {
681
+ type: "object",
682
+ additionalProperties: { $ref: "#/$defs/motionToken" },
683
+ },
684
+ surfaces: { type: "object", additionalProperties: { type: "string" } },
685
+ text: { type: "object", additionalProperties: { type: "string" } },
686
+ },
687
+ },
688
+ typographyToken: {
689
+ type: "object",
690
+ additionalProperties: false,
691
+ properties: {
692
+ fontFamily: { type: "string" },
693
+ fontSize: stringOrNumber,
694
+ lineHeight: stringOrNumber,
695
+ fontWeight: stringOrNumber,
696
+ letterSpacing: stringOrNumber,
697
+ },
698
+ },
699
+ motionToken: {
700
+ type: "object",
701
+ additionalProperties: false,
702
+ properties: {
703
+ duration: stringOrNumber,
704
+ easing: { type: "string" },
705
+ delay: stringOrNumber,
706
+ },
707
+ },
708
+ background: {
709
+ type: "object",
710
+ additionalProperties: false,
711
+ properties: {
712
+ color: { type: "string", minLength: 1 },
713
+ layers: { type: "array", items: { $ref: "#/$defs/backgroundLayer" } },
714
+ },
715
+ },
716
+ backgroundLayer: {
717
+ oneOf: [
718
+ { $ref: "#/$defs/linearGradientLayer" },
719
+ { $ref: "#/$defs/radialGradientLayer" },
720
+ ],
721
+ },
722
+ linearGradientLayer: {
723
+ type: "object",
724
+ required: ["type", "stops"],
725
+ additionalProperties: false,
726
+ properties: {
727
+ type: { const: "linear" },
728
+ stops: {
729
+ type: "array",
730
+ minItems: 1,
731
+ items: { $ref: "#/$defs/gradientStop" },
732
+ },
733
+ angle: { type: "number" },
734
+ blend: { enum: ["normal", "screen", "multiply", "overlay"] },
735
+ opacity: { type: "number", minimum: 0, maximum: 1 },
736
+ },
737
+ },
738
+ radialGradientLayer: {
739
+ type: "object",
740
+ required: ["type", "stops"],
741
+ additionalProperties: false,
742
+ properties: {
743
+ type: { const: "radial" },
744
+ stops: {
745
+ type: "array",
746
+ minItems: 1,
747
+ items: { $ref: "#/$defs/gradientStop" },
748
+ },
749
+ shape: { enum: ["circle", "ellipse"] },
750
+ position: {
751
+ type: "object",
752
+ required: ["x", "y"],
753
+ additionalProperties: false,
754
+ properties: {
755
+ x: { type: "number", minimum: 0, maximum: 100 },
756
+ y: { type: "number", minimum: 0, maximum: 100 },
757
+ },
758
+ },
759
+ blend: { enum: ["normal", "screen", "multiply", "overlay"] },
760
+ opacity: { type: "number", minimum: 0, maximum: 1 },
761
+ },
762
+ },
763
+ gradientStop: {
764
+ type: "object",
765
+ required: ["color"],
766
+ additionalProperties: false,
767
+ properties: {
768
+ color: { type: "string", minLength: 1 },
769
+ at: { type: "number", minimum: 0, maximum: 100 },
770
+ },
771
+ },
772
+ },
773
+ };
774
+ //# sourceMappingURL=manifest-schema.js.map