rainbowindex 0.4.0 → 0.5.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 +163 -0
- package/README.md +5 -4
- package/dist/browser.mjs +1 -1
- package/dist/{chunk-TLR6RP5L.mjs → chunk-CMB6BHVE.mjs} +27 -10
- package/dist/{chunk-4SVFFDS2.mjs → chunk-DT5HYIM3.mjs} +240 -65
- package/dist/{chunk-5Y7EXXLS.mjs → chunk-KRZL4IDK.mjs} +18 -5
- package/dist/{chunk-YLB6FGIG.mjs → chunk-NXJZX6KI.mjs} +2 -2
- package/dist/{chunk-6DAHUFNU.mjs → chunk-ZI5ZYNSU.mjs} +917 -630
- package/dist/cli.mjs +93 -38
- package/dist/editor.d.ts +2 -2
- package/dist/editor.mjs +4 -4
- package/dist/{index-BB2HoeMj.d.ts → index-Dp6i5TSv.d.ts} +15 -11
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +4 -4
- package/dist/vite.mjs +36 -60
- package/package.json +2 -1
package/dist/cli.mjs
CHANGED
|
@@ -2,28 +2,30 @@
|
|
|
2
2
|
import {
|
|
3
3
|
CSS_ENTRY_CANDIDATES,
|
|
4
4
|
enumerateClassNames
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-NXJZX6KI.mjs";
|
|
6
6
|
import {
|
|
7
7
|
DEFAULT_EXCLUDES,
|
|
8
8
|
DEFAULT_PATTERNS,
|
|
9
9
|
compileScannedProject,
|
|
10
10
|
getFontPreloadLinks
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-DT5HYIM3.mjs";
|
|
12
12
|
import {
|
|
13
13
|
MAX_DIRECTIVE_INPUT_SIZE,
|
|
14
|
+
codepointCompare,
|
|
15
|
+
extractClassesFromSource,
|
|
14
16
|
extractDirectives,
|
|
15
17
|
hasApplyLikeDirective,
|
|
16
18
|
hasRIActivation,
|
|
17
19
|
listVariants,
|
|
18
20
|
resolveDirectives
|
|
19
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-ZI5ZYNSU.mjs";
|
|
20
22
|
import {
|
|
21
23
|
devWarn
|
|
22
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-KRZL4IDK.mjs";
|
|
23
25
|
|
|
24
26
|
// src/entries/cli.ts
|
|
25
27
|
import { realpathSync } from "fs";
|
|
26
|
-
import { resolve as
|
|
28
|
+
import { resolve as resolve7 } from "path";
|
|
27
29
|
import { pathToFileURL } from "url";
|
|
28
30
|
|
|
29
31
|
// src/cli/args.ts
|
|
@@ -153,6 +155,22 @@ Examples:
|
|
|
153
155
|
rainbowindex generate-types
|
|
154
156
|
rainbowindex generate-types --strict --css src/styles.css`
|
|
155
157
|
},
|
|
158
|
+
scan: {
|
|
159
|
+
summary: "Show what the class scanner extracts (debugging)",
|
|
160
|
+
usage: " rainbowindex scan <file|glob...>",
|
|
161
|
+
flags: [],
|
|
162
|
+
positionals: "globs",
|
|
163
|
+
body: `Output:
|
|
164
|
+
One line per extracted class candidate, per file. Scanner warnings (skipped
|
|
165
|
+
over-long lines, unreadable files) print to stderr with [RI-NNNN] codes.
|
|
166
|
+
A class missing here was never seen by the scanner \u2014 check how it appears
|
|
167
|
+
in the markup. A class listed here that still does not generate fails
|
|
168
|
+
later \u2014 check the build warnings.
|
|
169
|
+
|
|
170
|
+
Examples:
|
|
171
|
+
rainbowindex scan src/components/icons/logo.tsx
|
|
172
|
+
rainbowindex scan "src/**/*.tsx"`
|
|
173
|
+
},
|
|
156
174
|
"preload-fonts": {
|
|
157
175
|
summary: 'Generate <link rel="preload"> tags',
|
|
158
176
|
usage: " rainbowindex preload-fonts [options]",
|
|
@@ -261,6 +279,11 @@ function parseArgs(argv, callbacks) {
|
|
|
261
279
|
if (opts.command === "create" && !opts.targetDir) {
|
|
262
280
|
throw new Error("create requires a project directory. Example: rainbowindex create my-app");
|
|
263
281
|
}
|
|
282
|
+
if (opts.command === "scan" && opts.globs.length === 0) {
|
|
283
|
+
throw new Error(
|
|
284
|
+
'scan requires at least one file or glob. Example: rainbowindex scan "src/**/*.tsx"'
|
|
285
|
+
);
|
|
286
|
+
}
|
|
264
287
|
if (opts.watch && !opts.output) {
|
|
265
288
|
throw new Error(
|
|
266
289
|
'--output is required with --watch. Example: rainbowindex "src/**/*.tsx" --watch -o dist/styles.css'
|
|
@@ -303,8 +326,7 @@ function printHelp(subcommand) {
|
|
|
303
326
|
${spec.usage}`,
|
|
304
327
|
...spec.intro ? [spec.intro] : [],
|
|
305
328
|
`Options:
|
|
306
|
-
${renderFlagLines(spec.flags)}
|
|
307
|
-
${HELP_LINE}`,
|
|
329
|
+
${[renderFlagLines(spec.flags), HELP_LINE].filter(Boolean).join("\n")}`,
|
|
308
330
|
spec.body
|
|
309
331
|
];
|
|
310
332
|
console.log(`
|
|
@@ -321,6 +343,7 @@ Usage:
|
|
|
321
343
|
rainbowindex create <dir> Scaffold a Vite app with Rainbow Index ready
|
|
322
344
|
rainbowindex generate-types Generate TypeScript types for ri()
|
|
323
345
|
rainbowindex preload-fonts Generate font preload link tags
|
|
346
|
+
rainbowindex scan <file...> Show what the class scanner extracts
|
|
324
347
|
|
|
325
348
|
Run \`rainbowindex <subcommand> --help\` for subcommand-specific options.
|
|
326
349
|
|
|
@@ -772,11 +795,40 @@ async function watchMode(opts, cwd) {
|
|
|
772
795
|
process.on("SIGTERM", cleanup);
|
|
773
796
|
}
|
|
774
797
|
|
|
798
|
+
// src/cli/scan.ts
|
|
799
|
+
import { readFile as readFile3 } from "fs/promises";
|
|
800
|
+
import { relative as relative2, resolve as resolve5 } from "path";
|
|
801
|
+
import { glob } from "tinyglobby";
|
|
802
|
+
async function scanFiles(opts, cwd) {
|
|
803
|
+
const files = [...new Set(await glob(opts.globs, { cwd }))].sort(codepointCompare);
|
|
804
|
+
if (files.length === 0) {
|
|
805
|
+
throw new Error(`No files matched ${opts.globs.map((g) => `"${g}"`).join(", ")}.`);
|
|
806
|
+
}
|
|
807
|
+
for (const file of files) {
|
|
808
|
+
const path = resolve5(cwd, file);
|
|
809
|
+
const warnings = [];
|
|
810
|
+
const classes = extractClassesFromSource(
|
|
811
|
+
{ path, content: await readFile3(path, "utf-8") },
|
|
812
|
+
warnings
|
|
813
|
+
);
|
|
814
|
+
const sorted = [...classes].sort(codepointCompare);
|
|
815
|
+
console.log(
|
|
816
|
+
`${relative2(cwd, path)} (${sorted.length} class${sorted.length === 1 ? "" : "es"})`
|
|
817
|
+
);
|
|
818
|
+
for (const cls of sorted) {
|
|
819
|
+
console.log(` ${cls}`);
|
|
820
|
+
}
|
|
821
|
+
for (const warning of warnings) {
|
|
822
|
+
console.error(` ${warning}`);
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
|
|
775
827
|
// src/cli/vite-setup.ts
|
|
776
828
|
import { spawn } from "child_process";
|
|
777
829
|
import { existsSync as existsSync3, readFileSync } from "fs";
|
|
778
|
-
import { mkdir as mkdir2, readFile as
|
|
779
|
-
import { dirname as dirname3, relative as
|
|
830
|
+
import { mkdir as mkdir2, readFile as readFile4, readdir, writeFile as writeFile3 } from "fs/promises";
|
|
831
|
+
import { dirname as dirname3, relative as relative3, resolve as resolve6 } from "path";
|
|
780
832
|
var VITE_CONFIG_FILES = [
|
|
781
833
|
"vite.config.ts",
|
|
782
834
|
"vite.config.mts",
|
|
@@ -839,32 +891,32 @@ async function initViteProject(opts, cwd, deps = {}) {
|
|
|
839
891
|
ensureStylesheet(cssPath)
|
|
840
892
|
]);
|
|
841
893
|
const entryChanged = cssCreated ? await ensureStylesheetImport(entryFile, cssPath) : false;
|
|
842
|
-
const rootLabel =
|
|
894
|
+
const rootLabel = relative3(process.cwd(), cwd) || ".";
|
|
843
895
|
console.log(`[rainbowindex] Initialized Vite project: ${rootLabel}`);
|
|
844
896
|
if (dependencyInstalled) {
|
|
845
897
|
console.log("[rainbowindex] Added dev dependency: rainbowindex");
|
|
846
898
|
}
|
|
847
899
|
if (configCreated) {
|
|
848
900
|
console.log(
|
|
849
|
-
`[rainbowindex] Created Vite config: ${
|
|
901
|
+
`[rainbowindex] Created Vite config: ${relative3(cwd, configPath).replaceAll("\\", "/")}`
|
|
850
902
|
);
|
|
851
903
|
} else if (configChanged) {
|
|
852
904
|
console.log(
|
|
853
|
-
`[rainbowindex] Updated Vite config: ${
|
|
905
|
+
`[rainbowindex] Updated Vite config: ${relative3(cwd, configPath).replaceAll("\\", "/")}`
|
|
854
906
|
);
|
|
855
907
|
}
|
|
856
908
|
if (cssCreated) {
|
|
857
909
|
console.log(
|
|
858
|
-
`[rainbowindex] Created stylesheet: ${
|
|
910
|
+
`[rainbowindex] Created stylesheet: ${relative3(cwd, cssPath).replaceAll("\\", "/")}`
|
|
859
911
|
);
|
|
860
912
|
} else if (cssChanged) {
|
|
861
913
|
console.log(
|
|
862
|
-
`[rainbowindex] Updated stylesheet: ${
|
|
914
|
+
`[rainbowindex] Updated stylesheet: ${relative3(cwd, cssPath).replaceAll("\\", "/")}`
|
|
863
915
|
);
|
|
864
916
|
}
|
|
865
917
|
if (entryChanged && entryFile) {
|
|
866
918
|
console.log(
|
|
867
|
-
`[rainbowindex] Added stylesheet import: ${
|
|
919
|
+
`[rainbowindex] Added stylesheet import: ${relative3(cwd, entryFile).replaceAll("\\", "/")}`
|
|
868
920
|
);
|
|
869
921
|
}
|
|
870
922
|
if (!dependencyInstalled && !configChanged && !configCreated && !cssChanged && !cssCreated) {
|
|
@@ -888,7 +940,7 @@ async function createViteProject(opts, cwd, deps = {}) {
|
|
|
888
940
|
const packageManager = deps.packageManager ?? detectPackageManager(cwd, deps.env);
|
|
889
941
|
const runner = deps.runner ?? DEFAULT_RUNNER;
|
|
890
942
|
const targetDir = opts.targetDir;
|
|
891
|
-
const targetRoot =
|
|
943
|
+
const targetRoot = resolve6(cwd, targetDir);
|
|
892
944
|
await ensureScaffoldTargetIsUsable(targetRoot);
|
|
893
945
|
const template = opts.template || DEFAULT_CREATE_TEMPLATE;
|
|
894
946
|
const scaffold = getCreateCommand(packageManager, targetDir, template);
|
|
@@ -899,15 +951,15 @@ async function createViteProject(opts, cwd, deps = {}) {
|
|
|
899
951
|
packageManager,
|
|
900
952
|
runner
|
|
901
953
|
});
|
|
902
|
-
const displayTarget =
|
|
954
|
+
const displayTarget = relative3(cwd, targetRoot) || ".";
|
|
903
955
|
console.log(`[rainbowindex] Ready: ${displayTarget}`);
|
|
904
956
|
console.log(`[rainbowindex] Next: cd ${displayTarget} && ${packageManager} run dev`);
|
|
905
957
|
}
|
|
906
958
|
function detectPackageManager(cwd, env = process.env) {
|
|
907
|
-
if (existsSync3(
|
|
908
|
-
if (existsSync3(
|
|
909
|
-
if (existsSync3(
|
|
910
|
-
if (existsSync3(
|
|
959
|
+
if (existsSync3(resolve6(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
960
|
+
if (existsSync3(resolve6(cwd, "yarn.lock"))) return "yarn";
|
|
961
|
+
if (existsSync3(resolve6(cwd, "bun.lock")) || existsSync3(resolve6(cwd, "bun.lockb"))) return "bun";
|
|
962
|
+
if (existsSync3(resolve6(cwd, "package-lock.json")) || existsSync3(resolve6(cwd, "npm-shrinkwrap.json"))) {
|
|
911
963
|
return "npm";
|
|
912
964
|
}
|
|
913
965
|
const packageJSON = readPackageJSONSync(cwd);
|
|
@@ -952,12 +1004,12 @@ async function installRainbowIndex(cwd, packageManager, runner) {
|
|
|
952
1004
|
async function ensureViteConfig(cwd, packageJSON, existingPath) {
|
|
953
1005
|
if (!existingPath) {
|
|
954
1006
|
const fileName = chooseViteConfigName(cwd, packageJSON);
|
|
955
|
-
const configPath =
|
|
1007
|
+
const configPath = resolve6(cwd, fileName);
|
|
956
1008
|
const content = 'import { defineConfig } from "vite";\nimport rainbowindex from "rainbowindex/vite";\n\nexport default defineConfig({\n plugins: [rainbowindex()],\n});\n';
|
|
957
1009
|
await writeFile3(configPath, content, "utf-8");
|
|
958
1010
|
return { path: configPath, changed: true, created: true };
|
|
959
1011
|
}
|
|
960
|
-
const original = await
|
|
1012
|
+
const original = await readFile4(existingPath, "utf-8");
|
|
961
1013
|
const updated = patchViteConfig(original, existingPath);
|
|
962
1014
|
if (updated === original) {
|
|
963
1015
|
return { path: existingPath, changed: false, created: false };
|
|
@@ -1086,14 +1138,14 @@ function findMatchingDelimiter(input, start, open, close) {
|
|
|
1086
1138
|
return -1;
|
|
1087
1139
|
}
|
|
1088
1140
|
async function resolveStylesheetPath(cwd, cssFile) {
|
|
1089
|
-
if (cssFile) return
|
|
1141
|
+
if (cssFile) return resolve6(cwd, cssFile);
|
|
1090
1142
|
const importedCSS = await findImportedStylesheet(cwd);
|
|
1091
1143
|
if (importedCSS) return importedCSS;
|
|
1092
1144
|
for (const candidate of CSS_ENTRY_CANDIDATES) {
|
|
1093
|
-
const fullPath =
|
|
1145
|
+
const fullPath = resolve6(cwd, candidate);
|
|
1094
1146
|
if (existsSync3(fullPath)) return fullPath;
|
|
1095
1147
|
}
|
|
1096
|
-
return existsSync3(
|
|
1148
|
+
return existsSync3(resolve6(cwd, "src")) ? resolve6(cwd, "src/index.css") : resolve6(cwd, "index.css");
|
|
1097
1149
|
}
|
|
1098
1150
|
async function ensureStylesheet(cssPath) {
|
|
1099
1151
|
if (!existsSync3(cssPath)) {
|
|
@@ -1101,7 +1153,7 @@ async function ensureStylesheet(cssPath) {
|
|
|
1101
1153
|
await writeFile3(cssPath, '@import "rainbowindex";\n', "utf-8");
|
|
1102
1154
|
return { changed: true, created: true };
|
|
1103
1155
|
}
|
|
1104
|
-
const original = await
|
|
1156
|
+
const original = await readFile4(cssPath, "utf-8");
|
|
1105
1157
|
if (/@import\s+["']rainbowindex["']/.test(original)) {
|
|
1106
1158
|
return { changed: false, created: false };
|
|
1107
1159
|
}
|
|
@@ -1128,7 +1180,7 @@ ${content}`;
|
|
|
1128
1180
|
}
|
|
1129
1181
|
async function ensureStylesheetImport(entryFile, cssPath) {
|
|
1130
1182
|
if (!entryFile || !existsSync3(entryFile)) return false;
|
|
1131
|
-
const original = await
|
|
1183
|
+
const original = await readFile4(entryFile, "utf-8");
|
|
1132
1184
|
const relativePath = toImportPath(dirname3(entryFile), cssPath);
|
|
1133
1185
|
if (hasStylesheetImport(original, relativePath)) {
|
|
1134
1186
|
return false;
|
|
@@ -1139,16 +1191,16 @@ async function ensureStylesheetImport(entryFile, cssPath) {
|
|
|
1139
1191
|
}
|
|
1140
1192
|
async function findImportedStylesheet(cwd) {
|
|
1141
1193
|
for (const entryFile of ENTRY_FILES) {
|
|
1142
|
-
const fullPath =
|
|
1194
|
+
const fullPath = resolve6(cwd, entryFile);
|
|
1143
1195
|
if (!existsSync3(fullPath)) continue;
|
|
1144
|
-
const content = await
|
|
1196
|
+
const content = await readFile4(fullPath, "utf-8");
|
|
1145
1197
|
const matches = content.matchAll(
|
|
1146
1198
|
/import\s+(?:.+?\s+from\s+)?["']([^"']+\.css(?:\?[^"']*)?)["']/g
|
|
1147
1199
|
);
|
|
1148
1200
|
for (const match of matches) {
|
|
1149
1201
|
const importPath = match[1].split("?")[0];
|
|
1150
1202
|
if (!importPath.startsWith(".")) continue;
|
|
1151
|
-
const stylesheet =
|
|
1203
|
+
const stylesheet = resolve6(dirname3(fullPath), importPath);
|
|
1152
1204
|
if (existsSync3(stylesheet)) return stylesheet;
|
|
1153
1205
|
}
|
|
1154
1206
|
}
|
|
@@ -1156,7 +1208,7 @@ async function findImportedStylesheet(cwd) {
|
|
|
1156
1208
|
}
|
|
1157
1209
|
async function findEntryFile(cwd) {
|
|
1158
1210
|
for (const entryFile of ENTRY_FILES) {
|
|
1159
|
-
const fullPath =
|
|
1211
|
+
const fullPath = resolve6(cwd, entryFile);
|
|
1160
1212
|
if (existsSync3(fullPath)) return fullPath;
|
|
1161
1213
|
}
|
|
1162
1214
|
return null;
|
|
@@ -1166,18 +1218,18 @@ function hasStylesheetImport(source, importPath) {
|
|
|
1166
1218
|
return new RegExp(`import\\s+(?:.+?\\s+from\\s+)?["']${escapedPath}["']`).test(source);
|
|
1167
1219
|
}
|
|
1168
1220
|
function toImportPath(fromDir, targetFile) {
|
|
1169
|
-
const rel =
|
|
1221
|
+
const rel = relative3(fromDir, targetFile).replaceAll("\\", "/");
|
|
1170
1222
|
return rel.startsWith(".") ? rel : `./${rel}`;
|
|
1171
1223
|
}
|
|
1172
1224
|
function findExistingViteConfig(cwd) {
|
|
1173
1225
|
for (const name of VITE_CONFIG_FILES) {
|
|
1174
|
-
const fullPath =
|
|
1226
|
+
const fullPath = resolve6(cwd, name);
|
|
1175
1227
|
if (existsSync3(fullPath)) return fullPath;
|
|
1176
1228
|
}
|
|
1177
1229
|
return null;
|
|
1178
1230
|
}
|
|
1179
1231
|
function chooseViteConfigName(cwd, packageJSON) {
|
|
1180
|
-
if (existsSync3(
|
|
1232
|
+
if (existsSync3(resolve6(cwd, "tsconfig.json")) || existsSync3(resolve6(cwd, "tsconfig.app.json")) || existsSync3(resolve6(cwd, "src/main.ts")) || existsSync3(resolve6(cwd, "src/main.tsx")) || packageJSON?.dependencies?.typescript || packageJSON?.devDependencies?.typescript) {
|
|
1181
1233
|
return "vite.config.ts";
|
|
1182
1234
|
}
|
|
1183
1235
|
return packageJSON?.type === "module" ? "vite.config.js" : "vite.config.mjs";
|
|
@@ -1225,7 +1277,7 @@ function getInstallCommand(packageManager) {
|
|
|
1225
1277
|
}
|
|
1226
1278
|
}
|
|
1227
1279
|
function readPackageJSONSync(cwd) {
|
|
1228
|
-
const packagePath =
|
|
1280
|
+
const packagePath = resolve6(cwd, "package.json");
|
|
1229
1281
|
if (!existsSync3(packagePath)) return null;
|
|
1230
1282
|
try {
|
|
1231
1283
|
return JSON.parse(readFileSync(packagePath, "utf-8"));
|
|
@@ -1236,7 +1288,7 @@ function readPackageJSONSync(cwd) {
|
|
|
1236
1288
|
|
|
1237
1289
|
// src/entries/cli.ts
|
|
1238
1290
|
function getVersion() {
|
|
1239
|
-
return true ? "0.
|
|
1291
|
+
return true ? "0.5.0" : "unknown";
|
|
1240
1292
|
}
|
|
1241
1293
|
async function main() {
|
|
1242
1294
|
const args = process.argv.slice(2);
|
|
@@ -1260,6 +1312,9 @@ async function main() {
|
|
|
1260
1312
|
case "preload-fonts":
|
|
1261
1313
|
await preloadFonts(opts, cwd);
|
|
1262
1314
|
break;
|
|
1315
|
+
case "scan":
|
|
1316
|
+
await scanFiles(opts, cwd);
|
|
1317
|
+
break;
|
|
1263
1318
|
case "build": {
|
|
1264
1319
|
if (opts.watch) {
|
|
1265
1320
|
await watchMode(opts, cwd);
|
|
@@ -1280,7 +1335,7 @@ var isDirectExecution = (() => {
|
|
|
1280
1335
|
const entry = process.argv[1];
|
|
1281
1336
|
if (entry === void 0) return false;
|
|
1282
1337
|
try {
|
|
1283
|
-
return import.meta.url === pathToFileURL(realpathSync(
|
|
1338
|
+
return import.meta.url === pathToFileURL(realpathSync(resolve7(entry))).href;
|
|
1284
1339
|
} catch {
|
|
1285
1340
|
return false;
|
|
1286
1341
|
}
|
package/dist/editor.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { P as ParsedDirective, R as ResolvedTheme } from './index-
|
|
2
|
-
export { b as createThemeSnapshot } from './index-
|
|
1
|
+
import { P as ParsedDirective, R as ResolvedTheme } from './index-Dp6i5TSv.js';
|
|
2
|
+
export { b as createThemeSnapshot } from './index-Dp6i5TSv.js';
|
|
3
3
|
import { b as CompilationSnapshot, C as ColorDefinition } from './context-ruu2x_jR.js';
|
|
4
4
|
export { e as defaultTheme } from './context-ruu2x_jR.js';
|
|
5
5
|
|
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-NXJZX6KI.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-ZI5ZYNSU.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-KRZL4IDK.mjs";
|
|
42
42
|
|
|
43
43
|
// src/engine/inspector.ts
|
|
44
44
|
var RESOLUTION_CACHE_CAP = 1e4;
|
|
@@ -383,7 +383,7 @@ function createEditorSession(options = {}) {
|
|
|
383
383
|
}
|
|
384
384
|
|
|
385
385
|
// src/entries/editor.ts
|
|
386
|
-
var version = true ? "0.
|
|
386
|
+
var version = true ? "0.5.0" : "0.0.0-dev";
|
|
387
387
|
var EDITOR_API_VERSION = 1;
|
|
388
388
|
var editorCapabilities = Object.freeze([
|
|
389
389
|
"class-candidates",
|
|
@@ -12,11 +12,9 @@ interface FontFace {
|
|
|
12
12
|
style: string;
|
|
13
13
|
/** font-display strategy. */
|
|
14
14
|
display: string;
|
|
15
|
-
/** Unicode subsets — used as a Google Fonts URL hint. */
|
|
16
|
-
subset: string;
|
|
17
15
|
/** Optional unicode-range descriptor emitted into the @font-face (local subsetting). */
|
|
18
16
|
unicodeRange?: string;
|
|
19
|
-
/**
|
|
17
|
+
/** Whether to emit a preload link for this face's font file. */
|
|
20
18
|
preload?: boolean;
|
|
21
19
|
/** Whether the weight was explicitly set by the user (not a default).
|
|
22
20
|
* Used by refreshFontWeightDefaults() to avoid overriding user intent. */
|
|
@@ -38,19 +36,25 @@ interface FontSlot {
|
|
|
38
36
|
features: string | null;
|
|
39
37
|
/** Font variation settings — applied via the font-<slot> utility. */
|
|
40
38
|
variation: string | null;
|
|
41
|
-
/** Slot-level preload default for faces that don't set their own. */
|
|
42
|
-
preload: boolean;
|
|
43
39
|
/** One or more faces — each emits an @font-face for local providers. */
|
|
44
40
|
faces: FontFace[];
|
|
45
|
-
/**
|
|
46
|
-
|
|
47
|
-
|
|
41
|
+
/**
|
|
42
|
+
* CLS-fallback metrics config from the `metrics:` key. Absent = automatic
|
|
43
|
+
* (from the built-in table when the family is known); `null` = disabled via
|
|
44
|
+
* `metrics: none`; an object overrides the fallback font and/or the numbers.
|
|
45
|
+
*/
|
|
46
|
+
metrics?: FontMetricsConfig | null;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Parsed `metrics:` value. `fallback` picks the local font to metric-match.
|
|
50
|
+
* The four override percentages are all-present or all-absent (the parser
|
|
51
|
+
* enforces arity); when absent they are computed from the built-in table.
|
|
52
|
+
*/
|
|
53
|
+
interface FontMetricsConfig {
|
|
54
|
+
fallback?: string;
|
|
48
55
|
sizeAdjust?: number;
|
|
49
|
-
/** User-specified ascent-override percentage. */
|
|
50
56
|
ascent?: number;
|
|
51
|
-
/** User-specified descent-override percentage. */
|
|
52
57
|
descent?: number;
|
|
53
|
-
/** User-specified line-gap-override percentage. */
|
|
54
58
|
lineGap?: number;
|
|
55
59
|
}
|
|
56
60
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { PluginCreator } from 'postcss';
|
|
2
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-ruu2x_jR.js';
|
|
3
3
|
export { D as DEFAULT_TEXT_SIZES, c as createRi, r as ri, s as safelist } from './safelist-D9-Plqta.js';
|
|
4
|
-
import { R as ResolvedTheme, P as ParsedDirective } from './index-
|
|
5
|
-
export { C as CompilationResult, a as CompiledRule, c as createCompiler } from './index-
|
|
4
|
+
import { R as ResolvedTheme, P as ParsedDirective } from './index-Dp6i5TSv.js';
|
|
5
|
+
export { C as CompilationResult, a as CompiledRule, c as createCompiler } from './index-Dp6i5TSv.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-CMB6BHVE.mjs";
|
|
7
7
|
import {
|
|
8
8
|
finalizeProjectCompilation,
|
|
9
9
|
resolveGoogleFonts
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-DT5HYIM3.mjs";
|
|
11
11
|
import {
|
|
12
12
|
analyzeProjectCSS,
|
|
13
13
|
createCompiler,
|
|
14
14
|
extractClassesFromSource,
|
|
15
15
|
pushWarningsDeduped
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-ZI5ZYNSU.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-KRZL4IDK.mjs";
|
|
29
29
|
|
|
30
30
|
// src/project/index.ts
|
|
31
31
|
async function compileProject(options) {
|
package/dist/vite.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
postcss_default
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-CMB6BHVE.mjs";
|
|
4
|
+
import "./chunk-DT5HYIM3.mjs";
|
|
5
5
|
import {
|
|
6
6
|
isSourceFile
|
|
7
7
|
} from "./chunk-3HRMFZGE.mjs";
|
|
@@ -12,10 +12,10 @@ import {
|
|
|
12
12
|
hasRIActivation,
|
|
13
13
|
isAtRuleBoundary,
|
|
14
14
|
isAtRuleNameChar
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-ZI5ZYNSU.mjs";
|
|
16
16
|
import {
|
|
17
17
|
devWarn
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-KRZL4IDK.mjs";
|
|
19
19
|
|
|
20
20
|
// src/integrations/vite.ts
|
|
21
21
|
import { existsSync } from "fs";
|
|
@@ -57,61 +57,33 @@ var KEYWORD_BODY_DIRECTIVES = new Set(
|
|
|
57
57
|
var REMOVAL_RE = /!([\w][\w-]*)\s*;/g;
|
|
58
58
|
var FLUID_KEYWORD_RE = /\b(no-parabolic|parabolic|no-shift|shift)\s*;?/g;
|
|
59
59
|
var COLOR_FLAG_RE = /(?<=[{;\s]|^)(inline|no-parabolic|parabolic)\s*(?:;|(?=}))/g;
|
|
60
|
-
function
|
|
61
|
-
|
|
60
|
+
function mapTopLevelSpans(body, mapOutside, mapBlock) {
|
|
61
|
+
let brace = body.indexOf("{");
|
|
62
|
+
if (brace === -1) return mapOutside(body);
|
|
62
63
|
let out = "";
|
|
63
64
|
let segStart = 0;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const
|
|
67
|
-
if (
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
depth++;
|
|
73
|
-
} else if (ch === "}") {
|
|
74
|
-
if (depth > 0) depth--;
|
|
75
|
-
if (depth === 0) {
|
|
76
|
-
out += body.slice(segStart, i + 1);
|
|
77
|
-
segStart = i + 1;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
65
|
+
while (brace !== -1) {
|
|
66
|
+
out += mapOutside(body.slice(segStart, brace));
|
|
67
|
+
const close = findClosingBrace(body, brace);
|
|
68
|
+
if (close === -1) return out + body.slice(brace);
|
|
69
|
+
out += `{${mapBlock(body.slice(brace + 1, close))}}`;
|
|
70
|
+
segStart = close + 1;
|
|
71
|
+
brace = body.indexOf("{", segStart);
|
|
80
72
|
}
|
|
81
|
-
out
|
|
82
|
-
return out;
|
|
73
|
+
return out + mapOutside(body.slice(segStart));
|
|
83
74
|
}
|
|
75
|
+
var keepSpan = (span) => span;
|
|
84
76
|
function rewriteColorOptionFlag(_match, keyword) {
|
|
85
77
|
if (keyword === "inline") return "--ri-inline: true;";
|
|
86
78
|
const negated = keyword.startsWith("no-");
|
|
87
79
|
return `--ri-${negated ? keyword.slice(3) : keyword}: ${negated ? "false" : "true"};`;
|
|
88
80
|
}
|
|
89
81
|
function rewriteColorOptionFlags(body) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
for (let i = 0; i < body.length; i++) {
|
|
96
|
-
const ch = body[i];
|
|
97
|
-
if (ch === "{") {
|
|
98
|
-
if (depth === 0) {
|
|
99
|
-
out += body.slice(segStart, i + 1);
|
|
100
|
-
blockStart = i + 1;
|
|
101
|
-
}
|
|
102
|
-
depth++;
|
|
103
|
-
} else if (ch === "}") {
|
|
104
|
-
if (depth > 0) depth--;
|
|
105
|
-
if (depth === 0 && blockStart !== -1) {
|
|
106
|
-
out += body.slice(blockStart, i).replace(COLOR_FLAG_RE, rewriteColorOptionFlag);
|
|
107
|
-
out += "}";
|
|
108
|
-
segStart = i + 1;
|
|
109
|
-
blockStart = -1;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
out += body.slice(segStart);
|
|
114
|
-
return out;
|
|
82
|
+
return mapTopLevelSpans(
|
|
83
|
+
body,
|
|
84
|
+
keepSpan,
|
|
85
|
+
(interior) => interior.replace(COLOR_FLAG_RE, rewriteColorOptionFlag)
|
|
86
|
+
);
|
|
115
87
|
}
|
|
116
88
|
function rewriteDirectiveBodies(code) {
|
|
117
89
|
let out = "";
|
|
@@ -146,17 +118,21 @@ function rewriteDirectiveBodies(code) {
|
|
|
146
118
|
const close = findClosingBrace(code, braceIdx);
|
|
147
119
|
const bodyStart = braceIdx + 1;
|
|
148
120
|
const bodyEnd = close === -1 ? code.length : close;
|
|
149
|
-
let rewritten =
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
s = s.replace(
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
121
|
+
let rewritten = mapTopLevelSpans(
|
|
122
|
+
code.slice(bodyStart, bodyEnd),
|
|
123
|
+
(span) => {
|
|
124
|
+
let s = span;
|
|
125
|
+
if (removals) s = s.replace(REMOVAL_RE, "--ri-rm: $1;");
|
|
126
|
+
if (keywords) {
|
|
127
|
+
s = s.replace(FLUID_KEYWORD_RE, (_, kw) => {
|
|
128
|
+
const negated = kw.startsWith("no-");
|
|
129
|
+
return `--ri-${negated ? kw.slice(3) : kw}: ${negated ? "false" : "true"};`;
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
return s;
|
|
133
|
+
},
|
|
134
|
+
keepSpan
|
|
135
|
+
);
|
|
160
136
|
if (name === "color") rewritten = rewriteColorOptionFlags(rewritten);
|
|
161
137
|
out += code.slice(last, bodyStart) + rewritten;
|
|
162
138
|
last = bodyEnd;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rainbowindex",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "CSS-first system for building and maintaining consistent user interfaces",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"css",
|
|
@@ -97,6 +97,7 @@
|
|
|
97
97
|
},
|
|
98
98
|
"devDependencies": {
|
|
99
99
|
"@biomejs/biome": "^2.4.16",
|
|
100
|
+
"@capsizecss/metrics": "^4.2.0",
|
|
100
101
|
"@types/node": "^25.9.1",
|
|
101
102
|
"@vitest/coverage-v8": "^4.1.0",
|
|
102
103
|
"postcss": "^8.5.8",
|