@json-to-office/shared 1.11.2 → 2.6.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/chunk-4MJFAJFW.js +507 -0
- package/dist/chunk-4MJFAJFW.js.map +1 -0
- package/dist/fonts/node.d.ts +9 -1
- package/dist/fonts/node.js +23 -0
- package/dist/fonts/node.js.map +1 -1
- package/dist/index.d.ts +1123 -6
- package/dist/index.js +197 -38
- package/dist/index.js.map +1 -1
- package/dist/schemas/slide-content.d.ts +10 -10
- package/dist/schemas/slide-content.js +5 -3
- package/dist/schemas/slide-content.js.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-6KUQYVPT.js +0 -177
- package/dist/chunk-6KUQYVPT.js.map +0 -1
|
@@ -0,0 +1,507 @@
|
|
|
1
|
+
// src/schemas/font-catalog.ts
|
|
2
|
+
import { Type } from "@sinclair/typebox";
|
|
3
|
+
var SAFE_FONTS = [
|
|
4
|
+
"Arial",
|
|
5
|
+
"Calibri",
|
|
6
|
+
"Cambria",
|
|
7
|
+
"Consolas",
|
|
8
|
+
"Courier New",
|
|
9
|
+
"Georgia",
|
|
10
|
+
"Segoe UI",
|
|
11
|
+
"Tahoma",
|
|
12
|
+
"Times New Roman",
|
|
13
|
+
"Trebuchet MS",
|
|
14
|
+
"Verdana",
|
|
15
|
+
"Helvetica",
|
|
16
|
+
"Helvetica Neue",
|
|
17
|
+
"Menlo",
|
|
18
|
+
"Monaco"
|
|
19
|
+
];
|
|
20
|
+
function isSafeFont(name) {
|
|
21
|
+
const lower = name.toLowerCase();
|
|
22
|
+
return SAFE_FONTS.some((f) => f.toLowerCase() === lower);
|
|
23
|
+
}
|
|
24
|
+
var FontFamilyNameSchema = Type.String({
|
|
25
|
+
description: "Font family name. Prefer a SAFE_FONTS entry (Arial, Calibri, Cambria, Consolas, Courier New, Georgia, Segoe UI, Tahoma, Times New Roman, Trebuchet MS, Verdana, Helvetica, Helvetica Neue, Menlo, Monaco) for zero-setup rendering. For any other font, register it in props.fontRegistry[] and reference it here by family. Unregistered non-safe names render with a host fallback.",
|
|
26
|
+
examples: ["Arial", "Calibri", "Georgia", "Inter", "Roboto"]
|
|
27
|
+
});
|
|
28
|
+
var FontWeightSchema = Type.Number({
|
|
29
|
+
minimum: 100,
|
|
30
|
+
maximum: 900,
|
|
31
|
+
description: "OpenType weight (100 thin ... 900 black). Default 400."
|
|
32
|
+
});
|
|
33
|
+
var FontItalicSchema = Type.Boolean({
|
|
34
|
+
description: "Whether this source is italic. Default false."
|
|
35
|
+
});
|
|
36
|
+
var SafeFontSourceSchema = Type.Object(
|
|
37
|
+
{
|
|
38
|
+
kind: Type.Literal("safe"),
|
|
39
|
+
family: Type.String({
|
|
40
|
+
description: "A SAFE_FONTS name \u2014 installed with Office."
|
|
41
|
+
})
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
additionalProperties: false,
|
|
45
|
+
description: "Office-installed font \u2014 no embedding"
|
|
46
|
+
}
|
|
47
|
+
);
|
|
48
|
+
var GoogleFontSourceSchema = Type.Object(
|
|
49
|
+
{
|
|
50
|
+
kind: Type.Literal("google"),
|
|
51
|
+
family: Type.String({
|
|
52
|
+
description: 'Exact Google Fonts family name (e.g. "Inter").'
|
|
53
|
+
}),
|
|
54
|
+
weights: Type.Optional(
|
|
55
|
+
Type.Array(FontWeightSchema, {
|
|
56
|
+
description: "Weights to fetch. Default [400, 700]."
|
|
57
|
+
})
|
|
58
|
+
),
|
|
59
|
+
italics: Type.Optional(
|
|
60
|
+
Type.Boolean({ description: "Include italic variants. Default false." })
|
|
61
|
+
)
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
additionalProperties: false,
|
|
65
|
+
description: "Google Fonts \u2014 auto-fetched and embedded"
|
|
66
|
+
}
|
|
67
|
+
);
|
|
68
|
+
var FileFontSourceSchema = Type.Object(
|
|
69
|
+
{
|
|
70
|
+
kind: Type.Literal("file"),
|
|
71
|
+
path: Type.String({
|
|
72
|
+
description: "Path to a .ttf/.otf file. Relative paths are resolved against the JSON document file."
|
|
73
|
+
}),
|
|
74
|
+
weight: Type.Optional(FontWeightSchema),
|
|
75
|
+
italic: Type.Optional(FontItalicSchema)
|
|
76
|
+
},
|
|
77
|
+
{ additionalProperties: false, description: "Local font file to embed" }
|
|
78
|
+
);
|
|
79
|
+
var UrlFontSourceSchema = Type.Object(
|
|
80
|
+
{
|
|
81
|
+
kind: Type.Literal("url"),
|
|
82
|
+
url: Type.String({
|
|
83
|
+
description: "HTTPS URL of a TTF or OTF file."
|
|
84
|
+
}),
|
|
85
|
+
weight: Type.Optional(FontWeightSchema),
|
|
86
|
+
italic: Type.Optional(FontItalicSchema)
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
additionalProperties: false,
|
|
90
|
+
description: "Direct TTF/OTF URL (non-Google CDN)"
|
|
91
|
+
}
|
|
92
|
+
);
|
|
93
|
+
var VariableFontSourceSchema = Type.Object(
|
|
94
|
+
{
|
|
95
|
+
kind: Type.Literal("variable"),
|
|
96
|
+
url: Type.String({
|
|
97
|
+
description: "HTTPS URL of a variable TTF (`fvar` axis table required)."
|
|
98
|
+
}),
|
|
99
|
+
weight: FontWeightSchema,
|
|
100
|
+
italic: Type.Optional(FontItalicSchema),
|
|
101
|
+
axes: Type.Optional(
|
|
102
|
+
Type.Record(Type.String(), Type.Number(), {
|
|
103
|
+
description: "Additional axis pin values (e.g. `{ ital: 1, opsz: 14 }`) merged on top of the derived `wght` pin. Uncommon \u2014 the `weight` field is usually enough."
|
|
104
|
+
})
|
|
105
|
+
)
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
additionalProperties: false,
|
|
109
|
+
description: "Variable-font instancer. The fetcher pins `wght` to `weight` (plus any `axes` overrides) and emits a clean static TTF, bypassing upstream distributions that collapse multiple static weights onto the same glyph geometry."
|
|
110
|
+
}
|
|
111
|
+
);
|
|
112
|
+
var DataFontSourceSchema = Type.Object(
|
|
113
|
+
{
|
|
114
|
+
kind: Type.Literal("data"),
|
|
115
|
+
data: Type.String({
|
|
116
|
+
description: "Base64-encoded TTF/OTF or data: URL (data:font/ttf;base64,...). Makes the JSON self-contained at the cost of size."
|
|
117
|
+
}),
|
|
118
|
+
weight: Type.Optional(FontWeightSchema),
|
|
119
|
+
italic: Type.Optional(FontItalicSchema)
|
|
120
|
+
},
|
|
121
|
+
{ additionalProperties: false, description: "Inline base64 font \u2014 portable" }
|
|
122
|
+
);
|
|
123
|
+
var FontSourceSchema = Type.Union(
|
|
124
|
+
[
|
|
125
|
+
SafeFontSourceSchema,
|
|
126
|
+
GoogleFontSourceSchema,
|
|
127
|
+
FileFontSourceSchema,
|
|
128
|
+
DataFontSourceSchema,
|
|
129
|
+
UrlFontSourceSchema,
|
|
130
|
+
VariableFontSourceSchema
|
|
131
|
+
],
|
|
132
|
+
{
|
|
133
|
+
description: 'A single font variant source. Use kind:"safe" for installed fonts, kind:"google" for Google Fonts, kind:"file" for local files, kind:"data" for base64, kind:"url" for direct HTTPS TTF/OTF URLs, kind:"variable" to instance a variable TTF at a specific weight.'
|
|
134
|
+
}
|
|
135
|
+
);
|
|
136
|
+
var FontCategorySchema = Type.Union(
|
|
137
|
+
[
|
|
138
|
+
Type.Literal("sans"),
|
|
139
|
+
Type.Literal("serif"),
|
|
140
|
+
Type.Literal("mono"),
|
|
141
|
+
Type.Literal("display"),
|
|
142
|
+
Type.Literal("handwriting")
|
|
143
|
+
],
|
|
144
|
+
{ description: "Broad category used for fallback selection" }
|
|
145
|
+
);
|
|
146
|
+
var FontRegistryEntrySchema = Type.Object(
|
|
147
|
+
{
|
|
148
|
+
id: Type.String({
|
|
149
|
+
description: 'Registry key. By convention, match the display family name ("Inter", "Roboto Slab").'
|
|
150
|
+
}),
|
|
151
|
+
family: Type.String({
|
|
152
|
+
description: "Display family used in font.family / fontFace / theme.fonts.*. Usually identical to id."
|
|
153
|
+
}),
|
|
154
|
+
category: Type.Optional(FontCategorySchema),
|
|
155
|
+
sources: Type.Array(FontSourceSchema, {
|
|
156
|
+
minItems: 1,
|
|
157
|
+
description: "One or more weight/style variants. List at least a regular (weight 400, italic false)."
|
|
158
|
+
})
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
additionalProperties: false,
|
|
162
|
+
description: "A font registered for this document. Referenced by family from font.family, fontFace, and theme.fonts.*."
|
|
163
|
+
}
|
|
164
|
+
);
|
|
165
|
+
var FontRegistrySchema = Type.Array(FontRegistryEntrySchema, {
|
|
166
|
+
description: "Document-scoped font registry. Every non-safe font used in this document must be registered here."
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// src/theme/design-system.ts
|
|
170
|
+
import { Type as Type2 } from "@sinclair/typebox";
|
|
171
|
+
var TYPE_ROLES = [
|
|
172
|
+
"eyebrow",
|
|
173
|
+
"display",
|
|
174
|
+
"stat",
|
|
175
|
+
"quote",
|
|
176
|
+
"label",
|
|
177
|
+
"footer",
|
|
178
|
+
"tableHeader",
|
|
179
|
+
"tableCell",
|
|
180
|
+
"chartLabel",
|
|
181
|
+
"tracker",
|
|
182
|
+
"source"
|
|
183
|
+
];
|
|
184
|
+
var TypeRoleNameSchema = Type2.Union(
|
|
185
|
+
TYPE_ROLES.map((name) => Type2.Literal(name))
|
|
186
|
+
);
|
|
187
|
+
var CANVASES = ["a4", "letter", "wide169", "standard43"];
|
|
188
|
+
var TextCaseSchema = Type2.Union([
|
|
189
|
+
Type2.Literal("none"),
|
|
190
|
+
Type2.Literal("upper"),
|
|
191
|
+
Type2.Literal("smallCaps")
|
|
192
|
+
]);
|
|
193
|
+
var ColorTokenSchema = Type2.String({
|
|
194
|
+
pattern: "^(#?[0-9A-Fa-f]{6}|[a-zA-Z][a-zA-Z0-9]*)$",
|
|
195
|
+
description: "Six-digit hex or a theme color/palette token. References must resolve without cycles."
|
|
196
|
+
});
|
|
197
|
+
var PaletteSchema = Type2.Object(
|
|
198
|
+
{
|
|
199
|
+
rule: Type2.Optional(ColorTokenSchema),
|
|
200
|
+
textMuted: Type2.Optional(ColorTokenSchema),
|
|
201
|
+
onPrimary: Type2.Optional(ColorTokenSchema),
|
|
202
|
+
surfaceInverse: Type2.Optional(ColorTokenSchema),
|
|
203
|
+
positive: Type2.Optional(ColorTokenSchema),
|
|
204
|
+
negative: Type2.Optional(ColorTokenSchema),
|
|
205
|
+
chart: Type2.Optional(
|
|
206
|
+
Type2.Array(ColorTokenSchema, { minItems: 1, maxItems: 12 })
|
|
207
|
+
)
|
|
208
|
+
},
|
|
209
|
+
{ additionalProperties: false }
|
|
210
|
+
);
|
|
211
|
+
var TypeRoleSchema = Type2.Object(
|
|
212
|
+
{
|
|
213
|
+
face: Type2.Optional(
|
|
214
|
+
Type2.Union([
|
|
215
|
+
Type2.Literal("heading"),
|
|
216
|
+
Type2.Literal("body"),
|
|
217
|
+
Type2.Literal("mono"),
|
|
218
|
+
Type2.Literal("light")
|
|
219
|
+
])
|
|
220
|
+
),
|
|
221
|
+
weight: Type2.Optional(Type2.Integer({ minimum: 100, maximum: 900 })),
|
|
222
|
+
size: Type2.Optional(
|
|
223
|
+
Type2.Number({
|
|
224
|
+
minimum: 5,
|
|
225
|
+
maximum: 200,
|
|
226
|
+
description: "Explicit size in points; takes precedence over the canvas scale."
|
|
227
|
+
})
|
|
228
|
+
),
|
|
229
|
+
lineHeight: Type2.Optional(Type2.Number({ minimum: 0.5, maximum: 3 })),
|
|
230
|
+
tracking: Type2.Optional(
|
|
231
|
+
Type2.Number({ description: "Tracking in hundredths of an em." })
|
|
232
|
+
),
|
|
233
|
+
case: Type2.Optional(TextCaseSchema),
|
|
234
|
+
color: Type2.Optional(ColorTokenSchema),
|
|
235
|
+
spaceBefore: Type2.Optional(Type2.Number({ minimum: 0 })),
|
|
236
|
+
spaceAfter: Type2.Optional(Type2.Number({ minimum: 0 }))
|
|
237
|
+
},
|
|
238
|
+
{ additionalProperties: false }
|
|
239
|
+
);
|
|
240
|
+
var TypeRolesSchema = Type2.Object(
|
|
241
|
+
{
|
|
242
|
+
eyebrow: Type2.Optional(TypeRoleSchema),
|
|
243
|
+
display: Type2.Optional(TypeRoleSchema),
|
|
244
|
+
stat: Type2.Optional(TypeRoleSchema),
|
|
245
|
+
quote: Type2.Optional(TypeRoleSchema),
|
|
246
|
+
label: Type2.Optional(TypeRoleSchema),
|
|
247
|
+
footer: Type2.Optional(TypeRoleSchema),
|
|
248
|
+
tableHeader: Type2.Optional(TypeRoleSchema),
|
|
249
|
+
tableCell: Type2.Optional(TypeRoleSchema),
|
|
250
|
+
chartLabel: Type2.Optional(TypeRoleSchema),
|
|
251
|
+
tracker: Type2.Optional(TypeRoleSchema),
|
|
252
|
+
source: Type2.Optional(TypeRoleSchema)
|
|
253
|
+
},
|
|
254
|
+
{ additionalProperties: false }
|
|
255
|
+
);
|
|
256
|
+
var ScaleSchema = Type2.Object(
|
|
257
|
+
{
|
|
258
|
+
base: Type2.Number({ minimum: 5, maximum: 200 }),
|
|
259
|
+
ratio: Type2.Optional(Type2.Number({ minimum: 1, maximum: 2 })),
|
|
260
|
+
baselinePt: Type2.Optional(
|
|
261
|
+
Type2.Number({ exclusiveMinimum: 0, maximum: 24 })
|
|
262
|
+
)
|
|
263
|
+
},
|
|
264
|
+
{ additionalProperties: false }
|
|
265
|
+
);
|
|
266
|
+
var TypographySchema = Type2.Object(
|
|
267
|
+
{
|
|
268
|
+
roles: Type2.Optional(TypeRolesSchema),
|
|
269
|
+
scale: Type2.Optional(
|
|
270
|
+
Type2.Object(
|
|
271
|
+
{
|
|
272
|
+
a4: Type2.Optional(ScaleSchema),
|
|
273
|
+
letter: Type2.Optional(ScaleSchema),
|
|
274
|
+
wide169: Type2.Optional(ScaleSchema),
|
|
275
|
+
standard43: Type2.Optional(ScaleSchema)
|
|
276
|
+
},
|
|
277
|
+
{ additionalProperties: false }
|
|
278
|
+
)
|
|
279
|
+
)
|
|
280
|
+
},
|
|
281
|
+
{ additionalProperties: false }
|
|
282
|
+
);
|
|
283
|
+
var CanvasSpacingSchema = Type2.Object(
|
|
284
|
+
{
|
|
285
|
+
safeAreaIn: Type2.Optional(Type2.Number({ minimum: 0 })),
|
|
286
|
+
gutterIn: Type2.Optional(Type2.Number({ minimum: 0 })),
|
|
287
|
+
columns: Type2.Optional(Type2.Integer({ minimum: 1, maximum: 100 })),
|
|
288
|
+
rows: Type2.Optional(Type2.Integer({ minimum: 1, maximum: 100 }))
|
|
289
|
+
},
|
|
290
|
+
{ additionalProperties: false }
|
|
291
|
+
);
|
|
292
|
+
var DesignSpacingSchema = Type2.Object(
|
|
293
|
+
{
|
|
294
|
+
basePt: Type2.Optional(Type2.Number({ exclusiveMinimum: 0 })),
|
|
295
|
+
blockGap: Type2.Optional(
|
|
296
|
+
Type2.Object(
|
|
297
|
+
{
|
|
298
|
+
tight: Type2.Optional(Type2.Number({ minimum: 0 })),
|
|
299
|
+
normal: Type2.Optional(Type2.Number({ minimum: 0 })),
|
|
300
|
+
loose: Type2.Optional(Type2.Number({ minimum: 0 }))
|
|
301
|
+
},
|
|
302
|
+
{ additionalProperties: false }
|
|
303
|
+
)
|
|
304
|
+
),
|
|
305
|
+
canvas: Type2.Optional(
|
|
306
|
+
Type2.Object(
|
|
307
|
+
{
|
|
308
|
+
a4: Type2.Optional(CanvasSpacingSchema),
|
|
309
|
+
letter: Type2.Optional(CanvasSpacingSchema),
|
|
310
|
+
wide169: Type2.Optional(CanvasSpacingSchema),
|
|
311
|
+
standard43: Type2.Optional(CanvasSpacingSchema)
|
|
312
|
+
},
|
|
313
|
+
{ additionalProperties: false }
|
|
314
|
+
)
|
|
315
|
+
)
|
|
316
|
+
},
|
|
317
|
+
{ additionalProperties: false }
|
|
318
|
+
);
|
|
319
|
+
var RecipeSchema = Type2.Object(
|
|
320
|
+
{
|
|
321
|
+
type: Type2.Optional(TypeRoleNameSchema),
|
|
322
|
+
color: Type2.Optional(ColorTokenSchema),
|
|
323
|
+
fill: Type2.Optional(ColorTokenSchema),
|
|
324
|
+
rule: Type2.Optional(
|
|
325
|
+
Type2.Object(
|
|
326
|
+
{
|
|
327
|
+
weightPt: Type2.Optional(Type2.Number({ minimum: 0 })),
|
|
328
|
+
color: Type2.Optional(ColorTokenSchema)
|
|
329
|
+
},
|
|
330
|
+
{ additionalProperties: false }
|
|
331
|
+
)
|
|
332
|
+
),
|
|
333
|
+
padPt: Type2.Optional(Type2.Number({ minimum: 0 })),
|
|
334
|
+
alignment: Type2.Optional(
|
|
335
|
+
Type2.Union([
|
|
336
|
+
Type2.Literal("left"),
|
|
337
|
+
Type2.Literal("center"),
|
|
338
|
+
Type2.Literal("right")
|
|
339
|
+
])
|
|
340
|
+
)
|
|
341
|
+
},
|
|
342
|
+
{ additionalProperties: false }
|
|
343
|
+
);
|
|
344
|
+
var ChromeSchema = Type2.Object(
|
|
345
|
+
{
|
|
346
|
+
runningHead: Type2.Optional(RecipeSchema),
|
|
347
|
+
tracker: Type2.Optional(RecipeSchema),
|
|
348
|
+
actionTitle: Type2.Optional(RecipeSchema),
|
|
349
|
+
keyTakeaways: Type2.Optional(RecipeSchema),
|
|
350
|
+
sourceLine: Type2.Optional(RecipeSchema),
|
|
351
|
+
confidentialFooter: Type2.Optional(RecipeSchema),
|
|
352
|
+
logoSlot: Type2.Optional(RecipeSchema),
|
|
353
|
+
cover: Type2.Optional(RecipeSchema)
|
|
354
|
+
},
|
|
355
|
+
{
|
|
356
|
+
additionalProperties: false,
|
|
357
|
+
description: "Visual recipes; consumers land in #361. No automatic content or presence requirements."
|
|
358
|
+
}
|
|
359
|
+
);
|
|
360
|
+
var MotifSchema = Type2.Object(
|
|
361
|
+
{
|
|
362
|
+
kind: Type2.Union([
|
|
363
|
+
Type2.Literal("none"),
|
|
364
|
+
Type2.Literal("rule"),
|
|
365
|
+
Type2.Literal("corner"),
|
|
366
|
+
Type2.Literal("band")
|
|
367
|
+
]),
|
|
368
|
+
color: Type2.Optional(ColorTokenSchema),
|
|
369
|
+
weightPt: Type2.Optional(Type2.Number({ minimum: 0 })),
|
|
370
|
+
placement: Type2.Optional(
|
|
371
|
+
Type2.Union([
|
|
372
|
+
Type2.Literal("top"),
|
|
373
|
+
Type2.Literal("bottom"),
|
|
374
|
+
Type2.Literal("left"),
|
|
375
|
+
Type2.Literal("right"),
|
|
376
|
+
Type2.Literal("topLeft"),
|
|
377
|
+
Type2.Literal("topRight"),
|
|
378
|
+
Type2.Literal("bottomLeft"),
|
|
379
|
+
Type2.Literal("bottomRight")
|
|
380
|
+
])
|
|
381
|
+
)
|
|
382
|
+
},
|
|
383
|
+
{
|
|
384
|
+
additionalProperties: false,
|
|
385
|
+
description: "At most one motif. Rendering consumers land in #361."
|
|
386
|
+
}
|
|
387
|
+
);
|
|
388
|
+
var DesignSystemProperties = {
|
|
389
|
+
palette: Type2.Optional(PaletteSchema),
|
|
390
|
+
typography: Type2.Optional(TypographySchema),
|
|
391
|
+
spacing: Type2.Optional(DesignSpacingSchema),
|
|
392
|
+
chrome: Type2.Optional(ChromeSchema),
|
|
393
|
+
motif: Type2.Optional(MotifSchema)
|
|
394
|
+
};
|
|
395
|
+
var DesignSystemSchema = Type2.Object(DesignSystemProperties, {
|
|
396
|
+
additionalProperties: false
|
|
397
|
+
});
|
|
398
|
+
function designCanvas(format, size) {
|
|
399
|
+
if (format === "docx") return size === "LETTER" ? "letter" : "a4";
|
|
400
|
+
const ratio = typeof size === "object" ? size.width / size.height : 4 / 3;
|
|
401
|
+
return Math.abs(ratio - 16 / 9) < Math.abs(ratio - 4 / 3) ? "wide169" : "standard43";
|
|
402
|
+
}
|
|
403
|
+
var ROLE_SCALE_STEPS = {
|
|
404
|
+
display: 4,
|
|
405
|
+
stat: 3,
|
|
406
|
+
quote: 1,
|
|
407
|
+
tableHeader: 0,
|
|
408
|
+
tableCell: 0,
|
|
409
|
+
label: -1,
|
|
410
|
+
eyebrow: -1,
|
|
411
|
+
chartLabel: -1,
|
|
412
|
+
tracker: -1,
|
|
413
|
+
footer: -2,
|
|
414
|
+
source: -2
|
|
415
|
+
};
|
|
416
|
+
function scaledSize(scale, step) {
|
|
417
|
+
if (step === 0) return scale.base;
|
|
418
|
+
const baseline = scale.baselinePt ?? 4;
|
|
419
|
+
const exact = scale.base * (scale.ratio ?? 1.25) ** step;
|
|
420
|
+
return Math.max(5, Math.min(200, Math.round(exact / baseline) * baseline));
|
|
421
|
+
}
|
|
422
|
+
function paletteScalars(palette) {
|
|
423
|
+
const scalars = {};
|
|
424
|
+
for (const [key, value] of Object.entries(palette ?? {})) {
|
|
425
|
+
if (typeof value === "string") scalars[key] = value;
|
|
426
|
+
}
|
|
427
|
+
return scalars;
|
|
428
|
+
}
|
|
429
|
+
function capsFormatting(textCase) {
|
|
430
|
+
return textCase === "upper" ? { allCaps: true } : { smallCaps: textCase === "smallCaps" };
|
|
431
|
+
}
|
|
432
|
+
function resolveTypeRoles(system, canvas, base) {
|
|
433
|
+
const scale = system.typography?.scale?.[canvas];
|
|
434
|
+
const roles = {};
|
|
435
|
+
for (const name of TYPE_ROLES) {
|
|
436
|
+
const role = system.typography?.roles?.[name];
|
|
437
|
+
if (!role) continue;
|
|
438
|
+
roles[name] = {
|
|
439
|
+
...role,
|
|
440
|
+
size: role.size ?? (scale ? scaledSize(scale, ROLE_SCALE_STEPS[name]) : base)
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
return roles;
|
|
444
|
+
}
|
|
445
|
+
function designColors(colors, palette) {
|
|
446
|
+
return { ...colors, ...paletteScalars(palette) };
|
|
447
|
+
}
|
|
448
|
+
function resolveDesignColor(value, colors) {
|
|
449
|
+
const seen = /* @__PURE__ */ new Set();
|
|
450
|
+
let current = value;
|
|
451
|
+
while (current !== void 0 && !seen.has(current)) {
|
|
452
|
+
if (!current.startsWith("#") && Object.hasOwn(colors, current)) {
|
|
453
|
+
seen.add(current);
|
|
454
|
+
current = colors[current];
|
|
455
|
+
} else {
|
|
456
|
+
return /^#?[0-9a-f]{6}$/i.test(current) ? current.replace(/^#/, "") : void 0;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
return void 0;
|
|
460
|
+
}
|
|
461
|
+
function validateDesignColors(system, colors) {
|
|
462
|
+
const resolved = designColors(colors, system.palette);
|
|
463
|
+
const entries = Object.entries(system.palette ?? {}).flatMap(
|
|
464
|
+
([key, value]) => Array.isArray(value) ? value.map((entry, i) => [`palette.${key}[${i}]`, entry]) : [[`palette.${key}`, value]]
|
|
465
|
+
);
|
|
466
|
+
for (const [name, role] of Object.entries(system.typography?.roles ?? {})) {
|
|
467
|
+
if (role.color)
|
|
468
|
+
entries.push([`typography.roles.${name}.color`, role.color]);
|
|
469
|
+
}
|
|
470
|
+
for (const [path, value] of entries) {
|
|
471
|
+
if (value && !resolveDesignColor(value, resolved)) {
|
|
472
|
+
throw new Error(
|
|
473
|
+
`Unresolvable theme color at ${path}: "${value}" (unknown token or cycle)`
|
|
474
|
+
);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
export {
|
|
480
|
+
SAFE_FONTS,
|
|
481
|
+
isSafeFont,
|
|
482
|
+
FontFamilyNameSchema,
|
|
483
|
+
FontSourceSchema,
|
|
484
|
+
FontRegistryEntrySchema,
|
|
485
|
+
FontRegistrySchema,
|
|
486
|
+
TYPE_ROLES,
|
|
487
|
+
TypeRoleNameSchema,
|
|
488
|
+
CANVASES,
|
|
489
|
+
TextCaseSchema,
|
|
490
|
+
PaletteSchema,
|
|
491
|
+
TypeRoleSchema,
|
|
492
|
+
TypeRolesSchema,
|
|
493
|
+
TypographySchema,
|
|
494
|
+
DesignSpacingSchema,
|
|
495
|
+
ChromeSchema,
|
|
496
|
+
MotifSchema,
|
|
497
|
+
DesignSystemProperties,
|
|
498
|
+
DesignSystemSchema,
|
|
499
|
+
designCanvas,
|
|
500
|
+
ROLE_SCALE_STEPS,
|
|
501
|
+
capsFormatting,
|
|
502
|
+
resolveTypeRoles,
|
|
503
|
+
designColors,
|
|
504
|
+
resolveDesignColor,
|
|
505
|
+
validateDesignColors
|
|
506
|
+
};
|
|
507
|
+
//# sourceMappingURL=chunk-4MJFAJFW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/schemas/font-catalog.ts","../src/theme/design-system.ts"],"sourcesContent":["/**\n * Font catalog + registry schemas.\n *\n * Shared by DOCX and PPTX pipelines. Defines:\n * - SAFE_FONTS: Office-safe font names (installed on Windows/macOS with Office).\n * - FontFamilyNameSchema: free-form string for `font.family` / `fontFace`, with LLM-facing guidance.\n * - FontSourceSchema: one binary variant (safe | google | file | data).\n * - FontRegistryEntrySchema / FontRegistrySchema: document-scoped font registry.\n */\n\nimport { Type, Static } from '@sinclair/typebox';\n\n/**\n * Fonts pre-installed with Microsoft Office on Windows + macOS.\n * Using one of these requires no registration and no embedding.\n */\nexport const SAFE_FONTS = [\n 'Arial',\n 'Calibri',\n 'Cambria',\n 'Consolas',\n 'Courier New',\n 'Georgia',\n 'Segoe UI',\n 'Tahoma',\n 'Times New Roman',\n 'Trebuchet MS',\n 'Verdana',\n 'Helvetica',\n 'Helvetica Neue',\n 'Menlo',\n 'Monaco',\n] as const;\n\nexport type SafeFontName = (typeof SAFE_FONTS)[number];\n\n/** Case-insensitive membership test against SAFE_FONTS. */\nexport function isSafeFont(name: string): boolean {\n const lower = name.toLowerCase();\n return SAFE_FONTS.some((f) => f.toLowerCase() === lower);\n}\n\n/**\n * Font family name used in `font.family` / `fontFace`.\n *\n * Stays a free-form string so users can reference custom or Google fonts.\n * Description + examples guide LLMs and JSON Schema consumers toward SAFE_FONTS.\n */\nexport const FontFamilyNameSchema = Type.String({\n description:\n 'Font family name. Prefer a SAFE_FONTS entry (Arial, Calibri, Cambria, Consolas, Courier New, Georgia, Segoe UI, Tahoma, Times New Roman, Trebuchet MS, Verdana, Helvetica, Helvetica Neue, Menlo, Monaco) for zero-setup rendering. For any other font, register it in props.fontRegistry[] and reference it here by family. Unregistered non-safe names render with a host fallback.',\n examples: ['Arial', 'Calibri', 'Georgia', 'Inter', 'Roboto'],\n});\n\n// ----------------------------------------------------------------------------\n// Font sources — one weight/style variant\n// ----------------------------------------------------------------------------\n\nconst FontWeightSchema = Type.Number({\n minimum: 100,\n maximum: 900,\n description: 'OpenType weight (100 thin ... 900 black). Default 400.',\n});\n\nconst FontItalicSchema = Type.Boolean({\n description: 'Whether this source is italic. Default false.',\n});\n\n/** Safe reference — no embedding needed. */\nconst SafeFontSourceSchema = Type.Object(\n {\n kind: Type.Literal('safe'),\n family: Type.String({\n description: 'A SAFE_FONTS name — installed with Office.',\n }),\n },\n {\n additionalProperties: false,\n description: 'Office-installed font — no embedding',\n }\n);\n\n/** Google Fonts — fetched and embedded at generate time. */\nconst GoogleFontSourceSchema = Type.Object(\n {\n kind: Type.Literal('google'),\n family: Type.String({\n description: 'Exact Google Fonts family name (e.g. \"Inter\").',\n }),\n weights: Type.Optional(\n Type.Array(FontWeightSchema, {\n description: 'Weights to fetch. Default [400, 700].',\n })\n ),\n italics: Type.Optional(\n Type.Boolean({ description: 'Include italic variants. Default false.' })\n ),\n },\n {\n additionalProperties: false,\n description: 'Google Fonts — auto-fetched and embedded',\n }\n);\n\n/** Local TTF/OTF file — resolved relative to the JSON file, or absolute. */\nconst FileFontSourceSchema = Type.Object(\n {\n kind: Type.Literal('file'),\n path: Type.String({\n description:\n 'Path to a .ttf/.otf file. Relative paths are resolved against the JSON document file.',\n }),\n weight: Type.Optional(FontWeightSchema),\n italic: Type.Optional(FontItalicSchema),\n },\n { additionalProperties: false, description: 'Local font file to embed' }\n);\n\n/**\n * Direct URL to a TTF/OTF. Used to bypass Google Fonts redistribution for\n * families with known metadata defects — e.g. rsms/inter hosted on jsDelivr.\n * A single URL fetches one variant; multiple URLs build a multi-weight family.\n */\nconst UrlFontSourceSchema = Type.Object(\n {\n kind: Type.Literal('url'),\n url: Type.String({\n description: 'HTTPS URL of a TTF or OTF file.',\n }),\n weight: Type.Optional(FontWeightSchema),\n italic: Type.Optional(FontItalicSchema),\n },\n {\n additionalProperties: false,\n description: 'Direct TTF/OTF URL (non-Google CDN)',\n }\n);\n\n/**\n * Variable-font-instanced variant. Points at a variable TTF URL plus a\n * target weight (and optional additional `axes` pins); the fetcher\n * downloads the variable TTF once (disk-cached) and uses harfbuzz to pin\n * the `wght` axis (plus any additional axes) to produce a clean static\n * TTF for embedding.\n *\n * Used to escape Google Fonts' lossy per-weight static generation — e.g.\n * Google ships Inter Thin and Inter ExtraLight as near-identical glyph\n * files (both sourced around wght=250), but the upstream variable Inter\n * produces properly distinct static instances when pinned precisely at\n * wght=100 vs wght=200.\n */\nconst VariableFontSourceSchema = Type.Object(\n {\n kind: Type.Literal('variable'),\n url: Type.String({\n description: 'HTTPS URL of a variable TTF (`fvar` axis table required).',\n }),\n weight: FontWeightSchema,\n italic: Type.Optional(FontItalicSchema),\n axes: Type.Optional(\n Type.Record(Type.String(), Type.Number(), {\n description:\n 'Additional axis pin values (e.g. `{ ital: 1, opsz: 14 }`) merged on top of the derived `wght` pin. Uncommon — the `weight` field is usually enough.',\n })\n ),\n },\n {\n additionalProperties: false,\n description:\n 'Variable-font instancer. The fetcher pins `wght` to `weight` (plus any `axes` overrides) and emits a clean static TTF, bypassing upstream distributions that collapse multiple static weights onto the same glyph geometry.',\n }\n);\n\n/** Inline base64 / data-URL — self-contained JSON. */\nconst DataFontSourceSchema = Type.Object(\n {\n kind: Type.Literal('data'),\n data: Type.String({\n description:\n 'Base64-encoded TTF/OTF or data: URL (data:font/ttf;base64,...). Makes the JSON self-contained at the cost of size.',\n }),\n weight: Type.Optional(FontWeightSchema),\n italic: Type.Optional(FontItalicSchema),\n },\n { additionalProperties: false, description: 'Inline base64 font — portable' }\n);\n\n/**\n * One weight/style variant backing a font registry entry.\n *\n * Kinds:\n * - safe: references an Office-installed font; no embedding.\n * - google: Google Fonts family; fetched and embedded at generate time.\n * - file: local .ttf/.otf read from disk.\n * - data: inline base64, makes JSON self-contained.\n */\nexport const FontSourceSchema = Type.Union(\n [\n SafeFontSourceSchema,\n GoogleFontSourceSchema,\n FileFontSourceSchema,\n DataFontSourceSchema,\n UrlFontSourceSchema,\n VariableFontSourceSchema,\n ],\n {\n description:\n 'A single font variant source. Use kind:\"safe\" for installed fonts, kind:\"google\" for Google Fonts, kind:\"file\" for local files, kind:\"data\" for base64, kind:\"url\" for direct HTTPS TTF/OTF URLs, kind:\"variable\" to instance a variable TTF at a specific weight.',\n }\n);\n\nexport type FontSource = Static<typeof FontSourceSchema>;\n\n// ----------------------------------------------------------------------------\n// Font registry entry\n// ----------------------------------------------------------------------------\n\nconst FontCategorySchema = Type.Union(\n [\n Type.Literal('sans'),\n Type.Literal('serif'),\n Type.Literal('mono'),\n Type.Literal('display'),\n Type.Literal('handwriting'),\n ],\n { description: 'Broad category used for fallback selection' }\n);\n\nexport const FontRegistryEntrySchema = Type.Object(\n {\n id: Type.String({\n description:\n 'Registry key. By convention, match the display family name (\"Inter\", \"Roboto Slab\").',\n }),\n family: Type.String({\n description:\n 'Display family used in font.family / fontFace / theme.fonts.*. Usually identical to id.',\n }),\n category: Type.Optional(FontCategorySchema),\n sources: Type.Array(FontSourceSchema, {\n minItems: 1,\n description:\n 'One or more weight/style variants. List at least a regular (weight 400, italic false).',\n }),\n },\n {\n additionalProperties: false,\n description:\n 'A font registered for this document. Referenced by family from font.family, fontFace, and theme.fonts.*.',\n }\n);\n\nexport type FontRegistryEntry = Static<typeof FontRegistryEntrySchema>;\n\n/**\n * Document-scoped font registry.\n *\n * Ships with the JSON — no runtime side-channel needed for the common case.\n * Every font name used in font.family / fontFace / theme.fonts.* that isn't\n * in SAFE_FONTS must resolve to an entry here (by family) or tooling warns.\n */\nexport const FontRegistrySchema = Type.Array(FontRegistryEntrySchema, {\n description:\n 'Document-scoped font registry. Every non-safe font used in this document must be registered here.',\n});\n\nexport type FontRegistryDefinition = Static<typeof FontRegistrySchema>;\n","import { Type, type Static } from '@sinclair/typebox';\n\n/** Visual values only. Profiles and blueprints own required content. */\nexport const TYPE_ROLES = [\n 'eyebrow',\n 'display',\n 'stat',\n 'quote',\n 'label',\n 'footer',\n 'tableHeader',\n 'tableCell',\n 'chartLabel',\n 'tracker',\n 'source',\n] as const;\nexport const TypeRoleNameSchema = Type.Union(\n TYPE_ROLES.map((name) => Type.Literal(name))\n);\nexport type TypeRoleName = (typeof TYPE_ROLES)[number];\nexport const CANVASES = ['a4', 'letter', 'wide169', 'standard43'] as const;\nexport type DesignCanvas = (typeof CANVASES)[number];\nexport const TextCaseSchema = Type.Union([\n Type.Literal('none'),\n Type.Literal('upper'),\n Type.Literal('smallCaps'),\n]);\nconst ColorTokenSchema = Type.String({\n pattern: '^(#?[0-9A-Fa-f]{6}|[a-zA-Z][a-zA-Z0-9]*)$',\n description:\n 'Six-digit hex or a theme color/palette token. References must resolve without cycles.',\n});\nexport const PaletteSchema = Type.Object(\n {\n rule: Type.Optional(ColorTokenSchema),\n textMuted: Type.Optional(ColorTokenSchema),\n onPrimary: Type.Optional(ColorTokenSchema),\n surfaceInverse: Type.Optional(ColorTokenSchema),\n positive: Type.Optional(ColorTokenSchema),\n negative: Type.Optional(ColorTokenSchema),\n chart: Type.Optional(\n Type.Array(ColorTokenSchema, { minItems: 1, maxItems: 12 })\n ),\n },\n { additionalProperties: false }\n);\n\nexport const TypeRoleSchema = Type.Object(\n {\n face: Type.Optional(\n Type.Union([\n Type.Literal('heading'),\n Type.Literal('body'),\n Type.Literal('mono'),\n Type.Literal('light'),\n ])\n ),\n weight: Type.Optional(Type.Integer({ minimum: 100, maximum: 900 })),\n size: Type.Optional(\n Type.Number({\n minimum: 5,\n maximum: 200,\n description:\n 'Explicit size in points; takes precedence over the canvas scale.',\n })\n ),\n lineHeight: Type.Optional(Type.Number({ minimum: 0.5, maximum: 3 })),\n tracking: Type.Optional(\n Type.Number({ description: 'Tracking in hundredths of an em.' })\n ),\n case: Type.Optional(TextCaseSchema),\n color: Type.Optional(ColorTokenSchema),\n spaceBefore: Type.Optional(Type.Number({ minimum: 0 })),\n spaceAfter: Type.Optional(Type.Number({ minimum: 0 })),\n },\n { additionalProperties: false }\n);\n// Explicit properties preserve literal keys in Static<> (Object.fromEntries does not).\nexport const TypeRolesSchema = Type.Object(\n {\n eyebrow: Type.Optional(TypeRoleSchema),\n display: Type.Optional(TypeRoleSchema),\n stat: Type.Optional(TypeRoleSchema),\n quote: Type.Optional(TypeRoleSchema),\n label: Type.Optional(TypeRoleSchema),\n footer: Type.Optional(TypeRoleSchema),\n tableHeader: Type.Optional(TypeRoleSchema),\n tableCell: Type.Optional(TypeRoleSchema),\n chartLabel: Type.Optional(TypeRoleSchema),\n tracker: Type.Optional(TypeRoleSchema),\n source: Type.Optional(TypeRoleSchema),\n },\n { additionalProperties: false }\n);\nconst ScaleSchema = Type.Object(\n {\n base: Type.Number({ minimum: 5, maximum: 200 }),\n ratio: Type.Optional(Type.Number({ minimum: 1, maximum: 2 })),\n baselinePt: Type.Optional(\n Type.Number({ exclusiveMinimum: 0, maximum: 24 })\n ),\n },\n { additionalProperties: false }\n);\nexport const TypographySchema = Type.Object(\n {\n roles: Type.Optional(TypeRolesSchema),\n scale: Type.Optional(\n Type.Object(\n {\n a4: Type.Optional(ScaleSchema),\n letter: Type.Optional(ScaleSchema),\n wide169: Type.Optional(ScaleSchema),\n standard43: Type.Optional(ScaleSchema),\n },\n { additionalProperties: false }\n )\n ),\n },\n { additionalProperties: false }\n);\nconst CanvasSpacingSchema = Type.Object(\n {\n safeAreaIn: Type.Optional(Type.Number({ minimum: 0 })),\n gutterIn: Type.Optional(Type.Number({ minimum: 0 })),\n columns: Type.Optional(Type.Integer({ minimum: 1, maximum: 100 })),\n rows: Type.Optional(Type.Integer({ minimum: 1, maximum: 100 })),\n },\n { additionalProperties: false }\n);\nexport const DesignSpacingSchema = Type.Object(\n {\n basePt: Type.Optional(Type.Number({ exclusiveMinimum: 0 })),\n blockGap: Type.Optional(\n Type.Object(\n {\n tight: Type.Optional(Type.Number({ minimum: 0 })),\n normal: Type.Optional(Type.Number({ minimum: 0 })),\n loose: Type.Optional(Type.Number({ minimum: 0 })),\n },\n { additionalProperties: false }\n )\n ),\n canvas: Type.Optional(\n Type.Object(\n {\n a4: Type.Optional(CanvasSpacingSchema),\n letter: Type.Optional(CanvasSpacingSchema),\n wide169: Type.Optional(CanvasSpacingSchema),\n standard43: Type.Optional(CanvasSpacingSchema),\n },\n { additionalProperties: false }\n )\n ),\n },\n { additionalProperties: false }\n);\nconst RecipeSchema = Type.Object(\n {\n type: Type.Optional(TypeRoleNameSchema),\n color: Type.Optional(ColorTokenSchema),\n fill: Type.Optional(ColorTokenSchema),\n rule: Type.Optional(\n Type.Object(\n {\n weightPt: Type.Optional(Type.Number({ minimum: 0 })),\n color: Type.Optional(ColorTokenSchema),\n },\n { additionalProperties: false }\n )\n ),\n padPt: Type.Optional(Type.Number({ minimum: 0 })),\n alignment: Type.Optional(\n Type.Union([\n Type.Literal('left'),\n Type.Literal('center'),\n Type.Literal('right'),\n ])\n ),\n },\n { additionalProperties: false }\n);\nexport const ChromeSchema = Type.Object(\n {\n runningHead: Type.Optional(RecipeSchema),\n tracker: Type.Optional(RecipeSchema),\n actionTitle: Type.Optional(RecipeSchema),\n keyTakeaways: Type.Optional(RecipeSchema),\n sourceLine: Type.Optional(RecipeSchema),\n confidentialFooter: Type.Optional(RecipeSchema),\n logoSlot: Type.Optional(RecipeSchema),\n cover: Type.Optional(RecipeSchema),\n },\n {\n additionalProperties: false,\n description:\n 'Visual recipes; consumers land in #361. No automatic content or presence requirements.',\n }\n);\nexport const MotifSchema = Type.Object(\n {\n kind: Type.Union([\n Type.Literal('none'),\n Type.Literal('rule'),\n Type.Literal('corner'),\n Type.Literal('band'),\n ]),\n color: Type.Optional(ColorTokenSchema),\n weightPt: Type.Optional(Type.Number({ minimum: 0 })),\n placement: Type.Optional(\n Type.Union([\n Type.Literal('top'),\n Type.Literal('bottom'),\n Type.Literal('left'),\n Type.Literal('right'),\n Type.Literal('topLeft'),\n Type.Literal('topRight'),\n Type.Literal('bottomLeft'),\n Type.Literal('bottomRight'),\n ])\n ),\n },\n {\n additionalProperties: false,\n description: 'At most one motif. Rendering consumers land in #361.',\n }\n);\nexport const DesignSystemProperties = {\n palette: Type.Optional(PaletteSchema),\n typography: Type.Optional(TypographySchema),\n spacing: Type.Optional(DesignSpacingSchema),\n chrome: Type.Optional(ChromeSchema),\n motif: Type.Optional(MotifSchema),\n};\nexport const DesignSystemSchema = Type.Object(DesignSystemProperties, {\n additionalProperties: false,\n});\nexport type DesignSystem = Static<typeof DesignSystemSchema>;\nexport type TypeRole = Static<typeof TypeRoleSchema>;\n\n/** Custom paper uses A4; custom slides use the closest supported aspect ratio. */\nexport function designCanvas(\n format: 'docx' | 'pptx',\n size?: string | { width: number; height: number }\n): DesignCanvas {\n if (format === 'docx') return size === 'LETTER' ? 'letter' : 'a4';\n const ratio = typeof size === 'object' ? size.width / size.height : 4 / 3;\n return Math.abs(ratio - 16 / 9) < Math.abs(ratio - 4 / 3)\n ? 'wide169'\n : 'standard43';\n}\nexport const ROLE_SCALE_STEPS: Record<TypeRoleName, number> = {\n display: 4,\n stat: 3,\n quote: 1,\n tableHeader: 0,\n tableCell: 0,\n label: -1,\n eyebrow: -1,\n chartLabel: -1,\n tracker: -1,\n footer: -2,\n source: -2,\n};\ntype Scale = Static<typeof ScaleSchema>;\n\n/**\n * `base × ratio^step`, snapped to the nearest baseline multiple and clamped to\n * the schema's 5-200pt window. A step-0 role keeps `base` exactly: snapping a\n * role that asked for no scaling would silently retune the authored base size.\n */\nfunction scaledSize(scale: Scale, step: number): number {\n if (step === 0) return scale.base;\n const baseline = scale.baselinePt ?? 4;\n const exact = scale.base * (scale.ratio ?? 1.25) ** step;\n return Math.max(5, Math.min(200, Math.round(exact / baseline) * baseline));\n}\n\n/** The palette minus its ordered chart array, which no scalar resolver reads. */\nfunction paletteScalars(\n palette?: DesignSystem['palette']\n): Record<string, string | undefined> {\n const scalars: Record<string, string | undefined> = {};\n for (const [key, value] of Object.entries(palette ?? {})) {\n if (typeof value === 'string') scalars[key] = value;\n }\n return scalars;\n}\n\n/**\n * Case as DOCX run flags. Word inherits case from the style, so a run that\n * asks for `none` must state the flag it turns off rather than omit it.\n */\nexport function capsFormatting(textCase: 'none' | 'upper' | 'smallCaps'): {\n allCaps?: boolean;\n smallCaps?: boolean;\n} {\n return textCase === 'upper'\n ? { allCaps: true }\n : { smallCaps: textCase === 'smallCaps' };\n}\n\nexport function resolveTypeRoles(\n system: DesignSystem,\n canvas: DesignCanvas,\n base: number\n): Partial<Record<TypeRoleName, TypeRole & { size: number }>> {\n const scale = system.typography?.scale?.[canvas];\n const roles: Partial<Record<TypeRoleName, TypeRole & { size: number }>> = {};\n for (const name of TYPE_ROLES) {\n const role = system.typography?.roles?.[name];\n if (!role) continue;\n roles[name] = {\n ...role,\n size:\n role.size ?? (scale ? scaledSize(scale, ROLE_SCALE_STEPS[name]) : base),\n };\n }\n return roles;\n}\n\n/** Exclude ordered chart arrays from the scalar resolver. Palette overrides legacy tokens. */\nexport function designColors(\n colors: Record<string, string | undefined>,\n palette?: DesignSystem['palette']\n): Record<string, string | undefined> {\n return { ...colors, ...paletteScalars(palette) };\n}\nexport function resolveDesignColor(\n value: string,\n colors: Record<string, string | undefined>\n): string | undefined {\n const seen = new Set<string>();\n let current: string | undefined = value;\n while (current !== undefined && !seen.has(current)) {\n // Token lookup first, consistent with legacy resolvers.\n if (!current.startsWith('#') && Object.hasOwn(colors, current)) {\n seen.add(current);\n current = colors[current];\n } else {\n return /^#?[0-9a-f]{6}$/i.test(current)\n ? current.replace(/^#/, '')\n : undefined;\n }\n }\n return undefined;\n}\n\n/** Reject dangling/cyclic new tokens before they can become invalid OOXML. */\nexport function validateDesignColors(\n system: DesignSystem,\n colors: Record<string, string | undefined>\n): void {\n const resolved = designColors(colors, system.palette);\n const entries = Object.entries(system.palette ?? {}).flatMap(\n ([key, value]) =>\n Array.isArray(value)\n ? value.map((entry, i) => [`palette.${key}[${i}]`, entry])\n : [[`palette.${key}`, value]]\n );\n for (const [name, role] of Object.entries(system.typography?.roles ?? {})) {\n if (role.color)\n entries.push([`typography.roles.${name}.color`, role.color]);\n }\n for (const [path, value] of entries) {\n if (value && !resolveDesignColor(value, resolved)) {\n throw new Error(\n `Unresolvable theme color at ${path}: \"${value}\" (unknown token or cycle)`\n );\n }\n }\n}\n"],"mappings":"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","names":["Type"]}
|
package/dist/fonts/node.d.ts
CHANGED
|
@@ -123,5 +123,13 @@ declare function toRasterizeFontFaces(fonts: readonly ResolvedFont[], warnings?:
|
|
|
123
123
|
* matching how the registry keys resolved fonts.
|
|
124
124
|
*/
|
|
125
125
|
declare function fromRasterizeFontFaces(faces: readonly RasterizeFontFace[]): ResolvedFont[];
|
|
126
|
+
/**
|
|
127
|
+
* Flatten resolved fonts into the faces a Highcharts export server can be
|
|
128
|
+
* handed as inline `@font-face` rules. Wider than `toRasterizeFontFaces`:
|
|
129
|
+
* the chart is drawn by Chromium, which reads WOFF and WOFF2 as readily as
|
|
130
|
+
* an sfnt, so only formats no browser loads are dropped. Safe-only fonts
|
|
131
|
+
* carry no bytes and are skipped; the server's own host faces cover them.
|
|
132
|
+
*/
|
|
133
|
+
declare function toChartFontFaces(fonts: readonly ResolvedFont[]): RasterizeFontFace[];
|
|
126
134
|
|
|
127
|
-
export { FontDiskCache, type VariableFetchOptions, fetchVariableFontSource, fromRasterizeFontFaces, loadFileFontSource, toRasterizeFontFaces };
|
|
135
|
+
export { FontDiskCache, type VariableFetchOptions, fetchVariableFontSource, fromRasterizeFontFaces, loadFileFontSource, toChartFontFaces, toRasterizeFontFaces };
|
package/dist/fonts/node.js
CHANGED
|
@@ -279,11 +279,34 @@ function fromRasterizeFontFaces(faces) {
|
|
|
279
279
|
}
|
|
280
280
|
return [...byFamily.values()];
|
|
281
281
|
}
|
|
282
|
+
var BROWSER_FORMATS = /* @__PURE__ */ new Set([
|
|
283
|
+
"ttf",
|
|
284
|
+
"otf",
|
|
285
|
+
"woff",
|
|
286
|
+
"woff2"
|
|
287
|
+
]);
|
|
288
|
+
function toChartFontFaces(fonts) {
|
|
289
|
+
const faces = [];
|
|
290
|
+
for (const font of fonts) {
|
|
291
|
+
for (const source of font.sources) {
|
|
292
|
+
if (!BROWSER_FORMATS.has(source.format)) continue;
|
|
293
|
+
faces.push({
|
|
294
|
+
family: font.family,
|
|
295
|
+
weight: source.weight,
|
|
296
|
+
italic: source.italic,
|
|
297
|
+
data: source.data.toString("base64"),
|
|
298
|
+
format: source.format
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
return faces;
|
|
303
|
+
}
|
|
282
304
|
export {
|
|
283
305
|
FontDiskCache,
|
|
284
306
|
fetchVariableFontSource,
|
|
285
307
|
fromRasterizeFontFaces,
|
|
286
308
|
loadFileFontSource,
|
|
309
|
+
toChartFontFaces,
|
|
287
310
|
toRasterizeFontFaces
|
|
288
311
|
};
|
|
289
312
|
//# sourceMappingURL=node.js.map
|