@elliemae/pui-cli 9.0.0-alpha.1 → 9.0.0-alpha.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/README.md +33 -0
- package/dist/cjs/commands/test.js +0 -1
- package/dist/cjs/commands/utils.js +4 -4
- package/dist/cjs/commands/vitest.js +0 -1
- package/dist/cjs/index.cjs +12 -0
- package/dist/cjs/index.js +6 -0
- package/dist/cjs/lint-config/eslint/common.cjs +1 -1
- package/dist/cjs/lint-config/eslint/flat/common.mjs +167 -0
- package/dist/cjs/lint-config/eslint/flat/index.mjs +20 -0
- package/dist/cjs/lint-config/eslint/flat/non-react-export.mjs +10 -0
- package/dist/cjs/lint-config/eslint/flat/non-react.mjs +6 -0
- package/dist/cjs/lint-config/eslint/flat/presets.mjs +78 -0
- package/dist/cjs/lint-config/eslint/flat/react-export.mjs +7 -0
- package/dist/cjs/lint-config/eslint/flat/react.mjs +60 -0
- package/dist/cjs/lint-config/eslint/flat/rules.mjs +185 -0
- package/dist/cjs/lint-config/eslint/typescript/non-react.cjs +1 -1
- package/dist/cjs/lint-config/eslint/typescript/react.cjs +1 -1
- package/dist/cjs/monorepo/utils.cjs +2 -2
- package/dist/cjs/monorepo/utils.js +1 -1
- package/dist/cjs/testing/jest.config.cjs +4 -4
- package/dist/cjs/testing/resolver.cjs +1 -1
- package/dist/cjs/testing/setup-react-env.js +1 -1
- package/dist/cjs/transpile/esbuild.js +1 -1
- package/dist/cjs/webpack/csp-plugin.js +2 -4
- package/dist/cjs/webpack/prop-types-shim.js +0 -1
- package/dist/cjs/webpack/webpack.lib.base.babel.js +0 -8
- package/dist/esm/commands/test.js +0 -1
- package/dist/esm/commands/utils.js +4 -4
- package/dist/esm/commands/vitest.js +0 -1
- package/dist/esm/index.cjs +12 -0
- package/dist/esm/index.js +12 -0
- package/dist/esm/lint-config/eslint/common.cjs +1 -1
- package/dist/esm/lint-config/eslint/flat/common.mjs +167 -0
- package/dist/esm/lint-config/eslint/flat/index.mjs +20 -0
- package/dist/esm/lint-config/eslint/flat/non-react-export.mjs +10 -0
- package/dist/esm/lint-config/eslint/flat/non-react.mjs +6 -0
- package/dist/esm/lint-config/eslint/flat/presets.mjs +78 -0
- package/dist/esm/lint-config/eslint/flat/react-export.mjs +7 -0
- package/dist/esm/lint-config/eslint/flat/react.mjs +60 -0
- package/dist/esm/lint-config/eslint/flat/rules.mjs +185 -0
- package/dist/esm/lint-config/eslint/typescript/non-react.cjs +1 -1
- package/dist/esm/lint-config/eslint/typescript/react.cjs +1 -1
- package/dist/esm/monorepo/utils.cjs +2 -2
- package/dist/esm/monorepo/utils.js +1 -1
- package/dist/esm/testing/jest.config.cjs +4 -4
- package/dist/esm/testing/resolver.cjs +1 -1
- package/dist/esm/testing/setup-react-env.js +1 -1
- package/dist/esm/transpile/esbuild.js +1 -1
- package/dist/esm/webpack/csp-plugin.js +2 -4
- package/dist/esm/webpack/prop-types-shim.js +0 -1
- package/dist/esm/webpack/webpack.lib.base.babel.js +0 -8
- package/dist/types/lib/commands/build.d.ts +1 -1
- package/dist/types/lib/commands/buildcdn.d.ts +1 -1
- package/dist/types/lib/commands/codemod.d.ts +1 -1
- package/dist/types/lib/commands/gendoc.d.ts +1 -1
- package/dist/types/lib/commands/lint.d.ts +1 -1
- package/dist/types/lib/commands/pack.d.ts +1 -1
- package/dist/types/lib/commands/start.d.ts +1 -1
- package/dist/types/lib/commands/storybook.d.ts +1 -1
- package/dist/types/lib/commands/test.d.ts +1 -1
- package/dist/types/lib/commands/tscheck.d.ts +1 -1
- package/dist/types/lib/commands/version.d.ts +1 -1
- package/dist/types/lib/commands/vitest.d.ts +1 -1
- package/dist/types/lib/index.d.cts +5 -1
- package/dist/types/lib/index.d.ts +4 -0
- package/dist/types/lib/lint-config/eslint/flat/common.d.mts +6 -0
- package/dist/types/lib/lint-config/eslint/flat/index.d.mts +6 -0
- package/dist/types/lib/lint-config/eslint/flat/non-react-export.d.mts +4 -0
- package/dist/types/lib/lint-config/eslint/flat/non-react.d.mts +3 -0
- package/dist/types/lib/lint-config/eslint/flat/presets.d.mts +63 -0
- package/dist/types/lib/lint-config/eslint/flat/react-export.d.mts +4 -0
- package/dist/types/lib/lint-config/eslint/flat/react.d.mts +4 -0
- package/dist/types/lib/lint-config/eslint/flat/rules.d.mts +358 -0
- package/dist/types/lib/server/appRoutes.d.ts +1 -1
- package/dist/types/lib/server/csp.d.ts +1 -1
- package/dist/types/lib/server/middlewares.d.ts +1 -1
- package/dist/types/lib/webpack/csp-plugin.d.ts +3 -3
- package/dist/types/lib/webpack/helpers.d.ts +1 -1
- package/dist/types/lib/webpack/interceptor-middleware.d.ts +2 -2
- package/dist/types/lib/webpack/webpack.base.babel.d.ts +1 -1
- package/dist/types/lib/webpack/webpack.lib.base.babel.d.ts +1 -1
- package/dist/types/lib/webpack/webpack.lib.prod.babel.d.ts +1 -1
- package/dist/types/lib/webpack/webpack.prod.babel.d.ts +1 -1
- package/dist/types/lib/webpack/webpack.storybook.d.ts +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/lib/lint-config/commitlint.config.cjs +1 -0
- package/lib/lint-config/eslint/common.cjs +164 -0
- package/lib/lint-config/eslint/flat/common.mjs +167 -0
- package/lib/lint-config/eslint/flat/index.mjs +20 -0
- package/lib/lint-config/eslint/flat/non-react-export.mjs +10 -0
- package/lib/lint-config/eslint/flat/non-react.mjs +6 -0
- package/lib/lint-config/eslint/flat/presets.mjs +78 -0
- package/lib/lint-config/eslint/flat/react-export.mjs +7 -0
- package/lib/lint-config/eslint/flat/react.mjs +60 -0
- package/lib/lint-config/eslint/flat/rules.mjs +185 -0
- package/lib/lint-config/eslint/non-react.cjs +14 -0
- package/lib/lint-config/eslint/react.cjs +26 -0
- package/lib/lint-config/eslint/typescript/common.cjs +49 -0
- package/lib/lint-config/eslint/typescript/non-react.cjs +12 -0
- package/lib/lint-config/eslint/typescript/react.cjs +19 -0
- package/lib/lint-config/lint-staged.config.js +15 -0
- package/lib/lint-config/prettier.config.cjs +8 -0
- package/lib/lint-config/stylelint.config.cjs +19 -0
- package/package.json +21 -22
package/README.md
CHANGED
|
@@ -8,6 +8,39 @@
|
|
|
8
8
|
|
|
9
9
|
## Migration Guide
|
|
10
10
|
|
|
11
|
+
### ESLint 9 flat config (alpha)
|
|
12
|
+
|
|
13
|
+
`pui-cli` now ships ESLint 9 with `typescript-eslint` v8 flat configs. Replace legacy `.eslintrc.cjs` with:
|
|
14
|
+
|
|
15
|
+
```js
|
|
16
|
+
// eslint.config.mjs — React apps and libraries
|
|
17
|
+
import { eslintFlatConfig } from '@elliemae/pui-cli/eslint';
|
|
18
|
+
|
|
19
|
+
export default eslintFlatConfig;
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
```js
|
|
23
|
+
// eslint.config.mjs — non-React Node/TS services
|
|
24
|
+
import { eslintFlatBaseConfig } from '@elliemae/pui-cli/eslint';
|
|
25
|
+
|
|
26
|
+
export default eslintFlatBaseConfig;
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**Strict mode** (after the default config is clean — `no-unsafe-*` and `exhaustive-deps` as error):
|
|
30
|
+
|
|
31
|
+
```js
|
|
32
|
+
import { eslintFlatConfigStrict } from '@elliemae/pui-cli/eslint';
|
|
33
|
+
// or eslintFlatBaseConfigStrict for non-React
|
|
34
|
+
|
|
35
|
+
export default eslintFlatConfigStrict;
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Remove `.eslintrc.cjs` and `.eslintignore` (ignores are included in the shared config). Run `pui-cli lint` / `pui-cli lint --fix` after upgrading `@elliemae/pui-cli`.
|
|
39
|
+
|
|
40
|
+
**Breaking changes:** Airbnb presets removed; type-aware rules use `projectService`; `import-x/*` replaces `import/*`; Prettier is not enforced via ESLint (use `lint-staged` / `prettier --write`).
|
|
41
|
+
|
|
42
|
+
**Rule-by-rule comparison:** [ESLint rules migration guide](docs/eslint-rules-migration.md) — old vs new presets, renamed rules, and what teams should expect after upgrade.
|
|
43
|
+
|
|
11
44
|
### v7 to v8
|
|
12
45
|
|
|
13
46
|
[Changelog](https://confluence.ice.com/display/FEAE/CLI+ChangeLog#CLIChangeLog-v8)
|
|
@@ -71,7 +71,7 @@ const readPackageLock = async () => {
|
|
|
71
71
|
const pkgLockJSON = await (0, import_promises.readFile)(appPkgLockFile, "utf8");
|
|
72
72
|
const { dependencies } = JSON.parse(pkgLockJSON);
|
|
73
73
|
return (moduleName) => dependencies[moduleName]?.version || "";
|
|
74
|
-
} catch
|
|
74
|
+
} catch {
|
|
75
75
|
console.warn("Package lock file not found");
|
|
76
76
|
return () => "";
|
|
77
77
|
}
|
|
@@ -101,8 +101,8 @@ const getModulesInfo = async () => {
|
|
|
101
101
|
cli: getModuleVersion("@elliemae/pui-cli"),
|
|
102
102
|
dimsum: getModuleVersion("@elliemae/ds-system")
|
|
103
103
|
};
|
|
104
|
-
} catch
|
|
105
|
-
console.warn(
|
|
104
|
+
} catch {
|
|
105
|
+
console.warn("Package lock file not found");
|
|
106
106
|
return {};
|
|
107
107
|
}
|
|
108
108
|
};
|
|
@@ -206,7 +206,7 @@ const isPathExist = async (pathToCheck) => {
|
|
|
206
206
|
try {
|
|
207
207
|
await (0, import_promises.access)(pathToCheck, import_node_fs.constants.F_OK);
|
|
208
208
|
return true;
|
|
209
|
-
} catch
|
|
209
|
+
} catch {
|
|
210
210
|
return false;
|
|
211
211
|
}
|
|
212
212
|
};
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
const { babelConfig } = require('./babel.config.cjs');
|
|
2
|
+
const {
|
|
3
|
+
eslintFlatBaseConfig,
|
|
4
|
+
eslintFlatBaseConfigStrict,
|
|
5
|
+
} = require('./lint-config/eslint/flat/non-react-export.mjs');
|
|
6
|
+
const {
|
|
7
|
+
eslintFlatConfig,
|
|
8
|
+
eslintFlatConfigStrict,
|
|
9
|
+
} = require('./lint-config/eslint/flat/react-export.mjs');
|
|
2
10
|
const {
|
|
3
11
|
esConfig: eslintBaseConfig,
|
|
4
12
|
} = require('./lint-config/eslint/non-react.cjs');
|
|
@@ -13,6 +21,10 @@ const { jestNodeConfig } = require('./testing/jest.node.config.cjs');
|
|
|
13
21
|
|
|
14
22
|
module.exports = {
|
|
15
23
|
babelConfig,
|
|
24
|
+
eslintFlatBaseConfig,
|
|
25
|
+
eslintFlatBaseConfigStrict,
|
|
26
|
+
eslintFlatConfig,
|
|
27
|
+
eslintFlatConfigStrict,
|
|
16
28
|
eslintBaseConfig,
|
|
17
29
|
eslintConfig,
|
|
18
30
|
stylelintConfig,
|
package/dist/cjs/index.js
CHANGED
|
@@ -22,6 +22,10 @@ __export(index_exports, {
|
|
|
22
22
|
commitlintConfig: () => import_commitlint_config.commitlintConfig,
|
|
23
23
|
eslintBaseConfig: () => import_non_react.esConfig,
|
|
24
24
|
eslintConfig: () => import_react.esReactConfig,
|
|
25
|
+
eslintFlatBaseConfig: () => import_non_react_export.eslintFlatBaseConfig,
|
|
26
|
+
eslintFlatBaseConfigStrict: () => import_non_react_export.eslintFlatBaseConfigStrict,
|
|
27
|
+
eslintFlatConfig: () => import_react_export.eslintFlatConfig,
|
|
28
|
+
eslintFlatConfigStrict: () => import_react_export.eslintFlatConfigStrict,
|
|
25
29
|
jestConfig: () => import_jest_config.jestConfig,
|
|
26
30
|
jestNodeConfig: () => import_jest_node_config.jestNodeConfig,
|
|
27
31
|
lintStagedConfig: () => import_lint_staged_config.lintStagedConfig,
|
|
@@ -32,6 +36,8 @@ __export(index_exports, {
|
|
|
32
36
|
});
|
|
33
37
|
module.exports = __toCommonJS(index_exports);
|
|
34
38
|
var import_babel_config = require("./babel.config.cjs");
|
|
39
|
+
var import_non_react_export = require("./lint-config/eslint/flat/non-react-export.mjs");
|
|
40
|
+
var import_react_export = require("./lint-config/eslint/flat/react-export.mjs");
|
|
35
41
|
var import_non_react = require("./lint-config/eslint/non-react.cjs");
|
|
36
42
|
var import_react = require("./lint-config/eslint/react.cjs");
|
|
37
43
|
var import_stylelint_config = require("./lint-config/stylelint.config.cjs");
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import eslint from '@eslint/js';
|
|
2
|
+
import { defineConfig } from 'eslint/config';
|
|
3
|
+
import eslintConfigPrettier from 'eslint-config-prettier';
|
|
4
|
+
import eslintComments from 'eslint-plugin-eslint-comments';
|
|
5
|
+
import importX from 'eslint-plugin-import-x';
|
|
6
|
+
import jest from 'eslint-plugin-jest';
|
|
7
|
+
import testingLibrary from 'eslint-plugin-testing-library';
|
|
8
|
+
import wdio from 'eslint-plugin-wdio';
|
|
9
|
+
import globals from 'globals';
|
|
10
|
+
import tseslint from 'typescript-eslint';
|
|
11
|
+
import {
|
|
12
|
+
jestRecommendedRules,
|
|
13
|
+
sharedCoreRules,
|
|
14
|
+
storybookFiles,
|
|
15
|
+
testFiles,
|
|
16
|
+
testJsxFiles,
|
|
17
|
+
testingLibraryDomRules,
|
|
18
|
+
testingLibraryReactRules,
|
|
19
|
+
wdioGlobals,
|
|
20
|
+
wdioRecommendedRules,
|
|
21
|
+
wdioSpecFiles,
|
|
22
|
+
} from './presets.mjs';
|
|
23
|
+
import {
|
|
24
|
+
ignorePatterns,
|
|
25
|
+
jsRules,
|
|
26
|
+
typescriptRules,
|
|
27
|
+
typescriptStrictRules,
|
|
28
|
+
typescriptTestRelaxedRules,
|
|
29
|
+
} from './rules.mjs';
|
|
30
|
+
|
|
31
|
+
const tsconfigRootDir = process.cwd();
|
|
32
|
+
|
|
33
|
+
const typescriptParserOptions = {
|
|
34
|
+
projectService: true,
|
|
35
|
+
tsconfigRootDir,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/** Cached flat config arrays (only two variants: default + strict). */
|
|
39
|
+
const configCache = new Map();
|
|
40
|
+
|
|
41
|
+
/** @param {Record<string, unknown>} tsRules - `typescriptRules` or `typescriptStrictRules` */
|
|
42
|
+
export function createBaseFlatConfigs(tsRules) {
|
|
43
|
+
if (configCache.has(tsRules)) {
|
|
44
|
+
return configCache.get(tsRules);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const config = defineConfig(
|
|
48
|
+
{ ignores: ignorePatterns },
|
|
49
|
+
eslint.configs.recommended,
|
|
50
|
+
eslintConfigPrettier,
|
|
51
|
+
{
|
|
52
|
+
plugins: {
|
|
53
|
+
'eslint-comments': eslintComments,
|
|
54
|
+
'import-x': importX,
|
|
55
|
+
},
|
|
56
|
+
languageOptions: {
|
|
57
|
+
ecmaVersion: 'latest',
|
|
58
|
+
sourceType: 'module',
|
|
59
|
+
parserOptions: {
|
|
60
|
+
ecmaFeatures: { jsx: true },
|
|
61
|
+
},
|
|
62
|
+
globals: {
|
|
63
|
+
...globals.browser,
|
|
64
|
+
...globals.node,
|
|
65
|
+
...globals.es2021,
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
settings: {
|
|
69
|
+
'import-x/resolver': {
|
|
70
|
+
node: { extensions: ['.js', '.jsx', '.ts', '.tsx'] },
|
|
71
|
+
typescript: { alwaysTryTypes: true },
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
rules: sharedCoreRules,
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
files: ['**/*.{js,jsx,mjs,cjs}'],
|
|
78
|
+
rules: jsRules,
|
|
79
|
+
},
|
|
80
|
+
...tseslint.configs.recommendedTypeChecked.map((config) => ({
|
|
81
|
+
...config,
|
|
82
|
+
files: ['**/*.{ts,tsx}'],
|
|
83
|
+
})),
|
|
84
|
+
{
|
|
85
|
+
files: ['**/*.{ts,tsx}'],
|
|
86
|
+
rules: tsRules,
|
|
87
|
+
languageOptions: {
|
|
88
|
+
parserOptions: typescriptParserOptions,
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
files: testFiles,
|
|
93
|
+
plugins: {
|
|
94
|
+
jest,
|
|
95
|
+
'testing-library': testingLibrary,
|
|
96
|
+
},
|
|
97
|
+
languageOptions: {
|
|
98
|
+
globals: globals.jest,
|
|
99
|
+
},
|
|
100
|
+
settings: {
|
|
101
|
+
jest: { version: 'detect' },
|
|
102
|
+
},
|
|
103
|
+
rules: {
|
|
104
|
+
...jestRecommendedRules,
|
|
105
|
+
...testingLibraryDomRules,
|
|
106
|
+
'testing-library/no-node-access': 'off',
|
|
107
|
+
...typescriptTestRelaxedRules,
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
files: testJsxFiles,
|
|
112
|
+
rules: {
|
|
113
|
+
...testingLibraryReactRules,
|
|
114
|
+
'testing-library/no-node-access': 'off',
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
files: wdioSpecFiles,
|
|
119
|
+
plugins: { wdio, jest },
|
|
120
|
+
languageOptions: { globals: wdioGlobals },
|
|
121
|
+
rules: {
|
|
122
|
+
...wdioRecommendedRules,
|
|
123
|
+
'jest/valid-expect': 'off',
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
files: ['**/eslint.config.{mjs,cjs,js}'],
|
|
128
|
+
rules: { 'import-x/no-unresolved': 'off' },
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
files: ['**/scripts/**', '**/ci_cd/**'],
|
|
132
|
+
rules: {
|
|
133
|
+
'no-console': 'off',
|
|
134
|
+
'max-lines': 'off',
|
|
135
|
+
complexity: 'off',
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
files: storybookFiles,
|
|
140
|
+
rules: { 'import-x/no-extraneous-dependencies': 'off' },
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
files: ['**/lint-config/**'],
|
|
144
|
+
rules: {
|
|
145
|
+
'max-lines': 'off',
|
|
146
|
+
'import-x/no-named-as-default-member': 'off',
|
|
147
|
+
'import-x/default': 'off',
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
files: ['**/*.d.ts'],
|
|
152
|
+
rules: {
|
|
153
|
+
'@typescript-eslint/no-explicit-any': 'off',
|
|
154
|
+
'@typescript-eslint/no-empty-object-type': 'off',
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
configCache.set(tsRules, config);
|
|
160
|
+
return config;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/** Default flat base — `no-unsafe-*` as warn in application TypeScript. */
|
|
164
|
+
export const baseFlatConfigs = createBaseFlatConfigs(typescriptRules);
|
|
165
|
+
|
|
166
|
+
/** Strict flat base — `no-unsafe-*` as error in application TypeScript. */
|
|
167
|
+
export const baseFlatConfigsStrict = createBaseFlatConfigs(typescriptStrictRules);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export { eslintFlatConfig, eslintFlatConfigStrict } from './react-export.mjs';
|
|
2
|
+
export {
|
|
3
|
+
eslintFlatBaseConfig,
|
|
4
|
+
eslintFlatBaseConfigStrict,
|
|
5
|
+
} from './non-react-export.mjs';
|
|
6
|
+
export { reactFlatConfigs, reactFlatConfigsStrict } from './react.mjs';
|
|
7
|
+
export {
|
|
8
|
+
nonReactFlatConfigs,
|
|
9
|
+
nonReactFlatConfigsStrict,
|
|
10
|
+
} from './non-react.mjs';
|
|
11
|
+
export {
|
|
12
|
+
baseFlatConfigs,
|
|
13
|
+
baseFlatConfigsStrict,
|
|
14
|
+
createBaseFlatConfigs,
|
|
15
|
+
} from './common.mjs';
|
|
16
|
+
export {
|
|
17
|
+
storybookFiles,
|
|
18
|
+
testFiles,
|
|
19
|
+
testJsxFiles,
|
|
20
|
+
} from './presets.mjs';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
nonReactFlatConfigs,
|
|
3
|
+
nonReactFlatConfigsStrict,
|
|
4
|
+
} from './non-react.mjs';
|
|
5
|
+
|
|
6
|
+
/** Flat ESLint config for non-React TypeScript libraries and services. */
|
|
7
|
+
export const eslintFlatBaseConfig = nonReactFlatConfigs;
|
|
8
|
+
|
|
9
|
+
/** Strict flat ESLint config for non-React TypeScript (`no-unsafe-*` as error). */
|
|
10
|
+
export const eslintFlatBaseConfigStrict = nonReactFlatConfigsStrict;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preset rule bundles and file globs computed once at module load (not per config factory call).
|
|
3
|
+
*/
|
|
4
|
+
import eslintComments from 'eslint-plugin-eslint-comments';
|
|
5
|
+
import importX from 'eslint-plugin-import-x';
|
|
6
|
+
import jest from 'eslint-plugin-jest';
|
|
7
|
+
import jsxA11y from 'eslint-plugin-jsx-a11y';
|
|
8
|
+
import react from 'eslint-plugin-react';
|
|
9
|
+
import reactHooks from 'eslint-plugin-react-hooks';
|
|
10
|
+
import reduxSaga from 'eslint-plugin-redux-saga';
|
|
11
|
+
import storybook from 'eslint-plugin-storybook';
|
|
12
|
+
import testingLibrary from 'eslint-plugin-testing-library';
|
|
13
|
+
import wdio from 'eslint-plugin-wdio';
|
|
14
|
+
|
|
15
|
+
export const testFiles = [
|
|
16
|
+
'**/*.{test,spec}.{js,jsx,ts,tsx}',
|
|
17
|
+
'**/__tests__/**',
|
|
18
|
+
'**/lib/testing/**',
|
|
19
|
+
'**/mocks/**',
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
export const testJsxFiles = ['**/*.{test,spec}.{jsx,tsx}'];
|
|
23
|
+
|
|
24
|
+
export const wdioSpecFiles = [
|
|
25
|
+
'**/*.func.spec.js',
|
|
26
|
+
'**/*.visual.spec.js',
|
|
27
|
+
'**/*e2e*.{js,ts}',
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
export const storybookFiles = [
|
|
31
|
+
'**/*.stories.{js,jsx,ts,tsx}',
|
|
32
|
+
'**/.storybook/**',
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
/** @type {import('eslint').Linter.RulesRecord} */
|
|
36
|
+
export const sharedCoreRules = {
|
|
37
|
+
...eslintComments.configs.recommended.rules,
|
|
38
|
+
...importX.configs.recommended.rules,
|
|
39
|
+
'import-x/named': 'off',
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/** @type {import('eslint').Linter.RulesRecord} */
|
|
43
|
+
export const jestRecommendedRules = jest.configs.recommended.rules;
|
|
44
|
+
|
|
45
|
+
const testingLibraryDom =
|
|
46
|
+
testingLibrary.configs['flat/dom'] ?? testingLibrary.configs.dom;
|
|
47
|
+
const testingLibraryReact =
|
|
48
|
+
testingLibrary.configs['flat/react'] ?? testingLibrary.configs.react;
|
|
49
|
+
|
|
50
|
+
/** @type {import('eslint').Linter.RulesRecord} */
|
|
51
|
+
export const testingLibraryDomRules = testingLibraryDom?.rules ?? {};
|
|
52
|
+
|
|
53
|
+
/** @type {import('eslint').Linter.RulesRecord} */
|
|
54
|
+
export const testingLibraryReactRules = testingLibraryReact?.rules ?? {};
|
|
55
|
+
|
|
56
|
+
/** @type {import('eslint').Linter.RulesRecord} */
|
|
57
|
+
export const reactPresetRules = {
|
|
58
|
+
...react.configs.recommended.rules,
|
|
59
|
+
...reactHooks.configs.recommended.rules,
|
|
60
|
+
...jsxA11y.flatConfigs.recommended.rules,
|
|
61
|
+
...reduxSaga.configs.recommended.rules,
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/** @type {import('eslint').Linter.RulesRecord} */
|
|
65
|
+
export const wdioRecommendedRules = wdio.configs.recommended.rules ?? {};
|
|
66
|
+
|
|
67
|
+
/** @type {Record<string, boolean>} */
|
|
68
|
+
export const wdioGlobals = wdio.configs.recommended.globals ?? {};
|
|
69
|
+
|
|
70
|
+
const storybookFlat =
|
|
71
|
+
storybook.configs['flat/recommended'] ??
|
|
72
|
+
storybook.configs.recommended ??
|
|
73
|
+
[];
|
|
74
|
+
|
|
75
|
+
/** Normalized once — Storybook flat config may be array or single object. */
|
|
76
|
+
export const storybookFlatConfigs = Array.isArray(storybookFlat)
|
|
77
|
+
? storybookFlat
|
|
78
|
+
: [storybookFlat];
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { reactFlatConfigs, reactFlatConfigsStrict } from './react.mjs';
|
|
2
|
+
|
|
3
|
+
/** Flat ESLint config for React + TypeScript PUI apps. */
|
|
4
|
+
export const eslintFlatConfig = reactFlatConfigs;
|
|
5
|
+
|
|
6
|
+
/** Strict flat ESLint config for React + TypeScript (errors on `no-unsafe-*` and `exhaustive-deps`). */
|
|
7
|
+
export const eslintFlatConfigStrict = reactFlatConfigsStrict;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { defineConfig } from 'eslint/config';
|
|
2
|
+
import jsxA11y from 'eslint-plugin-jsx-a11y';
|
|
3
|
+
import react from 'eslint-plugin-react';
|
|
4
|
+
import reactHooks from 'eslint-plugin-react-hooks';
|
|
5
|
+
import reduxSaga from 'eslint-plugin-redux-saga';
|
|
6
|
+
import { baseFlatConfigs, baseFlatConfigsStrict } from './common.mjs';
|
|
7
|
+
import {
|
|
8
|
+
reactPresetRules,
|
|
9
|
+
storybookFiles,
|
|
10
|
+
storybookFlatConfigs,
|
|
11
|
+
} from './presets.mjs';
|
|
12
|
+
import { reactRules, reactStrictRules } from './rules.mjs';
|
|
13
|
+
|
|
14
|
+
const reactPluginBlock = {
|
|
15
|
+
plugins: {
|
|
16
|
+
react,
|
|
17
|
+
'react-hooks': reactHooks,
|
|
18
|
+
'jsx-a11y': jsxA11y,
|
|
19
|
+
'redux-saga': reduxSaga,
|
|
20
|
+
},
|
|
21
|
+
settings: {
|
|
22
|
+
react: { version: 'detect' },
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @param {import('eslint').Linter.Config[]} baseConfigs
|
|
28
|
+
* @param {typeof reactRules} puiReactRules
|
|
29
|
+
*/
|
|
30
|
+
function createReactFlatConfigs(baseConfigs, puiReactRules) {
|
|
31
|
+
return defineConfig(
|
|
32
|
+
...baseConfigs,
|
|
33
|
+
{
|
|
34
|
+
...reactPluginBlock,
|
|
35
|
+
rules: {
|
|
36
|
+
...reactPresetRules,
|
|
37
|
+
...puiReactRules,
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
...storybookFlatConfigs,
|
|
41
|
+
{
|
|
42
|
+
files: storybookFiles,
|
|
43
|
+
rules: {
|
|
44
|
+
'react/jsx-props-no-spreading': 'off',
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Default React flat config — migration-friendly type-safety warnings. */
|
|
51
|
+
export const reactFlatConfigs = createReactFlatConfigs(
|
|
52
|
+
baseFlatConfigs,
|
|
53
|
+
reactRules,
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
/** Strict React flat config — `no-unsafe-*` and `exhaustive-deps` as error. */
|
|
57
|
+
export const reactFlatConfigsStrict = createReactFlatConfigs(
|
|
58
|
+
baseFlatConfigsStrict,
|
|
59
|
+
reactStrictRules,
|
|
60
|
+
);
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/** Shared rule sets migrated from legacy eslintrc (common.cjs + typescript/*.cjs). */
|
|
2
|
+
|
|
3
|
+
export const baseRules = {
|
|
4
|
+
'arrow-body-style': ['error', 'as-needed'],
|
|
5
|
+
'class-methods-use-this': 'off',
|
|
6
|
+
'import-x/imports-first': 'off',
|
|
7
|
+
'import-x/newline-after-import': 'off',
|
|
8
|
+
'import-x/no-dynamic-require': 'off',
|
|
9
|
+
'import-x/no-extraneous-dependencies': [
|
|
10
|
+
'error',
|
|
11
|
+
{
|
|
12
|
+
devDependencies: [
|
|
13
|
+
'**/*.{test,spec,stories}.{js,jsx,ts,tsx}',
|
|
14
|
+
'**/.storybook/**',
|
|
15
|
+
'**/eslint.config.{mjs,cjs,js}',
|
|
16
|
+
'**/*.{config,conf}.{ts,js,cjs,mjs}',
|
|
17
|
+
'**/scripts/**',
|
|
18
|
+
'**/ci_cd/**',
|
|
19
|
+
'**/lint-config/**',
|
|
20
|
+
'**/lib/testing/**',
|
|
21
|
+
'**/lib/transpile/**',
|
|
22
|
+
'**/mocks/**',
|
|
23
|
+
],
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
'import-x/no-named-as-default': 'off',
|
|
27
|
+
'import-x/no-unresolved': [
|
|
28
|
+
'error',
|
|
29
|
+
{ caseSensitive: true, caseSensitiveStrict: true },
|
|
30
|
+
],
|
|
31
|
+
'import-x/no-webpack-loader-syntax': 'off',
|
|
32
|
+
'import-x/prefer-default-export': 'off',
|
|
33
|
+
'import-x/default': 'off',
|
|
34
|
+
'import-x/namespace': 'off',
|
|
35
|
+
'import-x/extensions': [
|
|
36
|
+
'error',
|
|
37
|
+
'never',
|
|
38
|
+
{
|
|
39
|
+
json: 'ignorePackages',
|
|
40
|
+
js: 'ignorePackages',
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
complexity: ['error', { max: 10 }],
|
|
44
|
+
'max-depth': ['error', { max: 4 }],
|
|
45
|
+
'max-lines-per-function': 'off',
|
|
46
|
+
'max-nested-callbacks': ['error', { max: 3 }],
|
|
47
|
+
'max-params': ['error', { max: 3 }],
|
|
48
|
+
'max-statements': ['error', { max: 20 }],
|
|
49
|
+
'max-len': 'off',
|
|
50
|
+
'newline-per-chained-call': 'off',
|
|
51
|
+
'no-confusing-arrow': 'off',
|
|
52
|
+
'no-console': 'warn',
|
|
53
|
+
'no-param-reassign': ['error', { props: false }],
|
|
54
|
+
'prefer-template': 'error',
|
|
55
|
+
'require-yield': 'off',
|
|
56
|
+
'eslint-comments/disable-enable-pair': 'off',
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/** Relaxed type-checked rules for test files (shared by default and strict configs). */
|
|
60
|
+
export const typescriptTestRelaxedRules = {
|
|
61
|
+
'@typescript-eslint/no-unsafe-assignment': 'off',
|
|
62
|
+
'@typescript-eslint/no-unsafe-member-access': 'off',
|
|
63
|
+
'@typescript-eslint/no-unsafe-call': 'off',
|
|
64
|
+
'@typescript-eslint/no-unsafe-argument': 'off',
|
|
65
|
+
'@typescript-eslint/no-unsafe-return': 'off',
|
|
66
|
+
'@typescript-eslint/unbound-method': 'off',
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export const jsRules = {
|
|
70
|
+
...baseRules,
|
|
71
|
+
'max-lines': ['error', { max: 120, skipComments: true }],
|
|
72
|
+
'no-unused-vars': 'error',
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export const typescriptRules = {
|
|
76
|
+
...baseRules,
|
|
77
|
+
'max-lines': ['error', { max: 200, skipComments: true }],
|
|
78
|
+
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
|
79
|
+
'@typescript-eslint/explicit-function-return-type': 'off',
|
|
80
|
+
'@typescript-eslint/no-use-before-define': [
|
|
81
|
+
'error',
|
|
82
|
+
{ functions: false, classes: true, variables: true, typedefs: true },
|
|
83
|
+
],
|
|
84
|
+
'@typescript-eslint/unbound-method': ['error', { ignoreStatic: true }],
|
|
85
|
+
'@typescript-eslint/no-floating-promises': ['error', { ignoreIIFE: true }],
|
|
86
|
+
'@typescript-eslint/no-misused-promises': [
|
|
87
|
+
'error',
|
|
88
|
+
{ checksVoidReturn: { attributes: false } },
|
|
89
|
+
],
|
|
90
|
+
'@typescript-eslint/no-unsafe-assignment': 'warn',
|
|
91
|
+
'@typescript-eslint/no-unsafe-member-access': 'warn',
|
|
92
|
+
'@typescript-eslint/no-unsafe-call': 'warn',
|
|
93
|
+
'@typescript-eslint/no-unsafe-argument': 'warn',
|
|
94
|
+
'@typescript-eslint/no-unsafe-return': 'warn',
|
|
95
|
+
'@typescript-eslint/consistent-type-imports': [
|
|
96
|
+
'error',
|
|
97
|
+
{ prefer: 'type-imports', fixStyle: 'inline-type-imports' },
|
|
98
|
+
],
|
|
99
|
+
'@typescript-eslint/no-import-type-side-effects': 'error',
|
|
100
|
+
'no-unused-vars': 'off',
|
|
101
|
+
'@typescript-eslint/no-unused-vars': [
|
|
102
|
+
'error',
|
|
103
|
+
{ argsIgnorePattern: '^_', ignoreRestSiblings: true },
|
|
104
|
+
],
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
/** Stricter TypeScript rules (error on unsafe any usage). */
|
|
108
|
+
export const typescriptStrictRules = {
|
|
109
|
+
...typescriptRules,
|
|
110
|
+
'@typescript-eslint/no-unsafe-assignment': 'error',
|
|
111
|
+
'@typescript-eslint/no-unsafe-member-access': 'error',
|
|
112
|
+
'@typescript-eslint/no-unsafe-call': 'error',
|
|
113
|
+
'@typescript-eslint/no-unsafe-argument': 'error',
|
|
114
|
+
'@typescript-eslint/no-unsafe-return': 'error',
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
export const reactRules = {
|
|
118
|
+
'jsx-a11y/aria-props': 'error',
|
|
119
|
+
'jsx-a11y/heading-has-content': 'off',
|
|
120
|
+
'jsx-a11y/label-has-associated-control': [
|
|
121
|
+
'error',
|
|
122
|
+
{
|
|
123
|
+
controlComponents: ['Input'],
|
|
124
|
+
},
|
|
125
|
+
],
|
|
126
|
+
'jsx-a11y/label-has-for': 'off',
|
|
127
|
+
'jsx-a11y/mouse-events-have-key-events': 'error',
|
|
128
|
+
'jsx-a11y/role-has-required-aria-props': 'error',
|
|
129
|
+
'jsx-a11y/role-supports-aria-props': 'error',
|
|
130
|
+
'react/destructuring-assignment': 'off',
|
|
131
|
+
'react-hooks/rules-of-hooks': 'error',
|
|
132
|
+
'react-hooks/exhaustive-deps': 'warn',
|
|
133
|
+
'react/jsx-closing-tag-location': 'off',
|
|
134
|
+
'react/forbid-prop-types': 'off',
|
|
135
|
+
'react/jsx-first-prop-new-line': ['error', 'multiline'],
|
|
136
|
+
'react/jsx-no-target-blank': 'off',
|
|
137
|
+
'react/jsx-props-no-spreading': 'off',
|
|
138
|
+
'react/jsx-uses-vars': 'error',
|
|
139
|
+
'react/require-default-props': 'off',
|
|
140
|
+
'react/require-extension': 'off',
|
|
141
|
+
'react/self-closing-comp': 'off',
|
|
142
|
+
'react/sort-comp': 'off',
|
|
143
|
+
'react/react-in-jsx-scope': 'off',
|
|
144
|
+
'react/jsx-filename-extension': [
|
|
145
|
+
'warn',
|
|
146
|
+
{ extensions: ['.js', '.jsx', '.tsx', '.mdx'] },
|
|
147
|
+
],
|
|
148
|
+
'react/function-component-definition': [
|
|
149
|
+
'error',
|
|
150
|
+
{ namedComponents: 'arrow-function' },
|
|
151
|
+
],
|
|
152
|
+
'react/prop-types': 'off',
|
|
153
|
+
'redux-saga/no-yield-in-race': 'error',
|
|
154
|
+
'redux-saga/yield-effects': 'error',
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
/** Stricter React rules (exhaustive-deps as error). */
|
|
158
|
+
export const reactStrictRules = {
|
|
159
|
+
...reactRules,
|
|
160
|
+
'react-hooks/exhaustive-deps': 'error',
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
export const ignorePatterns = [
|
|
164
|
+
'**/build/**',
|
|
165
|
+
'**/node_modules/**',
|
|
166
|
+
'**/dist/**',
|
|
167
|
+
'**/reports/**',
|
|
168
|
+
'**/allure-report/**',
|
|
169
|
+
'**/coverage/**',
|
|
170
|
+
'**/demo/**',
|
|
171
|
+
'**/docs/**',
|
|
172
|
+
'**/docs/api/**',
|
|
173
|
+
'**/temp/**',
|
|
174
|
+
'**/.tmp/**',
|
|
175
|
+
'**/public/**',
|
|
176
|
+
'**/webroot/**',
|
|
177
|
+
'**/cdn/**',
|
|
178
|
+
'**/.docusaurus/**',
|
|
179
|
+
'**/vendor/*.js',
|
|
180
|
+
'**/.nx/**',
|
|
181
|
+
'**/pnpm-lock.yaml',
|
|
182
|
+
'**/.scannerwork/**',
|
|
183
|
+
'**/stats.json',
|
|
184
|
+
'**/jsconfig.json',
|
|
185
|
+
];
|