@elliemae/pui-cli 9.0.0-alpha.7 → 9.0.0-alpha.8
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/dist/cjs/lint-config/eslint/flat/compat.mjs +138 -6
- package/dist/cjs/lint-config/eslint/flat/react.mjs +2 -3
- package/dist/esm/lint-config/eslint/flat/compat.mjs +138 -6
- package/dist/esm/lint-config/eslint/flat/react.mjs +2 -3
- package/dist/types/lib/lint-config/eslint/flat/compat.d.mts +7 -2
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/lib/lint-config/eslint/flat/compat.mjs +138 -6
- package/lib/lint-config/eslint/flat/react.mjs +2 -3
- package/package.json +1 -1
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ESLint 10 removed deprecated context APIs (e.g. getSourceCode).
|
|
3
|
-
*
|
|
2
|
+
* ESLint 10 removed deprecated context APIs (e.g. getSourceCode, getScope, getFilename).
|
|
3
|
+
* Shim only plugins that still call those APIs until maintainers publish compatible releases.
|
|
4
|
+
*
|
|
5
|
+
* @eslint/compat fixupPluginRules assumes ESLint 9 sourceCode passthroughs that are also
|
|
6
|
+
* unavailable in ESLint 10, so we shim legacy context methods directly on the rule context.
|
|
4
7
|
*/
|
|
5
|
-
import
|
|
8
|
+
import react from 'eslint-plugin-react';
|
|
6
9
|
import reduxSaga from 'eslint-plugin-redux-saga';
|
|
7
10
|
import storybook from 'eslint-plugin-storybook';
|
|
8
11
|
|
|
@@ -11,10 +14,139 @@ const storybookFlat =
|
|
|
11
14
|
storybook.configs.recommended ??
|
|
12
15
|
[];
|
|
13
16
|
|
|
17
|
+
/** @type {WeakMap<import('eslint').ESLint.Plugin, import('eslint').ESLint.Plugin>} */
|
|
18
|
+
const fixedPlugins = new WeakMap();
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @param {import('eslint').Rule.RuleModule['create']} originalCreate
|
|
22
|
+
*/
|
|
23
|
+
function wrapRuleCreateWithLegacyContext(originalCreate) {
|
|
24
|
+
return function create(context) {
|
|
25
|
+
if (
|
|
26
|
+
typeof context.getScope === 'function' &&
|
|
27
|
+
typeof context.getFilename === 'function'
|
|
28
|
+
) {
|
|
29
|
+
return originalCreate(context);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const sourceCode = context.sourceCode;
|
|
33
|
+
let currentNode = sourceCode.ast;
|
|
34
|
+
|
|
35
|
+
const legacyContext = Object.assign(Object.create(context), {
|
|
36
|
+
getFilename() {
|
|
37
|
+
return context.filename;
|
|
38
|
+
},
|
|
39
|
+
getScope() {
|
|
40
|
+
return sourceCode.getScope(currentNode);
|
|
41
|
+
},
|
|
42
|
+
getAncestors() {
|
|
43
|
+
return sourceCode.getAncestors(currentNode);
|
|
44
|
+
},
|
|
45
|
+
getSourceCode() {
|
|
46
|
+
return sourceCode;
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
Object.freeze(legacyContext);
|
|
51
|
+
|
|
52
|
+
const visitor = originalCreate(legacyContext);
|
|
53
|
+
|
|
54
|
+
if (!visitor || typeof visitor !== 'object') {
|
|
55
|
+
return visitor;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
for (const [methodName, method] of Object.entries(visitor)) {
|
|
59
|
+
if (typeof method !== 'function') {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (methodName.startsWith('on')) {
|
|
64
|
+
visitor[methodName] = (...args) => {
|
|
65
|
+
currentNode = args[methodName === 'onCodePathSegmentLoop' ? 2 : 1];
|
|
66
|
+
return method.call(visitor, ...args);
|
|
67
|
+
};
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
visitor[methodName] = (node, ...rest) => {
|
|
72
|
+
currentNode = node;
|
|
73
|
+
return method.call(visitor, node, ...rest);
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return visitor;
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* @param {import('eslint').ESLint.Plugin} plugin
|
|
83
|
+
* @returns {import('eslint').ESLint.Plugin}
|
|
84
|
+
*/
|
|
85
|
+
function fixupLegacyPlugin(plugin) {
|
|
86
|
+
const cached = fixedPlugins.get(plugin);
|
|
87
|
+
if (cached) {
|
|
88
|
+
return cached;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (!plugin.rules) {
|
|
92
|
+
fixedPlugins.set(plugin, plugin);
|
|
93
|
+
return plugin;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const rules = {};
|
|
97
|
+
|
|
98
|
+
for (const [ruleName, ruleDefinition] of Object.entries(plugin.rules)) {
|
|
99
|
+
if (typeof ruleDefinition === 'function') {
|
|
100
|
+
rules[ruleName] = wrapRuleCreateWithLegacyContext(ruleDefinition);
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
rules[ruleName] = {
|
|
105
|
+
...ruleDefinition,
|
|
106
|
+
create: wrapRuleCreateWithLegacyContext(
|
|
107
|
+
ruleDefinition.create.bind(ruleDefinition),
|
|
108
|
+
),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const fixed = { ...plugin, rules };
|
|
113
|
+
fixedPlugins.set(plugin, fixed);
|
|
114
|
+
return fixed;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** @type {import('eslint').ESLint.Plugin} */
|
|
118
|
+
const storybookPlugin = fixupLegacyPlugin(storybook);
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* @param {import('eslint').Linter.Config[]} configs
|
|
122
|
+
* @returns {import('eslint').Linter.Config[]}
|
|
123
|
+
*/
|
|
124
|
+
function fixupStorybookFlatConfigs(configs) {
|
|
125
|
+
return configs.map((configItem) => {
|
|
126
|
+
if (!configItem.plugins?.storybook) {
|
|
127
|
+
return configItem;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
...configItem,
|
|
132
|
+
plugins: {
|
|
133
|
+
...configItem.plugins,
|
|
134
|
+
storybook: storybookPlugin,
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** React — uses context.getFilename / getScope (eslint-plugin-react@7). */
|
|
141
|
+
/** @type {import('eslint').ESLint.Plugin} */
|
|
142
|
+
export const reactPlugin = fixupLegacyPlugin(react);
|
|
143
|
+
|
|
144
|
+
/** Redux-saga — uses context.getScope in no-yield-in-race. */
|
|
14
145
|
/** @type {import('eslint').ESLint.Plugin} */
|
|
15
|
-
export const reduxSagaPlugin =
|
|
146
|
+
export const reduxSagaPlugin = fixupLegacyPlugin(reduxSaga);
|
|
16
147
|
|
|
17
|
-
/** Storybook flat presets
|
|
18
|
-
|
|
148
|
+
/** Storybook flat presets — uses legacy context APIs (eslint-plugin-storybook@0.12). */
|
|
149
|
+
/** @type {import('eslint').Linter.Config[]} */
|
|
150
|
+
export const storybookFlatConfigs = fixupStorybookFlatConfigs(
|
|
19
151
|
Array.isArray(storybookFlat) ? storybookFlat : [storybookFlat],
|
|
20
152
|
);
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { defineConfig } from 'eslint/config';
|
|
2
2
|
import jsxA11y from 'eslint-plugin-jsx-a11y';
|
|
3
|
-
import react from 'eslint-plugin-react';
|
|
4
3
|
import reactHooks from 'eslint-plugin-react-hooks';
|
|
5
4
|
import { baseFlatConfigs, baseFlatConfigsStrict } from './common.mjs';
|
|
6
|
-
import { reduxSagaPlugin } from './compat.mjs';
|
|
5
|
+
import { reactPlugin, reduxSagaPlugin } from './compat.mjs';
|
|
7
6
|
import {
|
|
8
7
|
reactPresetRules,
|
|
9
8
|
storybookFiles,
|
|
@@ -13,7 +12,7 @@ import { reactRules, reactStrictRules } from './rules.mjs';
|
|
|
13
12
|
|
|
14
13
|
const reactPluginBlock = {
|
|
15
14
|
plugins: {
|
|
16
|
-
react,
|
|
15
|
+
react: reactPlugin,
|
|
17
16
|
'react-hooks': reactHooks,
|
|
18
17
|
'jsx-a11y': jsxA11y,
|
|
19
18
|
'redux-saga': reduxSagaPlugin,
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ESLint 10 removed deprecated context APIs (e.g. getSourceCode).
|
|
3
|
-
*
|
|
2
|
+
* ESLint 10 removed deprecated context APIs (e.g. getSourceCode, getScope, getFilename).
|
|
3
|
+
* Shim only plugins that still call those APIs until maintainers publish compatible releases.
|
|
4
|
+
*
|
|
5
|
+
* @eslint/compat fixupPluginRules assumes ESLint 9 sourceCode passthroughs that are also
|
|
6
|
+
* unavailable in ESLint 10, so we shim legacy context methods directly on the rule context.
|
|
4
7
|
*/
|
|
5
|
-
import
|
|
8
|
+
import react from 'eslint-plugin-react';
|
|
6
9
|
import reduxSaga from 'eslint-plugin-redux-saga';
|
|
7
10
|
import storybook from 'eslint-plugin-storybook';
|
|
8
11
|
|
|
@@ -11,10 +14,139 @@ const storybookFlat =
|
|
|
11
14
|
storybook.configs.recommended ??
|
|
12
15
|
[];
|
|
13
16
|
|
|
17
|
+
/** @type {WeakMap<import('eslint').ESLint.Plugin, import('eslint').ESLint.Plugin>} */
|
|
18
|
+
const fixedPlugins = new WeakMap();
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @param {import('eslint').Rule.RuleModule['create']} originalCreate
|
|
22
|
+
*/
|
|
23
|
+
function wrapRuleCreateWithLegacyContext(originalCreate) {
|
|
24
|
+
return function create(context) {
|
|
25
|
+
if (
|
|
26
|
+
typeof context.getScope === 'function' &&
|
|
27
|
+
typeof context.getFilename === 'function'
|
|
28
|
+
) {
|
|
29
|
+
return originalCreate(context);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const sourceCode = context.sourceCode;
|
|
33
|
+
let currentNode = sourceCode.ast;
|
|
34
|
+
|
|
35
|
+
const legacyContext = Object.assign(Object.create(context), {
|
|
36
|
+
getFilename() {
|
|
37
|
+
return context.filename;
|
|
38
|
+
},
|
|
39
|
+
getScope() {
|
|
40
|
+
return sourceCode.getScope(currentNode);
|
|
41
|
+
},
|
|
42
|
+
getAncestors() {
|
|
43
|
+
return sourceCode.getAncestors(currentNode);
|
|
44
|
+
},
|
|
45
|
+
getSourceCode() {
|
|
46
|
+
return sourceCode;
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
Object.freeze(legacyContext);
|
|
51
|
+
|
|
52
|
+
const visitor = originalCreate(legacyContext);
|
|
53
|
+
|
|
54
|
+
if (!visitor || typeof visitor !== 'object') {
|
|
55
|
+
return visitor;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
for (const [methodName, method] of Object.entries(visitor)) {
|
|
59
|
+
if (typeof method !== 'function') {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (methodName.startsWith('on')) {
|
|
64
|
+
visitor[methodName] = (...args) => {
|
|
65
|
+
currentNode = args[methodName === 'onCodePathSegmentLoop' ? 2 : 1];
|
|
66
|
+
return method.call(visitor, ...args);
|
|
67
|
+
};
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
visitor[methodName] = (node, ...rest) => {
|
|
72
|
+
currentNode = node;
|
|
73
|
+
return method.call(visitor, node, ...rest);
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return visitor;
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* @param {import('eslint').ESLint.Plugin} plugin
|
|
83
|
+
* @returns {import('eslint').ESLint.Plugin}
|
|
84
|
+
*/
|
|
85
|
+
function fixupLegacyPlugin(plugin) {
|
|
86
|
+
const cached = fixedPlugins.get(plugin);
|
|
87
|
+
if (cached) {
|
|
88
|
+
return cached;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (!plugin.rules) {
|
|
92
|
+
fixedPlugins.set(plugin, plugin);
|
|
93
|
+
return plugin;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const rules = {};
|
|
97
|
+
|
|
98
|
+
for (const [ruleName, ruleDefinition] of Object.entries(plugin.rules)) {
|
|
99
|
+
if (typeof ruleDefinition === 'function') {
|
|
100
|
+
rules[ruleName] = wrapRuleCreateWithLegacyContext(ruleDefinition);
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
rules[ruleName] = {
|
|
105
|
+
...ruleDefinition,
|
|
106
|
+
create: wrapRuleCreateWithLegacyContext(
|
|
107
|
+
ruleDefinition.create.bind(ruleDefinition),
|
|
108
|
+
),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const fixed = { ...plugin, rules };
|
|
113
|
+
fixedPlugins.set(plugin, fixed);
|
|
114
|
+
return fixed;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** @type {import('eslint').ESLint.Plugin} */
|
|
118
|
+
const storybookPlugin = fixupLegacyPlugin(storybook);
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* @param {import('eslint').Linter.Config[]} configs
|
|
122
|
+
* @returns {import('eslint').Linter.Config[]}
|
|
123
|
+
*/
|
|
124
|
+
function fixupStorybookFlatConfigs(configs) {
|
|
125
|
+
return configs.map((configItem) => {
|
|
126
|
+
if (!configItem.plugins?.storybook) {
|
|
127
|
+
return configItem;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
...configItem,
|
|
132
|
+
plugins: {
|
|
133
|
+
...configItem.plugins,
|
|
134
|
+
storybook: storybookPlugin,
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** React — uses context.getFilename / getScope (eslint-plugin-react@7). */
|
|
141
|
+
/** @type {import('eslint').ESLint.Plugin} */
|
|
142
|
+
export const reactPlugin = fixupLegacyPlugin(react);
|
|
143
|
+
|
|
144
|
+
/** Redux-saga — uses context.getScope in no-yield-in-race. */
|
|
14
145
|
/** @type {import('eslint').ESLint.Plugin} */
|
|
15
|
-
export const reduxSagaPlugin =
|
|
146
|
+
export const reduxSagaPlugin = fixupLegacyPlugin(reduxSaga);
|
|
16
147
|
|
|
17
|
-
/** Storybook flat presets
|
|
18
|
-
|
|
148
|
+
/** Storybook flat presets — uses legacy context APIs (eslint-plugin-storybook@0.12). */
|
|
149
|
+
/** @type {import('eslint').Linter.Config[]} */
|
|
150
|
+
export const storybookFlatConfigs = fixupStorybookFlatConfigs(
|
|
19
151
|
Array.isArray(storybookFlat) ? storybookFlat : [storybookFlat],
|
|
20
152
|
);
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { defineConfig } from 'eslint/config';
|
|
2
2
|
import jsxA11y from 'eslint-plugin-jsx-a11y';
|
|
3
|
-
import react from 'eslint-plugin-react';
|
|
4
3
|
import reactHooks from 'eslint-plugin-react-hooks';
|
|
5
4
|
import { baseFlatConfigs, baseFlatConfigsStrict } from './common.mjs';
|
|
6
|
-
import { reduxSagaPlugin } from './compat.mjs';
|
|
5
|
+
import { reactPlugin, reduxSagaPlugin } from './compat.mjs';
|
|
7
6
|
import {
|
|
8
7
|
reactPresetRules,
|
|
9
8
|
storybookFiles,
|
|
@@ -13,7 +12,7 @@ import { reactRules, reactStrictRules } from './rules.mjs';
|
|
|
13
12
|
|
|
14
13
|
const reactPluginBlock = {
|
|
15
14
|
plugins: {
|
|
16
|
-
react,
|
|
15
|
+
react: reactPlugin,
|
|
17
16
|
'react-hooks': reactHooks,
|
|
18
17
|
'jsx-a11y': jsxA11y,
|
|
19
18
|
'redux-saga': reduxSagaPlugin,
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
+
/** React — uses context.getFilename / getScope (eslint-plugin-react@7). */
|
|
2
|
+
/** @type {import('eslint').ESLint.Plugin} */
|
|
3
|
+
export const reactPlugin: import("eslint").ESLint.Plugin;
|
|
4
|
+
/** Redux-saga — uses context.getScope in no-yield-in-race. */
|
|
1
5
|
/** @type {import('eslint').ESLint.Plugin} */
|
|
2
6
|
export const reduxSagaPlugin: import("eslint").ESLint.Plugin;
|
|
3
|
-
/** Storybook flat presets
|
|
4
|
-
|
|
7
|
+
/** Storybook flat presets — uses legacy context APIs (eslint-plugin-storybook@0.12). */
|
|
8
|
+
/** @type {import('eslint').Linter.Config[]} */
|
|
9
|
+
export const storybookFlatConfigs: import("eslint").Linter.Config[];
|