Skip to content

@kontsedal/olas-eslint-plugin ​

ESLint rules for Olas apps. Each rule catches a mistake the types cannot see, such as a React hook in a controller factory, a definition that loses its identity or an async factory. Another keeps test helpers out of app code, and two rules guard optimistic writes. Two opt-in rules keep network calls out of components and make each request take its abort signal.

Install ​

bash
pnpm add -D @kontsedal/olas-eslint-plugin eslint

eslint >= 9 is a peer dependency, and the plugin uses flat config. The tests run on ESLint 10. The rules read syntax only, so they need no type information. TypeScript files still need a parser, such as the one typescript-eslint sets up.

Setup ​

js
// eslint.config.js
import olas from '@kontsedal/olas-eslint-plugin'
import tseslint from 'typescript-eslint'

export default [...tseslint.configs.recommended, olas.configs.recommended]

olas.configs.strict adds the two opt-in rules and raises cancel-before-optimistic to an error.

The configs are typed with ESLint's own Linter.Config, so a typed eslint.config.ts accepts them as they are, in an array or through defineConfig. Each rule is named with the olas/ prefix, so one rule can be set on its own after a config:

js
export default [
  ...tseslint.configs.recommended,
  olas.configs.recommended,
  { rules: { 'olas/no-network-in-components': 'error' } },
]

Rules ​

RulerecommendedstrictCatches
no-react-hooks-in-controllerserrorerrorA React hook inside a defineController factory.
define-at-module-scopeerrorerrordefineQuery, defineInfiniteQuery, defineMutation or defineScope inside a function.
no-async-controller-factoryerrorerrorAn async factory, which makes the controller's api a promise.
optimistic-returns-snapshoterrorerrorA setData snapshot that onMutate does not return, or that other code discards.
cancel-before-optimisticwarnerrorAn optimistic setData in onMutate with no cancel on the same query before it.
no-testing-outside-testserrorerror@kontsedal/olas-core/testing imported from a file that is not a test.
no-network-in-componentsofferrorfetch or axios inside a React component.
honor-abort-signalofferrorA fetcher or mutate that does not read its signal, so a cancelled request runs to the end.

Two rules take options. no-testing-outside-tests takes testFiles, the globs that count as tests. honor-abort-signal takes ignorePattern, for a context whose name marks work with nothing to abort, such as _ctx.

How it is checked ​

  • tests/rules.test.ts runs every rule through @typescript-eslint/rule-tester, with valid and invalid cases.
  • tests/examples.test.ts runs recommended and strict over the source and tests of every example app in this repo, and expects no findings. The first run found four real mistakes in the examples: three optimistic writes with no cancel first, and one leaked snapshot. It also found two false positives in define-at-module-scope. All six are fixed.

Released under the MIT License.