@agilebot/eslint-plugin 0.2.3 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
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/prefer-named-property-access': string;
8
- '@agilebot/react/hook-use-ref': string;
9
- '@agilebot/react/no-inline-styles': 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;
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.5
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: null,
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: null,
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: null,
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: null,
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
- var noInlineStyles = {
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: 'Disallow style props on components and DOM Nodes',
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
- disallowInlineStyles:
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: 'disallowInlineStyles'
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: 'disallowInlineStyles'
2242
+ messageId: 'preferSxProp'
2152
2243
  });
2153
2244
  }
2154
2245
  }
@@ -2161,88 +2252,40 @@ var noInlineStyles = {
2161
2252
  }
2162
2253
  };
2163
2254
 
2164
- function* updateImportStatement(context, fixer, key) {
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: 'layout',
2195
- fixable: 'code',
2257
+ type: 'problem',
2196
2258
  docs: {
2197
- description:
2198
- 'Enforce importing each member of React namespace separately instead of accessing them through React namespace'
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
- TSQualifiedName(node) {
2267
+ TemplateLiteral(node) {
2268
+ const code = context.sourceCode.getText(node);
2209
2269
  if (
2210
- ('name' in node.left && node.left.name !== 'React') ||
2211
- ('name' in node.right && node.right.name.endsWith('Event'))
2270
+ code.startsWith('`${') &&
2271
+ code.endsWith('}`') &&
2272
+ code.split('${').length === 2
2212
2273
  ) {
2213
- return;
2214
- }
2215
- context.report({
2216
- node,
2217
- messageId: 'illegalReactPropertyAccess',
2218
- data: {
2219
- name: node.right.name
2220
- },
2221
- *fix(fixer) {
2222
- yield fixer.replaceText(node, node.right.name);
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
- src_rules_import_enforce_icon_alias: enforceIconAlias,
2533
- src_rules_import_monorepo: monorepo,
2534
- src_rules_intl_id_missing: idMissing,
2535
- src_rules_intl_id_prefix: idPrefix,
2536
- src_rules_intl_id_unused: idUnused,
2537
- src_rules_intl_no_default: noDefault,
2538
- src_rules_react_better_exhaustive_deps: betterExhaustiveDeps,
2539
- src_rules_react_hook_use_ref: hookUseRef,
2540
- src_rules_react_no_inline_styles: noInlineStyles,
2541
- src_rules_react_prefer_named_property_access: preferNamedPropertyAccess,
2542
- src_rules_stylistic_no_unnecessary_template_literals: noUnnecessaryTemplateLiterals,
2543
- src_rules_tss_class_naming: classNaming,
2544
- src_rules_tss_no_color_value: noColorValue,
2545
- src_rules_tss_unused_classes: unusedClasses
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(/^src_rules_/, '');
2551
- const finalKey = ruleKey.replace(/_/, '/').replace(/_/g, '-');
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/prefer-named-property-access': 'error',
2561
- '@agilebot/react/hook-use-ref': 'warn',
2562
- '@agilebot/react/no-inline-styles': 'error',
2563
- '@agilebot/tss/unused-classes': 'warn',
2564
- '@agilebot/tss/no-color-value': 'error',
2565
- '@agilebot/tss/class-naming': 'error',
2566
- '@agilebot/import/enforce-icon-alias': 'error',
2567
- '@agilebot/import/monorepo': 'error',
2568
- '@agilebot/stylistic/no-unnecessary-template-literals': 'error'
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",
3
+ "version": "0.2.5",
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.3"
23
+ "@agilebot/eslint-utils": "0.2.5"
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",