@webstudio-is/fonts 0.0.0-73cd6ea → 0.0.0-7a19155
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/lib/index.js +110 -55
- package/lib/types/font-weights.d.ts +1 -1
- package/lib/types/get-font-faces.d.ts +3 -2
- package/lib/types/schema.d.ts +64 -66
- package/package.json +4 -4
- package/lib/types/get-font-faces.test.d.ts +0 -1
package/lib/index.js
CHANGED
|
@@ -246,78 +246,98 @@ var FONT_STYLES = ["normal", "italic", "oblique"];
|
|
|
246
246
|
|
|
247
247
|
// src/get-font-faces.ts
|
|
248
248
|
var sanitizeCssUrl = (str) => JSON.stringify(str);
|
|
249
|
-
var
|
|
249
|
+
var fontFormatOrder = Array.from(FONT_FORMATS.values());
|
|
250
|
+
var getFontFormat = (asset) => {
|
|
251
|
+
const extension = asset.name.slice(asset.name.lastIndexOf(".") + 1);
|
|
252
|
+
return FONT_FORMATS.has(extension) ? FONT_FORMATS.get(extension) ?? asset.format : FONT_FORMATS.get(asset.format) ?? asset.format;
|
|
253
|
+
};
|
|
254
|
+
var formatFace = ({ asset, format, style, url }) => {
|
|
255
|
+
const face = {
|
|
256
|
+
fontFamily: asset.meta.family,
|
|
257
|
+
fontStyle: style,
|
|
258
|
+
fontDisplay: "swap",
|
|
259
|
+
src: `url(${sanitizeCssUrl(url)}) format("${format}")`
|
|
260
|
+
};
|
|
250
261
|
if ("variationAxes" in asset.meta) {
|
|
251
|
-
const { wght, wdth } = asset.meta
|
|
262
|
+
const { wght, wdth } = asset.meta.variationAxes;
|
|
252
263
|
return {
|
|
253
|
-
|
|
254
|
-
fontStyle: "normal",
|
|
255
|
-
fontDisplay: "swap",
|
|
256
|
-
src: `url(${sanitizeCssUrl(url)}) format("${format}")`,
|
|
264
|
+
...face,
|
|
257
265
|
fontStretch: wdth ? `${wdth.min}% ${wdth.max}%` : void 0,
|
|
258
266
|
fontWeight: wght ? `${wght.min} ${wght.max}` : void 0
|
|
259
267
|
};
|
|
260
268
|
}
|
|
261
269
|
return {
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
fontWeight: asset.meta.weight,
|
|
265
|
-
fontDisplay: "swap",
|
|
266
|
-
src: `url(${sanitizeCssUrl(url)}) format("${format}")`
|
|
270
|
+
...face,
|
|
271
|
+
fontWeight: asset.meta.weight
|
|
267
272
|
};
|
|
268
273
|
};
|
|
269
|
-
var getKey = (asset) => {
|
|
274
|
+
var getKey = (asset, style) => {
|
|
270
275
|
if ("variationAxes" in asset.meta) {
|
|
271
|
-
|
|
276
|
+
const { wght, wdth } = asset.meta.variationAxes;
|
|
277
|
+
return JSON.stringify([asset.meta.family, style, wght, wdth]);
|
|
278
|
+
}
|
|
279
|
+
return JSON.stringify([asset.meta.family, style, asset.meta.weight]);
|
|
280
|
+
};
|
|
281
|
+
var getStyles = (meta) => {
|
|
282
|
+
const styles = /* @__PURE__ */ new Set([meta.style]);
|
|
283
|
+
if ("variationAxes" in meta) {
|
|
284
|
+
const { ital, slnt } = meta.variationAxes;
|
|
285
|
+
if (ital !== void 0 && ital.min <= 0 && ital.max >= 1) {
|
|
286
|
+
styles.add("normal");
|
|
287
|
+
styles.add("italic");
|
|
288
|
+
}
|
|
289
|
+
if (slnt !== void 0 && slnt.min < slnt.max && slnt.min <= 0 && slnt.max >= 0) {
|
|
290
|
+
styles.add("normal");
|
|
291
|
+
styles.add("oblique");
|
|
292
|
+
}
|
|
272
293
|
}
|
|
273
|
-
return
|
|
294
|
+
return Array.from(styles);
|
|
274
295
|
};
|
|
275
296
|
var getFontFaces = (assets, options) => {
|
|
276
297
|
const { assetBaseUrl } = options;
|
|
277
298
|
const faces = /* @__PURE__ */ new Map();
|
|
299
|
+
const seenSources = /* @__PURE__ */ new Set();
|
|
278
300
|
for (const asset of assets) {
|
|
279
301
|
const url = `${assetBaseUrl}${asset.name}`;
|
|
280
|
-
const
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
302
|
+
for (const style of getStyles(asset.meta)) {
|
|
303
|
+
const sourceKey = JSON.stringify([url, style]);
|
|
304
|
+
if (seenSources.has(sourceKey)) {
|
|
305
|
+
continue;
|
|
306
|
+
}
|
|
307
|
+
seenSources.add(sourceKey);
|
|
308
|
+
const assetKey = getKey(asset, style);
|
|
309
|
+
const format = getFontFormat(asset);
|
|
310
|
+
const sources = faces.get(assetKey) ?? /* @__PURE__ */ new Map();
|
|
311
|
+
const existing = sources.get(format);
|
|
312
|
+
if (existing === void 0 || url < existing.url) {
|
|
313
|
+
sources.set(format, { asset, format, style, url });
|
|
314
|
+
}
|
|
315
|
+
faces.set(assetKey, sources);
|
|
285
316
|
}
|
|
286
|
-
if (face === void 0) {
|
|
287
|
-
const face2 = formatFace(asset, format, url);
|
|
288
|
-
faces.set(assetKey, face2);
|
|
289
|
-
continue;
|
|
290
|
-
}
|
|
291
|
-
face.src += `, url(${sanitizeCssUrl(url)}) format("${format}")`;
|
|
292
317
|
}
|
|
293
|
-
return Array.from(faces.values())
|
|
318
|
+
return Array.from(faces.values(), (sources) => {
|
|
319
|
+
const [source, ...fallbacks] = Array.from(sources.values()).sort(
|
|
320
|
+
(left, right) => fontFormatOrder.indexOf(left.format) - fontFormatOrder.indexOf(right.format)
|
|
321
|
+
);
|
|
322
|
+
const face = formatFace(source);
|
|
323
|
+
face.src += fallbacks.map(
|
|
324
|
+
({ format: fallbackFormat, url: fallbackUrl }) => `, url(${sanitizeCssUrl(fallbackUrl)}) format("${fallbackFormat}")`
|
|
325
|
+
).join("");
|
|
326
|
+
return face;
|
|
327
|
+
});
|
|
294
328
|
};
|
|
295
329
|
|
|
296
330
|
// src/schema.ts
|
|
297
331
|
import { z } from "zod";
|
|
298
|
-
var
|
|
332
|
+
var fontStyle = z.enum(FONT_STYLES);
|
|
333
|
+
var fontFormat = z.union([
|
|
299
334
|
z.literal("ttf"),
|
|
300
335
|
z.literal("woff"),
|
|
301
336
|
z.literal("woff2")
|
|
302
337
|
]);
|
|
303
|
-
var
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
"slnt",
|
|
307
|
-
"opsz",
|
|
308
|
-
"ital",
|
|
309
|
-
"GRAD",
|
|
310
|
-
"XTRA",
|
|
311
|
-
"XOPQ",
|
|
312
|
-
"YOPQ",
|
|
313
|
-
"YTLC",
|
|
314
|
-
"YTUC",
|
|
315
|
-
"YTAS",
|
|
316
|
-
"YTDE",
|
|
317
|
-
"YTFI"
|
|
318
|
-
]);
|
|
319
|
-
var VariationAxes = z.record(
|
|
320
|
-
AxisName,
|
|
338
|
+
var axisName = z.string().regex(/^[A-Za-z][A-Za-z0-9]* *$/).length(4);
|
|
339
|
+
var variationAxes = z.partialRecord(
|
|
340
|
+
axisName,
|
|
321
341
|
z.object({
|
|
322
342
|
name: z.string(),
|
|
323
343
|
min: z.number(),
|
|
@@ -325,16 +345,48 @@ var VariationAxes = z.record(
|
|
|
325
345
|
max: z.number()
|
|
326
346
|
})
|
|
327
347
|
);
|
|
328
|
-
var
|
|
348
|
+
var fontMetaStatic = z.object({
|
|
329
349
|
family: z.string(),
|
|
330
|
-
style:
|
|
350
|
+
style: fontStyle,
|
|
331
351
|
weight: z.number()
|
|
332
352
|
});
|
|
333
|
-
var
|
|
353
|
+
var fontMetaVariable = z.object({
|
|
334
354
|
family: z.string(),
|
|
335
|
-
|
|
355
|
+
style: fontStyle.default("normal"),
|
|
356
|
+
variationAxes
|
|
336
357
|
});
|
|
337
|
-
var
|
|
358
|
+
var fontMeta = z.union([fontMetaStatic, fontMetaVariable]);
|
|
359
|
+
var fontMetaUpdate = z.union([
|
|
360
|
+
fontMetaStatic.partial().strict(),
|
|
361
|
+
z.object({
|
|
362
|
+
family: fontMetaVariable.shape.family.optional(),
|
|
363
|
+
style: fontStyle.optional(),
|
|
364
|
+
variationAxes: fontMetaVariable.shape.variationAxes.optional()
|
|
365
|
+
}).strict()
|
|
366
|
+
]);
|
|
367
|
+
var mergeFontMeta = (current, override) => {
|
|
368
|
+
const result = fontMetaUpdate.safeParse(override);
|
|
369
|
+
if (result.success === false) {
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
const { family, style } = result.data;
|
|
373
|
+
if ("variationAxes" in current) {
|
|
374
|
+
const variationAxes2 = "variationAxes" in result.data ? result.data.variationAxes : void 0;
|
|
375
|
+
return {
|
|
376
|
+
...current,
|
|
377
|
+
...family === void 0 ? {} : { family },
|
|
378
|
+
...style === void 0 ? {} : { style },
|
|
379
|
+
...variationAxes2 === void 0 ? {} : { variationAxes: variationAxes2 }
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
const weight = "weight" in result.data ? result.data.weight : void 0;
|
|
383
|
+
return {
|
|
384
|
+
...current,
|
|
385
|
+
...family === void 0 ? {} : { family },
|
|
386
|
+
...style === void 0 ? {} : { style },
|
|
387
|
+
...weight === void 0 ? {} : { weight }
|
|
388
|
+
};
|
|
389
|
+
};
|
|
338
390
|
|
|
339
391
|
// src/font-weights.ts
|
|
340
392
|
var fontWeights = {
|
|
@@ -364,7 +416,7 @@ var fontWeights = {
|
|
|
364
416
|
},
|
|
365
417
|
"700": {
|
|
366
418
|
label: "Bold",
|
|
367
|
-
names: ["bold"
|
|
419
|
+
names: ["bold"]
|
|
368
420
|
},
|
|
369
421
|
"800": {
|
|
370
422
|
label: "Extra Bold",
|
|
@@ -386,11 +438,14 @@ export {
|
|
|
386
438
|
FONT_FORMATS,
|
|
387
439
|
FONT_MIME_TYPES,
|
|
388
440
|
FONT_STYLES,
|
|
389
|
-
FontFormat,
|
|
390
|
-
FontMeta,
|
|
391
|
-
FontMetaStatic,
|
|
392
441
|
SYSTEM_FONTS,
|
|
442
|
+
fontFormat,
|
|
443
|
+
fontMeta,
|
|
444
|
+
fontMetaStatic,
|
|
445
|
+
fontMetaUpdate,
|
|
446
|
+
fontMetaVariable,
|
|
393
447
|
fontWeightNames,
|
|
394
448
|
fontWeights,
|
|
395
|
-
getFontFaces
|
|
449
|
+
getFontFaces,
|
|
450
|
+
mergeFontMeta
|
|
396
451
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { type FontStyle } from "./constants";
|
|
2
|
+
import type { FontMeta, FontFormat } from "./schema";
|
|
2
3
|
export type PartialFontAsset = {
|
|
3
4
|
format: FontFormat;
|
|
4
5
|
meta: FontMeta;
|
|
@@ -8,7 +9,7 @@ export type FontFace = {
|
|
|
8
9
|
fontFamily: string;
|
|
9
10
|
fontDisplay: "swap" | "auto" | "block" | "fallback" | "optional";
|
|
10
11
|
src: string;
|
|
11
|
-
fontStyle?:
|
|
12
|
+
fontStyle?: FontStyle;
|
|
12
13
|
fontWeight?: number | string;
|
|
13
14
|
fontStretch?: string;
|
|
14
15
|
};
|
package/lib/types/schema.d.ts
CHANGED
|
@@ -1,83 +1,81 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
export declare const
|
|
3
|
-
export type FontFormat = z.infer<typeof
|
|
4
|
-
declare const
|
|
2
|
+
export declare const fontFormat: z.ZodUnion<readonly [z.ZodLiteral<"ttf">, z.ZodLiteral<"woff">, z.ZodLiteral<"woff2">]>;
|
|
3
|
+
export type FontFormat = z.infer<typeof fontFormat>;
|
|
4
|
+
declare const variationAxes: z.ZodRecord<z.ZodString & z.core.$partial, z.ZodObject<{
|
|
5
5
|
name: z.ZodString;
|
|
6
6
|
min: z.ZodNumber;
|
|
7
7
|
default: z.ZodNumber;
|
|
8
8
|
max: z.ZodNumber;
|
|
9
|
-
},
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
default: number;
|
|
13
|
-
max: number;
|
|
14
|
-
}, {
|
|
15
|
-
name: string;
|
|
16
|
-
min: number;
|
|
17
|
-
default: number;
|
|
18
|
-
max: number;
|
|
19
|
-
}>>;
|
|
20
|
-
export type VariationAxes = z.infer<typeof VariationAxes>;
|
|
21
|
-
export declare const FontMetaStatic: z.ZodObject<{
|
|
9
|
+
}, z.core.$strip>>;
|
|
10
|
+
export type VariationAxes = z.infer<typeof variationAxes>;
|
|
11
|
+
export declare const fontMetaStatic: z.ZodObject<{
|
|
22
12
|
family: z.ZodString;
|
|
23
|
-
style: z.ZodEnum<
|
|
13
|
+
style: z.ZodEnum<{
|
|
14
|
+
italic: "italic";
|
|
15
|
+
normal: "normal";
|
|
16
|
+
oblique: "oblique";
|
|
17
|
+
}>;
|
|
24
18
|
weight: z.ZodNumber;
|
|
25
|
-
},
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
weight: number;
|
|
29
|
-
}, {
|
|
30
|
-
family: string;
|
|
31
|
-
style: "normal" | "italic" | "oblique";
|
|
32
|
-
weight: number;
|
|
33
|
-
}>;
|
|
34
|
-
export type FontMetaStatic = z.infer<typeof FontMetaStatic>;
|
|
35
|
-
export declare const FontMeta: z.ZodUnion<[z.ZodObject<{
|
|
19
|
+
}, z.core.$strip>;
|
|
20
|
+
export type FontMetaStatic = z.infer<typeof fontMetaStatic>;
|
|
21
|
+
export declare const fontMetaVariable: z.ZodObject<{
|
|
36
22
|
family: z.ZodString;
|
|
37
|
-
style: z.ZodEnum<
|
|
23
|
+
style: z.ZodDefault<z.ZodEnum<{
|
|
24
|
+
italic: "italic";
|
|
25
|
+
normal: "normal";
|
|
26
|
+
oblique: "oblique";
|
|
27
|
+
}>>;
|
|
28
|
+
variationAxes: z.ZodRecord<z.ZodString & z.core.$partial, z.ZodObject<{
|
|
29
|
+
name: z.ZodString;
|
|
30
|
+
min: z.ZodNumber;
|
|
31
|
+
default: z.ZodNumber;
|
|
32
|
+
max: z.ZodNumber;
|
|
33
|
+
}, z.core.$strip>>;
|
|
34
|
+
}, z.core.$strip>;
|
|
35
|
+
export declare const fontMeta: z.ZodUnion<readonly [z.ZodObject<{
|
|
36
|
+
family: z.ZodString;
|
|
37
|
+
style: z.ZodEnum<{
|
|
38
|
+
italic: "italic";
|
|
39
|
+
normal: "normal";
|
|
40
|
+
oblique: "oblique";
|
|
41
|
+
}>;
|
|
38
42
|
weight: z.ZodNumber;
|
|
39
|
-
},
|
|
40
|
-
family: string;
|
|
41
|
-
style: "normal" | "italic" | "oblique";
|
|
42
|
-
weight: number;
|
|
43
|
-
}, {
|
|
44
|
-
family: string;
|
|
45
|
-
style: "normal" | "italic" | "oblique";
|
|
46
|
-
weight: number;
|
|
47
|
-
}>, z.ZodObject<{
|
|
43
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
48
44
|
family: z.ZodString;
|
|
49
|
-
|
|
45
|
+
style: z.ZodDefault<z.ZodEnum<{
|
|
46
|
+
italic: "italic";
|
|
47
|
+
normal: "normal";
|
|
48
|
+
oblique: "oblique";
|
|
49
|
+
}>>;
|
|
50
|
+
variationAxes: z.ZodRecord<z.ZodString & z.core.$partial, z.ZodObject<{
|
|
50
51
|
name: z.ZodString;
|
|
51
52
|
min: z.ZodNumber;
|
|
52
53
|
default: z.ZodNumber;
|
|
53
54
|
max: z.ZodNumber;
|
|
54
|
-
},
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
default: number;
|
|
63
|
-
max: number;
|
|
64
|
-
}>>;
|
|
65
|
-
}, "strip", z.ZodTypeAny, {
|
|
66
|
-
family: string;
|
|
67
|
-
variationAxes: Partial<Record<"wght" | "wdth" | "slnt" | "opsz" | "ital" | "GRAD" | "XTRA" | "XOPQ" | "YOPQ" | "YTLC" | "YTUC" | "YTAS" | "YTDE" | "YTFI", {
|
|
68
|
-
name: string;
|
|
69
|
-
min: number;
|
|
70
|
-
default: number;
|
|
71
|
-
max: number;
|
|
55
|
+
}, z.core.$strip>>;
|
|
56
|
+
}, z.core.$strip>]>;
|
|
57
|
+
export declare const fontMetaUpdate: z.ZodUnion<readonly [z.ZodObject<{
|
|
58
|
+
family: z.ZodOptional<z.ZodString>;
|
|
59
|
+
style: z.ZodOptional<z.ZodEnum<{
|
|
60
|
+
italic: "italic";
|
|
61
|
+
normal: "normal";
|
|
62
|
+
oblique: "oblique";
|
|
72
63
|
}>>;
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
64
|
+
weight: z.ZodOptional<z.ZodNumber>;
|
|
65
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
66
|
+
family: z.ZodOptional<z.ZodString>;
|
|
67
|
+
style: z.ZodOptional<z.ZodEnum<{
|
|
68
|
+
italic: "italic";
|
|
69
|
+
normal: "normal";
|
|
70
|
+
oblique: "oblique";
|
|
80
71
|
}>>;
|
|
81
|
-
|
|
82
|
-
|
|
72
|
+
variationAxes: z.ZodOptional<z.ZodRecord<z.ZodString & z.core.$partial, z.ZodObject<{
|
|
73
|
+
name: z.ZodString;
|
|
74
|
+
min: z.ZodNumber;
|
|
75
|
+
default: z.ZodNumber;
|
|
76
|
+
max: z.ZodNumber;
|
|
77
|
+
}, z.core.$strip>>>;
|
|
78
|
+
}, z.core.$strict>]>;
|
|
79
|
+
export type FontMeta = z.infer<typeof fontMeta>;
|
|
80
|
+
export declare const mergeFontMeta: (current: FontMeta, override: unknown) => FontMeta | undefined;
|
|
83
81
|
export {};
|
package/package.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webstudio-is/fonts",
|
|
3
|
-
"version": "0.0.0-
|
|
3
|
+
"version": "0.0.0-7a19155",
|
|
4
4
|
"description": "Fonts utils",
|
|
5
5
|
"author": "Webstudio <github@webstudio.is>",
|
|
6
6
|
"homepage": "https://webstudio.is",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"devDependencies": {
|
|
9
9
|
"vitest": "^3.1.2",
|
|
10
|
-
"zod": "^
|
|
10
|
+
"zod": "^4.4.3",
|
|
11
11
|
"@webstudio-is/tsconfig": "1.0.7"
|
|
12
12
|
},
|
|
13
13
|
"peerDependencies": {
|
|
14
|
-
"zod": "^
|
|
14
|
+
"zod": "^4.4.3"
|
|
15
15
|
},
|
|
16
16
|
"exports": {
|
|
17
17
|
"webstudio": "./src/index.ts",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"private": false,
|
|
27
27
|
"sideEffects": false,
|
|
28
28
|
"scripts": {
|
|
29
|
-
"typecheck": "tsc",
|
|
29
|
+
"typecheck": "tsc --noEmit",
|
|
30
30
|
"test": "vitest run",
|
|
31
31
|
"build": "rm -rf lib && esbuild src/index.ts --outdir=lib --bundle --format=esm --packages=external",
|
|
32
32
|
"dts": "tsc --project tsconfig.dts.json"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|