@agilebot/eslint-plugin 0.3.2 → 0.3.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
@@ -1,20 +1,10 @@
1
- declare namespace _default {
2
- export { rules };
3
- export namespace configs {
1
+ export default plugin;
2
+ declare namespace plugin {
3
+ let rules: import('eslint').Linter.RulesRecord;
4
+ namespace configs {
4
5
  namespace recommended {
5
6
  export let plugins: string[];
6
- let rules_1: {
7
- '@agilebot/no-unnecessary-template-literals': string;
8
- '@agilebot/no-async-array-methods': string;
9
- '@agilebot/react-prefer-named-property-access': string;
10
- '@agilebot/react-hook-use-ref': string;
11
- '@agilebot/react-prefer-sx-prop': string;
12
- '@agilebot/tss-unused-classes': string;
13
- '@agilebot/tss-no-color-value': string;
14
- '@agilebot/tss-class-naming': string;
15
- '@agilebot/import-enforce-icon-alias': string;
16
- '@agilebot/import-monorepo': string;
17
- };
7
+ let rules_1: import('eslint').Linter.RulesRecord;
18
8
  export { rules_1 as rules };
19
9
  export namespace settings {
20
10
  namespace react {
@@ -24,8 +14,3 @@ declare namespace _default {
24
14
  }
25
15
  }
26
16
  }
27
- export default _default;
28
- /**
29
- * @type {import('eslint').Linter.RulesRecord}
30
- */
31
- declare const rules: import('eslint').Linter.RulesRecord;
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license @agilebot/eslint-plugin v0.3.2
2
+ * @license @agilebot/eslint-plugin v0.3.4
3
3
  *
4
4
  * Copyright (c) Agilebot, Inc. and its affiliates.
5
5
  *
@@ -41,7 +41,10 @@ var enforceIconAlias = {
41
41
  recommended: true
42
42
  },
43
43
  fixable: 'code',
44
- schema: []
44
+ schema: [],
45
+ messages: {
46
+ iconAlias: 'Import for {{ name }} should be aliased.'
47
+ }
45
48
  },
46
49
  create(context) {
47
50
  return {
@@ -59,7 +62,10 @@ var enforceIconAlias = {
59
62
  if (specifier.imported.name === specifier.local.name) {
60
63
  context.report({
61
64
  node,
62
- message: `Import for ${node.source.value} should be aliased.`,
65
+ messageId: 'iconAlias',
66
+ data: {
67
+ name: node.source.value
68
+ },
63
69
  fix: fixer =>
64
70
  fixer.replaceText(
65
71
  specifier,
@@ -86,7 +92,10 @@ var monorepo = {
86
92
  recommended: true
87
93
  },
88
94
  fixable: 'code',
89
- schema: []
95
+ schema: [],
96
+ messages: {
97
+ monorepoImport: 'Import for {{ module }} should not contains src folder.'
98
+ }
90
99
  },
91
100
  create(context) {
92
101
  return {
@@ -110,7 +119,10 @@ var monorepo = {
110
119
  if (values[2] === 'src') {
111
120
  context.report({
112
121
  node,
113
- message: `Import for ${node.source.value} should not contains src folder.`,
122
+ messageId: 'monorepoImport',
123
+ data: {
124
+ module: node.source.value
125
+ },
114
126
  fix: fixer => {
115
127
  const correctedPath = values
116
128
  .filter((_, index) => index !== 2)
@@ -240,8 +252,7 @@ var idMissing = {
240
252
  meta: {
241
253
  docs: {
242
254
  description: 'Validates intl message ids are in locale file',
243
- category: 'Intl',
244
- recommended: true
255
+ category: 'Intl'
245
256
  },
246
257
  fixable: undefined,
247
258
  schema: []
@@ -322,8 +333,7 @@ var idPrefix = {
322
333
  meta: {
323
334
  docs: {
324
335
  description: 'Validates intl message ids has correct prefixes',
325
- category: 'Intl',
326
- recommended: true
336
+ category: 'Intl'
327
337
  },
328
338
  fixable: undefined,
329
339
  schema: [
@@ -400,8 +410,7 @@ var idUnused = {
400
410
  meta: {
401
411
  docs: {
402
412
  description: 'Finds unused intl message ids in locale file',
403
- category: 'Intl',
404
- recommended: true
413
+ category: 'Intl'
405
414
  },
406
415
  fixable: undefined,
407
416
  schema: []
@@ -483,8 +492,7 @@ var noDefault = {
483
492
  meta: {
484
493
  docs: {
485
494
  description: 'Validates defaultMessage is not used with react-intl',
486
- category: 'Intl',
487
- recommended: true
495
+ category: 'Intl'
488
496
  },
489
497
  fixable: undefined,
490
498
  schema: []
@@ -521,258 +529,12 @@ var noDefault = {
521
529
  }
522
530
  };
523
531
 
524
- function getBasicIdentifier(node) {
525
- if (node.type === 'Identifier') {
526
- return node.name;
527
- }
528
- if (node.type === 'Literal') {
529
- return node.value;
530
- }
531
- if (node.type === 'TemplateLiteral') {
532
- if (node.expressions.length > 0) {
533
- return null;
534
- }
535
- return node.quasis[0].value.raw;
536
- }
537
- return null;
538
- }
539
- function getBaseIdentifier(node) {
540
- switch (node.type) {
541
- case 'Identifier': {
542
- return node;
543
- }
544
- case 'CallExpression': {
545
- return getBaseIdentifier(node.callee);
546
- }
547
- case 'MemberExpression': {
548
- return getBaseIdentifier(node.object);
549
- }
550
- }
551
- return null;
552
- }
553
- function getStyesObj(node) {
554
- const isMakeStyles = node.callee.name === 'makeStyles';
555
- const isModernApi =
556
- node.callee.type === 'MemberExpression' &&
557
- node.callee.property.name === 'create' &&
558
- getBaseIdentifier(node.callee.object) &&
559
- getBaseIdentifier(node.callee.object).name === 'tss';
560
- if (!isMakeStyles && !isModernApi) {
561
- return;
562
- }
563
- const styles = (() => {
564
- if (isMakeStyles) {
565
- return node.parent.arguments[0];
566
- }
567
- if (isModernApi) {
568
- return node.callee.parent.arguments[0];
569
- }
570
- })();
571
- if (!styles) {
572
- return;
573
- }
574
- switch (styles.type) {
575
- case 'ObjectExpression':
576
- return styles;
577
- case 'ArrowFunctionExpression':
578
- {
579
- const { body } = styles;
580
- switch (body.type) {
581
- case 'ObjectExpression':
582
- return body;
583
- case 'BlockStatement': {
584
- let stylesObj;
585
- body.body.forEach(bodyNode => {
586
- if (
587
- bodyNode.type === 'ReturnStatement' &&
588
- bodyNode.argument.type === 'ObjectExpression'
589
- ) {
590
- stylesObj = bodyNode.argument;
591
- }
592
- });
593
- return stylesObj;
594
- }
595
- }
596
- }
597
- break;
598
- }
599
- }
600
-
601
- var classNaming = {
602
- meta: {
603
- type: 'problem'
604
- },
605
- create: function rule(context) {
606
- return {
607
- CallExpression(node) {
608
- const stylesObj = getStyesObj(node);
609
- if (stylesObj === undefined) {
610
- return;
611
- }
612
- stylesObj.properties.forEach(property => {
613
- if (property.computed) {
614
- return;
615
- }
616
- if (
617
- property.type === 'ExperimentalSpreadProperty' ||
618
- property.type === 'SpreadElement'
619
- ) {
620
- return;
621
- }
622
- const className = property.key.value || property.key.name;
623
- if (!eslintUtils.isCamelCase(className)) {
624
- context.report({
625
- node: property,
626
- message: `Class \`${className}\` must be camelCase in TSS.`
627
- });
628
- }
629
- });
630
- }
631
- };
632
- }
633
- };
634
-
635
- var noColorValue = {
636
- meta: {
637
- type: 'problem',
638
- docs: {
639
- description:
640
- 'Enforce the use of color variables instead of color codes within TSS'
641
- }
642
- },
643
- create: function (context) {
644
- const parserOptions = context.parserOptions;
645
- if (!parserOptions || !parserOptions.project) {
646
- return {};
647
- }
648
- return {
649
- CallExpression(node) {
650
- const stylesObj = getStyesObj(node);
651
- if (!stylesObj) {
652
- return;
653
- }
654
- function checkColorLiteral(value) {
655
- if (value.type === 'Literal' && typeof value.value === 'string') {
656
- const colorCodePattern =
657
- /#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\?\(\s*(\d{1,3}\s*,\s*){2}\d{1,3}(?:\s*,\s*\d*(?:\.\d+)?)?\s*\)/g;
658
- const isColorCode = colorCodePattern.test(value.value);
659
- if (isColorCode) {
660
- context.report({
661
- node: value,
662
- message: 'Use color variables instead of color codes in TSS.'
663
- });
664
- }
665
- }
666
- }
667
- function loopStylesObj(obj) {
668
- if (obj && obj.type === 'ObjectExpression') {
669
- obj.properties.forEach(property => {
670
- if (property.type === 'Property' && property.value) {
671
- if (property.value.type === 'ObjectExpression') {
672
- loopStylesObj(property.value);
673
- } else {
674
- checkColorLiteral(property.value);
675
- }
676
- }
677
- });
678
- }
679
- }
680
- loopStylesObj(stylesObj);
681
- }
682
- };
683
- }
684
- };
685
-
686
- var unusedClasses = {
687
- meta: {
688
- type: 'problem'
689
- },
690
- create: function rule(context) {
691
- const usedClasses = {};
692
- const definedClasses = {};
693
- return {
694
- CallExpression(node) {
695
- const stylesObj = getStyesObj(node);
696
- if (stylesObj === undefined) {
697
- return;
698
- }
699
- stylesObj.properties.forEach(property => {
700
- if (property.computed) {
701
- return;
702
- }
703
- if (
704
- property.type === 'ExperimentalSpreadProperty' ||
705
- property.type === 'SpreadElement'
706
- ) {
707
- return;
708
- }
709
- definedClasses[property.key.value || property.key.name] = property;
710
- });
711
- },
712
- MemberExpression(node) {
713
- if (
714
- node.object.type === 'Identifier' &&
715
- node.object.name === 'classes'
716
- ) {
717
- const whichClass = getBasicIdentifier(node.property);
718
- if (whichClass) {
719
- usedClasses[whichClass] = true;
720
- }
721
- return;
722
- }
723
- const classIdentifier = getBasicIdentifier(node.property);
724
- if (!classIdentifier) {
725
- return;
726
- }
727
- if (classIdentifier !== 'classes') {
728
- return;
729
- }
730
- const { parent } = node;
731
- if (parent.type !== 'MemberExpression') {
732
- return;
733
- }
734
- if (
735
- node.object.object &&
736
- node.object.object.type !== 'ThisExpression'
737
- ) {
738
- return;
739
- }
740
- const propsIdentifier = getBasicIdentifier(parent.object);
741
- if (propsIdentifier && propsIdentifier !== 'props') {
742
- return;
743
- }
744
- if (!propsIdentifier && parent.object.type !== 'MemberExpression') {
745
- return;
746
- }
747
- if (parent.parent.type === 'MemberExpression') {
748
- return;
749
- }
750
- const parentClassIdentifier = getBasicIdentifier(parent.property);
751
- if (parentClassIdentifier) {
752
- usedClasses[parentClassIdentifier] = true;
753
- }
754
- },
755
- 'Program:exit': () => {
756
- Object.keys(definedClasses).forEach(definedClassKey => {
757
- if (!usedClasses[definedClassKey]) {
758
- context.report({
759
- node: definedClasses[definedClassKey],
760
- message: `Class \`${definedClassKey}\` is unused`
761
- });
762
- }
763
- });
764
- }
765
- };
766
- }
767
- };
768
-
769
532
  var betterExhaustiveDeps = {
770
533
  meta: {
771
534
  type: 'suggestion',
772
535
  docs: {
773
536
  description:
774
537
  'verifies the list of dependencies for Hooks like useEffect and similar',
775
- recommended: true,
776
538
  url: 'https://github.com/facebook/react/issues/14920'
777
539
  },
778
540
  fixable: 'code',
@@ -2309,7 +2071,7 @@ var hookUseRef = {
2309
2071
  meta: {
2310
2072
  docs: {
2311
2073
  description: 'Ensure naming of useRef hook value.',
2312
- recommended: false
2074
+ recommended: true
2313
2075
  },
2314
2076
  schema: [],
2315
2077
  type: 'suggestion',
@@ -2370,7 +2132,8 @@ var preferNamedPropertyAccess = utils.ESLintUtils.RuleCreator.withoutDocs({
2370
2132
  fixable: 'code',
2371
2133
  docs: {
2372
2134
  description:
2373
- 'Enforce importing each member of React namespace separately instead of accessing them through React namespace'
2135
+ 'Enforce importing each member of React namespace separately instead of accessing them through React namespace',
2136
+ recommended: 'recommended'
2374
2137
  },
2375
2138
  messages: {
2376
2139
  illegalReactPropertyAccess:
@@ -2424,7 +2187,7 @@ var preferSxProp = {
2424
2187
  docs: {
2425
2188
  description: 'Prefer using sx prop instead of inline styles',
2426
2189
  category: 'Best Practices',
2427
- recommended: false
2190
+ recommended: true
2428
2191
  },
2429
2192
  messages: {
2430
2193
  preferSxProp:
@@ -2497,6 +2260,262 @@ var preferSxProp = {
2497
2260
  }
2498
2261
  };
2499
2262
 
2263
+ function getBasicIdentifier(node) {
2264
+ if (node.type === 'Identifier') {
2265
+ return node.name;
2266
+ }
2267
+ if (node.type === 'Literal') {
2268
+ return node.value;
2269
+ }
2270
+ if (node.type === 'TemplateLiteral') {
2271
+ if (node.expressions.length > 0) {
2272
+ return null;
2273
+ }
2274
+ return node.quasis[0].value.raw;
2275
+ }
2276
+ return null;
2277
+ }
2278
+ function getBaseIdentifier(node) {
2279
+ switch (node.type) {
2280
+ case 'Identifier': {
2281
+ return node;
2282
+ }
2283
+ case 'CallExpression': {
2284
+ return getBaseIdentifier(node.callee);
2285
+ }
2286
+ case 'MemberExpression': {
2287
+ return getBaseIdentifier(node.object);
2288
+ }
2289
+ }
2290
+ return null;
2291
+ }
2292
+ function getStyesObj(node) {
2293
+ const isMakeStyles = node.callee.name === 'makeStyles';
2294
+ const isModernApi =
2295
+ node.callee.type === 'MemberExpression' &&
2296
+ node.callee.property.name === 'create' &&
2297
+ getBaseIdentifier(node.callee.object) &&
2298
+ getBaseIdentifier(node.callee.object).name === 'tss';
2299
+ if (!isMakeStyles && !isModernApi) {
2300
+ return;
2301
+ }
2302
+ const styles = (() => {
2303
+ if (isMakeStyles) {
2304
+ return node.parent.arguments[0];
2305
+ }
2306
+ if (isModernApi) {
2307
+ return node.callee.parent.arguments[0];
2308
+ }
2309
+ })();
2310
+ if (!styles) {
2311
+ return;
2312
+ }
2313
+ switch (styles.type) {
2314
+ case 'ObjectExpression':
2315
+ return styles;
2316
+ case 'ArrowFunctionExpression':
2317
+ {
2318
+ const { body } = styles;
2319
+ switch (body.type) {
2320
+ case 'ObjectExpression':
2321
+ return body;
2322
+ case 'BlockStatement': {
2323
+ let stylesObj;
2324
+ body.body.forEach(bodyNode => {
2325
+ if (
2326
+ bodyNode.type === 'ReturnStatement' &&
2327
+ bodyNode.argument.type === 'ObjectExpression'
2328
+ ) {
2329
+ stylesObj = bodyNode.argument;
2330
+ }
2331
+ });
2332
+ return stylesObj;
2333
+ }
2334
+ }
2335
+ }
2336
+ break;
2337
+ }
2338
+ }
2339
+
2340
+ var classNaming = {
2341
+ meta: {
2342
+ type: 'problem',
2343
+ docs: {
2344
+ description: 'Enforce camelCase class names in TSS',
2345
+ category: 'Best Practices',
2346
+ recommended: true
2347
+ }
2348
+ },
2349
+ create: function rule(context) {
2350
+ return {
2351
+ CallExpression(node) {
2352
+ const stylesObj = getStyesObj(node);
2353
+ if (stylesObj === undefined) {
2354
+ return;
2355
+ }
2356
+ stylesObj.properties.forEach(property => {
2357
+ if (property.computed) {
2358
+ return;
2359
+ }
2360
+ if (
2361
+ property.type === 'ExperimentalSpreadProperty' ||
2362
+ property.type === 'SpreadElement'
2363
+ ) {
2364
+ return;
2365
+ }
2366
+ const className = property.key.value || property.key.name;
2367
+ if (!eslintUtils.isCamelCase(className)) {
2368
+ context.report({
2369
+ node: property,
2370
+ message: `Class \`${className}\` must be camelCase in TSS.`
2371
+ });
2372
+ }
2373
+ });
2374
+ }
2375
+ };
2376
+ }
2377
+ };
2378
+
2379
+ var noColorValue = {
2380
+ meta: {
2381
+ type: 'problem',
2382
+ docs: {
2383
+ description:
2384
+ 'Enforce the use of color variables instead of color codes within TSS',
2385
+ recommended: true
2386
+ }
2387
+ },
2388
+ create: function (context) {
2389
+ const parserOptions = context.parserOptions;
2390
+ if (!parserOptions || !parserOptions.project) {
2391
+ return {};
2392
+ }
2393
+ return {
2394
+ CallExpression(node) {
2395
+ const stylesObj = getStyesObj(node);
2396
+ if (!stylesObj) {
2397
+ return;
2398
+ }
2399
+ function checkColorLiteral(value) {
2400
+ if (value.type === 'Literal' && typeof value.value === 'string') {
2401
+ const colorCodePattern =
2402
+ /#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\?\(\s*(\d{1,3}\s*,\s*){2}\d{1,3}(?:\s*,\s*\d*(?:\.\d+)?)?\s*\)/g;
2403
+ const isColorCode = colorCodePattern.test(value.value);
2404
+ if (isColorCode) {
2405
+ context.report({
2406
+ node: value,
2407
+ message: 'Use color variables instead of color codes in TSS.'
2408
+ });
2409
+ }
2410
+ }
2411
+ }
2412
+ function loopStylesObj(obj) {
2413
+ if (obj && obj.type === 'ObjectExpression') {
2414
+ obj.properties.forEach(property => {
2415
+ if (property.type === 'Property' && property.value) {
2416
+ if (property.value.type === 'ObjectExpression') {
2417
+ loopStylesObj(property.value);
2418
+ } else {
2419
+ checkColorLiteral(property.value);
2420
+ }
2421
+ }
2422
+ });
2423
+ }
2424
+ }
2425
+ loopStylesObj(stylesObj);
2426
+ }
2427
+ };
2428
+ }
2429
+ };
2430
+
2431
+ var unusedClasses = {
2432
+ meta: {
2433
+ type: 'suggestion',
2434
+ docs: {
2435
+ description: 'Disallow unused classes in tss',
2436
+ category: 'Best Practices',
2437
+ recommended: true
2438
+ }
2439
+ },
2440
+ create: function rule(context) {
2441
+ const usedClasses = {};
2442
+ const definedClasses = {};
2443
+ return {
2444
+ CallExpression(node) {
2445
+ const stylesObj = getStyesObj(node);
2446
+ if (stylesObj === undefined) {
2447
+ return;
2448
+ }
2449
+ stylesObj.properties.forEach(property => {
2450
+ if (property.computed) {
2451
+ return;
2452
+ }
2453
+ if (
2454
+ property.type === 'ExperimentalSpreadProperty' ||
2455
+ property.type === 'SpreadElement'
2456
+ ) {
2457
+ return;
2458
+ }
2459
+ definedClasses[property.key.value || property.key.name] = property;
2460
+ });
2461
+ },
2462
+ MemberExpression(node) {
2463
+ if (
2464
+ node.object.type === 'Identifier' &&
2465
+ node.object.name === 'classes'
2466
+ ) {
2467
+ const whichClass = getBasicIdentifier(node.property);
2468
+ if (whichClass) {
2469
+ usedClasses[whichClass] = true;
2470
+ }
2471
+ return;
2472
+ }
2473
+ const classIdentifier = getBasicIdentifier(node.property);
2474
+ if (!classIdentifier) {
2475
+ return;
2476
+ }
2477
+ if (classIdentifier !== 'classes') {
2478
+ return;
2479
+ }
2480
+ const { parent } = node;
2481
+ if (parent.type !== 'MemberExpression') {
2482
+ return;
2483
+ }
2484
+ if (
2485
+ node.object.object &&
2486
+ node.object.object.type !== 'ThisExpression'
2487
+ ) {
2488
+ return;
2489
+ }
2490
+ const propsIdentifier = getBasicIdentifier(parent.object);
2491
+ if (propsIdentifier && propsIdentifier !== 'props') {
2492
+ return;
2493
+ }
2494
+ if (!propsIdentifier && parent.object.type !== 'MemberExpression') {
2495
+ return;
2496
+ }
2497
+ if (parent.parent.type === 'MemberExpression') {
2498
+ return;
2499
+ }
2500
+ const parentClassIdentifier = getBasicIdentifier(parent.property);
2501
+ if (parentClassIdentifier) {
2502
+ usedClasses[parentClassIdentifier] = true;
2503
+ }
2504
+ },
2505
+ 'Program:exit': () => {
2506
+ Object.keys(definedClasses).forEach(definedClassKey => {
2507
+ if (!usedClasses[definedClassKey]) {
2508
+ context.report({
2509
+ node: definedClasses[definedClassKey],
2510
+ message: `Class \`${definedClassKey}\` is unused`
2511
+ });
2512
+ }
2513
+ });
2514
+ }
2515
+ };
2516
+ }
2517
+ };
2518
+
2500
2519
  var noAsyncArrayMethods = {
2501
2520
  meta: {
2502
2521
  docs: {
@@ -2547,6 +2566,70 @@ var noAsyncArrayMethods = {
2547
2566
  }
2548
2567
  };
2549
2568
 
2569
+ var noThenCatchFinally = {
2570
+ meta: {
2571
+ type: 'suggestion',
2572
+ docs: {
2573
+ description:
2574
+ 'Disallow the use of then()/catch()/finally() when invoking specific functions.'
2575
+ },
2576
+ schema: [
2577
+ {
2578
+ type: 'object',
2579
+ properties: {
2580
+ restrictedFunctions: {
2581
+ type: 'array',
2582
+ uniqueItems: true,
2583
+ items: { type: 'string' }
2584
+ }
2585
+ }
2586
+ }
2587
+ ],
2588
+ messages: {
2589
+ forbiddenThenCatchFinally: `then()/catch()/finally() is forbidden when invoke {{ name }}().`
2590
+ }
2591
+ },
2592
+ create(context) {
2593
+ const configuration = context.options[0] || {};
2594
+ const restrictedFunctions = configuration.restrictedFunctions || [];
2595
+ function isTopLevelScoped() {
2596
+ return context.getScope().block.type === 'Program';
2597
+ }
2598
+ function isThenCatchFinally(node) {
2599
+ return (
2600
+ node.property &&
2601
+ (node.property.name === 'then' ||
2602
+ node.property.name === 'catch' ||
2603
+ node.property.name === 'finally')
2604
+ );
2605
+ }
2606
+ return {
2607
+ 'CallExpression > MemberExpression.callee'(node) {
2608
+ if (isTopLevelScoped()) {
2609
+ return;
2610
+ }
2611
+ if (!isThenCatchFinally(node)) {
2612
+ return;
2613
+ }
2614
+ const callExpression = node.object;
2615
+ if (
2616
+ callExpression.type === 'CallExpression' &&
2617
+ callExpression.callee.type === 'Identifier' &&
2618
+ restrictedFunctions.includes(callExpression.callee.name)
2619
+ ) {
2620
+ context.report({
2621
+ node: node.property,
2622
+ messageId: 'forbiddenThenCatchFinally',
2623
+ data: {
2624
+ name: callExpression.callee.name
2625
+ }
2626
+ });
2627
+ }
2628
+ }
2629
+ };
2630
+ }
2631
+ };
2632
+
2550
2633
  var noUnnecessaryTemplateLiterals = {
2551
2634
  meta: {
2552
2635
  type: 'problem',
@@ -2555,7 +2638,11 @@ var noUnnecessaryTemplateLiterals = {
2555
2638
  recommended: true
2556
2639
  },
2557
2640
  fixable: 'code',
2558
- schema: []
2641
+ schema: [],
2642
+ messages: {
2643
+ unnecessaryTemplateString:
2644
+ 'Unnecessary template string with only one ${}.'
2645
+ }
2559
2646
  },
2560
2647
  create(context) {
2561
2648
  return {
@@ -2568,7 +2655,7 @@ var noUnnecessaryTemplateLiterals = {
2568
2655
  ) {
2569
2656
  context.report({
2570
2657
  node,
2571
- message: 'Unnecessary template string with only one ${}.',
2658
+ messageId: 'unnecessaryTemplateString',
2572
2659
  fix(fixer) {
2573
2660
  return fixer.replaceText(
2574
2661
  node,
@@ -2598,32 +2685,16 @@ var ruleFiles = /*#__PURE__*/Object.freeze({
2598
2685
  rules_tss_no_color_value: noColorValue,
2599
2686
  rules_tss_unused_classes: unusedClasses,
2600
2687
  rules_unprefixed_no_async_array_methods: noAsyncArrayMethods,
2688
+ rules_unprefixed_no_then_catch_finally: noThenCatchFinally,
2601
2689
  rules_unprefixed_no_unnecessary_template_literals: noUnnecessaryTemplateLiterals
2602
2690
  });
2603
2691
 
2604
- const rules = {};
2605
- Object.keys(ruleFiles).forEach(key => {
2606
- const ruleKey = key.replace(/^rules_/, '').replace(/^unprefixed_/, '');
2607
- const finalKey = ruleKey.replace(/_/g, '-');
2608
- rules[finalKey] = ruleFiles[key];
2609
- });
2610
- var index = {
2611
- rules,
2692
+ const plugin = {
2693
+ rules: {},
2612
2694
  configs: {
2613
2695
  recommended: {
2614
2696
  plugins: ['@agilebot'],
2615
- rules: {
2616
- '@agilebot/no-unnecessary-template-literals': 'error',
2617
- '@agilebot/no-async-array-methods': 'error',
2618
- '@agilebot/react-prefer-named-property-access': 'error',
2619
- '@agilebot/react-hook-use-ref': 'warn',
2620
- '@agilebot/react-prefer-sx-prop': 'error',
2621
- '@agilebot/tss-unused-classes': 'warn',
2622
- '@agilebot/tss-no-color-value': 'error',
2623
- '@agilebot/tss-class-naming': 'error',
2624
- '@agilebot/import-enforce-icon-alias': 'error',
2625
- '@agilebot/import-monorepo': 'error'
2626
- },
2697
+ rules: {},
2627
2698
  settings: {
2628
2699
  react: {
2629
2700
  version: '18.0.0'
@@ -2632,5 +2703,15 @@ var index = {
2632
2703
  }
2633
2704
  }
2634
2705
  };
2706
+ Object.keys(ruleFiles).forEach(key => {
2707
+ const ruleKey = key.replace(/^rules_/, '').replace(/^unprefixed_/, '');
2708
+ const finalKey = ruleKey.replace(/_/g, '-');
2709
+ const rule = ruleFiles[key];
2710
+ plugin.rules[finalKey] = rule;
2711
+ if (rule.meta && rule.meta.docs && rule.meta.docs.recommended) {
2712
+ plugin.configs.recommended.rules[`@agilebot/${finalKey}`] =
2713
+ rule.meta.type === 'suggestion' ? 'warn' : 'error';
2714
+ }
2715
+ });
2635
2716
 
2636
- module.exports = index;
2717
+ module.exports = plugin;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agilebot/eslint-plugin",
3
- "version": "0.3.2",
3
+ "version": "0.3.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.7.0",
22
22
  "eslint-plugin-react": "^7.34.1",
23
- "@agilebot/eslint-utils": "0.3.2"
23
+ "@agilebot/eslint-utils": "0.3.4"
24
24
  },
25
25
  "peerDependencies": {
26
26
  "eslint": "^7.0.0 || ^8.0.0"
@@ -29,7 +29,8 @@
29
29
  "dist"
30
30
  ],
31
31
  "devDependencies": {
32
- "@types/estree": "^1.0.5"
32
+ "@types/estree": "^1.0.5",
33
+ "eslint-vitest-rule-tester": "^0.3.2"
33
34
  },
34
35
  "scripts": {
35
36
  "build": "rollup -c rollup.config.mjs && nr dts",