rainbowindex 0.5.0 → 0.5.1
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/CHANGELOG.md +197 -0
- package/README.md +66 -37
- package/dist/browser.d.ts +2 -2
- package/dist/browser.mjs +1 -1
- package/dist/{chunk-CMB6BHVE.mjs → chunk-4CTJLMYM.mjs} +47 -29
- package/dist/{chunk-KRZL4IDK.mjs → chunk-4UKFK2GE.mjs} +62 -47
- package/dist/{chunk-DT5HYIM3.mjs → chunk-F4VCBISU.mjs} +454 -432
- package/dist/{chunk-ZI5ZYNSU.mjs → chunk-PDORZSQX.mjs} +205 -138
- package/dist/{chunk-NXJZX6KI.mjs → chunk-RU4756NG.mjs} +5 -6
- package/dist/cli.mjs +8 -7
- package/dist/{context-ruu2x_jR.d.ts → context-B9yhJxd5.d.ts} +26 -8
- package/dist/editor.d.ts +9 -6
- package/dist/editor.mjs +9 -5
- package/dist/{index-Dp6i5TSv.d.ts → index-Dx-NpFFx.d.ts} +5 -5
- package/dist/index.d.ts +4 -4
- package/dist/index.mjs +6 -4
- package/dist/oxlint.d.ts +55 -0
- package/dist/oxlint.mjs +38 -0
- package/dist/{safelist-D9-Plqta.d.ts → safelist-DAkKuxCk.d.ts} +2 -15
- package/dist/vite.mjs +53 -12
- package/package.json +7 -1
|
@@ -15,10 +15,10 @@ import {
|
|
|
15
15
|
codepointCompare,
|
|
16
16
|
parseUtility,
|
|
17
17
|
resolveUtilityDeclarations
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-PDORZSQX.mjs";
|
|
19
19
|
import {
|
|
20
20
|
SPECIAL_COLORS
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-4UKFK2GE.mjs";
|
|
22
22
|
|
|
23
23
|
// src/project/css-entry.ts
|
|
24
24
|
var CSS_ENTRY_CANDIDATES = Object.freeze([
|
|
@@ -94,6 +94,7 @@ var ROUNDED_SIDES = Object.freeze([
|
|
|
94
94
|
...ROUNDED_SIDE_NAMES,
|
|
95
95
|
...ROUNDED_CORNER_NAMES
|
|
96
96
|
]);
|
|
97
|
+
var RADIUS_SAMPLES = Object.freeze([...SPACING_SAMPLES, "none", "full"]);
|
|
97
98
|
function buildValueSpaces() {
|
|
98
99
|
const table = /* @__PURE__ */ new Map();
|
|
99
100
|
for (const { roots, spec } of ROOT_GROUPS) {
|
|
@@ -141,13 +142,11 @@ function candidateValues(kind, theme) {
|
|
|
141
142
|
case "weight":
|
|
142
143
|
return Object.keys(theme.weights);
|
|
143
144
|
case "rounded":
|
|
144
|
-
return
|
|
145
|
+
return [...RADIUS_SAMPLES];
|
|
145
146
|
case "rounded-side": {
|
|
146
|
-
const tokens = Object.keys(theme.rounded);
|
|
147
147
|
const out = [];
|
|
148
148
|
for (const side of ROUNDED_SIDES) {
|
|
149
|
-
out.push(side);
|
|
150
|
-
for (const token of tokens) out.push(`${side}-${token}`);
|
|
149
|
+
for (const size of RADIUS_SAMPLES) out.push(`${side}-${size}`);
|
|
151
150
|
}
|
|
152
151
|
return out;
|
|
153
152
|
}
|
package/dist/cli.mjs
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
import {
|
|
3
3
|
CSS_ENTRY_CANDIDATES,
|
|
4
4
|
enumerateClassNames
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-RU4756NG.mjs";
|
|
6
6
|
import {
|
|
7
7
|
DEFAULT_EXCLUDES,
|
|
8
8
|
DEFAULT_PATTERNS,
|
|
9
9
|
compileScannedProject,
|
|
10
10
|
getFontPreloadLinks
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-F4VCBISU.mjs";
|
|
12
12
|
import {
|
|
13
13
|
MAX_DIRECTIVE_INPUT_SIZE,
|
|
14
14
|
codepointCompare,
|
|
@@ -18,10 +18,10 @@ import {
|
|
|
18
18
|
hasRIActivation,
|
|
19
19
|
listVariants,
|
|
20
20
|
resolveDirectives
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-PDORZSQX.mjs";
|
|
22
22
|
import {
|
|
23
23
|
devWarn
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-4UKFK2GE.mjs";
|
|
25
25
|
|
|
26
26
|
// src/entries/cli.ts
|
|
27
27
|
import { realpathSync } from "fs";
|
|
@@ -177,8 +177,9 @@ Examples:
|
|
|
177
177
|
flags: [CSS_INPUT_FONTS],
|
|
178
178
|
positionals: "none",
|
|
179
179
|
body: `Output:
|
|
180
|
-
Prints <link rel="preload"> tags to stdout
|
|
181
|
-
|
|
180
|
+
Prints <link rel="preload"> tags to stdout, one per @font face marked
|
|
181
|
+
preload. Only local-file and raw-URL faces qualify \u2014 Google serves CSS, not
|
|
182
|
+
the font binary, so a Google or system slot never produces a tag.
|
|
182
183
|
|
|
183
184
|
Examples:
|
|
184
185
|
rainbowindex preload-fonts --css src/styles.css > preload.html`
|
|
@@ -1288,7 +1289,7 @@ function readPackageJSONSync(cwd) {
|
|
|
1288
1289
|
|
|
1289
1290
|
// src/entries/cli.ts
|
|
1290
1291
|
function getVersion() {
|
|
1291
|
-
return true ? "0.5.
|
|
1292
|
+
return true ? "0.5.1" : "unknown";
|
|
1292
1293
|
}
|
|
1293
1294
|
async function main() {
|
|
1294
1295
|
const args = process.argv.slice(2);
|
|
@@ -83,7 +83,6 @@ interface Theme {
|
|
|
83
83
|
colors: Record<string, ColorDefinition>;
|
|
84
84
|
text: Record<string, TextSize>;
|
|
85
85
|
breakpoints: Record<string, string>;
|
|
86
|
-
rounded: Record<string, string>;
|
|
87
86
|
shadows: Record<string, string>;
|
|
88
87
|
weights: Record<string, number>;
|
|
89
88
|
easing: Record<string, string>;
|
|
@@ -104,6 +103,23 @@ type CornerShape = CornerShapeKeyword | {
|
|
|
104
103
|
};
|
|
105
104
|
declare const defaultTheme: Theme;
|
|
106
105
|
|
|
106
|
+
/**
|
|
107
|
+
* Claim resolution for ri() — utility name → CSS properties it sets.
|
|
108
|
+
*
|
|
109
|
+
* Split from merge/index.ts so each merge file is one concept: this file owns
|
|
110
|
+
* the dual-mode dispatch tables and resolvePropsWith(); index.ts owns the
|
|
111
|
+
* merge algorithm; context.ts owns the compilation-context lifecycle.
|
|
112
|
+
*
|
|
113
|
+
* Everything here is immutable module-init data plus pure closures over it —
|
|
114
|
+
* the mutable published compilation state lives in context.ts, and callers
|
|
115
|
+
* thread it in through resolvePropsWith()'s parameters.
|
|
116
|
+
*/
|
|
117
|
+
/** One functional `@utility name-*` root and the properties it claims. Declared
|
|
118
|
+
* here rather than in context.ts so this layer keeps taking its state as
|
|
119
|
+
* parameters instead of importing the context module. */
|
|
120
|
+
type CustomFunctionalEntry = readonly [root: string, properties: readonly string[]];
|
|
121
|
+
declare const DEFAULT_TEXT_SIZES: readonly ["xs", "sm", "base", "lg", "xl", "2xl", "3xl", "4xl", "5xl"];
|
|
122
|
+
|
|
107
123
|
/**
|
|
108
124
|
* Compilation-context lifecycle — all mutable state behind ri().
|
|
109
125
|
*
|
|
@@ -113,23 +129,25 @@ declare const defaultTheme: Theme;
|
|
|
113
129
|
* compilations. Split from merge/index.ts so the merge algorithm stays pure
|
|
114
130
|
* runtime and every piece of mutable state lives in one file.
|
|
115
131
|
*
|
|
116
|
-
* The default ri()
|
|
132
|
+
* The default ri() cache lives here rather than next to the merge loop
|
|
117
133
|
* because finalizeCompilationContext() must clear it: conflict resolution
|
|
118
134
|
* rules may change between compilations, and stale entries from a previous
|
|
119
135
|
* compilation (with different custom utilities) must never be returned.
|
|
120
136
|
*/
|
|
137
|
+
|
|
121
138
|
interface CompilationContext {
|
|
122
139
|
customStaticProps: Record<string, string[]>;
|
|
140
|
+
/** Roots of functional `@utility name-*` entries → the properties they set. */
|
|
141
|
+
customFunctionalProps: Record<string, string[]>;
|
|
123
142
|
textSizes: Set<string>;
|
|
124
143
|
fontFamilies: Set<string>;
|
|
125
144
|
colorNames: Set<string>;
|
|
126
145
|
}
|
|
127
|
-
|
|
128
|
-
* Frozen snapshot of compilation state for SSR-safe ri() instances.
|
|
129
|
-
* Created by finalizeCompilationContext() and consumed by createRi().
|
|
130
|
-
*/
|
|
146
|
+
|
|
131
147
|
interface CompilationSnapshot {
|
|
132
148
|
readonly customStaticProps: Readonly<Record<string, string[]>>;
|
|
149
|
+
/** Longest root first, so `glow-outer-*` wins over `glow-*` for `glow-outer-4`. */
|
|
150
|
+
readonly customFunctionalProps: readonly CustomFunctionalEntry[];
|
|
133
151
|
readonly textSizes: ReadonlySet<string>;
|
|
134
152
|
readonly fontFamilies: ReadonlySet<string>;
|
|
135
153
|
readonly colorNames: ReadonlySet<string>;
|
|
@@ -143,7 +161,7 @@ declare function createCompilationContext(): CompilationContext;
|
|
|
143
161
|
* Register a custom utility's CSS properties in the compilation context.
|
|
144
162
|
* Called by the engine when processing @utility directives.
|
|
145
163
|
*/
|
|
146
|
-
declare function registerCustomUtility(ctx: CompilationContext, name: string, properties: string[]): void;
|
|
164
|
+
declare function registerCustomUtility(ctx: CompilationContext, name: string, properties: string[], functional?: boolean): void;
|
|
147
165
|
/**
|
|
148
166
|
* Register custom text sizes so the merge function correctly classifies
|
|
149
167
|
* text-{custom} as a font-size utility rather than a color utility.
|
|
@@ -167,4 +185,4 @@ declare function registerColorNames(ctx: CompilationContext, names: string[]): v
|
|
|
167
185
|
*/
|
|
168
186
|
declare function finalizeCompilationContext(ctx: CompilationContext): CompilationSnapshot;
|
|
169
187
|
|
|
170
|
-
export { type AnimationDefinition as A, type ColorDefinition as C,
|
|
188
|
+
export { type AnimationDefinition as A, type ColorDefinition as C, DEFAULT_TEXT_SIZES as D, type FluidConfig as F, type TextSize as T, type CompilationContext as a, type CompilationSnapshot as b, type Theme as c, createCompilationContext as d, defaultTheme as e, finalizeCompilationContext as f, registerCustomFontFamilies as g, registerCustomTextSizes as h, registerCustomUtility as i, type DarkModeConfig as j, type CornerShape as k, registerColorNames as r };
|
package/dist/editor.d.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import { P as ParsedDirective, R as ResolvedTheme } from './index-
|
|
2
|
-
export { b as createThemeSnapshot } from './index-
|
|
3
|
-
import { b as CompilationSnapshot, C as ColorDefinition } from './context-
|
|
4
|
-
export { e as defaultTheme } from './context-
|
|
1
|
+
import { P as ParsedDirective, R as ResolvedTheme } from './index-Dx-NpFFx.js';
|
|
2
|
+
export { b as createThemeSnapshot } from './index-Dx-NpFFx.js';
|
|
3
|
+
import { b as CompilationSnapshot, C as ColorDefinition } from './context-B9yhJxd5.js';
|
|
4
|
+
export { e as defaultTheme } from './context-B9yhJxd5.js';
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
/** Where a candidate was found. "expression" marks a string literal sitting
|
|
7
|
+
* in a JS expression position that cannot be a class list — today, an
|
|
8
|
+
* operand of `==`/`!=` (`mode === "default"`). It is NOT a certain origin:
|
|
9
|
+
* editors should treat it like "plain" and never report it as a bad class. */
|
|
10
|
+
type CandidateOrigin = "attribute" | "helper" | "safelist" | "plain" | "expression";
|
|
7
11
|
interface ClassCandidate {
|
|
8
12
|
/** The class string in expanded form — for variant-group members this
|
|
9
13
|
* includes the group prefix (`hover:bg-red-500`) even though the span
|
|
@@ -455,7 +459,6 @@ interface ThemeTokens {
|
|
|
455
459
|
lineHeight: string;
|
|
456
460
|
}>;
|
|
457
461
|
breakpoints: Record<string, string>;
|
|
458
|
-
rounded: Record<string, string>;
|
|
459
462
|
shadows: Record<string, string>;
|
|
460
463
|
weights: Record<string, number>;
|
|
461
464
|
easing: Record<string, string>;
|
package/dist/editor.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
CSS_ENTRY_CANDIDATES,
|
|
3
3
|
UTILITY_VALUE_SPACES,
|
|
4
4
|
enumerateClassNames
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-RU4756NG.mjs";
|
|
6
6
|
import {
|
|
7
7
|
isSourceFile
|
|
8
8
|
} from "./chunk-3HRMFZGE.mjs";
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
parseUtility,
|
|
28
28
|
severityForCode,
|
|
29
29
|
warningCode
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-PDORZSQX.mjs";
|
|
31
31
|
import {
|
|
32
32
|
computeDarkStop,
|
|
33
33
|
defaultTheme,
|
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
oklabToLinearSrgb,
|
|
39
39
|
oklchToOklab,
|
|
40
40
|
resolverFor
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-4UKFK2GE.mjs";
|
|
42
42
|
|
|
43
43
|
// src/engine/inspector.ts
|
|
44
44
|
var RESOLUTION_CACHE_CAP = 1e4;
|
|
@@ -307,7 +307,6 @@ function listThemeTokens(theme) {
|
|
|
307
307
|
lineHeight: def.lineHeight
|
|
308
308
|
})),
|
|
309
309
|
breakpoints: { ...theme.breakpoints },
|
|
310
|
-
rounded: { ...theme.rounded },
|
|
311
310
|
shadows: { ...theme.shadows },
|
|
312
311
|
weights: { ...theme.weights },
|
|
313
312
|
easing: { ...theme.easing },
|
|
@@ -383,11 +382,16 @@ function createEditorSession(options = {}) {
|
|
|
383
382
|
}
|
|
384
383
|
|
|
385
384
|
// src/entries/editor.ts
|
|
386
|
-
var version = true ? "0.5.
|
|
385
|
+
var version = true ? "0.5.1" : "0.0.0-dev";
|
|
387
386
|
var EDITOR_API_VERSION = 1;
|
|
388
387
|
var editorCapabilities = Object.freeze([
|
|
389
388
|
"class-candidates",
|
|
390
389
|
"candidate-call-ids",
|
|
390
|
+
// A candidate carries a certain origin only when a context-aware collector
|
|
391
|
+
// tokenized it, so bare JS identifiers stay "plain"; equality operands
|
|
392
|
+
// report the "expression" origin. Without this, position alone decided,
|
|
393
|
+
// and `ri(mode === "x" ? …)` reported `mode` as a helper-origin class.
|
|
394
|
+
"candidate-origin-provenance",
|
|
391
395
|
"css-entry-detection",
|
|
392
396
|
"theme-analysis",
|
|
393
397
|
"class-inspection",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as ColorDefinition,
|
|
1
|
+
import { C as ColorDefinition, j as DarkModeConfig, k as CornerShape, A as AnimationDefinition, F as FluidConfig, b as CompilationSnapshot } from './context-B9yhJxd5.js';
|
|
2
2
|
|
|
3
3
|
/** Provider discriminant for a slot, derived from its faces. */
|
|
4
4
|
type FontProviderKind = "google" | "system" | "local" | "manual";
|
|
@@ -149,8 +149,6 @@ interface ResolvedTheme {
|
|
|
149
149
|
base: string;
|
|
150
150
|
}>;
|
|
151
151
|
readonly breakpoints: Readonly<Record<string, string>>;
|
|
152
|
-
readonly rounded: Readonly<Record<string, string>>;
|
|
153
|
-
readonly roundedRoof: string;
|
|
154
152
|
/**
|
|
155
153
|
* Corner shape set via `@rounded <shape>`. `null` means no shape was configured —
|
|
156
154
|
* the compiler emits neither a `corner-shape` rule nor the fallback `@supports not`
|
|
@@ -213,7 +211,6 @@ interface CompilationResult {
|
|
|
213
211
|
/** Set of used font slot names (for token pruning). */
|
|
214
212
|
usedFonts: Set<string>;
|
|
215
213
|
/** Set of used rounded value names (for token pruning). */
|
|
216
|
-
usedRounded: Set<string>;
|
|
217
214
|
/** Set of used shadow names (for token pruning). */
|
|
218
215
|
usedShadows: Set<string>;
|
|
219
216
|
/** Set of used animation shorthand names (for token pruning). */
|
|
@@ -254,7 +251,10 @@ declare function createThemeSnapshot(theme: ResolvedTheme): CompilationSnapshot;
|
|
|
254
251
|
* ```
|
|
255
252
|
*/
|
|
256
253
|
declare function createCompiler(): {
|
|
257
|
-
|
|
254
|
+
/** `authored` names the classes the user wrote by hand (`@source inline`,
|
|
255
|
+
* `@apply`, a caller-supplied list). Omit it to treat every class as
|
|
256
|
+
* authored — correct for callers who assembled the list themselves. */
|
|
257
|
+
compile: (classNames: Iterable<string>, theme: ResolvedTheme, authored?: ReadonlySet<string>) => CompilationResult;
|
|
258
258
|
createRi: () => (...inputs: (string | false | null | undefined)[]) => string;
|
|
259
259
|
/** Isolated font output cache for this compiler instance. Pass to
|
|
260
260
|
* `assembleSections()` to avoid sharing module-level font state. */
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { PluginCreator } from 'postcss';
|
|
2
|
-
export { C as ColorDefinition, a as CompilationContext, b as CompilationSnapshot, F as FluidConfig, T as TextSize, c as Theme, d as createCompilationContext, e as defaultTheme, f as finalizeCompilationContext, r as registerColorNames, g as registerCustomFontFamilies, h as registerCustomTextSizes, i as registerCustomUtility } from './context-
|
|
3
|
-
export {
|
|
4
|
-
import { R as ResolvedTheme, P as ParsedDirective } from './index-
|
|
5
|
-
export { C as CompilationResult, a as CompiledRule, c as createCompiler } from './index-
|
|
2
|
+
export { C as ColorDefinition, a as CompilationContext, b as CompilationSnapshot, D as DEFAULT_TEXT_SIZES, F as FluidConfig, T as TextSize, c as Theme, d as createCompilationContext, e as defaultTheme, f as finalizeCompilationContext, r as registerColorNames, g as registerCustomFontFamilies, h as registerCustomTextSizes, i as registerCustomUtility } from './context-B9yhJxd5.js';
|
|
3
|
+
export { c as createRi, r as ri, s as safelist } from './safelist-DAkKuxCk.js';
|
|
4
|
+
import { R as ResolvedTheme, P as ParsedDirective } from './index-Dx-NpFFx.js';
|
|
5
|
+
export { C as CompilationResult, a as CompiledRule, c as createCompiler } from './index-Dx-NpFFx.js';
|
|
6
6
|
|
|
7
7
|
interface RainbowIndexOptions {
|
|
8
8
|
sources?: string[];
|
package/dist/index.mjs
CHANGED
|
@@ -3,17 +3,17 @@ import {
|
|
|
3
3
|
} from "./chunk-PD4ZXGJ6.mjs";
|
|
4
4
|
import {
|
|
5
5
|
postcss_default
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-4CTJLMYM.mjs";
|
|
7
7
|
import {
|
|
8
8
|
finalizeProjectCompilation,
|
|
9
9
|
resolveGoogleFonts
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-F4VCBISU.mjs";
|
|
11
11
|
import {
|
|
12
12
|
analyzeProjectCSS,
|
|
13
13
|
createCompiler,
|
|
14
14
|
extractClassesFromSource,
|
|
15
15
|
pushWarningsDeduped
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-PDORZSQX.mjs";
|
|
17
17
|
import {
|
|
18
18
|
DEFAULT_TEXT_SIZES,
|
|
19
19
|
createCompilationContext,
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
registerCustomTextSizes,
|
|
26
26
|
registerCustomUtility,
|
|
27
27
|
ri
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-4UKFK2GE.mjs";
|
|
29
29
|
|
|
30
30
|
// src/project/index.ts
|
|
31
31
|
async function compileProject(options) {
|
|
@@ -36,6 +36,7 @@ async function compileProject(options) {
|
|
|
36
36
|
classNames.add(cls);
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
|
+
const authored = new Set(classNames);
|
|
39
40
|
if (options.sources) {
|
|
40
41
|
const extractionWarnings = [];
|
|
41
42
|
for (const source of options.sources) {
|
|
@@ -48,6 +49,7 @@ async function compileProject(options) {
|
|
|
48
49
|
return finalizeProjectCompilation({
|
|
49
50
|
css: options.css,
|
|
50
51
|
classNames,
|
|
52
|
+
authoredClassNames: authored,
|
|
51
53
|
analysis,
|
|
52
54
|
// Default to resolving google font weights so headless callers aren't silently
|
|
53
55
|
// stuck with "100 900" defaults; opt out with RI_OFFLINE / RI_FETCH_FONTS.
|
package/dist/oxlint.d.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Oxlint plugin for Rainbow Index projects.
|
|
3
|
+
*
|
|
4
|
+
* Oxlint loads a JS plugin by module specifier and reads its default export,
|
|
5
|
+
* so this entry keeps a default export even though the rest of the package
|
|
6
|
+
* prefers named ones. Register it from a Vite+ `vite.config.ts`:
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* export default defineConfig({
|
|
10
|
+
* lint: {
|
|
11
|
+
* jsPlugins: [{ name: "rainbowindex", specifier: "rainbowindex/oxlint" }],
|
|
12
|
+
* rules: { "rainbowindex/prefer-ri": "error" },
|
|
13
|
+
* },
|
|
14
|
+
* });
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* The types below describe only the slice of the Oxlint rule API this plugin
|
|
18
|
+
* touches. They are declared here rather than imported from `@oxlint/plugins`
|
|
19
|
+
* because that package is a transitive dependency of Oxlint that a consumer
|
|
20
|
+
* cannot resolve, and its `definePlugin` / `defineRule` helpers are identity
|
|
21
|
+
* functions with no runtime behavior to reuse.
|
|
22
|
+
*/
|
|
23
|
+
interface ImportDeclarationNode {
|
|
24
|
+
source: {
|
|
25
|
+
value: string;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
interface RuleContext {
|
|
29
|
+
report(diagnostic: {
|
|
30
|
+
message: string;
|
|
31
|
+
node: ImportDeclarationNode;
|
|
32
|
+
}): void;
|
|
33
|
+
}
|
|
34
|
+
interface RuleVisitor {
|
|
35
|
+
ImportDeclaration(node: ImportDeclarationNode): void;
|
|
36
|
+
}
|
|
37
|
+
interface OxlintRule {
|
|
38
|
+
meta: {
|
|
39
|
+
type: "suggestion";
|
|
40
|
+
docs: {
|
|
41
|
+
description: string;
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
create(context: RuleContext): RuleVisitor;
|
|
45
|
+
}
|
|
46
|
+
interface OxlintPlugin {
|
|
47
|
+
meta: {
|
|
48
|
+
name: string;
|
|
49
|
+
};
|
|
50
|
+
rules: Record<string, OxlintRule>;
|
|
51
|
+
}
|
|
52
|
+
declare const preferRiRule: OxlintRule;
|
|
53
|
+
declare const plugin: OxlintPlugin;
|
|
54
|
+
|
|
55
|
+
export { type OxlintPlugin, type OxlintRule, plugin as default, plugin, preferRiRule };
|
package/dist/oxlint.mjs
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// src/integrations/oxlint.ts
|
|
2
|
+
var REPLACED_PACKAGES = {
|
|
3
|
+
clsx: "composes conditional classes",
|
|
4
|
+
classnames: "composes conditional classes",
|
|
5
|
+
"tailwind-merge": "resolves class conflicts"
|
|
6
|
+
};
|
|
7
|
+
function packageName(specifier) {
|
|
8
|
+
return specifier.startsWith("@") ? specifier.split("/").slice(0, 2).join("/") : specifier.split("/")[0] ?? "";
|
|
9
|
+
}
|
|
10
|
+
var preferRiRule = {
|
|
11
|
+
meta: {
|
|
12
|
+
type: "suggestion",
|
|
13
|
+
docs: { description: "Merge class names with ri() from rainbowindex." }
|
|
14
|
+
},
|
|
15
|
+
create(context) {
|
|
16
|
+
return {
|
|
17
|
+
ImportDeclaration(node) {
|
|
18
|
+
const name = packageName(node.source.value);
|
|
19
|
+
const job = REPLACED_PACKAGES[name];
|
|
20
|
+
if (!job) return;
|
|
21
|
+
context.report({
|
|
22
|
+
message: `Import { ri } from "rainbowindex" instead of "${name}". ri() ${job}, and it reads the same theme the compiler emits.`,
|
|
23
|
+
node
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
var plugin = {
|
|
30
|
+
meta: { name: "rainbowindex" },
|
|
31
|
+
rules: { "prefer-ri": preferRiRule }
|
|
32
|
+
};
|
|
33
|
+
var oxlint_default = plugin;
|
|
34
|
+
export {
|
|
35
|
+
oxlint_default as default,
|
|
36
|
+
plugin,
|
|
37
|
+
preferRiRule
|
|
38
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { b as CompilationSnapshot } from './context-
|
|
1
|
+
import { b as CompilationSnapshot } from './context-B9yhJxd5.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* ri() — class merge function.
|
|
@@ -51,19 +51,6 @@ declare function ri(...inputs: ClassInput[]): string;
|
|
|
51
51
|
*/
|
|
52
52
|
declare function createRi(snapshot?: CompilationSnapshot): (...inputs: ClassInput[]) => string;
|
|
53
53
|
|
|
54
|
-
/**
|
|
55
|
-
* Claim resolution for ri() — utility name → CSS properties it sets.
|
|
56
|
-
*
|
|
57
|
-
* Split from merge/index.ts so each merge file is one concept: this file owns
|
|
58
|
-
* the dual-mode dispatch tables and resolvePropsWith(); index.ts owns the
|
|
59
|
-
* merge algorithm; context.ts owns the compilation-context lifecycle.
|
|
60
|
-
*
|
|
61
|
-
* Everything here is immutable module-init data plus pure closures over it —
|
|
62
|
-
* the mutable published compilation state lives in context.ts, and callers
|
|
63
|
-
* thread it in through resolvePropsWith()'s parameters.
|
|
64
|
-
*/
|
|
65
|
-
declare const DEFAULT_TEXT_SIZES: readonly ["xs", "sm", "base", "lg", "xl", "2xl", "3xl", "4xl", "5xl"];
|
|
66
|
-
|
|
67
54
|
/**
|
|
68
55
|
* `safelist()` — declare utility classes that must be emitted regardless of
|
|
69
56
|
* whether the consumer's source files reference them directly.
|
|
@@ -106,4 +93,4 @@ declare const DEFAULT_TEXT_SIZES: readonly ["xs", "sm", "base", "lg", "xl", "2xl
|
|
|
106
93
|
*/
|
|
107
94
|
declare function safelist(...parts: ReadonlyArray<string | false | null | undefined>): string;
|
|
108
95
|
|
|
109
|
-
export {
|
|
96
|
+
export { createRi as c, ri as r, safelist as s };
|
package/dist/vite.mjs
CHANGED
|
@@ -1,21 +1,26 @@
|
|
|
1
1
|
import {
|
|
2
2
|
postcss_default
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import
|
|
3
|
+
} from "./chunk-4CTJLMYM.mjs";
|
|
4
|
+
import {
|
|
5
|
+
enableSourceFileListCache,
|
|
6
|
+
invalidateSourceFileListCache
|
|
7
|
+
} from "./chunk-F4VCBISU.mjs";
|
|
5
8
|
import {
|
|
6
9
|
isSourceFile
|
|
7
10
|
} from "./chunk-3HRMFZGE.mjs";
|
|
8
11
|
import {
|
|
9
12
|
DIRECTIVE_TYPE_NAMES,
|
|
13
|
+
codepointCompare,
|
|
10
14
|
expandApplyGroups,
|
|
15
|
+
extractClassesFromSource,
|
|
11
16
|
findClosingBrace,
|
|
12
17
|
hasRIActivation,
|
|
13
18
|
isAtRuleBoundary,
|
|
14
19
|
isAtRuleNameChar
|
|
15
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-PDORZSQX.mjs";
|
|
16
21
|
import {
|
|
17
22
|
devWarn
|
|
18
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-4UKFK2GE.mjs";
|
|
19
24
|
|
|
20
25
|
// src/integrations/vite.ts
|
|
21
26
|
import { existsSync } from "fs";
|
|
@@ -162,6 +167,7 @@ function rainbowindexVite() {
|
|
|
162
167
|
let logger;
|
|
163
168
|
const riCSSFiles = /* @__PURE__ */ new Set();
|
|
164
169
|
const fileVersions = /* @__PURE__ */ new Map();
|
|
170
|
+
const candidateSignatures = /* @__PURE__ */ new Map();
|
|
165
171
|
let hotUpdateCount = 0;
|
|
166
172
|
const PRUNE_INTERVAL = 50;
|
|
167
173
|
return {
|
|
@@ -169,19 +175,27 @@ function rainbowindexVite() {
|
|
|
169
175
|
enforce: "pre",
|
|
170
176
|
async config(config) {
|
|
171
177
|
root = config.root ?? process.cwd();
|
|
178
|
+
const patch = {};
|
|
179
|
+
const ignorePatterns = await riStylesheetPatterns(root);
|
|
180
|
+
if (ignorePatterns.length > 0) {
|
|
181
|
+
patch.fmt = { ignorePatterns };
|
|
182
|
+
}
|
|
172
183
|
if (!hasLocalPostCSSConfig(root)) {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
plugins: [postcss_default()]
|
|
177
|
-
}
|
|
184
|
+
patch.css = {
|
|
185
|
+
postcss: {
|
|
186
|
+
plugins: [postcss_default()]
|
|
178
187
|
}
|
|
179
188
|
};
|
|
180
189
|
}
|
|
181
|
-
return
|
|
190
|
+
return patch;
|
|
182
191
|
},
|
|
183
192
|
configureServer(server) {
|
|
184
193
|
root = server.config?.root ?? process.cwd();
|
|
194
|
+
enableSourceFileListCache();
|
|
195
|
+
server.watcher?.on("add", invalidateSourceFileListCache);
|
|
196
|
+
server.watcher?.on("unlink", invalidateSourceFileListCache);
|
|
197
|
+
server.watcher?.on("unlinkDir", invalidateSourceFileListCache);
|
|
198
|
+
server.httpServer?.once("close", invalidateSourceFileListCache);
|
|
185
199
|
logger = {
|
|
186
200
|
info: (msg) => server.config.logger?.info?.(msg, { timestamp: true }),
|
|
187
201
|
warn: (msg) => server.config.logger?.warn?.(msg, { timestamp: true })
|
|
@@ -234,7 +248,8 @@ function rainbowindexVite() {
|
|
|
234
248
|
}
|
|
235
249
|
return null;
|
|
236
250
|
},
|
|
237
|
-
async handleHotUpdate(
|
|
251
|
+
async handleHotUpdate(ctx) {
|
|
252
|
+
const { file, server, modules } = ctx;
|
|
238
253
|
if (++hotUpdateCount % PRUNE_INTERVAL === 0) {
|
|
239
254
|
await pruneDeletedFiles();
|
|
240
255
|
}
|
|
@@ -243,6 +258,18 @@ function rainbowindexVite() {
|
|
|
243
258
|
return;
|
|
244
259
|
}
|
|
245
260
|
if (!isSourceFile(file)) return;
|
|
261
|
+
const previous = candidateSignatures.get(file);
|
|
262
|
+
let signature;
|
|
263
|
+
try {
|
|
264
|
+
const content = await ctx.read();
|
|
265
|
+
signature = [...extractClassesFromSource({ path: file, content })].sort(codepointCompare).join(" ");
|
|
266
|
+
} catch {
|
|
267
|
+
candidateSignatures.delete(file);
|
|
268
|
+
}
|
|
269
|
+
if (signature !== void 0) {
|
|
270
|
+
candidateSignatures.set(file, signature);
|
|
271
|
+
if (previous === signature) return;
|
|
272
|
+
}
|
|
246
273
|
const extraModules = [];
|
|
247
274
|
const hmrModules = new Set(modules);
|
|
248
275
|
for (const cssFile of riCSSFiles) {
|
|
@@ -261,13 +288,14 @@ function rainbowindexVite() {
|
|
|
261
288
|
}
|
|
262
289
|
};
|
|
263
290
|
async function pruneDeletedFiles() {
|
|
264
|
-
const tracked = /* @__PURE__ */ new Set([...riCSSFiles, ...fileVersions.keys()]);
|
|
291
|
+
const tracked = /* @__PURE__ */ new Set([...riCSSFiles, ...fileVersions.keys(), ...candidateSignatures.keys()]);
|
|
265
292
|
const checks = [...tracked].map(async (file) => {
|
|
266
293
|
try {
|
|
267
294
|
await access(file);
|
|
268
295
|
} catch {
|
|
269
296
|
riCSSFiles.delete(file);
|
|
270
297
|
fileVersions.delete(file);
|
|
298
|
+
candidateSignatures.delete(file);
|
|
271
299
|
}
|
|
272
300
|
});
|
|
273
301
|
await Promise.all(checks);
|
|
@@ -292,6 +320,19 @@ function rainbowindexVite() {
|
|
|
292
320
|
}
|
|
293
321
|
}
|
|
294
322
|
}
|
|
323
|
+
async function riStylesheetPatterns(root2) {
|
|
324
|
+
const files = await findCSSFilesOnDisk(root2);
|
|
325
|
+
const active = await Promise.all(
|
|
326
|
+
files.map(async (file) => {
|
|
327
|
+
try {
|
|
328
|
+
return hasRIActivation(await readFile(file, "utf-8")) ? file : null;
|
|
329
|
+
} catch {
|
|
330
|
+
return null;
|
|
331
|
+
}
|
|
332
|
+
})
|
|
333
|
+
);
|
|
334
|
+
return active.filter((file) => file !== null).map((file) => relative(root2, file).replaceAll("\\", "/"));
|
|
335
|
+
}
|
|
295
336
|
async function findCSSFilesOnDisk(root2) {
|
|
296
337
|
const results = [];
|
|
297
338
|
await collectCSSFiles(root2, results);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rainbowindex",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "CSS-first system for building and maintaining consistent user interfaces",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"css",
|
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
"postcss",
|
|
17
17
|
"postcss-plugin",
|
|
18
18
|
"vite-plugin",
|
|
19
|
+
"vite-plus",
|
|
20
|
+
"oxlint",
|
|
19
21
|
"class-merge",
|
|
20
22
|
"classnames",
|
|
21
23
|
"tailwind",
|
|
@@ -65,6 +67,10 @@
|
|
|
65
67
|
"types": "./dist/vite.d.ts",
|
|
66
68
|
"default": "./dist/vite.mjs"
|
|
67
69
|
},
|
|
70
|
+
"./oxlint": {
|
|
71
|
+
"types": "./dist/oxlint.d.ts",
|
|
72
|
+
"default": "./dist/oxlint.mjs"
|
|
73
|
+
},
|
|
68
74
|
"./package.json": "./package.json"
|
|
69
75
|
},
|
|
70
76
|
"bin": {
|