@useinsider/eslint-config 1.13.0-beta.4 → 1.13.0-beta.6

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.
Files changed (84) hide show
  1. package/README.md +367 -58
  2. package/dist/builders/jquery.d.ts +5 -0
  3. package/dist/builders/scopeBlocks.d.ts +40 -0
  4. package/dist/builders/spellChecker.d.ts +7 -0
  5. package/dist/builders/strict.d.ts +2 -0
  6. package/dist/builders/typescript.d.ts +6 -0
  7. package/dist/builders/vue.d.ts +8 -0
  8. package/dist/cli.cjs +1984 -0
  9. package/dist/cli.cjs.map +1 -0
  10. package/dist/configs/vitest/index.d.ts +3 -0
  11. package/dist/{javascript-BXgxOHrE.js → javascript-DRBDZ53G.js} +2 -2
  12. package/dist/{javascript-BXgxOHrE.js.map → javascript-DRBDZ53G.js.map} +1 -1
  13. package/dist/{javascript-ZbGsFE17.cjs → javascript-Dgd5YZ4v.cjs} +2 -2
  14. package/dist/{javascript-ZbGsFE17.cjs.map → javascript-Dgd5YZ4v.cjs.map} +1 -1
  15. package/dist/{javascript-dom-DQiJS6LF.js → javascript-dom-BUo0oazt.js} +2 -2
  16. package/dist/{javascript-dom-DQiJS6LF.js.map → javascript-dom-BUo0oazt.js.map} +1 -1
  17. package/dist/{javascript-dom-D7RX0w0r.cjs → javascript-dom-DY-dVg10.cjs} +2 -2
  18. package/dist/{javascript-dom-D7RX0w0r.cjs.map → javascript-dom-DY-dVg10.cjs.map} +1 -1
  19. package/dist/{javascript-node-fII8MlI4.cjs → javascript-node-B2q-5MCV.cjs} +2 -2
  20. package/dist/{javascript-node-fII8MlI4.cjs.map → javascript-node-B2q-5MCV.cjs.map} +1 -1
  21. package/dist/{javascript-node-DDpIBysN.js → javascript-node-Cdx69Dtd.js} +2 -2
  22. package/dist/{javascript-node-DDpIBysN.js.map → javascript-node-Cdx69Dtd.js.map} +1 -1
  23. package/dist/{jest-B0jgh-Ns.js → jest-CHnGdlOz.js} +1 -1
  24. package/dist/{jest-B0jgh-Ns.js.map → jest-CHnGdlOz.js.map} +1 -1
  25. package/dist/{jest-Ct_2c2e5.cjs → jest-Cxug-2aj.cjs} +1 -1
  26. package/dist/{jest-Ct_2c2e5.cjs.map → jest-Cxug-2aj.cjs.map} +1 -1
  27. package/dist/{jsdoc-based-ts-B40HFdNC.js → jsdoc-based-ts-11d7Q2xg.js} +1 -1
  28. package/dist/{jsdoc-based-ts-B40HFdNC.js.map → jsdoc-based-ts-11d7Q2xg.js.map} +1 -1
  29. package/dist/{jsdoc-based-ts-De6bAjFn.cjs → jsdoc-based-ts-CH0bJyiQ.cjs} +1 -1
  30. package/dist/{jsdoc-based-ts-De6bAjFn.cjs.map → jsdoc-based-ts-CH0bJyiQ.cjs.map} +1 -1
  31. package/dist/main.cjs +194 -52
  32. package/dist/main.cjs.map +1 -1
  33. package/dist/main.d.ts +49 -21
  34. package/dist/main.js +193 -52
  35. package/dist/main.js.map +1 -1
  36. package/dist/{removePluginsFromConfigs-v7vbA7i9.cjs → removePluginsFromConfigs-C6hBiYhB.cjs} +1 -1
  37. package/dist/{removePluginsFromConfigs-v7vbA7i9.cjs.map → removePluginsFromConfigs-C6hBiYhB.cjs.map} +1 -1
  38. package/dist/{removePluginsFromConfigs-D2glsmDB.js → removePluginsFromConfigs-CZVb8Llj.js} +1 -1
  39. package/dist/{removePluginsFromConfigs-D2glsmDB.js.map → removePluginsFromConfigs-CZVb8Llj.js.map} +1 -1
  40. package/dist/{strict-BfeS2xp_.js → strict-BCDy_p79.js} +1 -1
  41. package/dist/{strict-BfeS2xp_.js.map → strict-BCDy_p79.js.map} +1 -1
  42. package/dist/{strict-TbDHFSQX.cjs → strict-xrB0PqHI.cjs} +1 -1
  43. package/dist/{strict-TbDHFSQX.cjs.map → strict-xrB0PqHI.cjs.map} +1 -1
  44. package/dist/{stylistic-Cca81A-Y.js → stylistic-Bwo1XLKa.js} +1 -1
  45. package/dist/{stylistic-Cca81A-Y.js.map → stylistic-Bwo1XLKa.js.map} +1 -1
  46. package/dist/{stylistic-BltudTa0.cjs → stylistic-xuXbfq-L.cjs} +1 -1
  47. package/dist/{stylistic-BltudTa0.cjs.map → stylistic-xuXbfq-L.cjs.map} +1 -1
  48. package/dist/{typescript-Z0gBgZeY.js → typescript-B2c32sBy.js} +4 -4
  49. package/dist/{typescript-Z0gBgZeY.js.map → typescript-B2c32sBy.js.map} +1 -1
  50. package/dist/{typescript-RDy5oH7o.cjs → typescript-BRmCnG0B.cjs} +4 -4
  51. package/dist/{typescript-RDy5oH7o.cjs.map → typescript-BRmCnG0B.cjs.map} +1 -1
  52. package/dist/{typescript-dom-BFinGO4G.js → typescript-dom-C_rK3dMI.js} +2 -2
  53. package/dist/{typescript-dom-BFinGO4G.js.map → typescript-dom-C_rK3dMI.js.map} +1 -1
  54. package/dist/{typescript-dom-DUh1spmb.cjs → typescript-dom-DJBBaMuh.cjs} +2 -2
  55. package/dist/{typescript-dom-DUh1spmb.cjs.map → typescript-dom-DJBBaMuh.cjs.map} +1 -1
  56. package/dist/{typescript-node-ClKSHtBn.cjs → typescript-node-DFd38ywl.cjs} +2 -2
  57. package/dist/{typescript-node-ClKSHtBn.cjs.map → typescript-node-DFd38ywl.cjs.map} +1 -1
  58. package/dist/{typescript-node-B3akGwfD.js → typescript-node-Dw6QK1Du.js} +2 -2
  59. package/dist/{typescript-node-B3akGwfD.js.map → typescript-node-Dw6QK1Du.js.map} +1 -1
  60. package/dist/vitest-B-ezG20C.js +15 -0
  61. package/dist/vitest-B-ezG20C.js.map +1 -0
  62. package/dist/vitest-C66eWJuY.cjs +17 -0
  63. package/dist/vitest-C66eWJuY.cjs.map +1 -0
  64. package/dist/{vue2-DDKBhsLm.js → vue2-0JUzcNg8.js} +2 -2
  65. package/dist/{vue2-DDKBhsLm.js.map → vue2-0JUzcNg8.js.map} +1 -1
  66. package/dist/{vue2-Bh7W369C.cjs → vue2-BxcLGel4.cjs} +2 -2
  67. package/dist/{vue2-Bh7W369C.cjs.map → vue2-BxcLGel4.cjs.map} +1 -1
  68. package/dist/{vue2-typescript-CUqjxRHT.js → vue2-typescript-DnQmxB-V.js} +3 -3
  69. package/dist/{vue2-typescript-CUqjxRHT.js.map → vue2-typescript-DnQmxB-V.js.map} +1 -1
  70. package/dist/{vue2-typescript-GmtjjCxx.cjs → vue2-typescript-cGnAnPPW.cjs} +3 -3
  71. package/dist/{vue2-typescript-GmtjjCxx.cjs.map → vue2-typescript-cGnAnPPW.cjs.map} +1 -1
  72. package/dist/{vue3-BtNhSn_w.cjs → vue3-MaplnXCl.cjs} +2 -2
  73. package/dist/{vue3-BtNhSn_w.cjs.map → vue3-MaplnXCl.cjs.map} +1 -1
  74. package/dist/{vue3-CKwnKeS6.js → vue3-k9qGx747.js} +2 -2
  75. package/dist/{vue3-CKwnKeS6.js.map → vue3-k9qGx747.js.map} +1 -1
  76. package/dist/{vue3-typescript-P2UoKs0V.cjs → vue3-typescript-CgYTdvL7.cjs} +3 -3
  77. package/dist/{vue3-typescript-P2UoKs0V.cjs.map → vue3-typescript-CgYTdvL7.cjs.map} +1 -1
  78. package/dist/{vue3-typescript-CbM4dYzN.js → vue3-typescript-DD8QAZnh.js} +3 -3
  79. package/dist/{vue3-typescript-CbM4dYzN.js.map → vue3-typescript-DD8QAZnh.js.map} +1 -1
  80. package/package.json +6 -1
  81. package/dist/config-ByQJiSMj.cjs +0 -9
  82. package/dist/config-ByQJiSMj.cjs.map +0 -1
  83. package/dist/config-Css2Pu_R.js +0 -9
  84. package/dist/config-Css2Pu_R.js.map +0 -1
package/README.md CHANGED
@@ -1,97 +1,406 @@
1
- # ESLint Configurations
1
+ # @useinsider/eslint-config
2
+
3
+ Shared ESLint 9 flat-config for Insider projects. `useInsider()` takes a single
4
+ scope-keyed config object and returns a `defineConfig([...])` array — one
5
+ entry per file scope you describe. There is no opaque preset list, no
6
+ freeform `config` escape hatch, and no expectation that you spread the result
7
+ into your own array.
8
+
9
+ The default export is the resolved Promise returned by `useInsider(...)`;
10
+ ESLint 9 awaits it automatically. **Do not `await` it. Do not spread it. Do
11
+ not wrap it in an array.** If you find yourself wanting to append a block,
12
+ that is a sign your scope coverage is incomplete — describe the extra files
13
+ inside `useInsider({...})` instead.
2
14
 
3
15
  ## Table of Contents
4
- - [ESLint Configurations](#eslint-configurations)
5
- - [Table of Contents](#table-of-contents)
6
- - [Prerequisites](#prerequisites)
7
- - [Available Presets](#available-presets)
8
- - [Vanilla 🍦](#vanilla-)
9
- - [Library-specific \& Standalone Configs](#library-specific--standalone-configs)
10
- - [Framework-specific](#framework-specific)
11
- - [ Upcoming Configurations](#-upcoming-configurations)
12
- - [Examples](#examples)
13
- - [Troubleshooting](#troubleshooting)
14
- - [`Missing dependencies detected:`](#missing-dependencies-detected)
15
- - [Contributing](#contributing)
16
+
17
+ - [Prerequisites](#prerequisites)
18
+ - [Quick start](#quick-start)
19
+ - [Manual setup](#manual-setup)
20
+ - [Node + TypeScript](#node--typescript)
21
+ - [Browser + Vue 3 + TypeScript with split tsconfigs](#browser--vue-3--typescript-with-split-tsconfigs)
22
+ - [Vue 2 + JavaScript with jQuery globals](#vue-2--javascript-with-jquery-globals)
23
+ - [Strict and spell-checker knobs](#strict-and-spell-checker-knobs)
24
+ - [API reference](#api-reference)
25
+ - [Migrating from v1.x](#migrating-from-v1x)
26
+ - [First lint after install](#first-lint-after-install)
27
+ - [Troubleshooting](#troubleshooting)
28
+ - [Contributing](#contributing)
16
29
 
17
30
  ## Prerequisites
18
31
 
19
- - NodeJS 20+
32
+ - Node.js 20+
20
33
  - ESLint 9+
34
+ - pnpm, npm, or yarn
35
+
36
+ ## Quick start
37
+
38
+ ```bash
39
+ npx @useinsider/eslint-config
40
+ ```
41
+
42
+ The CLI walks an interactive prompt (project type, language, framework, test
43
+ runner, jQuery globals, tsconfig layout), installs every required ESLint
44
+ plugin pinned to the versions this package was built against, and writes a
45
+ starter `eslint.config.mjs` at the project root.
46
+
47
+ To migrate an existing v1 `eslint.config.{js,mjs,cjs}` or a legacy
48
+ `.eslintrc.{js,cjs}`:
49
+
50
+ ```bash
51
+ npx @useinsider/eslint-config migrate [path]
52
+ ```
53
+
54
+ The migrate flow auto-detects the source format. For flat configs it
55
+ parses the v1 file, prints a summary plus any dropped custom rules, asks
56
+ for confirmation, then rewrites the file in place. For legacy `.eslintrc`
57
+ files it writes a fresh `eslint.config.mjs` next to the original (custom
58
+ rules and non-`@useinsider/eslint-config/*` extends are dropped with a
59
+ loud warning so you can review what changed). The original is backed up
60
+ in both cases as `eslint.config.v1-backup.<ext>` or
61
+ `.eslintrc.v1-backup.<ext>`. Legacy `.eslintrc.{json,yml,yaml}` are not
62
+ supported in this release — convert them to `.eslintrc.{js,cjs}` first.
63
+
64
+ Example output for a Node + TypeScript project:
65
+
66
+ ```js
67
+ import { useInsider } from '@useinsider/eslint-config';
68
+
69
+ export default useInsider({
70
+ typescriptNode: [
71
+ {
72
+ files: ['**/*.{ts,tsx}'],
73
+ tsconfigPaths: ['tsconfig.json'],
74
+ },
75
+ ],
76
+ });
77
+ ```
78
+
79
+ What the CLI installs for that answer set (versions reflect the publish-time
80
+ pins):
81
+
82
+ - `@useinsider/eslint-config`
83
+ - `eslint`
84
+ - `globals`
85
+ - `typescript`
86
+ - `typescript-eslint`
21
87
 
22
- ## Available Presets
88
+ Vue, Jest, or Vitest answers add the matching plugin set (e.g. `eslint-plugin-vue`,
89
+ `vue-eslint-parser`, `eslint-plugin-vue-scoped-css`, `@vue/eslint-config-typescript`,
90
+ `@rushstack/eslint-patch`, `eslint-plugin-jest`, or `@vitest/eslint-plugin`).
23
91
 
24
- We provide a variety of configurations to suit different environments and
25
- frameworks. Here's a list of available presets:
92
+ ## Manual setup
26
93
 
27
- ### Vanilla 🍦
94
+ Install the package first:
28
95
 
29
- There are additional presets for DOM (browser) and Node.js environments, beside
30
- the vanilla configuration. The vanilla is suitable for general JavaScript and
31
- TypeScript projects that does not have any specific environment and can be
32
- configured for different environments, such as ServiceWorkers, WebWorkers, etc.
96
+ ```bash
97
+ pnpm add -E -D @useinsider/eslint-config
98
+ ```
99
+
100
+ Then create `eslint.config.mjs` and call `useInsider(...)` with the scopes
101
+ your project needs. Each scope holds an array of `{ files, ... }` entries;
102
+ each entry becomes its own flat-config block.
103
+
104
+ ### Node + TypeScript
105
+
106
+ ```js
107
+ import { useInsider } from '@useinsider/eslint-config';
108
+
109
+ export default useInsider({
110
+ typescriptNode: [
111
+ {
112
+ files: ['**/*.{ts,tsx}'],
113
+ tsconfigPaths: ['tsconfig.json'],
114
+ },
115
+ ],
116
+ vitest: [
117
+ { files: ['**/*.{test,spec}.{ts,tsx}'] },
118
+ ],
119
+ });
120
+ ```
121
+
122
+ ### Browser + Vue 3 + TypeScript with split tsconfigs
123
+
124
+ A project using `tsconfig.app.json` for source and `tsconfig.test.json` for
125
+ tests, with `RouterLink` and `RouterView` as globally-registered components.
33
126
 
34
- | Environment | Vanilla | Browser (DOM) | Node |
35
- | :---------------- | :---------------------------------------------- | :------------------------------------------------------ | :-------------------------------------------------------- |
36
- | **EcmaScript/JS** | [`javascript`](./src/configs/javascript#readme) | [`javascript-dom`](./src/configs/javascript-dom#readme) | [`javascript-node`](./src/configs/javascript-node#readme) |
37
- | **TypeScript** | [`typescript`](./src/configs/typescript#readme) | [`typescript-dom`](./src/configs/typescript-dom#readme) | [`typescript-node`](./src/configs/typescript-node#readme) |
127
+ ```js
128
+ import { useInsider } from '@useinsider/eslint-config';
38
129
 
39
- ### Library-specific & Standalone Configs
130
+ export default useInsider({
131
+ vue3Typescript: [
132
+ {
133
+ files: ['src/**/*.{ts,tsx,vue}'],
134
+ tsconfigPaths: ['tsconfig.app.json'],
135
+ globalComponents: ['RouterLink', 'RouterView'],
136
+ },
137
+ ],
138
+ vitest: [
139
+ {
140
+ files: ['**/*.{test,spec}.{ts,tsx}'],
141
+ },
142
+ ],
143
+ typescriptNode: [
144
+ {
145
+ files: ['*.config.{ts,mts,cts}'],
146
+ tsconfigPaths: ['tsconfig.node.json'],
147
+ },
148
+ ],
149
+ });
150
+ ```
40
151
 
41
- | Environment | JavaScript & TypeScript |
42
- | :--------------- | :-------------------------------------- |
43
- | **Config files** | [`config`](./src/configs/config#readme) |
44
- | **Jest** | [`jest`](./src/configs/jest#readme) |
45
- | **Strict** | [`strict`](./src/configs/strict#readme) |
152
+ Multiple `tsconfigPaths` entries are supported per block — pass an array of
153
+ paths if a single scope needs more than one project reference.
46
154
 
47
- ### Framework-specific
155
+ ### Vue 2 + JavaScript with jQuery globals
48
156
 
49
- | Environment | JavaScript | TypeScript |
50
- | :-------------------------------- | :-------------------------------------------------------- | :-------------------------------------------------------- |
51
- | **Vue 3 (Setup/Composition API)** | [`vue3`](./src/configs/vue3#readme) | [`vue3-typescript`](./src/configs/vue3-typescript#readme) |
52
- | **Vue 2 (Setup/Composition API)** | [`vue2-typescript`](./src/configs/vue2-typescript#readme) | [`vue2-typescript`](./src/configs/vue2-typescript#readme) |
53
- | **Vue 2 (Options API)** | [`vue2`](./src/configs/vue2#readme) | - |
157
+ ```js
158
+ import { useInsider } from '@useinsider/eslint-config';
159
+
160
+ export default useInsider({
161
+ vue2: [
162
+ { files: ['src/**/*.{js,vue}'] },
163
+ ],
164
+ javascriptNode: [
165
+ { files: ['*.{js,cjs,mjs}'] },
166
+ ],
167
+ jquery: [
168
+ { files: ['src/**/*.{js,vue}'] },
169
+ ],
170
+ });
171
+ ```
54
172
 
55
- ### Upcoming Configurations
173
+ `jquery` is a top-level scope. Pass an array of `{ files }` entries describing
174
+ the globs that should see the jQuery globals (`$`, `jQuery`). The block is
175
+ emitted after the scope blocks and before `strict`/`spellChecker`, so the
176
+ matching language scope still applies its rule set and jQuery globals are
177
+ layered on top of it.
56
178
 
57
- Planned configurations for the next
179
+ ### Strict and spell-checker knobs
58
180
 
59
- - Legacy ES5 💀​
181
+ `strict` and `spellChecker` are flat cross-cutting options. They sit at the
182
+ top level of the config, not inside a scope entry.
183
+
184
+ ```js
185
+ import { useInsider } from '@useinsider/eslint-config';
186
+
187
+ export default useInsider({
188
+ typescriptNode: [
189
+ {
190
+ files: ['**/*.{ts,tsx}'],
191
+ tsconfigPaths: ['tsconfig.json'],
192
+ },
193
+ ],
194
+ strict: ['src/**/*.ts'],
195
+ spellChecker: {
196
+ ignoredPaths: ['vendor/**', 'dist/**'],
197
+ customWordListFile: './cspell.custom.json',
198
+ },
199
+ silenceRules: ['no-console'],
200
+ });
201
+ ```
60
202
 
61
- ## Examples
203
+ - `strict: true` applies strict rules to every file.
204
+ - `strict: string[]` applies strict rules only to the matching paths.
205
+ - `spellChecker.customWordListFile` re-points `@cspell/spellchecker` to a
206
+ project-local word list.
207
+ - `spellChecker.ignoredPaths` turns the spell-checker off for the matching
208
+ globs (the off block is emitted after the custom-list block, so ignore
209
+ wins on overlap).
210
+ - `silenceRules` rewrites the severity of the listed rule IDs to `'warn'`
211
+ across every emitted block while preserving each rule's options.
62
212
 
63
- Checkout the [examples directory](../../examples) to see various apps with the extended ESLint
64
- configuration.
213
+ ## API reference
214
+
215
+ `useInsider(config)` accepts the following top-level properties. Each scope
216
+ holds an array of entries; each entry produces its own flat-config block.
217
+
218
+ Every scope entry shape also accepts two common fields:
219
+
220
+ - `ignores?: string[]` — applies as the block's `ignores` key, scoping the
221
+ rule set away from the listed globs.
222
+ - `globals?: Record<string, GlobalConf>` — merged on top of the globals the
223
+ preset already provides; pass `'readonly'`, `'writable'`, or `'off'` per
224
+ ESLint's `Linter.Globals`. Use this to declare project-specific globals
225
+ like `APP_URL`, `axios`, `atatus`.
226
+
227
+ | Property | Entry shape | Notes |
228
+ | ---------------- | -------------------------------------------------------------------------------------------------------- | ----- |
229
+ | `ignores` | `string[]` (top-level) | Emits a leading `{ ignores }` block applied to every other block. |
230
+ | `javascript` | `{ files: string[]; ignores?: string[]; globals?: Linter.Globals }` | Environment-agnostic JS (workers, isomorphic). |
231
+ | `javascriptDom` | `{ files: string[]; ignores?: string[]; globals?: Linter.Globals }` | Browser JS. |
232
+ | `javascriptNode` | `{ files: string[]; ignores?: string[]; globals?: Linter.Globals }` | Node JS. |
233
+ | `typescript` | `{ files: string[]; tsconfigPaths: string[]; ignores?: string[]; globals?: Linter.Globals }` | Environment-agnostic TS. |
234
+ | `typescriptDom` | `{ files: string[]; tsconfigPaths: string[]; ignores?: string[]; globals?: Linter.Globals }` | Browser TS. |
235
+ | `typescriptNode` | `{ files: string[]; tsconfigPaths: string[]; ignores?: string[]; globals?: Linter.Globals }` | Node TS. |
236
+ | `vue2` | `{ files: string[]; globalComponents?: string[]; ignores?: string[]; globals?: Linter.Globals }` | Vue 2 single-file components in JS. |
237
+ | `vue3` | `{ files: string[]; globalComponents?: string[]; ignores?: string[]; globals?: Linter.Globals }` | Vue 3 single-file components in JS. |
238
+ | `vue2Typescript` | `{ files: string[]; globalComponents?: string[]; tsconfigPaths: string[]; ignores?: string[]; globals?: Linter.Globals }` | Vue 2 + TS. |
239
+ | `vue3Typescript` | `{ files: string[]; globalComponents?: string[]; tsconfigPaths: string[]; ignores?: string[]; globals?: Linter.Globals }` | Vue 3 + TS. |
240
+ | `jest` | `{ files: string[]; ignores?: string[]; globals?: Linter.Globals }` | Jest test files. |
241
+ | `vitest` | `{ files: string[]; ignores?: string[]; globals?: Linter.Globals }` | Vitest test files. |
242
+ | `jsdocBasedTs` | `{ files: string[]; tsconfigPaths: string[]; ignores?: string[]; globals?: Linter.Globals }` | JS files type-checked via JSDoc. |
243
+ | `jquery` | `{ files: string[]; ignores?: string[]; globals?: Linter.Globals }` | Layers jQuery globals (`$`, `jQuery`) on top of the matching globs. Per-entry `globals` merge with the jQuery ones rather than replacing them. |
244
+ | `strict` | `boolean \| string[]` | Applies the strict preset globally (`true`) or scoped to globs. |
245
+ | `spellChecker` | `{ ignoredPaths?: string[]; customWordListFile?: string }` | Cross-cutting cspell overrides. |
246
+ | `silenceRules` | `string[]` | Rule IDs to demote to `'warn'` across every block. |
247
+
248
+ A scope entry with per-entry globals — declare project-specific bindings
249
+ without spreading the `useInsider` return into your own array:
250
+
251
+ ```js
252
+ import { useInsider } from '@useinsider/eslint-config';
253
+
254
+ export default useInsider({
255
+ ignores: ['dist', 'coverage'],
256
+ javascriptDom: [
257
+ {
258
+ files: ['src/**/*.js'],
259
+ ignores: ['src/vendor/**'],
260
+ globals: {
261
+ APP_URL: 'readonly',
262
+ axios: 'readonly',
263
+ atatus: 'readonly',
264
+ },
265
+ },
266
+ ],
267
+ });
268
+ ```
269
+
270
+ Block-emission order — scope blocks first (in the order their keys were
271
+ inserted into the config object), then `jquery` blocks, then any `strict`
272
+ blocks, then `spellChecker` blocks. Later blocks win on overlap, matching
273
+ ESLint's flat-config precedence model.
274
+
275
+ `useInsider` returns `Promise<Linter.Config[]>`. Export it directly — ESLint
276
+ 9 resolves the Promise at load time. `useInsider`'s return type carries
277
+ through, so no JSDoc annotation is needed; the `UseInsiderResult` type alias
278
+ is exported for TypeScript callers that wrap `useInsider` in a helper of
279
+ their own.
280
+
281
+ `silenceRules()` (named export) is also available as a global registration
282
+ hook. Call it at module top level to register rule IDs to demote *before*
283
+ `useInsider` is invoked; the per-call `silenceRules: [...]` option layers
284
+ on top.
285
+
286
+ ```js
287
+ import { useInsider, silenceRules } from '@useinsider/eslint-config';
288
+
289
+ silenceRules(['no-magic-numbers']);
290
+
291
+ export default useInsider({ /* ... */ });
292
+ ```
293
+
294
+ ## Migrating from v1.x
295
+
296
+ v2 is a hard break. The summary:
297
+
298
+ - **`preset: string[]`** → top-level scope properties. The order in the
299
+ v1 `preset` array no longer matters — the new shape has one property per
300
+ scope and overrides are explicit.
301
+
302
+ ```diff
303
+ - await useInsider({
304
+ - preset: ['typescript-node'],
305
+ - config: { files: ['src/**/*.ts'], languageOptions: { parserOptions: { project: ['./tsconfig.json'] } } },
306
+ - })
307
+ + useInsider({
308
+ + typescriptNode: [
309
+ + { files: ['src/**/*.ts'], tsconfigPaths: ['tsconfig.json'] },
310
+ + ],
311
+ + })
312
+ ```
313
+
314
+ - **`preset: ['vue3-typescript']` + `config`** → `vue3Typescript` entry
315
+ with a dedicated `globalComponents` field. No more hand-rolled
316
+ `vue/no-undef-components` overrides.
317
+
318
+ ```diff
319
+ - await useInsider({
320
+ - preset: ['vue3-typescript'],
321
+ - config: {
322
+ - files: ['src/**/*.{ts,vue}'],
323
+ - languageOptions: { parserOptions: { project: ['./tsconfig.app.json'] } },
324
+ - rules: { 'vue/no-undef-components': ['error', { ignorePatterns: ['^RouterLink$', '^RouterView$'] }] },
325
+ - },
326
+ - })
327
+ + useInsider({
328
+ + vue3Typescript: [
329
+ + {
330
+ + files: ['src/**/*.{ts,vue}'],
331
+ + tsconfigPaths: ['tsconfig.app.json'],
332
+ + globalComponents: ['RouterLink', 'RouterView'],
333
+ + },
334
+ + ],
335
+ + })
336
+ ```
337
+
338
+ - **`preset: ['strict']`** → top-level `strict: true | string[]`.
339
+
340
+ ```diff
341
+ - await useInsider({ preset: ['typescript-node', 'strict'], config: { files: ['src/**/*.ts'] } })
342
+ + useInsider({
343
+ + typescriptNode: [{ files: ['src/**/*.ts'], tsconfigPaths: ['tsconfig.json'] }],
344
+ + strict: true,
345
+ + })
346
+ ```
347
+
348
+ Behavior change: in v1 the `strict` preset was always global when listed.
349
+ In v2, `strict: true` keeps that global behavior; `strict: string[]`
350
+ scopes the strict rule set to the matching globs only. If you have
351
+ paths-targeted strict checks, set `strict: [...]` instead of
352
+ `strict: true`.
353
+
354
+ - **Shape change**: `useInsider(...)` is now exported directly as the
355
+ default export, without `await`, without spread, and without an array
356
+ wrap. ESLint 9 resolves the Promise on load. The old pattern
357
+ `export default [...await useInsider({...})]` still parses, but the
358
+ preferred shape is `export default useInsider({...})`. There is no
359
+ supported override path — describe every glob you want linted inside
360
+ the call, including jQuery files via the dedicated `jquery` scope.
361
+
362
+ - **Removed**: the `preset` array, the `config: Linter.Config` escape
363
+ hatch, and the `config` preset itself. Configuration-file linting is
364
+ now an ordinary `typescriptNode` (or `javascriptNode`) entry pointed at
365
+ the right tsconfig.
366
+
367
+ - **Kept**: `silenceRules` accepts the same `string[]` shape both as a
368
+ top-level option and via the named `silenceRules()` export.
369
+ `silenceDependencyWarning()` works unchanged. Side-effect lines such as
370
+ `silenceDependencyWarning(true)` continue to sit above the
371
+ `export default useInsider({...})` call.
372
+
373
+ ## First lint after install
374
+
375
+ The first time you run lint after installing v2, `ensureDependencies` may
376
+ detect that your project's `eslint` or `globals` version is older than the
377
+ pin and auto-install them, exiting with code `1`. Run lint again and it
378
+ will complete normally.
65
379
 
66
380
  ## Troubleshooting
67
381
 
68
382
  ### `Missing dependencies detected:`
69
- If you see this error, it means that the configuration you are trying to use
70
- has some dependencies that are not installed in your project. You can install
71
- them by running the command that it provides.
72
383
 
73
- If you want to silence the warning, you can add the following code to your
74
- ESLint config file.
384
+ If you see this error, your project is missing a peer plugin this config
385
+ needs. The error message lists the install command. To silence the warning
386
+ permanently:
75
387
 
76
388
  ```js
77
389
  import { useInsider, silenceDependencyWarning } from '@useinsider/eslint-config';
78
390
 
79
391
  silenceDependencyWarning(['@cspell/eslint-plugin', '@stylistic/eslint-plugin']);
80
- ```
81
392
 
82
- Or you can pass `true` to the `silenceDependencyWarning` function to silence all
83
- warnings.
393
+ export default useInsider({ /* ... */ });
394
+ ```
84
395
 
85
- However, this is not recommended as it may cause unexpected issues while
86
- maintaining the dependencies.
396
+ Passing `true` silences every warning; that is not recommended because the
397
+ warning is the only signal that your installed plugin versions drifted
398
+ from what the config expects.
87
399
 
88
400
  ```js
89
- import { useInsider, silenceDependencyWarning } from '@useinsider/eslint-config';
90
-
91
401
  silenceDependencyWarning(true);
92
402
  ```
93
403
 
94
404
  ## Contributing
95
405
 
96
- Please refer to the [CONTRIBUTING.md](CONTRIBUTING.md) file for guidelines on
97
- how to contribute to this project.
406
+ See [CONTRIBUTING.md](../../CONTRIBUTING.md) at the repo root.
@@ -0,0 +1,5 @@
1
+ import type { Linter } from 'eslint';
2
+ export interface JqueryEntry {
3
+ files: string[];
4
+ }
5
+ export declare function buildJqueryBlocks(entries: readonly JqueryEntry[] | undefined): Linter.Config[];
@@ -0,0 +1,40 @@
1
+ import type { Linter } from 'eslint';
2
+ export interface JsEntry {
3
+ files: string[];
4
+ }
5
+ export interface TsEntry {
6
+ files: string[];
7
+ tsconfigPaths: string[];
8
+ }
9
+ export interface VueEntry {
10
+ files: string[];
11
+ globalComponents?: string[];
12
+ }
13
+ export interface VueTsEntry {
14
+ files: string[];
15
+ globalComponents?: string[];
16
+ tsconfigPaths: string[];
17
+ }
18
+ export interface TestEntry {
19
+ files: string[];
20
+ }
21
+ export type ScopeEntry = JsEntry | TsEntry | VueEntry | VueTsEntry | TestEntry;
22
+ declare const scopeMap: {
23
+ javascript(): Promise<typeof import("../configs/javascript")>;
24
+ javascriptDom(): Promise<typeof import("../configs/javascript-dom")>;
25
+ javascriptNode(): Promise<typeof import("../configs/javascript-node")>;
26
+ typescript(): Promise<typeof import("../configs/typescript")>;
27
+ typescriptDom(): Promise<typeof import("../configs/typescript-dom")>;
28
+ typescriptNode(): Promise<typeof import("../configs/typescript-node")>;
29
+ vue2(): Promise<typeof import("../configs/vue2")>;
30
+ vue3(): Promise<typeof import("../configs/vue3")>;
31
+ vue2Typescript(): Promise<typeof import("../configs/vue2-typescript")>;
32
+ vue3Typescript(): Promise<typeof import("../configs/vue3-typescript")>;
33
+ jest(): Promise<typeof import("../configs/jest")>;
34
+ vitest(): Promise<typeof import("../configs/vitest")>;
35
+ jsdocBasedTs(): Promise<typeof import("../configs/jsdoc-based-ts")>;
36
+ };
37
+ export type ScopeName = keyof typeof scopeMap;
38
+ export declare function isScopeName(key: string): key is ScopeName;
39
+ export declare function buildScopeBlocks(scope: ScopeName, entries: readonly ScopeEntry[]): Promise<Linter.Config[]>;
40
+ export {};
@@ -0,0 +1,7 @@
1
+ import type { Linter } from 'eslint';
2
+ interface SpellCheckerInput {
3
+ ignoredPaths?: string[];
4
+ customWordListFile?: string;
5
+ }
6
+ export declare function buildSpellCheckerBlocks(input: SpellCheckerInput | undefined): Linter.Config[];
7
+ export {};
@@ -0,0 +1,2 @@
1
+ import type { Linter } from 'eslint';
2
+ export declare function buildStrictBlocks(value: boolean | string[] | undefined): Promise<Linter.Config[]>;
@@ -0,0 +1,6 @@
1
+ import type { Linter } from 'eslint';
2
+ interface TypescriptOverrideInput {
3
+ tsconfigPaths: string[];
4
+ }
5
+ export declare function applyTypescriptOverrides<BlockType extends Linter.Config>(block: BlockType, input: TypescriptOverrideInput): BlockType;
6
+ export {};
@@ -0,0 +1,8 @@
1
+ import type { Linter } from 'eslint';
2
+ interface VueOverrideInput {
3
+ globalComponents?: string[];
4
+ }
5
+ export declare function escapeRegex(input: string): string;
6
+ export declare function anchoredEscapeRegex(input: string): string;
7
+ export declare function applyVueOverrides<BlockType extends Linter.Config>(block: BlockType, input: VueOverrideInput): BlockType;
8
+ export {};