@arcgis/eslint-config 4.33.0-next.90 → 4.33.0-next.92

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
- const version = "4.33.0-next.90";
1
+ const version = "4.33.0-next.92";
2
2
  function makeEslintPlugin(pluginName, rules) {
3
3
  const config = {
4
4
  rules: Object.fromEntries(
@@ -1,6 +1,6 @@
1
1
  import { ESLintUtils, AST_NODE_TYPES, AST_TOKEN_TYPES } from "@typescript-eslint/utils";
2
2
  import ts from "typescript";
3
- import { m as makeEslintPlugin } from "../../makePlugin-lsyutBw7.js";
3
+ import { m as makeEslintPlugin } from "../../makePlugin-n5hoB6m9.js";
4
4
  import { camelToKebab } from "@arcgis/components-utils";
5
5
  const createRule = ESLintUtils.RuleCreator(
6
6
  (rule) => `https://devtopia.esri.com/WebGIS/arcgis-web-components/tree/main/packages/support-packages/eslint-config/src/plugins/lumina/rules/${rule}.ts`
@@ -326,6 +326,81 @@ function inferTrivialType(member) {
326
326
  return "Other";
327
327
  }
328
328
  const builtInConverterTypes = /* @__PURE__ */ new Set(["Number", "Boolean", "Array", "Object"]);
329
+ const banEvents = createRule({
330
+ name: "ban-events",
331
+ defaultOptions: [],
332
+ meta: {
333
+ docs: {
334
+ description: "This rule helps ban or warn against listened event types",
335
+ defaultLevel: "error"
336
+ },
337
+ messages: {
338
+ default: "{{message}}"
339
+ },
340
+ schema: {
341
+ type: "array",
342
+ items: {
343
+ anyOf: [
344
+ { type: "string" },
345
+ {
346
+ type: "object",
347
+ properties: {
348
+ event: { type: "string" },
349
+ message: {
350
+ type: "string",
351
+ minLength: 1
352
+ }
353
+ },
354
+ additionalProperties: false,
355
+ required: ["event"]
356
+ }
357
+ ]
358
+ },
359
+ uniqueItems: true
360
+ },
361
+ type: "problem"
362
+ },
363
+ create(context) {
364
+ const bannedEventToMessageLookup = /* @__PURE__ */ new Map();
365
+ context.options.forEach((option) => {
366
+ const event = typeof option === "string" ? option : option.event;
367
+ const message = typeof option === "string" ? null : option.message ?? null;
368
+ bannedEventToMessageLookup.set(event, message);
369
+ });
370
+ function buildMessage(eventName) {
371
+ return bannedEventToMessageLookup.get(eventName) ?? `${eventName} is not allowed`;
372
+ }
373
+ function checkEvent(node, eventName) {
374
+ if (bannedEventToMessageLookup.has(eventName)) {
375
+ context.report({
376
+ node,
377
+ messageId: "default",
378
+ data: {
379
+ message: buildMessage(eventName)
380
+ }
381
+ });
382
+ }
383
+ }
384
+ const luminaJsxCheck = checkForLuminaJsx();
385
+ return {
386
+ "ImportDeclaration": luminaJsxCheck,
387
+ "CallExpression:matches([callee.property.name=addEventListener], [callee.property.name=removeEventListener]), CallExpression[callee.object.type=ThisExpression][callee.property.name=listen]"(node) {
388
+ if (!luminaJsxCheck.isLuminaJsx) {
389
+ return;
390
+ }
391
+ const eventName = node.arguments[0].value;
392
+ checkEvent(node, eventName);
393
+ },
394
+ "CallExpression[callee.object.type=ThisExpression][callee.property.name=listenOn]"(node) {
395
+ if (!luminaJsxCheck.isLuminaJsx) {
396
+ return;
397
+ }
398
+ const eventName = node.arguments[1].value;
399
+ checkEvent(node, eventName);
400
+ }
401
+ };
402
+ }
403
+ });
329
404
  const description$g = `Lumina component must be declared in a TSX file with a matching folder name located inside of src/components folder.`;
330
405
  const componentPlacementRules = createRule({
331
406
  name: "component-placement-rules",
@@ -1083,6 +1158,65 @@ const memberOrdering = createRule({
1083
1158
  }
1084
1159
  })
1085
1160
  });
1161
+ const blockListedCustomElementNames = /* @__PURE__ */ new Set([
1162
+ "annotation-xml",
1163
+ "color-profile",
1164
+ "font-face",
1165
+ "font-face-src",
1166
+ "font-face-uri",
1167
+ "font-face-format",
1168
+ "font-face-name",
1169
+ "missing-glyph"
1170
+ ]);
1171
+ const noCreateElementComponent = createRule({
1172
+ name: "no-create-element-component",
1173
+ defaultOptions: [],
1174
+ meta: {
1175
+ docs: {
1176
+ description: "This rule ensures that components are not created with `document.createElement()` to ensure imports are tracked by the compiler.",
1177
+ defaultLevel: "error"
1178
+ },
1179
+ fixable: "code",
1180
+ messages: {
1181
+ default: "Use JSX instead of `document.createElement()` to create components.\nDetails: https://qawebgis.esri.com/components/lumina/jsx#rendering-jsx-outside-the-component"
1182
+ },
1183
+ schema: [],
1184
+ type: "problem"
1185
+ },
1186
+ create(context) {
1187
+ const luminaJsxCheck = checkForLuminaJsx();
1188
+ return {
1189
+ ImportDeclaration: luminaJsxCheck,
1190
+ CallExpression(node) {
1191
+ if (!luminaJsxCheck.isLuminaJsx) {
1192
+ return;
1193
+ }
1194
+ if (isCreateElementComponent(node)) {
1195
+ return void context.report({
1196
+ node,
1197
+ messageId: "default"
1198
+ });
1199
+ }
1200
+ }
1201
+ };
1202
+ }
1203
+ });
1204
+ function isCreateElementComponent(node) {
1205
+ if (!(node.callee?.type === AST_NODE_TYPES.MemberExpression && node.callee?.object?.type === AST_NODE_TYPES.Identifier && node.callee?.object?.name === "document" && node.callee?.property?.type === AST_NODE_TYPES.Identifier && node.callee?.property?.name === "createElement" && node.arguments.length >= 1)) {
1206
+ return false;
1207
+ }
1208
+ const localNameArg = node.arguments[0];
1209
+ if (localNameArg.type === AST_NODE_TYPES.Literal && typeof localNameArg.value === "string") {
1210
+ return isCustomElementTag(localNameArg.value);
1211
+ }
1212
+ if (localNameArg.type === AST_NODE_TYPES.TemplateLiteral && localNameArg.expressions.length === 0) {
1213
+ return isCustomElementTag(localNameArg.quasis[0].value.raw);
1214
+ }
1215
+ return false;
1216
+ }
1217
+ function isCustomElementTag(tag) {
1218
+ return tag.includes("-") && !blockListedCustomElementNames.has(tag);
1219
+ }
1086
1220
  const description$c = `Use @internal or @private JSDoc tag over @ignore. See https://qawebgis.esri.com/components/lumina/documenting-components#excluding-api-from-public-documentation`;
1087
1221
  const noIgnoreJsDocTag = createRule({
1088
1222
  name: "no-ignore-jsdoc-tag",
@@ -1930,26 +2064,18 @@ declare global {
1930
2064
  };
1931
2065
  }
1932
2066
  });
1933
- const blockListedCustomElementNames = /* @__PURE__ */ new Set([
1934
- "annotation-xml",
1935
- "color-profile",
1936
- "font-face",
1937
- "font-face-src",
1938
- "font-face-uri",
1939
- "font-face-format",
1940
- "font-face-name",
1941
- "missing-glyph"
1942
- ]);
1943
2067
  const tagNameToNormalizedClassName = (tagName) => tagName.replaceAll("-", "").toLowerCase();
1944
2068
  const reCustomElementName = /^[a-z]+(?:-[a-z\d]+)+$/u;
1945
2069
  const luminaPlugin = makeEslintPlugin("lumina", {
1946
2070
  "add-missing-jsx-import": addMissingJsxImport,
1947
2071
  "auto-add-type": autoAddType,
2072
+ "ban-events": banEvents,
1948
2073
  "component-placement-rules": componentPlacementRules,
1949
2074
  "consistent-event-naming": consistentEventNaming,
1950
2075
  "decorators-context": decoratorsContext,
1951
2076
  "explicit-setter-type": explicitSetterType,
1952
2077
  "member-ordering": memberOrdering,
2078
+ "no-create-element-component": noCreateElementComponent,
1953
2079
  "no-ignore-jsdoc-tag": noIgnoreJsDocTag,
1954
2080
  "no-incorrect-dynamic-tag-name": noIncorrectDynamicTagName,
1955
2081
  "no-inline-arrow-in-ref": noInlineArrowInRef,
@@ -0,0 +1,6 @@
1
+ type Options = (string | {
2
+ event: string;
3
+ message?: string;
4
+ })[];
5
+ export declare const banEvents: import('@typescript-eslint/utils/ts-eslint').RuleModule<"default", Options, import('../../utils/makePlugin').CommonDocs, import('@typescript-eslint/utils/ts-eslint').RuleListener>;
6
+ export {};
@@ -0,0 +1 @@
1
+ export declare const noCreateElementComponent: import('@typescript-eslint/utils/ts-eslint').RuleModule<"default", [], import('../../utils/makePlugin').CommonDocs, import('@typescript-eslint/utils/ts-eslint').RuleListener>;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Although most native elements do not contain dashes inside, there are a
3
+ * few exceptions. Explicitly declaring a custom element by this name is
4
+ * forbidden
5
+ *
6
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/define#valid_custom_element_names
7
+ */
8
+ export declare const blockListedCustomElementNames: Set<string>;
@@ -1,4 +1,4 @@
1
- import { m as makeEslintPlugin } from "../../makePlugin-lsyutBw7.js";
1
+ import { m as makeEslintPlugin } from "../../makePlugin-n5hoB6m9.js";
2
2
  import { ESLintUtils, AST_NODE_TYPES } from "@typescript-eslint/utils";
3
3
  import { resolve } from "node:path/posix";
4
4
  const isTestFile = (filePath) => filePath.includes("/test") || filePath.includes(".test") || filePath.includes(".spec") || filePath.includes("e2e") || filePath.includes("__") || filePath.includes("/.");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcgis/eslint-config",
3
- "version": "4.33.0-next.90",
3
+ "version": "4.33.0-next.92",
4
4
  "description": "ESLint configuration for arcgis-web-components",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -19,7 +19,7 @@
19
19
  ],
20
20
  "license": "SEE LICENSE IN LICENSE.md",
21
21
  "dependencies": {
22
- "@arcgis/components-utils": "4.33.0-next.90",
22
+ "@arcgis/components-utils": "4.33.0-next.92",
23
23
  "@eslint/js": "^9.17.0",
24
24
  "@types/confusing-browser-globals": "^1.0.3",
25
25
  "confusing-browser-globals": "^1.0.11",