@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
|
@@ -0,0 +1,587 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
2
|
+
/**
|
|
3
|
+
* v0.11.0 — Loose-name → canonical-DTCG-path normalizer for theme
|
|
4
|
+
* tokens (#45, follow-up comment §1).
|
|
5
|
+
*
|
|
6
|
+
* The AI naturally sends prose-shaped inputs ("set primary color to
|
|
7
|
+
* #ff6600", "use Inter for headings") — translating that into
|
|
8
|
+
* `{ primaryColor: "#ff6600", fontHeading: "Inter" }`. The canonical
|
|
9
|
+
* DTCG path is `color.primary.$value` / `typography.heading.fontFamily`.
|
|
10
|
+
* The server normalizes loose names to canonical paths so the AI never
|
|
11
|
+
* has to know the canonical surface up front.
|
|
12
|
+
*
|
|
13
|
+
* Coverage (from the issue's normalization table):
|
|
14
|
+
*
|
|
15
|
+
* primaryColor, colorPrimary, primary + color value → color.primary
|
|
16
|
+
* fontHeading, headingFont, heading-font → typography.heading.fontFamily
|
|
17
|
+
* spacingLg, spacing-lg, lg + CSS length → spacing.lg
|
|
18
|
+
* radiusMd, borderRadius, rounded-md → radius.md
|
|
19
|
+
* shadowSm, shadow-sm, boxShadow → shadow.sm
|
|
20
|
+
* gradient, heroGradient, gradientHero, gradient.hero → gradient.hero
|
|
21
|
+
* color.primary.$value (canonical DTCG path) → passthrough
|
|
22
|
+
* --color-primary (CSS-var) → color.primary
|
|
23
|
+
* "{color.brand.primary}" (DTCG alias) → passthrough at value layer
|
|
24
|
+
*
|
|
25
|
+
* Ambiguity (no value-shape signal) returns `UnknownTokenName` with
|
|
26
|
+
* did-you-mean suggestions, per CLAUDE.md §11 "Failure surfaces are
|
|
27
|
+
* AI-actionable".
|
|
28
|
+
*/
|
|
29
|
+
import { InvalidColorValue, TokenCategoryMismatch, UnknownTokenName } from "./themes-errors.js";
|
|
30
|
+
const COLOR_VALUE_REGEX = /^(#[0-9a-fA-F]{3,8}|(oklch|rgb|rgba|hsl|hsla|lab|lch|color|hwb)\(.+\)|transparent|currentColor)$/;
|
|
31
|
+
const CSS_LENGTH_REGEX = /^-?\d+(\.\d+)?(rem|em|px|%|vh|vw|vmin|vmax|pt|pc|ch|ex)?$/;
|
|
32
|
+
const DURATION_REGEX = /^\d+(\.\d+)?(ms|s)$/;
|
|
33
|
+
const ALIAS_REGEX = /^\{[a-zA-Z0-9_.-]+\}$/;
|
|
34
|
+
const SHADOW_VALUE_REGEX = /^(-?\d+(\.\d+)?(rem|em|px|%)? *){2,5}(.+)?$/;
|
|
35
|
+
// A CSS `*-gradient(...)` value. Mirrors (loosely) the stricter Zod
|
|
36
|
+
// `gradientValueString` in themes.ts — the normalizer only needs to
|
|
37
|
+
// RECOGNISE gradient strings to route them to the gradient category and
|
|
38
|
+
// infer `$type: "gradient"`; the document validator enforces the exact
|
|
39
|
+
// safe shape (no url(), no `;<>{}` breakout) downstream.
|
|
40
|
+
const GRADIENT_VALUE_REGEX = /^(?:repeating-)?(?:linear|radial|conic)-gradient\(.+\)$/i;
|
|
41
|
+
/**
|
|
42
|
+
* The canonical "well-known" tokens the AI is most likely to mean when
|
|
43
|
+
* it sends a bare or category-prefixed name. Used both as the
|
|
44
|
+
* normalization target AND as the suggestion pool when an input is
|
|
45
|
+
* ambiguous.
|
|
46
|
+
*/
|
|
47
|
+
const KNOWN_CANONICAL_PATHS = [
|
|
48
|
+
// colors (shadcn-inspired semantic set)
|
|
49
|
+
"color.background",
|
|
50
|
+
"color.foreground",
|
|
51
|
+
"color.primary",
|
|
52
|
+
"color.primary-foreground",
|
|
53
|
+
"color.secondary",
|
|
54
|
+
"color.secondary-foreground",
|
|
55
|
+
"color.accent",
|
|
56
|
+
"color.accent-foreground",
|
|
57
|
+
"color.muted",
|
|
58
|
+
"color.muted-foreground",
|
|
59
|
+
"color.card",
|
|
60
|
+
"color.card-foreground",
|
|
61
|
+
"color.border",
|
|
62
|
+
"color.ring",
|
|
63
|
+
"color.destructive",
|
|
64
|
+
"color.destructive-foreground",
|
|
65
|
+
"color.warning",
|
|
66
|
+
"color.success",
|
|
67
|
+
// typography (heading + body + display, each with fontFamily as the
|
|
68
|
+
// primary loose-name target; fontSize / fontWeight are addressable
|
|
69
|
+
// via direct DTCG paths)
|
|
70
|
+
"typography.heading.fontFamily",
|
|
71
|
+
"typography.body.fontFamily",
|
|
72
|
+
"typography.display.fontFamily",
|
|
73
|
+
"typography.mono.fontFamily",
|
|
74
|
+
// spacing scale (Tailwind-shaped)
|
|
75
|
+
"spacing.xs",
|
|
76
|
+
"spacing.sm",
|
|
77
|
+
"spacing.md",
|
|
78
|
+
"spacing.lg",
|
|
79
|
+
"spacing.xl",
|
|
80
|
+
"spacing.2xl",
|
|
81
|
+
// radius
|
|
82
|
+
"radius.sm",
|
|
83
|
+
"radius.md",
|
|
84
|
+
"radius.lg",
|
|
85
|
+
"radius.full",
|
|
86
|
+
// shadow
|
|
87
|
+
"shadow.sm",
|
|
88
|
+
"shadow.md",
|
|
89
|
+
"shadow.lg",
|
|
90
|
+
"shadow.xl",
|
|
91
|
+
// gradient (issue #153 — CSS gradient strings emitted as
|
|
92
|
+
// `--gradient-<name>`; `hero` + `subtle` are the seeded slots)
|
|
93
|
+
"gradient.hero",
|
|
94
|
+
"gradient.subtle",
|
|
95
|
+
];
|
|
96
|
+
const CATEGORIES = [
|
|
97
|
+
{
|
|
98
|
+
category: "color",
|
|
99
|
+
nameHints: [
|
|
100
|
+
/color/i,
|
|
101
|
+
/^bg$/i,
|
|
102
|
+
/background/i,
|
|
103
|
+
/foreground/i,
|
|
104
|
+
/destructive/i,
|
|
105
|
+
/primary$/i,
|
|
106
|
+
/secondary$/i,
|
|
107
|
+
/accent$/i,
|
|
108
|
+
/muted$/i,
|
|
109
|
+
/ring$/i,
|
|
110
|
+
/border$/i,
|
|
111
|
+
],
|
|
112
|
+
inferredType: "color",
|
|
113
|
+
buildPath: (basename) => `color.${basename}`,
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
category: "typography",
|
|
117
|
+
nameHints: [/font/i, /typography/i, /heading/i, /body/i, /display/i, /mono/i],
|
|
118
|
+
inferredType: "typography",
|
|
119
|
+
// v0.11.0 fix (#45 review thread): loose typography names target
|
|
120
|
+
// the composite ROOT (`typography.<name>`) — themeTypographyComposite
|
|
121
|
+
// Zod requires `$value` to be an object. The value gets wrapped as
|
|
122
|
+
// `{fontFamily: <input>}` in normalizeTokens (see compositeWrap
|
|
123
|
+
// below). The original sub-path shape (`typography.X.fontFamily`)
|
|
124
|
+
// produced documents Zod rejected.
|
|
125
|
+
buildPath: (basename) => `typography.${basename}`,
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
category: "spacing",
|
|
129
|
+
nameHints: [/^space/i, /^spacing/i, /^gap/i, /^padding/i, /^margin/i],
|
|
130
|
+
inferredType: "dimension",
|
|
131
|
+
buildPath: (basename) => `spacing.${basename}`,
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
category: "radius",
|
|
135
|
+
nameHints: [/radius/i, /rounded/i, /corner/i, /^border-?radius$/i],
|
|
136
|
+
inferredType: "dimension",
|
|
137
|
+
buildPath: (basename) => `radius.${basename}`,
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
category: "shadow",
|
|
141
|
+
nameHints: [/shadow/i, /elevation/i, /^box-?shadow$/i],
|
|
142
|
+
inferredType: "shadow",
|
|
143
|
+
buildPath: (basename) => `shadow.${basename}`,
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
// issue #153 — gradient tokens. Loose names (`gradient`,
|
|
147
|
+
// `heroGradient`, `gradientHero`) + the direct DTCG path
|
|
148
|
+
// (`gradient.hero`) all land in `gradient.<name>` with
|
|
149
|
+
// `$type: "gradient"`. Without this category the normalizer threw
|
|
150
|
+
// `UnknownTokenName` on every loose gradient name (the #1 red-error
|
|
151
|
+
// class in migration chat).
|
|
152
|
+
category: "gradient",
|
|
153
|
+
nameHints: [/gradient/i],
|
|
154
|
+
inferredType: "gradient",
|
|
155
|
+
buildPath: (basename) => `gradient.${basename}`,
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
category: "duration",
|
|
159
|
+
nameHints: [/duration/i, /timing/i],
|
|
160
|
+
inferredType: "duration",
|
|
161
|
+
buildPath: (basename) => `duration.${basename}`,
|
|
162
|
+
},
|
|
163
|
+
];
|
|
164
|
+
const DEFAULT_TIER = "sm"; // shadowSm / radiusMd default
|
|
165
|
+
/**
|
|
166
|
+
* Normalize a record of loose-name → value pairs into canonical DTCG
|
|
167
|
+
* paths. Throws `UnknownTokenName` on the first ambiguous entry so the
|
|
168
|
+
* AI gets a single concrete next-step rather than a wall of partial
|
|
169
|
+
* results.
|
|
170
|
+
*/
|
|
171
|
+
export function normalizeTokens(input) {
|
|
172
|
+
const set = {};
|
|
173
|
+
const types = {};
|
|
174
|
+
const paths = [];
|
|
175
|
+
for (const [rawName, rawValueIn] of Object.entries(input)) {
|
|
176
|
+
// issue #242 (F11) — tolerate the two encodings the AI actually
|
|
177
|
+
// sends for composite values, then validate content strictly:
|
|
178
|
+
// 1. a JSON-encoded object string → parse it;
|
|
179
|
+
// 2. the full DTCG envelope `{$type?, $value}` → unwrap to $value
|
|
180
|
+
// (storing the envelope verbatim would nest `$value.$value`
|
|
181
|
+
// and bounce off the document schema).
|
|
182
|
+
let rawValue = rawValueIn;
|
|
183
|
+
if (typeof rawValue === "string" && rawValue.trim().startsWith("{")) {
|
|
184
|
+
try {
|
|
185
|
+
rawValue = JSON.parse(rawValue);
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
// Not JSON after all — keep the literal string.
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if (rawValue !== null &&
|
|
192
|
+
typeof rawValue === "object" &&
|
|
193
|
+
!Array.isArray(rawValue) &&
|
|
194
|
+
"$value" in rawValue) {
|
|
195
|
+
rawValue = rawValue.$value;
|
|
196
|
+
}
|
|
197
|
+
const resolved = resolveOne(rawName, rawValue);
|
|
198
|
+
// v0.11.0 fix (#45 review thread on theme-normalize.ts:149) —
|
|
199
|
+
// typography is a composite; `$value` MUST be an object per the
|
|
200
|
+
// Zod schema. When the loose input (or a direct `typography.X.<sub>`
|
|
201
|
+
// DTCG path, or a `--font-X` / `--text-X` CSS-var) implied a single
|
|
202
|
+
// sub-field, wrap the scalar value as `{[subField]: value}` so the
|
|
203
|
+
// resulting document validates. applyDtcgWrites merges this into
|
|
204
|
+
// any existing typography composite at the path so partial updates
|
|
205
|
+
// don't erase sibling sub-fields.
|
|
206
|
+
let storedValue = rawValue;
|
|
207
|
+
if (resolved.compositeWrap && typeof rawValue === "string" && !ALIAS_REGEX.test(rawValue)) {
|
|
208
|
+
storedValue = { [resolved.compositeWrap]: rawValue };
|
|
209
|
+
}
|
|
210
|
+
else if (resolved.inferredType === "gradient" &&
|
|
211
|
+
typeof rawValue === "object" &&
|
|
212
|
+
rawValue !== null &&
|
|
213
|
+
!Array.isArray(rawValue)) {
|
|
214
|
+
// issue #153 — the AI sometimes sends a structured gradient
|
|
215
|
+
// (`{type, angle, stops}`) instead of the CSS string the DTCG
|
|
216
|
+
// gradient token stores. Fold it into the canonical
|
|
217
|
+
// `linear-gradient(...)` form so the document validates and the
|
|
218
|
+
// renderer emits a real `--gradient-<name>`. Unrecognised shapes
|
|
219
|
+
// pass through untouched so the document validator produces the
|
|
220
|
+
// actionable "gradient must be a CSS *-gradient(...) value" error
|
|
221
|
+
// rather than us silently inventing a gradient (CLAUDE.md §2).
|
|
222
|
+
storedValue = gradientObjectToCss(rawValue) ?? rawValue;
|
|
223
|
+
}
|
|
224
|
+
set[resolved.path] = storedValue;
|
|
225
|
+
types[resolved.path] = resolved.inferredType;
|
|
226
|
+
paths.push(resolved.path);
|
|
227
|
+
}
|
|
228
|
+
return { set, types, canonicalPaths: paths };
|
|
229
|
+
}
|
|
230
|
+
function resolveOne(rawName, rawValue) {
|
|
231
|
+
// 1. Direct canonical DTCG paths: pass through unchanged. Typography
|
|
232
|
+
// sub-paths (`typography.X.fontFamily` / `.fontSize` / …) collapse
|
|
233
|
+
// onto the composite root so the leaf carries `$value: {sub: val}`.
|
|
234
|
+
if (/^[a-z][a-z0-9_-]*(\.[a-z0-9_-]+)+(\.\$value)?$/i.test(rawName)) {
|
|
235
|
+
const path = rawName.replace(/\.\$value$/, "");
|
|
236
|
+
const parts = path.split(".");
|
|
237
|
+
const category = parts[0] ?? "";
|
|
238
|
+
if (category === "typography" &&
|
|
239
|
+
parts.length === 3 &&
|
|
240
|
+
isTypographyCompositeSubField(parts[2])) {
|
|
241
|
+
return {
|
|
242
|
+
path: `${parts[0]}.${parts[1]}`,
|
|
243
|
+
inferredType: "typography",
|
|
244
|
+
compositeWrap: parts[2],
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
validateValueShape(category, rawValue, path);
|
|
248
|
+
return { path, inferredType: inferTypeFromPath(path, rawValue) };
|
|
249
|
+
}
|
|
250
|
+
// 2. CSS-var form: `--color-primary` → `color.primary`.
|
|
251
|
+
if (rawName.startsWith("--")) {
|
|
252
|
+
const stripped = rawName.slice(2);
|
|
253
|
+
const firstHyphen = stripped.indexOf("-");
|
|
254
|
+
if (firstHyphen > 0) {
|
|
255
|
+
const category = stripped.slice(0, firstHyphen);
|
|
256
|
+
const rest = stripped.slice(firstHyphen + 1);
|
|
257
|
+
// Tailwind 4 typography split (--font + --text) maps onto the
|
|
258
|
+
// composite root with the right sub-field set; the value gets
|
|
259
|
+
// wrapped into `{fontFamily}` / `{fontSize}` by normalizeTokens
|
|
260
|
+
// so the leaf matches themeTypographyComposite.
|
|
261
|
+
if (category === "font") {
|
|
262
|
+
return {
|
|
263
|
+
path: `typography.${rest}`,
|
|
264
|
+
inferredType: "typography",
|
|
265
|
+
compositeWrap: "fontFamily",
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
if (category === "text") {
|
|
269
|
+
validateValueShape("spacing", rawValue, `typography.${rest}`);
|
|
270
|
+
return {
|
|
271
|
+
path: `typography.${rest}`,
|
|
272
|
+
inferredType: "typography",
|
|
273
|
+
compositeWrap: "fontSize",
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
const path = `${category}.${rest}`;
|
|
277
|
+
validateValueShape(category, rawValue, path);
|
|
278
|
+
return { path, inferredType: inferTypeFromPath(path, rawValue) };
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
// 3. Name-shape category hint.
|
|
282
|
+
const matched = [];
|
|
283
|
+
for (const cat of CATEGORIES) {
|
|
284
|
+
if (cat.nameHints.some((re) => re.test(rawName)))
|
|
285
|
+
matched.push(cat);
|
|
286
|
+
}
|
|
287
|
+
// 4. Value-shape signal — disambiguates when the name is bare or
|
|
288
|
+
// matched multiple categories.
|
|
289
|
+
const valueCategory = sniffCategoryFromValue(rawValue);
|
|
290
|
+
let chosen;
|
|
291
|
+
if (matched.length === 1) {
|
|
292
|
+
chosen = matched[0];
|
|
293
|
+
}
|
|
294
|
+
else if (matched.length > 1) {
|
|
295
|
+
// Prefer the category whose inferred type matches the value shape.
|
|
296
|
+
chosen = matched.find((m) => m.inferredType === valueCategory) ?? matched[0];
|
|
297
|
+
}
|
|
298
|
+
else if (valueCategory) {
|
|
299
|
+
// Bare name but value hints — pick category by value.
|
|
300
|
+
chosen = CATEGORIES.find((c) => c.inferredType === valueCategory);
|
|
301
|
+
}
|
|
302
|
+
if (!chosen) {
|
|
303
|
+
throw new UnknownTokenName(rawName, didYouMean(rawName));
|
|
304
|
+
}
|
|
305
|
+
// 5. Extract basename: strip category prefix + camel/kebab.
|
|
306
|
+
const basename = extractBasename(rawName, chosen.category);
|
|
307
|
+
const path = basename
|
|
308
|
+
? chosen.buildPath(basename)
|
|
309
|
+
: // Bare category word ("color" / "shadow") — pick the default tier
|
|
310
|
+
// (`primary` for color, `sm` for shadow/radius, etc.).
|
|
311
|
+
chosen.buildPath(defaultTier(chosen.category));
|
|
312
|
+
validateValueShape(chosen.category, rawValue, path);
|
|
313
|
+
// Typography is a composite — loose names imply a single sub-field
|
|
314
|
+
// (fontFamily by convention). The wrap happens in normalizeTokens.
|
|
315
|
+
if (chosen.category === "typography") {
|
|
316
|
+
return { path, inferredType: chosen.inferredType, compositeWrap: "fontFamily" };
|
|
317
|
+
}
|
|
318
|
+
return { path, inferredType: chosen.inferredType };
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Sub-field keys recognised by `themeTypographyComposite`. Used to
|
|
322
|
+
* detect direct DTCG sub-paths like `typography.heading.fontFamily`
|
|
323
|
+
* and collapse them onto the composite root with a wrapped value.
|
|
324
|
+
*/
|
|
325
|
+
function isTypographyCompositeSubField(segment) {
|
|
326
|
+
return (segment === "fontFamily" ||
|
|
327
|
+
segment === "fontSize" ||
|
|
328
|
+
segment === "fontWeight" ||
|
|
329
|
+
segment === "lineHeight" ||
|
|
330
|
+
segment === "letterSpacing");
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* v0.11.0 (#45 AC #7) — fail-fast value-shape validation for the
|
|
334
|
+
* AI-actionable error surface. Catches:
|
|
335
|
+
*
|
|
336
|
+
* - color slot + string value that isn't a valid CSS color
|
|
337
|
+
* → InvalidColorValue (carries supportedFormats list).
|
|
338
|
+
* - any slot + value whose sniffed category disagrees with the
|
|
339
|
+
* resolved slot's category → TokenCategoryMismatch (carries
|
|
340
|
+
* expected vs got).
|
|
341
|
+
*
|
|
342
|
+
* Aliases (`{color.primary}`) bypass — they're resolved at render
|
|
343
|
+
* time and may legitimately point at a value of any shape. Non-string
|
|
344
|
+
* values (numbers, composite objects) also bypass because the AI
|
|
345
|
+
* passes those only on direct DTCG paths where the Zod composite
|
|
346
|
+
* schema validates the shape downstream.
|
|
347
|
+
*
|
|
348
|
+
* Typography sub-paths (`typography.<name>.fontFamily`) skip the
|
|
349
|
+
* check because fontFamily accepts free-form strings.
|
|
350
|
+
*/
|
|
351
|
+
function validateValueShape(category, value, canonicalPath) {
|
|
352
|
+
if (typeof value !== "string")
|
|
353
|
+
return;
|
|
354
|
+
if (ALIAS_REGEX.test(value))
|
|
355
|
+
return;
|
|
356
|
+
if (category === "color") {
|
|
357
|
+
if (COLOR_VALUE_REGEX.test(value))
|
|
358
|
+
return;
|
|
359
|
+
const sniffed = sniffCategoryFromValue(value);
|
|
360
|
+
if (sniffed && sniffed !== "color") {
|
|
361
|
+
throw new TokenCategoryMismatch(canonicalPath, "color", sniffed);
|
|
362
|
+
}
|
|
363
|
+
throw new InvalidColorValue(value);
|
|
364
|
+
}
|
|
365
|
+
if (category === "spacing" || category === "radius" || category === "breakpoint") {
|
|
366
|
+
const sniffed = sniffCategoryFromValue(value);
|
|
367
|
+
if (sniffed && sniffed !== "dimension") {
|
|
368
|
+
throw new TokenCategoryMismatch(canonicalPath, "dimension", sniffed);
|
|
369
|
+
}
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
if (category === "duration") {
|
|
373
|
+
const sniffed = sniffCategoryFromValue(value);
|
|
374
|
+
if (sniffed && sniffed !== "duration") {
|
|
375
|
+
throw new TokenCategoryMismatch(canonicalPath, "duration", sniffed);
|
|
376
|
+
}
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
if (category === "gradient") {
|
|
380
|
+
if (GRADIENT_VALUE_REGEX.test(value))
|
|
381
|
+
return;
|
|
382
|
+
const sniffed = sniffCategoryFromValue(value);
|
|
383
|
+
if (sniffed && sniffed !== "gradient") {
|
|
384
|
+
// e.g. a flat color string sent to `gradient.hero` — name the
|
|
385
|
+
// mismatch instead of letting Zod reject with a vaguer message.
|
|
386
|
+
throw new TokenCategoryMismatch(canonicalPath, "gradient", sniffed);
|
|
387
|
+
}
|
|
388
|
+
// Not a recognised gradient and not clearly another category — defer
|
|
389
|
+
// to the document validator's precise "gradient must be a CSS
|
|
390
|
+
// *-gradient(...) value" message rather than guessing here.
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
// shadow / typography composites + unknown categories: caller's
|
|
394
|
+
// responsibility to pass a structurally-correct value; Zod catches
|
|
395
|
+
// the rest at validateThemeTokens time.
|
|
396
|
+
}
|
|
397
|
+
function inferTypeFromPath(path, value) {
|
|
398
|
+
const head = path.split(".")[0] ?? "";
|
|
399
|
+
switch (head) {
|
|
400
|
+
case "color":
|
|
401
|
+
return "color";
|
|
402
|
+
case "typography":
|
|
403
|
+
// Composite vs sub-field. A `.fontFamily` / `.fontSize` etc.
|
|
404
|
+
// suffix lives inside the composite — type stays "typography"
|
|
405
|
+
// for top-level + "dimension" / "color" / etc. for sub-fields
|
|
406
|
+
// depending on which slot. Caller stores at the composite root
|
|
407
|
+
// anyway, so this stays "typography" for any typography.* path.
|
|
408
|
+
return "typography";
|
|
409
|
+
case "spacing":
|
|
410
|
+
case "radius":
|
|
411
|
+
case "breakpoint":
|
|
412
|
+
return "dimension";
|
|
413
|
+
case "shadow":
|
|
414
|
+
return "shadow";
|
|
415
|
+
case "gradient":
|
|
416
|
+
// issue #153 — MUST return "gradient" (not the sniffed value
|
|
417
|
+
// category). The gradient token's `$type` is `z.literal("gradient")`;
|
|
418
|
+
// before this case, `gradient.hero` fell through to `default`, the
|
|
419
|
+
// gradient string sniffed as no known category → "dimension", and
|
|
420
|
+
// the stamped `$type: "dimension"` bounced off the document
|
|
421
|
+
// validator ("gradient token invalid: expected \"gradient\"").
|
|
422
|
+
return "gradient";
|
|
423
|
+
case "duration":
|
|
424
|
+
return "duration";
|
|
425
|
+
case "ease":
|
|
426
|
+
return "cubicBezier";
|
|
427
|
+
default: {
|
|
428
|
+
const sniffed = sniffCategoryFromValue(value);
|
|
429
|
+
return sniffed ?? "dimension";
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
function sniffCategoryFromValue(value) {
|
|
434
|
+
if (typeof value !== "string")
|
|
435
|
+
return undefined;
|
|
436
|
+
if (ALIAS_REGEX.test(value))
|
|
437
|
+
return undefined; // alias has no value shape
|
|
438
|
+
// Gradient before color: a `linear-gradient(...)` string could loosely
|
|
439
|
+
// read as a `color(...)`-shaped function otherwise.
|
|
440
|
+
if (GRADIENT_VALUE_REGEX.test(value))
|
|
441
|
+
return "gradient";
|
|
442
|
+
if (COLOR_VALUE_REGEX.test(value))
|
|
443
|
+
return "color";
|
|
444
|
+
if (DURATION_REGEX.test(value))
|
|
445
|
+
return "duration";
|
|
446
|
+
if (SHADOW_VALUE_REGEX.test(value) && /\s/.test(value))
|
|
447
|
+
return "shadow";
|
|
448
|
+
if (CSS_LENGTH_REGEX.test(value))
|
|
449
|
+
return "dimension";
|
|
450
|
+
return undefined;
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Pull the meaningful basename out of a loose name. `primaryColor` /
|
|
454
|
+
* `colorPrimary` / `primary-color` all reduce to `primary`. Plural
|
|
455
|
+
* forms (`spacingLg`) lose the category prefix to leave the tier (`lg`).
|
|
456
|
+
*
|
|
457
|
+
* Returns null when the input IS the category word alone.
|
|
458
|
+
*/
|
|
459
|
+
function extractBasename(rawName, category) {
|
|
460
|
+
// Lowercase camelCase → kebab-case for uniform tokenisation.
|
|
461
|
+
const kebab = rawName.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
|
|
462
|
+
const parts = kebab.split(/[-_]+/);
|
|
463
|
+
// Filter out category aliases (font / typography / heading-related
|
|
464
|
+
// names) AND the literal category itself.
|
|
465
|
+
const aliasesFor = {
|
|
466
|
+
color: ["color"],
|
|
467
|
+
typography: ["font", "typography"],
|
|
468
|
+
spacing: ["space", "spacing", "gap", "padding", "margin"],
|
|
469
|
+
radius: ["radius", "rounded", "border", "borderradius", "border-radius", "corner"],
|
|
470
|
+
shadow: ["shadow", "box", "boxshadow", "box-shadow", "elevation"],
|
|
471
|
+
duration: ["duration", "timing"],
|
|
472
|
+
gradient: ["gradient"],
|
|
473
|
+
};
|
|
474
|
+
const aliases = new Set(aliasesFor[category] ?? [category]);
|
|
475
|
+
const meaningful = parts.filter((p) => p.length > 0 && !aliases.has(p));
|
|
476
|
+
if (meaningful.length === 0)
|
|
477
|
+
return null;
|
|
478
|
+
return meaningful.join("-");
|
|
479
|
+
}
|
|
480
|
+
function defaultTier(category) {
|
|
481
|
+
switch (category) {
|
|
482
|
+
case "color":
|
|
483
|
+
return "primary";
|
|
484
|
+
case "typography":
|
|
485
|
+
return "body";
|
|
486
|
+
case "spacing":
|
|
487
|
+
return "md";
|
|
488
|
+
case "radius":
|
|
489
|
+
return "md";
|
|
490
|
+
case "shadow":
|
|
491
|
+
return DEFAULT_TIER;
|
|
492
|
+
case "duration":
|
|
493
|
+
return "fast";
|
|
494
|
+
case "gradient":
|
|
495
|
+
// The seeded default theme ships `gradient.hero` + `gradient.subtle`;
|
|
496
|
+
// a bare `gradient` almost always means the primary/hero surface.
|
|
497
|
+
return "hero";
|
|
498
|
+
default:
|
|
499
|
+
return "default";
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* issue #153 — best-effort structured-gradient → CSS-string converter.
|
|
504
|
+
*
|
|
505
|
+
* The DTCG gradient token stores a CSS `*-gradient(...)` string (see
|
|
506
|
+
* `themeGradientToken` in themes.ts). When the AI sends a structured
|
|
507
|
+
* shape instead, fold the RECOGNISED subset into that string:
|
|
508
|
+
*
|
|
509
|
+
* `{ type?: "linear"|"radial"|"conic", angle?: string|number,
|
|
510
|
+
* direction?: string, stops: Array<string | {color, position?}> }`
|
|
511
|
+
*
|
|
512
|
+
* → `linear-gradient(135deg, #4f46e5, #7c3aed 100%)`
|
|
513
|
+
*
|
|
514
|
+
* Returns `undefined` (caller keeps the raw value so the document
|
|
515
|
+
* validator emits its precise error) when the shape carries no usable
|
|
516
|
+
* stops — we never fabricate a gradient from nothing (CLAUDE.md §2).
|
|
517
|
+
*/
|
|
518
|
+
function gradientObjectToCss(obj) {
|
|
519
|
+
const rawStops = obj.stops;
|
|
520
|
+
if (!Array.isArray(rawStops) || rawStops.length < 2)
|
|
521
|
+
return undefined;
|
|
522
|
+
const stops = [];
|
|
523
|
+
for (const s of rawStops) {
|
|
524
|
+
if (typeof s === "string" && s.trim().length > 0) {
|
|
525
|
+
stops.push(s.trim());
|
|
526
|
+
continue;
|
|
527
|
+
}
|
|
528
|
+
if (s !== null && typeof s === "object" && !Array.isArray(s)) {
|
|
529
|
+
const stop = s;
|
|
530
|
+
const color = typeof stop.color === "string" ? stop.color.trim() : undefined;
|
|
531
|
+
if (!color)
|
|
532
|
+
return undefined;
|
|
533
|
+
const pos = typeof stop.position === "string"
|
|
534
|
+
? stop.position.trim()
|
|
535
|
+
: typeof stop.position === "number"
|
|
536
|
+
? `${stop.position}%`
|
|
537
|
+
: undefined;
|
|
538
|
+
stops.push(pos ? `${color} ${pos}` : color);
|
|
539
|
+
continue;
|
|
540
|
+
}
|
|
541
|
+
return undefined; // unrecognised stop entry — don't guess
|
|
542
|
+
}
|
|
543
|
+
const type = obj.type === "radial" || obj.type === "conic" || obj.type === "linear" ? obj.type : "linear";
|
|
544
|
+
// Leading orientation argument. Linear/conic accept an angle; radial
|
|
545
|
+
// accepts a shape/extent hint via `direction`. Only linear gets a
|
|
546
|
+
// default angle so a bare `{stops}` still reads as a diagonal sweep.
|
|
547
|
+
let head = "";
|
|
548
|
+
if (typeof obj.direction === "string" && obj.direction.trim().length > 0) {
|
|
549
|
+
head = obj.direction.trim();
|
|
550
|
+
}
|
|
551
|
+
else if (obj.angle !== undefined && obj.angle !== null) {
|
|
552
|
+
const a = obj.angle;
|
|
553
|
+
head = typeof a === "number" ? `${a}deg` : String(a).trim();
|
|
554
|
+
}
|
|
555
|
+
else if (type === "linear") {
|
|
556
|
+
head = "135deg";
|
|
557
|
+
}
|
|
558
|
+
const args = head ? `${head}, ${stops.join(", ")}` : stops.join(", ");
|
|
559
|
+
return `${type}-gradient(${args})`;
|
|
560
|
+
}
|
|
561
|
+
/**
|
|
562
|
+
* Closest-match suggestions for an unknown input. Cheap edit-distance
|
|
563
|
+
* over the canonical-paths set — good enough that the AI gets a useful
|
|
564
|
+
* "did you mean X?" without pulling a fuzzy-search dep.
|
|
565
|
+
*/
|
|
566
|
+
export function didYouMean(input) {
|
|
567
|
+
const lower = input.toLowerCase();
|
|
568
|
+
return KNOWN_CANONICAL_PATHS.map((p) => ({ path: p, score: similarity(lower, p.toLowerCase()) }))
|
|
569
|
+
.filter((c) => c.score >= 0.4)
|
|
570
|
+
.sort((a, b) => b.score - a.score)
|
|
571
|
+
.slice(0, 3)
|
|
572
|
+
.map((c) => c.path);
|
|
573
|
+
}
|
|
574
|
+
function similarity(a, b) {
|
|
575
|
+
const tokensA = new Set(tokenise(a));
|
|
576
|
+
const tokensB = new Set(tokenise(b));
|
|
577
|
+
let hits = 0;
|
|
578
|
+
for (const t of tokensA)
|
|
579
|
+
if (tokensB.has(t))
|
|
580
|
+
hits++;
|
|
581
|
+
const max = Math.max(tokensA.size, tokensB.size);
|
|
582
|
+
return max === 0 ? 0 : hits / max;
|
|
583
|
+
}
|
|
584
|
+
function tokenise(s) {
|
|
585
|
+
return s.split(/[.\-_]/).filter((p) => p.length > 0);
|
|
586
|
+
}
|
|
587
|
+
//# sourceMappingURL=theme-normalize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-normalize.js","sourceRoot":"","sources":["../src/theme-normalize.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { ThemeDocument } from "./themes.js";
|
|
2
|
+
/**
|
|
3
|
+
* v0.11.1 — failure surface for the OKLCh ramp generator. Carries the
|
|
4
|
+
* supported color input formats so the AI's next turn can fix the
|
|
5
|
+
* input without round-tripping (CLAUDE.md §11 AI-actionable errors).
|
|
6
|
+
*/
|
|
7
|
+
export declare class InvalidSeedColor extends Error {
|
|
8
|
+
readonly kind: "InvalidSeedColor";
|
|
9
|
+
readonly input: string;
|
|
10
|
+
readonly supportedFormats: readonly string[];
|
|
11
|
+
constructor(input: string);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* One ramp stop as a DTCG token leaf. The `_derived: true` annotation
|
|
15
|
+
* is a Caelo extension (sits under DTCG's open `$extensions`-style
|
|
16
|
+
* tolerance) so the admin UI can mark derived stops visually and the
|
|
17
|
+
* operator's explicit overrides can layer cleanly on top.
|
|
18
|
+
*/
|
|
19
|
+
export interface DerivedRampStop {
|
|
20
|
+
readonly $value: string;
|
|
21
|
+
readonly $type: "color";
|
|
22
|
+
readonly _derived: true;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Return shape: a DTCG group (`Record<string, DerivedRampStop | alias>`)
|
|
26
|
+
* intended to be merged at `color.primary` plus the list of canonical
|
|
27
|
+
* paths the generator wrote (for echo-back in the propose preview).
|
|
28
|
+
*/
|
|
29
|
+
export interface RampResult {
|
|
30
|
+
readonly tokens: Record<string, DerivedRampStop | {
|
|
31
|
+
$value: string;
|
|
32
|
+
$type: "color";
|
|
33
|
+
_derived: true;
|
|
34
|
+
}>;
|
|
35
|
+
readonly derivedPaths: readonly string[];
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Derive a 10-stop OKLCh primary-color ramp from a seed color.
|
|
39
|
+
*
|
|
40
|
+
* @param seedColor — any CSS color string. The seed's chroma + hue are
|
|
41
|
+
* preserved; lightness shifts to each ramp stop.
|
|
42
|
+
* @returns A DTCG group ready to write at `color.primary`.
|
|
43
|
+
* @throws InvalidSeedColor when the input doesn't parse as a CSS color.
|
|
44
|
+
*/
|
|
45
|
+
export declare function deriveOklchPrimaryRamp(seedColor: string): RampResult;
|
|
46
|
+
/**
|
|
47
|
+
* Merge a ramp result into a tokens document at `color.primary`,
|
|
48
|
+
* preserving any operator-supplied explicit stops in `overrides`
|
|
49
|
+
* (`{"color.primary.500": "#ff0000"}` keeps the explicit stop AND the
|
|
50
|
+
* derived ramp around it — explicit-wins precedence per Risk §6.2).
|
|
51
|
+
*
|
|
52
|
+
* Returns a fresh document; input is not mutated.
|
|
53
|
+
*/
|
|
54
|
+
export declare function mergeRampIntoTokens(baseTokens: ThemeDocument, ramp: RampResult, explicitOverrides: Record<string, unknown>): ThemeDocument;
|
|
55
|
+
//# sourceMappingURL=theme-ramp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-ramp.d.ts","sourceRoot":"","sources":["../src/theme-ramp.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD;;;;GAIG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,IAAI,EAAG,kBAAkB,CAAU;IAC5C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;gBACjC,KAAK,EAAE,MAAM;CAiB1B;AAcD;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC;CACzB;AAED;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CACrB,MAAM,EACN,eAAe,GAAG;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,IAAI,CAAA;KAAE,CACrE,CAAC;IACF,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,CA4CpE;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,aAAa,EACzB,IAAI,EAAE,UAAU,EAChB,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACzC,aAAa,CA0Bf"}
|