rainbowindex 0.6.0 → 0.7.0

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.
Files changed (43) hide show
  1. package/CHANGELOG.md +543 -0
  2. package/LICENSE +16 -17
  3. package/NOTICE.md +106 -0
  4. package/README.md +219 -65
  5. package/dist/browser.d.ts +4 -2
  6. package/dist/browser.mjs +12 -4
  7. package/dist/chunk-2T7V5XLK.mjs +912 -0
  8. package/dist/chunk-6OORICWF.mjs +16 -0
  9. package/dist/{chunk-KSNYSR3C.mjs → chunk-FJOZJIKB.mjs} +2499 -329
  10. package/dist/chunk-L56IRO7A.mjs +491 -0
  11. package/dist/chunk-PZDVDEZJ.mjs +196 -0
  12. package/dist/{chunk-3LWJTLOJ.mjs → chunk-RC6DDE4L.mjs} +23 -15
  13. package/dist/chunk-TQJYVQPE.mjs +217 -0
  14. package/dist/chunk-W756NVYI.mjs +33 -0
  15. package/dist/chunk-WBESS2ZD.mjs +598 -0
  16. package/dist/{chunk-3HRMFZGE.mjs → chunk-X66Z2YHT.mjs} +2 -1
  17. package/dist/{chunk-6U4IOFOS.mjs → chunk-XQGSG2HK.mjs} +199 -555
  18. package/dist/cli.mjs +1077 -123
  19. package/dist/{index-DSgpB6bS.d.ts → context-DcBtnnan.d.ts} +47 -103
  20. package/dist/editor.d.ts +71 -433
  21. package/dist/editor.mjs +51 -368
  22. package/dist/eslint.d.ts +16 -0
  23. package/dist/eslint.mjs +32 -0
  24. package/dist/{index-4Kyaq3IZ.d.ts → imports-C9esHd5Q.d.ts} +78 -84
  25. package/dist/index-CNqdL5U0.d.ts +56 -0
  26. package/dist/index-Czx-EUwh.d.ts +138 -0
  27. package/dist/index-DW8YSxTz.d.ts +104 -0
  28. package/dist/index.d.ts +46 -5
  29. package/dist/index.mjs +33 -9
  30. package/dist/oxlint.d.ts +21 -3
  31. package/dist/oxlint.mjs +19 -1
  32. package/dist/recipe.d.ts +111 -0
  33. package/dist/recipe.mjs +71 -0
  34. package/dist/safelist-CH3_PywB.d.ts +43 -0
  35. package/dist/session-CMaskdB7.d.ts +543 -0
  36. package/dist/tailwind.css +644 -0
  37. package/dist/theme-CIZiGlce.d.ts +115 -0
  38. package/dist/vite.d.ts +10 -1
  39. package/dist/vite.mjs +266 -118
  40. package/package.json +27 -5
  41. package/dist/chunk-WK6S4HTC.mjs +0 -1921
  42. package/dist/chunk-ZR7XJMUN.mjs +0 -251
  43. package/dist/safelist-CGCtF-Fr.d.ts +0 -96
package/dist/editor.mjs CHANGED
@@ -1,20 +1,29 @@
1
1
  import {
2
+ analyzeMerge,
3
+ createEditorSession,
4
+ renderStylesheet,
5
+ sortClasses
6
+ } from "./chunk-PZDVDEZJ.mjs";
7
+ import {
8
+ CANONICAL_COLOR_STOPS,
2
9
  CSS_ENTRY_CANDIDATES,
3
10
  UTILITY_VALUE_SPACES,
4
- enumerateClassNames
5
- } from "./chunk-ZR7XJMUN.mjs";
11
+ createClassInspector,
12
+ cssColorToHex,
13
+ enumerateClassNames,
14
+ listThemeTokens,
15
+ oklchToHex,
16
+ outermostCandidates,
17
+ resolveColorSwatch
18
+ } from "./chunk-WBESS2ZD.mjs";
6
19
  import {
7
20
  isSourceFile
8
- } from "./chunk-3HRMFZGE.mjs";
21
+ } from "./chunk-X66Z2YHT.mjs";
9
22
  import {
10
23
  CLASS_HELPER_NAMES,
11
24
  RI_IMPORT_SPECIFIERS,
12
- STATIC_UTILITIES,
13
25
  VARIANT_HELPER_NAMES,
14
26
  analyzeProjectCSS,
15
- buildBreakpointWeights,
16
- compileUtility,
17
- createEmptyCompilationResult,
18
27
  createThemeSnapshot,
19
28
  describeLoadedWeights,
20
29
  diagnosticFromWarning,
@@ -24,375 +33,26 @@ import {
24
33
  extractClassesFromSource,
25
34
  findClosest,
26
35
  hasRIActivation,
36
+ inlineDirectiveImports,
27
37
  isSuppressible,
28
38
  listVariants,
29
39
  parseUtility,
30
40
  severityForCode,
41
+ stripRIDirectives,
31
42
  warningCode,
32
43
  weightIsLoaded
33
- } from "./chunk-KSNYSR3C.mjs";
44
+ } from "./chunk-FJOZJIKB.mjs";
34
45
  import {
35
- computeDarkStop,
36
- defaultTheme,
37
- formatOklch,
38
- generateStop,
39
- linearToSrgb,
40
- mergeUncached,
41
- oklabToLinearSrgb,
42
- oklchToOklab,
43
- resolverFor
44
- } from "./chunk-6U4IOFOS.mjs";
45
-
46
- // src/engine/inspector.ts
47
- var RESOLUTION_CACHE_CAP = 1e4;
48
- var OK = Object.freeze({ ok: true });
49
- function createClassInspector(theme) {
50
- const customVariantMap = new Map(theme.customVariants.map((cv) => [cv.name, cv]));
51
- const breakpointWeights = buildBreakpointWeights(theme.breakpoints);
52
- const variantMemo = /* @__PURE__ */ new Map();
53
- const scratch = createEmptyCompilationResult();
54
- const warnSeen = /* @__PURE__ */ new Set();
55
- const detail = { reason: null, variant: null, declarations: null };
56
- const cache = /* @__PURE__ */ new Map();
57
- let variantList = null;
58
- let variantNames = null;
59
- let utilityCorpus = null;
60
- function variants() {
61
- if (!variantList) variantList = Object.freeze(listVariants(theme));
62
- return variantList;
63
- }
64
- function variantSuggestionCorpus() {
65
- if (!variantNames) {
66
- const names = [];
67
- for (const v of variants()) {
68
- if (v.kind !== "pattern") names.push(v.name);
69
- }
70
- variantNames = names;
71
- }
72
- return variantNames;
73
- }
74
- function utilitySuggestionCorpus() {
75
- if (!utilityCorpus) {
76
- const names = new Set(STATIC_UTILITIES);
77
- for (const custom of theme.customUtilities) {
78
- if (!custom.functional) names.add(custom.name);
79
- }
80
- for (const entry of enumerateClassNames(theme).classes) names.add(entry.name);
81
- utilityCorpus = [...names];
82
- }
83
- return utilityCorpus;
84
- }
85
- function baseName(raw, parsed) {
86
- let base = raw;
87
- if (parsed.variants.length > 0) {
88
- const prefix = `${parsed.variants.join(":")}:`;
89
- if (base.startsWith(prefix)) base = base.slice(prefix.length);
90
- }
91
- if (parsed.important && base.endsWith("!")) base = base.slice(0, -1);
92
- return base;
93
- }
94
- function resolve(className) {
95
- const cached = cache.get(className);
96
- if (cached) return cached;
97
- if (cache.size >= RESOLUTION_CACHE_CAP) {
98
- cache.clear();
99
- variantMemo.clear();
100
- }
101
- scratch.warnings.length = 0;
102
- warnSeen.clear();
103
- const parsed = parseUtility(className);
104
- const rule = compileUtility(
105
- parsed,
106
- theme,
107
- scratch,
108
- customVariantMap,
109
- warnSeen,
110
- breakpointWeights,
111
- variantMemo,
112
- detail
113
- );
114
- let entry;
115
- if (rule) {
116
- entry = {
117
- validation: OK,
118
- explanation: {
119
- parsed,
120
- declarations: detail.declarations ? [...detail.declarations] : [],
121
- selector: rule.selector,
122
- css: rule.css,
123
- sortKey: rule.sortKey
124
- }
125
- };
126
- } else if (detail.reason === "unknown-variant" && detail.variant !== null) {
127
- const suggestion = findClosest(detail.variant, variantSuggestionCorpus());
128
- entry = {
129
- validation: {
130
- ok: false,
131
- reason: "unknown-variant",
132
- offender: detail.variant,
133
- ...suggestion ? { suggestion } : {}
134
- },
135
- explanation: null
136
- };
137
- } else {
138
- const base = baseName(className, parsed);
139
- if (parsed.arbitrary || parsed.arbitraryProperty !== null) {
140
- entry = {
141
- validation: { ok: false, reason: "invalid-arbitrary", offender: base },
142
- explanation: null
143
- };
144
- } else {
145
- const suggestion = findClosest(base, utilitySuggestionCorpus());
146
- entry = {
147
- validation: {
148
- ok: false,
149
- reason: "unknown-utility",
150
- offender: base,
151
- ...suggestion ? { suggestion } : {}
152
- },
153
- explanation: null
154
- };
155
- }
156
- }
157
- cache.set(className, entry);
158
- return entry;
159
- }
160
- return {
161
- theme,
162
- validate: (className) => resolve(className).validation,
163
- explain: (className) => resolve(className).explanation,
164
- variants
165
- };
166
- }
167
-
168
- // src/merge/analyze.ts
169
- function analyzeMerge(classes, snapshot) {
170
- const resolve = resolverFor(snapshot);
171
- const trace = { claimers: /* @__PURE__ */ new Map(), dropped: [] };
172
- const output = mergeUncached(classes, resolve, trace);
173
- trace.dropped.sort((a, b) => a.index - b.index);
174
- const droppedIndexes = new Set(trace.dropped.map((d) => d.index));
175
- const kept = [];
176
- for (let i = 0; i < classes.length; i++) {
177
- if (!droppedIndexes.has(i)) kept.push(i);
178
- }
179
- return {
180
- output,
181
- kept,
182
- dropped: trace.dropped.map((d) => ({
183
- index: d.index,
184
- className: classes[d.index],
185
- overriddenBy: d.overriddenBy
186
- }))
187
- };
188
- }
189
-
190
- // src/theme/swatch.ts
191
- var CANONICAL_COLOR_STOPS = Object.freeze([
192
- 50,
193
- 100,
194
- 150,
195
- 200,
196
- 250,
197
- 300,
198
- 350,
199
- 400,
200
- 450,
201
- 500,
202
- 550,
203
- 600,
204
- 650,
205
- 700,
206
- 750,
207
- 800,
208
- 850,
209
- 900,
210
- 950
211
- ]);
212
- function channelHex(value) {
213
- return Math.round(Math.min(1, Math.max(0, value)) * 255).toString(16).padStart(2, "0");
214
- }
215
- function oklchToHex(l, c, h) {
216
- const [labL, labA, labB] = oklchToOklab(l, c, h);
217
- const [r, g, b] = oklabToLinearSrgb(labL, labA, labB);
218
- return `#${channelHex(linearToSrgb(r))}${channelHex(linearToSrgb(g))}${channelHex(linearToSrgb(b))}`;
219
- }
220
- var OKLCH_TEXT_RE = /^oklch\(\s*([\d.]+%?)\s+([\d.]+)\s+([\d.-]+)\s*(?:\/\s*[\d.]+%?\s*)?\)$/i;
221
- var HEX_TEXT_RE = /^#(?:[0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i;
222
- function cssColorToHex(css) {
223
- const text = css.trim();
224
- if (HEX_TEXT_RE.test(text)) {
225
- if (text.length === 4 || text.length === 5) {
226
- return `#${text[1]}${text[1]}${text[2]}${text[2]}${text[3]}${text[3]}`.toLowerCase();
227
- }
228
- return text.slice(0, 7).toLowerCase();
229
- }
230
- const match = OKLCH_TEXT_RE.exec(text);
231
- if (match) {
232
- const rawL = match[1];
233
- const l = rawL.endsWith("%") ? Number.parseFloat(rawL) / 100 : Number.parseFloat(rawL);
234
- const c = Number.parseFloat(match[2]);
235
- const h = Number.parseFloat(match[3]);
236
- if (Number.isFinite(l) && Number.isFinite(c) && Number.isFinite(h)) {
237
- return oklchToHex(l, c, h);
238
- }
239
- }
240
- return null;
241
- }
242
- var MAX_ALIAS_HOPS = 8;
243
- var SEMANTIC_SWATCHES = Object.freeze({
244
- paper: {
245
- light: { css: "oklch(1 0 0)", hex: "#ffffff" },
246
- dark: { css: "oklch(0 0 0)", hex: "#000000" }
247
- },
248
- ink: {
249
- light: { css: "oklch(0 0 0)", hex: "#000000" },
250
- dark: { css: "oklch(1 0 0)", hex: "#ffffff" }
251
- },
252
- white: {
253
- light: { css: "oklch(1 0 0)", hex: "#ffffff" },
254
- dark: null
255
- },
256
- black: {
257
- light: { css: "oklch(0 0 0)", hex: "#000000" },
258
- dark: null
259
- }
260
- });
261
- function swatchFromCss(css) {
262
- return { css, hex: cssColorToHex(css) };
263
- }
264
- function resolveColorSwatch(theme, name, stop = 500) {
265
- let def = theme.colors[name];
266
- for (let hop = 0; def && def.type === "alias" && hop < MAX_ALIAS_HOPS; hop++) {
267
- def = theme.colors[def.source];
268
- }
269
- if (!def || def.type === "alias") {
270
- return SEMANTIC_SWATCHES[name] ?? null;
271
- }
272
- switch (def.type) {
273
- case "generative": {
274
- const light = generateStop(def, stop);
275
- const lightSwatch = {
276
- css: formatOklch(light.l, light.c, light.h),
277
- hex: oklchToHex(light.l, light.c, light.h)
278
- };
279
- if (theme.darkConfig.mode === "off" || def.dark?.strategy === "fixed") {
280
- return { light: lightSwatch, dark: null };
281
- }
282
- const dark = computeDarkStop(def, stop, theme.darkConfig, def.dark);
283
- return {
284
- light: lightSwatch,
285
- dark: {
286
- css: formatOklch(dark.l, dark.c, dark.h),
287
- hex: oklchToHex(dark.l, dark.c, dark.h)
288
- }
289
- };
290
- }
291
- case "explicit":
292
- return { light: swatchFromCss(def.value), dark: null };
293
- case "pair":
294
- return {
295
- light: swatchFromCss(def.light),
296
- dark: theme.darkConfig.mode === "off" ? null : swatchFromCss(def.dark)
297
- };
298
- case "keyword":
299
- return null;
300
- }
301
- }
302
- function listThemeTokens(theme) {
303
- return {
304
- colors: Object.entries(theme.colors).map(([name, def]) => ({ name, kind: def.type })),
305
- colorStops: CANONICAL_COLOR_STOPS,
306
- spacingBase: theme.spacing.base,
307
- textSizes: Object.entries(theme.text).map(([name, def]) => ({
308
- name,
309
- fontSize: def.fontSize,
310
- lineHeight: def.lineHeight
311
- })),
312
- breakpoints: { ...theme.breakpoints },
313
- shadows: { ...theme.shadows },
314
- weights: { ...theme.weights },
315
- easing: { ...theme.easing },
316
- blur: { ...theme.blur },
317
- z: { ...theme.z },
318
- leading: { ...theme.leading },
319
- tracking: { ...theme.tracking },
320
- opacity: { ...theme.opacity },
321
- duration: { ...theme.duration },
322
- radii: { ...theme.radii },
323
- fluidRanges: Object.fromEntries(
324
- Object.entries(theme.fluidRanges).map(([name, range]) => [
325
- name,
326
- { min: range.min, max: range.max }
327
- ])
328
- ),
329
- fonts: theme.fonts.map((slot) => ({ slot: slot.slot, family: slot.family })),
330
- animations: Object.keys(theme.animations)
331
- };
332
- }
333
-
334
- // src/editor/session.ts
335
- function createEditorSession(options = {}) {
336
- let css = options.css ?? "";
337
- let analysis = null;
338
- let inspector = null;
339
- let enumeration = null;
340
- let tokens = null;
341
- let snapshot = null;
342
- const ensureAnalysis = () => {
343
- analysis ??= analyzeProjectCSS(css);
344
- return analysis;
345
- };
346
- const ensureSnapshot = () => {
347
- snapshot ??= createThemeSnapshot(ensureAnalysis().theme);
348
- return snapshot;
349
- };
350
- return {
351
- get css() {
352
- return css;
353
- },
354
- setCss(next) {
355
- if (next === css) return;
356
- css = next;
357
- analysis = null;
358
- inspector = null;
359
- enumeration = null;
360
- tokens = null;
361
- snapshot = null;
362
- },
363
- get theme() {
364
- return ensureAnalysis().theme;
365
- },
366
- get diagnostics() {
367
- return ensureAnalysis().diagnostics;
368
- },
369
- get inspector() {
370
- inspector ??= createClassInspector(ensureAnalysis().theme);
371
- return inspector;
372
- },
373
- enumerate() {
374
- enumeration ??= enumerateClassNames(ensureAnalysis().theme);
375
- return enumeration;
376
- },
377
- tokens() {
378
- tokens ??= listThemeTokens(ensureAnalysis().theme);
379
- return tokens;
380
- },
381
- snapshot: ensureSnapshot,
382
- analyzeMerge(classes) {
383
- return analyzeMerge(classes, ensureSnapshot());
384
- },
385
- extractCandidates(content, path) {
386
- return extractClassCandidates({ content, path });
387
- },
388
- swatch(name, stop) {
389
- return resolveColorSwatch(ensureAnalysis().theme, name, stop);
390
- }
391
- };
392
- }
46
+ defaultTheme
47
+ } from "./chunk-L56IRO7A.mjs";
48
+ import {
49
+ hydrateSnapshot,
50
+ publishSnapshot,
51
+ serializeSnapshot
52
+ } from "./chunk-XQGSG2HK.mjs";
393
53
 
394
54
  // src/entries/editor.ts
395
- var version = true ? "0.6.0" : "0.0.0-dev";
55
+ var version = true ? "0.7.0" : "0.0.0-dev";
396
56
  var EDITOR_API_VERSION = 1;
397
57
  var editorCapabilities = Object.freeze([
398
58
  "class-candidates",
@@ -419,7 +79,22 @@ var editorCapabilities = Object.freeze([
419
79
  "named-radii-and-fluid-ranges",
420
80
  // `weightIsLoaded` / `describeLoadedWeights` — the RI-1504 coverage check,
421
81
  // so an editor can answer "does any loaded font have this weight?".
422
- "font-weight-coverage"
82
+ "font-weight-coverage",
83
+ // `inlineDirectiveImports`, and `createEditorSession({ resolveImport })` —
84
+ // directives living in an `@import`ed file are read, given a host resolver.
85
+ "import-inlining",
86
+ // `serializeSnapshot` / `hydrateSnapshot` / `publishSnapshot` — a snapshot
87
+ // that survives JSON, so a theme can be shipped to a client bundle.
88
+ "serializable-snapshot",
89
+ // `renderStylesheet`, and `EditorSession.render` — the whole stylesheet,
90
+ // not just an answer about one class, from a graph with no `node:` in it.
91
+ "stylesheet-rendering",
92
+ // `sortClasses` — the emission order of a class list, so an editor command,
93
+ // a formatter and a codemod cannot disagree about what sorted means.
94
+ "class-sorting",
95
+ // `outermostCandidates` — one candidate per class the author wrote, for
96
+ // anything that maps a candidate back to a place in the source.
97
+ "candidate-spans-deduped"
423
98
  ]);
424
99
  export {
425
100
  CANONICAL_COLOR_STOPS,
@@ -446,14 +121,22 @@ export {
446
121
  extractClassesFromSource,
447
122
  findClosest,
448
123
  hasRIActivation,
124
+ hydrateSnapshot,
125
+ inlineDirectiveImports,
449
126
  isSourceFile,
450
127
  isSuppressible,
451
128
  listThemeTokens,
452
129
  listVariants,
453
130
  oklchToHex,
131
+ outermostCandidates,
454
132
  parseUtility,
133
+ publishSnapshot,
134
+ renderStylesheet,
455
135
  resolveColorSwatch,
136
+ serializeSnapshot,
456
137
  severityForCode,
138
+ sortClasses,
139
+ stripRIDirectives,
457
140
  version,
458
141
  warningCode,
459
142
  weightIsLoaded
@@ -0,0 +1,16 @@
1
+ import { L as LintRule } from './theme-CIZiGlce.js';
2
+ export { a as LintContext, b as LintFix, c as LintFixer, d as LintLoc, e as LintReport, f as LintSourceCode, g as LintSuggestion, h as LintVisitor, T as ThemeLintOptions, i as clearSessionCache, j as findCSSEntry, k as getSession, n as noConflictingClassesRule, l as noUnknownClassRule, r as rules } from './theme-CIZiGlce.js';
3
+ import './session-CMaskdB7.js';
4
+ import './imports-C9esHd5Q.js';
5
+ import './index-Czx-EUwh.js';
6
+ import './context-DcBtnnan.js';
7
+
8
+ /** The flat-config plugin object. `plugins: { rainbowindex }`. */
9
+ declare const plugin: {
10
+ meta: {
11
+ name: string;
12
+ };
13
+ rules: Readonly<Record<string, LintRule>>;
14
+ };
15
+
16
+ export { LintRule, plugin as default, plugin };
@@ -0,0 +1,32 @@
1
+ import {
2
+ clearSessionCache,
3
+ findCSSEntry,
4
+ getSession,
5
+ noConflictingClassesRule,
6
+ noUnknownClassRule,
7
+ rules
8
+ } from "./chunk-TQJYVQPE.mjs";
9
+ import "./chunk-PZDVDEZJ.mjs";
10
+ import "./chunk-WBESS2ZD.mjs";
11
+ import "./chunk-W756NVYI.mjs";
12
+ import "./chunk-X66Z2YHT.mjs";
13
+ import "./chunk-FJOZJIKB.mjs";
14
+ import "./chunk-L56IRO7A.mjs";
15
+ import "./chunk-XQGSG2HK.mjs";
16
+
17
+ // src/integrations/lint/index.ts
18
+ var plugin = {
19
+ meta: { name: "rainbowindex" },
20
+ rules
21
+ };
22
+ var lint_default = plugin;
23
+ export {
24
+ clearSessionCache,
25
+ lint_default as default,
26
+ findCSSEntry,
27
+ getSession,
28
+ noConflictingClassesRule,
29
+ noUnknownClassRule,
30
+ plugin,
31
+ rules
32
+ };