@checkdigit/eslint-plugin 6.6.0-PR.75-d33e → 6.6.0-PR.75-03e4

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.
@@ -102253,7 +102253,7 @@ function analyzeResponseReferences(variableDeclaration, scopeManager) {
102253
102253
  }
102254
102254
 
102255
102255
  // package.json
102256
- var package_default = { name: "@checkdigit/eslint-plugin", version: "6.6.0-PR.75-d33e", description: "Check Digit eslint plugins", keywords: ["eslint", "eslintplugin"], homepage: "https://github.com/checkdigit/eslint-plugin#readme", bugs: { url: "https://github.com/checkdigit/eslint-plugin/issues" }, repository: { type: "git", url: "https://github.com/checkdigit/eslint-plugin" }, license: "MIT", author: "Check Digit, LLC", sideEffects: false, type: "module", exports: { ".": { types: "./dist-types/index.d.ts", require: "./dist-cjs/index.cjs", import: "./dist-mjs/index.mjs", default: "./dist-mjs/index.mjs" } }, files: ["src", "dist-types", "dist-cjs", "dist-mjs", "!src/**/*.test.ts", "!src/**/*.spec.ts", "!dist-types/**/*.test.d.ts", "!dist-types/**/*.spec.d.ts", "!dist-cjs/**/*.test.cjs", "!dist-cjs/**/*.spec.cjs", "!dist-mjs/**/*.test.mjs", "!dist-mjs/**/*.spec.mjs", "SECURITY.md"], scripts: { "build:dist-cjs": 'rimraf dist-cjs && npx builder --type=commonjs --sourceMap --entryPoint=index.ts --outDir=dist-cjs --outFile=index.cjs --external=espree && echo "module.exports = module.exports.default;" >> dist-cjs/index.cjs', "build:dist-mjs": "rimraf dist-mjs && npx builder --type=module --sourceMap --outDir=dist-mjs && node dist-mjs/index.mjs", "build:dist-types": "rimraf dist-types && npx builder --type=types --outDir=dist-types", "ci:compile": "tsc --noEmit", "ci:coverage": 'NODE_OPTIONS="--disable-warning ExperimentalWarning --experimental-vm-modules" jest --coverage=true', "ci:lint": "npm run lint", "ci:style": "npm run prettier", "ci:test": 'NODE_OPTIONS="--disable-warning ExperimentalWarning --experimental-vm-modules" jest --coverage=false', lint: "eslint --max-warnings 0 --ignore-path .gitignore .", "lint:fix": "eslint --ignore-path .gitignore . --fix", prepublishOnly: "npm run build:dist-types && npm run build:dist-cjs && npm run build:dist-mjs", prettier: "prettier --ignore-path .gitignore --list-different .", "prettier:fix": "prettier --ignore-path .gitignore --write .", test: "npm run ci:compile && npm run ci:test && npm run ci:lint && npm run ci:style" }, prettier: "@checkdigit/prettier-config", jest: { preset: "@checkdigit/jest-config" }, dependencies: { "@typescript-eslint/type-utils": "7.18.0", "@typescript-eslint/utils": "7.18.0", "ts-api-utils": "^1.3.0" }, devDependencies: { "@checkdigit/jest-config": "^6.0.2", "@checkdigit/prettier-config": "^5.5.0", "@checkdigit/typescript-config": "6.0.0", "@types/eslint": "^8.56.10", "@typescript-eslint/eslint-plugin": "^7.18.0", "@typescript-eslint/parser": "^7.18.0", "@typescript-eslint/rule-tester": "7.18.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-eslint-plugin": "^6.2.0", "eslint-plugin-import": "^2.29.1", "eslint-plugin-no-only-tests": "^3.1.0", "eslint-plugin-no-secrets": "^1.0.2", "eslint-plugin-node": "^11.1.0", "eslint-plugin-sonarjs": "0.24.0" }, peerDependencies: { eslint: ">=8 <9" }, engines: { node: ">=20.14" } };
102256
+ var package_default = { name: "@checkdigit/eslint-plugin", version: "6.6.0-PR.75-03e4", description: "Check Digit eslint plugins", keywords: ["eslint", "eslintplugin"], homepage: "https://github.com/checkdigit/eslint-plugin#readme", bugs: { url: "https://github.com/checkdigit/eslint-plugin/issues" }, repository: { type: "git", url: "https://github.com/checkdigit/eslint-plugin" }, license: "MIT", author: "Check Digit, LLC", sideEffects: false, type: "module", exports: { ".": { types: "./dist-types/index.d.ts", require: "./dist-cjs/index.cjs", import: "./dist-mjs/index.mjs", default: "./dist-mjs/index.mjs" } }, files: ["src", "dist-types", "dist-cjs", "dist-mjs", "!src/**/*.test.ts", "!src/**/*.spec.ts", "!dist-types/**/*.test.d.ts", "!dist-types/**/*.spec.d.ts", "!dist-cjs/**/*.test.cjs", "!dist-cjs/**/*.spec.cjs", "!dist-mjs/**/*.test.mjs", "!dist-mjs/**/*.spec.mjs", "SECURITY.md"], scripts: { "build:dist-cjs": 'rimraf dist-cjs && npx builder --type=commonjs --sourceMap --entryPoint=index.ts --outDir=dist-cjs --outFile=index.cjs --external=espree && echo "module.exports = module.exports.default;" >> dist-cjs/index.cjs', "build:dist-mjs": "rimraf dist-mjs && npx builder --type=module --sourceMap --outDir=dist-mjs && node dist-mjs/index.mjs", "build:dist-types": "rimraf dist-types && npx builder --type=types --outDir=dist-types", "ci:compile": "tsc --noEmit", "ci:coverage": 'NODE_OPTIONS="--disable-warning ExperimentalWarning --experimental-vm-modules" jest --coverage=true', "ci:lint": "npm run lint", "ci:style": "npm run prettier", "ci:test": 'NODE_OPTIONS="--disable-warning ExperimentalWarning --experimental-vm-modules" jest --coverage=false', lint: "eslint --max-warnings 0 --ignore-path .gitignore .", "lint:fix": "eslint --ignore-path .gitignore . --fix", prepublishOnly: "npm run build:dist-types && npm run build:dist-cjs && npm run build:dist-mjs", prettier: "prettier --ignore-path .gitignore --list-different .", "prettier:fix": "prettier --ignore-path .gitignore --write .", test: "npm run ci:compile && npm run ci:test && npm run ci:lint && npm run ci:style" }, prettier: "@checkdigit/prettier-config", jest: { preset: "@checkdigit/jest-config" }, dependencies: { "@typescript-eslint/type-utils": "7.18.0", "@typescript-eslint/utils": "7.18.0", "ts-api-utils": "^1.3.0" }, devDependencies: { "@checkdigit/jest-config": "^6.0.2", "@checkdigit/prettier-config": "^5.5.0", "@checkdigit/typescript-config": "6.0.0", "@types/eslint": "^8.56.10", "@typescript-eslint/eslint-plugin": "^7.18.0", "@typescript-eslint/parser": "^7.18.0", "@typescript-eslint/rule-tester": "7.18.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-eslint-plugin": "^6.2.0", "eslint-plugin-import": "^2.29.1", "eslint-plugin-no-only-tests": "^3.1.0", "eslint-plugin-no-secrets": "^1.0.2", "eslint-plugin-node": "^11.1.0", "eslint-plugin-sonarjs": "0.24.0" }, peerDependencies: { eslint: ">=8 <9" }, engines: { node: ">=20.14" } };
102257
102257
 
102258
102258
  // src/get-documentation-url.ts
102259
102259
  function getDocumentationUrl(ruleId7) {
@@ -102369,7 +102369,7 @@ function isValidPropertyName(name) {
102369
102369
 
102370
102370
  // src/fixture/url.ts
102371
102371
  var PLAIN_URL_REGEXP = /^[`']\/\w+(?<serviceNamePart>-\w+)*\/v\d+\/.+[`']$/u;
102372
- var TOKENIZED_URL_REGEXP = /^`\$\{(?<serviceNamePart>\w+_)*BASE_PATH\}\/.+`$/u;
102372
+ var TOKENIZED_URL_REGEXP = /^`\$\{(?<serviceNamePart>[A-Z]+_)*BASE_PATH\}\/.+`$/u;
102373
102373
  function replaceEndpointUrlPrefixWithBasePath(url) {
102374
102374
  return url.replace(/^`\/\w+(?<parts>-\w+)*\/v\d+\//u, "`${BASE_PATH}/");
102375
102375
  }
@@ -12272,7 +12272,7 @@
12272
12272
  "format": "esm"
12273
12273
  },
12274
12274
  "src/fixture/url.ts": {
12275
- "bytes": 639,
12275
+ "bytes": 642,
12276
12276
  "imports": [],
12277
12277
  "format": "esm"
12278
12278
  },
@@ -12407,7 +12407,7 @@
12407
12407
  "format": "esm"
12408
12408
  },
12409
12409
  "src/fixture/no-service-wrapper.ts": {
12410
- "bytes": 9508,
12410
+ "bytes": 9507,
12411
12411
  "imports": [
12412
12412
  {
12413
12413
  "path": "node_modules/@typescript-eslint/utils/dist/index.js",
@@ -15386,7 +15386,7 @@
15386
15386
  "bytesInOutput": 118
15387
15387
  },
15388
15388
  "src/fixture/url.ts": {
15389
- "bytesInOutput": 454
15389
+ "bytesInOutput": 457
15390
15390
  },
15391
15391
  "src/fixture/fetch-then.ts": {
15392
15392
  "bytesInOutput": 12296
@@ -15434,7 +15434,7 @@
15434
15434
  "bytesInOutput": 3362
15435
15435
  }
15436
15436
  },
15437
- "bytes": 4292630
15437
+ "bytes": 4292633
15438
15438
  }
15439
15439
  }
15440
15440
  }
@@ -0,0 +1,60 @@
1
+ // src/fixture/no-status-code.ts
2
+ import { ESLintUtils } from "@typescript-eslint/utils";
3
+ import getDocumentationUrl from "../get-documentation-url.mjs";
4
+ var ruleId = "no-status-code";
5
+ var createRule = ESLintUtils.RuleCreator((name) => getDocumentationUrl(name));
6
+ var rule = createRule({
7
+ name: ruleId,
8
+ meta: {
9
+ type: "suggestion",
10
+ docs: {
11
+ description: 'Access the status code property of the fetch Response using "status" instead of "statusCode".'
12
+ },
13
+ messages: {
14
+ replaceStatusCode: 'Replacing "statusCode" with "status".',
15
+ unknownError: 'Unknown error occurred in file "{{fileName}}": {{ error }}.'
16
+ },
17
+ fixable: "code",
18
+ schema: []
19
+ },
20
+ defaultOptions: [],
21
+ // eslint-disable-next-line max-lines-per-function
22
+ create(context) {
23
+ const parserServices = ESLintUtils.getParserServices(context);
24
+ const typeChecker = parserServices.program.getTypeChecker();
25
+ return {
26
+ 'MemberExpression[property.name="statusCode"]': (responseStatusCode) => {
27
+ try {
28
+ const responseNode = parserServices.esTreeNodeToTSNodeMap.get(responseStatusCode.object);
29
+ const responseType = typeChecker.getTypeAtLocation(responseNode);
30
+ const shouldReplace = responseType.getProperties().some((symbol) => symbol.name === "status") && !responseType.getProperties().some((symbol) => symbol.name === "statusCode");
31
+ if (shouldReplace) {
32
+ context.report({
33
+ messageId: "replaceStatusCode",
34
+ node: responseStatusCode.property,
35
+ fix(fixer) {
36
+ return fixer.replaceText(responseStatusCode.property, "status");
37
+ }
38
+ });
39
+ }
40
+ } catch (error) {
41
+ console.error(`Failed to apply ${ruleId} rule for file "${context.filename}":`, error);
42
+ context.report({
43
+ node: responseStatusCode,
44
+ messageId: "unknownError",
45
+ data: {
46
+ fileName: context.filename,
47
+ error: error instanceof Error ? error.toString() : JSON.stringify(error)
48
+ }
49
+ });
50
+ }
51
+ }
52
+ };
53
+ }
54
+ });
55
+ var no_status_code_default = rule;
56
+ export {
57
+ no_status_code_default as default,
58
+ ruleId
59
+ };
60
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2ZpeHR1cmUvbm8tc3RhdHVzLWNvZGUudHMiXSwKICAibWFwcGluZ3MiOiAiO0FBUUEsU0FBUyxtQkFBNkI7QUFDdEMsT0FBTyx5QkFBeUI7QUFFekIsSUFBTSxTQUFTO0FBRXRCLElBQU0sYUFBYSxZQUFZLFlBQVksQ0FBQyxTQUFTLG9CQUFvQixJQUFJLENBQUM7QUFFOUUsSUFBTSxPQUFPLFdBQVc7QUFBQSxFQUN0QixNQUFNO0FBQUEsRUFDTixNQUFNO0FBQUEsSUFDSixNQUFNO0FBQUEsSUFDTixNQUFNO0FBQUEsTUFDSixhQUFhO0FBQUEsSUFDZjtBQUFBLElBQ0EsVUFBVTtBQUFBLE1BQ1IsbUJBQW1CO0FBQUEsTUFDbkIsY0FBYztBQUFBLElBQ2hCO0FBQUEsSUFDQSxTQUFTO0FBQUEsSUFDVCxRQUFRLENBQUM7QUFBQSxFQUNYO0FBQUEsRUFDQSxnQkFBZ0IsQ0FBQztBQUFBO0FBQUEsRUFFakIsT0FBTyxTQUFTO0FBQ2QsVUFBTSxpQkFBaUIsWUFBWSxrQkFBa0IsT0FBTztBQUM1RCxVQUFNLGNBQWMsZUFBZSxRQUFRLGVBQWU7QUFFMUQsV0FBTztBQUFBLE1BQ0wsZ0RBQWdELENBQUMsdUJBQWtEO0FBQ2pHLFlBQUk7QUFDRixnQkFBTSxlQUFlLGVBQWUsc0JBQXNCLElBQUksbUJBQW1CLE1BQU07QUFDdkYsZ0JBQU0sZUFBZSxZQUFZLGtCQUFrQixZQUFZO0FBRS9ELGdCQUFNLGdCQUNKLGFBQWEsY0FBYyxFQUFFLEtBQUssQ0FBQyxXQUFXLE9BQU8sU0FBUyxRQUFRLEtBQ3RFLENBQUMsYUFBYSxjQUFjLEVBQUUsS0FBSyxDQUFDLFdBQVcsT0FBTyxTQUFTLFlBQVk7QUFFN0UsY0FBSSxlQUFlO0FBQ2pCLG9CQUFRLE9BQU87QUFBQSxjQUNiLFdBQVc7QUFBQSxjQUNYLE1BQU0sbUJBQW1CO0FBQUEsY0FDekIsSUFBSSxPQUFPO0FBQ1QsdUJBQU8sTUFBTSxZQUFZLG1CQUFtQixVQUFVLFFBQVE7QUFBQSxjQUNoRTtBQUFBLFlBQ0YsQ0FBQztBQUFBLFVBQ0g7QUFBQSxRQUNGLFNBQVMsT0FBTztBQUVkLGtCQUFRLE1BQU0sbUJBQW1CLE1BQU0sbUJBQW1CLFFBQVEsUUFBUSxNQUFNLEtBQUs7QUFDckYsa0JBQVEsT0FBTztBQUFBLFlBQ2IsTUFBTTtBQUFBLFlBQ04sV0FBVztBQUFBLFlBQ1gsTUFBTTtBQUFBLGNBQ0osVUFBVSxRQUFRO0FBQUEsY0FDbEIsT0FBTyxpQkFBaUIsUUFBUSxNQUFNLFNBQVMsSUFBSSxLQUFLLFVBQVUsS0FBSztBQUFBLFlBQ3pFO0FBQUEsVUFDRixDQUFDO0FBQUEsUUFDSDtBQUFBLE1BQ0Y7QUFBQSxJQUNGO0FBQUEsRUFDRjtBQUNGLENBQUM7QUFFRCxJQUFPLHlCQUFROyIsCiAgIm5hbWVzIjogW10KfQo=
@@ -1,6 +1,6 @@
1
1
  // src/fixture/url.ts
2
2
  var PLAIN_URL_REGEXP = /^[`']\/\w+(?<serviceNamePart>-\w+)*\/v\d+\/.+[`']$/u;
3
- var TOKENIZED_URL_REGEXP = /^`\$\{(?<serviceNamePart>\w+_)*BASE_PATH\}\/.+`$/u;
3
+ var TOKENIZED_URL_REGEXP = /^`\$\{(?<serviceNamePart>[A-Z]+_)*BASE_PATH\}\/.+`$/u;
4
4
  function replaceEndpointUrlPrefixWithBasePath(url) {
5
5
  return url.replace(/^`\/\w+(?<parts>-\w+)*\/v\d+\//u, "`${BASE_PATH}/");
6
6
  }
@@ -0,0 +1,4 @@
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
2
+ export declare const ruleId = "no-status-code";
3
+ declare const rule: ESLintUtils.RuleModule<"unknownError" | "replaceStatusCode", never[], ESLintUtils.RuleListener>;
4
+ export default rule;
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"@checkdigit/eslint-plugin","version":"6.6.0-PR.75-d33e","description":"Check Digit eslint plugins","keywords":["eslint","eslintplugin"],"homepage":"https://github.com/checkdigit/eslint-plugin#readme","bugs":{"url":"https://github.com/checkdigit/eslint-plugin/issues"},"repository":{"type":"git","url":"https://github.com/checkdigit/eslint-plugin"},"license":"MIT","author":"Check Digit, LLC","sideEffects":false,"type":"module","exports":{".":{"types":"./dist-types/index.d.ts","require":"./dist-cjs/index.cjs","import":"./dist-mjs/index.mjs","default":"./dist-mjs/index.mjs"}},"files":["src","dist-types","dist-cjs","dist-mjs","!src/**/*.test.ts","!src/**/*.spec.ts","!dist-types/**/*.test.d.ts","!dist-types/**/*.spec.d.ts","!dist-cjs/**/*.test.cjs","!dist-cjs/**/*.spec.cjs","!dist-mjs/**/*.test.mjs","!dist-mjs/**/*.spec.mjs","SECURITY.md"],"scripts":{"build:dist-cjs":"rimraf dist-cjs && npx builder --type=commonjs --sourceMap --entryPoint=index.ts --outDir=dist-cjs --outFile=index.cjs --external=espree && echo \"module.exports = module.exports.default;\" >> dist-cjs/index.cjs","build:dist-mjs":"rimraf dist-mjs && npx builder --type=module --sourceMap --outDir=dist-mjs && node dist-mjs/index.mjs","build:dist-types":"rimraf dist-types && npx builder --type=types --outDir=dist-types","ci:compile":"tsc --noEmit","ci:coverage":"NODE_OPTIONS=\"--disable-warning ExperimentalWarning --experimental-vm-modules\" jest --coverage=true","ci:lint":"npm run lint","ci:style":"npm run prettier","ci:test":"NODE_OPTIONS=\"--disable-warning ExperimentalWarning --experimental-vm-modules\" jest --coverage=false","lint":"eslint --max-warnings 0 --ignore-path .gitignore .","lint:fix":"eslint --ignore-path .gitignore . --fix","prepublishOnly":"npm run build:dist-types && npm run build:dist-cjs && npm run build:dist-mjs","prettier":"prettier --ignore-path .gitignore --list-different .","prettier:fix":"prettier --ignore-path .gitignore --write .","test":"npm run ci:compile && npm run ci:test && npm run ci:lint && npm run ci:style"},"prettier":"@checkdigit/prettier-config","jest":{"preset":"@checkdigit/jest-config"},"dependencies":{"@typescript-eslint/type-utils":"7.18.0","@typescript-eslint/utils":"7.18.0","ts-api-utils":"^1.3.0"},"devDependencies":{"@checkdigit/jest-config":"^6.0.2","@checkdigit/prettier-config":"^5.5.0","@checkdigit/typescript-config":"6.0.0","@types/eslint":"^8.56.10","@typescript-eslint/eslint-plugin":"^7.18.0","@typescript-eslint/parser":"^7.18.0","@typescript-eslint/rule-tester":"7.18.0","eslint-config-prettier":"^9.1.0","eslint-plugin-eslint-plugin":"^6.2.0","eslint-plugin-import":"^2.29.1","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-no-secrets":"^1.0.2","eslint-plugin-node":"^11.1.0","eslint-plugin-sonarjs":"0.24.0"},"peerDependencies":{"eslint":">=8 <9"},"engines":{"node":">=20.14"}}
1
+ {"name":"@checkdigit/eslint-plugin","version":"6.6.0-PR.75-03e4","description":"Check Digit eslint plugins","keywords":["eslint","eslintplugin"],"homepage":"https://github.com/checkdigit/eslint-plugin#readme","bugs":{"url":"https://github.com/checkdigit/eslint-plugin/issues"},"repository":{"type":"git","url":"https://github.com/checkdigit/eslint-plugin"},"license":"MIT","author":"Check Digit, LLC","sideEffects":false,"type":"module","exports":{".":{"types":"./dist-types/index.d.ts","require":"./dist-cjs/index.cjs","import":"./dist-mjs/index.mjs","default":"./dist-mjs/index.mjs"}},"files":["src","dist-types","dist-cjs","dist-mjs","!src/**/*.test.ts","!src/**/*.spec.ts","!dist-types/**/*.test.d.ts","!dist-types/**/*.spec.d.ts","!dist-cjs/**/*.test.cjs","!dist-cjs/**/*.spec.cjs","!dist-mjs/**/*.test.mjs","!dist-mjs/**/*.spec.mjs","SECURITY.md"],"scripts":{"build:dist-cjs":"rimraf dist-cjs && npx builder --type=commonjs --sourceMap --entryPoint=index.ts --outDir=dist-cjs --outFile=index.cjs --external=espree && echo \"module.exports = module.exports.default;\" >> dist-cjs/index.cjs","build:dist-mjs":"rimraf dist-mjs && npx builder --type=module --sourceMap --outDir=dist-mjs && node dist-mjs/index.mjs","build:dist-types":"rimraf dist-types && npx builder --type=types --outDir=dist-types","ci:compile":"tsc --noEmit","ci:coverage":"NODE_OPTIONS=\"--disable-warning ExperimentalWarning --experimental-vm-modules\" jest --coverage=true","ci:lint":"npm run lint","ci:style":"npm run prettier","ci:test":"NODE_OPTIONS=\"--disable-warning ExperimentalWarning --experimental-vm-modules\" jest --coverage=false","lint":"eslint --max-warnings 0 --ignore-path .gitignore .","lint:fix":"eslint --ignore-path .gitignore . --fix","prepublishOnly":"npm run build:dist-types && npm run build:dist-cjs && npm run build:dist-mjs","prettier":"prettier --ignore-path .gitignore --list-different .","prettier:fix":"prettier --ignore-path .gitignore --write .","test":"npm run ci:compile && npm run ci:test && npm run ci:lint && npm run ci:style"},"prettier":"@checkdigit/prettier-config","jest":{"preset":"@checkdigit/jest-config"},"dependencies":{"@typescript-eslint/type-utils":"7.18.0","@typescript-eslint/utils":"7.18.0","ts-api-utils":"^1.3.0"},"devDependencies":{"@checkdigit/jest-config":"^6.0.2","@checkdigit/prettier-config":"^5.5.0","@checkdigit/typescript-config":"6.0.0","@types/eslint":"^8.56.10","@typescript-eslint/eslint-plugin":"^7.18.0","@typescript-eslint/parser":"^7.18.0","@typescript-eslint/rule-tester":"7.18.0","eslint-config-prettier":"^9.1.0","eslint-plugin-eslint-plugin":"^6.2.0","eslint-plugin-import":"^2.29.1","eslint-plugin-no-only-tests":"^3.1.0","eslint-plugin-no-secrets":"^1.0.2","eslint-plugin-node":"^11.1.0","eslint-plugin-sonarjs":"0.24.0"},"peerDependencies":{"eslint":">=8 <9"},"engines":{"node":">=20.14"}}
@@ -56,7 +56,7 @@ const rule = createRule({
56
56
  (urlArgument?.type === AST_NODE_TYPES.Literal && typeof urlArgument.value === 'string') ||
57
57
  urlArgument?.type === AST_NODE_TYPES.TemplateLiteral
58
58
  ) {
59
- const urlText = sourceCode.getText(urlArgument);
59
+ const urlText = sourceCode.getText(urlArgument);
60
60
  return PLAIN_URL_REGEXP.test(urlText) || TOKENIZED_URL_REGEXP.test(urlText);
61
61
  }
62
62
 
@@ -0,0 +1,72 @@
1
+ // fixture/no-status-code.ts
2
+
3
+ /*
4
+ * Copyright (c) 2021-2024 Check Digit, LLC
5
+ *
6
+ * This code is licensed under the MIT license (see LICENSE.txt for details).
7
+ */
8
+
9
+ import { ESLintUtils, TSESTree } from '@typescript-eslint/utils';
10
+ import getDocumentationUrl from '../get-documentation-url';
11
+
12
+ export const ruleId = 'no-status-code';
13
+
14
+ const createRule = ESLintUtils.RuleCreator((name) => getDocumentationUrl(name));
15
+
16
+ const rule = createRule({
17
+ name: ruleId,
18
+ meta: {
19
+ type: 'suggestion',
20
+ docs: {
21
+ description: 'Access the status code property of the fetch Response using "status" instead of "statusCode".',
22
+ },
23
+ messages: {
24
+ replaceStatusCode: 'Replacing "statusCode" with "status".',
25
+ unknownError: 'Unknown error occurred in file "{{fileName}}": {{ error }}.',
26
+ },
27
+ fixable: 'code',
28
+ schema: [],
29
+ },
30
+ defaultOptions: [],
31
+ // eslint-disable-next-line max-lines-per-function
32
+ create(context) {
33
+ const parserServices = ESLintUtils.getParserServices(context);
34
+ const typeChecker = parserServices.program.getTypeChecker();
35
+
36
+ return {
37
+ 'MemberExpression[property.name="statusCode"]': (responseStatusCode: TSESTree.MemberExpression) => {
38
+ try {
39
+ const responseNode = parserServices.esTreeNodeToTSNodeMap.get(responseStatusCode.object);
40
+ const responseType = typeChecker.getTypeAtLocation(responseNode);
41
+
42
+ const shouldReplace =
43
+ responseType.getProperties().some((symbol) => symbol.name === 'status') &&
44
+ !responseType.getProperties().some((symbol) => symbol.name === 'statusCode');
45
+
46
+ if (shouldReplace) {
47
+ context.report({
48
+ messageId: 'replaceStatusCode',
49
+ node: responseStatusCode.property,
50
+ fix(fixer) {
51
+ return fixer.replaceText(responseStatusCode.property, 'status');
52
+ },
53
+ });
54
+ }
55
+ } catch (error) {
56
+ // eslint-disable-next-line no-console
57
+ console.error(`Failed to apply ${ruleId} rule for file "${context.filename}":`, error);
58
+ context.report({
59
+ node: responseStatusCode,
60
+ messageId: 'unknownError',
61
+ data: {
62
+ fileName: context.filename,
63
+ error: error instanceof Error ? error.toString() : JSON.stringify(error),
64
+ },
65
+ });
66
+ }
67
+ },
68
+ };
69
+ },
70
+ });
71
+
72
+ export default rule;
@@ -1,7 +1,7 @@
1
1
  // fixture/url.ts
2
2
 
3
3
  export const PLAIN_URL_REGEXP = /^[`']\/\w+(?<serviceNamePart>-\w+)*\/v\d+\/.+[`']$/u;
4
- export const TOKENIZED_URL_REGEXP = /^`\$\{(?<serviceNamePart>\w+_)*BASE_PATH\}\/.+`$/u;
4
+ export const TOKENIZED_URL_REGEXP = /^`\$\{(?<serviceNamePart>[A-Z]+_)*BASE_PATH\}\/.+`$/u;
5
5
 
6
6
  export function replaceEndpointUrlPrefixWithBasePath(url: string) {
7
7
  // eslint-disable-next-line no-template-curly-in-string