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.
- package/CHANGELOG.md +543 -0
- package/LICENSE +16 -17
- package/NOTICE.md +106 -0
- package/README.md +219 -65
- package/dist/browser.d.ts +4 -2
- package/dist/browser.mjs +12 -4
- package/dist/chunk-2T7V5XLK.mjs +912 -0
- package/dist/chunk-6OORICWF.mjs +16 -0
- package/dist/{chunk-KSNYSR3C.mjs → chunk-FJOZJIKB.mjs} +2499 -329
- package/dist/chunk-L56IRO7A.mjs +491 -0
- package/dist/chunk-PZDVDEZJ.mjs +196 -0
- package/dist/{chunk-3LWJTLOJ.mjs → chunk-RC6DDE4L.mjs} +23 -15
- package/dist/chunk-TQJYVQPE.mjs +217 -0
- package/dist/chunk-W756NVYI.mjs +33 -0
- package/dist/chunk-WBESS2ZD.mjs +598 -0
- package/dist/{chunk-3HRMFZGE.mjs → chunk-X66Z2YHT.mjs} +2 -1
- package/dist/{chunk-6U4IOFOS.mjs → chunk-XQGSG2HK.mjs} +199 -555
- package/dist/cli.mjs +1077 -123
- package/dist/{index-DSgpB6bS.d.ts → context-DcBtnnan.d.ts} +47 -103
- package/dist/editor.d.ts +71 -433
- package/dist/editor.mjs +51 -368
- package/dist/eslint.d.ts +16 -0
- package/dist/eslint.mjs +32 -0
- package/dist/{index-4Kyaq3IZ.d.ts → imports-C9esHd5Q.d.ts} +78 -84
- package/dist/index-CNqdL5U0.d.ts +56 -0
- package/dist/index-Czx-EUwh.d.ts +138 -0
- package/dist/index-DW8YSxTz.d.ts +104 -0
- package/dist/index.d.ts +46 -5
- package/dist/index.mjs +33 -9
- package/dist/oxlint.d.ts +21 -3
- package/dist/oxlint.mjs +19 -1
- package/dist/recipe.d.ts +111 -0
- package/dist/recipe.mjs +71 -0
- package/dist/safelist-CH3_PywB.d.ts +43 -0
- package/dist/session-CMaskdB7.d.ts +543 -0
- package/dist/tailwind.css +644 -0
- package/dist/theme-CIZiGlce.d.ts +115 -0
- package/dist/vite.d.ts +10 -1
- package/dist/vite.mjs +266 -118
- package/package.json +27 -5
- package/dist/chunk-WK6S4HTC.mjs +0 -1921
- package/dist/chunk-ZR7XJMUN.mjs +0 -251
- package/dist/safelist-CGCtF-Fr.d.ts +0 -96
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
compileScannedProject
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-2T7V5XLK.mjs";
|
|
4
4
|
import {
|
|
5
5
|
APPLY_ALIASES,
|
|
6
6
|
DIRECTIVE_NAMES_SET,
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
checkAppliedFontWeights,
|
|
11
11
|
compileCSSFunctions,
|
|
12
12
|
computeSortKey,
|
|
13
|
-
|
|
13
|
+
expandApplyBodyGroups,
|
|
14
14
|
forEachApplyClassList,
|
|
15
15
|
hasApplyLikeDirective,
|
|
16
16
|
hasCSSFunctions,
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
resolveUtilityDeclarations,
|
|
22
22
|
resolveVariant,
|
|
23
23
|
splitSelectorList
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-FJOZJIKB.mjs";
|
|
25
25
|
|
|
26
26
|
// src/integrations/postcss/index.ts
|
|
27
27
|
import postcss2 from "postcss";
|
|
@@ -118,7 +118,7 @@ function processApply(root, theme, warnings, cssPath) {
|
|
|
118
118
|
const groupRoots = /* @__PURE__ */ new Set();
|
|
119
119
|
root.walkAtRules("apply", (atRule) => {
|
|
120
120
|
applyNodes.push(atRule);
|
|
121
|
-
const params =
|
|
121
|
+
const params = expandApplyBodyGroups(atRule.params, warnings, cssPath);
|
|
122
122
|
const classNames = params.trim().split(/\s+/).filter(Boolean);
|
|
123
123
|
classListByNode.set(atRule, classNames);
|
|
124
124
|
if (classNames.includes("group")) {
|
|
@@ -315,9 +315,7 @@ function expandApply(atRule, classNames, theme, warnings, customVariantMap, grou
|
|
|
315
315
|
bucket.nestedSelector,
|
|
316
316
|
bucket.nestedBlocks
|
|
317
317
|
);
|
|
318
|
-
|
|
319
|
-
docRoot().append(node);
|
|
320
|
-
}
|
|
318
|
+
for (const branch of node) docRoot().append(branch);
|
|
321
319
|
} else if (hasGroupVariants) {
|
|
322
320
|
const node = buildVariantNode(
|
|
323
321
|
fullNestingSelector(),
|
|
@@ -327,9 +325,7 @@ function expandApply(atRule, classNames, theme, warnings, customVariantMap, grou
|
|
|
327
325
|
bucket.nestedSelector,
|
|
328
326
|
bucket.nestedBlocks
|
|
329
327
|
);
|
|
330
|
-
|
|
331
|
-
docRoot().append(node);
|
|
332
|
-
}
|
|
328
|
+
for (const branch of node) docRoot().append(branch);
|
|
333
329
|
} else {
|
|
334
330
|
const node = buildVariantNode(
|
|
335
331
|
baseSelector,
|
|
@@ -339,9 +335,9 @@ function expandApply(atRule, classNames, theme, warnings, customVariantMap, grou
|
|
|
339
335
|
bucket.nestedSelector,
|
|
340
336
|
bucket.nestedBlocks
|
|
341
337
|
);
|
|
342
|
-
|
|
343
|
-
parentContainer.insertAfter(insertAfter,
|
|
344
|
-
insertAfter =
|
|
338
|
+
for (const branch of node) {
|
|
339
|
+
parentContainer.insertAfter(insertAfter, branch);
|
|
340
|
+
insertAfter = branch;
|
|
345
341
|
}
|
|
346
342
|
}
|
|
347
343
|
}
|
|
@@ -475,8 +471,20 @@ function buildNestedBlockNode(block, sourceNode, important) {
|
|
|
475
471
|
return node;
|
|
476
472
|
}
|
|
477
473
|
function buildVariantNode(baseSelector, wrappers, decls, sourceNode, nestedSelector, nestedBlocks) {
|
|
478
|
-
if (decls.length === 0 && nestedBlocks.length === 0) return
|
|
479
|
-
|
|
474
|
+
if (decls.length === 0 && nestedBlocks.length === 0) return [];
|
|
475
|
+
return applyVariantWrappers(baseSelector, wrappers).map(
|
|
476
|
+
({ selector, atRules, startingStyle }) => buildBranchNode(
|
|
477
|
+
selector,
|
|
478
|
+
atRules,
|
|
479
|
+
startingStyle,
|
|
480
|
+
decls,
|
|
481
|
+
sourceNode,
|
|
482
|
+
nestedSelector,
|
|
483
|
+
nestedBlocks
|
|
484
|
+
)
|
|
485
|
+
);
|
|
486
|
+
}
|
|
487
|
+
function buildBranchNode(selector, atRules, startingStyle, decls, sourceNode, nestedSelector, nestedBlocks) {
|
|
480
488
|
const rule = applySource(postcss.rule({ selector }), sourceNode);
|
|
481
489
|
let declTarget = rule;
|
|
482
490
|
if (nestedSelector) {
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createEditorSession
|
|
3
|
+
} from "./chunk-PZDVDEZJ.mjs";
|
|
4
|
+
import {
|
|
5
|
+
CSS_ENTRY_CANDIDATES,
|
|
6
|
+
outermostCandidates
|
|
7
|
+
} from "./chunk-WBESS2ZD.mjs";
|
|
8
|
+
import {
|
|
9
|
+
createNodeImportResolver
|
|
10
|
+
} from "./chunk-W756NVYI.mjs";
|
|
11
|
+
import {
|
|
12
|
+
isSourceFile
|
|
13
|
+
} from "./chunk-X66Z2YHT.mjs";
|
|
14
|
+
import {
|
|
15
|
+
extractClassCandidates,
|
|
16
|
+
hasRIActivation
|
|
17
|
+
} from "./chunk-FJOZJIKB.mjs";
|
|
18
|
+
|
|
19
|
+
// src/integrations/lint/theme.ts
|
|
20
|
+
import { existsSync, readFileSync, statSync } from "fs";
|
|
21
|
+
import { isAbsolute, resolve as resolvePath } from "path";
|
|
22
|
+
function findCSSEntry(cwd) {
|
|
23
|
+
for (const candidate of CSS_ENTRY_CANDIDATES) {
|
|
24
|
+
const path = resolvePath(cwd, candidate);
|
|
25
|
+
if (!existsSync(path)) continue;
|
|
26
|
+
try {
|
|
27
|
+
if (hasRIActivation(readFileSync(path, "utf8"))) return path;
|
|
28
|
+
} catch {
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
var sessions = /* @__PURE__ */ new Map();
|
|
34
|
+
function mtimeOf(path) {
|
|
35
|
+
try {
|
|
36
|
+
return statSync(path).mtimeMs;
|
|
37
|
+
} catch {
|
|
38
|
+
return -1;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function stampsFor(session, entry) {
|
|
42
|
+
const stamps = /* @__PURE__ */ new Map([[entry, mtimeOf(entry)]]);
|
|
43
|
+
for (const file of session.importedFiles) stamps.set(file, mtimeOf(file));
|
|
44
|
+
return stamps;
|
|
45
|
+
}
|
|
46
|
+
function isStale(cached) {
|
|
47
|
+
for (const [path, stamp] of cached.stamps) {
|
|
48
|
+
if (mtimeOf(path) !== stamp) return true;
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
function getSession(options = {}) {
|
|
53
|
+
const cwd = options.cwd ?? process.cwd();
|
|
54
|
+
const entry = options.css ? isAbsolute(options.css) ? options.css : resolvePath(cwd, options.css) : findCSSEntry(cwd);
|
|
55
|
+
if (entry === null) return null;
|
|
56
|
+
const cached = sessions.get(entry);
|
|
57
|
+
if (cached && !isStale(cached)) return cached.session;
|
|
58
|
+
let css;
|
|
59
|
+
try {
|
|
60
|
+
css = readFileSync(entry, "utf8");
|
|
61
|
+
} catch {
|
|
62
|
+
sessions.delete(entry);
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
const session = createEditorSession({
|
|
66
|
+
css,
|
|
67
|
+
cssPath: entry,
|
|
68
|
+
resolveImport: createNodeImportResolver({ cwd })
|
|
69
|
+
});
|
|
70
|
+
sessions.set(entry, { session, stamps: stampsFor(session, entry) });
|
|
71
|
+
return session;
|
|
72
|
+
}
|
|
73
|
+
function clearSessionCache() {
|
|
74
|
+
sessions.clear();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// src/integrations/lint/rules.ts
|
|
78
|
+
function sourceCodeOf(context) {
|
|
79
|
+
return context.sourceCode ?? context.getSourceCode?.() ?? null;
|
|
80
|
+
}
|
|
81
|
+
function scanPathFor(context) {
|
|
82
|
+
const filename = context.filename ?? context.getFilename?.() ?? "<input>";
|
|
83
|
+
return isSourceFile(filename) ? filename : `${filename}.tsx`;
|
|
84
|
+
}
|
|
85
|
+
function optionsOf(context) {
|
|
86
|
+
const first = context.options?.[0];
|
|
87
|
+
const options = first && typeof first === "object" ? { ...first } : {};
|
|
88
|
+
options.cwd ??= context.cwd ?? process.cwd();
|
|
89
|
+
return options;
|
|
90
|
+
}
|
|
91
|
+
var AUTHORED_ORIGINS = /* @__PURE__ */ new Set(["attribute", "helper", "safelist"]);
|
|
92
|
+
function authoredCandidates(source, path) {
|
|
93
|
+
return outermostCandidates(extractClassCandidates({ content: source, path })).filter(
|
|
94
|
+
(candidate) => AUTHORED_ORIGINS.has(candidate.origin)
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
function locOf(sourceCode, candidate) {
|
|
98
|
+
return {
|
|
99
|
+
start: sourceCode.getLocFromIndex(candidate.start),
|
|
100
|
+
end: sourceCode.getLocFromIndex(candidate.end)
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
var THEME_OPTION_SCHEMA = [
|
|
104
|
+
{
|
|
105
|
+
type: "object",
|
|
106
|
+
properties: { css: { type: "string" }, cwd: { type: "string" } },
|
|
107
|
+
additionalProperties: false
|
|
108
|
+
}
|
|
109
|
+
];
|
|
110
|
+
var noUnknownClassRule = {
|
|
111
|
+
meta: {
|
|
112
|
+
type: "problem",
|
|
113
|
+
docs: {
|
|
114
|
+
description: "Every class in a class position must compile against the project theme."
|
|
115
|
+
},
|
|
116
|
+
hasSuggestions: true,
|
|
117
|
+
schema: THEME_OPTION_SCHEMA
|
|
118
|
+
},
|
|
119
|
+
create(context) {
|
|
120
|
+
const sourceCode = sourceCodeOf(context);
|
|
121
|
+
if (sourceCode === null) return {};
|
|
122
|
+
const session = getSession(optionsOf(context));
|
|
123
|
+
if (session === null) return {};
|
|
124
|
+
return {
|
|
125
|
+
Program(node) {
|
|
126
|
+
const text = sourceCode.getText();
|
|
127
|
+
for (const candidate of authoredCandidates(text, scanPathFor(context))) {
|
|
128
|
+
const result = session.inspector.validate(candidate.value);
|
|
129
|
+
if (result.ok) continue;
|
|
130
|
+
const detail = result.reason === "unknown-variant" ? `Unknown variant "${result.offender}"` : result.reason === "invalid-arbitrary" ? `Invalid arbitrary value in "${result.offender}"` : `Unknown utility "${result.offender}"`;
|
|
131
|
+
const hint = result.suggestion ? ` Did you mean "${result.suggestion}"?` : "";
|
|
132
|
+
context.report({
|
|
133
|
+
message: `${detail} \u2014 "${candidate.value}" compiles to nothing.${hint}`,
|
|
134
|
+
node,
|
|
135
|
+
loc: locOf(sourceCode, candidate),
|
|
136
|
+
suggest: suggestionFor(text, candidate, result.offender, result.suggestion)
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
function suggestionFor(text, candidate, offender, suggestion) {
|
|
144
|
+
if (suggestion === void 0) return void 0;
|
|
145
|
+
const slice = text.slice(candidate.start, candidate.end);
|
|
146
|
+
const at = slice.indexOf(offender);
|
|
147
|
+
if (at === -1 || slice.indexOf(offender, at + 1) !== -1) return void 0;
|
|
148
|
+
const range = [candidate.start + at, candidate.start + at + offender.length];
|
|
149
|
+
return [
|
|
150
|
+
{
|
|
151
|
+
desc: `Replace "${offender}" with "${suggestion}"`,
|
|
152
|
+
fix: (fixer) => fixer.replaceTextRange(range, suggestion)
|
|
153
|
+
}
|
|
154
|
+
];
|
|
155
|
+
}
|
|
156
|
+
function classRuns(text, candidates) {
|
|
157
|
+
const runs = [];
|
|
158
|
+
let current = [];
|
|
159
|
+
let previousEnd = -1;
|
|
160
|
+
for (const candidate of candidates) {
|
|
161
|
+
const gap = previousEnd === -1 ? null : text.slice(previousEnd, candidate.start);
|
|
162
|
+
if (gap !== null && gap.trim() === "") {
|
|
163
|
+
current.push(candidate);
|
|
164
|
+
} else {
|
|
165
|
+
if (current.length > 0) runs.push(current);
|
|
166
|
+
current = [candidate];
|
|
167
|
+
}
|
|
168
|
+
previousEnd = candidate.end;
|
|
169
|
+
}
|
|
170
|
+
if (current.length > 0) runs.push(current);
|
|
171
|
+
return runs;
|
|
172
|
+
}
|
|
173
|
+
var noConflictingClassesRule = {
|
|
174
|
+
meta: {
|
|
175
|
+
type: "problem",
|
|
176
|
+
docs: {
|
|
177
|
+
description: "One class string must not contain classes that override each other."
|
|
178
|
+
},
|
|
179
|
+
schema: THEME_OPTION_SCHEMA
|
|
180
|
+
},
|
|
181
|
+
create(context) {
|
|
182
|
+
const sourceCode = sourceCodeOf(context);
|
|
183
|
+
if (sourceCode === null) return {};
|
|
184
|
+
const session = getSession(optionsOf(context));
|
|
185
|
+
if (session === null) return {};
|
|
186
|
+
return {
|
|
187
|
+
Program(node) {
|
|
188
|
+
const text = sourceCode.getText();
|
|
189
|
+
for (const run of classRuns(text, authoredCandidates(text, scanPathFor(context)))) {
|
|
190
|
+
if (run.length < 2) continue;
|
|
191
|
+
const analysis = session.analyzeMerge(run.map((candidate) => candidate.value));
|
|
192
|
+
for (const drop of analysis.dropped) {
|
|
193
|
+
const winners = drop.overriddenBy.map((index) => `"${run[index]?.value ?? "?"}"`).join(", ");
|
|
194
|
+
context.report({
|
|
195
|
+
message: `"${drop.className}" is overridden by ${winners} in the same class string, so it has no effect.`,
|
|
196
|
+
node,
|
|
197
|
+
loc: locOf(sourceCode, run[drop.index])
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
var rules = Object.freeze({
|
|
206
|
+
"no-unknown-class": noUnknownClassRule,
|
|
207
|
+
"no-conflicting-classes": noConflictingClassesRule
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
export {
|
|
211
|
+
findCSSEntry,
|
|
212
|
+
getSession,
|
|
213
|
+
clearSessionCache,
|
|
214
|
+
noUnknownClassRule,
|
|
215
|
+
noConflictingClassesRule,
|
|
216
|
+
rules
|
|
217
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MAX_DIRECTIVE_INPUT_SIZE
|
|
3
|
+
} from "./chunk-FJOZJIKB.mjs";
|
|
4
|
+
|
|
5
|
+
// src/project/resolve-import.ts
|
|
6
|
+
import { readFileSync, statSync } from "fs";
|
|
7
|
+
import { createRequire } from "module";
|
|
8
|
+
import { dirname, resolve as resolvePath } from "path";
|
|
9
|
+
var MAX_IMPORT_FILE_SIZE = MAX_DIRECTIVE_INPUT_SIZE;
|
|
10
|
+
function readIfSmallEnough(path) {
|
|
11
|
+
const size = statSync(path).size;
|
|
12
|
+
if (size > MAX_IMPORT_FILE_SIZE) return null;
|
|
13
|
+
const content = readFileSync(path, "utf8");
|
|
14
|
+
return { path, content: content.charCodeAt(0) === 65279 ? content.slice(1) : content };
|
|
15
|
+
}
|
|
16
|
+
function createNodeImportResolver(options) {
|
|
17
|
+
return (specifier, from) => {
|
|
18
|
+
try {
|
|
19
|
+
if (specifier.startsWith("./") || specifier.startsWith("../")) {
|
|
20
|
+
const base = from === void 0 ? options.cwd : dirname(from);
|
|
21
|
+
return readIfSmallEnough(resolvePath(base, specifier));
|
|
22
|
+
}
|
|
23
|
+
const anchor = from ?? resolvePath(options.cwd, "__ri_import_anchor__.js");
|
|
24
|
+
return readIfSmallEnough(createRequire(anchor).resolve(specifier));
|
|
25
|
+
} catch {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export {
|
|
32
|
+
createNodeImportResolver
|
|
33
|
+
};
|