@pob/codemods 0.17.1 → 0.18.1
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/bin/migrate.mjs +1 -1
- package/lib/data/eslint-to-oxlint-rule-names.json +492 -0
- package/lib/index.js +18 -0
- package/lib/runJscodeshift.cjs +7 -0
- package/lib/transforms/jest-to-node-runner.cjs +146 -0
- package/lib/transforms/oxlint-directives.cjs +31 -0
- package/lib/transforms/oxlint-eslint-config.cjs +194 -0
- package/lib/transforms/update-function-component-return-type.cjs +88 -0
- package/lib/utils/oxlintDirectives.cjs +220 -0
- package/lib/utils/prependImport.cjs +35 -0
- package/package.json +4 -4
package/bin/migrate.mjs
CHANGED
|
@@ -13,7 +13,7 @@ const globPaths = argv[1];
|
|
|
13
13
|
if (!transformerName || !globPaths) {
|
|
14
14
|
const transformerList = readdirSync(
|
|
15
15
|
new URL("../lib/transforms/", import.meta.url),
|
|
16
|
-
);
|
|
16
|
+
).filter((fileName) => fileName.endsWith(".cjs"));
|
|
17
17
|
throw new Error(
|
|
18
18
|
`Usage: pob-migrate <transformer-name> <glob-paths>\n${transformerList
|
|
19
19
|
.map((t) => `- "${t.slice(0, -4)}"`)
|
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
{
|
|
2
|
+
"@pob/forbid-non-native-fetch-import": "@pob/forbid-non-native-fetch-import",
|
|
3
|
+
"@pob/forbid-non-native-node-imports": "@pob/forbid-non-native-node-imports",
|
|
4
|
+
"@pob/no-useless-template-literal": "@pob/no-useless-template-literal",
|
|
5
|
+
"@pob/react-function-component-return-react-node": "@pob/react-function-component-return-react-node",
|
|
6
|
+
"@pob/react-named-import": "@pob/react-named-import",
|
|
7
|
+
"@typescript-eslint/adjacent-overload-signatures": "typescript/adjacent-overload-signatures",
|
|
8
|
+
"@typescript-eslint/array-type": "typescript/array-type",
|
|
9
|
+
"@typescript-eslint/await-thenable": "typescript/await-thenable",
|
|
10
|
+
"@typescript-eslint/ban-ts-comment": "typescript/ban-ts-comment",
|
|
11
|
+
"@typescript-eslint/ban-tslint-comment": "typescript/ban-tslint-comment",
|
|
12
|
+
"@typescript-eslint/class-literal-property-style": "typescript/class-literal-property-style",
|
|
13
|
+
"@typescript-eslint/consistent-generic-constructors": "typescript/consistent-generic-constructors",
|
|
14
|
+
"@typescript-eslint/consistent-indexed-object-style": "typescript/consistent-indexed-object-style",
|
|
15
|
+
"@typescript-eslint/consistent-type-assertions": "typescript/consistent-type-assertions",
|
|
16
|
+
"@typescript-eslint/consistent-type-definitions": "typescript/consistent-type-definitions",
|
|
17
|
+
"@typescript-eslint/consistent-type-exports": "typescript/consistent-type-exports",
|
|
18
|
+
"@typescript-eslint/consistent-type-imports": "typescript/consistent-type-imports",
|
|
19
|
+
"@typescript-eslint/default-param-last": "default-param-last",
|
|
20
|
+
"@typescript-eslint/dot-notation": "typescript/dot-notation",
|
|
21
|
+
"@typescript-eslint/explicit-function-return-type": "typescript/explicit-function-return-type",
|
|
22
|
+
"@typescript-eslint/explicit-module-boundary-types": "typescript/explicit-module-boundary-types",
|
|
23
|
+
"@typescript-eslint/max-params": "max-params",
|
|
24
|
+
"@typescript-eslint/method-signature-style": "typescript/method-signature-style",
|
|
25
|
+
"@typescript-eslint/no-array-constructor": "no-array-constructor",
|
|
26
|
+
"@typescript-eslint/no-array-delete": "typescript/no-array-delete",
|
|
27
|
+
"@typescript-eslint/no-base-to-string": "typescript/no-base-to-string",
|
|
28
|
+
"@typescript-eslint/no-confusing-non-null-assertion": "typescript/no-confusing-non-null-assertion",
|
|
29
|
+
"@typescript-eslint/no-confusing-void-expression": "typescript/no-confusing-void-expression",
|
|
30
|
+
"@typescript-eslint/no-deprecated": "typescript/no-deprecated",
|
|
31
|
+
"@typescript-eslint/no-dupe-class-members": "no-dupe-class-members",
|
|
32
|
+
"@typescript-eslint/no-duplicate-enum-values": "typescript/no-duplicate-enum-values",
|
|
33
|
+
"@typescript-eslint/no-duplicate-type-constituents": "typescript/no-duplicate-type-constituents",
|
|
34
|
+
"@typescript-eslint/no-dynamic-delete": "typescript/no-dynamic-delete",
|
|
35
|
+
"@typescript-eslint/no-empty-function": "no-empty-function",
|
|
36
|
+
"@typescript-eslint/no-empty-object-type": "typescript/no-empty-object-type",
|
|
37
|
+
"@typescript-eslint/no-explicit-any": "typescript/no-explicit-any",
|
|
38
|
+
"@typescript-eslint/no-extra-non-null-assertion": "typescript/no-extra-non-null-assertion",
|
|
39
|
+
"@typescript-eslint/no-floating-promises": "typescript/no-floating-promises",
|
|
40
|
+
"@typescript-eslint/no-for-in-array": "typescript/no-for-in-array",
|
|
41
|
+
"@typescript-eslint/no-implied-eval": "typescript/no-implied-eval",
|
|
42
|
+
"@typescript-eslint/no-import-type-side-effects": "typescript/no-import-type-side-effects",
|
|
43
|
+
"@typescript-eslint/no-inferrable-types": "typescript/no-inferrable-types",
|
|
44
|
+
"@typescript-eslint/no-invalid-void-type": "typescript/no-invalid-void-type",
|
|
45
|
+
"@typescript-eslint/no-loop-func": "no-loop-func",
|
|
46
|
+
"@typescript-eslint/no-loss-of-precision": "no-loss-of-precision",
|
|
47
|
+
"@typescript-eslint/no-meaningless-void-operator": "typescript/no-meaningless-void-operator",
|
|
48
|
+
"@typescript-eslint/no-misused-new": "typescript/no-misused-new",
|
|
49
|
+
"@typescript-eslint/no-misused-promises": "typescript/no-misused-promises",
|
|
50
|
+
"@typescript-eslint/no-misused-spread": "typescript/no-misused-spread",
|
|
51
|
+
"@typescript-eslint/no-mixed-enums": "typescript/no-mixed-enums",
|
|
52
|
+
"@typescript-eslint/no-namespace": "typescript/no-namespace",
|
|
53
|
+
"@typescript-eslint/no-non-null-asserted-nullish-coalescing": "typescript/no-non-null-asserted-nullish-coalescing",
|
|
54
|
+
"@typescript-eslint/no-non-null-asserted-optional-chain": "typescript/no-non-null-asserted-optional-chain",
|
|
55
|
+
"@typescript-eslint/no-non-null-assertion": "typescript/no-non-null-assertion",
|
|
56
|
+
"@typescript-eslint/no-redeclare": "no-redeclare",
|
|
57
|
+
"@typescript-eslint/no-redundant-type-constituents": "typescript/no-redundant-type-constituents",
|
|
58
|
+
"@typescript-eslint/no-this-alias": "typescript/no-this-alias",
|
|
59
|
+
"@typescript-eslint/no-unnecessary-boolean-literal-compare": "typescript/no-unnecessary-boolean-literal-compare",
|
|
60
|
+
"@typescript-eslint/no-unnecessary-condition": "typescript/no-unnecessary-condition",
|
|
61
|
+
"@typescript-eslint/no-unnecessary-qualifier": "typescript/no-unnecessary-qualifier",
|
|
62
|
+
"@typescript-eslint/no-unnecessary-template-expression": "typescript/no-unnecessary-template-expression",
|
|
63
|
+
"@typescript-eslint/no-unnecessary-type-assertion": "typescript/no-unnecessary-type-assertion",
|
|
64
|
+
"@typescript-eslint/no-unnecessary-type-constraint": "typescript/no-unnecessary-type-constraint",
|
|
65
|
+
"@typescript-eslint/no-unnecessary-type-conversion": "typescript/no-unnecessary-type-conversion",
|
|
66
|
+
"@typescript-eslint/no-unnecessary-type-parameters": "typescript/no-unnecessary-type-parameters",
|
|
67
|
+
"@typescript-eslint/no-unsafe-argument": "typescript/no-unsafe-argument",
|
|
68
|
+
"@typescript-eslint/no-unsafe-assignment": "typescript/no-unsafe-assignment",
|
|
69
|
+
"@typescript-eslint/no-unsafe-call": "typescript/no-unsafe-call",
|
|
70
|
+
"@typescript-eslint/no-unsafe-declaration-merging": "typescript/no-unsafe-declaration-merging",
|
|
71
|
+
"@typescript-eslint/no-unsafe-enum-comparison": "typescript/no-unsafe-enum-comparison",
|
|
72
|
+
"@typescript-eslint/no-unsafe-function-type": "typescript/no-unsafe-function-type",
|
|
73
|
+
"@typescript-eslint/no-unsafe-member-access": "typescript/no-unsafe-member-access",
|
|
74
|
+
"@typescript-eslint/no-unsafe-return": "typescript/no-unsafe-return",
|
|
75
|
+
"@typescript-eslint/no-unsafe-unary-minus": "typescript/no-unsafe-unary-minus",
|
|
76
|
+
"@typescript-eslint/no-unused-expressions": "no-unused-expressions",
|
|
77
|
+
"@typescript-eslint/no-unused-private-class-members": "no-unused-private-class-members",
|
|
78
|
+
"@typescript-eslint/no-unused-vars": "no-unused-vars",
|
|
79
|
+
"@typescript-eslint/no-use-before-define": "no-use-before-define",
|
|
80
|
+
"@typescript-eslint/no-useless-constructor": "no-useless-constructor",
|
|
81
|
+
"@typescript-eslint/no-useless-default-assignment": "typescript/no-useless-default-assignment",
|
|
82
|
+
"@typescript-eslint/no-useless-empty-export": "typescript/no-useless-empty-export",
|
|
83
|
+
"@typescript-eslint/no-wrapper-object-types": "typescript/no-wrapper-object-types",
|
|
84
|
+
"@typescript-eslint/non-nullable-type-assertion-style": "typescript/non-nullable-type-assertion-style",
|
|
85
|
+
"@typescript-eslint/only-throw-error": "typescript/only-throw-error",
|
|
86
|
+
"@typescript-eslint/parameter-properties": "typescript/parameter-properties",
|
|
87
|
+
"@typescript-eslint/prefer-as-const": "typescript/prefer-as-const",
|
|
88
|
+
"@typescript-eslint/prefer-enum-initializers": "typescript/prefer-enum-initializers",
|
|
89
|
+
"@typescript-eslint/prefer-find": "typescript/prefer-find",
|
|
90
|
+
"@typescript-eslint/prefer-function-type": "typescript/prefer-function-type",
|
|
91
|
+
"@typescript-eslint/prefer-literal-enum-member": "typescript/prefer-literal-enum-member",
|
|
92
|
+
"@typescript-eslint/prefer-namespace-keyword": "typescript/prefer-namespace-keyword",
|
|
93
|
+
"@typescript-eslint/prefer-optional-chain": "typescript/prefer-optional-chain",
|
|
94
|
+
"@typescript-eslint/prefer-promise-reject-errors": "typescript/prefer-promise-reject-errors",
|
|
95
|
+
"@typescript-eslint/prefer-reduce-type-parameter": "typescript/prefer-reduce-type-parameter",
|
|
96
|
+
"@typescript-eslint/prefer-regexp-exec": "typescript/prefer-regexp-exec",
|
|
97
|
+
"@typescript-eslint/prefer-return-this-type": "typescript/prefer-return-this-type",
|
|
98
|
+
"@typescript-eslint/prefer-string-starts-ends-with": "typescript/prefer-string-starts-ends-with",
|
|
99
|
+
"@typescript-eslint/related-getter-setter-pairs": "typescript/related-getter-setter-pairs",
|
|
100
|
+
"@typescript-eslint/require-await": "typescript/require-await",
|
|
101
|
+
"@typescript-eslint/restrict-plus-operands": "typescript/restrict-plus-operands",
|
|
102
|
+
"@typescript-eslint/restrict-template-expressions": "typescript/restrict-template-expressions",
|
|
103
|
+
"@typescript-eslint/return-await": "typescript/return-await",
|
|
104
|
+
"@typescript-eslint/switch-exhaustiveness-check": "typescript/switch-exhaustiveness-check",
|
|
105
|
+
"@typescript-eslint/triple-slash-reference": "typescript/triple-slash-reference",
|
|
106
|
+
"@typescript-eslint/unified-signatures": "typescript/unified-signatures",
|
|
107
|
+
"@typescript-eslint/use-unknown-in-catch-callback-variable": "typescript/use-unknown-in-catch-callback-variable",
|
|
108
|
+
"array-callback-return": "array-callback-return",
|
|
109
|
+
"block-scoped-var": "block-scoped-var",
|
|
110
|
+
"camelcase": "eslint-js/camelcase",
|
|
111
|
+
"complexity": "complexity",
|
|
112
|
+
"constructor-super": "constructor-super",
|
|
113
|
+
"curly": "curly",
|
|
114
|
+
"default-case": "default-case",
|
|
115
|
+
"default-case-last": "default-case-last",
|
|
116
|
+
"default-param-last": "default-param-last",
|
|
117
|
+
"dot-notation": "eslint-js/dot-notation",
|
|
118
|
+
"eqeqeq": "eqeqeq",
|
|
119
|
+
"for-direction": "for-direction",
|
|
120
|
+
"func-names": "func-names",
|
|
121
|
+
"getter-return": "getter-return",
|
|
122
|
+
"grouped-accessor-pairs": "grouped-accessor-pairs",
|
|
123
|
+
"guard-for-in": "guard-for-in",
|
|
124
|
+
"import-x/extensions": "import/extensions",
|
|
125
|
+
"import-x/first": "import/first",
|
|
126
|
+
"import-x/named": "import/named",
|
|
127
|
+
"import-x/namespace": "import/namespace",
|
|
128
|
+
"import-x/newline-after-import": "import/newline-after-import",
|
|
129
|
+
"import-x/no-absolute-path": "import/no-absolute-path",
|
|
130
|
+
"import-x/no-amd": "import/no-amd",
|
|
131
|
+
"import-x/no-anonymous-default-export": "import/no-anonymous-default-export",
|
|
132
|
+
"import-x/no-commonjs": "import/no-commonjs",
|
|
133
|
+
"import-x/no-cycle": "import/no-cycle",
|
|
134
|
+
"import-x/no-duplicates": "import/no-duplicates",
|
|
135
|
+
"import-x/no-dynamic-require": "import/no-dynamic-require",
|
|
136
|
+
"import-x/no-empty-named-blocks": "import/no-empty-named-blocks",
|
|
137
|
+
"import-x/no-mutable-exports": "import/no-mutable-exports",
|
|
138
|
+
"import-x/no-named-as-default": "import/no-named-as-default",
|
|
139
|
+
"import-x/no-named-as-default-member": "import/no-named-as-default-member",
|
|
140
|
+
"import-x/no-named-default": "import/no-named-default",
|
|
141
|
+
"import-x/no-self-import": "import/no-self-import",
|
|
142
|
+
"import-x/no-webpack-loader-syntax": "import/no-webpack-loader-syntax",
|
|
143
|
+
"jsx-a11y/alt-text": "jsx_a11y/alt-text",
|
|
144
|
+
"jsx-a11y/anchor-has-content": "jsx_a11y/anchor-has-content",
|
|
145
|
+
"jsx-a11y/anchor-is-valid": "jsx_a11y/anchor-is-valid",
|
|
146
|
+
"jsx-a11y/aria-activedescendant-has-tabindex": "jsx_a11y/aria-activedescendant-has-tabindex",
|
|
147
|
+
"jsx-a11y/aria-props": "jsx_a11y/aria-props",
|
|
148
|
+
"jsx-a11y/aria-proptypes": "jsx_a11y/aria-proptypes",
|
|
149
|
+
"jsx-a11y/aria-role": "jsx_a11y/aria-role",
|
|
150
|
+
"jsx-a11y/aria-unsupported-elements": "jsx_a11y/aria-unsupported-elements",
|
|
151
|
+
"jsx-a11y/autocomplete-valid": "jsx_a11y/autocomplete-valid",
|
|
152
|
+
"jsx-a11y/click-events-have-key-events": "jsx_a11y/click-events-have-key-events",
|
|
153
|
+
"jsx-a11y/heading-has-content": "jsx_a11y/heading-has-content",
|
|
154
|
+
"jsx-a11y/html-has-lang": "jsx_a11y/html-has-lang",
|
|
155
|
+
"jsx-a11y/iframe-has-title": "jsx_a11y/iframe-has-title",
|
|
156
|
+
"jsx-a11y/img-redundant-alt": "jsx_a11y/img-redundant-alt",
|
|
157
|
+
"jsx-a11y/interactive-supports-focus": "jsx_a11y/interactive-supports-focus",
|
|
158
|
+
"jsx-a11y/label-has-associated-control": "jsx_a11y/label-has-associated-control",
|
|
159
|
+
"jsx-a11y/media-has-caption": "jsx_a11y/media-has-caption",
|
|
160
|
+
"jsx-a11y/mouse-events-have-key-events": "jsx_a11y/mouse-events-have-key-events",
|
|
161
|
+
"jsx-a11y/no-access-key": "jsx_a11y/no-access-key",
|
|
162
|
+
"jsx-a11y/no-autofocus": "jsx_a11y/no-autofocus",
|
|
163
|
+
"jsx-a11y/no-distracting-elements": "jsx_a11y/no-distracting-elements",
|
|
164
|
+
"jsx-a11y/no-interactive-element-to-noninteractive-role": "jsx_a11y/no-interactive-element-to-noninteractive-role",
|
|
165
|
+
"jsx-a11y/no-noninteractive-element-interactions": "jsx_a11y/no-noninteractive-element-interactions",
|
|
166
|
+
"jsx-a11y/no-noninteractive-element-to-interactive-role": "jsx_a11y/no-noninteractive-element-to-interactive-role",
|
|
167
|
+
"jsx-a11y/no-noninteractive-tabindex": "jsx_a11y/no-noninteractive-tabindex",
|
|
168
|
+
"jsx-a11y/no-redundant-roles": "jsx_a11y/no-redundant-roles",
|
|
169
|
+
"jsx-a11y/no-static-element-interactions": "jsx_a11y/no-static-element-interactions",
|
|
170
|
+
"jsx-a11y/role-has-required-aria-props": "jsx_a11y/role-has-required-aria-props",
|
|
171
|
+
"jsx-a11y/role-supports-aria-props": "jsx_a11y/role-supports-aria-props",
|
|
172
|
+
"jsx-a11y/scope": "jsx_a11y/scope",
|
|
173
|
+
"jsx-a11y/tabindex-no-positive": "jsx_a11y/tabindex-no-positive",
|
|
174
|
+
"max-depth": "max-depth",
|
|
175
|
+
"max-params": "max-params",
|
|
176
|
+
"n/no-deprecated-api": "node-js/no-deprecated-api",
|
|
177
|
+
"n/no-exports-assign": "node/no-exports-assign",
|
|
178
|
+
"n/no-new-require": "node/no-new-require",
|
|
179
|
+
"n/no-path-concat": "node/no-path-concat",
|
|
180
|
+
"n/no-unpublished-bin": "node-js/no-unpublished-bin",
|
|
181
|
+
"n/no-unsupported-features/es-builtins": "node-js/no-unsupported-features/es-builtins",
|
|
182
|
+
"n/no-unsupported-features/es-syntax": "node-js/no-unsupported-features/es-syntax",
|
|
183
|
+
"n/no-unsupported-features/node-builtins": "node-js/no-unsupported-features/node-builtins",
|
|
184
|
+
"new-cap": "new-cap",
|
|
185
|
+
"no-alert": "no-alert",
|
|
186
|
+
"no-array-constructor": "no-array-constructor",
|
|
187
|
+
"no-async-promise-executor": "no-async-promise-executor",
|
|
188
|
+
"no-bitwise": "no-bitwise",
|
|
189
|
+
"no-caller": "no-caller",
|
|
190
|
+
"no-case-declarations": "no-case-declarations",
|
|
191
|
+
"no-class-assign": "no-class-assign",
|
|
192
|
+
"no-compare-neg-zero": "no-compare-neg-zero",
|
|
193
|
+
"no-cond-assign": "no-cond-assign",
|
|
194
|
+
"no-console": "no-console",
|
|
195
|
+
"no-const-assign": "no-const-assign",
|
|
196
|
+
"no-constant-binary-expression": "no-constant-binary-expression",
|
|
197
|
+
"no-constant-condition": "no-constant-condition",
|
|
198
|
+
"no-constructor-return": "no-constructor-return",
|
|
199
|
+
"no-control-regex": "no-control-regex",
|
|
200
|
+
"no-debugger": "no-debugger",
|
|
201
|
+
"no-delete-var": "no-delete-var",
|
|
202
|
+
"no-dupe-class-members": "no-dupe-class-members",
|
|
203
|
+
"no-dupe-else-if": "no-dupe-else-if",
|
|
204
|
+
"no-dupe-keys": "no-dupe-keys",
|
|
205
|
+
"no-duplicate-case": "no-duplicate-case",
|
|
206
|
+
"no-empty-character-class": "no-empty-character-class",
|
|
207
|
+
"no-empty-function": "no-empty-function",
|
|
208
|
+
"no-empty-pattern": "no-empty-pattern",
|
|
209
|
+
"no-empty-static-block": "no-empty-static-block",
|
|
210
|
+
"no-eval": "no-eval",
|
|
211
|
+
"no-ex-assign": "no-ex-assign",
|
|
212
|
+
"no-extend-native": "no-extend-native",
|
|
213
|
+
"no-extra-bind": "no-extra-bind",
|
|
214
|
+
"no-extra-boolean-cast": "no-extra-boolean-cast",
|
|
215
|
+
"no-extra-label": "no-extra-label",
|
|
216
|
+
"no-fallthrough": "no-fallthrough",
|
|
217
|
+
"no-func-assign": "no-func-assign",
|
|
218
|
+
"no-global-assign": "no-global-assign",
|
|
219
|
+
"no-implied-eval": "no-implied-eval",
|
|
220
|
+
"no-import-assign": "no-import-assign",
|
|
221
|
+
"no-invalid-regexp": "no-invalid-regexp",
|
|
222
|
+
"no-irregular-whitespace": "no-irregular-whitespace",
|
|
223
|
+
"no-label-var": "no-label-var",
|
|
224
|
+
"no-labels": "no-labels",
|
|
225
|
+
"no-lone-blocks": "eslint-js/no-lone-blocks",
|
|
226
|
+
"no-lonely-if": "no-lonely-if",
|
|
227
|
+
"no-loop-func": "no-loop-func",
|
|
228
|
+
"no-loss-of-precision": "no-loss-of-precision",
|
|
229
|
+
"no-misleading-character-class": "no-misleading-character-class",
|
|
230
|
+
"no-multi-assign": "no-multi-assign",
|
|
231
|
+
"no-multi-str": "no-multi-str",
|
|
232
|
+
"no-nested-ternary": "no-nested-ternary",
|
|
233
|
+
"no-new": "no-new",
|
|
234
|
+
"no-new-func": "no-new-func",
|
|
235
|
+
"no-new-native-nonconstructor": "no-new-native-nonconstructor",
|
|
236
|
+
"no-new-wrappers": "no-new-wrappers",
|
|
237
|
+
"no-nonoctal-decimal-escape": "no-nonoctal-decimal-escape",
|
|
238
|
+
"no-obj-calls": "no-obj-calls",
|
|
239
|
+
"no-object-constructor": "no-object-constructor",
|
|
240
|
+
"no-promise-executor-return": "no-promise-executor-return",
|
|
241
|
+
"no-proto": "no-proto",
|
|
242
|
+
"no-prototype-builtins": "no-prototype-builtins",
|
|
243
|
+
"no-redeclare": "no-redeclare",
|
|
244
|
+
"no-regex-spaces": "no-regex-spaces",
|
|
245
|
+
"no-restricted-exports": "no-restricted-exports",
|
|
246
|
+
"no-restricted-globals": "no-restricted-globals",
|
|
247
|
+
"no-restricted-properties": "no-restricted-properties",
|
|
248
|
+
"no-restricted-syntax": "eslint-js/no-restricted-syntax",
|
|
249
|
+
"no-return-assign": "no-return-assign",
|
|
250
|
+
"no-script-url": "no-script-url",
|
|
251
|
+
"no-self-assign": "no-self-assign",
|
|
252
|
+
"no-self-compare": "no-self-compare",
|
|
253
|
+
"no-sequences": "no-sequences",
|
|
254
|
+
"no-setter-return": "no-setter-return",
|
|
255
|
+
"no-shadow-restricted-names": "no-shadow-restricted-names",
|
|
256
|
+
"no-sparse-arrays": "no-sparse-arrays",
|
|
257
|
+
"no-template-curly-in-string": "no-template-curly-in-string",
|
|
258
|
+
"no-this-before-super": "no-this-before-super",
|
|
259
|
+
"no-throw-literal": "no-throw-literal",
|
|
260
|
+
"no-unassigned-vars": "no-unassigned-vars",
|
|
261
|
+
"no-undef-init": "eslint-js/no-undef-init",
|
|
262
|
+
"no-unexpected-multiline": "no-unexpected-multiline",
|
|
263
|
+
"no-unneeded-ternary": "no-unneeded-ternary",
|
|
264
|
+
"no-unreachable": "no-unreachable",
|
|
265
|
+
"no-unreachable-loop": "no-unreachable-loop",
|
|
266
|
+
"no-unsafe-finally": "no-unsafe-finally",
|
|
267
|
+
"no-unsafe-negation": "no-unsafe-negation",
|
|
268
|
+
"no-unsafe-optional-chaining": "no-unsafe-optional-chaining",
|
|
269
|
+
"no-unused-expressions": "no-unused-expressions",
|
|
270
|
+
"no-unused-labels": "no-unused-labels",
|
|
271
|
+
"no-unused-private-class-members": "no-unused-private-class-members",
|
|
272
|
+
"no-unused-vars": "no-unused-vars",
|
|
273
|
+
"no-use-before-define": "no-use-before-define",
|
|
274
|
+
"no-useless-assignment": "no-useless-assignment",
|
|
275
|
+
"no-useless-backreference": "no-useless-backreference",
|
|
276
|
+
"no-useless-catch": "no-useless-catch",
|
|
277
|
+
"no-useless-computed-key": "no-useless-computed-key",
|
|
278
|
+
"no-useless-concat": "no-useless-concat",
|
|
279
|
+
"no-useless-constructor": "no-useless-constructor",
|
|
280
|
+
"no-useless-escape": "no-useless-escape",
|
|
281
|
+
"no-useless-rename": "no-useless-rename",
|
|
282
|
+
"no-useless-return": "no-useless-return",
|
|
283
|
+
"no-var": "no-var",
|
|
284
|
+
"no-void": "no-void",
|
|
285
|
+
"no-with": "no-with",
|
|
286
|
+
"object-shorthand": "object-shorthand",
|
|
287
|
+
"prefer-arrow-callback": "prefer-arrow-callback",
|
|
288
|
+
"prefer-const": "prefer-const",
|
|
289
|
+
"prefer-exponentiation-operator": "prefer-exponentiation-operator",
|
|
290
|
+
"prefer-numeric-literals": "prefer-numeric-literals",
|
|
291
|
+
"prefer-object-has-own": "prefer-object-has-own",
|
|
292
|
+
"prefer-object-spread": "prefer-object-spread",
|
|
293
|
+
"prefer-promise-reject-errors": "prefer-promise-reject-errors",
|
|
294
|
+
"prefer-regex-literals": "prefer-regex-literals",
|
|
295
|
+
"prefer-rest-params": "prefer-rest-params",
|
|
296
|
+
"prefer-spread": "prefer-spread",
|
|
297
|
+
"prefer-template": "prefer-template",
|
|
298
|
+
"preserve-caught-error": "preserve-caught-error",
|
|
299
|
+
"radix": "radix",
|
|
300
|
+
"react-hooks/exhaustive-deps": "react/exhaustive-deps",
|
|
301
|
+
"react-hooks/rules-of-hooks": "react/rules-of-hooks",
|
|
302
|
+
"react/button-has-type": "react/button-has-type",
|
|
303
|
+
"react/function-component-definition": "react/function-component-definition",
|
|
304
|
+
"react/hook-use-state": "react/hook-use-state",
|
|
305
|
+
"react/jsx-boolean-value": "react/jsx-boolean-value",
|
|
306
|
+
"react/jsx-curly-brace-presence": "react/jsx-curly-brace-presence",
|
|
307
|
+
"react/jsx-fragments": "react/jsx-fragments",
|
|
308
|
+
"react/jsx-key": "react/jsx-key",
|
|
309
|
+
"react/jsx-no-comment-textnodes": "react/jsx-no-comment-textnodes",
|
|
310
|
+
"react/jsx-no-constructed-context-values": "react/jsx-no-constructed-context-values",
|
|
311
|
+
"react/jsx-no-duplicate-props": "react/jsx-no-duplicate-props",
|
|
312
|
+
"react/jsx-no-leaked-render": "@pob/jsx-no-leaked-render",
|
|
313
|
+
"react/jsx-no-script-url": "react/jsx-no-script-url",
|
|
314
|
+
"react/jsx-no-target-blank": "react/jsx-no-target-blank",
|
|
315
|
+
"react/jsx-no-undef": "react/jsx-no-undef",
|
|
316
|
+
"react/jsx-no-useless-fragment": "react/jsx-no-useless-fragment",
|
|
317
|
+
"react/jsx-pascal-case": "react/jsx-pascal-case",
|
|
318
|
+
"react/jsx-sort-props": "@pob/jsx-sort-props",
|
|
319
|
+
"react/no-array-index-key": "react/no-array-index-key",
|
|
320
|
+
"react/no-children-prop": "react/no-children-prop",
|
|
321
|
+
"react/no-danger-with-children": "react/no-danger-with-children",
|
|
322
|
+
"react/no-direct-mutation-state": "react/no-direct-mutation-state",
|
|
323
|
+
"react/no-find-dom-node": "react/no-find-dom-node",
|
|
324
|
+
"react/no-is-mounted": "react/no-is-mounted",
|
|
325
|
+
"react/no-namespace": "react/no-namespace",
|
|
326
|
+
"react/no-render-return-value": "react/no-render-return-value",
|
|
327
|
+
"react/no-string-refs": "react/no-string-refs",
|
|
328
|
+
"react/no-unknown-property": "react/no-unknown-property",
|
|
329
|
+
"react/no-unstable-nested-components": "react/no-unstable-nested-components",
|
|
330
|
+
"react/prefer-es6-class": "react/prefer-es6-class",
|
|
331
|
+
"react/require-render-return": "react/require-render-return",
|
|
332
|
+
"react/self-closing-comp": "react/self-closing-comp",
|
|
333
|
+
"regexp/confusing-quantifier": "regexp/confusing-quantifier",
|
|
334
|
+
"regexp/control-character-escape": "regexp/control-character-escape",
|
|
335
|
+
"regexp/match-any": "regexp/match-any",
|
|
336
|
+
"regexp/negation": "regexp/negation",
|
|
337
|
+
"regexp/no-contradiction-with-assertion": "regexp/no-contradiction-with-assertion",
|
|
338
|
+
"regexp/no-dupe-characters-character-class": "regexp/no-dupe-characters-character-class",
|
|
339
|
+
"regexp/no-dupe-disjunctions": "regexp/no-dupe-disjunctions",
|
|
340
|
+
"regexp/no-empty-alternative": "regexp/no-empty-alternative",
|
|
341
|
+
"regexp/no-empty-capturing-group": "regexp/no-empty-capturing-group",
|
|
342
|
+
"regexp/no-empty-character-class": "regexp/no-empty-character-class",
|
|
343
|
+
"regexp/no-empty-group": "regexp/no-empty-group",
|
|
344
|
+
"regexp/no-empty-lookarounds-assertion": "regexp/no-empty-lookarounds-assertion",
|
|
345
|
+
"regexp/no-empty-string-literal": "regexp/no-empty-string-literal",
|
|
346
|
+
"regexp/no-escape-backspace": "regexp/no-escape-backspace",
|
|
347
|
+
"regexp/no-extra-lookaround-assertions": "regexp/no-extra-lookaround-assertions",
|
|
348
|
+
"regexp/no-invalid-regexp": "regexp/no-invalid-regexp",
|
|
349
|
+
"regexp/no-invisible-character": "regexp/no-invisible-character",
|
|
350
|
+
"regexp/no-lazy-ends": "regexp/no-lazy-ends",
|
|
351
|
+
"regexp/no-legacy-features": "regexp/no-legacy-features",
|
|
352
|
+
"regexp/no-misleading-capturing-group": "regexp/no-misleading-capturing-group",
|
|
353
|
+
"regexp/no-misleading-unicode-character": "regexp/no-misleading-unicode-character",
|
|
354
|
+
"regexp/no-missing-g-flag": "regexp/no-missing-g-flag",
|
|
355
|
+
"regexp/no-non-standard-flag": "regexp/no-non-standard-flag",
|
|
356
|
+
"regexp/no-obscure-range": "regexp/no-obscure-range",
|
|
357
|
+
"regexp/no-optional-assertion": "regexp/no-optional-assertion",
|
|
358
|
+
"regexp/no-potentially-useless-backreference": "regexp/no-potentially-useless-backreference",
|
|
359
|
+
"regexp/no-super-linear-backtracking": "regexp/no-super-linear-backtracking",
|
|
360
|
+
"regexp/no-trivially-nested-assertion": "regexp/no-trivially-nested-assertion",
|
|
361
|
+
"regexp/no-trivially-nested-quantifier": "regexp/no-trivially-nested-quantifier",
|
|
362
|
+
"regexp/no-unused-capturing-group": "regexp/no-unused-capturing-group",
|
|
363
|
+
"regexp/no-useless-assertions": "regexp/no-useless-assertions",
|
|
364
|
+
"regexp/no-useless-backreference": "regexp/no-useless-backreference",
|
|
365
|
+
"regexp/no-useless-character-class": "regexp/no-useless-character-class",
|
|
366
|
+
"regexp/no-useless-dollar-replacements": "regexp/no-useless-dollar-replacements",
|
|
367
|
+
"regexp/no-useless-escape": "regexp/no-useless-escape",
|
|
368
|
+
"regexp/no-useless-flag": "regexp/no-useless-flag",
|
|
369
|
+
"regexp/no-useless-lazy": "regexp/no-useless-lazy",
|
|
370
|
+
"regexp/no-useless-non-capturing-group": "regexp/no-useless-non-capturing-group",
|
|
371
|
+
"regexp/no-useless-quantifier": "regexp/no-useless-quantifier",
|
|
372
|
+
"regexp/no-useless-range": "regexp/no-useless-range",
|
|
373
|
+
"regexp/no-useless-set-operand": "regexp/no-useless-set-operand",
|
|
374
|
+
"regexp/no-useless-string-literal": "regexp/no-useless-string-literal",
|
|
375
|
+
"regexp/no-useless-two-nums-quantifier": "regexp/no-useless-two-nums-quantifier",
|
|
376
|
+
"regexp/no-zero-quantifier": "regexp/no-zero-quantifier",
|
|
377
|
+
"regexp/optimal-lookaround-quantifier": "regexp/optimal-lookaround-quantifier",
|
|
378
|
+
"regexp/optimal-quantifier-concatenation": "regexp/optimal-quantifier-concatenation",
|
|
379
|
+
"regexp/prefer-character-class": "regexp/prefer-character-class",
|
|
380
|
+
"regexp/prefer-d": "regexp/prefer-d",
|
|
381
|
+
"regexp/prefer-plus-quantifier": "regexp/prefer-plus-quantifier",
|
|
382
|
+
"regexp/prefer-predefined-assertion": "regexp/prefer-predefined-assertion",
|
|
383
|
+
"regexp/prefer-question-quantifier": "regexp/prefer-question-quantifier",
|
|
384
|
+
"regexp/prefer-range": "regexp/prefer-range",
|
|
385
|
+
"regexp/prefer-set-operation": "regexp/prefer-set-operation",
|
|
386
|
+
"regexp/prefer-star-quantifier": "regexp/prefer-star-quantifier",
|
|
387
|
+
"regexp/prefer-unicode-codepoint-escapes": "regexp/prefer-unicode-codepoint-escapes",
|
|
388
|
+
"regexp/prefer-w": "regexp/prefer-w",
|
|
389
|
+
"regexp/simplify-set-operations": "regexp/simplify-set-operations",
|
|
390
|
+
"regexp/sort-flags": "regexp/sort-flags",
|
|
391
|
+
"regexp/strict": "regexp/strict",
|
|
392
|
+
"regexp/use-ignore-case": "regexp/use-ignore-case",
|
|
393
|
+
"require-await": "require-await",
|
|
394
|
+
"require-yield": "require-yield",
|
|
395
|
+
"sort-imports": "sort-imports",
|
|
396
|
+
"symbol-description": "symbol-description",
|
|
397
|
+
"unicorn/catch-error-name": "unicorn/catch-error-name",
|
|
398
|
+
"unicorn/consistent-assert": "unicorn/consistent-assert",
|
|
399
|
+
"unicorn/consistent-date-clone": "unicorn/consistent-date-clone",
|
|
400
|
+
"unicorn/consistent-existence-index-check": "unicorn/consistent-existence-index-check",
|
|
401
|
+
"unicorn/consistent-template-literal-escape": "unicorn/consistent-template-literal-escape",
|
|
402
|
+
"unicorn/custom-error-definition": "unicorn/custom-error-definition",
|
|
403
|
+
"unicorn/error-message": "unicorn/error-message",
|
|
404
|
+
"unicorn/escape-case": "unicorn/escape-case",
|
|
405
|
+
"unicorn/expiring-todo-comments": "unicorn-js/expiring-todo-comments",
|
|
406
|
+
"unicorn/explicit-length-check": "unicorn/explicit-length-check",
|
|
407
|
+
"unicorn/new-for-builtins": "unicorn/new-for-builtins",
|
|
408
|
+
"unicorn/no-accessor-recursion": "unicorn/no-accessor-recursion",
|
|
409
|
+
"unicorn/no-array-method-this-argument": "unicorn/no-array-method-this-argument",
|
|
410
|
+
"unicorn/no-array-reduce": "unicorn/no-array-reduce",
|
|
411
|
+
"unicorn/no-array-reverse": "unicorn/no-array-reverse",
|
|
412
|
+
"unicorn/no-array-sort": "unicorn/no-array-sort",
|
|
413
|
+
"unicorn/no-await-expression-member": "unicorn/no-await-expression-member",
|
|
414
|
+
"unicorn/no-document-cookie": "unicorn/no-document-cookie",
|
|
415
|
+
"unicorn/no-hex-escape": "unicorn/no-hex-escape",
|
|
416
|
+
"unicorn/no-immediate-mutation": "unicorn/no-immediate-mutation",
|
|
417
|
+
"unicorn/no-instanceof-builtins": "unicorn/no-instanceof-builtins",
|
|
418
|
+
"unicorn/no-invalid-remove-event-listener": "unicorn/no-invalid-remove-event-listener",
|
|
419
|
+
"unicorn/no-nested-ternary": "unicorn/no-nested-ternary",
|
|
420
|
+
"unicorn/no-new-array": "unicorn/no-new-array",
|
|
421
|
+
"unicorn/no-new-buffer": "unicorn/no-new-buffer",
|
|
422
|
+
"unicorn/no-process-exit": "unicorn/no-process-exit",
|
|
423
|
+
"unicorn/no-static-only-class": "unicorn/no-static-only-class",
|
|
424
|
+
"unicorn/no-this-assignment": "unicorn/no-this-assignment",
|
|
425
|
+
"unicorn/no-typeof-undefined": "unicorn/no-typeof-undefined",
|
|
426
|
+
"unicorn/no-unnecessary-await": "unicorn/no-unnecessary-await",
|
|
427
|
+
"unicorn/no-unnecessary-polyfills": "unicorn-js/no-unnecessary-polyfills",
|
|
428
|
+
"unicorn/no-unnecessary-slice-end": "unicorn/no-unnecessary-slice-end",
|
|
429
|
+
"unicorn/no-unreadable-iife": "unicorn/no-unreadable-iife",
|
|
430
|
+
"unicorn/no-useless-collection-argument": "unicorn/no-useless-collection-argument",
|
|
431
|
+
"unicorn/no-useless-fallback-in-spread": "unicorn/no-useless-fallback-in-spread",
|
|
432
|
+
"unicorn/no-useless-iterator-to-array": "unicorn/no-useless-iterator-to-array",
|
|
433
|
+
"unicorn/no-useless-length-check": "unicorn/no-useless-length-check",
|
|
434
|
+
"unicorn/no-useless-promise-resolve-reject": "unicorn/no-useless-promise-resolve-reject",
|
|
435
|
+
"unicorn/no-useless-spread": "unicorn/no-useless-spread",
|
|
436
|
+
"unicorn/number-literal-case": "unicorn/number-literal-case",
|
|
437
|
+
"unicorn/numeric-separators-style": "unicorn/numeric-separators-style",
|
|
438
|
+
"unicorn/prefer-add-event-listener": "unicorn-js/prefer-add-event-listener",
|
|
439
|
+
"unicorn/prefer-array-find": "unicorn/prefer-array-find",
|
|
440
|
+
"unicorn/prefer-array-flat": "unicorn/prefer-array-flat",
|
|
441
|
+
"unicorn/prefer-array-flat-map": "unicorn/prefer-array-flat-map",
|
|
442
|
+
"unicorn/prefer-array-index-of": "unicorn/prefer-array-index-of",
|
|
443
|
+
"unicorn/prefer-array-some": "unicorn/prefer-array-some",
|
|
444
|
+
"unicorn/prefer-at": "unicorn/prefer-at",
|
|
445
|
+
"unicorn/prefer-blob-reading-methods": "unicorn/prefer-blob-reading-methods",
|
|
446
|
+
"unicorn/prefer-class-fields": "unicorn/prefer-class-fields",
|
|
447
|
+
"unicorn/prefer-code-point": "unicorn/prefer-code-point",
|
|
448
|
+
"unicorn/prefer-date-now": "unicorn/prefer-date-now",
|
|
449
|
+
"unicorn/prefer-default-parameters": "unicorn/prefer-default-parameters",
|
|
450
|
+
"unicorn/prefer-dom-node-append": "unicorn/prefer-dom-node-append",
|
|
451
|
+
"unicorn/prefer-dom-node-dataset": "unicorn/prefer-dom-node-dataset",
|
|
452
|
+
"unicorn/prefer-dom-node-remove": "unicorn/prefer-dom-node-remove",
|
|
453
|
+
"unicorn/prefer-dom-node-text-content": "unicorn/prefer-dom-node-text-content",
|
|
454
|
+
"unicorn/prefer-event-target": "unicorn/prefer-event-target",
|
|
455
|
+
"unicorn/prefer-export-from": "unicorn/prefer-export-from",
|
|
456
|
+
"unicorn/prefer-global-this": "unicorn/prefer-global-this",
|
|
457
|
+
"unicorn/prefer-includes": "unicorn/prefer-includes",
|
|
458
|
+
"unicorn/prefer-json-parse-buffer": "unicorn-js/prefer-json-parse-buffer",
|
|
459
|
+
"unicorn/prefer-logical-operator-over-ternary": "unicorn/prefer-logical-operator-over-ternary",
|
|
460
|
+
"unicorn/prefer-math-min-max": "unicorn/prefer-math-min-max",
|
|
461
|
+
"unicorn/prefer-math-trunc": "unicorn/prefer-math-trunc",
|
|
462
|
+
"unicorn/prefer-modern-dom-apis": "unicorn/prefer-modern-dom-apis",
|
|
463
|
+
"unicorn/prefer-modern-math-apis": "unicorn/prefer-modern-math-apis",
|
|
464
|
+
"unicorn/prefer-module": "unicorn/prefer-module",
|
|
465
|
+
"unicorn/prefer-native-coercion-functions": "unicorn/prefer-native-coercion-functions",
|
|
466
|
+
"unicorn/prefer-negative-index": "unicorn/prefer-negative-index",
|
|
467
|
+
"unicorn/prefer-node-protocol": "unicorn/prefer-node-protocol",
|
|
468
|
+
"unicorn/prefer-object-from-entries": "unicorn/prefer-object-from-entries",
|
|
469
|
+
"unicorn/prefer-optional-catch-binding": "unicorn/prefer-optional-catch-binding",
|
|
470
|
+
"unicorn/prefer-prototype-methods": "unicorn/prefer-prototype-methods",
|
|
471
|
+
"unicorn/prefer-regexp-test": "unicorn/prefer-regexp-test",
|
|
472
|
+
"unicorn/prefer-response-static-json": "unicorn/prefer-response-static-json",
|
|
473
|
+
"unicorn/prefer-set-size": "unicorn/prefer-set-size",
|
|
474
|
+
"unicorn/prefer-single-call": "unicorn/prefer-single-call",
|
|
475
|
+
"unicorn/prefer-spread": "unicorn/prefer-spread",
|
|
476
|
+
"unicorn/prefer-string-slice": "unicorn/prefer-string-slice",
|
|
477
|
+
"unicorn/prefer-string-starts-ends-with": "unicorn/prefer-string-starts-ends-with",
|
|
478
|
+
"unicorn/prefer-string-trim-start-end": "unicorn/prefer-string-trim-start-end",
|
|
479
|
+
"unicorn/prefer-switch": "unicorn-js/prefer-switch",
|
|
480
|
+
"unicorn/prefer-top-level-await": "unicorn/prefer-top-level-await",
|
|
481
|
+
"unicorn/prefer-type-error": "unicorn/prefer-type-error",
|
|
482
|
+
"unicorn/relative-url-style": "unicorn/relative-url-style",
|
|
483
|
+
"unicorn/require-array-join-separator": "unicorn/require-array-join-separator",
|
|
484
|
+
"unicorn/require-number-to-fixed-digits-argument": "unicorn/require-number-to-fixed-digits-argument",
|
|
485
|
+
"unicorn/require-post-message-target-origin": "unicorn/require-post-message-target-origin",
|
|
486
|
+
"unicorn/switch-case-break-position": "unicorn/switch-case-break-position",
|
|
487
|
+
"unicorn/text-encoding-identifier-case": "unicorn/text-encoding-identifier-case",
|
|
488
|
+
"unicorn/throw-new-error": "unicorn/throw-new-error",
|
|
489
|
+
"use-isnan": "use-isnan",
|
|
490
|
+
"valid-typeof": "valid-typeof",
|
|
491
|
+
"yoda": "yoda"
|
|
492
|
+
}
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { fileURLToPath } from "node:url";
|
|
2
|
+
import runJscodeshift from "./runJscodeshift.cjs";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Runs a transform of lib/transforms on `paths`, like `pob-migrate`.
|
|
6
|
+
*
|
|
7
|
+
* @param {string} transformName
|
|
8
|
+
* @param {string[]} paths
|
|
9
|
+
* @param {Record<string, unknown>} [options] jscodeshift runner options
|
|
10
|
+
*/
|
|
11
|
+
export const runTransform = (transformName, paths, options = {}) =>
|
|
12
|
+
runJscodeshift(
|
|
13
|
+
fileURLToPath(
|
|
14
|
+
new URL(`./transforms/${transformName}.cjs`, import.meta.url),
|
|
15
|
+
),
|
|
16
|
+
paths,
|
|
17
|
+
options,
|
|
18
|
+
);
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/* oxlint-disable unicorn/prefer-array-some */
|
|
2
|
+
/* oxlint-disable unicorn/no-array-method-this-argument */
|
|
3
|
+
|
|
4
|
+
"use strict";
|
|
5
|
+
|
|
6
|
+
const { prependImport } = require("../utils/prependImport.cjs");
|
|
7
|
+
|
|
8
|
+
const jestToNodeGlobalMethods = {
|
|
9
|
+
test: "test",
|
|
10
|
+
describe: "describe",
|
|
11
|
+
it: "it",
|
|
12
|
+
beforeAll: "before",
|
|
13
|
+
afterAll: "after",
|
|
14
|
+
beforeEach: "beforeEach",
|
|
15
|
+
afterEach: "afterEach",
|
|
16
|
+
};
|
|
17
|
+
const propertiesMap = {
|
|
18
|
+
toBe: { default: "equal", not: "notEqual" },
|
|
19
|
+
toStrictEqual: { default: "equal", not: "notEqual" },
|
|
20
|
+
toEqual: { default: "equal", not: "notEqual" },
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// const mocks = {
|
|
24
|
+
// toHaveBeenCalledTimes: {
|
|
25
|
+
// default: 'mock.calls.length',
|
|
26
|
+
// },
|
|
27
|
+
// };
|
|
28
|
+
|
|
29
|
+
module.exports = (file, api, options) => {
|
|
30
|
+
if (
|
|
31
|
+
!(
|
|
32
|
+
file.path.endsWith(".test.js") ||
|
|
33
|
+
file.path.endsWith(".test.ts") ||
|
|
34
|
+
file.path.endsWith(".test.tsx")
|
|
35
|
+
)
|
|
36
|
+
) {
|
|
37
|
+
throw new Error(`Invalid file: "${file.path}"`);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const j = api.jscodeshift.withParser("tsx");
|
|
41
|
+
const root = j(file.source);
|
|
42
|
+
|
|
43
|
+
function updateTopLevelMethods() {
|
|
44
|
+
const topLevelMethodsUsed = new Set();
|
|
45
|
+
|
|
46
|
+
root
|
|
47
|
+
.find(j.CallExpression, {
|
|
48
|
+
callee: {
|
|
49
|
+
type: j.Identifier.name,
|
|
50
|
+
name: (name) => Object.keys(jestToNodeGlobalMethods).includes(name),
|
|
51
|
+
},
|
|
52
|
+
})
|
|
53
|
+
.replaceWith((p) => {
|
|
54
|
+
const { value } = p;
|
|
55
|
+
const replaceValue = jestToNodeGlobalMethods[value.callee.name];
|
|
56
|
+
topLevelMethodsUsed.add(replaceValue);
|
|
57
|
+
|
|
58
|
+
return j.callExpression(j.identifier(replaceValue), value.arguments);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
if (topLevelMethodsUsed.size > 0) {
|
|
62
|
+
prependImport(
|
|
63
|
+
j,
|
|
64
|
+
root,
|
|
65
|
+
j.importDeclaration(
|
|
66
|
+
[...topLevelMethodsUsed].map((method) =>
|
|
67
|
+
j.importSpecifier(j.identifier(method)),
|
|
68
|
+
),
|
|
69
|
+
j.stringLiteral("node:test"),
|
|
70
|
+
),
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function updateAssertions() {
|
|
76
|
+
let hasAssertions = false;
|
|
77
|
+
|
|
78
|
+
root
|
|
79
|
+
.find(j.MemberExpression, {
|
|
80
|
+
object: {
|
|
81
|
+
callee: { name: "expect" },
|
|
82
|
+
},
|
|
83
|
+
})
|
|
84
|
+
.forEach((memberExpressionPath) => {
|
|
85
|
+
const { value: memberExpression, parentPath } = memberExpressionPath;
|
|
86
|
+
let memberExpressionPathToReplace = memberExpressionPath;
|
|
87
|
+
let propertyName = memberExpression.property.name;
|
|
88
|
+
let not = false;
|
|
89
|
+
if (propertyName === "not") {
|
|
90
|
+
not = true;
|
|
91
|
+
memberExpressionPathToReplace = parentPath;
|
|
92
|
+
propertyName = parentPath.value.property.name;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (!propertiesMap[propertyName]) {
|
|
96
|
+
console.warn(
|
|
97
|
+
`Unsupported expect property: ${propertyName} in ${file.path}`,
|
|
98
|
+
);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const assertPropertyName =
|
|
103
|
+
propertiesMap[propertyName][not ? "not" : "default"];
|
|
104
|
+
const callExpressionPath = memberExpressionPathToReplace.parentPath;
|
|
105
|
+
|
|
106
|
+
const value = memberExpression.object.arguments[0];
|
|
107
|
+
const expected = callExpressionPath.value.arguments[0];
|
|
108
|
+
|
|
109
|
+
hasAssertions = true;
|
|
110
|
+
callExpressionPath.value.callee = j.memberExpression(
|
|
111
|
+
j.identifier("assert"),
|
|
112
|
+
j.identifier(assertPropertyName),
|
|
113
|
+
);
|
|
114
|
+
callExpressionPath.value.arguments = [value, expected];
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
if (hasAssertions) {
|
|
118
|
+
root
|
|
119
|
+
.find(j.ImportDeclaration, { source: { value: "node:assert" } })
|
|
120
|
+
.remove();
|
|
121
|
+
if (
|
|
122
|
+
// oxlint-disable-next-line no-constant-condition
|
|
123
|
+
(!root.find(j.ImportDeclaration),
|
|
124
|
+
{ source: { value: "node:assert/strict" } })
|
|
125
|
+
) {
|
|
126
|
+
prependImport(
|
|
127
|
+
j,
|
|
128
|
+
root,
|
|
129
|
+
j.importDeclaration(
|
|
130
|
+
[j.importDefaultSpecifier(j.identifier("assert"))],
|
|
131
|
+
j.stringLiteral("node:assert/strict"),
|
|
132
|
+
),
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
updateTopLevelMethods();
|
|
139
|
+
updateAssertions();
|
|
140
|
+
|
|
141
|
+
root
|
|
142
|
+
.find(j.ImportDeclaration, { source: { value: "@jest/globals" } })
|
|
143
|
+
.remove();
|
|
144
|
+
|
|
145
|
+
return root.toSource(options);
|
|
146
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const { parse } = require("@babel/parser");
|
|
4
|
+
const { rewriteDirectiveComments } = require("../utils/oxlintDirectives.cjs");
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Rewrites the eslint directive comments of rules moved to oxlint, for the
|
|
8
|
+
* major of @pob/eslint-config that no longer runs them in eslint.
|
|
9
|
+
*
|
|
10
|
+
* @type {import("jscodeshift").Transform}
|
|
11
|
+
*/
|
|
12
|
+
module.exports = (file) => {
|
|
13
|
+
const isTypescript = /\.[cm]?ts$/.test(file.path);
|
|
14
|
+
const { comments = [] } = parse(file.source, {
|
|
15
|
+
// .cjs files may use sloppy mode syntax
|
|
16
|
+
sourceType: /\.c[jt]s$/.test(file.path) ? "script" : "unambiguous",
|
|
17
|
+
allowReturnOutsideFunction: true,
|
|
18
|
+
// only comments are needed: syntax errors do not matter
|
|
19
|
+
errorRecovery: true,
|
|
20
|
+
plugins: isTypescript
|
|
21
|
+
? ["typescript", "decorators-legacy"]
|
|
22
|
+
: ["typescript", "jsx", "decorators-legacy"],
|
|
23
|
+
});
|
|
24
|
+
const result = rewriteDirectiveComments(
|
|
25
|
+
file.source,
|
|
26
|
+
/** @type {{ type: string; value: string; start: number; end: number }[]} */ (
|
|
27
|
+
comments
|
|
28
|
+
),
|
|
29
|
+
);
|
|
30
|
+
return result === file.source ? undefined : result;
|
|
31
|
+
};
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
eslintToOxlintRuleNames,
|
|
5
|
+
isRemovedEslintPluginRule,
|
|
6
|
+
} = require("../utils/oxlintDirectives.cjs");
|
|
7
|
+
|
|
8
|
+
// configs of @pob/eslint-config and @pob/eslint-config-typescript-react left
|
|
9
|
+
// without rules once oxlint runs every rule it supports
|
|
10
|
+
const removedConfigNames = new Set([
|
|
11
|
+
"allowImplicitReturnType",
|
|
12
|
+
"allowUnsafe",
|
|
13
|
+
"allowUnsafeAsWarn",
|
|
14
|
+
"app",
|
|
15
|
+
"oxlint",
|
|
16
|
+
]);
|
|
17
|
+
|
|
18
|
+
const renamedConfigNames = new Map([
|
|
19
|
+
["nodeCommonjs", "node"],
|
|
20
|
+
["nodeModule", "node"],
|
|
21
|
+
]);
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Updates eslint.config.js for the major of @pob/eslint-config running every
|
|
25
|
+
* rule supported by oxlint in oxlint only: removes the configs left empty,
|
|
26
|
+
* renames the deprecated ones, and removes the rule entries of rules moved to
|
|
27
|
+
* oxlint (reported: their options go in .oxlintrc.json).
|
|
28
|
+
*
|
|
29
|
+
* @type {import("jscodeshift").Transform}
|
|
30
|
+
*/
|
|
31
|
+
module.exports = (file, api) => {
|
|
32
|
+
const j = api.jscodeshift.withParser("tsx");
|
|
33
|
+
const root = j(file.source);
|
|
34
|
+
let hasModifications = false;
|
|
35
|
+
|
|
36
|
+
/** @param {any} node */
|
|
37
|
+
const getLine = (node) => (node.loc ? `:${node.loc.start.line}` : "");
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @param {any} key
|
|
41
|
+
* @param {boolean} [computed]
|
|
42
|
+
*/
|
|
43
|
+
const getKeyName = (key, computed) => {
|
|
44
|
+
if (key.type === "Identifier" && !computed) return key.name;
|
|
45
|
+
if (
|
|
46
|
+
(key.type === "StringLiteral" || key.type === "Literal") &&
|
|
47
|
+
typeof key.value === "string"
|
|
48
|
+
) {
|
|
49
|
+
return key.value;
|
|
50
|
+
}
|
|
51
|
+
return undefined;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/** @param {any} node */
|
|
55
|
+
const getPropertyName = (node) => getKeyName(node.property, node.computed);
|
|
56
|
+
|
|
57
|
+
/** `<x>.configs.<name>` or `configs.<name>` */
|
|
58
|
+
const isConfigsMember = (/** @type {any} */ node) =>
|
|
59
|
+
node.type === "MemberExpression" &&
|
|
60
|
+
((node.object.type === "Identifier" && node.object.name === "configs") ||
|
|
61
|
+
(node.object.type === "MemberExpression" &&
|
|
62
|
+
getPropertyName(node.object) === "configs"));
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Removes the closest spread element of an array containing `path`, like
|
|
66
|
+
* `...apply({ configs: [] })`.
|
|
67
|
+
*
|
|
68
|
+
* @param {any} path
|
|
69
|
+
*/
|
|
70
|
+
const removeEnclosingSpread = (path) => {
|
|
71
|
+
let current = path.parent;
|
|
72
|
+
while (current) {
|
|
73
|
+
if (
|
|
74
|
+
current.value.type === "SpreadElement" &&
|
|
75
|
+
current.parent.value.type === "ArrayExpression"
|
|
76
|
+
) {
|
|
77
|
+
current.prune();
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
current = current.parent;
|
|
81
|
+
}
|
|
82
|
+
return false;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/** @param {any} node */
|
|
86
|
+
const isConfigsProperty = (node) =>
|
|
87
|
+
(node.type === "Property" || node.type === "ObjectProperty") &&
|
|
88
|
+
getKeyName(node.key, node.computed) === "configs";
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Removes an element of an array, and the apply() call whose `configs` it
|
|
92
|
+
* leaves empty.
|
|
93
|
+
*
|
|
94
|
+
* @param {any} elementPath
|
|
95
|
+
*/
|
|
96
|
+
const pruneArrayElement = (elementPath) => {
|
|
97
|
+
const array = elementPath.parent;
|
|
98
|
+
elementPath.prune();
|
|
99
|
+
if (
|
|
100
|
+
array.value.elements.length === 0 &&
|
|
101
|
+
isConfigsProperty(array.parent.value)
|
|
102
|
+
) {
|
|
103
|
+
removeEnclosingSpread(array);
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
root
|
|
108
|
+
.find(j.MemberExpression)
|
|
109
|
+
.filter((path) => isConfigsMember(path.value))
|
|
110
|
+
.forEach((path) => {
|
|
111
|
+
const name = getPropertyName(path.value);
|
|
112
|
+
if (!name) return;
|
|
113
|
+
|
|
114
|
+
const renamed = renamedConfigNames.get(name);
|
|
115
|
+
if (renamed) {
|
|
116
|
+
path.value.property = j.identifier(renamed);
|
|
117
|
+
path.value.computed = false;
|
|
118
|
+
hasModifications = true;
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (!removedConfigNames.has(name)) return;
|
|
123
|
+
|
|
124
|
+
const parent = path.parent.value;
|
|
125
|
+
if (
|
|
126
|
+
parent.type === "SpreadElement" &&
|
|
127
|
+
path.parent.parent.value.type === "ArrayExpression"
|
|
128
|
+
) {
|
|
129
|
+
pruneArrayElement(path.parent);
|
|
130
|
+
hasModifications = true;
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (
|
|
135
|
+
isConfigsProperty(parent) &&
|
|
136
|
+
parent.value === path.value &&
|
|
137
|
+
removeEnclosingSpread(path)
|
|
138
|
+
) {
|
|
139
|
+
hasModifications = true;
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
api.report(
|
|
144
|
+
`${file.path}${getLine(path.value)}: "configs.${name}" was removed, update this usage by hand.`,
|
|
145
|
+
);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
// rule entries of rules moved to oxlint
|
|
149
|
+
root
|
|
150
|
+
.find(j.Node)
|
|
151
|
+
.filter(
|
|
152
|
+
(path) =>
|
|
153
|
+
(path.value.type === "Property" ||
|
|
154
|
+
path.value.type === "ObjectProperty") &&
|
|
155
|
+
getKeyName(path.value.key, path.value.computed) === "rules" &&
|
|
156
|
+
path.value.value.type === "ObjectExpression",
|
|
157
|
+
)
|
|
158
|
+
.forEach((path) => {
|
|
159
|
+
const rules = path.value.value;
|
|
160
|
+
rules.properties = rules.properties.filter((/** @type {any} */ rule) => {
|
|
161
|
+
const ruleName = getKeyName(rule.key, rule.computed);
|
|
162
|
+
if (typeof ruleName !== "string") return true;
|
|
163
|
+
const oxlintRuleName = eslintToOxlintRuleNames[ruleName];
|
|
164
|
+
if (!oxlintRuleName && !isRemovedEslintPluginRule(ruleName)) {
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
hasModifications = true;
|
|
168
|
+
api.report(
|
|
169
|
+
oxlintRuleName
|
|
170
|
+
? `${file.path}${getLine(rule)}: "${ruleName}" is checked by oxlint: configure "${oxlintRuleName}" in .oxlintrc.json instead.`
|
|
171
|
+
: `${file.path}${getLine(rule)}: "${ruleName}" was removed.`,
|
|
172
|
+
);
|
|
173
|
+
return false;
|
|
174
|
+
});
|
|
175
|
+
if (rules.properties.length > 0) return;
|
|
176
|
+
|
|
177
|
+
// remove the config when the rules were all it configured
|
|
178
|
+
const config = path.parent;
|
|
179
|
+
config.value.properties = config.value.properties.filter(
|
|
180
|
+
(/** @type {any} */ property) => property !== path.value,
|
|
181
|
+
);
|
|
182
|
+
const isEmptyConfig = config.value.properties.every(
|
|
183
|
+
(/** @type {any} */ property) =>
|
|
184
|
+
["files", "ignores", "name"].includes(
|
|
185
|
+
getKeyName(property.key, property.computed) ?? "",
|
|
186
|
+
),
|
|
187
|
+
);
|
|
188
|
+
if (isEmptyConfig && config.parent.value.type === "ArrayExpression") {
|
|
189
|
+
pruneArrayElement(config);
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
return hasModifications ? root.toSource({ trailingComma: true }) : undefined;
|
|
194
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
module.exports = (file, api, options) => {
|
|
4
|
+
const j = api.jscodeshift.withParser("tsx");
|
|
5
|
+
const root = j(file.source);
|
|
6
|
+
let hasModifications = false;
|
|
7
|
+
|
|
8
|
+
function processFunctionComponent(path) {
|
|
9
|
+
const node = path.value;
|
|
10
|
+
const { returnType } = node;
|
|
11
|
+
if (returnType == null) return;
|
|
12
|
+
if (returnType.type !== "TSTypeAnnotation") return;
|
|
13
|
+
const { typeAnnotation } = returnType;
|
|
14
|
+
if (typeAnnotation == null) return;
|
|
15
|
+
|
|
16
|
+
if (
|
|
17
|
+
typeAnnotation.type === "TSTypeReference" &&
|
|
18
|
+
typeAnnotation.typeName &&
|
|
19
|
+
typeAnnotation.typeName.type === "Identifier"
|
|
20
|
+
) {
|
|
21
|
+
if (typeAnnotation.typeName.name === "ReactElement") {
|
|
22
|
+
typeAnnotation.typeName.name = "ReactNode";
|
|
23
|
+
hasModifications = true;
|
|
24
|
+
}
|
|
25
|
+
} else if (
|
|
26
|
+
typeAnnotation.type === "TSUnionType" &&
|
|
27
|
+
typeAnnotation.types.every((unionTypeItem) => {
|
|
28
|
+
if (unionTypeItem.type === "TSTypeReference") {
|
|
29
|
+
return (
|
|
30
|
+
unionTypeItem.typeName &&
|
|
31
|
+
unionTypeItem.typeName.type === "Identifier" &&
|
|
32
|
+
unionTypeItem.typeName.name === "ReactElement"
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (unionTypeItem.type === "TSNullKeyword") {
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return false;
|
|
41
|
+
})
|
|
42
|
+
) {
|
|
43
|
+
returnType.typeAnnotation = j.tsTypeReference(j.identifier("ReactNode"));
|
|
44
|
+
hasModifications = true;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
root.find(j.FunctionDeclaration).forEach(processFunctionComponent);
|
|
49
|
+
|
|
50
|
+
if (hasModifications) {
|
|
51
|
+
root.find(j.ImportDeclaration).forEach((importDeclaration) => {
|
|
52
|
+
const { node } = importDeclaration;
|
|
53
|
+
if (node.source.value !== "react") return;
|
|
54
|
+
if (node.importKind !== "type") return;
|
|
55
|
+
|
|
56
|
+
node.specifiers = node.specifiers.filter((importSpecifier) => {
|
|
57
|
+
if (importSpecifier.local.name !== "ReactElement") return true;
|
|
58
|
+
if (importSpecifier.importKind !== "value") return true;
|
|
59
|
+
return (
|
|
60
|
+
j(importDeclaration)
|
|
61
|
+
.closestScope()
|
|
62
|
+
// oxlint-disable-next-line unicorn/no-array-method-this-argument -- not an array
|
|
63
|
+
.find(j.Identifier, { name: "ReactElement" })
|
|
64
|
+
.filter((p) => {
|
|
65
|
+
if (p.value.start === importSpecifier.local.start) return false;
|
|
66
|
+
if (p.parentPath.value.type === "Property" && p.name === "key") {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
if (p.name === "property") return false;
|
|
70
|
+
return true;
|
|
71
|
+
})
|
|
72
|
+
.size() > 0
|
|
73
|
+
);
|
|
74
|
+
});
|
|
75
|
+
if (
|
|
76
|
+
!node.specifiers.some(
|
|
77
|
+
(specifier) =>
|
|
78
|
+
specifier.type === "ImportSpecifier" &&
|
|
79
|
+
specifier.imported.name === "ReactNode",
|
|
80
|
+
)
|
|
81
|
+
) {
|
|
82
|
+
node.specifiers.push(j.importSpecifier(j.identifier("ReactNode")));
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return hasModifications ? root.toSource(options) : null;
|
|
88
|
+
};
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// eslint rule name → oxlint rule name, for every rule of the oxlint configs of
|
|
4
|
+
// @pob/eslint-config and @pob/eslint-config-typescript-react, frozen at the
|
|
5
|
+
// last version running them in eslint too.
|
|
6
|
+
const eslintToOxlintRuleNames = require("../data/eslint-to-oxlint-rule-names.json");
|
|
7
|
+
|
|
8
|
+
// plugins no longer loaded by @pob/eslint-config: eslint reports a directive
|
|
9
|
+
// naming one of their rules as "Definition for rule ... was not found"
|
|
10
|
+
const removedEslintPluginPrefixes = [
|
|
11
|
+
"@pob/",
|
|
12
|
+
"@typescript-eslint/",
|
|
13
|
+
"jsx-a11y/",
|
|
14
|
+
"react-hooks/",
|
|
15
|
+
"react/",
|
|
16
|
+
"regexp/",
|
|
17
|
+
"unicorn/",
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
// rules of the eslint-plugin-react JS plugin of oxlint (react-js), removed
|
|
21
|
+
// with eslint-plugin-react: renamed when moved to @pob/eslint-plugin
|
|
22
|
+
const renamedOxlintRuleNames = new Map([
|
|
23
|
+
["react-js/jsx-no-leaked-render", "@pob/jsx-no-leaked-render"],
|
|
24
|
+
["react-js/jsx-sort-props", "@pob/jsx-sort-props"],
|
|
25
|
+
]);
|
|
26
|
+
const removedOxlintPluginPrefixes = ["react-js/"];
|
|
27
|
+
|
|
28
|
+
/** @param {string} ruleName */
|
|
29
|
+
const isRemovedEslintPluginRule = (ruleName) =>
|
|
30
|
+
removedEslintPluginPrefixes.some((prefix) => ruleName.startsWith(prefix));
|
|
31
|
+
|
|
32
|
+
const directiveRegExp =
|
|
33
|
+
/^\s*(eslint|oxlint)-(disable-next-line|disable-line|disable|enable)(?=\s|$)/;
|
|
34
|
+
|
|
35
|
+
// same as eslint: the description starts at the first " -- "
|
|
36
|
+
const descriptionRegExp = /\s-{2,}\s/;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @param {string} commentValue the comment without its delimiters
|
|
40
|
+
*/
|
|
41
|
+
const parseDirective = (commentValue) => {
|
|
42
|
+
const [content, ...descriptionParts] = commentValue.split(descriptionRegExp);
|
|
43
|
+
const match = directiveRegExp.exec(content);
|
|
44
|
+
if (!match) return undefined;
|
|
45
|
+
const [prefix, tool, kind] = match;
|
|
46
|
+
const ruleList = content.slice(prefix.length);
|
|
47
|
+
return {
|
|
48
|
+
tool,
|
|
49
|
+
kind,
|
|
50
|
+
ruleNames: ruleList
|
|
51
|
+
.split(",")
|
|
52
|
+
.map((ruleName) => ruleName.trim())
|
|
53
|
+
.filter(Boolean),
|
|
54
|
+
description:
|
|
55
|
+
descriptionParts.length > 0
|
|
56
|
+
? commentValue.slice(content.length).trim()
|
|
57
|
+
: undefined,
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @param {string[]} ruleNames
|
|
63
|
+
*/
|
|
64
|
+
const splitRuleNames = (ruleNames) => {
|
|
65
|
+
/** @type {Set<string>} */
|
|
66
|
+
const eslintRuleNames = new Set();
|
|
67
|
+
/** @type {Set<string>} */
|
|
68
|
+
const oxlintRuleNames = new Set();
|
|
69
|
+
for (const ruleName of ruleNames) {
|
|
70
|
+
const oxlintRuleName = eslintToOxlintRuleNames[ruleName];
|
|
71
|
+
if (oxlintRuleName) {
|
|
72
|
+
oxlintRuleNames.add(oxlintRuleName);
|
|
73
|
+
} else if (!isRemovedEslintPluginRule(ruleName)) {
|
|
74
|
+
eslintRuleNames.add(ruleName);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
eslintRuleNames: [...eslintRuleNames],
|
|
79
|
+
oxlintRuleNames: [...oxlintRuleNames],
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @param {"eslint" | "oxlint"} tool
|
|
85
|
+
* @param {string} kind
|
|
86
|
+
* @param {string[]} ruleNames
|
|
87
|
+
* @param {string | undefined} description
|
|
88
|
+
*/
|
|
89
|
+
const formatDirective = (tool, kind, ruleNames, description) =>
|
|
90
|
+
[`${tool}-${kind}`, ruleNames.join(", "), description]
|
|
91
|
+
.filter(Boolean)
|
|
92
|
+
.join(" ");
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Renames or removes the rules of the react-js JS plugin in an oxlint
|
|
96
|
+
* directive comment.
|
|
97
|
+
*
|
|
98
|
+
* @param {{ type: "CommentLine" | "CommentBlock" }} comment
|
|
99
|
+
* @param {{ kind: string; ruleNames: string[]; description: string | undefined }} directive
|
|
100
|
+
* @returns {string | null | undefined}
|
|
101
|
+
*/
|
|
102
|
+
const rewriteOxlintDirective = (comment, { kind, ruleNames, description }) => {
|
|
103
|
+
const newRuleNames = [
|
|
104
|
+
...new Set(
|
|
105
|
+
ruleNames
|
|
106
|
+
.map((ruleName) => renamedOxlintRuleNames.get(ruleName) ?? ruleName)
|
|
107
|
+
.filter(
|
|
108
|
+
(ruleName) =>
|
|
109
|
+
!removedOxlintPluginPrefixes.some((prefix) =>
|
|
110
|
+
ruleName.startsWith(prefix),
|
|
111
|
+
),
|
|
112
|
+
),
|
|
113
|
+
),
|
|
114
|
+
];
|
|
115
|
+
if (
|
|
116
|
+
newRuleNames.length === ruleNames.length &&
|
|
117
|
+
newRuleNames.every((ruleName, index) => ruleName === ruleNames[index])
|
|
118
|
+
) {
|
|
119
|
+
return undefined;
|
|
120
|
+
}
|
|
121
|
+
if (newRuleNames.length === 0) return null;
|
|
122
|
+
const text = formatDirective("oxlint", kind, newRuleNames, description);
|
|
123
|
+
return comment.type === "CommentBlock" ? `/* ${text} */` : `// ${text}`;
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Rewrites an eslint directive comment for @pob/eslint-config running the
|
|
128
|
+
* moved rules in oxlint only: their names move to an `oxlint-` directive of
|
|
129
|
+
* the same kind, rules of removed eslint plugins are dropped.
|
|
130
|
+
*
|
|
131
|
+
* @param {{ type: "CommentLine" | "CommentBlock"; value: string }} comment
|
|
132
|
+
* @returns {string | null | undefined} the new comment text, `null` to remove
|
|
133
|
+
* the comment, `undefined` when unchanged
|
|
134
|
+
*/
|
|
135
|
+
const rewriteDirectiveComment = (comment) => {
|
|
136
|
+
const directive = parseDirective(comment.value);
|
|
137
|
+
if (!directive) return undefined;
|
|
138
|
+
const { tool, kind, ruleNames, description } = directive;
|
|
139
|
+
if (tool === "oxlint") return rewriteOxlintDirective(comment, directive);
|
|
140
|
+
|
|
141
|
+
// a blanket directive disables every rule, now in both tools
|
|
142
|
+
if (ruleNames.length === 0) {
|
|
143
|
+
const eslintDirective = `/* ${comment.value.trim()} */`;
|
|
144
|
+
const oxlintDirective = formatDirective("oxlint", kind, [], description);
|
|
145
|
+
return comment.type === "CommentLine"
|
|
146
|
+
? `${eslintDirective} // ${oxlintDirective}`
|
|
147
|
+
: `${eslintDirective} /* ${oxlintDirective} */`;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const { eslintRuleNames, oxlintRuleNames } = splitRuleNames(ruleNames);
|
|
151
|
+
if (oxlintRuleNames.length === 0) {
|
|
152
|
+
if (eslintRuleNames.length === ruleNames.length) return undefined;
|
|
153
|
+
if (eslintRuleNames.length === 0) return null;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const directives = [
|
|
157
|
+
eslintRuleNames.length > 0 &&
|
|
158
|
+
formatDirective("eslint", kind, eslintRuleNames, description),
|
|
159
|
+
oxlintRuleNames.length > 0 &&
|
|
160
|
+
formatDirective("oxlint", kind, oxlintRuleNames, description),
|
|
161
|
+
].filter(Boolean);
|
|
162
|
+
|
|
163
|
+
if (comment.type === "CommentBlock") {
|
|
164
|
+
return directives.map((text) => `/* ${text} */`).join(" ");
|
|
165
|
+
}
|
|
166
|
+
// a line comment ends the line: only the last directive can be one
|
|
167
|
+
return directives
|
|
168
|
+
.map((text, index) =>
|
|
169
|
+
index === directives.length - 1 ? `// ${text}` : `/* ${text} */`,
|
|
170
|
+
)
|
|
171
|
+
.join(" ");
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* @param {string} source
|
|
176
|
+
* @param {{ type: string; value: string; start: number; end: number }[]} comments
|
|
177
|
+
* @returns {string}
|
|
178
|
+
*/
|
|
179
|
+
const rewriteDirectiveComments = (source, comments) => {
|
|
180
|
+
let result = source;
|
|
181
|
+
// from the end, so that the offsets of the previous comments stay valid
|
|
182
|
+
for (const comment of comments.toSorted((a, b) => b.start - a.start)) {
|
|
183
|
+
if (comment.type !== "CommentLine" && comment.type !== "CommentBlock") {
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
const replacement = rewriteDirectiveComment(
|
|
187
|
+
/** @type {{ type: "CommentLine" | "CommentBlock"; value: string }} */ (
|
|
188
|
+
comment
|
|
189
|
+
),
|
|
190
|
+
);
|
|
191
|
+
if (replacement === undefined) continue;
|
|
192
|
+
|
|
193
|
+
let start = comment.start;
|
|
194
|
+
let end = comment.end;
|
|
195
|
+
if (replacement === null) {
|
|
196
|
+
// remove the whole line when the comment is alone on it
|
|
197
|
+
const lineStart = result.lastIndexOf("\n", start - 1) + 1;
|
|
198
|
+
const lineEndIndex = result.indexOf("\n", end);
|
|
199
|
+
const lineEnd = lineEndIndex === -1 ? result.length : lineEndIndex;
|
|
200
|
+
const before = result.slice(lineStart, start);
|
|
201
|
+
const after = result.slice(end, lineEnd);
|
|
202
|
+
if (before.trim() === "" && after.trim() === "") {
|
|
203
|
+
start = lineStart;
|
|
204
|
+
end = lineEndIndex === -1 ? lineEnd : lineEnd + 1;
|
|
205
|
+
} else if (before.trim() !== "") {
|
|
206
|
+
// trailing comment: also remove the spaces before it
|
|
207
|
+
start = lineStart + before.trimEnd().length;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
result = result.slice(0, start) + (replacement ?? "") + result.slice(end);
|
|
211
|
+
}
|
|
212
|
+
return result;
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
module.exports = {
|
|
216
|
+
eslintToOxlintRuleNames,
|
|
217
|
+
isRemovedEslintPluginRule,
|
|
218
|
+
rewriteDirectiveComment,
|
|
219
|
+
rewriteDirectiveComments,
|
|
220
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.prependImport = (j, source, importDeclaration) => {
|
|
4
|
+
const existingImports = source.find(j.ImportDeclaration);
|
|
5
|
+
if (existingImports.length > 0) {
|
|
6
|
+
const firstImport = existingImports.at(0);
|
|
7
|
+
const firstImportNode = firstImport.nodes()[0];
|
|
8
|
+
if (firstImportNode?.comments) {
|
|
9
|
+
importDeclaration.comments = firstImportNode.comments;
|
|
10
|
+
firstImportNode.comments = null;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
firstImport.insertBefore(importDeclaration);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const firstNode = source.find(j.Program).get("body", 0).node;
|
|
18
|
+
const { comments } = firstNode;
|
|
19
|
+
if (comments?.length) {
|
|
20
|
+
const comment = comments[0];
|
|
21
|
+
|
|
22
|
+
// Only move comments that look like file-level comments. Ignore
|
|
23
|
+
// line-level and JSDoc-style comments because these probably belong
|
|
24
|
+
// to the first node, rather than the file.
|
|
25
|
+
if (
|
|
26
|
+
(comment.type === "Block" || comment.type === "CommentBlock") &&
|
|
27
|
+
!comment.value.startsWith("*")
|
|
28
|
+
) {
|
|
29
|
+
importDeclaration.comments = comments;
|
|
30
|
+
firstNode.comments = null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
source.get("program", "body").unshift(importDeclaration);
|
|
35
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pob/codemods",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.1",
|
|
4
4
|
"description": "codemods for pob",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"homepage": "https://github.com/christophehurpeau/pob",
|
|
@@ -18,10 +18,9 @@
|
|
|
18
18
|
"pob-migrate": "./bin/migrate.mjs"
|
|
19
19
|
},
|
|
20
20
|
"files": [
|
|
21
|
-
"src",
|
|
22
|
-
"build",
|
|
23
21
|
"bin",
|
|
24
|
-
"lib
|
|
22
|
+
"lib",
|
|
23
|
+
"!lib/**/*.test.js"
|
|
25
24
|
],
|
|
26
25
|
"type": "module",
|
|
27
26
|
"main": "./lib/index.js",
|
|
@@ -33,6 +32,7 @@
|
|
|
33
32
|
"access": "public"
|
|
34
33
|
},
|
|
35
34
|
"dependencies": {
|
|
35
|
+
"@babel/parser": "7.29.9",
|
|
36
36
|
"jscodeshift": "17.4.0"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|