@caelo-cms/shared 0.10.22 → 0.10.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai-tools.d.ts +289 -273
- package/dist/ai-tools.d.ts.map +1 -1
- package/dist/ai-tools.js +342 -323
- package/dist/ai-tools.js.map +1 -1
- package/dist/auth-forms.d.ts.map +1 -1
- package/dist/auth-forms.js +4 -1
- package/dist/auth-forms.js.map +1 -1
- package/dist/base-css.d.ts +35 -0
- package/dist/base-css.d.ts.map +1 -0
- package/dist/base-css.js +40 -0
- package/dist/base-css.js.map +1 -0
- package/dist/build-page.d.ts +330 -0
- package/dist/build-page.d.ts.map +1 -0
- package/dist/build-page.js +282 -0
- package/dist/build-page.js.map +1 -0
- package/dist/content.d.ts +322 -9
- package/dist/content.d.ts.map +1 -1
- package/dist/content.js +354 -11
- package/dist/content.js.map +1 -1
- package/dist/css-gradient-scan.d.ts +14 -0
- package/dist/css-gradient-scan.d.ts.map +1 -0
- package/dist/css-gradient-scan.js +81 -0
- package/dist/css-gradient-scan.js.map +1 -0
- package/dist/css-var-scan.d.ts +56 -0
- package/dist/css-var-scan.d.ts.map +1 -0
- package/dist/css-var-scan.js +97 -0
- package/dist/css-var-scan.js.map +1 -0
- package/dist/design-draft-shell.d.ts +21 -0
- package/dist/design-draft-shell.d.ts.map +1 -0
- package/dist/design-draft-shell.js +81 -0
- package/dist/design-draft-shell.js.map +1 -0
- package/dist/design-manifest.d.ts +36 -0
- package/dist/design-manifest.d.ts.map +1 -0
- package/dist/design-manifest.js +90 -0
- package/dist/design-manifest.js.map +1 -0
- package/dist/fonts.d.ts +89 -0
- package/dist/fonts.d.ts.map +1 -0
- package/dist/fonts.js +241 -0
- package/dist/fonts.js.map +1 -0
- package/dist/genesis-inventory.d.ts +32 -0
- package/dist/genesis-inventory.d.ts.map +1 -0
- package/dist/genesis-inventory.js +186 -0
- package/dist/genesis-inventory.js.map +1 -0
- package/dist/genesis.d.ts +102 -0
- package/dist/genesis.d.ts.map +1 -0
- package/dist/genesis.js +145 -0
- package/dist/genesis.js.map +1 -0
- package/dist/i18n.d.ts +29 -36
- package/dist/i18n.d.ts.map +1 -1
- package/dist/i18n.js +53 -128
- package/dist/i18n.js.map +1 -1
- package/dist/index.d.ts +28 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +28 -1
- package/dist/index.js.map +1 -1
- package/dist/interactions.d.ts +23 -0
- package/dist/interactions.d.ts.map +1 -0
- package/dist/interactions.js +44 -0
- package/dist/interactions.js.map +1 -0
- package/dist/media.d.ts +101 -16
- package/dist/media.d.ts.map +1 -1
- package/dist/media.js +126 -15
- package/dist/media.js.map +1 -1
- package/dist/page-log.d.ts +94 -0
- package/dist/page-log.d.ts.map +1 -0
- package/dist/page-log.js +111 -0
- package/dist/page-log.js.map +1 -0
- package/dist/preview-compose.d.ts +85 -12
- package/dist/preview-compose.d.ts.map +1 -1
- package/dist/preview-compose.js +157 -67
- package/dist/preview-compose.js.map +1 -1
- package/dist/proposal-status.d.ts +40 -0
- package/dist/proposal-status.d.ts.map +1 -0
- package/dist/proposal-status.js +34 -0
- package/dist/proposal-status.js.map +1 -0
- package/dist/responsive-images.d.ts +64 -0
- package/dist/responsive-images.d.ts.map +1 -0
- package/dist/responsive-images.js +98 -0
- package/dist/responsive-images.js.map +1 -0
- package/dist/safe-keys.d.ts +9 -0
- package/dist/safe-keys.d.ts.map +1 -0
- package/dist/safe-keys.js +20 -0
- package/dist/safe-keys.js.map +1 -0
- package/dist/seo.d.ts +11 -16
- package/dist/seo.d.ts.map +1 -1
- package/dist/seo.js +7 -23
- package/dist/seo.js.map +1 -1
- package/dist/skills.d.ts +14 -68
- package/dist/skills.d.ts.map +1 -1
- package/dist/skills.js +19 -113
- package/dist/skills.js.map +1 -1
- package/dist/strip-cdata.d.ts +7 -0
- package/dist/strip-cdata.d.ts.map +1 -0
- package/dist/strip-cdata.js +48 -0
- package/dist/strip-cdata.js.map +1 -0
- package/dist/structured-sets.d.ts +6 -52
- package/dist/structured-sets.d.ts.map +1 -1
- package/dist/structured-sets.js +6 -68
- package/dist/structured-sets.js.map +1 -1
- package/dist/subagents.d.ts +105 -3
- package/dist/subagents.d.ts.map +1 -1
- package/dist/subagents.js +224 -41
- package/dist/subagents.js.map +1 -1
- package/dist/template-engine.d.ts +85 -0
- package/dist/template-engine.d.ts.map +1 -0
- package/dist/template-engine.js +403 -0
- package/dist/template-engine.js.map +1 -0
- package/dist/theme-importers/auto-detect.d.ts +26 -0
- package/dist/theme-importers/auto-detect.d.ts.map +1 -0
- package/dist/theme-importers/auto-detect.js +42 -0
- package/dist/theme-importers/auto-detect.js.map +1 -0
- package/dist/theme-importers/css-comments.d.ts +12 -0
- package/dist/theme-importers/css-comments.d.ts.map +1 -0
- package/dist/theme-importers/css-comments.js +15 -0
- package/dist/theme-importers/css-comments.js.map +1 -0
- package/dist/theme-importers/dtcg.d.ts +46 -0
- package/dist/theme-importers/dtcg.d.ts.map +1 -0
- package/dist/theme-importers/dtcg.js +111 -0
- package/dist/theme-importers/dtcg.js.map +1 -0
- package/dist/theme-importers/loose.d.ts +3 -0
- package/dist/theme-importers/loose.d.ts.map +1 -0
- package/dist/theme-importers/loose.js +76 -0
- package/dist/theme-importers/loose.js.map +1 -0
- package/dist/theme-importers/shadcn.d.ts +24 -0
- package/dist/theme-importers/shadcn.d.ts.map +1 -0
- package/dist/theme-importers/shadcn.js +135 -0
- package/dist/theme-importers/shadcn.js.map +1 -0
- package/dist/theme-importers/style-dictionary.d.ts +17 -0
- package/dist/theme-importers/style-dictionary.d.ts.map +1 -0
- package/dist/theme-importers/style-dictionary.js +125 -0
- package/dist/theme-importers/style-dictionary.js.map +1 -0
- package/dist/theme-importers/tailwind.d.ts +3 -0
- package/dist/theme-importers/tailwind.d.ts.map +1 -0
- package/dist/theme-importers/tailwind.js +218 -0
- package/dist/theme-importers/tailwind.js.map +1 -0
- package/dist/theme-literal-binding.d.ts +37 -0
- package/dist/theme-literal-binding.d.ts.map +1 -0
- package/dist/theme-literal-binding.js +138 -0
- package/dist/theme-literal-binding.js.map +1 -0
- package/dist/theme-normalize.d.ts +31 -0
- package/dist/theme-normalize.d.ts.map +1 -0
- package/dist/theme-normalize.js +587 -0
- package/dist/theme-normalize.js.map +1 -0
- package/dist/theme-ramp.d.ts +55 -0
- package/dist/theme-ramp.d.ts.map +1 -0
- package/dist/theme-ramp.js +149 -0
- package/dist/theme-ramp.js.map +1 -0
- package/dist/theme-render.d.ts +105 -0
- package/dist/theme-render.d.ts.map +1 -0
- package/dist/theme-render.js +441 -0
- package/dist/theme-render.js.map +1 -0
- package/dist/themes-errors.d.ts +109 -0
- package/dist/themes-errors.d.ts.map +1 -0
- package/dist/themes-errors.js +170 -0
- package/dist/themes-errors.js.map +1 -0
- package/dist/themes.d.ts +343 -0
- package/dist/themes.d.ts.map +1 -0
- package/dist/themes.js +697 -0
- package/dist/themes.js.map +1 -0
- package/dist/version.d.ts +7 -4
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +6 -3
- package/dist/version.js.map +1 -1
- package/package.json +10 -2
- package/src/__tests__/redos-hardening.test.ts +160 -0
- package/src/ai-tools-add-module-modes.test.ts +106 -0
- package/src/ai-tools-position.test.ts +134 -0
- package/src/ai-tools.test.ts +81 -0
- package/src/ai-tools.ts +1105 -0
- package/src/auth-forms.ts +36 -0
- package/src/base-css.ts +42 -0
- package/src/build-page.test.ts +228 -0
- package/src/build-page.ts +319 -0
- package/src/cap-failures.ts +67 -0
- package/src/content.test.ts +170 -0
- package/src/content.ts +620 -0
- package/src/context.ts +43 -0
- package/src/css-gradient-scan.ts +88 -0
- package/src/css-var-scan.test.ts +96 -0
- package/src/css-var-scan.ts +144 -0
- package/src/derive-module-type.test.ts +80 -0
- package/src/design-draft-shell.test.ts +85 -0
- package/src/design-draft-shell.ts +109 -0
- package/src/design-manifest.ts +93 -0
- package/src/fonts.test.ts +157 -0
- package/src/fonts.ts +296 -0
- package/src/genesis-inventory.test.ts +86 -0
- package/src/genesis-inventory.ts +215 -0
- package/src/genesis-sanitize.test.ts +35 -0
- package/src/genesis.ts +158 -0
- package/src/i18n.test.ts +58 -0
- package/src/i18n.ts +91 -0
- package/src/index.test.ts +10 -0
- package/src/index.ts +59 -0
- package/src/interactions.ts +48 -0
- package/src/logger.ts +147 -0
- package/src/media.test.ts +160 -0
- package/src/media.ts +355 -0
- package/src/page-log.test.ts +163 -0
- package/src/page-log.ts +124 -0
- package/src/preview-compose.test.ts +637 -0
- package/src/preview-compose.ts +656 -0
- package/src/preview-scanner.test.ts +96 -0
- package/src/preview-scanner.ts +214 -0
- package/src/proposal-status.test.ts +69 -0
- package/src/proposal-status.ts +40 -0
- package/src/responsive-images.test.ts +104 -0
- package/src/responsive-images.ts +151 -0
- package/src/result.ts +29 -0
- package/src/safe-keys.ts +21 -0
- package/src/seo.test.ts +194 -0
- package/src/seo.ts +233 -0
- package/src/skills.ts +48 -0
- package/src/snapshots.test.ts +80 -0
- package/src/snapshots.ts +81 -0
- package/src/strip-cdata.test.ts +41 -0
- package/src/strip-cdata.ts +50 -0
- package/src/structured-sets.ts +114 -0
- package/src/subagents.test.ts +262 -0
- package/src/subagents.ts +432 -0
- package/src/template-engine.test.ts +379 -0
- package/src/template-engine.ts +520 -0
- package/src/theme-gradient.test.ts +92 -0
- package/src/theme-importers/__tests__/proto-pollution.test.ts +54 -0
- package/src/theme-importers/auto-detect.ts +84 -0
- package/src/theme-importers/css-comments.ts +15 -0
- package/src/theme-importers/dtcg.ts +106 -0
- package/src/theme-importers/loose.ts +76 -0
- package/src/theme-importers/shadcn.ts +133 -0
- package/src/theme-importers/style-dictionary.ts +125 -0
- package/src/theme-importers/tailwind.ts +217 -0
- package/src/theme-literal-binding.test.ts +71 -0
- package/src/theme-literal-binding.ts +159 -0
- package/src/theme-motion.test.ts +115 -0
- package/src/theme-normalize-envelope.test.ts +43 -0
- package/src/theme-normalize-gradient.test.ts +135 -0
- package/src/theme-normalize.ts +661 -0
- package/src/theme-ramp.ts +187 -0
- package/src/theme-render-sanitize.test.ts +45 -0
- package/src/theme-render.test.ts +119 -0
- package/src/theme-render.ts +487 -0
- package/src/theme-shadow.test.ts +56 -0
- package/src/themes-errors.ts +199 -0
- package/src/themes.ts +842 -0
- package/src/version.ts +66 -0
- package/dist/translation.d.ts +0 -127
- package/dist/translation.d.ts.map +0 -1
- package/dist/translation.js +0 -208
- package/dist/translation.js.map +0 -1
package/dist/fonts.js
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
2
|
+
/**
|
|
3
|
+
* Families that ship with operating systems — nothing to download, no
|
|
4
|
+
* @font-face to emit. Generic CSS keywords included. Lowercased for
|
|
5
|
+
* case-insensitive membership tests.
|
|
6
|
+
*/
|
|
7
|
+
const SYSTEM_FONT_FAMILIES = new Set([
|
|
8
|
+
// Generic keywords + UI stacks
|
|
9
|
+
"serif",
|
|
10
|
+
"sans-serif",
|
|
11
|
+
"monospace",
|
|
12
|
+
"cursive",
|
|
13
|
+
"fantasy",
|
|
14
|
+
"system-ui",
|
|
15
|
+
"ui-sans-serif",
|
|
16
|
+
"ui-serif",
|
|
17
|
+
"ui-monospace",
|
|
18
|
+
"ui-rounded",
|
|
19
|
+
"-apple-system",
|
|
20
|
+
"blinkmacsystemfont",
|
|
21
|
+
// Cross-platform classics
|
|
22
|
+
"arial",
|
|
23
|
+
"arial black",
|
|
24
|
+
"helvetica",
|
|
25
|
+
"helvetica neue",
|
|
26
|
+
"georgia",
|
|
27
|
+
"times",
|
|
28
|
+
"times new roman",
|
|
29
|
+
"courier",
|
|
30
|
+
"courier new",
|
|
31
|
+
"verdana",
|
|
32
|
+
"tahoma",
|
|
33
|
+
"trebuchet ms",
|
|
34
|
+
"impact",
|
|
35
|
+
"palatino",
|
|
36
|
+
"garamond",
|
|
37
|
+
// Platform UI/mono staples browsers resolve locally
|
|
38
|
+
"segoe ui",
|
|
39
|
+
"sf pro",
|
|
40
|
+
"sf pro text",
|
|
41
|
+
"sf pro display",
|
|
42
|
+
"sf mono",
|
|
43
|
+
"sfmono-regular",
|
|
44
|
+
"menlo",
|
|
45
|
+
"monaco",
|
|
46
|
+
"consolas",
|
|
47
|
+
"lucida console",
|
|
48
|
+
"lucida sans",
|
|
49
|
+
].map((f) => f.toLowerCase()));
|
|
50
|
+
/** True when the family resolves locally on visitors' machines. */
|
|
51
|
+
export function isSystemFontFamily(family) {
|
|
52
|
+
return SYSTEM_FONT_FAMILIES.has(family.trim().toLowerCase());
|
|
53
|
+
}
|
|
54
|
+
/** Strip quotes + whitespace from one family in a font stack. */
|
|
55
|
+
function cleanFamilyName(raw) {
|
|
56
|
+
return raw
|
|
57
|
+
.trim()
|
|
58
|
+
.replace(/^["']|["']$/g, "")
|
|
59
|
+
.trim();
|
|
60
|
+
}
|
|
61
|
+
const KEYWORD_WEIGHTS = {
|
|
62
|
+
normal: 400,
|
|
63
|
+
bold: 700,
|
|
64
|
+
// Relative keywords have no absolute value; anchor to the common pair
|
|
65
|
+
// so the request still covers a usable range.
|
|
66
|
+
lighter: 300,
|
|
67
|
+
bolder: 700,
|
|
68
|
+
};
|
|
69
|
+
const DEFAULT_WEIGHTS = [400, 700];
|
|
70
|
+
/**
|
|
71
|
+
* Walk `typography.*` composites and collect every non-system family
|
|
72
|
+
* with the weights the theme declares for it. Alias entries (`$value`
|
|
73
|
+
* as `{other.token}` string) are skipped — they point at a concrete
|
|
74
|
+
* composite that is collected on its own.
|
|
75
|
+
*
|
|
76
|
+
* Only the FIRST family of a declared stack is requested: the rest of
|
|
77
|
+
* the stack is the author's fallback chain, which by definition is not
|
|
78
|
+
* delivered.
|
|
79
|
+
*/
|
|
80
|
+
export function extractThemeFontRequests(tokens) {
|
|
81
|
+
const typography = tokens.typography;
|
|
82
|
+
if (typography === undefined || typography === null || typeof typography !== "object") {
|
|
83
|
+
return [];
|
|
84
|
+
}
|
|
85
|
+
const byFamily = new Map();
|
|
86
|
+
for (const [role, entry] of Object.entries(typography)) {
|
|
87
|
+
if (entry === null || typeof entry !== "object")
|
|
88
|
+
continue;
|
|
89
|
+
const value = entry.$value;
|
|
90
|
+
if (value === null || typeof value !== "object")
|
|
91
|
+
continue; // alias or malformed
|
|
92
|
+
const composite = value;
|
|
93
|
+
if (typeof composite.fontFamily !== "string")
|
|
94
|
+
continue;
|
|
95
|
+
const primary = cleanFamilyName(composite.fontFamily.split(",")[0] ?? "");
|
|
96
|
+
if (primary === "" || isSystemFontFamily(primary))
|
|
97
|
+
continue;
|
|
98
|
+
const bucket = byFamily.get(primary) ?? { weights: new Set(), roles: [] };
|
|
99
|
+
if (typeof composite.fontWeight === "number") {
|
|
100
|
+
bucket.weights.add(composite.fontWeight);
|
|
101
|
+
}
|
|
102
|
+
else if (typeof composite.fontWeight === "string") {
|
|
103
|
+
const mapped = KEYWORD_WEIGHTS[composite.fontWeight];
|
|
104
|
+
if (mapped !== undefined)
|
|
105
|
+
bucket.weights.add(mapped);
|
|
106
|
+
}
|
|
107
|
+
bucket.roles.push(role);
|
|
108
|
+
byFamily.set(primary, bucket);
|
|
109
|
+
}
|
|
110
|
+
return [...byFamily.entries()].map(([family, b]) => ({
|
|
111
|
+
family,
|
|
112
|
+
weights: b.weights.size > 0
|
|
113
|
+
? [...b.weights].sort((a, z) => a - z)
|
|
114
|
+
: [...DEFAULT_WEIGHTS],
|
|
115
|
+
roles: b.roles,
|
|
116
|
+
}));
|
|
117
|
+
}
|
|
118
|
+
/** css2 request URL for one family (woff2 negotiated via the UA header). */
|
|
119
|
+
export function googleFontsCssUrl(request) {
|
|
120
|
+
const family = encodeURIComponent(request.family).replace(/%20/g, "+");
|
|
121
|
+
const weights = request.weights.join(";");
|
|
122
|
+
return `https://fonts.googleapis.com/css2?family=${family}:wght@${weights}&display=swap`;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* `[^{}]*` (not `[^}]*`): the char class excluding BOTH braces makes the
|
|
126
|
+
* pattern unambiguous — on adversarial payloads full of unclosed
|
|
127
|
+
* `@font-face{` starts, a failed match aborts at the next `{` instead of
|
|
128
|
+
* rescanning to end-of-input per start position (the polynomial-ReDoS
|
|
129
|
+
* shape CodeQL flags; this file parses remotely-served CSS).
|
|
130
|
+
*/
|
|
131
|
+
const FONT_FACE_BLOCK_RE = /@font-face\s*\{([^{}]*)\}/g;
|
|
132
|
+
/** css2 responses are ~10–50 KB; anything past this is not a fonts CSS. */
|
|
133
|
+
const MAX_FONTS_CSS_BYTES = 1_000_000;
|
|
134
|
+
function declValue(block, prop) {
|
|
135
|
+
const m = new RegExp(`${prop}\\s*:\\s*([^;]+);`, "i").exec(block);
|
|
136
|
+
return m ? (m[1] ?? "").trim() : null;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Parse a fonts-CSS payload (css2 response shape) into face records.
|
|
140
|
+
* Faces without a woff2/woff URL are dropped; a payload yielding zero
|
|
141
|
+
* faces is the caller's loud-failure signal, not a silent empty set.
|
|
142
|
+
* Oversized payloads short-circuit to [] for the same loud path —
|
|
143
|
+
* a legitimate css2 response is orders of magnitude smaller.
|
|
144
|
+
*/
|
|
145
|
+
export function parseFontsCss(cssText) {
|
|
146
|
+
if (cssText.length > MAX_FONTS_CSS_BYTES)
|
|
147
|
+
return [];
|
|
148
|
+
const faces = [];
|
|
149
|
+
for (const m of cssText.matchAll(FONT_FACE_BLOCK_RE)) {
|
|
150
|
+
const block = m[1] ?? "";
|
|
151
|
+
const familyRaw = declValue(block, "font-family");
|
|
152
|
+
const src = declValue(block, "src");
|
|
153
|
+
if (familyRaw === null || src === null)
|
|
154
|
+
continue;
|
|
155
|
+
// Capture the whole url(...) argument with an unambiguous class,
|
|
156
|
+
// then check the extension in code — `[^)]+\.woff2?` is the classic
|
|
157
|
+
// ambiguous-suffix polynomial pattern.
|
|
158
|
+
const urlMatch = /url\(([^()]*)\)/i.exec(src);
|
|
159
|
+
if (!urlMatch)
|
|
160
|
+
continue;
|
|
161
|
+
const srcUrl = (urlMatch[1] ?? "").trim().replace(/^["']|["']$/g, "");
|
|
162
|
+
const lower = srcUrl.toLowerCase();
|
|
163
|
+
if (!(lower.endsWith(".woff2") || lower.endsWith(".woff")))
|
|
164
|
+
continue;
|
|
165
|
+
faces.push({
|
|
166
|
+
family: cleanFamilyName(familyRaw),
|
|
167
|
+
style: declValue(block, "font-style") ?? "normal",
|
|
168
|
+
weight: declValue(block, "font-weight") ?? "400",
|
|
169
|
+
unicodeRange: declValue(block, "unicode-range"),
|
|
170
|
+
srcUrl,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
return faces;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Emit self-hosted @font-face CSS. `font-display: swap` always — text
|
|
177
|
+
* must render in the fallback while the woff2 loads.
|
|
178
|
+
*/
|
|
179
|
+
export function buildFontFaceCss(faces) {
|
|
180
|
+
return faces
|
|
181
|
+
.map((f) => {
|
|
182
|
+
const range = f.unicodeRange !== null ? `unicode-range:${f.unicodeRange};` : "";
|
|
183
|
+
return (`@font-face{font-family:${JSON.stringify(f.family)};` +
|
|
184
|
+
`font-style:${f.style};font-weight:${f.weight};font-display:swap;` +
|
|
185
|
+
`src:url(${f.publicUrl}) format('woff2');${range}}`);
|
|
186
|
+
})
|
|
187
|
+
.join("\n");
|
|
188
|
+
}
|
|
189
|
+
/** Latin-subset heuristic: css2 marks it with a range starting U+0000. */
|
|
190
|
+
function isLatinFace(f) {
|
|
191
|
+
return f.unicodeRange === null || f.unicodeRange.toLowerCase().includes("u+0000");
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Pick the faces worth a `<link rel="preload">`: one per family — the
|
|
195
|
+
* latin, normal-style face at the lowest declared weight (the body-copy
|
|
196
|
+
* face; heavier display cuts arrive via normal loading). Capped at two
|
|
197
|
+
* families so the preload budget stays sane on multi-family themes.
|
|
198
|
+
*/
|
|
199
|
+
export function selectPreloadFaces(faces) {
|
|
200
|
+
const byFamily = new Map();
|
|
201
|
+
for (const f of faces) {
|
|
202
|
+
if (f.style !== "normal" || !isLatinFace(f))
|
|
203
|
+
continue;
|
|
204
|
+
const list = byFamily.get(f.family) ?? [];
|
|
205
|
+
list.push(f);
|
|
206
|
+
byFamily.set(f.family, list);
|
|
207
|
+
}
|
|
208
|
+
const picks = [];
|
|
209
|
+
for (const list of byFamily.values()) {
|
|
210
|
+
list.sort((a, z) => Number.parseInt(a.weight, 10) - Number.parseInt(z.weight, 10));
|
|
211
|
+
const first = list[0];
|
|
212
|
+
if (first !== undefined)
|
|
213
|
+
picks.push(first);
|
|
214
|
+
}
|
|
215
|
+
return picks.slice(0, 2);
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Structured marker for a family that could not be resolved. Lands in
|
|
219
|
+
* `missingSlots` (preview, soft) or a thrown deploy error (hard) — the
|
|
220
|
+
* same loud-signal convention as `theme-asset-unbound:<slot>`.
|
|
221
|
+
*/
|
|
222
|
+
export function fontUnresolvableMarker(family) {
|
|
223
|
+
return `theme-font-unresolvable:${family}`;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Filesystem/URL-safe slug for a family name. Shared between the font
|
|
227
|
+
* resolver (writes `<cacheDir>/<slug>/…`) and the admin serve route
|
|
228
|
+
* (reads the same path from the URL) so the two can't drift.
|
|
229
|
+
*/
|
|
230
|
+
export function fontFamilySlug(family) {
|
|
231
|
+
// After the collapse pass, dash RUNS no longer exist — at most one
|
|
232
|
+
// leading + one trailing dash remain, so the trim pattern needs no
|
|
233
|
+
// quantifier (a `-+$` here is the polynomial-ReDoS shape on
|
|
234
|
+
// adversarial all-dash input; this runs on library-supplied strings).
|
|
235
|
+
return family
|
|
236
|
+
.trim()
|
|
237
|
+
.toLowerCase()
|
|
238
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
239
|
+
.replace(/^-|-$/g, "");
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=fonts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fonts.js","sourceRoot":"","sources":["../src/fonts.ts"],"names":[],"mappings":"AAAA,mCAAmC;AAgDnC;;;;GAIG;AACH,MAAM,oBAAoB,GAAwB,IAAI,GAAG,CACvD;IACE,+BAA+B;IAC/B,OAAO;IACP,YAAY;IACZ,WAAW;IACX,SAAS;IACT,SAAS;IACT,WAAW;IACX,eAAe;IACf,UAAU;IACV,cAAc;IACd,YAAY;IACZ,eAAe;IACf,oBAAoB;IACpB,0BAA0B;IAC1B,OAAO;IACP,aAAa;IACb,WAAW;IACX,gBAAgB;IAChB,SAAS;IACT,OAAO;IACP,iBAAiB;IACjB,SAAS;IACT,aAAa;IACb,SAAS;IACT,QAAQ;IACR,cAAc;IACd,QAAQ;IACR,UAAU;IACV,UAAU;IACV,oDAAoD;IACpD,UAAU;IACV,QAAQ;IACR,aAAa;IACb,gBAAgB;IAChB,SAAS;IACT,gBAAgB;IAChB,OAAO;IACP,QAAQ;IACR,UAAU;IACV,gBAAgB;IAChB,aAAa;CACd,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAC9B,CAAC;AAEF,mEAAmE;AACnE,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,OAAO,oBAAoB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;AAC/D,CAAC;AAED,iEAAiE;AACjE,SAAS,eAAe,CAAC,GAAW;IAClC,OAAO,GAAG;SACP,IAAI,EAAE;SACN,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC;SAC3B,IAAI,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,eAAe,GAA2B;IAC9C,MAAM,EAAE,GAAG;IACX,IAAI,EAAE,GAAG;IACT,sEAAsE;IACtE,8CAA8C;IAC9C,OAAO,EAAE,GAAG;IACZ,MAAM,EAAE,GAAG;CACZ,CAAC;AAEF,MAAM,eAAe,GAAG,CAAC,GAAG,EAAE,GAAG,CAAU,CAAC;AAE5C;;;;;;;;;GASG;AACH,MAAM,UAAU,wBAAwB,CAAC,MAAqB;IAC5D,MAAM,UAAU,GAAI,MAAkC,CAAC,UAAU,CAAC;IAClE,IAAI,UAAU,KAAK,SAAS,IAAI,UAAU,KAAK,IAAI,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;QACtF,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAqD,CAAC;IAC9E,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAqC,CAAC,EAAE,CAAC;QAClF,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,SAAS;QAC1D,MAAM,KAAK,GAAI,KAA8B,CAAC,MAAM,CAAC;QACrD,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,SAAS,CAAC,qBAAqB;QAChF,MAAM,SAAS,GAAG,KAAuD,CAAC;QAC1E,IAAI,OAAO,SAAS,CAAC,UAAU,KAAK,QAAQ;YAAE,SAAS;QACvD,MAAM,OAAO,GAAG,eAAe,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1E,IAAI,OAAO,KAAK,EAAE,IAAI,kBAAkB,CAAC,OAAO,CAAC;YAAE,SAAS;QAE5D,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,GAAG,EAAU,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;QAClF,IAAI,OAAO,SAAS,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;YAC7C,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAC3C,CAAC;aAAM,IAAI,OAAO,SAAS,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;YACpD,MAAM,MAAM,GAAG,eAAe,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;YACrD,IAAI,MAAM,KAAK,SAAS;gBAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACvD,CAAC;QACD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxB,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,CAAC,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACnD,MAAM;QACN,OAAO,EACL,CAAC,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC;YAChB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;YACtC,CAAC,CAAE,CAAC,GAAG,eAAe,CAAc;QACxC,KAAK,EAAE,CAAC,CAAC,KAAK;KACf,CAAC,CAAC,CAAC;AACN,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,iBAAiB,CAAC,OAAoB;IACpD,MAAM,MAAM,GAAG,kBAAkB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACvE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC1C,OAAO,4CAA4C,MAAM,SAAS,OAAO,eAAe,CAAC;AAC3F,CAAC;AAED;;;;;;GAMG;AACH,MAAM,kBAAkB,GAAG,4BAA4B,CAAC;AAExD,2EAA2E;AAC3E,MAAM,mBAAmB,GAAG,SAAS,CAAC;AAEtC,SAAS,SAAS,CAAC,KAAa,EAAE,IAAY;IAC5C,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,GAAG,IAAI,mBAAmB,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACxC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,IAAI,OAAO,CAAC,MAAM,GAAG,mBAAmB;QAAE,OAAO,EAAE,CAAC;IACpD,MAAM,KAAK,GAAqB,EAAE,CAAC;IACnC,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACrD,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACzB,MAAM,SAAS,GAAG,SAAS,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;QAClD,MAAM,GAAG,GAAG,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACpC,IAAI,SAAS,KAAK,IAAI,IAAI,GAAG,KAAK,IAAI;YAAE,SAAS;QACjD,iEAAiE;QACjE,oEAAoE;QACpE,uCAAuC;QACvC,MAAM,QAAQ,GAAG,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9C,IAAI,CAAC,QAAQ;YAAE,SAAS;QACxB,MAAM,MAAM,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QACtE,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;QACnC,IAAI,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAAE,SAAS;QACrE,KAAK,CAAC,IAAI,CAAC;YACT,MAAM,EAAE,eAAe,CAAC,SAAS,CAAC;YAClC,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,YAAY,CAAC,IAAI,QAAQ;YACjD,MAAM,EAAE,SAAS,CAAC,KAAK,EAAE,aAAa,CAAC,IAAI,KAAK;YAChD,YAAY,EAAE,SAAS,CAAC,KAAK,EAAE,eAAe,CAAC;YAC/C,MAAM;SACP,CAAC,CAAC;IACL,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAkC;IACjE,OAAO,KAAK;SACT,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,KAAK,GAAG,CAAC,CAAC,YAAY,KAAK,IAAI,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAChF,OAAO,CACL,0BAA0B,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG;YACrD,cAAc,CAAC,CAAC,KAAK,gBAAgB,CAAC,CAAC,MAAM,qBAAqB;YAClE,WAAW,CAAC,CAAC,SAAS,qBAAqB,KAAK,GAAG,CACpD,CAAC;IACJ,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED,0EAA0E;AAC1E,SAAS,WAAW,CAAC,CAAmB;IACtC,OAAO,CAAC,CAAC,YAAY,KAAK,IAAI,IAAI,CAAC,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACpF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAkC;IACnE,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA8B,CAAC;IACvD,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;YAAE,SAAS;QACtD,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QAC1C,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACb,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC/B,CAAC;IACD,MAAM,KAAK,GAAuB,EAAE,CAAC;IACrC,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;QACrC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;QACnF,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,KAAK,KAAK,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC3B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAc;IACnD,OAAO,2BAA2B,MAAM,EAAE,CAAC;AAC7C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,MAAc;IAC3C,mEAAmE;IACnE,mEAAmE;IACnE,4DAA4D;IAC5D,sEAAsE;IACtE,OAAO,MAAM;SACV,IAAI,EAAE;SACN,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AAC3B,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** One distinct color literal with where/how often the draft uses it. */
|
|
2
|
+
export interface ColorUsage {
|
|
3
|
+
readonly value: string;
|
|
4
|
+
readonly count: number;
|
|
5
|
+
/** Distinct declaration properties using it (background, color, …). */
|
|
6
|
+
readonly properties: readonly string[];
|
|
7
|
+
}
|
|
8
|
+
export interface GenesisDraftInventory {
|
|
9
|
+
readonly colors: readonly ColorUsage[];
|
|
10
|
+
readonly gradients: readonly string[];
|
|
11
|
+
readonly fontFamilies: readonly string[];
|
|
12
|
+
readonly fontSizes: readonly string[];
|
|
13
|
+
readonly spacingValues: readonly string[];
|
|
14
|
+
readonly radiusValues: readonly string[];
|
|
15
|
+
readonly shadows: readonly string[];
|
|
16
|
+
/** Ordered structural outline of the body (tag + text snippet). */
|
|
17
|
+
readonly outline: readonly {
|
|
18
|
+
tag: string;
|
|
19
|
+
text: string;
|
|
20
|
+
}[];
|
|
21
|
+
}
|
|
22
|
+
/** Linear extraction of every <style> block's contents. */
|
|
23
|
+
export declare function extractDraftCss(html: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* Build the inventory. Caps guard pathological drafts: the boundary
|
|
26
|
+
* already limits draft size (GENESIS_DRAFT_MAX_HTML_BYTES), and each
|
|
27
|
+
* result list is truncated to what a decision-maker can actually use.
|
|
28
|
+
*/
|
|
29
|
+
export declare function inventoryGenesisDraft(html: string): GenesisDraftInventory;
|
|
30
|
+
/** Compact, prompt-friendly rendering of the inventory. */
|
|
31
|
+
export declare function formatGenesisInventory(inv: GenesisDraftInventory): string;
|
|
32
|
+
//# sourceMappingURL=genesis-inventory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"genesis-inventory.d.ts","sourceRoot":"","sources":["../src/genesis-inventory.ts"],"names":[],"mappings":"AAsBA,yEAAyE;AACzE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,uEAAuE;IACvE,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,CAAC;IACvC,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,mEAAmE;IACnE,QAAQ,CAAC,OAAO,EAAE,SAAS;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC5D;AAED,2DAA2D;AAC3D,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAepD;AAiDD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,qBAAqB,CAkFzE;AAED,2DAA2D;AAC3D,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,qBAAqB,GAAG,MAAM,CAiBzE"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
2
|
+
/**
|
|
3
|
+
* issue #164 — design-compiler stage 1: the deterministic INVENTORY.
|
|
4
|
+
*
|
|
5
|
+
* Compiler contract (epic #149): the AI decides, code executes and
|
|
6
|
+
* verifies. This module is the "code" half of the first stage — it
|
|
7
|
+
* parses a Genesis draft (complete single-file HTML) into a fact base
|
|
8
|
+
* of design values (colors with usage contexts, font families, size /
|
|
9
|
+
* spacing / radius histograms, gradients, shadows) plus a section
|
|
10
|
+
* outline. The AI reads the inventory and makes the DECISIONS (which
|
|
11
|
+
* literal becomes which token, what things are called); it never has
|
|
12
|
+
* to re-derive facts by eyeballing raw CSS, and the facts can't be
|
|
13
|
+
* hallucinated.
|
|
14
|
+
*
|
|
15
|
+
* Pure string analysis, linear scans, unambiguous regex classes
|
|
16
|
+
* (ReDoS-aware per issue #113 — drafts are AI-authored but the parser
|
|
17
|
+
* budget must hold on adversarial input too).
|
|
18
|
+
*/
|
|
19
|
+
import { scanCssGradients } from "./css-gradient-scan.js";
|
|
20
|
+
/** Linear extraction of every <style> block's contents. */
|
|
21
|
+
export function extractDraftCss(html) {
|
|
22
|
+
const parts = [];
|
|
23
|
+
const lower = html.toLowerCase();
|
|
24
|
+
let from = 0;
|
|
25
|
+
while (true) {
|
|
26
|
+
const open = lower.indexOf("<style", from);
|
|
27
|
+
if (open === -1)
|
|
28
|
+
break;
|
|
29
|
+
const openEnd = lower.indexOf(">", open);
|
|
30
|
+
if (openEnd === -1)
|
|
31
|
+
break;
|
|
32
|
+
const close = lower.indexOf("</style", openEnd);
|
|
33
|
+
if (close === -1)
|
|
34
|
+
break;
|
|
35
|
+
parts.push(html.slice(openEnd + 1, close));
|
|
36
|
+
from = close + 8;
|
|
37
|
+
}
|
|
38
|
+
return parts.join("\n");
|
|
39
|
+
}
|
|
40
|
+
const DECLARATION_RE = /([a-zA-Z-]+)\s*:\s*([^;{}]+)/g;
|
|
41
|
+
const COLOR_LITERAL_RE = /#[0-9a-fA-F]{3,8}\b|(?:oklch|rgba?|hsla?|lab|lch|hwb)\([^()]*\)/g;
|
|
42
|
+
const LENGTH_RE = /-?\d+(?:\.\d+)?(?:rem|em|px|vh|vw|ch|%)\b/g;
|
|
43
|
+
const SPACING_PROPS = new Set([
|
|
44
|
+
"margin",
|
|
45
|
+
"margin-top",
|
|
46
|
+
"margin-bottom",
|
|
47
|
+
"margin-left",
|
|
48
|
+
"margin-right",
|
|
49
|
+
"margin-block",
|
|
50
|
+
"margin-inline",
|
|
51
|
+
"padding",
|
|
52
|
+
"padding-top",
|
|
53
|
+
"padding-bottom",
|
|
54
|
+
"padding-left",
|
|
55
|
+
"padding-right",
|
|
56
|
+
"padding-block",
|
|
57
|
+
"padding-inline",
|
|
58
|
+
"gap",
|
|
59
|
+
"row-gap",
|
|
60
|
+
"column-gap",
|
|
61
|
+
]);
|
|
62
|
+
const GENERIC_FONT_KEYWORDS = new Set([
|
|
63
|
+
"serif",
|
|
64
|
+
"sans-serif",
|
|
65
|
+
"monospace",
|
|
66
|
+
"cursive",
|
|
67
|
+
"fantasy",
|
|
68
|
+
"system-ui",
|
|
69
|
+
"ui-sans-serif",
|
|
70
|
+
"ui-serif",
|
|
71
|
+
"ui-monospace",
|
|
72
|
+
]);
|
|
73
|
+
function pushCount(map, key) {
|
|
74
|
+
map.set(key, (map.get(key) ?? 0) + 1);
|
|
75
|
+
}
|
|
76
|
+
function sortedByCount(map) {
|
|
77
|
+
return [...map.entries()].sort((a, z) => z[1] - a[1]).map(([k]) => k);
|
|
78
|
+
}
|
|
79
|
+
const OUTLINE_TAG_RE = /<(section|header|footer|main|nav|h1|h2|h3)\b[^>]*>/gi;
|
|
80
|
+
const TAG_STRIP_RE = /<[^>]*>/g;
|
|
81
|
+
/**
|
|
82
|
+
* Build the inventory. Caps guard pathological drafts: the boundary
|
|
83
|
+
* already limits draft size (GENESIS_DRAFT_MAX_HTML_BYTES), and each
|
|
84
|
+
* result list is truncated to what a decision-maker can actually use.
|
|
85
|
+
*/
|
|
86
|
+
export function inventoryGenesisDraft(html) {
|
|
87
|
+
const css = extractDraftCss(html);
|
|
88
|
+
const colorMeta = new Map();
|
|
89
|
+
const gradients = new Map();
|
|
90
|
+
const fontFamilies = new Map();
|
|
91
|
+
const fontSizes = new Map();
|
|
92
|
+
const spacing = new Map();
|
|
93
|
+
const radii = new Map();
|
|
94
|
+
const shadows = new Map();
|
|
95
|
+
for (const decl of css.matchAll(DECLARATION_RE)) {
|
|
96
|
+
const prop = (decl[1] ?? "").toLowerCase();
|
|
97
|
+
const value = (decl[2] ?? "").trim();
|
|
98
|
+
for (const g of scanCssGradients(value)) {
|
|
99
|
+
pushCount(gradients, g.literal);
|
|
100
|
+
}
|
|
101
|
+
// Colors inside gradients still count — a gradient stop color is a
|
|
102
|
+
// palette member the token map must name.
|
|
103
|
+
for (const c of value.matchAll(COLOR_LITERAL_RE)) {
|
|
104
|
+
const key = c[0].toLowerCase();
|
|
105
|
+
const meta = colorMeta.get(key) ?? { count: 0, properties: new Set() };
|
|
106
|
+
meta.count += 1;
|
|
107
|
+
meta.properties.add(prop);
|
|
108
|
+
colorMeta.set(key, meta);
|
|
109
|
+
}
|
|
110
|
+
if (prop === "font-family") {
|
|
111
|
+
for (const fam of value.split(",")) {
|
|
112
|
+
const clean = fam.trim().replace(/^["']|["']$/g, "");
|
|
113
|
+
// Generic keywords are fallback-chain noise, not palette
|
|
114
|
+
// members — the token map names real typefaces.
|
|
115
|
+
if (clean.length > 0 &&
|
|
116
|
+
clean.length < 80 &&
|
|
117
|
+
!GENERIC_FONT_KEYWORDS.has(clean.toLowerCase())) {
|
|
118
|
+
pushCount(fontFamilies, clean);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
else if (prop === "font-size") {
|
|
123
|
+
pushCount(fontSizes, value);
|
|
124
|
+
}
|
|
125
|
+
else if (SPACING_PROPS.has(prop)) {
|
|
126
|
+
for (const len of value.matchAll(LENGTH_RE))
|
|
127
|
+
pushCount(spacing, len[0]);
|
|
128
|
+
}
|
|
129
|
+
else if (prop === "border-radius") {
|
|
130
|
+
pushCount(radii, value);
|
|
131
|
+
}
|
|
132
|
+
else if (prop === "box-shadow" || prop === "text-shadow") {
|
|
133
|
+
pushCount(shadows, value);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
const outline = [];
|
|
137
|
+
for (const m of html.matchAll(OUTLINE_TAG_RE)) {
|
|
138
|
+
if (outline.length >= 60)
|
|
139
|
+
break;
|
|
140
|
+
const tag = (m[1] ?? "").toLowerCase();
|
|
141
|
+
const start = (m.index ?? 0) + m[0].length;
|
|
142
|
+
const text = html
|
|
143
|
+
.slice(start, start + 400)
|
|
144
|
+
.replace(TAG_STRIP_RE, " ")
|
|
145
|
+
.replace(/\s+/g, " ")
|
|
146
|
+
.trim()
|
|
147
|
+
.slice(0, 80);
|
|
148
|
+
outline.push({ tag, text });
|
|
149
|
+
}
|
|
150
|
+
return {
|
|
151
|
+
colors: [...colorMeta.entries()]
|
|
152
|
+
.sort((a, z) => z[1].count - a[1].count)
|
|
153
|
+
.slice(0, 40)
|
|
154
|
+
.map(([value, meta]) => ({
|
|
155
|
+
value,
|
|
156
|
+
count: meta.count,
|
|
157
|
+
properties: [...meta.properties].sort(),
|
|
158
|
+
})),
|
|
159
|
+
gradients: sortedByCount(gradients).slice(0, 12),
|
|
160
|
+
fontFamilies: sortedByCount(fontFamilies).slice(0, 12),
|
|
161
|
+
fontSizes: sortedByCount(fontSizes).slice(0, 24),
|
|
162
|
+
spacingValues: sortedByCount(spacing).slice(0, 24),
|
|
163
|
+
radiusValues: sortedByCount(radii).slice(0, 12),
|
|
164
|
+
shadows: sortedByCount(shadows).slice(0, 12),
|
|
165
|
+
outline,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
/** Compact, prompt-friendly rendering of the inventory. */
|
|
169
|
+
export function formatGenesisInventory(inv) {
|
|
170
|
+
const lines = [];
|
|
171
|
+
lines.push(`Colors (${inv.colors.length}): ${inv.colors
|
|
172
|
+
.map((c) => `${c.value}×${c.count}[${c.properties.join("/")}]`)
|
|
173
|
+
.join(", ")}`);
|
|
174
|
+
if (inv.gradients.length > 0)
|
|
175
|
+
lines.push(`Gradients: ${inv.gradients.join(" | ")}`);
|
|
176
|
+
lines.push(`Font families: ${inv.fontFamilies.join(", ") || "(none declared)"}`);
|
|
177
|
+
lines.push(`Font sizes: ${inv.fontSizes.join(", ")}`);
|
|
178
|
+
lines.push(`Spacing values: ${inv.spacingValues.join(", ")}`);
|
|
179
|
+
if (inv.radiusValues.length > 0)
|
|
180
|
+
lines.push(`Radii: ${inv.radiusValues.join(", ")}`);
|
|
181
|
+
if (inv.shadows.length > 0)
|
|
182
|
+
lines.push(`Shadows: ${inv.shadows.join(" | ")}`);
|
|
183
|
+
lines.push(`Outline: ${inv.outline.map((o) => `<${o.tag}>${o.text ? ` ${o.text}` : ""}`).join(" → ")}`);
|
|
184
|
+
return lines.join("\n");
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=genesis-inventory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"genesis-inventory.js","sourceRoot":"","sources":["../src/genesis-inventory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* issue #163 — Site Genesis shared shapes; issue #375 generalises the
|
|
3
|
+
* same draft loop to growth-time.
|
|
4
|
+
*
|
|
5
|
+
* Design-time is divergent: the AI drafts complete freeform HTML pages
|
|
6
|
+
* (one per design direction) and the operator picks one; the CMS
|
|
7
|
+
* structure is derived FROM that choice (#164's compiler). Growth-time
|
|
8
|
+
* reuses the identical draft → present → select → materialise loop at
|
|
9
|
+
* smaller scope: `page` and `module` drafts are FRAGMENTS bound to the
|
|
10
|
+
* site's `var(--…)` theme tokens, composed into the real theme shell
|
|
11
|
+
* only at view time (never an AI approximation of the theme — #375).
|
|
12
|
+
* These are the boundary schemas for the brief + the draft rows.
|
|
13
|
+
*/
|
|
14
|
+
import { z } from "zod";
|
|
15
|
+
/**
|
|
16
|
+
* The structured Design Brief the discovery dialog produces. Every
|
|
17
|
+
* field optional — the AI fills what the conversation answered; the
|
|
18
|
+
* draft prompts degrade gracefully on gaps. Stored on
|
|
19
|
+
* `site_defaults.design_brief`.
|
|
20
|
+
*/
|
|
21
|
+
export declare const designBriefSchema: z.ZodObject<{
|
|
22
|
+
audience: z.ZodOptional<z.ZodString>;
|
|
23
|
+
moodWords: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
24
|
+
tone: z.ZodOptional<z.ZodString>;
|
|
25
|
+
industry: z.ZodOptional<z.ZodString>;
|
|
26
|
+
differentiators: z.ZodOptional<z.ZodString>;
|
|
27
|
+
imageryDirection: z.ZodOptional<z.ZodString>;
|
|
28
|
+
avoid: z.ZodOptional<z.ZodString>;
|
|
29
|
+
}, z.core.$strict>;
|
|
30
|
+
export type DesignBrief = z.infer<typeof designBriefSchema>;
|
|
31
|
+
/** Complete single-file drafts stay well under this (inline CSS only). */
|
|
32
|
+
export declare const GENESIS_DRAFT_MAX_HTML_BYTES = 300000;
|
|
33
|
+
export declare const genesisDraftStatus: z.ZodEnum<{
|
|
34
|
+
candidate: "candidate";
|
|
35
|
+
selected: "selected";
|
|
36
|
+
discarded: "discarded";
|
|
37
|
+
}>;
|
|
38
|
+
export type GenesisDraftStatus = z.infer<typeof genesisDraftStatus>;
|
|
39
|
+
/** issue #199 — where a draft came from. */
|
|
40
|
+
export declare const genesisDraftSourceKind: z.ZodEnum<{
|
|
41
|
+
genesis: "genesis";
|
|
42
|
+
byod_image: "byod_image";
|
|
43
|
+
byod_html: "byod_html";
|
|
44
|
+
}>;
|
|
45
|
+
export type GenesisDraftSourceKind = z.infer<typeof genesisDraftSourceKind>;
|
|
46
|
+
/**
|
|
47
|
+
* issue #375 — what a draft covers. `site` is the Genesis case (a whole
|
|
48
|
+
* new design); `page` / `module` are growth-time variants of something
|
|
49
|
+
* that already exists.
|
|
50
|
+
*/
|
|
51
|
+
export declare const designDraftScope: z.ZodEnum<{
|
|
52
|
+
module: "module";
|
|
53
|
+
page: "page";
|
|
54
|
+
site: "site";
|
|
55
|
+
}>;
|
|
56
|
+
export type DesignDraftScope = z.infer<typeof designDraftScope>;
|
|
57
|
+
/**
|
|
58
|
+
* issue #375 — how a draft's HTML is stored. `site` drafts are complete
|
|
59
|
+
* standalone documents (Genesis, unchanged); `page`/`module` drafts are
|
|
60
|
+
* fragments that only become a renderable document when composed with
|
|
61
|
+
* the site's real theme shell at view time — so a stored variant never
|
|
62
|
+
* freezes a stale copy of the theme.
|
|
63
|
+
*/
|
|
64
|
+
export declare const designDraftFormat: z.ZodEnum<{
|
|
65
|
+
document: "document";
|
|
66
|
+
fragment: "fragment";
|
|
67
|
+
}>;
|
|
68
|
+
export type DesignDraftFormat = z.infer<typeof designDraftFormat>;
|
|
69
|
+
/** The stored format is fully determined by the scope (see the paired
|
|
70
|
+
* DB CHECK constraint): `site` → standalone document, else fragment. */
|
|
71
|
+
export declare function draftFormatForScope(scope: DesignDraftScope): DesignDraftFormat;
|
|
72
|
+
/** Scope/target pairing rules shared by the op and the AI tool. */
|
|
73
|
+
export declare const genesisAddDraftInput: z.ZodObject<{
|
|
74
|
+
direction: z.ZodString;
|
|
75
|
+
rationale: z.ZodDefault<z.ZodString>;
|
|
76
|
+
html: z.ZodString;
|
|
77
|
+
scope: z.ZodDefault<z.ZodEnum<{
|
|
78
|
+
module: "module";
|
|
79
|
+
page: "page";
|
|
80
|
+
site: "site";
|
|
81
|
+
}>>;
|
|
82
|
+
targetPageId: z.ZodOptional<z.ZodString>;
|
|
83
|
+
targetModuleId: z.ZodOptional<z.ZodString>;
|
|
84
|
+
variantSetId: z.ZodOptional<z.ZodString>;
|
|
85
|
+
sourceKind: z.ZodDefault<z.ZodEnum<{
|
|
86
|
+
genesis: "genesis";
|
|
87
|
+
byod_image: "byod_image";
|
|
88
|
+
byod_html: "byod_html";
|
|
89
|
+
}>>;
|
|
90
|
+
referenceAssetId: z.ZodOptional<z.ZodString>;
|
|
91
|
+
}, z.core.$strict>;
|
|
92
|
+
export type GenesisAddDraftInput = z.infer<typeof genesisAddDraftInput>;
|
|
93
|
+
/**
|
|
94
|
+
* issue #199 — strip <script> blocks from operator-provided draft
|
|
95
|
+
* HTML. Defense in depth: drafts render inside sandbox="" iframes
|
|
96
|
+
* (scripts never execute there), but stored HTML flows onward into
|
|
97
|
+
* materialisation, so the boundary removes them outright. Linear
|
|
98
|
+
* scan per the #113 discipline; case-insensitive; unterminated
|
|
99
|
+
* script blocks drop everything to EOF (never leak half a script).
|
|
100
|
+
*/
|
|
101
|
+
export declare function sanitizeDraftHtml(html: string): string;
|
|
102
|
+
//# sourceMappingURL=genesis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"genesis.d.ts","sourceRoot":"","sources":["../src/genesis.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;kBAWnB,CAAC;AACZ,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,0EAA0E;AAC1E,eAAO,MAAM,4BAA4B,SAAU,CAAC;AAEpD,eAAO,MAAM,kBAAkB;;;;EAAiD,CAAC;AACjF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAEpE,4CAA4C;AAC5C,eAAO,MAAM,sBAAsB;;;;EAAiD,CAAC;AACrF,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAE5E;;;;GAIG;AACH,eAAO,MAAM,gBAAgB;;;;EAAqC,CAAC;AACnE,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEhE;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB;;;EAAmC,CAAC;AAClE,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAElE;yEACyE;AACzE,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,gBAAgB,GAAG,iBAAiB,CAE9E;AA+BD,mEAAmE;AACnE,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;kBA2B/B,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAExE;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAiBtD"}
|