@oncoursesystems/eslint-config 1.0.1 → 2.0.0

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/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  <div align="center">
2
- <img width="250" src="https://raw.githubusercontent.com/oncoursesystems/.github/master/assets/logo.jpg" />
2
+ <img width="250" alt="OnCourse Systems logo" src="https://raw.githubusercontent.com/oncoursesystems/.github/master/assets/logo.jpg" />
3
3
  <br/><br/>
4
4
 
5
5
  # `@oncoursesystems/eslint-config`
6
6
 
7
- OnCourse Systems' ESLint and Prettier config presets for JS/TS/React/ReactNative/Sencha.
7
+ OnCourse Systems' ESLint config presets for JS/TS, React, React Native/Expo, and Sencha ExtJS.
8
8
 
9
9
  <a href="https://github.com/oncoursesystems/eslint-config/blob/main/LICENSE">
10
10
  <img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="OnCourse Systems ESLint config is released under the MIT license." />
@@ -14,30 +14,73 @@ OnCourse Systems' ESLint and Prettier config presets for JS/TS/React/ReactNative
14
14
  </a>
15
15
  </div>
16
16
 
17
- ## Usage
17
+ ## What's in the box
18
18
 
19
- ### Install
19
+ Built on top of [`@antfu/eslint-config`](https://github.com/antfu/eslint-config) (v9) with OnCourse house style (4-space indent, single quotes, semicolons, Prettier-backed formatters). Requires **ESLint 10** and the flat config format.
20
+
21
+ Four factories are exported:
22
+
23
+ | Factory | Use it for | Includes |
24
+ | -------------------- | -------------------------------- | --------------------------------------------------------------- |
25
+ | `oncourse` (default) | Plain JS/TS libraries & services | antfu base + OnCourse house style |
26
+ | `react` | React web apps | base + React (`@eslint-react`, hooks, refresh) + TanStack Query |
27
+ | `expo` | React Native / Expo apps | `react` + `eslint-plugin-expo` rules + RN globals |
28
+ | `sencha` | Sencha ExtJS apps | lean classic-JS base + `@sencha/eslint-plugin-extjs` |
29
+
30
+ ## Install
20
31
 
21
32
  ```bash
22
- # NPM
23
- npm install -D eslint @oncoursesystems/eslint-config
33
+ # pnpm
34
+ pnpm add -D eslint @oncoursesystems/eslint-config
24
35
 
25
- # PNPM
26
- pnpm i -D esling @oncoursesystems/eslint-config
36
+ # npm
37
+ npm install -D eslint @oncoursesystems/eslint-config
27
38
  ```
28
39
 
29
- Create a `esling.config.{js|ts|mjs}' file in your project root:
40
+ Create an `eslint.config.{js,ts,mjs}` file in your project root and pick the factory that matches your project:
30
41
 
31
- ```js
32
- // eslint.config.ts
42
+ ```ts
43
+ // eslint.config.ts — plain JS/TS project
33
44
  import oncourse from '@oncoursesystems/eslint-config';
34
45
 
35
46
  export default oncourse();
36
47
  ```
37
48
 
38
- ### Add script for package.json
49
+ ```ts
50
+ // eslint.config.ts — React web app
51
+ import { react } from '@oncoursesystems/eslint-config';
52
+
53
+ export default react();
54
+ ```
55
+
56
+ ```ts
57
+ // eslint.config.ts — React Native / Expo app
58
+ import { expo } from '@oncoursesystems/eslint-config';
59
+
60
+ export default expo();
61
+ ```
62
+
63
+ ```ts
64
+ // eslint.config.ts — Sencha ExtJS app
65
+ import { sencha } from '@oncoursesystems/eslint-config';
39
66
 
40
- For example:
67
+ export default sencha();
68
+ ```
69
+
70
+ The first time you run `npx eslint`, you'll be prompted to install any framework-specific plugins that aren't present yet (React, Expo, Sencha, TanStack Query, Tailwind). You can also install them up front:
71
+
72
+ ```bash
73
+ # React / Expo
74
+ pnpm add -D @eslint-react/eslint-plugin eslint-plugin-react-hooks eslint-plugin-react-refresh @tanstack/eslint-plugin-query
75
+
76
+ # Expo (in addition to the React plugins above)
77
+ pnpm add -D eslint-plugin-expo
78
+
79
+ # Sencha ExtJS
80
+ pnpm add -D @sencha/eslint-plugin-extjs
81
+ ```
82
+
83
+ ## Add scripts to package.json
41
84
 
42
85
  ```json
43
86
  {
@@ -48,9 +91,90 @@ For example:
48
91
  }
49
92
  ```
50
93
 
51
- ### Config VS Code auto-fix on save
94
+ ## Options
95
+
96
+ Each factory accepts the same `(options?, ...userConfigs)` signature. `options` is passed straight through to `@antfu/eslint-config`, so anything documented in [antfu's customization guide](https://github.com/antfu/eslint-config#customization) works here too. Additional flat-config objects can be appended after it.
97
+
98
+ ```ts
99
+ // eslint.config.ts
100
+ import { react } from '@oncoursesystems/eslint-config';
101
+
102
+ export default react(
103
+ // Configure integrations here (antfu options + OnCourse flags)
104
+ {
105
+ typescript: {
106
+ tsconfigPath: './tsconfig.json',
107
+ },
108
+ },
109
+ // Any additional objects are passed in as ESLint flat configs
110
+ {
111
+ files: ['src/**/*.ts', 'src/**/*.tsx'],
112
+ rules: {
113
+ 'ts/typedef': 'off',
114
+ },
115
+ },
116
+ );
117
+ ```
118
+
119
+ ### OnCourse-specific flags
120
+
121
+ These are available on the `react` and `expo` factories:
122
+
123
+ | Flag | Default | Description |
124
+ | ---------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
125
+ | `query` | `true` | Enable [`@tanstack/eslint-plugin-query`](https://tanstack.com/query) recommended rules. |
126
+ | `tailwind` | `false` | Enable [`eslint-plugin-tailwindcss`](https://github.com/francoismassart/eslint-plugin-tailwindcss) (v4 track). Opt-in while the v4 plugin is in beta. |
127
+
128
+ ```ts
129
+ import { react } from '@oncoursesystems/eslint-config';
130
+
131
+ export default react({
132
+ tailwind: true, // turn on Tailwind linting
133
+ query: false, // turn off TanStack Query linting
134
+ });
135
+ ```
136
+
137
+ ## Migrating from v1 to v2
138
+
139
+ v2 is a breaking change. The headline differences:
52
140
 
53
- Install [VS Code ESLint extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) and create `.vscode/settings.json`
141
+ - **ESLint 10 is required** (v1 targeted ESLint 9). Bump `eslint` to `^10` in your project.
142
+ - **The `react` / `expo` / `sencha` boolean options are gone.** Instead of one `oncourse()` factory with flags, there are now dedicated factory exports. Pick the one for your project.
143
+ - **Plain JS/TS projects are unchanged** — the default `oncourse()` export still works the same way.
144
+ - **Tailwind is now opt-in** via the `tailwind` flag (and uses the `eslint-plugin-tailwindcss` v4 track).
145
+ - **TanStack Query is on by default** in the `react` and `expo` configs; disable it with `query: false`.
146
+
147
+ Update your `eslint.config.{js,ts}`:
148
+
149
+ ```diff
150
+ - import oncourse from '@oncoursesystems/eslint-config';
151
+ + import { react } from '@oncoursesystems/eslint-config';
152
+
153
+ - export default oncourse({ react: true });
154
+ + export default react();
155
+ ```
156
+
157
+ ```diff
158
+ - import oncourse from '@oncoursesystems/eslint-config';
159
+ + import { expo } from '@oncoursesystems/eslint-config';
160
+
161
+ - export default oncourse({ expo: true });
162
+ + export default expo();
163
+ ```
164
+
165
+ ```diff
166
+ - import oncourse from '@oncoursesystems/eslint-config';
167
+ + import { sencha } from '@oncoursesystems/eslint-config';
168
+
169
+ - export default oncourse({ sencha: true });
170
+ + export default sencha();
171
+ ```
172
+
173
+ Anything you previously passed to `oncourse()` (antfu options, extra flat-config objects) still works — just move it into the new factory call, e.g. `react({ typescript: { tsconfigPath: './tsconfig.json' } }, { rules: { /* ... */ } })`.
174
+
175
+ ## Config VS Code auto-fix on save
176
+
177
+ Install the [VS Code ESLint extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) and add to `.vscode/settings.json`:
54
178
 
55
179
  ```json
56
180
  {
@@ -60,11 +184,11 @@ Install [VS Code ESLint extension](https://marketplace.visualstudio.com/items?it
60
184
 
61
185
  // Auto-fix on save
62
186
  "editor.codeActionsOnSave": {
63
- "source.fixAll.eslint": true,
64
- "source.organizeImports": true
187
+ "source.fixAll.eslint": "explicit",
188
+ "source.organizeImports": "never"
65
189
  },
66
190
 
67
- // Silent the stylistic rules in your IDS, but still auto-fix them
191
+ // Silence the stylistic rules in your IDE, but still auto-fix them
68
192
  "eslint.rules.customizations": [
69
193
  { "rule": "style/*", "severity": "off", "fixable": true },
70
194
  { "rule": "format/*", "severity": "off", "fixable": true },
@@ -88,7 +212,6 @@ Install [VS Code ESLint extension](https://marketplace.visualstudio.com/items?it
88
212
  "markdown",
89
213
  "json",
90
214
  "jsonc",
91
- "yaml",
92
215
  "toml",
93
216
  "xml",
94
217
  "css",
@@ -98,96 +221,24 @@ Install [VS Code ESLint extension](https://marketplace.visualstudio.com/items?it
98
221
  }
99
222
  ```
100
223
 
101
- ### React Configuration
102
-
103
- To enable React support, you need to explicitly turn it on:
104
-
105
- ```js
106
- // eslint.config.js
107
- import oncourse from '@oncoursesystems/eslint-config';
108
-
109
- export default oncourse({
110
- react: true,
111
- });
112
- ```
113
-
114
- Running npx eslint should prompt you to install the required dependencies, otherwise, you can install them manually:
115
-
116
- ```bash
117
- # NPM
118
- npm i -D @eslint-react/eslint-plugin eslint-plugin-react-hooks eslint-plugin-react-refresh @tanstack/eslint-plugin-query
119
-
120
- # PNPM
121
- pnpm i -D @eslint-react/eslint-plugin eslint-plugin-react-hooks eslint-plugin-react-refresh @tanstack/eslint-plugin-query
122
- ```
123
-
124
- ### Sencha ExtJS Configuration
125
-
126
- To enable Sencha ExtJS support, you need to explicitly turn it on:
127
-
128
- ```js
129
- // eslint.config.js
130
- import oncourse from '@oncoursesystems/eslint-config';
131
-
132
- export default oncourse({
133
- react: true,
134
- });
135
- ```
136
-
137
- Running npx eslint should prompt you to install the required dependencies, otherwise, you can install them manually:
138
-
139
- ```bash
140
- # NPM
141
- npm i -D @sencha/eslint-plugin-extjs
142
-
143
- # PNPM
144
- pnpm i -D @sencha/eslint-plugin-extjs
145
- ```
146
-
147
- ### Customization
148
-
149
- Configure the initial preset with the same parameters as expose [@antfu/eslint-config](https://github.com/antfu/eslint-config/blob/main/README.md#customization)
150
-
151
- Example:
152
-
153
- ```js
154
- // eslint.config.ts
155
- import oncourse from '@oncoursesystems/eslint-config';
156
-
157
- export default oncourse(
158
- // Configure integrations here
159
- {
160
- formatters: false,
161
- },
162
- // Any additional objects will be passed in as ESLint Flat Configs
163
- // The files config is optional, but can be used to specify which files to lint
164
- {
165
- files: ['src/**/*.ts', 'src/**/*.tsx'],
166
- rules: {
167
- 'ts/typedef': 'off',
168
- }
169
- },
170
- );
171
- ```
172
-
173
- ## View Enabled Rules
224
+ ## View enabled rules
174
225
 
175
- To view what rules are enabled in your project and apply them to files, go to your project root that contains `eslint.config.js` and run:
226
+ From the project root that contains your `eslint.config.{js,ts}`:
176
227
 
177
228
  ```bash
178
229
  npx @eslint/config-inspector
179
230
  ```
180
231
 
181
- ## Release & Publish
232
+ ## Release & publish
182
233
 
183
- Make sure you have authenticated to your npm account using `npm login`. To publish packages, run the following command:
234
+ Make sure you're authenticated to npm (`npm login`), then run:
184
235
 
185
236
  ```sh
186
237
  pnpm run release
187
238
  ```
188
239
 
189
- This will auto-bump the version numbers, then upload the packages to [NPM](https://www.npmjs.com/oncoursesystems). It will also create a new GitHub release with the tagged version.
240
+ This bumps the version, publishes to [NPM](https://www.npmjs.com/package/@oncoursesystems/eslint-config), and creates a tagged GitHub release.
190
241
 
191
242
  ## Credits
192
243
 
193
- The project is built on top of Anthony Fu's amazing `[@antfu/eslint-config](https://github.com/antfu/eslint-config)` package.
244
+ Built on top of Anthony Fu's excellent [`@antfu/eslint-config`](https://github.com/antfu/eslint-config).
package/dist/index.cjs CHANGED
@@ -29,28 +29,49 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
29
29
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
30
 
31
31
  // src/index.ts
32
- var src_exports = {};
33
- __export(src_exports, {
34
- default: () => src_default
32
+ var index_exports = {};
33
+ __export(index_exports, {
34
+ baseOptions: () => baseOptions,
35
+ baseRules: () => baseRules,
36
+ default: () => index_default,
37
+ expo: () => expo2,
38
+ oncourse: () => oncourse,
39
+ react: () => react,
40
+ sencha: () => sencha2
35
41
  });
36
- module.exports = __toCommonJS(src_exports);
37
- var import_eslint_config = require("@antfu/eslint-config");
42
+ module.exports = __toCommonJS(index_exports);
43
+ var import_eslint_config8 = require("@antfu/eslint-config");
38
44
 
39
- // src/config.ts
45
+ // src/base.ts
40
46
  var import_node_process = __toESM(require("process"), 1);
41
47
  var SORT_GROUPS = [
42
48
  "type",
43
49
  ["builtin", "external"],
44
- "internal-type",
50
+ "type-internal",
45
51
  "internal",
46
- ["parent-type", "sibling-type", "index-type"],
52
+ ["type-parent", "type-sibling", "type-index"],
47
53
  ["parent", "sibling", "index"],
48
- "object",
49
54
  "unknown"
50
55
  ];
51
- function oncourseConfigs() {
56
+ function baseOptions(options = {}) {
57
+ const { tailwind: _tailwind, query: _query, ...rest } = options;
58
+ return {
59
+ name: "oncourse",
60
+ formatters: true,
61
+ stylistic: {
62
+ indent: 4,
63
+ quotes: "single",
64
+ semi: true
65
+ },
66
+ yaml: false,
67
+ ...rest
68
+ };
69
+ }
70
+ function baseRules(options = {}) {
71
+ const stylisticEnabled = options.stylistic !== false;
52
72
  return [
53
73
  {
74
+ name: "oncourse/rules",
54
75
  rules: {
55
76
  "perfectionist/sort-imports": [
56
77
  "error",
@@ -69,7 +90,12 @@ function oncourseConfigs() {
69
90
  allow: ["table", "info", "warn", "error"]
70
91
  }
71
92
  ],
72
- "node/prefer-global/process": "warn",
93
+ "node/prefer-global/process": "warn"
94
+ }
95
+ },
96
+ ...stylisticEnabled ? [{
97
+ name: "oncourse/stylistic",
98
+ rules: {
73
99
  "style/comma-dangle": "off",
74
100
  "style/brace-style": ["error", "1tbs", { allowSingleLine: true }],
75
101
  "style/jsx-one-expression-per-line": "off",
@@ -79,42 +105,167 @@ function oncourseConfigs() {
79
105
  { overrides: { "?": "before", ":": "before" } }
80
106
  ]
81
107
  }
108
+ }] : []
109
+ ];
110
+ }
111
+
112
+ // src/factories/expo.ts
113
+ var import_eslint_config4 = require("@antfu/eslint-config");
114
+
115
+ // src/plugins/expo.ts
116
+ var import_eslint_config = require("@antfu/eslint-config");
117
+ async function expo() {
118
+ await (0, import_eslint_config.ensurePackages)(["eslint-plugin-expo"]);
119
+ const pluginExpo = await (0, import_eslint_config.interopDefault)(import("eslint-plugin-expo"));
120
+ return [
121
+ {
122
+ name: "oncourse/expo/setup",
123
+ plugins: {
124
+ expo: pluginExpo
125
+ },
126
+ languageOptions: {
127
+ globals: {
128
+ __DEV__: "readonly",
129
+ ErrorUtils: "readonly"
130
+ }
131
+ }
132
+ },
133
+ {
134
+ name: "oncourse/expo/rules",
135
+ rules: {
136
+ "expo/no-dynamic-env-var": "error",
137
+ "expo/no-env-var-destructuring": "error",
138
+ "expo/prefer-box-shadow": "warn",
139
+ "expo/use-dom-exports": "warn"
140
+ }
82
141
  }
83
142
  ];
84
143
  }
85
144
 
86
- // src/options.ts
87
- function oncourseOptions(options) {
88
- return {
89
- formatters: true,
90
- name: "oncourse",
91
- stylistic: {
92
- indent: 4,
93
- quotes: "single",
94
- semi: true
145
+ // src/plugins/query.ts
146
+ var import_eslint_config2 = require("@antfu/eslint-config");
147
+ async function query() {
148
+ await (0, import_eslint_config2.ensurePackages)(["@tanstack/eslint-plugin-query"]);
149
+ const pluginQuery = await (0, import_eslint_config2.interopDefault)(import("@tanstack/eslint-plugin-query"));
150
+ return pluginQuery.configs["flat/recommended"];
151
+ }
152
+
153
+ // src/plugins/tailwind.ts
154
+ var import_eslint_config3 = require("@antfu/eslint-config");
155
+ async function tailwind() {
156
+ await (0, import_eslint_config3.ensurePackages)(["eslint-plugin-tailwindcss"]);
157
+ const pluginTailwind = await (0, import_eslint_config3.interopDefault)(
158
+ import("eslint-plugin-tailwindcss")
159
+ );
160
+ return pluginTailwind.configs["flat/recommended"];
161
+ }
162
+
163
+ // src/factories/expo.ts
164
+ async function expo2(options = {}, ...userConfigs) {
165
+ const { query: query2 = true, tailwind: tailwind2 = false } = options;
166
+ const integrations = [
167
+ ...query2 ? await query() : [],
168
+ ...tailwind2 ? await tailwind() : [],
169
+ ...await expo()
170
+ ];
171
+ return (0, import_eslint_config4.antfu)(
172
+ {
173
+ ...baseOptions(options),
174
+ react: true
95
175
  },
96
- typescript: {
97
- tsconfigPath: "tsconfig.json"
176
+ ...baseRules(options),
177
+ ...integrations,
178
+ ...userConfigs
179
+ );
180
+ }
181
+
182
+ // src/factories/react.ts
183
+ var import_eslint_config5 = require("@antfu/eslint-config");
184
+ async function react(options = {}, ...userConfigs) {
185
+ const { query: query2 = true, tailwind: tailwind2 = false } = options;
186
+ const integrations = [
187
+ ...query2 ? await query() : [],
188
+ ...tailwind2 ? await tailwind() : []
189
+ ];
190
+ return (0, import_eslint_config5.antfu)(
191
+ {
192
+ ...baseOptions(options),
193
+ react: true
98
194
  },
99
- yaml: false,
100
- ...options
101
- };
195
+ ...baseRules(options),
196
+ ...integrations,
197
+ ...userConfigs
198
+ );
102
199
  }
103
200
 
104
- // src/index.ts
105
- __reExport(src_exports, require("@antfu/eslint-config"), module.exports);
106
- async function oncourse(options, ...configs) {
107
- return (0, import_eslint_config.antfu)(
201
+ // src/factories/sencha.ts
202
+ var import_eslint_config7 = require("@antfu/eslint-config");
203
+
204
+ // src/plugins/sencha.ts
205
+ var import_eslint_config6 = require("@antfu/eslint-config");
206
+ async function sencha() {
207
+ await (0, import_eslint_config6.ensurePackages)(["@sencha/eslint-plugin-extjs"]);
208
+ const pluginSencha = await (0, import_eslint_config6.interopDefault)(
209
+ import("@sencha/eslint-plugin-extjs")
210
+ );
211
+ return [
212
+ {
213
+ name: "oncourse/sencha/setup",
214
+ plugins: {
215
+ "@sencha/extjs": pluginSencha
216
+ },
217
+ settings: {
218
+ extjs: {
219
+ version: "latest"
220
+ }
221
+ },
222
+ languageOptions: {
223
+ globals: {
224
+ Ext: "readonly"
225
+ }
226
+ }
227
+ },
228
+ {
229
+ name: "oncourse/sencha/rules",
230
+ rules: {
231
+ ...pluginSencha.configs.recommended.rules
232
+ }
233
+ }
234
+ ];
235
+ }
236
+
237
+ // src/factories/sencha.ts
238
+ async function sencha2(options = {}, ...userConfigs) {
239
+ return (0, import_eslint_config7.antfu)(
108
240
  {
109
- ...oncourseOptions(options),
110
- ...options
241
+ ...baseOptions(options),
242
+ jsx: false,
243
+ react: false,
244
+ typescript: false
111
245
  },
112
- ...oncourseConfigs(),
113
- ...configs
246
+ ...baseRules(options),
247
+ ...await sencha(),
248
+ ...userConfigs
249
+ );
250
+ }
251
+
252
+ // src/index.ts
253
+ __reExport(index_exports, require("@antfu/eslint-config"), module.exports);
254
+ async function oncourse(options = {}, ...userConfigs) {
255
+ return (0, import_eslint_config8.antfu)(
256
+ baseOptions(options),
257
+ ...baseRules(options),
258
+ ...userConfigs
114
259
  );
115
260
  }
116
- var src_default = oncourse;
261
+ var index_default = oncourse;
117
262
  // Annotate the CommonJS export names for ESM import in node:
118
263
  0 && (module.exports = {
264
+ baseOptions,
265
+ baseRules,
266
+ expo,
267
+ oncourse,
268
+ react,
269
+ sencha,
119
270
  ...require("@antfu/eslint-config")
120
271
  });
package/dist/index.d.cts CHANGED
@@ -1,14 +1,121 @@
1
- import { TypedFlatConfigItem, OptionsConfig, ConfigNames, Awaitable } from '@antfu/eslint-config';
1
+ import { antfu, TypedFlatConfigItem, OptionsConfig, Awaitable } from '@antfu/eslint-config';
2
2
  export * from '@antfu/eslint-config';
3
3
  import { Linter } from 'eslint';
4
- import { FlatConfigComposer } from 'eslint-flat-config-utils';
5
4
 
6
- type Options = Omit<TypedFlatConfigItem, 'files'> & OptionsConfig & {
7
- expo?: boolean;
8
- sencha?: boolean;
5
+ /**
6
+ * The composer instance returned by every OnCourse factory. It is awaitable and
7
+ * can be further customised with `.append()`, `.override()`, etc.
8
+ *
9
+ * Derived from antfu's own return type so we don't take a direct dependency on
10
+ * `eslint-flat-config-utils`.
11
+ */
12
+ type Composer = ReturnType<typeof antfu>;
13
+ /**
14
+ * Extra flat-config items consumers may pass after the options object. Mirrors
15
+ * the shape accepted by `@antfu/eslint-config`.
16
+ */
17
+ type UserConfigs = Array<Awaitable<Array<Linter.Config> | Array<TypedFlatConfigItem> | Composer | TypedFlatConfigItem>>;
18
+ /**
19
+ * Options shared by every OnCourse factory. Everything `@antfu/eslint-config`
20
+ * accepts, plus a couple of OnCourse-specific integration toggles.
21
+ */
22
+ type OncourseOptions = Omit<TypedFlatConfigItem, 'files'> & OptionsConfig & {
23
+ /**
24
+ * Enable Tailwind CSS linting via `eslint-plugin-tailwindcss`.
25
+ *
26
+ * Off by default — the v4 plugin track is still beta. Requires the
27
+ * plugin to be installed (you will be prompted).
28
+ *
29
+ * @default false
30
+ */
31
+ tailwind?: boolean;
32
+ /**
33
+ * Enable TanStack Query linting via `@tanstack/eslint-plugin-query`.
34
+ *
35
+ * @default true
36
+ */
37
+ query?: boolean;
9
38
  };
10
- type Composer = FlatConfigComposer<TypedFlatConfigItem, ConfigNames>;
11
- type Configs = Array<Awaitable<Array<Linter.Config> | Array<TypedFlatConfigItem> | FlatConfigComposer<any, any> | TypedFlatConfigItem>>;
12
- declare function oncourse(options?: Options, ...configs: Configs): Promise<Composer>;
13
39
 
14
- export { type Composer, type Configs, type Options, oncourse as default };
40
+ /**
41
+ * The OnCourse "house style" options layered on top of `@antfu/eslint-config`:
42
+ * 4-space indent, single quotes, semicolons, Prettier-backed formatters for
43
+ * non-JS files. Consumer-supplied options always win.
44
+ */
45
+ declare function baseOptions(options?: OncourseOptions): Omit<TypedFlatConfigItem, 'files'> & OptionsConfig;
46
+ /**
47
+ * OnCourse rule overrides applied on top of antfu's defaults. These are the
48
+ * cross-language house preferences — they intentionally do NOT re-add the old
49
+ * `ts/*` overrides (array-type/accessibility/redeclare/use-before-define),
50
+ * which antfu 9's defaults now handle better.
51
+ *
52
+ * The `style/*` overrides are only emitted when stylistic linting is enabled,
53
+ * since antfu doesn't register the `style` plugin when `stylistic: false`.
54
+ */
55
+ declare function baseRules(options?: OncourseOptions): Array<TypedFlatConfigItem>;
56
+
57
+ /**
58
+ * ESLint config for OnCourse React Native / Expo apps.
59
+ *
60
+ * Everything the `react` config provides, plus `eslint-plugin-expo` rules and
61
+ * React Native ambient globals. TanStack Query is on by default; Tailwind
62
+ * (e.g. NativeWind) is opt-in.
63
+ *
64
+ * @example
65
+ * ```ts
66
+ * import { expo } from '@oncoursesystems/eslint-config';
67
+ *
68
+ * export default expo();
69
+ * ```
70
+ */
71
+ declare function expo(options?: OncourseOptions, ...userConfigs: UserConfigs): Promise<Composer>;
72
+
73
+ /**
74
+ * ESLint config for OnCourse React (web) apps.
75
+ *
76
+ * antfu base + OnCourse house style + React (`@eslint-react`, react-hooks,
77
+ * react-refresh) + TanStack Query (on by default). Tailwind is opt-in.
78
+ *
79
+ * @example
80
+ * ```ts
81
+ * import { react } from '@oncoursesystems/eslint-config';
82
+ *
83
+ * export default react();
84
+ * // with options + extra flat configs:
85
+ * export default react({ tailwind: true }, { rules: { 'no-console': 'off' } });
86
+ * ```
87
+ */
88
+ declare function react(options?: OncourseOptions, ...userConfigs: UserConfigs): Promise<Composer>;
89
+
90
+ /**
91
+ * ESLint config for OnCourse Sencha ExtJS apps.
92
+ *
93
+ * Deliberately lean: OnCourse house style over classic JavaScript only — no
94
+ * TypeScript program, no React/JSX — plus the `@sencha/eslint-plugin-extjs`
95
+ * recommended rules and the `Ext` global. ExtJS is global-heavy classic JS, so
96
+ * the TypeScript and React layers are intentionally disabled.
97
+ *
98
+ * @example
99
+ * ```ts
100
+ * import { sencha } from '@oncoursesystems/eslint-config';
101
+ *
102
+ * export default sencha();
103
+ * ```
104
+ */
105
+ declare function sencha(options?: OncourseOptions, ...userConfigs: UserConfigs): Promise<Composer>;
106
+
107
+ /**
108
+ * The OnCourse base config: `@antfu/eslint-config` + OnCourse house style
109
+ * (4-space indent, single quotes, semicolons, formatters) for plain JS/TS
110
+ * projects. The `react`, `expo`, and `sencha` factories all build on this.
111
+ *
112
+ * @example
113
+ * ```ts
114
+ * import oncourse from '@oncoursesystems/eslint-config';
115
+ *
116
+ * export default oncourse();
117
+ * ```
118
+ */
119
+ declare function oncourse(options?: OncourseOptions, ...userConfigs: UserConfigs): Promise<Composer>;
120
+
121
+ export { type Composer, type OncourseOptions, type UserConfigs, baseOptions, baseRules, oncourse as default, expo, oncourse, react, sencha };
package/dist/index.d.ts CHANGED
@@ -1,14 +1,121 @@
1
- import { TypedFlatConfigItem, OptionsConfig, ConfigNames, Awaitable } from '@antfu/eslint-config';
1
+ import { antfu, TypedFlatConfigItem, OptionsConfig, Awaitable } from '@antfu/eslint-config';
2
2
  export * from '@antfu/eslint-config';
3
3
  import { Linter } from 'eslint';
4
- import { FlatConfigComposer } from 'eslint-flat-config-utils';
5
4
 
6
- type Options = Omit<TypedFlatConfigItem, 'files'> & OptionsConfig & {
7
- expo?: boolean;
8
- sencha?: boolean;
5
+ /**
6
+ * The composer instance returned by every OnCourse factory. It is awaitable and
7
+ * can be further customised with `.append()`, `.override()`, etc.
8
+ *
9
+ * Derived from antfu's own return type so we don't take a direct dependency on
10
+ * `eslint-flat-config-utils`.
11
+ */
12
+ type Composer = ReturnType<typeof antfu>;
13
+ /**
14
+ * Extra flat-config items consumers may pass after the options object. Mirrors
15
+ * the shape accepted by `@antfu/eslint-config`.
16
+ */
17
+ type UserConfigs = Array<Awaitable<Array<Linter.Config> | Array<TypedFlatConfigItem> | Composer | TypedFlatConfigItem>>;
18
+ /**
19
+ * Options shared by every OnCourse factory. Everything `@antfu/eslint-config`
20
+ * accepts, plus a couple of OnCourse-specific integration toggles.
21
+ */
22
+ type OncourseOptions = Omit<TypedFlatConfigItem, 'files'> & OptionsConfig & {
23
+ /**
24
+ * Enable Tailwind CSS linting via `eslint-plugin-tailwindcss`.
25
+ *
26
+ * Off by default — the v4 plugin track is still beta. Requires the
27
+ * plugin to be installed (you will be prompted).
28
+ *
29
+ * @default false
30
+ */
31
+ tailwind?: boolean;
32
+ /**
33
+ * Enable TanStack Query linting via `@tanstack/eslint-plugin-query`.
34
+ *
35
+ * @default true
36
+ */
37
+ query?: boolean;
9
38
  };
10
- type Composer = FlatConfigComposer<TypedFlatConfigItem, ConfigNames>;
11
- type Configs = Array<Awaitable<Array<Linter.Config> | Array<TypedFlatConfigItem> | FlatConfigComposer<any, any> | TypedFlatConfigItem>>;
12
- declare function oncourse(options?: Options, ...configs: Configs): Promise<Composer>;
13
39
 
14
- export { type Composer, type Configs, type Options, oncourse as default };
40
+ /**
41
+ * The OnCourse "house style" options layered on top of `@antfu/eslint-config`:
42
+ * 4-space indent, single quotes, semicolons, Prettier-backed formatters for
43
+ * non-JS files. Consumer-supplied options always win.
44
+ */
45
+ declare function baseOptions(options?: OncourseOptions): Omit<TypedFlatConfigItem, 'files'> & OptionsConfig;
46
+ /**
47
+ * OnCourse rule overrides applied on top of antfu's defaults. These are the
48
+ * cross-language house preferences — they intentionally do NOT re-add the old
49
+ * `ts/*` overrides (array-type/accessibility/redeclare/use-before-define),
50
+ * which antfu 9's defaults now handle better.
51
+ *
52
+ * The `style/*` overrides are only emitted when stylistic linting is enabled,
53
+ * since antfu doesn't register the `style` plugin when `stylistic: false`.
54
+ */
55
+ declare function baseRules(options?: OncourseOptions): Array<TypedFlatConfigItem>;
56
+
57
+ /**
58
+ * ESLint config for OnCourse React Native / Expo apps.
59
+ *
60
+ * Everything the `react` config provides, plus `eslint-plugin-expo` rules and
61
+ * React Native ambient globals. TanStack Query is on by default; Tailwind
62
+ * (e.g. NativeWind) is opt-in.
63
+ *
64
+ * @example
65
+ * ```ts
66
+ * import { expo } from '@oncoursesystems/eslint-config';
67
+ *
68
+ * export default expo();
69
+ * ```
70
+ */
71
+ declare function expo(options?: OncourseOptions, ...userConfigs: UserConfigs): Promise<Composer>;
72
+
73
+ /**
74
+ * ESLint config for OnCourse React (web) apps.
75
+ *
76
+ * antfu base + OnCourse house style + React (`@eslint-react`, react-hooks,
77
+ * react-refresh) + TanStack Query (on by default). Tailwind is opt-in.
78
+ *
79
+ * @example
80
+ * ```ts
81
+ * import { react } from '@oncoursesystems/eslint-config';
82
+ *
83
+ * export default react();
84
+ * // with options + extra flat configs:
85
+ * export default react({ tailwind: true }, { rules: { 'no-console': 'off' } });
86
+ * ```
87
+ */
88
+ declare function react(options?: OncourseOptions, ...userConfigs: UserConfigs): Promise<Composer>;
89
+
90
+ /**
91
+ * ESLint config for OnCourse Sencha ExtJS apps.
92
+ *
93
+ * Deliberately lean: OnCourse house style over classic JavaScript only — no
94
+ * TypeScript program, no React/JSX — plus the `@sencha/eslint-plugin-extjs`
95
+ * recommended rules and the `Ext` global. ExtJS is global-heavy classic JS, so
96
+ * the TypeScript and React layers are intentionally disabled.
97
+ *
98
+ * @example
99
+ * ```ts
100
+ * import { sencha } from '@oncoursesystems/eslint-config';
101
+ *
102
+ * export default sencha();
103
+ * ```
104
+ */
105
+ declare function sencha(options?: OncourseOptions, ...userConfigs: UserConfigs): Promise<Composer>;
106
+
107
+ /**
108
+ * The OnCourse base config: `@antfu/eslint-config` + OnCourse house style
109
+ * (4-space indent, single quotes, semicolons, formatters) for plain JS/TS
110
+ * projects. The `react`, `expo`, and `sencha` factories all build on this.
111
+ *
112
+ * @example
113
+ * ```ts
114
+ * import oncourse from '@oncoursesystems/eslint-config';
115
+ *
116
+ * export default oncourse();
117
+ * ```
118
+ */
119
+ declare function oncourse(options?: OncourseOptions, ...userConfigs: UserConfigs): Promise<Composer>;
120
+
121
+ export { type Composer, type OncourseOptions, type UserConfigs, baseOptions, baseRules, oncourse as default, expo, oncourse, react, sencha };
package/dist/index.js CHANGED
@@ -1,21 +1,36 @@
1
1
  // src/index.ts
2
- import { antfu } from "@antfu/eslint-config";
2
+ import { antfu as antfu4 } from "@antfu/eslint-config";
3
3
 
4
- // src/config.ts
5
- import process from "node:process";
4
+ // src/base.ts
5
+ import process from "process";
6
6
  var SORT_GROUPS = [
7
7
  "type",
8
8
  ["builtin", "external"],
9
- "internal-type",
9
+ "type-internal",
10
10
  "internal",
11
- ["parent-type", "sibling-type", "index-type"],
11
+ ["type-parent", "type-sibling", "type-index"],
12
12
  ["parent", "sibling", "index"],
13
- "object",
14
13
  "unknown"
15
14
  ];
16
- function oncourseConfigs() {
15
+ function baseOptions(options = {}) {
16
+ const { tailwind: _tailwind, query: _query, ...rest } = options;
17
+ return {
18
+ name: "oncourse",
19
+ formatters: true,
20
+ stylistic: {
21
+ indent: 4,
22
+ quotes: "single",
23
+ semi: true
24
+ },
25
+ yaml: false,
26
+ ...rest
27
+ };
28
+ }
29
+ function baseRules(options = {}) {
30
+ const stylisticEnabled = options.stylistic !== false;
17
31
  return [
18
32
  {
33
+ name: "oncourse/rules",
19
34
  rules: {
20
35
  "perfectionist/sort-imports": [
21
36
  "error",
@@ -34,7 +49,12 @@ function oncourseConfigs() {
34
49
  allow: ["table", "info", "warn", "error"]
35
50
  }
36
51
  ],
37
- "node/prefer-global/process": "warn",
52
+ "node/prefer-global/process": "warn"
53
+ }
54
+ },
55
+ ...stylisticEnabled ? [{
56
+ name: "oncourse/stylistic",
57
+ rules: {
38
58
  "style/comma-dangle": "off",
39
59
  "style/brace-style": ["error", "1tbs", { allowSingleLine: true }],
40
60
  "style/jsx-one-expression-per-line": "off",
@@ -44,41 +64,166 @@ function oncourseConfigs() {
44
64
  { overrides: { "?": "before", ":": "before" } }
45
65
  ]
46
66
  }
67
+ }] : []
68
+ ];
69
+ }
70
+
71
+ // src/factories/expo.ts
72
+ import { antfu } from "@antfu/eslint-config";
73
+
74
+ // src/plugins/expo.ts
75
+ import { ensurePackages, interopDefault } from "@antfu/eslint-config";
76
+ async function expo() {
77
+ await ensurePackages(["eslint-plugin-expo"]);
78
+ const pluginExpo = await interopDefault(import("eslint-plugin-expo"));
79
+ return [
80
+ {
81
+ name: "oncourse/expo/setup",
82
+ plugins: {
83
+ expo: pluginExpo
84
+ },
85
+ languageOptions: {
86
+ globals: {
87
+ __DEV__: "readonly",
88
+ ErrorUtils: "readonly"
89
+ }
90
+ }
91
+ },
92
+ {
93
+ name: "oncourse/expo/rules",
94
+ rules: {
95
+ "expo/no-dynamic-env-var": "error",
96
+ "expo/no-env-var-destructuring": "error",
97
+ "expo/prefer-box-shadow": "warn",
98
+ "expo/use-dom-exports": "warn"
99
+ }
47
100
  }
48
101
  ];
49
102
  }
50
103
 
51
- // src/options.ts
52
- function oncourseOptions(options) {
53
- return {
54
- formatters: true,
55
- name: "oncourse",
56
- stylistic: {
57
- indent: 4,
58
- quotes: "single",
59
- semi: true
104
+ // src/plugins/query.ts
105
+ import { ensurePackages as ensurePackages2, interopDefault as interopDefault2 } from "@antfu/eslint-config";
106
+ async function query() {
107
+ await ensurePackages2(["@tanstack/eslint-plugin-query"]);
108
+ const pluginQuery = await interopDefault2(import("@tanstack/eslint-plugin-query"));
109
+ return pluginQuery.configs["flat/recommended"];
110
+ }
111
+
112
+ // src/plugins/tailwind.ts
113
+ import { ensurePackages as ensurePackages3, interopDefault as interopDefault3 } from "@antfu/eslint-config";
114
+ async function tailwind() {
115
+ await ensurePackages3(["eslint-plugin-tailwindcss"]);
116
+ const pluginTailwind = await interopDefault3(
117
+ import("eslint-plugin-tailwindcss")
118
+ );
119
+ return pluginTailwind.configs["flat/recommended"];
120
+ }
121
+
122
+ // src/factories/expo.ts
123
+ async function expo2(options = {}, ...userConfigs) {
124
+ const { query: query2 = true, tailwind: tailwind2 = false } = options;
125
+ const integrations = [
126
+ ...query2 ? await query() : [],
127
+ ...tailwind2 ? await tailwind() : [],
128
+ ...await expo()
129
+ ];
130
+ return antfu(
131
+ {
132
+ ...baseOptions(options),
133
+ react: true
60
134
  },
61
- typescript: {
62
- tsconfigPath: "tsconfig.json"
135
+ ...baseRules(options),
136
+ ...integrations,
137
+ ...userConfigs
138
+ );
139
+ }
140
+
141
+ // src/factories/react.ts
142
+ import { antfu as antfu2 } from "@antfu/eslint-config";
143
+ async function react(options = {}, ...userConfigs) {
144
+ const { query: query2 = true, tailwind: tailwind2 = false } = options;
145
+ const integrations = [
146
+ ...query2 ? await query() : [],
147
+ ...tailwind2 ? await tailwind() : []
148
+ ];
149
+ return antfu2(
150
+ {
151
+ ...baseOptions(options),
152
+ react: true
63
153
  },
64
- yaml: false,
65
- ...options
66
- };
154
+ ...baseRules(options),
155
+ ...integrations,
156
+ ...userConfigs
157
+ );
67
158
  }
68
159
 
69
- // src/index.ts
70
- export * from "@antfu/eslint-config";
71
- async function oncourse(options, ...configs) {
72
- return antfu(
160
+ // src/factories/sencha.ts
161
+ import { antfu as antfu3 } from "@antfu/eslint-config";
162
+
163
+ // src/plugins/sencha.ts
164
+ import { ensurePackages as ensurePackages4, interopDefault as interopDefault4 } from "@antfu/eslint-config";
165
+ async function sencha() {
166
+ await ensurePackages4(["@sencha/eslint-plugin-extjs"]);
167
+ const pluginSencha = await interopDefault4(
168
+ import("@sencha/eslint-plugin-extjs")
169
+ );
170
+ return [
73
171
  {
74
- ...oncourseOptions(options),
75
- ...options
172
+ name: "oncourse/sencha/setup",
173
+ plugins: {
174
+ "@sencha/extjs": pluginSencha
175
+ },
176
+ settings: {
177
+ extjs: {
178
+ version: "latest"
179
+ }
180
+ },
181
+ languageOptions: {
182
+ globals: {
183
+ Ext: "readonly"
184
+ }
185
+ }
76
186
  },
77
- ...oncourseConfigs(),
78
- ...configs
187
+ {
188
+ name: "oncourse/sencha/rules",
189
+ rules: {
190
+ ...pluginSencha.configs.recommended.rules
191
+ }
192
+ }
193
+ ];
194
+ }
195
+
196
+ // src/factories/sencha.ts
197
+ async function sencha2(options = {}, ...userConfigs) {
198
+ return antfu3(
199
+ {
200
+ ...baseOptions(options),
201
+ jsx: false,
202
+ react: false,
203
+ typescript: false
204
+ },
205
+ ...baseRules(options),
206
+ ...await sencha(),
207
+ ...userConfigs
208
+ );
209
+ }
210
+
211
+ // src/index.ts
212
+ export * from "@antfu/eslint-config";
213
+ async function oncourse(options = {}, ...userConfigs) {
214
+ return antfu4(
215
+ baseOptions(options),
216
+ ...baseRules(options),
217
+ ...userConfigs
79
218
  );
80
219
  }
81
- var src_default = oncourse;
220
+ var index_default = oncourse;
82
221
  export {
83
- src_default as default
222
+ baseOptions,
223
+ baseRules,
224
+ index_default as default,
225
+ expo2 as expo,
226
+ oncourse,
227
+ react,
228
+ sencha2 as sencha
84
229
  };
package/package.json CHANGED
@@ -1,80 +1,104 @@
1
1
  {
2
- "name": "@oncoursesystems/eslint-config",
3
- "type": "module",
4
- "version": "1.0.1",
5
- "description": "OnCourse Systems' ESLint configurations",
6
- "author": "OnCourse Systems For Education",
7
- "license": "MIT",
8
- "homepage": "https://github.com/oncoursesystems/eslint-config#readme",
9
- "repository": {
10
- "type": "git",
11
- "url": "git+https://github.com/oncoursesystems/eslint-config.git"
12
- },
13
- "keywords": [
14
- "eslint-config"
15
- ],
16
- "exports": {
17
- ".": {
18
- "types": "./dist/index.d.ts",
19
- "import": "./dist/index.js",
20
- "require": "./dist/index.cjs"
2
+ "name": "@oncoursesystems/eslint-config",
3
+ "type": "module",
4
+ "version": "2.0.0",
5
+ "description": "OnCourse Systems' ESLint configurations",
6
+ "author": "OnCourse Systems For Education",
7
+ "license": "MIT",
8
+ "homepage": "https://github.com/oncoursesystems/eslint-config#readme",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/oncoursesystems/eslint-config.git"
12
+ },
13
+ "keywords": [
14
+ "eslint-config",
15
+ "react",
16
+ "react-native",
17
+ "expo",
18
+ "sencha",
19
+ "extjs"
20
+ ],
21
+ "exports": {
22
+ ".": {
23
+ "types": "./dist/index.d.ts",
24
+ "import": "./dist/index.js",
25
+ "require": "./dist/index.cjs"
26
+ }
27
+ },
28
+ "main": "./dist/index.js",
29
+ "types": "./dist/index.d.ts",
30
+ "files": [
31
+ "dist"
32
+ ],
33
+ "publishConfig": {
34
+ "access": "public"
35
+ },
36
+ "scripts": {
37
+ "build": "tsup --format esm,cjs --clean --dts",
38
+ "stub": "tsup --format esm",
39
+ "dev": "npx @eslint/config-inspector --config eslint.config.ts",
40
+ "build:inspector": "pnpm build && npx @eslint/config-inspector build",
41
+ "watch": "tsup --format esm,cjs --watch",
42
+ "lint": "eslint .",
43
+ "lint:fix": "eslint . --fix",
44
+ "prepack": "pnpm build",
45
+ "release": "bumpp",
46
+ "test": "vitest",
47
+ "typecheck": "tsc --noEmit",
48
+ "prepare": "simple-git-hooks"
49
+ },
50
+ "peerDependencies": {
51
+ "@sencha/eslint-plugin-extjs": "^8.0.0",
52
+ "@tanstack/eslint-plugin-query": "^5.101.0",
53
+ "eslint": "^10.0.0",
54
+ "eslint-plugin-expo": "^1.0.3",
55
+ "eslint-plugin-tailwindcss": "^4.0.0-beta.0"
56
+ },
57
+ "peerDependenciesMeta": {
58
+ "@sencha/eslint-plugin-extjs": {
59
+ "optional": true
60
+ },
61
+ "@tanstack/eslint-plugin-query": {
62
+ "optional": true
63
+ },
64
+ "eslint-plugin-expo": {
65
+ "optional": true
66
+ },
67
+ "eslint-plugin-tailwindcss": {
68
+ "optional": true
69
+ }
70
+ },
71
+ "dependencies": {
72
+ "@antfu/eslint-config": "^9.0.0"
73
+ },
74
+ "devDependencies": {
75
+ "@eslint-react/eslint-plugin": "^5.8.12",
76
+ "@eslint/config-inspector": "^3.0.4",
77
+ "@sencha/eslint-plugin-extjs": "^8.0.0",
78
+ "@tanstack/eslint-plugin-query": "^5.101.0",
79
+ "@types/fs-extra": "^11.0.4",
80
+ "@types/node": "^25.9.2",
81
+ "bumpp": "^11.1.0",
82
+ "eslint": "^10.4.1",
83
+ "eslint-plugin-expo": "^1.0.3",
84
+ "eslint-plugin-format": "^2.0.1",
85
+ "eslint-plugin-react-hooks": "^7.1.1",
86
+ "eslint-plugin-react-refresh": "^0.5.2",
87
+ "eslint-plugin-tailwindcss": "4.0.0-beta.0",
88
+ "execa": "^9.6.1",
89
+ "fast-glob": "^3.3.3",
90
+ "fs-extra": "^11.3.5",
91
+ "jiti": "^2.7.0",
92
+ "lint-staged": "^17.0.7",
93
+ "simple-git-hooks": "^2.13.1",
94
+ "tsup": "^8.5.1",
95
+ "typescript": "^6.0.3",
96
+ "vitest": "^4.1.8"
97
+ },
98
+ "simple-git-hooks": {
99
+ "pre-commit": "npx lint-staged"
100
+ },
101
+ "lint-staged": {
102
+ "*": "eslint --fix"
21
103
  }
22
- },
23
- "main": "./dist/index.js",
24
- "types": "./dist/index.d.ts",
25
- "files": [
26
- "bin",
27
- "dist"
28
- ],
29
- "dependencies": {
30
- "@antfu/eslint-config": "^3.10.0"
31
- },
32
- "devDependencies": {
33
- "@eslint-react/eslint-plugin": "^1.17.1",
34
- "@eslint/config-inspector": "^0.5.6",
35
- "@sencha/eslint-plugin-extjs": "^7.8.0",
36
- "@stylistic/eslint-plugin-migrate": "^2.11.0",
37
- "@tanstack/eslint-plugin-query": "^5.61.4",
38
- "@types/fs-extra": "^11.0.4",
39
- "@types/node": "^22.10.0",
40
- "bumpp": "^9.8.1",
41
- "eslint": "^9.15.0",
42
- "eslint-flat-config-utils": "^0.4.0",
43
- "eslint-plugin-expo": "^0.1.0",
44
- "eslint-plugin-format": "^0.1.2",
45
- "eslint-plugin-react-hooks": "^5.0.0",
46
- "eslint-plugin-react-refresh": "^0.4.14",
47
- "eslint-plugin-tailwindcss": "^3.17.5",
48
- "eslint-typegen": "^0.3.2",
49
- "esno": "^4.8.0",
50
- "execa": "^9.5.1",
51
- "fast-glob": "^3.3.2",
52
- "fs-extra": "^11.2.0",
53
- "jiti": "^2.4.0",
54
- "lint-staged": "^15.2.10",
55
- "prettier": "^3.4.1",
56
- "simple-git-hooks": "^2.11.1",
57
- "tsup": "^8.3.5",
58
- "typescript": "^5.7.2",
59
- "vitest": "^2.1.6",
60
- "wrangler": "^3.90.0"
61
- },
62
- "simple-git-hooks": {
63
- "pre-commit": "npx lint-staged"
64
- },
65
- "lint-staged": {
66
- "*": "eslint --flag unstable_ts_config --fix"
67
- },
68
- "scripts": {
69
- "build": "tsup --format esm,cjs --clean --dts",
70
- "stub": "tsup --format esm",
71
- "dev": "npx @pn --config eslint.config.ts",
72
- "build:inspector": "pnpm build && npx @eslint/config-inspector build",
73
- "watch": "tsup --format esm,cjs --watch",
74
- "lint": "eslint --flag unstable_ts_config .",
75
- "lint:fix": "eslint --flag unstable_ts_config . --fix",
76
- "release": "bumpp && pnpm publish",
77
- "test": "vitest",
78
- "typecheck": "tsc --noEmit"
79
- }
80
- }
104
+ }