api-tests-coverage 1.0.23 → 1.0.25

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 (175) hide show
  1. package/README.md +39 -0
  2. package/config.yaml.example +35 -0
  3. package/dist/dashboard/dist/assets/_basePickBy-BHjg34fk.js +1 -0
  4. package/dist/dashboard/dist/assets/_basePickBy-D4Hl8chy.js +1 -0
  5. package/dist/dashboard/dist/assets/_baseUniq-BSUUnV_V.js +1 -0
  6. package/dist/dashboard/dist/assets/_baseUniq-DxJYHd7T.js +1 -0
  7. package/dist/dashboard/dist/assets/arc-DcXkmNi0.js +1 -0
  8. package/dist/dashboard/dist/assets/arc-DhDluTY5.js +1 -0
  9. package/dist/dashboard/dist/assets/architectureDiagram-VXUJARFQ-ChMY32ql.js +36 -0
  10. package/dist/dashboard/dist/assets/architectureDiagram-VXUJARFQ-DGlUU7dC.js +36 -0
  11. package/dist/dashboard/dist/assets/blockDiagram-VD42YOAC-CgXi3kEZ.js +122 -0
  12. package/dist/dashboard/dist/assets/blockDiagram-VD42YOAC-DVhWtRxG.js +122 -0
  13. package/dist/dashboard/dist/assets/c4Diagram-YG6GDRKO-B6esYq70.js +10 -0
  14. package/dist/dashboard/dist/assets/c4Diagram-YG6GDRKO-Cr3xB15y.js +10 -0
  15. package/dist/dashboard/dist/assets/channel-DYAie-7m.js +1 -0
  16. package/dist/dashboard/dist/assets/channel-Df6s6dhy.js +1 -0
  17. package/dist/dashboard/dist/assets/chunk-4BX2VUAB-B7Pkx3C3.js +1 -0
  18. package/dist/dashboard/dist/assets/chunk-4BX2VUAB-BaW3__pI.js +1 -0
  19. package/dist/dashboard/dist/assets/chunk-55IACEB6-8ClDkPsD.js +1 -0
  20. package/dist/dashboard/dist/assets/chunk-55IACEB6-DyYevfEQ.js +1 -0
  21. package/dist/dashboard/dist/assets/chunk-B4BG7PRW--cjprmFF.js +165 -0
  22. package/dist/dashboard/dist/assets/chunk-B4BG7PRW-C2bwZFec.js +165 -0
  23. package/dist/dashboard/dist/assets/chunk-DI55MBZ5-D9bxNSnS.js +220 -0
  24. package/dist/dashboard/dist/assets/chunk-DI55MBZ5-DO0T2xne.js +220 -0
  25. package/dist/dashboard/dist/assets/chunk-FMBD7UC4-CCYA4j_f.js +15 -0
  26. package/dist/dashboard/dist/assets/chunk-FMBD7UC4-CSek7h3u.js +15 -0
  27. package/dist/dashboard/dist/assets/chunk-QN33PNHL-BRCzcTtl.js +1 -0
  28. package/dist/dashboard/dist/assets/chunk-QN33PNHL-Cdhqs7xo.js +1 -0
  29. package/dist/dashboard/dist/assets/chunk-QZHKN3VN-BzHw38Ki.js +1 -0
  30. package/dist/dashboard/dist/assets/chunk-QZHKN3VN-TFdw1-iS.js +1 -0
  31. package/dist/dashboard/dist/assets/chunk-TZMSLE5B-CWotsEVz.js +1 -0
  32. package/dist/dashboard/dist/assets/chunk-TZMSLE5B-dkJ0rsgF.js +1 -0
  33. package/dist/dashboard/dist/assets/classDiagram-2ON5EDUG-DiIv5Pho.js +1 -0
  34. package/dist/dashboard/dist/assets/classDiagram-2ON5EDUG-Dr8j2BkV.js +1 -0
  35. package/dist/dashboard/dist/assets/classDiagram-v2-WZHVMYZB-DiIv5Pho.js +1 -0
  36. package/dist/dashboard/dist/assets/classDiagram-v2-WZHVMYZB-Dr8j2BkV.js +1 -0
  37. package/dist/dashboard/dist/assets/clone-B4LorrSy.js +1 -0
  38. package/dist/dashboard/dist/assets/clone-D-A0zWrx.js +1 -0
  39. package/dist/dashboard/dist/assets/cose-bilkent-S5V4N54A-L06bC_vI.js +1 -0
  40. package/dist/dashboard/dist/assets/cose-bilkent-S5V4N54A-jzGbyPIS.js +1 -0
  41. package/dist/dashboard/dist/assets/dagre-6UL2VRFP-D7rgvBx1.js +4 -0
  42. package/dist/dashboard/dist/assets/dagre-6UL2VRFP-LQJxsDjp.js +4 -0
  43. package/dist/dashboard/dist/assets/diagram-PSM6KHXK-2rYklqon.js +24 -0
  44. package/dist/dashboard/dist/assets/diagram-PSM6KHXK-Bguvtjhb.js +24 -0
  45. package/dist/dashboard/dist/assets/diagram-QEK2KX5R-CDM-bAUc.js +43 -0
  46. package/dist/dashboard/dist/assets/diagram-QEK2KX5R-CGrvALqm.js +43 -0
  47. package/dist/dashboard/dist/assets/diagram-S2PKOQOG-DA3c-QP4.js +24 -0
  48. package/dist/dashboard/dist/assets/diagram-S2PKOQOG-DNQuKOCA.js +24 -0
  49. package/dist/dashboard/dist/assets/erDiagram-Q2GNP2WA-BsYH8cLH.js +60 -0
  50. package/dist/dashboard/dist/assets/erDiagram-Q2GNP2WA-CgAEujxC.js +60 -0
  51. package/dist/dashboard/dist/assets/flowDiagram-NV44I4VS-C8juupCT.js +162 -0
  52. package/dist/dashboard/dist/assets/flowDiagram-NV44I4VS-Da_JhBCy.js +162 -0
  53. package/dist/dashboard/dist/assets/ganttDiagram-JELNMOA3-BzXOAiOm.js +267 -0
  54. package/dist/dashboard/dist/assets/ganttDiagram-JELNMOA3-D8FTswNn.js +267 -0
  55. package/dist/dashboard/dist/assets/gitGraphDiagram-V2S2FVAM-6Rn0oWgA.js +65 -0
  56. package/dist/dashboard/dist/assets/gitGraphDiagram-V2S2FVAM-BFJR-ITH.js +65 -0
  57. package/dist/dashboard/dist/assets/graph-CIvnjOQQ.js +1 -0
  58. package/dist/dashboard/dist/assets/graph-VO6A5Zyb.js +1 -0
  59. package/dist/dashboard/dist/assets/index-BD_Ue7zI.js +777 -0
  60. package/dist/dashboard/dist/assets/index-BWX0sSZn.css +1 -0
  61. package/dist/dashboard/dist/assets/index-CbAFWEor.js +777 -0
  62. package/dist/dashboard/dist/assets/infoDiagram-HS3SLOUP-BEOgUULT.js +2 -0
  63. package/dist/dashboard/dist/assets/infoDiagram-HS3SLOUP-OcK0Lxgi.js +2 -0
  64. package/dist/dashboard/dist/assets/journeyDiagram-XKPGCS4Q-CBFUW_L2.js +139 -0
  65. package/dist/dashboard/dist/assets/journeyDiagram-XKPGCS4Q-DTJukVOY.js +139 -0
  66. package/dist/dashboard/dist/assets/kanban-definition-3W4ZIXB7-BXpodEnf.js +89 -0
  67. package/dist/dashboard/dist/assets/kanban-definition-3W4ZIXB7-Di65fNuD.js +89 -0
  68. package/dist/dashboard/dist/assets/layout-Cpj8l95P.js +1 -0
  69. package/dist/dashboard/dist/assets/layout-DAt24RVX.js +1 -0
  70. package/dist/dashboard/dist/assets/mindmap-definition-VGOIOE7T-DxI8MXCF.js +68 -0
  71. package/dist/dashboard/dist/assets/mindmap-definition-VGOIOE7T-_3DZbNEl.js +68 -0
  72. package/dist/dashboard/dist/assets/pieDiagram-ADFJNKIX-B--OM1Gs.js +30 -0
  73. package/dist/dashboard/dist/assets/pieDiagram-ADFJNKIX-BafKx3_Y.js +30 -0
  74. package/dist/dashboard/dist/assets/quadrantDiagram-AYHSOK5B-BcZsArkk.js +7 -0
  75. package/dist/dashboard/dist/assets/quadrantDiagram-AYHSOK5B-CDx0v76p.js +7 -0
  76. package/dist/dashboard/dist/assets/requirementDiagram-UZGBJVZJ-CbvZ1a-7.js +64 -0
  77. package/dist/dashboard/dist/assets/requirementDiagram-UZGBJVZJ-CqFAO2t6.js +64 -0
  78. package/dist/dashboard/dist/assets/sankeyDiagram-TZEHDZUN-CqSaCg-3.js +10 -0
  79. package/dist/dashboard/dist/assets/sankeyDiagram-TZEHDZUN-D-fji9s3.js +10 -0
  80. package/dist/dashboard/dist/assets/sequenceDiagram-WL72ISMW-6IXD1uqW.js +145 -0
  81. package/dist/dashboard/dist/assets/sequenceDiagram-WL72ISMW-CWB1Ub2x.js +145 -0
  82. package/dist/dashboard/dist/assets/stateDiagram-FKZM4ZOC-DvSVQAfp.js +1 -0
  83. package/dist/dashboard/dist/assets/stateDiagram-FKZM4ZOC-J-c1KNJ7.js +1 -0
  84. package/dist/dashboard/dist/assets/stateDiagram-v2-4FDKWEC3-BMFdt0QQ.js +1 -0
  85. package/dist/dashboard/dist/assets/stateDiagram-v2-4FDKWEC3-DRL2jF9p.js +1 -0
  86. package/dist/dashboard/dist/assets/timeline-definition-IT6M3QCI-Cll7Nvth.js +61 -0
  87. package/dist/dashboard/dist/assets/timeline-definition-IT6M3QCI-LOxOovzx.js +61 -0
  88. package/dist/dashboard/dist/assets/treemap-GDKQZRPO-C6DntuKu.js +162 -0
  89. package/dist/dashboard/dist/assets/treemap-GDKQZRPO-DtqX8zNC.js +162 -0
  90. package/dist/dashboard/dist/assets/xychartDiagram-PRI3JC2R-BKisDUaz.js +7 -0
  91. package/dist/dashboard/dist/assets/xychartDiagram-PRI3JC2R-zxwS9i0A.js +7 -0
  92. package/dist/dashboard/dist/index.html +2 -2
  93. package/dist/dashboard/dist/reports/coverage-summary.json +75 -1
  94. package/dist/dashboard/dist/reports/security-full.json +157 -0
  95. package/dist/src/compatibilityCoverage.d.ts +34 -15
  96. package/dist/src/compatibilityCoverage.d.ts.map +1 -1
  97. package/dist/src/compatibilityCoverage.js +387 -85
  98. package/dist/src/config/defaultConfig.d.ts.map +1 -1
  99. package/dist/src/config/defaultConfig.js +62 -0
  100. package/dist/src/config/schema.d.ts.map +1 -1
  101. package/dist/src/config/schema.js +1 -1
  102. package/dist/src/config/types.d.ts +81 -1
  103. package/dist/src/config/types.d.ts.map +1 -1
  104. package/dist/src/config/validateConfig.d.ts.map +1 -1
  105. package/dist/src/config/validateConfig.js +126 -0
  106. package/dist/src/contracts/compatibilityMatrix.d.ts +20 -0
  107. package/dist/src/contracts/compatibilityMatrix.d.ts.map +1 -0
  108. package/dist/src/contracts/compatibilityMatrix.js +198 -0
  109. package/dist/src/contracts/pactBrokerClient.d.ts +10 -0
  110. package/dist/src/contracts/pactBrokerClient.d.ts.map +1 -0
  111. package/dist/src/contracts/pactBrokerClient.js +117 -0
  112. package/dist/src/contracts/schemaEvolutionChecker.d.ts +17 -0
  113. package/dist/src/contracts/schemaEvolutionChecker.d.ts.map +1 -0
  114. package/dist/src/contracts/schemaEvolutionChecker.js +95 -0
  115. package/dist/src/contracts/springCloudContractParser.d.ts +10 -0
  116. package/dist/src/contracts/springCloudContractParser.d.ts.map +1 -0
  117. package/dist/src/contracts/springCloudContractParser.js +144 -0
  118. package/dist/src/discovery/fileClassifier.d.ts.map +1 -1
  119. package/dist/src/discovery/fileClassifier.js +25 -0
  120. package/dist/src/discovery/projectDiscovery.d.ts +2 -0
  121. package/dist/src/discovery/projectDiscovery.d.ts.map +1 -1
  122. package/dist/src/discovery/projectDiscovery.js +25 -25
  123. package/dist/src/index.js +233 -16
  124. package/dist/src/inference/routeInference.d.ts +10 -2
  125. package/dist/src/inference/routeInference.d.ts.map +1 -1
  126. package/dist/src/inference/routeInference.js +363 -62
  127. package/dist/src/languageDetection.d.ts.map +1 -1
  128. package/dist/src/languageDetection.js +21 -4
  129. package/dist/src/lib/index.d.ts +3 -0
  130. package/dist/src/lib/index.d.ts.map +1 -1
  131. package/dist/src/lib/index.js +3 -1
  132. package/dist/src/pipeline/stages/tia/parameterizedTestExpander.js +152 -79
  133. package/dist/src/pipeline/stages/tia/testEndpointMapper.d.ts +5 -1
  134. package/dist/src/pipeline/stages/tia/testEndpointMapper.d.ts.map +1 -1
  135. package/dist/src/pipeline/stages/tia/testEndpointMapper.js +356 -42
  136. package/dist/src/pipeline/stages/tia/testLayerClassifier.d.ts.map +1 -1
  137. package/dist/src/pipeline/stages/tia/testLayerClassifier.js +20 -5
  138. package/dist/src/pipeline/stages/tia/tiaStage.d.ts.map +1 -1
  139. package/dist/src/pipeline/stages/tia/tiaStage.js +3 -1
  140. package/dist/src/pipeline/stages/tia/types.d.ts +11 -2
  141. package/dist/src/pipeline/stages/tia/types.d.ts.map +1 -1
  142. package/dist/src/projectDefaults.d.ts +6 -0
  143. package/dist/src/projectDefaults.d.ts.map +1 -0
  144. package/dist/src/projectDefaults.js +43 -0
  145. package/dist/src/security/hub.d.ts +81 -0
  146. package/dist/src/security/hub.d.ts.map +1 -0
  147. package/dist/src/security/hub.js +420 -0
  148. package/dist/src/security/index.d.ts +1 -0
  149. package/dist/src/security/index.d.ts.map +1 -1
  150. package/dist/src/security/index.js +8 -2
  151. package/dist/src/security/normalizers/gitleaks.d.ts +7 -0
  152. package/dist/src/security/normalizers/gitleaks.d.ts.map +1 -0
  153. package/dist/src/security/normalizers/gitleaks.js +32 -0
  154. package/dist/src/security/scanners/gitleaks.d.ts +3 -0
  155. package/dist/src/security/scanners/gitleaks.d.ts.map +1 -0
  156. package/dist/src/security/scanners/gitleaks.js +105 -0
  157. package/dist/src/security/scanners/semgrep.d.ts.map +1 -1
  158. package/dist/src/security/scanners/semgrep.js +24 -2
  159. package/dist/src/security/scanners/trivy.d.ts.map +1 -1
  160. package/dist/src/security/scanners/trivy.js +24 -2
  161. package/dist/src/security/scanners/zap.d.ts.map +1 -1
  162. package/dist/src/security/scanners/zap.js +27 -2
  163. package/dist/src/security/types.d.ts +15 -1
  164. package/dist/src/security/types.d.ts.map +1 -1
  165. package/dist/src/streaming/schema/index.d.ts +23 -0
  166. package/dist/src/streaming/schema/index.d.ts.map +1 -0
  167. package/dist/src/streaming/schema/index.js +196 -0
  168. package/dist/src/summary/markdownRenderer.d.ts.map +1 -1
  169. package/dist/src/summary/markdownRenderer.js +15 -1
  170. package/dist/src/summary/summaryTypes.d.ts.map +1 -1
  171. package/dist/src/summary/summaryTypes.js +1 -0
  172. package/dist/src/unitAnalysis.d.ts +145 -0
  173. package/dist/src/unitAnalysis.d.ts.map +1 -0
  174. package/dist/src/unitAnalysis.js +1392 -0
  175. package/package.json +1 -1
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fetchContractsFromBroker = fetchContractsFromBroker;
4
+ exports.publishVerificationResults = publishVerificationResults;
5
+ function buildHeaders(config) {
6
+ return {
7
+ Accept: 'application/json',
8
+ 'Content-Type': 'application/json',
9
+ ...(config.token ? { Authorization: `Bearer ${config.token}`, 'Pact-Token': config.token } : {}),
10
+ };
11
+ }
12
+ function parsePactPayload(raw, filePath) {
13
+ var _a, _b;
14
+ if (!raw || typeof raw !== 'object')
15
+ return null;
16
+ const obj = raw;
17
+ if (!Array.isArray(obj['interactions']))
18
+ return null;
19
+ const interactions = obj['interactions']
20
+ .filter((entry) => !!entry && typeof entry === 'object')
21
+ .map((interaction) => {
22
+ var _a, _b;
23
+ const request = ((_a = interaction['request']) !== null && _a !== void 0 ? _a : {});
24
+ const response = ((_b = interaction['response']) !== null && _b !== void 0 ? _b : {});
25
+ return {
26
+ description: typeof interaction['description'] === 'string' ? interaction['description'] : '',
27
+ method: typeof request['method'] === 'string' ? request['method'].toLowerCase() : '',
28
+ path: typeof request['path'] === 'string' ? request['path'] : '',
29
+ requestBody: request['body'],
30
+ expectedStatus: typeof response['status'] === 'number' ? response['status'] : 200,
31
+ expectedBody: response['body'],
32
+ };
33
+ })
34
+ .filter((interaction) => interaction.method && interaction.path);
35
+ return {
36
+ consumer: typeof obj['consumer'] === 'object' && obj['consumer'] !== null
37
+ ? String((_a = obj['consumer']['name']) !== null && _a !== void 0 ? _a : 'unknown')
38
+ : 'unknown',
39
+ provider: typeof obj['provider'] === 'object' && obj['provider'] !== null
40
+ ? String((_b = obj['provider']['name']) !== null && _b !== void 0 ? _b : 'unknown')
41
+ : 'unknown',
42
+ interactions,
43
+ filePath,
44
+ };
45
+ }
46
+ function extractContracts(payload, sourceUrl) {
47
+ var _a;
48
+ if (!payload || typeof payload !== 'object')
49
+ return [];
50
+ const obj = payload;
51
+ if (Array.isArray(obj['interactions'])) {
52
+ const single = parsePactPayload(obj, sourceUrl);
53
+ return single ? [single] : [];
54
+ }
55
+ const embedded = ((_a = obj['_embedded']) !== null && _a !== void 0 ? _a : {});
56
+ const pacts = Array.isArray(embedded['pacts']) ? embedded['pacts'] : [];
57
+ return pacts
58
+ .map((entry, index) => parsePactPayload(entry, `${sourceUrl}#${index}`))
59
+ .filter((entry) => entry !== null);
60
+ }
61
+ async function fetchContractsFromBroker(config) {
62
+ if (!config.url || !config.providerName || typeof fetch !== 'function') {
63
+ return [];
64
+ }
65
+ const baseUrl = config.url.replace(/\/$/, '');
66
+ const candidateUrls = [
67
+ `${baseUrl}/pacts/provider/${encodeURIComponent(config.providerName)}/latest`,
68
+ `${baseUrl}/pacts/provider/${encodeURIComponent(config.providerName)}/latest?tag=main`,
69
+ ];
70
+ for (const url of candidateUrls) {
71
+ try {
72
+ const response = await fetch(url, { headers: buildHeaders(config) });
73
+ if (!response.ok)
74
+ continue;
75
+ const payload = (await response.json());
76
+ const contracts = extractContracts(payload, url);
77
+ if (contracts.length > 0)
78
+ return contracts;
79
+ }
80
+ catch (error) {
81
+ console.warn(`Unable to fetch Pact Broker contracts from ${url}: ${error instanceof Error ? error.message : String(error)}`);
82
+ return [];
83
+ }
84
+ }
85
+ return [];
86
+ }
87
+ async function publishVerificationResults(config, results) {
88
+ if (!config.publishResults || !config.url || typeof fetch !== 'function') {
89
+ return;
90
+ }
91
+ const baseUrl = config.url.replace(/\/$/, '');
92
+ const url = `${baseUrl}/pacts/provider/${encodeURIComponent(config.providerName)}/verification-results`;
93
+ try {
94
+ await fetch(url, {
95
+ method: 'POST',
96
+ headers: buildHeaders(config),
97
+ body: JSON.stringify({
98
+ providerName: config.providerName,
99
+ results: results.map((result) => ({
100
+ consumer: result.contract.consumer,
101
+ provider: result.contract.provider,
102
+ passed: result.passed,
103
+ interactions: result.interactionResults.map((interactionResult) => ({
104
+ description: interactionResult.interaction.description,
105
+ method: interactionResult.interaction.method,
106
+ path: interactionResult.interaction.path,
107
+ passed: interactionResult.passed,
108
+ reason: interactionResult.reason,
109
+ })),
110
+ })),
111
+ }),
112
+ });
113
+ }
114
+ catch (error) {
115
+ console.warn(`Unable to publish Pact verification results to ${url}: ${error instanceof Error ? error.message : String(error)}`);
116
+ }
117
+ }
@@ -0,0 +1,17 @@
1
+ import type { ParsedSchema } from '../streaming/schema';
2
+ export type SchemaCompatibilityType = 'BACKWARD' | 'FORWARD' | 'FULL' | 'NONE';
3
+ export interface SchemaEvolutionResult {
4
+ topicOrQueue: string;
5
+ format: 'avro' | 'protobuf' | 'json-schema';
6
+ isBackwardCompatible: boolean;
7
+ isForwardCompatible: boolean;
8
+ overallRisk: 'NONE' | 'LOW' | 'HIGH' | 'BREAKING';
9
+ changes: Array<{
10
+ field: string;
11
+ changeType: 'added' | 'removed' | 'type-changed' | 'enum-changed';
12
+ breaking: boolean;
13
+ fixHint: string;
14
+ }>;
15
+ }
16
+ export declare function checkSchemaEvolution(oldSchema: ParsedSchema, newSchema: ParsedSchema, topicOrQueue: string): SchemaEvolutionResult;
17
+ //# sourceMappingURL=schemaEvolutionChecker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemaEvolutionChecker.d.ts","sourceRoot":"","sources":["../../../src/contracts/schemaEvolutionChecker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAqB,MAAM,qBAAqB,CAAC;AAE3E,MAAM,MAAM,uBAAuB,GAAG,UAAU,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;AAE/E,MAAM,WAAW,qBAAqB;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,aAAa,CAAC;IAC5C,oBAAoB,EAAE,OAAO,CAAC;IAC9B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,WAAW,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,UAAU,CAAC;IAClD,OAAO,EAAE,KAAK,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,OAAO,GAAG,SAAS,GAAG,cAAc,GAAG,cAAc,CAAC;QAClE,QAAQ,EAAE,OAAO,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;CACJ;AAkBD,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,YAAY,EACvB,SAAS,EAAE,YAAY,EACvB,YAAY,EAAE,MAAM,GACnB,qBAAqB,CAgFvB"}
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.checkSchemaEvolution = checkSchemaEvolution;
4
+ function flattenFields(fields, prefix = '') {
5
+ const result = [];
6
+ for (const field of fields) {
7
+ const qualifiedName = prefix ? `${prefix}.${field.name}` : field.name;
8
+ result.push({ ...field, name: qualifiedName });
9
+ if (field.fields && field.fields.length > 0) {
10
+ result.push(...flattenFields(field.fields, qualifiedName));
11
+ }
12
+ }
13
+ return result;
14
+ }
15
+ function enumSignature(field) {
16
+ var _a;
17
+ return ((_a = field.enumValues) !== null && _a !== void 0 ? _a : []).join('|');
18
+ }
19
+ function checkSchemaEvolution(oldSchema, newSchema, topicOrQueue) {
20
+ var _a, _b;
21
+ const oldFields = flattenFields(oldSchema.fields);
22
+ const newFields = flattenFields(newSchema.fields);
23
+ const oldMap = new Map(oldFields.map((field) => [field.name, field]));
24
+ const newMap = new Map(newFields.map((field) => [field.name, field]));
25
+ const changes = [];
26
+ for (const [name, oldField] of oldMap) {
27
+ const newField = newMap.get(name);
28
+ if (!newField) {
29
+ const breaking = oldField.required && !oldField.defaultValue;
30
+ changes.push({
31
+ field: name,
32
+ changeType: 'removed',
33
+ breaking,
34
+ fixHint: breaking
35
+ ? 'Restore the field or keep it optional with a default value to preserve backward compatibility.'
36
+ : 'Optional field removal is usually safe, but keep consumers in sync.',
37
+ });
38
+ continue;
39
+ }
40
+ if (oldField.type !== newField.type) {
41
+ changes.push({
42
+ field: name,
43
+ changeType: 'type-changed',
44
+ breaking: true,
45
+ fixHint: 'Avoid changing field types in-place; add a new field and deprecate the old one instead.',
46
+ });
47
+ continue;
48
+ }
49
+ if (enumSignature(oldField) !== enumSignature(newField)) {
50
+ const oldValues = new Set((_a = oldField.enumValues) !== null && _a !== void 0 ? _a : []);
51
+ const newValues = new Set((_b = newField.enumValues) !== null && _b !== void 0 ? _b : []);
52
+ const removedValues = [...oldValues].filter((value) => !newValues.has(value));
53
+ const breaking = removedValues.length > 0;
54
+ changes.push({
55
+ field: name,
56
+ changeType: 'enum-changed',
57
+ breaking,
58
+ fixHint: breaking
59
+ ? 'Do not remove enum values that existing consumers may still emit or expect.'
60
+ : 'Adding enum values is safe when consumers tolerate unknown values.',
61
+ });
62
+ }
63
+ }
64
+ for (const [name, newField] of newMap) {
65
+ if (oldMap.has(name))
66
+ continue;
67
+ const breaking = newField.required && !newField.defaultValue && !newField.nullable;
68
+ changes.push({
69
+ field: name,
70
+ changeType: 'added',
71
+ breaking,
72
+ fixHint: breaking
73
+ ? 'Make the new field optional or give it a default value for backward compatibility.'
74
+ : 'Optional fields are backward compatible.',
75
+ });
76
+ }
77
+ const isBackwardCompatible = !changes.some((change) => change.breaking);
78
+ // Treat any detected breaking schema change as both backward and forward incompatible for deploy safety.
79
+ const isForwardCompatible = !changes.some((change) => change.breaking);
80
+ const overallRisk = changes.some((change) => change.breaking)
81
+ ? 'BREAKING'
82
+ : changes.length === 0
83
+ ? 'NONE'
84
+ : changes.some((change) => change.changeType === 'enum-changed')
85
+ ? 'HIGH'
86
+ : 'LOW';
87
+ return {
88
+ topicOrQueue,
89
+ format: newSchema.format,
90
+ isBackwardCompatible,
91
+ isForwardCompatible,
92
+ overallRisk,
93
+ changes,
94
+ };
95
+ }
@@ -0,0 +1,10 @@
1
+ import type { ContractInteraction } from '../compatibilityCoverage';
2
+ export interface SpringCloudContract {
3
+ filePath: string;
4
+ contractName: string;
5
+ interaction: ContractInteraction;
6
+ format: 'groovy' | 'yaml';
7
+ }
8
+ export declare function inferSpringConsumerName(filePath: string): string;
9
+ export declare function parseSpringCloudContracts(globPattern: string): Promise<SpringCloudContract[]>;
10
+ //# sourceMappingURL=springCloudContractParser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"springCloudContractParser.d.ts","sourceRoot":"","sources":["../../../src/contracts/springCloudContractParser.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAEpE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,mBAAmB,CAAC;IACjC,MAAM,EAAE,QAAQ,GAAG,MAAM,CAAC;CAC3B;AAwED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAShE;AAED,wBAAsB,yBAAyB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAqBnG"}
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.inferSpringConsumerName = inferSpringConsumerName;
40
+ exports.parseSpringCloudContracts = parseSpringCloudContracts;
41
+ const fs = __importStar(require("fs"));
42
+ const path = __importStar(require("path"));
43
+ const fast_glob_1 = __importDefault(require("fast-glob"));
44
+ const yaml = __importStar(require("js-yaml"));
45
+ const DEFAULT_PATTERNS = [
46
+ '**/src/test/resources/contracts/**/*.groovy',
47
+ '**/src/test/resources/contracts/**/*.yml',
48
+ '**/contracts/**/*.groovy',
49
+ '**/contracts/**/*.yml',
50
+ ];
51
+ function parseBodyFields(bodyContent) {
52
+ return bodyContent
53
+ .split(',')
54
+ .map((part) => part.trim())
55
+ .filter(Boolean)
56
+ .reduce((acc, entry) => {
57
+ const match = entry.match(/([A-Za-z0-9_\-]+)\s*:\s*['"]?([^,'"]+)['"]?/);
58
+ if (match)
59
+ acc[match[1]] = match[2];
60
+ return acc;
61
+ }, {});
62
+ }
63
+ function parseGroovyContract(content, filePath) {
64
+ var _a;
65
+ const methodMatch = content.match(/method\s+(\w+)\(\)/i);
66
+ const urlMatch = content.match(/url\s+["']([^"']+)["']/i);
67
+ const statusMatch = content.match(/status\s+(\w+)\(\)/i);
68
+ const bodyMatch = content.match(/body\(\[([^\]]+)\]\)/i);
69
+ if (!methodMatch || !urlMatch)
70
+ return null;
71
+ const statusToken = (_a = statusMatch === null || statusMatch === void 0 ? void 0 : statusMatch[1]) !== null && _a !== void 0 ? _a : '200';
72
+ const status = Number.parseInt(statusToken, 10);
73
+ const expectedStatus = Number.isFinite(status) ? status : 200;
74
+ const expectedBody = bodyMatch ? parseBodyFields(bodyMatch[1]) : undefined;
75
+ return {
76
+ filePath,
77
+ contractName: path.basename(filePath, path.extname(filePath)),
78
+ format: 'groovy',
79
+ interaction: {
80
+ description: path.basename(filePath),
81
+ method: methodMatch[1].toLowerCase(),
82
+ path: urlMatch[1],
83
+ expectedStatus,
84
+ expectedBody,
85
+ },
86
+ };
87
+ }
88
+ function parseYamlContract(content, filePath) {
89
+ var _a, _b;
90
+ const parsed = yaml.load(content);
91
+ if (!parsed || typeof parsed !== 'object')
92
+ return null;
93
+ const request = ((_a = parsed['request']) !== null && _a !== void 0 ? _a : {});
94
+ const response = ((_b = parsed['response']) !== null && _b !== void 0 ? _b : {});
95
+ const method = typeof request['method'] === 'string' ? request['method'].toLowerCase() : '';
96
+ const url = typeof request['url'] === 'string' ? request['url'] : '';
97
+ if (!method || !url)
98
+ return null;
99
+ return {
100
+ filePath,
101
+ contractName: path.basename(filePath, path.extname(filePath)),
102
+ format: 'yaml',
103
+ interaction: {
104
+ description: path.basename(filePath),
105
+ method,
106
+ path: url,
107
+ expectedStatus: typeof response['status'] === 'number' ? response['status'] : 200,
108
+ expectedBody: response['body'],
109
+ requestBody: request['body'],
110
+ },
111
+ };
112
+ }
113
+ function inferSpringConsumerName(filePath) {
114
+ const normalized = filePath.replace(/\\/g, '/');
115
+ const contractsIndex = normalized.lastIndexOf('/contracts/');
116
+ if (contractsIndex >= 0) {
117
+ const rest = normalized.slice(contractsIndex + '/contracts/'.length);
118
+ const segment = rest.split('/')[0];
119
+ if (segment && !segment.includes('.'))
120
+ return segment;
121
+ }
122
+ return path.basename(path.dirname(filePath));
123
+ }
124
+ async function parseSpringCloudContracts(globPattern) {
125
+ const patterns = globPattern.trim().length > 0
126
+ ? globPattern.split(',').map((entry) => entry.trim()).filter(Boolean)
127
+ : DEFAULT_PATTERNS;
128
+ const files = await (0, fast_glob_1.default)(patterns, { absolute: true, onlyFiles: true, unique: true });
129
+ const contracts = [];
130
+ for (const filePath of files) {
131
+ try {
132
+ const content = fs.readFileSync(filePath, 'utf-8');
133
+ const parsed = filePath.endsWith('.groovy')
134
+ ? parseGroovyContract(content, filePath)
135
+ : parseYamlContract(content, filePath);
136
+ if (parsed)
137
+ contracts.push(parsed);
138
+ }
139
+ catch (error) {
140
+ console.warn(`Skipping Spring Cloud Contract file ${filePath}: ${error instanceof Error ? error.message : String(error)}`);
141
+ }
142
+ }
143
+ return contracts;
144
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"fileClassifier.d.ts","sourceRoot":"","sources":["../../../src/discovery/fileClassifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,MAAM,MAAM,YAAY,GACpB,eAAe,GACf,cAAc,GACd,WAAW,GACX,eAAe,GACf,WAAW,GACX,aAAa,GACb,kBAAkB,GAClB,eAAe,GACf,UAAU,GACV,SAAS,CAAC;AAEd,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,YAAY,CAAC;IACvB,4DAA4D;IAC5D,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AAED,4DAA4D;AAC5D,eAAO,MAAM,4BAA4B,EAAE,WAAW,CAAC,YAAY,CAGjE,CAAC;AAkEH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CA4E7D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,CAEnE;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE,CAEhF;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAapD"}
1
+ {"version":3,"file":"fileClassifier.d.ts","sourceRoot":"","sources":["../../../src/discovery/fileClassifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH,MAAM,MAAM,YAAY,GACpB,eAAe,GACf,cAAc,GACd,WAAW,GACX,eAAe,GACf,WAAW,GACX,aAAa,GACb,kBAAkB,GAClB,eAAe,GACf,UAAU,GACV,SAAS,CAAC;AAEd,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,YAAY,CAAC;IACvB,4DAA4D;IAC5D,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AAED,4DAA4D;AAC5D,eAAO,MAAM,4BAA4B,EAAE,WAAW,CAAC,YAAY,CAGjE,CAAC;AAoEH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CAqG7D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,CAEnE;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE,CAEhF;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAepD"}
@@ -48,6 +48,7 @@ exports.classifyFiles = classifyFiles;
48
48
  exports.filterCoverageEvidence = filterCoverageEvidence;
49
49
  exports.isTestFile = isTestFile;
50
50
  const path = __importStar(require("path"));
51
+ const projectDefaults_1 = require("../projectDefaults");
51
52
  /** Files that must NEVER contribute to coverage evidence */
52
53
  exports.COVERAGE_EVIDENCE_CATEGORIES = new Set([
53
54
  'test_code',
@@ -100,6 +101,7 @@ const CONFIG_BASENAMES = new Set([
100
101
  const EXTENSION_MAP = {
101
102
  '.feature': 'bdd_scenarios',
102
103
  };
104
+ const GENERATED_SOURCE_SEGMENTS = new Set(projectDefaults_1.DEFAULT_GENERATED_SOURCE_PATH_SEGMENTS);
103
105
  /** Glob-style path-segment patterns for security reports */
104
106
  const SECURITY_REPORT_DIRS = ['zap', 'trivy', 'semgrep'];
105
107
  /** Glob-style path-segment patterns for performance artifacts */
@@ -167,6 +169,25 @@ function classifyFile(filePath) {
167
169
  return make(filePath, 'performance');
168
170
  }
169
171
  }
172
+ // Generated sources should be treated as service code only, even if their
173
+ // filenames look like tests (e.g. generated OpenAPI stubs).
174
+ if (segments.some((segment) => GENERATED_SOURCE_SEGMENTS.has(segment))) {
175
+ const GENERATED_SOURCE_EXTS = new Set([
176
+ '.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs',
177
+ '.java', '.kt', '.kts', '.groovy',
178
+ '.py', '.rb', '.go', '.cs',
179
+ ]);
180
+ if (GENERATED_SOURCE_EXTS.has(ext)) {
181
+ return make(filePath, 'service_code');
182
+ }
183
+ }
184
+ // Java/Kotlin/Groovy multi-module test sources live under **/src/test/<lang>/.
185
+ if ((normalizedPath.includes('/src/test/java/') ||
186
+ normalizedPath.includes('/src/test/kotlin/') ||
187
+ normalizedPath.includes('/src/test/groovy/')) &&
188
+ ['.java', '.kt', '.kts', '.groovy'].includes(ext)) {
189
+ return make(filePath, 'test_code');
190
+ }
170
191
  // 8. Test code — matches *.test.*, *.spec.*, *Test.*, *Tests.*, *Spec.*
171
192
  const basenameOriginal = path.basename(filePath);
172
193
  if (isTestFile(basenameOriginal)) {
@@ -216,6 +237,10 @@ function isTestFile(basename) {
216
237
  return true;
217
238
  if (/Tests\.(java|kt|kts)$/.test(basename))
218
239
  return true;
240
+ if (/IT\.(java|kt|kts)$/.test(basename))
241
+ return true;
242
+ if (/IntegrationTest\.(java|kt|kts)$/.test(basename))
243
+ return true;
219
244
  if (/Spec\.(java|kt|kts|rb|ts|js)$/.test(basename))
220
245
  return true;
221
246
  // Python conventions
@@ -58,6 +58,8 @@ export interface DiscoveryOptions {
58
58
  explicitTests?: string[];
59
59
  /** If provided, these paths override the auto-discovered contract files */
60
60
  explicitContracts?: string[];
61
+ /** Generated source directories that should be scanned even under excluded build/target dirs */
62
+ generatedSourceDirs?: string[];
61
63
  }
62
64
  /**
63
65
  * Discover all project artifacts from `rootDir`.
@@ -1 +1 @@
1
- {"version":3,"file":"projectDiscovery.d.ts","sourceRoot":"","sources":["../../../src/discovery/projectDiscovery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAAgB,cAAc,EAAgB,MAAM,kBAAkB,CAAC;AAC9E,OAAO,EAAuB,oBAAoB,EAAoB,MAAM,qBAAqB,CAAC;AAElG,YAAY,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAIlF,MAAM,MAAM,gBAAgB,GACxB,MAAM,GACN,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,YAAY,GACZ,YAAY,GACZ,IAAI,GACJ,QAAQ,CAAC;AAEb,MAAM,MAAM,iBAAiB,GAEzB,OAAO,GACP,QAAQ,GACR,aAAa,GAEb,QAAQ,GACR,UAAU,GAEV,OAAO,GACP,UAAU,GAEV,MAAM,GACN,OAAO,GACP,SAAS,GACT,YAAY,GAEZ,UAAU,GACV,SAAS,CAAC;AAEd,MAAM,WAAW,mBAAmB;IAClC,4BAA4B;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,yCAAyC;IACzC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,oDAAoD;IACpD,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,qCAAqC;IACrC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,kCAAkC;IAClC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,uDAAuD;IACvD,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,iCAAiC;IACjC,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,gCAAgC;IAChC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,qCAAqC;IACrC,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,+BAA+B;IAC/B,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,0EAA0E;IAC1E,aAAa,EAAE,oBAAoB,EAAE,CAAC;IACtC,8EAA8E;IAC9E,eAAe,EAAE,MAAM,CAAC,MAAM,IAAI,CAAC,mBAAmB,EAAE,UAAU,GAAG,aAAa,GAAG,iBAAiB,GAAG,WAAW,GAAG,YAAY,GAAG,eAAe,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC,CAAC;CACpL;AAED,MAAM,WAAW,gBAAgB;IAC/B,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uEAAuE;IACvE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,uEAAuE;IACvE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,2EAA2E;IAC3E,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC9B;AAiHD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,OAAO,GAAE,gBAAqB,GAAG,mBAAmB,CAkFnF"}
1
+ {"version":3,"file":"projectDiscovery.d.ts","sourceRoot":"","sources":["../../../src/discovery/projectDiscovery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAAgB,cAAc,EAAgB,MAAM,kBAAkB,CAAC;AAC9E,OAAO,EAAuB,oBAAoB,EAAoB,MAAM,qBAAqB,CAAC;AAMlG,YAAY,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAIlF,MAAM,MAAM,gBAAgB,GACxB,MAAM,GACN,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,YAAY,GACZ,YAAY,GACZ,IAAI,GACJ,QAAQ,CAAC;AAEb,MAAM,MAAM,iBAAiB,GAEzB,OAAO,GACP,QAAQ,GACR,aAAa,GAEb,QAAQ,GACR,UAAU,GAEV,OAAO,GACP,UAAU,GAEV,MAAM,GACN,OAAO,GACP,SAAS,GACT,YAAY,GAEZ,UAAU,GACV,SAAS,CAAC;AAEd,MAAM,WAAW,mBAAmB;IAClC,4BAA4B;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,yCAAyC;IACzC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,oDAAoD;IACpD,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,qCAAqC;IACrC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,kCAAkC;IAClC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,uDAAuD;IACvD,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,iCAAiC;IACjC,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,gCAAgC;IAChC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,qCAAqC;IACrC,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,+BAA+B;IAC/B,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,0EAA0E;IAC1E,aAAa,EAAE,oBAAoB,EAAE,CAAC;IACtC,8EAA8E;IAC9E,eAAe,EAAE,MAAM,CAAC,MAAM,IAAI,CAAC,mBAAmB,EAAE,UAAU,GAAG,aAAa,GAAG,iBAAiB,GAAG,WAAW,GAAG,YAAY,GAAG,eAAe,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC,CAAC;CACpL;AAED,MAAM,WAAW,gBAAgB;IAC/B,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uEAAuE;IACvE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,uEAAuE;IACvE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,2EAA2E;IAC3E,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,gGAAgG;IAChG,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;CAChC;AAkGD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,OAAO,GAAE,gBAAqB,GAAG,mBAAmB,CAsFnF"}
@@ -49,23 +49,9 @@ const fs = __importStar(require("fs"));
49
49
  const path = __importStar(require("path"));
50
50
  const fileClassifier_1 = require("./fileClassifier");
51
51
  const frameworkDetector_1 = require("./frameworkDetector");
52
+ const projectDefaults_1 = require("../projectDefaults");
52
53
  // ─── Default exclude list ─────────────────────────────────────────────────────
53
- const DEFAULT_EXCLUDE_DIRS = new Set([
54
- 'node_modules',
55
- '.git',
56
- 'dist',
57
- 'build',
58
- 'target',
59
- '.cache',
60
- 'coverage',
61
- '.nyc_output',
62
- '__pycache__',
63
- '.pytest_cache',
64
- '.tox',
65
- 'vendor',
66
- '.bundle',
67
- '.gradle',
68
- ]);
54
+ const DEFAULT_EXCLUDE_DIRS = new Set(projectDefaults_1.DEFAULT_DISCOVERY_EXCLUDE_DIRS);
69
55
  // ─── Language detection ───────────────────────────────────────────────────────
70
56
  /** Map build-file basenames to language */
71
57
  const BUILD_FILE_LANGUAGE_MAP = {
@@ -169,15 +155,19 @@ function scanDirectory(dir, excludeDirs, maxDepth, currentDepth = 0) {
169
155
  * "always discovers" behaviour while respecting explicit configuration.
170
156
  */
171
157
  function discoverProject(options = {}) {
172
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
158
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
173
159
  const rootDir = (_a = options.rootDir) !== null && _a !== void 0 ? _a : process.cwd();
174
160
  const excludeDirs = new Set([
175
161
  ...DEFAULT_EXCLUDE_DIRS,
176
162
  ...((_b = options.excludeDirs) !== null && _b !== void 0 ? _b : []),
177
163
  ]);
178
164
  const maxDepth = (_c = options.maxDepth) !== null && _c !== void 0 ? _c : 20;
165
+ const generatedSourceDirs = (_d = options.generatedSourceDirs) !== null && _d !== void 0 ? _d : projectDefaults_1.DEFAULT_GENERATED_SOURCE_DIRS;
179
166
  // ── Scan + classify ────────────────────────────────────────────────────────
180
- const rawPaths = scanDirectory(rootDir, excludeDirs, maxDepth);
167
+ const rawPaths = Array.from(new Set([
168
+ ...scanDirectory(rootDir, excludeDirs, maxDepth),
169
+ ...scanGeneratedSourceDirs(rootDir, generatedSourceDirs, maxDepth),
170
+ ]));
181
171
  const allFiles = rawPaths.map(fileClassifier_1.classifyFile);
182
172
  const byCategory = groupByCategory(allFiles);
183
173
  // ── Artifact resolution ────────────────────────────────────────────────────
@@ -190,14 +180,14 @@ function discoverProject(options = {}) {
190
180
  securityReportFiles: 'discovered',
191
181
  serviceFiles: 'discovered',
192
182
  };
193
- let specs = paths((_d = byCategory.specification) !== null && _d !== void 0 ? _d : []);
183
+ let specs = paths((_e = byCategory.specification) !== null && _e !== void 0 ? _e : []);
194
184
  if (options.explicitSpecs && options.explicitSpecs.length > 0) {
195
185
  specs = options.explicitSpecs;
196
186
  discoverySource.specs = 'explicit';
197
187
  }
198
- const featureFiles = paths((_e = byCategory.bdd_scenarios) !== null && _e !== void 0 ? _e : []);
188
+ const featureFiles = paths((_f = byCategory.bdd_scenarios) !== null && _f !== void 0 ? _f : []);
199
189
  let testFiles = [
200
- ...paths((_f = byCategory.test_code) !== null && _f !== void 0 ? _f : []),
190
+ ...paths((_g = byCategory.test_code) !== null && _g !== void 0 ? _g : []),
201
191
  ...featureFiles,
202
192
  ];
203
193
  if (options.explicitTests && options.explicitTests.length > 0) {
@@ -205,14 +195,14 @@ function discoverProject(options = {}) {
205
195
  discoverySource.testFiles = 'explicit';
206
196
  discoverySource.featureFiles = 'explicit';
207
197
  }
208
- let contractFiles = paths((_g = byCategory.contracts) !== null && _g !== void 0 ? _g : []);
198
+ let contractFiles = paths((_h = byCategory.contracts) !== null && _h !== void 0 ? _h : []);
209
199
  if (options.explicitContracts && options.explicitContracts.length > 0) {
210
200
  contractFiles = options.explicitContracts;
211
201
  discoverySource.contractFiles = 'explicit';
212
202
  }
213
- const performanceFiles = paths((_h = byCategory.performance) !== null && _h !== void 0 ? _h : []);
214
- const securityReportFiles = paths((_j = byCategory.security_reports) !== null && _j !== void 0 ? _j : []);
215
- const serviceFiles = paths((_k = byCategory.service_code) !== null && _k !== void 0 ? _k : []);
203
+ const performanceFiles = paths((_j = byCategory.performance) !== null && _j !== void 0 ? _j : []);
204
+ const securityReportFiles = paths((_k = byCategory.security_reports) !== null && _k !== void 0 ? _k : []);
205
+ const serviceFiles = paths((_l = byCategory.service_code) !== null && _l !== void 0 ? _l : []);
216
206
  // ── Language detection ─────────────────────────────────────────────────────
217
207
  const languages = detectLanguages(rawPaths);
218
208
  // ── Framework detection ────────────────────────────────────────────────────
@@ -239,6 +229,16 @@ function discoverProject(options = {}) {
239
229
  discoverySource,
240
230
  };
241
231
  }
232
+ function scanGeneratedSourceDirs(rootDir, generatedSourceDirs, maxDepth) {
233
+ const results = [];
234
+ for (const relDir of generatedSourceDirs) {
235
+ const fullPath = path.join(rootDir, relDir);
236
+ if (!fs.existsSync(fullPath))
237
+ continue;
238
+ results.push(...scanDirectory(fullPath, new Set(['node_modules', '.git', '.gradle']), maxDepth));
239
+ }
240
+ return results;
241
+ }
242
242
  // ─── Language detection helpers ───────────────────────────────────────────────
243
243
  function detectLanguages(filePaths) {
244
244
  const found = new Set();