@arcgis/eslint-config 5.2.0-next.6 → 5.2.0-next.60

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.
@@ -1,4 +1,4 @@
1
- import { m as makeEslintPlugin } from "../../makePlugin-CsjR4Cb9.js";
1
+ import { m as makeEslintPlugin } from "../../makePlugin-MXVxg4Ss.js";
2
2
  import { TSESTree, AST_TOKEN_TYPES, AST_NODE_TYPES, TSESLint } from "@typescript-eslint/utils";
3
3
  import path from "node:path";
4
4
  import { resolve } from "path/posix";
@@ -27,7 +27,8 @@ plugin.createRule({
27
27
  // Disabled by default because the rule is most relevant for autocasting
28
28
  // and only on public classes. We are discouraging autocasting in new
29
29
  // code.
30
- defaultLevel: "off"
30
+ defaultLevel: "off",
31
+ isTypeChecked: false
31
32
  },
32
33
  messages: {
33
34
  name: `By convention, the first parameter on an Accessor-based class must be called "properties". This is needed for autocasting - https://webgis.esri.com/references/api-extractor/api-node-kinds#constructor. If your class has constructors overloads, at least one of them must have a "properties" parameter.`,
@@ -77,7 +78,8 @@ If you wish to use a loose type like any/object, create a type alias \`type {{ e
77
78
  return;
78
79
  }
79
80
  const extendsText = node.superClass ? context.sourceCode.getText(node.superClass) : "";
80
- const isCollectionClass = extendsText.includes("Collection.ofType") || extendsText.includes("(Collection)") || extendsText === "Collection" || extendsText === "OwningCollection" || context.filename.endsWith(`esri${path.sep}core${path.sep}Collection.ts`);
81
+ const isCollectionClass = extendsText.includes("Collection.ofType") || extendsText.includes("(Collection)") || extendsText === "Collection" || extendsText === "OwningCollection" || // TODO: drop the esri/ case once core is in the monorepo
82
+ context.filename.endsWith(`esri${path.sep}core${path.sep}Collection.ts`) || context.filename.endsWith(`src${path.sep}core${path.sep}Collection.ts`);
81
83
  if (isCollectionClass) {
82
84
  return;
83
85
  }
@@ -110,13 +112,14 @@ If you wish to use a loose type like any/object, create a type alias \`type {{ e
110
112
  };
111
113
  }
112
114
  });
113
- const description$6 = `Enforce consistent logging so that ArcGIS developers can easily debug errors or warnings logged by our web components, which may lack a meaningful context in compiled code. See [our documentation on @arcgis/toolkit/log](https://webgis.esri.com/references/toolkit/log).`;
115
+ const description$7 = `Enforce consistent logging so that ArcGIS developers can easily debug errors or warnings logged by our web components, which may lack a meaningful context in compiled code. See [our documentation on @arcgis/toolkit/log](https://webgis.esri.com/references/toolkit/log).`;
114
116
  plugin.createRule({
115
117
  name: "consistent-logging",
116
118
  meta: {
117
119
  docs: {
118
- description: description$6,
119
- defaultLevel: "off"
120
+ description: description$7,
121
+ defaultLevel: "off",
122
+ isTypeChecked: false
120
123
  },
121
124
  messages: {
122
125
  consistentLoggingWarning: `For consistency, use the log utility from @arcgis/toolkit/log instead of console.{{logMethodName}}.`
@@ -154,7 +157,8 @@ plugin.createRule({
154
157
  description: "Enforce consistent mixin pattern. See https://webgis.esri.com/sdk/contributing/core/core/mixins",
155
158
  // Enabled by default because the rule targets a very specific pattern
156
159
  // and that pattern is tricky to get right without this rule.
157
- defaultLevel: "error"
160
+ defaultLevel: "error",
161
+ isTypeChecked: false
158
162
  },
159
163
  messages: {
160
164
  updateMixinCode: "Mixin typings need to be updated.",
@@ -479,17 +483,18 @@ function expressionToTypeString(expression, context, asConst) {
479
483
  }
480
484
  return;
481
485
  }
482
- const description$5 = "Using .d.ts files is discouraged. Prefer .ts files instead, as they are type-checked and not in global scope.";
486
+ const description$6 = "Using .d.ts files is discouraged. Prefer .ts files instead, as they are type-checked and not in global scope.";
483
487
  const allowedNames = /* @__PURE__ */ new Set(["vite-env.d.ts", "components.d.ts"]);
484
488
  plugin.createRule({
485
489
  name: "no-dts-files",
486
490
  meta: {
487
491
  docs: {
488
- description: description$5,
489
- defaultLevel: "warn"
492
+ description: description$6,
493
+ defaultLevel: "warn",
494
+ isTypeChecked: false
490
495
  },
491
496
  messages: {
492
- avoidDtsFiles: description$5
497
+ avoidDtsFiles: description$6
493
498
  },
494
499
  type: "suggestion",
495
500
  schema: []
@@ -525,7 +530,8 @@ plugin.createRule({
525
530
  docs: {
526
531
  description: "Disallow empty catch calls since empty catch calls in a promise chain don't catch any exceptions",
527
532
  // Enabled by default because this caught real bugs and has autofix
528
- defaultLevel: "error"
533
+ defaultLevel: "error",
534
+ isTypeChecked: false
529
535
  },
530
536
  messages: { emptyCatch: "no empty catch calls" },
531
537
  schema: [],
@@ -546,16 +552,17 @@ plugin.createRule({
546
552
  };
547
553
  }
548
554
  });
549
- const description$4 = `Imports of files outside the src/ folder are not-portable and likely to break for consumers of this package.`;
555
+ const description$5 = `Imports of files outside the src/ folder are not-portable and likely to break for consumers of this package.`;
550
556
  plugin.createRule({
551
557
  name: "no-import-outside-src",
552
558
  meta: {
553
559
  docs: {
554
- description: description$4,
555
- defaultLevel: "error"
560
+ description: description$5,
561
+ defaultLevel: "error",
562
+ isTypeChecked: false
556
563
  },
557
564
  messages: {
558
- noImportOutsideSrc: description$4
565
+ noImportOutsideSrc: description$5
559
566
  },
560
567
  type: "problem",
561
568
  schema: []
@@ -597,7 +604,8 @@ plugin.createRule({
597
604
  // Disabling by default because this matters for
598
605
  // lower-level libraries more than higher-level libraries or applications.
599
606
  // Also, many false-positives.
600
- defaultLevel: "off"
607
+ defaultLevel: "off",
608
+ isTypeChecked: false
601
609
  },
602
610
  schema: [
603
611
  {
@@ -683,6 +691,59 @@ function isClassDefinition(definition) {
683
691
  }
684
692
  return variableNode.init?.type === AST_NODE_TYPES.ClassExpression;
685
693
  }
694
+ const description$4 = "For Node.js compatibility, when TypeScript file imports another TypeScript file, use .ts extension over .js";
695
+ plugin.createRule({
696
+ name: "no-js-in-ts-imports",
697
+ meta: {
698
+ docs: {
699
+ description: description$4,
700
+ defaultLevel: "off",
701
+ isTypeChecked: false
702
+ },
703
+ messages: {
704
+ noJsInTsImports: description$4
705
+ },
706
+ type: "problem",
707
+ fixable: "code",
708
+ schema: []
709
+ },
710
+ defaultOptions: [],
711
+ create(context) {
712
+ if (!/\.tsx?$/u.test(context.filename)) {
713
+ return {};
714
+ }
715
+ function checkSpecifier(node) {
716
+ const specifier = node.value;
717
+ if (!(specifier.startsWith("./") || specifier.startsWith("../")) || !specifier.endsWith(".js")) {
718
+ return;
719
+ }
720
+ context.report({
721
+ node,
722
+ messageId: "noJsInTsImports",
723
+ data: { specifier },
724
+ fix: (fixer) => fixer.replaceTextRange([node.range[1] - 3, node.range[1] - 1], "ts")
725
+ });
726
+ }
727
+ return {
728
+ ImportDeclaration(node) {
729
+ checkSpecifier(node.source);
730
+ },
731
+ ImportExpression(node) {
732
+ if (node.source.type === AST_NODE_TYPES.Literal && typeof node.source.value === "string") {
733
+ checkSpecifier(node.source);
734
+ }
735
+ },
736
+ ExportAllDeclaration(node) {
737
+ checkSpecifier(node.source);
738
+ },
739
+ ExportNamedDeclaration(node) {
740
+ if (node.source) {
741
+ checkSpecifier(node.source);
742
+ }
743
+ }
744
+ };
745
+ }
746
+ });
686
747
  plugin.createRule({
687
748
  name: "no-kebab-case-props",
688
749
  meta: {
@@ -691,7 +752,8 @@ plugin.createRule({
691
752
  // Off by default till
692
753
  // https://devtopia.esri.com/WebGIS/arcgis-web-components/issues/5364#issuecomment-6321339
693
754
  // is resolved
694
- defaultLevel: "off"
755
+ defaultLevel: "off",
756
+ isTypeChecked: false
695
757
  },
696
758
  messages: {
697
759
  kebab: "JSX props should use camelCase instead of kebab-case, except for data- or aria- attributes"
@@ -748,7 +810,8 @@ plugin.createRule({
748
810
  meta: {
749
811
  docs: {
750
812
  description: description$3,
751
- defaultLevel: "off"
813
+ defaultLevel: "off",
814
+ isTypeChecked: false
752
815
  },
753
816
  messages: {
754
817
  noStoryRenderArgsTypeAnnotation: "Do not annotate `render(args)` in stories. Type the story with `Meta<T>` or `StoryObj<T>` and let `args` infer from that."
@@ -789,7 +852,8 @@ plugin.createRule({
789
852
  meta: {
790
853
  docs: {
791
854
  description: description$2,
792
- defaultLevel: "warn"
855
+ defaultLevel: "warn",
856
+ isTypeChecked: false
793
857
  },
794
858
  messages: {
795
859
  noTouchingJsDoc: description$2
@@ -834,7 +898,8 @@ plugin.createRule({
834
898
  meta: {
835
899
  docs: {
836
900
  description: description$1,
837
- defaultLevel: "warn"
901
+ defaultLevel: "warn",
902
+ isTypeChecked: false
838
903
  },
839
904
  messages: {
840
905
  error: description$1
@@ -889,7 +954,8 @@ plugin.createRule({
889
954
  docs: {
890
955
  description: "Async tests must await a screenshot assertion.",
891
956
  // Enabled by default because it targets a specific pattern and has autofix
892
- defaultLevel: "error"
957
+ defaultLevel: "error",
958
+ isTypeChecked: false
893
959
  },
894
960
  messages: { asyncAssert: "Async tests must await a screenshot assertion." },
895
961
  schema: [],
@@ -922,7 +988,8 @@ plugin.createRule({
922
988
  // presumably work correctly today) so enabling it is a bit too disruptive.
923
989
  // We should coordinate enabling it with enabling other lint rules to
924
990
  // announce at once.
925
- defaultLevel: "off"
991
+ defaultLevel: "off",
992
+ isTypeChecked: false
926
993
  },
927
994
  messages: { missingType: "An explicit type attribute is required on buttons" },
928
995
  schema: [],
@@ -944,17 +1011,18 @@ plugin.createRule({
944
1011
  };
945
1012
  }
946
1013
  });
947
- const description = `@arcgis/core imports need to end with .js for better compatibility with ESM CDN builds for @arcgis/core and other packages.`;
948
- const packagesToEnforce = ["@arcgis/core/", "@amcharts/amcharts4/", "@amcharts/amcharts5/"];
1014
+ const description = `Imports of certain packages need to end with .js for better compatibility with CDN and bundlers.`;
1015
+ const packagesToEnforce = ["@arcgis/core/", "@amcharts/amcharts4/", "@amcharts/amcharts5/", "@vaadin/grid/"];
949
1016
  plugin.createRule({
950
1017
  name: "require-js-in-imports",
951
1018
  meta: {
952
1019
  docs: {
953
1020
  description,
954
- defaultLevel: "warn"
1021
+ defaultLevel: "warn",
1022
+ isTypeChecked: false
955
1023
  },
956
1024
  messages: {
957
- requireJsInCoreImport: description
1025
+ requireJsInImports: description
958
1026
  },
959
1027
  type: "problem",
960
1028
  fixable: "code",
@@ -978,7 +1046,7 @@ plugin.createRule({
978
1046
  }
979
1047
  context.report({
980
1048
  node: node.source,
981
- messageId: "requireJsInCoreImport",
1049
+ messageId: "requireJsInImports",
982
1050
  fix: (fixer) => fixer.replaceText(node.source, `"${specifier}.js"`)
983
1051
  });
984
1052
  }
@@ -988,6 +1056,63 @@ plugin.createRule({
988
1056
  };
989
1057
  }
990
1058
  });
1059
+ plugin.createRule({
1060
+ name: "require-ts-in-imports",
1061
+ meta: {
1062
+ docs: {
1063
+ description: "Require configured packages to be imported through their TypeScript source entrypoints when built output may be unavailable.",
1064
+ defaultLevel: "off",
1065
+ isTypeChecked: false
1066
+ },
1067
+ messages: {
1068
+ requireTsInImports: "Import '{{specifier}}' through its '/ts' source entrypoint because built output for '{{packageName}}' may not yet be available when current package is invoked."
1069
+ },
1070
+ type: "problem",
1071
+ schema: [
1072
+ {
1073
+ type: "array",
1074
+ items: { type: "string" },
1075
+ uniqueItems: true
1076
+ }
1077
+ ]
1078
+ },
1079
+ defaultOptions: [[]],
1080
+ create(context) {
1081
+ const packageNames = context.options[0];
1082
+ function checkSpecifier(node) {
1083
+ const specifier = node.value;
1084
+ const packageName = packageNames.find(
1085
+ (candidate) => specifier === candidate || specifier.startsWith(`${candidate}/`)
1086
+ );
1087
+ if (packageName === void 0 || specifier === `${packageName}/package.json` || specifier.endsWith("/ts")) {
1088
+ return;
1089
+ }
1090
+ context.report({
1091
+ node,
1092
+ messageId: "requireTsInImports",
1093
+ data: { packageName, specifier }
1094
+ });
1095
+ }
1096
+ return {
1097
+ ImportDeclaration(node) {
1098
+ checkSpecifier(node.source);
1099
+ },
1100
+ ImportExpression(node) {
1101
+ if (node.source.type === AST_NODE_TYPES.Literal && typeof node.source.value === "string") {
1102
+ checkSpecifier(node.source);
1103
+ }
1104
+ },
1105
+ ExportAllDeclaration(node) {
1106
+ checkSpecifier(node.source);
1107
+ },
1108
+ ExportNamedDeclaration(node) {
1109
+ if (node.source) {
1110
+ checkSpecifier(node.source);
1111
+ }
1112
+ }
1113
+ };
1114
+ }
1115
+ });
991
1116
  const webgisPlugin = plugin.finalize();
992
1117
  export {
993
1118
  webgisPlugin
@@ -4,7 +4,8 @@ import type { TSESLint } from "@typescript-eslint/utils";
4
4
  * A utility for temporary running ESLint with only specific rules enabled.
5
5
  *
6
6
  * @param config - flat config
7
- * @param enabledRules - exceptions
7
+ * @param enabledRules - exceptions. Set a rule to `true` to preserve existing
8
+ * configuration
8
9
  * @param disableTypeChecking - make ESLint much faster by temporary disabling
9
10
  * type-aware linting.
10
11
  * @returns a new flat config array where every rule is disabled,
@@ -21,4 +22,4 @@ import type { TSESLint } from "@typescript-eslint/utils";
21
22
  * true,
22
23
  * );
23
24
  */
24
- export function disableAllRulesExcept(config: TSESLint.FlatConfig.ConfigArray, enabledRules: Record<string, TSESLint.FlatConfig.RuleLevel>, disableTypeChecking: boolean): TSESLint.FlatConfig.ConfigArray;
25
+ export function disableAllRulesExcept(config: TSESLint.FlatConfig.ConfigArray, enabledRules: Partial<Record<string, TSESLint.FlatConfig.RuleEntry | true>>, disableTypeChecking: boolean): TSESLint.FlatConfig.ConfigArray;
@@ -10,7 +10,7 @@ function applyRulesAndOptions(entry, enabledRules, disableTypeChecking) {
10
10
  rules: Object.fromEntries(
11
11
  Object.keys(entry.rules).map((ruleName) => {
12
12
  const override = enabledRules[ruleName];
13
- return [ruleName, override ?? "off"];
13
+ return [ruleName, override === true ? entry.rules[ruleName] : override ?? "off"];
14
14
  })
15
15
  )
16
16
  } : entry;
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@arcgis/eslint-config",
3
- "version": "5.2.0-next.6",
3
+ "version": "5.2.0-next.60",
4
4
  "description": "ESLint configuration for WebGIS SDK",
5
5
  "type": "module",
6
6
  "exports": {
7
7
  ".": "./dist/config/index.js",
8
8
  "./application": "./dist/config/applications.js",
9
+ "./core": "./dist/config/core.js",
9
10
  "./extra": "./dist/config/extra.js",
10
11
  "./lumina": "./dist/config/lumina.js",
11
12
  "./plugins/core": "./dist/plugins/core/index.js",
@@ -21,23 +22,28 @@
21
22
  "license": "SEE LICENSE IN LICENSE.md",
22
23
  "dependencies": {
23
24
  "@eslint/js": "^10.0.1",
24
- "@eslint/markdown": "^8.0.1",
25
+ "@eslint/markdown": "^8.0.3",
25
26
  "@types/confusing-browser-globals": "^1.0.3",
26
- "@typescript-eslint/utils": "^8.58.0",
27
+ "@typescript-eslint/utils": "^8.63.0",
27
28
  "confusing-browser-globals": "^1.0.11",
28
- "eslint-import-resolver-typescript": "^4.4.4",
29
- "eslint-plugin-import-x": "^4.16.2",
29
+ "eslint-import-resolver-typescript": "^4.4.5",
30
+ "eslint-plugin-import-x": "^4.17.1",
31
+ "eslint-plugin-jsdoc": "~63.0.13",
30
32
  "eslint-plugin-package-json": "~0.91.1",
33
+ "eslint-plugin-perfectionist": "~5.10.0",
34
+ "eslint-plugin-react-jsx": "~5.11.2",
35
+ "eslint-plugin-regexp": "~3.1.1",
31
36
  "eslint-plugin-storybook": "^10.3.4",
37
+ "eslint-plugin-unicorn": "~64.0.0",
32
38
  "globals": "^16.5.0",
33
39
  "jsonc-eslint-parser": "^3.1.0",
34
40
  "prettier-linter-helpers": "^1.0.1",
35
41
  "tslib": "^2.8.1",
36
- "typescript": "~6.0.2",
37
- "typescript-eslint": "^8.58.0",
38
- "@arcgis/toolkit": "5.2.0-next.6"
42
+ "typescript": "~6.0.3",
43
+ "typescript-eslint": "^8.63.0",
44
+ "@arcgis/toolkit": "5.2.0-next.60"
39
45
  },
40
46
  "peerDependencies": {
41
- "eslint": "^10.2.0"
47
+ "eslint": "^10.6.0"
42
48
  }
43
49
  }