document-schema 0.0.0 → 1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +36 -0
- package/dist/index.cjs +602 -0
- package/dist/index.d.cts +2416 -0
- package/dist/index.d.ts +2416 -0
- package/dist/index.js +539 -0
- package/package.json +83 -3
package/dist/index.js
ADDED
|
@@ -0,0 +1,539 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
//#region src/color.ts
|
|
3
|
+
const ColorSchema = z.object({
|
|
4
|
+
r: z.number().min(0).max(1),
|
|
5
|
+
g: z.number().min(0).max(1),
|
|
6
|
+
b: z.number().min(0).max(1)
|
|
7
|
+
});
|
|
8
|
+
const COLOR_BLACK = {
|
|
9
|
+
r: 0,
|
|
10
|
+
g: 0,
|
|
11
|
+
b: 0
|
|
12
|
+
};
|
|
13
|
+
const HEX_COLOR_PATTERN = /^#?([0-9a-fA-F]{6})$/;
|
|
14
|
+
const HEX_BYTE_MAX = 255;
|
|
15
|
+
function rgbHexToColor(hex) {
|
|
16
|
+
const match = HEX_COLOR_PATTERN.exec(hex);
|
|
17
|
+
if (match === null) throw new Error(`not a 6-digit hex colour: ${hex}`);
|
|
18
|
+
const digits = match[1];
|
|
19
|
+
if (digits === void 0) throw new Error(`not a 6-digit hex colour: ${hex}`);
|
|
20
|
+
const r = Number.parseInt(digits.slice(0, 2), 16);
|
|
21
|
+
const g = Number.parseInt(digits.slice(2, 4), 16);
|
|
22
|
+
const b = Number.parseInt(digits.slice(4, 6), 16);
|
|
23
|
+
return {
|
|
24
|
+
r: r / HEX_BYTE_MAX,
|
|
25
|
+
g: g / HEX_BYTE_MAX,
|
|
26
|
+
b: b / HEX_BYTE_MAX
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function toHexByte(component) {
|
|
30
|
+
return Math.round(component * HEX_BYTE_MAX).toString(16).padStart(2, "0");
|
|
31
|
+
}
|
|
32
|
+
function colorToRgbHex(color) {
|
|
33
|
+
return `${toHexByte(color.r)}${toHexByte(color.g)}${toHexByte(color.b)}`;
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
//#region src/geometry.ts
|
|
37
|
+
const BoxSchema = z.object({
|
|
38
|
+
xPt: z.number(),
|
|
39
|
+
yPt: z.number(),
|
|
40
|
+
widthPt: z.number().nonnegative(),
|
|
41
|
+
heightPt: z.number().nonnegative()
|
|
42
|
+
});
|
|
43
|
+
const PageSizeSchema = z.object({
|
|
44
|
+
widthPt: z.number().positive(),
|
|
45
|
+
heightPt: z.number().positive()
|
|
46
|
+
});
|
|
47
|
+
const MarginsSchema = z.object({
|
|
48
|
+
topPt: z.number().nonnegative(),
|
|
49
|
+
rightPt: z.number().nonnegative(),
|
|
50
|
+
bottomPt: z.number().nonnegative(),
|
|
51
|
+
leftPt: z.number().nonnegative()
|
|
52
|
+
});
|
|
53
|
+
const PAGE_SIZE_LETTER = {
|
|
54
|
+
widthPt: 612,
|
|
55
|
+
heightPt: 792
|
|
56
|
+
};
|
|
57
|
+
const PAGE_SIZE_A4 = {
|
|
58
|
+
widthPt: 595.28,
|
|
59
|
+
heightPt: 841.89
|
|
60
|
+
};
|
|
61
|
+
const SLIDE_SIZE_WIDESCREEN = {
|
|
62
|
+
widthPt: 960,
|
|
63
|
+
heightPt: 540
|
|
64
|
+
};
|
|
65
|
+
const SLIDE_SIZE_STANDARD = {
|
|
66
|
+
widthPt: 720,
|
|
67
|
+
heightPt: 540
|
|
68
|
+
};
|
|
69
|
+
//#endregion
|
|
70
|
+
//#region src/style.ts
|
|
71
|
+
const AlignmentSchema = z.enum([
|
|
72
|
+
"left",
|
|
73
|
+
"center",
|
|
74
|
+
"right",
|
|
75
|
+
"justify"
|
|
76
|
+
]);
|
|
77
|
+
const LayoutFontSchema = z.object({
|
|
78
|
+
family: z.string(),
|
|
79
|
+
weight: z.enum(["normal", "bold"]),
|
|
80
|
+
style: z.enum(["normal", "italic"])
|
|
81
|
+
});
|
|
82
|
+
const DEFAULT_LAYOUT_FONT = {
|
|
83
|
+
family: "Helvetica",
|
|
84
|
+
weight: "normal",
|
|
85
|
+
style: "normal"
|
|
86
|
+
};
|
|
87
|
+
//#endregion
|
|
88
|
+
//#region src/metadata.ts
|
|
89
|
+
const LayoutMetadataSchema = z.object({
|
|
90
|
+
title: z.string().optional(),
|
|
91
|
+
author: z.string().optional(),
|
|
92
|
+
subject: z.string().optional(),
|
|
93
|
+
keywords: z.array(z.string()).optional(),
|
|
94
|
+
creator: z.string().optional(),
|
|
95
|
+
producer: z.string().optional(),
|
|
96
|
+
createdIso: z.string().optional(),
|
|
97
|
+
modifiedIso: z.string().optional()
|
|
98
|
+
});
|
|
99
|
+
//#endregion
|
|
100
|
+
//#region src/content.ts
|
|
101
|
+
const ContentRunSchema = z.object({
|
|
102
|
+
text: z.string(),
|
|
103
|
+
bold: z.boolean().optional(),
|
|
104
|
+
italic: z.boolean().optional(),
|
|
105
|
+
underline: z.boolean().optional(),
|
|
106
|
+
strike: z.boolean().optional(),
|
|
107
|
+
fontFamily: z.string().optional(),
|
|
108
|
+
sizePt: z.number().positive().optional(),
|
|
109
|
+
color: ColorSchema.optional(),
|
|
110
|
+
hyperlink: z.string().optional(),
|
|
111
|
+
sourcePath: z.string().optional()
|
|
112
|
+
});
|
|
113
|
+
const ContentListMembershipSchema = z.object({
|
|
114
|
+
numId: z.string(),
|
|
115
|
+
level: z.number().int().nonnegative()
|
|
116
|
+
});
|
|
117
|
+
const ContentParagraphSchema = z.object({
|
|
118
|
+
kind: z.literal("paragraph"),
|
|
119
|
+
runs: z.array(ContentRunSchema),
|
|
120
|
+
styleId: z.string().optional(),
|
|
121
|
+
alignment: AlignmentSchema.optional(),
|
|
122
|
+
list: ContentListMembershipSchema.optional(),
|
|
123
|
+
spacingBeforePt: z.number().optional(),
|
|
124
|
+
spacingAfterPt: z.number().optional(),
|
|
125
|
+
lineSpacing: z.number().positive().optional(),
|
|
126
|
+
indentLeftPt: z.number().optional(),
|
|
127
|
+
indentFirstLinePt: z.number().optional(),
|
|
128
|
+
sourcePath: z.string().optional()
|
|
129
|
+
});
|
|
130
|
+
const ContentImageBlockSchema = z.object({
|
|
131
|
+
kind: z.literal("image"),
|
|
132
|
+
format: z.enum(["png", "jpeg"]),
|
|
133
|
+
base64: z.string(),
|
|
134
|
+
widthPt: z.number().positive(),
|
|
135
|
+
heightPt: z.number().positive(),
|
|
136
|
+
altText: z.string().optional(),
|
|
137
|
+
sourcePath: z.string().optional()
|
|
138
|
+
});
|
|
139
|
+
const ContentPageBreakSchema = z.object({
|
|
140
|
+
kind: z.literal("pageBreak"),
|
|
141
|
+
sourcePath: z.string().optional()
|
|
142
|
+
});
|
|
143
|
+
function isRecord(value) {
|
|
144
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
145
|
+
}
|
|
146
|
+
function isContentRun(value) {
|
|
147
|
+
return isRecord(value) && typeof value.text === "string";
|
|
148
|
+
}
|
|
149
|
+
function isContentTableCell(value) {
|
|
150
|
+
return isRecord(value) && Array.isArray(value.blocks) && value.blocks.every(isContentBlock);
|
|
151
|
+
}
|
|
152
|
+
function isContentTableRow(value) {
|
|
153
|
+
return isRecord(value) && Array.isArray(value.cells) && value.cells.every(isContentTableCell) && (value.heightPt === void 0 || typeof value.heightPt === "number");
|
|
154
|
+
}
|
|
155
|
+
function isContentEmbeddedObjectKind(value) {
|
|
156
|
+
return value === "formula" || value === "wordprocessing" || value === "presentation" || value === "spreadsheet" || value === "drawing";
|
|
157
|
+
}
|
|
158
|
+
function isContentEmbeddedObject(value) {
|
|
159
|
+
return isRecord(value) && isContentEmbeddedObjectKind(value.objectKind) && BoxSchema.safeParse(value.frame).success && ContentDocumentSchema.safeParse(value.document).success;
|
|
160
|
+
}
|
|
161
|
+
function isContentEmbeddedObjectBlock(value) {
|
|
162
|
+
return isRecord(value) && value.kind === "embeddedObject" && isContentEmbeddedObject(value);
|
|
163
|
+
}
|
|
164
|
+
function isContentBlock(value) {
|
|
165
|
+
if (!isRecord(value)) return false;
|
|
166
|
+
const kind = value.kind;
|
|
167
|
+
if (kind === "paragraph") return Array.isArray(value.runs) && value.runs.every(isContentRun);
|
|
168
|
+
if (kind === "image") return (value.format === "png" || value.format === "jpeg") && typeof value.base64 === "string" && typeof value.widthPt === "number" && typeof value.heightPt === "number";
|
|
169
|
+
if (kind === "pageBreak") return true;
|
|
170
|
+
if (kind === "table") return Array.isArray(value.rows) && value.rows.every(isContentTableRow) && Array.isArray(value.columnWidthsPt) && value.columnWidthsPt.every((w) => typeof w === "number");
|
|
171
|
+
if (kind === "embeddedObject") return isContentEmbeddedObject(value);
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
const ContentBlockSchema = z.custom(isContentBlock);
|
|
175
|
+
const ContentEmbeddedObjectSchema = z.custom(isContentEmbeddedObject);
|
|
176
|
+
const ContentEmbeddedObjectBlockSchema = z.custom(isContentEmbeddedObjectBlock);
|
|
177
|
+
const ContentTableCellSchema = z.object({
|
|
178
|
+
blocks: z.array(ContentBlockSchema),
|
|
179
|
+
colSpan: z.number().int().positive().optional(),
|
|
180
|
+
rowSpan: z.number().int().positive().optional(),
|
|
181
|
+
background: ColorSchema.optional()
|
|
182
|
+
});
|
|
183
|
+
const ContentTableRowSchema = z.object({
|
|
184
|
+
cells: z.array(ContentTableCellSchema),
|
|
185
|
+
heightPt: z.number().positive().optional()
|
|
186
|
+
});
|
|
187
|
+
const ContentTableSchema = z.object({
|
|
188
|
+
kind: z.literal("table"),
|
|
189
|
+
rows: z.array(ContentTableRowSchema),
|
|
190
|
+
columnWidthsPt: z.array(z.number().positive()),
|
|
191
|
+
sourcePath: z.string().optional()
|
|
192
|
+
});
|
|
193
|
+
const ContentSectionSchema = z.object({
|
|
194
|
+
pageSize: PageSizeSchema,
|
|
195
|
+
margins: MarginsSchema,
|
|
196
|
+
blocks: z.array(ContentBlockSchema)
|
|
197
|
+
});
|
|
198
|
+
const ContentShapeSchema = z.object({
|
|
199
|
+
name: z.string().optional(),
|
|
200
|
+
frame: BoxSchema,
|
|
201
|
+
rotationDeg: z.number().optional(),
|
|
202
|
+
insetLeftPt: z.number().nonnegative(),
|
|
203
|
+
insetTopPt: z.number().nonnegative(),
|
|
204
|
+
insetRightPt: z.number().nonnegative(),
|
|
205
|
+
insetBottomPt: z.number().nonnegative(),
|
|
206
|
+
fontScale: z.number().positive().optional(),
|
|
207
|
+
lineSpacingReduction: z.number().nonnegative().optional(),
|
|
208
|
+
sourcePath: z.string().optional(),
|
|
209
|
+
blocks: z.array(ContentBlockSchema)
|
|
210
|
+
});
|
|
211
|
+
const ContentSlideSchema = z.object({
|
|
212
|
+
size: PageSizeSchema,
|
|
213
|
+
shapes: z.array(ContentShapeSchema),
|
|
214
|
+
notes: z.string()
|
|
215
|
+
});
|
|
216
|
+
const ContentCellValueSchema = z.discriminatedUnion("kind", [
|
|
217
|
+
z.object({
|
|
218
|
+
kind: z.literal("number"),
|
|
219
|
+
value: z.number()
|
|
220
|
+
}),
|
|
221
|
+
z.object({
|
|
222
|
+
kind: z.literal("percentage"),
|
|
223
|
+
value: z.number()
|
|
224
|
+
}),
|
|
225
|
+
z.object({
|
|
226
|
+
kind: z.literal("currency"),
|
|
227
|
+
value: z.number(),
|
|
228
|
+
currency: z.string().optional()
|
|
229
|
+
}),
|
|
230
|
+
z.object({
|
|
231
|
+
kind: z.literal("boolean"),
|
|
232
|
+
value: z.boolean()
|
|
233
|
+
}),
|
|
234
|
+
z.object({
|
|
235
|
+
kind: z.literal("date"),
|
|
236
|
+
value: z.string()
|
|
237
|
+
}),
|
|
238
|
+
z.object({
|
|
239
|
+
kind: z.literal("time"),
|
|
240
|
+
value: z.string()
|
|
241
|
+
}),
|
|
242
|
+
z.object({
|
|
243
|
+
kind: z.literal("string"),
|
|
244
|
+
value: z.string()
|
|
245
|
+
}),
|
|
246
|
+
z.object({
|
|
247
|
+
kind: z.literal("error"),
|
|
248
|
+
value: z.string()
|
|
249
|
+
}),
|
|
250
|
+
z.object({ kind: z.literal("empty") })
|
|
251
|
+
]);
|
|
252
|
+
const ContentSheetCellSchema = z.object({
|
|
253
|
+
row: z.number().int().nonnegative(),
|
|
254
|
+
column: z.number().int().nonnegative(),
|
|
255
|
+
value: ContentCellValueSchema,
|
|
256
|
+
formula: z.string().optional(),
|
|
257
|
+
displayText: z.string(),
|
|
258
|
+
runs: z.array(ContentRunSchema).optional(),
|
|
259
|
+
colSpan: z.number().int().positive().optional(),
|
|
260
|
+
rowSpan: z.number().int().positive().optional()
|
|
261
|
+
});
|
|
262
|
+
const ContentSheetColumnSchema = z.object({
|
|
263
|
+
index: z.number().int().nonnegative(),
|
|
264
|
+
widthPt: z.number().nonnegative(),
|
|
265
|
+
hidden: z.boolean().optional()
|
|
266
|
+
});
|
|
267
|
+
const ContentSheetRowSchema = z.object({
|
|
268
|
+
index: z.number().int().nonnegative(),
|
|
269
|
+
heightPt: z.number().nonnegative(),
|
|
270
|
+
hidden: z.boolean().optional()
|
|
271
|
+
});
|
|
272
|
+
const ContentSheetPrintRangeSchema = z.object({
|
|
273
|
+
startRow: z.number().int().nonnegative(),
|
|
274
|
+
startColumn: z.number().int().nonnegative(),
|
|
275
|
+
endRow: z.number().int().nonnegative(),
|
|
276
|
+
endColumn: z.number().int().nonnegative()
|
|
277
|
+
});
|
|
278
|
+
const ContentSheetRepeatRangeSchema = z.object({
|
|
279
|
+
start: z.number().int().nonnegative(),
|
|
280
|
+
end: z.number().int().nonnegative()
|
|
281
|
+
});
|
|
282
|
+
const ContentSheetPrintSettingsSchema = z.object({
|
|
283
|
+
pageSize: PageSizeSchema,
|
|
284
|
+
margins: MarginsSchema,
|
|
285
|
+
printRange: ContentSheetPrintRangeSchema.optional(),
|
|
286
|
+
scale: z.number().positive().optional(),
|
|
287
|
+
fitToPages: z.object({
|
|
288
|
+
width: z.number().int().positive(),
|
|
289
|
+
height: z.number().int().positive()
|
|
290
|
+
}).optional(),
|
|
291
|
+
repeatRows: ContentSheetRepeatRangeSchema.optional(),
|
|
292
|
+
repeatColumns: ContentSheetRepeatRangeSchema.optional(),
|
|
293
|
+
gridlines: z.boolean(),
|
|
294
|
+
headers: z.boolean(),
|
|
295
|
+
pageOrder: z.enum(["downThenOver", "overThenDown"]),
|
|
296
|
+
manualBreaks: z.object({
|
|
297
|
+
rows: z.array(z.number().int().nonnegative()),
|
|
298
|
+
columns: z.array(z.number().int().nonnegative())
|
|
299
|
+
}).optional()
|
|
300
|
+
});
|
|
301
|
+
const ContentSheetImageSchema = ContentImageBlockSchema.extend({
|
|
302
|
+
anchorRow: z.number().int().nonnegative(),
|
|
303
|
+
anchorColumn: z.number().int().nonnegative(),
|
|
304
|
+
offsetXPt: z.number(),
|
|
305
|
+
offsetYPt: z.number()
|
|
306
|
+
});
|
|
307
|
+
const ContentSheetSchema = z.object({
|
|
308
|
+
name: z.string(),
|
|
309
|
+
cells: z.array(ContentSheetCellSchema),
|
|
310
|
+
columns: z.array(ContentSheetColumnSchema),
|
|
311
|
+
rows: z.array(ContentSheetRowSchema),
|
|
312
|
+
images: z.array(ContentSheetImageSchema),
|
|
313
|
+
printSettings: ContentSheetPrintSettingsSchema,
|
|
314
|
+
embeddedObjects: z.array(ContentEmbeddedObjectSchema).optional()
|
|
315
|
+
});
|
|
316
|
+
const ContentStrokeSchema = z.object({
|
|
317
|
+
color: ColorSchema,
|
|
318
|
+
widthPt: z.number().positive()
|
|
319
|
+
});
|
|
320
|
+
const ContentPathPointSchema = z.object({
|
|
321
|
+
xPt: z.number(),
|
|
322
|
+
yPt: z.number()
|
|
323
|
+
});
|
|
324
|
+
const ContentPathSegmentSchema = z.discriminatedUnion("kind", [z.object({
|
|
325
|
+
kind: z.literal("line"),
|
|
326
|
+
to: ContentPathPointSchema
|
|
327
|
+
}), z.object({
|
|
328
|
+
kind: z.literal("cubic"),
|
|
329
|
+
control1: ContentPathPointSchema,
|
|
330
|
+
control2: ContentPathPointSchema,
|
|
331
|
+
to: ContentPathPointSchema
|
|
332
|
+
})]);
|
|
333
|
+
const ContentSubpathSchema = z.object({
|
|
334
|
+
start: ContentPathPointSchema,
|
|
335
|
+
segments: z.array(ContentPathSegmentSchema),
|
|
336
|
+
closed: z.boolean()
|
|
337
|
+
});
|
|
338
|
+
const ContentVectorSchema = z.discriminatedUnion("kind", [
|
|
339
|
+
z.object({
|
|
340
|
+
kind: z.literal("rect"),
|
|
341
|
+
frame: BoxSchema,
|
|
342
|
+
fill: ColorSchema.optional(),
|
|
343
|
+
stroke: ContentStrokeSchema.optional(),
|
|
344
|
+
sourcePath: z.string().optional()
|
|
345
|
+
}),
|
|
346
|
+
z.object({
|
|
347
|
+
kind: z.literal("ellipse"),
|
|
348
|
+
frame: BoxSchema,
|
|
349
|
+
fill: ColorSchema.optional(),
|
|
350
|
+
stroke: ContentStrokeSchema.optional(),
|
|
351
|
+
sourcePath: z.string().optional()
|
|
352
|
+
}),
|
|
353
|
+
z.object({
|
|
354
|
+
kind: z.literal("line"),
|
|
355
|
+
from: ContentPathPointSchema,
|
|
356
|
+
to: ContentPathPointSchema,
|
|
357
|
+
stroke: ContentStrokeSchema,
|
|
358
|
+
sourcePath: z.string().optional()
|
|
359
|
+
}),
|
|
360
|
+
z.object({
|
|
361
|
+
kind: z.literal("path"),
|
|
362
|
+
frame: BoxSchema,
|
|
363
|
+
subpaths: z.array(ContentSubpathSchema),
|
|
364
|
+
fill: ColorSchema.optional(),
|
|
365
|
+
fillRule: z.enum(["nonzero", "evenodd"]).optional(),
|
|
366
|
+
stroke: ContentStrokeSchema.optional(),
|
|
367
|
+
sourcePath: z.string().optional()
|
|
368
|
+
})
|
|
369
|
+
]);
|
|
370
|
+
const ContentDrawPageSchema = z.object({
|
|
371
|
+
size: PageSizeSchema,
|
|
372
|
+
shapes: z.array(ContentShapeSchema),
|
|
373
|
+
vectors: z.array(ContentVectorSchema)
|
|
374
|
+
});
|
|
375
|
+
const CONTENT_FORMAT_VERSION = 1;
|
|
376
|
+
const ContentDocumentSchema = z.discriminatedUnion("kind", [
|
|
377
|
+
z.object({
|
|
378
|
+
kind: z.literal("wordprocessing"),
|
|
379
|
+
formatVersion: z.literal(1),
|
|
380
|
+
metadata: LayoutMetadataSchema,
|
|
381
|
+
sections: z.array(ContentSectionSchema)
|
|
382
|
+
}),
|
|
383
|
+
z.object({
|
|
384
|
+
kind: z.literal("presentation"),
|
|
385
|
+
formatVersion: z.literal(1),
|
|
386
|
+
metadata: LayoutMetadataSchema,
|
|
387
|
+
slides: z.array(ContentSlideSchema)
|
|
388
|
+
}),
|
|
389
|
+
z.object({
|
|
390
|
+
kind: z.literal("spreadsheet"),
|
|
391
|
+
formatVersion: z.literal(1),
|
|
392
|
+
metadata: LayoutMetadataSchema,
|
|
393
|
+
sheets: z.array(ContentSheetSchema)
|
|
394
|
+
}),
|
|
395
|
+
z.object({
|
|
396
|
+
kind: z.literal("drawing"),
|
|
397
|
+
formatVersion: z.literal(1),
|
|
398
|
+
metadata: LayoutMetadataSchema,
|
|
399
|
+
pages: z.array(ContentDrawPageSchema)
|
|
400
|
+
})
|
|
401
|
+
]);
|
|
402
|
+
//#endregion
|
|
403
|
+
//#region src/layout.ts
|
|
404
|
+
const LAYOUT_FORMAT_VERSION = 1;
|
|
405
|
+
const LayoutTextSchema = z.object({
|
|
406
|
+
kind: z.literal("text"),
|
|
407
|
+
text: z.string(),
|
|
408
|
+
xPt: z.number(),
|
|
409
|
+
yPt: z.number(),
|
|
410
|
+
font: LayoutFontSchema,
|
|
411
|
+
sizePt: z.number().positive(),
|
|
412
|
+
color: ColorSchema,
|
|
413
|
+
widthPt: z.number().nonnegative().optional(),
|
|
414
|
+
rotationDeg: z.number().optional(),
|
|
415
|
+
underline: z.boolean().optional(),
|
|
416
|
+
sourcePath: z.string().optional()
|
|
417
|
+
});
|
|
418
|
+
const LayoutImageSchema = z.object({
|
|
419
|
+
kind: z.literal("image"),
|
|
420
|
+
imageId: z.string(),
|
|
421
|
+
xPt: z.number(),
|
|
422
|
+
yPt: z.number(),
|
|
423
|
+
widthPt: z.number().positive(),
|
|
424
|
+
heightPt: z.number().positive(),
|
|
425
|
+
rotationDeg: z.number().optional(),
|
|
426
|
+
sourcePath: z.string().optional()
|
|
427
|
+
});
|
|
428
|
+
const LayoutRectSchema = z.object({
|
|
429
|
+
kind: z.literal("rect"),
|
|
430
|
+
xPt: z.number(),
|
|
431
|
+
yPt: z.number(),
|
|
432
|
+
widthPt: z.number().nonnegative(),
|
|
433
|
+
heightPt: z.number().nonnegative(),
|
|
434
|
+
fill: ColorSchema.optional(),
|
|
435
|
+
stroke: z.object({
|
|
436
|
+
color: ColorSchema,
|
|
437
|
+
widthPt: z.number().positive()
|
|
438
|
+
}).optional(),
|
|
439
|
+
sourcePath: z.string().optional()
|
|
440
|
+
});
|
|
441
|
+
const LayoutLineSchema = z.object({
|
|
442
|
+
kind: z.literal("line"),
|
|
443
|
+
x1Pt: z.number(),
|
|
444
|
+
y1Pt: z.number(),
|
|
445
|
+
x2Pt: z.number(),
|
|
446
|
+
y2Pt: z.number(),
|
|
447
|
+
color: ColorSchema,
|
|
448
|
+
widthPt: z.number().positive(),
|
|
449
|
+
sourcePath: z.string().optional()
|
|
450
|
+
});
|
|
451
|
+
const LayoutEllipseSchema = z.object({
|
|
452
|
+
kind: z.literal("ellipse"),
|
|
453
|
+
xPt: z.number(),
|
|
454
|
+
yPt: z.number(),
|
|
455
|
+
widthPt: z.number().positive(),
|
|
456
|
+
heightPt: z.number().positive(),
|
|
457
|
+
fill: ColorSchema.optional(),
|
|
458
|
+
stroke: z.object({
|
|
459
|
+
color: ColorSchema,
|
|
460
|
+
widthPt: z.number().positive()
|
|
461
|
+
}).optional(),
|
|
462
|
+
sourcePath: z.string().optional()
|
|
463
|
+
});
|
|
464
|
+
const LayoutPathSegmentSchema = z.discriminatedUnion("kind", [z.object({
|
|
465
|
+
kind: z.literal("line"),
|
|
466
|
+
xPt: z.number(),
|
|
467
|
+
yPt: z.number()
|
|
468
|
+
}), z.object({
|
|
469
|
+
kind: z.literal("cubic"),
|
|
470
|
+
c1xPt: z.number(),
|
|
471
|
+
c1yPt: z.number(),
|
|
472
|
+
c2xPt: z.number(),
|
|
473
|
+
c2yPt: z.number(),
|
|
474
|
+
xPt: z.number(),
|
|
475
|
+
yPt: z.number()
|
|
476
|
+
})]);
|
|
477
|
+
const LayoutSubpathSchema = z.object({
|
|
478
|
+
startXPt: z.number(),
|
|
479
|
+
startYPt: z.number(),
|
|
480
|
+
segments: z.array(LayoutPathSegmentSchema),
|
|
481
|
+
closed: z.boolean()
|
|
482
|
+
});
|
|
483
|
+
const LayoutPathSchema = z.object({
|
|
484
|
+
kind: z.literal("path"),
|
|
485
|
+
subpaths: z.array(LayoutSubpathSchema),
|
|
486
|
+
fill: ColorSchema.optional(),
|
|
487
|
+
fillRule: z.enum(["nonzero", "evenodd"]).optional(),
|
|
488
|
+
stroke: z.object({
|
|
489
|
+
color: ColorSchema,
|
|
490
|
+
widthPt: z.number().positive()
|
|
491
|
+
}).optional(),
|
|
492
|
+
sourcePath: z.string().optional()
|
|
493
|
+
});
|
|
494
|
+
const LayoutLinkSchema = z.object({
|
|
495
|
+
kind: z.literal("link"),
|
|
496
|
+
uri: z.string(),
|
|
497
|
+
xPt: z.number(),
|
|
498
|
+
yPt: z.number(),
|
|
499
|
+
widthPt: z.number().nonnegative(),
|
|
500
|
+
heightPt: z.number().nonnegative(),
|
|
501
|
+
sourcePath: z.string().optional()
|
|
502
|
+
});
|
|
503
|
+
const LayoutItemSchema = z.discriminatedUnion("kind", [
|
|
504
|
+
LayoutTextSchema,
|
|
505
|
+
LayoutImageSchema,
|
|
506
|
+
LayoutRectSchema,
|
|
507
|
+
LayoutLineSchema,
|
|
508
|
+
LayoutEllipseSchema,
|
|
509
|
+
LayoutPathSchema,
|
|
510
|
+
LayoutLinkSchema
|
|
511
|
+
]);
|
|
512
|
+
const LayoutPageSchema = z.object({
|
|
513
|
+
widthPt: z.number().positive(),
|
|
514
|
+
heightPt: z.number().positive(),
|
|
515
|
+
items: z.array(LayoutItemSchema),
|
|
516
|
+
notes: z.string().optional()
|
|
517
|
+
});
|
|
518
|
+
const LayoutImageAssetSchema = z.object({
|
|
519
|
+
format: z.enum(["png", "jpeg"]),
|
|
520
|
+
base64: z.string(),
|
|
521
|
+
widthPx: z.number().int().positive(),
|
|
522
|
+
heightPx: z.number().int().positive()
|
|
523
|
+
});
|
|
524
|
+
const LayoutDocumentSchema = z.object({
|
|
525
|
+
formatVersion: z.literal(1),
|
|
526
|
+
metadata: LayoutMetadataSchema,
|
|
527
|
+
pages: z.array(LayoutPageSchema),
|
|
528
|
+
images: z.record(z.string(), LayoutImageAssetSchema)
|
|
529
|
+
});
|
|
530
|
+
//#endregion
|
|
531
|
+
//#region src/package.ts
|
|
532
|
+
const DOCUMENT_PACKAGE_FORMAT_VERSION = 1;
|
|
533
|
+
const DocumentPackageSchema = z.object({
|
|
534
|
+
formatVersion: z.literal(1),
|
|
535
|
+
content: ContentDocumentSchema,
|
|
536
|
+
layout: LayoutDocumentSchema.optional()
|
|
537
|
+
});
|
|
538
|
+
//#endregion
|
|
539
|
+
export { AlignmentSchema, BoxSchema, COLOR_BLACK, CONTENT_FORMAT_VERSION, ColorSchema, ContentBlockSchema, ContentCellValueSchema, ContentDocumentSchema, ContentDrawPageSchema, ContentEmbeddedObjectBlockSchema, ContentEmbeddedObjectSchema, ContentImageBlockSchema, ContentListMembershipSchema, ContentPageBreakSchema, ContentParagraphSchema, ContentPathPointSchema, ContentPathSegmentSchema, ContentRunSchema, ContentSectionSchema, ContentShapeSchema, ContentSheetCellSchema, ContentSheetColumnSchema, ContentSheetImageSchema, ContentSheetPrintRangeSchema, ContentSheetPrintSettingsSchema, ContentSheetRepeatRangeSchema, ContentSheetRowSchema, ContentSheetSchema, ContentSlideSchema, ContentStrokeSchema, ContentSubpathSchema, ContentTableCellSchema, ContentTableRowSchema, ContentTableSchema, ContentVectorSchema, DEFAULT_LAYOUT_FONT, DOCUMENT_PACKAGE_FORMAT_VERSION, DocumentPackageSchema, LAYOUT_FORMAT_VERSION, LayoutDocumentSchema, LayoutEllipseSchema, LayoutFontSchema, LayoutImageAssetSchema, LayoutImageSchema, LayoutItemSchema, LayoutLineSchema, LayoutLinkSchema, LayoutMetadataSchema, LayoutPageSchema, LayoutPathSchema, LayoutPathSegmentSchema, LayoutRectSchema, LayoutSubpathSchema, LayoutTextSchema, MarginsSchema, PAGE_SIZE_A4, PAGE_SIZE_LETTER, PageSizeSchema, SLIDE_SIZE_STANDARD, SLIDE_SIZE_WIDESCREEN, colorToRgbHex, isContentBlock, rgbHexToColor };
|
package/package.json
CHANGED
|
@@ -1,5 +1,85 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "document-schema",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
|
|
3
|
+
"version": "1.5.2",
|
|
4
|
+
"description": "The canonical, format-agnostic content and layout schemas shared by ooxml.js, odf.js, and documents.js -- pure Zod schemas, no behaviour.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/ExaDev/document-schema.js.git"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/ExaDev/document-schema.js#readme",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/ExaDev/document-schema.js/issues"
|
|
13
|
+
},
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": {
|
|
17
|
+
"import": "./dist/index.d.ts",
|
|
18
|
+
"require": "./dist/index.d.cts"
|
|
19
|
+
},
|
|
20
|
+
"import": "./dist/index.js",
|
|
21
|
+
"require": "./dist/index.cjs"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"main": "./dist/index.cjs",
|
|
25
|
+
"module": "./dist/index.js",
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"files": [
|
|
28
|
+
"dist"
|
|
29
|
+
],
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"access": "public",
|
|
32
|
+
"provenance": true,
|
|
33
|
+
"registry": "https://registry.npmjs.org/"
|
|
34
|
+
},
|
|
35
|
+
"sideEffects": false,
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=20"
|
|
38
|
+
},
|
|
39
|
+
"keywords": [
|
|
40
|
+
"document",
|
|
41
|
+
"content-model",
|
|
42
|
+
"zod",
|
|
43
|
+
"schema",
|
|
44
|
+
"docx",
|
|
45
|
+
"pptx",
|
|
46
|
+
"xlsx",
|
|
47
|
+
"odt",
|
|
48
|
+
"odp",
|
|
49
|
+
"ods"
|
|
50
|
+
],
|
|
51
|
+
"license": "MIT",
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"zod": "^4.4.3"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@arethetypeswrong/cli": "^0.18.5",
|
|
57
|
+
"@commitlint/cli": "^21.2.1",
|
|
58
|
+
"@commitlint/config-conventional": "^21.2.0",
|
|
59
|
+
"@eslint/js": "^10.0.1",
|
|
60
|
+
"@semantic-release/changelog": "^7.0.0",
|
|
61
|
+
"@semantic-release/git": "^11.0.1",
|
|
62
|
+
"@types/node": "^26.1.1",
|
|
63
|
+
"@vitest/coverage-v8": "^4.1.10",
|
|
64
|
+
"eslint": "^10.8.0",
|
|
65
|
+
"globals": "^17.8.0",
|
|
66
|
+
"husky": "^9.1.7",
|
|
67
|
+
"lint-staged": "^17.2.0",
|
|
68
|
+
"publint": "^0.3.21",
|
|
69
|
+
"semantic-release": "^25.0.8",
|
|
70
|
+
"tsdown": "^0.22.13",
|
|
71
|
+
"typescript": "^6.0.3",
|
|
72
|
+
"typescript-eslint": "^8.65.0",
|
|
73
|
+
"vitest": "^4.1.10"
|
|
74
|
+
},
|
|
75
|
+
"scripts": {
|
|
76
|
+
"build": "tsdown",
|
|
77
|
+
"lint": "eslint . --max-warnings 0",
|
|
78
|
+
"typecheck": "tsc --noEmit",
|
|
79
|
+
"test": "vitest run --project unit",
|
|
80
|
+
"test:watch": "vitest --project unit",
|
|
81
|
+
"test:coverage": "vitest run --project unit --coverage",
|
|
82
|
+
"test:smoke": "tsdown && vitest run --project smoke",
|
|
83
|
+
"release": "semantic-release"
|
|
84
|
+
}
|
|
85
|
+
}
|