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

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.
Files changed (77) hide show
  1. package/dist-mjs/index.mjs +8 -156
  2. package/dist-mjs/no-status-code-assert.mjs +63 -0
  3. package/dist-mjs/require-resolve-full-response.mjs +5 -5
  4. package/dist-types/no-status-code-assert.d.ts +5 -0
  5. package/package.json +1 -1
  6. package/src/index.ts +4 -152
  7. package/src/no-status-code-assert.ts +85 -0
  8. package/src/require-resolve-full-response.ts +4 -4
  9. package/dist-mjs/agent/add-assert-import.mjs +0 -58
  10. package/dist-mjs/agent/add-base-path-const.mjs +0 -65
  11. package/dist-mjs/agent/add-base-path-import.mjs +0 -60
  12. package/dist-mjs/agent/add-url-domain.mjs +0 -61
  13. package/dist-mjs/agent/agent-test-wiring.mjs +0 -221
  14. package/dist-mjs/agent/fetch-response-body-json.mjs +0 -146
  15. package/dist-mjs/agent/fetch-response-header-getter.mjs +0 -117
  16. package/dist-mjs/agent/fetch-response-status.mjs +0 -76
  17. package/dist-mjs/agent/fetch-then.mjs +0 -273
  18. package/dist-mjs/agent/fetch.mjs +0 -48
  19. package/dist-mjs/agent/file.mjs +0 -43
  20. package/dist-mjs/agent/fix-function-call-arguments.mjs +0 -153
  21. package/dist-mjs/agent/no-fixture.mjs +0 -397
  22. package/dist-mjs/agent/no-mapped-response.mjs +0 -75
  23. package/dist-mjs/agent/no-service-wrapper.mjs +0 -185
  24. package/dist-mjs/agent/no-status-code.mjs +0 -59
  25. package/dist-mjs/agent/no-supertest.mjs +0 -346
  26. package/dist-mjs/agent/no-unused-function-argument.mjs +0 -79
  27. package/dist-mjs/agent/no-unused-imports.mjs +0 -81
  28. package/dist-mjs/agent/no-unused-service-variable.mjs +0 -74
  29. package/dist-mjs/agent/response-reference.mjs +0 -78
  30. package/dist-mjs/agent/supertest-then.mjs +0 -170
  31. package/dist-mjs/agent/url.mjs +0 -32
  32. package/dist-types/agent/add-assert-import.d.ts +0 -4
  33. package/dist-types/agent/add-base-path-const.d.ts +0 -4
  34. package/dist-types/agent/add-base-path-import.d.ts +0 -4
  35. package/dist-types/agent/add-url-domain.d.ts +0 -4
  36. package/dist-types/agent/agent-test-wiring.d.ts +0 -4
  37. package/dist-types/agent/fetch-response-body-json.d.ts +0 -4
  38. package/dist-types/agent/fetch-response-header-getter.d.ts +0 -4
  39. package/dist-types/agent/fetch-response-status.d.ts +0 -4
  40. package/dist-types/agent/fetch-then.d.ts +0 -4
  41. package/dist-types/agent/fetch.d.ts +0 -8
  42. package/dist-types/agent/file.d.ts +0 -7
  43. package/dist-types/agent/fix-function-call-arguments.d.ts +0 -9
  44. package/dist-types/agent/no-fixture.d.ts +0 -4
  45. package/dist-types/agent/no-mapped-response.d.ts +0 -4
  46. package/dist-types/agent/no-service-wrapper.d.ts +0 -4
  47. package/dist-types/agent/no-status-code.d.ts +0 -4
  48. package/dist-types/agent/no-supertest.d.ts +0 -4
  49. package/dist-types/agent/no-unused-function-argument.d.ts +0 -4
  50. package/dist-types/agent/no-unused-imports.d.ts +0 -4
  51. package/dist-types/agent/no-unused-service-variable.d.ts +0 -4
  52. package/dist-types/agent/response-reference.d.ts +0 -17
  53. package/dist-types/agent/supertest-then.d.ts +0 -4
  54. package/dist-types/agent/url.d.ts +0 -4
  55. package/src/agent/add-assert-import.ts +0 -74
  56. package/src/agent/add-base-path-const.ts +0 -81
  57. package/src/agent/add-base-path-import.ts +0 -69
  58. package/src/agent/add-url-domain.ts +0 -76
  59. package/src/agent/agent-test-wiring.ts +0 -273
  60. package/src/agent/fetch-response-body-json.ts +0 -194
  61. package/src/agent/fetch-response-header-getter.ts +0 -148
  62. package/src/agent/fetch-response-status.ts +0 -100
  63. package/src/agent/fetch-then.ts +0 -359
  64. package/src/agent/fetch.ts +0 -69
  65. package/src/agent/file.ts +0 -42
  66. package/src/agent/fix-function-call-arguments.ts +0 -200
  67. package/src/agent/no-fixture.ts +0 -581
  68. package/src/agent/no-mapped-response.ts +0 -84
  69. package/src/agent/no-service-wrapper.ts +0 -241
  70. package/src/agent/no-status-code.ts +0 -69
  71. package/src/agent/no-supertest.ts +0 -517
  72. package/src/agent/no-unused-function-argument.ts +0 -98
  73. package/src/agent/no-unused-imports.ts +0 -103
  74. package/src/agent/no-unused-service-variable.ts +0 -93
  75. package/src/agent/response-reference.ts +0 -153
  76. package/src/agent/supertest-then.ts +0 -230
  77. package/src/agent/url.ts +0 -32
@@ -0,0 +1,85 @@
1
+ // no-status-code-assert.ts
2
+
3
+ /*
4
+ * Copyright (c) 2022-2024 Check Digit, LLC
5
+ *
6
+ * This code is licensed under the MIT license (see LICENSE.txt for details).
7
+ */
8
+
9
+ import { AST_NODE_TYPES, ESLintUtils, TSESLint, TSESTree } from '@typescript-eslint/utils';
10
+ import getDocumentationUrl from './get-documentation-url';
11
+
12
+ export const ruleId = 'no-status-code-assert';
13
+ const NO_STATUS_CODE_ASSERT = 'NO_STATUS_CODE_ASSERT';
14
+ const keywords = ['status', 'code', 'StatusCodes', 'statusCode'];
15
+
16
+ const createRule = ESLintUtils.RuleCreator((name) => getDocumentationUrl(name));
17
+
18
+ /**
19
+ * Checks if a given string contains any of the specified keywords ('status', 'code', 'StatusCodes', or 'statusCode').
20
+ *
21
+ * @param name - The string to check.
22
+ * @returns `true` if the string contains any of the specified keywords, otherwise `false`.
23
+ */
24
+ const checkName = (name?: string): boolean =>
25
+ name !== undefined && keywords.some((keyword) => name.toLowerCase().includes(keyword));
26
+
27
+ /**
28
+ * Checks if a given AST node contains any identifier, member expression, or binary expression
29
+ * that includes the keywords 'status', 'code', 'StatusCodes', or 'statusCode'.
30
+ *
31
+ * @param arg - The AST node to check.
32
+ * @returns `true` if the node or its sub-nodes contain any of the specified keywords, otherwise `false`.
33
+ */
34
+ const hasStatusCodeOrValue = (arg: TSESTree.Node): boolean => {
35
+ switch (arg.type) {
36
+ case AST_NODE_TYPES.Identifier:
37
+ return checkName(arg.name);
38
+ case AST_NODE_TYPES.MemberExpression: {
39
+ const object = arg.object;
40
+ const property = arg.property;
41
+ if (object.type === AST_NODE_TYPES.Identifier && checkName(object.name)) {
42
+ return true;
43
+ }
44
+ if (property.type === AST_NODE_TYPES.Identifier) {
45
+ return checkName(property.name);
46
+ }
47
+ if (property.type === AST_NODE_TYPES.Literal && typeof property.value === 'string') {
48
+ return checkName(property.value);
49
+ }
50
+ break;
51
+ }
52
+ case AST_NODE_TYPES.BinaryExpression:
53
+ return hasStatusCodeOrValue(arg.left) || hasStatusCodeOrValue(arg.right);
54
+ }
55
+ return false;
56
+ };
57
+
58
+ const rule: TSESLint.RuleModule<typeof NO_STATUS_CODE_ASSERT> = createRule({
59
+ name: ruleId,
60
+ meta: {
61
+ type: 'problem',
62
+ docs: {
63
+ description: 'Disallow the use of status, code, or value as parameter in assert',
64
+ },
65
+ schema: [],
66
+ messages: {
67
+ [NO_STATUS_CODE_ASSERT]: 'Avoid using status, code, or value in assert',
68
+ },
69
+ },
70
+ defaultOptions: [],
71
+ create(context) {
72
+ return {
73
+ CallExpression(node: TSESTree.CallExpression) {
74
+ if (node.arguments.some(hasStatusCodeOrValue)) {
75
+ context.report({
76
+ node,
77
+ messageId: NO_STATUS_CODE_ASSERT,
78
+ });
79
+ }
80
+ },
81
+ };
82
+ },
83
+ });
84
+
85
+ export default rule;
@@ -38,8 +38,8 @@ const rule: ESLintUtils.RuleModule<'invalidOptions' | 'unknownError'> = createRu
38
38
  create(context) {
39
39
  const sourceCode = context.sourceCode;
40
40
  const scopeManager = sourceCode.scopeManager;
41
- const parserServices = ESLintUtils.getParserServices(context);
42
- const typeChecker = parserServices.program.getTypeChecker();
41
+ const parserService = ESLintUtils.getParserServices(context);
42
+ const typeChecker = parserService.program.getTypeChecker();
43
43
 
44
44
  function isUrlArgumentValid(urlArgument: TSESTree.Node | undefined, scope: Scope) {
45
45
  if (
@@ -67,7 +67,7 @@ const rule: ESLintUtils.RuleModule<'invalidOptions' | 'unknownError'> = createRu
67
67
  }
68
68
 
69
69
  function getType(identifier: TSESTree.Identifier) {
70
- const variable = parserServices.esTreeNodeToTSNodeMap.get(identifier);
70
+ const variable = parserService.esTreeNodeToTSNodeMap.get(identifier);
71
71
  const variableType = typeChecker.getTypeAtLocation(variable);
72
72
  return typeChecker.typeToString(variableType);
73
73
  }
@@ -171,7 +171,7 @@ const rule: ESLintUtils.RuleModule<'invalidOptions' | 'unknownError'> = createRu
171
171
  if (optionsTypeString === 'FullResponseOptions') {
172
172
  return;
173
173
  }
174
- const variable = parserServices.esTreeNodeToTSNodeMap.get(optionsArgument);
174
+ const variable = parserService.esTreeNodeToTSNodeMap.get(optionsArgument);
175
175
  const optionType = typeChecker.getTypeAtLocation(variable);
176
176
  const resolveWithFullResponseProperty = optionType.getProperty('resolveWithFullResponse');
177
177
  if (resolveWithFullResponseProperty?.declarations?.[0]?.getText() === 'resolveWithFullResponse: true') {
@@ -1,58 +0,0 @@
1
- // src/agent/add-assert-import.ts
2
- import { strict as assert } from "node:assert";
3
- import { AST_NODE_TYPES, ESLintUtils } from "@typescript-eslint/utils";
4
- import getDocumentationUrl from "../get-documentation-url.mjs";
5
- var ruleId = "add-assert-import";
6
- var ASSERT_IMPORT_STATEMENT = "import { strict as assert } from 'node:assert';";
7
- var createRule = ESLintUtils.RuleCreator((name) => getDocumentationUrl(name));
8
- var rule = createRule({
9
- name: ruleId,
10
- meta: {
11
- type: "suggestion",
12
- docs: {
13
- description: "Add import of assert module of node."
14
- },
15
- messages: {
16
- addAssertImport: "Add import of assert module of node."
17
- },
18
- fixable: "code",
19
- schema: []
20
- },
21
- defaultOptions: [],
22
- create(context) {
23
- let isAssertImported = false;
24
- let isAssertUsed = false;
25
- return {
26
- ImportDeclaration: (node) => {
27
- if (node.source.value === "assert" || node.source.value === "node:assert") {
28
- isAssertImported = true;
29
- }
30
- },
31
- CallExpression: (callExpression) => {
32
- if (callExpression.callee.type === AST_NODE_TYPES.Identifier && callExpression.callee.name === "assert" || callExpression.callee.type === AST_NODE_TYPES.MemberExpression && callExpression.callee.object.type === AST_NODE_TYPES.Identifier && callExpression.callee.object.name === "assert") {
33
- isAssertUsed = true;
34
- }
35
- },
36
- "Program:exit": (program) => {
37
- if (isAssertUsed && !isAssertImported) {
38
- const firstStatement = program.body[0];
39
- assert(firstStatement);
40
- context.report({
41
- node: program,
42
- messageId: "addAssertImport",
43
- fix(fixer) {
44
- return fixer.insertTextBefore(firstStatement, `${ASSERT_IMPORT_STATEMENT}
45
- `);
46
- }
47
- });
48
- }
49
- }
50
- };
51
- }
52
- });
53
- var add_assert_import_default = rule;
54
- export {
55
- add_assert_import_default as default,
56
- ruleId
57
- };
58
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2FnZW50L2FkZC1hc3NlcnQtaW1wb3J0LnRzIl0sCiAgIm1hcHBpbmdzIjogIjtBQVFBLFNBQVMsVUFBVSxjQUFjO0FBRWpDLFNBQVMsZ0JBQWdCLG1CQUFtQjtBQUU1QyxPQUFPLHlCQUF5QjtBQUV6QixJQUFNLFNBQVM7QUFFdEIsSUFBTSwwQkFBMEI7QUFFaEMsSUFBTSxhQUFhLFlBQVksWUFBWSxDQUFDLFNBQVMsb0JBQW9CLElBQUksQ0FBQztBQUU5RSxJQUFNLE9BQWtELFdBQVc7QUFBQSxFQUNqRSxNQUFNO0FBQUEsRUFDTixNQUFNO0FBQUEsSUFDSixNQUFNO0FBQUEsSUFDTixNQUFNO0FBQUEsTUFDSixhQUFhO0FBQUEsSUFDZjtBQUFBLElBQ0EsVUFBVTtBQUFBLE1BQ1IsaUJBQWlCO0FBQUEsSUFDbkI7QUFBQSxJQUNBLFNBQVM7QUFBQSxJQUNULFFBQVEsQ0FBQztBQUFBLEVBQ1g7QUFBQSxFQUNBLGdCQUFnQixDQUFDO0FBQUEsRUFDakIsT0FBTyxTQUFTO0FBQ2QsUUFBSSxtQkFBbUI7QUFDdkIsUUFBSSxlQUFlO0FBRW5CLFdBQU87QUFBQSxNQUNMLG1CQUFtQixDQUFDLFNBQVM7QUFDM0IsWUFBSSxLQUFLLE9BQU8sVUFBVSxZQUFZLEtBQUssT0FBTyxVQUFVLGVBQWU7QUFDekUsNkJBQW1CO0FBQUEsUUFDckI7QUFBQSxNQUNGO0FBQUEsTUFDQSxnQkFBZ0IsQ0FBQyxtQkFBbUI7QUFFbEMsWUFDRyxlQUFlLE9BQU8sU0FBUyxlQUFlLGNBQWMsZUFBZSxPQUFPLFNBQVMsWUFDM0YsZUFBZSxPQUFPLFNBQVMsZUFBZSxvQkFDN0MsZUFBZSxPQUFPLE9BQU8sU0FBUyxlQUFlLGNBQ3JELGVBQWUsT0FBTyxPQUFPLFNBQVMsVUFDeEM7QUFDQSx5QkFBZTtBQUFBLFFBQ2pCO0FBQUEsTUFDRjtBQUFBLE1BQ0EsZ0JBQWdCLENBQUMsWUFBWTtBQUUzQixZQUFJLGdCQUFnQixDQUFDLGtCQUFrQjtBQUNyQyxnQkFBTSxpQkFBaUIsUUFBUSxLQUFLLENBQUM7QUFDckMsaUJBQU8sY0FBYztBQUNyQixrQkFBUSxPQUFPO0FBQUEsWUFDYixNQUFNO0FBQUEsWUFDTixXQUFXO0FBQUEsWUFDWCxJQUFJLE9BQU87QUFDVCxxQkFBTyxNQUFNLGlCQUFpQixnQkFBZ0IsR0FBRyx1QkFBdUI7QUFBQSxDQUFJO0FBQUEsWUFDOUU7QUFBQSxVQUNGLENBQUM7QUFBQSxRQUNIO0FBQUEsTUFDRjtBQUFBLElBQ0Y7QUFBQSxFQUNGO0FBQ0YsQ0FBQztBQUVELElBQU8sNEJBQVE7IiwKICAibmFtZXMiOiBbXQp9Cg==
@@ -1,65 +0,0 @@
1
- // src/agent/add-base-path-const.ts
2
- import { strict as assert } from "node:assert";
3
- import { AST_NODE_TYPES, ESLintUtils } from "@typescript-eslint/utils";
4
- import getDocumentationUrl from "../get-documentation-url.mjs";
5
- import { getProjectRootFolder, getSwaggerPathByIndexFile, isApiIndexFile, loadPackageJson, loadSwagger } from "./file.mjs";
6
- var ruleId = "add-base-path-const";
7
- var createRule = ESLintUtils.RuleCreator((name) => getDocumentationUrl(name));
8
- var rule = createRule({
9
- name: ruleId,
10
- meta: {
11
- type: "suggestion",
12
- docs: {
13
- description: "Add BASE_PATH const variable."
14
- },
15
- messages: {
16
- addBasePathConst: "Add BASE_PATH const variable."
17
- },
18
- fixable: "code",
19
- schema: []
20
- },
21
- defaultOptions: [],
22
- create(context) {
23
- const sourceCode = context.sourceCode;
24
- return {
25
- Program: (program) => {
26
- if (!isApiIndexFile(context.filename)) {
27
- return;
28
- }
29
- const scope = sourceCode.getScope(program).childScopes[0];
30
- assert(scope);
31
- const foundBasePathConst = scope.variables.find((variable) => variable.name === "BASE_PATH");
32
- if (foundBasePathConst) {
33
- return;
34
- }
35
- const swaggerPath = getSwaggerPathByIndexFile(context.filename);
36
- const swaggerFileContents = loadSwagger(swaggerPath);
37
- const baseUrlLine = swaggerFileContents.split("\n").find((line) => /^\s*-\s*url:\s*\/.*$/u.test(line) || /^basePath:.*/u.test(line));
38
- const baseUrl = baseUrlLine?.split(":")[1]?.trim();
39
- assert(baseUrl !== void 0);
40
- const packageRoot = getProjectRootFolder(context.filename);
41
- const packageJson = JSON.parse(loadPackageJson(packageRoot));
42
- const serviceName = packageJson.name.split("/")[1];
43
- assert(serviceName !== void 0);
44
- const domain = `https://${serviceName}.checkdigit${baseUrl}`;
45
- const lastImportStatement = program.body.findLast((node) => node.type === AST_NODE_TYPES.ImportDeclaration);
46
- assert(lastImportStatement);
47
- context.report({
48
- messageId: "addBasePathConst",
49
- node: program,
50
- fix(fixer) {
51
- return fixer.insertTextAfter(lastImportStatement, `
52
- export const BASE_PATH = '${domain}';
53
- `);
54
- }
55
- });
56
- }
57
- };
58
- }
59
- });
60
- var add_base_path_const_default = rule;
61
- export {
62
- add_base_path_const_default as default,
63
- ruleId
64
- };
65
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2FnZW50L2FkZC1iYXNlLXBhdGgtY29uc3QudHMiXSwKICAibWFwcGluZ3MiOiAiO0FBUUEsU0FBUyxVQUFVLGNBQWM7QUFFakMsU0FBUyxnQkFBZ0IsbUJBQTZCO0FBRXRELE9BQU8seUJBQXlCO0FBQ2hDLFNBQVMsc0JBQXNCLDJCQUEyQixnQkFBZ0IsaUJBQWlCLG1CQUFtQjtBQUV2RyxJQUFNLFNBQVM7QUFFdEIsSUFBTSxhQUFhLFlBQVksWUFBWSxDQUFDLFNBQVMsb0JBQW9CLElBQUksQ0FBQztBQUU5RSxJQUFNLE9BQW1ELFdBQVc7QUFBQSxFQUNsRSxNQUFNO0FBQUEsRUFDTixNQUFNO0FBQUEsSUFDSixNQUFNO0FBQUEsSUFDTixNQUFNO0FBQUEsTUFDSixhQUFhO0FBQUEsSUFDZjtBQUFBLElBQ0EsVUFBVTtBQUFBLE1BQ1Isa0JBQWtCO0FBQUEsSUFDcEI7QUFBQSxJQUNBLFNBQVM7QUFBQSxJQUNULFFBQVEsQ0FBQztBQUFBLEVBQ1g7QUFBQSxFQUNBLGdCQUFnQixDQUFDO0FBQUEsRUFDakIsT0FBTyxTQUFTO0FBQ2QsVUFBTSxhQUFhLFFBQVE7QUFFM0IsV0FBTztBQUFBLE1BQ0wsU0FBUyxDQUFDLFlBQThCO0FBQ3RDLFlBQUksQ0FBQyxlQUFlLFFBQVEsUUFBUSxHQUFHO0FBQ3JDO0FBQUEsUUFDRjtBQUVBLGNBQU0sUUFBUSxXQUFXLFNBQVMsT0FBTyxFQUFFLFlBQVksQ0FBQztBQUN4RCxlQUFPLEtBQUs7QUFFWixjQUFNLHFCQUFxQixNQUFNLFVBQVUsS0FBSyxDQUFDLGFBQWEsU0FBUyxTQUFTLFdBQVc7QUFDM0YsWUFBSSxvQkFBb0I7QUFDdEI7QUFBQSxRQUNGO0FBRUEsY0FBTSxjQUFjLDBCQUEwQixRQUFRLFFBQVE7QUFDOUQsY0FBTSxzQkFBc0IsWUFBWSxXQUFXO0FBQ25ELGNBQU0sY0FBYyxvQkFDakIsTUFBTSxJQUFJLEVBQ1YsS0FBSyxDQUFDLFNBQVMsd0JBQXdCLEtBQUssSUFBSSxLQUFLLGdCQUFnQixLQUFLLElBQUksQ0FBQztBQUNsRixjQUFNLFVBQVUsYUFBYSxNQUFNLEdBQUcsRUFBRSxDQUFDLEdBQUcsS0FBSztBQUNqRCxlQUFPLFlBQVksTUFBUztBQUU1QixjQUFNLGNBQWMscUJBQXFCLFFBQVEsUUFBUTtBQUN6RCxjQUFNLGNBQWMsS0FBSyxNQUFNLGdCQUFnQixXQUFXLENBQUM7QUFDM0QsY0FBTSxjQUFjLFlBQVksS0FBSyxNQUFNLEdBQUcsRUFBRSxDQUFDO0FBQ2pELGVBQU8sZ0JBQWdCLE1BQVM7QUFFaEMsY0FBTSxTQUFTLFdBQVcsV0FBVyxjQUFjLE9BQU87QUFFMUQsY0FBTSxzQkFBc0IsUUFBUSxLQUFLLFNBQVMsQ0FBQyxTQUFTLEtBQUssU0FBUyxlQUFlLGlCQUFpQjtBQUMxRyxlQUFPLG1CQUFtQjtBQUUxQixnQkFBUSxPQUFPO0FBQUEsVUFDYixXQUFXO0FBQUEsVUFDWCxNQUFNO0FBQUEsVUFDTixJQUFJLE9BQU87QUFDVCxtQkFBTyxNQUFNLGdCQUFnQixxQkFBcUI7QUFBQSw0QkFBK0IsTUFBTTtBQUFBLENBQU07QUFBQSxVQUMvRjtBQUFBLFFBQ0YsQ0FBQztBQUFBLE1BQ0g7QUFBQSxJQUNGO0FBQUEsRUFDRjtBQUNGLENBQUM7QUFFRCxJQUFPLDhCQUFROyIsCiAgIm5hbWVzIjogW10KfQo=
@@ -1,60 +0,0 @@
1
- // src/agent/add-base-path-import.ts
2
- import { strict as assert } from "node:assert";
3
- import { AST_NODE_TYPES, ESLintUtils } from "@typescript-eslint/utils";
4
- import getDocumentationUrl from "../get-documentation-url.mjs";
5
- import { getApiIndexPathByFilename } from "./file.mjs";
6
- var ruleId = "add-base-path-import";
7
- var createRule = ESLintUtils.RuleCreator((name) => getDocumentationUrl(name));
8
- var rule = createRule({
9
- name: ruleId,
10
- meta: {
11
- type: "suggestion",
12
- docs: {
13
- description: "Add import of BASE_PATH if it is used but not imported."
14
- },
15
- messages: {
16
- addBasePathImport: "Add import of BASE_PATH."
17
- },
18
- fixable: "code",
19
- schema: []
20
- },
21
- defaultOptions: [],
22
- create(context) {
23
- const sourceCode = context.sourceCode;
24
- return {
25
- Program: (program) => {
26
- const isBasePathUsed = sourceCode.text.includes(`\${BASE_PATH}`);
27
- if (isBasePathUsed) {
28
- const topScope = sourceCode.getScope(program).childScopes[0];
29
- assert(topScope);
30
- if (topScope.variables.some((variable) => variable.name === "BASE_PATH")) {
31
- return;
32
- }
33
- const apiIndexPath = getApiIndexPathByFilename(context.filename);
34
- if (apiIndexPath !== void 0) {
35
- const lastImportStatement = program.body.findLast(
36
- (statement) => statement.type === AST_NODE_TYPES.ImportDeclaration
37
- );
38
- assert(lastImportStatement);
39
- const basePathImportStatement = `
40
- import { BASE_PATH } from '${apiIndexPath}';
41
- `;
42
- context.report({
43
- node: program,
44
- messageId: "addBasePathImport",
45
- fix(fixer) {
46
- return fixer.insertTextAfter(lastImportStatement, basePathImportStatement);
47
- }
48
- });
49
- }
50
- }
51
- }
52
- };
53
- }
54
- });
55
- var add_base_path_import_default = rule;
56
- export {
57
- add_base_path_import_default as default,
58
- ruleId
59
- };
60
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2FnZW50L2FkZC1iYXNlLXBhdGgtaW1wb3J0LnRzIl0sCiAgIm1hcHBpbmdzIjogIjtBQVFBLFNBQVMsVUFBVSxjQUFjO0FBRWpDLFNBQVMsZ0JBQWdCLG1CQUFtQjtBQUU1QyxPQUFPLHlCQUF5QjtBQUNoQyxTQUFTLGlDQUFpQztBQUVuQyxJQUFNLFNBQVM7QUFFdEIsSUFBTSxhQUFhLFlBQVksWUFBWSxDQUFDLFNBQVMsb0JBQW9CLElBQUksQ0FBQztBQUU5RSxJQUFNLE9BQW9ELFdBQVc7QUFBQSxFQUNuRSxNQUFNO0FBQUEsRUFDTixNQUFNO0FBQUEsSUFDSixNQUFNO0FBQUEsSUFDTixNQUFNO0FBQUEsTUFDSixhQUFhO0FBQUEsSUFDZjtBQUFBLElBQ0EsVUFBVTtBQUFBLE1BQ1IsbUJBQW1CO0FBQUEsSUFDckI7QUFBQSxJQUNBLFNBQVM7QUFBQSxJQUNULFFBQVEsQ0FBQztBQUFBLEVBQ1g7QUFBQSxFQUNBLGdCQUFnQixDQUFDO0FBQUEsRUFDakIsT0FBTyxTQUFTO0FBQ2QsVUFBTSxhQUFhLFFBQVE7QUFFM0IsV0FBTztBQUFBLE1BQ0wsU0FBUyxDQUFDLFlBQVk7QUFDcEIsY0FBTSxpQkFBaUIsV0FBVyxLQUFLLFNBQVMsZUFBZTtBQUMvRCxZQUFJLGdCQUFnQjtBQUNsQixnQkFBTSxXQUFXLFdBQVcsU0FBUyxPQUFPLEVBQUUsWUFBWSxDQUFDO0FBQzNELGlCQUFPLFFBQVE7QUFDZixjQUFJLFNBQVMsVUFBVSxLQUFLLENBQUMsYUFBYSxTQUFTLFNBQVMsV0FBVyxHQUFHO0FBQ3hFO0FBQUEsVUFDRjtBQUVBLGdCQUFNLGVBQWUsMEJBQTBCLFFBQVEsUUFBUTtBQUMvRCxjQUFJLGlCQUFpQixRQUFXO0FBQzlCLGtCQUFNLHNCQUFzQixRQUFRLEtBQUs7QUFBQSxjQUN2QyxDQUFDLGNBQWMsVUFBVSxTQUFTLGVBQWU7QUFBQSxZQUNuRDtBQUNBLG1CQUFPLG1CQUFtQjtBQUUxQixrQkFBTSwwQkFBMEI7QUFBQSw2QkFBZ0MsWUFBWTtBQUFBO0FBQzVFLG9CQUFRLE9BQU87QUFBQSxjQUNiLE1BQU07QUFBQSxjQUNOLFdBQVc7QUFBQSxjQUNYLElBQUksT0FBTztBQUNULHVCQUFPLE1BQU0sZ0JBQWdCLHFCQUFxQix1QkFBdUI7QUFBQSxjQUMzRTtBQUFBLFlBQ0YsQ0FBQztBQUFBLFVBQ0g7QUFBQSxRQUNGO0FBQUEsTUFDRjtBQUFBLElBQ0Y7QUFBQSxFQUNGO0FBQ0YsQ0FBQztBQUVELElBQU8sK0JBQVE7IiwKICAibmFtZXMiOiBbXQp9Cg==
@@ -1,61 +0,0 @@
1
- // src/agent/add-url-domain.ts
2
- import { AST_NODE_TYPES, ESLintUtils } from "@typescript-eslint/utils";
3
- import getDocumentationUrl from "../get-documentation-url.mjs";
4
- import { addBasePathUrlDomain } from "./url.mjs";
5
- var ruleId = "add-url-domain";
6
- var createRule = ESLintUtils.RuleCreator((name) => getDocumentationUrl(name));
7
- var rule = createRule({
8
- name: ruleId,
9
- meta: {
10
- type: "suggestion",
11
- docs: {
12
- description: "Add HTTP domain to the BASE_PATH like url constant variable."
13
- },
14
- messages: {
15
- addDomain: "Add HTTP domain to the BASE_PATH like url constant variable.",
16
- unknownError: 'Unknown error occurred in file "{{fileName}}": {{ error }}.'
17
- },
18
- fixable: "code",
19
- schema: []
20
- },
21
- defaultOptions: [],
22
- create(context) {
23
- const sourceCode = context.sourceCode;
24
- return {
25
- "VariableDeclarator[id.name=/^([A-Z]+_)*BASE_PATH$/]": (basePathDeclarator) => {
26
- try {
27
- if (basePathDeclarator.init === null || basePathDeclarator.init.type !== AST_NODE_TYPES.Literal && basePathDeclarator.init.type !== AST_NODE_TYPES.TemplateLiteral) {
28
- return;
29
- }
30
- const urlText = sourceCode.getText(basePathDeclarator.init);
31
- const replacement = addBasePathUrlDomain(urlText);
32
- if (replacement !== urlText) {
33
- context.report({
34
- messageId: "addDomain",
35
- node: basePathDeclarator.init,
36
- fix(fixer) {
37
- return fixer.replaceText(basePathDeclarator.init, replacement);
38
- }
39
- });
40
- }
41
- } catch (error) {
42
- console.error(`Failed to apply ${ruleId} rule for file "${context.filename}":`, error);
43
- context.report({
44
- node: basePathDeclarator,
45
- messageId: "unknownError",
46
- data: {
47
- fileName: context.filename,
48
- error: error instanceof Error ? error.toString() : JSON.stringify(error)
49
- }
50
- });
51
- }
52
- }
53
- };
54
- }
55
- });
56
- var add_url_domain_default = rule;
57
- export {
58
- add_url_domain_default as default,
59
- ruleId
60
- };
61
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2FnZW50L2FkZC11cmwtZG9tYWluLnRzIl0sCiAgIm1hcHBpbmdzIjogIjtBQVFBLFNBQVMsZ0JBQWdCLG1CQUE2QjtBQUV0RCxPQUFPLHlCQUF5QjtBQUNoQyxTQUFTLDRCQUE0QjtBQUU5QixJQUFNLFNBQVM7QUFFdEIsSUFBTSxhQUFhLFlBQVksWUFBWSxDQUFDLFNBQVMsb0JBQW9CLElBQUksQ0FBQztBQUU5RSxJQUFNLE9BQTZELFdBQVc7QUFBQSxFQUM1RSxNQUFNO0FBQUEsRUFDTixNQUFNO0FBQUEsSUFDSixNQUFNO0FBQUEsSUFDTixNQUFNO0FBQUEsTUFDSixhQUFhO0FBQUEsSUFDZjtBQUFBLElBQ0EsVUFBVTtBQUFBLE1BQ1IsV0FBVztBQUFBLE1BQ1gsY0FBYztBQUFBLElBQ2hCO0FBQUEsSUFDQSxTQUFTO0FBQUEsSUFDVCxRQUFRLENBQUM7QUFBQSxFQUNYO0FBQUEsRUFDQSxnQkFBZ0IsQ0FBQztBQUFBLEVBQ2pCLE9BQU8sU0FBUztBQUNkLFVBQU0sYUFBYSxRQUFRO0FBRTNCLFdBQU87QUFBQSxNQUNMLHVEQUF1RCxDQUFDLHVCQUFvRDtBQUMxRyxZQUFJO0FBQ0YsY0FDRSxtQkFBbUIsU0FBUyxRQUMzQixtQkFBbUIsS0FBSyxTQUFTLGVBQWUsV0FDL0MsbUJBQW1CLEtBQUssU0FBUyxlQUFlLGlCQUNsRDtBQUNBO0FBQUEsVUFDRjtBQUVBLGdCQUFNLFVBQVUsV0FBVyxRQUFRLG1CQUFtQixJQUFJO0FBQzFELGdCQUFNLGNBQWMscUJBQXFCLE9BQU87QUFFaEQsY0FBSSxnQkFBZ0IsU0FBUztBQUMzQixvQkFBUSxPQUFPO0FBQUEsY0FDYixXQUFXO0FBQUEsY0FDWCxNQUFNLG1CQUFtQjtBQUFBLGNBQ3pCLElBQUksT0FBTztBQUNULHVCQUFPLE1BQU0sWUFBWSxtQkFBbUIsTUFBdUIsV0FBVztBQUFBLGNBQ2hGO0FBQUEsWUFDRixDQUFDO0FBQUEsVUFDSDtBQUFBLFFBQ0YsU0FBUyxPQUFPO0FBRWQsa0JBQVEsTUFBTSxtQkFBbUIsTUFBTSxtQkFBbUIsUUFBUSxRQUFRLE1BQU0sS0FBSztBQUNyRixrQkFBUSxPQUFPO0FBQUEsWUFDYixNQUFNO0FBQUEsWUFDTixXQUFXO0FBQUEsWUFDWCxNQUFNO0FBQUEsY0FDSixVQUFVLFFBQVE7QUFBQSxjQUNsQixPQUFPLGlCQUFpQixRQUFRLE1BQU0sU0FBUyxJQUFJLEtBQUssVUFBVSxLQUFLO0FBQUEsWUFDekU7QUFBQSxVQUNGLENBQUM7QUFBQSxRQUNIO0FBQUEsTUFDRjtBQUFBLElBQ0Y7QUFBQSxFQUNGO0FBQ0YsQ0FBQztBQUVELElBQU8seUJBQVE7IiwKICAibmFtZXMiOiBbXQp9Cg==
@@ -1,221 +0,0 @@
1
- // src/agent/agent-test-wiring.ts
2
- import { strict as assert } from "node:assert";
3
- import { AST_TOKEN_TYPES, ESLintUtils, TSESTree } from "@typescript-eslint/utils";
4
- import debug from "debug";
5
- import getDocumentationUrl from "../get-documentation-url.mjs";
6
- var ruleId = "agent-test-wiring";
7
- var createRule = ESLintUtils.RuleCreator((name) => getDocumentationUrl(name));
8
- var log = debug("eslint-plugin:agent:agent-test-wiring");
9
- var STATEMENT_FIXTURE_RESET = "fixture.reset()";
10
- var STATEMENT_FIXTURE_RESET_AWAITED = `await ${STATEMENT_FIXTURE_RESET};`;
11
- var STATEMENT_AGENT_DECLARATION = "let agent: Agent;";
12
- var STATEMENT_AGENT_CREATION = "agent = await createAgent();";
13
- var STATEMENT_AGENT_REGISTER = "agent.register(await fixturePlugin(fixture));";
14
- var STATEMENT_AGENT_ENABLE = "agent.enable();";
15
- var STATEMENT_AGENT_DISPOSE = "await agent[Symbol.asyncDispose]();";
16
- var rule = createRule({
17
- name: ruleId,
18
- meta: {
19
- type: "suggestion",
20
- docs: {
21
- description: "Update test wiring."
22
- },
23
- messages: {
24
- updateTestWiring: "Updating test wiring.",
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
- log("Processing file:", context.filename);
34
- const sourceCode = context.sourceCode;
35
- const importDeclarations = /* @__PURE__ */ new Map();
36
- let isFixtureUsed = false;
37
- let beforeAll;
38
- let beforeEach;
39
- let afterAll;
40
- return {
41
- ImportDeclaration(importDeclaration) {
42
- const moduleName = importDeclaration.source.value;
43
- importDeclarations.set(moduleName, importDeclaration);
44
- if (moduleName === "@checkdigit/fixture" && importDeclaration.specifiers.some(
45
- (specifier) => specifier.type === TSESTree.AST_NODE_TYPES.ImportSpecifier && specifier.imported.type === TSESTree.AST_NODE_TYPES.Identifier && specifier.imported.name === "createFixture"
46
- )) {
47
- isFixtureUsed = true;
48
- }
49
- },
50
- 'CallExpression[callee.name="beforeAll"]': (callExpression) => {
51
- beforeAll = callExpression;
52
- },
53
- 'CallExpression[callee.name="beforeEach"]': (callExpression) => {
54
- beforeEach = callExpression;
55
- },
56
- 'CallExpression[callee.name="afterAll"]': (callExpression) => {
57
- afterAll = callExpression;
58
- },
59
- // eslint-disable-next-line sonarjs/cognitive-complexity
60
- "Program:exit"(program) {
61
- if (!isFixtureUsed || beforeAll === void 0 && beforeEach === void 0) {
62
- return;
63
- }
64
- try {
65
- let jestImportFixer;
66
- let agentImportFixer;
67
- let fixturePluginImportFixer;
68
- let agentDeclarationFixer;
69
- let beforeAllOrEachFixer;
70
- let afterAllFixer;
71
- const lastImportDeclaration = [...importDeclarations.values()].at(-1);
72
- assert.ok(lastImportDeclaration);
73
- const jestImportDeclaration = importDeclarations.get("@jest/globals");
74
- assert.ok(jestImportDeclaration);
75
- const importsToAdd = ["afterAll", "beforeAll"].filter(
76
- (jestHook) => !jestImportDeclaration.specifiers.some(
77
- (specifier) => specifier.type === TSESTree.AST_NODE_TYPES.ImportSpecifier && specifier.imported.type === TSESTree.AST_NODE_TYPES.Identifier && specifier.imported.name === jestHook
78
- )
79
- );
80
- if (importsToAdd.length > 0) {
81
- const firstImportSpecifier = jestImportDeclaration.specifiers[0];
82
- assert.ok(firstImportSpecifier);
83
- jestImportFixer = (fixer) => fixer.insertTextBefore(firstImportSpecifier, `${importsToAdd.join(", ")}, `);
84
- }
85
- const agentImportDeclaration = importDeclarations.get("@checkdigit/agent");
86
- if (!agentImportDeclaration) {
87
- agentImportFixer = (fixer) => fixer.insertTextAfter(
88
- lastImportDeclaration,
89
- `
90
- import createAgent, { type Agent } from '@checkdigit/agent';`
91
- );
92
- }
93
- const pathLets = context.filename.split("/");
94
- const currentFileIndex = pathLets.length - 1;
95
- const pluginFolderIndex = pathLets.lastIndexOf("src") + 1;
96
- const fixturePluginImportPath = `${"../".repeat(currentFileIndex - pluginFolderIndex)}plugin/fixture.test`;
97
- if (!importDeclarations.get(fixturePluginImportPath)) {
98
- fixturePluginImportFixer = (fixer) => fixer.insertTextAfter(lastImportDeclaration, `
99
- import fixturePlugin from '${fixturePluginImportPath}';`);
100
- }
101
- if (beforeAll === void 0) {
102
- beforeAllOrEachFixer = (fixer) => fixer.insertTextBefore(
103
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
104
- beforeEach,
105
- [
106
- STATEMENT_AGENT_DECLARATION,
107
- `beforeAll(async () => {`,
108
- [STATEMENT_AGENT_CREATION, STATEMENT_AGENT_REGISTER, STATEMENT_AGENT_ENABLE].join("\n"),
109
- `});
110
- `
111
- ].join("\n")
112
- );
113
- } else {
114
- const beforeAllArgument = beforeAll.arguments[0];
115
- assert.ok(beforeAllArgument !== void 0);
116
- if (!sourceCode.getText(beforeAllArgument).includes(STATEMENT_AGENT_CREATION)) {
117
- if (beforeAllArgument.type === TSESTree.AST_NODE_TYPES.ArrowFunctionExpression && beforeAllArgument.body.type === TSESTree.AST_NODE_TYPES.BlockStatement) {
118
- const fixtureResetStatement = beforeAllArgument.body.body.find(
119
- (statement) => sourceCode.getText(statement) === STATEMENT_FIXTURE_RESET_AWAITED
120
- );
121
- assert.ok(fixtureResetStatement !== void 0);
122
- beforeAllOrEachFixer = (fixer) => fixer.replaceText(
123
- fixtureResetStatement,
124
- [
125
- STATEMENT_AGENT_CREATION,
126
- STATEMENT_AGENT_REGISTER,
127
- STATEMENT_AGENT_ENABLE,
128
- STATEMENT_FIXTURE_RESET_AWAITED
129
- ].join("\n")
130
- );
131
- } else {
132
- beforeAllOrEachFixer = (fixer) => fixer.replaceText(
133
- beforeAllArgument,
134
- [
135
- `async () => {`,
136
- STATEMENT_AGENT_CREATION,
137
- STATEMENT_AGENT_REGISTER,
138
- STATEMENT_AGENT_ENABLE,
139
- STATEMENT_FIXTURE_RESET_AWAITED,
140
- `}`
141
- ].join("\n")
142
- );
143
- }
144
- agentDeclarationFixer = (fixer) => (
145
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
146
- fixer.insertTextBefore(beforeAll, `${STATEMENT_AGENT_DECLARATION}
147
- `)
148
- );
149
- }
150
- }
151
- if (afterAll !== void 0) {
152
- const afterAllArrowFunctionExpression = afterAll.arguments[0];
153
- assert.ok(
154
- afterAllArrowFunctionExpression !== void 0 && afterAllArrowFunctionExpression.type === TSESTree.AST_NODE_TYPES.ArrowFunctionExpression
155
- );
156
- const arrowFunctionBody = afterAllArrowFunctionExpression.body;
157
- assert.ok(arrowFunctionBody.type === TSESTree.AST_NODE_TYPES.BlockStatement);
158
- const afterAllBodyText = sourceCode.getText(arrowFunctionBody);
159
- if (!afterAllBodyText.includes(STATEMENT_AGENT_DISPOSE)) {
160
- const lastStatement = arrowFunctionBody.body.at(-1);
161
- assert.ok(lastStatement);
162
- afterAllFixer = (fixer) => fixer.insertTextAfter(lastStatement, STATEMENT_AGENT_DISPOSE);
163
- }
164
- } else {
165
- const nextToken = sourceCode.getTokenAfter(beforeAll ?? beforeEach);
166
- afterAllFixer = (fixer) => fixer.insertTextAfter(
167
- nextToken !== null && nextToken.type === AST_TOKEN_TYPES.Punctuator ? nextToken : (
168
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
169
- beforeAll
170
- ),
171
- ["", `afterAll(async () => {`, STATEMENT_AGENT_DISPOSE, `});`].join("\n")
172
- );
173
- }
174
- if (jestImportFixer !== void 0 || agentImportFixer !== void 0 || fixturePluginImportFixer !== void 0 || agentDeclarationFixer !== void 0 || beforeAllOrEachFixer !== void 0 || afterAllFixer !== void 0) {
175
- context.report({
176
- messageId: "updateTestWiring",
177
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
178
- node: beforeAll ?? beforeEach,
179
- *fix(fixer) {
180
- if (jestImportFixer !== void 0) {
181
- yield jestImportFixer(fixer);
182
- }
183
- if (agentImportFixer !== void 0) {
184
- yield agentImportFixer(fixer);
185
- }
186
- if (fixturePluginImportFixer !== void 0) {
187
- yield fixturePluginImportFixer(fixer);
188
- }
189
- if (agentDeclarationFixer !== void 0) {
190
- yield agentDeclarationFixer(fixer);
191
- }
192
- if (beforeAllOrEachFixer !== void 0) {
193
- yield beforeAllOrEachFixer(fixer);
194
- }
195
- if (afterAllFixer !== void 0) {
196
- yield afterAllFixer(fixer);
197
- }
198
- }
199
- });
200
- }
201
- } catch (error) {
202
- console.error(`Failed to apply ${ruleId} rule for file "${context.filename}":`, error);
203
- context.report({
204
- node: program,
205
- messageId: "unknownError",
206
- data: {
207
- fileName: context.filename,
208
- error: error instanceof Error ? error.toString() : JSON.stringify(error)
209
- }
210
- });
211
- }
212
- }
213
- };
214
- }
215
- });
216
- var agent_test_wiring_default = rule;
217
- export {
218
- agent_test_wiring_default as default,
219
- ruleId
220
- };
221
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2FnZW50L2FnZW50LXRlc3Qtd2lyaW5nLnRzIl0sCiAgIm1hcHBpbmdzIjogIjtBQVFBLFNBQVMsVUFBVSxjQUFjO0FBRWpDLFNBQVMsaUJBQWlCLGFBQWEsZ0JBQWdCO0FBRXZELE9BQU8sV0FBVztBQUVsQixPQUFPLHlCQUF5QjtBQUV6QixJQUFNLFNBQVM7QUFDdEIsSUFBTSxhQUFhLFlBQVksWUFBWSxDQUFDLFNBQVMsb0JBQW9CLElBQUksQ0FBQztBQUM5RSxJQUFNLE1BQU0sTUFBTSx1Q0FBdUM7QUFFekQsSUFBTSwwQkFBMEI7QUFDaEMsSUFBTSxrQ0FBa0MsU0FBUyx1QkFBdUI7QUFDeEUsSUFBTSw4QkFBOEI7QUFDcEMsSUFBTSwyQkFBMkI7QUFDakMsSUFBTSwyQkFBMkI7QUFDakMsSUFBTSx5QkFBeUI7QUFDL0IsSUFBTSwwQkFBMEI7QUFFaEMsSUFBTSxPQUFvRSxXQUFXO0FBQUEsRUFDbkYsTUFBTTtBQUFBLEVBQ04sTUFBTTtBQUFBLElBQ0osTUFBTTtBQUFBLElBQ04sTUFBTTtBQUFBLE1BQ0osYUFBYTtBQUFBLElBQ2Y7QUFBQSxJQUNBLFVBQVU7QUFBQSxNQUNSLGtCQUFrQjtBQUFBLE1BQ2xCLGNBQWM7QUFBQSxJQUNoQjtBQUFBLElBQ0EsU0FBUztBQUFBLElBQ1QsUUFBUSxDQUFDO0FBQUEsRUFDWDtBQUFBLEVBQ0EsZ0JBQWdCLENBQUM7QUFBQTtBQUFBLEVBRWpCLE9BQU8sU0FBUztBQUNkLFFBQUksb0JBQW9CLFFBQVEsUUFBUTtBQUN4QyxVQUFNLGFBQWEsUUFBUTtBQUMzQixVQUFNLHFCQUFxQixvQkFBSSxJQUF3QztBQUN2RSxRQUFJLGdCQUFnQjtBQUNwQixRQUFJO0FBQ0osUUFBSTtBQUNKLFFBQUk7QUFFSixXQUFPO0FBQUEsTUFDTCxrQkFBa0IsbUJBQW1CO0FBQ25DLGNBQU0sYUFBYSxrQkFBa0IsT0FBTztBQUM1QywyQkFBbUIsSUFBSSxZQUFZLGlCQUFpQjtBQUNwRCxZQUNFLGVB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LFlBQ3BHO0FBQUEsVUFDRixPQUFPO0FBRUwsa0JBQU0sWUFBWSxXQUFXLGNBQWMsYUFBYSxVQUFXO0FBQ25FLDRCQUFnQixDQUFDLFVBQ2YsTUFBTTtBQUFBLGNBQ0osY0FBYyxRQUFRLFVBQVUsU0FBUyxnQkFBZ0IsYUFDckQ7QUFBQTtBQUFBLGdCQUVBO0FBQUE7QUFBQSxjQUNKLENBQUMsSUFBSSwwQkFBMEIseUJBQXlCLEtBQUssRUFBRSxLQUFLLElBQUk7QUFBQSxZQUMxRTtBQUFBLFVBQ0o7QUFFQSxjQUNFLG9CQUFvQixVQUNwQixxQkFBcUIsVUFDckIsNkJBQTZCLFVBQzdCLDBCQUEwQixVQUMxQix5QkFBeUIsVUFDekIsa0JBQWtCLFFBQ2xCO0FBQ0Esb0JBQVEsT0FBTztBQUFBLGNBQ2IsV0FBVztBQUFBO0FBQUEsY0FFWCxNQUFNLGFBQWE7QUFBQSxjQUNuQixDQUFDLElBQUksT0FBTztBQUNWLG9CQUFJLG9CQUFvQixRQUFXO0FBQ2pDLHdCQUFNLGdCQUFnQixLQUFLO0FBQUEsZ0JBQzdCO0FBQ0Esb0JBQUkscUJBQXFCLFFBQVc7QUFDbEMsd0JBQU0saUJBQWlCLEtBQUs7QUFBQSxnQkFDOUI7QUFDQSxvQkFBSSw2QkFBNkIsUUFBVztBQUMxQyx3QkFBTSx5QkFBeUIsS0FBSztBQUFBLGdCQUN0QztBQUNBLG9CQUFJLDBCQUEwQixRQUFXO0FBQ3ZDLHdCQUFNLHNCQUFzQixLQUFLO0FBQUEsZ0JBQ25DO0FBQ0Esb0JBQUkseUJBQXlCLFFBQVc7QUFDdEMsd0JBQU0scUJBQXFCLEtBQUs7QUFBQSxnQkFDbEM7QUFDQSxvQkFBSSxrQkFBa0IsUUFBVztBQUMvQix3QkFBTSxjQUFjLEtBQUs7QUFBQSxnQkFDM0I7QUFBQSxjQUNGO0FBQUEsWUFDRixDQUFDO0FBQUEsVUFDSDtBQUFBLFFBQ0YsU0FBUyxPQUFPO0FBRWQsa0JBQVEsTUFBTSxtQkFBbUIsTUFBTSxtQkFBbUIsUUFBUSxRQUFRLE1BQU0sS0FBSztBQUNyRixrQkFBUSxPQUFPO0FBQUEsWUFDYixNQUFNO0FBQUEsWUFDTixXQUFXO0FBQUEsWUFDWCxNQUFNO0FBQUEsY0FDSixVQUFVLFFBQVE7QUFBQSxjQUNsQixPQUFPLGlCQUFpQixRQUFRLE1BQU0sU0FBUyxJQUFJLEtBQUssVUFBVSxLQUFLO0FBQUEsWUFDekU7QUFBQSxVQUNGLENBQUM7QUFBQSxRQUNIO0FBQUEsTUFDRjtBQUFBLElBQ0Y7QUFBQSxFQUNGO0FBQ0YsQ0FBQztBQUVELElBQU8sNEJBQVE7IiwKICAibmFtZXMiOiBbXQp9Cg==