@webstudio-is/fonts 0.289.0 → 0.291.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/lib/index.js CHANGED
@@ -251,58 +251,75 @@ var getFontFormat = (asset) => {
251
251
  const extension = asset.name.slice(asset.name.lastIndexOf(".") + 1);
252
252
  return FONT_FORMATS.has(extension) ? FONT_FORMATS.get(extension) ?? asset.format : FONT_FORMATS.get(asset.format) ?? asset.format;
253
253
  };
254
- var formatFace = (asset, format, url) => {
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
+ };
255
261
  if ("variationAxes" in asset.meta) {
256
- const { wght, wdth } = asset.meta?.variationAxes ?? {};
262
+ const { wght, wdth } = asset.meta.variationAxes;
257
263
  return {
258
- fontFamily: asset.meta.family,
259
- fontStyle: "normal",
260
- fontDisplay: "swap",
261
- src: `url(${sanitizeCssUrl(url)}) format("${format}")`,
264
+ ...face,
262
265
  fontStretch: wdth ? `${wdth.min}% ${wdth.max}%` : void 0,
263
266
  fontWeight: wght ? `${wght.min} ${wght.max}` : void 0
264
267
  };
265
268
  }
266
269
  return {
267
- fontFamily: asset.meta.family,
268
- fontStyle: asset.meta.style,
269
- fontWeight: asset.meta.weight,
270
- fontDisplay: "swap",
271
- src: `url(${sanitizeCssUrl(url)}) format("${format}")`
270
+ ...face,
271
+ fontWeight: asset.meta.weight
272
272
  };
273
273
  };
274
- var getKey = (asset) => {
274
+ var getKey = (asset, style) => {
275
275
  if ("variationAxes" in asset.meta) {
276
- return asset.meta.family + Object.values(asset.meta.variationAxes).join("");
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
+ }
277
293
  }
278
- return asset.meta.family + asset.meta.style + asset.meta.weight;
294
+ return Array.from(styles);
279
295
  };
280
296
  var getFontFaces = (assets, options) => {
281
297
  const { assetBaseUrl } = options;
282
298
  const faces = /* @__PURE__ */ new Map();
283
- const seenUrls = /* @__PURE__ */ new Set();
299
+ const seenSources = /* @__PURE__ */ new Set();
284
300
  for (const asset of assets) {
285
301
  const url = `${assetBaseUrl}${asset.name}`;
286
- const assetKey = getKey(asset);
287
- if (seenUrls.has(url)) {
288
- continue;
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);
289
316
  }
290
- seenUrls.add(url);
291
- const format = getFontFormat(asset);
292
- const sources = faces.get(assetKey) ?? /* @__PURE__ */ new Map();
293
- const existing = sources.get(format);
294
- if (existing === void 0 || url < existing.url) {
295
- sources.set(format, { asset, format, url });
296
- }
297
- faces.set(assetKey, sources);
298
317
  }
299
318
  return Array.from(faces.values(), (sources) => {
300
- const [{ asset, format, url }, ...fallbacks] = Array.from(
301
- sources.values()
302
- ).sort(
319
+ const [source, ...fallbacks] = Array.from(sources.values()).sort(
303
320
  (left, right) => fontFormatOrder.indexOf(left.format) - fontFormatOrder.indexOf(right.format)
304
321
  );
305
- const face = formatFace(asset, format, url);
322
+ const face = formatFace(source);
306
323
  face.src += fallbacks.map(
307
324
  ({ format: fallbackFormat, url: fallbackUrl }) => `, url(${sanitizeCssUrl(fallbackUrl)}) format("${fallbackFormat}")`
308
325
  ).join("");
@@ -312,27 +329,13 @@ var getFontFaces = (assets, options) => {
312
329
 
313
330
  // src/schema.ts
314
331
  import { z } from "zod";
332
+ var fontStyle = z.enum(FONT_STYLES);
315
333
  var fontFormat = z.union([
316
334
  z.literal("ttf"),
317
335
  z.literal("woff"),
318
336
  z.literal("woff2")
319
337
  ]);
320
- var axisName = z.enum([
321
- "wght",
322
- "wdth",
323
- "slnt",
324
- "opsz",
325
- "ital",
326
- "GRAD",
327
- "XTRA",
328
- "XOPQ",
329
- "YOPQ",
330
- "YTLC",
331
- "YTUC",
332
- "YTAS",
333
- "YTDE",
334
- "YTFI"
335
- ]);
338
+ var axisName = z.string().regex(/^[A-Za-z][A-Za-z0-9]* *$/).length(4);
336
339
  var variationAxes = z.partialRecord(
337
340
  axisName,
338
341
  z.object({
@@ -344,18 +347,46 @@ var variationAxes = z.partialRecord(
344
347
  );
345
348
  var fontMetaStatic = z.object({
346
349
  family: z.string(),
347
- style: z.enum(FONT_STYLES),
350
+ style: fontStyle,
348
351
  weight: z.number()
349
352
  });
350
353
  var fontMetaVariable = z.object({
351
354
  family: z.string(),
355
+ style: fontStyle.default("normal"),
352
356
  variationAxes
353
357
  });
354
358
  var fontMeta = z.union([fontMetaStatic, fontMetaVariable]);
355
359
  var fontMetaUpdate = z.union([
356
360
  fontMetaStatic.partial().strict(),
357
- fontMetaVariable.partial().strict()
361
+ z.object({
362
+ family: fontMetaVariable.shape.family.optional(),
363
+ style: fontStyle.optional(),
364
+ variationAxes: fontMetaVariable.shape.variationAxes.optional()
365
+ }).strict()
358
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
+ };
359
390
 
360
391
  // src/font-weights.ts
361
392
  var fontWeights = {
@@ -415,5 +446,6 @@ export {
415
446
  fontMetaVariable,
416
447
  fontWeightNames,
417
448
  fontWeights,
418
- getFontFaces
449
+ getFontFaces,
450
+ mergeFontMeta
419
451
  };
@@ -1,4 +1,5 @@
1
- import type { FontMeta, FontFormat, FontMetaStatic } from "./schema";
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?: FontMetaStatic["style"];
12
+ fontStyle?: FontStyle;
12
13
  fontWeight?: number | string;
13
14
  fontStretch?: string;
14
15
  };
@@ -1,22 +1,7 @@
1
1
  import { z } from "zod";
2
2
  export declare const fontFormat: z.ZodUnion<readonly [z.ZodLiteral<"ttf">, z.ZodLiteral<"woff">, z.ZodLiteral<"woff2">]>;
3
3
  export type FontFormat = z.infer<typeof fontFormat>;
4
- declare const variationAxes: z.ZodRecord<z.ZodEnum<{
5
- GRAD: "GRAD";
6
- XOPQ: "XOPQ";
7
- XTRA: "XTRA";
8
- YOPQ: "YOPQ";
9
- YTAS: "YTAS";
10
- YTDE: "YTDE";
11
- YTFI: "YTFI";
12
- YTLC: "YTLC";
13
- YTUC: "YTUC";
14
- ital: "ital";
15
- opsz: "opsz";
16
- slnt: "slnt";
17
- wdth: "wdth";
18
- wght: "wght";
19
- }> & z.core.$partial, z.ZodObject<{
4
+ declare const variationAxes: z.ZodRecord<z.ZodString & z.core.$partial, z.ZodObject<{
20
5
  name: z.ZodString;
21
6
  min: z.ZodNumber;
22
7
  default: z.ZodNumber;
@@ -35,22 +20,12 @@ export declare const fontMetaStatic: z.ZodObject<{
35
20
  export type FontMetaStatic = z.infer<typeof fontMetaStatic>;
36
21
  export declare const fontMetaVariable: z.ZodObject<{
37
22
  family: z.ZodString;
38
- variationAxes: z.ZodRecord<z.ZodEnum<{
39
- GRAD: "GRAD";
40
- XOPQ: "XOPQ";
41
- XTRA: "XTRA";
42
- YOPQ: "YOPQ";
43
- YTAS: "YTAS";
44
- YTDE: "YTDE";
45
- YTFI: "YTFI";
46
- YTLC: "YTLC";
47
- YTUC: "YTUC";
48
- ital: "ital";
49
- opsz: "opsz";
50
- slnt: "slnt";
51
- wdth: "wdth";
52
- wght: "wght";
53
- }> & z.core.$partial, z.ZodObject<{
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<{
54
29
  name: z.ZodString;
55
30
  min: z.ZodNumber;
56
31
  default: z.ZodNumber;
@@ -67,22 +42,12 @@ export declare const fontMeta: z.ZodUnion<readonly [z.ZodObject<{
67
42
  weight: z.ZodNumber;
68
43
  }, z.core.$strip>, z.ZodObject<{
69
44
  family: z.ZodString;
70
- variationAxes: z.ZodRecord<z.ZodEnum<{
71
- GRAD: "GRAD";
72
- XOPQ: "XOPQ";
73
- XTRA: "XTRA";
74
- YOPQ: "YOPQ";
75
- YTAS: "YTAS";
76
- YTDE: "YTDE";
77
- YTFI: "YTFI";
78
- YTLC: "YTLC";
79
- YTUC: "YTUC";
80
- ital: "ital";
81
- opsz: "opsz";
82
- slnt: "slnt";
83
- wdth: "wdth";
84
- wght: "wght";
85
- }> & z.core.$partial, z.ZodObject<{
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<{
86
51
  name: z.ZodString;
87
52
  min: z.ZodNumber;
88
53
  default: z.ZodNumber;
@@ -99,22 +64,12 @@ export declare const fontMetaUpdate: z.ZodUnion<readonly [z.ZodObject<{
99
64
  weight: z.ZodOptional<z.ZodNumber>;
100
65
  }, z.core.$strict>, z.ZodObject<{
101
66
  family: z.ZodOptional<z.ZodString>;
102
- variationAxes: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
103
- GRAD: "GRAD";
104
- XOPQ: "XOPQ";
105
- XTRA: "XTRA";
106
- YOPQ: "YOPQ";
107
- YTAS: "YTAS";
108
- YTDE: "YTDE";
109
- YTFI: "YTFI";
110
- YTLC: "YTLC";
111
- YTUC: "YTUC";
112
- ital: "ital";
113
- opsz: "opsz";
114
- slnt: "slnt";
115
- wdth: "wdth";
116
- wght: "wght";
117
- }> & z.core.$partial, z.ZodObject<{
67
+ style: z.ZodOptional<z.ZodEnum<{
68
+ italic: "italic";
69
+ normal: "normal";
70
+ oblique: "oblique";
71
+ }>>;
72
+ variationAxes: z.ZodOptional<z.ZodRecord<z.ZodString & z.core.$partial, z.ZodObject<{
118
73
  name: z.ZodString;
119
74
  min: z.ZodNumber;
120
75
  default: z.ZodNumber;
@@ -122,4 +77,5 @@ export declare const fontMetaUpdate: z.ZodUnion<readonly [z.ZodObject<{
122
77
  }, z.core.$strip>>>;
123
78
  }, z.core.$strict>]>;
124
79
  export type FontMeta = z.infer<typeof fontMeta>;
80
+ export declare const mergeFontMeta: (current: FontMeta, override: unknown) => FontMeta | undefined;
125
81
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webstudio-is/fonts",
3
- "version": "0.289.0",
3
+ "version": "0.291.0",
4
4
  "description": "Fonts utils",
5
5
  "author": "Webstudio <github@webstudio.is>",
6
6
  "homepage": "https://webstudio.is",