@checkdigit/eslint-plugin 7.17.1 → 7.18.0-PR.143-8290

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 (80) hide show
  1. package/dist-mjs/athena/api-locator.mjs +30 -0
  2. package/dist-mjs/athena/api-matcher.mjs +108 -0
  3. package/dist-mjs/athena/athena.mjs +331 -0
  4. package/dist-mjs/athena/column.mjs +1 -0
  5. package/dist-mjs/athena/context.mjs +21 -0
  6. package/dist-mjs/athena/index.mjs +1 -0
  7. package/dist-mjs/athena/service-table.mjs +32 -0
  8. package/dist-mjs/athena/types.mjs +1 -0
  9. package/dist-mjs/athena/visitor.mjs +258 -0
  10. package/dist-mjs/index.mjs +8 -4
  11. package/dist-mjs/no-status-code-assert.mjs +1 -1
  12. package/dist-mjs/openapi/deref-schema.mjs +14 -0
  13. package/dist-mjs/openapi/generate-schema.mjs +273 -0
  14. package/dist-mjs/openapi/service-schema-generator.mjs +147 -0
  15. package/dist-mjs/peggy/athena-peggy.mjs +20629 -0
  16. package/dist-types/athena/api-locator.d.ts +2 -0
  17. package/dist-types/athena/api-matcher.d.ts +14 -0
  18. package/dist-types/athena/athena.d.ts +6 -0
  19. package/dist-types/athena/column.d.ts +1 -0
  20. package/dist-types/athena/context.d.ts +21 -0
  21. package/dist-types/athena/index.d.ts +8 -0
  22. package/dist-types/athena/service-table.d.ts +8 -0
  23. package/dist-types/athena/types.d.ts +474 -0
  24. package/dist-types/athena/visitor.d.ts +63 -0
  25. package/dist-types/no-status-code-assert.d.ts +1 -1
  26. package/dist-types/openapi/deref-schema.d.ts +1 -0
  27. package/dist-types/openapi/generate-schema.d.ts +33 -0
  28. package/dist-types/openapi/service-schema-generator.d.ts +5 -0
  29. package/dist-types/peggy/athena-peggy.d.ts +13 -0
  30. package/package.json +1 -96
  31. package/src/athena/ATHENA.md +387 -0
  32. package/src/athena/PLAN.md +355 -0
  33. package/src/athena/api-locator.ts +39 -0
  34. package/src/athena/api-matcher.ts +169 -0
  35. package/src/athena/athena.ts +491 -0
  36. package/src/athena/column.ts +2 -0
  37. package/src/athena/context.ts +47 -0
  38. package/src/athena/index.ts +11 -0
  39. package/src/athena/service-table.ts +55 -0
  40. package/src/athena/types.ts +526 -0
  41. package/src/athena/visitor.ts +365 -0
  42. package/src/index.ts +4 -0
  43. package/src/no-side-effects.ts +1 -1
  44. package/src/no-status-code-assert.ts +2 -2
  45. package/src/openapi/deref-schema.ts +14 -0
  46. package/src/openapi/generate-schema.ts +422 -0
  47. package/src/openapi/service-schema-generator.ts +189 -0
  48. package/src/peggy/athena-chat.peggy +608 -0
  49. package/src/peggy/athena-peggy.ts +22078 -0
  50. package/src/peggy/athena.peggy +2967 -0
  51. package/src/require-service-call-response-declaration.ts +2 -2
  52. package/src/services/interchange/v1/swagger.schema.deref.json +849 -0
  53. package/src/services/interchange/v1/swagger.schema.json +473 -0
  54. package/src/services/interchange/v1/swagger.yml +414 -0
  55. package/src/services/ledger/v1/swagger.schema.deref.json +6694 -0
  56. package/src/services/ledger/v1/swagger.schema.json +1820 -0
  57. package/src/services/ledger/v1/swagger.yml +1094 -0
  58. package/src/services/link/v1/swagger.schema.deref.json +648 -0
  59. package/src/services/link/v1/swagger.schema.json +444 -0
  60. package/src/services/link/v1/swagger.yml +343 -0
  61. package/src/services/message/v1/swagger.schema.deref.json +22049 -0
  62. package/src/services/message/v1/swagger.schema.json +3470 -0
  63. package/src/services/message/v1/swagger.yml +2798 -0
  64. package/src/services/message/v2/swagger.schema.deref.json +72221 -0
  65. package/src/services/message/v2/swagger.schema.json +3558 -0
  66. package/src/services/message/v2/swagger.yml +3009 -0
  67. package/src/services/paymentCard/v1/swagger.schema.deref.json +4346 -0
  68. package/src/services/paymentCard/v1/swagger.schema.json +2181 -0
  69. package/src/services/paymentCard/v1/swagger.yml +1161 -0
  70. package/src/services/paymentCard/v2/swagger.schema.deref.json +4336 -0
  71. package/src/services/paymentCard/v2/swagger.schema.json +2155 -0
  72. package/src/services/paymentCard/v2/swagger.yml +1149 -0
  73. package/src/services/person/v1/swagger.schema.deref.json +6786 -0
  74. package/src/services/person/v1/swagger.schema.json +1445 -0
  75. package/src/services/person/v1/swagger.yml +1157 -0
  76. package/src/services/teampayApproval/v1/swagger.schema.deref.json +9898 -0
  77. package/src/services/teampayCardManagement/v1/swagger.schema.deref.json +6187 -0
  78. package/src/services/teampayClientManagement/v1/swagger.schema.deref.json +4914 -0
  79. package/src/services/teampayClientManagement/v1/swagger.schema.json +1964 -0
  80. package/src/services/teampayClientManagement/v1/swagger.yml +1376 -0
@@ -0,0 +1,147 @@
1
+ // src/openapi/service-schema-generator.ts
2
+ import { execFileSync } from "node:child_process";
3
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
4
+ import debug from "debug";
5
+ import { buildApiSchemaFromYaml } from "./generate-schema.mjs";
6
+ var log = debug("eslint-plugin:athena:service-schema-generator");
7
+ var GITHUB_ORGANIZATIONS = ["checkdigit", "rebolt-checkdigit"];
8
+ var SWAGGER_SCHEMA_DEREF_FILENAME = "swagger.schema.deref.json";
9
+ function derefApiSchemas(schemas) {
10
+ const definitions = schemas.definitions ?? {};
11
+ function derefValue(value, resolving = /* @__PURE__ */ new Set()) {
12
+ if (value === null || typeof value !== "object") {
13
+ return value;
14
+ }
15
+ if (Array.isArray(value)) {
16
+ return value.map((item) => derefValue(item, resolving));
17
+ }
18
+ const obj = value;
19
+ if (typeof obj["$ref"] === "string") {
20
+ const refName = /\/definitions\/(?<name>[^/]+)$/u.exec(obj["$ref"])?.groups?.["name"];
21
+ if (refName !== void 0 && !resolving.has(refName)) {
22
+ return derefValue(definitions[refName], /* @__PURE__ */ new Set([...resolving, refName]));
23
+ }
24
+ }
25
+ return Object.fromEntries(Object.entries(obj).map(([key, val]) => [key, derefValue(val, resolving)]));
26
+ }
27
+ const resolvedApis = derefValue(schemas.apis);
28
+ if (schemas.definitions !== void 0) {
29
+ return {
30
+ apis: resolvedApis,
31
+ definitions: derefValue(schemas.definitions)
32
+ };
33
+ }
34
+ return { apis: resolvedApis };
35
+ }
36
+ function fetchUrlSync(url) {
37
+ try {
38
+ return execFileSync(process.execPath, ["--input-type=module"], {
39
+ input: `const r=await fetch(${JSON.stringify(url)});if(!r.ok)process.exit(1);process.stdout.write(await r.text());`,
40
+ encoding: "utf-8",
41
+ timeout: 15e3
42
+ });
43
+ } catch {
44
+ return null;
45
+ }
46
+ }
47
+ function readServiceConfig(packageJsonContent, org, serviceName) {
48
+ const packageJson = JSON.parse(packageJsonContent);
49
+ const apiRoot = packageJson.service?.api?.root;
50
+ const apiEndpoints = packageJson.service?.api?.endpoints;
51
+ if (apiRoot === void 0 || apiEndpoints === void 0 || apiEndpoints.length === 0) {
52
+ return null;
53
+ }
54
+ const pkgOrg = packageJson.name?.slice(1).split("/")[0] ?? org;
55
+ const pkgServiceName = packageJson.name?.slice(1).split("/")[1] ?? serviceName;
56
+ return { organization: pkgOrg, serviceName: pkgServiceName, apiRoot, endpoints: apiEndpoints };
57
+ }
58
+ function findServiceInNodeModules(serviceName) {
59
+ for (const org of GITHUB_ORGANIZATIONS) {
60
+ const packageDir = `node_modules/@${org}/${serviceName}`;
61
+ const packageJsonPath = `${packageDir}/package.json`;
62
+ if (!existsSync(packageJsonPath)) {
63
+ continue;
64
+ }
65
+ try {
66
+ const config = readServiceConfig(readFileSync(packageJsonPath, "utf-8"), org, serviceName);
67
+ if (config === null) {
68
+ continue;
69
+ }
70
+ const endpoints = [];
71
+ for (const endpoint of config.endpoints) {
72
+ const swaggerPath = `${packageDir}/${config.apiRoot}/${endpoint}/swagger.yml`;
73
+ if (existsSync(swaggerPath)) {
74
+ endpoints.push({ path: endpoint, yamlContent: readFileSync(swaggerPath, "utf-8") });
75
+ }
76
+ }
77
+ if (endpoints.length > 0) {
78
+ return { organization: config.organization, serviceName: config.serviceName, endpoints };
79
+ }
80
+ } catch {
81
+ }
82
+ }
83
+ return null;
84
+ }
85
+ function findServiceOnGitHub(serviceName) {
86
+ for (const org of GITHUB_ORGANIZATIONS) {
87
+ const pkgUrl = `https://raw.githubusercontent.com/${org}/${serviceName}/main/package.json`;
88
+ log(`fetching package.json from ${pkgUrl}`);
89
+ const pkgContent = fetchUrlSync(pkgUrl);
90
+ if (pkgContent === null) {
91
+ continue;
92
+ }
93
+ try {
94
+ const config = readServiceConfig(pkgContent, org, serviceName);
95
+ if (config === null) {
96
+ continue;
97
+ }
98
+ const endpoints = [];
99
+ for (const endpoint of config.endpoints) {
100
+ const swaggerUrl = `https://raw.githubusercontent.com/${org}/${serviceName}/main/${config.apiRoot}/${endpoint}/swagger.yml`;
101
+ log(`fetching swagger.yml from ${swaggerUrl}`);
102
+ const yamlContent = fetchUrlSync(swaggerUrl);
103
+ if (yamlContent !== null) {
104
+ endpoints.push({ path: endpoint, yamlContent });
105
+ }
106
+ }
107
+ if (endpoints.length > 0) {
108
+ return { organization: config.organization, serviceName: config.serviceName, endpoints };
109
+ }
110
+ } catch {
111
+ }
112
+ }
113
+ return null;
114
+ }
115
+ function generateSchemasForService(serviceName, outputDir) {
116
+ log("generating schemas for service", serviceName);
117
+ const source = findServiceInNodeModules(serviceName) ?? findServiceOnGitHub(serviceName);
118
+ if (source === null) {
119
+ log("no swagger source found for service", serviceName);
120
+ return [];
121
+ }
122
+ const results = [];
123
+ for (const { path: endpoint, yamlContent } of source.endpoints) {
124
+ try {
125
+ const rawSchema = buildApiSchemaFromYaml(yamlContent, source.organization, source.serviceName);
126
+ if (rawSchema === null) {
127
+ continue;
128
+ }
129
+ const schema = derefApiSchemas(rawSchema);
130
+ results.push({ schema, endpoint });
131
+ if (outputDir !== void 0) {
132
+ const versionFolder = endpoint.split("/").at(-1) ?? endpoint;
133
+ const dir = `${outputDir}/${versionFolder}`;
134
+ mkdirSync(dir, { recursive: true });
135
+ writeFileSync(`${dir}/${SWAGGER_SCHEMA_DEREF_FILENAME}`, JSON.stringify(schema, void 0, 2));
136
+ log(`cached schema to ${dir}/${SWAGGER_SCHEMA_DEREF_FILENAME}`);
137
+ }
138
+ } catch (error) {
139
+ log("error generating schema for endpoint", endpoint, error);
140
+ }
141
+ }
142
+ return results;
143
+ }
144
+ export {
145
+ generateSchemasForService
146
+ };
147
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL29wZW5hcGkvc2VydmljZS1zY2hlbWEtZ2VuZXJhdG9yLnRzIl0sCiAgIm1hcHBpbmdzIjogIjtBQUVBLFNBQVMsb0JBQW9CO0FBQzdCLFNBQVMsWUFBWSxXQUFXLGNBQWMscUJBQXFCO0FBRW5FLE9BQU8sV0FBVztBQUVsQixTQUEwQiw4QkFBOEI7QUFFeEQsSUFBTSxNQUFNLE1BQU0sK0NBQStDO0FBRWpFLElBQU0sdUJBQXVCLENBQUMsY0FBYyxtQkFBbUI7QUFDL0QsSUFBTSxnQ0FBZ0M7QUFhdEMsU0FBUyxnQkFBZ0IsU0FBaUM7QUFDeEQsUUFBTSxjQUFjLFFBQVEsZUFBZSxDQUFDO0FBRTVDLFdBQVMsV0FBVyxPQUFnQixZQUF5QixvQkFBSSxJQUFZLEdBQVk7QUFDdkYsUUFBSSxVQUFVLFFBQVEsT0FBTyxVQUFVLFVBQVU7QUFDL0MsYUFBTztBQUFBLElBQ1Q7QUFDQSxRQUFJLE1BQU0sUUFBUSxLQUFLLEdBQUc7QUFDeEIsYUFBTyxNQUFNLElBQUksQ0FBQyxTQUFTLFdBQVcsTUFBTSxTQUFTLENBQUM7QUFBQSxJQUN4RDtBQUNBLFVBQU0sTUFBTTtBQUNaLFFBQUksT0FBTyxJQUFJLE1BQU0sTUFBTSxVQUFVO0FBQ25DLFlBQU0sVUFBVSxrQ0FBa0MsS0FBSyxJQUFJLE1BQU0sQ0FBQyxHQUFHLFNBQVMsTUFBTTtBQUNwRixVQUFJLFlBQVksVUFBYSxDQUFDLFVBQVUsSUFBSSxPQUFPLEdBQUc7QUFDcEQsZUFBTyxXQUFXLFlBQVksT0FBTyxHQUFHLG9CQUFJLElBQVksQ0FBQyxHQUFHLFdBQVcsT0FBTyxDQUFDLENBQUM7QUFBQSxNQUNsRjtBQUFBLElBQ0Y7QUFDQSxXQUFPLE9BQU8sWUFBWSxPQUFPLFFBQVEsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUMsS0FBSyxXQUFXLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQztBQUFBLEVBQ3RHO0FBRUEsUUFBTSxlQUFlLFdBQVcs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