@hyperframes/core 0.6.79 → 0.6.81
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/fonts/aliases.d.ts +91 -0
- package/dist/fonts/aliases.d.ts.map +1 -0
- package/dist/fonts/aliases.js +122 -0
- package/dist/fonts/aliases.js.map +1 -0
- package/dist/fonts/systemFontLocator.d.ts +28 -0
- package/dist/fonts/systemFontLocator.d.ts.map +1 -0
- package/dist/fonts/systemFontLocator.js +367 -0
- package/dist/fonts/systemFontLocator.js.map +1 -0
- package/dist/generated/runtime-inline.js +1 -1
- package/dist/generated/runtime-inline.js.map +1 -1
- package/dist/hyperframe.manifest.json +1 -1
- package/dist/hyperframe.runtime.iife.js +19 -19
- package/dist/hyperframe.runtime.mjs +19 -19
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/lint/rules/fonts.d.ts.map +1 -1
- package/dist/lint/rules/fonts.js +38 -37
- package/dist/lint/rules/fonts.js.map +1 -1
- package/dist/lint/types.d.ts +8 -0
- package/dist/lint/types.d.ts.map +1 -1
- package/dist/parsers/gsapConstants.d.ts.map +1 -1
- package/dist/parsers/gsapConstants.js +2 -0
- package/dist/parsers/gsapConstants.js.map +1 -1
- package/dist/registry/types.d.ts +1 -1
- package/dist/registry/types.d.ts.map +1 -1
- package/dist/registry/types.js +3 -0
- package/dist/registry/types.js.map +1 -1
- package/dist/studio-api/routes/fonts.d.ts.map +1 -1
- package/dist/studio-api/routes/fonts.js +51 -88
- package/dist/studio-api/routes/fonts.js.map +1 -1
- package/dist/telemetryRedaction.d.ts +2 -0
- package/dist/telemetryRedaction.d.ts.map +1 -0
- package/dist/telemetryRedaction.js +21 -0
- package/dist/telemetryRedaction.js.map +1 -0
- package/dist/templates/constants.d.ts +1 -1
- package/dist/templates/constants.d.ts.map +1 -1
- package/dist/templates/constants.js +1 -1
- package/dist/templates/constants.js.map +1 -1
- package/package.json +9 -1
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single source of truth for the deterministic font alias map. Both the
|
|
3
|
+
* producer's @font-face injector and the core lint rules import from here,
|
|
4
|
+
* eliminating manual drift between the two.
|
|
5
|
+
*
|
|
6
|
+
* Keys are lowercase font family names. Values are canonical font slugs
|
|
7
|
+
* matching CANONICAL_FONTS keys in the producer's deterministicFonts module.
|
|
8
|
+
*/
|
|
9
|
+
export declare const FONT_ALIAS_MAP: {
|
|
10
|
+
inter: string;
|
|
11
|
+
montserrat: string;
|
|
12
|
+
outfit: string;
|
|
13
|
+
nunito: string;
|
|
14
|
+
oswald: string;
|
|
15
|
+
"league gothic": string;
|
|
16
|
+
"archivo black": string;
|
|
17
|
+
"space mono": string;
|
|
18
|
+
"ibm plex mono": string;
|
|
19
|
+
"jetbrains mono": string;
|
|
20
|
+
"eb garamond": string;
|
|
21
|
+
"playfair display": string;
|
|
22
|
+
"source code pro": string;
|
|
23
|
+
"noto sans jp": string;
|
|
24
|
+
roboto: string;
|
|
25
|
+
"open sans": string;
|
|
26
|
+
lato: string;
|
|
27
|
+
poppins: string;
|
|
28
|
+
"helvetica neue": string;
|
|
29
|
+
helvetica: string;
|
|
30
|
+
arial: string;
|
|
31
|
+
"helvetica bold": string;
|
|
32
|
+
futura: string;
|
|
33
|
+
"din alternate": string;
|
|
34
|
+
"arial black": string;
|
|
35
|
+
"bebas neue": string;
|
|
36
|
+
"courier new": string;
|
|
37
|
+
courier: string;
|
|
38
|
+
garamond: string;
|
|
39
|
+
"noto sans japanese": string;
|
|
40
|
+
"segoe ui": string;
|
|
41
|
+
"sf pro": string;
|
|
42
|
+
"sf pro display": string;
|
|
43
|
+
"sf pro text": string;
|
|
44
|
+
"sf pro rounded": string;
|
|
45
|
+
avenir: string;
|
|
46
|
+
"avenir next": string;
|
|
47
|
+
"lucida grande": string;
|
|
48
|
+
geneva: string;
|
|
49
|
+
optima: string;
|
|
50
|
+
verdana: string;
|
|
51
|
+
tahoma: string;
|
|
52
|
+
"trebuchet ms": string;
|
|
53
|
+
calibri: string;
|
|
54
|
+
candara: string;
|
|
55
|
+
corbel: string;
|
|
56
|
+
"lucida sans": string;
|
|
57
|
+
"lucida sans unicode": string;
|
|
58
|
+
"noto sans": string;
|
|
59
|
+
"dejavu sans": string;
|
|
60
|
+
"liberation sans": string;
|
|
61
|
+
"sf mono": string;
|
|
62
|
+
menlo: string;
|
|
63
|
+
monaco: string;
|
|
64
|
+
consolas: string;
|
|
65
|
+
"lucida console": string;
|
|
66
|
+
"lucida sans typewriter": string;
|
|
67
|
+
"andale mono": string;
|
|
68
|
+
"dejavu sans mono": string;
|
|
69
|
+
"liberation mono": string;
|
|
70
|
+
georgia: string;
|
|
71
|
+
palatino: string;
|
|
72
|
+
"palatino linotype": string;
|
|
73
|
+
"book antiqua": string;
|
|
74
|
+
cambria: string;
|
|
75
|
+
times: string;
|
|
76
|
+
"times new roman": string;
|
|
77
|
+
"dejavu serif": string;
|
|
78
|
+
"liberation serif": string;
|
|
79
|
+
};
|
|
80
|
+
export declare const FONT_ALIAS_KEYS: ReadonlySet<string>;
|
|
81
|
+
/**
|
|
82
|
+
* Human-readable display names for canonical font slugs. Used by the lint
|
|
83
|
+
* rule to tell authors what their aliased font will render as.
|
|
84
|
+
*/
|
|
85
|
+
export declare const CANONICAL_FONT_DISPLAY_NAMES: Readonly<Record<string, string>>;
|
|
86
|
+
/**
|
|
87
|
+
* Resolve a font alias to its canonical display name, or undefined if the
|
|
88
|
+
* alias is not in the map.
|
|
89
|
+
*/
|
|
90
|
+
export declare function resolveAliasDisplayName(alias: string): string | undefined;
|
|
91
|
+
//# sourceMappingURL=aliases.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aliases.d.ts","sourceRoot":"","sources":["../../src/fonts/aliases.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmFiB,CAAC;AAE7C,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,MAAM,CAAwC,CAAC;AAEzF;;;GAGG;AACH,eAAO,MAAM,4BAA4B,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAmBzE,CAAC;AAEF;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAIzE"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single source of truth for the deterministic font alias map. Both the
|
|
3
|
+
* producer's @font-face injector and the core lint rules import from here,
|
|
4
|
+
* eliminating manual drift between the two.
|
|
5
|
+
*
|
|
6
|
+
* Keys are lowercase font family names. Values are canonical font slugs
|
|
7
|
+
* matching CANONICAL_FONTS keys in the producer's deterministicFonts module.
|
|
8
|
+
*/
|
|
9
|
+
export const FONT_ALIAS_MAP = {
|
|
10
|
+
// ── Canonical bundled fonts (self-referencing) ────────────────────────
|
|
11
|
+
inter: "inter",
|
|
12
|
+
montserrat: "montserrat",
|
|
13
|
+
outfit: "outfit",
|
|
14
|
+
nunito: "nunito",
|
|
15
|
+
oswald: "oswald",
|
|
16
|
+
"league gothic": "league-gothic",
|
|
17
|
+
"archivo black": "archivo-black",
|
|
18
|
+
"space mono": "space-mono",
|
|
19
|
+
"ibm plex mono": "ibm-plex-mono",
|
|
20
|
+
"jetbrains mono": "jetbrains-mono",
|
|
21
|
+
"eb garamond": "eb-garamond",
|
|
22
|
+
"playfair display": "playfair-display",
|
|
23
|
+
"source code pro": "source-code-pro",
|
|
24
|
+
"noto sans jp": "noto-sans-jp",
|
|
25
|
+
roboto: "roboto",
|
|
26
|
+
"open sans": "open-sans",
|
|
27
|
+
lato: "lato",
|
|
28
|
+
poppins: "poppins",
|
|
29
|
+
// ── Common aliases → nearest canonical ────────────────────────────────
|
|
30
|
+
"helvetica neue": "inter",
|
|
31
|
+
helvetica: "inter",
|
|
32
|
+
arial: "inter",
|
|
33
|
+
"helvetica bold": "inter",
|
|
34
|
+
futura: "montserrat",
|
|
35
|
+
"din alternate": "montserrat",
|
|
36
|
+
"arial black": "montserrat",
|
|
37
|
+
"bebas neue": "league-gothic",
|
|
38
|
+
"courier new": "jetbrains-mono",
|
|
39
|
+
courier: "jetbrains-mono",
|
|
40
|
+
garamond: "eb-garamond",
|
|
41
|
+
"noto sans japanese": "noto-sans-jp",
|
|
42
|
+
"segoe ui": "roboto",
|
|
43
|
+
// ── macOS sans-serif system fonts → inter ─────────────────────────────
|
|
44
|
+
"sf pro": "inter",
|
|
45
|
+
"sf pro display": "inter",
|
|
46
|
+
"sf pro text": "inter",
|
|
47
|
+
"sf pro rounded": "inter",
|
|
48
|
+
avenir: "inter",
|
|
49
|
+
"avenir next": "inter",
|
|
50
|
+
"lucida grande": "inter",
|
|
51
|
+
geneva: "inter",
|
|
52
|
+
optima: "inter",
|
|
53
|
+
// ── Windows sans-serif system fonts → inter ───────────────────────────
|
|
54
|
+
verdana: "inter",
|
|
55
|
+
tahoma: "inter",
|
|
56
|
+
"trebuchet ms": "inter",
|
|
57
|
+
calibri: "inter",
|
|
58
|
+
candara: "inter",
|
|
59
|
+
corbel: "inter",
|
|
60
|
+
"lucida sans": "inter",
|
|
61
|
+
"lucida sans unicode": "inter",
|
|
62
|
+
// ── Linux sans-serif system fonts → inter ─────────────────────────────
|
|
63
|
+
"noto sans": "inter",
|
|
64
|
+
"dejavu sans": "inter",
|
|
65
|
+
"liberation sans": "inter",
|
|
66
|
+
// ── Monospace system fonts → jetbrains-mono ───────────────────────────
|
|
67
|
+
"sf mono": "jetbrains-mono",
|
|
68
|
+
menlo: "jetbrains-mono",
|
|
69
|
+
monaco: "jetbrains-mono",
|
|
70
|
+
consolas: "jetbrains-mono",
|
|
71
|
+
"lucida console": "jetbrains-mono",
|
|
72
|
+
"lucida sans typewriter": "jetbrains-mono",
|
|
73
|
+
"andale mono": "jetbrains-mono",
|
|
74
|
+
"dejavu sans mono": "jetbrains-mono",
|
|
75
|
+
"liberation mono": "jetbrains-mono",
|
|
76
|
+
// ── Serif system fonts → eb-garamond ──────────────────────────────────
|
|
77
|
+
georgia: "eb-garamond",
|
|
78
|
+
palatino: "eb-garamond",
|
|
79
|
+
"palatino linotype": "eb-garamond",
|
|
80
|
+
"book antiqua": "eb-garamond",
|
|
81
|
+
cambria: "eb-garamond",
|
|
82
|
+
times: "eb-garamond",
|
|
83
|
+
"times new roman": "eb-garamond",
|
|
84
|
+
"dejavu serif": "eb-garamond",
|
|
85
|
+
"liberation serif": "eb-garamond",
|
|
86
|
+
};
|
|
87
|
+
export const FONT_ALIAS_KEYS = new Set(Object.keys(FONT_ALIAS_MAP));
|
|
88
|
+
/**
|
|
89
|
+
* Human-readable display names for canonical font slugs. Used by the lint
|
|
90
|
+
* rule to tell authors what their aliased font will render as.
|
|
91
|
+
*/
|
|
92
|
+
export const CANONICAL_FONT_DISPLAY_NAMES = {
|
|
93
|
+
inter: "Inter",
|
|
94
|
+
montserrat: "Montserrat",
|
|
95
|
+
outfit: "Outfit",
|
|
96
|
+
nunito: "Nunito",
|
|
97
|
+
oswald: "Oswald",
|
|
98
|
+
"league-gothic": "League Gothic",
|
|
99
|
+
"archivo-black": "Archivo Black",
|
|
100
|
+
"space-mono": "Space Mono",
|
|
101
|
+
"ibm-plex-mono": "IBM Plex Mono",
|
|
102
|
+
"jetbrains-mono": "JetBrains Mono",
|
|
103
|
+
"eb-garamond": "EB Garamond",
|
|
104
|
+
"playfair-display": "Playfair Display",
|
|
105
|
+
"source-code-pro": "Source Code Pro",
|
|
106
|
+
"noto-sans-jp": "Noto Sans JP",
|
|
107
|
+
roboto: "Roboto",
|
|
108
|
+
"open-sans": "Open Sans",
|
|
109
|
+
lato: "Lato",
|
|
110
|
+
poppins: "Poppins",
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Resolve a font alias to its canonical display name, or undefined if the
|
|
114
|
+
* alias is not in the map.
|
|
115
|
+
*/
|
|
116
|
+
export function resolveAliasDisplayName(alias) {
|
|
117
|
+
const slug = FONT_ALIAS_MAP[alias.toLowerCase()];
|
|
118
|
+
if (!slug)
|
|
119
|
+
return undefined;
|
|
120
|
+
return CANONICAL_FONT_DISPLAY_NAMES[slug];
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=aliases.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aliases.js","sourceRoot":"","sources":["../../src/fonts/aliases.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export declare const SYSTEM_FONT_SIZE_LIMIT: number;
|
|
2
|
+
export type FontFileFormat = "ttf" | "otf" | "woff2" | "woff" | "ttc";
|
|
3
|
+
export interface LocatedFont {
|
|
4
|
+
path: string;
|
|
5
|
+
format: FontFileFormat;
|
|
6
|
+
}
|
|
7
|
+
export declare const FONT_EXT_RE: RegExp;
|
|
8
|
+
export declare function toFamilyName(fileName: string): string | null;
|
|
9
|
+
export declare function fontDirectories(): string[];
|
|
10
|
+
export interface FontFileEntry {
|
|
11
|
+
path: string;
|
|
12
|
+
fileName: string;
|
|
13
|
+
family: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Iterates font files in a directory (up to `depth` 2) and yields each file's
|
|
17
|
+
* path, filename, and derived family name. Shared by the font listing route
|
|
18
|
+
* and the per-family locator to avoid duplicating the directory scan loop.
|
|
19
|
+
*/
|
|
20
|
+
export declare function collectFontFileEntries(dir: string, depth?: number): FontFileEntry[];
|
|
21
|
+
export declare function locateSystemFont(family: string): LocatedFont | null;
|
|
22
|
+
export interface LocatedFontVariant extends LocatedFont {
|
|
23
|
+
weight: string;
|
|
24
|
+
style: "normal" | "italic";
|
|
25
|
+
}
|
|
26
|
+
export declare function locateSystemFontVariants(family: string): LocatedFontVariant[];
|
|
27
|
+
export declare function clearSystemFontCache(): void;
|
|
28
|
+
//# sourceMappingURL=systemFontLocator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"systemFontLocator.d.ts","sourceRoot":"","sources":["../../src/fonts/systemFontLocator.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,sBAAsB,QAAkB,CAAC;AAEtD,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;AAEtE,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,eAAO,MAAM,WAAW,QAA6B,CAAC;AA4FtD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAe5D;AAQD,wBAAgB,eAAe,IAAI,MAAM,EAAE,CA2B1C;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,aAAa,EAAE,CAqB9E;AAkHD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAyBnE;AAED,MAAM,WAAW,kBAAmB,SAAQ,WAAW;IACrD,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,QAAQ,GAAG,QAAQ,CAAC;CAC5B;AAkCD,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,kBAAkB,EAAE,CA0B7E;AAWD,wBAAgB,oBAAoB,IAAI,IAAI,CAI3C"}
|
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
import { existsSync, lstatSync, readdirSync, realpathSync } from "node:fs";
|
|
3
|
+
import { homedir, platform } from "node:os";
|
|
4
|
+
import { join, resolve } from "node:path";
|
|
5
|
+
export const SYSTEM_FONT_SIZE_LIMIT = 5 * 1024 * 1024;
|
|
6
|
+
export const FONT_EXT_RE = /\.(otf|ttf|ttc|woff2?)$/i;
|
|
7
|
+
const FORMAT_PRIORITY = {
|
|
8
|
+
woff2: 0,
|
|
9
|
+
otf: 1,
|
|
10
|
+
ttf: 2,
|
|
11
|
+
woff: 3,
|
|
12
|
+
ttc: 4,
|
|
13
|
+
};
|
|
14
|
+
const STYLE_SUFFIXES = new Set([
|
|
15
|
+
"black",
|
|
16
|
+
"bold",
|
|
17
|
+
"book",
|
|
18
|
+
"condensed",
|
|
19
|
+
"demi",
|
|
20
|
+
"demibold",
|
|
21
|
+
"display",
|
|
22
|
+
"extra",
|
|
23
|
+
"extrabold",
|
|
24
|
+
"hairline",
|
|
25
|
+
"heavy",
|
|
26
|
+
"italic",
|
|
27
|
+
"light",
|
|
28
|
+
"medium",
|
|
29
|
+
"normal",
|
|
30
|
+
"regular",
|
|
31
|
+
"roman",
|
|
32
|
+
"semibold",
|
|
33
|
+
"thin",
|
|
34
|
+
"ultra",
|
|
35
|
+
"ultralight",
|
|
36
|
+
]);
|
|
37
|
+
const REGULAR_TOKENS = new Set(["regular", "roman", "normal", "book"]);
|
|
38
|
+
const cache = new Map();
|
|
39
|
+
let allowedDirsCache = null;
|
|
40
|
+
function getAllowedFontDirs() {
|
|
41
|
+
if (allowedDirsCache)
|
|
42
|
+
return allowedDirsCache;
|
|
43
|
+
allowedDirsCache = fontDirectories()
|
|
44
|
+
.filter((d) => existsSync(d))
|
|
45
|
+
.map((d) => {
|
|
46
|
+
try {
|
|
47
|
+
return realpathSync(d);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return resolve(d);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
return allowedDirsCache;
|
|
54
|
+
}
|
|
55
|
+
function isPathBounded(filePath) {
|
|
56
|
+
try {
|
|
57
|
+
const real = realpathSync(filePath);
|
|
58
|
+
const allowed = getAllowedFontDirs();
|
|
59
|
+
return allowed.some((dir) => real.startsWith(dir + "/") || real.startsWith(dir + "\\"));
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function isRegularFile(filePath) {
|
|
66
|
+
try {
|
|
67
|
+
const lst = lstatSync(filePath);
|
|
68
|
+
if (lst.isSymbolicLink())
|
|
69
|
+
return isPathBounded(filePath) && lstatSync(realpathSync(filePath)).isFile();
|
|
70
|
+
return lst.isFile();
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function normalizeName(name) {
|
|
77
|
+
return name
|
|
78
|
+
.trim()
|
|
79
|
+
.replace(/^['"]|['"]$/g, "")
|
|
80
|
+
.trim()
|
|
81
|
+
.toLowerCase();
|
|
82
|
+
}
|
|
83
|
+
function extensionToFormat(ext) {
|
|
84
|
+
const lower = ext.toLowerCase().replace(/^\./, "");
|
|
85
|
+
if (lower === "woff2")
|
|
86
|
+
return "woff2";
|
|
87
|
+
if (lower === "woff")
|
|
88
|
+
return "woff";
|
|
89
|
+
if (lower === "otf")
|
|
90
|
+
return "otf";
|
|
91
|
+
if (lower === "ttc")
|
|
92
|
+
return "ttc";
|
|
93
|
+
return "ttf";
|
|
94
|
+
}
|
|
95
|
+
export function toFamilyName(fileName) {
|
|
96
|
+
const withoutExt = fileName.replace(FONT_EXT_RE, "");
|
|
97
|
+
if (!withoutExt || withoutExt.startsWith("."))
|
|
98
|
+
return null;
|
|
99
|
+
const spaced = withoutExt
|
|
100
|
+
.replace(/[_-]+/g, " ")
|
|
101
|
+
.replace(/([a-z])([A-Z])/g, "$1 $2")
|
|
102
|
+
.replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2")
|
|
103
|
+
.replace(/\s+/g, " ")
|
|
104
|
+
.trim();
|
|
105
|
+
const words = spaced.split(" ").filter(Boolean);
|
|
106
|
+
while (words.length > 1 && STYLE_SUFFIXES.has((words.at(-1) ?? "").toLowerCase())) {
|
|
107
|
+
words.pop();
|
|
108
|
+
}
|
|
109
|
+
const family = words.join(" ").trim();
|
|
110
|
+
return family.length >= 2 ? family : null;
|
|
111
|
+
}
|
|
112
|
+
function isRegularWeight(fileName) {
|
|
113
|
+
const lower = fileName.toLowerCase();
|
|
114
|
+
if (REGULAR_TOKENS.has(lower.replace(FONT_EXT_RE, "").split(/[-_ ]/).pop() ?? ""))
|
|
115
|
+
return true;
|
|
116
|
+
return !lower.includes("bold") && !lower.includes("italic") && !lower.includes("light");
|
|
117
|
+
}
|
|
118
|
+
export function fontDirectories() {
|
|
119
|
+
const home = homedir();
|
|
120
|
+
if (platform() === "darwin") {
|
|
121
|
+
return [
|
|
122
|
+
join(home, "Library", "Fonts"),
|
|
123
|
+
"/Library/Fonts",
|
|
124
|
+
"/System/Library/Fonts",
|
|
125
|
+
"/System/Library/Fonts/Supplemental",
|
|
126
|
+
];
|
|
127
|
+
}
|
|
128
|
+
if (platform() === "win32") {
|
|
129
|
+
return [
|
|
130
|
+
join(process.env.WINDIR || "C:\\Windows", "Fonts"),
|
|
131
|
+
join(process.env.LOCALAPPDATA || join(homedir(), "AppData", "Local"), "Microsoft", "Windows", "Fonts"),
|
|
132
|
+
];
|
|
133
|
+
}
|
|
134
|
+
return [
|
|
135
|
+
join(home, ".fonts"),
|
|
136
|
+
join(home, ".local", "share", "fonts"),
|
|
137
|
+
"/usr/local/share/fonts",
|
|
138
|
+
"/usr/share/fonts",
|
|
139
|
+
];
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Iterates font files in a directory (up to `depth` 2) and yields each file's
|
|
143
|
+
* path, filename, and derived family name. Shared by the font listing route
|
|
144
|
+
* and the per-family locator to avoid duplicating the directory scan loop.
|
|
145
|
+
*/
|
|
146
|
+
export function collectFontFileEntries(dir, depth = 0) {
|
|
147
|
+
if (!existsSync(dir) || depth > 2)
|
|
148
|
+
return [];
|
|
149
|
+
const entries = [];
|
|
150
|
+
try {
|
|
151
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
152
|
+
const fullPath = join(dir, entry.name);
|
|
153
|
+
if (entry.isDirectory()) {
|
|
154
|
+
entries.push(...collectFontFileEntries(fullPath, depth + 1));
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
if (!FONT_EXT_RE.test(entry.name))
|
|
158
|
+
continue;
|
|
159
|
+
if (!isRegularFile(fullPath))
|
|
160
|
+
continue;
|
|
161
|
+
const family = toFamilyName(entry.name);
|
|
162
|
+
if (family)
|
|
163
|
+
entries.push({ path: fullPath, fileName: entry.name, family });
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
// Directory read failed — skip
|
|
168
|
+
}
|
|
169
|
+
return entries;
|
|
170
|
+
}
|
|
171
|
+
function collectCandidatesFromDir(dir, targetFamily, depth = 0) {
|
|
172
|
+
return collectFontFileEntries(dir, depth)
|
|
173
|
+
.filter((e) => normalizeName(e.family) === targetFamily)
|
|
174
|
+
.map((e) => {
|
|
175
|
+
const ext = e.fileName.match(FONT_EXT_RE)?.[1] ?? "ttf";
|
|
176
|
+
return {
|
|
177
|
+
path: e.path,
|
|
178
|
+
format: extensionToFormat(ext),
|
|
179
|
+
isRegular: isRegularWeight(e.fileName),
|
|
180
|
+
};
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
function pickBestCandidate(candidates) {
|
|
184
|
+
if (candidates.length === 0)
|
|
185
|
+
return null;
|
|
186
|
+
candidates.sort((a, b) => {
|
|
187
|
+
if (a.isRegular !== b.isRegular)
|
|
188
|
+
return a.isRegular ? -1 : 1;
|
|
189
|
+
return (FORMAT_PRIORITY[a.format] ?? 9) - (FORMAT_PRIORITY[b.format] ?? 9);
|
|
190
|
+
});
|
|
191
|
+
const best = candidates[0];
|
|
192
|
+
return { path: best.path, format: best.format };
|
|
193
|
+
}
|
|
194
|
+
let profilerCache = null;
|
|
195
|
+
// fallow-ignore-next-line complexity
|
|
196
|
+
function getSystemProfilerIndex() {
|
|
197
|
+
if (profilerCache)
|
|
198
|
+
return profilerCache;
|
|
199
|
+
profilerCache = new Map();
|
|
200
|
+
if (platform() !== "darwin")
|
|
201
|
+
return profilerCache;
|
|
202
|
+
try {
|
|
203
|
+
const raw = execFileSync("system_profiler", ["SPFontsDataType", "-json"], {
|
|
204
|
+
encoding: "utf8",
|
|
205
|
+
maxBuffer: 12 * 1024 * 1024,
|
|
206
|
+
timeout: 5000,
|
|
207
|
+
});
|
|
208
|
+
const parsed = JSON.parse(raw);
|
|
209
|
+
if (!parsed?.SPFontsDataType || !Array.isArray(parsed.SPFontsDataType))
|
|
210
|
+
return profilerCache;
|
|
211
|
+
for (const fontEntry of parsed.SPFontsDataType) {
|
|
212
|
+
if (!fontEntry?.typefaces || !Array.isArray(fontEntry.typefaces))
|
|
213
|
+
continue;
|
|
214
|
+
for (const typeface of fontEntry.typefaces) {
|
|
215
|
+
if (!typeface)
|
|
216
|
+
continue;
|
|
217
|
+
const family = typeface.family ?? typeface.fullname ?? typeface._name;
|
|
218
|
+
if (typeof family !== "string")
|
|
219
|
+
continue;
|
|
220
|
+
const filePath = typeface.path;
|
|
221
|
+
if (typeof filePath !== "string" || !FONT_EXT_RE.test(filePath))
|
|
222
|
+
continue;
|
|
223
|
+
const normalized = normalizeName(family);
|
|
224
|
+
const ext = filePath.match(FONT_EXT_RE)?.[1] ?? "ttf";
|
|
225
|
+
const entry = {
|
|
226
|
+
family: normalized,
|
|
227
|
+
path: filePath,
|
|
228
|
+
format: extensionToFormat(ext),
|
|
229
|
+
isRegular: isRegularWeight(filePath),
|
|
230
|
+
};
|
|
231
|
+
const list = profilerCache.get(normalized) ?? [];
|
|
232
|
+
list.push(entry);
|
|
233
|
+
profilerCache.set(normalized, list);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
catch {
|
|
238
|
+
// system_profiler unavailable
|
|
239
|
+
}
|
|
240
|
+
return profilerCache;
|
|
241
|
+
}
|
|
242
|
+
function locateViaSystemProfiler(targetFamily) {
|
|
243
|
+
const index = getSystemProfilerIndex();
|
|
244
|
+
const entries = index.get(targetFamily);
|
|
245
|
+
if (!entries || entries.length === 0)
|
|
246
|
+
return null;
|
|
247
|
+
const candidates = entries
|
|
248
|
+
.filter((e) => isRegularFile(e.path) && isPathBounded(e.path))
|
|
249
|
+
.map((e) => ({ path: e.path, format: e.format, isRegular: e.isRegular }));
|
|
250
|
+
return pickBestCandidate(candidates);
|
|
251
|
+
}
|
|
252
|
+
// fallow-ignore-next-line complexity
|
|
253
|
+
function locateViaFcMatch(targetFamily) {
|
|
254
|
+
if (platform() !== "linux")
|
|
255
|
+
return null;
|
|
256
|
+
try {
|
|
257
|
+
const result = execFileSync("fc-match", [targetFamily, "--format=%{file}"], {
|
|
258
|
+
encoding: "utf8",
|
|
259
|
+
timeout: 3000,
|
|
260
|
+
}).trim();
|
|
261
|
+
if (!result || !isRegularFile(result) || !isPathBounded(result))
|
|
262
|
+
return null;
|
|
263
|
+
const fileName = result.split("/").pop() ?? "";
|
|
264
|
+
const derivedFamily = toFamilyName(fileName);
|
|
265
|
+
if (!derivedFamily || normalizeName(derivedFamily) !== targetFamily)
|
|
266
|
+
return null;
|
|
267
|
+
const ext = fileName.match(FONT_EXT_RE)?.[1] ?? "ttf";
|
|
268
|
+
return { path: result, format: extensionToFormat(ext) };
|
|
269
|
+
}
|
|
270
|
+
catch {
|
|
271
|
+
return null;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
export function locateSystemFont(family) {
|
|
275
|
+
const normalized = normalizeName(family);
|
|
276
|
+
if (!normalized)
|
|
277
|
+
return null;
|
|
278
|
+
const cached = cache.get(normalized);
|
|
279
|
+
if (cached !== undefined)
|
|
280
|
+
return cached;
|
|
281
|
+
let result = null;
|
|
282
|
+
result = locateViaSystemProfiler(normalized);
|
|
283
|
+
if (!result) {
|
|
284
|
+
result = locateViaFcMatch(normalized);
|
|
285
|
+
}
|
|
286
|
+
if (!result) {
|
|
287
|
+
const allCandidates = [];
|
|
288
|
+
for (const dir of fontDirectories()) {
|
|
289
|
+
allCandidates.push(...collectCandidatesFromDir(dir, normalized));
|
|
290
|
+
}
|
|
291
|
+
result = pickBestCandidate(allCandidates);
|
|
292
|
+
}
|
|
293
|
+
cache.set(normalized, result);
|
|
294
|
+
return result;
|
|
295
|
+
}
|
|
296
|
+
const WEIGHT_TOKENS = {
|
|
297
|
+
thin: "100",
|
|
298
|
+
hairline: "100",
|
|
299
|
+
ultralight: "200",
|
|
300
|
+
extralight: "200",
|
|
301
|
+
light: "300",
|
|
302
|
+
regular: "400",
|
|
303
|
+
normal: "400",
|
|
304
|
+
book: "400",
|
|
305
|
+
roman: "400",
|
|
306
|
+
medium: "500",
|
|
307
|
+
demibold: "600",
|
|
308
|
+
semibold: "600",
|
|
309
|
+
bold: "700",
|
|
310
|
+
extrabold: "800",
|
|
311
|
+
ultrabold: "800",
|
|
312
|
+
heavy: "800",
|
|
313
|
+
black: "900",
|
|
314
|
+
ultrablack: "950",
|
|
315
|
+
};
|
|
316
|
+
const WEIGHT_TOKENS_SORTED = Object.entries(WEIGHT_TOKENS).sort(([a], [b]) => b.length - a.length);
|
|
317
|
+
function inferWeightAndStyle(fileName) {
|
|
318
|
+
const lower = fileName.toLowerCase().replace(FONT_EXT_RE, "");
|
|
319
|
+
const style = lower.includes("italic") || lower.includes("oblique") ? "italic" : "normal";
|
|
320
|
+
for (const [token, weight] of WEIGHT_TOKENS_SORTED) {
|
|
321
|
+
if (lower.includes(token))
|
|
322
|
+
return { weight, style };
|
|
323
|
+
}
|
|
324
|
+
return { weight: "400", style };
|
|
325
|
+
}
|
|
326
|
+
export function locateSystemFontVariants(family) {
|
|
327
|
+
const normalized = normalizeName(family);
|
|
328
|
+
if (!normalized)
|
|
329
|
+
return [];
|
|
330
|
+
const variants = [];
|
|
331
|
+
const profilerIndex = getSystemProfilerIndex();
|
|
332
|
+
const profilerEntries = profilerIndex.get(normalized);
|
|
333
|
+
if (profilerEntries && profilerEntries.length > 0) {
|
|
334
|
+
for (const e of profilerEntries) {
|
|
335
|
+
if (!isRegularFile(e.path) || !isPathBounded(e.path))
|
|
336
|
+
continue;
|
|
337
|
+
const { weight, style } = inferWeightAndStyle(e.path);
|
|
338
|
+
variants.push({ path: e.path, format: e.format, weight, style });
|
|
339
|
+
}
|
|
340
|
+
if (variants.length > 0)
|
|
341
|
+
return dedupeVariants(variants);
|
|
342
|
+
}
|
|
343
|
+
const allCandidates = [];
|
|
344
|
+
for (const dir of fontDirectories()) {
|
|
345
|
+
allCandidates.push(...collectCandidatesFromDir(dir, normalized));
|
|
346
|
+
}
|
|
347
|
+
for (const c of allCandidates) {
|
|
348
|
+
const { weight, style } = inferWeightAndStyle(c.path);
|
|
349
|
+
variants.push({ path: c.path, format: c.format, weight, style });
|
|
350
|
+
}
|
|
351
|
+
return dedupeVariants(variants);
|
|
352
|
+
}
|
|
353
|
+
function dedupeVariants(variants) {
|
|
354
|
+
const seen = new Map();
|
|
355
|
+
for (const v of variants) {
|
|
356
|
+
const key = `${v.weight}:${v.style}`;
|
|
357
|
+
if (!seen.has(key))
|
|
358
|
+
seen.set(key, v);
|
|
359
|
+
}
|
|
360
|
+
return Array.from(seen.values());
|
|
361
|
+
}
|
|
362
|
+
export function clearSystemFontCache() {
|
|
363
|
+
cache.clear();
|
|
364
|
+
profilerCache = null;
|
|
365
|
+
allowedDirsCache = null;
|
|
366
|
+
}
|
|
367
|
+
//# sourceMappingURL=systemFontLocator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"systemFontLocator.js","sourceRoot":"","sources":["../../src/fonts/systemFontLocator.ts"],"names":[],"mappings":"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"}
|