oxlint-plugin-arch 0.12.6 → 0.13.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 +121 -0
- package/README.md +4 -4
- package/dist/index.js +1059 -306
- package/dist/preset/preset-effect.d.ts +3 -0
- package/dist/preset/preset-recipes.d.ts +10 -0
- package/dist/preset/preset.constants.d.ts +21 -2
- package/dist/preset/preset.d.ts +11 -1
- package/dist/preset/preset.js +715 -223
- package/dist/preset/preset.utils.d.ts +6 -0
- package/dist/rules/code/code-delegate.d.ts +1 -0
- package/dist/rules/layout/layout-type-arguments.d.ts +1 -0
- package/dist/rules/react/react-query-props.d.ts +1 -0
- package/dist/types/backend.types.d.ts +2 -3
- package/dist/types/boundaries.types.d.ts +26 -1
- package/dist/types/code.types.d.ts +7 -0
- package/dist/types/comments.types.d.ts +1 -0
- package/dist/types/dillon-anti-slop.types.d.ts +6 -0
- package/dist/types/effect.types.d.ts +1 -0
- package/dist/types/files.types.d.ts +3 -2
- package/dist/types/layout.types.d.ts +16 -0
- package/dist/types/naming.types.d.ts +4 -0
- package/dist/types/preset.types.d.ts +26 -24
- package/dist/types/react.types.d.ts +17 -0
- package/dist/types/types.types.d.ts +8 -0
- package/dist/utils/ast.utils.d.ts +1 -2
- package/dist/utils/boundaries.utils.d.ts +72 -4
- package/dist/utils/options.utils.d.ts +1 -0
- package/dist/vendor/dillon-anti-slop/index.js +38 -16
- package/package.json +15 -1
- package/src/vendor/dillon-anti-slop/UPSTREAM.md +3 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,126 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.13.1
|
|
4
|
+
|
|
5
|
+
Preset defaults that change what an app reports:
|
|
6
|
+
|
|
7
|
+
- `effect` group: `layout-call-arguments` adds `pipe: { min: 2 }`; `layout-call-depth` counts through callbacks; `layout-object` adds `params`, `nested`, `siblings` and `inner: 2`; `layout-ternary` splits a one-line ternary over 100 columns (was `fit: false`); `layout-type-arguments` is on with `min: 3`.
|
|
8
|
+
- Effect servers: `comments-code` keeps one-line step comments (`steps: true`); `effect-layer-file` names local layers `<Role>Layer` (`suffix: 'Layer'`). An app that keeps `layer<Role>` writes `'apps/server/src/domains/*/*.layer.ts': { rules: { 'arch/effect-layer-file': 'error' } }`.
|
|
9
|
+
- `sql` group: `layout-chain` breaks Kysely chains of 3+ calls.
|
|
10
|
+
- Effect servers and contract packages ban `ai` and `@ai-sdk/**` ("Use effect/ai.").
|
|
11
|
+
|
|
12
|
+
Rules and options:
|
|
13
|
+
|
|
14
|
+
- Preset: when several file keys match one file, their settings merge on it, broadest key first; before, the later key's group or `rules` replaced the earlier one's, so a broad key could undo a convention's exception.
|
|
15
|
+
- `boundaries-*`: the `@/`, `#/` and `#services/` prefixes resolve `..` segments, so `#services/chat/../service` reaches the registry check.
|
|
16
|
+
- `react-memo` also reports `R['memo']` and a `{ default as R }` import.
|
|
17
|
+
- Vendored `require-safety-comment-for-type-assertion` matches a `comment` that starts with a non-ASCII letter.
|
|
18
|
+
- `effect-layer-file` takes `suffix`, such as `'Layer'`, to name local layers `<Role>Layer`; it also recognises those names as Layers.
|
|
19
|
+
- `comments-code` takes `steps`: a single `//` line directly above a statement in a function, or above a property in an object literal, stays.
|
|
20
|
+
- `layout-object` takes `params`, which splits a one-line destructured parameter with `min` properties, and `nested`, which splits a one-line object holding an object or function.
|
|
21
|
+
- `layout-call-arguments` takes `pipe: { min }`, which splits a one-line pipe with `min` steps even while `split` is off.
|
|
22
|
+
- `layout-pipe` takes `methods`, and `layout-call-arguments` `pipe.methods`, for pipe methods other than `pipe`.
|
|
23
|
+
- `naming-types` takes `pattern`; `types-local-alias` takes `allow`.
|
|
24
|
+
- `react-dynamic-classes` takes `attributes`; `react-empty-effect` takes `hooks`; `react-memo` takes `names`, `sources` and `message`.
|
|
25
|
+
- Vendored `no-shape-in-symbol-names` takes `terms`; `require-safety-comment-for-type-assertion` takes `comment`.
|
|
26
|
+
- `boundaries-imports`, `boundaries-next` and `boundaries-tanstack` take `conventions` for every file and folder name they read; `boundaries-imports` `portable` also takes a folder name, and `boundaries-tanstack` takes `serverHooks`. The `#services/` prefix follows the services folder.
|
|
27
|
+
- New `layout-type-arguments`: a one-line type argument list holding a union of `min` types puts each type on its own line, each after a leading `|`.
|
|
28
|
+
- `layout-object` `nested` reports without a fix inside a ternary or before a chained call; new `inner` splits an object with `inner` or more entries inside a split object, at every depth; new `siblings` splits an object argument to match a split sibling call in the same array.
|
|
29
|
+
- With `layout-call-arguments` `pipe` set, `join` leaves every pipe as written.
|
|
30
|
+
- `layout-call-arguments` `hug` also reports a call whose argument drops to the next line while `)` stays on it, and splits it fully.
|
|
31
|
+
- `code-inline` no longer asks to inline a top-level value when the result would pass `max` columns or `nesting`.
|
|
32
|
+
- `layout-call-depth` takes `callbacks`, which counts nesting through inline callbacks; `code-inline` takes the same `callbacks`, and the `effect` group sets both.
|
|
33
|
+
|
|
34
|
+
## 0.13.0
|
|
35
|
+
|
|
36
|
+
### Migrating from 0.12
|
|
37
|
+
|
|
38
|
+
Every line an app's config may need to change. A removed option throws ``Unknown option``; the other rows change what detection adds or what a group sets, so read them against your config.
|
|
39
|
+
|
|
40
|
+
| Was | Now |
|
|
41
|
+
| --- | --- |
|
|
42
|
+
| `'apps/server': { orpc: { composers: ['bulkOutput', 'rpcPaginationOutput'] } },` | `'apps/server': { orpc: true },` a plain function around a named schema passes by itself; the line can go where the `backend` recipe applies |
|
|
43
|
+
| `'arch/backend-orpc-output': ['error', { composers: ['bulkOutput'] }]` | `'arch/backend-orpc-output': 'error'` |
|
|
44
|
+
| `'apps/server': { backend: { writes: ['insertInto', 'updateTable', 'deleteFrom', 'mergeInto', 'replaceInto', 'dispatch', 'send', 'publish'] } },` | `'apps/server/src/services/**/*-query.*.ts': { deny: { calls: { publish: 'Query files only read; move writes to an action.' } } },` (`send: false` drops a built-in call) |
|
|
45
|
+
| `'apps/server': { sql: { sanitizers: ['escapeLike'] } },` | `'apps/server/src/services': { rules: { 'arch/backend-sql-like': ['error', { sanitizers: ['escapeLike'] }] } },` |
|
|
46
|
+
| `'apps/web': { forms: { resolver: 'zodResolver' } },` | `'apps/web': { rules: { 'arch/code-paired-call': ['error', { when: 'useForm', require: 'zodResolver' }] } },` |
|
|
47
|
+
| `'apps/web': { externals: { packages: [...externals, 'ai', 'stripe'] } },` | `'apps/web/vite.config.ts': { rules: { 'arch/files-externals': ['error', { packages: [...externals, 'ai', 'stripe'] }] } },` |
|
|
48
|
+
| `'.': { layout: { suffixes: ['prompts', 'driver'] } },` | `'.': { layout: { files: ['*.prompts.ts', '*.driver.ts'] } },` |
|
|
49
|
+
| `'apps/server': { layout: { suffixes: ['gateway'] } },` (the strict name check allowed the name in every app) | `'.': { layout: { files: ['*.gateway.ts'] } },` for every app, or the same line on `'apps/server'` for that app only: the check follows the list of the folder a file is in |
|
|
50
|
+
| `'apps/web': { ...recipes.react, layout: { services: 'flat' } },` on a detected TanStack app (merged with the detected recipe) | `'apps/web': { layout: { services: 'flat' } },` (a recipe you write replaces the detected one, so drop it or write the right one: `{ ...recipes.tanstack, layout: { services: 'flat' } }`) |
|
|
51
|
+
| `'packages/core': { effect: true },` on a workspace that depends on `effect` | the line can go: it is detected, as a backend in Effect style when it has a backend package or `domains/`; `'packages/core': recipes.library` opts out |
|
|
52
|
+
| a React workspace that depends on `effect`, with no `effect` line | it gets `effect: { code: false }` (type assertions, line width, the optional packages) and the four import bans; `'packages/ui': { effect: false }` turns them off |
|
|
53
|
+
| `'.': { deny: { imports: { effect: '…', zod: '…', 'ts-pattern': '…', dayjs: '…' } } },` | the lines can go where the workspace depends on `effect` or uses `recipes.effect`; `deny: { imports: { dayjs: false } }` drops one |
|
|
54
|
+
| `'packages/ui': { deny: { imports: { '@acme/web': '…', '@acme/web/**': '…' } } },` on an Effect UI kit | the line can go: a UI kit with the `effect` group bans every other workspace package that is not a UI kit; `deny: { imports: { '@acme/web': false } }` drops one |
|
|
55
|
+
| a package with `pages/` or `link.tsx`, detected as `ui` | it is detected as `react`; `'packages/x': recipes.ui` keeps the kit |
|
|
56
|
+
| `'.agents': { console: true },` | the line can go; `.agents` uses the default quotes and semicolons, and `'.agents': { style: { quotes: 'double' } }` keeps the root's |
|
|
57
|
+
| `effect: true` relying on width 160 | `effect: { width: 160 }` |
|
|
58
|
+
| `rules: { 'typescript/consistent-type-assertions': ['error', { assertionStyle: 'never' }], 'eslint-js/max-len': ['error', { code: 140, ignoreUrls: true, ignoreComments: true, ignoreRegExpLiterals: true }], 'arch/code-object-params': ['error', { all: true, services: true }], 'arch/code-switch': ['error', { message: 'Branch with Match.' }], 'arch/naming-exports': 'off' }` on an Effect folder | the lines can go: the `effect` group sets them; `rules: { 'typescript/consistent-type-assertions': 'off' }` turns one off |
|
|
59
|
+
| `'arch/backend-sql-like': ['error', { methods: ['like', 'ilike'], operators: ['where'], sanitizers: ['escapeLikeWildcards'] }]` | `'arch/backend-sql-like': 'error'`; a line that set only `sanitizers` now also checks `where` calls, and `operators: []` keeps the old reach |
|
|
60
|
+
| `deny: { imports: { '**/domains/*/!(*.layer.ts)': '…' } }` (the `*` read as a literal, so every file matched) | the same line skips `*.layer.ts`; ban those files with their own entry if you relied on it |
|
|
61
|
+
|
|
62
|
+
Where a config ends up: the whole config of an Effect app with a server, a contract package, a frontend package, a UI kit and a TanStack app ([`examples/effect.oxlint.config.ts`](examples/effect.oxlint.config.ts)).
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
export default preset({
|
|
66
|
+
root: import.meta.dirname,
|
|
67
|
+
folders: {
|
|
68
|
+
'.': { deny: { imports: { '@acme/kit-queues': 'Workflows are the only background primitive.' } } },
|
|
69
|
+
'apps/server/src/domains': {
|
|
70
|
+
deny: { imports: { '@acme/kit-!(contracts)/!(schema|contract)': 'Never a kit driver subpath.' } },
|
|
71
|
+
},
|
|
72
|
+
'alchemy.*.ts': { rules: { 'import-extra/no-relative-packages': 'off' } },
|
|
73
|
+
},
|
|
74
|
+
})
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Added
|
|
78
|
+
|
|
79
|
+
- Preset keys: a key in `folders` can be a list of folders (`src/lib/{dgsi,dr}`), one file (`src/app/default.tsx`) or a file pattern (`apps/server/src/domains/**/*.actions.ts`). A file key takes what a folder takes, except `source`, `services`, `tanstack`, `next`, `expo`, `backend`, `console`, `kit` and `layout.operations`; it changes the settings of the files it matches on top of their folder's, the later of two file keys wins, its `rules` come after every folder's, and `false` ignores its files. A missing literal file throws; a pattern that matches nothing does not. A folder written alone and inside a folder list (`'packages/ui'` and `'packages/{ui,frontend}'`) merges in config order instead of throwing "listed twice".
|
|
80
|
+
- `layout.files`: the file names a folder's service layout allows, such as `['*.prompts.ts', '*.gateway.ts', '!*.utils.ts']`. The list adds to the parent folder's list, starting from the built-in names (`*.service.ts`, `*.client.ts`, `*.server.ts`, `*.rsc.ts`, `*.rsc.tsx`, `*.utils.ts`, `*.types.ts`, `*.constants.ts`, `*.handler.ts`, `*.test.ts`, `*.spec.ts`, `*-action.*.ts`, `*-query.*.ts`); `!name` removes one. A `*.<word>.ts` name that is not built-in gets every check a `layout.suffixes` word got.
|
|
81
|
+
- Detection may add file keys; an app's file key with the same key merges over it, and `layout.files` lists from a convention and the app add up.
|
|
82
|
+
- Effect server conventions: a unit with the `effect` group whose source holds `domains/` gets the backend recipe's groups with `services: 'domains'`, and detection adds its conventions as folder and file keys: the domain file names, export names for actions and queries, 1,000-line actions and queries, no writes or actions imports in queries, the layer file rule on layer and driver files, no query builder or database in workflows, no types or inline object shapes (with `types: { placement: false }` on the unit, so the `types` group's placement advice stays off), no functions in constants files, no web frameworks, `effect/Config` only in `application/app.config.ts`, layers and workflows only into `application/app.ts`, JSX only in `mails/*.mail.tsx`, docblocks on functions (`arch/comments-code` with `jsdoc: true`) and delegating `rpc` handlers. Each key can be restated to extend, override or turn off.
|
|
83
|
+
- Effect contract conventions: a unit with the `effect` group whose source holds a `<d>/<d>.contract.ts` gets file keys for its file names, folder-prefixed file names, domain-prefixed exports (`Admin` first in admin files, a plural folder drops its `s`), constants and types only in schemas and contract files (a function, exported or local, reported once by `arch/files-no-functions`; functions allowed in `shared/` and `contract*.ts`), no functions in errors and layer types files, `arch/types-imported-alias` and `arch/schemas-single-use` for `Schema`, and `types: { placement: false }` on the unit. Each key can be restated to extend, override or turn off.
|
|
84
|
+
- Effect error classes: every unit with the `effect` group denies `Schema.TaggedError`, `Schema.ErrorClass`, `Data.TaggedError` and `Data.Error` outside `*.errors.ts`.
|
|
85
|
+
- Frontend package conventions: a React package with the `effect` group and `pages/` or `link.tsx` gets `forms`, `arch/react-query-props`, an `@orpc/*` ban, the router only through `link.tsx` (`ClientOnly` allowed) and frontend client services. In a project with a contract package, a TanStack or Next app imports the contract's root entry as types only. A UI kit with the `effect` group bans the other workspace packages.
|
|
86
|
+
- `effect` group: `code` option (default `true`); with `false` only the project style runs (`typescript/consistent-type-assertions`, `eslint-js/max-len`) and the two Effect packages are not needed. A React package or framework app that depends on `effect` gets `effect: { code: false }`.
|
|
87
|
+
- `effect` group: loads `eslint-plugin-regexp` (`flat/recommended`), `eslint-plugin-de-morgan` (`recommended`) and `eslint-plugin-sonarjs` (`sonarjs/super-linear-regex`) when each is installed; all three are optional peer dependencies.
|
|
88
|
+
- Every unit with the `effect` group on, in either mode (detected for a workspace that depends on `effect`), and `recipes.effect` ban the `effect` root, `zod`, `ts-pattern` and `dayjs` imports; `effect: false` drops them.
|
|
89
|
+
- `arch/code-delegate`: a handler (a function passed to a call ending in `methods`, default `handler` and `effect`) only reads its services, makes at most `max` (default `1`) yielded or awaited calls and returns. Any other statement, a call past `max`, a ternary and a nested function are reported. `reads` (default `['Effect.serviceOption']`) names calls that read a service. The Effect server conventions turn it on for `rpc`.
|
|
90
|
+
- `arch/react-query-props`: the data function given to a query hook (`hooks`, default `useQuery`, `useMutation`, `useInfiniteQuery`, `useSuspenseQuery`) under one of `functions` (default `queryFn`, `mutationFn`) is a prop of the enclosing component or hook, or a function that calls one; options that are not an object literal, or hold a spread, are reported. The frontend package conventions turn it on.
|
|
91
|
+
- `arch/files-exports`: `stem: 'folder'` reads the domain from the folder the file is in (`supplier-order/` gives `SupplierOrder`), and `singularize: 'trailing-s'` drops a trailing `s` from the domain's last word (`automatic-orders` gives `AutomaticOrder`). Defaults unchanged.
|
|
92
|
+
- `arch/types-inline`: `variables` (variable and class property annotations), `assertions` (`as` and `satisfies`) and `arguments` (type arguments of calls and `new`), each default `false`; `functions` and `min` apply to them too.
|
|
93
|
+
- `arch/types-declarations`: `modules` (default `false`) allows a `type` or `interface` inside `declare module '…' {}` or `declare global {}`.
|
|
94
|
+
- `arch/code-trivial-functions`: `defaults` (default `true`); with `false`, the file's default export is not checked, whether a named declaration, an anonymous function or a name exported as default below its declaration.
|
|
95
|
+
|
|
96
|
+
### Changed
|
|
97
|
+
|
|
98
|
+
- **Breaking:** `arch/backend-orpc-output` has no `composers` option. `.output(X)` passes when `X` is a named schema or a plain function called with one (`paged(Order)`, `eventIterator(Order)`); a member call (`z.array(Order)`), a nested call, an inline object and no argument are reported. `'arch/backend-orpc-output': 'error'` is complete.
|
|
99
|
+
- **Breaking:** `arch/backend-sql-like` requires no option: `methods` defaults to `['like', 'ilike']`, `sanitizers` to `['escapeLikeWildcards']` and `operators` to `['where']` (was `[]`), so `'arch/backend-sql-like': 'error'` is complete and setting one option keeps the others.
|
|
100
|
+
- **Breaking:** the strict layout name check follows the `layout.files` list of the folder a file is in: a name listed on `apps/server` is no longer allowed in another app. It leaves out `*-action.*.ts` and `*-query.*.ts` files only while the list holds those names. Its message is now `Domain files use one of: <names>. Add a name to layout.files.`
|
|
101
|
+
- **Breaking:** a folder set to a recipe (as is or spread) no longer merges with the recipe detection picked; `'.'` keeps its `framer-motion` ban. A hand-written folder still merges.
|
|
102
|
+
- **Breaking:** detection picks `effect` for a workspace that depends on `effect` and is not a framework, desktop or React package; with a backend package or a `domains/` folder it is a backend in Effect style (the `backend` recipe with `effect` over it) and keeps every backend check.
|
|
103
|
+
- **Breaking:** a React package with `pages/` or `link.tsx` (or `link.ts`) in its source is detected as `react`, not `ui`, wherever it lives, and gets a flat `services/` when it holds more files than folders; `pages/` and the link file also make a React package without `components/` count.
|
|
104
|
+
- `.agents` is detected: it gets the `cli` recipe with the default quotes and semicolons, whatever the root sets.
|
|
105
|
+
- The `backend` recipe turns on the `orpc` group; it still checks only `orpc.public`, which defaults to `<backend source>/rpc/api/**` when that folder exists. `orpc: false` turns it off.
|
|
106
|
+
- The `basics` group gives a Next app's `app/**/{layout,page,default}.tsx` files `arch/code-trivial-functions` with `defaults: false`, so their default export may be trivial. Lines like `'src/app': { rules: { 'arch/code-trivial-functions': ['error', { …, allow: '^(RootLayout|CatchAllPage)$' }] } }` and `'src/app/default.tsx': { rules: { 'arch/code-trivial-functions': 'off' } }` can go; they still win when kept.
|
|
107
|
+
- **Breaking:** the `effect` group's `width` defaults to 140 (was 160).
|
|
108
|
+
- **Breaking:** the `effect` group sets `typescript/consistent-type-assertions` (`assertionStyle: 'never'`), `eslint-js/max-len` at its width, `arch/code-object-params` (`all: true, services: true`), `arch/code-switch` ("Branch with Match.") and turns `arch/naming-exports` off.
|
|
109
|
+
- `boundaries-deny` and `files-externals` globs: a `*` inside `!(…)` matches within the segment, so `!(*.layer.ts)` is any segment not ending in `.layer.ts`.
|
|
110
|
+
|
|
111
|
+
### Removed
|
|
112
|
+
|
|
113
|
+
- **Breaking:** the preset's `layout.suffixes` option; setting it throws ``Unknown option `layout.suffixes`.``
|
|
114
|
+
- **Breaking:** the preset's `backend.writes` option; setting it throws ``Unknown option `backend.writes`.`` Query files still may not call `insertInto`, `updateTable`, `deleteFrom`, `mergeInto`, `replaceInto`, `dispatch` or `send`.
|
|
115
|
+
- **Breaking:** the preset's `sql.sanitizers` option; setting it throws ``Unknown option `sql.sanitizers`.`` `sql` takes `true`, `false` or `'warn'`.
|
|
116
|
+
- **Breaking:** the preset's `forms.resolver` option; setting it throws ``Unknown option `forms.resolver`.`` `forms` takes `true`, `false` or `'warn'`.
|
|
117
|
+
- **Breaking:** the preset's `externals.packages` option; setting it throws ``Unknown option `externals.packages`.`` `externals` takes `true`, `false` or `'warn'`; the `externals` list stays exported.
|
|
118
|
+
- **Breaking:** the preset's `orpc.composers` option; setting it throws ``Unknown option `orpc.composers`.``
|
|
119
|
+
|
|
120
|
+
### Fixed
|
|
121
|
+
|
|
122
|
+
- Migration numbers read a dated prefix whole (`2026-11-12`, with optional `-HH`, `-mm`, `-ss` parts), so two dated migrations of the same year are no longer duplicates; other names read as before.
|
|
123
|
+
|
|
3
124
|
## 0.12.6
|
|
4
125
|
|
|
5
126
|
### Added
|
package/README.md
CHANGED
|
@@ -57,19 +57,19 @@ On by default: [`layout`](docs/groups/layout.md), [`limits`](docs/groups/limits.
|
|
|
57
57
|
|
|
58
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), [`effect`](docs/groups/effect.md), [`console`](docs/groups/console.md).
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
84 rules, IDs `arch/<rule>`. 🔧 = autofix.
|
|
61
61
|
|
|
62
62
|
| Family | Covers | Rules |
|
|
63
63
|
| --- | --- | --- |
|
|
64
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
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-branch-once`](docs/rules/code-branch-once.md), [`code-constructor`](docs/rules/code-constructor.md), [`code-double-negation`](docs/rules/code-double-negation.md), [`code-function-nesting`](docs/rules/code-function-nesting.md), [`code-inline`](docs/rules/code-inline.md), [`code-justified-call`](docs/rules/code-justified-call.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-traced`](docs/rules/code-traced.md), [`code-trivial-functions`](docs/rules/code-trivial-functions.md), [`code-yield-argument`](docs/rules/code-yield-argument.md) |
|
|
66
|
+
| `code` | Code shapes to avoid | [`code-branch-once`](docs/rules/code-branch-once.md), [`code-constructor`](docs/rules/code-constructor.md), [`code-delegate`](docs/rules/code-delegate.md), [`code-double-negation`](docs/rules/code-double-negation.md), [`code-function-nesting`](docs/rules/code-function-nesting.md), [`code-inline`](docs/rules/code-inline.md), [`code-justified-call`](docs/rules/code-justified-call.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-traced`](docs/rules/code-traced.md), [`code-trivial-functions`](docs/rules/code-trivial-functions.md), [`code-yield-argument`](docs/rules/code-yield-argument.md) |
|
|
67
67
|
| `comments` | Comments and directives | [`comments-code`](docs/rules/comments-code.md) 🔧, [`comments-directives`](docs/rules/comments-directives.md) |
|
|
68
68
|
| `copy` | User-facing text | [`copy-dashes`](docs/rules/copy-dashes.md) |
|
|
69
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-arrow-body`](docs/rules/layout-arrow-body.md) 🔧, [`layout-call-arguments`](docs/rules/layout-call-arguments.md) 🔧, [`layout-call-array`](docs/rules/layout-call-array.md) 🔧, [`layout-call-depth`](docs/rules/layout-call-depth.md), [`layout-chain`](docs/rules/layout-chain.md) 🔧, [`layout-items`](docs/rules/layout-items.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-pipe`](docs/rules/layout-pipe.md), [`layout-ternary`](docs/rules/layout-ternary.md) 🔧 |
|
|
70
|
+
| `layout` | Layout a formatter leaves alone | [`layout-arrow-body`](docs/rules/layout-arrow-body.md) 🔧, [`layout-call-arguments`](docs/rules/layout-call-arguments.md) 🔧, [`layout-call-array`](docs/rules/layout-call-array.md) 🔧, [`layout-call-depth`](docs/rules/layout-call-depth.md), [`layout-chain`](docs/rules/layout-chain.md) 🔧, [`layout-items`](docs/rules/layout-items.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-pipe`](docs/rules/layout-pipe.md), [`layout-ternary`](docs/rules/layout-ternary.md) 🔧, [`layout-type-arguments`](docs/rules/layout-type-arguments.md) 🔧 |
|
|
71
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) |
|
|
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), [`react-query-props`](docs/rules/react-query-props.md) |
|
|
73
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
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
75
|
| `types` | Type placement and shape | [`types-declarations`](docs/rules/types-declarations.md), [`types-duplicate`](docs/rules/types-duplicate.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) |
|