@theme-registry/refract 0.1.0 → 0.1.2
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 +191 -0
- package/dist/_errors-be768b25.cjs.js.map +1 -1
- package/dist/_errors-d75a5c74.esm.js.map +1 -1
- package/dist/build.cjs.js +1 -1
- package/dist/build.cjs.js.map +1 -1
- package/dist/build.esm.js +1 -1
- package/dist/build.esm.js.map +1 -1
- package/dist/cli.js +69 -24
- package/dist/cli.js.map +1 -1
- package/dist/core/assertRawTheme.d.ts +2 -0
- package/dist/core/errors.d.ts +5 -2
- package/dist/core/index.d.ts +1 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
- package/skills/adapter-scaffold/SKILL.md +2 -2
- package/skills/adapter-usage/SKILL.md +1 -1
- package/skills/colors/SKILL.md +1 -1
- package/skills/layout/SKILL.md +1 -1
- package/skills/theme-authoring/SKILL.md +1 -1
- package/skills/typography/SKILL.md +1 -1
- package/skills/visual-effects/SKILL.md +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# @theme-registry/refract
|
|
2
|
+
|
|
3
|
+
[](https://github.com/theme-registry/refract/actions/workflows/ci.yml)
|
|
4
|
+
|
|
5
|
+
A framework-agnostic design-token toolkit. You author one **raw theme**; refract
|
|
6
|
+
compiles it into a single, format-neutral **Model** and lowers that Model to whatever
|
|
7
|
+
output you need through an **adapter** — CSS custom properties, styled-components,
|
|
8
|
+
SCSS `$variables`, or plain JSON. One source of truth, many targets.
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
raw theme ──▶ Model (format-neutral) ──▶ adapter ──▶ CSS │ styled-components │ SCSS │ JSON
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
> **Status: `0.x` (pinned).** Published on npm as `@theme-registry/refract`. Pin exact versions
|
|
15
|
+
> through `0.x`. **Docs, live playground & API reference:** <https://theme-registry.github.io/refract/>
|
|
16
|
+
|
|
17
|
+
## Stability
|
|
18
|
+
|
|
19
|
+
| Surface | Package | Tier |
|
|
20
|
+
| --- | --- | --- |
|
|
21
|
+
| Core + CLI (incl. DTCG interop at `/dtcg`) | `@theme-registry/refract` | **Stable** |
|
|
22
|
+
| CSS adapter | `@theme-registry/refract-css` | **Stable** |
|
|
23
|
+
| styled-components adapter | `@theme-registry/refract-styled-components` | **Stable** |
|
|
24
|
+
| MCP server (agent query surface) | `@theme-registry/refract-mcp` | **Stable** |
|
|
25
|
+
| SCSS adapter | `@theme-registry/refract-scss` | Experimental |
|
|
26
|
+
| JSON adapter | `@theme-registry/refract-json` | Experimental |
|
|
27
|
+
|
|
28
|
+
**Stable** — breaking changes are deliberate, announced events. **Experimental** — the shape may
|
|
29
|
+
still change; these adapters are reachable via the npm `experimental` dist-tag.
|
|
30
|
+
|
|
31
|
+
## Versioning
|
|
32
|
+
|
|
33
|
+
All packages share **one lockstep version** through the `0.x` line (a Changesets `fixed` group) and
|
|
34
|
+
publish together. Tiers are signalled by npm dist-tag, not by divergent versions. **Pin exact
|
|
35
|
+
versions** until `1.0`, when the group splits into independent lines. Details: **[RELEASING.md](RELEASING.md)**.
|
|
36
|
+
|
|
37
|
+
**Token paths are stable identifiers.** A token path (`colors.brand.dark`) is treated as public API —
|
|
38
|
+
it won't change or disappear within a minor/patch release, so agents, the `guide` manifest (`schema`-
|
|
39
|
+
versioned), and DTCG round-trips can bind to it. Removals/renames are breaking (major) changes.
|
|
40
|
+
|
|
41
|
+
## Install
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npm install @theme-registry/refract
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
`styled-components` and `typescript` are **optional** peers — only needed if you use the
|
|
48
|
+
styled-components adapter or the `.ts` build config, respectively.
|
|
49
|
+
|
|
50
|
+
## Quick start
|
|
51
|
+
|
|
52
|
+
`createTheme(raw, { adapter })` builds the theme. The `adapter` is **required** — core
|
|
53
|
+
ships no default, which is what keeps it format-neutral.
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
import { createTheme } from "@theme-registry/refract";
|
|
57
|
+
import { createCssAdapter } from "@theme-registry/refract-css"; // adapters are separate packages
|
|
58
|
+
|
|
59
|
+
const theme = createTheme(
|
|
60
|
+
{
|
|
61
|
+
breakpoints: { sm: 576, md: 768, lg: 1024 },
|
|
62
|
+
colors: {
|
|
63
|
+
brand: { base: "#4c6ef5", text: "#ffffff" }, // → brand, brand.text, brand.light/dark/…
|
|
64
|
+
recipes: {
|
|
65
|
+
solid: { brand: { background: "brand", color: "brand.text" } },
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
{ adapter: createCssAdapter() },
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
theme.css; // the full stylesheet (:root vars + .classes)
|
|
73
|
+
theme.tokens["colors.brand"]; // { ref?: string, value?: … } — the flat token map
|
|
74
|
+
theme.resolveToken("colors.brand.dark"); // "#3d58c4" — derived step (follows aliases + runs derivations)
|
|
75
|
+
theme.classes; // recipe → className map
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Swap the adapter, keep the raw theme:
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
import { createScssAdapter } from "@theme-registry/refract-scss"; // each adapter is its own package
|
|
82
|
+
const scss = createTheme(raw, { adapter: createScssAdapter() }); // scss.scss → $variables + classes
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Authoring the raw theme
|
|
86
|
+
|
|
87
|
+
The raw theme is the file you live in. It is one key per **subsystem**, each with
|
|
88
|
+
properties and an optional nested `recipes` block:
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
import type { RawTheme } from "@theme-registry/refract/build";
|
|
92
|
+
|
|
93
|
+
const raw = {
|
|
94
|
+
breakpoints: { sm: 576, md: 768, lg: 1024 },
|
|
95
|
+
|
|
96
|
+
colors: { /* palettes: hex | { base, text, variants, steps, responsive } + recipes */ },
|
|
97
|
+
typography: { /* fontFamily/Size/Weight/lineHeight/… (modular scale) + recipes */ },
|
|
98
|
+
effects: { /* radius/shadow/transitions/opacity/zIndex/blur/… + recipes */ },
|
|
99
|
+
layout: { /* spacing/gutters + columns/grids/stacks/container + recipes */ },
|
|
100
|
+
components: { /* composition-only: recipes that reference other subsystems' recipes */ },
|
|
101
|
+
} satisfies RawTheme;
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Property values can be **literals** (`"#4c6ef5"`, `16`), **references** to other tokens
|
|
105
|
+
(`color: "brand.text"`), and carry **responsive / variant / target** overrides keyed on
|
|
106
|
+
your breakpoints. Recipes group reusable rule-sets with **states** (`hover`, `disabled`, …).
|
|
107
|
+
Full field-by-field walkthrough: **[docs/authoring.md](https://github.com/theme-registry/refract/blob/main/docs/authoring.md)**.
|
|
108
|
+
|
|
109
|
+
## Adapters — the multi-format thesis
|
|
110
|
+
|
|
111
|
+
Every adapter consumes the same Model and decides how to realize it. Four ship in-box:
|
|
112
|
+
|
|
113
|
+
Core ships **zero** adapters; each is its own installable package (`npm i @theme-registry/refract-<name>`).
|
|
114
|
+
|
|
115
|
+
| Adapter | Package | Output | Notes |
|
|
116
|
+
| --- | --- | --- | --- |
|
|
117
|
+
| **CSS** | `@theme-registry/refract-css` | `:root` custom properties + classes | the batteries-included default |
|
|
118
|
+
| **styled-components** | `@theme-registry/refract-styled-components` | `css` blocks + `createGlobalStyle` + `theme.media` | needs the `styled-components` peer |
|
|
119
|
+
| **SCSS** | `@theme-registry/refract-scss` | compile-time `$variables` + classes from Sass | `TUnit = string`, a genuinely distinct format |
|
|
120
|
+
| **JSON** | `@theme-registry/refract-json` | the full Model as address-keyed data | `TUnit = object` — proves the contract is format-generic |
|
|
121
|
+
|
|
122
|
+
Write your own with `defineAdapter(spec)` — you fill four primitives (`recipeName`,
|
|
123
|
+
`renderRecipe`, `renderVariables`, `join`) and core supplies the rest. See
|
|
124
|
+
**[docs/extending.md](https://github.com/theme-registry/refract/blob/main/docs/extending.md)** or run the `adapter-scaffold` skill.
|
|
125
|
+
|
|
126
|
+
## Build to disk (CLI)
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
npx refract init # scaffold a theme.config.(ts|js|mjs)
|
|
130
|
+
npx refract build # load the config → write every target's files to its outDir
|
|
131
|
+
npx refract tokens # export theme.tokens as a DTCG tokens.json (adapter-free)
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
`theme.config.ts` is your code — it imports the adapters (and the raw theme) it wants:
|
|
135
|
+
|
|
136
|
+
```ts
|
|
137
|
+
import { defineConfig } from "@theme-registry/refract/build";
|
|
138
|
+
import { createCssAdapter } from "@theme-registry/refract-css";
|
|
139
|
+
import { raw } from "./theme.raw"; // a native, RawTheme-typed sibling .ts (graph-compiled)
|
|
140
|
+
|
|
141
|
+
export default defineConfig({
|
|
142
|
+
raw,
|
|
143
|
+
targets: [
|
|
144
|
+
{ name: "css", adapter: createCssAdapter(), outDir: "dist/theme" },
|
|
145
|
+
{ name: "split", adapter: createCssAdapter(), outDir: "dist/split", emit: { type: "split" } },
|
|
146
|
+
],
|
|
147
|
+
});
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### `emit` — how output is written
|
|
151
|
+
|
|
152
|
+
Each target's `emit` picks the output shape (CSS adapter):
|
|
153
|
+
|
|
154
|
+
| Mode | Result |
|
|
155
|
+
| --- | --- |
|
|
156
|
+
| `single` (default) | one `theme.css` — all `:root` vars + all rules |
|
|
157
|
+
| `split` | `styles.css` + `variables.css` (load-order contract, no `@import`) |
|
|
158
|
+
| `subsystem` | a styles+variables pair per subsystem (`colors.css`, `colors.variables.css`, …) |
|
|
159
|
+
| `components` | each component variant flattened into one self-contained file (`inline: true` bakes values; `inline: false` emits `var(--…)` + a tree-shaken `variables.css`) |
|
|
160
|
+
|
|
161
|
+
## DTCG round-trip
|
|
162
|
+
|
|
163
|
+
The `./dtcg` subpath reads/writes the W3C Design Token Community Group `tokens.json`
|
|
164
|
+
format, so a theme round-trips through Figma / Style Dictionary / other DTCG tooling.
|
|
165
|
+
It is data-interchange, **not** an output adapter — property tokens only.
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
import { fromDTCG, toDTCG } from "@theme-registry/refract/dtcg";
|
|
169
|
+
|
|
170
|
+
const raw = fromDTCG(designTokensJson); // DTCG document → createTheme raw input
|
|
171
|
+
const doc = toDTCG(theme); // built theme's tokens → DTCG document
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Package entry points
|
|
175
|
+
|
|
176
|
+
| Subpath | Contents |
|
|
177
|
+
| --- | --- |
|
|
178
|
+
| `@theme-registry/refract` | `createTheme`, `createCssAdapter`, `createStyledComponentsAdapter`, `defineAdapter`, the Model/adapter types, subsystem descriptors |
|
|
179
|
+
| `…/css` · `…/styled-components` · `…/json` · `…/scss` | each adapter's factory + types, as its own bundle |
|
|
180
|
+
| `…/dtcg` | `fromDTCG` / `toDTCG` / `parseDTCGDocument` (pure, no runtime adapter graph) |
|
|
181
|
+
| `…/build` | `defineConfig`, `emitTheme`, the `RawTheme` authoring types, the `Emit` vocabulary (Node-only) |
|
|
182
|
+
|
|
183
|
+
## Documentation
|
|
184
|
+
|
|
185
|
+
- **[docs/authoring.md](https://github.com/theme-registry/refract/blob/main/docs/authoring.md)** — author a theme + consume its output (the user guide).
|
|
186
|
+
- **[docs/extending.md](https://github.com/theme-registry/refract/blob/main/docs/extending.md)** — write a subsystem or an adapter against the frozen contract.
|
|
187
|
+
- **[AGENTS.md](AGENTS.md)** — orientation for AI coding agents.
|
|
188
|
+
|
|
189
|
+
## License
|
|
190
|
+
|
|
191
|
+
MIT © Petyo Stoyanov
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_errors-be768b25.cjs.js","sources":["../src/core/errors.ts"],"sourcesContent":["/**\n * Stable, machine-readable error codes (§P2-3). Every error refract throws for a theme authoring /\n * build problem — everything reachable from {@link createTheme} (subsystem normalization, token\n * derivation, DTCG parsing) — is a {@link RefractError} carrying a `code` from {@link RefractErrorCode}:\n * a stable identifier an agent (or a catch block) can branch on without string-matching the human\n * message. The message text stays human-first and unchanged; the code is additive.\n *\n * Scope: authoring/build errors. Pure CLI-tooling failures in `src/build/*` (bad arguments, a missing\n * file, an unknown command) stay plain `Error`s — they're usage errors from `refract <cmd>`, not a\n * problem with the theme an agent is editing.\n *\n * Dependency-free leaf on purpose, so any module (including the standalone `adapter-kit`) can throw one\n * without pulling in the core graph.\n */\nexport type RefractErrorCode =\n | \"REFRACT_E_COLOR_INPUT\" // a colour value wasn't a derivable colour\n | \"REFRACT_E_COLOR_TUPLE\" // an [r,g,b] tuple was malformed\n | \"REFRACT_E_STEPS\" // colors.<name>.steps out of range / non-numeric\n | \"REFRACT_E_VARIANT\" // a derivation-spec variant / modifier chain was malformed\n | \"REFRACT_E_VARIANT_REF\" // a variant referenced an unknown source\n | \"REFRACT_E_CYCLE\" // a cyclic reference (colour variant, token, recipe, DTCG alias)\n | \"REFRACT_E_ADJUST\" // an adjust dial was out of range\n | \"REFRACT_E_HARMONY\" // an invalid harmony scheme\n | \"REFRACT_E_VALIDATION\" // aggregate: one or more post-build ref-validation failures (see `failures`)\n | \"REFRACT_E_RECIPE_PROPERTY\" // a recipe declaration key is neither a known CSS property nor a reserved key\n | \"REFRACT_E_TOKEN_PATH\" // a token path is unknown / malformed / uses an unknown derivation fn\n | \"REFRACT_E_BREAKPOINT\" // a responsive entry omitted or named an unknown breakpoint\n | \"REFRACT_E_STATE\" // a recipe state entry named a state the adapter doesn't know\n | \"REFRACT_E_CONTAINER\" // a container-query entry named an unknown container / size / unsupported axis\n | \"REFRACT_E_RESPONSIVE\" // a responsive/mode override was malformed (variant+target conflict, unknown ref)\n | \"REFRACT_E_MEDIA\" // an invalid media / container query range (min > max)\n | \"REFRACT_E_MODE\" // an appearance-mode override with no base to override\n | \"REFRACT_E_PRESET\" // an unknown globals preset name\n | \"REFRACT_E_EFFECTS\" // a malformed effects value (shadow / transition layer)\n | \"REFRACT_E_LAYOUT\" // a malformed layout scale (ratio+step, bad rung)\n | \"REFRACT_E_UNITS\" // a malformed units config\n | \"REFRACT_E_PROPERTY\" // a property couldn't be normalized (no resolvable base value)\n | \"REFRACT_E_REFERENCE\" // a composition / rule-set reference didn't resolve\n | \"REFRACT_E_NAMING\" // a naming override / default path produced a collision\n | \"REFRACT_E_DTCG_VERSION\" // an unreadable DTCG refract-extension version\n | \"REFRACT_E_AUDIT\"
|
|
1
|
+
{"version":3,"file":"_errors-be768b25.cjs.js","sources":["../src/core/errors.ts"],"sourcesContent":["/**\n * Stable, machine-readable error codes (§P2-3). Every error refract throws for a theme authoring /\n * build problem — everything reachable from {@link createTheme} (subsystem normalization, token\n * derivation, DTCG parsing) — is a {@link RefractError} carrying a `code` from {@link RefractErrorCode}:\n * a stable identifier an agent (or a catch block) can branch on without string-matching the human\n * message. The message text stays human-first and unchanged; the code is additive.\n *\n * Scope: authoring/build errors. Pure CLI-tooling failures in `src/build/*` (bad arguments, a missing\n * file, an unknown command) stay plain `Error`s — they're usage errors from `refract <cmd>`, not a\n * problem with the theme an agent is editing. The one build-layer exception is `REFRACT_E_RAW_SHAPE`:\n * a value handed to `diff` / `validate` (or the MCP server) where a `RawTheme` is required but the\n * value isn't theme-shaped — that IS a theme problem, and a governance tool must fail loud + coded on\n * it (see {@link assertRawTheme}) rather than emit a nonsense \"everything removed\" diff at exit 0.\n *\n * Dependency-free leaf on purpose, so any module (including the standalone `adapter-kit`) can throw one\n * without pulling in the core graph.\n */\nexport type RefractErrorCode =\n | \"REFRACT_E_COLOR_INPUT\" // a colour value wasn't a derivable colour\n | \"REFRACT_E_COLOR_TUPLE\" // an [r,g,b] tuple was malformed\n | \"REFRACT_E_STEPS\" // colors.<name>.steps out of range / non-numeric\n | \"REFRACT_E_VARIANT\" // a derivation-spec variant / modifier chain was malformed\n | \"REFRACT_E_VARIANT_REF\" // a variant referenced an unknown source\n | \"REFRACT_E_CYCLE\" // a cyclic reference (colour variant, token, recipe, DTCG alias)\n | \"REFRACT_E_ADJUST\" // an adjust dial was out of range\n | \"REFRACT_E_HARMONY\" // an invalid harmony scheme\n | \"REFRACT_E_VALIDATION\" // aggregate: one or more post-build ref-validation failures (see `failures`)\n | \"REFRACT_E_RECIPE_PROPERTY\" // a recipe declaration key is neither a known CSS property nor a reserved key\n | \"REFRACT_E_TOKEN_PATH\" // a token path is unknown / malformed / uses an unknown derivation fn\n | \"REFRACT_E_BREAKPOINT\" // a responsive entry omitted or named an unknown breakpoint\n | \"REFRACT_E_STATE\" // a recipe state entry named a state the adapter doesn't know\n | \"REFRACT_E_CONTAINER\" // a container-query entry named an unknown container / size / unsupported axis\n | \"REFRACT_E_RESPONSIVE\" // a responsive/mode override was malformed (variant+target conflict, unknown ref)\n | \"REFRACT_E_MEDIA\" // an invalid media / container query range (min > max)\n | \"REFRACT_E_MODE\" // an appearance-mode override with no base to override\n | \"REFRACT_E_PRESET\" // an unknown globals preset name\n | \"REFRACT_E_EFFECTS\" // a malformed effects value (shadow / transition layer)\n | \"REFRACT_E_LAYOUT\" // a malformed layout scale (ratio+step, bad rung)\n | \"REFRACT_E_UNITS\" // a malformed units config\n | \"REFRACT_E_PROPERTY\" // a property couldn't be normalized (no resolvable base value)\n | \"REFRACT_E_REFERENCE\" // a composition / rule-set reference didn't resolve\n | \"REFRACT_E_NAMING\" // a naming override / default path produced a collision\n | \"REFRACT_E_DTCG_VERSION\" // an unreadable DTCG refract-extension version\n | \"REFRACT_E_AUDIT\" // a strict contrast audit failed\n | \"REFRACT_E_RAW_SHAPE\"; // a value passed where a RawTheme is required isn't theme-shaped (e.g. a defineConfig, an array, null)\n\n/**\n * An authoring / build error with a stable {@link RefractErrorCode}. For an aggregate (collect-all)\n * error, `failures` lists each individual message so a caller can report them all at once.\n */\nexport class RefractError extends Error {\n readonly code: RefractErrorCode;\n readonly failures?: readonly string[];\n\n constructor(code: RefractErrorCode, message: string, failures?: readonly string[]) {\n super(message);\n this.name = \"RefractError\";\n this.code = code;\n if (failures) this.failures = failures;\n // Keep `instanceof RefractError` working after transpilation to ES5-ish targets.\n Object.setPrototypeOf(this, RefractError.prototype);\n }\n}\n"],"names":["RefractError","Error","constructor","code","message","failures","super","this","name","Object","setPrototypeOf","prototype"],"mappings":"aAkDM,MAAOA,UAAqBC,MAIhC,WAAAC,CAAYC,EAAwBC,EAAiBC,GACnDC,MAAMF,GACNG,KAAKC,KAAO,eACZD,KAAKJ,KAAOA,EACRE,IAAUE,KAAKF,SAAWA,GAE9BI,OAAOC,eAAeH,KAAMP,EAAaW,UAC1C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_errors-d75a5c74.esm.js","sources":["../src/core/errors.ts"],"sourcesContent":["/**\n * Stable, machine-readable error codes (§P2-3). Every error refract throws for a theme authoring /\n * build problem — everything reachable from {@link createTheme} (subsystem normalization, token\n * derivation, DTCG parsing) — is a {@link RefractError} carrying a `code` from {@link RefractErrorCode}:\n * a stable identifier an agent (or a catch block) can branch on without string-matching the human\n * message. The message text stays human-first and unchanged; the code is additive.\n *\n * Scope: authoring/build errors. Pure CLI-tooling failures in `src/build/*` (bad arguments, a missing\n * file, an unknown command) stay plain `Error`s — they're usage errors from `refract <cmd>`, not a\n * problem with the theme an agent is editing.\n *\n * Dependency-free leaf on purpose, so any module (including the standalone `adapter-kit`) can throw one\n * without pulling in the core graph.\n */\nexport type RefractErrorCode =\n | \"REFRACT_E_COLOR_INPUT\" // a colour value wasn't a derivable colour\n | \"REFRACT_E_COLOR_TUPLE\" // an [r,g,b] tuple was malformed\n | \"REFRACT_E_STEPS\" // colors.<name>.steps out of range / non-numeric\n | \"REFRACT_E_VARIANT\" // a derivation-spec variant / modifier chain was malformed\n | \"REFRACT_E_VARIANT_REF\" // a variant referenced an unknown source\n | \"REFRACT_E_CYCLE\" // a cyclic reference (colour variant, token, recipe, DTCG alias)\n | \"REFRACT_E_ADJUST\" // an adjust dial was out of range\n | \"REFRACT_E_HARMONY\" // an invalid harmony scheme\n | \"REFRACT_E_VALIDATION\" // aggregate: one or more post-build ref-validation failures (see `failures`)\n | \"REFRACT_E_RECIPE_PROPERTY\" // a recipe declaration key is neither a known CSS property nor a reserved key\n | \"REFRACT_E_TOKEN_PATH\" // a token path is unknown / malformed / uses an unknown derivation fn\n | \"REFRACT_E_BREAKPOINT\" // a responsive entry omitted or named an unknown breakpoint\n | \"REFRACT_E_STATE\" // a recipe state entry named a state the adapter doesn't know\n | \"REFRACT_E_CONTAINER\" // a container-query entry named an unknown container / size / unsupported axis\n | \"REFRACT_E_RESPONSIVE\" // a responsive/mode override was malformed (variant+target conflict, unknown ref)\n | \"REFRACT_E_MEDIA\" // an invalid media / container query range (min > max)\n | \"REFRACT_E_MODE\" // an appearance-mode override with no base to override\n | \"REFRACT_E_PRESET\" // an unknown globals preset name\n | \"REFRACT_E_EFFECTS\" // a malformed effects value (shadow / transition layer)\n | \"REFRACT_E_LAYOUT\" // a malformed layout scale (ratio+step, bad rung)\n | \"REFRACT_E_UNITS\" // a malformed units config\n | \"REFRACT_E_PROPERTY\" // a property couldn't be normalized (no resolvable base value)\n | \"REFRACT_E_REFERENCE\" // a composition / rule-set reference didn't resolve\n | \"REFRACT_E_NAMING\" // a naming override / default path produced a collision\n | \"REFRACT_E_DTCG_VERSION\" // an unreadable DTCG refract-extension version\n | \"REFRACT_E_AUDIT\"
|
|
1
|
+
{"version":3,"file":"_errors-d75a5c74.esm.js","sources":["../src/core/errors.ts"],"sourcesContent":["/**\n * Stable, machine-readable error codes (§P2-3). Every error refract throws for a theme authoring /\n * build problem — everything reachable from {@link createTheme} (subsystem normalization, token\n * derivation, DTCG parsing) — is a {@link RefractError} carrying a `code` from {@link RefractErrorCode}:\n * a stable identifier an agent (or a catch block) can branch on without string-matching the human\n * message. The message text stays human-first and unchanged; the code is additive.\n *\n * Scope: authoring/build errors. Pure CLI-tooling failures in `src/build/*` (bad arguments, a missing\n * file, an unknown command) stay plain `Error`s — they're usage errors from `refract <cmd>`, not a\n * problem with the theme an agent is editing. The one build-layer exception is `REFRACT_E_RAW_SHAPE`:\n * a value handed to `diff` / `validate` (or the MCP server) where a `RawTheme` is required but the\n * value isn't theme-shaped — that IS a theme problem, and a governance tool must fail loud + coded on\n * it (see {@link assertRawTheme}) rather than emit a nonsense \"everything removed\" diff at exit 0.\n *\n * Dependency-free leaf on purpose, so any module (including the standalone `adapter-kit`) can throw one\n * without pulling in the core graph.\n */\nexport type RefractErrorCode =\n | \"REFRACT_E_COLOR_INPUT\" // a colour value wasn't a derivable colour\n | \"REFRACT_E_COLOR_TUPLE\" // an [r,g,b] tuple was malformed\n | \"REFRACT_E_STEPS\" // colors.<name>.steps out of range / non-numeric\n | \"REFRACT_E_VARIANT\" // a derivation-spec variant / modifier chain was malformed\n | \"REFRACT_E_VARIANT_REF\" // a variant referenced an unknown source\n | \"REFRACT_E_CYCLE\" // a cyclic reference (colour variant, token, recipe, DTCG alias)\n | \"REFRACT_E_ADJUST\" // an adjust dial was out of range\n | \"REFRACT_E_HARMONY\" // an invalid harmony scheme\n | \"REFRACT_E_VALIDATION\" // aggregate: one or more post-build ref-validation failures (see `failures`)\n | \"REFRACT_E_RECIPE_PROPERTY\" // a recipe declaration key is neither a known CSS property nor a reserved key\n | \"REFRACT_E_TOKEN_PATH\" // a token path is unknown / malformed / uses an unknown derivation fn\n | \"REFRACT_E_BREAKPOINT\" // a responsive entry omitted or named an unknown breakpoint\n | \"REFRACT_E_STATE\" // a recipe state entry named a state the adapter doesn't know\n | \"REFRACT_E_CONTAINER\" // a container-query entry named an unknown container / size / unsupported axis\n | \"REFRACT_E_RESPONSIVE\" // a responsive/mode override was malformed (variant+target conflict, unknown ref)\n | \"REFRACT_E_MEDIA\" // an invalid media / container query range (min > max)\n | \"REFRACT_E_MODE\" // an appearance-mode override with no base to override\n | \"REFRACT_E_PRESET\" // an unknown globals preset name\n | \"REFRACT_E_EFFECTS\" // a malformed effects value (shadow / transition layer)\n | \"REFRACT_E_LAYOUT\" // a malformed layout scale (ratio+step, bad rung)\n | \"REFRACT_E_UNITS\" // a malformed units config\n | \"REFRACT_E_PROPERTY\" // a property couldn't be normalized (no resolvable base value)\n | \"REFRACT_E_REFERENCE\" // a composition / rule-set reference didn't resolve\n | \"REFRACT_E_NAMING\" // a naming override / default path produced a collision\n | \"REFRACT_E_DTCG_VERSION\" // an unreadable DTCG refract-extension version\n | \"REFRACT_E_AUDIT\" // a strict contrast audit failed\n | \"REFRACT_E_RAW_SHAPE\"; // a value passed where a RawTheme is required isn't theme-shaped (e.g. a defineConfig, an array, null)\n\n/**\n * An authoring / build error with a stable {@link RefractErrorCode}. For an aggregate (collect-all)\n * error, `failures` lists each individual message so a caller can report them all at once.\n */\nexport class RefractError extends Error {\n readonly code: RefractErrorCode;\n readonly failures?: readonly string[];\n\n constructor(code: RefractErrorCode, message: string, failures?: readonly string[]) {\n super(message);\n this.name = \"RefractError\";\n this.code = code;\n if (failures) this.failures = failures;\n // Keep `instanceof RefractError` working after transpilation to ES5-ish targets.\n Object.setPrototypeOf(this, RefractError.prototype);\n }\n}\n"],"names":["RefractError","Error","constructor","code","message","failures","super","this","name","Object","setPrototypeOf","prototype"],"mappings":"AAkDM,MAAOA,UAAqBC,MAIhC,WAAAC,CAAYC,EAAwBC,EAAiBC,GACnDC,MAAMF,GACNG,KAAKC,KAAO,eACZD,KAAKJ,KAAOA,EACRE,IAAUE,KAAKF,SAAWA,GAE9BI,OAAOC,eAAeH,KAAMP,EAAaW,UAC1C"}
|