@oculum/scanner 1.0.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 (281) hide show
  1. package/dist/formatters/cli-terminal.d.ts +27 -0
  2. package/dist/formatters/cli-terminal.d.ts.map +1 -0
  3. package/dist/formatters/cli-terminal.js +412 -0
  4. package/dist/formatters/cli-terminal.js.map +1 -0
  5. package/dist/formatters/github-comment.d.ts +41 -0
  6. package/dist/formatters/github-comment.d.ts.map +1 -0
  7. package/dist/formatters/github-comment.js +306 -0
  8. package/dist/formatters/github-comment.js.map +1 -0
  9. package/dist/formatters/grouping.d.ts +52 -0
  10. package/dist/formatters/grouping.d.ts.map +1 -0
  11. package/dist/formatters/grouping.js +152 -0
  12. package/dist/formatters/grouping.js.map +1 -0
  13. package/dist/formatters/index.d.ts +9 -0
  14. package/dist/formatters/index.d.ts.map +1 -0
  15. package/dist/formatters/index.js +35 -0
  16. package/dist/formatters/index.js.map +1 -0
  17. package/dist/formatters/vscode-diagnostic.d.ts +103 -0
  18. package/dist/formatters/vscode-diagnostic.d.ts.map +1 -0
  19. package/dist/formatters/vscode-diagnostic.js +151 -0
  20. package/dist/formatters/vscode-diagnostic.js.map +1 -0
  21. package/dist/index.d.ts +52 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +648 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/layer1/comments.d.ts +8 -0
  26. package/dist/layer1/comments.d.ts.map +1 -0
  27. package/dist/layer1/comments.js +203 -0
  28. package/dist/layer1/comments.js.map +1 -0
  29. package/dist/layer1/config-audit.d.ts +8 -0
  30. package/dist/layer1/config-audit.d.ts.map +1 -0
  31. package/dist/layer1/config-audit.js +252 -0
  32. package/dist/layer1/config-audit.js.map +1 -0
  33. package/dist/layer1/entropy.d.ts +8 -0
  34. package/dist/layer1/entropy.d.ts.map +1 -0
  35. package/dist/layer1/entropy.js +500 -0
  36. package/dist/layer1/entropy.js.map +1 -0
  37. package/dist/layer1/file-flags.d.ts +7 -0
  38. package/dist/layer1/file-flags.d.ts.map +1 -0
  39. package/dist/layer1/file-flags.js +112 -0
  40. package/dist/layer1/file-flags.js.map +1 -0
  41. package/dist/layer1/index.d.ts +36 -0
  42. package/dist/layer1/index.d.ts.map +1 -0
  43. package/dist/layer1/index.js +132 -0
  44. package/dist/layer1/index.js.map +1 -0
  45. package/dist/layer1/patterns.d.ts +8 -0
  46. package/dist/layer1/patterns.d.ts.map +1 -0
  47. package/dist/layer1/patterns.js +482 -0
  48. package/dist/layer1/patterns.js.map +1 -0
  49. package/dist/layer1/urls.d.ts +8 -0
  50. package/dist/layer1/urls.d.ts.map +1 -0
  51. package/dist/layer1/urls.js +296 -0
  52. package/dist/layer1/urls.js.map +1 -0
  53. package/dist/layer1/weak-crypto.d.ts +7 -0
  54. package/dist/layer1/weak-crypto.d.ts.map +1 -0
  55. package/dist/layer1/weak-crypto.js +291 -0
  56. package/dist/layer1/weak-crypto.js.map +1 -0
  57. package/dist/layer2/ai-agent-tools.d.ts +19 -0
  58. package/dist/layer2/ai-agent-tools.d.ts.map +1 -0
  59. package/dist/layer2/ai-agent-tools.js +528 -0
  60. package/dist/layer2/ai-agent-tools.js.map +1 -0
  61. package/dist/layer2/ai-endpoint-protection.d.ts +36 -0
  62. package/dist/layer2/ai-endpoint-protection.d.ts.map +1 -0
  63. package/dist/layer2/ai-endpoint-protection.js +332 -0
  64. package/dist/layer2/ai-endpoint-protection.js.map +1 -0
  65. package/dist/layer2/ai-execution-sinks.d.ts +18 -0
  66. package/dist/layer2/ai-execution-sinks.d.ts.map +1 -0
  67. package/dist/layer2/ai-execution-sinks.js +496 -0
  68. package/dist/layer2/ai-execution-sinks.js.map +1 -0
  69. package/dist/layer2/ai-fingerprinting.d.ts +7 -0
  70. package/dist/layer2/ai-fingerprinting.d.ts.map +1 -0
  71. package/dist/layer2/ai-fingerprinting.js +654 -0
  72. package/dist/layer2/ai-fingerprinting.js.map +1 -0
  73. package/dist/layer2/ai-prompt-hygiene.d.ts +19 -0
  74. package/dist/layer2/ai-prompt-hygiene.d.ts.map +1 -0
  75. package/dist/layer2/ai-prompt-hygiene.js +356 -0
  76. package/dist/layer2/ai-prompt-hygiene.js.map +1 -0
  77. package/dist/layer2/ai-rag-safety.d.ts +21 -0
  78. package/dist/layer2/ai-rag-safety.d.ts.map +1 -0
  79. package/dist/layer2/ai-rag-safety.js +459 -0
  80. package/dist/layer2/ai-rag-safety.js.map +1 -0
  81. package/dist/layer2/ai-schema-validation.d.ts +25 -0
  82. package/dist/layer2/ai-schema-validation.d.ts.map +1 -0
  83. package/dist/layer2/ai-schema-validation.js +375 -0
  84. package/dist/layer2/ai-schema-validation.js.map +1 -0
  85. package/dist/layer2/auth-antipatterns.d.ts +20 -0
  86. package/dist/layer2/auth-antipatterns.d.ts.map +1 -0
  87. package/dist/layer2/auth-antipatterns.js +333 -0
  88. package/dist/layer2/auth-antipatterns.js.map +1 -0
  89. package/dist/layer2/byok-patterns.d.ts +12 -0
  90. package/dist/layer2/byok-patterns.d.ts.map +1 -0
  91. package/dist/layer2/byok-patterns.js +299 -0
  92. package/dist/layer2/byok-patterns.js.map +1 -0
  93. package/dist/layer2/dangerous-functions.d.ts +7 -0
  94. package/dist/layer2/dangerous-functions.d.ts.map +1 -0
  95. package/dist/layer2/dangerous-functions.js +1375 -0
  96. package/dist/layer2/dangerous-functions.js.map +1 -0
  97. package/dist/layer2/data-exposure.d.ts +16 -0
  98. package/dist/layer2/data-exposure.d.ts.map +1 -0
  99. package/dist/layer2/data-exposure.js +279 -0
  100. package/dist/layer2/data-exposure.js.map +1 -0
  101. package/dist/layer2/framework-checks.d.ts +7 -0
  102. package/dist/layer2/framework-checks.d.ts.map +1 -0
  103. package/dist/layer2/framework-checks.js +388 -0
  104. package/dist/layer2/framework-checks.js.map +1 -0
  105. package/dist/layer2/index.d.ts +58 -0
  106. package/dist/layer2/index.d.ts.map +1 -0
  107. package/dist/layer2/index.js +380 -0
  108. package/dist/layer2/index.js.map +1 -0
  109. package/dist/layer2/logic-gates.d.ts +7 -0
  110. package/dist/layer2/logic-gates.d.ts.map +1 -0
  111. package/dist/layer2/logic-gates.js +182 -0
  112. package/dist/layer2/logic-gates.js.map +1 -0
  113. package/dist/layer2/risky-imports.d.ts +7 -0
  114. package/dist/layer2/risky-imports.d.ts.map +1 -0
  115. package/dist/layer2/risky-imports.js +161 -0
  116. package/dist/layer2/risky-imports.js.map +1 -0
  117. package/dist/layer2/variables.d.ts +8 -0
  118. package/dist/layer2/variables.d.ts.map +1 -0
  119. package/dist/layer2/variables.js +152 -0
  120. package/dist/layer2/variables.js.map +1 -0
  121. package/dist/layer3/anthropic.d.ts +83 -0
  122. package/dist/layer3/anthropic.d.ts.map +1 -0
  123. package/dist/layer3/anthropic.js +1745 -0
  124. package/dist/layer3/anthropic.js.map +1 -0
  125. package/dist/layer3/index.d.ts +24 -0
  126. package/dist/layer3/index.d.ts.map +1 -0
  127. package/dist/layer3/index.js +119 -0
  128. package/dist/layer3/index.js.map +1 -0
  129. package/dist/layer3/openai.d.ts +25 -0
  130. package/dist/layer3/openai.d.ts.map +1 -0
  131. package/dist/layer3/openai.js +238 -0
  132. package/dist/layer3/openai.js.map +1 -0
  133. package/dist/layer3/package-check.d.ts +63 -0
  134. package/dist/layer3/package-check.d.ts.map +1 -0
  135. package/dist/layer3/package-check.js +508 -0
  136. package/dist/layer3/package-check.js.map +1 -0
  137. package/dist/modes/incremental.d.ts +66 -0
  138. package/dist/modes/incremental.d.ts.map +1 -0
  139. package/dist/modes/incremental.js +200 -0
  140. package/dist/modes/incremental.js.map +1 -0
  141. package/dist/tiers.d.ts +125 -0
  142. package/dist/tiers.d.ts.map +1 -0
  143. package/dist/tiers.js +234 -0
  144. package/dist/tiers.js.map +1 -0
  145. package/dist/types.d.ts +175 -0
  146. package/dist/types.d.ts.map +1 -0
  147. package/dist/types.js +50 -0
  148. package/dist/types.js.map +1 -0
  149. package/dist/utils/auth-helper-detector.d.ts +56 -0
  150. package/dist/utils/auth-helper-detector.d.ts.map +1 -0
  151. package/dist/utils/auth-helper-detector.js +360 -0
  152. package/dist/utils/auth-helper-detector.js.map +1 -0
  153. package/dist/utils/context-helpers.d.ts +96 -0
  154. package/dist/utils/context-helpers.d.ts.map +1 -0
  155. package/dist/utils/context-helpers.js +493 -0
  156. package/dist/utils/context-helpers.js.map +1 -0
  157. package/dist/utils/diff-detector.d.ts +53 -0
  158. package/dist/utils/diff-detector.d.ts.map +1 -0
  159. package/dist/utils/diff-detector.js +104 -0
  160. package/dist/utils/diff-detector.js.map +1 -0
  161. package/dist/utils/diff-parser.d.ts +80 -0
  162. package/dist/utils/diff-parser.d.ts.map +1 -0
  163. package/dist/utils/diff-parser.js +202 -0
  164. package/dist/utils/diff-parser.js.map +1 -0
  165. package/dist/utils/imported-auth-detector.d.ts +37 -0
  166. package/dist/utils/imported-auth-detector.d.ts.map +1 -0
  167. package/dist/utils/imported-auth-detector.js +251 -0
  168. package/dist/utils/imported-auth-detector.js.map +1 -0
  169. package/dist/utils/middleware-detector.d.ts +55 -0
  170. package/dist/utils/middleware-detector.d.ts.map +1 -0
  171. package/dist/utils/middleware-detector.js +260 -0
  172. package/dist/utils/middleware-detector.js.map +1 -0
  173. package/dist/utils/oauth-flow-detector.d.ts +41 -0
  174. package/dist/utils/oauth-flow-detector.d.ts.map +1 -0
  175. package/dist/utils/oauth-flow-detector.js +202 -0
  176. package/dist/utils/oauth-flow-detector.js.map +1 -0
  177. package/dist/utils/path-exclusions.d.ts +55 -0
  178. package/dist/utils/path-exclusions.d.ts.map +1 -0
  179. package/dist/utils/path-exclusions.js +222 -0
  180. package/dist/utils/path-exclusions.js.map +1 -0
  181. package/dist/utils/project-context-builder.d.ts +119 -0
  182. package/dist/utils/project-context-builder.d.ts.map +1 -0
  183. package/dist/utils/project-context-builder.js +534 -0
  184. package/dist/utils/project-context-builder.js.map +1 -0
  185. package/dist/utils/registry-clients.d.ts +93 -0
  186. package/dist/utils/registry-clients.d.ts.map +1 -0
  187. package/dist/utils/registry-clients.js +273 -0
  188. package/dist/utils/registry-clients.js.map +1 -0
  189. package/dist/utils/trpc-analyzer.d.ts +78 -0
  190. package/dist/utils/trpc-analyzer.d.ts.map +1 -0
  191. package/dist/utils/trpc-analyzer.js +297 -0
  192. package/dist/utils/trpc-analyzer.js.map +1 -0
  193. package/package.json +45 -0
  194. package/src/__tests__/benchmark/fixtures/false-positives.ts +227 -0
  195. package/src/__tests__/benchmark/fixtures/index.ts +68 -0
  196. package/src/__tests__/benchmark/fixtures/layer1/config-audit.ts +364 -0
  197. package/src/__tests__/benchmark/fixtures/layer1/hardcoded-secrets.ts +173 -0
  198. package/src/__tests__/benchmark/fixtures/layer1/high-entropy.ts +234 -0
  199. package/src/__tests__/benchmark/fixtures/layer1/index.ts +31 -0
  200. package/src/__tests__/benchmark/fixtures/layer1/sensitive-urls.ts +90 -0
  201. package/src/__tests__/benchmark/fixtures/layer1/weak-crypto.ts +197 -0
  202. package/src/__tests__/benchmark/fixtures/layer2/ai-agent-tools.ts +170 -0
  203. package/src/__tests__/benchmark/fixtures/layer2/ai-endpoint-protection.ts +418 -0
  204. package/src/__tests__/benchmark/fixtures/layer2/ai-execution-sinks.ts +189 -0
  205. package/src/__tests__/benchmark/fixtures/layer2/ai-fingerprinting.ts +316 -0
  206. package/src/__tests__/benchmark/fixtures/layer2/ai-prompt-hygiene.ts +178 -0
  207. package/src/__tests__/benchmark/fixtures/layer2/ai-rag-safety.ts +184 -0
  208. package/src/__tests__/benchmark/fixtures/layer2/ai-schema-validation.ts +434 -0
  209. package/src/__tests__/benchmark/fixtures/layer2/auth-antipatterns.ts +159 -0
  210. package/src/__tests__/benchmark/fixtures/layer2/byok-patterns.ts +112 -0
  211. package/src/__tests__/benchmark/fixtures/layer2/dangerous-functions.ts +246 -0
  212. package/src/__tests__/benchmark/fixtures/layer2/data-exposure.ts +168 -0
  213. package/src/__tests__/benchmark/fixtures/layer2/framework-checks.ts +346 -0
  214. package/src/__tests__/benchmark/fixtures/layer2/index.ts +67 -0
  215. package/src/__tests__/benchmark/fixtures/layer2/injection-vulnerabilities.ts +239 -0
  216. package/src/__tests__/benchmark/fixtures/layer2/logic-gates.ts +246 -0
  217. package/src/__tests__/benchmark/fixtures/layer2/risky-imports.ts +231 -0
  218. package/src/__tests__/benchmark/fixtures/layer2/variables.ts +167 -0
  219. package/src/__tests__/benchmark/index.ts +29 -0
  220. package/src/__tests__/benchmark/run-benchmark.ts +144 -0
  221. package/src/__tests__/benchmark/run-depth-validation.ts +206 -0
  222. package/src/__tests__/benchmark/run-real-world-test.ts +243 -0
  223. package/src/__tests__/benchmark/security-benchmark-script.ts +1737 -0
  224. package/src/__tests__/benchmark/tier-integration-script.ts +177 -0
  225. package/src/__tests__/benchmark/types.ts +144 -0
  226. package/src/__tests__/benchmark/utils/test-runner.ts +475 -0
  227. package/src/__tests__/regression/known-false-positives.test.ts +467 -0
  228. package/src/__tests__/snapshots/__snapshots__/scan-depth.test.ts.snap +178 -0
  229. package/src/__tests__/snapshots/scan-depth.test.ts +258 -0
  230. package/src/__tests__/validation/analyze-results.ts +542 -0
  231. package/src/__tests__/validation/extract-for-triage.ts +146 -0
  232. package/src/__tests__/validation/fp-deep-analysis.ts +327 -0
  233. package/src/__tests__/validation/run-validation.ts +364 -0
  234. package/src/__tests__/validation/triage-template.md +132 -0
  235. package/src/formatters/cli-terminal.ts +446 -0
  236. package/src/formatters/github-comment.ts +382 -0
  237. package/src/formatters/grouping.ts +190 -0
  238. package/src/formatters/index.ts +47 -0
  239. package/src/formatters/vscode-diagnostic.ts +243 -0
  240. package/src/index.ts +823 -0
  241. package/src/layer1/comments.ts +218 -0
  242. package/src/layer1/config-audit.ts +289 -0
  243. package/src/layer1/entropy.ts +583 -0
  244. package/src/layer1/file-flags.ts +127 -0
  245. package/src/layer1/index.ts +181 -0
  246. package/src/layer1/patterns.ts +516 -0
  247. package/src/layer1/urls.ts +334 -0
  248. package/src/layer1/weak-crypto.ts +328 -0
  249. package/src/layer2/ai-agent-tools.ts +601 -0
  250. package/src/layer2/ai-endpoint-protection.ts +387 -0
  251. package/src/layer2/ai-execution-sinks.ts +580 -0
  252. package/src/layer2/ai-fingerprinting.ts +758 -0
  253. package/src/layer2/ai-prompt-hygiene.ts +411 -0
  254. package/src/layer2/ai-rag-safety.ts +511 -0
  255. package/src/layer2/ai-schema-validation.ts +421 -0
  256. package/src/layer2/auth-antipatterns.ts +394 -0
  257. package/src/layer2/byok-patterns.ts +336 -0
  258. package/src/layer2/dangerous-functions.ts +1563 -0
  259. package/src/layer2/data-exposure.ts +315 -0
  260. package/src/layer2/framework-checks.ts +433 -0
  261. package/src/layer2/index.ts +473 -0
  262. package/src/layer2/logic-gates.ts +206 -0
  263. package/src/layer2/risky-imports.ts +186 -0
  264. package/src/layer2/variables.ts +166 -0
  265. package/src/layer3/anthropic.ts +2030 -0
  266. package/src/layer3/index.ts +130 -0
  267. package/src/layer3/package-check.ts +604 -0
  268. package/src/modes/incremental.ts +293 -0
  269. package/src/tiers.ts +318 -0
  270. package/src/types.ts +284 -0
  271. package/src/utils/auth-helper-detector.ts +443 -0
  272. package/src/utils/context-helpers.ts +535 -0
  273. package/src/utils/diff-detector.ts +135 -0
  274. package/src/utils/diff-parser.ts +272 -0
  275. package/src/utils/imported-auth-detector.ts +320 -0
  276. package/src/utils/middleware-detector.ts +333 -0
  277. package/src/utils/oauth-flow-detector.ts +246 -0
  278. package/src/utils/path-exclusions.ts +266 -0
  279. package/src/utils/project-context-builder.ts +707 -0
  280. package/src/utils/registry-clients.ts +351 -0
  281. package/src/utils/trpc-analyzer.ts +382 -0
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Diff Detection Utility
3
+ * Compares current repository tree against previous scan data to detect changed files
4
+ * Used for incremental scanning (Story D)
5
+ */
6
+ export interface TreeFileInfo {
7
+ path: string;
8
+ sha: string;
9
+ }
10
+ export interface DiffResult {
11
+ /** Files that are new (not in previous scan) */
12
+ added: string[];
13
+ /** Files whose SHA changed (content modified) */
14
+ modified: string[];
15
+ /** Files that were deleted (in previous scan but not in current) */
16
+ deleted: string[];
17
+ /** Files that haven't changed */
18
+ unchanged: string[];
19
+ /** Total count of changed files (added + modified) */
20
+ changedCount: number;
21
+ /** Whether this is a significant change warranting incremental scan */
22
+ shouldUseIncremental: boolean;
23
+ }
24
+ /**
25
+ * Detect which files have changed between the current tree and previous scan
26
+ *
27
+ * @param currentTree - Array of files from current GitHub tree (path + sha)
28
+ * @param previousFileShas - Map of {file_path: sha} from previous scan
29
+ * @returns DiffResult with categorized file changes
30
+ */
31
+ export declare function detectChangedFiles(currentTree: TreeFileInfo[], previousFileShas: Record<string, string> | null | undefined): DiffResult;
32
+ /**
33
+ * Build a file SHA map from a GitHub tree response
34
+ * Filters to only include blob (file) entries
35
+ *
36
+ * @param tree - GitHub tree items with path and sha
37
+ * @returns Map of {file_path: sha}
38
+ */
39
+ export declare function buildFileShaMap(tree: Array<{
40
+ path: string;
41
+ sha: string;
42
+ type: 'blob' | 'tree';
43
+ }>): Record<string, string>;
44
+ /**
45
+ * Check if two tree SHAs are different
46
+ * Quick check before doing detailed file comparison
47
+ *
48
+ * @param currentTreeSha - SHA of current tree
49
+ * @param previousTreeSha - SHA from previous scan
50
+ * @returns true if trees are different (need detailed comparison)
51
+ */
52
+ export declare function hasTreeChanged(currentTreeSha: string, previousTreeSha: string | null | undefined): boolean;
53
+ //# sourceMappingURL=diff-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff-detector.d.ts","sourceRoot":"","sources":["../../src/utils/diff-detector.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;CACZ;AAED,MAAM,WAAW,UAAU;IACzB,gDAAgD;IAChD,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,iDAAiD;IACjD,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,oEAAoE;IACpE,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,iCAAiC;IACjC,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,sDAAsD;IACtD,YAAY,EAAE,MAAM,CAAA;IACpB,uEAAuE;IACvE,oBAAoB,EAAE,OAAO,CAAA;CAC9B;AAQD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,YAAY,EAAE,EAC3B,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,GAAG,SAAS,GAC1D,UAAU,CAsDZ;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAC,GAChE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAWxB;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,cAAc,EAAE,MAAM,EACtB,eAAe,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACzC,OAAO,CAGT"}
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ /**
3
+ * Diff Detection Utility
4
+ * Compares current repository tree against previous scan data to detect changed files
5
+ * Used for incremental scanning (Story D)
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.detectChangedFiles = detectChangedFiles;
9
+ exports.buildFileShaMap = buildFileShaMap;
10
+ exports.hasTreeChanged = hasTreeChanged;
11
+ /**
12
+ * Maximum number of changed files before falling back to full scan
13
+ * Beyond this threshold, incremental mode provides diminishing returns
14
+ */
15
+ const MAX_CHANGED_FILES_FOR_INCREMENTAL = 50;
16
+ /**
17
+ * Detect which files have changed between the current tree and previous scan
18
+ *
19
+ * @param currentTree - Array of files from current GitHub tree (path + sha)
20
+ * @param previousFileShas - Map of {file_path: sha} from previous scan
21
+ * @returns DiffResult with categorized file changes
22
+ */
23
+ function detectChangedFiles(currentTree, previousFileShas) {
24
+ // If no previous data, everything is "new"
25
+ if (!previousFileShas || Object.keys(previousFileShas).length === 0) {
26
+ return {
27
+ added: currentTree.map(f => f.path),
28
+ modified: [],
29
+ deleted: [],
30
+ unchanged: [],
31
+ changedCount: currentTree.length,
32
+ shouldUseIncremental: false, // No baseline = full scan
33
+ };
34
+ }
35
+ const added = [];
36
+ const modified = [];
37
+ const unchanged = [];
38
+ const currentPaths = new Set();
39
+ // Compare current files against previous
40
+ for (const file of currentTree) {
41
+ currentPaths.add(file.path);
42
+ const previousSha = previousFileShas[file.path];
43
+ if (!previousSha) {
44
+ // File didn't exist before
45
+ added.push(file.path);
46
+ }
47
+ else if (previousSha !== file.sha) {
48
+ // File content changed (SHA differs)
49
+ modified.push(file.path);
50
+ }
51
+ else {
52
+ // Same SHA = unchanged
53
+ unchanged.push(file.path);
54
+ }
55
+ }
56
+ // Find deleted files (in previous but not in current)
57
+ const deleted = [];
58
+ for (const path of Object.keys(previousFileShas)) {
59
+ if (!currentPaths.has(path)) {
60
+ deleted.push(path);
61
+ }
62
+ }
63
+ const changedCount = added.length + modified.length;
64
+ const shouldUseIncremental = changedCount > 0 && changedCount <= MAX_CHANGED_FILES_FOR_INCREMENTAL;
65
+ return {
66
+ added,
67
+ modified,
68
+ deleted,
69
+ unchanged,
70
+ changedCount,
71
+ shouldUseIncremental,
72
+ };
73
+ }
74
+ /**
75
+ * Build a file SHA map from a GitHub tree response
76
+ * Filters to only include blob (file) entries
77
+ *
78
+ * @param tree - GitHub tree items with path and sha
79
+ * @returns Map of {file_path: sha}
80
+ */
81
+ function buildFileShaMap(tree) {
82
+ const map = {};
83
+ for (const item of tree) {
84
+ // Only include files (blobs), not directories (trees)
85
+ if (item.type === 'blob') {
86
+ map[item.path] = item.sha;
87
+ }
88
+ }
89
+ return map;
90
+ }
91
+ /**
92
+ * Check if two tree SHAs are different
93
+ * Quick check before doing detailed file comparison
94
+ *
95
+ * @param currentTreeSha - SHA of current tree
96
+ * @param previousTreeSha - SHA from previous scan
97
+ * @returns true if trees are different (need detailed comparison)
98
+ */
99
+ function hasTreeChanged(currentTreeSha, previousTreeSha) {
100
+ if (!previousTreeSha)
101
+ return true;
102
+ return currentTreeSha !== previousTreeSha;
103
+ }
104
+ //# sourceMappingURL=diff-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff-detector.js","sourceRoot":"","sources":["../../src/utils/diff-detector.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AAmCH,gDAyDC;AASD,0CAaC;AAUD,wCAMC;AA5GD;;;GAGG;AACH,MAAM,iCAAiC,GAAG,EAAE,CAAA;AAE5C;;;;;;GAMG;AACH,SAAgB,kBAAkB,CAChC,WAA2B,EAC3B,gBAA2D;IAE3D,2CAA2C;IAC3C,IAAI,CAAC,gBAAgB,IAAI,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpE,OAAO;YACL,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YACnC,QAAQ,EAAE,EAAE;YACZ,OAAO,EAAE,EAAE;YACX,SAAS,EAAE,EAAE;YACb,YAAY,EAAE,WAAW,CAAC,MAAM;YAChC,oBAAoB,EAAE,KAAK,EAAE,0BAA0B;SACxD,CAAA;IACH,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,MAAM,QAAQ,GAAa,EAAE,CAAA;IAC7B,MAAM,SAAS,GAAa,EAAE,CAAA;IAC9B,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAA;IAEtC,yCAAyC;IACzC,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC3B,MAAM,WAAW,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAE/C,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,2BAA2B;YAC3B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACvB,CAAC;aAAM,IAAI,WAAW,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC;YACpC,qCAAqC;YACrC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC1B,CAAC;aAAM,CAAC;YACN,uBAAuB;YACvB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC3B,CAAC;IACH,CAAC;IAED,sDAAsD;IACtD,MAAM,OAAO,GAAa,EAAE,CAAA;IAC5B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACjD,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACpB,CAAC;IACH,CAAC;IAED,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAA;IACnD,MAAM,oBAAoB,GAAG,YAAY,GAAG,CAAC,IAAI,YAAY,IAAI,iCAAiC,CAAA;IAElG,OAAO;QACL,KAAK;QACL,QAAQ;QACR,OAAO;QACP,SAAS;QACT,YAAY;QACZ,oBAAoB;KACrB,CAAA;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,eAAe,CAC7B,IAAiE;IAEjE,MAAM,GAAG,GAA2B,EAAE,CAAA;IAEtC,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;QACxB,sDAAsD;QACtD,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACzB,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAA;QAC3B,CAAC;IACH,CAAC;IAED,OAAO,GAAG,CAAA;AACZ,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,cAAc,CAC5B,cAAsB,EACtB,eAA0C;IAE1C,IAAI,CAAC,eAAe;QAAE,OAAO,IAAI,CAAA;IACjC,OAAO,cAAc,KAAK,eAAe,CAAA;AAC3C,CAAC"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Git Diff Parser
3
+ * Parses unified diff format to extract changed line ranges
4
+ * Used for incremental scanning to only flag findings on changed lines
5
+ */
6
+ /**
7
+ * A hunk represents a contiguous block of changes
8
+ */
9
+ export interface DiffHunk {
10
+ /** Starting line in the old file */
11
+ oldStart: number;
12
+ /** Number of lines in old file */
13
+ oldLines: number;
14
+ /** Starting line in the new file */
15
+ newStart: number;
16
+ /** Number of lines in new file */
17
+ newLines: number;
18
+ /** Lines that were added (line numbers in new file) */
19
+ addedLines: number[];
20
+ /** Lines that were removed (line numbers in old file) */
21
+ removedLines: number[];
22
+ /** Lines that were modified (context around changes in new file) */
23
+ contextLines: number[];
24
+ }
25
+ /**
26
+ * Parsed file diff
27
+ */
28
+ export interface FileDiff {
29
+ /** File path (after rename if applicable) */
30
+ path: string;
31
+ /** Old file path (if renamed) */
32
+ oldPath?: string;
33
+ /** Whether the file was added */
34
+ isNew: boolean;
35
+ /** Whether the file was deleted */
36
+ isDeleted: boolean;
37
+ /** Whether the file was renamed */
38
+ isRenamed: boolean;
39
+ /** Hunks containing the actual changes */
40
+ hunks: DiffHunk[];
41
+ /** All changed line numbers in the new file */
42
+ changedLines: Set<number>;
43
+ /** All lines near changes (within context window) */
44
+ affectedLines: Set<number>;
45
+ }
46
+ /**
47
+ * Parse a unified diff output
48
+ *
49
+ * @param diffOutput - The raw git diff output
50
+ * @param contextWindow - Lines around changes to consider "affected" (default: 5)
51
+ * @returns Map of file path to FileDiff
52
+ */
53
+ export declare function parseDiff(diffOutput: string, contextWindow?: number): Map<string, FileDiff>;
54
+ /**
55
+ * Parse a simple list of changed file paths
56
+ * Used when full diff isn't available (e.g., GitHub API file list)
57
+ */
58
+ export declare function parseChangedFileList(files: string[]): Map<string, FileDiff>;
59
+ /**
60
+ * Check if a finding is on a changed line
61
+ */
62
+ export declare function isOnChangedLine(filePath: string, lineNumber: number, diffs: Map<string, FileDiff>): boolean;
63
+ /**
64
+ * Check if a finding is near a changed line (within context window)
65
+ */
66
+ export declare function isNearChangedLine(filePath: string, lineNumber: number, diffs: Map<string, FileDiff>): boolean;
67
+ /**
68
+ * Get all changed file paths from diffs
69
+ */
70
+ export declare function getChangedFilePaths(diffs: Map<string, FileDiff>): string[];
71
+ /**
72
+ * Filter vulnerabilities to only those on/near changed lines
73
+ */
74
+ export declare function filterToChangedLines<T extends {
75
+ filePath: string;
76
+ lineNumber: number;
77
+ }>(findings: T[], diffs: Map<string, FileDiff>, options?: {
78
+ strictMode?: boolean;
79
+ }): T[];
80
+ //# sourceMappingURL=diff-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff-parser.d.ts","sourceRoot":"","sources":["../../src/utils/diff-parser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,oCAAoC;IACpC,QAAQ,EAAE,MAAM,CAAA;IAChB,kCAAkC;IAClC,QAAQ,EAAE,MAAM,CAAA;IAChB,oCAAoC;IACpC,QAAQ,EAAE,MAAM,CAAA;IAChB,kCAAkC;IAClC,QAAQ,EAAE,MAAM,CAAA;IAChB,uDAAuD;IACvD,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,yDAAyD;IACzD,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,oEAAoE;IACpE,YAAY,EAAE,MAAM,EAAE,CAAA;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAA;IACZ,iCAAiC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,iCAAiC;IACjC,KAAK,EAAE,OAAO,CAAA;IACd,mCAAmC;IACnC,SAAS,EAAE,OAAO,CAAA;IAClB,mCAAmC;IACnC,SAAS,EAAE,OAAO,CAAA;IAClB,0CAA0C;IAC1C,KAAK,EAAE,QAAQ,EAAE,CAAA;IACjB,+CAA+C;IAC/C,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACzB,qDAAqD;IACrD,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAC3B;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,aAAa,GAAE,MAAU,GAAG,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAkB9F;AA6GD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAiB3E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,GAC3B,OAAO,CAQT;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,GAC3B,OAAO,CAQT;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,MAAM,EAAE,CAK1E;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,SAAS;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,EACrF,QAAQ,EAAE,CAAC,EAAE,EACb,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,EAC5B,OAAO,GAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAO,GACrC,CAAC,EAAE,CAeL"}
@@ -0,0 +1,202 @@
1
+ "use strict";
2
+ /**
3
+ * Git Diff Parser
4
+ * Parses unified diff format to extract changed line ranges
5
+ * Used for incremental scanning to only flag findings on changed lines
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.parseDiff = parseDiff;
9
+ exports.parseChangedFileList = parseChangedFileList;
10
+ exports.isOnChangedLine = isOnChangedLine;
11
+ exports.isNearChangedLine = isNearChangedLine;
12
+ exports.getChangedFilePaths = getChangedFilePaths;
13
+ exports.filterToChangedLines = filterToChangedLines;
14
+ /**
15
+ * Parse a unified diff output
16
+ *
17
+ * @param diffOutput - The raw git diff output
18
+ * @param contextWindow - Lines around changes to consider "affected" (default: 5)
19
+ * @returns Map of file path to FileDiff
20
+ */
21
+ function parseDiff(diffOutput, contextWindow = 5) {
22
+ const files = new Map();
23
+ if (!diffOutput || diffOutput.trim() === '') {
24
+ return files;
25
+ }
26
+ // Split into file sections (each starts with "diff --git")
27
+ const fileSections = diffOutput.split(/^diff --git /gm).filter(s => s.trim());
28
+ for (const section of fileSections) {
29
+ const fileDiff = parseFileSection('diff --git ' + section, contextWindow);
30
+ if (fileDiff) {
31
+ files.set(fileDiff.path, fileDiff);
32
+ }
33
+ }
34
+ return files;
35
+ }
36
+ /**
37
+ * Parse a single file's diff section
38
+ */
39
+ function parseFileSection(section, contextWindow) {
40
+ const lines = section.split('\n');
41
+ // Extract file paths from header
42
+ // Format: diff --git a/path/to/file b/path/to/file
43
+ const headerMatch = lines[0].match(/diff --git a\/(.+) b\/(.+)/);
44
+ if (!headerMatch)
45
+ return null;
46
+ const oldPath = headerMatch[1];
47
+ const newPath = headerMatch[2];
48
+ // Detect file status
49
+ let isNew = false;
50
+ let isDeleted = false;
51
+ let isRenamed = oldPath !== newPath;
52
+ for (const line of lines.slice(0, 10)) {
53
+ if (line.startsWith('new file mode'))
54
+ isNew = true;
55
+ if (line.startsWith('deleted file mode'))
56
+ isDeleted = true;
57
+ if (line.startsWith('rename from'))
58
+ isRenamed = true;
59
+ }
60
+ // Parse hunks
61
+ const hunks = [];
62
+ const changedLines = new Set();
63
+ const affectedLines = new Set();
64
+ // Find hunk headers: @@ -oldStart,oldLines +newStart,newLines @@
65
+ const hunkRegex = /@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/g;
66
+ let match;
67
+ const sectionContent = section;
68
+ while ((match = hunkRegex.exec(sectionContent)) !== null) {
69
+ const oldStart = parseInt(match[1], 10);
70
+ const oldLines = parseInt(match[2] || '1', 10);
71
+ const newStart = parseInt(match[3], 10);
72
+ const newLines = parseInt(match[4] || '1', 10);
73
+ // Find the content of this hunk (until next @@ or end)
74
+ const hunkStartIndex = match.index + match[0].length;
75
+ const nextHunkMatch = /@@ -\d+/.exec(sectionContent.slice(hunkStartIndex + 1));
76
+ const hunkEndIndex = nextHunkMatch
77
+ ? hunkStartIndex + 1 + nextHunkMatch.index
78
+ : sectionContent.length;
79
+ const hunkContent = sectionContent.slice(hunkStartIndex, hunkEndIndex);
80
+ const hunkLines = hunkContent.split('\n');
81
+ const addedLines = [];
82
+ const removedLines = [];
83
+ const contextLines = [];
84
+ let newLineNum = newStart;
85
+ let oldLineNum = oldStart;
86
+ for (const line of hunkLines) {
87
+ if (line.startsWith('+') && !line.startsWith('+++')) {
88
+ // Added line
89
+ addedLines.push(newLineNum);
90
+ changedLines.add(newLineNum);
91
+ newLineNum++;
92
+ }
93
+ else if (line.startsWith('-') && !line.startsWith('---')) {
94
+ // Removed line
95
+ removedLines.push(oldLineNum);
96
+ oldLineNum++;
97
+ }
98
+ else if (line.startsWith(' ') || line === '') {
99
+ // Context line
100
+ contextLines.push(newLineNum);
101
+ newLineNum++;
102
+ oldLineNum++;
103
+ }
104
+ }
105
+ hunks.push({
106
+ oldStart,
107
+ oldLines,
108
+ newStart,
109
+ newLines,
110
+ addedLines,
111
+ removedLines,
112
+ contextLines,
113
+ });
114
+ }
115
+ // Calculate affected lines (changed lines + context window)
116
+ for (const line of changedLines) {
117
+ for (let i = Math.max(1, line - contextWindow); i <= line + contextWindow; i++) {
118
+ affectedLines.add(i);
119
+ }
120
+ }
121
+ return {
122
+ path: newPath,
123
+ oldPath: isRenamed ? oldPath : undefined,
124
+ isNew,
125
+ isDeleted,
126
+ isRenamed,
127
+ hunks,
128
+ changedLines,
129
+ affectedLines,
130
+ };
131
+ }
132
+ /**
133
+ * Parse a simple list of changed file paths
134
+ * Used when full diff isn't available (e.g., GitHub API file list)
135
+ */
136
+ function parseChangedFileList(files) {
137
+ const result = new Map();
138
+ for (const path of files) {
139
+ result.set(path, {
140
+ path,
141
+ isNew: false,
142
+ isDeleted: false,
143
+ isRenamed: false,
144
+ hunks: [],
145
+ // Without diff content, consider all lines as changed
146
+ changedLines: new Set(),
147
+ affectedLines: new Set(),
148
+ });
149
+ }
150
+ return result;
151
+ }
152
+ /**
153
+ * Check if a finding is on a changed line
154
+ */
155
+ function isOnChangedLine(filePath, lineNumber, diffs) {
156
+ const fileDiff = diffs.get(filePath);
157
+ if (!fileDiff)
158
+ return false;
159
+ // If no specific changed lines (file list only), consider all findings relevant
160
+ if (fileDiff.changedLines.size === 0)
161
+ return true;
162
+ return fileDiff.changedLines.has(lineNumber);
163
+ }
164
+ /**
165
+ * Check if a finding is near a changed line (within context window)
166
+ */
167
+ function isNearChangedLine(filePath, lineNumber, diffs) {
168
+ const fileDiff = diffs.get(filePath);
169
+ if (!fileDiff)
170
+ return false;
171
+ // If no specific affected lines, consider all findings relevant
172
+ if (fileDiff.affectedLines.size === 0)
173
+ return true;
174
+ return fileDiff.affectedLines.has(lineNumber);
175
+ }
176
+ /**
177
+ * Get all changed file paths from diffs
178
+ */
179
+ function getChangedFilePaths(diffs) {
180
+ return Array.from(diffs.keys()).filter(path => {
181
+ const diff = diffs.get(path);
182
+ return diff && !diff.isDeleted;
183
+ });
184
+ }
185
+ /**
186
+ * Filter vulnerabilities to only those on/near changed lines
187
+ */
188
+ function filterToChangedLines(findings, diffs, options = {}) {
189
+ const { strictMode = false } = options;
190
+ return findings.filter(finding => {
191
+ // If file not in diff, it wasn't changed - exclude
192
+ if (!diffs.has(finding.filePath))
193
+ return false;
194
+ // In strict mode, only include findings on exactly changed lines
195
+ if (strictMode) {
196
+ return isOnChangedLine(finding.filePath, finding.lineNumber, diffs);
197
+ }
198
+ // In normal mode, include findings near changed lines
199
+ return isNearChangedLine(finding.filePath, finding.lineNumber, diffs);
200
+ });
201
+ }
202
+ //# sourceMappingURL=diff-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff-parser.js","sourceRoot":"","sources":["../../src/utils/diff-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Imported Auth Detector
3
+ *
4
+ * Detects auth middleware/helpers imported from other files to avoid
5
+ * false positives on routes that are actually protected via imports.
6
+ *
7
+ * Example: A route file that does `import { authMiddleware } from '@/lib/auth'`
8
+ * and wraps handlers with it should not be flagged as "missing auth".
9
+ */
10
+ import type { ScanFile } from '../types';
11
+ export interface ImportedAuthInfo {
12
+ importPath: string;
13
+ importedNames: string[];
14
+ isAuthRelated: boolean;
15
+ }
16
+ export interface FileAuthImports {
17
+ filePath: string;
18
+ imports: ImportedAuthInfo[];
19
+ usesImportedAuth: boolean;
20
+ }
21
+ /**
22
+ * Extract all imports from a file's content
23
+ */
24
+ export declare function extractImports(content: string): ImportedAuthInfo[];
25
+ /**
26
+ * Check if imported auth is actually used to protect routes/handlers
27
+ */
28
+ export declare function detectImportedAuthUsage(content: string, authImports: ImportedAuthInfo[]): boolean;
29
+ /**
30
+ * Build a registry of files and their auth imports
31
+ */
32
+ export declare function buildFileAuthImports(files: ScanFile[]): Map<string, FileAuthImports>;
33
+ /**
34
+ * Check if a specific file uses imported auth protection
35
+ */
36
+ export declare function fileUsesImportedAuth(filePath: string, registry: Map<string, FileAuthImports>): boolean;
37
+ //# sourceMappingURL=imported-auth-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"imported-auth-detector.d.ts","sourceRoot":"","sources":["../../src/utils/imported-auth-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAMxC,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,aAAa,EAAE,OAAO,CAAA;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,gBAAgB,EAAE,CAAA;IAC3B,gBAAgB,EAAE,OAAO,CAAA;CAC1B;AAkFD;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,EAAE,CA8ElE;AA+BD;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,gBAAgB,EAAE,GAC9B,OAAO,CAgDT;AAaD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAmBpF;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,GACrC,OAAO,CAET"}