@gusnips/vite 0.8.32 → 0.8.34

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 CHANGED
@@ -274,6 +274,40 @@ If the app merges fragments at runtime with a spread (`{ ...auth.en, ...nav.en }
274
274
  off and set `ownTopLevel: true`. A spread keeps only the second of two fragments that share a
275
275
  top-level key, so that is refused.
276
276
 
277
+ ## Check your contrast
278
+
279
+ ```ts
280
+ // scripts/check-contrast.ts
281
+ import { checkContrast, formatContrastReport } from "@gusnips/vite/contrast";
282
+
283
+ const report = await checkContrast([
284
+ { name: "web", entry: "src/index.css", sources: ["src/**/*.{ts,tsx}"] },
285
+ ]);
286
+
287
+ console.log(formatContrastReport(report));
288
+ process.exit(report.problems.some((p) => p.level === "error") ? 1 : 0);
289
+ ```
290
+
291
+ The tokens package measures the placeholder colours it ships. This measures yours: it compiles
292
+ your entry with the real Tailwind CLI and reads the CSS that comes back.
293
+
294
+ | It fails when | Because the reader gets |
295
+ | ------------------------------------------------------------------ | --------------------------------------------------------- |
296
+ | `--color-input` is under 3:1 on `--color-background`, either mode | a field border some people cannot see |
297
+ | `--color-foreground` is under 4.5:1 on the background, either mode | body copy some people cannot read |
298
+ | `--color-primary` is the same fill in both modes | a control that lands on the 3:1 line at night |
299
+ | a token has no value in `.dark` | one mode keeping the other mode's colour |
300
+ | a class paints from a colour your `@theme` never declares | `text-white` reading right at noon and vanishing at night |
301
+
302
+ A floor it cannot measure fails too: a value that is not a hex colour (or a `var()` chain to
303
+ one) is a floor nobody is keeping. State variants are held to the same token rule, and a
304
+ `hover:` that paints the same fill the base already has is a warning — the state changes
305
+ nothing. A class that compiles to no rule at all is a warning as well: a token Tailwind does
306
+ not have, or a class built dynamically that no scan can see.
307
+
308
+ Pass `allow: [/^bg-brand-/]` for the classes a repo means. Floors take no allow list: a
309
+ measured ratio is not a judgement call.
310
+
277
311
  ## The vite preset
278
312
 
279
313
  ```ts
@@ -0,0 +1,43 @@
1
+ export interface ContrastBundle {
2
+ /** Shown beside every problem: `"apps/web"`. */
3
+ name: string;
4
+ /** The CSS file holding the adopter's `@theme`, relative to `root`. */
5
+ entry: string;
6
+ /** Source holding class strings, as globs relative to `root`. Tests are skipped. */
7
+ sources: readonly string[];
8
+ /** Classes the untokened rule skips, e.g. `[/^bg-brand-/]` for a marketing page that means it. */
9
+ allow?: readonly RegExp[];
10
+ }
11
+ export interface CheckContrastOptions {
12
+ /** What `entry` and `sources` are relative to. Default: the working directory. */
13
+ root?: string;
14
+ }
15
+ export type ContrastRule = "load" | "floor" | "retune" | "rebind" | "untokened" | "hover" | "dead";
16
+ export interface ContrastProblem {
17
+ rule: ContrastRule;
18
+ /** A warning is shown and does not fail the gate. */
19
+ level: "error" | "warning";
20
+ bundle: string;
21
+ class?: string;
22
+ /** `file:line`, for a problem found in source. */
23
+ at?: string;
24
+ message: string;
25
+ }
26
+ export interface ContrastReport {
27
+ problems: ContrastProblem[];
28
+ }
29
+ /**
30
+ * Run the gate over every bundle. Returns what it found rather than printing or exiting, so a
31
+ * repo can add checks of its own to the same report and decide how CI fails:
32
+ *
33
+ * ```ts
34
+ * const report = await checkContrast([{ name: "apps/web", entry: "src/index.css", sources: ["src/**"] }]);
35
+ * console.log(formatContrastReport(report));
36
+ * process.exit(report.problems.some((p) => p.level === "error") ? 1 : 0);
37
+ * ```
38
+ */
39
+ export declare function checkContrast(bundles: readonly ContrastBundle[], options?: CheckContrastOptions): Promise<ContrastReport>;
40
+ /** The report as lines for a terminal: one per problem, grouped by bundle, and a last line that
41
+ * says whether the gate passed. */
42
+ export declare function formatContrastReport(report: ContrastReport): string;
43
+ //# sourceMappingURL=contrast.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contrast.d.ts","sourceRoot":"","sources":["../src/contrast.ts"],"names":[],"mappings":"AA0CA,MAAM,WAAW,cAAc;IAC7B,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAC;IACd,oFAAoF;IACpF,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,kGAAkG;IAClG,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,oBAAoB;IACnC,kFAAkF;IAClF,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC;AAEnG,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,YAAY,CAAC;IACnB,qDAAqD;IACrD,KAAK,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAyYD;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,SAAS,cAAc,EAAE,EAClC,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,cAAc,CAAC,CAIzB;AAED;oCACoC;AACpC,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAoBnE"}
@@ -0,0 +1,429 @@
1
+ /**
2
+ * The contrast gate: what a compiler cannot see in a theme and a set of class strings, checked
3
+ * where CI runs.
4
+ *
5
+ * Eight repos wrote this, in two halves that never met: one half measured token values (a
6
+ * control floor, `var()` chains), the other read class strings (untokened colours, the hover
7
+ * rung). Each half passed what the other would have caught, so this is the merge — one compile,
8
+ * both readings.
9
+ *
10
+ * The approach is the tokens package's compile check, extended to an adopter's values rather
11
+ * than duplicated beside it: write a fixture holding every class the sources use, run the real
12
+ * Tailwind CLI over the adopter's own entry, and read the CSS that comes back. The exit code
13
+ * proves nothing; the assertions below are the test. What cannot be imported is the reason:
14
+ * `tokens/` is a leaf with no JavaScript, so the few pure helpers this shares with its script
15
+ * (luminance, the rule lookup) are restated here, with their provenance, rather than reached
16
+ * for across the boundary.
17
+ *
18
+ * What this checks:
19
+ *
20
+ * - **floor**: `--color-input` clears 3:1 against `--color-background` in both modes (WCAG
21
+ * 1.4.11 — it is a control boundary), and `--color-foreground` clears 4.5:1. Three adopters
22
+ * failed the first, all under it, none visibly broken on screen.
23
+ * - **retune**: `--color-primary` carries its own dark value. Holding one brand colour across
24
+ * both modes lands the fill on the 3:1 line instead of clear of it.
25
+ * - **rebind**: when a `.dark` block exists, every token is rebound in it. The one that rots.
26
+ * - **untokened**: every colour a scanned class paints resolves to a token the adopter's own
27
+ * `@theme` declares. `text-white`, `bg-black/40`, `border-gray-300` all read a default-palette
28
+ * rung instead — correct in one mode and unreadable in the other.
29
+ * - **hover**: a state variant painting the same fill its base already has changes nothing.
30
+ * - **dead**: a class that compiles to no rule at all — a token Tailwind does not have, or a
31
+ * name the scanner caught half of. A warning: dynamic construction reads the same way.
32
+ *
33
+ * Runs on node and bun: `fs.promises.glob`, never Bun's `Glob`, and no `import.meta.dir`.
34
+ * Needs `@tailwindcss/cli` installed where it runs (an optional peer, reachable only from
35
+ * `@gusnips/vite/contrast`), because the fixture is compiled, not guessed.
36
+ */
37
+ import { spawnSync } from "node:child_process";
38
+ import { glob, mkdir, readFile, rm, writeFile } from "node:fs/promises";
39
+ import { createRequire } from "node:module";
40
+ import { dirname, join, resolve } from "node:path";
41
+ import { fileURLToPath } from "node:url";
42
+ // ── Colour ────────────────────────────────────────────────────────────────────
43
+ // Restated from the tokens compile check (`tokens/scripts/compile-check.ts`), which this gate
44
+ // extends: a leaf ships no JavaScript, so there is nothing to import.
45
+ function luminance(hex) {
46
+ const n = Number.parseInt(hex.slice(1), 16);
47
+ const channel = (c) => {
48
+ const v = c / 255;
49
+ return v <= 0.04045 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4;
50
+ };
51
+ return (0.2126 * channel((n >> 16) & 255) + 0.7152 * channel((n >> 8) & 255) + 0.0722 * channel(n & 255));
52
+ }
53
+ function contrast(a, b) {
54
+ const [x, y] = [luminance(a), luminance(b)];
55
+ const [hi, lo] = x > y ? [x, y] : [y, x];
56
+ return (hi + 0.05) / (lo + 0.05);
57
+ }
58
+ /** `#fff` → `#ffffff`. Anything else hex-shaped passes through; anything else is null. */
59
+ function normalizeHex(value) {
60
+ const hex = value.trim().toLowerCase();
61
+ if (/^#[0-9a-f]{6}$/.test(hex))
62
+ return hex;
63
+ const short = /^#([0-9a-f])([0-9a-f])([0-9a-f])$/.exec(hex);
64
+ return short === null
65
+ ? null
66
+ : `#${short[1]}${short[1]}${short[2]}${short[2]}${short[3]}${short[3]}`;
67
+ }
68
+ // ── Theme ─────────────────────────────────────────────────────────────────────
69
+ /** `--color-*` declarations out of every `@theme { … }` block. Values stay raw. */
70
+ function themeBlock(entry, at) {
71
+ const found = new Map();
72
+ for (const block of entry.matchAll(at)) {
73
+ for (const match of (block[1] ?? "").matchAll(/(--color-[\w-]+)\s*:\s*([^;]+);/g)) {
74
+ found.set(match[1] ?? "", (match[2] ?? "").trim());
75
+ }
76
+ }
77
+ return found;
78
+ }
79
+ /**
80
+ * Follow a `var()` chain to the literal it bottoms out at. Indirection is legitimate — a token
81
+ * may point at another — so only the terminal is measured, never the link. A cycle, a name the
82
+ * theme never declares, or a fallback that is itself unresolvable measures as nothing, which the
83
+ * floor reports rather than guesses.
84
+ */
85
+ function resolveChain(value, map, seen = new Set()) {
86
+ const ref = /^\s*var\(\s*(--[\w-]+)\s*(?:,\s*([\s\S]+?))?\s*\)\s*$/.exec(value);
87
+ if (ref === null)
88
+ return value;
89
+ const target = map.get(ref[1] ?? "");
90
+ if (target === undefined || seen.has(ref[1] ?? "")) {
91
+ return ref[2] === undefined ? null : resolveChain(ref[2], map, seen);
92
+ }
93
+ seen.add(ref[1] ?? "");
94
+ return resolveChain(target, map, seen);
95
+ }
96
+ function measured(value, map) {
97
+ const terminal = resolveChain(value, map);
98
+ return terminal === null ? null : normalizeHex(terminal);
99
+ }
100
+ // ── Sources ───────────────────────────────────────────────────────────────────
101
+ const ATTR = /\bclass(?:Name)?\s*=\s*(?:"([^"]*)"|'([^']*)'|`((?:[^`$]|\$(?!\{))*)`)/g;
102
+ const HELPER = /\b(?:cn|clsx|cva|twMerge|twJoin)\s*\(([^)]*)\)/g;
103
+ const STR = /"([^"]*)"|'([^']*)'/g;
104
+ const skipped = (file) => /(?:^|\/)__tests__\//.test(file) || /\.(test|spec)\.[tj]sx?$/.test(file);
105
+ /** Every class string the sources use, with the first `file:line` that uses it. */
106
+ async function scanSources(root, patterns) {
107
+ const found = new Map();
108
+ const files = new Set();
109
+ for (const pattern of patterns) {
110
+ for await (const file of glob(pattern, { cwd: root })) {
111
+ if (!skipped(file))
112
+ files.add(file);
113
+ }
114
+ }
115
+ const lineAt = (source, index) => {
116
+ let line = 1;
117
+ for (let i = 0; i < index; i++)
118
+ if (source.charCodeAt(i) === 10)
119
+ line++;
120
+ return line;
121
+ };
122
+ const keep = (raw, file, index, source) => {
123
+ for (const cls of raw.split(/\s+/).filter(Boolean)) {
124
+ // A token that would break the fixture's quoting is skipped rather than escaped:
125
+ // Tailwind reads the fixture as TEXT, so an entity would read as a different class.
126
+ if (/["&<>]/.test(cls))
127
+ continue;
128
+ const at = { file, line: lineAt(source, index) };
129
+ const seen = found.get(cls);
130
+ if (seen === undefined)
131
+ found.set(cls, [at]);
132
+ else if (!seen.some((entry) => entry.file === file))
133
+ seen.push(at);
134
+ }
135
+ };
136
+ for (const file of [...files].sort()) {
137
+ const source = await readFile(resolve(root, file), "utf8");
138
+ for (const match of source.matchAll(ATTR)) {
139
+ keep(match[1] ?? match[2] ?? match[3] ?? "", file, match.index, source);
140
+ }
141
+ for (const call of source.matchAll(HELPER)) {
142
+ for (const match of (call[1] ?? "").matchAll(STR)) {
143
+ keep(match[1] ?? match[2] ?? "", file, (call.index ?? 0) + (match.index ?? 0), source);
144
+ }
145
+ }
146
+ }
147
+ return found;
148
+ }
149
+ // ── Compile ───────────────────────────────────────────────────────────────────
150
+ // The tokens approach: a fixture holding every class, the real CLI over the adopter's own
151
+ // entry, and the CSS that comes back. The fixture is plain text, not HTML — Tailwind reads
152
+ // candidates out of the raw bytes, so no quoting can corrupt a class.
153
+ /**
154
+ * The body of the first rule whose selector uses `cls` as a whole class name.
155
+ * Follows the tokens compile check: `.text-card` must not match `.text-card-foreground`.
156
+ */
157
+ function ruleBody(css, cls) {
158
+ const selector = `.${cls.replace(/[^a-zA-Z0-9_-]/g, (c) => `\\${c}`)}`;
159
+ let from = 0;
160
+ for (;;) {
161
+ const at = css.indexOf(selector, from);
162
+ if (at === -1)
163
+ return null;
164
+ from = at + selector.length;
165
+ if (/^[-\w\\]/.test(css.slice(from)))
166
+ continue;
167
+ const open = css.indexOf("{", at);
168
+ if (open === -1)
169
+ return null;
170
+ let depth = 0;
171
+ for (let i = open; i < css.length; i++) {
172
+ if (css[i] === "{")
173
+ depth++;
174
+ else if (css[i] === "}" && --depth === 0)
175
+ return css.slice(open + 1, i);
176
+ }
177
+ return null;
178
+ }
179
+ }
180
+ async function compile(entryAbs, classes, workDir) {
181
+ // `createRequire` and not `import.meta.resolve`: this runs in whatever runtime the adopter's
182
+ // CI uses, and `require.resolve` holds everywhere. Never `import.meta.dir` — it is bun-only.
183
+ const cliPkg = createRequire(fileURLToPath(import.meta.url)).resolve("@tailwindcss/cli/package.json");
184
+ const cli = join(dirname(cliPkg), "dist", "index.mjs");
185
+ // The entry must live where `tailwindcss` resolves: beside the adopter's tree, which the
186
+ // workdir is. The adopter's own entry is imported by absolute path, so its `@source`
187
+ // directives — relative to the file it is reading — resolve the way its build resolves them.
188
+ await mkdir(workDir, { recursive: true });
189
+ await writeFile(join(workDir, "fixture.txt"), `${[...classes].sort().join("\n")}\n`);
190
+ await writeFile(join(workDir, "entry.css"), `@import "tailwindcss";\n@import "${entryAbs}";\n@source "./fixture.txt";\n`);
191
+ const out = join(workDir, "out.css");
192
+ const run = spawnSync(process.execPath, [cli, "-i", join(workDir, "entry.css"), "-o", out], {
193
+ cwd: workDir,
194
+ encoding: "utf-8",
195
+ // The compile takes seconds. The CLI has hung once with no output, and with no deadline
196
+ // that held a gate open for five minutes instead of failing it.
197
+ timeout: 120_000,
198
+ });
199
+ if (run.error !== undefined)
200
+ throw new Error(`tailwindcss did not finish: ${run.error.message}`);
201
+ if (run.status !== 0) {
202
+ // Left on disk on purpose: the compiled CSS is the first thing you want to read.
203
+ throw new Error(`tailwindcss failed to compile ${entryAbs}${run.stderr ? `: ${run.stderr.slice(0, 500)}` : ""} (workdir kept at ${workDir})`);
204
+ }
205
+ const css = await readFile(out, "utf-8");
206
+ await rm(workDir, { recursive: true, force: true });
207
+ return css;
208
+ }
209
+ // ── The check ─────────────────────────────────────────────────────────────────
210
+ const COLOR_PROPS = new Set([
211
+ "color",
212
+ "background-color",
213
+ "border-color",
214
+ "border-top-color",
215
+ "border-right-color",
216
+ "border-bottom-color",
217
+ "border-left-color",
218
+ "outline-color",
219
+ "text-decoration-color",
220
+ "fill",
221
+ "stroke",
222
+ ]);
223
+ const LITERAL_COLOR = /#[0-9a-fA-F]{3,8}\b|(?:rgb|hsl|oklch|oklab|lab|lch|color-mix|color)\s*\(/;
224
+ /** The first `file:line` that uses a class, for problems found in source. */
225
+ function firstAt(scanned, cls) {
226
+ const at = scanned.get(cls)?.[0];
227
+ return at === undefined ? undefined : `${at.file}:${String(at.line)}`;
228
+ }
229
+ /** `hover:bg-primary` → `bg-primary`. Every variant prefix comes off, not just the first. */
230
+ function stem(cls) {
231
+ return cls.replace(/^(?:[a-z][a-z0-9-]*:)+/, "");
232
+ }
233
+ function isStateVariant(cls) {
234
+ return /^(?:hover|focus|focus-visible|focus-within|active):/.test(cls);
235
+ }
236
+ async function checkBundle(bundle, options, report) {
237
+ const root = options.root ?? process.cwd();
238
+ const problem = (p) => {
239
+ report.problems.push({ bundle: bundle.name, level: "error", ...p });
240
+ };
241
+ const entryAbs = resolve(root, bundle.entry);
242
+ const entry = await readFile(entryAbs, "utf8").catch(() => null);
243
+ if (entry === null) {
244
+ // A theme that does not load reads as one with no tokens, which would pass every rule
245
+ // below. It fails here instead — the i18n gate's load rule, for the same reason.
246
+ problem({ rule: "load", message: `${bundle.entry} could not be read` });
247
+ return;
248
+ }
249
+ const light = themeBlock(entry, /@theme\s*\{([^}]*)\}/g);
250
+ const dark = themeBlock(entry, /\.dark\s*\{([^}]*)\}/g);
251
+ const semantic = new Set(light.keys());
252
+ // ── Floors, on the values that actually ship ──
253
+ const floors = [
254
+ ["--color-input", "--color-background", 3, "a field border (WCAG 1.4.11)"],
255
+ ["--color-foreground", "--color-background", 4.5, "body copy (WCAG 1.4.3)"],
256
+ ];
257
+ const modes = [["light", light]];
258
+ if (dark.size > 0)
259
+ modes.push(["dark", dark]);
260
+ for (const [mode, map] of modes) {
261
+ for (const [token, against, floor, why] of floors) {
262
+ const fg = map.has(token) ? measured(map.get(token) ?? "", map) : null;
263
+ const bg = map.has(against) ? measured(map.get(against) ?? "", map) : null;
264
+ if (fg === null || bg === null) {
265
+ problem({
266
+ rule: "floor",
267
+ message: `${mode}: cannot measure ${token} on ${against} — one of them is no longer a ` +
268
+ `hex colour. Keep the values hex, or teach this check the new notation; ` +
269
+ `do not let the floor go unmeasured.`,
270
+ });
271
+ continue;
272
+ }
273
+ const ratio = contrast(fg, bg);
274
+ if (ratio < floor) {
275
+ problem({
276
+ rule: "floor",
277
+ message: `${mode}: ${token} (${fg}) on ${against} (${bg}) is ${ratio.toFixed(2)}:1, ` +
278
+ `under the ${floor}:1 floor for ${why}`,
279
+ });
280
+ }
281
+ }
282
+ }
283
+ if (dark.size > 0) {
284
+ for (const name of light.keys()) {
285
+ if (!dark.has(name))
286
+ problem({
287
+ rule: "rebind",
288
+ message: `\`${name}\` is missing from the .dark block — one mode keeps the light value`,
289
+ });
290
+ }
291
+ // A fill chosen against a white page lands on the 3:1 line on a near-black card instead of
292
+ // clear of it. The day a brand colour truly works in both modes, this is the line that says
293
+ // the contract moved.
294
+ const day = measured(light.get("--color-primary") ?? "", light);
295
+ const night = measured(dark.get("--color-primary") ?? "", dark);
296
+ if (day !== null && night !== null && day === night) {
297
+ problem({
298
+ rule: "retune",
299
+ message: `--color-primary (${day}) is the same fill in both modes — lift it for dark, and ` +
300
+ `flip --color-primary-foreground with it`,
301
+ });
302
+ }
303
+ }
304
+ // ── Classes, against the compiled output ──
305
+ const scanned = await scanSources(root, bundle.sources);
306
+ const classes = [...scanned.keys()];
307
+ let css;
308
+ try {
309
+ css = await compile(entryAbs, classes, join(root, ".contrast-check"));
310
+ }
311
+ catch (error) {
312
+ problem({
313
+ rule: "load",
314
+ message: error instanceof Error ? error.message : String(error),
315
+ });
316
+ return;
317
+ }
318
+ const allowed = (cls) => (bundle.allow ?? []).some((re) => re.test(cls));
319
+ const byStem = new Map();
320
+ for (const cls of classes) {
321
+ const set = byStem.get(stem(cls)) ?? new Set();
322
+ set.add(cls);
323
+ byStem.set(stem(cls), set);
324
+ }
325
+ for (const cls of classes.sort()) {
326
+ const body = ruleBody(css, cls);
327
+ if (body === null) {
328
+ problem({
329
+ rule: "dead",
330
+ level: "warning",
331
+ class: cls,
332
+ at: firstAt(scanned, cls),
333
+ message: "compiled to no rule — a token Tailwind does not have, or a class built dynamically",
334
+ });
335
+ continue;
336
+ }
337
+ if (allowed(cls))
338
+ continue;
339
+ for (const declaration of body.split(";")) {
340
+ const colon = declaration.indexOf(":");
341
+ if (colon === -1)
342
+ continue;
343
+ const prop = declaration.slice(0, colon).trim();
344
+ if (!COLOR_PROPS.has(prop))
345
+ continue;
346
+ const value = declaration.slice(colon + 1);
347
+ const tokens = [...value.matchAll(/var\(\s*(--color-[\w-]+)/g)].map((m) => m[1] ?? "");
348
+ if (tokens.length === 0) {
349
+ if (!LITERAL_COLOR.test(value))
350
+ continue;
351
+ for (const { file, line } of scanned.get(cls) ?? []) {
352
+ problem({
353
+ rule: "untokened",
354
+ class: cls,
355
+ at: `${file}:${String(line)}`,
356
+ message: `paints ${prop} with a literal colour — point it at a theme token instead`,
357
+ });
358
+ }
359
+ continue;
360
+ }
361
+ for (const token of tokens) {
362
+ if (semantic.has(token))
363
+ continue;
364
+ for (const { file, line } of scanned.get(cls) ?? []) {
365
+ problem({
366
+ rule: "untokened",
367
+ class: cls,
368
+ at: `${file}:${String(line)}`,
369
+ message: `paints ${prop} from \`${token}\`, which the theme never declares — ` +
370
+ `a default-palette rung that reads right in one mode and vanishes in the other`,
371
+ });
372
+ }
373
+ }
374
+ }
375
+ }
376
+ // ── The hover rung ──
377
+ for (const [base, variants] of byStem) {
378
+ if (!variants.has(base))
379
+ continue;
380
+ for (const variant of [...variants].sort()) {
381
+ if (variant === base || !isStateVariant(variant) || stem(variant) !== base)
382
+ continue;
383
+ problem({
384
+ rule: "hover",
385
+ level: "warning",
386
+ class: variant,
387
+ at: firstAt(scanned, variant),
388
+ message: `paints the same ${base} the base state already has — the state changes nothing. ` +
389
+ `If these are on different elements, ignore this.`,
390
+ });
391
+ }
392
+ }
393
+ }
394
+ /**
395
+ * Run the gate over every bundle. Returns what it found rather than printing or exiting, so a
396
+ * repo can add checks of its own to the same report and decide how CI fails:
397
+ *
398
+ * ```ts
399
+ * const report = await checkContrast([{ name: "apps/web", entry: "src/index.css", sources: ["src/**"] }]);
400
+ * console.log(formatContrastReport(report));
401
+ * process.exit(report.problems.some((p) => p.level === "error") ? 1 : 0);
402
+ * ```
403
+ */
404
+ export async function checkContrast(bundles, options = {}) {
405
+ const report = { problems: [] };
406
+ for (const bundle of bundles)
407
+ await checkBundle(bundle, options, report);
408
+ return report;
409
+ }
410
+ /** The report as lines for a terminal: one per problem, grouped by bundle, and a last line that
411
+ * says whether the gate passed. */
412
+ export function formatContrastReport(report) {
413
+ const lines = [];
414
+ const bundles = [...new Set(report.problems.map((p) => p.bundle))];
415
+ for (const bundle of bundles) {
416
+ lines.push(bundle);
417
+ for (const p of report.problems.filter((q) => q.bundle === bundle)) {
418
+ const where = [p.class, p.at].filter((part) => part !== undefined).join(" ");
419
+ lines.push(` ${p.level === "error" ? "✖" : "⚠"} ${p.rule}: ${where}${where === "" ? "" : " "}${p.message}`);
420
+ }
421
+ }
422
+ const errors = report.problems.filter((p) => p.level === "error").length;
423
+ const warnings = report.problems.length - errors;
424
+ lines.push(errors === 0
425
+ ? `✔ contrast: no errors${warnings > 0 ? `, ${warnings} warning(s)` : ""}`
426
+ : `✖ contrast: ${errors} error(s)${warnings > 0 ? `, ${warnings} warning(s)` : ""}`);
427
+ return lines.join("\n");
428
+ }
429
+ //# sourceMappingURL=contrast.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contrast.js","sourceRoot":"","sources":["../src/contrast.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAmCzC,iFAAiF;AACjF,8FAA8F;AAC9F,sEAAsE;AAEtE,SAAS,SAAS,CAAC,GAAW;IAC5B,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAG,CAAC,CAAS,EAAU,EAAE;QACpC,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;QAClB,OAAO,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,GAAG,CAAC;IACjE,CAAC,CAAC;IACF,OAAO,CACL,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,GAAG,CAAC,CACjG,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,CAAS,EAAE,CAAS;IACpC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5C,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACzC,OAAO,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;AACnC,CAAC;AAED,0FAA0F;AAC1F,SAAS,YAAY,CAAC,KAAa;IACjC,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACvC,IAAI,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC;IAC3C,MAAM,KAAK,GAAG,mCAAmC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5D,OAAO,KAAK,KAAK,IAAI;QACnB,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAC5E,CAAC;AAED,iFAAiF;AAEjF,mFAAmF;AACnF,SAAS,UAAU,CAAC,KAAa,EAAE,EAAU;IAC3C,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IACxC,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;QACvC,KAAK,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,kCAAkC,CAAC,EAAE,CAAC;YAClF,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,SAAS,YAAY,CACnB,KAAa,EACb,GAAwB,EACxB,OAAoB,IAAI,GAAG,EAAE;IAE7B,MAAM,GAAG,GAAG,uDAAuD,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChF,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC/B,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACrC,IAAI,MAAM,KAAK,SAAS,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;QACnD,OAAO,GAAG,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IACvE,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACvB,OAAO,YAAY,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;AACzC,CAAC;AAED,SAAS,QAAQ,CAAC,KAAa,EAAE,GAAwB;IACvD,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC1C,OAAO,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;AAC3D,CAAC;AAED,iFAAiF;AAEjF,MAAM,IAAI,GAAG,yEAAyE,CAAC;AACvF,MAAM,MAAM,GAAG,iDAAiD,CAAC;AACjE,MAAM,GAAG,GAAG,sBAAsB,CAAC;AAEnC,MAAM,OAAO,GAAG,CAAC,IAAY,EAAW,EAAE,CACxC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAE3E,mFAAmF;AACnF,KAAK,UAAU,WAAW,CACxB,IAAY,EACZ,QAA2B;IAE3B,MAAM,KAAK,GAAG,IAAI,GAAG,EAA4C,CAAC;IAClE,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;YACtD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;gBAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAG,CAAC,MAAc,EAAE,KAAa,EAAU,EAAE;QACvD,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE;YAAE,IAAI,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,EAAE;gBAAE,IAAI,EAAE,CAAC;QACxE,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IACF,MAAM,IAAI,GAAG,CAAC,GAAW,EAAE,IAAY,EAAE,KAAa,EAAE,MAAc,EAAQ,EAAE;QAC9E,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YACnD,iFAAiF;YACjF,oFAAoF;YACpF,IAAI,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC;gBAAE,SAAS;YACjC,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC;YACjD,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC5B,IAAI,IAAI,KAAK,SAAS;gBAAE,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;iBACxC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC;gBAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrE,CAAC;IACH,CAAC,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;QAC3D,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1C,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC1E,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3C,KAAK,MAAM,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAClD,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;YACzF,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,iFAAiF;AACjF,0FAA0F;AAC1F,2FAA2F;AAC3F,sEAAsE;AAEtE;;;GAGG;AACH,SAAS,QAAQ,CAAC,GAAW,EAAE,GAAW;IACxC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;IACvE,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,SAAS,CAAC;QACR,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACvC,IAAI,EAAE,KAAK,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QAC3B,IAAI,GAAG,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC;QAC5B,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAAE,SAAS;QAC/C,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAClC,IAAI,IAAI,KAAK,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QAC7B,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACvC,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG;gBAAE,KAAK,EAAE,CAAC;iBACvB,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,EAAE,KAAK,KAAK,CAAC;gBAAE,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAC1E,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,KAAK,UAAU,OAAO,CAAC,QAAgB,EAAE,OAAiB,EAAE,OAAe;IACzE,6FAA6F;IAC7F,6FAA6F;IAC7F,MAAM,MAAM,GAAG,aAAa,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAClE,+BAA+B,CAChC,CAAC;IACF,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;IAEvD,yFAAyF;IACzF,qFAAqF;IACrF,6FAA6F;IAC7F,MAAM,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1C,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrF,MAAM,SAAS,CACb,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,EAC1B,oCAAoC,QAAQ,gCAAgC,CAC7E,CAAC;IAEF,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IACrC,MAAM,GAAG,GAAG,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,EAAE;QAC1F,GAAG,EAAE,OAAO;QACZ,QAAQ,EAAE,OAAO;QACjB,wFAAwF;QACxF,gEAAgE;QAChE,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IACH,IAAI,GAAG,CAAC,KAAK,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACjG,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrB,iFAAiF;QACjF,MAAM,IAAI,KAAK,CACb,iCAAiC,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,qBAAqB,OAAO,GAAG,CAC7H,CAAC;IACJ,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACzC,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,iFAAiF;AAEjF,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC;IAC1B,OAAO;IACP,kBAAkB;IAClB,cAAc;IACd,kBAAkB;IAClB,oBAAoB;IACpB,qBAAqB;IACrB,mBAAmB;IACnB,eAAe;IACf,uBAAuB;IACvB,MAAM;IACN,QAAQ;CACT,CAAC,CAAC;AAEH,MAAM,aAAa,GAAG,0EAA0E,CAAC;AAEjG,6EAA6E;AAC7E,SAAS,OAAO,CACd,OAAsD,EACtD,GAAW;IAEX,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACjC,OAAO,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;AACxE,CAAC;AAED,6FAA6F;AAC7F,SAAS,IAAI,CAAC,GAAW;IACvB,OAAO,GAAG,CAAC,OAAO,CAAC,wBAAwB,EAAE,EAAE,CAAC,CAAC;AACnD,CAAC;AAED,SAAS,cAAc,CAAC,GAAW;IACjC,OAAO,qDAAqD,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzE,CAAC;AAED,KAAK,UAAU,WAAW,CACxB,MAAsB,EACtB,OAA6B,EAC7B,MAAsB;IAEtB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAC3C,MAAM,OAAO,GAAG,CAAC,CAAoE,EAAQ,EAAE;QAC7F,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;IACtE,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IACjE,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,sFAAsF;QACtF,iFAAiF;QACjF,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,KAAK,oBAAoB,EAAE,CAAC,CAAC;QACxE,OAAO;IACT,CAAC;IAED,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,EAAE,uBAAuB,CAAC,CAAC;IACzD,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,EAAE,uBAAuB,CAAC,CAAC;IACxD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IAEvC,iDAAiD;IACjD,MAAM,MAAM,GAAwE;QAClF,CAAC,eAAe,EAAE,oBAAoB,EAAE,CAAC,EAAE,8BAA8B,CAAC;QAC1E,CAAC,oBAAoB,EAAE,oBAAoB,EAAE,GAAG,EAAE,wBAAwB,CAAC;KAC5E,CAAC;IACF,MAAM,KAAK,GAAoD,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;IAClF,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IAC9C,KAAK,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,KAAK,EAAE,CAAC;QAChC,KAAK,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,IAAI,MAAM,EAAE,CAAC;YAClD,MAAM,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACvE,MAAM,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC3E,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;gBAC/B,OAAO,CAAC;oBACN,IAAI,EAAE,OAAO;oBACb,OAAO,EACL,GAAG,IAAI,oBAAoB,KAAK,OAAO,OAAO,gCAAgC;wBAC9E,yEAAyE;wBACzE,qCAAqC;iBACxC,CAAC,CAAC;gBACH,SAAS;YACX,CAAC;YACD,MAAM,KAAK,GAAG,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;YAC/B,IAAI,KAAK,GAAG,KAAK,EAAE,CAAC;gBAClB,OAAO,CAAC;oBACN,IAAI,EAAE,OAAO;oBACb,OAAO,EACL,GAAG,IAAI,KAAK,KAAK,KAAK,EAAE,QAAQ,OAAO,KAAK,EAAE,QAAQ,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM;wBAC5E,aAAa,KAAK,gBAAgB,GAAG,EAAE;iBAC1C,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QAClB,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;YAChC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;gBACjB,OAAO,CAAC;oBACN,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,KAAK,IAAI,qEAAqE;iBACxF,CAAC,CAAC;QACP,CAAC;QACD,2FAA2F;QAC3F,4FAA4F;QAC5F,sBAAsB;QACtB,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC;QAChE,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC;QAChE,IAAI,GAAG,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;YACpD,OAAO,CAAC;gBACN,IAAI,EAAE,QAAQ;gBACd,OAAO,EACL,oBAAoB,GAAG,2DAA2D;oBAClF,yCAAyC;aAC5C,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,6CAA6C;IAC7C,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IACxD,MAAM,OAAO,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACpC,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,OAAO,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC;IACxE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC;YACN,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAChE,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,CAAC,GAAW,EAAW,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1F,MAAM,MAAM,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC9C,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,GAAG,EAAU,CAAC;QACvD,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACb,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;QACjC,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAChC,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAClB,OAAO,CAAC;gBACN,IAAI,EAAE,MAAM;gBACZ,KAAK,EAAE,SAAS;gBAChB,KAAK,EAAE,GAAG;gBACV,EAAE,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC;gBACzB,OAAO,EACL,oFAAoF;aACvF,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QACD,IAAI,OAAO,CAAC,GAAG,CAAC;YAAE,SAAS;QAC3B,KAAK,MAAM,WAAW,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1C,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACvC,IAAI,KAAK,KAAK,CAAC,CAAC;gBAAE,SAAS;YAC3B,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;YAChD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,SAAS;YACrC,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;YAC3C,MAAM,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,2BAA2B,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YACvF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACxB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC;oBAAE,SAAS;gBACzC,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;oBACpD,OAAO,CAAC;wBACN,IAAI,EAAE,WAAW;wBACjB,KAAK,EAAE,GAAG;wBACV,EAAE,EAAE,GAAG,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE;wBAC7B,OAAO,EAAE,UAAU,IAAI,4DAA4D;qBACpF,CAAC,CAAC;gBACL,CAAC;gBACD,SAAS;YACX,CAAC;YACD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,IAAI,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC;oBAAE,SAAS;gBAClC,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;oBACpD,OAAO,CAAC;wBACN,IAAI,EAAE,WAAW;wBACjB,KAAK,EAAE,GAAG;wBACV,EAAE,EAAE,GAAG,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE;wBAC7B,OAAO,EACL,UAAU,IAAI,WAAW,KAAK,uCAAuC;4BACrE,+EAA+E;qBAClF,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,uBAAuB;IACvB,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,MAAM,EAAE,CAAC;QACtC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,SAAS;QAClC,KAAK,MAAM,OAAO,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YAC3C,IAAI,OAAO,KAAK,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI;gBAAE,SAAS;YACrF,OAAO,CAAC;gBACN,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE,SAAS;gBAChB,KAAK,EAAE,OAAO;gBACd,EAAE,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC;gBAC7B,OAAO,EACL,mBAAmB,IAAI,2DAA2D;oBAClF,kDAAkD;aACrD,CAAC,CAAC;QACL,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,OAAkC,EAClC,UAAgC,EAAE;IAElC,MAAM,MAAM,GAAmB,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAChD,KAAK,MAAM,MAAM,IAAI,OAAO;QAAE,MAAM,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACzE,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;oCACoC;AACpC,MAAM,UAAU,oBAAoB,CAAC,MAAsB;IACzD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACnE,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACnB,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,EAAE,CAAC;YACnE,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC7E,KAAK,CAAC,IAAI,CACR,KAAK,CAAC,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,KAAK,KAAK,GAAG,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,EAAE,CACjG,CAAC;QACJ,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC,MAAM,CAAC;IACzE,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC;IACjD,KAAK,CAAC,IAAI,CACR,MAAM,KAAK,CAAC;QACV,CAAC,CAAC,wBAAwB,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,QAAQ,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE;QAC1E,CAAC,CAAC,eAAe,MAAM,YAAY,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,QAAQ,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE,CACtF,CAAC;IACF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
package/dist/head.d.ts CHANGED
@@ -76,6 +76,23 @@ export interface HeadTags {
76
76
  * recognised Spanish value, and the tag's job is to be understood, not precise about dialect.
77
77
  */
78
78
  export declare function ogLocale(tag: string): string;
79
+ /** One question and its answer, as the page renders them — pass the same strings, so the
80
+ * structured data cannot drift from the copy. One donor's template carried four questions
81
+ * where the page renders seven, and nothing compared them until the migration. */
82
+ export interface FaqEntry {
83
+ question: string;
84
+ answer: string;
85
+ }
86
+ /**
87
+ * FAQ structured data for `headExtra`, with the script-closing sequence escaped.
88
+ *
89
+ * A `</script>` inside an answer ends the element early and ships the rest of the JSON as
90
+ * markup. `<\/` is the same string to a JSON parser and inert to an HTML one, so every `</`
91
+ * becomes `<\/` and `<!--` becomes `<\!--`. `JSON.stringify` never emits `<` outside a string
92
+ * — the structural characters are all brackets, quotes and digits — so the replace only ever
93
+ * touches copy.
94
+ */
95
+ export declare function faqJsonLd(faqs: readonly FaqEntry[]): string;
79
96
  /**
80
97
  * One page's `<head>` and body, written into the built template.
81
98
  *
@@ -1 +1 @@
1
- {"version":3,"file":"head.d.ts","sourceRoot":"","sources":["../src/head.ts"],"names":[],"mappings":"AAiBA,4FAA4F;AAC5F,eAAO,MAAM,UAAU,4BAA0B,CAAC;AA0FlD,uFAAuF;AACvF,MAAM,WAAW,SAAS;IACxB;yBACqB;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,QAAQ;IACvB,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;2DACuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;gDAC4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,SAAS,SAAS,EAAE,CAAC;IAClC;;;;;;;;;;;;OAYG;IACH,IAAI,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACxC;AAED;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG5C;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,MAAM,CAuHjE;AAED,MAAM,WAAW,cAAc;IAC7B,2FAA2F;IAC3F,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;uDACmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAsBD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,cAAmB,GAC1B,IAAI,CAgEN"}
1
+ {"version":3,"file":"head.d.ts","sourceRoot":"","sources":["../src/head.ts"],"names":[],"mappings":"AAiBA,4FAA4F;AAC5F,eAAO,MAAM,UAAU,4BAA0B,CAAC;AA0FlD,uFAAuF;AACvF,MAAM,WAAW,SAAS;IACxB;yBACqB;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,QAAQ;IACvB,wDAAwD;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;2DACuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;gDAC4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,SAAS,SAAS,EAAE,CAAC;IAClC;;;;;;;;;;;;OAYG;IACH,IAAI,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACxC;AAED;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG5C;AAED;;mFAEmF;AACnF,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,GAAG,MAAM,CAY3D;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,MAAM,CAuHjE;AAED,MAAM,WAAW,cAAc;IAC7B,2FAA2F;IAC3F,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;uDACmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAsBD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,cAAmB,GAC1B,IAAI,CAgEN"}
package/dist/head.js CHANGED
@@ -112,6 +112,28 @@ export function ogLocale(tag) {
112
112
  const TERRITORY = { en: "en_US", es: "es_ES" };
113
113
  return TERRITORY[tag] ?? tag.replace("-", "_");
114
114
  }
115
+ /**
116
+ * FAQ structured data for `headExtra`, with the script-closing sequence escaped.
117
+ *
118
+ * A `</script>` inside an answer ends the element early and ships the rest of the JSON as
119
+ * markup. `<\/` is the same string to a JSON parser and inert to an HTML one, so every `</`
120
+ * becomes `<\/` and `<!--` becomes `<\!--`. `JSON.stringify` never emits `<` outside a string
121
+ * — the structural characters are all brackets, quotes and digits — so the replace only ever
122
+ * touches copy.
123
+ */
124
+ export function faqJsonLd(faqs) {
125
+ const data = {
126
+ "@context": "https://schema.org",
127
+ "@type": "FAQPage",
128
+ mainEntity: faqs.map((faq) => ({
129
+ "@type": "Question",
130
+ name: faq.question,
131
+ acceptedAnswer: { "@type": "Answer", text: faq.answer },
132
+ })),
133
+ };
134
+ const json = JSON.stringify(data).replace(/<\//g, "<\\/").replace(/<!--/g, "<\\!--");
135
+ return `<script type="application/ld+json">${json}</script>`;
136
+ }
115
137
  /**
116
138
  * One page's `<head>` and body, written into the built template.
117
139
  *
package/dist/head.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"head.js","sourceRoot":"","sources":["../src/head.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"head.js","sourceRoot":"","sources":["../src/head.ts"],"names":[],"mappings":"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"}