@driftime/sanity-plugin-font 0.0.0-stage → 0.1.1
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/README.md +492 -2
- package/dist/catalog-BVw1r_SG.js +183 -0
- package/dist/catalog-BVw1r_SG.js.map +1 -0
- package/dist/catalog-KAqAIjzw.js +96 -0
- package/dist/catalog-KAqAIjzw.js.map +1 -0
- package/dist/catalog.d.ts +29 -0
- package/dist/catalog.d.ts.map +1 -0
- package/dist/catalog.js +10 -0
- package/dist/catalog.js.map +1 -0
- package/dist/family-BAGnEjZg.js +36 -0
- package/dist/family-BAGnEjZg.js.map +1 -0
- package/dist/font-styles.d.ts +21 -0
- package/dist/font-styles.d.ts.map +1 -0
- package/dist/font-styles.js +43 -0
- package/dist/font-styles.js.map +1 -0
- package/dist/index.d.ts +76 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2364 -0
- package/dist/index.js.map +1 -0
- package/dist/names.d.ts +8 -0
- package/dist/names.d.ts.map +1 -0
- package/dist/names.js +0 -0
- package/dist/next-loader.d.ts +19 -0
- package/dist/next-loader.d.ts.map +1 -0
- package/dist/next-loader.js +28 -0
- package/dist/next-loader.js.map +1 -0
- package/dist/next.d.ts +42 -0
- package/dist/next.d.ts.map +1 -0
- package/dist/next.js +48 -0
- package/dist/next.js.map +1 -0
- package/dist/render.d.ts +12 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +183 -0
- package/dist/render.js.map +1 -0
- package/dist/resolve-Bkp0dEmr.d.ts +81 -0
- package/dist/resolve-Bkp0dEmr.d.ts.map +1 -0
- package/dist/types-DZl90ROd.d.ts +106 -0
- package/dist/types-DZl90ROd.d.ts.map +1 -0
- package/dist/types-DheP5tax.js +27 -0
- package/dist/types-DheP5tax.js.map +1 -0
- package/dist/utils-BV38iODp.js +29 -0
- package/dist/utils-BV38iODp.js.map +1 -0
- package/dist/vite.d.ts +61 -0
- package/dist/vite.d.ts.map +1 -0
- package/dist/vite.js +53 -0
- package/dist/vite.js.map +1 -0
- package/package.json +120 -4
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { n as isRecord, t as isDefined } from "./utils-BV38iODp.js";
|
|
2
|
+
import { c as logger, l as pluginName, n as parseWeights, t as parseCatalog } from "./catalog-KAqAIjzw.js";
|
|
3
|
+
import { randomUUID } from "node:crypto";
|
|
4
|
+
import { mkdir, readFile, rename, stat, writeFile } from "node:fs/promises";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { realpathSync } from "node:fs";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
/**
|
|
9
|
+
* Resolves symbolic links in a path, so a package linked into `node_modules` matches its real location.
|
|
10
|
+
*
|
|
11
|
+
* @param file - The path.
|
|
12
|
+
* @returns The real path, or the path unchanged when it doesn't exist.
|
|
13
|
+
*/
|
|
14
|
+
function resolveRealPath(file) {
|
|
15
|
+
try {
|
|
16
|
+
return realpathSync(file);
|
|
17
|
+
} catch {
|
|
18
|
+
return file;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Path of the placeholder catalog module the Studio imports, which the build step replaces. The build step's own code
|
|
23
|
+
* is published next to it, so the path is found from this file's location.
|
|
24
|
+
*/
|
|
25
|
+
const catalogModulePath = resolveRealPath(fileURLToPath(new URL("catalog.js", import.meta.url)));
|
|
26
|
+
/**
|
|
27
|
+
* Checks whether a module the bundler is loading is the placeholder catalog.
|
|
28
|
+
*
|
|
29
|
+
* @param id - The module's path, possibly followed by a query.
|
|
30
|
+
* @returns Whether it's the placeholder.
|
|
31
|
+
*/
|
|
32
|
+
function isCatalogModule(id) {
|
|
33
|
+
let [file] = id.split("?");
|
|
34
|
+
return isDefined(file) && resolveRealPath(file) === catalogModulePath;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Writes the module that replaces the placeholder catalog, which imports the catalog only when a picker opens.
|
|
38
|
+
*
|
|
39
|
+
* @param specifier - What the bundler imports the catalog from, or undefined when there's no catalog to import.
|
|
40
|
+
* @returns The module's code.
|
|
41
|
+
*/
|
|
42
|
+
function createCatalogModule(specifier) {
|
|
43
|
+
return isDefined(specifier) ? `export const fontCatalog = { ready: true, load: () => import(${JSON.stringify(specifier)}) };` : "export const fontCatalog = { ready: true };";
|
|
44
|
+
}
|
|
45
|
+
/** Types file the plugin reads family names from, published next to the placeholder catalog. */
|
|
46
|
+
const namesFile = path.join(path.dirname(catalogModulePath), "names.d.ts");
|
|
47
|
+
/**
|
|
48
|
+
* Writes the catalog's family names into the plugin's own types, so options that list families are checked against
|
|
49
|
+
* them. The file is replaced rather than edited, because pnpm shares a package's files between projects.
|
|
50
|
+
*
|
|
51
|
+
* @param families - Every family name in the catalog.
|
|
52
|
+
*/
|
|
53
|
+
async function writeFontNames(families) {
|
|
54
|
+
let union = [...new Set(families)].toSorted().map((name) => JSON.stringify(name)), content = [
|
|
55
|
+
`// Written by ${pluginName}'s build step from the Google Fonts catalog.`,
|
|
56
|
+
`export type SanityFontNames = ${isDefined(union) ? union.join(" | ") : "never"};`,
|
|
57
|
+
""
|
|
58
|
+
].join("\n");
|
|
59
|
+
if (await readFile(namesFile, "utf8").catch(() => "") === content) return;
|
|
60
|
+
let temporary = `${namesFile}.${process.pid}.tmp`;
|
|
61
|
+
await writeFile(temporary, content), await rename(temporary, namesFile);
|
|
62
|
+
}
|
|
63
|
+
/** Google Fonts' own list of families, which only Node can read because it sends no CORS header. */
|
|
64
|
+
const categories = {
|
|
65
|
+
"Sans Serif": "sans-serif",
|
|
66
|
+
Serif: "serif",
|
|
67
|
+
Display: "display",
|
|
68
|
+
Handwriting: "handwriting",
|
|
69
|
+
Monospace: "monospace"
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Converts one family from Google's list, keeping only what the picker filters and previews by.
|
|
73
|
+
*
|
|
74
|
+
* @param value - The family from Google's list.
|
|
75
|
+
* @returns The family and its rank in popularity, or undefined when it can't be read or has no weight a font field can
|
|
76
|
+
* load.
|
|
77
|
+
*/
|
|
78
|
+
function convertFamily(value) {
|
|
79
|
+
if (!isRecord(value)) return;
|
|
80
|
+
let { family, category, fonts, axes, subsets, trending, dateAdded, popularity } = value, mapped = typeof category == "string" ? categories[category] : void 0;
|
|
81
|
+
if (typeof family != "string" || !isDefined(mapped) || !isRecord(fonts) || !Array.isArray(subsets)) return;
|
|
82
|
+
let variants = Object.keys(fonts), weights = parseWeights(variants.filter((key) => !key.endsWith("i")).map(Number)), italics = parseWeights(variants.filter((key) => key.endsWith("i")).map((key) => Number(key.slice(0, -1))));
|
|
83
|
+
if (isDefined(weights) || isDefined(italics)) return {
|
|
84
|
+
converted: {
|
|
85
|
+
family,
|
|
86
|
+
category: mapped,
|
|
87
|
+
weights,
|
|
88
|
+
italics,
|
|
89
|
+
variable: Array.isArray(axes) && isDefined(axes),
|
|
90
|
+
subsets: subsets.filter((subset) => typeof subset == "string" && subset !== "menu"),
|
|
91
|
+
trending: typeof trending == "number" ? trending : 2 ** 53 - 1,
|
|
92
|
+
added: typeof dateAdded == "string" ? dateAdded : ""
|
|
93
|
+
},
|
|
94
|
+
popularity: typeof popularity == "number" ? popularity : Infinity
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Downloads Google's list of families and converts it.
|
|
99
|
+
*
|
|
100
|
+
* @returns Every family, most popular first, or undefined when Google couldn't be reached or the list couldn't be read.
|
|
101
|
+
*/
|
|
102
|
+
async function downloadCatalog() {
|
|
103
|
+
try {
|
|
104
|
+
let response = await fetch("https://fonts.google.com/metadata/fonts", { signal: AbortSignal.timeout(2e4) });
|
|
105
|
+
if (!response.ok) return;
|
|
106
|
+
let metadata = await response.json();
|
|
107
|
+
return !isRecord(metadata) || !Array.isArray(metadata.familyMetadataList) ? void 0 : metadata.familyMetadataList.flatMap((entry) => {
|
|
108
|
+
let family = convertFamily(entry);
|
|
109
|
+
return isDefined(family) ? [family] : [];
|
|
110
|
+
}).toSorted((first, second) => first.popularity - second.popularity).map(({ converted }) => converted);
|
|
111
|
+
} catch {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Reads the catalog an earlier build wrote.
|
|
117
|
+
*
|
|
118
|
+
* @param file - Path of the file.
|
|
119
|
+
* @returns The families and how long ago they were written, or undefined when there's no usable file.
|
|
120
|
+
*/
|
|
121
|
+
async function readCachedCatalog(file) {
|
|
122
|
+
try {
|
|
123
|
+
let [content, details] = await Promise.all([readFile(file, "utf8"), stat(file)]), families = parseCatalog(JSON.parse(content));
|
|
124
|
+
return isDefined(families) ? {
|
|
125
|
+
families,
|
|
126
|
+
written: details.mtime
|
|
127
|
+
} : void 0;
|
|
128
|
+
} catch {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Downloads the catalog unless a recent one is cached, and writes it where the bundler can import it. If Google can't
|
|
134
|
+
* be reached, the last download is used instead.
|
|
135
|
+
*
|
|
136
|
+
* @param root - The project folder.
|
|
137
|
+
* @returns The catalog, or undefined when there's neither a download nor an earlier one to use.
|
|
138
|
+
*/
|
|
139
|
+
async function writeCatalogOnce(root) {
|
|
140
|
+
let file = path.join(root, "node_modules", ".cache", "driftime-font", "catalog.json"), cached = await readCachedCatalog(file);
|
|
141
|
+
if (isDefined(cached) && Date.now() - cached.written.getTime() < 864e5) return {
|
|
142
|
+
file,
|
|
143
|
+
families: cached.families
|
|
144
|
+
};
|
|
145
|
+
let families = await downloadCatalog();
|
|
146
|
+
if (isDefined(families)) {
|
|
147
|
+
let temporary = `${file}.${randomUUID()}.tmp`;
|
|
148
|
+
return await mkdir(path.dirname(file), { recursive: !0 }), await writeFile(temporary, JSON.stringify(families)), await rename(temporary, file), logger.info(`Downloaded ${families.length.toLocaleString("en-US")} Google Fonts families.`), {
|
|
149
|
+
file,
|
|
150
|
+
families
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
if (isDefined(cached)) return logger.warn(`Couldn't reach Google Fonts, so the picker lists the families downloaded on ${cached.written.toLocaleDateString("en-US", { dateStyle: "long" })}.`), {
|
|
154
|
+
file,
|
|
155
|
+
families: cached.families
|
|
156
|
+
};
|
|
157
|
+
logger.error("Couldn't reach Google Fonts, and there's no earlier download to use. Restart once it can be reached.");
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Writes the catalog, then the family names the plugin's types check options against.
|
|
161
|
+
*
|
|
162
|
+
* @param root - The project folder.
|
|
163
|
+
* @returns The catalog, or undefined when there's neither a download nor an earlier one to use.
|
|
164
|
+
*/
|
|
165
|
+
async function prepareCatalog(root) {
|
|
166
|
+
let catalog = await writeCatalogOnce(root);
|
|
167
|
+
return isDefined(catalog) && await writeFontNames(catalog.families.map(({ family }) => family)), catalog;
|
|
168
|
+
}
|
|
169
|
+
/** Catalog writes in progress, keyed by project folder, so one process downloads the catalog once. */
|
|
170
|
+
const catalogWrites = /* @__PURE__ */ new Map();
|
|
171
|
+
/**
|
|
172
|
+
* Writes the catalog for a project, reusing a write already in progress.
|
|
173
|
+
*
|
|
174
|
+
* @param root - The project folder.
|
|
175
|
+
* @returns The catalog, or undefined when there's neither a download nor an earlier one to use.
|
|
176
|
+
*/
|
|
177
|
+
async function writeFontCatalog(root) {
|
|
178
|
+
let write = catalogWrites.get(root);
|
|
179
|
+
return isDefined(write) || (write = prepareCatalog(root), catalogWrites.set(root, write)), await write;
|
|
180
|
+
}
|
|
181
|
+
export { isCatalogModule as i, catalogModulePath as n, createCatalogModule as r, writeFontCatalog as t };
|
|
182
|
+
|
|
183
|
+
//# sourceMappingURL=catalog-BVw1r_SG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog-BVw1r_SG.js","names":["realpathSync","fileURLToPath","isDefined","resolveRealPath","file","catalogModulePath","URL","import","meta","url","isCatalogModule","id","split","createCatalogModule","specifier","JSON","stringify","readFile","rename","writeFile","path","isDefined","catalogModulePath","pluginName","namesFile","join","dirname","writeFontNames","families","union","Set","toSorted","map","name","JSON","stringify","content","current","catch","temporary","process","pid","randomUUID","mkdir","readFile","rename","stat","writeFile","path","isDefined","isRecord","writeFontNames","logger","CatalogFamily","parseCatalog","parseWeights","SanityFontCategory","WrittenCatalog","file","families","metadataUrl","cacheLifetime","categories","Record","Serif","Display","Handwriting","Monospace","convertFamily","value","undefined","family","category","fonts","axes","subsets","trending","dateAdded","popularity","mapped","Array","isArray","variants","Object","keys","weights","filter","key","endsWith","map","Number","italics","slice","converted","variable","subset","MAX_SAFE_INTEGER","added","POSITIVE_INFINITY","downloadCatalog","response","fetch","signal","AbortSignal","timeout","ok","metadata","json","flatMap","entry","toSorted","first","second","readCachedCatalog","content","details","Promise","all","JSON","parse","written","mtime","writeCatalogOnce","root","join","cached","Date","now","getTime","temporary","dirname","recursive","stringify","info","length","toLocaleString","warn","toLocaleDateString","dateStyle","error","prepareCatalog","catalog","catalogWrites","Map","writeFontCatalog","write","get","set","\"familyMetadataList\""],"sources":["../src/build/module.ts","../src/build/names.ts","../src/build/catalog.ts"],"sourcesContent":["import { realpathSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\n\nimport { isDefined } from \"@repo/lib/utils\";\n\n/**\n * Resolves symbolic links in a path, so a package linked into `node_modules` matches its real location.\n *\n * @param file - The path.\n * @returns The real path, or the path unchanged when it doesn't exist.\n */\nfunction resolveRealPath(file: string) {\n try {\n return realpathSync(file);\n } catch {\n return file;\n }\n}\n\n/**\n * Path of the placeholder catalog module the Studio imports, which the build step replaces. The build step's own code\n * is published next to it, so the path is found from this file's location.\n */\nexport const catalogModulePath = resolveRealPath(fileURLToPath(new URL(\"catalog.js\", import.meta.url)));\n\n/**\n * Checks whether a module the bundler is loading is the placeholder catalog.\n *\n * @param id - The module's path, possibly followed by a query.\n * @returns Whether it's the placeholder.\n */\nexport function isCatalogModule(id: string) {\n const [file] = id.split(\"?\");\n\n return isDefined(file) && resolveRealPath(file) === catalogModulePath;\n}\n\n/**\n * Writes the module that replaces the placeholder catalog, which imports the catalog only when a picker opens.\n *\n * @param specifier - What the bundler imports the catalog from, or undefined when there's no catalog to import.\n * @returns The module's code.\n */\nexport function createCatalogModule(specifier: string | undefined) {\n if (!isDefined(specifier)) return \"export const fontCatalog = { ready: true };\";\n\n return `export const fontCatalog = { ready: true, load: () => import(${JSON.stringify(specifier)}) };`;\n}\n","import { readFile, rename, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { isDefined } from \"@repo/lib/utils\";\n\nimport { catalogModulePath } from \"@/build/module\";\nimport { pluginName } from \"@/config/defaults\";\n\n/** Types file the plugin reads family names from, published next to the placeholder catalog. */\nconst namesFile = path.join(path.dirname(catalogModulePath), \"names.d.ts\");\n\n/**\n * Writes the catalog's family names into the plugin's own types, so options that list families are checked against\n * them. The file is replaced rather than edited, because pnpm shares a package's files between projects.\n *\n * @param families - Every family name in the catalog.\n */\nexport async function writeFontNames(families: string[]) {\n const union = [...new Set(families)].toSorted().map((name) => JSON.stringify(name));\n\n const content = [\n `// Written by ${pluginName}'s build step from the Google Fonts catalog.`,\n `export type SanityFontNames = ${isDefined(union) ? union.join(\" | \") : \"never\"};`,\n \"\",\n ].join(\"\\n\");\n\n const current = await readFile(namesFile, \"utf8\").catch(() => \"\");\n if (current === content) return;\n\n const temporary = `${namesFile}.${process.pid}.tmp`;\n await writeFile(temporary, content);\n await rename(temporary, namesFile);\n}\n","import { randomUUID } from \"node:crypto\";\nimport { mkdir, readFile, rename, stat, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { isDefined, isRecord } from \"@repo/lib/utils\";\n\nimport { writeFontNames } from \"@/build/names\";\nimport { logger } from \"@/config/defaults\";\nimport type { CatalogFamily } from \"@/lib/catalog\";\nimport { parseCatalog, parseWeights } from \"@/lib/catalog\";\nimport type { SanityFontCategory } from \"@/types\";\n\n/** A catalog the build step has written, and the file it's in. */\ninterface WrittenCatalog {\n /** Path of the file. */\n file: string;\n /** Every family in it, most popular first. */\n families: CatalogFamily[];\n}\n\n/** Google Fonts' own list of families, which only Node can read because it sends no CORS header. */\nconst metadataUrl = \"https://fonts.google.com/metadata/fonts\";\n\n/** How long a downloaded catalog is used before it's downloaded again, so restarting a dev server stays offline. */\nconst cacheLifetime = 24 * 60 * 60 * 1000;\n\n/** Kind of typeface each Google Fonts category maps to. */\nconst categories: Record<string, SanityFontCategory> = {\n \"Sans Serif\": \"sans-serif\",\n Serif: \"serif\",\n Display: \"display\",\n Handwriting: \"handwriting\",\n Monospace: \"monospace\",\n};\n\n/**\n * Converts one family from Google's list, keeping only what the picker filters and previews by.\n *\n * @param value - The family from Google's list.\n * @returns The family and its rank in popularity, or undefined when it can't be read or has no weight a font field can\n * load.\n */\nfunction convertFamily(value: unknown) {\n if (!isRecord(value)) return undefined;\n\n const { family, category, fonts, axes, subsets, trending, dateAdded, popularity } = value;\n const mapped = typeof category === \"string\" ? categories[category] : undefined;\n if (typeof family !== \"string\" || !isDefined(mapped) || !isRecord(fonts) || !Array.isArray(subsets)) {\n return undefined;\n }\n\n const variants = Object.keys(fonts);\n const weights = parseWeights(variants.filter((key) => !key.endsWith(\"i\")).map(Number));\n const italics = parseWeights(variants.filter((key) => key.endsWith(\"i\")).map((key) => Number(key.slice(0, -1))));\n if (!isDefined(weights) && !isDefined(italics)) return undefined;\n\n const converted: CatalogFamily = {\n family,\n category: mapped,\n weights,\n italics,\n variable: Array.isArray(axes) && isDefined(axes),\n // Google lists `menu` on every family, for the cut-down font its own site uses to draw family names.\n subsets: subsets.filter((subset: unknown): subset is string => typeof subset === \"string\" && subset !== \"menu\"),\n trending: typeof trending === \"number\" ? trending : Number.MAX_SAFE_INTEGER,\n added: typeof dateAdded === \"string\" ? dateAdded : \"\",\n };\n\n return { converted, popularity: typeof popularity === \"number\" ? popularity : Number.POSITIVE_INFINITY };\n}\n\n/**\n * Downloads Google's list of families and converts it.\n *\n * @returns Every family, most popular first, or undefined when Google couldn't be reached or the list couldn't be read.\n */\nasync function downloadCatalog() {\n try {\n const response = await fetch(metadataUrl, { signal: AbortSignal.timeout(20_000) });\n if (!response.ok) return undefined;\n\n const metadata: unknown = await response.json();\n if (!isRecord(metadata) || !Array.isArray(metadata[\"familyMetadataList\"])) return undefined;\n\n const families = metadata[\"familyMetadataList\"].flatMap((entry: unknown) => {\n const family = convertFamily(entry);\n\n return isDefined(family) ? [family] : [];\n });\n\n return families.toSorted((first, second) => first.popularity - second.popularity).map(({ converted }) => converted);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Reads the catalog an earlier build wrote.\n *\n * @param file - Path of the file.\n * @returns The families and how long ago they were written, or undefined when there's no usable file.\n */\nasync function readCachedCatalog(file: string) {\n try {\n const [content, details] = await Promise.all([readFile(file, \"utf8\"), stat(file)]);\n const families = parseCatalog(JSON.parse(content));\n\n return isDefined(families) ? { families, written: details.mtime } : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Downloads the catalog unless a recent one is cached, and writes it where the bundler can import it. If Google can't\n * be reached, the last download is used instead.\n *\n * @param root - The project folder.\n * @returns The catalog, or undefined when there's neither a download nor an earlier one to use.\n */\nasync function writeCatalogOnce(root: string): Promise<WrittenCatalog | undefined> {\n const file = path.join(root, \"node_modules\", \".cache\", \"driftime-font\", \"catalog.json\");\n const cached = await readCachedCatalog(file);\n\n if (isDefined(cached) && Date.now() - cached.written.getTime() < cacheLifetime) {\n return { file, families: cached.families };\n }\n\n const families = await downloadCatalog();\n\n if (isDefined(families)) {\n const temporary = `${file}.${randomUUID()}.tmp`;\n\n // The browser and server builds can write at once, so the catalog is swapped in whole.\n await mkdir(path.dirname(file), { recursive: true });\n await writeFile(temporary, JSON.stringify(families));\n await rename(temporary, file);\n logger.info(`Downloaded ${families.length.toLocaleString(\"en-US\")} Google Fonts families.`);\n\n return { file, families };\n }\n\n if (isDefined(cached)) {\n logger.warn(\n `Couldn't reach Google Fonts, so the picker lists the families downloaded on ${cached.written.toLocaleDateString(\"en-US\", { dateStyle: \"long\" })}.`,\n );\n\n return { file, families: cached.families };\n }\n\n logger.error(\"Couldn't reach Google Fonts, and there's no earlier download to use. Restart once it can be reached.\");\n\n return undefined;\n}\n\n/**\n * Writes the catalog, then the family names the plugin's types check options against.\n *\n * @param root - The project folder.\n * @returns The catalog, or undefined when there's neither a download nor an earlier one to use.\n */\nasync function prepareCatalog(root: string) {\n const catalog = await writeCatalogOnce(root);\n if (isDefined(catalog)) await writeFontNames(catalog.families.map(({ family }) => family));\n\n return catalog;\n}\n\n/** Catalog writes in progress, keyed by project folder, so one process downloads the catalog once. */\nconst catalogWrites = new Map<string, Promise<WrittenCatalog | undefined>>();\n\n/**\n * Writes the catalog for a project, reusing a write already in progress.\n *\n * @param root - The project folder.\n * @returns The catalog, or undefined when there's neither a download nor an earlier one to use.\n */\nexport async function writeFontCatalog(root: string) {\n let write = catalogWrites.get(root);\n\n if (!isDefined(write)) {\n write = prepareCatalog(root);\n catalogWrites.set(root, write);\n }\n\n const catalog = await write;\n\n return catalog;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { n as isRecord, t as isDefined } from "./utils-BV38iODp.js";
|
|
2
|
+
import { s as fontWeights, t as fontCategories } from "./types-DheP5tax.js";
|
|
3
|
+
/** Whether this is a development build, the only kind in which the plugin logs. */
|
|
4
|
+
const isDevelopment = process.env.NODE_ENV === "development", prefixStyle = "color: #2276fc";
|
|
5
|
+
/**
|
|
6
|
+
* Creates a logger that prefixes messages with the plugin's name and only logs in development builds.
|
|
7
|
+
* Browser consoles show the prefix in blue.
|
|
8
|
+
*
|
|
9
|
+
* @param name - The package name to prefix messages with.
|
|
10
|
+
* @returns Functions that log progress, a warning, or an error, or format a message to throw.
|
|
11
|
+
*/
|
|
12
|
+
function createLogger(name) {
|
|
13
|
+
let prefix = `[${name}]`;
|
|
14
|
+
/**
|
|
15
|
+
* Prefixes a message with the package name.
|
|
16
|
+
*
|
|
17
|
+
* @param message - The message.
|
|
18
|
+
* @returns The prefixed message.
|
|
19
|
+
*/
|
|
20
|
+
function format(message) {
|
|
21
|
+
return `${prefix} ${message}`;
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
/**
|
|
25
|
+
* Logs progress worth seeing, such as what a build step did, in development builds only.
|
|
26
|
+
*
|
|
27
|
+
* @param message - What happened.
|
|
28
|
+
*/
|
|
29
|
+
info(message) {
|
|
30
|
+
isDevelopment && console.info(`%c${prefix}%c ${message}`, prefixStyle, "");
|
|
31
|
+
},
|
|
32
|
+
/**
|
|
33
|
+
* Logs a warning about something the plugin recovered from, in development builds only.
|
|
34
|
+
*
|
|
35
|
+
* @param message - What happened and what to do about it.
|
|
36
|
+
*/
|
|
37
|
+
warn(message) {
|
|
38
|
+
isDevelopment && console.warn(`%c${prefix}%c ${message}`, prefixStyle, "");
|
|
39
|
+
},
|
|
40
|
+
/**
|
|
41
|
+
* Logs an error the plugin couldn't recover from, in development builds only.
|
|
42
|
+
*
|
|
43
|
+
* @param message - What went wrong and what to do about it.
|
|
44
|
+
*/
|
|
45
|
+
error(message) {
|
|
46
|
+
isDevelopment && console.error(`%c${prefix}%c ${message}`, prefixStyle, "");
|
|
47
|
+
},
|
|
48
|
+
format
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/** Package name, used as the prefix on every logged message. */
|
|
52
|
+
const pluginName = "@driftime/sanity-plugin-font", logger = createLogger(pluginName), apiVersion = "2026-01-01", defaultSources = ["google", "upload"], defaultWeights = [400, 600], defaultStyles = ["normal"], defaultSubsets = ["latin"];
|
|
53
|
+
/**
|
|
54
|
+
* Reads a list of weights, keeping only the ones a font can be loaded in.
|
|
55
|
+
*
|
|
56
|
+
* @param value - The value to read.
|
|
57
|
+
* @returns The weights.
|
|
58
|
+
*/
|
|
59
|
+
function parseWeights(value) {
|
|
60
|
+
return Array.isArray(value) ? fontWeights.filter((weight) => value.includes(weight)) : [];
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Reads one family of the catalog.
|
|
64
|
+
*
|
|
65
|
+
* @param value - The value to read.
|
|
66
|
+
* @returns The family, or undefined when the value isn't one.
|
|
67
|
+
*/
|
|
68
|
+
function parseCatalogFamily(value) {
|
|
69
|
+
if (!isRecord(value)) return;
|
|
70
|
+
let { family, category, weights, italics, variable, subsets, trending, added } = value, parsedCategory = fontCategories.find((member) => member === category);
|
|
71
|
+
if (typeof family == "string" && isDefined(parsedCategory) && Array.isArray(subsets) && typeof trending == "number" && typeof added == "string") return {
|
|
72
|
+
family,
|
|
73
|
+
category: parsedCategory,
|
|
74
|
+
weights: parseWeights(weights),
|
|
75
|
+
italics: parseWeights(italics),
|
|
76
|
+
variable: variable === !0,
|
|
77
|
+
subsets: subsets.filter((subset) => typeof subset == "string"),
|
|
78
|
+
trending,
|
|
79
|
+
added
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Reads the catalog, keeping only the families whose data is usable.
|
|
84
|
+
*
|
|
85
|
+
* @param value - The value to read.
|
|
86
|
+
* @returns The families, or undefined when the value isn't a catalog.
|
|
87
|
+
*/
|
|
88
|
+
function parseCatalog(value) {
|
|
89
|
+
if (Array.isArray(value)) return value.flatMap((entry) => {
|
|
90
|
+
let family = parseCatalogFamily(entry);
|
|
91
|
+
return isDefined(family) ? [family] : [];
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
export { defaultStyles as a, logger as c, defaultSources as i, pluginName as l, parseWeights as n, defaultSubsets as o, apiVersion as r, defaultWeights as s, parseCatalog as t };
|
|
95
|
+
|
|
96
|
+
//# sourceMappingURL=catalog-KAqAIjzw.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog-KAqAIjzw.js","names":["isDevelopment","process","env","isDevelopment","prefixStyle","createLogger","name","prefix","format","message","info","console","warn","error","createLogger","SanityFontSource","SanityFontStyle","SanityFontWeight","pluginName","logger","apiVersion","uploadConcurrency","uploadRetries","defaultSources","defaultWeights","defaultStyles","defaultSubsets","defaultPreviewText","isDefined","isRecord","SanityFontCategory","SanityFontWeight","fontCategories","fontWeights","CatalogFamily","family","category","weights","italics","variable","subsets","trending","added","FontCatalogLoader","Promise","default","FontCatalog","ready","load","parseWeights","value","Array","isArray","filter","weight","includes","parseCatalogFamily","undefined","parsedCategory","find","member","subset","parseCatalog","flatMap","entry","\"NODE_ENV\""],"sources":["../../@repo/lib/environment.ts","../../@repo/lib/logger.ts","../src/config/defaults.ts","../src/lib/catalog.ts"],"sourcesContent":["/** Whether this is a development build, the only kind in which the plugin logs. */\nexport const isDevelopment = process.env[\"NODE_ENV\"] === \"development\";\n","import { isDevelopment } from \"./environment\";\n\n/** Console style for the prefix, in the blue the Studio uses for its own messages. */\nconst prefixStyle = \"color: #2276fc\";\n\n/**\n * Creates a logger that prefixes messages with the plugin's name and only logs in development builds.\n * Browser consoles show the prefix in blue.\n *\n * @param name - The package name to prefix messages with.\n * @returns Functions that log progress, a warning, or an error, or format a message to throw.\n */\nexport function createLogger(name: string) {\n const prefix = `[${name}]`;\n\n /**\n * Prefixes a message with the package name.\n *\n * @param message - The message.\n * @returns The prefixed message.\n */\n function format(message: string) {\n return `${prefix} ${message}`;\n }\n\n return {\n /**\n * Logs progress worth seeing, such as what a build step did, in development builds only.\n *\n * @param message - What happened.\n */\n info(message: string) {\n if (isDevelopment) console.info(`%c${prefix}%c ${message}`, prefixStyle, \"\");\n },\n /**\n * Logs a warning about something the plugin recovered from, in development builds only.\n *\n * @param message - What happened and what to do about it.\n */\n warn(message: string) {\n if (isDevelopment) console.warn(`%c${prefix}%c ${message}`, prefixStyle, \"\");\n },\n /**\n * Logs an error the plugin couldn't recover from, in development builds only.\n *\n * @param message - What went wrong and what to do about it.\n */\n error(message: string) {\n if (isDevelopment) console.error(`%c${prefix}%c ${message}`, prefixStyle, \"\");\n },\n format,\n };\n}\n","import { createLogger } from \"@repo/lib/logger\";\n\nimport type { SanityFontSource, SanityFontStyle, SanityFontWeight } from \"@/types\";\n\n/** Package name, used as the prefix on every logged message. */\nexport const pluginName = \"@driftime/sanity-plugin-font\";\n\n/** The package's logger. */\nexport const logger = createLogger(pluginName);\n\n/** API version for the plugin's client. */\nexport const apiVersion = \"2026-01-01\";\n\n/** Files uploaded at once, so a large drop isn't refused by the API. */\nexport const uploadConcurrency = 3;\n\n/** Times a failed upload is tried again before it's reported. */\nexport const uploadRetries = 2;\n\n/** Sources a field offers when none are configured. */\nexport const defaultSources: SanityFontSource[] = [\"google\", \"upload\"];\n\n/** Weights a font must have when none are configured. */\nexport const defaultWeights: SanityFontWeight[] = [400, 600];\n\n/** Styles a font must have when none are configured. */\nexport const defaultStyles: SanityFontStyle[] = [\"normal\"];\n\n/** Character sets a Google font must cover when none are configured. */\nexport const defaultSubsets = [\"latin\"];\n\n/** Text shown in each weight and style of the chosen font when none is configured. */\nexport const defaultPreviewText = \"Aa\";\n","import { isDefined, isRecord } from \"@repo/lib/utils\";\n\nimport type { SanityFontCategory, SanityFontWeight } from \"@/types\";\nimport { fontCategories, fontWeights } from \"@/types\";\n\n/** One Google Fonts family, with what the picker filters, sorts, and previews by. */\nexport interface CatalogFamily {\n /** Name of the family. */\n family: string;\n /** Kind of typeface. */\n category: SanityFontCategory;\n /** Weights available in the normal style. */\n weights: SanityFontWeight[];\n /** Weights available in italic. */\n italics: SanityFontWeight[];\n /** Whether the family is a variable font. */\n variable: boolean;\n /** Character sets the family covers, such as `latin`. */\n subsets: string[];\n /** Google's ranking of how quickly the family is gaining use, where 1 is the fastest. */\n trending: number;\n /** Date Google added the family, as `YYYY-MM-DD`. */\n added: string;\n}\n\n/**\n * Loads the downloaded catalog, as a module whose default export is the list of families.\n *\n * @public\n */\nexport type FontCatalogLoader = () => Promise<{ default: unknown }>;\n\n/**\n * What the build step generates: whether it ran, and the loader for the catalog it downloaded.\n *\n * @public\n */\nexport interface FontCatalog {\n /** Whether the build step generated the catalog, rather than the placeholder being used. */\n ready: boolean;\n /** Loads the catalog, or undefined when the build step couldn't download one. */\n load?: FontCatalogLoader;\n}\n\n/**\n * Reads a list of weights, keeping only the ones a font can be loaded in.\n *\n * @param value - The value to read.\n * @returns The weights.\n */\nexport function parseWeights(value: unknown) {\n if (!Array.isArray(value)) return [];\n\n return fontWeights.filter((weight) => value.includes(weight));\n}\n\n/**\n * Reads one family of the catalog.\n *\n * @param value - The value to read.\n * @returns The family, or undefined when the value isn't one.\n */\nfunction parseCatalogFamily(value: unknown): CatalogFamily | undefined {\n if (!isRecord(value)) return undefined;\n\n const { family, category, weights, italics, variable, subsets, trending, added } = value;\n const parsedCategory = fontCategories.find((member) => member === category);\n\n if (\n typeof family !== \"string\" ||\n !isDefined(parsedCategory) ||\n !Array.isArray(subsets) ||\n typeof trending !== \"number\" ||\n typeof added !== \"string\"\n ) {\n return undefined;\n }\n\n return {\n family,\n category: parsedCategory,\n weights: parseWeights(weights),\n italics: parseWeights(italics),\n variable: variable === true,\n subsets: subsets.filter((subset: unknown) => typeof subset === \"string\"),\n trending,\n added,\n };\n}\n\n/**\n * Reads the catalog, keeping only the families whose data is usable.\n *\n * @param value - The value to read.\n * @returns The families, or undefined when the value isn't a catalog.\n */\nexport function parseCatalog(value: unknown) {\n if (!Array.isArray(value)) return undefined;\n\n return value.flatMap((entry: unknown) => {\n const family = parseCatalogFamily(entry);\n\n return isDefined(family) ? [family] : [];\n });\n}\n"],"mappings":";;;AACA,MAAaA,gBAAgBC,QAAQC,IAAI+D,aAAgB,eCEnD7D,cAAc;;;;;;;;AASpB,SAAgBC,aAAaC,MAAc;CACzC,IAAMC,SAAS,IAAID,KAAI;;;;;;;CAQvB,SAASE,OAAOC,SAAiB;EAC/B,OAAO,GAAGF,OAAM,GAAIE;CACtB;CAEA,OAAO;;;;;;EAMLC,KAAKD,SAAiB;GACpB,AAAIN,iBAAeQ,QAAQD,KAAK,KAAKH,OAAM,KAAME,WAAWL,aAAa,EAAE;EAC7E;;;;;;EAMAQ,KAAKH,SAAiB;GACpB,AAAIN,iBAAeQ,QAAQC,KAAK,KAAKL,OAAM,KAAME,WAAWL,aAAa,EAAE;EAC7E;;;;;;EAMAS,MAAMJ,SAAiB;GACrB,AAAIN,iBAAeQ,QAAQE,MAAM,KAAKN,OAAM,KAAME,WAAWL,aAAa,EAAE;EAC9E;EACAI;CACF;AACF;;AC/CA,MAAaU,aAAa,gCAGbC,SAASL,aAAaI,UAAU,GAGhCE,aAAa,cASbG,iBAAqC,CAAC,UAAU,QAAQ,GAGxDC,iBAAqC,CAAC,KAAK,GAAG,GAG9CC,gBAAmC,CAAC,QAAQ,GAG5CC,iBAAiB,CAAC,OAAO;;;;;;;ACqBtC,SAAgBuB,aAAaC,OAAgB;CAG3C,OAFKC,MAAMC,QAAQF,KAAK,IAEjBjB,YAAYoB,QAAQC,WAAWJ,MAAMK,SAASD,MAAM,CAAC,IAF1B,CAAA;AAGpC;;;;;;;AAQA,SAASE,mBAAmBN,OAA2C;CACrE,IAAI,CAACrB,SAASqB,KAAK,GAAG;CAEtB,IAAM,EAAEf,QAAQC,UAAUC,SAASC,SAASC,UAAUC,SAASC,UAAUC,UAAUQ,OAC7EQ,iBAAiB1B,eAAe2B,MAAMC,WAAWA,WAAWxB,QAAQ;CAE1E,IACE,OAAOD,UAAW,YACjBP,UAAU8B,cAAc,KACxBP,MAAMC,QAAQZ,OAAO,KACtB,OAAOC,YAAa,YACpB,OAAOC,SAAU,UAKnB,OAAO;EACLP;EACAC,UAAUsB;EACVrB,SAASY,aAAaZ,OAAO;EAC7BC,SAASW,aAAaX,OAAO;EAC7BC,UAAUA,aAAa;EACvBC,SAASA,QAAQa,QAAQQ,WAAoB,OAAOA,UAAW,QAAQ;EACvEpB;EACAC;CACF;AACF;;;;;;;AAQA,SAAgBoB,aAAaZ,OAAgB;CAC3C,IAAKC,MAAMC,QAAQF,KAAK,GAExB,OAAOA,MAAMa,SAASC,UAAmB;EACvC,IAAM7B,SAASqB,mBAAmBQ,KAAK;EAEvC,OAAOpC,UAAUO,MAAM,IAAI,CAACA,MAAM,IAAI,CAAA;CACxC,CAAC;AACH"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import "./types-DZl90ROd.js";
|
|
2
|
+
/**
|
|
3
|
+
* Loads the downloaded catalog, as a module whose default export is the list of families.
|
|
4
|
+
*
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
type FontCatalogLoader = () => Promise<{
|
|
8
|
+
default: unknown;
|
|
9
|
+
}>;
|
|
10
|
+
/**
|
|
11
|
+
* What the build step generates: whether it ran, and the loader for the catalog it downloaded.
|
|
12
|
+
*
|
|
13
|
+
* @public
|
|
14
|
+
*/
|
|
15
|
+
interface FontCatalog {
|
|
16
|
+
/** Whether the build step generated the catalog, rather than the placeholder being used. */
|
|
17
|
+
ready: boolean;
|
|
18
|
+
/** Loads the catalog, or undefined when the build step couldn't download one. */
|
|
19
|
+
load?: FontCatalogLoader;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Google Fonts catalog for the Studio. This is a placeholder: the build step replaces the module with the catalog it
|
|
23
|
+
* downloaded, so a Studio built without it has no Google fonts to offer.
|
|
24
|
+
*
|
|
25
|
+
* @public
|
|
26
|
+
*/
|
|
27
|
+
export declare const fontCatalog: FontCatalog;
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=catalog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.d.ts","names":["SanityFontCategory","SanityFontWeight","CatalogFamily","FontCatalogLoader","Promise","FontCatalog","parseWeights","parseCatalog","FontCatalog","fontCatalog"],"sources":["../src/lib/catalog.ts","../src/catalog.ts"],"mappings":";;;;;;KA8BYG,0BAA0BC;EAAU;;;;;;;UAO/BC;;EAEf;;EAEA,OAAOF;;;;;;;;qBCjCIM,aAAaD"}
|
package/dist/catalog.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Google Fonts catalog for the Studio. This is a placeholder: the build step replaces the module with the catalog it
|
|
3
|
+
* downloaded, so a Studio built without it has no Google fonts to offer.
|
|
4
|
+
*
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
const fontCatalog = { ready: !1 };
|
|
8
|
+
export { fontCatalog };
|
|
9
|
+
|
|
10
|
+
//# sourceMappingURL=catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.js","names":["FontCatalog","fontCatalog","ready"],"sources":["../src/catalog.ts"],"sourcesContent":["import type { FontCatalog } from \"@/lib/catalog\";\n\n/**\n * Google Fonts catalog for the Studio. This is a placeholder: the build step replaces the module with the catalog it\n * downloaded, so a Studio built without it has no Google fonts to offer.\n *\n * @public\n */\nexport const fontCatalog: FontCatalog = { ready: false };\n"],"mappings":";;;;;;AAQA,MAAaC,cAA2B,EAAEC,OAAO,GAAM"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { t as isDefined } from "./utils-BV38iODp.js";
|
|
2
|
+
import { stegaClean } from "@sanity/client/stega";
|
|
3
|
+
/**
|
|
4
|
+
* Builds the address of Google Fonts' stylesheet for a family, in every combination of the weights and styles given.
|
|
5
|
+
* The Studio's previews and the site both load fonts through it, so they always ask Google for the same thing.
|
|
6
|
+
*
|
|
7
|
+
* @param family - Name of the family.
|
|
8
|
+
* @param weights - Weights to load.
|
|
9
|
+
* @param styles - Styles to load.
|
|
10
|
+
* @param display - How the font is shown while it loads.
|
|
11
|
+
* @param text - Characters to load, or undefined for the whole font.
|
|
12
|
+
* @returns The stylesheet's address.
|
|
13
|
+
*/
|
|
14
|
+
function createStylesheetUrl(family, weights, styles, display = "swap", text) {
|
|
15
|
+
let name = encodeURIComponent(family).replaceAll("%20", "+"), sortedWeights = [...new Set(weights)].toSorted((first, second) => first - second), italic = styles.includes("italic"), normal = !italic || styles.includes("normal"), variants = italic ? `:ital,wght@${[...normal ? sortedWeights.map((weight) => `0,${weight}`) : [], ...sortedWeights.map((weight) => `1,${weight}`)].join(";")}` : `:wght@${sortedWeights.join(";")}`;
|
|
16
|
+
return `https://fonts.googleapis.com/css2?${[
|
|
17
|
+
`family=${name}${isDefined(sortedWeights) ? variants : ""}`,
|
|
18
|
+
`display=${display}`,
|
|
19
|
+
...isDefined(text) ? [`text=${encodeURIComponent(text)}`] : []
|
|
20
|
+
].join("&")}`;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Reads the name a font is used under: the family entered for it, or for an uploaded font left without one, the
|
|
24
|
+
* family its files name.
|
|
25
|
+
*
|
|
26
|
+
* @param value - The stored font.
|
|
27
|
+
* @returns The family name, cleaned, or undefined when neither gives one.
|
|
28
|
+
*/
|
|
29
|
+
function getFamilyName(value) {
|
|
30
|
+
let { source, family, files } = value ?? {}, entered = stegaClean(family)?.trim();
|
|
31
|
+
if (isDefined(entered)) return entered;
|
|
32
|
+
if (stegaClean(source) === "upload") return files?.map((file) => stegaClean(file.family)?.trim()).find((name) => isDefined(name));
|
|
33
|
+
}
|
|
34
|
+
export { createStylesheetUrl as n, getFamilyName as t };
|
|
35
|
+
|
|
36
|
+
//# sourceMappingURL=family-BAGnEjZg.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"family-BAGnEjZg.js","names":["isDefined","SanityFontDisplay","SanityFontStyle","SanityFontWeight","createStylesheetUrl","family","weights","styles","display","text","name","encodeURIComponent","replaceAll","sortedWeights","Set","toSorted","first","second","italic","includes","normal","variants","map","weight","join","parameters","isDefined","stegaClean","SanityFont","getFamilyName","value","Partial","source","family","files","entered","trim","undefined","map","file","find","name"],"sources":["../src/lib/google.ts","../src/lib/family.ts"],"sourcesContent":["import { isDefined } from \"@repo/lib/utils\";\n\nimport type { SanityFontDisplay, SanityFontStyle, SanityFontWeight } from \"@/types\";\n\n/**\n * Builds the address of Google Fonts' stylesheet for a family, in every combination of the weights and styles given.\n * The Studio's previews and the site both load fonts through it, so they always ask Google for the same thing.\n *\n * @param family - Name of the family.\n * @param weights - Weights to load.\n * @param styles - Styles to load.\n * @param display - How the font is shown while it loads.\n * @param text - Characters to load, or undefined for the whole font.\n * @returns The stylesheet's address.\n */\nexport function createStylesheetUrl(\n family: string,\n weights: SanityFontWeight[],\n styles: SanityFontStyle[],\n display: SanityFontDisplay = \"swap\",\n text?: string,\n) {\n const name = encodeURIComponent(family).replaceAll(\"%20\", \"+\");\n const sortedWeights = [...new Set(weights)].toSorted((first, second) => first - second);\n const italic = styles.includes(\"italic\");\n const normal = !italic || styles.includes(\"normal\");\n\n const variants = italic\n ? `:ital,wght@${[...(normal ? sortedWeights.map((weight) => `0,${weight}`) : []), ...sortedWeights.map((weight) => `1,${weight}`)].join(\";\")}`\n : `:wght@${sortedWeights.join(\";\")}`;\n\n const parameters = [\n `family=${name}${isDefined(sortedWeights) ? variants : \"\"}`,\n `display=${display}`,\n ...(isDefined(text) ? [`text=${encodeURIComponent(text)}`] : []),\n ];\n\n return `https://fonts.googleapis.com/css2?${parameters.join(\"&\")}`;\n}\n","import { isDefined } from \"@repo/lib/utils\";\nimport { stegaClean } from \"@sanity/client/stega\";\n\nimport type { SanityFont } from \"@/types\";\n\n/**\n * Reads the name a font is used under: the family entered for it, or for an uploaded font left without one, the\n * family its files name.\n *\n * @param value - The stored font.\n * @returns The family name, cleaned, or undefined when neither gives one.\n */\nexport function getFamilyName(value: Partial<SanityFont> | undefined) {\n const { source, family, files } = value ?? {};\n\n const entered = stegaClean(family)?.trim();\n if (isDefined(entered)) return entered;\n if (stegaClean(source) !== \"upload\") return undefined;\n\n return files?.map((file) => stegaClean(file.family)?.trim()).find((name) => isDefined(name));\n}\n"],"mappings":";;;;;;;;;;;;;AAeA,SAAgBI,oBACdC,QACAC,SACAC,QACAC,UAA6B,QAC7BC,MACA;CACA,IAAMC,OAAOC,mBAAmBN,MAAM,CAAC,CAACO,WAAW,OAAO,GAAG,GACvDC,gBAAgB,CAAC,GAAG,IAAIC,IAAIR,OAAO,CAAC,CAAC,CAACS,UAAUC,OAAOC,WAAWD,QAAQC,MAAM,GAChFC,SAASX,OAAOY,SAAS,QAAQ,GACjCC,SAAS,CAACF,UAAUX,OAAOY,SAAS,QAAQ,GAE5CE,WAAWH,SACb,cAAc,CAAC,GAAIE,SAASP,cAAcS,KAAKC,WAAW,KAAKA,QAAQ,IAAI,CAAA,GAAK,GAAGV,cAAcS,KAAKC,WAAW,KAAKA,QAAQ,CAAC,CAAC,CAACC,KAAK,GAAG,MACzI,SAASX,cAAcW,KAAK,GAAG;CAQnC,OAAO,qCAAqCC;EAL1C,UAAUf,OAAOV,UAAUa,aAAa,IAAIQ,WAAW;EACvD,WAAWb;EACX,GAAIR,UAAUS,IAAI,IAAI,CAAC,QAAQE,mBAAmBF,IAAI,GAAG,IAAI,CAAA;CAGnBgB,CAAU,CAACD,KAAK,GAAG;AACjE;;;;;;;;AC1BA,SAAgBK,cAAcC,OAAwC;CACpE,IAAM,EAAEE,QAAQC,QAAQC,UAAUJ,SAAS,CAAC,GAEtCK,UAAUR,WAAWM,MAAM,CAAC,EAAEG,KAAK;CACzC,IAAIV,UAAUS,OAAO,GAAG,OAAOA;CAC/B,IAAIR,WAAWK,MAAM,MAAM,UAE3B,OAAOE,OAAOI,KAAKC,SAASZ,WAAWY,KAAKN,MAAM,CAAC,EAAEG,KAAK,CAAC,CAAC,CAACI,MAAMC,SAASf,UAAUe,IAAI,CAAC;AAC7F"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { i as SanityResolvedFont } from "./resolve-Bkp0dEmr.js";
|
|
2
|
+
/**
|
|
3
|
+
* Props for adding resolved fonts to the page.
|
|
4
|
+
*
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
interface SanityFontStylesProps {
|
|
8
|
+
/** Resolved font, or fonts, to add. Fonts that are undefined, because nothing was chosen, are skipped. */
|
|
9
|
+
font: SanityResolvedFont | undefined | (SanityResolvedFont | undefined)[];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Adds the rules behind resolved fonts' classes to the page, with Google's stylesheet and hints that start their files
|
|
13
|
+
* downloading early. It can sit anywhere: React moves its links and styles into the document's head, and a font added
|
|
14
|
+
* more than once is only added once.
|
|
15
|
+
*
|
|
16
|
+
* @returns The links and styles.
|
|
17
|
+
* @public
|
|
18
|
+
*/
|
|
19
|
+
export declare function FontStyles({ font }: SanityFontStylesProps): import("react").JSX.Element;
|
|
20
|
+
export type { SanityFontStylesProps };
|
|
21
|
+
//# sourceMappingURL=font-styles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"font-styles.d.ts","names":["SanityResolvedFont","SanityFontStylesProps","FontStyles","font"],"sources":["../src/components/font-styles.tsx"],"mappings":";;;;;;UAaiBC;;EAEf,MAAMD,kCAAkCA;;;;;;;;;;wBAW1BE,aAAaC,QAAQF,wCAAqB,IAAA"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { t as isDefined } from "./utils-BV38iODp.js";
|
|
2
|
+
import { Fragment } from "react";
|
|
3
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
/**
|
|
5
|
+
* Adds the rules behind resolved fonts' classes to the page, with Google's stylesheet and hints that start their files
|
|
6
|
+
* downloading early. It can sit anywhere: React moves its links and styles into the document's head, and a font added
|
|
7
|
+
* more than once is only added once.
|
|
8
|
+
*
|
|
9
|
+
* @returns The links and styles.
|
|
10
|
+
* @public
|
|
11
|
+
*/
|
|
12
|
+
function FontStyles({ font }) {
|
|
13
|
+
let fonts = (Array.isArray(font) ? font : [font]).filter((entry) => isDefined(entry)), preconnect = new Map(fonts.flatMap(({ preconnect: origins }) => origins).map((origin) => [origin.href, origin])), preload = new Map(fonts.flatMap(({ preload: files }) => files).map((file) => [file.href, file]));
|
|
14
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
15
|
+
[...preconnect.values()].map(({ href, crossOrigin }) => /* @__PURE__ */ jsx("link", {
|
|
16
|
+
rel: "preconnect",
|
|
17
|
+
href,
|
|
18
|
+
crossOrigin: crossOrigin ? "" : void 0
|
|
19
|
+
}, href)),
|
|
20
|
+
[...preload.values()].map(({ href: href_0, type }) => /* @__PURE__ */ jsx("link", {
|
|
21
|
+
rel: "preload",
|
|
22
|
+
as: "font",
|
|
23
|
+
href: href_0,
|
|
24
|
+
type,
|
|
25
|
+
crossOrigin: ""
|
|
26
|
+
}, href_0)),
|
|
27
|
+
fonts.map(({ className, variable, stylesheet, css }) => {
|
|
28
|
+
let key = isDefined(variable) ? variable : className;
|
|
29
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [isDefined(stylesheet) && /* @__PURE__ */ jsx("link", {
|
|
30
|
+
rel: "stylesheet",
|
|
31
|
+
href: stylesheet,
|
|
32
|
+
precedence: "default"
|
|
33
|
+
}), /* @__PURE__ */ jsx("style", {
|
|
34
|
+
href: key,
|
|
35
|
+
precedence: "default",
|
|
36
|
+
children: css
|
|
37
|
+
})] }, key);
|
|
38
|
+
})
|
|
39
|
+
] });
|
|
40
|
+
}
|
|
41
|
+
export { FontStyles };
|
|
42
|
+
|
|
43
|
+
//# sourceMappingURL=font-styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"font-styles.js","names":["isDefined","Fragment","SanityResolvedFont","SanityFontStylesProps","font","FontStyles","fonts","Array","isArray","filter","entry","preconnect","Map","flatMap","origins","map","origin","href","preload","files","file","values","crossOrigin","undefined","type","className","variable","stylesheet","css","key"],"sources":["../src/components/font-styles.tsx"],"sourcesContent":["// Consumers render this in server components, where the compiler's memo cache hook can't run.\n\"use no memo\";\n\nimport { isDefined } from \"@repo/lib/utils\";\nimport { Fragment } from \"react\";\n\nimport type { SanityResolvedFont } from \"@/lib/resolve\";\n\n/**\n * Props for adding resolved fonts to the page.\n *\n * @public\n */\nexport interface SanityFontStylesProps {\n /** Resolved font, or fonts, to add. Fonts that are undefined, because nothing was chosen, are skipped. */\n font: SanityResolvedFont | undefined | (SanityResolvedFont | undefined)[];\n}\n\n/**\n * Adds the rules behind resolved fonts' classes to the page, with Google's stylesheet and hints that start their files\n * downloading early. It can sit anywhere: React moves its links and styles into the document's head, and a font added\n * more than once is only added once.\n *\n * @returns The links and styles.\n * @public\n */\nexport function FontStyles({ font }: SanityFontStylesProps) {\n const fonts = (Array.isArray(font) ? font : [font]).filter((entry) => isDefined(entry));\n const preconnect = new Map(\n fonts.flatMap(({ preconnect: origins }) => origins).map((origin) => [origin.href, origin]),\n );\n const preload = new Map(fonts.flatMap(({ preload: files }) => files).map((file) => [file.href, file]));\n\n return (\n <>\n {[...preconnect.values()].map(({ href, crossOrigin }) => (\n <link key={href} rel=\"preconnect\" href={href} crossOrigin={crossOrigin ? \"\" : undefined} />\n ))}\n {[...preload.values()].map(({ href, type }) => (\n <link key={href} rel=\"preload\" as=\"font\" href={href} type={type} crossOrigin=\"\" />\n ))}\n {fonts.map(({ className, variable, stylesheet, css }) => {\n const key = isDefined(variable) ? variable : className;\n\n return (\n <Fragment key={key}>\n {isDefined(stylesheet) && <link rel=\"stylesheet\" href={stylesheet} precedence=\"default\" />}\n <style href={key} precedence=\"default\">\n {css}\n </style>\n </Fragment>\n );\n })}\n </>\n );\n}\n"],"mappings":";;;;;;;;;;;AA0BA,SAAgBK,WAAW,EAAED,QAA+B;CAC1D,IAAME,SAASC,MAAMC,QAAQJ,IAAI,IAAIA,OAAO,CAACA,IAAI,EAAA,CAAGK,QAAQC,UAAUV,UAAUU,KAAK,CAAC,GAChFC,aAAa,IAAIC,IACrBN,MAAMO,SAAS,EAAEF,YAAYG,cAAcA,OAAO,CAAC,CAACC,KAAKC,WAAW,CAACA,OAAOC,MAAMD,MAAM,CAAC,CAC3F,GACME,UAAU,IAAIN,IAAIN,MAAMO,SAAS,EAAEK,SAASC,YAAYA,KAAK,CAAC,CAACJ,KAAKK,SAAS,CAACA,KAAKH,MAAMG,IAAI,CAAC,CAAC;CAErG,OACE,qBAAA,YAAA,EAAA,UAAA;EACG,CAAC,GAAGT,WAAWU,OAAO,CAAC,CAAC,CAACN,KAAK,EAAEE,MAAMK,kBACrC,oBAAC,QAAD;GAAiB,KAAI;GAAmBL;GAAM,aAAaK,cAAc,KAAKC,KAAAA;EAAU,GAA7EN,IAA6E,CACzF;EACA,CAAC,GAAGC,QAAQG,OAAO,CAAC,CAAC,CAACN,KAAK,EAAEE,MAAAA,QAAMO,WAClC,oBAAC,QAAD;GAAiB,KAAI;GAAU,IAAG;GAAO,MAAMP;GAAYO;GAAM,aAAY;EAAE,GAApEP,MAAoE,CAChF;EACAX,MAAMS,KAAK,EAAEU,WAAWC,UAAUC,YAAYC,UAAU;GACvD,IAAMC,MAAM7B,UAAU0B,QAAQ,IAAIA,WAAWD;GAE7C,OACE,qBAAC,UAAD,EAAA,UAAA,CACGzB,UAAU2B,UAAU,KAAK,oBAAC,QAAD;IAAM,KAAI;IAAa,MAAMA;IAAY,YAAW;GAAS,CAAA,GACvF,oBAAC,SAAD;IAAO,MAAME;IAAK,YAAW;IAC1BD,UAAAA;GACI,CAAA,CACC,EAAA,GALKC,GAKL;EAEd,CAAC;CACH,EAAA,CAAA;AAEJ"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { a as SanityFontFamily, c as SanityFontStyle, l as SanityFontWeight, n as SanityFontAsset, o as SanityFontFile, r as SanityFontCategory, s as SanityFontSource, t as SanityFont, u as fontTypeName } from "./types-DZl90ROd.js";
|
|
2
|
+
import { ObjectOptions, TypeAliasDefinition } from "sanity";
|
|
3
|
+
import { ComponentProps } from "react";
|
|
4
|
+
declare module "@sanity/types" {
|
|
5
|
+
interface IntrinsicDefinitions {
|
|
6
|
+
/** Definition of a field of type `font`. */
|
|
7
|
+
font: SanityFontDefinition;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Settings for the sample shown below the field once a font is chosen.
|
|
12
|
+
*
|
|
13
|
+
* @public
|
|
14
|
+
*/
|
|
15
|
+
interface SanityFontPreview {
|
|
16
|
+
/** Text shown in each weight and style of the chosen font. Defaults to "Aa". */
|
|
17
|
+
text?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* What a font field offers and what a font must have. The picker only lists Google fonts that have every weight,
|
|
21
|
+
* style, and character set, and validation lists any an upload is missing.
|
|
22
|
+
*
|
|
23
|
+
* @public
|
|
24
|
+
*/
|
|
25
|
+
interface SanityFontConfig {
|
|
26
|
+
/** Where fonts come from. Defaults to both Google Fonts and uploads. */
|
|
27
|
+
sources?: SanityFontSource[];
|
|
28
|
+
/** Kinds of typeface a font can be, such as `serif`. Defaults to every kind. */
|
|
29
|
+
categories?: SanityFontCategory[];
|
|
30
|
+
/** Google families the picker offers, in the order listed. Names the catalog doesn't have are skipped. Defaults to every family. */
|
|
31
|
+
families?: SanityFontFamily[];
|
|
32
|
+
/** Weights a font must have. Defaults to 400 and 600. */
|
|
33
|
+
weights?: SanityFontWeight[];
|
|
34
|
+
/** Styles a font must have in every weight. Defaults to normal only. */
|
|
35
|
+
styles?: SanityFontStyle[];
|
|
36
|
+
/** Character sets a Google font must cover, such as `latin-ext`. Defaults to `latin`. */
|
|
37
|
+
subsets?: string[];
|
|
38
|
+
/** Settings for the sample shown below the field. */
|
|
39
|
+
preview?: SanityFontPreview;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Options for a font field. Each list a field sets replaces the plugin's, and its preview text replaces the plugin's.
|
|
43
|
+
*
|
|
44
|
+
* @public
|
|
45
|
+
*/
|
|
46
|
+
interface SanityFontOptions extends ObjectOptions, SanityFontConfig {}
|
|
47
|
+
/**
|
|
48
|
+
* Definition of a field or array member holding a font, so its options are type-checked like a built-in type's.
|
|
49
|
+
*
|
|
50
|
+
* @public
|
|
51
|
+
*/
|
|
52
|
+
interface SanityFontDefinition extends Omit<TypeAliasDefinition<typeof fontTypeName, undefined>, "options"> {
|
|
53
|
+
/** Options for the field. */
|
|
54
|
+
options?: SanityFontOptions;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Adds a font field type to Sanity Studio, with a searchable picker for Google Fonts and uploads for anything else.
|
|
58
|
+
*
|
|
59
|
+
* @param config - The plugin configuration, which every field uses unless it sets its own.
|
|
60
|
+
* @returns The plugin.
|
|
61
|
+
* @public
|
|
62
|
+
*/
|
|
63
|
+
export declare function fontPlugin(config?: SanityFontConfig): import("sanity").PluginOptions;
|
|
64
|
+
type PreviewProps = Omit<ComponentProps<"span">, "children"> & {
|
|
65
|
+
value: Partial<SanityFont>;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Creates preview media for a stored font, so each document shows a sample in its own font instead of an icon.
|
|
69
|
+
*
|
|
70
|
+
* @param value - The stored font.
|
|
71
|
+
* @returns The media component, or undefined when neither a family nor a file was stored.
|
|
72
|
+
* @public
|
|
73
|
+
*/
|
|
74
|
+
export declare function createFontPreview(value: SanityFont | undefined): (() => import("react").FunctionComponentElement<PreviewProps>) | undefined;
|
|
75
|
+
export type { SanityFont, SanityFontAsset, SanityFontCategory, SanityFontConfig, SanityFontDefinition, SanityFontFamily, SanityFontFile, SanityFontOptions, SanityFontPreview, SanityFontSource, SanityFontStyle, SanityFontWeight };
|
|
76
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":["ObjectOptions","ObjectSchemaType","TypeAliasDefinition","SanityFontCategory","SanityFontFamily","SanityFontSource","SanityFontStyle","SanityFontWeight","fontTypeName","_0","SanityFontDefinition","sideEffect","SanityFontPreview","SanityFontConfig","SanityFontOptions","Omit","FontSchemaType","fontPlugin","ComponentProps","SanityFont","PreviewProps","Omit","Partial","Preview","value","style","_$__components_preview0","SanityFont","createFontPreview","PreviewProps","_$__components_preview0.PreviewProps"],"sources":["../src/plugin.ts","../src/components/preview.tsx","../src/lib/preview.ts"],"mappings":";;;;YAeY;;IAER,MAAMU;;;;;;;;UASOE;;EAEf;;;;;;;;UASeC;;EAEf,UAAUR;;EAEV,aAAaF;;EAEb,WAAWC;;EAEX,UAAUG;;EAEV,SAASD;;EAET;;EAEA,UAAUM;;;;;;;UAQKE,0BAA0Bd,eAAea;;;;;;UAOzCH,6BAA6BK,KAAKb,2BAA2BM;;EAE5E,UAAUM;;;;;;;;;wBAsBIG,WAAW,SAAQJ,oCAAqB;KCnF5CO,eAAeC,KAAKH;EAC9B,OAAOI,QAAQH;;;;;;;;;wBCMDS,kBAAkB,OAAOD,gDAAsB,yBAAtBD"}
|