@todoist/eslint-config 0.0.0-stage → 13.1.2

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 ADDED
@@ -0,0 +1,144 @@
1
+ # 13.1.2
2
+
3
+ - Publish as `@todoist/eslint-config`, retaining CommonJS and flat/eslintrc entrypoints.
4
+ - Use `@todoist/eslint-plugin-doist@2.0.2` with the `@todoist/doist` rule namespace and ESLint 8.57/9 support.
5
+ - Require Node 24.10 or later to match the plugin's current toolchain policy.
6
+ - Group current and legacy package scopes together when sorting imports.
7
+ - Retain one release artifact for public npm publication and the private GitHub mirror.
8
+
9
+ # 13.0.0
10
+
11
+ - Add flat config support
12
+ - Move .eslintrc to `@doist/eslint-config/eslintrc`
13
+
14
+ See README.md for configuration guidance.
15
+
16
+ # 12.0.1
17
+
18
+ - Enable trusted publishing and npm provenance
19
+
20
+ # 12.0.0
21
+
22
+ - Update `eslint-plugin-react-hooks` to v7.0.1
23
+
24
+ # 11.2.1
25
+
26
+ - Update ESLint rule from `@typescript-eslint/no-throw-literal` to `@typescript-eslint/only-throw-error`
27
+
28
+ # 11.2.0
29
+
30
+ - Add support for typescript-eslint v7 and 8
31
+
32
+ # 11.1.0
33
+
34
+ - Add support for latest `eslint-plugin-simple-import-sort` v12
35
+
36
+ # 11.0.0
37
+
38
+ - Update `@doist/prettier-config` to v4, and drops support for ESLint v7.
39
+
40
+ # 10.0.0
41
+
42
+ - Update the `@typescript-eslint/*` dependencies to v6. This is a breaking change as it requires changing from `recommended-requiring-type-checking` to `recommended-type-checked`. This keeps the package inline with the @typescript-eslint team's naming.
43
+
44
+ # 9.0.0
45
+
46
+ - This change sorts our side effects so that all external dependencies, including css, are imported before our own internal modules.
47
+
48
+ # 8.1.3
49
+
50
+ - Move [eslint-plugin-doist](https://github.com/Doist/eslint-plugin-doist) to dependencies.
51
+
52
+ # 8.1.2
53
+
54
+ - Move [eslint-plugin-doist](https://github.com/Doist/eslint-plugin-doist) to peerDependencies.
55
+
56
+ # 8.1.1
57
+
58
+ - Recommend `gettext-literal-arg`, `import-file-naming` and `static-path-literal-arg` from [eslint-plugin-doist](https://github.com/Doist/eslint-plugin-doist).
59
+
60
+ # 8.0.1
61
+
62
+ - Allow expressions for `react/jsx-no-useless-fragment` ([#120](https://github.com/Doist/eslint-config/pull/120))
63
+
64
+ # 8.0.0
65
+
66
+ - Restrict default and wildcard React imports ([#119](https://github.com/Doist/eslint-config/pull/119))
67
+
68
+ # 7.5.0
69
+
70
+ - _Nothing changed. Trying to fix deploy process._
71
+
72
+ # 7.4.0
73
+
74
+ - _Nothing changed. Trying to fix deploy process._
75
+
76
+ # 7.3.0
77
+
78
+ - _Nothing changed. Trying to fix deploy process._
79
+
80
+ # 7.2.0
81
+
82
+ - Add support for `eslint-plugin-simple-import-sort@8`
83
+
84
+ # 7.1.2
85
+
86
+ - Fixes to work with eslint-config-prettier 8.x.
87
+
88
+ # 7.1.1
89
+
90
+ - Add support for Eslint 8 ([#111](https://github.com/Doist/eslint-config/pull/111))
91
+ - Add `@typescript-eslint/no-useless-constructor` ([#107](https://github.com/Doist/eslint-config/pull/107))
92
+
93
+ # 7.1.0
94
+
95
+ - Add optional configuration with `eslint-plugin-simple-import-sort` ([#106](https://github.com/Doist/eslint-config/pull/106))
96
+ - Update most dependencies to current versions ([#105](https://github.com/Doist/eslint-config/pull/105))
97
+
98
+ # 7.0.0
99
+
100
+ - Add rule `no-useless-return` ([#101](https://github.com/Doist/eslint-config/pull/101))
101
+ - Ignore unused vars prefixed with `_`. ([#99](https://github.com/Doist/eslint-config/pull/99))
102
+
103
+ # 6.0.2
104
+
105
+ - Publish to public npm registry.
106
+
107
+ # 6.0.1
108
+
109
+ - Fix: move `@typescript-eslint/no-implicit-any-catch` to rule to `recommended-requiring-type-checking` config.
110
+
111
+ # 6.0.0
112
+
113
+ - Add [@typescript-eslint/no-implicit-any-catch](https://github.com/Doist/eslint-config/pull/88)
114
+ - Add [no-implicit-coercion](https://github.com/Doist/eslint-config/pull/87)
115
+
116
+ # 5.0.1
117
+
118
+ - Fix: move `no-throw-literal` to rule to `recommended-requiring-type-checking` config.
119
+
120
+ # 5.0.0
121
+
122
+ - Add [no-throw-literal](https://github.com/Doist/eslint-config/pull/82)
123
+ - Add [react/no-unstable-nested-components](https://github.com/Doist/eslint-config/pull/81)
124
+ - Add [react/self-closing-comp](https://github.com/Doist/eslint-config/pull/77)
125
+ - Add [@typescript-eslint/prefer-reduce-type-parameter](https://github.com/Doist/eslint-config/pull/73)
126
+
127
+ # 4.0.0
128
+
129
+ - [Updated peer dependencies](https://github.com/Doist/eslint-config/pull/68)
130
+ - Add [consistent-type-assertions `as`](https://github.com/Doist/eslint-config/pull/67)
131
+ - Add [prefer-optional-chain](https://github.com/Doist/eslint-config/pull/64)
132
+ - Add [prefer-stateless-function](https://github.com/Doist/eslint-config/pull/63)
133
+ - Add [no-unused-expressions](https://github.com/Doist/eslint-config/pull/58)
134
+ - Add [no-void](https://github.com/Doist/eslint-config/pull/57)
135
+
136
+ # 3.0.0
137
+
138
+ - Add [array-callback-return](https://github.com/Doist/eslint-config/pull/45) rule.
139
+ - Add [import/first](https://github.com/Doist/eslint-config/issues/43) rule.
140
+ - Add [import/no-default-export](https://github.com/Doist/eslint-config/issues/41) rule.
141
+
142
+ # 2.0.0
143
+
144
+ - First stable release.
package/README.md CHANGED
@@ -1,3 +1,117 @@
1
- # Temporary Holding Version
1
+ # `@todoist/eslint-config`
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Doist [ESLint](https://eslint.org) config.
4
+
5
+ ## Usage
6
+
7
+ ### Install
8
+
9
+ ```sh
10
+ npm install --save-dev @todoist/eslint-config
11
+ ```
12
+
13
+ Requires Node.js **24.10 or later**, ESLint **8.57 or 9**, and the declared plugin peers.
14
+ The current-forward `@todoist/eslint-plugin-doist@2.0.2` retains all three rules in
15
+ both configuration formats. Import sorting groups `@todoist` and legacy `@doist`
16
+ packages together during migration.
17
+
18
+ ### Flat Config
19
+
20
+ ```js
21
+ // eslint.config.js
22
+ import eslintConfig from '@todoist/eslint-config'
23
+
24
+ export default [
25
+ // Core set of rules, recommended for all JS projects
26
+ ...eslintConfig.recommended,
27
+ // OR
28
+ // Core set of rules, recommended for all TS projects
29
+ ...eslintConfig.recommendedTypeChecked,
30
+
31
+ // Additional rules for sorting/grouping import statements (optional)
32
+ ...eslintConfig.simpleImportSort,
33
+
34
+ // Recommended for projects using React.
35
+ ...eslintConfig.react,
36
+ ]
37
+ ```
38
+
39
+ ### .eslintrc Config (Legacy)
40
+
41
+ In `.eslintrc`:
42
+
43
+ ```jsonc
44
+ {
45
+ // ...
46
+ "extends": [
47
+ // ...
48
+
49
+ // Core set of rules, recommended for all projects.
50
+ "@todoist/eslint-config/eslintrc/recommended",
51
+
52
+ // Additional rules requiring type information (recommended for TypeScript projects).
53
+ "@todoist/eslint-config/eslintrc/recommended-type-checked",
54
+
55
+ // Additional rules for sorting/grouping import statements (optional)
56
+ "@todoist/eslint-config/eslintrc/simple-import-sort",
57
+
58
+ // Recommended for projects using React.
59
+ "@todoist/eslint-config/eslintrc/react",
60
+ ],
61
+
62
+ // When using `recommended-type-checked`,
63
+ // you need to link to `tsconfig.eslint.json` file (see section below) for the project.
64
+ "parserOptions": {
65
+ "project": "tsconfig.eslint.json",
66
+ },
67
+ }
68
+ ```
69
+
70
+ ### Path alias support for import sorting
71
+
72
+ If your project uses path aliases (e.g. `@components` maps to `src/components/`), you can configure `simple-import-sort` to group them together, between third-party and relative imports, by using `simpleImportSortFactory`.
73
+
74
+ **Flat config:**
75
+
76
+ ```js
77
+ // eslint.config.js
78
+ import eslintConfig from '@todoist/eslint-config'
79
+
80
+ export default [
81
+ ...eslintConfig.recommended,
82
+ // Replace ...eslintConfig.simpleImportSort with a custom config:
83
+ ...eslintConfig.simpleImportSortFactory({ aliases: ['@app', '@components'] }),
84
+ ]
85
+ ```
86
+
87
+ **Legacy config** — override the rule in `.eslintrc`:
88
+
89
+ ```js
90
+ const config = {
91
+ extends: ['@todoist/eslint-config/eslintrc/simple-import-sort'],
92
+ rules: {
93
+ 'simple-import-sort/imports':
94
+ require('@todoist/eslint-config/lib/create-simple-import-sort-config').createSimpleImportSortConfig(
95
+ { aliases: ['@app', '@components'] },
96
+ ),
97
+ },
98
+ }
99
+ ```
100
+
101
+ Aliases are grouped together (no blank lines between them), ordered by their position in the array.
102
+
103
+ ### Configuring with type-checking
104
+
105
+ For type-based rules to work, project's `tsconfig.json` file needs to be specified in `parserOptions.project`. If you want to lint files not included in build, we recommend
106
+ creating a separate `tsconfig.eslint.json` config and specifying it instead of the default one.
107
+
108
+ Note: In flat config, `recommendedTypeChecked` sets `project: true` by default, which auto-detects `tsconfig.json`.
109
+
110
+ ## Releasing
111
+
112
+ See [the release runbook](docs/releasing.md) for the pack-only first release,
113
+ registry setup, and retrying a missing mirror with the same artifact.
114
+
115
+ ## Links
116
+
117
+ - [ESLint shareable configs](https://eslint.org/docs/developer-guide/shareable-configs)
@@ -0,0 +1,3 @@
1
+ module.exports = {
2
+ extends: ['./recommended'],
3
+ }
@@ -0,0 +1,34 @@
1
+ module.exports = {
2
+ plugins: ['react', 'react-hooks'],
3
+ extends: [
4
+ 'plugin:react/recommended',
5
+ 'plugin:react-hooks/recommended',
6
+ 'prettier',
7
+ ],
8
+ rules: {
9
+ 'react/no-did-mount-set-state': 'error',
10
+ 'react/no-did-update-set-state': 'error',
11
+ 'react/prefer-stateless-function': 'error',
12
+ 'react/prop-types': ['error', { skipUndeclared: true }],
13
+ 'react/self-closing-comp': 'error',
14
+ 'react/no-unstable-nested-components': 'error',
15
+ 'react/jsx-no-useless-fragment': [
16
+ 'error',
17
+ {
18
+ allowExpressions: true,
19
+ },
20
+ ],
21
+ 'no-restricted-imports': [
22
+ 'error',
23
+ {
24
+ paths: [
25
+ {
26
+ name: 'react',
27
+ importNames: ['*', 'default'],
28
+ message: 'Please use named imports instead.',
29
+ },
30
+ ],
31
+ },
32
+ ],
33
+ },
34
+ }
@@ -0,0 +1,12 @@
1
+ module.exports = {
2
+ extends: ['./recommended', 'plugin:@typescript-eslint/recommended-type-checked'],
3
+ rules: {
4
+ '@typescript-eslint/prefer-includes': 'error',
5
+ '@typescript-eslint/prefer-string-starts-ends-with': 'error',
6
+ '@typescript-eslint/prefer-reduce-type-parameter': 'error',
7
+ 'no-throw-literal': 'off',
8
+ '@typescript-eslint/only-throw-error': ['error'],
9
+ '@typescript-eslint/no-duplicate-type-constituents': 'off',
10
+ '@typescript-eslint/no-redundant-type-constituents': 'off'
11
+ },
12
+ }
@@ -0,0 +1,63 @@
1
+ module.exports = {
2
+ parser: '@typescript-eslint/parser',
3
+ plugins: ['import', '@typescript-eslint', '@todoist/doist'],
4
+ extends: [
5
+ 'eslint:recommended',
6
+ 'plugin:prettier/recommended',
7
+
8
+ 'plugin:import/recommended',
9
+ 'plugin:import/typescript',
10
+
11
+ 'plugin:@typescript-eslint/recommended',
12
+ 'prettier',
13
+ ],
14
+ rules: {
15
+ 'array-callback-return': 'error',
16
+ eqeqeq: ['error', 'smart'],
17
+ 'func-style': ['error', 'declaration'],
18
+ 'no-console': 'error',
19
+ 'no-implicit-coercion': 'error',
20
+ 'no-unused-expressions': 'error',
21
+ 'no-unused-vars': 'off', // Disabled because of @typescript-eslint/no-unused-vars, see: https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-unused-vars.md#how-to-use
22
+ '@typescript-eslint/no-unused-vars': [
23
+ 'error',
24
+ { argsIgnorePattern: '^_', ignoreRestSiblings: true },
25
+ ],
26
+ 'no-use-before-define': 'off', // See: https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-use-before-define.md#how-to-use
27
+ '@typescript-eslint/no-use-before-define': ['error', { functions: false }],
28
+ 'no-useless-constructor': 'off', // See: https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/no-useless-constructor.md#how-to-use
29
+ '@typescript-eslint/no-useless-constructor': 'error',
30
+ '@typescript-eslint/prefer-optional-chain': 'error',
31
+ '@typescript-eslint/consistent-type-assertions': [
32
+ 'error',
33
+ { assertionStyle: 'as', objectLiteralTypeAssertions: 'allow' },
34
+ ],
35
+ 'no-useless-return': 'error',
36
+ 'no-var': 'error',
37
+ 'no-void': 'error',
38
+ 'prefer-promise-reject-errors': 'error',
39
+
40
+ // eslint-config-prettier
41
+ // ref.: https://github.com/prettier/eslint-config-prettier/blob/main/README.md#example-single-quote-configuration
42
+ quotes: ['error', 'single', { avoidEscape: true, allowTemplateLiterals: false }],
43
+
44
+ // eslint-plugin-import
45
+ 'import/first': 'error',
46
+ 'import/newline-after-import': 'error',
47
+ 'import/no-named-as-default': 'error',
48
+ 'import/no-named-as-default-member': 'error',
49
+ 'import/no-duplicates': 'error',
50
+ 'import/no-default-export': 'error',
51
+
52
+ // eslint-plugin-doist
53
+ '@todoist/doist/gettext-literal-arg': 'error',
54
+ '@todoist/doist/static-path-literal-arg': 'error',
55
+ '@todoist/doist/import-file-naming': [
56
+ 'error',
57
+ {
58
+ camelcase: ['jpg', 'png', 'mp4'],
59
+ pascalcase: ['svg'],
60
+ },
61
+ ],
62
+ },
63
+ }
@@ -0,0 +1,9 @@
1
+ const { createSimpleImportSortConfig } = require('../lib/create-simple-import-sort-config')
2
+
3
+ module.exports = {
4
+ plugins: ['simple-import-sort'],
5
+ rules: {
6
+ 'simple-import-sort/imports': createSimpleImportSortConfig(),
7
+ 'simple-import-sort/exports': 'warn',
8
+ },
9
+ }
package/flat/react.js ADDED
@@ -0,0 +1,42 @@
1
+ const react = require('eslint-plugin-react')
2
+ const reactHooks = require('eslint-plugin-react-hooks')
3
+ const prettier = require('eslint-config-prettier/flat')
4
+
5
+ module.exports = [
6
+ react.configs.flat.recommended,
7
+ reactHooks.configs.flat["recommended-latest"],
8
+ prettier,
9
+ {
10
+ settings: {
11
+ react: {
12
+ version: 'detect',
13
+ },
14
+ },
15
+ rules: {
16
+ 'react/no-did-mount-set-state': 'error',
17
+ 'react/no-did-update-set-state': 'error',
18
+ 'react/prefer-stateless-function': 'error',
19
+ 'react/prop-types': ['error', { skipUndeclared: true }],
20
+ 'react/self-closing-comp': 'error',
21
+ 'react/no-unstable-nested-components': 'error',
22
+ 'react/jsx-no-useless-fragment': [
23
+ 'error',
24
+ {
25
+ allowExpressions: true,
26
+ },
27
+ ],
28
+ 'no-restricted-imports': [
29
+ 'error',
30
+ {
31
+ paths: [
32
+ {
33
+ name: 'react',
34
+ importNames: ['*', 'default'],
35
+ message: 'Please use named imports instead.',
36
+ },
37
+ ],
38
+ },
39
+ ],
40
+ },
41
+ },
42
+ ]
@@ -0,0 +1,23 @@
1
+ const tseslint = require('typescript-eslint')
2
+ const recommended = require('./recommended')
3
+
4
+ module.exports = [
5
+ ...recommended,
6
+ ...tseslint.configs.recommendedTypeChecked,
7
+ {
8
+ languageOptions: {
9
+ parserOptions: {
10
+ project: true,
11
+ },
12
+ },
13
+ rules: {
14
+ '@typescript-eslint/prefer-includes': 'error',
15
+ '@typescript-eslint/prefer-string-starts-ends-with': 'error',
16
+ '@typescript-eslint/prefer-reduce-type-parameter': 'error',
17
+ 'no-throw-literal': 'off',
18
+ '@typescript-eslint/only-throw-error': ['error'],
19
+ '@typescript-eslint/no-duplicate-type-constituents': 'off',
20
+ '@typescript-eslint/no-redundant-type-constituents': 'off',
21
+ },
22
+ },
23
+ ]
@@ -0,0 +1,80 @@
1
+ const eslint = require('@eslint/js')
2
+ const tseslint = require('typescript-eslint')
3
+ const importPlugin = require('eslint-plugin-import')
4
+ const prettierConfig = require('eslint-config-prettier')
5
+ const doistPlugin = require('@todoist/eslint-plugin-doist')
6
+ const globals = require('globals')
7
+
8
+ module.exports = [
9
+ eslint.configs.recommended,
10
+ ...tseslint.configs.recommended,
11
+ importPlugin.flatConfigs.recommended,
12
+ importPlugin.flatConfigs.typescript,
13
+ prettierConfig,
14
+ {
15
+ plugins: {
16
+ '@todoist/doist': doistPlugin,
17
+ },
18
+ languageOptions: {
19
+ parser: tseslint.parser,
20
+ globals: {
21
+ ...globals.browser,
22
+ ...globals.node,
23
+ },
24
+ },
25
+ settings: {
26
+ 'import/resolver': {
27
+ typescript: true,
28
+ node: true,
29
+ },
30
+ },
31
+ rules: {
32
+ 'array-callback-return': 'error',
33
+ eqeqeq: ['error', 'smart'],
34
+ 'func-style': ['error', 'declaration'],
35
+ 'no-console': 'error',
36
+ 'no-implicit-coercion': 'error',
37
+ 'no-unused-expressions': 'error',
38
+ 'no-unused-vars': 'off',
39
+ '@typescript-eslint/no-unused-vars': [
40
+ 'error',
41
+ { argsIgnorePattern: '^_', ignoreRestSiblings: true },
42
+ ],
43
+ 'no-use-before-define': 'off',
44
+ '@typescript-eslint/no-use-before-define': ['error', { functions: false }],
45
+ 'no-useless-constructor': 'off',
46
+ '@typescript-eslint/no-useless-constructor': 'error',
47
+ '@typescript-eslint/prefer-optional-chain': 'error',
48
+ '@typescript-eslint/consistent-type-assertions': [
49
+ 'error',
50
+ { assertionStyle: 'as', objectLiteralTypeAssertions: 'allow' },
51
+ ],
52
+ 'no-useless-return': 'error',
53
+ 'no-var': 'error',
54
+ 'no-void': 'error',
55
+ 'prefer-promise-reject-errors': 'error',
56
+
57
+ // eslint-config-prettier
58
+ quotes: ['error', 'single', { avoidEscape: true, allowTemplateLiterals: false }],
59
+
60
+ // eslint-plugin-import
61
+ 'import/first': 'error',
62
+ 'import/newline-after-import': 'error',
63
+ 'import/no-named-as-default': 'error',
64
+ 'import/no-named-as-default-member': 'error',
65
+ 'import/no-duplicates': 'error',
66
+ 'import/no-default-export': 'error',
67
+
68
+ // eslint-plugin-doist
69
+ '@todoist/doist/gettext-literal-arg': 'error',
70
+ '@todoist/doist/static-path-literal-arg': 'error',
71
+ '@todoist/doist/import-file-naming': [
72
+ 'error',
73
+ {
74
+ camelcase: ['jpg', 'png', 'mp4'],
75
+ pascalcase: ['svg'],
76
+ },
77
+ ],
78
+ },
79
+ },
80
+ ]
@@ -0,0 +1,14 @@
1
+ const simpleImportSort = require('eslint-plugin-simple-import-sort')
2
+ const { createSimpleImportSortConfig } = require('../lib/create-simple-import-sort-config')
3
+
4
+ module.exports = [
5
+ {
6
+ plugins: {
7
+ 'simple-import-sort': simpleImportSort,
8
+ },
9
+ rules: {
10
+ 'simple-import-sort/imports': createSimpleImportSortConfig(),
11
+ 'simple-import-sort/exports': 'warn',
12
+ },
13
+ },
14
+ ]
package/index.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ import type { Linter } from 'eslint'
2
+
3
+ declare const config: {
4
+ recommended: Linter.Config[]
5
+ recommendedTypeChecked: Linter.Config[]
6
+ react: Linter.Config[]
7
+ simpleImportSort: Linter.Config[]
8
+ simpleImportSortFactory: (options?: { aliases?: string[] }) => Linter.Config[]
9
+ }
10
+
11
+ export = config
package/index.js ADDED
@@ -0,0 +1,21 @@
1
+ const simpleImportSortPlugin = require('eslint-plugin-simple-import-sort')
2
+ const { createSimpleImportSortConfig } = require('./lib/create-simple-import-sort-config')
3
+
4
+ module.exports = {
5
+ recommended: require('./flat/recommended'),
6
+ recommendedTypeChecked: require('./flat/recommended-type-checked'),
7
+ react: require('./flat/react'),
8
+ simpleImportSort: require('./flat/simple-import-sort'),
9
+ /** @param {Parameters<typeof createSimpleImportSortConfig>[0]} options */
10
+ simpleImportSortFactory(options) {
11
+ return [
12
+ {
13
+ plugins: { 'simple-import-sort': simpleImportSortPlugin },
14
+ rules: {
15
+ 'simple-import-sort/imports': createSimpleImportSortConfig(options),
16
+ 'simple-import-sort/exports': 'warn',
17
+ },
18
+ },
19
+ ]
20
+ },
21
+ }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Generates simple-import-sort groups with optional alias support.
3
+ * Aliases share a single group (no blank lines between them), ordered by their
4
+ * position in the array, placed between third-party and relative imports.
5
+ *
6
+ * @param { object } [options]
7
+ * @param { string[] } [options.aliases] - Ordered array of alias prefixes (e.g. ['@app', '@pages', '@state'])
8
+ * @returns {import('eslint').Linter.RuleLevelAndOptions} The rule value for 'simple-import-sort/imports'
9
+ */
10
+ function createSimpleImportSortConfig({ aliases = [] } = {}) {
11
+ const aliasGroup = aliases.map((a) => `^${a}(/|$)`)
12
+
13
+ const aliasNames = aliases
14
+ .filter((a) => a.startsWith('@'))
15
+ .map((a) => a.slice(1).replace(/[.*+?^${}()|[\]\\]/g, '\\$&'))
16
+ const scopedThirdParty =
17
+ aliasNames.length > 0 ? `^@(?!(${aliasNames.join('|')})(/|$))\\w` : '^@\\w'
18
+
19
+ const groups = [
20
+ // Node.js builtins (supports both 'fs' and 'node:fs')
21
+ [`^(node:)?(${require('module').builtinModules.join('|')})(/|$)`],
22
+ // Third-party modules (side effects)
23
+ ['^\\u0000@?\\w'],
24
+ // Current and legacy Doist stylesheets (side effects)
25
+ ['^\\u0000@(todoist|doist)/.*\\.(s?css|less)$'],
26
+ // Third-party stylesheets (side effects)
27
+ ['^\\u0000@?\\w.*\\.(s?css|less)$'],
28
+ // Internal modules (side effects)
29
+ ['^\\u0000\\..*'],
30
+ // Internal stylesheets (side effects)
31
+ ['^\\u0000\\..*\\.(s?css|less)$'],
32
+ // React and related modules
33
+ ['^react'],
34
+ // Current and legacy Doist modules
35
+ ['^@(todoist|doist)/'],
36
+ // Third-party modules (excluding aliases)
37
+ [scopedThirdParty, '^\\w'],
38
+ // Aliases (ordered)
39
+ ...(aliasGroup.length > 0 ? [aliasGroup] : []),
40
+ // Internal parent-level modules
41
+ ['^\\.\\.(?!/?$)', '^\\.\\./?$'],
42
+ // Internal same-level modules
43
+ ['^\\./(?=.*/)(?!/?$)', '^\\.(?!/?$)', '^\\./?$'],
44
+ // Internal CSS Modules
45
+ ['^.*\\.module\\.css$'],
46
+ // Internal type imports as a separate group
47
+ ['^@?\\w.*\\u0000$', '^[^.].*\\u0000$', '^\\..*\\u0000$'],
48
+ ]
49
+
50
+ return ['warn', { groups }]
51
+ }
52
+
53
+ module.exports = { createSimpleImportSortConfig }
package/package.json CHANGED
@@ -1,6 +1,63 @@
1
1
  {
2
- "name": "@todoist/eslint-config",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
2
+ "name": "@todoist/eslint-config",
3
+ "version": "13.1.2",
4
+ "description": "Doist global [eslint](https://eslint.org) config.",
5
+ "repository": "https://github.com/todoist/eslint-config",
6
+ "main": "index.js",
7
+ "types": "index.d.ts",
8
+ "exports": {
9
+ ".": "./index.js",
10
+ "./eslintrc": "./eslintrc/index.js",
11
+ "./eslintrc/*": "./eslintrc/*.js",
12
+ "./lib/*": "./lib/*.js"
13
+ },
14
+ "author": "David Miotti <davidm@doist.com>",
15
+ "license": "MIT",
16
+ "prettier": "@todoist/prettier-config",
17
+ "engines": {
18
+ "node": ">=24.10.0"
19
+ },
20
+ "peerDependencies": {
21
+ "@typescript-eslint/eslint-plugin": "^6.0.0 || ^7.0.0 || ^8.0.0",
22
+ "@typescript-eslint/parser": "^6.0.0 || ^7.0.0 || ^8.0.0",
23
+ "eslint": "^8.57.0 || ^9.0.0",
24
+ "eslint-plugin-import": "^2.29.0",
25
+ "eslint-plugin-prettier": "^5.0.0",
26
+ "eslint-plugin-react": "^7.29.4",
27
+ "eslint-plugin-react-hooks": "^7.0.1",
28
+ "eslint-plugin-simple-import-sort": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^12.0.0"
29
+ },
30
+ "dependencies": {
31
+ "@todoist/eslint-plugin-doist": "2.0.2",
32
+ "@eslint/js": "^9.0.0",
33
+ "eslint-config-prettier": "^10.1.1",
34
+ "globals": "^15.0.0",
35
+ "typescript-eslint": "^8.0.0"
36
+ },
37
+ "devDependencies": {
38
+ "@todoist/prettier-config": "4.0.2",
39
+ "@types/eslint": "8.44.1",
40
+ "@types/eslint-config-prettier": "6.11.3",
41
+ "@types/jest": "29.5.1",
42
+ "eslint": "8.57.0",
43
+ "eslint-import-resolver-typescript": "4.4.4",
44
+ "eslint-plugin-react": "7.37.5",
45
+ "eslint-plugin-simple-import-sort": "10.0.0",
46
+ "jest": "29.5.0",
47
+ "ts-jest": "29.1.0"
48
+ },
49
+ "scripts": {
50
+ "test": "jest",
51
+ "test:watch": "jest --watch",
52
+ "test:compat": "node --test tests/config-compatibility.cjs",
53
+ "test:release": "node --test .github/scripts/release.test.mjs"
54
+ },
55
+ "files": [
56
+ "index.js",
57
+ "index.d.ts",
58
+ "flat/",
59
+ "eslintrc/",
60
+ "lib/",
61
+ "CHANGELOG.md"
62
+ ]
63
+ }