@eddacraft/anvil-core 0.1.0

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 (215) hide show
  1. package/LICENSE +14 -0
  2. package/dist/antipattern/index.d.ts +11 -0
  3. package/dist/antipattern/index.d.ts.map +1 -0
  4. package/dist/antipattern/index.js +31 -0
  5. package/dist/antipattern/patterns-css.d.ts +17 -0
  6. package/dist/antipattern/patterns-css.d.ts.map +1 -0
  7. package/dist/antipattern/patterns-css.js +72 -0
  8. package/dist/antipattern/patterns-html.d.ts +21 -0
  9. package/dist/antipattern/patterns-html.d.ts.map +1 -0
  10. package/dist/antipattern/patterns-html.js +139 -0
  11. package/dist/antipattern/patterns.d.ts +72 -0
  12. package/dist/antipattern/patterns.d.ts.map +1 -0
  13. package/dist/antipattern/patterns.js +301 -0
  14. package/dist/antipattern/scanner.d.ts +32 -0
  15. package/dist/antipattern/scanner.d.ts.map +1 -0
  16. package/dist/antipattern/scanner.js +89 -0
  17. package/dist/antipattern/types.d.ts +318 -0
  18. package/dist/antipattern/types.d.ts.map +1 -0
  19. package/dist/antipattern/types.js +278 -0
  20. package/dist/architecture/analyzer.d.ts +123 -0
  21. package/dist/architecture/analyzer.d.ts.map +1 -0
  22. package/dist/architecture/analyzer.js +321 -0
  23. package/dist/architecture/baseline.d.ts +112 -0
  24. package/dist/architecture/baseline.d.ts.map +1 -0
  25. package/dist/architecture/baseline.js +245 -0
  26. package/dist/architecture/compiler.d.ts +24 -0
  27. package/dist/architecture/compiler.d.ts.map +1 -0
  28. package/dist/architecture/compiler.js +57 -0
  29. package/dist/architecture/context.d.ts +129 -0
  30. package/dist/architecture/context.d.ts.map +1 -0
  31. package/dist/architecture/context.js +116 -0
  32. package/dist/architecture/dc-generator.d.ts +9 -0
  33. package/dist/architecture/dc-generator.d.ts.map +1 -0
  34. package/dist/architecture/dc-generator.js +220 -0
  35. package/dist/architecture/definition-schema.d.ts +128 -0
  36. package/dist/architecture/definition-schema.d.ts.map +1 -0
  37. package/dist/architecture/definition-schema.js +94 -0
  38. package/dist/architecture/edge-detector-html.d.ts +6 -0
  39. package/dist/architecture/edge-detector-html.d.ts.map +1 -0
  40. package/dist/architecture/edge-detector-html.js +5 -0
  41. package/dist/architecture/edge-detector-web.d.ts +32 -0
  42. package/dist/architecture/edge-detector-web.d.ts.map +1 -0
  43. package/dist/architecture/edge-detector-web.js +133 -0
  44. package/dist/architecture/edge-detector.d.ts +116 -0
  45. package/dist/architecture/edge-detector.d.ts.map +1 -0
  46. package/dist/architecture/edge-detector.js +229 -0
  47. package/dist/architecture/entry-detector.d.ts +44 -0
  48. package/dist/architecture/entry-detector.d.ts.map +1 -0
  49. package/dist/architecture/entry-detector.js +263 -0
  50. package/dist/architecture/index.d.ts +21 -0
  51. package/dist/architecture/index.d.ts.map +1 -0
  52. package/dist/architecture/index.js +48 -0
  53. package/dist/architecture/layer-detector.d.ts +60 -0
  54. package/dist/architecture/layer-detector.d.ts.map +1 -0
  55. package/dist/architecture/layer-detector.js +331 -0
  56. package/dist/architecture/rego-generator.d.ts +25 -0
  57. package/dist/architecture/rego-generator.d.ts.map +1 -0
  58. package/dist/architecture/rego-generator.js +229 -0
  59. package/dist/architecture/templates/index.d.ts +39 -0
  60. package/dist/architecture/templates/index.d.ts.map +1 -0
  61. package/dist/architecture/templates/index.js +124 -0
  62. package/dist/architecture/types.d.ts +280 -0
  63. package/dist/architecture/types.d.ts.map +1 -0
  64. package/dist/architecture/types.js +269 -0
  65. package/dist/architecture/yaml-parser.d.ts +13 -0
  66. package/dist/architecture/yaml-parser.d.ts.map +1 -0
  67. package/dist/architecture/yaml-parser.js +234 -0
  68. package/dist/config/constants.d.ts +9 -0
  69. package/dist/config/constants.d.ts.map +1 -0
  70. package/dist/config/constants.js +20 -0
  71. package/dist/config/index.d.ts +9 -0
  72. package/dist/config/index.d.ts.map +1 -0
  73. package/dist/config/index.js +8 -0
  74. package/dist/config/loader.d.ts +41 -0
  75. package/dist/config/loader.d.ts.map +1 -0
  76. package/dist/config/loader.js +76 -0
  77. package/dist/config/nudge-config.d.ts +35 -0
  78. package/dist/config/nudge-config.d.ts.map +1 -0
  79. package/dist/config/nudge-config.js +34 -0
  80. package/dist/config/types.d.ts +30 -0
  81. package/dist/config/types.d.ts.map +1 -0
  82. package/dist/config/types.js +4 -0
  83. package/dist/contracts/index.d.ts +14 -0
  84. package/dist/contracts/index.d.ts.map +1 -0
  85. package/dist/contracts/index.js +13 -0
  86. package/dist/contracts/schemas/aps.schema.d.ts +269 -0
  87. package/dist/contracts/schemas/aps.schema.d.ts.map +1 -0
  88. package/dist/contracts/schemas/aps.schema.js +183 -0
  89. package/dist/contracts/schemas/index.d.ts +12 -0
  90. package/dist/contracts/schemas/index.d.ts.map +1 -0
  91. package/dist/contracts/schemas/index.js +14 -0
  92. package/dist/contracts/schemas/json-schema.d.ts +14 -0
  93. package/dist/contracts/schemas/json-schema.d.ts.map +1 -0
  94. package/dist/contracts/schemas/json-schema.js +31 -0
  95. package/dist/contracts/schemas/warning.schema.d.ts +171 -0
  96. package/dist/contracts/schemas/warning.schema.d.ts.map +1 -0
  97. package/dist/contracts/schemas/warning.schema.js +123 -0
  98. package/dist/contracts/types/gate.types.d.ts +194 -0
  99. package/dist/contracts/types/gate.types.d.ts.map +1 -0
  100. package/dist/contracts/types/gate.types.js +19 -0
  101. package/dist/contracts/types/index.d.ts +9 -0
  102. package/dist/contracts/types/index.d.ts.map +1 -0
  103. package/dist/contracts/types/index.js +8 -0
  104. package/dist/crypto/hash.d.ts +47 -0
  105. package/dist/crypto/hash.d.ts.map +1 -0
  106. package/dist/crypto/hash.js +110 -0
  107. package/dist/crypto/index.d.ts +7 -0
  108. package/dist/crypto/index.d.ts.map +1 -0
  109. package/dist/crypto/index.js +6 -0
  110. package/dist/drift/index.d.ts +6 -0
  111. package/dist/drift/index.d.ts.map +1 -0
  112. package/dist/drift/index.js +5 -0
  113. package/dist/drift/report-generator.d.ts +21 -0
  114. package/dist/drift/report-generator.d.ts.map +1 -0
  115. package/dist/drift/report-generator.js +240 -0
  116. package/dist/drift/snapshot-capture.d.ts +26 -0
  117. package/dist/drift/snapshot-capture.d.ts.map +1 -0
  118. package/dist/drift/snapshot-capture.js +195 -0
  119. package/dist/drift/snapshot-compare.d.ts +50 -0
  120. package/dist/drift/snapshot-compare.d.ts.map +1 -0
  121. package/dist/drift/snapshot-compare.js +142 -0
  122. package/dist/drift/snapshot-schema.d.ts +197 -0
  123. package/dist/drift/snapshot-schema.d.ts.map +1 -0
  124. package/dist/drift/snapshot-schema.js +193 -0
  125. package/dist/drift/snapshot-storage.d.ts +25 -0
  126. package/dist/drift/snapshot-storage.d.ts.map +1 -0
  127. package/dist/drift/snapshot-storage.js +179 -0
  128. package/dist/explain/antipattern-explainer.d.ts +4 -0
  129. package/dist/explain/antipattern-explainer.d.ts.map +1 -0
  130. package/dist/explain/antipattern-explainer.js +196 -0
  131. package/dist/explain/boundary-explainer.d.ts +5 -0
  132. package/dist/explain/boundary-explainer.d.ts.map +1 -0
  133. package/dist/explain/boundary-explainer.js +261 -0
  134. package/dist/explain/explain-service.d.ts +19 -0
  135. package/dist/explain/explain-service.d.ts.map +1 -0
  136. package/dist/explain/explain-service.js +106 -0
  137. package/dist/explain/index.d.ts +7 -0
  138. package/dist/explain/index.d.ts.map +1 -0
  139. package/dist/explain/index.js +5 -0
  140. package/dist/explain/template-loader.d.ts +9 -0
  141. package/dist/explain/template-loader.d.ts.map +1 -0
  142. package/dist/explain/template-loader.js +51 -0
  143. package/dist/explain/types.d.ts +46 -0
  144. package/dist/explain/types.d.ts.map +1 -0
  145. package/dist/explain/types.js +31 -0
  146. package/dist/index.d.ts +26 -0
  147. package/dist/index.d.ts.map +1 -0
  148. package/dist/index.js +37 -0
  149. package/dist/provenance/collector.d.ts +86 -0
  150. package/dist/provenance/collector.d.ts.map +1 -0
  151. package/dist/provenance/collector.js +425 -0
  152. package/dist/provenance/git-ai-standard/git-notes.d.ts +85 -0
  153. package/dist/provenance/git-ai-standard/git-notes.d.ts.map +1 -0
  154. package/dist/provenance/git-ai-standard/git-notes.js +292 -0
  155. package/dist/provenance/git-ai-standard/index.d.ts +44 -0
  156. package/dist/provenance/git-ai-standard/index.d.ts.map +1 -0
  157. package/dist/provenance/git-ai-standard/index.js +47 -0
  158. package/dist/provenance/git-ai-standard/serializer.d.ts +54 -0
  159. package/dist/provenance/git-ai-standard/serializer.d.ts.map +1 -0
  160. package/dist/provenance/git-ai-standard/serializer.js +224 -0
  161. package/dist/provenance/git-ai-standard/session.d.ts +51 -0
  162. package/dist/provenance/git-ai-standard/session.d.ts.map +1 -0
  163. package/dist/provenance/git-ai-standard/session.js +118 -0
  164. package/dist/provenance/git-ai-standard/types.d.ts +173 -0
  165. package/dist/provenance/git-ai-standard/types.d.ts.map +1 -0
  166. package/dist/provenance/git-ai-standard/types.js +109 -0
  167. package/dist/provenance/index.d.ts +5 -0
  168. package/dist/provenance/index.d.ts.map +1 -0
  169. package/dist/provenance/index.js +6 -0
  170. package/dist/provenance/store.d.ts +83 -0
  171. package/dist/provenance/store.d.ts.map +1 -0
  172. package/dist/provenance/store.js +248 -0
  173. package/dist/provenance/types.d.ts +160 -0
  174. package/dist/provenance/types.d.ts.map +1 -0
  175. package/dist/provenance/types.js +112 -0
  176. package/dist/suppression/index.d.ts +4 -0
  177. package/dist/suppression/index.d.ts.map +1 -0
  178. package/dist/suppression/index.js +3 -0
  179. package/dist/suppression/parser.d.ts +31 -0
  180. package/dist/suppression/parser.d.ts.map +1 -0
  181. package/dist/suppression/parser.js +219 -0
  182. package/dist/suppression/service.d.ts +29 -0
  183. package/dist/suppression/service.d.ts.map +1 -0
  184. package/dist/suppression/service.js +132 -0
  185. package/dist/suppression/store.d.ts +61 -0
  186. package/dist/suppression/store.d.ts.map +1 -0
  187. package/dist/suppression/store.js +169 -0
  188. package/dist/utils/debug.d.ts +48 -0
  189. package/dist/utils/debug.d.ts.map +1 -0
  190. package/dist/utils/debug.js +100 -0
  191. package/dist/utils/index.d.ts +4 -0
  192. package/dist/utils/index.d.ts.map +1 -0
  193. package/dist/utils/index.js +3 -0
  194. package/dist/utils/path-safety.d.ts +21 -0
  195. package/dist/utils/path-safety.d.ts.map +1 -0
  196. package/dist/utils/path-safety.js +49 -0
  197. package/dist/utils/severity.d.ts +37 -0
  198. package/dist/utils/severity.d.ts.map +1 -0
  199. package/dist/utils/severity.js +22 -0
  200. package/dist/validation/aps-validator.d.ts +66 -0
  201. package/dist/validation/aps-validator.d.ts.map +1 -0
  202. package/dist/validation/aps-validator.js +173 -0
  203. package/dist/validation/errors.d.ts +52 -0
  204. package/dist/validation/errors.d.ts.map +1 -0
  205. package/dist/validation/errors.js +115 -0
  206. package/dist/validation/index.d.ts +8 -0
  207. package/dist/validation/index.d.ts.map +1 -0
  208. package/dist/validation/index.js +13 -0
  209. package/dist/warnings/index.d.ts +2 -0
  210. package/dist/warnings/index.d.ts.map +1 -0
  211. package/dist/warnings/index.js +1 -0
  212. package/dist/warnings/warning-id.d.ts +180 -0
  213. package/dist/warnings/warning-id.d.ts.map +1 -0
  214. package/dist/warnings/warning-id.js +257 -0
  215. package/package.json +79 -0
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Edge detector for architecture boundary analysis
3
+ *
4
+ * Extracts import edges from source files and compares them against
5
+ * the baseline to identify NEW vs existing violations.
6
+ *
7
+ * **Limitations**:
8
+ * - Import extraction is line-based regex. Multi-line imports split across
9
+ * lines (e.g., imports with many named exports) may not be detected.
10
+ * - For accurate detection, use TypeScript compiler API in production.
11
+ */
12
+ import type { DependencyEdge, BaselineViolation } from './types.js';
13
+ /**
14
+ * Import edge extracted from source code
15
+ */
16
+ export interface ImportEdge {
17
+ /** Source file path (relative to workspace) */
18
+ from: string;
19
+ /** Target file path (resolved, relative to workspace) - used for baseline comparison */
20
+ to: string;
21
+ /** Line number of import statement (1-based) */
22
+ line: number;
23
+ /** Type of import */
24
+ type: 'import' | 'require' | 'dynamic';
25
+ /** Raw import specifier as written in code */
26
+ specifier: string;
27
+ }
28
+ /**
29
+ * Result of baseline comparison
30
+ */
31
+ export interface BaselineComparison {
32
+ /** Edges that exist in baseline (existing violations) */
33
+ existing: ImportEdge[];
34
+ /** Edges NOT in baseline (new violations) */
35
+ new: ImportEdge[];
36
+ /** Edges in baseline but not in current (fixed violations) */
37
+ fixed: BaselineViolation[];
38
+ }
39
+ /**
40
+ * Options for import extraction
41
+ */
42
+ export interface ExtractOptions {
43
+ /** Include dynamic imports (default: true) */
44
+ includeDynamic?: boolean;
45
+ /** Include require() calls (default: true) */
46
+ includeRequire?: boolean;
47
+ }
48
+ /**
49
+ * Resolve an import specifier to a workspace-relative path
50
+ *
51
+ * Relative imports (./foo, ../bar) are resolved against the importing file.
52
+ * Absolute/package imports are returned as-is (external dependencies).
53
+ */
54
+ export declare function resolveImportPath(specifier: string, fromFile: string): string;
55
+ /**
56
+ * Create a stable fingerprint for an edge
57
+ *
58
+ * Used for deduplication and baseline comparison.
59
+ * Format: SHA-256 hash of "from:to:line"
60
+ */
61
+ export declare function createEdgeFingerprint(from: string, to: string, line: number): string;
62
+ /**
63
+ * Create a fingerprint for an ImportEdge
64
+ */
65
+ export declare function fingerprintEdge(edge: ImportEdge): string;
66
+ /**
67
+ * Extract all import edges from a source file
68
+ *
69
+ * @param filePath - Path to source file (relative to workspace)
70
+ * @param workspaceRoot - Workspace root directory
71
+ * @param options - Extraction options
72
+ * @returns Array of import edges found in the file
73
+ */
74
+ export declare function extractImports(filePath: string, workspaceRoot: string, options?: ExtractOptions): ImportEdge[];
75
+ /**
76
+ * Extract imports from multiple files
77
+ *
78
+ * @param filePaths - Array of file paths (relative to workspace)
79
+ * @param workspaceRoot - Workspace root directory
80
+ * @param options - Extraction options
81
+ * @returns Array of all import edges
82
+ */
83
+ export declare function extractImportsFromFiles(filePaths: string[], workspaceRoot: string, options?: ExtractOptions): ImportEdge[];
84
+ /**
85
+ * Compare current edges against baseline violations
86
+ *
87
+ * @param currentEdges - Edges extracted from current code
88
+ * @param baselineViolations - Violations recorded in baseline
89
+ * @returns Comparison result with new, existing, and fixed violations
90
+ */
91
+ export declare function compareToBaseline(currentEdges: ImportEdge[], baselineViolations: BaselineViolation[]): BaselineComparison;
92
+ /**
93
+ * Convert ImportEdge to DependencyEdge
94
+ *
95
+ * @param edge - Import edge to convert
96
+ * @param fromLayer - Source layer (null if unknown)
97
+ * @param toLayer - Target layer (null if unknown)
98
+ * @returns DependencyEdge for use in violation tracking
99
+ */
100
+ export declare function toDependencyEdge(edge: ImportEdge, fromLayer?: string | null, toLayer?: string | null): DependencyEdge;
101
+ /**
102
+ * Deduplicate edges by fingerprint
103
+ *
104
+ * @param edges - Array of edges (may contain duplicates)
105
+ * @returns Deduplicated array
106
+ */
107
+ export declare function deduplicateEdges(edges: ImportEdge[]): ImportEdge[];
108
+ /**
109
+ * Filter edges to only include those crossing layer boundaries
110
+ *
111
+ * @param edges - All import edges
112
+ * @param getLayer - Function to determine layer for a file path
113
+ * @returns Edges that cross layer boundaries
114
+ */
115
+ export declare function filterCrossLayerEdges(edges: ImportEdge[], getLayer: (filePath: string) => string | null): ImportEdge[];
116
+ //# sourceMappingURL=edge-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edge-detector.d.ts","sourceRoot":"","sources":["../../src/architecture/edge-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAOpE;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,wFAAwF;IACxF,EAAE,EAAE,MAAM,CAAC;IACX,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,qBAAqB;IACrB,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;IACvC,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,yDAAyD;IACzD,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,6CAA6C;IAC7C,GAAG,EAAE,UAAU,EAAE,CAAC;IAClB,8DAA8D;IAC9D,KAAK,EAAE,iBAAiB,EAAE,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,8CAA8C;IAC9C,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,8CAA8C;IAC9C,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAOD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAO7E;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAGpF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAExD;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE,cAAmB,GAC3B,UAAU,EAAE,CA8Ed;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EAAE,EACnB,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE,cAAmB,GAC3B,UAAU,EAAE,CASd;AAMD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,UAAU,EAAE,EAC1B,kBAAkB,EAAE,iBAAiB,EAAE,GACtC,kBAAkB,CAuBpB;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,UAAU,EAChB,SAAS,GAAE,MAAM,GAAG,IAAW,EAC/B,OAAO,GAAE,MAAM,GAAG,IAAW,GAC5B,cAAc,CAShB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,UAAU,EAAE,CAalE;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,UAAU,EAAE,EACnB,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GAC5C,UAAU,EAAE,CAQd"}
@@ -0,0 +1,229 @@
1
+ /**
2
+ * Edge detector for architecture boundary analysis
3
+ *
4
+ * Extracts import edges from source files and compares them against
5
+ * the baseline to identify NEW vs existing violations.
6
+ *
7
+ * **Limitations**:
8
+ * - Import extraction is line-based regex. Multi-line imports split across
9
+ * lines (e.g., imports with many named exports) may not be detected.
10
+ * - For accurate detection, use TypeScript compiler API in production.
11
+ */
12
+ import { readFileSync } from 'node:fs';
13
+ import { join, dirname, normalize, extname } from 'node:path';
14
+ import { createHash } from 'node:crypto';
15
+ import { createViolationId } from './types.js';
16
+ import { extractHtmlEdges, extractCssEdges } from './edge-detector-web.js';
17
+ import { createDebugger } from '../utils/debug.js';
18
+ const debug = createDebugger('edge-detector');
19
+ const IMPORT_FROM_REGEX = /import\s+(?:[\w\s{},*]+\s+from\s+)?['"]([^'"]+)['"]/g;
20
+ const DYNAMIC_IMPORT_REGEX = /import\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
21
+ const REQUIRE_REGEX = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
22
+ const EXPORT_FROM_REGEX = /export\s+(?:[\w\s{},*]+\s+from\s+)['"]([^'"]+)['"]/g;
23
+ /**
24
+ * Resolve an import specifier to a workspace-relative path
25
+ *
26
+ * Relative imports (./foo, ../bar) are resolved against the importing file.
27
+ * Absolute/package imports are returned as-is (external dependencies).
28
+ */
29
+ export function resolveImportPath(specifier, fromFile) {
30
+ if (specifier.startsWith('.')) {
31
+ const fromDir = dirname(fromFile);
32
+ const resolved = normalize(join(fromDir, specifier));
33
+ return resolved.replace(/\\/g, '/');
34
+ }
35
+ return specifier;
36
+ }
37
+ /**
38
+ * Create a stable fingerprint for an edge
39
+ *
40
+ * Used for deduplication and baseline comparison.
41
+ * Format: SHA-256 hash of "from:to:line"
42
+ */
43
+ export function createEdgeFingerprint(from, to, line) {
44
+ const input = `${from}:${to}:${line}`;
45
+ return createHash('sha256').update(input).digest('hex').slice(0, 16);
46
+ }
47
+ /**
48
+ * Create a fingerprint for an ImportEdge
49
+ */
50
+ export function fingerprintEdge(edge) {
51
+ return createEdgeFingerprint(edge.from, edge.to, edge.line);
52
+ }
53
+ /**
54
+ * Extract all import edges from a source file
55
+ *
56
+ * @param filePath - Path to source file (relative to workspace)
57
+ * @param workspaceRoot - Workspace root directory
58
+ * @param options - Extraction options
59
+ * @returns Array of import edges found in the file
60
+ */
61
+ export function extractImports(filePath, workspaceRoot, options = {}) {
62
+ const { includeDynamic = true, includeRequire = true } = options;
63
+ const edges = [];
64
+ let content;
65
+ try {
66
+ const fullPath = workspaceRoot ? join(workspaceRoot, filePath) : filePath;
67
+ content = readFileSync(fullPath, 'utf-8');
68
+ }
69
+ catch (err) {
70
+ debug('failed to read file for import extraction:', err);
71
+ return edges;
72
+ }
73
+ // Delegate to HTML/CSS extractors based on file extension
74
+ const ext = extname(filePath).toLowerCase();
75
+ if (ext === '.html' || ext === '.htm') {
76
+ return extractHtmlEdges(filePath, content);
77
+ }
78
+ if (ext === '.css' || ext === '.scss' || ext === '.less') {
79
+ return extractCssEdges(filePath, content);
80
+ }
81
+ const lines = content.split('\n');
82
+ for (let i = 0; i < lines.length; i++) {
83
+ const line = lines[i];
84
+ const lineNumber = i + 1;
85
+ for (const match of line.matchAll(IMPORT_FROM_REGEX)) {
86
+ const specifier = match[1];
87
+ edges.push({
88
+ from: filePath,
89
+ to: resolveImportPath(specifier, filePath),
90
+ line: lineNumber,
91
+ type: 'import',
92
+ specifier,
93
+ });
94
+ }
95
+ for (const match of line.matchAll(EXPORT_FROM_REGEX)) {
96
+ const specifier = match[1];
97
+ edges.push({
98
+ from: filePath,
99
+ to: resolveImportPath(specifier, filePath),
100
+ line: lineNumber,
101
+ type: 'import',
102
+ specifier,
103
+ });
104
+ }
105
+ if (includeDynamic) {
106
+ for (const match of line.matchAll(DYNAMIC_IMPORT_REGEX)) {
107
+ const specifier = match[1];
108
+ edges.push({
109
+ from: filePath,
110
+ to: resolveImportPath(specifier, filePath),
111
+ line: lineNumber,
112
+ type: 'dynamic',
113
+ specifier,
114
+ });
115
+ }
116
+ }
117
+ if (includeRequire) {
118
+ for (const match of line.matchAll(REQUIRE_REGEX)) {
119
+ const specifier = match[1];
120
+ edges.push({
121
+ from: filePath,
122
+ to: resolveImportPath(specifier, filePath),
123
+ line: lineNumber,
124
+ type: 'require',
125
+ specifier,
126
+ });
127
+ }
128
+ }
129
+ }
130
+ return edges;
131
+ }
132
+ /**
133
+ * Extract imports from multiple files
134
+ *
135
+ * @param filePaths - Array of file paths (relative to workspace)
136
+ * @param workspaceRoot - Workspace root directory
137
+ * @param options - Extraction options
138
+ * @returns Array of all import edges
139
+ */
140
+ export function extractImportsFromFiles(filePaths, workspaceRoot, options = {}) {
141
+ const allEdges = [];
142
+ for (const filePath of filePaths) {
143
+ const edges = extractImports(filePath, workspaceRoot, options);
144
+ allEdges.push(...edges);
145
+ }
146
+ return allEdges;
147
+ }
148
+ function edgeToViolationId(edge) {
149
+ return createViolationId(edge.from, edge.to, edge.line);
150
+ }
151
+ /**
152
+ * Compare current edges against baseline violations
153
+ *
154
+ * @param currentEdges - Edges extracted from current code
155
+ * @param baselineViolations - Violations recorded in baseline
156
+ * @returns Comparison result with new, existing, and fixed violations
157
+ */
158
+ export function compareToBaseline(currentEdges, baselineViolations) {
159
+ const baselineIds = new Set(baselineViolations.map((v) => v.id));
160
+ const currentIds = new Set(currentEdges.map((e) => edgeToViolationId(e)));
161
+ const existingEdges = [];
162
+ const newEdges = [];
163
+ for (const edge of currentEdges) {
164
+ const violationId = edgeToViolationId(edge);
165
+ if (baselineIds.has(violationId)) {
166
+ existingEdges.push(edge);
167
+ }
168
+ else {
169
+ newEdges.push(edge);
170
+ }
171
+ }
172
+ const fixedViolations = baselineViolations.filter((v) => !currentIds.has(v.id));
173
+ return {
174
+ existing: existingEdges,
175
+ new: newEdges,
176
+ fixed: fixedViolations,
177
+ };
178
+ }
179
+ /**
180
+ * Convert ImportEdge to DependencyEdge
181
+ *
182
+ * @param edge - Import edge to convert
183
+ * @param fromLayer - Source layer (null if unknown)
184
+ * @param toLayer - Target layer (null if unknown)
185
+ * @returns DependencyEdge for use in violation tracking
186
+ */
187
+ export function toDependencyEdge(edge, fromLayer = null, toLayer = null) {
188
+ return {
189
+ from: edge.from,
190
+ to: edge.to,
191
+ from_layer: fromLayer,
192
+ to_layer: toLayer,
193
+ line: edge.line,
194
+ type: edge.type,
195
+ };
196
+ }
197
+ /**
198
+ * Deduplicate edges by fingerprint
199
+ *
200
+ * @param edges - Array of edges (may contain duplicates)
201
+ * @returns Deduplicated array
202
+ */
203
+ export function deduplicateEdges(edges) {
204
+ const seen = new Set();
205
+ const unique = [];
206
+ for (const edge of edges) {
207
+ const fingerprint = fingerprintEdge(edge);
208
+ if (!seen.has(fingerprint)) {
209
+ seen.add(fingerprint);
210
+ unique.push(edge);
211
+ }
212
+ }
213
+ return unique;
214
+ }
215
+ /**
216
+ * Filter edges to only include those crossing layer boundaries
217
+ *
218
+ * @param edges - All import edges
219
+ * @param getLayer - Function to determine layer for a file path
220
+ * @returns Edges that cross layer boundaries
221
+ */
222
+ export function filterCrossLayerEdges(edges, getLayer) {
223
+ return edges.filter((edge) => {
224
+ const fromLayer = getLayer(edge.from);
225
+ const toLayer = getLayer(edge.to);
226
+ // Only include if both have layers and they're different
227
+ return fromLayer !== null && toLayer !== null && fromLayer !== toLayer;
228
+ });
229
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Entry point detection heuristics
3
+ *
4
+ * Detects application entry points from file patterns and exports.
5
+ */
6
+ import type { EntryPoint } from './types.js';
7
+ /**
8
+ * Entry point detector
9
+ */
10
+ export declare class EntryPointDetector {
11
+ private workspaceRoot;
12
+ constructor(workspaceRoot: string);
13
+ /**
14
+ * Detect entry point type for a file
15
+ *
16
+ * Detection priority:
17
+ * 1. package.json bin entries (highest - explicit CLI declaration)
18
+ * 2. File name matches (specific file names like main.ts, cli.ts)
19
+ * 3. Directory matches (files in specific directories like routes/, workers/)
20
+ * 4. package.json main/exports (fallback for package entries)
21
+ */
22
+ detectEntryPoint(filePath: string): EntryPoint | null;
23
+ /**
24
+ * Check if file is a bin entry in package.json
25
+ */
26
+ private checkPackageJsonBin;
27
+ /**
28
+ * Check if file is referenced in package.json main or exports
29
+ */
30
+ private checkPackageJsonMainExports;
31
+ /**
32
+ * Detect all entry points from a list of files
33
+ */
34
+ detectEntryPoints(filePaths: string[]): EntryPoint[];
35
+ /**
36
+ * Filter to only non-test entry points
37
+ */
38
+ filterNonTestEntryPoints(entryPoints: EntryPoint[]): EntryPoint[];
39
+ }
40
+ /**
41
+ * Create an entry point detector
42
+ */
43
+ export declare function createEntryPointDetector(workspaceRoot: string): EntryPointDetector;
44
+ //# sourceMappingURL=entry-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entry-detector.d.ts","sourceRoot":"","sources":["../../src/architecture/entry-detector.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAuC,MAAM,YAAY,CAAC;AA8ElF;;GAEG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,aAAa,CAAS;gBAElB,aAAa,EAAE,MAAM;IAIjC;;;;;;;;OAQG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAuDrD;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAgC3B;;OAEG;IACH,OAAO,CAAC,2BAA2B;IAiEnC;;OAEG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,UAAU,EAAE;IAgCpD;;OAEG;IACH,wBAAwB,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,UAAU,EAAE;CAGlE;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,aAAa,EAAE,MAAM,GAAG,kBAAkB,CAElF"}
@@ -0,0 +1,263 @@
1
+ /**
2
+ * Entry point detection heuristics
3
+ *
4
+ * Detects application entry points from file patterns and exports.
5
+ */
6
+ import { existsSync, readFileSync } from 'node:fs';
7
+ import { join, basename, dirname } from 'node:path';
8
+ import { createDebugger } from '../utils/debug.js';
9
+ const debug = createDebugger('entry-detector');
10
+ /**
11
+ * Default entry point patterns
12
+ *
13
+ * Order matters: more specific patterns (application, cli, worker) come before
14
+ * generic ones (package). File name matches take priority over directory matches.
15
+ */
16
+ const ENTRY_POINT_PATTERNS = [
17
+ // Tests (check first - test files should always be identified as tests)
18
+ {
19
+ type: 'test',
20
+ filePatterns: [/\.(test|spec)\.(ts|js)$/, /^test\.(ts|js)$/],
21
+ directoryPatterns: [/^__tests__$/, /^tests?$/, /^spec$/],
22
+ confidence: 'high',
23
+ },
24
+ // Application entries (specific file names)
25
+ {
26
+ type: 'application',
27
+ filePatterns: [
28
+ /^main\.(ts|js|mjs|cjs)$/,
29
+ /^app\.(ts|js|mjs|cjs)$/,
30
+ /^server\.(ts|js|mjs|cjs)$/,
31
+ /^start\.(ts|js|mjs|cjs)$/,
32
+ ],
33
+ directoryPatterns: [/^app$/, /^server$/], // Removed /^src$/ - too generic
34
+ confidence: 'high',
35
+ },
36
+ // CLI commands (specific file names and directories)
37
+ {
38
+ type: 'cli',
39
+ filePatterns: [/^cli\.(ts|js)$/, /^bin\.(ts|js)$/, /^command\.(ts|js)$/],
40
+ directoryPatterns: [/^cli$/, /^bin$/, /^commands$/],
41
+ confidence: 'high',
42
+ },
43
+ // Workers (specific file names and directories)
44
+ {
45
+ type: 'worker',
46
+ filePatterns: [/^worker\.(ts|js)$/, /^job\.(ts|js)$/, /^consumer\.(ts|js)$/],
47
+ directoryPatterns: [/^workers$/, /^jobs$/, /^consumers$/, /^queues$/],
48
+ confidence: 'high',
49
+ },
50
+ // HTTP handlers (specific directories)
51
+ {
52
+ type: 'http',
53
+ filePatterns: [/^routes\.(ts|js)$/, /^router\.(ts|js)$/],
54
+ directoryPatterns: [/^routes$/, /^controllers$/, /^handlers$/],
55
+ confidence: 'high',
56
+ },
57
+ // API handlers (specific directories)
58
+ {
59
+ type: 'api',
60
+ filePatterns: [/^api\.(ts|js)$/, /^handler\.(ts|js)$/],
61
+ directoryPatterns: [/^api$/, /^endpoints$/],
62
+ confidence: 'medium',
63
+ },
64
+ // Package entries (generic - check last)
65
+ {
66
+ type: 'package',
67
+ filePatterns: [/^index\.(ts|js|mjs|cjs)$/],
68
+ directoryPatterns: [], // Removed /^src$/ - too generic, causes false positives
69
+ confidence: 'high',
70
+ },
71
+ ];
72
+ /**
73
+ * Entry point detector
74
+ */
75
+ export class EntryPointDetector {
76
+ workspaceRoot;
77
+ constructor(workspaceRoot) {
78
+ this.workspaceRoot = workspaceRoot;
79
+ }
80
+ /**
81
+ * Detect entry point type for a file
82
+ *
83
+ * Detection priority:
84
+ * 1. package.json bin entries (highest - explicit CLI declaration)
85
+ * 2. File name matches (specific file names like main.ts, cli.ts)
86
+ * 3. Directory matches (files in specific directories like routes/, workers/)
87
+ * 4. package.json main/exports (fallback for package entries)
88
+ */
89
+ detectEntryPoint(filePath) {
90
+ const fileName = basename(filePath);
91
+ const relativePath = filePath.startsWith(this.workspaceRoot)
92
+ ? filePath.slice(this.workspaceRoot.length + 1)
93
+ : filePath;
94
+ // Get all directory segments for matching (e.g., src/api/v1 -> ['src', 'api', 'v1'])
95
+ const pathSegments = dirname(relativePath).split(/[/\\]/).filter(Boolean);
96
+ // First: check package.json bin entries (explicit CLI declaration takes priority)
97
+ const binEntry = this.checkPackageJsonBin(relativePath);
98
+ if (binEntry) {
99
+ return binEntry;
100
+ }
101
+ // Second: check file name patterns (highest priority for pattern matching)
102
+ for (const pattern of ENTRY_POINT_PATTERNS) {
103
+ const fileMatch = pattern.filePatterns.some((p) => p.test(fileName));
104
+ if (fileMatch) {
105
+ const dirMatch = pathSegments.some((segment) => pattern.directoryPatterns.some((p) => p.test(segment)));
106
+ return {
107
+ path: relativePath,
108
+ type: pattern.type,
109
+ confidence: fileMatch && dirMatch ? 'high' : pattern.confidence,
110
+ };
111
+ }
112
+ }
113
+ // Third: check directory patterns (any segment in path)
114
+ for (const pattern of ENTRY_POINT_PATTERNS) {
115
+ const dirMatch = pathSegments.some((segment) => pattern.directoryPatterns.some((p) => p.test(segment)));
116
+ if (dirMatch) {
117
+ return {
118
+ path: relativePath,
119
+ type: pattern.type,
120
+ confidence: pattern.confidence,
121
+ };
122
+ }
123
+ }
124
+ // Fourth: check package.json main/exports (fallback)
125
+ const pkgEntry = this.checkPackageJsonMainExports(relativePath);
126
+ if (pkgEntry) {
127
+ return pkgEntry;
128
+ }
129
+ return null;
130
+ }
131
+ /**
132
+ * Check if file is a bin entry in package.json
133
+ */
134
+ checkPackageJsonBin(filePath) {
135
+ const pkgPath = join(this.workspaceRoot, 'package.json');
136
+ if (!existsSync(pkgPath)) {
137
+ return null;
138
+ }
139
+ try {
140
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
141
+ const normalisedPath = filePath.replace(/\\/g, '/');
142
+ if (pkg.bin) {
143
+ const binEntries = typeof pkg.bin === 'string' ? { [pkg.name]: pkg.bin } : pkg.bin;
144
+ for (const binPath of Object.values(binEntries)) {
145
+ const normalisedBin = binPath.replace(/^\.\//, '');
146
+ if (normalisedPath === normalisedBin || normalisedPath.endsWith(normalisedBin)) {
147
+ return {
148
+ path: filePath,
149
+ type: 'cli',
150
+ confidence: 'high',
151
+ };
152
+ }
153
+ }
154
+ }
155
+ }
156
+ catch (err) {
157
+ debug('failed to parse package.json bin entries', err);
158
+ }
159
+ return null;
160
+ }
161
+ /**
162
+ * Check if file is referenced in package.json main or exports
163
+ */
164
+ checkPackageJsonMainExports(filePath) {
165
+ const pkgPath = join(this.workspaceRoot, 'package.json');
166
+ if (!existsSync(pkgPath)) {
167
+ return null;
168
+ }
169
+ try {
170
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
171
+ const normalisedPath = filePath.replace(/\\/g, '/');
172
+ // Check main entry
173
+ if (pkg.main) {
174
+ const mainPath = pkg.main.replace(/^\.\//, '');
175
+ if (normalisedPath === mainPath || normalisedPath.endsWith(mainPath)) {
176
+ return {
177
+ path: filePath,
178
+ type: 'package',
179
+ confidence: 'high',
180
+ };
181
+ }
182
+ }
183
+ // Check exports (depth-limited to prevent abuse via deeply nested exports)
184
+ if (pkg.exports) {
185
+ const MAX_EXPORTS_DEPTH = 10;
186
+ const checkExports = (exports, prefix = '', depth = 0) => {
187
+ if (depth >= MAX_EXPORTS_DEPTH)
188
+ return null;
189
+ for (const [key, value] of Object.entries(exports)) {
190
+ if (typeof value === 'string') {
191
+ const exportPath = value.replace(/^\.\//, '');
192
+ if (normalisedPath === exportPath || normalisedPath.endsWith(exportPath)) {
193
+ return {
194
+ path: filePath,
195
+ type: 'package',
196
+ confidence: 'high',
197
+ exports: [prefix + key],
198
+ };
199
+ }
200
+ }
201
+ else if (typeof value === 'object' && value !== null) {
202
+ const result = checkExports(value, prefix + key + '/', depth + 1);
203
+ if (result)
204
+ return result;
205
+ }
206
+ }
207
+ return null;
208
+ };
209
+ const exportEntry = checkExports(pkg.exports);
210
+ if (exportEntry)
211
+ return exportEntry;
212
+ }
213
+ }
214
+ catch (err) {
215
+ debug('failed to parse package.json main/exports', err);
216
+ }
217
+ return null;
218
+ }
219
+ /**
220
+ * Detect all entry points from a list of files
221
+ */
222
+ detectEntryPoints(filePaths) {
223
+ const entryPoints = [];
224
+ const seen = new Set();
225
+ for (const filePath of filePaths) {
226
+ const entry = this.detectEntryPoint(filePath);
227
+ if (entry && !seen.has(entry.path)) {
228
+ seen.add(entry.path);
229
+ entryPoints.push(entry);
230
+ }
231
+ }
232
+ // Sort by confidence and type
233
+ return entryPoints.sort((a, b) => {
234
+ const confOrder = { high: 0, medium: 1, low: 2 };
235
+ const confDiff = confOrder[a.confidence] - confOrder[b.confidence];
236
+ if (confDiff !== 0)
237
+ return confDiff;
238
+ const typeOrder = {
239
+ package: 0,
240
+ application: 1,
241
+ http: 2,
242
+ api: 3,
243
+ cli: 4,
244
+ worker: 5,
245
+ test: 6,
246
+ unknown: 7,
247
+ };
248
+ return typeOrder[a.type] - typeOrder[b.type];
249
+ });
250
+ }
251
+ /**
252
+ * Filter to only non-test entry points
253
+ */
254
+ filterNonTestEntryPoints(entryPoints) {
255
+ return entryPoints.filter((e) => e.type !== 'test');
256
+ }
257
+ }
258
+ /**
259
+ * Create an entry point detector
260
+ */
261
+ export function createEntryPointDetector(workspaceRoot) {
262
+ return new EntryPointDetector(workspaceRoot);
263
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Architecture analysis module
3
+ *
4
+ * Provides architecture baseline management, layer detection,
5
+ * entry point detection, and boundary violation analysis.
6
+ */
7
+ export { EntryPointTypeSchema, type EntryPointType, DetectionConfidenceSchema, type DetectionConfidence, EntryPointSchema, type EntryPoint, StandardLayerSchema, type StandardLayer, LayerSchema, type Layer, LayersSchema, type Layers, BoundarySchema, type Boundary, BaselineViolationSchema, type BaselineViolation, BaselineSnapshotSchema, type BaselineSnapshot, ArchitectureBaselineSchema, type ArchitectureBaseline, LayerAssignmentSchema, type LayerAssignment, DependencyEdgeSchema, type DependencyEdge, BoundaryViolationSchema, type BoundaryViolation, createViolationId, isExistingViolation, createDefaultLayers, createDefaultBoundaries, } from './types.js';
8
+ export { LayerDetector, createLayerDetector } from './layer-detector.js';
9
+ export { EntryPointDetector, createEntryPointDetector } from './entry-detector.js';
10
+ export { BASELINE_FILENAME, ANVIL_DIR, getBaselinePath, baselineExists, loadBaseline, saveBaseline, createBaseline, updateBaseline, mergeViolations, findNewViolations, findFixedViolations, BaselineManager, createBaselineManager, } from './baseline.js';
11
+ export { type AnalysisResult, type AnalyzerOptions, type InferBaselineOptions, ArchitectureAnalyzer, createArchitectureAnalyzer, analyseArchitecture, inferBaseline, } from './analyzer.js';
12
+ export { extractHtmlEdges, extractCssEdges } from './edge-detector-web.js';
13
+ export { type ImportEdge, type BaselineComparison, type ExtractOptions, createEdgeFingerprint, fingerprintEdge, resolveImportPath, extractImports, extractImportsFromFiles, compareToBaseline, toDependencyEdge, deduplicateEdges, filterCrossLayerEdges, } from './edge-detector.js';
14
+ export { ArchitectureTemplateSchema, type ArchitectureTemplate, LayerDefinitionSchema, type LayerDefinition, BoundedContextSchema, type BoundedContext, RuleSeveritySchema, type RuleSeverity, ArchitectureRuleSchema, type ArchitectureRule, ArchitectureOptionsSchema, type ArchitectureOptions, ArchitectureDefinitionSchema, type ArchitectureDefinition, AVAILABLE_TEMPLATES, getAvailableTemplates, isValidTemplate, ARCHITECTURE_DEFINITION_VERSION, validateArchitectureDefinition, getDefaultOptions, } from './definition-schema.js';
15
+ export { ARCHITECTURE_YAML_FILENAME, getArchitectureYamlPath, architectureYamlExists, parseArchitectureDefinition, writeArchitectureYaml, getTemplateDefaults, mergeWithTemplate, createDefinitionFromTemplate, } from './yaml-parser.js';
16
+ export { DC_CONFIG_FILENAME, getDCConfigPath, dcConfigExists, needsRegeneration, writeDCConfig, generateDCConfig, } from './dc-generator.js';
17
+ export { GENERATED_POLICIES_DIR, REGO_FILENAME, REGO_PACKAGE, getRegoPath, regoExists, needsRegoRegeneration, writeRegoPolicy, generateRegoPolicy, } from './rego-generator.js';
18
+ export { type CompileResult, type CompileOptions, compileArchitecture, needsCompilation, } from './compiler.js';
19
+ export { type TemplateFile, type LoadedTemplate, TemplateLoader, getTemplateLoader, listTemplates, getTemplate as getArchitectureTemplate, validateTemplate, } from './templates/index.js';
20
+ export { ArchViolationSeveritySchema, type ArchViolationSeverity, ArchViolationSchema, type ArchViolation, ModuleInfoSchema, type ModuleInfo, LayerStatsSchema, type LayerStats, ArchitectureContextSchema, type ArchitectureContext, createEmptyContext, ArchitectureContextBuilder, createContextBuilder, } from './context.js';
21
+ //# sourceMappingURL=index.d.ts.map