@agilebot/eslint-plugin 0.2.3 → 0.2.4
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/index.d.ts +9 -9
- package/dist/index.js +147 -142
- package/package.json +5 -2
package/dist/index.d.ts
CHANGED
@@ -4,15 +4,15 @@ declare namespace _default {
|
|
4
4
|
namespace recommended {
|
5
5
|
export let plugins: string[];
|
6
6
|
let rules_1: {
|
7
|
-
'@agilebot/react
|
8
|
-
'@agilebot/react
|
9
|
-
'@agilebot/react
|
10
|
-
'@agilebot/tss
|
11
|
-
'@agilebot/tss
|
12
|
-
'@agilebot/tss
|
13
|
-
'@agilebot/import
|
14
|
-
'@agilebot/import
|
15
|
-
'@agilebot/stylistic
|
7
|
+
'@agilebot/react-prefer-named-property-access': string;
|
8
|
+
'@agilebot/react-hook-use-ref': string;
|
9
|
+
'@agilebot/react-prefer-sx-prop': string;
|
10
|
+
'@agilebot/tss-unused-classes': string;
|
11
|
+
'@agilebot/tss-no-color-value': string;
|
12
|
+
'@agilebot/tss-class-naming': string;
|
13
|
+
'@agilebot/import-enforce-icon-alias': string;
|
14
|
+
'@agilebot/import-monorepo': string;
|
15
|
+
'@agilebot/stylistic-no-unnecessary-template-literals': string;
|
16
16
|
};
|
17
17
|
export { rules_1 as rules };
|
18
18
|
export namespace settings {
|
package/dist/index.js
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
/**
|
2
|
+
* @license @agilebot/eslint-plugin v0.2.4
|
3
|
+
*
|
4
|
+
* Copyright (c) Agilebot, Inc. and its affiliates.
|
5
|
+
*
|
6
|
+
* This source code is licensed under the MIT license found in the
|
7
|
+
* LICENSE file in the root directory of this source tree.
|
8
|
+
*/
|
1
9
|
'use strict';
|
2
10
|
|
3
11
|
var fs = require('node:fs');
|
@@ -235,7 +243,7 @@ var idMissing = {
|
|
235
243
|
category: 'Intl',
|
236
244
|
recommended: true
|
237
245
|
},
|
238
|
-
fixable:
|
246
|
+
fixable: undefined,
|
239
247
|
schema: []
|
240
248
|
},
|
241
249
|
create: function (context) {
|
@@ -317,7 +325,7 @@ var idPrefix = {
|
|
317
325
|
category: 'Intl',
|
318
326
|
recommended: true
|
319
327
|
},
|
320
|
-
fixable:
|
328
|
+
fixable: undefined,
|
321
329
|
schema: [
|
322
330
|
{
|
323
331
|
type: 'array',
|
@@ -395,7 +403,7 @@ var idUnused = {
|
|
395
403
|
category: 'Intl',
|
396
404
|
recommended: true
|
397
405
|
},
|
398
|
-
fixable:
|
406
|
+
fixable: undefined,
|
399
407
|
schema: []
|
400
408
|
},
|
401
409
|
create: function (context) {
|
@@ -478,7 +486,7 @@ var noDefault = {
|
|
478
486
|
category: 'Intl',
|
479
487
|
recommended: true
|
480
488
|
},
|
481
|
-
fixable:
|
489
|
+
fixable: undefined,
|
482
490
|
schema: []
|
483
491
|
},
|
484
492
|
create: function (context) {
|
@@ -2083,15 +2091,98 @@ var hookUseRef = {
|
|
2083
2091
|
}))
|
2084
2092
|
};
|
2085
2093
|
|
2086
|
-
|
2094
|
+
function* updateImportStatement(context, fixer, key) {
|
2095
|
+
const sourceCode = context.sourceCode;
|
2096
|
+
const importNode = sourceCode.ast.body.find(
|
2097
|
+
node => node.type === 'ImportDeclaration' && node.source.value === 'react'
|
2098
|
+
);
|
2099
|
+
if (!importNode) {
|
2100
|
+
yield fixer.insertTextBefore(
|
2101
|
+
sourceCode.ast.body[0],
|
2102
|
+
`import { ${key} } from 'react';\n`
|
2103
|
+
);
|
2104
|
+
return;
|
2105
|
+
}
|
2106
|
+
if (
|
2107
|
+
importNode.specifiers.length === 1 &&
|
2108
|
+
importNode.specifiers[0].type === 'ImportDefaultSpecifier'
|
2109
|
+
) {
|
2110
|
+
yield fixer.insertTextAfter(importNode.specifiers[0], `, { ${key} }`);
|
2111
|
+
return;
|
2112
|
+
}
|
2113
|
+
const alreadyImportedKeys = importNode.specifiers
|
2114
|
+
.filter(specifier => specifier.type === 'ImportSpecifier')
|
2115
|
+
.map(specifier => specifier.imported.name);
|
2116
|
+
if (alreadyImportedKeys.includes(key)) {
|
2117
|
+
return;
|
2118
|
+
}
|
2119
|
+
yield fixer.insertTextAfter([...importNode.specifiers].pop(), `, ${key}`);
|
2120
|
+
}
|
2121
|
+
var preferNamedPropertyAccess = utils.ESLintUtils.RuleCreator.withoutDocs({
|
2122
|
+
defaultOptions: [],
|
2123
|
+
meta: {
|
2124
|
+
type: 'layout',
|
2125
|
+
fixable: 'code',
|
2126
|
+
docs: {
|
2127
|
+
description:
|
2128
|
+
'Enforce importing each member of React namespace separately instead of accessing them through React namespace'
|
2129
|
+
},
|
2130
|
+
messages: {
|
2131
|
+
illegalReactPropertyAccess:
|
2132
|
+
'Illegal React property access: {{name}}. Use named import instead.'
|
2133
|
+
},
|
2134
|
+
schema: []
|
2135
|
+
},
|
2136
|
+
create(context) {
|
2137
|
+
return {
|
2138
|
+
TSQualifiedName(node) {
|
2139
|
+
if (
|
2140
|
+
('name' in node.left && node.left.name !== 'React') ||
|
2141
|
+
('name' in node.right && node.right.name.endsWith('Event'))
|
2142
|
+
) {
|
2143
|
+
return;
|
2144
|
+
}
|
2145
|
+
context.report({
|
2146
|
+
node,
|
2147
|
+
messageId: 'illegalReactPropertyAccess',
|
2148
|
+
data: {
|
2149
|
+
name: node.right.name
|
2150
|
+
},
|
2151
|
+
*fix(fixer) {
|
2152
|
+
yield fixer.replaceText(node, node.right.name);
|
2153
|
+
yield* updateImportStatement(context, fixer, node.right.name);
|
2154
|
+
}
|
2155
|
+
});
|
2156
|
+
},
|
2157
|
+
MemberExpression(node) {
|
2158
|
+
if (node.object.name !== 'React') {
|
2159
|
+
return;
|
2160
|
+
}
|
2161
|
+
context.report({
|
2162
|
+
node,
|
2163
|
+
messageId: 'illegalReactPropertyAccess',
|
2164
|
+
data: {
|
2165
|
+
name: node.property.name
|
2166
|
+
},
|
2167
|
+
*fix(fixer) {
|
2168
|
+
yield fixer.replaceText(node, node.property.name);
|
2169
|
+
yield* updateImportStatement(context, fixer, node.property.name);
|
2170
|
+
}
|
2171
|
+
});
|
2172
|
+
}
|
2173
|
+
};
|
2174
|
+
}
|
2175
|
+
});
|
2176
|
+
|
2177
|
+
var preferSxProp = {
|
2087
2178
|
meta: {
|
2088
2179
|
docs: {
|
2089
|
-
description: '
|
2180
|
+
description: 'Prefer using sx prop instead of inline styles',
|
2090
2181
|
category: 'Best Practices',
|
2091
2182
|
recommended: false
|
2092
2183
|
},
|
2093
2184
|
messages: {
|
2094
|
-
|
2185
|
+
preferSxProp:
|
2095
2186
|
'Avoid using inline styles, use sx prop or tss-react or styled-component instead'
|
2096
2187
|
},
|
2097
2188
|
schema: [
|
@@ -2130,7 +2221,7 @@ var noInlineStyles = {
|
|
2130
2221
|
if (prop === 'style') {
|
2131
2222
|
context.report({
|
2132
2223
|
node,
|
2133
|
-
messageId: '
|
2224
|
+
messageId: 'preferSxProp'
|
2134
2225
|
});
|
2135
2226
|
}
|
2136
2227
|
}
|
@@ -2148,7 +2239,7 @@ var noInlineStyles = {
|
|
2148
2239
|
if (prop === 'style') {
|
2149
2240
|
context.report({
|
2150
2241
|
node,
|
2151
|
-
messageId: '
|
2242
|
+
messageId: 'preferSxProp'
|
2152
2243
|
});
|
2153
2244
|
}
|
2154
2245
|
}
|
@@ -2161,88 +2252,40 @@ var noInlineStyles = {
|
|
2161
2252
|
}
|
2162
2253
|
};
|
2163
2254
|
|
2164
|
-
|
2165
|
-
const sourceCode = context.getSourceCode();
|
2166
|
-
const importNode = sourceCode.ast.body.find(
|
2167
|
-
node => node.type === 'ImportDeclaration' && node.source.value === 'react'
|
2168
|
-
);
|
2169
|
-
if (!importNode) {
|
2170
|
-
yield fixer.insertTextBefore(
|
2171
|
-
sourceCode.ast.body[0],
|
2172
|
-
`import { ${key} } from 'react';\n`
|
2173
|
-
);
|
2174
|
-
return;
|
2175
|
-
}
|
2176
|
-
if (
|
2177
|
-
importNode.specifiers.length === 1 &&
|
2178
|
-
importNode.specifiers[0].type === 'ImportDefaultSpecifier'
|
2179
|
-
) {
|
2180
|
-
yield fixer.insertTextAfter(importNode.specifiers[0], `, { ${key} }`);
|
2181
|
-
return;
|
2182
|
-
}
|
2183
|
-
const alreadyImportedKeys = importNode.specifiers
|
2184
|
-
.filter(specifier => specifier.type === 'ImportSpecifier')
|
2185
|
-
.map(specifier => specifier.imported.name);
|
2186
|
-
if (alreadyImportedKeys.includes(key)) {
|
2187
|
-
return;
|
2188
|
-
}
|
2189
|
-
yield fixer.insertTextAfter([...importNode.specifiers].pop(), `, ${key}`);
|
2190
|
-
}
|
2191
|
-
var preferNamedPropertyAccess = utils.ESLintUtils.RuleCreator.withoutDocs({
|
2192
|
-
defaultOptions: [],
|
2255
|
+
var noUnnecessaryTemplateLiterals = {
|
2193
2256
|
meta: {
|
2194
|
-
type: '
|
2195
|
-
fixable: 'code',
|
2257
|
+
type: 'problem',
|
2196
2258
|
docs: {
|
2197
|
-
description:
|
2198
|
-
|
2199
|
-
},
|
2200
|
-
messages: {
|
2201
|
-
illegalReactPropertyAccess:
|
2202
|
-
'Illegal React property access: {{name}}. Use named import instead.'
|
2259
|
+
description: 'Check if a template string contains only one ${}',
|
2260
|
+
recommended: true
|
2203
2261
|
},
|
2262
|
+
fixable: 'code',
|
2204
2263
|
schema: []
|
2205
2264
|
},
|
2206
2265
|
create(context) {
|
2207
2266
|
return {
|
2208
|
-
|
2267
|
+
TemplateLiteral(node) {
|
2268
|
+
const code = context.sourceCode.getText(node);
|
2209
2269
|
if (
|
2210
|
-
('
|
2211
|
-
|
2270
|
+
code.startsWith('`${') &&
|
2271
|
+
code.endsWith('}`') &&
|
2272
|
+
code.split('${').length === 2
|
2212
2273
|
) {
|
2213
|
-
|
2214
|
-
|
2215
|
-
|
2216
|
-
|
2217
|
-
|
2218
|
-
|
2219
|
-
|
2220
|
-
|
2221
|
-
|
2222
|
-
|
2223
|
-
yield* updateImportStatement(context, fixer, node.right.name);
|
2224
|
-
}
|
2225
|
-
});
|
2226
|
-
},
|
2227
|
-
MemberExpression(node) {
|
2228
|
-
if (node.object.name !== 'React') {
|
2229
|
-
return;
|
2274
|
+
context.report({
|
2275
|
+
node,
|
2276
|
+
message: 'Unnecessary template string with only one ${}.',
|
2277
|
+
fix(fixer) {
|
2278
|
+
return fixer.replaceText(
|
2279
|
+
node,
|
2280
|
+
code.substring(3, code.length - 2)
|
2281
|
+
);
|
2282
|
+
}
|
2283
|
+
});
|
2230
2284
|
}
|
2231
|
-
context.report({
|
2232
|
-
node,
|
2233
|
-
messageId: 'illegalReactPropertyAccess',
|
2234
|
-
data: {
|
2235
|
-
name: node.property.name
|
2236
|
-
},
|
2237
|
-
*fix(fixer) {
|
2238
|
-
yield fixer.replaceText(node, node.property.name);
|
2239
|
-
yield* updateImportStatement(context, fixer, node.property.name);
|
2240
|
-
}
|
2241
|
-
});
|
2242
2285
|
}
|
2243
2286
|
};
|
2244
2287
|
}
|
2245
|
-
}
|
2288
|
+
};
|
2246
2289
|
|
2247
2290
|
function getBasicIdentifier(node) {
|
2248
2291
|
if (node.type === 'Identifier') {
|
@@ -2320,9 +2363,6 @@ function getStyesObj(node) {
|
|
2320
2363
|
break;
|
2321
2364
|
}
|
2322
2365
|
}
|
2323
|
-
function isCamelCase(value) {
|
2324
|
-
return /^[a-z][a-zA-Z0-9]*$/.test(value);
|
2325
|
-
}
|
2326
2366
|
|
2327
2367
|
var classNaming = {
|
2328
2368
|
meta: {
|
@@ -2346,7 +2386,7 @@ var classNaming = {
|
|
2346
2386
|
return;
|
2347
2387
|
}
|
2348
2388
|
const className = property.key.value || property.key.name;
|
2349
|
-
if (!isCamelCase(className)) {
|
2389
|
+
if (!eslintUtils.isCamelCase(className)) {
|
2350
2390
|
context.report({
|
2351
2391
|
node: property,
|
2352
2392
|
message: `Class \`${className}\` must be camelCase in TSS.`
|
@@ -2492,63 +2532,28 @@ var unusedClasses = {
|
|
2492
2532
|
}
|
2493
2533
|
};
|
2494
2534
|
|
2495
|
-
var noUnnecessaryTemplateLiterals = {
|
2496
|
-
meta: {
|
2497
|
-
type: 'problem',
|
2498
|
-
docs: {
|
2499
|
-
description: 'Check if a template string contains only one ${}',
|
2500
|
-
recommended: true
|
2501
|
-
},
|
2502
|
-
fixable: 'code',
|
2503
|
-
schema: []
|
2504
|
-
},
|
2505
|
-
create(context) {
|
2506
|
-
return {
|
2507
|
-
TemplateLiteral(node) {
|
2508
|
-
const code = context.sourceCode.getText(node);
|
2509
|
-
if (
|
2510
|
-
code.startsWith('`${') &&
|
2511
|
-
code.endsWith('}`') &&
|
2512
|
-
code.split('${').length === 2
|
2513
|
-
) {
|
2514
|
-
context.report({
|
2515
|
-
node,
|
2516
|
-
message: 'Unnecessary template string with only one ${}.',
|
2517
|
-
fix(fixer) {
|
2518
|
-
return fixer.replaceText(
|
2519
|
-
node,
|
2520
|
-
code.substring(3, code.length - 2)
|
2521
|
-
);
|
2522
|
-
}
|
2523
|
-
});
|
2524
|
-
}
|
2525
|
-
}
|
2526
|
-
};
|
2527
|
-
}
|
2528
|
-
};
|
2529
|
-
|
2530
2535
|
var ruleFiles = /*#__PURE__*/Object.freeze({
|
2531
2536
|
__proto__: null,
|
2532
|
-
|
2533
|
-
|
2534
|
-
|
2535
|
-
|
2536
|
-
|
2537
|
-
|
2538
|
-
|
2539
|
-
|
2540
|
-
|
2541
|
-
|
2542
|
-
|
2543
|
-
|
2544
|
-
|
2545
|
-
|
2537
|
+
rules_import_enforce_icon_alias: enforceIconAlias,
|
2538
|
+
rules_import_monorepo: monorepo,
|
2539
|
+
rules_intl_id_missing: idMissing,
|
2540
|
+
rules_intl_id_prefix: idPrefix,
|
2541
|
+
rules_intl_id_unused: idUnused,
|
2542
|
+
rules_intl_no_default: noDefault,
|
2543
|
+
rules_react_better_exhaustive_deps: betterExhaustiveDeps,
|
2544
|
+
rules_react_hook_use_ref: hookUseRef,
|
2545
|
+
rules_react_prefer_named_property_access: preferNamedPropertyAccess,
|
2546
|
+
rules_react_prefer_sx_prop: preferSxProp,
|
2547
|
+
rules_stylistic_no_unnecessary_template_literals: noUnnecessaryTemplateLiterals,
|
2548
|
+
rules_tss_class_naming: classNaming,
|
2549
|
+
rules_tss_no_color_value: noColorValue,
|
2550
|
+
rules_tss_unused_classes: unusedClasses
|
2546
2551
|
});
|
2547
2552
|
|
2548
2553
|
const rules = {};
|
2549
2554
|
Object.keys(ruleFiles).forEach(key => {
|
2550
|
-
const ruleKey = key.replace(/^
|
2551
|
-
const finalKey = ruleKey.replace(/_
|
2555
|
+
const ruleKey = key.replace(/^rules_/, '');
|
2556
|
+
const finalKey = ruleKey.replace(/_/g, '-');
|
2552
2557
|
rules[finalKey] = ruleFiles[key];
|
2553
2558
|
});
|
2554
2559
|
var index = {
|
@@ -2557,15 +2562,15 @@ var index = {
|
|
2557
2562
|
recommended: {
|
2558
2563
|
plugins: ['@agilebot'],
|
2559
2564
|
rules: {
|
2560
|
-
'@agilebot/react
|
2561
|
-
'@agilebot/react
|
2562
|
-
'@agilebot/react
|
2563
|
-
'@agilebot/tss
|
2564
|
-
'@agilebot/tss
|
2565
|
-
'@agilebot/tss
|
2566
|
-
'@agilebot/import
|
2567
|
-
'@agilebot/import
|
2568
|
-
'@agilebot/stylistic
|
2565
|
+
'@agilebot/react-prefer-named-property-access': 'error',
|
2566
|
+
'@agilebot/react-hook-use-ref': 'warn',
|
2567
|
+
'@agilebot/react-prefer-sx-prop': 'error',
|
2568
|
+
'@agilebot/tss-unused-classes': 'warn',
|
2569
|
+
'@agilebot/tss-no-color-value': 'error',
|
2570
|
+
'@agilebot/tss-class-naming': 'error',
|
2571
|
+
'@agilebot/import-enforce-icon-alias': 'error',
|
2572
|
+
'@agilebot/import-monorepo': 'error',
|
2573
|
+
'@agilebot/stylistic-no-unnecessary-template-literals': 'error'
|
2569
2574
|
},
|
2570
2575
|
settings: {
|
2571
2576
|
react: {
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@agilebot/eslint-plugin",
|
3
|
-
"version": "0.2.
|
3
|
+
"version": "0.2.4",
|
4
4
|
"description": "Agilebot's ESLint plugin",
|
5
5
|
"main": "dist/index.js",
|
6
6
|
"types": "dist/index.d.ts",
|
@@ -20,7 +20,7 @@
|
|
20
20
|
"dependencies": {
|
21
21
|
"@typescript-eslint/utils": "^7.6.0",
|
22
22
|
"eslint-plugin-react": "^7.34.1",
|
23
|
-
"@agilebot/eslint-utils": "0.2.
|
23
|
+
"@agilebot/eslint-utils": "0.2.4"
|
24
24
|
},
|
25
25
|
"peerDependencies": {
|
26
26
|
"eslint": "^7.0.0 || ^8.0.0"
|
@@ -28,6 +28,9 @@
|
|
28
28
|
"files": [
|
29
29
|
"dist"
|
30
30
|
],
|
31
|
+
"devDependencies": {
|
32
|
+
"@types/estree": "^1.0.5"
|
33
|
+
},
|
31
34
|
"scripts": {
|
32
35
|
"build": "rollup -c rollup.config.mjs && nr dts",
|
33
36
|
"dts": "tsc -p tsconfig.dts.json",
|