@agilebot/eslint-plugin 0.2.3 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/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.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: 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.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.3"
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",