-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patheslint.config.ts
More file actions
63 lines (62 loc) · 3.73 KB
/
Copy patheslint.config.ts
File metadata and controls
63 lines (62 loc) · 3.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import js from '@eslint/js';
import globals from 'globals';
import tseslint from 'typescript-eslint';
import noPointlessReassignment from './eslint-rules/no-pointless-reassignment.js';
import noSideEffectsInIndex from './eslint-rules/no-side-effects-in-index.js';
export default tseslint.config(
{
// test/smoke.test.mjs imports from ../dist, a build artefact that may not exist at lint time and is deliberately outside tsconfig's "src" program (it tests the built output, not the source) -- see its own top-of-file comment and CLAUDE.md.
ignores: ['dist', 'coverage', 'node_modules', 'test'],
},
{
// Pin the TSConfig root so the parser isn't confused by stray tsconfig.json files elsewhere in the tree. Required because lint-staged runs eslint at commit time.
//
// `projectService` (global -- no `files` filter) powers the type-checked rules below; it must apply to every matched file or the type-checked configs crash on files outside the program.
languageOptions: {
parserOptions: { projectService: true, tsconfigRootDir: import.meta.dirname },
globals: { ...globals.node },
},
},
js.configs.recommended,
...tseslint.configs.recommended,
// Type-checked tier: catches floating promises, misused async handlers, unsafe `any`, and invalid template expressions. Requires the `projectService` parser option set above.
...tseslint.configs.recommendedTypeChecked,
...tseslint.configs.stylisticTypeChecked,
{
// No inline eslint-disable / config comments anywhere -- an exception belongs in this file, scoped to the file or line it actually applies to, not hidden in the source it's disabling a rule for.
linterOptions: { noInlineConfig: true },
},
{
rules: {
// No type assertions anywhere: narrow with a guard or parse with Zod instead.
'@typescript-eslint/consistent-type-assertions': ['error', { assertionStyle: 'never' }],
'@typescript-eslint/consistent-type-imports': ['error', { fixStyle: 'inline-type-imports' }],
},
},
{
// Local custom rules (eslint-rules/*.ts) -- not published as a package, matching this family's own convention of keeping shared dev-tooling config as identical per-repo copies rather than a shared devDependency.
plugins: { local: { rules: { 'no-pointless-reassignment': noPointlessReassignment, 'no-side-effects-in-index': noSideEffectsInIndex } } },
rules: { 'local/no-pointless-reassignment': 'error' },
},
{
// The structural counterpart to the re-export ban below: that rule says re-exports belong only in src/index.ts, this one says src/index.ts may contain only re-exports -- together pinning the barrel to exactly one shape, one that can never have a side effect at import time.
files: ['src/index.ts'],
rules: { 'local/no-side-effects-in-index': 'error' },
},
{
// Re-exports belong only in src/index.ts, the public barrel -- a re-export anywhere else risks silently surfacing the wrong thing under a name a consumer expects to mean something else.
files: ['src/**/*.ts'],
ignores: [
'src/index.ts',
// A deliberate, pre-existing canonical re-export point: document-schema.js's Alignment/AlignmentSchema already IS ODF's paragraph-alignment vocabulary one-for-one, so this file re-exports it as the one place a reader looks for "ODF alignment" rather than duplicating it.
'src/typed/shared/style.ts',
],
rules: {
'no-restricted-syntax': [
'error',
{ selector: 'ExportAllDeclaration', message: 'Re-exports belong only in src/index.ts (the public barrel). Define or import this locally instead.' },
{ selector: 'ExportNamedDeclaration[source]', message: 'Re-exports belong only in src/index.ts (the public barrel). Define or import this locally instead.' },
],
},
},
);