rainbowindex 0.2.2 → 0.4.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 +70 -14
- package/LICENSE +1 -1
- package/README.md +23 -2
- package/dist/browser.d.ts +2 -2
- package/dist/browser.mjs +1 -1
- package/dist/chunk-3HRMFZGE.mjs +19 -0
- package/dist/{chunk-FHATRQMN.mjs → chunk-4SVFFDS2.mjs} +495 -461
- package/dist/{chunk-SOMDX7V6.mjs → chunk-5Y7EXXLS.mjs} +320 -417
- package/dist/{chunk-W6XIBM4M.mjs → chunk-6DAHUFNU.mjs} +5278 -4928
- package/dist/{chunk-CUUW2K35.mjs → chunk-TLR6RP5L.mjs} +41 -120
- package/dist/chunk-YLB6FGIG.mjs +244 -0
- package/dist/cli.mjs +280 -277
- package/dist/{index-CfDtWufj.d.ts → context-ruu2x_jR.d.ts} +15 -70
- package/dist/editor.d.ts +106 -28
- package/dist/editor.mjs +44 -12
- package/dist/{index-DK6APAGD.d.ts → index-BB2HoeMj.d.ts} +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.mjs +4 -4
- package/dist/safelist-D9-Plqta.d.ts +109 -0
- package/dist/vite.mjs +48 -27
- package/package.json +1 -1
- package/dist/chunk-KYDEHYIE.mjs +0 -691
- package/dist/safelist-CH3_PywB.d.ts +0 -43
package/dist/cli.mjs
CHANGED
|
@@ -2,28 +2,24 @@
|
|
|
2
2
|
import {
|
|
3
3
|
CSS_ENTRY_CANDIDATES,
|
|
4
4
|
enumerateClassNames
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-YLB6FGIG.mjs";
|
|
6
6
|
import {
|
|
7
7
|
DEFAULT_EXCLUDES,
|
|
8
8
|
DEFAULT_PATTERNS,
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
resolveGoogleFonts,
|
|
13
|
-
validateGlobPattern
|
|
14
|
-
} from "./chunk-FHATRQMN.mjs";
|
|
9
|
+
compileScannedProject,
|
|
10
|
+
getFontPreloadLinks
|
|
11
|
+
} from "./chunk-4SVFFDS2.mjs";
|
|
15
12
|
import {
|
|
16
13
|
MAX_DIRECTIVE_INPUT_SIZE,
|
|
17
|
-
analyzeProjectCSS,
|
|
18
14
|
extractDirectives,
|
|
19
15
|
hasApplyLikeDirective,
|
|
20
16
|
hasRIActivation,
|
|
21
17
|
listVariants,
|
|
22
18
|
resolveDirectives
|
|
23
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-6DAHUFNU.mjs";
|
|
24
20
|
import {
|
|
25
21
|
devWarn
|
|
26
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-5Y7EXXLS.mjs";
|
|
27
23
|
|
|
28
24
|
// src/entries/cli.ts
|
|
29
25
|
import { realpathSync } from "fs";
|
|
@@ -32,6 +28,153 @@ import { pathToFileURL } from "url";
|
|
|
32
28
|
|
|
33
29
|
// src/cli/args.ts
|
|
34
30
|
import { relative, resolve } from "path";
|
|
31
|
+
var OUTPUT = {
|
|
32
|
+
names: ["-o", "--output"],
|
|
33
|
+
valueName: "<file>",
|
|
34
|
+
describe: "Output CSS file path (omit to write to stdout)",
|
|
35
|
+
apply(opts, value) {
|
|
36
|
+
opts.output = value;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
var WATCH = {
|
|
40
|
+
names: ["--watch"],
|
|
41
|
+
describe: "Re-run on source-file changes (requires --output)",
|
|
42
|
+
apply(opts) {
|
|
43
|
+
opts.watch = true;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
var MINIFY = {
|
|
47
|
+
names: ["--minify", "--optimize"],
|
|
48
|
+
helpLabel: "--minify",
|
|
49
|
+
describe: "Minify + browser fallbacks via LightningCSS (alias: --optimize)",
|
|
50
|
+
apply(opts) {
|
|
51
|
+
opts.minify = true;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
var STRICT = {
|
|
55
|
+
names: ["--strict"],
|
|
56
|
+
describe: "Drop the `string & {}` escape hatch from the union",
|
|
57
|
+
apply(opts) {
|
|
58
|
+
opts.strict = true;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
var TEMPLATE = {
|
|
62
|
+
names: ["--template"],
|
|
63
|
+
valueName: "<name>",
|
|
64
|
+
describe: "Vite template (default: react-ts)\nExamples: vanilla, vanilla-ts, react, react-ts, vue, vue-ts, svelte, svelte-ts",
|
|
65
|
+
apply(opts, value) {
|
|
66
|
+
opts.template = value;
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
var applyCSSFile = (opts, value) => {
|
|
70
|
+
opts.cssFile = value;
|
|
71
|
+
};
|
|
72
|
+
var CSS_INPUT = {
|
|
73
|
+
names: ["--css"],
|
|
74
|
+
valueName: "<file>",
|
|
75
|
+
describe: "CSS input with directives (auto-detected if omitted)",
|
|
76
|
+
apply: applyCSSFile
|
|
77
|
+
};
|
|
78
|
+
var CSS_INPUT_TYPES = {
|
|
79
|
+
names: ["--css"],
|
|
80
|
+
valueName: "<file>",
|
|
81
|
+
describe: "CSS input with @color/@text/@utility/etc directives",
|
|
82
|
+
apply: applyCSSFile
|
|
83
|
+
};
|
|
84
|
+
var CSS_INPUT_FONTS = {
|
|
85
|
+
names: ["--css"],
|
|
86
|
+
valueName: "<file>",
|
|
87
|
+
describe: "CSS input with @font directives",
|
|
88
|
+
apply: applyCSSFile
|
|
89
|
+
};
|
|
90
|
+
var CSS_TARGET = {
|
|
91
|
+
names: ["--css"],
|
|
92
|
+
valueName: "<file>",
|
|
93
|
+
describe: "Stylesheet path to create/patch (default: src/index.css)",
|
|
94
|
+
apply: applyCSSFile
|
|
95
|
+
};
|
|
96
|
+
var COMMANDS = {
|
|
97
|
+
build: {
|
|
98
|
+
summary: "Generate CSS from source files",
|
|
99
|
+
usage: " rainbowindex <glob...> [options]\n rainbowindex --css <file> [options]",
|
|
100
|
+
flags: [OUTPUT, WATCH, MINIFY, CSS_INPUT],
|
|
101
|
+
positionals: "globs",
|
|
102
|
+
body: `Inputs:
|
|
103
|
+
Pass one or more globs to scan for class names. If no globs are passed and
|
|
104
|
+
a CSS file with @source directives is found, those are used instead.
|
|
105
|
+
|
|
106
|
+
Examples:
|
|
107
|
+
rainbowindex "src/**/*.tsx" -o dist/styles.css
|
|
108
|
+
rainbowindex "src/**/*.tsx" --watch -o dist/styles.css
|
|
109
|
+
rainbowindex --css src/styles.css -o dist/styles.css --minify`
|
|
110
|
+
},
|
|
111
|
+
init: {
|
|
112
|
+
summary: "Wire Rainbow Index into the current Vite app",
|
|
113
|
+
usage: " rainbowindex init [options]",
|
|
114
|
+
intro: `What this does:
|
|
115
|
+
1. Installs rainbowindex as a dev dependency (if not already installed).
|
|
116
|
+
2. Creates or patches vite.config.* to register the Vite plugin.
|
|
117
|
+
3. Creates or updates a CSS entry file with @import "rainbowindex".
|
|
118
|
+
4. Adds the CSS import to your entry file (src/main.tsx, src/main.ts, \u2026).`,
|
|
119
|
+
flags: [CSS_TARGET],
|
|
120
|
+
positionals: "none",
|
|
121
|
+
body: `Notes:
|
|
122
|
+
Detects pnpm / yarn / bun / npm from lockfiles, package.json#packageManager,
|
|
123
|
+
and npm_config_user_agent. Requires an existing Vite project \u2014 if you do not
|
|
124
|
+
have one yet, use \`rainbowindex create <dir>\`.
|
|
125
|
+
|
|
126
|
+
Examples:
|
|
127
|
+
rainbowindex init
|
|
128
|
+
rainbowindex init --css src/styles.css`
|
|
129
|
+
},
|
|
130
|
+
create: {
|
|
131
|
+
summary: "Scaffold a Vite app with Rainbow Index ready",
|
|
132
|
+
usage: " rainbowindex create <dir> [options]",
|
|
133
|
+
flags: [TEMPLATE, CSS_TARGET],
|
|
134
|
+
positionals: "targetDir",
|
|
135
|
+
body: `What this does:
|
|
136
|
+
1. Runs \`create vite\` for the given template.
|
|
137
|
+
2. Runs \`rainbowindex init\` inside the new directory.
|
|
138
|
+
|
|
139
|
+
Examples:
|
|
140
|
+
rainbowindex create my-app
|
|
141
|
+
rainbowindex create my-app --template vue-ts`
|
|
142
|
+
},
|
|
143
|
+
"generate-types": {
|
|
144
|
+
summary: "Generate TypeScript types for ri() autocomplete",
|
|
145
|
+
usage: " rainbowindex generate-types [options]",
|
|
146
|
+
flags: [CSS_INPUT_TYPES, STRICT],
|
|
147
|
+
positionals: "none",
|
|
148
|
+
body: `Output:
|
|
149
|
+
Writes \`rainbowindex-env.d.ts\` to the current working directory. Include it
|
|
150
|
+
in tsconfig.json#include (or the equivalent) so the editor picks it up.
|
|
151
|
+
|
|
152
|
+
Examples:
|
|
153
|
+
rainbowindex generate-types
|
|
154
|
+
rainbowindex generate-types --strict --css src/styles.css`
|
|
155
|
+
},
|
|
156
|
+
"preload-fonts": {
|
|
157
|
+
summary: 'Generate <link rel="preload"> tags',
|
|
158
|
+
usage: " rainbowindex preload-fonts [options]",
|
|
159
|
+
flags: [CSS_INPUT_FONTS],
|
|
160
|
+
positionals: "none",
|
|
161
|
+
body: `Output:
|
|
162
|
+
Prints <link rel="preload"> tags to stdout for fonts declared in the @font
|
|
163
|
+
block (faces marked preload), or via @font-face.
|
|
164
|
+
|
|
165
|
+
Examples:
|
|
166
|
+
rainbowindex preload-fonts --css src/styles.css > preload.html`
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
var FLAG_TAKES_VALUE = /* @__PURE__ */ new Map();
|
|
170
|
+
for (const spec of Object.values(COMMANDS).flatMap((command) => command.flags)) {
|
|
171
|
+
for (const name of spec.names) {
|
|
172
|
+
FLAG_TAKES_VALUE.set(name, spec.valueName !== void 0);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
function asSubcommand(token) {
|
|
176
|
+
return Object.hasOwn(COMMANDS, token) ? token : null;
|
|
177
|
+
}
|
|
35
178
|
function parseArgs(argv, callbacks) {
|
|
36
179
|
if (argv[0] === "framework") {
|
|
37
180
|
throw new Error(
|
|
@@ -47,104 +190,73 @@ function parseArgs(argv, callbacks) {
|
|
|
47
190
|
subcommandExplicit: false,
|
|
48
191
|
earlyExit: false
|
|
49
192
|
};
|
|
50
|
-
let
|
|
51
|
-
|
|
52
|
-
const
|
|
53
|
-
if (
|
|
54
|
-
opts.command =
|
|
55
|
-
opts.subcommandExplicit = true;
|
|
56
|
-
i++;
|
|
57
|
-
continue;
|
|
58
|
-
}
|
|
59
|
-
if (arg === "generate-types") {
|
|
60
|
-
opts.command = "generate-types";
|
|
61
|
-
opts.subcommandExplicit = true;
|
|
62
|
-
i++;
|
|
63
|
-
continue;
|
|
64
|
-
}
|
|
65
|
-
if (arg === "init" || arg === "--init") {
|
|
66
|
-
opts.command = "init";
|
|
193
|
+
let keywordIndex = -1;
|
|
194
|
+
for (let j = 0; j < argv.length; j++) {
|
|
195
|
+
const token = argv[j];
|
|
196
|
+
if (token === "--init" || token === "--create") {
|
|
197
|
+
opts.command = token.slice(2);
|
|
67
198
|
opts.subcommandExplicit = true;
|
|
68
|
-
|
|
69
|
-
|
|
199
|
+
keywordIndex = j;
|
|
200
|
+
break;
|
|
70
201
|
}
|
|
71
|
-
if (
|
|
72
|
-
|
|
73
|
-
opts.subcommandExplicit = true;
|
|
74
|
-
i++;
|
|
202
|
+
if (token.startsWith("-")) {
|
|
203
|
+
if (FLAG_TAKES_VALUE.get(token)) j++;
|
|
75
204
|
continue;
|
|
76
205
|
}
|
|
77
|
-
|
|
78
|
-
|
|
206
|
+
const command = asSubcommand(token);
|
|
207
|
+
if (command) {
|
|
208
|
+
opts.command = command;
|
|
79
209
|
opts.subcommandExplicit = true;
|
|
80
|
-
|
|
81
|
-
continue;
|
|
82
|
-
}
|
|
83
|
-
if (arg === "-o" || arg === "--output") {
|
|
84
|
-
if (i + 1 >= argv.length) {
|
|
85
|
-
throw new Error(`Missing value for ${arg}`);
|
|
86
|
-
}
|
|
87
|
-
opts.output = argv[++i];
|
|
88
|
-
i++;
|
|
89
|
-
continue;
|
|
210
|
+
keywordIndex = j;
|
|
90
211
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
const spec = COMMANDS[opts.command];
|
|
215
|
+
for (let i = 0; i < argv.length; i++) {
|
|
216
|
+
if (i === keywordIndex) continue;
|
|
217
|
+
const arg = argv[i];
|
|
218
|
+
if (arg === "--version" || arg === "-v" || arg === "--help" || arg === "-h") {
|
|
219
|
+
if (keywordIndex > i) {
|
|
220
|
+
opts.command = "build";
|
|
221
|
+
opts.subcommandExplicit = false;
|
|
94
222
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
if (arg === "--template") {
|
|
100
|
-
if (i + 1 >= argv.length) {
|
|
101
|
-
throw new Error("Missing value for --template");
|
|
223
|
+
if (arg === "--version" || arg === "-v") {
|
|
224
|
+
console.log(callbacks.getVersion());
|
|
225
|
+
} else {
|
|
226
|
+
callbacks.printHelp(opts.subcommandExplicit ? opts.command : void 0);
|
|
102
227
|
}
|
|
103
|
-
opts.template = argv[++i];
|
|
104
|
-
i++;
|
|
105
|
-
continue;
|
|
106
|
-
}
|
|
107
|
-
if (arg === "--watch") {
|
|
108
|
-
opts.watch = true;
|
|
109
|
-
i++;
|
|
110
|
-
continue;
|
|
111
|
-
}
|
|
112
|
-
if (arg === "--minify") {
|
|
113
|
-
opts.minify = true;
|
|
114
|
-
i++;
|
|
115
|
-
continue;
|
|
116
|
-
}
|
|
117
|
-
if (arg === "--strict") {
|
|
118
|
-
opts.strict = true;
|
|
119
|
-
i++;
|
|
120
|
-
continue;
|
|
121
|
-
}
|
|
122
|
-
if (arg === "--version" || arg === "-v") {
|
|
123
|
-
console.log(callbacks.getVersion());
|
|
124
|
-
opts.earlyExit = true;
|
|
125
|
-
return opts;
|
|
126
|
-
}
|
|
127
|
-
if (arg === "--help" || arg === "-h") {
|
|
128
|
-
callbacks.printHelp(opts.subcommandExplicit ? opts.command : void 0);
|
|
129
228
|
opts.earlyExit = true;
|
|
130
229
|
return opts;
|
|
131
230
|
}
|
|
132
231
|
if (arg.startsWith("-")) {
|
|
232
|
+
const flag = spec.flags.find((f) => f.names.includes(arg));
|
|
233
|
+
if (flag) {
|
|
234
|
+
if (flag.valueName !== void 0) {
|
|
235
|
+
if (i + 1 >= argv.length) {
|
|
236
|
+
throw new Error(`Missing value for ${arg}`);
|
|
237
|
+
}
|
|
238
|
+
flag.apply(opts, argv[++i]);
|
|
239
|
+
} else {
|
|
240
|
+
flag.apply(opts);
|
|
241
|
+
}
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
if (FLAG_TAKES_VALUE.has(arg)) {
|
|
245
|
+
throw new Error(
|
|
246
|
+
`${arg} is not supported by ${opts.command}. Run rainbowindex ${opts.command} --help for usage.`
|
|
247
|
+
);
|
|
248
|
+
}
|
|
133
249
|
throw new Error(`Unknown option "${arg}". Run rainbowindex --help for usage.`);
|
|
134
250
|
}
|
|
135
|
-
if (
|
|
136
|
-
|
|
137
|
-
throw new Error(`Unexpected extra argument "${arg}" for create.`);
|
|
138
|
-
}
|
|
139
|
-
opts.targetDir = arg;
|
|
140
|
-
i++;
|
|
251
|
+
if (spec.positionals === "globs") {
|
|
252
|
+
opts.globs.push(arg);
|
|
141
253
|
continue;
|
|
142
254
|
}
|
|
143
|
-
if (
|
|
144
|
-
|
|
255
|
+
if (spec.positionals === "targetDir" && !opts.targetDir) {
|
|
256
|
+
opts.targetDir = arg;
|
|
257
|
+
continue;
|
|
145
258
|
}
|
|
146
|
-
opts.
|
|
147
|
-
i++;
|
|
259
|
+
throw new Error(`Unexpected extra argument "${arg}" for ${opts.command}.`);
|
|
148
260
|
}
|
|
149
261
|
if (opts.command === "create" && !opts.targetDir) {
|
|
150
262
|
throw new Error("create requires a project directory. Example: rainbowindex create my-app");
|
|
@@ -165,115 +277,39 @@ function parseArgs(argv, callbacks) {
|
|
|
165
277
|
}
|
|
166
278
|
return opts;
|
|
167
279
|
}
|
|
168
|
-
var
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
a CSS file with @source directives is found, those are used instead.
|
|
186
|
-
|
|
187
|
-
Examples:
|
|
188
|
-
rainbowindex "src/**/*.tsx" -o dist/styles.css
|
|
189
|
-
rainbowindex "src/**/*.tsx" --watch -o dist/styles.css
|
|
190
|
-
rainbowindex --css src/styles.css -o dist/styles.css --minify
|
|
191
|
-
`,
|
|
192
|
-
init: `
|
|
193
|
-
\u{1F308} rainbowindex init \u2014 Wire Rainbow Index into the current Vite app
|
|
194
|
-
|
|
195
|
-
Usage:
|
|
196
|
-
rainbowindex init [options]
|
|
197
|
-
|
|
198
|
-
What this does:
|
|
199
|
-
1. Installs rainbowindex as a dev dependency (if not already installed).
|
|
200
|
-
2. Creates or patches vite.config.* to register the Vite plugin.
|
|
201
|
-
3. Creates or updates a CSS entry file with @import "rainbowindex".
|
|
202
|
-
4. Adds the CSS import to your entry file (src/main.tsx, src/main.ts, \u2026).
|
|
203
|
-
|
|
204
|
-
Options:
|
|
205
|
-
--css <file> Stylesheet path to create/patch (default: src/index.css)
|
|
206
|
-
-h, --help Show this help
|
|
207
|
-
|
|
208
|
-
Notes:
|
|
209
|
-
Detects pnpm / yarn / bun / npm from lockfiles, package.json#packageManager,
|
|
210
|
-
and npm_config_user_agent. Requires an existing Vite project \u2014 if you do not
|
|
211
|
-
have one yet, use \`rainbowindex create <dir>\`.
|
|
212
|
-
|
|
213
|
-
Examples:
|
|
214
|
-
rainbowindex init
|
|
215
|
-
rainbowindex init --css src/styles.css
|
|
216
|
-
`,
|
|
217
|
-
create: `
|
|
218
|
-
\u{1F308} rainbowindex create \u2014 Scaffold a Vite app with Rainbow Index ready
|
|
219
|
-
|
|
220
|
-
Usage:
|
|
221
|
-
rainbowindex create <dir> [options]
|
|
222
|
-
|
|
223
|
-
Options:
|
|
224
|
-
--template <name> Vite template (default: react-ts)
|
|
225
|
-
Examples: vanilla, vanilla-ts, react, react-ts, vue, vue-ts, svelte, svelte-ts
|
|
226
|
-
--css <file> Stylesheet path inside the new app (default: src/index.css)
|
|
227
|
-
-h, --help Show this help
|
|
228
|
-
|
|
229
|
-
What this does:
|
|
230
|
-
1. Runs \`create vite\` for the given template.
|
|
231
|
-
2. Runs \`rainbowindex init\` inside the new directory.
|
|
232
|
-
|
|
233
|
-
Examples:
|
|
234
|
-
rainbowindex create my-app
|
|
235
|
-
rainbowindex create my-app --template vue-ts
|
|
236
|
-
`,
|
|
237
|
-
"generate-types": `
|
|
238
|
-
\u{1F308} rainbowindex generate-types \u2014 Generate TypeScript types for ri() autocomplete
|
|
239
|
-
|
|
240
|
-
Usage:
|
|
241
|
-
rainbowindex generate-types [options]
|
|
242
|
-
|
|
243
|
-
Options:
|
|
244
|
-
--css <file> CSS input with @color/@text/@utility/etc directives
|
|
245
|
-
--strict Drop the \`string & {}\` escape hatch from the union
|
|
246
|
-
-h, --help Show this help
|
|
247
|
-
|
|
248
|
-
Output:
|
|
249
|
-
Writes \`rainbowindex-env.d.ts\` to the current working directory. Include it
|
|
250
|
-
in tsconfig.json#include (or the equivalent) so the editor picks it up.
|
|
251
|
-
|
|
252
|
-
Examples:
|
|
253
|
-
rainbowindex generate-types
|
|
254
|
-
rainbowindex generate-types --strict --css src/styles.css
|
|
255
|
-
`,
|
|
256
|
-
"preload-fonts": `
|
|
257
|
-
\u{1F308} rainbowindex preload-fonts \u2014 Generate <link rel="preload"> tags
|
|
258
|
-
|
|
259
|
-
Usage:
|
|
260
|
-
rainbowindex preload-fonts [options]
|
|
261
|
-
|
|
262
|
-
Options:
|
|
263
|
-
--css <file> CSS input with @font directives
|
|
264
|
-
-h, --help Show this help
|
|
265
|
-
|
|
266
|
-
Output:
|
|
267
|
-
Prints <link rel="preload"> tags to stdout for fonts declared in the @font
|
|
268
|
-
block (faces marked preload), or via @font-face.
|
|
269
|
-
|
|
270
|
-
Examples:
|
|
271
|
-
rainbowindex preload-fonts --css src/styles.css > preload.html
|
|
272
|
-
`
|
|
273
|
-
};
|
|
280
|
+
var HELP_DESCRIBE_COLUMN = 25;
|
|
281
|
+
function renderFlagLines(flags) {
|
|
282
|
+
const lines = [];
|
|
283
|
+
for (const flag of flags) {
|
|
284
|
+
const label = flag.helpLabel ?? flag.names.join(", ");
|
|
285
|
+
const heading = ` ${label}${flag.valueName ? ` ${flag.valueName}` : ""}`;
|
|
286
|
+
const [first, ...rest] = flag.describe.split("\n");
|
|
287
|
+
lines.push(`${heading.padEnd(HELP_DESCRIBE_COLUMN)}${first}`);
|
|
288
|
+
for (const continuation of rest) {
|
|
289
|
+
lines.push(`${" ".repeat(HELP_DESCRIBE_COLUMN)}${continuation}`);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return lines.join("\n");
|
|
293
|
+
}
|
|
294
|
+
var HELP_LINE = `${" -h, --help".padEnd(HELP_DESCRIBE_COLUMN)}Show this help`;
|
|
295
|
+
var VERSION_LINE = `${" -v, --version".padEnd(HELP_DESCRIBE_COLUMN)}Show version`;
|
|
296
|
+
var GLOBAL_HELP_FLAGS = [OUTPUT, WATCH, MINIFY, CSS_INPUT, TEMPLATE, STRICT];
|
|
274
297
|
function printHelp(subcommand) {
|
|
275
298
|
if (subcommand) {
|
|
276
|
-
|
|
299
|
+
const spec = COMMANDS[subcommand];
|
|
300
|
+
const sections = [
|
|
301
|
+
`\u{1F308} rainbowindex ${subcommand} \u2014 ${spec.summary}`,
|
|
302
|
+
`Usage:
|
|
303
|
+
${spec.usage}`,
|
|
304
|
+
...spec.intro ? [spec.intro] : [],
|
|
305
|
+
`Options:
|
|
306
|
+
${renderFlagLines(spec.flags)}
|
|
307
|
+
${HELP_LINE}`,
|
|
308
|
+
spec.body
|
|
309
|
+
];
|
|
310
|
+
console.log(`
|
|
311
|
+
${sections.join("\n\n")}
|
|
312
|
+
`);
|
|
277
313
|
return;
|
|
278
314
|
}
|
|
279
315
|
console.log(`
|
|
@@ -289,14 +325,9 @@ Usage:
|
|
|
289
325
|
Run \`rainbowindex <subcommand> --help\` for subcommand-specific options.
|
|
290
326
|
|
|
291
327
|
Options:
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
--css <file> CSS file with directives (default: auto-detect)
|
|
296
|
-
--template <name> Vite template for create (default: react-ts)
|
|
297
|
-
--strict No string escape hatch in generated types
|
|
298
|
-
-v, --version Show version
|
|
299
|
-
-h, --help Show this help
|
|
328
|
+
${renderFlagLines(GLOBAL_HELP_FLAGS)}
|
|
329
|
+
${VERSION_LINE}
|
|
330
|
+
${HELP_LINE}
|
|
300
331
|
|
|
301
332
|
Environment Variables:
|
|
302
333
|
RI_CACHE_DIR Override font metadata cache directory (default: node_modules/.cache/rainbowindex)
|
|
@@ -377,40 +408,24 @@ async function loadProjectTheme(opts, cwd) {
|
|
|
377
408
|
// src/cli/build.ts
|
|
378
409
|
async function buildCSS(opts, cwd) {
|
|
379
410
|
const { css: cssSource, cssFile } = await loadProjectCSS(opts, cwd);
|
|
380
|
-
const
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
if (err) {
|
|
411
|
+
const { compiled } = await compileScannedProject({
|
|
412
|
+
css: cssSource,
|
|
413
|
+
cwd,
|
|
414
|
+
surfacePatterns: opts.globs,
|
|
415
|
+
onInvalidPattern: (err) => {
|
|
386
416
|
console.error(`[RI-1404] CLI glob pattern rejected: ${err}`);
|
|
387
|
-
|
|
388
|
-
validGlobs.push(g);
|
|
417
|
+
return void 0;
|
|
389
418
|
}
|
|
390
|
-
}
|
|
391
|
-
const cliSources = validGlobs.map((g) => ({ pattern: g, negated: false, inline: false }));
|
|
392
|
-
const scannedClasses = await collectProjectClasses(
|
|
393
|
-
theme.sources,
|
|
394
|
-
cliSources,
|
|
395
|
-
cwd,
|
|
396
|
-
warnings,
|
|
397
|
-
warningSeen
|
|
398
|
-
);
|
|
419
|
+
});
|
|
399
420
|
const buildWarnings = [];
|
|
400
421
|
if (hasApplyLikeDirective(cssSource)) {
|
|
401
422
|
buildWarnings.push(
|
|
402
423
|
'[RI-1009] @apply is only supported via the PostCSS plugin. To expand @apply: (1) add `postcss.config.js` with `import rainbowindex from "rainbowindex"; export default { plugins: [rainbowindex()] };`, or (2) use the Vite plugin (`import rainbowindex from "rainbowindex/vite"`), which wires PostCSS automatically. The CLI does not run PostCSS so it cannot expand @apply.'
|
|
403
424
|
);
|
|
404
425
|
}
|
|
405
|
-
const compiled = await finalizeProjectCompilation({
|
|
406
|
-
css: cssSource,
|
|
407
|
-
classNames: scannedClasses,
|
|
408
|
-
analysis,
|
|
409
|
-
resolveFonts: resolveGoogleFonts
|
|
410
|
-
});
|
|
411
426
|
if (compiled.classNames.length === 0) {
|
|
412
427
|
const hadAnyGlob = opts.globs.length > 0;
|
|
413
|
-
const hadAnySource = theme.sources.length > 0;
|
|
428
|
+
const hadAnySource = compiled.theme.sources.length > 0;
|
|
414
429
|
if (!hadAnyGlob && !hadAnySource) {
|
|
415
430
|
buildWarnings.push(
|
|
416
431
|
'[RI-1603] No source files were scanned and no utility classes were compiled. Either pass a glob (`rainbowindex "src/**/*.{ts,tsx}" -o out.css`) or add `@source "src/**/*.{ts,tsx}";` to your CSS input.'
|
|
@@ -654,10 +669,8 @@ async function watchMode(opts, cwd) {
|
|
|
654
669
|
awaitWriteFinish: { stabilityThreshold: 50 }
|
|
655
670
|
});
|
|
656
671
|
let debounceTimer = null;
|
|
657
|
-
let
|
|
658
|
-
let
|
|
659
|
-
let buildDoneResolve = null;
|
|
660
|
-
let buildDonePromise = null;
|
|
672
|
+
let currentBuild = null;
|
|
673
|
+
let dirty = false;
|
|
661
674
|
let consecutiveErrors = 0;
|
|
662
675
|
let errorsPaused = false;
|
|
663
676
|
const MAX_CONSECUTIVE_ERRORS = 5;
|
|
@@ -688,11 +701,31 @@ async function watchMode(opts, cwd) {
|
|
|
688
701
|
}
|
|
689
702
|
};
|
|
690
703
|
syncSourceWatchPaths(initialBuild.theme);
|
|
691
|
-
const
|
|
704
|
+
const runBuild = async () => {
|
|
705
|
+
lastBuildStart = Date.now();
|
|
706
|
+
try {
|
|
707
|
+
const result = await buildAndWrite(opts, cwd, outputFile);
|
|
708
|
+
console.log(`[rainbowindex] Rebuilt: ${outputFile}`);
|
|
709
|
+
consecutiveErrors = 0;
|
|
710
|
+
errorsPaused = false;
|
|
711
|
+
syncSourceWatchPaths(result.theme);
|
|
712
|
+
} catch (err) {
|
|
713
|
+
consecutiveErrors++;
|
|
714
|
+
console.error("[rainbowindex] Build error:", err);
|
|
715
|
+
} finally {
|
|
716
|
+
currentBuild = null;
|
|
717
|
+
if (dirty) {
|
|
718
|
+
dirty = false;
|
|
719
|
+
scheduleRebuild();
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
};
|
|
723
|
+
const scheduleRebuild = () => {
|
|
692
724
|
if (debounceTimer) clearTimeout(debounceTimer);
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
725
|
+
const delay = Math.max(100, MIN_REBUILD_INTERVAL_MS - (Date.now() - lastBuildStart));
|
|
726
|
+
debounceTimer = setTimeout(() => {
|
|
727
|
+
if (currentBuild) {
|
|
728
|
+
dirty = true;
|
|
696
729
|
return;
|
|
697
730
|
}
|
|
698
731
|
if (errorsPaused) {
|
|
@@ -705,42 +738,12 @@ async function watchMode(opts, cwd) {
|
|
|
705
738
|
errorsPaused = true;
|
|
706
739
|
return;
|
|
707
740
|
}
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
if (lastBuildStart > 0 && elapsed < MIN_REBUILD_INTERVAL_MS) {
|
|
711
|
-
pendingRebuild = true;
|
|
712
|
-
setTimeout(rebuild, MIN_REBUILD_INTERVAL_MS - elapsed);
|
|
713
|
-
return;
|
|
714
|
-
}
|
|
715
|
-
lastBuildStart = now;
|
|
716
|
-
building = true;
|
|
717
|
-
buildDonePromise = new Promise((resolveBuild) => {
|
|
718
|
-
buildDoneResolve = resolveBuild;
|
|
719
|
-
});
|
|
720
|
-
try {
|
|
721
|
-
const result = await buildAndWrite(opts, cwd, outputFile);
|
|
722
|
-
console.log(`[rainbowindex] Rebuilt: ${outputFile}`);
|
|
723
|
-
consecutiveErrors = 0;
|
|
724
|
-
errorsPaused = false;
|
|
725
|
-
syncSourceWatchPaths(result.theme);
|
|
726
|
-
} catch (err) {
|
|
727
|
-
consecutiveErrors++;
|
|
728
|
-
console.error("[rainbowindex] Build error:", err);
|
|
729
|
-
} finally {
|
|
730
|
-
building = false;
|
|
731
|
-
buildDoneResolve?.();
|
|
732
|
-
buildDoneResolve = null;
|
|
733
|
-
buildDonePromise = null;
|
|
734
|
-
if (pendingRebuild) {
|
|
735
|
-
pendingRebuild = false;
|
|
736
|
-
rebuild();
|
|
737
|
-
}
|
|
738
|
-
}
|
|
739
|
-
}, 100);
|
|
741
|
+
currentBuild = runBuild();
|
|
742
|
+
}, delay);
|
|
740
743
|
};
|
|
741
|
-
watcher.on("change",
|
|
742
|
-
watcher.on("add",
|
|
743
|
-
watcher.on("unlink",
|
|
744
|
+
watcher.on("change", scheduleRebuild);
|
|
745
|
+
watcher.on("add", scheduleRebuild);
|
|
746
|
+
watcher.on("unlink", scheduleRebuild);
|
|
744
747
|
watcher.on("error", (err) => {
|
|
745
748
|
console.error("[rainbowindex] Watcher error:", err);
|
|
746
749
|
});
|
|
@@ -749,7 +752,7 @@ async function watchMode(opts, cwd) {
|
|
|
749
752
|
if (cleanupCalled) return;
|
|
750
753
|
cleanupCalled = true;
|
|
751
754
|
if (debounceTimer) clearTimeout(debounceTimer);
|
|
752
|
-
|
|
755
|
+
dirty = false;
|
|
753
756
|
const doExit = () => {
|
|
754
757
|
watcher.close().then(() => {
|
|
755
758
|
console.log("\n[rainbowindex] Watcher stopped.");
|
|
@@ -758,9 +761,9 @@ async function watchMode(opts, cwd) {
|
|
|
758
761
|
process.exit(1);
|
|
759
762
|
});
|
|
760
763
|
};
|
|
761
|
-
if (
|
|
764
|
+
if (currentBuild) {
|
|
762
765
|
const timeout = new Promise((r) => setTimeout(r, 5e3));
|
|
763
|
-
Promise.race([
|
|
766
|
+
Promise.race([currentBuild, timeout]).then(doExit);
|
|
764
767
|
} else {
|
|
765
768
|
doExit();
|
|
766
769
|
}
|
|
@@ -1233,7 +1236,7 @@ function readPackageJSONSync(cwd) {
|
|
|
1233
1236
|
|
|
1234
1237
|
// src/entries/cli.ts
|
|
1235
1238
|
function getVersion() {
|
|
1236
|
-
return true ? "0.
|
|
1239
|
+
return true ? "0.4.0" : "unknown";
|
|
1237
1240
|
}
|
|
1238
1241
|
async function main() {
|
|
1239
1242
|
const args = process.argv.slice(2);
|