@mkrz/oxlint-config 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,624 @@
1
+ import { defineConfig as defineConfig$1 } from "oxlint";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ //#region src/configs/ignore-patterns.ts
6
+ /**
7
+ * Build output, caches, and lockfiles that should never be linted.
8
+ *
9
+ * Oxlint only honors `ignorePatterns` on the root config; patterns inside an
10
+ * extended config are dropped. Spread this list into the root config.
11
+ */
12
+ const ignorePatterns = [
13
+ "**/__snapshots__/**",
14
+ "**/.next/**",
15
+ "**/.turbo/**",
16
+ "**/*.d.ts",
17
+ "**/*.min.*",
18
+ "**/CHANGELOG.md",
19
+ "**/coverage/**",
20
+ "**/dist/**",
21
+ "**/node_modules/**",
22
+ "**/out/**",
23
+ "**/output/**",
24
+ "**/package-lock.json",
25
+ "**/pnpm-lock.yaml",
26
+ "**/yarn.lock"
27
+ ];
28
+ //#endregion
29
+ //#region src/configs/base.ts
30
+ /**
31
+ * Fast defaults for TypeScript projects.
32
+ *
33
+ * Rule policy: the `correctness` and `suspicious` categories are enabled at
34
+ * error severity for every enabled plugin, so rules in those categories are
35
+ * not repeated here. The explicit list below only holds rules outside those
36
+ * categories, rules that need options, and rules turned off for TypeScript
37
+ * because the compiler already reports them.
38
+ */
39
+ const base = {
40
+ plugins: [
41
+ "import",
42
+ "oxc",
43
+ "promise",
44
+ "typescript",
45
+ "unicorn"
46
+ ],
47
+ categories: {
48
+ correctness: "error",
49
+ suspicious: "error"
50
+ },
51
+ env: {
52
+ builtin: true,
53
+ node: true
54
+ },
55
+ options: { reportUnusedDisableDirectives: "error" },
56
+ rules: {
57
+ "mkrz/no-chained-type-assertions": "error",
58
+ "mkrz/no-known-value-widening": "error",
59
+ "mkrz/no-let": "error",
60
+ "mkrz/no-module-mocking": "error",
61
+ "mkrz/no-reflect-apply": "error",
62
+ "mkrz/no-reflect-get": "error",
63
+ "mkrz/no-type-assertion": "error",
64
+ "mkrz/no-unknown-parameters": "error",
65
+ "mkrz/no-unknown-returns": "error",
66
+ "mkrz/no-unknown-type-aliases": "error",
67
+ "mkrz/no-unsafe-dictionary-type": "error",
68
+ "mkrz/no-widen-then-assert": "error",
69
+ "mkrz/padding-line-between-statements": [
70
+ "error",
71
+ {
72
+ blankLine: "always",
73
+ prev: {
74
+ selector: "*",
75
+ lineMode: "multiline"
76
+ },
77
+ next: "*"
78
+ },
79
+ {
80
+ blankLine: "always",
81
+ prev: "block-like",
82
+ next: "*"
83
+ },
84
+ {
85
+ blankLine: "always",
86
+ prev: "*",
87
+ next: "return"
88
+ },
89
+ {
90
+ blankLine: "any",
91
+ prev: "import",
92
+ next: "import"
93
+ }
94
+ ],
95
+ "array-callback-return": "error",
96
+ complexity: ["error", { max: 10 }],
97
+ curly: ["error", "all"],
98
+ "default-case-last": "error",
99
+ eqeqeq: [
100
+ "error",
101
+ "always",
102
+ { null: "ignore" }
103
+ ],
104
+ "import/consistent-type-specifier-style": ["error", "prefer-inline"],
105
+ "import/no-duplicates": "error",
106
+ "import/no-relative-parent-imports": "error",
107
+ "no-alert": "error",
108
+ "no-array-constructor": "error",
109
+ "no-case-declarations": "error",
110
+ "no-empty": "error",
111
+ "no-empty-function": "error",
112
+ "no-fallthrough": "error",
113
+ "no-new-wrappers": "error",
114
+ "no-promise-executor-return": "error",
115
+ "no-prototype-builtins": "error",
116
+ "no-self-compare": "error",
117
+ "no-template-curly-in-string": "error",
118
+ "no-unreachable-loop": "error",
119
+ "no-unused-vars": ["error", {
120
+ argsIgnorePattern: "^_",
121
+ caughtErrorsIgnorePattern: "^_",
122
+ varsIgnorePattern: "^_"
123
+ }],
124
+ "no-var": "error",
125
+ "no-warning-comments": ["error", { terms: ["@nocommit"] }],
126
+ "oxc/bad-bitwise-operator": "error",
127
+ "oxc/no-accumulating-spread": "error",
128
+ "prefer-const": "error",
129
+ "prefer-object-has-own": "error",
130
+ "promise/no-return-wrap": "error",
131
+ "typescript/adjacent-overload-signatures": "error",
132
+ "typescript/array-type": "error",
133
+ "typescript/ban-ts-comment": "error",
134
+ "typescript/ban-tslint-comment": "error",
135
+ "typescript/class-literal-property-style": "error",
136
+ "typescript/consistent-generic-constructors": "error",
137
+ "typescript/consistent-indexed-object-style": "error",
138
+ "typescript/consistent-type-definitions": ["error", "type"],
139
+ "typescript/consistent-type-imports": ["error", {
140
+ fixStyle: "inline-type-imports",
141
+ prefer: "type-imports"
142
+ }],
143
+ "typescript/no-empty-object-type": "error",
144
+ "typescript/no-explicit-any": "error",
145
+ "typescript/no-inferrable-types": "error",
146
+ "typescript/no-namespace": "error",
147
+ "typescript/no-non-null-asserted-nullish-coalescing": "error",
148
+ "typescript/no-non-null-assertion": "error",
149
+ "typescript/no-require-imports": "error",
150
+ "typescript/no-unnecessary-type-assertion": "off",
151
+ "typescript/no-unsafe-function-type": "error",
152
+ "typescript/no-unsafe-type-assertion": "off",
153
+ "typescript/prefer-for-of": "error",
154
+ "typescript/prefer-function-type": "error",
155
+ "unicorn/no-abusive-eslint-disable": "error",
156
+ "unicorn/no-magic-array-flat-depth": "error",
157
+ "unicorn/no-unnecessary-slice-end": "error",
158
+ "unicorn/no-useless-promise-resolve-reject": "error",
159
+ "unicorn/prefer-array-flat-map": "error",
160
+ "unicorn/prefer-array-some": "error",
161
+ "unicorn/prefer-date-now": "error",
162
+ "unicorn/prefer-node-protocol": "error",
163
+ "unicorn/prefer-number-properties": "error",
164
+ "unicorn/throw-new-error": "error"
165
+ },
166
+ overrides: [{
167
+ files: [
168
+ "**/*.cts",
169
+ "**/*.mts",
170
+ "**/*.ts",
171
+ "**/*.tsx"
172
+ ],
173
+ rules: {
174
+ "constructor-super": "off",
175
+ "getter-return": "off",
176
+ "no-class-assign": "off",
177
+ "no-const-assign": "off",
178
+ "no-dupe-class-members": "off",
179
+ "no-dupe-keys": "off",
180
+ "no-func-assign": "off",
181
+ "no-import-assign": "off",
182
+ "no-new-native-nonconstructor": "off",
183
+ "no-obj-calls": "off",
184
+ "no-setter-return": "off",
185
+ "no-this-before-super": "off",
186
+ "no-unreachable": "off",
187
+ "no-unsafe-negation": "off",
188
+ "no-with": "off",
189
+ "prefer-rest-params": "error",
190
+ "prefer-spread": "error"
191
+ }
192
+ }, {
193
+ files: ["**/*.cjs"],
194
+ rules: { "typescript/no-require-imports": "off" }
195
+ }]
196
+ };
197
+ //#endregion
198
+ //#region src/configs/monorepo.ts
199
+ const message = "Move shared code into a package and import it from there instead.";
200
+ /**
201
+ * Overrides for the apps/packages layout.
202
+ *
203
+ * Relative imports that climb out of a package are already rejected by
204
+ * `import/no-relative-parent-imports` in `base`, so only workspace package
205
+ * names need a rule here.
206
+ */
207
+ function monorepo({ appsPath = ["apps/**"], packagesPath = ["packages/**"], appPackages = [] } = {}) {
208
+ const packageRules = { "mkrz/package-disable-policy": "error" };
209
+ if (appPackages.length > 0) {
210
+ const patterns = appPackages.flatMap((name) => [name, `${name}/**`]);
211
+ packageRules["mkrz/no-app-requires"] = ["error", patterns];
212
+ packageRules["no-restricted-imports"] = ["error", { patterns: [{
213
+ group: patterns,
214
+ message
215
+ }] }];
216
+ }
217
+ return { overrides: [{
218
+ files: appsPath,
219
+ rules: { "mkrz/no-oxlint-disable": "error" }
220
+ }, {
221
+ files: packagesPath,
222
+ rules: packageRules
223
+ }] };
224
+ }
225
+ //#endregion
226
+ //#region src/configs/plugin-specifiers.ts
227
+ const modulePath = fileURLToPath(import.meta.url);
228
+ const moduleExtension = path.extname(modulePath);
229
+ const pluginCandidates = [`../plugin/index${moduleExtension}`, `./plugin/index${moduleExtension}`].map((candidate) => fileURLToPath(new URL(candidate, import.meta.url)));
230
+ const mkrzPluginSpecifier = pluginCandidates.find((candidate) => fs.existsSync(candidate));
231
+ if (mkrzPluginSpecifier === void 0) throw new Error(`@mkrz/oxlint-config cannot locate its plugin module; looked at ${pluginCandidates.join(" and ")}.`);
232
+ /** Absolute specifier so `extends` of this config still loads the plugin. */
233
+ const mkrzPlugin = {
234
+ name: "mkrz",
235
+ specifier: mkrzPluginSpecifier
236
+ };
237
+ //#endregion
238
+ //#region src/configs/react.ts
239
+ /**
240
+ * React, accessibility, compiler, query, and store rules.
241
+ *
242
+ * React and jsx-a11y rules in the `correctness` and `suspicious` categories
243
+ * are already on through `base`; only rules outside those categories, rules
244
+ * with options, and rules turned off are listed.
245
+ */
246
+ const react = {
247
+ plugins: ["jsx-a11y", "react"],
248
+ env: { browser: true },
249
+ rules: {
250
+ "import/no-unassigned-import": ["error", { allow: [
251
+ "**/*.css",
252
+ "**/*.less",
253
+ "**/*.sass",
254
+ "**/*.scss"
255
+ ] }],
256
+ "jsx-a11y/interactive-supports-focus": ["error", { tabbable: [
257
+ "button",
258
+ "checkbox",
259
+ "link",
260
+ "searchbox",
261
+ "spinbutton",
262
+ "switch",
263
+ "textbox"
264
+ ] }],
265
+ "jsx-a11y/label-has-associated-control": ["error", {
266
+ controlComponents: [
267
+ "Checkbox",
268
+ "Input",
269
+ "Select",
270
+ "Switch"
271
+ ],
272
+ depth: 3
273
+ }],
274
+ "jsx-a11y/no-interactive-element-to-noninteractive-role": ["error", {
275
+ canvas: ["img"],
276
+ tr: ["none", "presentation"]
277
+ }],
278
+ "jsx-a11y/no-noninteractive-element-interactions": ["error", {
279
+ alert: [
280
+ "onKeyDown",
281
+ "onKeyPress",
282
+ "onKeyUp"
283
+ ],
284
+ body: ["onError", "onLoad"],
285
+ dialog: [
286
+ "onKeyDown",
287
+ "onKeyPress",
288
+ "onKeyUp"
289
+ ],
290
+ handlers: [
291
+ "onClick",
292
+ "onError",
293
+ "onKeyDown",
294
+ "onKeyPress",
295
+ "onKeyUp",
296
+ "onLoad",
297
+ "onMouseDown",
298
+ "onMouseUp"
299
+ ],
300
+ iframe: ["onError", "onLoad"],
301
+ img: ["onError", "onLoad"]
302
+ }],
303
+ "jsx-a11y/no-noninteractive-element-to-interactive-role": ["error", {
304
+ fieldset: ["presentation", "radiogroup"],
305
+ li: [
306
+ "menuitem",
307
+ "menuitemcheckbox",
308
+ "menuitemradio",
309
+ "option",
310
+ "row",
311
+ "tab",
312
+ "treeitem"
313
+ ],
314
+ ol: [
315
+ "listbox",
316
+ "menu",
317
+ "menubar",
318
+ "radiogroup",
319
+ "tablist",
320
+ "tree",
321
+ "treegrid"
322
+ ],
323
+ table: ["grid"],
324
+ td: ["gridcell"],
325
+ ul: [
326
+ "listbox",
327
+ "menu",
328
+ "menubar",
329
+ "radiogroup",
330
+ "tablist",
331
+ "tree",
332
+ "treegrid"
333
+ ]
334
+ }],
335
+ "jsx-a11y/no-noninteractive-tabindex": ["error", {
336
+ allowExpressionValues: true,
337
+ roles: ["tabpanel"],
338
+ tags: []
339
+ }],
340
+ "jsx-a11y/no-static-element-interactions": ["error", {
341
+ allowExpressionValues: true,
342
+ handlers: [
343
+ "onClick",
344
+ "onKeyDown",
345
+ "onKeyPress",
346
+ "onKeyUp",
347
+ "onMouseDown",
348
+ "onMouseUp"
349
+ ]
350
+ }],
351
+ "mkrz/no-query-result-destructuring": "error",
352
+ "mkrz/no-restricted-react-hooks": "error",
353
+ "mkrz/require-store-selector": "error",
354
+ "react/button-has-type": "error",
355
+ "react/checked-requires-onchange-or-readonly": "error",
356
+ "react/display-name": "error",
357
+ "react/exhaustive-effect-dependencies": "off",
358
+ "react/jsx-no-constructed-context-values": "error",
359
+ "react/jsx-no-target-blank": "error",
360
+ "react/jsx-no-useless-fragment": "error",
361
+ "react/no-array-index-key": "error",
362
+ "react/no-unescaped-entities": "error",
363
+ "react/no-unknown-property": "error",
364
+ "react/react-in-jsx-scope": "off",
365
+ "react/require-render-return": "error",
366
+ "react/rules-of-hooks": "error",
367
+ "react/unsupported-syntax": "error"
368
+ }
369
+ };
370
+ //#endregion
371
+ //#region src/configs/repository.ts
372
+ const monorepoDirectories = ["apps", "packages"];
373
+ /**
374
+ * A `pnpm-workspace.yaml` only marks a monorepo when it declares `packages`.
375
+ * Single-package repositories use the file for the catalog alone.
376
+ */
377
+ function declaresWorkspacePackages(root) {
378
+ const file = path.join(root, "pnpm-workspace.yaml");
379
+ return fs.existsSync(file) && /^packages:/mu.test(fs.readFileSync(file, "utf8"));
380
+ }
381
+ function readManifest(root) {
382
+ const file = path.join(root, "package.json");
383
+ if (!fs.existsSync(file)) return null;
384
+ const parsed = JSON.parse(fs.readFileSync(file, "utf8"));
385
+ if (typeof parsed !== "object" || parsed === null) return null;
386
+ return {
387
+ private: "private" in parsed && parsed.private === true,
388
+ workspaces: "workspaces" in parsed && parsed.workspaces != null
389
+ };
390
+ }
391
+ /**
392
+ * Detect the repository type from the directory Oxlint runs in.
393
+ *
394
+ * A `pnpm-workspace.yaml` with `packages`, a `workspaces` field, or an `apps/`
395
+ * or `packages/` directory means `monorepo`. Otherwise `package.json` decides:
396
+ * `"private": true` means `app`, anything else `library`. Without a
397
+ * `package.json` the result is `app`, with a warning.
398
+ *
399
+ * A workspace without the default `apps/` and `packages/` directories also
400
+ * warns, because the monorepo overrides would then match no file at all.
401
+ */
402
+ function detectRepositoryType(root, warn) {
403
+ const manifest = readManifest(root);
404
+ if (monorepoDirectories.some((directory) => fs.existsSync(path.join(root, directory)))) return "monorepo";
405
+ if (declaresWorkspacePackages(root) || manifest?.workspaces === true) {
406
+ warn(`@mkrz/oxlint-config: ${root} is a workspace but has no apps/ or packages/ directory, so the disable-directive policy applies to no file. Pass repositoryType: 'monorepo' with appsPath and packagesPath to mkrz().`);
407
+ return "monorepo";
408
+ }
409
+ if (manifest === null) {
410
+ warn(`@mkrz/oxlint-config: no package.json in ${root}; treating the repository as an application. Pass repositoryType to mkrz() to silence this.`);
411
+ return "app";
412
+ }
413
+ return manifest.private ? "app" : "library";
414
+ }
415
+ const app = { overrides: [{
416
+ files: ["**/*"],
417
+ rules: { "mkrz/no-oxlint-disable": "error" }
418
+ }] };
419
+ const library = { overrides: [{
420
+ files: ["**/*"],
421
+ rules: { "mkrz/package-disable-policy": "error" }
422
+ }] };
423
+ /** The overrides that carry the disable-directive and import policy. */
424
+ function repository(type, layout = {}) {
425
+ switch (type) {
426
+ case "app": return app;
427
+ case "library": return library;
428
+ default: return monorepo(layout);
429
+ }
430
+ }
431
+ /**
432
+ * Test-file rules: vitest checks, plus permission to use type assertions and
433
+ * non-null assertions.
434
+ */
435
+ const tests = { overrides: [{
436
+ files: [
437
+ "**/*.{test,spec}.*",
438
+ "**/*.test-d.*",
439
+ "**/__tests__/**"
440
+ ],
441
+ plugins: ["vitest"],
442
+ rules: {
443
+ "mkrz/no-chained-type-assertions": "off",
444
+ "mkrz/no-known-value-widening": "off",
445
+ "mkrz/no-type-assertion": "off",
446
+ "mkrz/no-widen-then-assert": "off",
447
+ "typescript/no-non-null-assertion": "off",
448
+ "vitest/expect-expect": "error",
449
+ "vitest/no-disabled-tests": "error",
450
+ "vitest/no-focused-tests": "error"
451
+ }
452
+ }] };
453
+ //#endregion
454
+ //#region src/configs/type-aware.ts
455
+ function* ancestors(directory) {
456
+ const parent = path.dirname(directory);
457
+ yield directory;
458
+ if (parent !== directory) yield* ancestors(parent);
459
+ }
460
+ /**
461
+ * Whether Oxlint will find the `tsgolint` binary when run from `root`.
462
+ *
463
+ * Oxlint reads `OXLINT_TSGOLINT_PATH` first and otherwise looks for the
464
+ * `.bin/tsgolint` shim in the `node_modules` directories above the working
465
+ * directory. Resolving the package beside this config is insufficient: a
466
+ * linked config may live outside the executable search path.
467
+ */
468
+ function hasTsgolint(root) {
469
+ if (process.env.OXLINT_TSGOLINT_PATH !== void 0) return true;
470
+ return [...ancestors(root)].some((directory) => fs.existsSync(path.join(directory, "node_modules", ".bin", "tsgolint")));
471
+ }
472
+ /**
473
+ * Type-checked rules for consumers that can pay the extra lint time.
474
+ *
475
+ * Type-aware rules in the `correctness` and `suspicious` categories are
476
+ * already on through `base`; only rules outside those categories are listed.
477
+ */
478
+ const typeAware = {
479
+ options: { typeAware: true },
480
+ plugins: ["typescript"],
481
+ rules: {
482
+ "typescript/dot-notation": "error",
483
+ "typescript/no-misused-promises": "error",
484
+ "typescript/no-mixed-enums": "error",
485
+ "typescript/no-unsafe-argument": "error",
486
+ "typescript/no-unsafe-assignment": "error",
487
+ "typescript/no-unsafe-call": "error",
488
+ "typescript/no-unsafe-member-access": "error",
489
+ "typescript/no-unsafe-return": "error",
490
+ "typescript/only-throw-error": "error",
491
+ "typescript/prefer-find": "error",
492
+ "typescript/prefer-includes": "error",
493
+ "typescript/prefer-nullish-coalescing": "error",
494
+ "typescript/prefer-optional-chain": "error",
495
+ "typescript/prefer-promise-reject-errors": "error",
496
+ "typescript/prefer-regexp-exec": "error",
497
+ "typescript/prefer-string-starts-ends-with": "error",
498
+ "typescript/related-getter-setter-pairs": "error",
499
+ "typescript/require-await": "error",
500
+ "typescript/restrict-plus-operands": "error",
501
+ "typescript/return-await": "error",
502
+ "typescript/switch-exhaustiveness-check": ["error", { considerDefaultExhaustiveForUnions: true }]
503
+ }
504
+ };
505
+ //#endregion
506
+ //#region src/mkrz.ts
507
+ /** Shallow-merge two optional record fields, the second winning. */
508
+ function merged(first, second) {
509
+ return first === void 0 && second === void 0 ? void 0 : Object.assign({}, first, second);
510
+ }
511
+ /** Concatenate two optional array fields. */
512
+ function joined(first, second) {
513
+ return first === void 0 && second === void 0 ? void 0 : [...first ?? [], ...second ?? []];
514
+ }
515
+ /**
516
+ * Lay `top` over `bottom` the way `extends` should: object fields merge with
517
+ * `top` winning, list fields concatenate, and nothing is dropped.
518
+ */
519
+ function layer(bottom, top) {
520
+ const plugins = joined(bottom.plugins, top.plugins);
521
+ return {
522
+ ...bottom,
523
+ ...top,
524
+ categories: merged(bottom.categories, top.categories),
525
+ env: merged(bottom.env, top.env),
526
+ globals: merged(bottom.globals, top.globals),
527
+ ignorePatterns: joined(bottom.ignorePatterns, top.ignorePatterns),
528
+ jsPlugins: joined(bottom.jsPlugins ?? void 0, top.jsPlugins ?? void 0),
529
+ options: merged(bottom.options, top.options),
530
+ overrides: joined(bottom.overrides, top.overrides),
531
+ plugins: plugins === void 0 ? void 0 : [...new Set(plugins)],
532
+ rules: merged(bottom.rules, top.rules),
533
+ settings: merged(bottom.settings, top.settings)
534
+ };
535
+ }
536
+ /**
537
+ * `defineConfig` from Oxlint for consumers who compose with `extends`.
538
+ *
539
+ * Oxlint only honors `ignorePatterns`, `env`, `globals`, and `settings` on
540
+ * the root config and drops them from extended configs. This wrapper folds
541
+ * those fields from every entry of `extends` into the root, and adds this
542
+ * package's ignore list. Prefer the second argument of `mkrz` when you only
543
+ * need to layer settings on this ruleset.
544
+ */
545
+ function defineConfig(config) {
546
+ const inherited = inheritedRootFields(config);
547
+ return defineConfig$1({
548
+ ...config,
549
+ ...inherited,
550
+ ignorePatterns: [...ignorePatterns, ...inherited.ignorePatterns ?? []]
551
+ });
552
+ }
553
+ /** Fold root-only fields without changing Oxlint's rule/override precedence. */
554
+ function inheritedRootFields(config) {
555
+ const inherited = (config.extends ?? []).reduce((accumulated, entry) => layer(accumulated, inheritedRootFields(entry)), {});
556
+ return {
557
+ env: merged(inherited.env, config.env),
558
+ globals: merged(inherited.globals, config.globals),
559
+ settings: merged(inherited.settings, config.settings),
560
+ ignorePatterns: joined(inherited.ignorePatterns, config.ignorePatterns)
561
+ };
562
+ }
563
+ const empty = {};
564
+ function typeAwareEnabled(requested, root, warn) {
565
+ if (requested === false || hasTsgolint(root)) return requested ?? true;
566
+ if (requested === true) throw new Error("@mkrz/oxlint-config: typeAware is on but oxlint-tsgolint is not installed. Add it with `pnpm add -D oxlint-tsgolint` or pass typeAware: false.");
567
+ warn("@mkrz/oxlint-config: oxlint-tsgolint is not installed; type-aware rules are off until it is. Add it with `pnpm add -D oxlint-tsgolint` or pass typeAware: false to silence this.");
568
+ return false;
569
+ }
570
+ function resolveRepositoryType(options, root, warn) {
571
+ return options.repositoryType === void 0 || options.repositoryType === "auto" ? detectRepositoryType(root, warn) : options.repositoryType;
572
+ }
573
+ function build(options, config, warn) {
574
+ const root = process.cwd();
575
+ const { react: withReact = true, typeAware: typeAwareOption } = options;
576
+ const typeAwarePiece = typeAwareEnabled(typeAwareOption, root, warn) ? typeAware : empty;
577
+ const reactPiece = withReact ? react : empty;
578
+ const repositoryPiece = options.repositoryType === "monorepo" ? repository("monorepo", options) : repository(resolveRepositoryType(options, root, warn));
579
+ const ruleset = {
580
+ jsPlugins: [mkrzPlugin],
581
+ plugins: [...new Set([
582
+ base,
583
+ typeAwarePiece,
584
+ reactPiece
585
+ ].flatMap((piece) => piece.plugins ?? []))],
586
+ categories: base.categories,
587
+ env: {
588
+ ...base.env,
589
+ ...reactPiece.env
590
+ },
591
+ options: {
592
+ ...base.options,
593
+ ...typeAwarePiece.options
594
+ },
595
+ rules: {
596
+ ...base.rules,
597
+ ...typeAwarePiece.rules,
598
+ ...reactPiece.rules
599
+ },
600
+ overrides: [
601
+ base,
602
+ tests,
603
+ repositoryPiece
604
+ ].flatMap((piece) => piece.overrides ?? []),
605
+ ignorePatterns
606
+ };
607
+ return defineConfig$1(layer(ruleset, config));
608
+ }
609
+ /**
610
+ * The complete ruleset as one flat root config.
611
+ *
612
+ * Everything is built as a single object rather than a chain of `extends`
613
+ * pieces: the plugin is declared once, the rule categories are declared once,
614
+ * and no subset can be handed to Oxlint that fails to load or runs at the
615
+ * wrong severity. `config` is the consumer's own root config and is layered
616
+ * on top: its root `rules` win over our root rules, its `overrides` run last,
617
+ * and its `ignorePatterns` are added to this package's list. Matching file
618
+ * overrides still take precedence over root rules.
619
+ */
620
+ function mkrz(options = {}, config = {}) {
621
+ return build(options, config, console.warn);
622
+ }
623
+ //#endregion
624
+ export { defineConfig, ignorePatterns, mkrz };
@@ -0,0 +1,4 @@
1
+ //#region src/plugin/index.d.ts
2
+ declare const plugin: import("@oxlint/plugins").Plugin;
3
+ //#endregion
4
+ export { plugin as default };