load-oxfmt-config 0.8.0 → 0.9.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/README.md CHANGED
@@ -5,12 +5,12 @@
5
5
  [![NPM DOWNLOADS](https://img.shields.io/npm/dy/load-oxfmt-config.svg)](https://www.npmjs.com/package/load-oxfmt-config)
6
6
  [![LICENSE](https://img.shields.io/github/license/ntnyq/load-oxfmt-config.svg)](https://github.com/ntnyq/load-oxfmt-config/blob/main/LICENSE)
7
7
 
8
- > Load and resolve oxfmt configuration files and merge supported `.editorconfig` settings for [oxfmt](https://oxc.rs/docs/guide/usage/formatter.html).
8
+ > Load and resolve oxfmt configuration files, including explicit JS/TS config paths, and merge supported `.editorconfig` settings for [oxfmt](https://oxc.rs/docs/guide/usage/formatter.html).
9
9
 
10
10
  ## Features
11
11
 
12
12
  - 🔍 **Auto-discovery** - Automatically searches for config files in current and parent directories
13
- - 📦 **Multiple formats** - Supports `.oxfmtrc.json`, `.oxfmtrc.jsonc`, and `oxfmt.config.ts`
13
+ - 📦 **Multiple formats** - Auto-discovers `.oxfmtrc.json`, `.oxfmtrc.jsonc`, and `oxfmt.config.ts`, and also supports explicit `.js` / `.mjs` / `.cjs` / `.mts` / `.cts` config paths
14
14
  - 🧩 **EditorConfig fallback** - Merges supported `.editorconfig` fields into the returned oxfmt config result
15
15
  - 🚫 **Ignore resolution** - Resolves ignore status with oxfmt CLI-like global + config-scoped semantics
16
16
  - ⚡ **Built-in caching** - Caches both file resolution and parsed configs for optimal performance
@@ -31,6 +31,8 @@ yarn add load-oxfmt-config
31
31
  pnpm add load-oxfmt-config
32
32
  ```
33
33
 
34
+ > `oxfmt` is a peer dependency and should be installed alongside this package.
35
+
34
36
  ## Usage
35
37
 
36
38
  ### Basic Usage
@@ -189,7 +191,16 @@ Option fields:
189
191
  - **Type:** `string`
190
192
  - **Default:** `process.cwd()`
191
193
 
192
- Current working directory to start searching for config files. The loader will walk up from this directory to find a config file.
194
+ Current working directory for config resolution.
195
+ By default config discovery starts here, unless `filepath` is provided.
196
+
197
+ #### `filepath`
198
+
199
+ - **Type:** `string`
200
+ - **Default:** `undefined`
201
+
202
+ Target file path for nested config resolution.
203
+ When provided (and `configPath` is not set), config discovery starts from `dirname(filepath)` and walks upward to match oxfmt per-file semantics.
193
204
 
194
205
  #### `configPath`
195
206
 
@@ -202,6 +213,14 @@ Explicit path to the config file:
202
213
  - **Absolute path:** Used as-is
203
214
  - **When provided:** Skips auto-discovery and uses this path directly
204
215
 
216
+ #### `disableNestedConfig`
217
+
218
+ - **Type:** `boolean`
219
+ - **Default:** `false`
220
+
221
+ Disable nested config lookup.
222
+ When `true`, config discovery is anchored to `cwd` (or explicit `configPath`) instead of `filepath`.
223
+
205
224
  #### `useCache`
206
225
 
207
226
  - **Type:** `boolean`
@@ -222,7 +241,9 @@ Set to `false` to force reload from disk on every call.
222
241
 
223
242
  Control how `.editorconfig` files are read and merged:
224
243
 
225
- - **`true`** — Read and merge the nearest `.editorconfig`, walking up from the config file's directory (or `cwd` when no config path is given).
244
+ - **`true`** — Read and merge the nearest `.editorconfig`, walking up from the config-discovery start directory:
245
+ - `dirname(filepath)` when nested lookup is enabled and `filepath` is provided
246
+ - otherwise `cwd`
226
247
  - **`false`** — Disable `.editorconfig` reading entirely.
227
248
  - **`EditorconfigOption`** — Enable with additional settings:
228
249
 
@@ -343,7 +364,7 @@ When `false`, `isOxfmtIgnored()` only applies global ignore and skips config loa
343
364
 
344
365
  When `configPath` is not provided, the loader automatically searches for config files:
345
366
 
346
- 1. **Search order:** Starts from `cwd` and walks up to parent directories
367
+ 1. **Search order:** Starts from `dirname(filepath)` when `filepath` is provided **and nested lookup is enabled**; otherwise starts from `cwd`, then walks up to parent directories
347
368
  2. **Supported filenames:**
348
369
  - `.oxfmtrc.json`
349
370
  - `.oxfmtrc.jsonc`
@@ -351,7 +372,7 @@ When `configPath` is not provided, the loader automatically searches for config
351
372
  3. **Stops when:**
352
373
  - A valid config file is found
353
374
  - Reaches the filesystem root
354
- 4. **EditorConfig:** The nearest `.editorconfig` is also resolved and merged into the returned result
375
+ 4. **EditorConfig:** The nearest `.editorconfig` is resolved from the same start directory and merged into the returned result
355
376
  5. **Returns:** Empty object `{}` if no config file is found
356
377
 
357
378
  ## Supported Config Formats
@@ -443,6 +464,7 @@ Notes:
443
464
  - default: nearest config from target file directory upward
444
465
  - `disableNestedConfig: true`: resolve from `cwd` only
445
466
  - `configPath`: also disables nested lookup (same intent as CLI `-c`)
467
+ - invalid nested config only fails files that resolve to that config (no project-wide pre-scan)
446
468
 
447
469
  ## Precedence
448
470
 
@@ -468,7 +490,7 @@ try {
468
490
  const result = await loadOxfmtConfig()
469
491
  console.log(result.config)
470
492
  } catch (error) {
471
- // Thrown when config file exists but contains invalid JSON/JSONC
493
+ // Thrown when a resolved config file cannot be parsed or loaded
472
494
  console.error('Failed to parse oxfmt config:', error.message)
473
495
  }
474
496
  ```
@@ -483,6 +505,7 @@ The caching system maintains two separate caches:
483
505
  **Cache keys are based on:**
484
506
 
485
507
  - `cwd` + `configPath` for path resolution
508
+ - or `dirname(filepath)` + `configPath` when `filepath` is provided and nested lookup is enabled
486
509
  - Resolved oxfmt path and resolved `.editorconfig` path for config content
487
510
 
488
511
  **Cache invalidation:**
package/dist/index.d.mts CHANGED
@@ -48,6 +48,19 @@ interface LoadOxfmtConfigOptions {
48
48
  * Current working directory
49
49
  */
50
50
  cwd?: string;
51
+ /**
52
+ * File path being formatted. When provided (and `configPath` is not set),
53
+ * config discovery starts from this file's directory to match oxfmt nested
54
+ * config behavior.
55
+ */
56
+ filepath?: string;
57
+ /**
58
+ * Disable nested config lookup.
59
+ * When true, config discovery is anchored to `cwd` (or explicit `configPath`).
60
+ *
61
+ * @default false
62
+ */
63
+ disableNestedConfig?: boolean;
51
64
  /**
52
65
  * Whether to use cache
53
66
  */
package/dist/index.mjs CHANGED
@@ -399,15 +399,17 @@ const configCache = /* @__PURE__ */ new Map();
399
399
  async function loadOxfmtConfig(options = {}) {
400
400
  const useCache = options.useCache !== false;
401
401
  const cwd = resolve(options.cwd || process.cwd());
402
+ const filepath = options.filepath ? resolve(cwd, options.filepath) : void 0;
403
+ const configLookupCwd = options.configPath || options.disableNestedConfig || !filepath ? cwd : dirname(filepath);
402
404
  const editorconfig = options.editorconfig ?? true;
403
405
  const useEditorconfig = editorconfig !== false;
404
406
  const isEditorconfigOptionsObject = useEditorconfig && isObject(editorconfig);
405
407
  const onlyCwd = isEditorconfigOptionsObject ? editorconfig.onlyCwd ?? false : false;
406
408
  const editorconfigCwd = isEditorconfigOptionsObject && editorconfig.cwd ? resolve(editorconfig.cwd) : void 0;
407
- const resolveKey = getResolveCacheKey(cwd, options.configPath);
408
- const editorconfigSearchDir = editorconfigCwd || getEditorconfigSearchDir(cwd, options.configPath);
409
+ const resolveKey = getResolveCacheKey(configLookupCwd, options.configPath);
410
+ const editorconfigSearchDir = editorconfigCwd || getEditorconfigSearchDir(configLookupCwd, options.configPath);
409
411
  const editorconfigResolveKey = editorconfigCwd ? getEditorconfigResolveCacheKey(`${editorconfigCwd}::${options.configPath || ""}`) : getEditorconfigResolveCacheKey(resolveKey);
410
- const resolvedPath = useCache ? await cachePromise(resolveCache, resolveKey, () => resolveOxfmtrcPath(cwd, options.configPath)) : await resolveOxfmtrcPath(cwd, options.configPath);
412
+ const resolvedPath = useCache ? await cachePromise(resolveCache, resolveKey, () => resolveOxfmtrcPath(configLookupCwd, options.configPath)) : await resolveOxfmtrcPath(configLookupCwd, options.configPath);
411
413
  const editorconfigPath = useEditorconfig ? await (useCache ? cachePromise(resolveCache, editorconfigResolveKey, () => resolveEditorconfigPath(editorconfigSearchDir, onlyCwd)) : resolveEditorconfigPath(editorconfigSearchDir, onlyCwd)) : void 0;
412
414
  const anchorDir = dirname(resolvedPath || editorconfigPath || cwd);
413
415
  const loadTask = async () => {
@@ -647,7 +649,9 @@ async function isOxfmtIgnored(options) {
647
649
  }
648
650
  if (!loadConfigForIgnorePatterns) return { ignored: false };
649
651
  const configResult = await loadOxfmtConfig({
650
- cwd: options.configPath || options.disableNestedConfig ? cwd : dirname(filepath),
652
+ cwd,
653
+ filepath,
654
+ ...options.disableNestedConfig === true ? { disableNestedConfig: true } : {},
651
655
  ...options.configPath ? { configPath: options.configPath } : {},
652
656
  editorconfig: false,
653
657
  useCache
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "load-oxfmt-config",
3
- "version": "0.8.0",
4
- "description": "Load oxfmt config files and merge supported .editorconfig options.",
3
+ "version": "0.9.0",
4
+ "description": "Load and resolve oxfmt configuration files, including explicit JS/TS config paths, and merge supported `.editorconfig` settings for Oxfmt.",
5
5
  "keywords": [
6
6
  "editorconfig",
7
7
  "jsonc-parser",
@@ -48,20 +48,20 @@
48
48
  },
49
49
  "devDependencies": {
50
50
  "@ntnyq/tsconfig": "^3.1.0",
51
- "@types/node": "^25.7.0",
51
+ "@types/node": "^25.8.0",
52
52
  "@types/picomatch": "^4.0.3",
53
- "@typescript/native-preview": "^7.0.0-dev.20260511.1",
53
+ "@typescript/native-preview": "^7.0.0-dev.20260517.1",
54
54
  "bumpp": "^11.1.0",
55
55
  "husky": "^9.1.7",
56
56
  "nano-staged": "^1.0.2",
57
57
  "npm-run-all2": "^8.0.4",
58
- "oxfmt": "^0.49.0",
59
- "oxlint": "^1.64.0",
58
+ "oxfmt": "^0.50.0",
59
+ "oxlint": "^1.65.0",
60
60
  "tsdown": "^0.22.0",
61
61
  "vitest": "^4.1.6"
62
62
  },
63
63
  "peerDependencies": {
64
- "oxfmt": ">=0.49.0"
64
+ "oxfmt": ">=0.50.0"
65
65
  },
66
66
  "nano-staged": {
67
67
  "*.{js,ts,mjs,tsx}": "oxlint --fix",