api-tests-coverage 1.0.16 → 1.0.17

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 (56) hide show
  1. package/dist/dashboard/dist/index.html +1 -1
  2. package/dist/src/discovery/fileClassifier.d.ts.map +1 -1
  3. package/dist/src/discovery/fileClassifier.js +15 -16
  4. package/dist/src/discovery/projectDiscovery.d.ts.map +1 -1
  5. package/dist/src/discovery/projectDiscovery.js +4 -1
  6. package/dist/src/languages/java/semanticBuilder.d.ts.map +1 -1
  7. package/dist/src/languages/java/semanticBuilder.js +69 -12
  8. package/dist/src/languages/javascript/angularDetector.d.ts.map +1 -1
  9. package/dist/src/languages/javascript/angularDetector.js +50 -17
  10. package/dist/src/languages/javascript/assertionResolver.js +6 -4
  11. package/dist/src/languages/javascript/hapiDetector.d.ts.map +1 -1
  12. package/dist/src/languages/javascript/hapiDetector.js +48 -5
  13. package/dist/src/languages/javascript/vueDetector.d.ts +2 -0
  14. package/dist/src/languages/javascript/vueDetector.d.ts.map +1 -1
  15. package/dist/src/languages/javascript/vueDetector.js +22 -0
  16. package/dist/src/languages/python/index.d.ts +1 -1
  17. package/dist/src/languages/python/index.d.ts.map +1 -1
  18. package/dist/src/languages/python/index.js +33 -3
  19. package/dist/src/pipeline/confidence.d.ts +6 -1
  20. package/dist/src/pipeline/confidence.d.ts.map +1 -1
  21. package/dist/src/pipeline/confidence.js +8 -3
  22. package/dist/src/pipeline/graph.d.ts.map +1 -1
  23. package/dist/src/pipeline/graph.js +16 -4
  24. package/dist/src/pipeline/stages/ast/astStage.d.ts.map +1 -1
  25. package/dist/src/pipeline/stages/ast/astStage.js +46 -2
  26. package/dist/src/pipeline/stages/ast/baseUrlComposer.d.ts.map +1 -1
  27. package/dist/src/pipeline/stages/ast/baseUrlComposer.js +18 -4
  28. package/dist/src/pipeline/stages/ast/crossFileResolver.js +29 -0
  29. package/dist/src/pipeline/stages/ast/graphBuilder.d.ts.map +1 -1
  30. package/dist/src/pipeline/stages/ast/graphBuilder.js +81 -0
  31. package/dist/src/pipeline/stages/ast/optionalAuthUnifier.d.ts +3 -1
  32. package/dist/src/pipeline/stages/ast/optionalAuthUnifier.d.ts.map +1 -1
  33. package/dist/src/pipeline/stages/ast/optionalAuthUnifier.js +34 -14
  34. package/dist/src/pipeline/stages/ast/resolvers/angularInjectionResolver.d.ts.map +1 -1
  35. package/dist/src/pipeline/stages/ast/resolvers/angularInjectionResolver.js +22 -3
  36. package/dist/src/pipeline/stages/ast/resolvers/dddLayerResolver.d.ts.map +1 -1
  37. package/dist/src/pipeline/stages/ast/resolvers/dddLayerResolver.js +104 -28
  38. package/dist/src/pipeline/stages/ast/resolvers/mybatisResolver.d.ts.map +1 -1
  39. package/dist/src/pipeline/stages/ast/resolvers/mybatisResolver.js +56 -0
  40. package/dist/src/pipeline/stages/ast/resolvers/vuexActionResolver.d.ts.map +1 -1
  41. package/dist/src/pipeline/stages/ast/resolvers/vuexActionResolver.js +43 -18
  42. package/dist/src/pipeline/stages/ast/rulesEnforcer.d.ts.map +1 -1
  43. package/dist/src/pipeline/stages/ast/rulesEnforcer.js +336 -45
  44. package/dist/src/pipeline/stages/merge/conflictDetector.d.ts +2 -0
  45. package/dist/src/pipeline/stages/merge/conflictDetector.d.ts.map +1 -1
  46. package/dist/src/pipeline/stages/merge/conflictDetector.js +54 -2
  47. package/dist/src/pipeline/stages/merge/coverageMappingBuilder.d.ts.map +1 -1
  48. package/dist/src/pipeline/stages/merge/coverageMappingBuilder.js +67 -3
  49. package/dist/src/pipeline/stages/tia/mockBoundaryDetector.d.ts.map +1 -1
  50. package/dist/src/pipeline/stages/tia/mockBoundaryDetector.js +8 -1
  51. package/dist/src/pipeline/stages/tia/parameterizedTestExpander.js +8 -4
  52. package/dist/src/pipeline/stages/tia/testLayerClassifier.d.ts.map +1 -1
  53. package/dist/src/pipeline/stages/tia/testLayerClassifier.js +36 -10
  54. package/dist/src/pipeline/types.d.ts +1 -1
  55. package/dist/src/pipeline/types.d.ts.map +1 -1
  56. package/package.json +3 -3
@@ -151,8 +151,13 @@ function hasPartialResolution(graph, pathNodeIds) {
151
151
  /**
152
152
  * Build a ConfidenceEvidence object from a coverage path in the graph.
153
153
  * Inspects the nodes and their source stages to determine what evidence exists.
154
+ *
155
+ * Optional `iastConfirmed` and `dastConfirmed` flags allow the caller to
156
+ * inject runtime confirmation state that may not be discoverable by walking
157
+ * `pathNodeIds` alone (e.g. when IAST/DAST nodes are not directly on the
158
+ * endpoint→test path in the graph).
154
159
  */
155
- function buildConfidenceEvidence(graph, pathNodeIds, isStaticOnlyMode) {
160
+ function buildConfidenceEvidence(graph, pathNodeIds, isStaticOnlyMode, iastConfirmed, dastConfirmed) {
156
161
  var _a, _b;
157
162
  const sourceStages = new Set();
158
163
  let hasIastConfirmation = false;
@@ -187,8 +192,8 @@ function buildConfidenceEvidence(graph, pathNodeIds, isStaticOnlyMode) {
187
192
  }
188
193
  return {
189
194
  sourceStages: Array.from(sourceStages),
190
- hasIastConfirmation,
191
- hasDastConfirmation,
195
+ hasIastConfirmation: hasIastConfirmation || (iastConfirmed !== null && iastConfirmed !== void 0 ? iastConfirmed : false),
196
+ hasDastConfirmation: hasDastConfirmation || (dastConfirmed !== null && dastConfirmed !== void 0 ? dastConfirmed : false),
192
197
  hasAssertionConfirmation,
193
198
  hasMockBoundary,
194
199
  hasPartialResolution: hasPartial,
@@ -1 +1 @@
1
- {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../../src/pipeline/graph.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,SAAS,EACT,SAAS,EACT,aAAa,EACb,aAAa,EACb,YAAY,EACZ,SAAS,EACV,MAAM,SAAS,CAAC;AAEjB,qBAAa,sBAAsB;IACjC,OAAO,CAAC,KAAK,CAAqC;IAClD,OAAO,CAAC,KAAK,CAAqC;IAIlD,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IAI9B,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAI1C,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAI5B,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAI/B,cAAc,CAAC,IAAI,EAAE,aAAa,GAAG,SAAS,EAAE;IAIhD,eAAe,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,EAAE;IAI9C,WAAW,IAAI,SAAS,EAAE;IAI1B,IAAI,SAAS,IAAI,MAAM,CAEtB;IAID,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IAI9B,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAI1C,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAI5B,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAI/B,mDAAmD;IACnD,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE;IAIzC,8CAA8C;IAC9C,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE;IAIvC,sEAAsE;IACtE,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE;IAQ9D,wCAAwC;IACxC,cAAc,CAAC,IAAI,EAAE,aAAa,GAAG,SAAS,EAAE;IAIhD,WAAW,IAAI,SAAS,EAAE;IAI1B,IAAI,SAAS,IAAI,MAAM,CAEtB;IAID;;;OAGG;IACH,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,aAAa,EAAE,GAAG,SAAS,EAAE;IA4B5E;;;OAGG;IACH,iBAAiB,CACf,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,aAAa,GACtB,OAAO;IAiCV;;;OAGG;IACH,KAAK,CAAC,KAAK,EAAE,sBAAsB,GAAG,YAAY,EAAE;IAwCpD,cAAc,IAAI;QAAE,KAAK,EAAE,SAAS,EAAE,CAAC;QAAC,KAAK,EAAE,SAAS,EAAE,CAAA;KAAE;IAO5D,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,SAAS,EAAE,CAAC;QAAC,KAAK,EAAE,SAAS,EAAE,CAAA;KAAE,GAAG,sBAAsB;IAajG,KAAK,IAAI,IAAI;CAId"}
1
+ {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../../src/pipeline/graph.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,SAAS,EACT,SAAS,EACT,aAAa,EACb,aAAa,EACb,YAAY,EACZ,SAAS,EACV,MAAM,SAAS,CAAC;AAEjB,qBAAa,sBAAsB;IACjC,OAAO,CAAC,KAAK,CAAqC;IAClD,OAAO,CAAC,KAAK,CAAqC;IAIlD,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IAI9B,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAI1C,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAI5B,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAa/B,cAAc,CAAC,IAAI,EAAE,aAAa,GAAG,SAAS,EAAE;IAIhD,eAAe,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,EAAE;IAI9C,WAAW,IAAI,SAAS,EAAE;IAI1B,IAAI,SAAS,IAAI,MAAM,CAEtB;IAID,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IAI9B,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAI1C,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAI5B,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAI/B,mDAAmD;IACnD,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE;IAIzC,8CAA8C;IAC9C,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE;IAIvC,sEAAsE;IACtE,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE;IAQ9D,wCAAwC;IACxC,cAAc,CAAC,IAAI,EAAE,aAAa,GAAG,SAAS,EAAE;IAIhD,WAAW,IAAI,SAAS,EAAE;IAI1B,IAAI,SAAS,IAAI,MAAM,CAEtB;IAID;;;OAGG;IACH,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,aAAa,EAAE,GAAG,SAAS,EAAE;IA4B5E;;;OAGG;IACH,iBAAiB,CACf,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,aAAa,GACtB,OAAO;IAmCV;;;OAGG;IACH,KAAK,CAAC,KAAK,EAAE,sBAAsB,GAAG,YAAY,EAAE;IAwCpD,cAAc,IAAI;QAAE,KAAK,EAAE,SAAS,EAAE,CAAC;QAAC,KAAK,EAAE,SAAS,EAAE,CAAA;KAAE;IAO5D,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,SAAS,EAAE,CAAC;QAAC,KAAK,EAAE,SAAS,EAAE,CAAA;KAAE,GAAG,sBAAsB;IAajG,KAAK,IAAI,IAAI;CAId"}
@@ -23,7 +23,16 @@ class CoverageKnowledgeGraph {
23
23
  return this.nodes.has(id);
24
24
  }
25
25
  removeNode(id) {
26
- return this.nodes.delete(id);
26
+ const deleted = this.nodes.delete(id);
27
+ if (deleted) {
28
+ // Remove all edges that reference this node to avoid dangling edges
29
+ for (const [edgeId, edge] of this.edges) {
30
+ if (edge.sourceNodeId === id || edge.targetNodeId === id) {
31
+ this.edges.delete(edgeId);
32
+ }
33
+ }
34
+ }
35
+ return deleted;
27
36
  }
28
37
  getNodesByType(type) {
29
38
  return Array.from(this.nodes.values()).filter((n) => n.type === type);
@@ -112,9 +121,11 @@ class CoverageKnowledgeGraph {
112
121
  while (queue.length > 0) {
113
122
  const path = queue.shift();
114
123
  const currentId = path[path.length - 1];
115
- if (visited.has(currentId))
124
+ // Don't skip endId — we need to check every path that arrives at it
125
+ if (currentId !== endId && visited.has(currentId))
116
126
  continue;
117
- visited.add(currentId);
127
+ if (currentId !== endId)
128
+ visited.add(currentId);
118
129
  if (currentId === endId) {
119
130
  // Check interior nodes (not start or end)
120
131
  for (let i = 1; i < path.length - 1; i++) {
@@ -122,7 +133,8 @@ class CoverageKnowledgeGraph {
122
133
  if ((node === null || node === void 0 ? void 0 : node.type) === nodeType)
123
134
  return true;
124
135
  }
125
- return false;
136
+ // Don't return false here — other paths may still contain the node type
137
+ continue;
126
138
  }
127
139
  const outEdges = this.getEdgesFrom(currentId);
128
140
  for (const edge of outEdges) {
@@ -1 +1 @@
1
- {"version":3,"file":"astStage.d.ts","sourceRoot":"","sources":["../../../../../src/pipeline/stages/ast/astStage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE3E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAmB9C,qBAAa,QAAS,YAAW,aAAa,CAAC,cAAc,CAAC;IAC5D,QAAQ,CAAC,IAAI,EAAG,KAAK,CAAU;IAC/B,QAAQ,CAAC,QAAQ,SAAS;IAEpB,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;CAoLjE"}
1
+ {"version":3,"file":"astStage.d.ts","sourceRoot":"","sources":["../../../../../src/pipeline/stages/ast/astStage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE3E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AA2B9C,qBAAa,QAAS,YAAW,aAAa,CAAC,cAAc,CAAC;IAC5D,QAAQ,CAAC,IAAI,EAAG,KAAK,CAAU;IAC/B,QAAQ,CAAC,QAAQ,SAAS;IAEpB,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;CAoNjE"}
@@ -53,6 +53,14 @@ const graphBuilder_1 = require("./graphBuilder");
53
53
  const fileClassifier_1 = require("../../../discovery/fileClassifier");
54
54
  const projectDiscovery_1 = require("../../../discovery/projectDiscovery");
55
55
  const parserRegistry_1 = require("../../../ast/parserRegistry");
56
+ const rulesEnforcer_1 = require("./rulesEnforcer");
57
+ const optionalAuthUnifier_1 = require("./optionalAuthUnifier");
58
+ const expressRouterResolver_1 = require("./resolvers/expressRouterResolver");
59
+ const flaskBlueprintResolver_1 = require("./resolvers/flaskBlueprintResolver");
60
+ const angularInjectionResolver_1 = require("./resolvers/angularInjectionResolver");
61
+ const vuexActionResolver_1 = require("./resolvers/vuexActionResolver");
62
+ const mybatisResolver_1 = require("./resolvers/mybatisResolver");
63
+ const dddLayerResolver_1 = require("./resolvers/dddLayerResolver");
56
64
  const fs = __importStar(require("fs"));
57
65
  const path = __importStar(require("path"));
58
66
  class AstStage {
@@ -71,7 +79,8 @@ class AstStage {
71
79
  const scaOutput = context.stageOutputs.get('sca');
72
80
  // Build analysis context
73
81
  const analysisContext = (0, astAnalysisOrchestrator_1.buildAnalysisContext)(context.config.astConfig);
74
- // Discover all files
82
+ // Discover all files — XML, GraphQL, and PHP files are included in serviceFiles
83
+ // via SERVICE_CODE_EXTS in fileClassifier.ts (RULE-SA05, SA06)
75
84
  const artifacts = (0, projectDiscovery_1.discoverProject)({ rootDir: context.projectRoot });
76
85
  const allSourceFiles = [
77
86
  ...artifacts.testFiles,
@@ -131,8 +140,33 @@ class AstStage {
131
140
  }
132
141
  // Phase 2: Build cross-file symbol table
133
142
  const crossFileTable = (0, crossFileResolver_1.buildCrossFileSymbolTable)(models, context.projectRoot);
134
- // Phase 2b: Run cross-file resolution pass (Feature 27)
143
+ // Phase 2b: Register and run cross-file resolvers (Feature 27)
144
+ // Clear any stale registrations from prior runs, then register all 6 resolvers
145
+ (0, crossFileResolutionPass_1.clearCrossFileResolvers)();
146
+ (0, crossFileResolutionPass_1.registerCrossFileResolver)(new expressRouterResolver_1.ExpressRouterResolver());
147
+ (0, crossFileResolutionPass_1.registerCrossFileResolver)(new flaskBlueprintResolver_1.FlaskBlueprintResolver());
148
+ (0, crossFileResolutionPass_1.registerCrossFileResolver)(new angularInjectionResolver_1.AngularInjectionResolver());
149
+ (0, crossFileResolutionPass_1.registerCrossFileResolver)(new vuexActionResolver_1.VuexActionResolver());
150
+ (0, crossFileResolutionPass_1.registerCrossFileResolver)(new mybatisResolver_1.MyBatisResolver());
151
+ (0, crossFileResolutionPass_1.registerCrossFileResolver)(new dddLayerResolver_1.DddLayerResolver());
135
152
  const crossFileResolutionResult = (0, crossFileResolutionPass_1.runCrossFileResolution)(crossFileTable, context.projectRoot, artifacts.apiFrameworks, allSourceFiles);
153
+ // Phase 2c: Detect auth coverage gaps (Feature 27)
154
+ // Collect all endpoints with their security classifications for gap analysis
155
+ const endpointsForAuthGaps = [];
156
+ for (const [filePath, model] of crossFileTable.models) {
157
+ if (!model.routeRegistrations)
158
+ continue;
159
+ for (const reg of model.routeRegistrations) {
160
+ endpointsForAuthGaps.push({
161
+ path: reg.path,
162
+ security: reg.security,
163
+ sourceFile: filePath,
164
+ });
165
+ }
166
+ }
167
+ const authCoverageGaps = (0, optionalAuthUnifier_1.detectAuthCoverageGaps)(endpointsForAuthGaps, new Set());
168
+ // Phase 2d: Enforce structure-agnostic rules (Feature 27)
169
+ const rulesResult = (0, rulesEnforcer_1.enforceStructureAgnosticRules)(crossFileTable, context.projectRoot);
136
170
  // Phase 3: Run abstract layer traversal for test files
137
171
  const traversalResults = new Map();
138
172
  const depthCap = context.config.traversalDepthCap;
@@ -204,6 +238,10 @@ class AstStage {
204
238
  graphEdgesAdded: edges.length,
205
239
  crossFileResolversRun: crossFileResolutionResult.resolverResults.length,
206
240
  crossFileEntriesAdded: crossFileResolutionResult.totalEntriesAdded,
241
+ rulesChecked: rulesResult.rulesChecked,
242
+ rulesPassed: rulesResult.rulesPassed,
243
+ ruleViolations: rulesResult.violations.length,
244
+ authCoverageGaps: authCoverageGaps.length,
207
245
  },
208
246
  };
209
247
  context.diagnostics.set('ast', diagnostics);
@@ -238,7 +276,13 @@ function detectLanguage(filePath, scaOutput) {
238
276
  '.kts': 'kotlin',
239
277
  '.py': 'python',
240
278
  '.rb': 'ruby',
279
+ '.php': 'php',
241
280
  '.feature': 'cucumber',
242
281
  };
282
+ // Handle GraphQL schema files and XML as special-case languages
283
+ if (ext === '.graphqls' || ext === '.graphql')
284
+ return 'graphql';
285
+ if (ext === '.xml')
286
+ return 'xml';
243
287
  return extensionMap[ext];
244
288
  }
@@ -1 +1 @@
1
- {"version":3,"file":"baseUrlComposer.d.ts","sourceRoot":"","sources":["../../../../../src/pipeline/stages/ast/baseUrlComposer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH;;;GAGG;AACH,wBAAgB,UAAU,CAAC,GAAG,QAAQ,EAAE,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,GAAG,MAAM,CAStE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAkBlD;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQxD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE;IACL,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB,GACA,MAAM,CAUR"}
1
+ {"version":3,"file":"baseUrlComposer.d.ts","sourceRoot":"","sources":["../../../../../src/pipeline/stages/ast/baseUrlComposer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH;;;GAGG;AACH,wBAAgB,UAAU,CAAC,GAAG,QAAQ,EAAE,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,GAAG,MAAM,CAyBtE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAkBlD;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQxD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE;IACL,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB,GACA,MAAM,CAUR"}
@@ -24,10 +24,24 @@ exports.composeFrameworkUrl = composeFrameworkUrl;
24
24
  */
25
25
  function composeUrl(...segments) {
26
26
  const parts = segments
27
- .filter((s) => typeof s === 'string' && s.length > 0)
28
- .map((s) => s.replace(/^\/+|\/+$/g, ''));
29
- const joined = parts.join('/');
30
- const normalized = '/' + joined.replace(/\/+/g, '/');
27
+ .filter((s) => typeof s === 'string' && s.length > 0);
28
+ if (parts.length === 0)
29
+ return '/';
30
+ // Detect protocol in the first segment (e.g. http://, https://)
31
+ const protocolMatch = parts[0].match(/^(\w+:\/\/)/);
32
+ let protocol = '';
33
+ if (protocolMatch) {
34
+ protocol = protocolMatch[1];
35
+ parts[0] = parts[0].slice(protocol.length);
36
+ }
37
+ const stripped = parts.map((s) => s.replace(/^\/+|\/+$/g, ''));
38
+ const joined = stripped.join('/');
39
+ const deduped = joined.replace(/\/+/g, '/');
40
+ if (protocol) {
41
+ const normalized = protocol + deduped;
42
+ return normalized.replace(/\/+$/, '') || protocol;
43
+ }
44
+ const normalized = '/' + deduped;
31
45
  return normalized === '/' ? '/' : normalized.replace(/\/+$/, '');
32
46
  }
33
47
  /**
@@ -107,12 +107,31 @@ function resolveSymbolCrossFile(symbolName, fromFile, table) {
107
107
  }
108
108
  return undefined;
109
109
  }
110
+ /** Built-in objects that should never be treated as import module names */
111
+ const BUILTIN_OBJECTS = new Set([
112
+ 'console', 'math', 'json', 'object', 'array', 'promise', 'date',
113
+ 'string', 'number', 'boolean', 'symbol', 'regexp', 'error', 'map',
114
+ 'set', 'weakmap', 'weakset', 'proxy', 'reflect', 'intl',
115
+ 'arraybuffer', 'sharedarraybuffer', 'atomics', 'dataview',
116
+ 'this', 'self', 'super', 'window', 'document', 'process',
117
+ 'global', 'globalthis', 'module', 'exports', 'require',
118
+ '__dirname', '__filename',
119
+ ]);
110
120
  /**
111
121
  * Extract import declarations from a semantic model.
112
122
  * This is a heuristic extraction — real import extraction would come from the AST.
113
123
  */
114
124
  function extractImportsFromModel(filePath, model, projectRoot) {
115
125
  const imports = [];
126
+ // Build a set of known identifiers from the model (constants and local variables)
127
+ // These are the names that could plausibly be import aliases
128
+ const knownIdentifiers = new Set();
129
+ for (const [name] of model.constants) {
130
+ knownIdentifiers.add(name);
131
+ }
132
+ for (const [name] of model.localVariables) {
133
+ knownIdentifiers.add(name);
134
+ }
116
135
  // Use functions' calledFunctions to infer cross-file references
117
136
  for (const [, func] of model.functions) {
118
137
  for (const calledName of func.calledFunctions) {
@@ -120,6 +139,16 @@ function extractImportsFromModel(filePath, model, projectRoot) {
120
139
  const dotIndex = calledName.indexOf('.');
121
140
  if (dotIndex > 0) {
122
141
  const modulePart = calledName.substring(0, dotIndex);
142
+ // Skip common built-in objects that are never import sources
143
+ if (BUILTIN_OBJECTS.has(modulePart.toLowerCase())) {
144
+ continue;
145
+ }
146
+ // Only treat as an import if the prefix matches a known identifier
147
+ // (constant or local variable) in this file, which is how import
148
+ // aliases typically appear in the semantic model
149
+ if (!knownIdentifiers.has(modulePart)) {
150
+ continue;
151
+ }
123
152
  const resolvedPath = (0, importResolver_1.resolveImportPath)(`./${modulePart}`, filePath, projectRoot, model.language);
124
153
  if (resolvedPath) {
125
154
  imports.push({
@@ -1 +1 @@
1
- {"version":3,"file":"graphBuilder.d.ts","sourceRoot":"","sources":["../../../../../src/pipeline/stages/ast/graphBuilder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAoB,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AACtG,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,KAAK,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAIrE;;GAEG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,EAClC,cAAc,EAAE,oBAAoB,EACpC,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,EAC9C,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,uBAAuB,EAAE,CAAC,GACnD;IAAE,KAAK,EAAE,SAAS,EAAE,CAAC;IAAC,KAAK,EAAE,SAAS,EAAE,CAAA;CAAE,CAsN5C"}
1
+ {"version":3,"file":"graphBuilder.d.ts","sourceRoot":"","sources":["../../../../../src/pipeline/stages/ast/graphBuilder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAoB,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AACtG,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAiB,MAAM,aAAa,CAAC;AACvE,OAAO,KAAK,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAIrE;;GAEG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,EAClC,cAAc,EAAE,oBAAoB,EACpC,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,EAC9C,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,uBAAuB,EAAE,CAAC,GACnD;IAAE,KAAK,EAAE,SAAS,EAAE,CAAC;IAAC,KAAK,EAAE,SAAS,EAAE,CAAA;CAAE,CA4S5C"}
@@ -60,6 +60,28 @@ function buildAstGraph(models, crossFileTable, traversalResults, interactions) {
60
60
  addedEdgeIds.add(edge.id);
61
61
  edges.push(edge);
62
62
  }
63
+ /**
64
+ * Ensure a node exists in the graph. If the node ID is not yet present,
65
+ * create a stub node flagged as cross-file-unresolved (spec §2.3).
66
+ * Confidence on stub nodes is capped at 'low'.
67
+ */
68
+ function ensureNodeExists(nodeId, missingFilePath, nodeType) {
69
+ if (addedNodeIds.has(nodeId))
70
+ return nodeId;
71
+ addNode({
72
+ id: nodeId,
73
+ type: nodeType,
74
+ label: `[unresolved] ${path.basename(missingFilePath)}`,
75
+ sourceStage: 'ast',
76
+ filePath: missingFilePath,
77
+ metadata: {
78
+ resolution: 'cross-file-unresolved',
79
+ confidence: 'low',
80
+ diagnostic: `Cross-file resolution failed: file "${missingFilePath}" was not found in parsed models`,
81
+ },
82
+ });
83
+ return nodeId;
84
+ }
63
85
  // 1. Create file nodes for every parsed file
64
86
  for (const [filePath, model] of models) {
65
87
  const basename = path.basename(filePath);
@@ -241,6 +263,65 @@ function buildAstGraph(models, crossFileTable, traversalResults, interactions) {
241
263
  });
242
264
  }
243
265
  }
266
+ // 7. Feature 27: Create router mount edges
267
+ for (const [filePath, mounts] of crossFileTable.routerMounts) {
268
+ const sourceId = `file:${filePath}`;
269
+ if (!addedNodeIds.has(sourceId))
270
+ continue;
271
+ for (const mount of mounts) {
272
+ const targetId = `file:${mount.targetModulePath}`;
273
+ // Create edge even if target not parsed (creates stub node for missing files)
274
+ addEdge({
275
+ id: `${sourceId}->mounts->${mount.prefix}:${mount.targetModulePath}`,
276
+ type: 'router-mount',
277
+ sourceNodeId: sourceId,
278
+ targetNodeId: ensureNodeExists(targetId, mount.targetModulePath, 'file'),
279
+ sourceStage: 'ast',
280
+ metadata: {
281
+ prefix: mount.prefix,
282
+ targetModule: mount.targetModulePath,
283
+ middlewareCount: mount.middleware.length,
284
+ },
285
+ });
286
+ }
287
+ }
288
+ // 8. Feature 27: Create injection chain edges
289
+ for (const [consumerFile, chains] of crossFileTable.injectionChains) {
290
+ for (const chain of chains) {
291
+ const consumerNodeId = `file:${chain.consumerFile}`;
292
+ const serviceNodeId = `file:${chain.serviceFile}`;
293
+ addEdge({
294
+ id: `${consumerNodeId}->injects->${chain.serviceClass}:${chain.serviceFile}`,
295
+ type: 'injects',
296
+ sourceNodeId: ensureNodeExists(consumerNodeId, chain.consumerFile, 'file'),
297
+ targetNodeId: ensureNodeExists(serviceNodeId, chain.serviceFile, 'file'),
298
+ sourceStage: 'ast',
299
+ metadata: {
300
+ consumerClass: chain.consumerClass,
301
+ serviceClass: chain.serviceClass,
302
+ injectionStyle: chain.injectionStyle,
303
+ },
304
+ });
305
+ }
306
+ }
307
+ // 9. Feature 27: Create interface implementation edges
308
+ for (const [ifaceFile, impls] of crossFileTable.interfaceImplementations) {
309
+ for (const impl of impls) {
310
+ const ifaceNodeId = `file:${impl.interfaceFile}`;
311
+ const implNodeId = `file:${impl.implFile}`;
312
+ addEdge({
313
+ id: `${implNodeId}->implements->${impl.interfaceName}:${impl.interfaceFile}`,
314
+ type: 'implements',
315
+ sourceNodeId: ensureNodeExists(implNodeId, impl.implFile, 'file'),
316
+ targetNodeId: ensureNodeExists(ifaceNodeId, impl.interfaceFile, 'file'),
317
+ sourceStage: 'ast',
318
+ metadata: {
319
+ interfaceName: impl.interfaceName,
320
+ implName: impl.implName,
321
+ },
322
+ });
323
+ }
324
+ }
244
325
  return { nodes, edges };
245
326
  }
246
327
  /**
@@ -7,7 +7,9 @@
7
7
  * Express auth.optional / credentialsRequired: false → { optional: true }
8
8
  * HapiJS auth: { mode: 'try' } → { optional: true }
9
9
  * Spring @PreAuthorize → { required: true }
10
- * Angular route guarddepends on guard type
10
+ * Slim PHP optionalAuth{ optional: true }, jwt/auth → { required: true }
11
+ * Angular canActivate:none → { optional: true } (interceptor-based)
12
+ * NestJS @UseGuards → { required: true }
11
13
  */
12
14
  import type { SecurityClassification } from '../../../ast/astTypes';
13
15
  export interface AuthClassificationEntry {
@@ -1 +1 @@
1
- {"version":3,"file":"optionalAuthUnifier.d.ts","sourceRoot":"","sources":["../../../../../src/pipeline/stages/ast/optionalAuthUnifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAEpE,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,sBAAsB,CAAC;CACxC;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,sBAAsB,GAAG,SAAS,CAwCpC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,kBAAkB,GAAG,4BAA4B,CAAC;IACxD,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,sBAAsB,CAAC;IACjC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,sBAAsB,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,EACzF,kBAAkB,EAAE,GAAG,CAAC,MAAM,CAAC,GAC9B,eAAe,EAAE,CA0BnB"}
1
+ {"version":3,"file":"optionalAuthUnifier.d.ts","sourceRoot":"","sources":["../../../../../src/pipeline/stages/ast/optionalAuthUnifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAEpE,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,sBAAsB,CAAC;CACxC;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,sBAAsB,GAAG,SAAS,CA6DpC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,kBAAkB,GAAG,4BAA4B,CAAC;IACxD,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,sBAAsB,CAAC;IACjC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,sBAAsB,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,EACzF,kBAAkB,EAAE,GAAG,CAAC,MAAM,CAAC,GAC9B,eAAe,EAAE,CA0BnB"}
@@ -8,7 +8,9 @@
8
8
  * Express auth.optional / credentialsRequired: false → { optional: true }
9
9
  * HapiJS auth: { mode: 'try' } → { optional: true }
10
10
  * Spring @PreAuthorize → { required: true }
11
- * Angular route guarddepends on guard type
11
+ * Slim PHP optionalAuth{ optional: true }, jwt/auth → { required: true }
12
+ * Angular canActivate:none → { optional: true } (interceptor-based)
13
+ * NestJS @UseGuards → { required: true }
12
14
  */
13
15
  Object.defineProperty(exports, "__esModule", { value: true });
14
16
  exports.unifyAuthClassification = unifyAuthClassification;
@@ -18,36 +20,54 @@ exports.detectAuthCoverageGaps = detectAuthCoverageGaps;
18
20
  */
19
21
  function unifyAuthClassification(framework, pattern) {
20
22
  const key = `${framework}:${pattern}`.toLowerCase();
21
- // Flask patterns
22
- if (key.includes('flask:@jwt_required') || key.includes('flask:jwt_required')) {
23
+ // Flask patterns — use word-boundary regex to avoid matching e.g. "@jwt_required_custom"
24
+ if (/^flask:@?jwt_required\b/.test(key)) {
23
25
  return { type: 'jwt', required: true, optional: false, sourcePattern: pattern };
24
26
  }
25
- if (key.includes('flask:@jwt_optional') || key.includes('flask:jwt_optional')) {
27
+ if (/^flask:@?jwt_optional\b/.test(key)) {
26
28
  return { type: 'jwt', required: false, optional: true, sourcePattern: pattern };
27
29
  }
28
- if (key.includes('flask:@login_required') || key.includes('flask:login_required')) {
30
+ if (/^flask:@?login_required\b/.test(key)) {
29
31
  return { type: 'session', required: true, optional: false, sourcePattern: pattern };
30
32
  }
31
- // Express patterns
32
- if (key.includes('express:auth.required') || key.includes('express:credentialsrequired: true')) {
33
+ // Express patterns — use word-boundary regex for precise matching
34
+ if (/^express:auth\.required\b/.test(key) || /^express:credentialsrequired:\s*true\b/.test(key)) {
33
35
  return { type: 'jwt', required: true, optional: false, sourcePattern: pattern };
34
36
  }
35
- if (key.includes('express:auth.optional') || key.includes('express:credentialsrequired: false')) {
37
+ if (/^express:auth\.optional\b/.test(key) || /^express:credentialsrequired:\s*false\b/.test(key)) {
36
38
  return { type: 'jwt', required: false, optional: true, sourcePattern: pattern };
37
39
  }
38
- if (key.includes('express:passport.authenticate')) {
40
+ if (/^express:passport\.authenticate\b/.test(key)) {
39
41
  return { type: 'jwt', required: true, optional: false, sourcePattern: pattern };
40
42
  }
41
43
  // HapiJS patterns (framework may be 'hapi' or 'hapijs')
42
- const isHapi = key.startsWith('hapi:') || key.startsWith('hapijs:');
43
- if (isHapi && key.includes('auth') && key.includes('mode') && (key.includes('try') || key.includes('optional'))) {
44
+ const isHapi = /^hapi(?:js)?:/.test(key);
45
+ if (isHapi && /\bauth\b/.test(key) && /\bmode\b/.test(key) && (/\btry\b/.test(key) || /\boptional\b/.test(key))) {
44
46
  return { type: 'jwt', required: false, optional: true, sourcePattern: pattern };
45
47
  }
46
- if (isHapi && key.includes('auth') && !key.includes('false') && !key.includes('try') && !key.includes('optional')) {
48
+ if (isHapi && /\bauth\b/.test(key) && !/\bfalse\b/.test(key) && !/\btry\b/.test(key) && !/\boptional\b/.test(key)) {
47
49
  return { type: 'jwt', required: true, optional: false, sourcePattern: pattern };
48
50
  }
49
- // Spring patterns
50
- if (key.includes('spring:@preauthorize') || key.includes('spring:@secured')) {
51
+ // Spring patterns — include @RolesAllowed and @WithMockUser
52
+ if (/^spring:@?preauthorize\b/.test(key) || /^spring:@?secured\b/.test(key) || /^spring:@?rolesallowed\b/.test(key)) {
53
+ return { type: 'custom', required: true, optional: false, sourcePattern: pattern };
54
+ }
55
+ if (/^spring:@?withmockuser\b/.test(key)) {
56
+ return { type: 'custom', required: true, optional: false, sourcePattern: pattern };
57
+ }
58
+ // Slim PHP patterns — slim:optionalAuth is optional, slim:jwt or slim:auth is required
59
+ if (/^slim:optionalauth\b/.test(key)) {
60
+ return { type: 'jwt', required: false, optional: true, sourcePattern: pattern };
61
+ }
62
+ if (/^slim:(?:jwt|auth)\b/.test(key)) {
63
+ return { type: 'jwt', required: true, optional: false, sourcePattern: pattern };
64
+ }
65
+ // Angular patterns — canActivate:none (no guard) with interceptor tokens is optional
66
+ if (/^angular:canactivate:none\b/.test(key)) {
67
+ return { type: 'custom', required: false, optional: true, sourcePattern: pattern };
68
+ }
69
+ // NestJS patterns — @UseGuards is required auth
70
+ if (/^nestjs:@?useguards\b/.test(key)) {
51
71
  return { type: 'custom', required: true, optional: false, sourcePattern: pattern };
52
72
  }
53
73
  return undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"angularInjectionResolver.d.ts","sourceRoot":"","sources":["../../../../../../src/pipeline/stages/ast/resolvers/angularInjectionResolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EACV,iBAAiB,EACjB,0BAA0B,EAC1B,yBAAyB,EAC1B,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AAEpF,qBAAa,wBAAyB,YAAW,iBAAiB;IAChE,QAAQ,CAAC,IAAI,uBAAuB;IAEpC,SAAS,CAAC,UAAU,EAAE,oBAAoB,EAAE,GAAG,OAAO;IAItD,OAAO,CAAC,GAAG,EAAE,0BAA0B,GAAG,yBAAyB;CA0CpE"}
1
+ {"version":3,"file":"angularInjectionResolver.d.ts","sourceRoot":"","sources":["../../../../../../src/pipeline/stages/ast/resolvers/angularInjectionResolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EACV,iBAAiB,EACjB,0BAA0B,EAC1B,yBAAyB,EAC1B,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AAEpF,qBAAa,wBAAyB,YAAW,iBAAiB;IAChE,QAAQ,CAAC,IAAI,uBAAuB;IAEpC,SAAS,CAAC,UAAU,EAAE,oBAAoB,EAAE,GAAG,OAAO;IAItD,OAAO,CAAC,GAAG,EAAE,0BAA0B,GAAG,yBAAyB;CAyCpE"}
@@ -24,9 +24,7 @@ class AngularInjectionResolver {
24
24
  const unresolvedRefs = [];
25
25
  // Build injection chains from class registry
26
26
  for (const [className, classInfo] of ctx.symbolTable.classes) {
27
- // If class implements interfaces, it may be a service
28
- if (!classInfo.implementsInterfaces)
29
- continue;
27
+ // Check any class that has a model Angular services typically don't implement interfaces
30
28
  // Look for classes that have methods making HTTP calls
31
29
  const model = ctx.symbolTable.models.get(classInfo.filePath);
32
30
  if (!model)
@@ -73,5 +71,26 @@ function findConsumers(serviceName, ctx) {
73
71
  }
74
72
  }
75
73
  }
74
+ // Fallback: search class registry for classes that might inject this service
75
+ // (constructor injection detected by parameter name matching)
76
+ for (const [className, classInfo] of ctx.symbolTable.classes) {
77
+ // Skip if already found as a consumer
78
+ if (consumers.some((c) => c.className === className && c.file === classInfo.filePath))
79
+ continue;
80
+ // Check if this class's model has the service name in its calledFunctions
81
+ const model = ctx.symbolTable.models.get(classInfo.filePath);
82
+ if (!model)
83
+ continue;
84
+ for (const [, func] of model.functions) {
85
+ if (func.calledFunctions.some((f) => f.includes(serviceName))) {
86
+ consumers.push({
87
+ className,
88
+ file: classInfo.filePath,
89
+ style: 'constructor',
90
+ });
91
+ break;
92
+ }
93
+ }
94
+ }
76
95
  return consumers;
77
96
  }
@@ -1 +1 @@
1
- {"version":3,"file":"dddLayerResolver.d.ts","sourceRoot":"","sources":["../../../../../../src/pipeline/stages/ast/resolvers/dddLayerResolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EACV,iBAAiB,EACjB,0BAA0B,EAC1B,yBAAyB,EAC1B,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AAEpF,MAAM,WAAW,sBAAsB;IACrC,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;IAC3C,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,gBAAiB,YAAW,iBAAiB;IACxD,QAAQ,CAAC,IAAI,eAAe;IAE5B,SAAS,CAAC,UAAU,EAAE,oBAAoB,EAAE,GAAG,OAAO;IAMtD,OAAO,CAAC,GAAG,EAAE,0BAA0B,GAAG,yBAAyB;CAqEpE;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,sBAAsB,EAAE,CAgFrG;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,cAAc,EAAE,CAiCrF;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAcjG"}
1
+ {"version":3,"file":"dddLayerResolver.d.ts","sourceRoot":"","sources":["../../../../../../src/pipeline/stages/ast/resolvers/dddLayerResolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EACV,iBAAiB,EACjB,0BAA0B,EAC1B,yBAAyB,EAC1B,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AAEpF,MAAM,WAAW,sBAAsB;IACrC,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;IAC3C,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,gBAAiB,YAAW,iBAAiB;IACxD,QAAQ,CAAC,IAAI,eAAe;IAE5B,SAAS,CAAC,UAAU,EAAE,oBAAoB,EAAE,GAAG,OAAO;IAMtD,OAAO,CAAC,GAAG,EAAE,0BAA0B,GAAG,yBAAyB;CA+JpE;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,sBAAsB,EAAE,CAgFrG;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,cAAc,EAAE,CAiCrF;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAcjG"}