@checkdigit/eslint-plugin 7.6.0-PR.75-7ee9 → 7.6.0-PR.75-a611

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/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"@checkdigit/eslint-plugin","version":"7.6.0-PR.75-7ee9","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","import":"./dist-mjs/index.mjs","default":"./dist-mjs/index.mjs"}},"files":["src","dist-types","dist-mjs","!src/**/test/**","!src/**/*.test.ts","!src/**/*.spec.ts","!dist-types/**/test/**","!dist-types/**/*.test.d.ts","!dist-types/**/*.spec.d.ts","!dist-mjs/**/test/**","!dist-mjs/**/*.test.mjs","!dist-mjs/**/*.spec.mjs","SECURITY.md"],"scripts":{"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 .","lint:fix":"eslint --max-warnings 0 --fix .","prepare":"","prepublishOnly":"npm run build:dist-types && 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":"^8.15.0","@typescript-eslint/utils":"^8.15.0","debug":"^4.3.7","ts-api-utils":"^1.4.0"},"devDependencies":{"@checkdigit/jest-config":"^6.0.2","@checkdigit/prettier-config":"^5.5.1","@checkdigit/typescript-config":"^8.0.0","@eslint/js":"^9.15.0","@types/debug":"^4.1.12","@types/eslint":"^9.6.1","@types/eslint-config-prettier":"^6.11.3","@typescript-eslint/parser":"^8.15.0","@typescript-eslint/rule-tester":"^8.15.0","eslint":"^9.15.0","eslint-config-prettier":"^9.1.0","eslint-import-resolver-typescript":"^3.6.3","eslint-plugin-eslint-plugin":"^6.3.2","eslint-plugin-import":"^2.31.0","eslint-plugin-no-only-tests":"^3.3.0","eslint-plugin-no-secrets":"^1.1.2","eslint-plugin-node":"^11.1.0","eslint-plugin-sonarjs":"1.0.4","http-status-codes":"^2.3.0","rimraf":"^6.0.1","typescript-eslint":"^8.15.0"},"peerDependencies":{"eslint":">=9 <10"},"engines":{"node":">=20.17"}}
1
+ {"name":"@checkdigit/eslint-plugin","version":"7.6.0-PR.75-a611","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","import":"./dist-mjs/index.mjs","default":"./dist-mjs/index.mjs"}},"files":["src","dist-types","dist-mjs","!src/**/test/**","!src/**/*.test.ts","!src/**/*.spec.ts","!dist-types/**/test/**","!dist-types/**/*.test.d.ts","!dist-types/**/*.spec.d.ts","!dist-mjs/**/test/**","!dist-mjs/**/*.test.mjs","!dist-mjs/**/*.spec.mjs","SECURITY.md"],"scripts":{"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 .","lint:fix":"eslint --max-warnings 0 --fix .","prepare":"","prepublishOnly":"npm run build:dist-types && 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":"^8.15.0","@typescript-eslint/utils":"^8.15.0","debug":"^4.3.7","ts-api-utils":"^1.4.0"},"devDependencies":{"@checkdigit/jest-config":"^6.0.2","@checkdigit/prettier-config":"^5.5.1","@checkdigit/typescript-config":"^8.0.0","@eslint/js":"^9.15.0","@types/debug":"^4.1.12","@types/eslint":"^9.6.1","@types/eslint-config-prettier":"^6.11.3","@typescript-eslint/parser":"^8.15.0","@typescript-eslint/rule-tester":"^8.15.0","eslint":"^9.15.0","eslint-config-prettier":"^9.1.0","eslint-import-resolver-typescript":"^3.6.3","eslint-plugin-eslint-plugin":"^6.3.2","eslint-plugin-import":"^2.31.0","eslint-plugin-no-only-tests":"^3.3.0","eslint-plugin-no-secrets":"^1.1.2","eslint-plugin-node":"^11.1.0","eslint-plugin-sonarjs":"1.0.4","http-status-codes":"^2.3.0","rimraf":"^6.0.1","typescript-eslint":"^8.15.0"},"peerDependencies":{"eslint":">=9 <10"},"engines":{"node":">=20.17"}}
@@ -38,7 +38,7 @@ const rule: ESLintUtils.RuleModule<'unknownError' | 'replaceBodyWithJson' | 'ref
38
38
  },
39
39
  messages: {
40
40
  refactorNeeded:
41
- 'Please extract the fetch call and check its reponse status code before accessing its response body.',
41
+ 'Please extract the fetch call and check its response status code before accessing its response body.',
42
42
  replaceBodyWithJson: 'Replace "response.body" with "await response.json()".',
43
43
  unknownError: 'Unknown error occurred in file "{{fileName}}": {{ error }}.',
44
44
  },
@@ -8,15 +8,15 @@
8
8
 
9
9
  import { strict as assert } from 'node:assert';
10
10
 
11
- import { ScopeManager, Variable } from '@typescript-eslint/scope-manager';
11
+ // import { ScopeManager, Variable } from '@typescript-eslint/scope-manager';
12
12
  import { AST_NODE_TYPES, ESLintUtils, TSESTree } from '@typescript-eslint/utils';
13
13
  import type { SourceCode } from '@typescript-eslint/utils/ts-eslint';
14
14
 
15
- import { getEnclosingFunction, getEnclosingStatement, getParent, isUsedInArrayOrAsArgument } from '../library/ts-tree';
15
+ import { getEnclosingFunction, getParent, isUsedInArrayOrAsArgument } from '../library/ts-tree';
16
16
  import getDocumentationUrl from '../get-documentation-url';
17
17
  import { getIndentation } from '../library/format';
18
18
  import { isValidPropertyName } from '../library/variable';
19
- import { hasAssertions, isInvalidResponseHeadersAccess } from './fetch';
19
+ import { hasAssertions } from './fetch';
20
20
  import { replaceEndpointUrlPrefixWithBasePath } from './url';
21
21
 
22
22
  export const ruleId = 'fetch-then';
@@ -143,52 +143,52 @@ function createResponseAssertions(
143
143
  };
144
144
  }
145
145
 
146
- function getResponseHeadersAccesses(responseVariables: Variable[], scopeManager: ScopeManager, sourceCode: SourceCode) {
147
- const responseHeadersAccesses: TSESTree.MemberExpression[] = [];
148
- for (const responseVariable of responseVariables) {
149
- for (const responseReference of responseVariable.references) {
150
- const responseAccess = getParent(responseReference.identifier);
151
- if (!responseAccess || responseAccess.type !== AST_NODE_TYPES.MemberExpression) {
152
- continue;
153
- }
146
+ // function getResponseHeadersAccesses(responseVariables: Variable[], scopeManager: ScopeManager, sourceCode: SourceCode) {
147
+ // const responseHeadersAccesses: TSESTree.MemberExpression[] = [];
148
+ // for (const responseVariable of responseVariables) {
149
+ // for (const responseReference of responseVariable.references) {
150
+ // const responseAccess = getParent(responseReference.identifier);
151
+ // if (!responseAccess || responseAccess.type !== AST_NODE_TYPES.MemberExpression) {
152
+ // continue;
153
+ // }
154
154
 
155
- const responseAccessParent = getParent(responseAccess);
156
- if (!responseAccessParent) {
157
- continue;
158
- }
155
+ // const responseAccessParent = getParent(responseAccess);
156
+ // if (!responseAccessParent) {
157
+ // continue;
158
+ // }
159
159
 
160
- if (
161
- responseAccessParent.type === AST_NODE_TYPES.CallExpression &&
162
- responseAccessParent.arguments[0]?.type === AST_NODE_TYPES.ArrowFunctionExpression
163
- ) {
164
- // map-like operation against responses, e.g. responses.map((response) => response.headers.etag)
165
- responseHeadersAccesses.push(
166
- ...getResponseHeadersAccesses(
167
- scopeManager.getDeclaredVariables(responseAccessParent.arguments[0]),
168
- scopeManager,
169
- sourceCode,
170
- ),
171
- );
172
- continue;
173
- }
160
+ // if (
161
+ // responseAccessParent.type === AST_NODE_TYPES.CallExpression &&
162
+ // responseAccessParent.arguments[0]?.type === AST_NODE_TYPES.ArrowFunctionExpression
163
+ // ) {
164
+ // // map-like operation against responses, e.g. responses.map((response) => response.headers.etag)
165
+ // responseHeadersAccesses.push(
166
+ // ...getResponseHeadersAccesses(
167
+ // scopeManager.getDeclaredVariables(responseAccessParent.arguments[0]),
168
+ // scopeManager,
169
+ // sourceCode,
170
+ // ),
171
+ // );
172
+ // continue;
173
+ // }
174
174
 
175
- if (
176
- responseAccess.computed &&
177
- responseAccess.property.type === AST_NODE_TYPES.Literal &&
178
- responseAccessParent.type === AST_NODE_TYPES.MemberExpression
179
- ) {
180
- // header access through indexed responses array, e.g. responses[0].headers, responses[1].get(...), etc.
181
- responseHeadersAccesses.push(responseAccessParent);
182
- } else {
183
- responseHeadersAccesses.push(responseAccess);
184
- }
185
- }
186
- }
187
- return responseHeadersAccesses;
188
- }
175
+ // if (
176
+ // responseAccess.computed &&
177
+ // responseAccess.property.type === AST_NODE_TYPES.Literal &&
178
+ // responseAccessParent.type === AST_NODE_TYPES.MemberExpression
179
+ // ) {
180
+ // // header access through indexed responses array, e.g. responses[0].headers, responses[1].get(...), etc.
181
+ // responseHeadersAccesses.push(responseAccessParent);
182
+ // } else {
183
+ // responseHeadersAccesses.push(responseAccess);
184
+ // }
185
+ // }
186
+ // }
187
+ // return responseHeadersAccesses;
188
+ // }
189
189
 
190
190
  const createRule = ESLintUtils.RuleCreator((name) => getDocumentationUrl(name));
191
- const rule: ESLintUtils.RuleModule<'unknownError' | 'preferNativeFetch' | 'shouldUseHeaderGetter'> = createRule({
191
+ const rule: ESLintUtils.RuleModule<'unknownError' | 'preferNativeFetch'> = createRule({
192
192
  name: ruleId,
193
193
  meta: {
194
194
  type: 'suggestion',
@@ -198,7 +198,7 @@ const rule: ESLintUtils.RuleModule<'unknownError' | 'preferNativeFetch' | 'shoul
198
198
  },
199
199
  messages: {
200
200
  preferNativeFetch: 'Prefer native fetch API over customized fixture API.',
201
- shouldUseHeaderGetter: 'Getter should be used to access response headers.',
201
+ // shouldUseHeaderGetter: 'Getter should be used to access response headers.',
202
202
  unknownError: 'Unknown error occurred in file "{{fileName}}": {{ error }}.',
203
203
  },
204
204
  fixable: 'code',
@@ -213,7 +213,6 @@ const rule: ESLintUtils.RuleModule<'unknownError' | 'preferNativeFetch' | 'shoul
213
213
  return {
214
214
  'CallExpression[callee.object.object.name="fixture"][callee.object.property.name="api"]': (
215
215
  fixtureCall: TSESTree.CallExpression,
216
- // eslint-disable-next-line sonarjs/cognitive-complexity
217
216
  ) => {
218
217
  try {
219
218
  if (!hasAssertions(fixtureCall)) {
@@ -294,51 +293,51 @@ const rule: ESLintUtils.RuleModule<'unknownError' | 'preferNativeFetch' | 'shoul
294
293
  },
295
294
  });
296
295
 
297
- const responsesVariable = getEnclosingStatement(fixtureCallInformation.fixtureNode);
298
- if (!responsesVariable) {
299
- return;
300
- }
296
+ // const responsesVariable = getEnclosingStatement(fixtureCallInformation.fixtureNode);
297
+ // if (!responsesVariable) {
298
+ // return;
299
+ // }
301
300
 
302
- const responseVariableReferences = scopeManager.getDeclaredVariables(responsesVariable);
303
- const responseHeadersAccesses = getResponseHeadersAccesses(
304
- responseVariableReferences,
305
- scopeManager,
306
- sourceCode,
307
- );
308
- for (const responseHeadersAccess of responseHeadersAccesses) {
309
- if (isInvalidResponseHeadersAccess(responseHeadersAccess)) {
310
- const headerAccess = getParent(responseHeadersAccess);
311
- if (headerAccess?.type === AST_NODE_TYPES.MemberExpression) {
312
- const headerNameNode = headerAccess.property;
313
- const headerName = headerAccess.computed
314
- ? sourceCode.getText(headerNameNode)
315
- : `'${sourceCode.getText(headerNameNode)}'`;
316
- const headerAccessReplacementText = `${sourceCode.getText(headerAccess.object)}.get(${headerName})`;
301
+ // const responseVariableReferences = scopeManager.getDeclaredVariables(responsesVariable);
302
+ // const responseHeadersAccesses = getResponseHeadersAccesses(
303
+ // responseVariableReferences,
304
+ // scopeManager,
305
+ // sourceCode,
306
+ // );
307
+ // for (const responseHeadersAccess of responseHeadersAccesses) {
308
+ // if (isInvalidResponseHeadersAccess(responseHeadersAccess)) {
309
+ // const headerAccess = getParent(responseHeadersAccess);
310
+ // if (headerAccess?.type === AST_NODE_TYPES.MemberExpression) {
311
+ // const headerNameNode = headerAccess.property;
312
+ // const headerName = headerAccess.computed
313
+ // ? sourceCode.getText(headerNameNode)
314
+ // : `'${sourceCode.getText(headerNameNode)}'`;
315
+ // const headerAccessReplacementText = `${sourceCode.getText(headerAccess.object)}.get(${headerName})`;
317
316
 
318
- context.report({
319
- node: headerAccess,
320
- messageId: 'shouldUseHeaderGetter',
321
- fix(fixer) {
322
- return fixer.replaceText(headerAccess, headerAccessReplacementText);
323
- },
324
- });
325
- } else if (
326
- headerAccess?.type === AST_NODE_TYPES.CallExpression &&
327
- responseHeadersAccess.property.type === AST_NODE_TYPES.Identifier &&
328
- responseHeadersAccess.property.name === 'get'
329
- ) {
330
- const headerAccessReplacementText = `${sourceCode.getText(responseHeadersAccess.object)}.headers.get(${sourceCode.getText(headerAccess.arguments[0])})`;
317
+ // context.report({
318
+ // node: headerAccess,
319
+ // messageId: 'shouldUseHeaderGetter',
320
+ // fix(fixer) {
321
+ // return fixer.replaceText(headerAccess, headerAccessReplacementText);
322
+ // },
323
+ // });
324
+ // } else if (
325
+ // headerAccess?.type === AST_NODE_TYPES.CallExpression &&
326
+ // responseHeadersAccess.property.type === AST_NODE_TYPES.Identifier &&
327
+ // responseHeadersAccess.property.name === 'get'
328
+ // ) {
329
+ // const headerAccessReplacementText = `${sourceCode.getText(responseHeadersAccess.object)}.headers.get(${sourceCode.getText(headerAccess.arguments[0])})`;
331
330
 
332
- context.report({
333
- node: headerAccess,
334
- messageId: 'shouldUseHeaderGetter',
335
- fix(fixer) {
336
- return fixer.replaceText(headerAccess, headerAccessReplacementText);
337
- },
338
- });
339
- }
340
- }
341
- }
331
+ // context.report({
332
+ // node: headerAccess,
333
+ // messageId: 'shouldUseHeaderGetter',
334
+ // fix(fixer) {
335
+ // return fixer.replaceText(headerAccess, headerAccessReplacementText);
336
+ // },
337
+ // });
338
+ // }
339
+ // }
340
+ // }
342
341
  } catch (error) {
343
342
  // eslint-disable-next-line no-console
344
343
  console.error(`Failed to apply ${ruleId} rule for file "${context.filename}":`, error);
@@ -63,7 +63,9 @@ export function hasAssertions(fixtureCall: TSESTree.Node): boolean {
63
63
 
64
64
  export function isFetchResponse(type: ts.Type): boolean {
65
65
  return (
66
- type.getProperties().some((symbol) => symbol.name === 'body') &&
67
- type.getProperties().some((symbol) => symbol.name === 'json')
66
+ type.getProperties().some((symbol) => symbol.name === 'json') &&
67
+ type.getProperties().some((symbol) => symbol.name === 'status') &&
68
+ type.getProperties().some((symbol) => symbol.name === 'headers') &&
69
+ type.getProperties().some((symbol) => symbol.name === 'body')
68
70
  );
69
71
  }