@kbach/react 1.0.0-beta.8 → 1.0.0-beta.9

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.
@@ -9,6 +9,7 @@ import {
9
9
  // src/vite-plugin/index.ts
10
10
  import { readFileSync as readFileSync3, writeFileSync, mkdirSync, existsSync, statSync as statSync2 } from "fs";
11
11
  import { join as join4, dirname } from "path";
12
+ import { pathToFileURL } from "url";
12
13
  import { createRequire } from "module";
13
14
 
14
15
  // src/vite-plugin/cssVars.ts
@@ -1262,16 +1263,36 @@ function writeFileEnsuringDir(path, content) {
1262
1263
  mkdirSync(dirname(path), { recursive: true });
1263
1264
  writeFileSync(path, content, "utf-8");
1264
1265
  }
1265
- function loadConfigFile(root) {
1266
- const path = join4(root, "kbach.config.js");
1267
- if (!existsSync(path)) return void 0;
1266
+ function isEsmRequireFailure(err) {
1267
+ if (!(err instanceof Error)) return false;
1268
+ return err.code === "ERR_REQUIRE_ESM" || /is not defined in ES module scope/.test(err.message);
1269
+ }
1270
+ async function importConfigModule(path) {
1271
+ const mod = await import(pathToFileURL(path).href);
1272
+ return mod.default ?? mod;
1273
+ }
1274
+ function requireConfigModule(root, path) {
1268
1275
  const mod = createRequire(root)(path);
1269
1276
  return mod.default ?? mod;
1270
1277
  }
1271
- function resolveEffectiveTheme(root, options) {
1278
+ async function loadConfigFile(root) {
1279
+ const cjsPath = join4(root, "kbach.config.cjs");
1280
+ if (existsSync(cjsPath)) return requireConfigModule(root, cjsPath);
1281
+ const mjsPath = join4(root, "kbach.config.mjs");
1282
+ if (existsSync(mjsPath)) return importConfigModule(mjsPath);
1283
+ const jsPath = join4(root, "kbach.config.js");
1284
+ if (!existsSync(jsPath)) return void 0;
1285
+ try {
1286
+ return requireConfigModule(root, jsPath);
1287
+ } catch (err) {
1288
+ if (!isEsmRequireFailure(err)) throw err;
1289
+ return importConfigModule(jsPath);
1290
+ }
1291
+ }
1292
+ async function resolveEffectiveTheme(root, options) {
1272
1293
  if (options.theme) return options.theme;
1273
1294
  if (options.config) return resolveKbachConfig(options.config);
1274
- const discovered = loadConfigFile(root);
1295
+ const discovered = await loadConfigFile(root);
1275
1296
  return discovered ? resolveKbachConfig(discovered) : defaultTheme;
1276
1297
  }
1277
1298
  function kbach(options = {}) {
@@ -1306,9 +1327,9 @@ function kbach(options = {}) {
1306
1327
  return {
1307
1328
  name: "kbach",
1308
1329
  enforce: "pre",
1309
- configResolved(resolved) {
1330
+ async configResolved(resolved) {
1310
1331
  root = resolved.root;
1311
- theme = resolveEffectiveTheme(root, options);
1332
+ theme = await resolveEffectiveTheme(root, options);
1312
1333
  engine = createKbachStaticCssEngine({ root, theme, themeJson: JSON.stringify(theme), includeDirs, safelist });
1313
1334
  mainCSSFilePath = findMainCSSFile(root, includeDirs, options.cssFile);
1314
1335
  },
@@ -618,6 +618,7 @@ function createKbachStaticCssEngine(options) {
618
618
  // src/vite-plugin/index.ts
619
619
  var import_fs2 = require("fs");
620
620
  var import_path4 = require("path");
621
+ var import_url = require("url");
621
622
  var import_module = require("module");
622
623
 
623
624
  // src/generatedPalette.ts
@@ -1038,16 +1039,36 @@ function resolveKbachConfig(config) {
1038
1039
 
1039
1040
  // src/vite-plugin/index.ts
1040
1041
  var DEFAULT_SCAN_DIRS = ["src", "app", "pages", "components"];
1041
- function loadConfigFile(root) {
1042
- const path = (0, import_path4.join)(root, "kbach.config.js");
1043
- if (!(0, import_fs2.existsSync)(path)) return void 0;
1042
+ function isEsmRequireFailure(err) {
1043
+ if (!(err instanceof Error)) return false;
1044
+ return err.code === "ERR_REQUIRE_ESM" || /is not defined in ES module scope/.test(err.message);
1045
+ }
1046
+ async function importConfigModule(path) {
1047
+ const mod = await import((0, import_url.pathToFileURL)(path).href);
1048
+ return mod.default ?? mod;
1049
+ }
1050
+ function requireConfigModule(root, path) {
1044
1051
  const mod = (0, import_module.createRequire)(root)(path);
1045
1052
  return mod.default ?? mod;
1046
1053
  }
1047
- function resolveEffectiveTheme(root, options) {
1054
+ async function loadConfigFile(root) {
1055
+ const cjsPath = (0, import_path4.join)(root, "kbach.config.cjs");
1056
+ if ((0, import_fs2.existsSync)(cjsPath)) return requireConfigModule(root, cjsPath);
1057
+ const mjsPath = (0, import_path4.join)(root, "kbach.config.mjs");
1058
+ if ((0, import_fs2.existsSync)(mjsPath)) return importConfigModule(mjsPath);
1059
+ const jsPath = (0, import_path4.join)(root, "kbach.config.js");
1060
+ if (!(0, import_fs2.existsSync)(jsPath)) return void 0;
1061
+ try {
1062
+ return requireConfigModule(root, jsPath);
1063
+ } catch (err) {
1064
+ if (!isEsmRequireFailure(err)) throw err;
1065
+ return importConfigModule(jsPath);
1066
+ }
1067
+ }
1068
+ async function resolveEffectiveTheme(root, options) {
1048
1069
  if (options.theme) return options.theme;
1049
1070
  if (options.config) return resolveKbachConfig(options.config);
1050
- const discovered = loadConfigFile(root);
1071
+ const discovered = await loadConfigFile(root);
1051
1072
  return discovered ? resolveKbachConfig(discovered) : defaultTheme;
1052
1073
  }
1053
1074
 
@@ -1089,9 +1110,9 @@ function spliceGeneratedCss(root, generatedCss) {
1089
1110
  function kbachPostcss(options = {}) {
1090
1111
  return {
1091
1112
  postcssPlugin: "kbach",
1092
- Once(root, { result }) {
1113
+ async Once(root, { result }) {
1093
1114
  const projectRoot = options.root ?? process.cwd();
1094
- const theme = resolveEffectiveTheme(projectRoot, options);
1115
+ const theme = await resolveEffectiveTheme(projectRoot, options);
1095
1116
  const includeDirs = options.include ?? DEFAULT_SCAN_DIRS;
1096
1117
  const safelist = options.safelist ?? [];
1097
1118
  const engine = createKbachStaticCssEngine({
@@ -2,7 +2,7 @@ import {
2
2
  DEFAULT_SCAN_DIRS,
3
3
  createKbachStaticCssEngine,
4
4
  resolveEffectiveTheme
5
- } from "./chunk-3E26VMLA.mjs";
5
+ } from "./chunk-7JBSTM5D.mjs";
6
6
  import "./chunk-NKR3PSWO.mjs";
7
7
  import "./chunk-N5HCQIBB.mjs";
8
8
 
@@ -46,9 +46,9 @@ function spliceGeneratedCss(root, generatedCss) {
46
46
  function kbachPostcss(options = {}) {
47
47
  return {
48
48
  postcssPlugin: "kbach",
49
- Once(root, { result }) {
49
+ async Once(root, { result }) {
50
50
  const projectRoot = options.root ?? process.cwd();
51
- const theme = resolveEffectiveTheme(projectRoot, options);
51
+ const theme = await resolveEffectiveTheme(projectRoot, options);
52
52
  const includeDirs = options.include ?? DEFAULT_SCAN_DIRS;
53
53
  const safelist = options.safelist ?? [];
54
54
  const engine = createKbachStaticCssEngine({
@@ -65,24 +65,40 @@ declare function findMainCSSFile(root: string, includeDirs: string[], explicitCs
65
65
  declare const DEFAULT_SCAN_DIRS: string[];
66
66
  declare const CSS_SYNC_DEBOUNCE_MS = 50;
67
67
  /**
68
- * Auto-discovers `kbach.config.js` at the project root — `undefined` if it
69
- * doesn't exist (the common case: most projects have no customization at
68
+ * Auto-discovers a `kbach.config.*` file at the project root — `undefined`
69
+ * if none exists (the common case: most projects have no customization at
70
70
  * all, so this is a silent, expected no-op, not a warning).
71
71
  *
72
- * Uses `require()` (a real project's `kbach.config.js` is plain CommonJS,
73
- * `module.exports = {...}`, matching every example in this package's own
74
- * README), built via `createRequire(root)` rather than
72
+ * Checks three filenames, in order, mirroring Node's own module-format
73
+ * conventions rather than assuming one: `kbach.config.cjs` (always
74
+ * CommonJS, `module.exports = {...}` — the one unambiguous choice
75
+ * regardless of the project's package.json) and `kbach.config.mjs`
76
+ * (always real ESM, `export default {...}`) are tried first, each loaded
77
+ * the one way that's guaranteed correct for that extension. Only the bare
78
+ * `kbach.config.js` — whose actual meaning depends on the nearest
79
+ * package.json's `"type"` field, exactly like every other `.js` file in
80
+ * the project — needs the fallback below: try `require()` first (correct
81
+ * for `"type": "commonjs"`/no `"type"` field, the more common case), and
82
+ * only on a failure that specifically indicates an ESM/CJS mismatch (see
83
+ * `isEsmRequireFailure`), retry via a real dynamic `import()` instead. A
84
+ * genuine syntax error in an otherwise-correctly-formatted config file is
85
+ * NOT caught here — it propagates as a real, actionable build failure,
86
+ * rather than being silently swallowed into a confusing second attempt.
87
+ *
88
+ * `require()` is built via `createRequire(root)` rather than
75
89
  * `createRequire(import.meta.url)` — this file is written as ESM source,
76
90
  * but tsup's CJS build output has no real `import.meta.url` (esbuild
77
91
  * leaves it `undefined` there), which would make `createRequire` throw for
78
92
  * anyone consuming this package's `require('@kbach/react/vite')` entry.
79
93
  * `root` works as `createRequire`'s base in either build: it's always an
80
- * absolute, already-`existsSync`-validated-by-caller directory, and
81
- * `require()` given `path` (itself already absolute) doesn't consult the
82
- * base for resolution anyway — the base only matters for a RELATIVE
83
- * specifier, which this never passes it.
94
+ * absolute, already-`existsSync`-validated directory, and `require()`
95
+ * given an already-absolute `path` doesn't consult the base for
96
+ * resolution anyway — the base only matters for a relative specifier,
97
+ * which this never passes it. `import()` needs a real `file://` URL, not
98
+ * a bare Windows path (`C:\...` isn't a valid ESM specifier) — hence
99
+ * `pathToFileURL`.
84
100
  */
85
- declare function loadConfigFile(root: string): KbachConfig | undefined;
101
+ declare function loadConfigFile(root: string): Promise<KbachConfig | undefined>;
86
102
  /**
87
103
  * Resolves the theme to use, applying the same "explicit theme/config
88
104
  * always wins over kbach.config.js auto-discovery" precedence both
@@ -91,7 +107,7 @@ declare function loadConfigFile(root: string): KbachConfig | undefined;
91
107
  declare function resolveEffectiveTheme(root: string, options: {
92
108
  theme?: ThemeConfig;
93
109
  config?: KbachConfig;
94
- }): ThemeConfig;
110
+ }): Promise<ThemeConfig>;
95
111
  /**
96
112
  * Build-time static CSS generation for Vite — scans source files for
97
113
  * Kbach class strings, resolves them through the same Rust engine the
@@ -65,24 +65,40 @@ declare function findMainCSSFile(root: string, includeDirs: string[], explicitCs
65
65
  declare const DEFAULT_SCAN_DIRS: string[];
66
66
  declare const CSS_SYNC_DEBOUNCE_MS = 50;
67
67
  /**
68
- * Auto-discovers `kbach.config.js` at the project root — `undefined` if it
69
- * doesn't exist (the common case: most projects have no customization at
68
+ * Auto-discovers a `kbach.config.*` file at the project root — `undefined`
69
+ * if none exists (the common case: most projects have no customization at
70
70
  * all, so this is a silent, expected no-op, not a warning).
71
71
  *
72
- * Uses `require()` (a real project's `kbach.config.js` is plain CommonJS,
73
- * `module.exports = {...}`, matching every example in this package's own
74
- * README), built via `createRequire(root)` rather than
72
+ * Checks three filenames, in order, mirroring Node's own module-format
73
+ * conventions rather than assuming one: `kbach.config.cjs` (always
74
+ * CommonJS, `module.exports = {...}` — the one unambiguous choice
75
+ * regardless of the project's package.json) and `kbach.config.mjs`
76
+ * (always real ESM, `export default {...}`) are tried first, each loaded
77
+ * the one way that's guaranteed correct for that extension. Only the bare
78
+ * `kbach.config.js` — whose actual meaning depends on the nearest
79
+ * package.json's `"type"` field, exactly like every other `.js` file in
80
+ * the project — needs the fallback below: try `require()` first (correct
81
+ * for `"type": "commonjs"`/no `"type"` field, the more common case), and
82
+ * only on a failure that specifically indicates an ESM/CJS mismatch (see
83
+ * `isEsmRequireFailure`), retry via a real dynamic `import()` instead. A
84
+ * genuine syntax error in an otherwise-correctly-formatted config file is
85
+ * NOT caught here — it propagates as a real, actionable build failure,
86
+ * rather than being silently swallowed into a confusing second attempt.
87
+ *
88
+ * `require()` is built via `createRequire(root)` rather than
75
89
  * `createRequire(import.meta.url)` — this file is written as ESM source,
76
90
  * but tsup's CJS build output has no real `import.meta.url` (esbuild
77
91
  * leaves it `undefined` there), which would make `createRequire` throw for
78
92
  * anyone consuming this package's `require('@kbach/react/vite')` entry.
79
93
  * `root` works as `createRequire`'s base in either build: it's always an
80
- * absolute, already-`existsSync`-validated-by-caller directory, and
81
- * `require()` given `path` (itself already absolute) doesn't consult the
82
- * base for resolution anyway — the base only matters for a RELATIVE
83
- * specifier, which this never passes it.
94
+ * absolute, already-`existsSync`-validated directory, and `require()`
95
+ * given an already-absolute `path` doesn't consult the base for
96
+ * resolution anyway — the base only matters for a relative specifier,
97
+ * which this never passes it. `import()` needs a real `file://` URL, not
98
+ * a bare Windows path (`C:\...` isn't a valid ESM specifier) — hence
99
+ * `pathToFileURL`.
84
100
  */
85
- declare function loadConfigFile(root: string): KbachConfig | undefined;
101
+ declare function loadConfigFile(root: string): Promise<KbachConfig | undefined>;
86
102
  /**
87
103
  * Resolves the theme to use, applying the same "explicit theme/config
88
104
  * always wins over kbach.config.js auto-discovery" precedence both
@@ -91,7 +107,7 @@ declare function loadConfigFile(root: string): KbachConfig | undefined;
91
107
  declare function resolveEffectiveTheme(root: string, options: {
92
108
  theme?: ThemeConfig;
93
109
  config?: KbachConfig;
94
- }): ThemeConfig;
110
+ }): Promise<ThemeConfig>;
95
111
  /**
96
112
  * Build-time static CSS generation for Vite — scans source files for
97
113
  * Kbach class strings, resolves them through the same Rust engine the
@@ -30,6 +30,7 @@ __export(vite_plugin_exports, {
30
30
  module.exports = __toCommonJS(vite_plugin_exports);
31
31
  var import_fs3 = require("fs");
32
32
  var import_path4 = require("path");
33
+ var import_url = require("url");
33
34
  var import_module = require("module");
34
35
 
35
36
  // src/vite-plugin/cssVars.ts
@@ -1782,16 +1783,36 @@ function writeFileEnsuringDir(path, content) {
1782
1783
  (0, import_fs3.mkdirSync)((0, import_path4.dirname)(path), { recursive: true });
1783
1784
  (0, import_fs3.writeFileSync)(path, content, "utf-8");
1784
1785
  }
1785
- function loadConfigFile(root) {
1786
- const path = (0, import_path4.join)(root, "kbach.config.js");
1787
- if (!(0, import_fs3.existsSync)(path)) return void 0;
1786
+ function isEsmRequireFailure(err) {
1787
+ if (!(err instanceof Error)) return false;
1788
+ return err.code === "ERR_REQUIRE_ESM" || /is not defined in ES module scope/.test(err.message);
1789
+ }
1790
+ async function importConfigModule(path) {
1791
+ const mod = await import((0, import_url.pathToFileURL)(path).href);
1792
+ return mod.default ?? mod;
1793
+ }
1794
+ function requireConfigModule(root, path) {
1788
1795
  const mod = (0, import_module.createRequire)(root)(path);
1789
1796
  return mod.default ?? mod;
1790
1797
  }
1791
- function resolveEffectiveTheme(root, options) {
1798
+ async function loadConfigFile(root) {
1799
+ const cjsPath = (0, import_path4.join)(root, "kbach.config.cjs");
1800
+ if ((0, import_fs3.existsSync)(cjsPath)) return requireConfigModule(root, cjsPath);
1801
+ const mjsPath = (0, import_path4.join)(root, "kbach.config.mjs");
1802
+ if ((0, import_fs3.existsSync)(mjsPath)) return importConfigModule(mjsPath);
1803
+ const jsPath = (0, import_path4.join)(root, "kbach.config.js");
1804
+ if (!(0, import_fs3.existsSync)(jsPath)) return void 0;
1805
+ try {
1806
+ return requireConfigModule(root, jsPath);
1807
+ } catch (err) {
1808
+ if (!isEsmRequireFailure(err)) throw err;
1809
+ return importConfigModule(jsPath);
1810
+ }
1811
+ }
1812
+ async function resolveEffectiveTheme(root, options) {
1792
1813
  if (options.theme) return options.theme;
1793
1814
  if (options.config) return resolveKbachConfig(options.config);
1794
- const discovered = loadConfigFile(root);
1815
+ const discovered = await loadConfigFile(root);
1795
1816
  return discovered ? resolveKbachConfig(discovered) : defaultTheme;
1796
1817
  }
1797
1818
  function kbach(options = {}) {
@@ -1826,9 +1847,9 @@ function kbach(options = {}) {
1826
1847
  return {
1827
1848
  name: "kbach",
1828
1849
  enforce: "pre",
1829
- configResolved(resolved) {
1850
+ async configResolved(resolved) {
1830
1851
  root = resolved.root;
1831
- theme = resolveEffectiveTheme(root, options);
1852
+ theme = await resolveEffectiveTheme(root, options);
1832
1853
  engine = createKbachStaticCssEngine({ root, theme, themeJson: JSON.stringify(theme), includeDirs, safelist });
1833
1854
  mainCSSFilePath = findMainCSSFile(root, includeDirs, options.cssFile);
1834
1855
  },
@@ -5,7 +5,7 @@ import {
5
5
  kbach,
6
6
  loadConfigFile,
7
7
  resolveEffectiveTheme
8
- } from "./chunk-3E26VMLA.mjs";
8
+ } from "./chunk-7JBSTM5D.mjs";
9
9
  import "./chunk-NKR3PSWO.mjs";
10
10
  import "./chunk-N5HCQIBB.mjs";
11
11
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kbach/react",
3
- "version": "1.0.0-beta.8",
3
+ "version": "1.0.0-beta.9",
4
4
  "description": "A utility-first styling engine for React, powered by a real Rust/WASM core — Tailwind CSS v4 feature parity with Kbach's own color palette.",
5
5
  "keywords": ["css", "react", "tailwind", "utility-first", "wasm", "styling"],
6
6
  "license": "MIT",