oxlint-plugin-arch 0.11.0 โ 0.12.1
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/CHANGELOG.md +241 -0
- package/README.md +52 -218
- package/dist/index.js +5205 -4073
- package/dist/preset/groups/backend.d.ts +2 -0
- package/dist/preset/groups/basics.d.ts +2 -0
- package/dist/preset/groups/comments.d.ts +2 -0
- package/dist/preset/groups/console.d.ts +2 -0
- package/dist/preset/groups/deny.d.ts +2 -0
- package/dist/preset/groups/expo.d.ts +2 -0
- package/dist/preset/groups/externals.d.ts +2 -0
- package/dist/preset/groups/forms.d.ts +2 -0
- package/dist/preset/groups/imports.d.ts +2 -0
- package/dist/preset/groups/layout.d.ts +2 -0
- package/dist/preset/groups/limits.d.ts +2 -0
- package/dist/preset/groups/naming.d.ts +2 -0
- package/dist/preset/groups/next.d.ts +2 -0
- package/dist/preset/groups/orpc.d.ts +2 -0
- package/dist/preset/groups/react.d.ts +2 -0
- package/dist/preset/groups/schemas.d.ts +2 -0
- package/dist/preset/groups/shadcn.d.ts +2 -0
- package/dist/preset/groups/sql.d.ts +2 -0
- package/dist/preset/groups/style.d.ts +2 -0
- package/dist/preset/groups/tailwind.d.ts +2 -0
- package/dist/preset/groups/tanstack.d.ts +2 -0
- package/dist/preset/groups/tests.d.ts +2 -0
- package/dist/preset/groups/types.d.ts +2 -0
- package/dist/preset/preset-detect.d.ts +3 -0
- package/dist/preset/preset-folders.d.ts +2 -0
- package/dist/preset/preset-recipes.d.ts +82 -0
- package/dist/preset/preset-stylesheet.d.ts +1 -0
- package/dist/preset/preset-units.d.ts +2 -0
- package/dist/preset/preset.constants.d.ts +79 -0
- package/dist/preset/preset.d.ts +89 -0
- package/dist/preset/preset.js +2299 -0
- package/dist/preset/preset.utils.d.ts +14 -0
- package/dist/rules/backend/backend-orpc-output.d.ts +1 -0
- package/dist/rules/backend/backend-registry.d.ts +1 -0
- package/dist/rules/backend/backend-service-functions.d.ts +1 -0
- package/dist/rules/backend/backend-sql-like.d.ts +1 -0
- package/dist/rules/boundaries/boundaries-deny.d.ts +1 -0
- package/dist/rules/boundaries/boundaries-imports.d.ts +1 -0
- package/dist/rules/boundaries/boundaries-next.d.ts +1 -0
- package/dist/rules/boundaries/boundaries-rpc-database.d.ts +1 -0
- package/dist/rules/boundaries/boundaries-tanstack.d.ts +1 -0
- package/dist/rules/boundaries/boundaries-token-owner.d.ts +1 -0
- package/dist/rules/code/code-constructor.d.ts +1 -0
- package/dist/rules/code/code-double-negation.d.ts +1 -0
- package/dist/rules/code/code-literal-in.d.ts +1 -0
- package/dist/rules/code/code-mutable-state.d.ts +1 -0
- package/dist/rules/code/code-object-params.d.ts +1 -0
- package/dist/rules/code/code-paired-call.d.ts +1 -0
- package/dist/rules/code/code-promise-mutation.d.ts +1 -0
- package/dist/rules/code/code-switch.d.ts +1 -0
- package/dist/rules/code/code-trivial-functions.d.ts +1 -0
- package/dist/rules/comments/comments-code.d.ts +1 -0
- package/dist/rules/comments/comments-directives.d.ts +1 -0
- package/dist/rules/copy/copy-dashes.d.ts +1 -0
- package/dist/rules/files/files-components-only.d.ts +1 -0
- package/dist/rules/files/files-constants-only.d.ts +1 -0
- package/dist/rules/files/files-domain-constants.d.ts +1 -0
- package/dist/rules/files/files-exports.d.ts +1 -0
- package/dist/rules/files/files-externals.d.ts +1 -0
- package/dist/rules/files/files-factory-keys.d.ts +1 -0
- package/dist/rules/files/files-helpers.d.ts +1 -0
- package/dist/rules/files/files-no-functions.d.ts +1 -0
- package/dist/rules/files/files-restricted.d.ts +1 -0
- package/dist/rules/files/files-route.d.ts +1 -0
- package/dist/rules/files/files-types-only.d.ts +1 -0
- package/dist/rules/layout/layout-call-arguments.d.ts +1 -0
- package/dist/rules/layout/layout-call-array.d.ts +1 -0
- package/dist/rules/layout/layout-chain.d.ts +1 -0
- package/dist/rules/layout/layout-jsx-attributes.d.ts +1 -0
- package/dist/rules/layout/layout-key-value.d.ts +1 -0
- package/dist/rules/layout/layout-object.d.ts +1 -0
- package/dist/rules/layout/layout-padding.d.ts +1 -0
- package/dist/rules/layout/layout-ternary.d.ts +1 -0
- package/dist/rules/naming/naming-declarations.d.ts +1 -0
- package/dist/rules/naming/naming-exports.d.ts +1 -0
- package/dist/rules/naming/naming-file.d.ts +1 -0
- package/dist/rules/naming/naming-folder.d.ts +1 -0
- package/dist/rules/naming/naming-types.d.ts +1 -0
- package/dist/rules/react/react-dynamic-classes.d.ts +1 -0
- package/dist/rules/react/react-empty-effect.d.ts +1 -0
- package/dist/rules/react/react-memo.d.ts +1 -0
- package/dist/rules/react/react-props.d.ts +1 -0
- package/dist/rules/schemas/schemas-inline.d.ts +1 -0
- package/dist/rules/schemas/schemas-local.d.ts +1 -0
- package/dist/rules/schemas/schemas-rederive.d.ts +1 -0
- package/dist/rules/schemas/schemas-single-use.d.ts +1 -0
- package/dist/rules/tests/tests-assertions.d.ts +1 -0
- package/dist/rules/tests/tests-concurrent-db.d.ts +1 -0
- package/dist/rules/tests/tests-modifiers.d.ts +1 -0
- package/dist/rules/tests/tests-titles.d.ts +1 -0
- package/dist/rules/types/types-declarations.d.ts +1 -0
- package/dist/rules/types/types-imported-alias.d.ts +1 -0
- package/dist/rules/types/types-inline.d.ts +1 -0
- package/dist/rules/types/types-local-alias.d.ts +1 -0
- package/dist/rules/types/types-namespace-import.d.ts +1 -0
- package/dist/rules/types/types-service.d.ts +1 -0
- package/dist/rules/types/types-unknown.d.ts +1 -0
- package/dist/types/ast.types.d.ts +2 -0
- package/dist/types/backend.types.d.ts +24 -0
- package/dist/types/boundaries.types.d.ts +72 -0
- package/dist/types/code.types.d.ts +59 -0
- package/dist/types/comments.types.d.ts +12 -0
- package/dist/types/copy.types.d.ts +4 -0
- package/dist/types/declarations.types.d.ts +20 -0
- package/dist/types/dillon-anti-slop.types.d.ts +55 -0
- package/dist/types/exports.types.d.ts +11 -0
- package/dist/types/files.types.d.ts +85 -0
- package/dist/types/layout.types.d.ts +55 -0
- package/dist/types/naming.types.d.ts +52 -0
- package/dist/types/options.types.d.ts +4 -0
- package/dist/types/preset.types.d.ts +248 -129
- package/dist/types/react.types.d.ts +14 -0
- package/dist/types/schemas.types.d.ts +20 -0
- package/dist/types/source.types.d.ts +1 -0
- package/dist/types/tests.types.d.ts +39 -0
- package/dist/types/types.types.d.ts +20 -0
- package/dist/utils/ast.utils.d.ts +19 -0
- package/dist/utils/boundaries.utils.d.ts +85 -0
- package/dist/utils/declarations.utils.d.ts +21 -0
- package/dist/utils/exports.utils.d.ts +6 -0
- package/dist/utils/naming.utils.d.ts +11 -0
- package/dist/utils/options.utils.d.ts +11 -0
- package/dist/utils/react.utils.d.ts +3 -0
- package/dist/utils/schemas.utils.d.ts +36 -0
- package/dist/utils/source.utils.d.ts +18 -0
- package/dist/vendor/dillon-anti-slop/index.js +1770 -0
- package/dist/vendor/dillon-anti-slop/rules/no-known-value-widening.d.ts +2 -0
- package/dist/vendor/dillon-anti-slop/rules/no-module-mocking.d.ts +2 -0
- package/dist/vendor/dillon-anti-slop/shared/dictionary-types.d.ts +5 -0
- package/dist/vendor/dillon-anti-slop/shared/expressions.d.ts +5 -0
- package/dist/vendor/dillon-anti-slop/shared/lexical-type-parameters.d.ts +2 -0
- package/dist/vendor/dillon-anti-slop/shared/reflect-method.d.ts +1 -0
- package/dist/vendor/dillon-anti-slop/shared/resolve-variable.d.ts +2 -0
- package/dist/vendor/dillon-anti-slop/shared/signatures.d.ts +15 -0
- package/dist/vendor/dillon-anti-slop/shared/type-aliases.d.ts +4 -0
- package/dist/vendor/dillon-anti-slop/shared/type-environment.d.ts +9 -0
- package/dist/vendor/dillon-anti-slop/shared/type-reference-name.d.ts +2 -0
- package/dist/vendor/dillon-anti-slop/shared/widening-targets.d.ts +3 -0
- package/package.json +51 -43
- package/src/{rules โ vendor}/dillon-anti-slop/UPSTREAM.md +9 -6
- package/dist/configs/boundaries.d.ts +0 -2
- package/dist/configs/modules.d.ts +0 -2
- package/dist/configs/plugins.d.ts +0 -3
- package/dist/configs/react.d.ts +0 -2
- package/dist/configs/source.d.ts +0 -2
- package/dist/configs/tests.d.ts +0 -2
- package/dist/configs/types.d.ts +0 -2
- package/dist/constants/preset.constants.d.ts +0 -38
- package/dist/constants/test.constants.d.ts +0 -1
- package/dist/presets/index.d.ts +0 -4
- package/dist/presets/index.js +0 -1736
- package/dist/presets/next-react-modules-preset.d.ts +0 -4
- package/dist/presets/next-react-modules-preset.js +0 -1729
- package/dist/presets/react-modules-preset.d.ts +0 -4
- package/dist/presets/react-modules-preset.js +0 -1724
- package/dist/presets/tanstack-start-react-modules-preset.d.ts +0 -4
- package/dist/presets/tanstack-start-react-modules-preset.js +0 -1729
- package/dist/rules/dillon-anti-slop/index.js +0 -2719
- package/dist/rules/dillon-anti-slop/rules/no-known-value-widening.d.ts +0 -1
- package/dist/rules/dillon-anti-slop/rules/no-module-mocking.d.ts +0 -8
- package/dist/rules/dillon-anti-slop/shared/dictionary-types.d.ts +0 -19
- package/dist/rules/dillon-anti-slop/shared/lexical-type-parameters.d.ts +0 -4
- package/dist/rules/dillon-anti-slop/shared/reflect-method.d.ts +0 -2
- package/dist/rules/module-policy/domain-constants.d.ts +0 -2
- package/dist/rules/module-policy/import-boundaries.d.ts +0 -2
- package/dist/rules/module-policy/index.js +0 -2266
- package/dist/rules/module-policy/memoization.d.ts +0 -2
- package/dist/rules/module-policy/next-runtime.d.ts +0 -7
- package/dist/rules/module-policy/no-unknown.d.ts +0 -6
- package/dist/rules/module-policy/reasoned-directives.d.ts +0 -2
- package/dist/rules/module-policy/service-functions.d.ts +0 -2
- package/dist/rules/module-policy/service-types.d.ts +0 -2
- package/dist/rules/module-policy/tanstack-runtime.d.ts +0 -2
- package/dist/rules/module-policy/test-assertions.d.ts +0 -2
- package/dist/rules/module-policy/test-modifiers.d.ts +0 -2
- package/dist/services/preset-compose.d.ts +0 -3
- package/dist/services/preset-context.d.ts +0 -2
- package/dist/types/module-policy.types.d.ts +0 -39
- package/dist/types/test-analysis.types.d.ts +0 -11
- package/dist/utils/helpers/ast.d.ts +0 -12
- package/dist/utils/helpers/boundaries.d.ts +0 -3
- package/dist/utils/helpers/comments.d.ts +0 -6
- package/dist/utils/helpers/declarations.d.ts +0 -35
- package/dist/utils/helpers/exports.d.ts +0 -18
- package/dist/utils/helpers/factories.d.ts +0 -9
- package/dist/utils/helpers/guards.d.ts +0 -11
- package/dist/utils/helpers/index.d.ts +0 -18
- package/dist/utils/helpers/layout.d.ts +0 -15
- package/dist/utils/helpers/mocking.d.ts +0 -2
- package/dist/utils/helpers/naming.d.ts +0 -13
- package/dist/utils/helpers/options.d.ts +0 -22
- package/dist/utils/helpers/orpc.d.ts +0 -3
- package/dist/utils/helpers/preset.d.ts +0 -9
- package/dist/utils/helpers/react-components.d.ts +0 -13
- package/dist/utils/helpers/routes.d.ts +0 -5
- package/dist/utils/helpers/runtime.d.ts +0 -14
- package/dist/utils/helpers/sanitizers.d.ts +0 -3
- package/dist/utils/helpers/schemas.d.ts +0 -10
- package/dist/utils/helpers/syntax.d.ts +0 -1
- package/dist/utils/helpers/test-tables.d.ts +0 -8
- package/dist/utils/helpers/trivial.d.ts +0 -6
- package/dist/utils/index.d.ts +0 -1
- /package/dist/{rules/module-policy/index.d.ts โ index.d.ts} +0 -0
- /package/dist/{rules โ vendor}/dillon-anti-slop/index.d.ts +0 -0
- /package/dist/{rules โ vendor}/dillon-anti-slop/rules/no-chained-type-assertions.d.ts +0 -0
- /package/dist/{rules โ vendor}/dillon-anti-slop/rules/no-conditional-empty-object-spread.d.ts +0 -0
- /package/dist/{rules โ vendor}/dillon-anti-slop/rules/no-object-parameters.d.ts +0 -0
- /package/dist/{rules โ vendor}/dillon-anti-slop/rules/no-reflect-apply.d.ts +0 -0
- /package/dist/{rules โ vendor}/dillon-anti-slop/rules/no-reflect-get.d.ts +0 -0
- /package/dist/{rules โ vendor}/dillon-anti-slop/rules/no-runtime-typeof.d.ts +0 -0
- /package/dist/{rules โ vendor}/dillon-anti-slop/rules/no-shape-in-symbol-names.d.ts +0 -0
- /package/dist/{rules โ vendor}/dillon-anti-slop/rules/no-unknown-parameters.d.ts +0 -0
- /package/dist/{rules โ vendor}/dillon-anti-slop/rules/no-unknown-returns.d.ts +0 -0
- /package/dist/{rules โ vendor}/dillon-anti-slop/rules/no-unknown-type-aliases.d.ts +0 -0
- /package/dist/{rules โ vendor}/dillon-anti-slop/rules/no-unsafe-dictionary-type.d.ts +0 -0
- /package/dist/{rules โ vendor}/dillon-anti-slop/rules/no-widen-then-assert.d.ts +0 -0
- /package/dist/{rules โ vendor}/dillon-anti-slop/rules/require-safety-comment-for-type-assertion.d.ts +0 -0
- /package/src/{rules โ vendor}/dillon-anti-slop/LICENSE +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,246 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.12.1
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- Preset: tests live in a `tests/` (or `test/`) folder. A `*.test.*` or `*.spec.*` file inside a unit's source is reported by `arch/files-restricted`.
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Preset detection reads `pnpm-workspace.yaml` (block or flow lists), workspace globs with `*` anywhere, `**`, `{a,b}` and `!exclude`, and peer dependencies (a UI package with React as a peer is `ui`). Packages and service domains named like output folders (`build`, `public`) are no longer skipped.
|
|
12
|
+
- Preset detection keeps a root app's or backend's recipe next to its workspace packages (when the root has its own source folder), gives a single root package its recipe (`library` included), and keeps the root unit next to a detected `scripts/` CLI. A folder with its own `package.json` is a unit with its own kind, also when nested in another workspace or listed through a `*` key, instead of inheriting the root app's kind.
|
|
13
|
+
- Preset: a unit without `src/` uses its own folder as source (a workspace Next app with `app/` at the package root).
|
|
14
|
+
- Preset detection honors a configured `source`, `backend.registry` file or `false`, expands `*` keys (with exact keys beside them, which also inherit the wildcard's `source`) before adding conventions, and understands import maps such as `"#/*": "./src/*.ts"`, `"#/*.ts": "./src/*.ts"`, exact and conditional entries.
|
|
15
|
+
- Preset detection: a service may import its own domain's operations; other domains stay banned through one `!(domain)` pattern per domain, and a ban you configure yourself is never lifted. A web app's or package's own aliases that overlap the backend's (`#/*`, `#/lib/*`) are no longer banned.
|
|
16
|
+
- Preset detection skips broken symlinks, follows symlinked folders, and drops conventions inside a `false` folder or for a group a parent sets to `false` (an exact key beats a `*` key at the same depth, and an exact key that revives a unit under a `false` wildcard keeps its conventions), instead of throwing.
|
|
17
|
+
- Preset: folder keys accept dots (`packages/my.lib`, `.agents`), and `apps/web/` or `./apps` match the detected `apps/web` and `apps`.
|
|
18
|
+
- Preset: nested group options merge with the inherited ones (`tests.mocking: { allow: [] }` keeps the parent's `preset` and `deny`, also when the parent used the `'strict'` shorthand).
|
|
19
|
+
- Preset: the registry file is exempt from the domain layout and its file and folder name checks; test files skip the domain, operation and frontend runtime file name checks (the `tests/` check below reports them once); operation files in `actions/` and `queries/` keep the single-export check; `layout.strict` accepts `.rsc.tsx`.
|
|
20
|
+
- Preset: Tailwind stylesheet detection ignores comments, strings and plugins such as `tailwindcss-animate`, accepts `@import url("tailwindcss")` with or without quotes, and follows symlinked folders.
|
|
21
|
+
- Preset: `dist`, `build`, `coverage` and `.output` are ignored at the project root and at each unit's root, not at any depth, so a `services/build/` domain is linted.
|
|
22
|
+
- `arch/boundaries-deny` import globs accept `!(a|b)`: one path segment that is none of the names.
|
|
23
|
+
- Preset: `layout.strict` checks domain file names at any depth under `services/<domain>/`, so a nested or misnamed file (`order/queries/order-query-list.ts`) is reported for its name, not only its folder. `layout.operations: 'folders'` keeps its own `actions/` and `queries/` names.
|
|
24
|
+
- Preset detection: a `next` or `vinext` dependency wins over a leftover `@tanstack/react-start` one.
|
|
25
|
+
- Preset detection: a package with `services/<domain>/<domain>.service.ts` gets the `backend` recipe without a backend framework dependency.
|
|
26
|
+
- Preset: `services/**/*.rsc.{ts,tsx}` files and frontend operation files (`*-action.*.client.ts` and the other runtime suffixes) keep the export prefix check next to their name pattern or template. Since 0.12.0 the later override replaced it; 0.11 ran both.
|
|
27
|
+
- `dillon-anti-slop/no-shape-in-symbol-names` reports only names you declare: not another API's property (`schema.shape`, `record.shape = 1`), a renamed destructured property or import, a qualified type read, a JSX member or attribute, or a renamed re-export from another module. A shorthand property reports once.
|
|
28
|
+
|
|
29
|
+
## 0.12.0
|
|
30
|
+
|
|
31
|
+
### Breaking: rebuilt package
|
|
32
|
+
|
|
33
|
+
- Every owned rule is now `arch/<family>-<subject>`; the `modules` plugin is gone. Update configs and `oxlint-disable` comments with the table below. Old IDs are not aliased: an old ID in a disable comment no longer suppresses anything.
|
|
34
|
+
- Entry points: `oxlint-plugin-arch` (rules), `oxlint-plugin-arch/preset` (`preset`, `recipes`, `templates`, `PresetError` and the option types) and `oxlint-plugin-arch/dillon-anti-slop`. The `presets/*` and `rules/*` subpaths are removed.
|
|
35
|
+
- Selector rules (`code-switch`, `code-double-negation`, `naming-types`, `types-local-alias`, `react-empty-effect`, `react-dynamic-classes`, `boundaries-rpc-database`, `tests-concurrent-db`) accept an optional `message` option.
|
|
36
|
+
- The preset is `preset({ root, folders })`: folders map to groups, nested folders inherit and refine, recipes and templates hold shared defaults. `reactModulesPreset`, `nextReactModulesPreset`, `tanstackStartReactModulesPreset`, `architecture`, roles, `policies`, `ruleSeverities` and `ruleExclusions` are removed; see the option table below. Expo apps get an `expo` group. `naming-shape` in the preset is replaced by `dillon-anti-slop/no-shape-in-symbol-names`. Invalid folders and options throw `PresetError`.
|
|
37
|
+
- Rule options use one short vocabulary (`allow`, `deny`, `min`, `max`, `message`, ...); see the rule option table below. Old option names are not aliased and fail schema validation. Defaults are unchanged. Rule behavior and messages are otherwise unchanged apart from the fixes under Fixed (two messages that named an option now name the new one); checked by running the 0.11 rule tests against the new rules, and by linting two consumer monorepos with equivalent folder configs.
|
|
38
|
+
- Merged rules: `naming-export-prefix`, `naming-export-pattern` and `naming-export-template` are now `naming-exports`, one check per option object (`mode: 'prefix' | 'pattern' | 'template'`), so several checks can share a file: `['error', { mode: 'prefix' }, { mode: 'pattern', pattern: '^use[A-Z]' }]`. `allDeclarations: true` โ `scope: 'declarations'`, `allFunctions: true` โ `scope: 'functions'`, `naming-export-template`'s `mode: 'all' | 'some'` โ `match`; the other options follow the rule option table. `files-factory` is now `files-exports` with `factory` (its `allDeclarations: true` โ `scope: 'declarations'`; `names` is no longer required). `comments-members` is now `comments-code` with `members: 'only'` (`'also'` adds member checks to the normal ones). `naming-shape` is removed; use `dillon-anti-slop/no-shape-in-symbol-names`. `code-switch` now defaults to `'Avoid switch statements.'`. Message IDs and texts are unchanged, apart from the fixes under Fixed.
|
|
39
|
+
- Docs: `docs/folders.md`, one page per group in `docs/groups/`, one page per rule in `docs/rules/`, `docs/vendor.md` and `docs/plugin-only.md`. The README group and rule tables are generated (`bun run docs`).
|
|
40
|
+
- New `arch/copy-dashes`: reports em dashes in strings, template text and JSX text. On in the preset as `style.dashes`.
|
|
41
|
+
- React plugins, `oxlint-tailwindcss` and `@shadcn/lint` are optional peer dependencies, loaded only when a folder turns on their group; a missing one throws `PresetError` with the install command.
|
|
42
|
+
- `bun run bench <repo>` times every rule against a consumer repo and prints the slowest.
|
|
43
|
+
- Architecture checks that needed vitest tests are now lint:
|
|
44
|
+
- `deny` group (on, empty): per-folder `imports` and `calls` bans, inherited and merged down the tree, via the new `arch/boundaries-deny` (static, re-export and literal dynamic imports).
|
|
45
|
+
- `externals` group (on): new `arch/files-externals` checks `ssr.external` in `vite.config.*` and `serverExternalPackages` in `next.config.*` against `package.json`; `externals` exports the default must-stay-external list.
|
|
46
|
+
- `backend.registry`: new `arch/backend-registry`, every `services/<domain>/` has `<domain>.service.ts` and is listed in the registry file. `backend.writes`: methods query files may not call (Kysely writes by default).
|
|
47
|
+
- `layout.strict` (closed set of domain file roles), `layout.operations: 'folders'` (`actions/` and `queries/` with `makeโฆ` factories), `layout.service` (allowed `.service.ts` exports).
|
|
48
|
+
- `naming.files` and `naming.exports` take a regex for the folder; `naming.unique` keeps a file name part unique per folder (migration numbers), via the new `unique` option of `arch/naming-file`.
|
|
49
|
+
- `tanstack` keeps `@tanstack/react-start/rsc` in `services/*.rsc.{ts,tsx}`; `expo` checks Expo Router file names and keeps route files free of helpers.
|
|
50
|
+
- Folder `rules` take `[level, options]` as well as a level.
|
|
51
|
+
|
|
52
|
+
| Old preset option | New |
|
|
53
|
+
| --- | --- |
|
|
54
|
+
| `tanstackStartReactModulesPreset(...)` | `preset({ root, folders })` |
|
|
55
|
+
| `architecture: { 'apps/web': 'web' }` | `folders: { 'apps/web': recipes.tanstack }` (`recipes.next`, `recipes.expo`) |
|
|
56
|
+
| role `server` / `runner` | `recipes.backend` |
|
|
57
|
+
| role `packages` | `recipes.library` (`'packages/*'` for a folder of packages) |
|
|
58
|
+
| role `scripts`, `cliFiles` | `recipes.cli` on the folder |
|
|
59
|
+
| entry `layout: { services: 'flat' }`, `sourceDir` | folder `layout: { services: 'flat' }`, `source` |
|
|
60
|
+
| `framework` | the `tanstack` / `next` / `expo` group on the folder |
|
|
61
|
+
| `severity` | folder `severity` |
|
|
62
|
+
| `ruleSeverities`, `ruleExclusions` | folder `rules: { 'arch/x': 'warn' \| 'off' }` |
|
|
63
|
+
| `policies: { x: false }` | the group set to `false` on the folder |
|
|
64
|
+
| `ignorePatterns` | the folder set to `false` |
|
|
65
|
+
| `formatting.semi`, `formatting.quotes` | `style.semicolons`, `style.quotes` |
|
|
66
|
+
| `limits.maxFileLines`, `maxTypeFileLines`, `maxFunctionComplexity` | `limits.lines`, `limits.types`, `limits.complexity` |
|
|
67
|
+
| `modules.customFileRoles` | `layout.suffixes` |
|
|
68
|
+
| `modules.migrationFiles` | the migrations folder with `layout: false` |
|
|
69
|
+
| `modules.colocatedTypeFiles` | `types.colocated` |
|
|
70
|
+
| `imports.backendEntryPoints`, `aliases`, `internalSortPatterns` | `backend.exports`, `imports.aliases`, `imports.internal` |
|
|
71
|
+
| `orpc.publicProcedureFiles`, `outputSchemaComposers`, `clientOwnerFile` | `orpc.public`, `orpc.composers`, `orpc.client` |
|
|
72
|
+
| `sql.likeSanitizers`, `forms.schemaResolver` | `sql.sanitizers`, `forms.resolver` |
|
|
73
|
+
| `react.compiler`, `react.componentProps` | `react.compiler`, `react.props` |
|
|
74
|
+
| `tests.profile`, `additionalTestFunctions`, `additionalAssertionFunctions`, `mocking` | `tests.fixtures`, `tests.functions`, `tests.assertions`, `tests.mocking` |
|
|
75
|
+
| `tanstackStart.*` / `next.*` server, client, computed imports | `tanstack` / `next` group `server`, `client`, `dynamic` |
|
|
76
|
+
| `tailwind.cssEntryPoint(sByRoot)`, `rootFontSize` | folder `tailwind.css`, `tailwind.rem` |
|
|
77
|
+
| `shadcn.ui`, `shadcn.components` | `shadcn.ui`, `shadcn.components`; mark UI kit packages with `kit: true` |
|
|
78
|
+
|
|
79
|
+
| Old ID | New ID |
|
|
80
|
+
| --- | --- |
|
|
81
|
+
| `arch/call-arguments-multiline` | `arch/layout-call-arguments` |
|
|
82
|
+
| `arch/call-array-multiline` | `arch/layout-call-array` |
|
|
83
|
+
| `arch/chain-newline` | `arch/layout-chain` |
|
|
84
|
+
| `arch/component-props` | `arch/react-props` |
|
|
85
|
+
| `arch/declaration-name` | `arch/naming-declarations` |
|
|
86
|
+
| `arch/export-file-prefix` | `arch/naming-exports` |
|
|
87
|
+
| `arch/export-name-pattern` | `arch/naming-exports` (`mode: 'pattern'`) |
|
|
88
|
+
| `arch/filename-export-name` | `arch/naming-exports` (`mode: 'template'`) |
|
|
89
|
+
| `arch/filename-match` | `arch/naming-file` |
|
|
90
|
+
| `arch/folder-prefix` | `arch/naming-folder` |
|
|
91
|
+
| `arch/jsx-attributes-multiline` | `arch/layout-jsx-attributes` |
|
|
92
|
+
| `arch/key-value-same-line` | `arch/layout-key-value` |
|
|
93
|
+
| `arch/no-comments` | `arch/comments-code` |
|
|
94
|
+
| `arch/no-extra-exports` | `arch/files-exports` |
|
|
95
|
+
| `arch/no-extra-factory-keys` | `arch/files-factory-keys` |
|
|
96
|
+
| `arch/no-file-level-helpers` | `arch/files-helpers` |
|
|
97
|
+
| `arch/no-imported-type-alias` | `arch/types-imported-alias` |
|
|
98
|
+
| `arch/no-inline-schema-elements` | `arch/schemas-inline` |
|
|
99
|
+
| `arch/no-inline-types` | `arch/types-inline` |
|
|
100
|
+
| `arch/no-literal-in` | `arch/code-literal-in` |
|
|
101
|
+
| `arch/no-local-schema-construction` | `arch/schemas-local` |
|
|
102
|
+
| `arch/no-member-comments` | `arch/comments-code` (`members: 'only'`) |
|
|
103
|
+
| `arch/no-module-mutable-state` | `arch/code-mutable-state` |
|
|
104
|
+
| `arch/no-promise-all-mutation` | `arch/code-promise-mutation` |
|
|
105
|
+
| `arch/no-rederive-schema` | `arch/schemas-rederive` |
|
|
106
|
+
| `arch/no-restricted-constructor` | `arch/code-constructor` |
|
|
107
|
+
| `arch/no-restricted-files` | `arch/files-restricted` |
|
|
108
|
+
| `arch/no-restricted-token` | `arch/boundaries-token-owner` |
|
|
109
|
+
| `arch/no-runtime-in-types` | `arch/files-types-only` |
|
|
110
|
+
| `arch/no-single-use-scalar-schema` | `arch/schemas-single-use` |
|
|
111
|
+
| `arch/no-top-level-functions` | `arch/files-no-functions` |
|
|
112
|
+
| `arch/no-trivial-functions` | `arch/code-trivial-functions` |
|
|
113
|
+
| `arch/no-type-declarations` | `arch/types-declarations` |
|
|
114
|
+
| `arch/no-unescaped-like` | `arch/backend-sql-like` |
|
|
115
|
+
| `arch/object-multiline` | `arch/layout-object` |
|
|
116
|
+
| `arch/only-export-components` | `arch/files-components-only` |
|
|
117
|
+
| `arch/only-export-constants` | `arch/files-constants-only` |
|
|
118
|
+
| `arch/padding-between-statements` | `arch/layout-padding` |
|
|
119
|
+
| `arch/prefer-namespace-type-import` | `arch/types-namespace-import` |
|
|
120
|
+
| `arch/require-file-factory` | `arch/files-exports` (`factory`) |
|
|
121
|
+
| `arch/require-object-params` | `arch/code-object-params` |
|
|
122
|
+
| `arch/require-orpc-output` | `arch/backend-orpc-output` |
|
|
123
|
+
| `arch/require-paired-call` | `arch/code-paired-call` |
|
|
124
|
+
| `arch/route-surface` | `arch/files-route` |
|
|
125
|
+
| `arch/ternary-layout` | `arch/layout-ternary` |
|
|
126
|
+
| `arch/test-title-pattern` | `arch/tests-titles` |
|
|
127
|
+
| `modules/backend-switch` | `arch/code-switch` |
|
|
128
|
+
| `modules/concurrent-db` | `arch/tests-concurrent-db` |
|
|
129
|
+
| `modules/domain-constants` | `arch/files-domain-constants` |
|
|
130
|
+
| `modules/double-negation` | `arch/code-double-negation` |
|
|
131
|
+
| `modules/dynamic-classes` | `arch/react-dynamic-classes` |
|
|
132
|
+
| `modules/empty-effect` | `arch/react-empty-effect` |
|
|
133
|
+
| `modules/import-boundaries` | `arch/boundaries-imports` |
|
|
134
|
+
| `modules/local-type-alias` | `arch/types-local-alias` |
|
|
135
|
+
| `modules/memoization` | `arch/react-memo` |
|
|
136
|
+
| `modules/next-runtime` | `arch/boundaries-next` |
|
|
137
|
+
| `modules/no-unknown` | `arch/types-unknown` |
|
|
138
|
+
| `modules/pascal-interface` | `arch/naming-types` |
|
|
139
|
+
| `modules/reasoned-directives` | `arch/comments-directives` |
|
|
140
|
+
| `modules/rpc-database` | `arch/boundaries-rpc-database` |
|
|
141
|
+
| `modules/service-functions` | `arch/backend-service-functions` |
|
|
142
|
+
| `modules/service-types` | `arch/types-service` |
|
|
143
|
+
| `modules/shape-suffix` | `dillon-anti-slop/no-shape-in-symbol-names` |
|
|
144
|
+
| `modules/tanstack-runtime` | `arch/boundaries-tanstack` |
|
|
145
|
+
| `modules/test-assertions` | `arch/tests-assertions` |
|
|
146
|
+
| `modules/test-modifiers` | `arch/tests-modifiers` |
|
|
147
|
+
|
|
148
|
+
| Rule | Old option | New option |
|
|
149
|
+
| --- | --- | --- |
|
|
150
|
+
| `backend-orpc-output` | `handlerMethod`, `outputMethod` | `handler`, `output` |
|
|
151
|
+
| `backend-service-functions` | `allowLocalHelpers`, `allowReturnedMethods`, `singleExport` | `helpers`, `methods`, `single` |
|
|
152
|
+
| `backend-sql-like` | `allowSanitizedBindings`, `operatorMethods` | `bindings`, `operators` |
|
|
153
|
+
| `boundaries-imports` | `fileRoles`, `portableLib`, `publicEntrypoints` | `roles`, `portable`, `entrypoints` |
|
|
154
|
+
| `boundaries-next`, `boundaries-tanstack` | `serverImports`, `clientImports`, `allowComputedImportsIn` | `server`, `client`, `dynamic` |
|
|
155
|
+
| `boundaries-tanstack` | `rpcClients` | `rpc` |
|
|
156
|
+
| `boundaries-token-owner` (and each `restrictions[]` entry) | `allowIn`, `allowPathPatterns` | `allow`, `patterns` |
|
|
157
|
+
| `code-constructor` | `checkCalls` | `calls` |
|
|
158
|
+
| `code-mutable-state` | `allowNamePattern` | `allow` |
|
|
159
|
+
| `code-object-params` | `maxParams`, `allDeclarations`, `serviceMethods`, `allowPattern` | `max`, `all`, `services`, `allow` |
|
|
160
|
+
| `code-promise-mutation` | `checkAssignments` | `assignments` |
|
|
161
|
+
| `code-trivial-functions` | `allowPattern`, `allowCallees`, `allowAsync`, `checkServiceMethods`, `bannedNames`, `checkGenericGuards` | `allow`, `callees`, `async`, `services`, `deny`, `guards` |
|
|
162
|
+
| `comments-code` | `allowWhy`, `allowPatterns`, `allowJsdoc` | `why`, `allow`, `jsdoc` |
|
|
163
|
+
| `files-components-only` | `matchFileName`, `trailingRoles`, `allowTypeExports`, `denyTypePattern` | `filename`, `roles`, `types`, `deny` |
|
|
164
|
+
| `files-constants-only` | `allowFunctionValues`, `allowTypeExports`, `allowReExports` | `functions`, `types`, `reexports` |
|
|
165
|
+
| `files-domain-constants` | `includeData`, `allowServiceMethods` | `data`, `services` |
|
|
166
|
+
| `files-exports` | `domainStem`, `trailingRoles`, `roleSeparators`, `allowTypeExports`, `factoryScope` | `stem`, `roles`, `separators`, `types`, `scope` |
|
|
167
|
+
| `files-factory-keys` (and each `sets[]` entry) | `factoryPattern`, `requireKeys`, `keySets` | `factory`, `required`, `sets` |
|
|
168
|
+
| `files-helpers` | `allowPattern`, `detectComponents`, `hookPattern` | `allow`, `components`, `hooks` |
|
|
169
|
+
| `files-no-functions` | `banReExports`, `allowPattern` | `reexports`, `allow` |
|
|
170
|
+
| `files-route` | `exportName`, `allowedExports`, `inspectExports`, `bannedHooks`, `banIntrinsicJsx` | `export`, `exports`, `inspect`, `hooks`, `intrinsic` |
|
|
171
|
+
| `files-types-only` | `runtimeImports`, `allowImportSources`, `banReExports` | `imports`, `sources`, `reexports` |
|
|
172
|
+
| `layout-call-arguments` | `minArguments` | `min` |
|
|
173
|
+
| `layout-call-array` | `minElements` | `min` |
|
|
174
|
+
| `layout-chain` (`groups[]`) | `minDepth`, `onlyMethods`, `rootPattern` | `min`, `only`, `root` |
|
|
175
|
+
| `layout-jsx-attributes` | `minAttributes` | `min` |
|
|
176
|
+
| `layout-object` | `minProperties` | `min` |
|
|
177
|
+
| `layout-padding` | `returnMinStatements`, `multilineVariables` | `min`, `multiline` |
|
|
178
|
+
| `layout-ternary` | `maxLength` | `max` |
|
|
179
|
+
| `naming-declarations` | `trailingRoles`, `roleSeparators`, `allowPattern` | `roles`, `separators`, `allow` |
|
|
180
|
+
| `naming-exports` | `trailingRoles`, `roleSeparators`, `ignoreTypeExports`, `serviceMethods`, `allowPattern`, `placeholderPattern` | `roles`, `separators`, `types`, `services`, `allow`, `placeholder` |
|
|
181
|
+
| `naming-folder` | `stripPrefixes` | `prefixes` |
|
|
182
|
+
| `react-props` | `filePrefix` | `prefix` |
|
|
183
|
+
| `schemas-inline`, `schemas-single-use` | `structuralMethods`, `allowZodScalars` | `structural`, `scalars` |
|
|
184
|
+
| `schemas-local` | `allowIn`, `allowPathPatterns`, `runtimeImportMessage` | `allow`, `patterns`, `importMessage` |
|
|
185
|
+
| `tests-assertions` | `additionalTestFunctions`, `additionalAssertionFunctions` | `functions`, `assertions` |
|
|
186
|
+
| `tests-modifiers` | `additionalTestFunctions` | `functions` |
|
|
187
|
+
| `tests-titles` | `forbid` | `deny` |
|
|
188
|
+
| `types-declarations` | `allowPattern` | `allow` |
|
|
189
|
+
| `types-inline` | `functionTypes`, `minMembers` | `functions`, `min` |
|
|
190
|
+
|
|
191
|
+
### Changed
|
|
192
|
+
|
|
193
|
+
- Preset detection: `preset()` picks each workspace folder's recipe from its `package.json` dependencies, and adds conventions for backend `services/`, `core/`, `rpc/`, `routes/`, `cli/`, `tests/kits/` and `migrations/` folders, web apps and packages. It also detects the Tailwind stylesheet by content (`app.css`, `styles.css`, `globals.css`, ...), the backend registry file, backend entries from `exports`, and flat web services. Your folders merge over the detected ones; `detect: false` turns it off. See `docs/folders.md`.
|
|
194
|
+
- New recipes `react`, `desktop` and `ui`; `kit` stays as an alias of `ui`.
|
|
195
|
+
- A UI kit without its own stylesheet uses the stylesheet of the web app that depends on it, else the first web app's, and no longer throws when there are several web apps.
|
|
196
|
+
- `backend.registry` takes an options object without `file`. A configured `file` skips no service by default.
|
|
197
|
+
- `backend.writes` adds `dispatch` and `send`.
|
|
198
|
+
- `backend-registry` accepts a singular or plural registry key for a service folder (`order` โ `orders`, `category` โ `categories`).
|
|
199
|
+
- `boundaries-imports`, `boundaries-next` and `boundaries-tanstack` no longer require their root and package options. An omitted `web`, `backend`, `packages`, `backendPackages`, `appPackages`, `entrypoints` or `rpc` defaults to `[]`, and `aliases` to `{}`; configs that set them behave as before.
|
|
200
|
+
- Preset: a key inside a `false` folder, `backend.writes` below a backend folder, a non-object group value (`null`, arrays, numbers), folders that disagree on `tailwind.rem` or `shadcn.ui`/`shadcn.components`, and expo `client`/`dynamic` now throw instead of being ignored.
|
|
201
|
+
- Preset types: `console` and `kit` take `true` or `false`; expo options are `{ server }` (`PresetExpoOptions`).
|
|
202
|
+
|
|
203
|
+
### Fixed
|
|
204
|
+
|
|
205
|
+
- `comments-code` (was `no-comments`): member-comment fixes keep member tokens, separating line breaks and blank lines, skip comments a `disable-next-line` targets, and honor `jsdoc` and `allow`. Removing an inline comment between two spaces leaves one space.
|
|
206
|
+
- `layout-chain` skips chains with computed links instead of reporting them forever. `layout-call-arguments` and `layout-object` fixes keep the original trailing-comma presence.
|
|
207
|
+
- `types-namespace-import` reports without an autofix.
|
|
208
|
+
- `backend-registry`: keys come from top-level objects and factory results (or the one named by `object`), string keys count, a domain without `<folder>.service.ts` is reported on the registry file, and a missing `services` folder is no longer a crash.
|
|
209
|
+
- `backend-sql-like`: sanitized bindings resolve by scope, a reassigned top-level binding is not trusted, and every dynamic part of a LIKE value must be sanitized.
|
|
210
|
+
- `boundaries-tanstack`: browser globals inside server callbacks are reported in any file; code under `<T>x` casts and non-`declare` enums or namespaces counts as runtime; global lookups no longer scale quadratically.
|
|
211
|
+
- `boundaries-tanstack`, `boundaries-next`, `boundaries-imports`: library identities are options with today's values as defaults (`serverPackages`, `clientPackages`, `hookPackages`, `startPackages`, `rscPackages`, `uiPackages`, `publicEnv`); subpaths of server-only and client-only packages match.
|
|
212
|
+
- `boundaries-imports`: `export { type X } from` counts as type-only. `boundaries-deny` and `boundaries-rpc-database` match literal computed callees (`console['log']()`), and `boundaries-rpc-database` no longer matches `db[name]()`.
|
|
213
|
+
- `files-externals`: subpath externals (`pg/native`) check their package; a list with spreads skips the missing-package check; a malformed nearest `package.json` skips the rule.
|
|
214
|
+
- `files-components-only` splits file names only on `-` and `.` again (`user_card.tsx` โ `User_card`). `naming-exports` pattern mode treats an empty pattern as match-all again.
|
|
215
|
+
- `naming-file` takes several option objects; `unique` counts only sibling files its object's `pattern` accepts.
|
|
216
|
+
- `files-no-functions`, `code-object-params` and `code-trivial-functions` check `export default` function expressions; `code-object-params` checks a defaulted parameter by its type. `files-no-functions` no longer reports type-only re-exports. `files-exports` checks an aliased export (`export { local as useInvoiceQuery }`) by its exported name. `schemas-inline` names the namespace actually called.
|
|
217
|
+
- Preset: a folder's `naming.files` and `naming.unique` add to the built-in file checks instead of replacing them; invalid `naming` regexes and `layout.operations` below an app or package folder throw `PresetError`; `backend.registry` works for a root-level backend and takes `object`.
|
|
218
|
+
- `bun run bench` resolves plugins from the consumer's config.
|
|
219
|
+
- `boundaries-tanstack` reports static server imports used inside explicit client callbacks even in `.server.ts` files.
|
|
220
|
+
- `layout-call-arguments` reports incorrect layouts with comments or unsafe argument ranges without offering an autofix.
|
|
221
|
+
- `comments-code` removes horizontal padding around inline comments after opening parentheses, producing `foo(1)` from `foo(/* note */ 1)`.
|
|
222
|
+
- Export-name rules (`naming-exports`, `files-exports` and others) read every name in a destructured export (`export const { a, b } = source`) instead of reporting `<anonymous>`.
|
|
223
|
+
- `files-exports` factory mode checks an aliased export by its exported name, and reports aliased exports at the export specifier.
|
|
224
|
+
- `files-no-functions` also allows `export type * from` and `export { type A } from`.
|
|
225
|
+
- `files-factory-keys` checks returned objects wrapped in `as const`, `satisfies` or `!`.
|
|
226
|
+
- `bun run bench` shows Oxlint startup errors, works when no JS rule ran, removes its temp files and resolves symlinked repo paths.
|
|
227
|
+
- `bun run build` clears `dist/` first, so local packs no longer ship stale modules.
|
|
228
|
+
- Preset: when `'.'` is an app, backend or CLI it stays a unit; a top-level key becomes its own unit only when it sets `tanstack`, `next`, `expo`, `backend` or `console`, and a `console` key beside a root app is a CLI rather than an inherited app.
|
|
229
|
+
- Preset: `imports.aliases` and `imports.internal` apply to the folder that sets them; two apps with their own `@/` alias no longer share the last one (`arch/boundaries-imports`, `arch/boundaries-tanstack`, `arch/boundaries-next`, import sorting).
|
|
230
|
+
- Preset: a folder `severity` now also sets the level of the common rules in that folder, and `no-console` inherits `severity` from parent folders.
|
|
231
|
+
- Preset: an exact key beside a `false` `*` key (`'packages/*': false, 'packages/ui': {...}`) is linted instead of ignored.
|
|
232
|
+
- Preset: a `naming.files` pattern in a folder adds to the `layout.strict` domain file check instead of replacing it.
|
|
233
|
+
- Preset: `root` resolves through symlinks, so absolute option paths match the file paths Oxlint reports.
|
|
234
|
+
- `tests-assertions` finds the test callback before a trailing timeout or after an options object, so `test('x', () => {}, 1000)` is reported and its assertions are no longer flagged as standalone.
|
|
235
|
+
- `tests-assertions` no longer follows a helper binding that is reassigned after its declaration.
|
|
236
|
+
- `tests-assertions` tracks renamed `test`, `it` and assertion imports from `bun:test`.
|
|
237
|
+
- `tests-concurrent-db` only reports `db` destructured from the `test.concurrent` callback's context (its parameter, or the parameter destructured in the body), not unrelated local `db` patterns or nested callbacks.
|
|
238
|
+
- `tests-modifiers` reports `.only`, `.skip` and `.todo` after `skipIf()`, `runIf()` and `if()` builders.
|
|
239
|
+
- `types-imported-alias` ignores an alias whose target is its own type parameter (`type Identity<T> = T`), and no longer resolves `export { X } from './other'` against a local alias named `X`.
|
|
240
|
+
- `react-memo` resolves the member root binding, so a local or parameter named `React` no longer counts as React.
|
|
241
|
+
- `dillon-anti-slop/no-widen-then-assert` resolves identifiers through their scope instead of scanning every scope's references, removing quadratic work on files with many assertions.
|
|
242
|
+
- `naming-exports` template mode checks an aliased export (`export { create as makeReportActionCreate }`) by its exported name.
|
|
243
|
+
|
|
3
244
|
## 0.11.0
|
|
4
245
|
|
|
5
246
|
- `modules/no-unknown` allows `unknown` on the narrowed parameter of a type guard (`function isAppError(error: unknown): error is AppError`) and on the error parameter of a catch callback (`catch: (error: unknown) => E`, `.catch((error: unknown) => โฆ)`). Other uses still fail. This applies to every root.
|
package/README.md
CHANGED
|
@@ -1,251 +1,85 @@
|
|
|
1
1
|
# ๐๏ธ oxlint-plugin-arch
|
|
2
2
|
|
|
3
|
-
> Architecture rules for [Oxlint](https://oxc.rs),
|
|
3
|
+
> Architecture rules for [Oxlint](https://oxc.rs): files in the right folders, exports named after their file, types where they belong.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Linters catch bugs; this catches drift. Describe your folders once, and the preset wires the right rules into each one: apps, backends, libraries, UI kits and scripts. Relax a folder by changing one key, not by writing overrides.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
- ๐๏ธ **Configurable.** No app names, folders, or libraries are baked in. Globs and policy live in your config.
|
|
9
|
-
- ๐ **Safe autofix.** Layout and comment rules touch whitespace or comments; `object-multiline` and `call-arguments-multiline` can also add trailing commas. Type-import fixes qualify scope-resolved references and skip unsafe rewrites.
|
|
10
|
-
- โก **Fast.** Built on Oxlint's JS plugin API and ESTree, with no extra parser.
|
|
7
|
+
## โจ Features
|
|
11
8
|
|
|
12
|
-
|
|
9
|
+
- ๐๏ธ **Folders, not flags.** Each folder says what it holds (`react`, `tanstack`, `backend`, `kit`); nested folders inherit and refine.
|
|
10
|
+
- ๐ท๏ธ **Filename-aware.** Rules derive names from the file they run on: `user-action.create.ts` must export `userActionCreate`.
|
|
11
|
+
- ๐๏ธ **Configurable.** No app names or paths baked in. Every rule works on its own too.
|
|
12
|
+
- ๐ **Safe autofix.** ๐ง rules only touch whitespace or comments.
|
|
13
|
+
- โก **Fast.** Oxlint's JS plugin API, no extra parser.
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
## ๐งฐ Built with
|
|
16
|
+
|
|
17
|
+
[Oxlint](https://oxc.rs) ยท [oxlint-tsgolint](https://github.com/oxc-project/tsgolint) ยท [Bun](https://bun.sh) ยท TypeScript
|
|
18
|
+
|
|
19
|
+
## ๐ Install in 3 steps
|
|
18
20
|
|
|
19
|
-
|
|
21
|
+
**You need:** Oxlint 1.85 or newer.
|
|
22
|
+
|
|
23
|
+
**1. Install**
|
|
20
24
|
|
|
21
25
|
```sh
|
|
22
26
|
bun add -d oxlint oxlint-tsgolint oxlint-plugin-arch
|
|
27
|
+
# React, Tailwind and shadcn groups (the tanstack, next, expo, react and ui recipes):
|
|
28
|
+
bun add -d eslint-plugin-react eslint-plugin-react-you-might-not-need-an-effect eslint-plugin-svg-jsx oxlint-tailwindcss @shadcn/lint
|
|
23
29
|
```
|
|
24
30
|
|
|
31
|
+
**2. Add the preset**
|
|
32
|
+
|
|
25
33
|
```ts
|
|
26
34
|
// oxlint.config.ts
|
|
27
|
-
import preset from 'oxlint-plugin-arch/
|
|
35
|
+
import { preset } from 'oxlint-plugin-arch/preset'
|
|
28
36
|
|
|
29
37
|
export default preset({
|
|
30
38
|
root: import.meta.dirname,
|
|
31
|
-
|
|
32
|
-
'
|
|
33
|
-
'apps/server': 'server',
|
|
34
|
-
scripts: 'scripts',
|
|
35
|
-
packages: 'packages',
|
|
39
|
+
folders: {
|
|
40
|
+
'packages/ui': { react: { a11y: false } },
|
|
36
41
|
},
|
|
37
|
-
})
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
For a Next.js app use `oxlint-plugin-arch/presets/next-react-modules-preset`. See [architecture](docs/preset/architecture.md), [frameworks](docs/preset/frameworks.md) and [options](docs/preset/options.md).
|
|
41
|
-
|
|
42
|
-
## ๐ฆ Install
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
bun add -d oxlint-plugin-arch oxlint @oxlint/plugins
|
|
42
|
+
})
|
|
46
43
|
```
|
|
47
44
|
|
|
48
|
-
|
|
49
|
-
> Keep `oxlint` and `@oxlint/plugins` on matching versions.
|
|
45
|
+
The preset detects each workspace from its `package.json` (TanStack, Next, Expo, backend, UI kit, library) along with its stylesheet, service registry and migrations. List only the folders you want to change. Detection, inheritance, groups, recipes and templates: [docs/folders.md](docs/folders.md). Rules without the preset: [docs/plugin-only.md](docs/plugin-only.md).
|
|
50
46
|
|
|
51
|
-
|
|
47
|
+
**3. Lint**
|
|
52
48
|
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
export default defineConfig({
|
|
57
|
-
jsPlugins: [
|
|
58
|
-
{ name: 'arch', specifier: 'oxlint-plugin-arch' },
|
|
59
|
-
],
|
|
60
|
-
})
|
|
49
|
+
```sh
|
|
50
|
+
bunx oxlint
|
|
61
51
|
```
|
|
62
52
|
|
|
63
|
-
|
|
53
|
+
## ๐ Groups and rules
|
|
64
54
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
jsPlugins: [{ name: 'arch', specifier: 'oxlint-plugin-arch' }],
|
|
68
|
-
rules: {
|
|
69
|
-
'arch/no-literal-in': 'error',
|
|
70
|
-
},
|
|
71
|
-
overrides: [
|
|
72
|
-
{
|
|
73
|
-
files: ['**/src/components/**/*.tsx'],
|
|
74
|
-
rules: {
|
|
75
|
-
'arch/only-export-components': ['error', { matchFileName: true }],
|
|
76
|
-
},
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
files: ['**/*.test.ts'],
|
|
80
|
-
rules: {
|
|
81
|
-
'arch/test-title-pattern': ['error', { forbid: '^should\\b', flags: 'i' }],
|
|
82
|
-
},
|
|
83
|
-
},
|
|
84
|
-
],
|
|
85
|
-
})
|
|
86
|
-
```
|
|
55
|
+
<!-- generated:start -->
|
|
56
|
+
On by default: [`layout`](docs/groups/layout.md), [`limits`](docs/groups/limits.md), [`style`](docs/groups/style.md), [`basics`](docs/groups/basics.md), [`naming`](docs/groups/naming.md), [`comments`](docs/groups/comments.md), [`types`](docs/groups/types.md), [`imports`](docs/groups/imports.md), [`tests`](docs/groups/tests.md), [`deny`](docs/groups/deny.md), [`externals`](docs/groups/externals.md).
|
|
87
57
|
|
|
88
|
-
|
|
58
|
+
Opt-in: [`react`](docs/groups/react.md), [`tanstack`](docs/groups/tanstack.md), [`next`](docs/groups/next.md), [`expo`](docs/groups/expo.md), [`tailwind`](docs/groups/tailwind.md), [`shadcn`](docs/groups/shadcn.md), [`kit`](docs/groups/kit.md), [`backend`](docs/groups/backend.md), [`orpc`](docs/groups/orpc.md), [`schemas`](docs/groups/schemas.md), [`forms`](docs/groups/forms.md), [`sql`](docs/groups/sql.md), [`console`](docs/groups/console.md).
|
|
89
59
|
|
|
90
|
-
|
|
60
|
+
65 rules, IDs `arch/<rule>`. ๐ง = autofix.
|
|
91
61
|
|
|
92
|
-
|
|
|
93
|
-
| --- | --- |
|
|
94
|
-
|
|
|
95
|
-
|
|
|
96
|
-
| [`
|
|
97
|
-
|
|
|
98
|
-
| [`
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
### `arch/*`
|
|
110
|
-
|
|
111
|
-
#### ๐ Files & folders
|
|
112
|
-
|
|
113
|
-
| Rule | What it enforces |
|
|
114
|
-
| --- | --- |
|
|
115
|
-
| [`filename-match`](docs/rules/arch/filename-match.md) | Filenames match a pattern you configure. |
|
|
116
|
-
| [`folder-prefix`](docs/rules/arch/folder-prefix.md) | Filenames start with their parent folder name, or the folders after a root you choose. |
|
|
117
|
-
| [`no-restricted-files`](docs/rules/arch/no-restricted-files.md) | Files matching a glob you forbid are reported, for example misplaced `*.types.ts`. |
|
|
118
|
-
|
|
119
|
-
#### ๐ท๏ธ Naming & exports
|
|
120
|
-
|
|
121
|
-
| Rule | What it enforces |
|
|
122
|
-
| --- | --- |
|
|
123
|
-
| [`declaration-name`](docs/rules/arch/declaration-name.md) | Selected declarations start with a prefix taken from the filename, or match a pattern. |
|
|
124
|
-
| [`export-file-prefix`](docs/rules/arch/export-file-prefix.md) | Names start with the filename prefix. |
|
|
125
|
-
| [`export-name-pattern`](docs/rules/arch/export-name-pattern.md) | Export names (or every function and type) match a regular expression. |
|
|
126
|
-
| [`filename-export-name`](docs/rules/arch/filename-export-name.md) | Function names follow a template built from the filename. |
|
|
127
|
-
| [`no-extra-exports`](docs/rules/arch/no-extra-exports.md) | A file exports only the names you allow. |
|
|
128
|
-
| [`only-export-constants`](docs/rules/arch/only-export-constants.md) | Constant files export only local `const` values. |
|
|
129
|
-
|
|
130
|
-
#### ๐ญ Functions & factories
|
|
131
|
-
|
|
132
|
-
| Rule | What it enforces |
|
|
133
|
-
| --- | --- |
|
|
134
|
-
| [`require-file-factory`](docs/rules/arch/require-file-factory.md) | The file defines the factory function its filename promises. |
|
|
135
|
-
| [`no-extra-factory-keys`](docs/rules/arch/no-extra-factory-keys.md) | A factory returns only the keys you allow. |
|
|
136
|
-
| [`require-object-params`](docs/rules/arch/require-object-params.md) | Functions take object parameters instead of long positional lists. |
|
|
137
|
-
| [`no-file-level-helpers`](docs/rules/arch/no-file-level-helpers.md) | No stray helper functions at module scope. |
|
|
138
|
-
| [`no-top-level-functions`](docs/rules/arch/no-top-level-functions.md) | No top-level functions (and optionally no re-exports) in matched files. |
|
|
139
|
-
| [`no-trivial-functions`](docs/rules/arch/no-trivial-functions.md) | No empty or pass-through functions. |
|
|
140
|
-
| [`no-module-mutable-state`](docs/rules/arch/no-module-mutable-state.md) | No module-level `let`/`var`, which is shared across requests and tests. |
|
|
141
|
-
|
|
142
|
-
#### ๐ท Types
|
|
143
|
-
|
|
144
|
-
| Rule | What it enforces |
|
|
145
|
-
| --- | --- |
|
|
146
|
-
| [`no-inline-types`](docs/rules/arch/no-inline-types.md) | Function signatures use named types instead of inline `{ ... }` objects. |
|
|
147
|
-
| [`no-type-declarations`](docs/rules/arch/no-type-declarations.md) | No type aliases or interfaces in matched files, so types live in one place. |
|
|
148
|
-
| [`no-runtime-in-types`](docs/rules/arch/no-runtime-in-types.md) | Type modules stay free of runtime code. |
|
|
149
|
-
| [`no-imported-type-alias`](docs/rules/arch/no-imported-type-alias.md) | No exported aliases that only rename an imported type. |
|
|
150
|
-
| [`prefer-namespace-type-import`](docs/rules/arch/prefer-namespace-type-import.md) ๐ง | Long type-only named imports become a namespace import with qualified references. |
|
|
151
|
-
|
|
152
|
-
#### ๐งช Schemas & APIs
|
|
153
|
-
|
|
154
|
-
| Rule | What it enforces |
|
|
155
|
-
| --- | --- |
|
|
156
|
-
| [`no-local-schema-construction`](docs/rules/arch/no-local-schema-construction.md) | No schemas built outside the files that own them. |
|
|
157
|
-
| [`no-inline-schema-elements`](docs/rules/arch/no-inline-schema-elements.md) | Named schemas inside combinators like `z.array(...)`. |
|
|
158
|
-
| [`no-rederive-schema`](docs/rules/arch/no-rederive-schema.md) | No re-deriving types from schemas imported from elsewhere. |
|
|
159
|
-
| [`no-single-use-scalar-schema`](docs/rules/arch/no-single-use-scalar-schema.md) | Reports scalar Zod aliases that are used only once. |
|
|
160
|
-
| [`require-orpc-output`](docs/rules/arch/require-orpc-output.md) | oRPC procedures declare a named `.output()` schema. |
|
|
161
|
-
| [`no-unescaped-like`](docs/rules/arch/no-unescaped-like.md) | `LIKE` / `ILIKE` values pass through your sanitizer. |
|
|
162
|
-
|
|
163
|
-
#### ๐ง Boundaries & safety
|
|
164
|
-
|
|
165
|
-
| Rule | What it enforces |
|
|
166
|
-
| --- | --- |
|
|
167
|
-
| [`no-restricted-token`](docs/rules/arch/no-restricted-token.md) | Identifiers or member calls appear only in owner files. |
|
|
168
|
-
| [`no-restricted-constructor`](docs/rules/arch/no-restricted-constructor.md) | No `new Error()` (or any constructor you list) where typed errors are required. |
|
|
169
|
-
| [`require-paired-call`](docs/rules/arch/require-paired-call.md) | Calling one function requires calling another, for example `useForm` with a schema resolver. |
|
|
170
|
-
| [`no-promise-all-mutation`](docs/rules/arch/no-promise-all-mutation.md) | No `results.push(...)` or `total += x` on outer variables inside `Promise.all`. Return values instead. |
|
|
171
|
-
| [`no-literal-in`](docs/rules/arch/no-literal-in.md) | No `'key' in value`. Use `Object.hasOwn()` or a discriminated union. |
|
|
172
|
-
|
|
173
|
-
#### โ๏ธ React
|
|
174
|
-
|
|
175
|
-
| Rule | What it enforces |
|
|
176
|
-
| --- | --- |
|
|
177
|
-
| [`component-props`](docs/rules/arch/component-props.md) | Components type props with `interface XProps` declared directly above them. |
|
|
178
|
-
| [`only-export-components`](docs/rules/arch/only-export-components.md) | Component files export only components, named after the file. |
|
|
179
|
-
| [`route-surface`](docs/rules/arch/route-surface.md) | Route files export only the route, with no banned hooks or raw JSX. |
|
|
180
|
-
|
|
181
|
-
#### ๐ฌ Comments & tests
|
|
182
|
-
|
|
183
|
-
| Rule | What it enforces |
|
|
184
|
-
| --- | --- |
|
|
185
|
-
| [`no-comments`](docs/rules/arch/no-comments.md) ๐ง | No comments in matched files, except directives and `Why:` notes. |
|
|
186
|
-
| [`no-member-comments`](docs/rules/arch/no-member-comments.md) ๐ง | No comments on interface, type, and object members. |
|
|
187
|
-
| [`test-title-pattern`](docs/rules/arch/test-title-pattern.md) | Test titles match your rules, for example no leading "should". |
|
|
188
|
-
|
|
189
|
-
#### ๐จ Layout
|
|
190
|
-
|
|
191
|
-
| Rule | What it enforces |
|
|
192
|
-
| --- | --- |
|
|
193
|
-
| [`padding-between-statements`](docs/rules/arch/padding-between-statements.md) ๐ง | Blank lines around functions, classes, control flow and late returns. |
|
|
194
|
-
| [`object-multiline`](docs/rules/arch/object-multiline.md) ๐ง | Objects with 3+ properties passed to a call go one property per line. |
|
|
195
|
-
| [`ternary-layout`](docs/rules/arch/ternary-layout.md) ๐ง | Join short conditionals or split long ones before `?` and `:`. |
|
|
196
|
-
| [`call-arguments-multiline`](docs/rules/arch/call-arguments-multiline.md) ๐ง | Calls and constructors with 3+ arguments go one argument per line. |
|
|
197
|
-
| [`key-value-same-line`](docs/rules/arch/key-value-same-line.md) ๐ง | An object key and the start of its value stay on the same line. |
|
|
198
|
-
| [`chain-newline`](docs/rules/arch/chain-newline.md) ๐ง | Long method chains go one call per line. |
|
|
199
|
-
| [`call-array-multiline`](docs/rules/arch/call-array-multiline.md) ๐ง | Arrays passed to `Promise.all` (or callees you list) go one element per line. |
|
|
200
|
-
| [`jsx-attributes-multiline`](docs/rules/arch/jsx-attributes-multiline.md) ๐ง | JSX tags with 3+ attributes go one attribute per line. |
|
|
62
|
+
| Family | Covers | Rules |
|
|
63
|
+
| --- | --- | --- |
|
|
64
|
+
| `backend` | Service and RPC structure | [`backend-orpc-output`](docs/rules/backend-orpc-output.md), [`backend-registry`](docs/rules/backend-registry.md), [`backend-service-functions`](docs/rules/backend-service-functions.md), [`backend-sql-like`](docs/rules/backend-sql-like.md) |
|
|
65
|
+
| `boundaries` | Import and runtime boundaries | [`boundaries-deny`](docs/rules/boundaries-deny.md), [`boundaries-imports`](docs/rules/boundaries-imports.md), [`boundaries-next`](docs/rules/boundaries-next.md), [`boundaries-rpc-database`](docs/rules/boundaries-rpc-database.md), [`boundaries-tanstack`](docs/rules/boundaries-tanstack.md), [`boundaries-token-owner`](docs/rules/boundaries-token-owner.md) |
|
|
66
|
+
| `code` | Code shapes to avoid | [`code-constructor`](docs/rules/code-constructor.md), [`code-double-negation`](docs/rules/code-double-negation.md), [`code-literal-in`](docs/rules/code-literal-in.md), [`code-mutable-state`](docs/rules/code-mutable-state.md), [`code-object-params`](docs/rules/code-object-params.md), [`code-paired-call`](docs/rules/code-paired-call.md), [`code-promise-mutation`](docs/rules/code-promise-mutation.md), [`code-switch`](docs/rules/code-switch.md), [`code-trivial-functions`](docs/rules/code-trivial-functions.md) |
|
|
67
|
+
| `comments` | Comments and directives | [`comments-code`](docs/rules/comments-code.md) ๐ง, [`comments-directives`](docs/rules/comments-directives.md) |
|
|
68
|
+
| `copy` | User-facing text | [`copy-dashes`](docs/rules/copy-dashes.md) |
|
|
69
|
+
| `files` | What a file may contain or export | [`files-components-only`](docs/rules/files-components-only.md), [`files-constants-only`](docs/rules/files-constants-only.md), [`files-domain-constants`](docs/rules/files-domain-constants.md), [`files-exports`](docs/rules/files-exports.md), [`files-externals`](docs/rules/files-externals.md), [`files-factory-keys`](docs/rules/files-factory-keys.md), [`files-helpers`](docs/rules/files-helpers.md), [`files-no-functions`](docs/rules/files-no-functions.md), [`files-restricted`](docs/rules/files-restricted.md), [`files-route`](docs/rules/files-route.md), [`files-types-only`](docs/rules/files-types-only.md) |
|
|
70
|
+
| `layout` | Layout a formatter leaves alone | [`layout-call-arguments`](docs/rules/layout-call-arguments.md) ๐ง, [`layout-call-array`](docs/rules/layout-call-array.md) ๐ง, [`layout-chain`](docs/rules/layout-chain.md) ๐ง, [`layout-jsx-attributes`](docs/rules/layout-jsx-attributes.md) ๐ง, [`layout-key-value`](docs/rules/layout-key-value.md) ๐ง, [`layout-object`](docs/rules/layout-object.md) ๐ง, [`layout-padding`](docs/rules/layout-padding.md) ๐ง, [`layout-ternary`](docs/rules/layout-ternary.md) ๐ง |
|
|
71
|
+
| `naming` | File, folder and export names | [`naming-declarations`](docs/rules/naming-declarations.md), [`naming-exports`](docs/rules/naming-exports.md), [`naming-file`](docs/rules/naming-file.md), [`naming-folder`](docs/rules/naming-folder.md), [`naming-types`](docs/rules/naming-types.md) |
|
|
72
|
+
| `react` | Components, effects, class names | [`react-dynamic-classes`](docs/rules/react-dynamic-classes.md), [`react-empty-effect`](docs/rules/react-empty-effect.md), [`react-memo`](docs/rules/react-memo.md), [`react-props`](docs/rules/react-props.md) |
|
|
73
|
+
| `schemas` | Schema placement | [`schemas-inline`](docs/rules/schemas-inline.md), [`schemas-local`](docs/rules/schemas-local.md), [`schemas-rederive`](docs/rules/schemas-rederive.md), [`schemas-single-use`](docs/rules/schemas-single-use.md) |
|
|
74
|
+
| `tests` | Test structure | [`tests-assertions`](docs/rules/tests-assertions.md), [`tests-concurrent-db`](docs/rules/tests-concurrent-db.md), [`tests-modifiers`](docs/rules/tests-modifiers.md), [`tests-titles`](docs/rules/tests-titles.md) |
|
|
75
|
+
| `types` | Type placement and shape | [`types-declarations`](docs/rules/types-declarations.md), [`types-imported-alias`](docs/rules/types-imported-alias.md), [`types-inline`](docs/rules/types-inline.md), [`types-local-alias`](docs/rules/types-local-alias.md), [`types-namespace-import`](docs/rules/types-namespace-import.md), [`types-service`](docs/rules/types-service.md), [`types-unknown`](docs/rules/types-unknown.md) |
|
|
76
|
+
<!-- generated:end -->
|
|
77
|
+
|
|
78
|
+
Also bundled: [Dillon Mulroy's anti-slop rules](docs/vendor.md) as `oxlint-plugin-arch/dillon-anti-slop`.
|
|
201
79
|
|
|
202
80
|
> [!WARNING]
|
|
203
|
-
|
|
204
|
-
### `modules/*`
|
|
205
|
-
|
|
206
|
-
Rules the preset uses to keep its policies from overwriting each other. You can also register them on their own.
|
|
207
|
-
|
|
208
|
-
| Rule | What it enforces |
|
|
209
|
-
| --- | --- |
|
|
210
|
-
| [`backend-switch`](docs/rules/modules/backend-switch.md) | Do not use `switch` in backend application code. Use ts-pattern instead. |
|
|
211
|
-
| [`concurrent-db`](docs/rules/modules/concurrent-db.md) | Concurrent tests must not destructure a `db` fixture. Use an isolated database fixture instead. |
|
|
212
|
-
| [`domain-constants`](docs/rules/modules/domain-constants.md) | Move module data to a domain `.constants.ts` file. Do not keep SCREAMING_SNAKE constants (or configured data) in the service file. |
|
|
213
|
-
| [`double-negation`](docs/rules/modules/double-negation.md) | Do not coerce with `!!`. Use `Boolean(value)` or an explicit comparison. |
|
|
214
|
-
| [`dynamic-classes`](docs/rules/modules/dynamic-classes.md) | Write complete `className` strings. Do not build them with template expressions or `+`. |
|
|
215
|
-
| [`empty-effect`](docs/rules/modules/empty-effect.md) | Remove `useEffect` / `useLayoutEffect` callbacks whose body is empty. |
|
|
216
|
-
| [`import-boundaries`](docs/rules/modules/import-boundaries.md) | Reject imports that cross configured application boundaries, including type-only imports. |
|
|
217
|
-
| [`local-type-alias`](docs/rules/modules/local-type-alias.md) | Do not declare type aliases in component and hook files. Use an interface named for the owner, or move derived aliases to domain types. |
|
|
218
|
-
| [`memoization`](docs/rules/modules/memoization.md) | Do not import or call React `memo`, `useMemo` or `useCallback`. Use the React Compiler. Unrelated `cache.memo` calls are left alone. |
|
|
219
|
-
| [`next-runtime`](docs/rules/modules/next-runtime.md) | Check Next.js runtime ownership from file names and directives. `.server` / `.rsc` and `'use server'` modules stay off the browser. `.client` and `'use client'` modules stay off server-only APIs. Shared modules use neither. |
|
|
220
|
-
| [`no-unknown`](docs/rules/modules/no-unknown.md) | Do not write the `unknown` type. Use an owned domain type. |
|
|
221
|
-
| [`pascal-interface`](docs/rules/modules/pascal-interface.md) | Interface names must be PascalCase. |
|
|
222
|
-
| [`reasoned-directives`](docs/rules/modules/reasoned-directives.md) | Lint disables must name specific rules and explain why after `--`. |
|
|
223
|
-
| [`rpc-database`](docs/rules/modules/rpc-database.md) | RPC handlers must not call the database. Delegate that work to services. |
|
|
224
|
-
| [`service-functions`](docs/rules/modules/service-functions.md) | Keep backend operations strict. Frontend modules may expose several operations, with helpers nested inside them. |
|
|
225
|
-
| [`service-types`](docs/rules/modules/service-types.md) | Only the matching factory-derived `Service` alias may stay in a service file. Types such as `ChatDeps` belong in domain types. |
|
|
226
|
-
| [`shape-suffix`](docs/rules/modules/shape-suffix.md) | Do not name a declaration with a `Shape` suffix. Name it for its domain role. |
|
|
227
|
-
| [`tanstack-runtime`](docs/rules/modules/tanstack-runtime.md) | Check direct runtime dependencies and imported TanStack execution boundaries. Compilation still owns graph isolation. |
|
|
228
|
-
| [`test-assertions`](docs/rules/modules/test-assertions.md) | Every test case must contain a recognized assertion, and `expect` calls must sit inside a test or assertion helper. |
|
|
229
|
-
| [`test-modifiers`](docs/rules/modules/test-modifiers.md) | Reject focused, skipped and placeholder tests, including renamed imports such as `check.only`. |
|
|
230
|
-
|
|
231
|
-
### `dillon-anti-slop/*`
|
|
232
|
-
|
|
233
|
-
15 vendored [anti-slop](https://github.com/dmmulroy/anti-slop) rules by Dillon Mulroy. [List](docs/rules/dillon-anti-slop.md). Rules with local options have their own page:
|
|
234
|
-
|
|
235
|
-
| Rule | What it enforces |
|
|
236
|
-
| --- | --- |
|
|
237
|
-
| [`no-module-mocking`](docs/rules/dillon-anti-slop/no-module-mocking.md) | No `vi.mock` or `jest.mock`. Options also ban stubs such as `vi.spyOn`. |
|
|
238
|
-
|
|
239
|
-
## โก Benchmarks
|
|
240
|
-
|
|
241
|
-
Wall time for a full `oxlint` run over three real TypeScript monorepos, best of 5, including process startup.
|
|
242
|
-
|
|
243
|
-
| Project | Files | Lines | Plugin loaded, no rules | [Monorepo example](examples/monorepo.oxlint.config.ts) | All 42 rules on every file |
|
|
244
|
-
| --- | ---: | ---: | ---: | ---: | ---: |
|
|
245
|
-
| Small | 246 | 14.5k | 0.09s | **0.20s** | 0.23s |
|
|
246
|
-
| Medium | 792 | 100.5k | 0.10s | **0.49s** | 0.69s |
|
|
247
|
-
| Large | 1,880 | 190k | 0.10s | **0.72s** | 1.08s |
|
|
81
|
+
> Upgrading from 0.11 or earlier: the preset API, rule IDs and entry points changed. See the [changelog](CHANGELOG.md).
|
|
248
82
|
|
|
249
83
|
## ๐ License
|
|
250
84
|
|
|
251
|
-
MIT
|
|
85
|
+
MIT. The `dillon-anti-slop` rules are by [Dillon Mulroy](https://github.com/dmmulroy/anti-slop), MIT, vendored with [attribution](src/vendor/dillon-anti-slop/UPSTREAM.md).
|