@csszyx/unplugin 0.16.0 → 0.17.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.
Files changed (42) hide show
  1. package/README.md +1 -1
  2. package/dist/index.cjs +7 -4
  3. package/dist/index.d.cts +2 -2
  4. package/dist/index.d.mts +2 -2
  5. package/dist/index.mjs +6 -4
  6. package/dist/jest-transform.cjs +186 -0
  7. package/dist/jest-transform.d.cts +112 -0
  8. package/dist/jest-transform.d.mts +110 -0
  9. package/dist/jest-transform.mjs +175 -0
  10. package/dist/next-prebuild.cjs +6 -5
  11. package/dist/next-prebuild.mjs +5 -4
  12. package/dist/next-turbo-loader.cjs +10 -8
  13. package/dist/next-turbo-loader.mjs +7 -5
  14. package/dist/next-watcher.cjs +3 -2
  15. package/dist/next-watcher.mjs +3 -2
  16. package/dist/shared/{unplugin.J6ue_lRJ.cjs → unplugin.2qOISpzl.cjs} +1 -114
  17. package/dist/shared/{unplugin.C-oQU1jl.mjs → unplugin.2uf-U76p.mjs} +1 -1
  18. package/dist/shared/{unplugin.Ceq-N4jI.mjs → unplugin.995yC_cN.mjs} +2 -110
  19. package/dist/shared/{unplugin.D3yBoTHP.cjs → unplugin.9zs6T4Gf.cjs} +75 -66
  20. package/dist/shared/{unplugin.PKo7wFzu.d.cts → unplugin.BO2_hyS3.d.cts} +38 -5
  21. package/dist/shared/{unplugin.DH_ij6cf.mjs → unplugin.Ba3O1r8M.mjs} +2 -6
  22. package/dist/shared/unplugin.BqKLlo1h.cjs +8 -0
  23. package/dist/shared/{unplugin.Vn9x8SBP.mjs → unplugin.C3bgc29e.mjs} +3 -2
  24. package/dist/shared/{unplugin.Dx0ngYWw.mjs → unplugin.Cs4H9z9v.mjs} +48 -40
  25. package/dist/shared/{unplugin.BLptVbUe.mjs → unplugin.DPSQP5XG.mjs} +1 -1
  26. package/dist/shared/{unplugin.DDSWQJYX.cjs → unplugin.DS6CFjim.cjs} +3 -8
  27. package/dist/shared/{unplugin.gksolKh2.cjs → unplugin.DXzIP7lP.cjs} +5 -4
  28. package/dist/shared/unplugin.DcXM9sq5.mjs +109 -0
  29. package/dist/shared/unplugin.Defu9wGh.cjs +115 -0
  30. package/dist/shared/{unplugin.Bu2rzRtv.d.mts → unplugin.DptK3pl4.d.mts} +38 -5
  31. package/dist/shared/{unplugin.BzF0V2kw.cjs → unplugin.YcnV3Izb.cjs} +6 -6
  32. package/dist/shared/{unplugin.BWnmKv07.cjs → unplugin.alhYXymJ.cjs} +1 -1
  33. package/dist/shared/unplugin.wMeicb6E.mjs +6 -0
  34. package/dist/vite.cjs +6 -4
  35. package/dist/vite.d.cts +2 -2
  36. package/dist/vite.d.mts +1 -1
  37. package/dist/vite.mjs +6 -4
  38. package/dist/webpack.cjs +6 -4
  39. package/dist/webpack.d.cts +1 -2
  40. package/dist/webpack.d.mts +1 -1
  41. package/dist/webpack.mjs +6 -4
  42. package/package.json +19 -9
@@ -13,10 +13,12 @@ import { preprocess as preprocess$1 } from '@csszyx/svelte-adapter';
13
13
  import { isTailwindReservedCustomProperty, CSSZYX_GLOBAL_ALIAS_PREFIX, isCsszyxGlobalAliasCustomProperty, DEFAULT_IMPORTED_STATIC_SZ, DEFAULT_BUILD_CONFIG, validateGlobalVarMangleConfig } from '@csszyx/types';
14
14
  import { preprocess } from '@csszyx/vue-adapter';
15
15
  import { createUnplugin } from 'unplugin';
16
- import { s as sortStrings, n as normalizePathSeparators, h as stripCssBlockComments, S as SAFELIST_FILE, i as findLegacySourceDirective, l as legacySourceMessage, b as cssImportsTailwind, c as computeSafelistRelPath, a as appendTailwindSourceDirective, r as renderSafelistFile, d as atomicWriteFileSync, e as removeLegacySafelists } from './unplugin.DH_ij6cf.mjs';
17
- import { c as collectSpecifierAliases, r as resolveTransformCacheDir, h as evictOldTransformCacheEntries, j as recordSzvRegistryFile, k as recordCrossModuleForwards, l as recordSzObjectRegistryFile, m as mayExportSzvFactories, n as resolveProviderPath, i as importedSpecifiersIn, s as specifierBases, a as resolveProviderPathWith, o as resolveCrossModuleStaticsFor, e as createTransformCacheKey, w as writeTransformCache, g as readTransformCache, p as evictMemoryCacheToBudget, d as isReadableProviderFile } from './unplugin.C-oQU1jl.mjs';
16
+ import { s as sortStrings, h as stripCssBlockComments, S as SAFELIST_FILE, i as findLegacySourceDirective, l as legacySourceMessage, b as cssImportsTailwind, c as computeSafelistRelPath, a as appendTailwindSourceDirective, r as renderSafelistFile, d as atomicWriteFileSync, e as removeLegacySafelists } from './unplugin.Ba3O1r8M.mjs';
17
+ import { c as collectSpecifierAliases, r as resolveTransformCacheDir, h as evictOldTransformCacheEntries, j as recordSzvRegistryFile, k as recordCrossModuleForwards, l as recordSzObjectRegistryFile, m as mayExportSzvFactories, n as resolveProviderPath, i as importedSpecifiersIn, s as specifierBases, a as resolveProviderPathWith, o as resolveCrossModuleStaticsFor, e as createTransformCacheKey, w as writeTransformCache, g as readTransformCache, p as evictMemoryCacheToBudget, d as isReadableProviderFile } from './unplugin.2uf-U76p.mjs';
18
18
  import { mangleCSSSync, classAttributeSelectorKey } from '../css-mangler.mjs';
19
- import { c as createMangleRuntimeModule, M as MANGLE_RUNTIME_VIRTUAL_ID, e as ensureThemeGroupsFile, R as RESOLVED_VIRTUAL_MODULE_ID, d as createMangleMapModule, f as RESOLVED_VIRTUAL_CHECKSUM_ID, g as createChecksumModule, j as RESOLVED_MANGLE_RUNTIME_VIRTUAL_ID, k as RESOLVED_THEME_GROUPS_VIRTUAL_ID, l as createThemeGroupsModule, n as isVirtualModule, r as resolveVirtualModule, p as parseThemeBlocks, m as mergeThemes, o as discoverProjectTheme, C as CHECKSUM_PLACEHOLDER, q as CENSUS_PLACEHOLDER, u as importsRuntimeHelper, v as findRuntimeImportClause, T as THEME_GROUPS_VIRTUAL_ID, w as THEME_GROUPS_FILE_MARKER, t as themeGroupsSpecifier, a as parseUtilityBlocks, x as runtimeHelperGroupsFromUsage, b as insertAfterUseDirective, y as MANGLE_MAP_PLACEHOLDER, V as VAR_MANGLE_MAP_PLACEHOLDER } from './unplugin.Ceq-N4jI.mjs';
19
+ import { b as importsRuntimeHelper, f as findRuntimeImportClause, r as runtimeHelperGroupsFromUsage, a as insertAfterUseDirective } from './unplugin.DcXM9sq5.mjs';
20
+ import { n as normalizePathSeparators } from './unplugin.wMeicb6E.mjs';
21
+ import { c as createMangleRuntimeModule, M as MANGLE_RUNTIME_VIRTUAL_ID, e as ensureThemeGroupsFile, R as RESOLVED_VIRTUAL_MODULE_ID, b as createMangleMapModule, d as RESOLVED_VIRTUAL_CHECKSUM_ID, f as createChecksumModule, g as RESOLVED_MANGLE_RUNTIME_VIRTUAL_ID, i as RESOLVED_THEME_GROUPS_VIRTUAL_ID, j as createThemeGroupsModule, k as isVirtualModule, r as resolveVirtualModule, p as parseThemeBlocks, m as mergeThemes, l as discoverProjectTheme, C as CHECKSUM_PLACEHOLDER, n as CENSUS_PLACEHOLDER, T as THEME_GROUPS_VIRTUAL_ID, o as THEME_GROUPS_FILE_MARKER, t as themeGroupsSpecifier, a as parseUtilityBlocks, q as MANGLE_MAP_PLACEHOLDER, V as VAR_MANGLE_MAP_PLACEHOLDER } from './unplugin.995yC_cN.mjs';
20
22
  import { gzipSync } from 'node:zlib';
21
23
  import postcss from 'postcss';
22
24
  import valueParser from 'postcss-value-parser';
@@ -1779,24 +1781,10 @@ function injectMangleMapScript(html, mangleMap, options = {}) {
1779
1781
  const scriptTag = `<script id="__CSSZYX_MANGLE_MAP__" type="application/json">${safeJsonForScriptTag(checksumMap, prettyPrint)}<\/script>`;
1780
1782
  return withScriptTag(html, scriptTag);
1781
1783
  }
1782
- function injectMangleMapAttribute(html, mangleMap, minify = false, varMangleMap = {}) {
1783
- const attrName = minify ? "data-sz-m" : "data-sz-map";
1784
- const jsonContent = JSON.stringify(createHydrationMangleMap(mangleMap, varMangleMap));
1785
- return injectHtmlOpeningAttr(html, ` ${attrName}='${jsonContent}'`);
1786
- }
1787
1784
  function injectHydrationData(html, mangleMap, checksum, options = {}) {
1788
- const { mode = "script", minify = false } = options;
1789
- let result = html;
1790
- result = injectChecksum(result, checksum, minify);
1791
- if (mode === "inline") {
1792
- result = injectMangleMapAttribute(result, mangleMap, minify, options.varMangleMap);
1793
- } else if (mode === "script") {
1794
- result = injectMangleMapScript(result, mangleMap, options);
1795
- } else if (mode === "both") {
1796
- result = injectMangleMapAttribute(result, mangleMap, minify, options.varMangleMap);
1797
- result = injectMangleMapScript(result, mangleMap, options);
1798
- }
1799
- return result;
1785
+ const { minify = false, census = true } = options;
1786
+ const result = injectChecksum(html, checksum, minify);
1787
+ return census ? injectMangleMapScript(result, mangleMap, options) : result;
1800
1788
  }
1801
1789
  function transformIndexHtml(html, mangleMap, checksum, options = {}) {
1802
1790
  return injectHydrationData(html, mangleMap, checksum, options);
@@ -1910,6 +1898,9 @@ function needsRuntimeMangleRegistration(manglingEnabled, mangleMap) {
1910
1898
  if (!manglingEnabled) return false;
1911
1899
  return Object.keys(mangleMap).length > 0;
1912
1900
  }
1901
+ function removedInjectChecksumMessage() {
1902
+ return "[csszyx] production.injectChecksum has been removed and was never read. The hydration checksum and the inert census ship on every production build, and no option turned them off \u2014 a build that set this to false still carried both. Delete the option. The census carries no class entries when production.mangle is off, and both tags are data, not script: see https://csszyx.com/docs/security/";
1903
+ }
1913
1904
  function removedMangleMapDeliveryMessage() {
1914
1905
  return "[csszyx] production.mangleMapDelivery has been removed and is ignored. The runtime mangle map is always registered from inside the JS bundle now, on every lane, so the built HTML never carries an executable inline <script> and a strict script-src 'self' policy needs no exception. Delete the option. (`window.__csszyx` is now opt-in through `production.mangleDebugGlobal`.)";
1915
1906
  }
@@ -2372,8 +2363,9 @@ function quoteForConfig(entry) {
2372
2363
  function preserveEntriesFor(hazard) {
2373
2364
  const quote = quoteForConfig;
2374
2365
  const { value } = hazard;
2375
- if (hazard.renamed.every((name) => name === value)) return [quote(value)];
2376
- if (hazard.renamed.every((name) => name.startsWith(value))) return [quote(`${value}*`)];
2366
+ const utilities = hazard.renamed.map((name) => name.slice(utilityStart(name)));
2367
+ if (utilities.every((name) => name === value)) return [quote(value)];
2368
+ if (utilities.every((name) => name.startsWith(value))) return [quote(`${value}*`)];
2377
2369
  return hazard.renamed.map(quote);
2378
2370
  }
2379
2371
  function mangleHybridHazardMessage(hazards) {
@@ -2387,34 +2379,34 @@ function mangleHybridHazardMessage(hazards) {
2387
2379
  if (collisions.length > 0) {
2388
2380
  const sample = collisions.slice(0, 8).join(", ");
2389
2381
  parts.push(
2390
- ` ${collisions.length} mangled token(s) collide with class names in non-csszyx CSS (e.g. ${sample}) \u2014 those tokens will cross-contaminate external ".${collisions[0]}" elements.`,
2391
- " HOTFIX: pass `production: { mangle: false }` to the csszyx plugin to ship now. THEN fix it: if these short names are in your OWN CSS, rename them to something specific (e.g. `.x` \u2192 `.resize-handle-x`) \u2014 short/common names also clash on specificity with other libraries. Only for names in a third-party stylesheet you cannot edit, list them in `production.mangleExclude` instead. Run `npx @csszyx/cli scan-collisions` to find every offending name."
2382
+ `${collisions.length} mangled token(s) collide with class names in non-csszyx CSS (e.g. ${sample}) \u2014 those tokens will cross-contaminate external ".${collisions[0]}" elements.`,
2383
+ "HOTFIX: pass `production: { mangle: false }` to the csszyx plugin to ship now. THEN fix it: if these short names are in your OWN CSS, rename them to something specific (e.g. `.x` \u2192 `.resize-handle-x`) \u2014 short/common names also clash on specificity with other libraries. Only for names in a third-party stylesheet you cannot edit, list them in `production.mangleExclude` instead. Run `npx @csszyx/cli scan-collisions` to find every offending name."
2392
2384
  );
2393
2385
  }
2394
2386
  if (orphans.length > 0) {
2395
2387
  const sample = orphans.slice(0, 8).join(", ");
2396
2388
  parts.push(
2397
- ` ${orphans.length} mangled class(es) have no emitted CSS rule (e.g. ${sample}) \u2014 those elements lose styling.`,
2398
- " Those classes are csszyx-owned but no CSS was emitted for them (e.g. a separate Tailwind plugin owns the utility CSS, or the class is not a real utility). Ensure that CSS is generated, or pass `production: { mangle: false }` to the csszyx plugin until the pipelines are reconciled."
2389
+ `${orphans.length} mangled class(es) have no emitted CSS rule (e.g. ${sample}) \u2014 those elements lose styling.`,
2390
+ "Those classes are csszyx-owned but no CSS was emitted for them (e.g. a separate Tailwind plugin owns the utility CSS, or the class is not a real utility). Ensure that CSS is generated, or pass `production: { mangle: false }` to the csszyx plugin until the pipelines are reconciled."
2399
2391
  );
2400
2392
  }
2401
2393
  if (broken.length > 0) {
2402
2394
  const sample = broken.slice(0, 3).map((hazard) => `${hazard.selector} \u2192 ${hazard.renamed.slice(0, 4).join(", ")}`).join("; ");
2403
2395
  const entries = [...new Set(broken.flatMap(preserveEntriesFor))].join(", ");
2404
2396
  parts.push(
2405
- ` ${broken.length} attribute selector(s) match class names by text (e.g. ${sample}) \u2014 those rules stop matching once the classes are renamed, so the elements lose those styles.`,
2406
- ` Keep those classes readable with production.manglePreserve: [${entries}] (paste-ready), or key the rule off a data attribute, which mangling never touches. production.mangleExclude cannot help here: it reserves token names and does not keep a class from being renamed.`
2397
+ `${broken.length} attribute selector(s) match class names by text (e.g. ${sample}) \u2014 those rules stop matching once the classes are renamed, so the elements lose those styles.`,
2398
+ `Keep those classes readable with production.manglePreserve: [${entries}] (paste-ready), or key the rule off a data attribute, which mangling never touches. production.mangleExclude cannot help here: it reserves token names and does not keep a class from being renamed.`
2407
2399
  );
2408
2400
  }
2409
2401
  if (newlyMatched.length > 0) {
2410
2402
  const sample = newlyMatched.slice(0, 3).map((hazard) => `${hazard.selector} \u2192 ${hazard.matchedTokens.slice(0, 4).join(", ")}`).join("; ");
2411
2403
  const tokens = [...new Set(newlyMatched.flatMap((hazard) => hazard.matchedTokens))].map(quoteForConfig).join(", ");
2412
2404
  parts.push(
2413
- ` ${newlyMatched.length} attribute selector(s) would start matching mangled tokens instead (e.g. ${sample}).`,
2414
- ` Reserve those token names with production.mangleExclude: [${tokens}] (paste-ready) so no class is renamed to one of them, or key the rule off a data attribute, which mangling never touches; a prefix or substring selector goes on matching other tokens, so the data attribute is the durable fix.`
2405
+ `${newlyMatched.length} attribute selector(s) would start matching mangled tokens instead (e.g. ${sample}).`,
2406
+ `Reserve those token names with production.mangleExclude: [${tokens}] (paste-ready) so no class is renamed to one of them, or key the rule off a data attribute, which mangling never touches; a prefix or substring selector goes on matching other tokens, so the data attribute is the durable fix.`
2415
2407
  );
2416
2408
  }
2417
- return parts.join("");
2409
+ return parts.join("\n");
2418
2410
  }
2419
2411
  const TAILWIND_IMPORT_SPECIFIER = /@import\s+["']tailwindcss(?:\/[^"']*)?["']/g;
2420
2412
  const SOURCE_MODIFIER = /\bsource\(/;
@@ -2457,13 +2449,15 @@ function shouldWarnUnscopedMonorepo(sawTailwindEntry, tailwindEntryScoped, inMon
2457
2449
  function unscopedMonorepoMessage() {
2458
2450
  return '[csszyx] Tailwind content detection is UNSCOPED in a monorepo. Tailwind v4 scans every file under its detection base \u2014 .md/.mdx/.txt included \u2014 so a doc or fixture holding class-shaped strings becomes CSS, which can generate phantom or broken url() classes and fail the build. That base is as wide as the build makes it: a Vite build roots it at the Vite root, other setups at the workspace root. Scope it in your Tailwind CSS entry:\n @import "tailwindcss" source(none);\n @source ".";\nThat @source is your package, relative to the CSS file; csszyx auto-injects one for the classes it generates, so only your own templates need listing. Guide: https://csszyx.com/docs/monorepo-content-scope/\nSilence (if a broad scan is intentional): csszyx({ contentScopeCheck: false }).';
2459
2451
  }
2452
+ const CLASS_NAME_PRECEDENCE_MARKER = 'takes precedence over the runtime "className"';
2453
+ const MANGLE_VARS_HOIST_SKIP_MARKER = "mangleVars skipped component CSS variable hoist";
2460
2454
  function isAdvisoryDiagnostic(message) {
2461
- return !(message.includes("unresolvable sz spread") || message.includes("AST budget exceeded") || szFallbackConsequenceOf(message) === "missing-css");
2455
+ return szFallbackConsequenceOf(message) === "nudge" || message.includes(CLASS_NAME_PRECEDENCE_MARKER) || message.includes(MANGLE_VARS_HOIST_SKIP_MARKER);
2462
2456
  }
2463
2457
  function suppressedAdvisoryMessage(count) {
2464
2458
  if (count <= 0) return null;
2465
- const held = count === 1 ? "1 advisory sz fallback" : `${count} advisory sz fallbacks`;
2466
- return `[csszyx] ${held} not listed above. At an sz prop a fallback is advisory \u2014 the runtime path works and the classes are collected \u2014 so a production build keeps the list short. A development build prints each one with its file and position.`;
2459
+ const held = count === 1 ? "1 advisory note" : `${count} advisory notes`;
2460
+ return `[csszyx] ${held} not listed above. An advisory reports something csszyx handled \u2014 a fallback at an sz prop, a className whose precedence over sz is unstated, or a variable hoist the planner declined \u2014 so the styles are there and a production build keeps the list short. A development build prints each one with its file and position.`;
2467
2461
  }
2468
2462
  function resolveQuietMode(quiet) {
2469
2463
  if (quiet === true || quiet === "all") return "all";
@@ -2480,6 +2474,13 @@ function shouldEmitWarning(quiet, devOnly, isProduction) {
2480
2474
  }
2481
2475
  return true;
2482
2476
  }
2477
+ function emitKeyValueDiagnostic(quiet, message, id, emit) {
2478
+ if (resolveQuietMode(quiet) === "all" || szFallbackConsequenceOf(message) !== void 0 || isAdvisoryDiagnostic(message)) {
2479
+ return;
2480
+ }
2481
+ emit(`[csszyx] ${id}
2482
+ ${message}`);
2483
+ }
2483
2484
  function shouldEmitMissingCssFallback(quiet, message) {
2484
2485
  return resolveQuietMode(quiet) !== "all" && szFallbackConsequenceOf(message) === "missing-css";
2485
2486
  }
@@ -3315,6 +3316,8 @@ ${errors.join("\n")}`
3315
3316
  function createCsszyxPlugins(options = {}) {
3316
3317
  assertGlobalVarMangleConfig(options);
3317
3318
  let manglingEnabled = options.production?.mangle === true;
3319
+ const censusRequested = options.production?.hydrationCensus !== false;
3320
+ const censusHasContent = () => manglingEnabled && Object.keys(state.mangleMap).length > 0 || Object.keys(state.varMangleMap).length > 0;
3318
3321
  let serving = false;
3319
3322
  const importedStaticSzEnabled = options.build?.importedStaticSz ?? DEFAULT_IMPORTED_STATIC_SZ;
3320
3323
  const szvCrossModuleRegistry = /* @__PURE__ */ new Map();
@@ -3338,6 +3341,9 @@ function createCsszyxPlugins(options = {}) {
3338
3341
  if (options.production?.mangleMapDelivery !== void 0) {
3339
3342
  console.warn(removedMangleMapDeliveryMessage());
3340
3343
  }
3344
+ if (options.production?.injectChecksum !== void 0) {
3345
+ console.warn(removedInjectChecksumMessage());
3346
+ }
3341
3347
  const sizeAccount = createMangleSizeAccount();
3342
3348
  const astBudgetOverride = options.build?.astBudgetLimit;
3343
3349
  const prescanAstBudget = astBudgetOverride ?? 5e5;
@@ -3432,6 +3438,7 @@ function createCsszyxPlugins(options = {}) {
3432
3438
  skipWarningEmitted: false,
3433
3439
  classesCapped: false,
3434
3440
  ownedClasses: /* @__PURE__ */ new Set(),
3441
+ mangleEligible: [],
3435
3442
  authoredClasses: /* @__PURE__ */ new Set(),
3436
3443
  mangleMap: {},
3437
3444
  varMangleEntriesByFile: varMangleEntries,
@@ -4236,6 +4243,8 @@ function createCsszyxPlugins(options = {}) {
4236
4243
  const unmatched = manglePreserve.unmatched(state.ownedClasses);
4237
4244
  if (unmatched.length > 0) emitWarning(manglePreserveNoMatchMessage(unmatched));
4238
4245
  }
4246
+ state.mangleEligible = eligible;
4247
+ if (!manglingEnabled) return {};
4239
4248
  return allocateMangleTokens(eligible, forbiddenTokens);
4240
4249
  }
4241
4250
  function freezeMangleMap() {
@@ -4453,6 +4462,7 @@ function createCsszyxPlugins(options = {}) {
4453
4462
  continue;
4454
4463
  }
4455
4464
  emitMissingCssFallback(quiet, message, id, console.warn);
4465
+ emitKeyValueDiagnostic(quiet, message, id, console.warn);
4456
4466
  }
4457
4467
  const advisories = result.diagnostics.filter(isAdvisoryDiagnostic);
4458
4468
  if (advisories.length === 0) return;
@@ -4512,7 +4522,7 @@ function createCsszyxPlugins(options = {}) {
4512
4522
  }
4513
4523
  let transformedCode = `${code.slice(0, htmlTag.close)} ${attrName}="${CHECKSUM_PLACEHOLDER}"${code.slice(htmlTag.close)}`;
4514
4524
  const censusTag = `<script id="__CSSZYX_MANGLE_MAP__" type="application/json" dangerouslySetInnerHTML={{__html: \`${CENSUS_PLACEHOLDER}\`}} />`;
4515
- const bodyTag = findOpeningTag(transformedCode, "body");
4525
+ const bodyTag = censusRequested && censusHasContent() ? findOpeningTag(transformedCode, "body") : null;
4516
4526
  if (bodyTag) {
4517
4527
  transformedCode = `${transformedCode.slice(0, bodyTag.close + 1)}${censusTag}${transformedCode.slice(bodyTag.close + 1)}`;
4518
4528
  }
@@ -4969,9 +4979,7 @@ ${transformedCode}`;
4969
4979
  finalizeMangleMap();
4970
4980
  const injectedMangleMap = manglingEnabled ? state.mangleMap : {};
4971
4981
  let result = transformIndexHtml(html, injectedMangleMap, state.checksum, {
4972
- // Always 'script' — the inert JSON census; the
4973
- // checksum attribute is injected regardless.
4974
- mode: "script",
4982
+ census: censusRequested && censusHasContent(),
4975
4983
  minify: process.env.NODE_ENV === "production",
4976
4984
  varMangleMap: state.varMangleMap
4977
4985
  });
@@ -5016,7 +5024,7 @@ ${transformedCode}`;
5016
5024
  const manifest = {
5017
5025
  version: "0.4.0",
5018
5026
  buildId: state.checksum,
5019
- classes: Object.keys(state.mangleMap)
5027
+ classes: [...state.mangleEligible]
5020
5028
  };
5021
5029
  if (includeMangleMap && Object.keys(state.mangleMap).length > 0) {
5022
5030
  manifest.mangleMap = state.mangleMap;
@@ -5378,4 +5386,4 @@ const esbuildPlugin = (options = {}) => {
5378
5386
  };
5379
5387
  };
5380
5388
 
5381
- export { suppressedAdvisoryMessage as $, isPackagesSkippedSource as A, isRSCServerModule as B, isTailwindReservedGlobalVar as C, lateMangleCensusMessage as D, mangleCodeClassesSync as E, mangleEligibleClasses as F, mangleHybridHazardMessage as G, missingTailwindEntryMessage as H, normalizeGlobalVarAliasesForCache as I, planGlobalVarAliases as J, readGlobalVarScanCache as K, realContentHashDisabledMessage as L, recordGlobalVarSourceFile as M, resolveCompileSourceDirs as N, resolveGlobalVarScanCacheDir as O, resolveNativeCacheIdentity as P, resolveQuietMode as Q, rewriteGlobalVarCssAliases as R, rollupPlugin as S, scanGlobalVarCss as T, shouldEmitMissingCssFallback as U, shouldEmitWarning as V, shouldHoldAdvisories as W, shouldTrackGlobalVarSources as X, shouldWarnMissingTailwindEntry as Y, shouldWarnUnscopedMonorepo as Z, skippedSzFilesMessage as _, allocateMangleTokens as a, unscopedMonorepoMessage as a0, validateGlobalVarAliasInputs as a1, vitePlugin as a2, watchModeMangleMessage as a3, webpackPlugin as a4, writeGlobalVarScanCache as a5, assertNoRSCBoundaryViolation as b, assertNoRSCGraphViolation as c, collectMangleHybridHazards as d, createGlobalVarAliasValidationOptions as e, createGlobalVarMapAssetSource as f, createGlobalVarScanCacheKey as g, createRSCModuleRecord as h, cssHasContentScope as i, deleteRSCModuleRecord as j, emitMissingCssFallback as k, esbuildPlugin as l, extractGlobalVarAliasesForManifest as m, fileMayContainSafelistableSz as n, findLocalImportSources as o, findRSCBoundaryViolation as p, findRSCGraphViolation as q, hasInjectableTailwindCandidate as r, hasUseClientDirective as s, hasUseServerDirective as t, unplugin as u, isAdvisoryDiagnostic as v, isCompileSourceOptedIn as w, isHardIgnoredPath as x, isMangleableCssId as y, isMonorepoPackage as z };
5389
+ export { skippedSzFilesMessage as $, isMonorepoPackage as A, isPackagesSkippedSource as B, isRSCServerModule as C, isTailwindReservedGlobalVar as D, lateMangleCensusMessage as E, mangleCodeClassesSync as F, mangleEligibleClasses as G, mangleHybridHazardMessage as H, missingTailwindEntryMessage as I, normalizeGlobalVarAliasesForCache as J, planGlobalVarAliases as K, readGlobalVarScanCache as L, realContentHashDisabledMessage as M, recordGlobalVarSourceFile as N, resolveCompileSourceDirs as O, resolveGlobalVarScanCacheDir as P, resolveNativeCacheIdentity as Q, resolveQuietMode as R, rewriteGlobalVarCssAliases as S, rollupPlugin as T, scanGlobalVarCss as U, shouldEmitMissingCssFallback as V, shouldEmitWarning as W, shouldHoldAdvisories as X, shouldTrackGlobalVarSources as Y, shouldWarnMissingTailwindEntry as Z, shouldWarnUnscopedMonorepo as _, allocateMangleTokens as a, suppressedAdvisoryMessage as a0, unscopedMonorepoMessage as a1, validateGlobalVarAliasInputs as a2, vitePlugin as a3, watchModeMangleMessage as a4, webpackPlugin as a5, writeGlobalVarScanCache as a6, assertNoRSCBoundaryViolation as b, assertNoRSCGraphViolation as c, collectMangleHybridHazards as d, createGlobalVarAliasValidationOptions as e, createGlobalVarMapAssetSource as f, createGlobalVarScanCacheKey as g, createRSCModuleRecord as h, cssHasContentScope as i, deleteRSCModuleRecord as j, emitKeyValueDiagnostic as k, emitMissingCssFallback as l, esbuildPlugin as m, extractGlobalVarAliasesForManifest as n, fileMayContainSafelistableSz as o, findLocalImportSources as p, findRSCBoundaryViolation as q, findRSCGraphViolation as r, hasInjectableTailwindCandidate as s, hasUseClientDirective as t, unplugin as u, hasUseServerDirective as v, isAdvisoryDiagnostic as w, isCompileSourceOptedIn as x, isHardIgnoredPath as y, isMangleableCssId as z };
@@ -1,6 +1,6 @@
1
1
  import * as path from 'node:path';
2
2
  import * as fs from 'node:fs';
3
- import { S as SAFELIST_FILE, d as atomicWriteFileSync, s as sortStrings, r as renderSafelistFile, e as removeLegacySafelists, g as assertNoLegacySourceStylesheet } from './unplugin.DH_ij6cf.mjs';
3
+ import { S as SAFELIST_FILE, d as atomicWriteFileSync, s as sortStrings, r as renderSafelistFile, e as removeLegacySafelists, g as assertNoLegacySourceStylesheet } from './unplugin.Ba3O1r8M.mjs';
4
4
  import { createHash, randomUUID } from 'node:crypto';
5
5
  import { hostname } from 'node:os';
6
6
  import lockfile from 'proper-lockfile';
@@ -3,6 +3,7 @@
3
3
  const node_crypto = require('node:crypto');
4
4
  const fs = require('node:fs');
5
5
  const path = require('node:path');
6
+ const pathNormalization = require('./unplugin.BqKLlo1h.cjs');
6
7
 
7
8
  function _interopNamespaceCompat(e) {
8
9
  if (e && typeof e === 'object' && 'default' in e) return e;
@@ -27,11 +28,6 @@ function sortStrings(values) {
27
28
  });
28
29
  }
29
30
 
30
- const WINDOWS_PATH_SEPARATOR = String.fromCodePoint(92);
31
- function normalizePathSeparators(value) {
32
- return value.split(WINDOWS_PATH_SEPARATOR).join("/");
33
- }
34
-
35
31
  const DEFAULT_RENAME_RETRIES = 5;
36
32
  const DEFAULT_RENAME_RETRY_DELAY_MS = 10;
37
33
  function isRetryableRenameError(error) {
@@ -229,8 +225,8 @@ function legacySourceMessage(cssFile, target) {
229
225
  const TAILWIND_SPECIFIER = String.raw`["']tailwindcss(?:\/[^"']*)?["']`;
230
226
  const TAILWIND_IMPORT = new RegExp(String.raw`@import\s+${TAILWIND_SPECIFIER}`);
231
227
  function computeSafelistRelPath(rootDir, safelistFilename, cssId) {
232
- const safelistPath = normalizePathSeparators(path__namespace.join(rootDir, safelistFilename));
233
- const cssDir = normalizePathSeparators(path__namespace.dirname(cssId));
228
+ const safelistPath = pathNormalization.normalizePathSeparators(path__namespace.join(rootDir, safelistFilename));
229
+ const cssDir = pathNormalization.normalizePathSeparators(path__namespace.dirname(cssId));
234
230
  let relPath = path__namespace.posix.relative(cssDir, safelistPath);
235
231
  if (!relPath.startsWith("./") && !relPath.startsWith("../")) {
236
232
  relPath = `./${relPath}`;
@@ -282,7 +278,6 @@ exports.findLegacySourceDirective = findLegacySourceDirective;
282
278
  exports.findPostcssConfigWithoutCsszyx = findPostcssConfigWithoutCsszyx;
283
279
  exports.legacySourceMessage = legacySourceMessage;
284
280
  exports.missingPostcssPluginMessage = missingPostcssPluginMessage;
285
- exports.normalizePathSeparators = normalizePathSeparators;
286
281
  exports.removeLegacySafelists = removeLegacySafelists;
287
282
  exports.renderSafelistFile = renderSafelistFile;
288
283
  exports.sortStrings = sortStrings;
@@ -4,9 +4,10 @@ const fs = require('node:fs');
4
4
  const path = require('node:path');
5
5
  const compiler = require('@csszyx/compiler');
6
6
  const types = require('@csszyx/types');
7
- const transformCache = require('./unplugin.BzF0V2kw.cjs');
8
- const safelistSource = require('./unplugin.DDSWQJYX.cjs');
7
+ const transformCache = require('./unplugin.YcnV3Izb.cjs');
8
+ const pathNormalization = require('./unplugin.BqKLlo1h.cjs');
9
9
  const node_crypto = require('node:crypto');
10
+ const safelistSource = require('./unplugin.DS6CFjim.cjs');
10
11
 
11
12
  function _interopNamespaceCompat(e) {
12
13
  if (e && typeof e === 'object' && 'default' in e) return e;
@@ -124,7 +125,7 @@ function configWithImportedStaticSz(config, importedStaticSz) {
124
125
  };
125
126
  }
126
127
  function normalizeProviderPaths(providers) {
127
- return [...new Set(providers.map(safelistSource.normalizePathSeparators))];
128
+ return [...new Set(providers.map(pathNormalization.normalizePathSeparators))];
128
129
  }
129
130
 
130
131
  function readPackageVersion(relativePackageJson, fromUrl) {
@@ -283,7 +284,7 @@ function createNextSourceTransformCacheInput(input, filename, producer) {
283
284
  };
284
285
  }
285
286
  function normalizeSourceFilename(filename) {
286
- return safelistSource.normalizePathSeparators(filename);
287
+ return pathNormalization.normalizePathSeparators(filename);
287
288
  }
288
289
  function normalizeGlobalVarAliasesForCache(aliases) {
289
290
  if (!aliases) {
@@ -0,0 +1,109 @@
1
+ const LEADING_WHITESPACE_RE = /^\s+/;
2
+ const LINE_COMMENT_RE = /^\/\/[^\n]*(?:\n|$)/;
3
+ const BLOCK_COMMENT_RE = /^\/\*[\s\S]*?\*\//;
4
+ const USE_DIRECTIVE_RE = /^['"]use (?:client|server)['"];?\s*/;
5
+ function insertAfterUseDirective(code, insertion) {
6
+ let offset = 0;
7
+ while (offset < code.length) {
8
+ const triviaLength = leadingTriviaLength(code.slice(offset));
9
+ if (triviaLength === 0) break;
10
+ offset += triviaLength;
11
+ }
12
+ const directive = USE_DIRECTIVE_RE.exec(code.slice(offset));
13
+ if (!directive) return `${insertion}${code}`;
14
+ const insertionOffset = offset + directive[0].length;
15
+ return `${code.slice(0, insertionOffset)}${insertion}${code.slice(insertionOffset)}`;
16
+ }
17
+ function leadingTriviaLength(source) {
18
+ return LEADING_WHITESPACE_RE.exec(source)?.[0].length ?? LINE_COMMENT_RE.exec(source)?.[0].length ?? BLOCK_COMMENT_RE.exec(source)?.[0].length ?? 0;
19
+ }
20
+
21
+ const RUNTIME_IMPORT_CLAUSE_RE = /(?:import|export)\s+\{([^{}]*)\}\s*from\s*['"]@csszyx\/runtime['"]/g;
22
+ function clauseNames(clauseBody) {
23
+ const names = [];
24
+ for (const part of clauseBody.split(",")) {
25
+ const trimmed = part.trim();
26
+ if (!trimmed) {
27
+ continue;
28
+ }
29
+ const spaceAt = trimmed.search(/\s/);
30
+ names.push(spaceAt === -1 ? trimmed : trimmed.slice(0, spaceAt));
31
+ }
32
+ return names;
33
+ }
34
+ function importsRuntimeHelper(code, helper) {
35
+ RUNTIME_IMPORT_CLAUSE_RE.lastIndex = 0;
36
+ for (let match = RUNTIME_IMPORT_CLAUSE_RE.exec(code); match; match = RUNTIME_IMPORT_CLAUSE_RE.exec(code)) {
37
+ if (clauseNames(match[1]).includes(helper)) {
38
+ return true;
39
+ }
40
+ }
41
+ return false;
42
+ }
43
+ const RUNTIME_IMPORT_APPEND_RE = /(import\s+\{[^{}]*)\}\s*from\s*['"]@csszyx\/runtime['"]/;
44
+ function findRuntimeImportClause(code) {
45
+ const match = RUNTIME_IMPORT_APPEND_RE.exec(code);
46
+ return match ? { statement: match[0], prefixWithBody: match[1] } : null;
47
+ }
48
+
49
+ function runtimeHelperGroupsFromUsage(usage) {
50
+ const slim = usage.usesSzPart === true && usage.szPartArgsProvable === true && usage.usesRuntime !== true && usage.usesMerge !== true;
51
+ const groups = { all: [], barrel: [], merge: [] };
52
+ const append = (helper, toMerge = false) => {
53
+ groups.all.push(helper);
54
+ (toMerge ? groups.merge : groups.barrel).push(helper);
55
+ };
56
+ if (usage.usesRuntime) append("_sz");
57
+ if (usage.usesMerge) append("_szMerge");
58
+ if (usage.usesSzcn) append("_szcn", slim);
59
+ if (usage.usesSzPart) append("_szPart", slim);
60
+ if (usage.usesSzvPick) append("__szvPick");
61
+ if (usage.usesSzvPick1) append("__szvPick1");
62
+ if (usage.usesColorVar) append("__szColorVar");
63
+ if (usage.usesSpacingVar) append("__szSpacingVar");
64
+ if (usage.usesUnitVar) append("__szUnitVar");
65
+ if (usage.usesBoolClass) append("__szBoolClass");
66
+ return groups;
67
+ }
68
+ function injectNextRuntimeImports(code, usage) {
69
+ const groups = runtimeHelperGroupsFromUsage(usage);
70
+ const helpers = groups.all;
71
+ if (helpers.length === 0) {
72
+ return { code, injected: [] };
73
+ }
74
+ const hasRuntimeImport = code.includes("@csszyx/runtime");
75
+ const missing = hasRuntimeImport ? helpers.filter((helper) => !importsRuntimeHelper(code, helper)) : helpers;
76
+ if (missing.length === 0) {
77
+ return { code, injected: [] };
78
+ }
79
+ if (groups.merge.length > 0) {
80
+ const mergeHelpers = missing.filter((helper) => groups.merge.includes(helper));
81
+ const barrelHelpers = missing.filter((helper) => groups.barrel.includes(helper));
82
+ let next = insertRuntimeImport(
83
+ code,
84
+ `import { ${mergeHelpers.join(", ")} } from '@csszyx/runtime/merge';
85
+ `
86
+ );
87
+ if (barrelHelpers.length > 0) {
88
+ next = insertRuntimeImport(
89
+ next,
90
+ `import { ${barrelHelpers.join(", ")} } from '@csszyx/runtime';
91
+ `
92
+ );
93
+ }
94
+ return { code: next, injected: missing };
95
+ }
96
+ return {
97
+ code: insertRuntimeImport(
98
+ code,
99
+ `import { ${missing.join(", ")} } from '@csszyx/runtime';
100
+ `
101
+ ),
102
+ injected: missing
103
+ };
104
+ }
105
+ function insertRuntimeImport(code, importStmt) {
106
+ return insertAfterUseDirective(code, importStmt);
107
+ }
108
+
109
+ export { insertAfterUseDirective as a, importsRuntimeHelper as b, findRuntimeImportClause as f, injectNextRuntimeImports as i, runtimeHelperGroupsFromUsage as r };
@@ -0,0 +1,115 @@
1
+ 'use strict';
2
+
3
+ const LEADING_WHITESPACE_RE = /^\s+/;
4
+ const LINE_COMMENT_RE = /^\/\/[^\n]*(?:\n|$)/;
5
+ const BLOCK_COMMENT_RE = /^\/\*[\s\S]*?\*\//;
6
+ const USE_DIRECTIVE_RE = /^['"]use (?:client|server)['"];?\s*/;
7
+ function insertAfterUseDirective(code, insertion) {
8
+ let offset = 0;
9
+ while (offset < code.length) {
10
+ const triviaLength = leadingTriviaLength(code.slice(offset));
11
+ if (triviaLength === 0) break;
12
+ offset += triviaLength;
13
+ }
14
+ const directive = USE_DIRECTIVE_RE.exec(code.slice(offset));
15
+ if (!directive) return `${insertion}${code}`;
16
+ const insertionOffset = offset + directive[0].length;
17
+ return `${code.slice(0, insertionOffset)}${insertion}${code.slice(insertionOffset)}`;
18
+ }
19
+ function leadingTriviaLength(source) {
20
+ return LEADING_WHITESPACE_RE.exec(source)?.[0].length ?? LINE_COMMENT_RE.exec(source)?.[0].length ?? BLOCK_COMMENT_RE.exec(source)?.[0].length ?? 0;
21
+ }
22
+
23
+ const RUNTIME_IMPORT_CLAUSE_RE = /(?:import|export)\s+\{([^{}]*)\}\s*from\s*['"]@csszyx\/runtime['"]/g;
24
+ function clauseNames(clauseBody) {
25
+ const names = [];
26
+ for (const part of clauseBody.split(",")) {
27
+ const trimmed = part.trim();
28
+ if (!trimmed) {
29
+ continue;
30
+ }
31
+ const spaceAt = trimmed.search(/\s/);
32
+ names.push(spaceAt === -1 ? trimmed : trimmed.slice(0, spaceAt));
33
+ }
34
+ return names;
35
+ }
36
+ function importsRuntimeHelper(code, helper) {
37
+ RUNTIME_IMPORT_CLAUSE_RE.lastIndex = 0;
38
+ for (let match = RUNTIME_IMPORT_CLAUSE_RE.exec(code); match; match = RUNTIME_IMPORT_CLAUSE_RE.exec(code)) {
39
+ if (clauseNames(match[1]).includes(helper)) {
40
+ return true;
41
+ }
42
+ }
43
+ return false;
44
+ }
45
+ const RUNTIME_IMPORT_APPEND_RE = /(import\s+\{[^{}]*)\}\s*from\s*['"]@csszyx\/runtime['"]/;
46
+ function findRuntimeImportClause(code) {
47
+ const match = RUNTIME_IMPORT_APPEND_RE.exec(code);
48
+ return match ? { statement: match[0], prefixWithBody: match[1] } : null;
49
+ }
50
+
51
+ function runtimeHelperGroupsFromUsage(usage) {
52
+ const slim = usage.usesSzPart === true && usage.szPartArgsProvable === true && usage.usesRuntime !== true && usage.usesMerge !== true;
53
+ const groups = { all: [], barrel: [], merge: [] };
54
+ const append = (helper, toMerge = false) => {
55
+ groups.all.push(helper);
56
+ (toMerge ? groups.merge : groups.barrel).push(helper);
57
+ };
58
+ if (usage.usesRuntime) append("_sz");
59
+ if (usage.usesMerge) append("_szMerge");
60
+ if (usage.usesSzcn) append("_szcn", slim);
61
+ if (usage.usesSzPart) append("_szPart", slim);
62
+ if (usage.usesSzvPick) append("__szvPick");
63
+ if (usage.usesSzvPick1) append("__szvPick1");
64
+ if (usage.usesColorVar) append("__szColorVar");
65
+ if (usage.usesSpacingVar) append("__szSpacingVar");
66
+ if (usage.usesUnitVar) append("__szUnitVar");
67
+ if (usage.usesBoolClass) append("__szBoolClass");
68
+ return groups;
69
+ }
70
+ function injectNextRuntimeImports(code, usage) {
71
+ const groups = runtimeHelperGroupsFromUsage(usage);
72
+ const helpers = groups.all;
73
+ if (helpers.length === 0) {
74
+ return { code, injected: [] };
75
+ }
76
+ const hasRuntimeImport = code.includes("@csszyx/runtime");
77
+ const missing = hasRuntimeImport ? helpers.filter((helper) => !importsRuntimeHelper(code, helper)) : helpers;
78
+ if (missing.length === 0) {
79
+ return { code, injected: [] };
80
+ }
81
+ if (groups.merge.length > 0) {
82
+ const mergeHelpers = missing.filter((helper) => groups.merge.includes(helper));
83
+ const barrelHelpers = missing.filter((helper) => groups.barrel.includes(helper));
84
+ let next = insertRuntimeImport(
85
+ code,
86
+ `import { ${mergeHelpers.join(", ")} } from '@csszyx/runtime/merge';
87
+ `
88
+ );
89
+ if (barrelHelpers.length > 0) {
90
+ next = insertRuntimeImport(
91
+ next,
92
+ `import { ${barrelHelpers.join(", ")} } from '@csszyx/runtime';
93
+ `
94
+ );
95
+ }
96
+ return { code: next, injected: missing };
97
+ }
98
+ return {
99
+ code: insertRuntimeImport(
100
+ code,
101
+ `import { ${missing.join(", ")} } from '@csszyx/runtime';
102
+ `
103
+ ),
104
+ injected: missing
105
+ };
106
+ }
107
+ function insertRuntimeImport(code, importStmt) {
108
+ return insertAfterUseDirective(code, importStmt);
109
+ }
110
+
111
+ exports.findRuntimeImportClause = findRuntimeImportClause;
112
+ exports.importsRuntimeHelper = importsRuntimeHelper;
113
+ exports.injectNextRuntimeImports = injectNextRuntimeImports;
114
+ exports.insertAfterUseDirective = insertAfterUseDirective;
115
+ exports.runtimeHelperGroupsFromUsage = runtimeHelperGroupsFromUsage;
@@ -523,6 +523,14 @@ interface PluginState {
523
523
  * by a raw selector consumer.
524
524
  */
525
525
  ownedClasses: Set<string>;
526
+ /**
527
+ * Owned classes that a mangle map WOULD carry: `ownedClasses` minus the
528
+ * authored ones and minus `manglePreserve`. Recorded whether or not
529
+ * mangling runs, because the bundle manifest lists them either way and used
530
+ * to read them off the map's keys — which is why the map had to be
531
+ * allocated on a build that never mangles.
532
+ */
533
+ mangleEligible: string[];
526
534
  /**
527
535
  * Classes written through author-facing class/className attributes. Any
528
536
  * overlap with ownedClasses must keep its original name because bundled
@@ -751,9 +759,18 @@ declare function unscopedMonorepoMessage(): string;
751
759
  /**
752
760
  * Whether a diagnostic is an advisory one — the class a build may hold back.
753
761
  *
754
- * Spread warnings, budget bails and `missing-css` fallbacks all describe absent
755
- * output and print regardless. What is left says the runtime path was taken
756
- * where a compiled one was possible: real, worth acting on, and not a failure.
762
+ * Advisory means one thing: the styles are THERE, and the note is about how
763
+ * they got there. An `sz`-site nudge fallback took the runtime path where a
764
+ * compiled one was possible; the precedence advisory says which of two sources
765
+ * won. Everything else describes output that is absent or dead, and a
766
+ * production build has to print it.
767
+ *
768
+ * Asked positively on purpose. The predicate used to be "not one of three known
769
+ * kinds", which quietly made every key and value diagnostic advisory: a
770
+ * production build of a file with five typo'd keys printed nothing but a census
771
+ * calling them fallbacks, while `csszyx check` on the same tree named all six.
772
+ * A classifier written by exclusion cannot stay right as diagnostics are added,
773
+ * because a new one joins the silent side by default.
757
774
  *
758
775
  * @param message - One raw diagnostic line as an engine emitted it.
759
776
  * @returns True when the diagnostic is advisory rather than a build result.
@@ -772,7 +789,7 @@ declare function isAdvisoryDiagnostic(message: string): boolean;
772
789
  * Suppression is the right default; implying zero is not. One line costs
773
790
  * nothing and keeps the difference visible.
774
791
  *
775
- * @param count - Advisory fallbacks the build declined to list.
792
+ * @param count - Advisory notes the build declined to list.
776
793
  * @returns The disclosure, or null when nothing was held back.
777
794
  */
778
795
  declare function suppressedAdvisoryMessage(count: number): string | null;
@@ -807,6 +824,22 @@ declare function resolveQuietMode(quiet: boolean | 'nudges' | QuietMode | undefi
807
824
  * @returns true when the warning should be printed.
808
825
  */
809
826
  declare function shouldEmitWarning(quiet: QuietMode, devOnly: boolean, isProduction: boolean): boolean;
827
+ /**
828
+ * Emit one key or value diagnostic — the family that says a class is dead.
829
+ *
830
+ * Its own channel because the two that existed both answer a different
831
+ * question: `emitMissingCssFallback` handles fallback sites, and the advisory
832
+ * channel handles notes about styles that ARE present. A typo'd key matched
833
+ * neither, so a production build dropped it on the floor while `csszyx check`
834
+ * on the same tree exited 1 and named it. Muted only by `quiet: true`, on the
835
+ * same reasoning as the missing-css channel: wrong output is not a usage nudge.
836
+ *
837
+ * @param quiet - Resolved quiet mode.
838
+ * @param message - Compiler diagnostic to classify and emit.
839
+ * @param id - Bundler module identifier included in the warning.
840
+ * @param emit - Warning output channel.
841
+ */
842
+ declare function emitKeyValueDiagnostic(quiet: QuietMode, message: string, id: string, emit: (message: string) => void): void;
810
843
  /**
811
844
  * Whether a transform diagnostic describes missing CSS and may be printed.
812
845
  *
@@ -1079,5 +1112,5 @@ declare const rollupPlugin: (options?: PartialCsszyxConfig) => InputPluginOption
1079
1112
  */
1080
1113
  declare const esbuildPlugin: (options?: PartialCsszyxConfig) => Plugin;
1081
1114
 
1082
- export { isRSCServerModule as $, unplugin as A, deleteRSCModuleRecord as B, emitMissingCssFallback as D, esbuildPlugin as E, extractGlobalVarAliasesForManifest as F, fileMayContainSafelistableSz as H, findLocalImportSources as I, findRSCBoundaryViolation as J, findRSCGraphViolation as K, hasInjectableTailwindCandidate as L, hasTokens as N, hasUseClientDirective as O, hasUseServerDirective as T, isAdvisoryDiagnostic as U, isCompileSourceOptedIn as W, isHardIgnoredPath as X, isMangleableCssId as Y, isMonorepoPackage as Z, isPackagesSkippedSource as _, lateMangleCensusMessage as a0, mangleCodeClassesSync as a1, mangleEligibleClasses as a2, mangleHybridHazardMessage as a3, mergeThemes as a4, missingTailwindEntryMessage as a5, normalizeGlobalVarAliasesForCache as a6, parseThemeBlocks as a7, parseUtilityBlocks as a8, realContentHashDisabledMessage as a9, recordGlobalVarSourceFile as aa, resolveCompileSourceDirs as ab, resolveNativeCacheIdentity as ac, resolveQuietMode as ad, rollupPlugin as ae, scanCustomPropertyNames as af, shouldEmitMissingCssFallback as ag, shouldEmitWarning as ah, shouldHoldAdvisories as ai, shouldTrackGlobalVarSources as aj, shouldWarnMissingTailwindEntry as ak, shouldWarnUnscopedMonorepo as al, skippedSzFilesMessage as am, suppressedAdvisoryMessage as an, unscopedMonorepoMessage as ao, vitePlugin as ap, watchModeMangleMessage as aq, webpackPlugin as ar, allocateMangleTokens as t, assertNoRSCBoundaryViolation as u, assertNoRSCGraphViolation as v, collectMangleHybridHazards as w, createGlobalVarMapAssetSource as x, createRSCModuleRecord as y, cssHasContentScope as z };
1115
+ export { isPackagesSkippedSource as $, unplugin as A, deleteRSCModuleRecord as B, emitKeyValueDiagnostic as D, emitMissingCssFallback as E, esbuildPlugin as F, extractGlobalVarAliasesForManifest as H, fileMayContainSafelistableSz as I, findLocalImportSources as J, findRSCBoundaryViolation as K, findRSCGraphViolation as L, hasInjectableTailwindCandidate as N, hasTokens as O, hasUseClientDirective as T, hasUseServerDirective as U, isAdvisoryDiagnostic as W, isCompileSourceOptedIn as X, isHardIgnoredPath as Y, isMangleableCssId as Z, isMonorepoPackage as _, isRSCServerModule as a0, lateMangleCensusMessage as a1, mangleCodeClassesSync as a2, mangleEligibleClasses as a3, mangleHybridHazardMessage as a4, mergeThemes as a5, missingTailwindEntryMessage as a6, normalizeGlobalVarAliasesForCache as a7, parseThemeBlocks as a8, parseUtilityBlocks as a9, realContentHashDisabledMessage as aa, recordGlobalVarSourceFile as ab, resolveCompileSourceDirs as ac, resolveNativeCacheIdentity as ad, resolveQuietMode as ae, rollupPlugin as af, scanCustomPropertyNames as ag, shouldEmitMissingCssFallback as ah, shouldEmitWarning as ai, shouldHoldAdvisories as aj, shouldTrackGlobalVarSources as ak, shouldWarnMissingTailwindEntry as al, shouldWarnUnscopedMonorepo as am, skippedSzFilesMessage as an, suppressedAdvisoryMessage as ao, unscopedMonorepoMessage as ap, vitePlugin as aq, watchModeMangleMessage as ar, webpackPlugin as as, allocateMangleTokens as t, assertNoRSCBoundaryViolation as u, assertNoRSCGraphViolation as v, collectMangleHybridHazards as w, createGlobalVarMapAssetSource as x, createRSCModuleRecord as y, cssHasContentScope as z };
1083
1116
  export type { CssVarScanResult as C, GlobalVarScanCacheKeyInput as G, MangleHybridHazards as M, PlanGlobalVarAliasesInput as P, QuietMode as Q, RewriteGlobalVarCssAliasesOptions as R, ScanGlobalVarCssOptions as S, ValidateGlobalVarAliasInputsOptions as V, GlobalVarAliasPlan as a, GlobalVarCssAliasRewriteResult as b, CreateGlobalVarAliasValidationOptionsInput as c, GlobalVarAliasValidationResult as d, CssVarDefinition as e, CssVarLocation as f, CssVarReference as g, GlobalVarAliasDiagnostic as h, GlobalVarAliasDiagnosticSeverity as i, GlobalVarAliasEntry as j, GlobalVarCodeSource as k, GlobalVarCssAssetSource as l, GlobalVarCssSource as m, GlobalVarScanCacheEntry as n, MangleSelectorHazard as o, ParsedTheme as p, ParsedUtilities as q, RSCBoundaryViolation as r, RSCModuleRecord as s };