@bamboocss/vite 1.30.1 → 1.32.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/dist/index.cjs +30 -20
- package/dist/index.d.cts +7 -3
- package/dist/index.d.mts +7 -3
- package/dist/index.mjs +30 -20
- package/package.json +9 -9
package/dist/index.cjs
CHANGED
|
@@ -1108,8 +1108,7 @@ const createCssContext = (ctx) => ({
|
|
|
1108
1108
|
hash: Boolean(ctx.hash.className),
|
|
1109
1109
|
conditions: {
|
|
1110
1110
|
shift: ctx.conditions.shift,
|
|
1111
|
-
finalize: ctx.conditions.finalize
|
|
1112
|
-
breakpoints: { keys: ctx.conditions.breakpoints.keys }
|
|
1111
|
+
finalize: ctx.conditions.finalize
|
|
1113
1112
|
},
|
|
1114
1113
|
utility: {
|
|
1115
1114
|
prefix: ctx.utility.prefix,
|
|
@@ -1196,8 +1195,7 @@ const createRuntimeRecipe = (ctx) => {
|
|
|
1196
1195
|
hash: Boolean(ctx.hash.className),
|
|
1197
1196
|
conditions: {
|
|
1198
1197
|
shift: ctx.conditions.shift,
|
|
1199
|
-
finalize: ctx.conditions.finalize
|
|
1200
|
-
breakpoints: { keys: ctx.conditions.breakpoints.keys }
|
|
1198
|
+
finalize: ctx.conditions.finalize
|
|
1201
1199
|
},
|
|
1202
1200
|
utility: {
|
|
1203
1201
|
prefix: ctx.utility.prefix,
|
|
@@ -1271,7 +1269,7 @@ const UNFOLDABLE_TYPES = new Set(["cva", "sva"]);
|
|
|
1271
1269
|
*
|
|
1272
1270
|
* `overlapping` is handled by the enclosing fold, and `not-imported` is somebody else's
|
|
1273
1271
|
* function of the same name — neither leaves a call of ours. `not-foldable` is a `cva`/`sva`
|
|
1274
|
-
* definition, which keeps the recipe runtime rather than the css engine; see `
|
|
1272
|
+
* definition, which keeps the recipe runtime rather than the css engine; see `failOnUnfolded`.
|
|
1275
1273
|
*/
|
|
1276
1274
|
const SURVIVES_TO_RUNTIME = new Set([
|
|
1277
1275
|
"dynamic",
|
|
@@ -1280,7 +1278,8 @@ const SURVIVES_TO_RUNTIME = new Set([
|
|
|
1280
1278
|
"unsupported-kind",
|
|
1281
1279
|
"no-call-expression",
|
|
1282
1280
|
"empty",
|
|
1283
|
-
"unresolved-token"
|
|
1281
|
+
"unresolved-token",
|
|
1282
|
+
"fold-failed"
|
|
1284
1283
|
]);
|
|
1285
1284
|
/**
|
|
1286
1285
|
* A call of a recipe the file bound itself: `const badge = cva(...)`, then `badge({ tone })`.
|
|
@@ -1333,7 +1332,7 @@ const isValueReference = (identifier) => {
|
|
|
1333
1332
|
*
|
|
1334
1333
|
* `cva` and `sva` are there for the reason `SURVIVES_TO_RUNTIME` omits `not-foldable`: a
|
|
1335
1334
|
* recipe *definition* cannot fold to a class string and never could, and what it keeps is the
|
|
1336
|
-
* recipe runtime rather than the css engine — which `
|
|
1335
|
+
* recipe runtime rather than the css engine — which `failOnUnfolded` accepts. Their unfoldable
|
|
1337
1336
|
* invocations are reported separately, as `recipe-call`.
|
|
1338
1337
|
*/
|
|
1339
1338
|
const PERMITTED_BINDINGS = new Set([
|
|
@@ -1356,10 +1355,11 @@ const TRAILING_INDEX = /\/index$/;
|
|
|
1356
1355
|
/**
|
|
1357
1356
|
* An argument that cannot run anything when it is evaluated.
|
|
1358
1357
|
*
|
|
1359
|
-
* `token(
|
|
1360
|
-
* the
|
|
1361
|
-
*
|
|
1362
|
-
*
|
|
1358
|
+
* `token()` takes one argument, but javascript evaluates every argument a call site passes
|
|
1359
|
+
* before the call — so a fold that drops an extra one also drops whatever evaluating it would
|
|
1360
|
+
* have done. `token('x', compute())` is pathological and no longer type-checks, and the fold's
|
|
1361
|
+
* contract is behaviour preservation regardless: a literal is the cheap way to prove it, since
|
|
1362
|
+
* it means no call, no property read, no getter.
|
|
1363
1363
|
*/
|
|
1364
1364
|
const isInertArgument = (node) => ts_morph.Node.isStringLiteral(node) || ts_morph.Node.isNumericLiteral(node) || ts_morph.Node.isNoSubstitutionTemplateLiteral(node) || node.getKind() === ts_morph.SyntaxKind.TrueKeyword || node.getKind() === ts_morph.SyntaxKind.FalseKeyword || node.getKind() === ts_morph.SyntaxKind.NullKeyword || ts_morph.Node.isIdentifier(node) && node.getText() === "undefined";
|
|
1365
1365
|
/**
|
|
@@ -2268,7 +2268,7 @@ const foldSource = (options) => {
|
|
|
2268
2268
|
* Deliberately not driven by `parserResult`: that is the recogniser, and the point here is
|
|
2269
2269
|
* to catch what it did not see. A namespace import called as `s.cva(...)`, a default
|
|
2270
2270
|
* import, a specifier that resolved to nothing — each leaves a live reference and no ledger
|
|
2271
|
-
* entry at all, which is how `
|
|
2271
|
+
* entry at all, which is how `failOnUnfolded` came to pass a build that still shipped the engine.
|
|
2272
2272
|
*
|
|
2273
2273
|
* The helpers the fold itself writes are excluded: `cx`, `cvaPick`, `splitProps` and the
|
|
2274
2274
|
* leaf helper live in `cx` and pull no engine, so a reference to one is the fold working
|
|
@@ -2430,7 +2430,7 @@ const formatSkipped = (id, skipped) => {
|
|
|
2430
2430
|
* with no matching rule.
|
|
2431
2431
|
*/
|
|
2432
2432
|
const bamboocss = (options = {}) => {
|
|
2433
|
-
const { transform = true, partial, configPath, cwd, reportSkipped = false, reportSummary = true,
|
|
2433
|
+
const { transform = true, partial, configPath, cwd, reportSkipped = false, reportSummary = true, failOnUnfolded = false } = options;
|
|
2434
2434
|
/** Totals across the build, for the summary. */
|
|
2435
2435
|
const totals = {
|
|
2436
2436
|
folded: 0,
|
|
@@ -2438,7 +2438,7 @@ const bamboocss = (options = {}) => {
|
|
|
2438
2438
|
filesWithFolds: 0,
|
|
2439
2439
|
skipped: /* @__PURE__ */ new Map()
|
|
2440
2440
|
};
|
|
2441
|
-
/** Under `
|
|
2441
|
+
/** Under `failOnUnfolded`, every call that would still reach the runtime. */
|
|
2442
2442
|
const survivors = [];
|
|
2443
2443
|
/**
|
|
2444
2444
|
* Recipe configs read out of modules other than the one being transformed.
|
|
@@ -2520,7 +2520,7 @@ const bamboocss = (options = {}) => {
|
|
|
2520
2520
|
try {
|
|
2521
2521
|
const sourceFile = ctx.project.addSourceFile(filePath, code);
|
|
2522
2522
|
const parserResult = ctx.project.parseSourceFile(filePath);
|
|
2523
|
-
if (!parserResult || parserResult.isEmpty() && !
|
|
2523
|
+
if (!parserResult || parserResult.isEmpty() && !failOnUnfolded) return null;
|
|
2524
2524
|
result = foldSource({
|
|
2525
2525
|
ctx,
|
|
2526
2526
|
code,
|
|
@@ -2530,18 +2530,26 @@ const bamboocss = (options = {}) => {
|
|
|
2530
2530
|
partial,
|
|
2531
2531
|
parseModule: (path) => ctx?.project.parseSourceFile(path),
|
|
2532
2532
|
recipeConfigCache,
|
|
2533
|
-
reportSurvivors:
|
|
2533
|
+
reportSurvivors: failOnUnfolded,
|
|
2534
2534
|
sourceFile
|
|
2535
2535
|
});
|
|
2536
2536
|
} catch (error) {
|
|
2537
2537
|
_bamboocss_logger.logger.caughtError("vite:transform", `Failed to fold ${filePath}`, error);
|
|
2538
|
+
totals.files++;
|
|
2539
|
+
totals.skipped.set("fold-failed", (totals.skipped.get("fold-failed") ?? 0) + 1);
|
|
2540
|
+
if (failOnUnfolded) survivors.push({
|
|
2541
|
+
file: filePath,
|
|
2542
|
+
line: 1,
|
|
2543
|
+
name: "fold",
|
|
2544
|
+
reason: "fold-failed"
|
|
2545
|
+
});
|
|
2538
2546
|
return null;
|
|
2539
2547
|
}
|
|
2540
2548
|
totals.files++;
|
|
2541
2549
|
totals.folded += result.folded.length;
|
|
2542
2550
|
if (result.folded.length) totals.filesWithFolds++;
|
|
2543
2551
|
for (const entry of result.skipped) totals.skipped.set(entry.reason, (totals.skipped.get(entry.reason) ?? 0) + 1);
|
|
2544
|
-
if (
|
|
2552
|
+
if (failOnUnfolded) {
|
|
2545
2553
|
for (const entry of result.skipped) {
|
|
2546
2554
|
if (!SURVIVES_TO_RUNTIME.has(entry.reason)) continue;
|
|
2547
2555
|
survivors.push({
|
|
@@ -2568,15 +2576,17 @@ const bamboocss = (options = {}) => {
|
|
|
2568
2576
|
};
|
|
2569
2577
|
},
|
|
2570
2578
|
buildEnd() {
|
|
2571
|
-
if (
|
|
2579
|
+
if (failOnUnfolded && survivors.length) {
|
|
2572
2580
|
const byFile = /* @__PURE__ */ new Map();
|
|
2573
2581
|
for (const entry of survivors) {
|
|
2574
2582
|
const list = byFile.get(entry.file) ?? [];
|
|
2575
2583
|
list.push(entry);
|
|
2576
2584
|
byFile.set(entry.file, list);
|
|
2577
2585
|
}
|
|
2578
|
-
const
|
|
2579
|
-
|
|
2586
|
+
const named = (e) => e.reason === "runtime-binding" || e.reason === "fold-failed" ? e.name : `${e.name}()`;
|
|
2587
|
+
const detail = Array.from(byFile.entries()).map(([file, entries]) => [` ${file}`, ...entries.map((e) => ` ${e.line}: ${named(e)} — ${e.reason}`)].join("\n")).join("\n");
|
|
2588
|
+
const threw = survivors.some((entry) => entry.reason === "fold-failed");
|
|
2589
|
+
throw new Error(`bamboocss: ${survivors.length} call(s) could not be folded, and \`failOnUnfolded\` is on.\n\n${detail}\n\n` + (threw ? "`fold-failed` is a module the fold threw on — see the error logged for it above. Nothing was established about its calls either way, so it cannot support the guarantee this option makes.\n\n" : "") + "Each one keeps `styled-system/css` in the bundle, so the engine cannot be dropped however many other calls folded. Make the values static, move the variation into a `cva` variant, or generate them with `staticCss` — or set `failOnUnfolded: false` to accept the runtime.");
|
|
2580
2590
|
}
|
|
2581
2591
|
if (!transform || !reportSummary) return;
|
|
2582
2592
|
const declined = Array.from(totals.skipped.values()).reduce((sum, count) => sum + count, 0);
|
package/dist/index.d.cts
CHANGED
|
@@ -105,7 +105,7 @@ declare const createRuntimeCss: (ctx: Context) => RuntimeCss;
|
|
|
105
105
|
* Why a call site was left alone. Surfaced through `panda`-style diagnostics so a
|
|
106
106
|
* user can tell the difference between "this folded" and "this silently didn't".
|
|
107
107
|
*/
|
|
108
|
-
type SkipReason = 'dynamic' | 'raw-call' | 'not-foldable' | 'recipe-call' | 'unsupported-kind' | 'not-imported' | 'no-call-expression' | 'overlapping' | 'empty' | 'unresolved-token' | 'runtime-binding';
|
|
108
|
+
type SkipReason = 'dynamic' | 'raw-call' | 'not-foldable' | 'recipe-call' | 'unsupported-kind' | 'not-imported' | 'no-call-expression' | 'overlapping' | 'empty' | 'unresolved-token' | 'runtime-binding' | 'fold-failed';
|
|
109
109
|
interface FoldedCall {
|
|
110
110
|
name: string;
|
|
111
111
|
/**
|
|
@@ -198,7 +198,7 @@ interface FoldOptions {
|
|
|
198
198
|
*
|
|
199
199
|
* This asks what the guarantee actually claims: after the rewrite, is anything from a
|
|
200
200
|
* bamboo module still referenced? Off by default because it costs an identifier walk, and
|
|
201
|
-
* only `
|
|
201
|
+
* only `failOnUnfolded` needs an answer it can fail a build on.
|
|
202
202
|
*/
|
|
203
203
|
reportSurvivors?: boolean;
|
|
204
204
|
/**
|
|
@@ -284,9 +284,13 @@ interface BambooVitePluginOptions {
|
|
|
284
284
|
* writing recipes — and recipes keep their own much smaller runtime by design. What this
|
|
285
285
|
* guarantees is narrower and checkable: nothing still calls `css()`.
|
|
286
286
|
*
|
|
287
|
+
* Named for what it checks. It was `strict`, which meant nothing in common with
|
|
288
|
+
* `strictTokens` or a pattern's old `strict` — three unrelated options sharing a word, to
|
|
289
|
+
* the point that comments in this repo used a bare "strict" for all three.
|
|
290
|
+
*
|
|
287
291
|
* @default false
|
|
288
292
|
*/
|
|
289
|
-
|
|
293
|
+
failOnUnfolded?: boolean;
|
|
290
294
|
}
|
|
291
295
|
/**
|
|
292
296
|
* Vite integration for Bamboo CSS.
|
package/dist/index.d.mts
CHANGED
|
@@ -105,7 +105,7 @@ declare const createRuntimeCss: (ctx: Context) => RuntimeCss;
|
|
|
105
105
|
* Why a call site was left alone. Surfaced through `panda`-style diagnostics so a
|
|
106
106
|
* user can tell the difference between "this folded" and "this silently didn't".
|
|
107
107
|
*/
|
|
108
|
-
type SkipReason = 'dynamic' | 'raw-call' | 'not-foldable' | 'recipe-call' | 'unsupported-kind' | 'not-imported' | 'no-call-expression' | 'overlapping' | 'empty' | 'unresolved-token' | 'runtime-binding';
|
|
108
|
+
type SkipReason = 'dynamic' | 'raw-call' | 'not-foldable' | 'recipe-call' | 'unsupported-kind' | 'not-imported' | 'no-call-expression' | 'overlapping' | 'empty' | 'unresolved-token' | 'runtime-binding' | 'fold-failed';
|
|
109
109
|
interface FoldedCall {
|
|
110
110
|
name: string;
|
|
111
111
|
/**
|
|
@@ -198,7 +198,7 @@ interface FoldOptions {
|
|
|
198
198
|
*
|
|
199
199
|
* This asks what the guarantee actually claims: after the rewrite, is anything from a
|
|
200
200
|
* bamboo module still referenced? Off by default because it costs an identifier walk, and
|
|
201
|
-
* only `
|
|
201
|
+
* only `failOnUnfolded` needs an answer it can fail a build on.
|
|
202
202
|
*/
|
|
203
203
|
reportSurvivors?: boolean;
|
|
204
204
|
/**
|
|
@@ -284,9 +284,13 @@ interface BambooVitePluginOptions {
|
|
|
284
284
|
* writing recipes — and recipes keep their own much smaller runtime by design. What this
|
|
285
285
|
* guarantees is narrower and checkable: nothing still calls `css()`.
|
|
286
286
|
*
|
|
287
|
+
* Named for what it checks. It was `strict`, which meant nothing in common with
|
|
288
|
+
* `strictTokens` or a pattern's old `strict` — three unrelated options sharing a word, to
|
|
289
|
+
* the point that comments in this repo used a bare "strict" for all three.
|
|
290
|
+
*
|
|
287
291
|
* @default false
|
|
288
292
|
*/
|
|
289
|
-
|
|
293
|
+
failOnUnfolded?: boolean;
|
|
290
294
|
}
|
|
291
295
|
/**
|
|
292
296
|
* Vite integration for Bamboo CSS.
|
package/dist/index.mjs
CHANGED
|
@@ -1081,8 +1081,7 @@ const createCssContext = (ctx) => ({
|
|
|
1081
1081
|
hash: Boolean(ctx.hash.className),
|
|
1082
1082
|
conditions: {
|
|
1083
1083
|
shift: ctx.conditions.shift,
|
|
1084
|
-
finalize: ctx.conditions.finalize
|
|
1085
|
-
breakpoints: { keys: ctx.conditions.breakpoints.keys }
|
|
1084
|
+
finalize: ctx.conditions.finalize
|
|
1086
1085
|
},
|
|
1087
1086
|
utility: {
|
|
1088
1087
|
prefix: ctx.utility.prefix,
|
|
@@ -1169,8 +1168,7 @@ const createRuntimeRecipe = (ctx) => {
|
|
|
1169
1168
|
hash: Boolean(ctx.hash.className),
|
|
1170
1169
|
conditions: {
|
|
1171
1170
|
shift: ctx.conditions.shift,
|
|
1172
|
-
finalize: ctx.conditions.finalize
|
|
1173
|
-
breakpoints: { keys: ctx.conditions.breakpoints.keys }
|
|
1171
|
+
finalize: ctx.conditions.finalize
|
|
1174
1172
|
},
|
|
1175
1173
|
utility: {
|
|
1176
1174
|
prefix: ctx.utility.prefix,
|
|
@@ -1244,7 +1242,7 @@ const UNFOLDABLE_TYPES = new Set(["cva", "sva"]);
|
|
|
1244
1242
|
*
|
|
1245
1243
|
* `overlapping` is handled by the enclosing fold, and `not-imported` is somebody else's
|
|
1246
1244
|
* function of the same name — neither leaves a call of ours. `not-foldable` is a `cva`/`sva`
|
|
1247
|
-
* definition, which keeps the recipe runtime rather than the css engine; see `
|
|
1245
|
+
* definition, which keeps the recipe runtime rather than the css engine; see `failOnUnfolded`.
|
|
1248
1246
|
*/
|
|
1249
1247
|
const SURVIVES_TO_RUNTIME = new Set([
|
|
1250
1248
|
"dynamic",
|
|
@@ -1253,7 +1251,8 @@ const SURVIVES_TO_RUNTIME = new Set([
|
|
|
1253
1251
|
"unsupported-kind",
|
|
1254
1252
|
"no-call-expression",
|
|
1255
1253
|
"empty",
|
|
1256
|
-
"unresolved-token"
|
|
1254
|
+
"unresolved-token",
|
|
1255
|
+
"fold-failed"
|
|
1257
1256
|
]);
|
|
1258
1257
|
/**
|
|
1259
1258
|
* A call of a recipe the file bound itself: `const badge = cva(...)`, then `badge({ tone })`.
|
|
@@ -1306,7 +1305,7 @@ const isValueReference = (identifier) => {
|
|
|
1306
1305
|
*
|
|
1307
1306
|
* `cva` and `sva` are there for the reason `SURVIVES_TO_RUNTIME` omits `not-foldable`: a
|
|
1308
1307
|
* recipe *definition* cannot fold to a class string and never could, and what it keeps is the
|
|
1309
|
-
* recipe runtime rather than the css engine — which `
|
|
1308
|
+
* recipe runtime rather than the css engine — which `failOnUnfolded` accepts. Their unfoldable
|
|
1310
1309
|
* invocations are reported separately, as `recipe-call`.
|
|
1311
1310
|
*/
|
|
1312
1311
|
const PERMITTED_BINDINGS = new Set([
|
|
@@ -1329,10 +1328,11 @@ const TRAILING_INDEX = /\/index$/;
|
|
|
1329
1328
|
/**
|
|
1330
1329
|
* An argument that cannot run anything when it is evaluated.
|
|
1331
1330
|
*
|
|
1332
|
-
* `token(
|
|
1333
|
-
* the
|
|
1334
|
-
*
|
|
1335
|
-
*
|
|
1331
|
+
* `token()` takes one argument, but javascript evaluates every argument a call site passes
|
|
1332
|
+
* before the call — so a fold that drops an extra one also drops whatever evaluating it would
|
|
1333
|
+
* have done. `token('x', compute())` is pathological and no longer type-checks, and the fold's
|
|
1334
|
+
* contract is behaviour preservation regardless: a literal is the cheap way to prove it, since
|
|
1335
|
+
* it means no call, no property read, no getter.
|
|
1336
1336
|
*/
|
|
1337
1337
|
const isInertArgument = (node) => Node.isStringLiteral(node) || Node.isNumericLiteral(node) || Node.isNoSubstitutionTemplateLiteral(node) || node.getKind() === SyntaxKind.TrueKeyword || node.getKind() === SyntaxKind.FalseKeyword || node.getKind() === SyntaxKind.NullKeyword || Node.isIdentifier(node) && node.getText() === "undefined";
|
|
1338
1338
|
/**
|
|
@@ -2241,7 +2241,7 @@ const foldSource = (options) => {
|
|
|
2241
2241
|
* Deliberately not driven by `parserResult`: that is the recogniser, and the point here is
|
|
2242
2242
|
* to catch what it did not see. A namespace import called as `s.cva(...)`, a default
|
|
2243
2243
|
* import, a specifier that resolved to nothing — each leaves a live reference and no ledger
|
|
2244
|
-
* entry at all, which is how `
|
|
2244
|
+
* entry at all, which is how `failOnUnfolded` came to pass a build that still shipped the engine.
|
|
2245
2245
|
*
|
|
2246
2246
|
* The helpers the fold itself writes are excluded: `cx`, `cvaPick`, `splitProps` and the
|
|
2247
2247
|
* leaf helper live in `cx` and pull no engine, so a reference to one is the fold working
|
|
@@ -2403,7 +2403,7 @@ const formatSkipped = (id, skipped) => {
|
|
|
2403
2403
|
* with no matching rule.
|
|
2404
2404
|
*/
|
|
2405
2405
|
const bamboocss = (options = {}) => {
|
|
2406
|
-
const { transform = true, partial, configPath, cwd, reportSkipped = false, reportSummary = true,
|
|
2406
|
+
const { transform = true, partial, configPath, cwd, reportSkipped = false, reportSummary = true, failOnUnfolded = false } = options;
|
|
2407
2407
|
/** Totals across the build, for the summary. */
|
|
2408
2408
|
const totals = {
|
|
2409
2409
|
folded: 0,
|
|
@@ -2411,7 +2411,7 @@ const bamboocss = (options = {}) => {
|
|
|
2411
2411
|
filesWithFolds: 0,
|
|
2412
2412
|
skipped: /* @__PURE__ */ new Map()
|
|
2413
2413
|
};
|
|
2414
|
-
/** Under `
|
|
2414
|
+
/** Under `failOnUnfolded`, every call that would still reach the runtime. */
|
|
2415
2415
|
const survivors = [];
|
|
2416
2416
|
/**
|
|
2417
2417
|
* Recipe configs read out of modules other than the one being transformed.
|
|
@@ -2493,7 +2493,7 @@ const bamboocss = (options = {}) => {
|
|
|
2493
2493
|
try {
|
|
2494
2494
|
const sourceFile = ctx.project.addSourceFile(filePath, code);
|
|
2495
2495
|
const parserResult = ctx.project.parseSourceFile(filePath);
|
|
2496
|
-
if (!parserResult || parserResult.isEmpty() && !
|
|
2496
|
+
if (!parserResult || parserResult.isEmpty() && !failOnUnfolded) return null;
|
|
2497
2497
|
result = foldSource({
|
|
2498
2498
|
ctx,
|
|
2499
2499
|
code,
|
|
@@ -2503,18 +2503,26 @@ const bamboocss = (options = {}) => {
|
|
|
2503
2503
|
partial,
|
|
2504
2504
|
parseModule: (path) => ctx?.project.parseSourceFile(path),
|
|
2505
2505
|
recipeConfigCache,
|
|
2506
|
-
reportSurvivors:
|
|
2506
|
+
reportSurvivors: failOnUnfolded,
|
|
2507
2507
|
sourceFile
|
|
2508
2508
|
});
|
|
2509
2509
|
} catch (error) {
|
|
2510
2510
|
logger.caughtError("vite:transform", `Failed to fold ${filePath}`, error);
|
|
2511
|
+
totals.files++;
|
|
2512
|
+
totals.skipped.set("fold-failed", (totals.skipped.get("fold-failed") ?? 0) + 1);
|
|
2513
|
+
if (failOnUnfolded) survivors.push({
|
|
2514
|
+
file: filePath,
|
|
2515
|
+
line: 1,
|
|
2516
|
+
name: "fold",
|
|
2517
|
+
reason: "fold-failed"
|
|
2518
|
+
});
|
|
2511
2519
|
return null;
|
|
2512
2520
|
}
|
|
2513
2521
|
totals.files++;
|
|
2514
2522
|
totals.folded += result.folded.length;
|
|
2515
2523
|
if (result.folded.length) totals.filesWithFolds++;
|
|
2516
2524
|
for (const entry of result.skipped) totals.skipped.set(entry.reason, (totals.skipped.get(entry.reason) ?? 0) + 1);
|
|
2517
|
-
if (
|
|
2525
|
+
if (failOnUnfolded) {
|
|
2518
2526
|
for (const entry of result.skipped) {
|
|
2519
2527
|
if (!SURVIVES_TO_RUNTIME.has(entry.reason)) continue;
|
|
2520
2528
|
survivors.push({
|
|
@@ -2541,15 +2549,17 @@ const bamboocss = (options = {}) => {
|
|
|
2541
2549
|
};
|
|
2542
2550
|
},
|
|
2543
2551
|
buildEnd() {
|
|
2544
|
-
if (
|
|
2552
|
+
if (failOnUnfolded && survivors.length) {
|
|
2545
2553
|
const byFile = /* @__PURE__ */ new Map();
|
|
2546
2554
|
for (const entry of survivors) {
|
|
2547
2555
|
const list = byFile.get(entry.file) ?? [];
|
|
2548
2556
|
list.push(entry);
|
|
2549
2557
|
byFile.set(entry.file, list);
|
|
2550
2558
|
}
|
|
2551
|
-
const
|
|
2552
|
-
|
|
2559
|
+
const named = (e) => e.reason === "runtime-binding" || e.reason === "fold-failed" ? e.name : `${e.name}()`;
|
|
2560
|
+
const detail = Array.from(byFile.entries()).map(([file, entries]) => [` ${file}`, ...entries.map((e) => ` ${e.line}: ${named(e)} — ${e.reason}`)].join("\n")).join("\n");
|
|
2561
|
+
const threw = survivors.some((entry) => entry.reason === "fold-failed");
|
|
2562
|
+
throw new Error(`bamboocss: ${survivors.length} call(s) could not be folded, and \`failOnUnfolded\` is on.\n\n${detail}\n\n` + (threw ? "`fold-failed` is a module the fold threw on — see the error logged for it above. Nothing was established about its calls either way, so it cannot support the guarantee this option makes.\n\n" : "") + "Each one keeps `styled-system/css` in the bundle, so the engine cannot be dropped however many other calls folded. Make the values static, move the variation into a `cva` variant, or generate them with `staticCss` — or set `failOnUnfolded: false` to accept the runtime.");
|
|
2553
2563
|
}
|
|
2554
2564
|
if (!transform || !reportSummary) return;
|
|
2555
2565
|
const declined = Array.from(totals.skipped.values()).reduce((sum, count) => sum + count, 0);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bamboocss/vite",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.32.0",
|
|
4
4
|
"description": "Vite integration for Bamboo CSS",
|
|
5
5
|
"homepage": "https://bamboocss.com",
|
|
6
6
|
"license": "MIT",
|
|
@@ -37,18 +37,18 @@
|
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"magic-string": "0.30.21",
|
|
39
39
|
"ts-morph": "28.0.0",
|
|
40
|
-
"@bamboocss/
|
|
41
|
-
"@bamboocss/
|
|
42
|
-
"@bamboocss/
|
|
43
|
-
"@bamboocss/
|
|
44
|
-
"@bamboocss/
|
|
45
|
-
"@bamboocss/shared": "1.
|
|
46
|
-
"@bamboocss/types": "1.
|
|
40
|
+
"@bamboocss/core": "1.32.0",
|
|
41
|
+
"@bamboocss/config": "1.32.0",
|
|
42
|
+
"@bamboocss/extractor": "1.32.0",
|
|
43
|
+
"@bamboocss/node": "1.32.0",
|
|
44
|
+
"@bamboocss/logger": "1.32.0",
|
|
45
|
+
"@bamboocss/shared": "1.32.0",
|
|
46
|
+
"@bamboocss/types": "1.32.0"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@jridgewell/trace-mapping": "^0.3.31",
|
|
50
50
|
"vite": "7.2.6",
|
|
51
|
-
"@bamboocss/fixture": "1.
|
|
51
|
+
"@bamboocss/fixture": "1.32.0"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
54
|
"vite": ">=5"
|