@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.
- package/dist/background-validation.d.ts +3 -0
- package/dist/background-validation.d.ts.map +1 -0
- package/dist/background-validation.js +177 -0
- package/dist/background-validation.js.map +1 -0
- package/dist/builders.d.ts +134 -0
- package/dist/builders.d.ts.map +1 -0
- package/dist/builders.js +332 -0
- package/dist/builders.js.map +1 -0
- package/dist/capabilities.d.ts +7 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/capabilities.js +59 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/layout-validation.d.ts +4 -0
- package/dist/layout-validation.d.ts.map +1 -0
- package/dist/layout-validation.js +745 -0
- package/dist/layout-validation.js.map +1 -0
- package/dist/manifest-schema.d.ts +1328 -0
- package/dist/manifest-schema.d.ts.map +1 -0
- package/dist/manifest-schema.js +774 -0
- package/dist/manifest-schema.js.map +1 -0
- package/dist/theme-validation.d.ts +3 -0
- package/dist/theme-validation.d.ts.map +1 -0
- package/dist/theme-validation.js +239 -0
- package/dist/theme-validation.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types.d.ts +398 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/validation-issue.d.ts +18 -0
- package/dist/validation-issue.d.ts.map +1 -0
- package/dist/validation-issue.js +30 -0
- package/dist/validation-issue.js.map +1 -0
- package/dist/validation.d.ts +4 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +274 -0
- package/dist/validation.js.map +1 -0
- package/package.json +16 -0
- package/src/background-validation.ts +315 -0
- package/src/builders.ts +626 -0
- package/src/capabilities.ts +99 -0
- package/src/index.ts +147 -0
- package/src/layout-validation.ts +1385 -0
- package/src/manifest-schema.ts +823 -0
- package/src/theme-validation.ts +410 -0
- package/src/types.ts +560 -0
- package/src/validation-issue.ts +43 -0
- package/src/validation.ts +468 -0
- package/tsconfig.json +9 -0
package/src/types.ts
ADDED
|
@@ -0,0 +1,560 @@
|
|
|
1
|
+
export type JsonPrimitive = string | number | boolean | null;
|
|
2
|
+
|
|
3
|
+
export type JsonValue =
|
|
4
|
+
| JsonPrimitive
|
|
5
|
+
| { readonly [key: string]: JsonValue }
|
|
6
|
+
| readonly JsonValue[];
|
|
7
|
+
|
|
8
|
+
export type SlideKind = "slide" | "scene";
|
|
9
|
+
|
|
10
|
+
export interface DeckMetadata {
|
|
11
|
+
readonly title: string;
|
|
12
|
+
readonly description?: string;
|
|
13
|
+
readonly author?: string;
|
|
14
|
+
readonly watermark?: string;
|
|
15
|
+
readonly [key: string]: JsonValue | undefined;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface CameraVector {
|
|
19
|
+
readonly x?: number;
|
|
20
|
+
readonly y?: number;
|
|
21
|
+
readonly z?: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface Camera {
|
|
25
|
+
readonly from?: CameraVector;
|
|
26
|
+
readonly to?: CameraVector;
|
|
27
|
+
readonly zoom?: number;
|
|
28
|
+
readonly [key: string]: JsonValue | CameraVector | undefined;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export type CameraEasing =
|
|
32
|
+
| "linear"
|
|
33
|
+
| "ease"
|
|
34
|
+
| "ease-in"
|
|
35
|
+
| "ease-out"
|
|
36
|
+
| "ease-in-out";
|
|
37
|
+
|
|
38
|
+
export interface CameraView {
|
|
39
|
+
readonly x: number;
|
|
40
|
+
readonly y: number;
|
|
41
|
+
readonly zoom?: number;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface CameraTransition {
|
|
45
|
+
readonly duration?: number;
|
|
46
|
+
readonly easing?: CameraEasing;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface CameraStop {
|
|
50
|
+
readonly camera: CameraView;
|
|
51
|
+
readonly transition?: CameraTransition;
|
|
52
|
+
readonly cues?: readonly Cue[];
|
|
53
|
+
readonly hold?: number;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface Layer {
|
|
57
|
+
readonly id?: string;
|
|
58
|
+
readonly type: string;
|
|
59
|
+
readonly content?: JsonValue;
|
|
60
|
+
readonly props?: Record<string, JsonValue>;
|
|
61
|
+
readonly timing?: Record<string, JsonValue>;
|
|
62
|
+
readonly visible?: boolean;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface LayoutMeta {
|
|
66
|
+
readonly safeArea?: "default" | "full-bleed" | "title-safe";
|
|
67
|
+
readonly depth?: number;
|
|
68
|
+
readonly cameraHint?: "static" | "push" | "pan" | "orbit";
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface HeadingElement {
|
|
72
|
+
readonly kind: "heading";
|
|
73
|
+
readonly text: string;
|
|
74
|
+
readonly size?: "default" | "display" | "hero";
|
|
75
|
+
readonly level?: 1 | 2 | 3 | 4 | 5 | 6;
|
|
76
|
+
readonly transform?: "uppercase" | "lowercase" | "capitalize";
|
|
77
|
+
readonly decoration?: "underline" | "line-through";
|
|
78
|
+
readonly glow?: boolean;
|
|
79
|
+
readonly tone?:
|
|
80
|
+
| "default"
|
|
81
|
+
| "muted"
|
|
82
|
+
| "accent"
|
|
83
|
+
| "danger"
|
|
84
|
+
| "magenta"
|
|
85
|
+
| "cyan"
|
|
86
|
+
| "purple"
|
|
87
|
+
| "green";
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export interface TextElement {
|
|
91
|
+
readonly kind: "text";
|
|
92
|
+
readonly text: string;
|
|
93
|
+
readonly variant?: "body" | "lead" | "caption";
|
|
94
|
+
readonly transform?: "uppercase" | "lowercase" | "capitalize";
|
|
95
|
+
readonly decoration?: "underline" | "line-through";
|
|
96
|
+
readonly glow?: boolean;
|
|
97
|
+
readonly tone?:
|
|
98
|
+
| "default"
|
|
99
|
+
| "muted"
|
|
100
|
+
| "accent"
|
|
101
|
+
| "danger"
|
|
102
|
+
| "magenta"
|
|
103
|
+
| "cyan"
|
|
104
|
+
| "purple"
|
|
105
|
+
| "green";
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export interface MediaElement {
|
|
109
|
+
readonly kind: "media";
|
|
110
|
+
readonly src: string;
|
|
111
|
+
readonly alt: string;
|
|
112
|
+
readonly fit?: "contain" | "cover" | "fill";
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export interface CalloutElement {
|
|
116
|
+
readonly kind: "callout";
|
|
117
|
+
readonly tone?: "info" | "warning" | "success" | "danger" | "quote";
|
|
118
|
+
readonly children: readonly LayoutNode[];
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export interface StackLayout {
|
|
122
|
+
readonly kind: "stack";
|
|
123
|
+
readonly children: readonly LayoutNode[];
|
|
124
|
+
readonly direction?: "vertical" | "horizontal";
|
|
125
|
+
readonly align?: "start" | "center" | "end" | "stretch";
|
|
126
|
+
readonly gap?: string;
|
|
127
|
+
readonly justify?: "start" | "center" | "between" | "end";
|
|
128
|
+
readonly meta?: LayoutMeta;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export interface GridLayout {
|
|
132
|
+
readonly kind: "grid";
|
|
133
|
+
readonly children: readonly LayoutNode[];
|
|
134
|
+
readonly columns?: number;
|
|
135
|
+
readonly rows?: number;
|
|
136
|
+
readonly meta?: LayoutMeta;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export interface SplitLayout {
|
|
140
|
+
readonly kind: "split";
|
|
141
|
+
readonly children: readonly LayoutNode[];
|
|
142
|
+
readonly weights?: readonly number[];
|
|
143
|
+
readonly meta?: LayoutMeta;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export interface HeroLayout {
|
|
147
|
+
readonly kind: "hero";
|
|
148
|
+
readonly children: readonly LayoutNode[];
|
|
149
|
+
readonly meta?: LayoutMeta;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export interface FrameLayout {
|
|
153
|
+
readonly kind: "frame";
|
|
154
|
+
readonly children: readonly LayoutNode[];
|
|
155
|
+
readonly meta?: LayoutMeta;
|
|
156
|
+
readonly tone?:
|
|
157
|
+
| "default"
|
|
158
|
+
| "muted"
|
|
159
|
+
| "accent"
|
|
160
|
+
| "danger"
|
|
161
|
+
| "magenta"
|
|
162
|
+
| "cyan"
|
|
163
|
+
| "purple"
|
|
164
|
+
| "green";
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export interface CanvasItem {
|
|
168
|
+
readonly x: number;
|
|
169
|
+
readonly y: number;
|
|
170
|
+
readonly width?: number;
|
|
171
|
+
readonly height?: number;
|
|
172
|
+
readonly child: LayoutNode;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export interface CanvasLayout {
|
|
176
|
+
readonly kind: "canvas";
|
|
177
|
+
readonly items: readonly CanvasItem[];
|
|
178
|
+
readonly meta?: LayoutMeta;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export interface TableColumn {
|
|
182
|
+
readonly header?: LayoutNode;
|
|
183
|
+
readonly weight?: number;
|
|
184
|
+
readonly align?: "start" | "center" | "end";
|
|
185
|
+
readonly emphasis?: boolean;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export interface TableLayout {
|
|
189
|
+
readonly kind: "table";
|
|
190
|
+
readonly columns: readonly TableColumn[];
|
|
191
|
+
readonly rows: readonly (readonly LayoutNode[])[];
|
|
192
|
+
readonly meta?: LayoutMeta;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export type AnimationName =
|
|
196
|
+
| "rise"
|
|
197
|
+
| "fade"
|
|
198
|
+
| "zoom"
|
|
199
|
+
| "draw"
|
|
200
|
+
| "in-left"
|
|
201
|
+
| "in-right"
|
|
202
|
+
| "glow"
|
|
203
|
+
| "blink"
|
|
204
|
+
| "pulse"
|
|
205
|
+
| "sweep";
|
|
206
|
+
|
|
207
|
+
export interface AnimateLayout {
|
|
208
|
+
readonly kind: "animate";
|
|
209
|
+
readonly name: AnimationName;
|
|
210
|
+
readonly delay?: number;
|
|
211
|
+
readonly duration?: number;
|
|
212
|
+
readonly easing?: string;
|
|
213
|
+
readonly child: LayoutNode;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export type CodeTokenKind =
|
|
217
|
+
| "keyword"
|
|
218
|
+
| "function"
|
|
219
|
+
| "string"
|
|
220
|
+
| "number"
|
|
221
|
+
| "property"
|
|
222
|
+
| "comment"
|
|
223
|
+
| "punctuation"
|
|
224
|
+
| "plain";
|
|
225
|
+
|
|
226
|
+
export interface CodeToken {
|
|
227
|
+
readonly text: string;
|
|
228
|
+
readonly kind?: CodeTokenKind;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export interface CodeElement {
|
|
232
|
+
readonly kind: "code";
|
|
233
|
+
readonly lines: readonly (readonly CodeToken[])[];
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export type IconName = "check" | "cross" | "dash" | "ring" | "dot" | "arrow";
|
|
237
|
+
|
|
238
|
+
export interface IconElement {
|
|
239
|
+
readonly kind: "icon";
|
|
240
|
+
readonly name: IconName;
|
|
241
|
+
readonly tone?:
|
|
242
|
+
| "default"
|
|
243
|
+
| "muted"
|
|
244
|
+
| "accent"
|
|
245
|
+
| "danger"
|
|
246
|
+
| "magenta"
|
|
247
|
+
| "cyan"
|
|
248
|
+
| "purple"
|
|
249
|
+
| "green";
|
|
250
|
+
readonly label?: string;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
export interface ConnectorPoint {
|
|
254
|
+
readonly x: number;
|
|
255
|
+
readonly y: number;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export interface ConnectorElement {
|
|
259
|
+
readonly kind: "connector";
|
|
260
|
+
readonly from: ConnectorPoint;
|
|
261
|
+
readonly to: ConnectorPoint;
|
|
262
|
+
readonly control?: ConnectorPoint;
|
|
263
|
+
readonly arrow?: "none" | "end" | "start" | "both";
|
|
264
|
+
readonly dashed?: boolean;
|
|
265
|
+
readonly tone?:
|
|
266
|
+
| "default"
|
|
267
|
+
| "muted"
|
|
268
|
+
| "accent"
|
|
269
|
+
| "danger"
|
|
270
|
+
| "magenta"
|
|
271
|
+
| "cyan"
|
|
272
|
+
| "purple"
|
|
273
|
+
| "green";
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export interface BadgeElement {
|
|
277
|
+
readonly kind: "badge";
|
|
278
|
+
readonly text: string;
|
|
279
|
+
readonly tone?:
|
|
280
|
+
| "default"
|
|
281
|
+
| "muted"
|
|
282
|
+
| "accent"
|
|
283
|
+
| "danger"
|
|
284
|
+
| "magenta"
|
|
285
|
+
| "cyan"
|
|
286
|
+
| "purple"
|
|
287
|
+
| "green";
|
|
288
|
+
readonly variant?: "outline" | "soft" | "solid";
|
|
289
|
+
readonly dot?: BadgeElement["tone"];
|
|
290
|
+
readonly mono?: boolean;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
export interface RuleElement {
|
|
294
|
+
readonly kind: "rule";
|
|
295
|
+
readonly length?: string | number;
|
|
296
|
+
readonly thickness?: number;
|
|
297
|
+
readonly tone?: BadgeElement["tone"];
|
|
298
|
+
readonly gradient?: readonly [BadgeElement["tone"], BadgeElement["tone"]];
|
|
299
|
+
readonly radius?: number;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
export type ContentElement =
|
|
303
|
+
| HeadingElement
|
|
304
|
+
| TextElement
|
|
305
|
+
| MediaElement
|
|
306
|
+
| CalloutElement
|
|
307
|
+
| CodeElement
|
|
308
|
+
| IconElement
|
|
309
|
+
| ConnectorElement
|
|
310
|
+
| BadgeElement
|
|
311
|
+
| RuleElement;
|
|
312
|
+
|
|
313
|
+
export type LayoutNode =
|
|
314
|
+
| StackLayout
|
|
315
|
+
| GridLayout
|
|
316
|
+
| SplitLayout
|
|
317
|
+
| HeroLayout
|
|
318
|
+
| FrameLayout
|
|
319
|
+
| CanvasLayout
|
|
320
|
+
| AnimateLayout
|
|
321
|
+
| TableLayout
|
|
322
|
+
| ContentElement;
|
|
323
|
+
|
|
324
|
+
export interface Fragment {
|
|
325
|
+
readonly id: string;
|
|
326
|
+
readonly layerId?: string;
|
|
327
|
+
readonly transition?: string;
|
|
328
|
+
readonly cues?: readonly string[];
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
export interface CueAction {
|
|
332
|
+
readonly type: string;
|
|
333
|
+
readonly target?: string;
|
|
334
|
+
readonly payload?: JsonValue;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
export interface Cue {
|
|
338
|
+
readonly time: number;
|
|
339
|
+
readonly action: CueAction;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
export type BlendMode = "normal" | "screen" | "multiply" | "overlay";
|
|
343
|
+
|
|
344
|
+
export interface GradientStop {
|
|
345
|
+
readonly color: string;
|
|
346
|
+
readonly at?: number;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
export interface LinearGradientLayer {
|
|
350
|
+
readonly type: "linear";
|
|
351
|
+
readonly stops: readonly GradientStop[];
|
|
352
|
+
readonly angle?: number;
|
|
353
|
+
readonly blend?: BlendMode;
|
|
354
|
+
readonly opacity?: number;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
export interface RadialGradientLayer {
|
|
358
|
+
readonly type: "radial";
|
|
359
|
+
readonly stops: readonly GradientStop[];
|
|
360
|
+
readonly shape?: "circle" | "ellipse";
|
|
361
|
+
readonly position?: { readonly x: number; readonly y: number };
|
|
362
|
+
readonly blend?: BlendMode;
|
|
363
|
+
readonly opacity?: number;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
export type BackgroundLayer = LinearGradientLayer | RadialGradientLayer;
|
|
367
|
+
|
|
368
|
+
export interface Background {
|
|
369
|
+
readonly color?: string;
|
|
370
|
+
readonly layers?: readonly BackgroundLayer[];
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
export interface Slide {
|
|
374
|
+
readonly id: string;
|
|
375
|
+
readonly kind: "slide";
|
|
376
|
+
readonly background?: Background;
|
|
377
|
+
readonly content?: JsonValue;
|
|
378
|
+
readonly layout?: LayoutNode;
|
|
379
|
+
readonly layers?: readonly Layer[];
|
|
380
|
+
readonly fragments?: readonly Fragment[];
|
|
381
|
+
readonly cues?: readonly Cue[];
|
|
382
|
+
readonly notes?: string;
|
|
383
|
+
readonly mood?: string;
|
|
384
|
+
readonly transition?: string;
|
|
385
|
+
readonly chrome?: boolean;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
export interface Scene {
|
|
389
|
+
readonly id: string;
|
|
390
|
+
readonly kind: "scene";
|
|
391
|
+
readonly background?: Background;
|
|
392
|
+
readonly duration?: number;
|
|
393
|
+
readonly camera?: Camera;
|
|
394
|
+
readonly cameraPath?: readonly CameraStop[];
|
|
395
|
+
readonly layout?: LayoutNode;
|
|
396
|
+
readonly layers?: readonly Layer[];
|
|
397
|
+
readonly fragments?: readonly Fragment[];
|
|
398
|
+
readonly cues?: readonly Cue[];
|
|
399
|
+
readonly notes?: string;
|
|
400
|
+
readonly mood?: string;
|
|
401
|
+
readonly transition?: string;
|
|
402
|
+
readonly chrome?: boolean;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
export type SlideEntry = Slide | Scene;
|
|
406
|
+
|
|
407
|
+
export interface Asset {
|
|
408
|
+
readonly id: string;
|
|
409
|
+
readonly type: string;
|
|
410
|
+
readonly src: string;
|
|
411
|
+
readonly metadata?: Record<string, JsonValue>;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
export interface Plugin {
|
|
415
|
+
readonly id: string;
|
|
416
|
+
readonly packageName?: string;
|
|
417
|
+
readonly options?: Record<string, JsonValue>;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
export type TokenReference = string;
|
|
421
|
+
|
|
422
|
+
export interface TypographyToken {
|
|
423
|
+
readonly fontFamily?: string;
|
|
424
|
+
readonly fontSize?: string | number;
|
|
425
|
+
readonly lineHeight?: string | number;
|
|
426
|
+
readonly fontWeight?: string | number;
|
|
427
|
+
readonly letterSpacing?: string | number;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
export interface MotionToken {
|
|
431
|
+
readonly duration?: string | number;
|
|
432
|
+
readonly easing?: string;
|
|
433
|
+
readonly delay?: string | number;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
export interface ThemeTokens {
|
|
437
|
+
readonly colors?: Record<string, string>;
|
|
438
|
+
readonly typography?: Record<string, TypographyToken>;
|
|
439
|
+
readonly spacing?: Record<string, string | number>;
|
|
440
|
+
readonly radii?: Record<string, string | number>;
|
|
441
|
+
readonly shadows?: Record<string, string>;
|
|
442
|
+
readonly motion?: Record<string, MotionToken>;
|
|
443
|
+
readonly surfaces?: Record<string, TokenReference>;
|
|
444
|
+
readonly text?: Record<string, TokenReference>;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
export interface ThemeFontFace {
|
|
448
|
+
readonly family: string;
|
|
449
|
+
readonly source: string;
|
|
450
|
+
readonly format?: string;
|
|
451
|
+
readonly weight?: string | number;
|
|
452
|
+
readonly style?: string;
|
|
453
|
+
readonly display?: string;
|
|
454
|
+
readonly unicodeRange?: string;
|
|
455
|
+
readonly stretch?: string;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
export interface Theme {
|
|
459
|
+
readonly id: string;
|
|
460
|
+
readonly tokens?: ThemeTokens;
|
|
461
|
+
readonly css?: string;
|
|
462
|
+
readonly fonts?: readonly ThemeFontFace[];
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
export interface ExportOptions {
|
|
466
|
+
readonly formats?: readonly string[];
|
|
467
|
+
readonly metadata?: Record<string, JsonValue>;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
export interface RuntimeOptions {
|
|
471
|
+
readonly [key: string]: JsonValue | undefined;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
export interface Deck {
|
|
475
|
+
readonly title: string;
|
|
476
|
+
readonly description?: string;
|
|
477
|
+
readonly theme?: string | Theme;
|
|
478
|
+
readonly slides: readonly SlideEntry[];
|
|
479
|
+
readonly assets?: readonly Asset[];
|
|
480
|
+
readonly plugins?: readonly Plugin[];
|
|
481
|
+
readonly runtime?: RuntimeOptions;
|
|
482
|
+
readonly export?: ExportOptions;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
export interface Manifest {
|
|
486
|
+
readonly deck: DeckMetadata;
|
|
487
|
+
readonly slides: readonly SlideEntry[];
|
|
488
|
+
readonly assets?: readonly Asset[];
|
|
489
|
+
readonly plugins?: readonly Plugin[];
|
|
490
|
+
readonly theme?: Theme;
|
|
491
|
+
readonly export?: ExportOptions;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
export type ValidationIssueCode =
|
|
495
|
+
| "required"
|
|
496
|
+
| "wrong_type"
|
|
497
|
+
| "unknown_field"
|
|
498
|
+
| "unknown_kind"
|
|
499
|
+
| "invalid_enum"
|
|
500
|
+
| "invalid_value"
|
|
501
|
+
| "constraint"
|
|
502
|
+
| "not_serializable"
|
|
503
|
+
| "renderer_specific";
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* A single, machine-readable validation problem.
|
|
507
|
+
*
|
|
508
|
+
* `message` is the human-readable string (identical to the legacy flat
|
|
509
|
+
* `errors` entries). `code`, `expected`, `received`, and `suggestion` are the
|
|
510
|
+
* AI-first additions: a stable code an agent can branch on, the expected shape
|
|
511
|
+
* or allowed values, what was actually found, and a concrete fix hint.
|
|
512
|
+
*/
|
|
513
|
+
export interface ValidationIssue {
|
|
514
|
+
readonly path: string;
|
|
515
|
+
readonly code: ValidationIssueCode;
|
|
516
|
+
readonly message: string;
|
|
517
|
+
readonly expected?: string;
|
|
518
|
+
readonly received?: string;
|
|
519
|
+
readonly suggestion?: string;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
export interface ManifestValidationResult {
|
|
523
|
+
readonly valid: boolean;
|
|
524
|
+
readonly errors: readonly string[];
|
|
525
|
+
readonly issues: readonly ValidationIssue[];
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
/**
|
|
529
|
+
* A single authorable field on a layout or content node, as advertised to an
|
|
530
|
+
* agent through {@link VelumoCapabilities}.
|
|
531
|
+
*
|
|
532
|
+
* `type` is a friendly type hint derived from the schema: a JSON type
|
|
533
|
+
* (`string`, `number`, `integer`, `boolean`, `object`, `array`), a union like
|
|
534
|
+
* `string|number`, `enum` (with allowed values in `enum`), or `node[]` for a
|
|
535
|
+
* field that holds child layout nodes.
|
|
536
|
+
*/
|
|
537
|
+
export interface CapabilityField {
|
|
538
|
+
readonly name: string;
|
|
539
|
+
readonly required: boolean;
|
|
540
|
+
readonly type: string;
|
|
541
|
+
readonly enum?: readonly string[];
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
export interface NodeCapability {
|
|
545
|
+
readonly kind: string;
|
|
546
|
+
readonly fields: readonly CapabilityField[];
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
/**
|
|
550
|
+
* A discoverable, machine-readable description of what an author can express:
|
|
551
|
+
* the available slide kinds, layout/content node kinds with their fields and
|
|
552
|
+
* allowed values, and the theme token families. Projected from
|
|
553
|
+
* `manifestJsonSchema`, so it can never drift from the validated contract.
|
|
554
|
+
*/
|
|
555
|
+
export interface VelumoCapabilities {
|
|
556
|
+
readonly schemaId: string;
|
|
557
|
+
readonly slideKinds: readonly string[];
|
|
558
|
+
readonly nodes: readonly NodeCapability[];
|
|
559
|
+
readonly themeTokenFamilies: readonly string[];
|
|
560
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { ValidationIssue, ValidationIssueCode } from "./types.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Describe the runtime type of a value for the `received` field of an issue.
|
|
5
|
+
* Distinguishes the JSON-relevant cases (null, array) from `typeof`.
|
|
6
|
+
*/
|
|
7
|
+
export function describeType(value: unknown): string {
|
|
8
|
+
if (value === null) {
|
|
9
|
+
return "null";
|
|
10
|
+
}
|
|
11
|
+
if (Array.isArray(value)) {
|
|
12
|
+
return "array";
|
|
13
|
+
}
|
|
14
|
+
return typeof value;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface IssueExtras {
|
|
18
|
+
readonly expected?: string;
|
|
19
|
+
readonly received?: string;
|
|
20
|
+
readonly suggestion?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Build a {@link ValidationIssue}, omitting any optional field that is
|
|
25
|
+
* undefined so issues stay clean to compare and serialize.
|
|
26
|
+
*/
|
|
27
|
+
export function issue(
|
|
28
|
+
path: string,
|
|
29
|
+
code: ValidationIssueCode,
|
|
30
|
+
message: string,
|
|
31
|
+
extras: IssueExtras = {},
|
|
32
|
+
): ValidationIssue {
|
|
33
|
+
return {
|
|
34
|
+
path,
|
|
35
|
+
code,
|
|
36
|
+
message,
|
|
37
|
+
...(extras.expected !== undefined ? { expected: extras.expected } : {}),
|
|
38
|
+
...(extras.received !== undefined ? { received: extras.received } : {}),
|
|
39
|
+
...(extras.suggestion !== undefined
|
|
40
|
+
? { suggestion: extras.suggestion }
|
|
41
|
+
: {}),
|
|
42
|
+
};
|
|
43
|
+
}
|