load-oxfmt-config 0.2.0 → 0.3.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,13 @@
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 `.oxfmtrc.json(c)` configuration files for [oxfmt](https://oxc.rs/docs/guide/usage/formatter.html).
8
+ > Load and resolve oxfmt configuration files 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 both `.oxfmtrc.json` and `.oxfmtrc.jsonc` (JSON with comments)
13
+ - 📦 **Multiple formats** - Supports `.oxfmtrc.json`, `.oxfmtrc.jsonc`, and `oxfmt.config.ts`
14
+ - 🧩 **EditorConfig fallback** - Merges supported `.editorconfig` fields into the returned oxfmt config result
14
15
  - ⚡ **Built-in caching** - Caches both file resolution and parsed configs for optimal performance
15
16
  - 🎯 **TypeScript support** - Fully typed with comprehensive type definitions
16
17
  - 🛠️ **Flexible API** - Support explicit config paths or automatic discovery
@@ -38,11 +39,29 @@ Load config from current directory or parent directories:
38
39
  ```ts
39
40
  import { loadOxfmtConfig } from 'load-oxfmt-config'
40
41
 
41
- // Automatically searches for .oxfmtrc.json(c) in current and parent directories
42
+ // Automatically searches for oxfmt config files and the nearest .editorconfig
42
43
  const config = await loadOxfmtConfig()
43
44
  console.log(config) // { printWidth: 80, ... }
44
45
  ```
45
46
 
47
+ ### Merge With `.editorconfig`
48
+
49
+ ```ts
50
+ import { loadOxfmtConfig } from 'load-oxfmt-config'
51
+
52
+ const config = await loadOxfmtConfig({ cwd: '/path/to/project' })
53
+
54
+ // Returns one merged static config object
55
+ console.log(config)
56
+ // {
57
+ // tabWidth: 2,
58
+ // printWidth: 100,
59
+ // overrides: [
60
+ // { files: ['src/**/*.ts'], options: { printWidth: 120 } }
61
+ // ]
62
+ // }
63
+ ```
64
+
46
65
  ### Specify Working Directory
47
66
 
48
67
  ```ts
@@ -70,6 +89,28 @@ const config = await loadOxfmtConfig({
70
89
  })
71
90
  ```
72
91
 
92
+ ### Disable `.editorconfig`
93
+
94
+ ```ts
95
+ import { loadOxfmtConfig } from 'load-oxfmt-config'
96
+
97
+ // Skip .editorconfig reading entirely
98
+ const config = await loadOxfmtConfig({
99
+ editorconfig: false,
100
+ })
101
+ ```
102
+
103
+ ### Limit `.editorconfig` to `cwd`
104
+
105
+ ```ts
106
+ import { loadOxfmtConfig } from 'load-oxfmt-config'
107
+
108
+ // Only look in the cwd directory itself, no upward traversal
109
+ const config = await loadOxfmtConfig({
110
+ editorconfig: { onlyCwd: true },
111
+ })
112
+ ```
113
+
73
114
  ### Disable Caching
74
115
 
75
116
  ```ts
@@ -95,13 +136,13 @@ console.log(configPath) // '/path/to/.oxfmtrc.json' or undefined
95
136
 
96
137
  ### `loadOxfmtConfig(options?)`
97
138
 
98
- Load and parse oxfmt configuration file.
139
+ Load and parse oxfmt configuration files, then merge supported `.editorconfig` fields into the returned result.
99
140
 
100
141
  **Parameters:**
101
142
 
102
143
  - `options` - Optional configuration object
103
144
 
104
- **Returns:** `Promise<FormatOptions>` - Parsed oxfmt configuration object. Returns empty object `{}` if no config file is found.
145
+ **Returns:** `Promise<FormatOptions>` - Parsed and merged oxfmt configuration object. Returns empty object `{}` if no supported config file is found.
105
146
 
106
147
  **Throws:** Error if config file exists but cannot be parsed.
107
148
 
@@ -151,6 +192,21 @@ Enable in-memory caching for both path resolution and parsed config contents. Wh
151
192
 
152
193
  Set to `false` to force reload from disk on every call.
153
194
 
195
+ ### `editorconfig`
196
+
197
+ - **Type:** `boolean | EditorconfigOption`
198
+ - **Default:** `true`
199
+
200
+ Control how `.editorconfig` files are read and merged:
201
+
202
+ - **`true`** — Read and merge the nearest `.editorconfig`, walking up from the config file's directory (or `cwd` when no config path is given).
203
+ - **`false`** — Disable `.editorconfig` reading entirely.
204
+ - **`EditorconfigOption`** — Enable with additional settings:
205
+
206
+ | Property | Type | Default | Description |
207
+ | --------- | --------- | ------- | --------------------------------------------------------------------------------- |
208
+ | `onlyCwd` | `boolean` | `false` | When `true`, only look for `.editorconfig` in `cwd` itself — no upward traversal. |
209
+
154
210
  ## Config File Discovery
155
211
 
156
212
  When `configPath` is not provided, the loader automatically searches for config files:
@@ -159,10 +215,14 @@ When `configPath` is not provided, the loader automatically searches for config
159
215
  2. **Supported filenames:**
160
216
  - `.oxfmtrc.json`
161
217
  - `.oxfmtrc.jsonc`
218
+
219
+ - `oxfmt.config.ts`
220
+
162
221
  3. **Stops when:**
163
222
  - A valid config file is found
164
223
  - Reaches the filesystem root
165
- 4. **Returns:** Empty object `{}` if no config file is found
224
+ 4. **EditorConfig:** The nearest `.editorconfig` is also resolved and merged into the returned result
225
+ 5. **Returns:** Empty object `{}` if no config file is found
166
226
 
167
227
  ## Supported Config Formats
168
228
 
@@ -191,10 +251,46 @@ JSON with comments support:
191
251
  /* Code style preferences */
192
252
  "useTabs": false,
193
253
  "semi": true,
194
- "singleQuote": true
254
+ "singleQuote": true,
195
255
  }
196
256
  ```
197
257
 
258
+ ### TypeScript (`oxfmt.config.ts`)
259
+
260
+ ```ts
261
+ export default {
262
+ printWidth: 100,
263
+ tabWidth: 2,
264
+ }
265
+ ```
266
+
267
+ ## `.editorconfig` Support
268
+
269
+ The loader reads the nearest `.editorconfig` file and maps the subset of fields that oxfmt supports:
270
+
271
+ - `end_of_line` → `endOfLine`
272
+ - `indent_style` → `useTabs`
273
+ - `indent_size` / `tab_width` → `tabWidth`
274
+ - `max_line_length` → `printWidth`
275
+ - `insert_final_newline` → `insertFinalNewline`
276
+
277
+ Glob sections such as `[*.ts]` are converted into returned `overrides` entries.
278
+
279
+ ## Precedence
280
+
281
+ The merged result follows this order:
282
+
283
+ 1. Root-level values from the nearest `.editorconfig`
284
+ 2. Root-level values from `.oxfmtrc.json`, `.oxfmtrc.jsonc`, or `oxfmt.config.ts`
285
+ 3. Overrides generated from `.editorconfig` sections
286
+ 4. Overrides declared directly in the oxfmt config file
287
+
288
+ This means explicit oxfmt config values always win over `.editorconfig` fallback values.
289
+
290
+ ## Limitations
291
+
292
+ `loadOxfmtConfig()` returns a static `OxfmtOptions` object. That means `.editorconfig` support is represented as a merged config shape, not as per-file runtime evaluation. In practice this works well for common root settings and section-based overrides, but it is not a full replacement for oxfmt's own file-by-file config resolution.
293
+
198
294
  ## Error Handling
199
295
 
200
296
  ```ts
@@ -218,7 +314,7 @@ The caching system maintains two separate caches:
218
314
  **Cache keys are based on:**
219
315
 
220
316
  - `cwd` + `configPath` for path resolution
221
- - Resolved file path for config content
317
+ - Resolved oxfmt path and resolved `.editorconfig` path for config content
222
318
 
223
319
  **Cache invalidation:**
224
320
 
package/dist/index.d.mts CHANGED
@@ -1,10 +1,22 @@
1
- import { FormatOptions } from "oxfmt";
1
+ import { FormatConfig } from "oxfmt";
2
2
 
3
3
  //#region src/types.d.ts
4
+ /**
5
+ * Object-form editorconfig option, enabling fine-grained control.
6
+ */
7
+ interface EditorconfigOption {
8
+ /**
9
+ * When `true`, only look for `.editorconfig` in the `cwd` directory itself
10
+ * (no upward traversal).
11
+ *
12
+ * @default false
13
+ */
14
+ onlyCwd?: boolean;
15
+ }
4
16
  /**
5
17
  * Format option override for a single matching rule
6
18
  */
7
- interface FormatOptionOverride {
19
+ interface OxfmtConfigOverride {
8
20
  /**
9
21
  * Glob patterns to match files
10
22
  */
@@ -16,7 +28,7 @@ interface FormatOptionOverride {
16
28
  /**
17
29
  * Format options to apply
18
30
  */
19
- options?: FormatOptions;
31
+ options?: FormatConfig;
20
32
  }
21
33
  interface Options {
22
34
  /**
@@ -31,11 +43,21 @@ interface Options {
31
43
  * Whether to use cache
32
44
  */
33
45
  useCache?: boolean;
46
+ /**
47
+ * Control `.editorconfig` reading.
48
+ * - `true` (default): read and merge `.editorconfig`, walking up from the config
49
+ * file's directory (or `cwd` when no config path is given).
50
+ * - `false`: disable `.editorconfig` reading entirely.
51
+ * - `EditorconfigOption`: enable with additional settings (e.g. `onlyCwd`).
52
+ *
53
+ * @default true
54
+ */
55
+ editorconfig?: boolean | EditorconfigOption;
34
56
  }
35
57
  /**
36
58
  * Final oxfmt options (including overrides)
37
59
  */
38
- interface OxfmtOptions extends FormatOptions {
60
+ interface OxfmtOptions extends FormatConfig {
39
61
  /**
40
62
  * Ignore files matching these glob patterns
41
63
  * Patterns are based on the location of the Oxfmt configuration file
@@ -44,8 +66,12 @@ interface OxfmtOptions extends FormatOptions {
44
66
  /**
45
67
  * Array of format option overrides
46
68
  */
47
- overrides?: FormatOptionOverride[];
69
+ overrides?: OxfmtConfigOverride[];
48
70
  }
71
+ /**
72
+ * @deprecated Use `OxfmtConfigOverride` instead
73
+ */
74
+ type FormatOptionOverride = OxfmtConfigOverride;
49
75
  //#endregion
50
76
  //#region src/core.d.ts
51
77
  /**
@@ -73,4 +99,4 @@ declare function resolveOxfmtrcPath(cwd: string, configPath?: string): Promise<s
73
99
  */
74
100
  declare function loadOxfmtConfig(options?: Options): Promise<OxfmtOptions>;
75
101
  //#endregion
76
- export { FormatOptionOverride, Options, OxfmtOptions, loadOxfmtConfig, resolveOxfmtrcPath };
102
+ export { EditorconfigOption, FormatOptionOverride, Options, OxfmtConfigOverride, OxfmtOptions, loadOxfmtConfig, resolveOxfmtrcPath };
package/dist/index.mjs CHANGED
@@ -1,13 +1,128 @@
1
1
  import { readFile, stat } from "node:fs/promises";
2
- import { isAbsolute, join } from "node:path";
2
+ import { dirname, isAbsolute, join, relative } from "node:path";
3
3
  import process from "node:process";
4
+ import { interopDefault } from "@ntnyq/utils";
4
5
  import { parse } from "jsonc-parser";
6
+ import { parseBuffer } from "editorconfig";
5
7
  //#region src/constants.ts
6
8
  /**
7
9
  * Supported configuration files for oxfmt.
8
10
  * @see https://oxc.rs/docs/guide/usage/formatter/config.html#oxfmtrc-json-c
9
11
  */
10
- const OXFMT_CONFIG_FILES = [".oxfmtrc.json", ".oxfmtrc.jsonc"];
12
+ const OXFMT_CONFIG_FILES = [
13
+ ".oxfmtrc.json",
14
+ ".oxfmtrc.jsonc",
15
+ "oxfmt.config.ts"
16
+ ];
17
+ /**
18
+ * Supported EditorConfig filename.
19
+ */
20
+ const EDITORCONFIG_FILE = ".editorconfig";
21
+ /**
22
+ * Sections that apply globally and can be merged into root-level oxfmt options.
23
+ */
24
+ const EDITORCONFIG_GLOBAL_SECTION_NAMES = ["*", "**"];
25
+ //#endregion
26
+ //#region src/editorconfig.ts
27
+ function getEditorconfigResolveCacheKey(resolveKey) {
28
+ return `editorconfig::${resolveKey}`;
29
+ }
30
+ function getEditorconfigSearchDir(cwd, configPath) {
31
+ if (!configPath) return cwd;
32
+ return dirname(isAbsolute(configPath) ? configPath : join(cwd, configPath));
33
+ }
34
+ function mergeRootOptions(oxfmtConfig, editorconfigRootOptions) {
35
+ return {
36
+ ...editorconfigRootOptions,
37
+ ...oxfmtConfig
38
+ };
39
+ }
40
+ function mergeOverrides(oxfmtOverrides, editorconfigOverrides) {
41
+ const mergedOverrides = [...editorconfigOverrides, ...oxfmtOverrides || []];
42
+ return mergedOverrides.length > 0 ? mergedOverrides : void 0;
43
+ }
44
+ async function resolveEditorconfigPath(startDir, onlyCwd = false) {
45
+ let currentDir = startDir;
46
+ while (true) {
47
+ const editorconfigPath = join(currentDir, EDITORCONFIG_FILE);
48
+ try {
49
+ if ((await stat(editorconfigPath)).isFile()) return editorconfigPath;
50
+ } catch {}
51
+ if (onlyCwd) break;
52
+ const parentDir = join(currentDir, "..");
53
+ if (parentDir === currentDir) break;
54
+ currentDir = parentDir;
55
+ }
56
+ }
57
+ function toPosixPath(path) {
58
+ return path.replaceAll("\\", "/");
59
+ }
60
+ function isEditorconfigGlobalSection(sectionName) {
61
+ return Boolean(sectionName && EDITORCONFIG_GLOBAL_SECTION_NAMES.includes(sectionName));
62
+ }
63
+ function parseEditorconfigBoolean(value) {
64
+ if (value === "true") return true;
65
+ if (value === "false") return false;
66
+ }
67
+ function parseEditorconfigEndOfLine(value) {
68
+ if (value === "lf" || value === "crlf" || value === "cr") return value;
69
+ }
70
+ function parseEditorconfigTabWidth(section) {
71
+ const indentSize = section["indent_size"];
72
+ const tabWidth = section["tab_width"];
73
+ if (indentSize && indentSize !== "unset" && indentSize !== "tab") {
74
+ const parsedIndentSize = Number(indentSize);
75
+ if (Number.isFinite(parsedIndentSize)) return parsedIndentSize;
76
+ }
77
+ if (tabWidth && tabWidth !== "unset") {
78
+ const parsedTabWidth = Number(tabWidth);
79
+ if (Number.isFinite(parsedTabWidth)) return parsedTabWidth;
80
+ }
81
+ }
82
+ function mapEditorconfigSectionToOptions(section) {
83
+ const options = {};
84
+ const endOfLine = parseEditorconfigEndOfLine(section["end_of_line"]);
85
+ if (endOfLine) options.endOfLine = endOfLine;
86
+ if (section["indent_style"] === "tab") options.useTabs = true;
87
+ else if (section["indent_style"] === "space") options.useTabs = false;
88
+ const tabWidth = parseEditorconfigTabWidth(section);
89
+ if (typeof tabWidth === "number") options.tabWidth = tabWidth;
90
+ if (section["max_line_length"] && section["max_line_length"] !== "unset") {
91
+ const parsedPrintWidth = Number(section["max_line_length"]);
92
+ if (Number.isFinite(parsedPrintWidth)) options.printWidth = parsedPrintWidth;
93
+ }
94
+ const insertFinalNewline = parseEditorconfigBoolean(section["insert_final_newline"]);
95
+ if (typeof insertFinalNewline === "boolean") options.insertFinalNewline = insertFinalNewline;
96
+ return options;
97
+ }
98
+ function rebaseEditorconfigPattern(pattern, editorconfigDir, anchorDir) {
99
+ const relativePrefix = toPosixPath(relative(anchorDir, editorconfigDir));
100
+ if (!relativePrefix || relativePrefix === ".") return pattern;
101
+ return `${relativePrefix}/${pattern.replace(/^\//, "")}`;
102
+ }
103
+ async function readEditorconfigFromFile(editorconfigPath, anchorDir) {
104
+ const parsedSections = parseBuffer(await readFile(editorconfigPath));
105
+ const editorconfigDir = dirname(editorconfigPath);
106
+ const rootOptions = {};
107
+ const overrides = [];
108
+ for (const [sectionName, sectionBody] of parsedSections) {
109
+ if (!sectionName) continue;
110
+ const mappedOptions = mapEditorconfigSectionToOptions(sectionBody);
111
+ if (Object.keys(mappedOptions).length === 0) continue;
112
+ if (isEditorconfigGlobalSection(sectionName)) {
113
+ Object.assign(rootOptions, mappedOptions);
114
+ continue;
115
+ }
116
+ overrides.push({
117
+ files: [rebaseEditorconfigPattern(sectionName, editorconfigDir, anchorDir)],
118
+ options: mappedOptions
119
+ });
120
+ }
121
+ return {
122
+ overrides,
123
+ rootOptions
124
+ };
125
+ }
11
126
  //#endregion
12
127
  //#region src/core.ts
13
128
  const resolveCache = /* @__PURE__ */ new Map();
@@ -34,11 +149,12 @@ function cachePromise(cache, key, factory) {
34
149
  * Build a cache key for config content; prefixes missing entries with `missing:`.
35
150
  *
36
151
  * @param resolvedPath - Resolved config path or undefined when missing.
152
+ * @param editorconfigPath - Resolved editorconfig path or undefined when missing.
37
153
  * @param resolveKey - Key used for path resolution caching.
38
154
  * @returns Cache key for config content.
39
155
  */
40
- function getConfigCacheKey(resolvedPath, resolveKey) {
41
- return resolvedPath || `missing:${resolveKey}`;
156
+ function getConfigCacheKey(resolvedPath, editorconfigPath, resolveKey) {
157
+ return `${resolvedPath || `missing-oxfmt:${resolveKey}`}::${editorconfigPath || `missing-editorconfig:${resolveKey}`}`;
42
158
  }
43
159
  /**
44
160
  * Resolve the oxfmt config file path.
@@ -75,12 +191,16 @@ function getResolveCacheKey(cwd, configPath) {
75
191
  return `${cwd}::${configPath || ""}`;
76
192
  }
77
193
  /**
78
- * Read and parse config file, supporting JSON and JSONC.
194
+ * Read and parse config file, supporting JSON, JSONC, and TypeScript/JavaScript.
79
195
  *
80
196
  * @param resolvedPath - Absolute path to the config file.
81
197
  * @returns Parsed OxfmtOptions object.
82
198
  */
83
199
  async function readConfigFromFile(resolvedPath) {
200
+ if (resolvedPath.endsWith(".ts")) {
201
+ const mod = await (await interopDefault(import("jiti")))(import.meta.url).import(resolvedPath);
202
+ return mod["default"] ?? mod;
203
+ }
84
204
  const content = await readFile(resolvedPath, "utf8");
85
205
  if (resolvedPath.endsWith(".jsonc")) return parse(content);
86
206
  return JSON.parse(content);
@@ -101,17 +221,35 @@ async function readConfigFromFile(resolvedPath) {
101
221
  async function loadOxfmtConfig(options = {}) {
102
222
  const useCache = options.useCache !== false;
103
223
  const cwd = options.cwd || process.cwd();
224
+ const editorconfig = options.editorconfig ?? true;
225
+ const useEditorconfig = editorconfig !== false;
226
+ const onlyCwd = useEditorconfig && typeof editorconfig === "object" ? editorconfig.onlyCwd ?? false : false;
104
227
  const resolveKey = getResolveCacheKey(cwd, options.configPath);
228
+ const editorconfigSearchDir = getEditorconfigSearchDir(cwd, options.configPath);
229
+ const editorconfigResolveKey = getEditorconfigResolveCacheKey(resolveKey);
105
230
  const resolvedPath = useCache ? await cachePromise(resolveCache, resolveKey, () => resolveOxfmtrcPath(cwd, options.configPath)) : await resolveOxfmtrcPath(cwd, options.configPath);
106
- if (!resolvedPath) {
231
+ const editorconfigPath = useEditorconfig ? await (useCache ? cachePromise(resolveCache, editorconfigResolveKey, () => resolveEditorconfigPath(editorconfigSearchDir, onlyCwd)) : resolveEditorconfigPath(editorconfigSearchDir, onlyCwd)) : void 0;
232
+ const anchorDir = dirname(resolvedPath || editorconfigPath || cwd);
233
+ const loadTask = async () => {
234
+ const oxfmtConfig = resolvedPath ? await readConfigFromFile(resolvedPath).catch((error) => {
235
+ throw new Error(`Failed to parse oxfmt configuration file at ${resolvedPath}: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
236
+ }) : {};
237
+ if (!editorconfigPath) return oxfmtConfig;
238
+ const editorconfigData = await readEditorconfigFromFile(editorconfigPath, anchorDir);
239
+ const mergedConfig = mergeRootOptions(oxfmtConfig, editorconfigData.rootOptions);
240
+ const mergedOverrides = mergeOverrides(oxfmtConfig.overrides, editorconfigData.overrides);
241
+ if (!mergedOverrides) return mergedConfig;
242
+ return {
243
+ ...mergedConfig,
244
+ overrides: mergedOverrides
245
+ };
246
+ };
247
+ if (!resolvedPath && !editorconfigPath) {
107
248
  if (!useCache) return {};
108
- return cachePromise(configCache, getConfigCacheKey(resolvedPath, resolveKey), () => Promise.resolve({}));
249
+ return cachePromise(configCache, getConfigCacheKey(resolvedPath, editorconfigPath, resolveKey), () => Promise.resolve({}));
109
250
  }
110
- const loadTask = () => readConfigFromFile(resolvedPath).catch((error) => {
111
- throw new Error(`Failed to parse oxfmt configuration file at ${resolvedPath}: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
112
- });
113
251
  if (!useCache) return loadTask();
114
- return cachePromise(configCache, getConfigCacheKey(resolvedPath, resolveKey), loadTask);
252
+ return cachePromise(configCache, getConfigCacheKey(resolvedPath, editorconfigPath, resolveKey), loadTask);
115
253
  }
116
254
  //#endregion
117
255
  export { loadOxfmtConfig, resolveOxfmtrcPath };
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "load-oxfmt-config",
3
- "version": "0.2.0",
4
- "description": "Load .oxfmtrc.json(c) for oxfmt.",
3
+ "version": "0.3.0",
4
+ "description": "Load oxfmt config files and merge supported .editorconfig options.",
5
5
  "keywords": [
6
+ "editorconfig",
6
7
  "jsonc-parser",
7
8
  "load-config",
8
9
  "load-oxfmt-config",
@@ -38,23 +39,26 @@
38
39
  "access": "public"
39
40
  },
40
41
  "dependencies": {
42
+ "@ntnyq/utils": "^0.11.2",
43
+ "editorconfig": "^3.0.2",
44
+ "jiti": "^2.6.1",
41
45
  "jsonc-parser": "^3.3.1"
42
46
  },
43
47
  "devDependencies": {
44
48
  "@ntnyq/tsconfig": "^3.1.0",
45
- "@types/node": "^25.4.0",
46
- "@typescript/native-preview": "^7.0.0-dev.20260312.1",
47
- "bumpp": "^10.4.1",
49
+ "@types/node": "^25.5.0",
50
+ "@typescript/native-preview": "^7.0.0-dev.20260326.1",
51
+ "bumpp": "^11.0.1",
48
52
  "husky": "^9.1.7",
49
53
  "nano-staged": "^0.9.0",
50
54
  "npm-run-all2": "^8.0.4",
51
- "oxfmt": "^0.39.0",
52
- "oxlint": "^1.54.0",
53
- "tsdown": "^0.21.2",
54
- "vitest": "^4.0.18"
55
+ "oxfmt": "^0.42.0",
56
+ "oxlint": "^1.57.0",
57
+ "tsdown": "^0.21.5",
58
+ "vitest": "^4.1.2"
55
59
  },
56
60
  "peerDependencies": {
57
- "oxfmt": "0.x"
61
+ "oxfmt": ">=0.41.0"
58
62
  },
59
63
  "nano-staged": {
60
64
  "*.{js,ts,mjs,tsx}": "oxlint --fix",