kirograph 0.17.0 → 0.19.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 (329) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +103 -1822
  3. package/dist/architecture/layers/dart.js +112 -0
  4. package/dist/architecture/layers/dart.js.map +7 -0
  5. package/dist/architecture/layers/index.js +3 -1
  6. package/dist/architecture/layers/index.js.map +2 -2
  7. package/dist/bin/banner.js +74 -6
  8. package/dist/bin/banner.js.map +2 -2
  9. package/dist/bin/commands/attack-surface.js +157 -0
  10. package/dist/bin/commands/attack-surface.js.map +7 -0
  11. package/dist/bin/commands/benchmark.js +206 -0
  12. package/dist/bin/commands/benchmark.js.map +7 -0
  13. package/dist/bin/commands/budget.js +70 -0
  14. package/dist/bin/commands/budget.js.map +7 -0
  15. package/dist/bin/commands/communities.js +77 -0
  16. package/dist/bin/commands/communities.js.map +7 -0
  17. package/dist/bin/commands/dep-confusion.js +119 -0
  18. package/dist/bin/commands/dep-confusion.js.map +7 -0
  19. package/dist/bin/commands/export.js +304 -10
  20. package/dist/bin/commands/export.js.map +2 -2
  21. package/dist/bin/commands/flows.js +97 -0
  22. package/dist/bin/commands/flows.js.map +7 -0
  23. package/dist/bin/commands/help.js +382 -101
  24. package/dist/bin/commands/help.js.map +2 -2
  25. package/dist/bin/commands/install.js +90 -8
  26. package/dist/bin/commands/install.js.map +2 -2
  27. package/dist/bin/commands/licenses.js +201 -0
  28. package/dist/bin/commands/licenses.js.map +7 -0
  29. package/dist/bin/commands/reachability.js +160 -0
  30. package/dist/bin/commands/reachability.js.map +7 -0
  31. package/dist/bin/commands/read.js +100 -0
  32. package/dist/bin/commands/read.js.map +7 -0
  33. package/dist/bin/commands/refactor.js +116 -0
  34. package/dist/bin/commands/refactor.js.map +7 -0
  35. package/dist/bin/commands/remediation.js +133 -0
  36. package/dist/bin/commands/remediation.js.map +7 -0
  37. package/dist/bin/commands/sbom.js +76 -0
  38. package/dist/bin/commands/sbom.js.map +7 -0
  39. package/dist/bin/commands/security-ci-report.js +267 -0
  40. package/dist/bin/commands/security-ci-report.js.map +7 -0
  41. package/dist/bin/commands/security-export.js +1349 -0
  42. package/dist/bin/commands/security-export.js.map +7 -0
  43. package/dist/bin/commands/security-flows.js +126 -0
  44. package/dist/bin/commands/security-flows.js.map +7 -0
  45. package/dist/bin/commands/security-secrets.js +170 -0
  46. package/dist/bin/commands/security-secrets.js.map +7 -0
  47. package/dist/bin/commands/security.js +193 -0
  48. package/dist/bin/commands/security.js.map +7 -0
  49. package/dist/bin/commands/staleness.js +144 -0
  50. package/dist/bin/commands/staleness.js.map +7 -0
  51. package/dist/bin/commands/status.js +102 -2
  52. package/dist/bin/commands/status.js.map +2 -2
  53. package/dist/bin/commands/supply-chain.js +138 -0
  54. package/dist/bin/commands/supply-chain.js.map +7 -0
  55. package/dist/bin/commands/uninit.js +109 -60
  56. package/dist/bin/commands/uninit.js.map +2 -2
  57. package/dist/bin/commands/vex.js +76 -0
  58. package/dist/bin/commands/vex.js.map +7 -0
  59. package/dist/bin/commands/vuln-suppress.js +95 -0
  60. package/dist/bin/commands/vuln-suppress.js.map +7 -0
  61. package/dist/bin/commands/vulns.js +382 -0
  62. package/dist/bin/commands/vulns.js.map +7 -0
  63. package/dist/bin/installer/auto-detect.js +125 -0
  64. package/dist/bin/installer/auto-detect.js.map +7 -0
  65. package/dist/bin/installer/cli-agent.js +28 -5
  66. package/dist/bin/installer/cli-agent.js.map +2 -2
  67. package/dist/bin/installer/common.js +47 -0
  68. package/dist/bin/installer/common.js.map +2 -2
  69. package/dist/bin/installer/config-prompt.js +12 -1
  70. package/dist/bin/installer/config-prompt.js.map +2 -2
  71. package/dist/bin/installer/detect.js +309 -0
  72. package/dist/bin/installer/detect.js.map +7 -0
  73. package/dist/bin/installer/index.js +9 -1
  74. package/dist/bin/installer/index.js.map +2 -2
  75. package/dist/bin/installer/instructions.js +195 -3
  76. package/dist/bin/installer/instructions.js.map +2 -2
  77. package/dist/bin/installer/steering.js +407 -0
  78. package/dist/bin/installer/steering.js.map +2 -2
  79. package/dist/bin/installer/targets/aider.js +3 -3
  80. package/dist/bin/installer/targets/aider.js.map +2 -2
  81. package/dist/bin/installer/targets/amp.js +3 -3
  82. package/dist/bin/installer/targets/amp.js.map +2 -2
  83. package/dist/bin/installer/targets/antigravity.js +35 -6
  84. package/dist/bin/installer/targets/antigravity.js.map +2 -2
  85. package/dist/bin/installer/targets/augment.js +3 -3
  86. package/dist/bin/installer/targets/augment.js.map +2 -2
  87. package/dist/bin/installer/targets/claude.js +49 -5
  88. package/dist/bin/installer/targets/claude.js.map +2 -2
  89. package/dist/bin/installer/targets/cline.js +32 -6
  90. package/dist/bin/installer/targets/cline.js.map +2 -2
  91. package/dist/bin/installer/targets/codex.js +64 -12
  92. package/dist/bin/installer/targets/codex.js.map +2 -2
  93. package/dist/bin/installer/targets/continue.js +2 -2
  94. package/dist/bin/installer/targets/continue.js.map +2 -2
  95. package/dist/bin/installer/targets/copilot-cli.js +101 -0
  96. package/dist/bin/installer/targets/copilot-cli.js.map +7 -0
  97. package/dist/bin/installer/targets/copilot.js +31 -5
  98. package/dist/bin/installer/targets/copilot.js.map +2 -2
  99. package/dist/bin/installer/targets/cursor.js +4 -4
  100. package/dist/bin/installer/targets/cursor.js.map +2 -2
  101. package/dist/bin/installer/targets/devin.js +2 -2
  102. package/dist/bin/installer/targets/devin.js.map +2 -2
  103. package/dist/bin/installer/targets/gemini-cli.js +2 -2
  104. package/dist/bin/installer/targets/gemini-cli.js.map +2 -2
  105. package/dist/bin/installer/targets/generic.js +2 -14
  106. package/dist/bin/installer/targets/generic.js.map +2 -2
  107. package/dist/bin/installer/targets/goose.js +3 -3
  108. package/dist/bin/installer/targets/goose.js.map +2 -2
  109. package/dist/bin/installer/targets/index.js +250 -0
  110. package/dist/bin/installer/targets/index.js.map +2 -2
  111. package/dist/bin/installer/targets/junie.js +2 -2
  112. package/dist/bin/installer/targets/junie.js.map +2 -2
  113. package/dist/bin/installer/targets/kilo.js +2 -2
  114. package/dist/bin/installer/targets/kilo.js.map +2 -2
  115. package/dist/bin/installer/targets/kiro.js +3 -3
  116. package/dist/bin/installer/targets/kiro.js.map +2 -2
  117. package/dist/bin/installer/targets/opencode.js +2 -2
  118. package/dist/bin/installer/targets/opencode.js.map +2 -2
  119. package/dist/bin/installer/targets/openhands.js +3 -3
  120. package/dist/bin/installer/targets/openhands.js.map +2 -2
  121. package/dist/bin/installer/targets/qoder.js +91 -0
  122. package/dist/bin/installer/targets/qoder.js.map +7 -0
  123. package/dist/bin/installer/targets/qwen.js +96 -0
  124. package/dist/bin/installer/targets/qwen.js.map +7 -0
  125. package/dist/bin/installer/targets/replit.js +3 -3
  126. package/dist/bin/installer/targets/replit.js.map +2 -2
  127. package/dist/bin/installer/targets/roo.js +2 -2
  128. package/dist/bin/installer/targets/roo.js.map +2 -2
  129. package/dist/bin/installer/targets/tabnine.js +3 -3
  130. package/dist/bin/installer/targets/tabnine.js.map +2 -2
  131. package/dist/bin/installer/targets/trae.js +5 -5
  132. package/dist/bin/installer/targets/trae.js.map +2 -2
  133. package/dist/bin/installer/targets/warp.js +2 -2
  134. package/dist/bin/installer/targets/warp.js.map +2 -2
  135. package/dist/bin/installer/targets/windsurf.js +35 -6
  136. package/dist/bin/installer/targets/windsurf.js.map +2 -2
  137. package/dist/bin/kirograph.js +72 -6
  138. package/dist/bin/kirograph.js.map +3 -3
  139. package/dist/compression/tracker.js +80 -0
  140. package/dist/compression/tracker.js.map +2 -2
  141. package/dist/config.js +90 -3
  142. package/dist/config.js.map +2 -2
  143. package/dist/core/pipeline.js +36 -2
  144. package/dist/core/pipeline.js.map +2 -2
  145. package/dist/db/database.js +56 -5
  146. package/dist/db/database.js.map +2 -2
  147. package/dist/db/memory-schema.sql +5 -1
  148. package/dist/db/schema.sql +3 -1
  149. package/dist/db/security-schema.sql +72 -0
  150. package/dist/extraction/extractor.js +81 -0
  151. package/dist/extraction/extractor.js.map +2 -2
  152. package/dist/extraction/grammars.js +32 -8
  153. package/dist/extraction/grammars.js.map +2 -2
  154. package/dist/extraction/languages.js +43 -1
  155. package/dist/extraction/languages.js.map +2 -2
  156. package/dist/extraction/notebook.js +300 -0
  157. package/dist/extraction/notebook.js.map +7 -0
  158. package/dist/extraction/wasm/tree-sitter-astro.wasm +0 -0
  159. package/dist/extraction/wasm/tree-sitter-gdscript.wasm +0 -0
  160. package/dist/extraction/wasm/tree-sitter-julia.wasm +0 -0
  161. package/dist/extraction/wasm/tree-sitter-nix.wasm +0 -0
  162. package/dist/extraction/wasm/tree-sitter-perl.wasm +0 -0
  163. package/dist/extraction/wasm/tree-sitter-powershell.wasm +0 -0
  164. package/dist/extraction/wasm/tree-sitter-r.wasm +0 -0
  165. package/dist/extraction/wasm/tree-sitter-sql.wasm +0 -0
  166. package/dist/extraction/wasm/tree-sitter-verilog.wasm +0 -0
  167. package/dist/frameworks/flutter.js +130 -0
  168. package/dist/frameworks/flutter.js.map +7 -0
  169. package/dist/frameworks/index.js +7 -1
  170. package/dist/frameworks/index.js.map +3 -3
  171. package/dist/graph/communities.js +317 -0
  172. package/dist/graph/communities.js.map +7 -0
  173. package/dist/graph/flows.js +138 -0
  174. package/dist/graph/flows.js.map +7 -0
  175. package/dist/graph/refactor.js +155 -0
  176. package/dist/graph/refactor.js.map +7 -0
  177. package/dist/index.js +1 -1
  178. package/dist/index.js.map +2 -2
  179. package/dist/mcp/cache.js +172 -0
  180. package/dist/mcp/cache.js.map +7 -0
  181. package/dist/mcp/read-modes.js +295 -0
  182. package/dist/mcp/read-modes.js.map +7 -0
  183. package/dist/mcp/server.js +2 -1
  184. package/dist/mcp/server.js.map +2 -2
  185. package/dist/mcp/tool-names.js +21 -1
  186. package/dist/mcp/tool-names.js.map +2 -2
  187. package/dist/mcp/tools.js +1160 -1
  188. package/dist/mcp/tools.js.map +3 -3
  189. package/dist/memory/database.js +32 -2
  190. package/dist/memory/database.js.map +2 -2
  191. package/dist/memory/types.js.map +1 -1
  192. package/dist/resolution/bridges/android-rn.js +298 -0
  193. package/dist/resolution/bridges/android-rn.js.map +7 -0
  194. package/dist/resolution/bridges/expo-modules.js +155 -0
  195. package/dist/resolution/bridges/expo-modules.js.map +7 -0
  196. package/dist/resolution/bridges/flutter-channel.js +385 -0
  197. package/dist/resolution/bridges/flutter-channel.js.map +7 -0
  198. package/dist/resolution/bridges/index.js +80 -0
  199. package/dist/resolution/bridges/index.js.map +7 -0
  200. package/dist/resolution/bridges/native-events.js +188 -0
  201. package/dist/resolution/bridges/native-events.js.map +7 -0
  202. package/dist/resolution/bridges/native-views.js +244 -0
  203. package/dist/resolution/bridges/native-views.js.map +7 -0
  204. package/dist/resolution/bridges/react-native.js +161 -0
  205. package/dist/resolution/bridges/react-native.js.map +7 -0
  206. package/dist/resolution/bridges/swift-objc.js +227 -0
  207. package/dist/resolution/bridges/swift-objc.js.map +7 -0
  208. package/dist/resolution/bridges/turbomodules.js +216 -0
  209. package/dist/resolution/bridges/turbomodules.js.map +7 -0
  210. package/dist/resolution/index.js +61 -2
  211. package/dist/resolution/index.js.map +2 -2
  212. package/dist/security/attack-surface.js +164 -0
  213. package/dist/security/attack-surface.js.map +7 -0
  214. package/dist/security/context-warnings.js +123 -0
  215. package/dist/security/context-warnings.js.map +7 -0
  216. package/dist/security/context-warnings.test.js +300 -0
  217. package/dist/security/context-warnings.test.js.map +7 -0
  218. package/dist/security/data-flows.js +228 -0
  219. package/dist/security/data-flows.js.map +7 -0
  220. package/dist/security/dep-confusion.js +255 -0
  221. package/dist/security/dep-confusion.js.map +7 -0
  222. package/dist/security/errors.js +51 -0
  223. package/dist/security/errors.js.map +7 -0
  224. package/dist/security/export/fix-suggestions.js +58 -0
  225. package/dist/security/export/fix-suggestions.js.map +7 -0
  226. package/dist/security/export/fix-suggestions.test.js +74 -0
  227. package/dist/security/export/fix-suggestions.test.js.map +7 -0
  228. package/dist/security/export/sbom.js +230 -0
  229. package/dist/security/export/sbom.js.map +7 -0
  230. package/dist/security/export/sbom.test.js +288 -0
  231. package/dist/security/export/sbom.test.js.map +7 -0
  232. package/dist/security/export/serialization.js +142 -0
  233. package/dist/security/export/serialization.js.map +7 -0
  234. package/dist/security/export/serialization.test.js +310 -0
  235. package/dist/security/export/serialization.test.js.map +7 -0
  236. package/dist/security/export/vex.js +220 -0
  237. package/dist/security/export/vex.js.map +7 -0
  238. package/dist/security/export/vex.test.js +278 -0
  239. package/dist/security/export/vex.test.js.map +7 -0
  240. package/dist/security/index.js +67 -0
  241. package/dist/security/index.js.map +7 -0
  242. package/dist/security/integrator-transitives.test.js +359 -0
  243. package/dist/security/integrator-transitives.test.js.map +7 -0
  244. package/dist/security/integrator.js +491 -0
  245. package/dist/security/integrator.js.map +7 -0
  246. package/dist/security/integrator.test.js +237 -0
  247. package/dist/security/integrator.test.js.map +7 -0
  248. package/dist/security/license.js +70 -0
  249. package/dist/security/license.js.map +7 -0
  250. package/dist/security/manifest/adapter.js +243 -0
  251. package/dist/security/manifest/adapter.js.map +7 -0
  252. package/dist/security/manifest/adapter.test.js +272 -0
  253. package/dist/security/manifest/adapter.test.js.map +7 -0
  254. package/dist/security/manifest/parser.js +376 -0
  255. package/dist/security/manifest/parser.js.map +7 -0
  256. package/dist/security/manifest/parser.test.js +110 -0
  257. package/dist/security/manifest/parser.test.js.map +7 -0
  258. package/dist/security/manifest/plugins/cargo.js +233 -0
  259. package/dist/security/manifest/plugins/cargo.js.map +7 -0
  260. package/dist/security/manifest/plugins/cargo.test.js +304 -0
  261. package/dist/security/manifest/plugins/cargo.test.js.map +7 -0
  262. package/dist/security/manifest/plugins/composer.js +152 -0
  263. package/dist/security/manifest/plugins/composer.js.map +7 -0
  264. package/dist/security/manifest/plugins/go.js +146 -0
  265. package/dist/security/manifest/plugins/go.js.map +7 -0
  266. package/dist/security/manifest/plugins/go.test.js +341 -0
  267. package/dist/security/manifest/plugins/go.test.js.map +7 -0
  268. package/dist/security/manifest/plugins/gradle.js +159 -0
  269. package/dist/security/manifest/plugins/gradle.js.map +7 -0
  270. package/dist/security/manifest/plugins/hex.js +159 -0
  271. package/dist/security/manifest/plugins/hex.js.map +7 -0
  272. package/dist/security/manifest/plugins/maven.js +128 -0
  273. package/dist/security/manifest/plugins/maven.js.map +7 -0
  274. package/dist/security/manifest/plugins/maven.test.js +389 -0
  275. package/dist/security/manifest/plugins/maven.test.js.map +7 -0
  276. package/dist/security/manifest/plugins/npm.js +284 -0
  277. package/dist/security/manifest/plugins/npm.js.map +7 -0
  278. package/dist/security/manifest/plugins/npm.test.js +298 -0
  279. package/dist/security/manifest/plugins/npm.test.js.map +7 -0
  280. package/dist/security/manifest/plugins/nuget.js +186 -0
  281. package/dist/security/manifest/plugins/nuget.js.map +7 -0
  282. package/dist/security/manifest/plugins/pip.js +123 -0
  283. package/dist/security/manifest/plugins/pip.js.map +7 -0
  284. package/dist/security/manifest/plugins/pip.test.js +208 -0
  285. package/dist/security/manifest/plugins/pip.test.js.map +7 -0
  286. package/dist/security/manifest/plugins/pubspec.js +212 -0
  287. package/dist/security/manifest/plugins/pubspec.js.map +7 -0
  288. package/dist/security/manifest/plugins/pyproject.js +261 -0
  289. package/dist/security/manifest/plugins/pyproject.js.map +7 -0
  290. package/dist/security/manifest/plugins/rubygems.js +185 -0
  291. package/dist/security/manifest/plugins/rubygems.js.map +7 -0
  292. package/dist/security/manifest/plugins/swift.js +200 -0
  293. package/dist/security/manifest/plugins/swift.js.map +7 -0
  294. package/dist/security/owasp.js +104 -0
  295. package/dist/security/owasp.js.map +7 -0
  296. package/dist/security/pipeline.js +125 -0
  297. package/dist/security/pipeline.js.map +7 -0
  298. package/dist/security/reachability.js +276 -0
  299. package/dist/security/reachability.js.map +7 -0
  300. package/dist/security/reachability.test.js +394 -0
  301. package/dist/security/reachability.test.js.map +7 -0
  302. package/dist/security/remediation.js +126 -0
  303. package/dist/security/remediation.js.map +7 -0
  304. package/dist/security/secrets.js +176 -0
  305. package/dist/security/secrets.js.map +7 -0
  306. package/dist/security/staleness.js +231 -0
  307. package/dist/security/staleness.js.map +7 -0
  308. package/dist/security/supply-chain.js +301 -0
  309. package/dist/security/supply-chain.js.map +7 -0
  310. package/dist/security/suppressions.js +106 -0
  311. package/dist/security/suppressions.js.map +7 -0
  312. package/dist/security/types.js +17 -0
  313. package/dist/security/types.js.map +7 -0
  314. package/dist/security/vuln/client.js +355 -0
  315. package/dist/security/vuln/client.js.map +7 -0
  316. package/dist/security/vuln/client.test.js +288 -0
  317. package/dist/security/vuln/client.test.js.map +7 -0
  318. package/dist/security/vuln/epss-client.js +95 -0
  319. package/dist/security/vuln/epss-client.js.map +7 -0
  320. package/dist/security/vuln/index.js +29 -0
  321. package/dist/security/vuln/index.js.map +7 -0
  322. package/dist/security/vuln/osv-adapter.js +321 -0
  323. package/dist/security/vuln/osv-adapter.js.map +7 -0
  324. package/dist/security/vuln/osv-adapter.test.js +391 -0
  325. package/dist/security/vuln/osv-adapter.test.js.map +7 -0
  326. package/dist/security/vuln/types.js +17 -0
  327. package/dist/security/vuln/types.js.map +7 -0
  328. package/dist/types.js.map +2 -2
  329. package/package.json +2 -1
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var serialization_exports = {};
20
+ __export(serialization_exports, {
21
+ deserializeAll: () => deserializeAll,
22
+ deserializeComponentToDependency: () => deserializeComponentToDependency,
23
+ serializeAll: () => serializeAll,
24
+ serializeDependencyToComponent: () => serializeDependencyToComponent
25
+ });
26
+ module.exports = __toCommonJS(serialization_exports);
27
+ const ECOSYSTEM_TO_PURL = {
28
+ npm: "npm",
29
+ maven: "maven",
30
+ go: "golang",
31
+ pypi: "pypi",
32
+ cargo: "cargo"
33
+ };
34
+ const PURL_TO_ECOSYSTEM = {
35
+ npm: "npm",
36
+ maven: "maven",
37
+ golang: "go",
38
+ pypi: "pypi",
39
+ cargo: "cargo"
40
+ };
41
+ function serializeDependencyToComponent(dep) {
42
+ const purlType = ECOSYSTEM_TO_PURL[dep.ecosystem];
43
+ if (!purlType) {
44
+ throw new Error(`Unsupported ecosystem: ${dep.ecosystem}`);
45
+ }
46
+ const version = dep.resolved_version ?? dep.declared_constraint;
47
+ if (!version) {
48
+ throw new Error(`No version or constraint available for dependency: ${dep.package_name}`);
49
+ }
50
+ if (!dep.package_name) {
51
+ throw new Error("Dependency package_name is required");
52
+ }
53
+ const purl = `pkg:${purlType}/${dep.package_name}@${version}`;
54
+ const scope = dep.scope === "production" ? "required" : "optional";
55
+ const component = {
56
+ type: "library",
57
+ name: dep.package_name,
58
+ version,
59
+ purl,
60
+ scope,
61
+ properties: [
62
+ { name: "kirograph:declaredConstraint", value: dep.declared_constraint }
63
+ ]
64
+ };
65
+ return component;
66
+ }
67
+ function deserializeComponentToDependency(component) {
68
+ if (!component.purl) {
69
+ throw new Error(`Component "${component.name}" is missing purl`);
70
+ }
71
+ if (!component.name) {
72
+ throw new Error("Component name is required");
73
+ }
74
+ const purlMatch = component.purl.match(/^pkg:([^/]+)\/(.+)@(.+)$/);
75
+ if (!purlMatch) {
76
+ throw new Error(`Invalid purl format: ${component.purl}`);
77
+ }
78
+ const [, purlType, purlName, purlVersion] = purlMatch;
79
+ const ecosystem = PURL_TO_ECOSYSTEM[purlType];
80
+ if (!ecosystem) {
81
+ throw new Error(`Unsupported purl type: ${purlType}`);
82
+ }
83
+ const constraintProp = component.properties?.find(
84
+ (p) => p.name === "kirograph:declaredConstraint"
85
+ );
86
+ const declaredConstraint = constraintProp?.value ?? component.version;
87
+ const scope = component.scope === "optional" ? "optional" : "production";
88
+ const row = {
89
+ node_id: `dep:${ecosystem}:${purlName}`,
90
+ ecosystem,
91
+ package_name: purlName,
92
+ declared_constraint: declaredConstraint,
93
+ resolved_version: purlVersion,
94
+ scope,
95
+ transitive_status: "complete",
96
+ last_vuln_check: null,
97
+ vuln_data_stale: 0,
98
+ vuln_data_stale_since: null,
99
+ source_manifests: "[]"
100
+ };
101
+ return row;
102
+ }
103
+ function serializeAll(deps) {
104
+ const components = [];
105
+ const errors = [];
106
+ for (const dep of deps) {
107
+ try {
108
+ const component = serializeDependencyToComponent(dep);
109
+ components.push(component);
110
+ } catch (err) {
111
+ errors.push({
112
+ name: dep.package_name || dep.node_id || "unknown",
113
+ reason: err instanceof Error ? err.message : String(err)
114
+ });
115
+ }
116
+ }
117
+ return { components, errors };
118
+ }
119
+ function deserializeAll(components) {
120
+ const deps = [];
121
+ const errors = [];
122
+ for (const component of components) {
123
+ try {
124
+ const dep = deserializeComponentToDependency(component);
125
+ deps.push(dep);
126
+ } catch (err) {
127
+ errors.push({
128
+ name: component.name || "unknown",
129
+ reason: err instanceof Error ? err.message : String(err)
130
+ });
131
+ }
132
+ }
133
+ return { deps, errors };
134
+ }
135
+ // Annotate the CommonJS export names for ESM import in node:
136
+ 0 && (module.exports = {
137
+ deserializeAll,
138
+ deserializeComponentToDependency,
139
+ serializeAll,
140
+ serializeDependencyToComponent
141
+ });
142
+ //# sourceMappingURL=serialization.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/security/export/serialization.ts"],
4
+ "sourcesContent": ["/**\n * CycloneDX serialization utilities for Dependency_Nodes.\n *\n * Provides serialize/deserialize between DependencyRow (sec_dependencies table)\n * and CycloneDX JSON component format, with partial failure resilience.\n *\n * Requirements: 8.2, 8.3, 8.4\n */\nimport type { CycloneDXComponent } from '../types';\n\n// \u2500\u2500 Interfaces \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Represents a row from the sec_dependencies table.\n */\nexport interface DependencyRow {\n node_id: string;\n ecosystem: string;\n package_name: string;\n declared_constraint: string;\n resolved_version: string | null;\n scope: 'production' | 'development' | 'optional';\n transitive_status: 'complete' | 'incomplete';\n last_vuln_check: number | null;\n vuln_data_stale: number;\n vuln_data_stale_since: number | null;\n source_manifests: string; // JSON array of manifest paths\n}\n\n/**\n * Error reported when a single node fails serialization/deserialization.\n */\nexport interface SerializationError {\n name: string;\n reason: string;\n}\n\n// \u2500\u2500 Ecosystem \u2194 purl type mapping \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst ECOSYSTEM_TO_PURL: Record<string, string> = {\n npm: 'npm',\n maven: 'maven',\n go: 'golang',\n pypi: 'pypi',\n cargo: 'cargo',\n};\n\nconst PURL_TO_ECOSYSTEM: Record<string, string> = {\n npm: 'npm',\n maven: 'maven',\n golang: 'go',\n pypi: 'pypi',\n cargo: 'cargo',\n};\n\n// \u2500\u2500 Single-item serialization \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Converts a dependency database row to a CycloneDX component object.\n * Stores the declared constraint in a `properties` array entry with\n * name \"kirograph:declaredConstraint\".\n *\n * The purl format is: pkg:<ecosystem>/<name>@<version>\n */\nexport function serializeDependencyToComponent(dep: DependencyRow): CycloneDXComponent {\n const purlType = ECOSYSTEM_TO_PURL[dep.ecosystem];\n if (!purlType) {\n throw new Error(`Unsupported ecosystem: ${dep.ecosystem}`);\n }\n\n const version = dep.resolved_version ?? dep.declared_constraint;\n if (!version) {\n throw new Error(`No version or constraint available for dependency: ${dep.package_name}`);\n }\n\n if (!dep.package_name) {\n throw new Error('Dependency package_name is required');\n }\n\n const purl = `pkg:${purlType}/${dep.package_name}@${version}`;\n\n const scope: 'required' | 'optional' =\n dep.scope === 'production' ? 'required' : 'optional';\n\n const component: CycloneDXComponent = {\n type: 'library',\n name: dep.package_name,\n version,\n purl,\n scope,\n properties: [\n { name: 'kirograph:declaredConstraint', value: dep.declared_constraint },\n ],\n };\n\n return component;\n}\n\n// \u2500\u2500 Single-item deserialization \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Converts a CycloneDX component back to a dependency row.\n * Extracts the constraint from the properties array.\n */\nexport function deserializeComponentToDependency(component: CycloneDXComponent): DependencyRow {\n if (!component.purl) {\n throw new Error(`Component \"${component.name}\" is missing purl`);\n }\n\n if (!component.name) {\n throw new Error('Component name is required');\n }\n\n // Parse purl: pkg:<type>/<name>@<version>\n const purlMatch = component.purl.match(/^pkg:([^/]+)\\/(.+)@(.+)$/);\n if (!purlMatch) {\n throw new Error(`Invalid purl format: ${component.purl}`);\n }\n\n const [, purlType, purlName, purlVersion] = purlMatch;\n\n const ecosystem = PURL_TO_ECOSYSTEM[purlType];\n if (!ecosystem) {\n throw new Error(`Unsupported purl type: ${purlType}`);\n }\n\n // Extract declared constraint from properties\n const constraintProp = component.properties?.find(\n (p) => p.name === 'kirograph:declaredConstraint',\n );\n const declaredConstraint = constraintProp?.value ?? component.version;\n\n // Map CycloneDX scope back to dependency scope\n const scope: 'production' | 'development' | 'optional' =\n component.scope === 'optional' ? 'optional' : 'production';\n\n const row: DependencyRow = {\n node_id: `dep:${ecosystem}:${purlName}`,\n ecosystem,\n package_name: purlName,\n declared_constraint: declaredConstraint,\n resolved_version: purlVersion,\n scope,\n transitive_status: 'complete',\n last_vuln_check: null,\n vuln_data_stale: 0,\n vuln_data_stale_since: null,\n source_manifests: '[]',\n };\n\n return row;\n}\n\n// \u2500\u2500 Batch serialization with partial failure resilience \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Serializes all dependencies, collecting errors for any that fail\n * without aborting the batch.\n */\nexport function serializeAll(deps: DependencyRow[]): {\n components: CycloneDXComponent[];\n errors: SerializationError[];\n} {\n const components: CycloneDXComponent[] = [];\n const errors: SerializationError[] = [];\n\n for (const dep of deps) {\n try {\n const component = serializeDependencyToComponent(dep);\n components.push(component);\n } catch (err) {\n errors.push({\n name: dep.package_name || dep.node_id || 'unknown',\n reason: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n return { components, errors };\n}\n\n/**\n * Deserializes all components back to dependency rows,\n * collecting errors for any that fail without aborting the batch.\n */\nexport function deserializeAll(components: CycloneDXComponent[]): {\n deps: DependencyRow[];\n errors: SerializationError[];\n} {\n const deps: DependencyRow[] = [];\n const errors: SerializationError[] = [];\n\n for (const component of components) {\n try {\n const dep = deserializeComponentToDependency(component);\n deps.push(dep);\n } catch (err) {\n errors.push({\n name: component.name || 'unknown',\n reason: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n return { deps, errors };\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,310 @@
1
+ "use strict";
2
+ var import_vitest = require("vitest");
3
+ var import_serialization = require("./serialization");
4
+ function makeDependencyRow(overrides) {
5
+ return {
6
+ node_id: "dep:npm:express",
7
+ ecosystem: "npm",
8
+ package_name: "express",
9
+ declared_constraint: "^4.18.0",
10
+ resolved_version: "4.18.2",
11
+ scope: "production",
12
+ transitive_status: "complete",
13
+ last_vuln_check: null,
14
+ vuln_data_stale: 0,
15
+ vuln_data_stale_since: null,
16
+ source_manifests: '["package.json"]',
17
+ ...overrides
18
+ };
19
+ }
20
+ (0, import_vitest.describe)("serializeDependencyToComponent", () => {
21
+ (0, import_vitest.it)("should serialize an npm dependency to a CycloneDX component", () => {
22
+ const dep = makeDependencyRow();
23
+ const component = (0, import_serialization.serializeDependencyToComponent)(dep);
24
+ (0, import_vitest.expect)(component.type).toBe("library");
25
+ (0, import_vitest.expect)(component.name).toBe("express");
26
+ (0, import_vitest.expect)(component.version).toBe("4.18.2");
27
+ (0, import_vitest.expect)(component.purl).toBe("pkg:npm/express@4.18.2");
28
+ (0, import_vitest.expect)(component.scope).toBe("required");
29
+ (0, import_vitest.expect)(component.properties).toEqual([
30
+ { name: "kirograph:declaredConstraint", value: "^4.18.0" }
31
+ ]);
32
+ });
33
+ (0, import_vitest.it)("should use declared_constraint as version when resolved_version is null", () => {
34
+ const dep = makeDependencyRow({ resolved_version: null });
35
+ const component = (0, import_serialization.serializeDependencyToComponent)(dep);
36
+ (0, import_vitest.expect)(component.version).toBe("^4.18.0");
37
+ (0, import_vitest.expect)(component.purl).toBe("pkg:npm/express@^4.18.0");
38
+ });
39
+ (0, import_vitest.it)("should map production scope to required", () => {
40
+ const dep = makeDependencyRow({ scope: "production" });
41
+ const component = (0, import_serialization.serializeDependencyToComponent)(dep);
42
+ (0, import_vitest.expect)(component.scope).toBe("required");
43
+ });
44
+ (0, import_vitest.it)("should map development scope to optional", () => {
45
+ const dep = makeDependencyRow({ scope: "development" });
46
+ const component = (0, import_serialization.serializeDependencyToComponent)(dep);
47
+ (0, import_vitest.expect)(component.scope).toBe("optional");
48
+ });
49
+ (0, import_vitest.it)("should map optional scope to optional", () => {
50
+ const dep = makeDependencyRow({ scope: "optional" });
51
+ const component = (0, import_serialization.serializeDependencyToComponent)(dep);
52
+ (0, import_vitest.expect)(component.scope).toBe("optional");
53
+ });
54
+ (0, import_vitest.it)("should correctly map maven ecosystem to purl type", () => {
55
+ const dep = makeDependencyRow({
56
+ node_id: "dep:maven:log4j-core",
57
+ ecosystem: "maven",
58
+ package_name: "org.apache.logging.log4j/log4j-core",
59
+ resolved_version: "2.17.0"
60
+ });
61
+ const component = (0, import_serialization.serializeDependencyToComponent)(dep);
62
+ (0, import_vitest.expect)(component.purl).toBe("pkg:maven/org.apache.logging.log4j/log4j-core@2.17.0");
63
+ });
64
+ (0, import_vitest.it)("should correctly map go ecosystem to golang purl type", () => {
65
+ const dep = makeDependencyRow({
66
+ node_id: "dep:go:github.com/gin-gonic/gin",
67
+ ecosystem: "go",
68
+ package_name: "github.com/gin-gonic/gin",
69
+ resolved_version: "1.9.1"
70
+ });
71
+ const component = (0, import_serialization.serializeDependencyToComponent)(dep);
72
+ (0, import_vitest.expect)(component.purl).toBe("pkg:golang/github.com/gin-gonic/gin@1.9.1");
73
+ });
74
+ (0, import_vitest.it)("should correctly map pypi ecosystem", () => {
75
+ const dep = makeDependencyRow({
76
+ node_id: "dep:pypi:django",
77
+ ecosystem: "pypi",
78
+ package_name: "django",
79
+ resolved_version: "4.2.0"
80
+ });
81
+ const component = (0, import_serialization.serializeDependencyToComponent)(dep);
82
+ (0, import_vitest.expect)(component.purl).toBe("pkg:pypi/django@4.2.0");
83
+ });
84
+ (0, import_vitest.it)("should correctly map cargo ecosystem", () => {
85
+ const dep = makeDependencyRow({
86
+ node_id: "dep:cargo:serde",
87
+ ecosystem: "cargo",
88
+ package_name: "serde",
89
+ resolved_version: "1.0.188"
90
+ });
91
+ const component = (0, import_serialization.serializeDependencyToComponent)(dep);
92
+ (0, import_vitest.expect)(component.purl).toBe("pkg:cargo/serde@1.0.188");
93
+ });
94
+ (0, import_vitest.it)("should throw for unsupported ecosystem", () => {
95
+ const dep = makeDependencyRow({ ecosystem: "unknown" });
96
+ (0, import_vitest.expect)(() => (0, import_serialization.serializeDependencyToComponent)(dep)).toThrow("Unsupported ecosystem: unknown");
97
+ });
98
+ (0, import_vitest.it)("should throw when both version and constraint are empty", () => {
99
+ const dep = makeDependencyRow({
100
+ resolved_version: null,
101
+ declared_constraint: ""
102
+ });
103
+ (0, import_vitest.expect)(() => (0, import_serialization.serializeDependencyToComponent)(dep)).toThrow(
104
+ "No version or constraint available"
105
+ );
106
+ });
107
+ (0, import_vitest.it)("should throw when package_name is empty", () => {
108
+ const dep = makeDependencyRow({ package_name: "" });
109
+ (0, import_vitest.expect)(() => (0, import_serialization.serializeDependencyToComponent)(dep)).toThrow(
110
+ "Dependency package_name is required"
111
+ );
112
+ });
113
+ });
114
+ (0, import_vitest.describe)("deserializeComponentToDependency", () => {
115
+ (0, import_vitest.it)("should deserialize a CycloneDX component to a dependency row", () => {
116
+ const component = {
117
+ type: "library",
118
+ name: "express",
119
+ version: "4.18.2",
120
+ purl: "pkg:npm/express@4.18.2",
121
+ scope: "required",
122
+ properties: [{ name: "kirograph:declaredConstraint", value: "^4.18.0" }]
123
+ };
124
+ const dep = (0, import_serialization.deserializeComponentToDependency)(component);
125
+ (0, import_vitest.expect)(dep.ecosystem).toBe("npm");
126
+ (0, import_vitest.expect)(dep.package_name).toBe("express");
127
+ (0, import_vitest.expect)(dep.resolved_version).toBe("4.18.2");
128
+ (0, import_vitest.expect)(dep.declared_constraint).toBe("^4.18.0");
129
+ (0, import_vitest.expect)(dep.scope).toBe("production");
130
+ (0, import_vitest.expect)(dep.node_id).toBe("dep:npm:express");
131
+ });
132
+ (0, import_vitest.it)("should use version as declared_constraint when property is missing", () => {
133
+ const component = {
134
+ type: "library",
135
+ name: "express",
136
+ version: "4.18.2",
137
+ purl: "pkg:npm/express@4.18.2"
138
+ };
139
+ const dep = (0, import_serialization.deserializeComponentToDependency)(component);
140
+ (0, import_vitest.expect)(dep.declared_constraint).toBe("4.18.2");
141
+ });
142
+ (0, import_vitest.it)("should map optional scope back to optional", () => {
143
+ const component = {
144
+ type: "library",
145
+ name: "jest",
146
+ version: "29.0.0",
147
+ purl: "pkg:npm/jest@29.0.0",
148
+ scope: "optional"
149
+ };
150
+ const dep = (0, import_serialization.deserializeComponentToDependency)(component);
151
+ (0, import_vitest.expect)(dep.scope).toBe("optional");
152
+ });
153
+ (0, import_vitest.it)("should map required scope back to production", () => {
154
+ const component = {
155
+ type: "library",
156
+ name: "express",
157
+ version: "4.18.2",
158
+ purl: "pkg:npm/express@4.18.2",
159
+ scope: "required"
160
+ };
161
+ const dep = (0, import_serialization.deserializeComponentToDependency)(component);
162
+ (0, import_vitest.expect)(dep.scope).toBe("production");
163
+ });
164
+ (0, import_vitest.it)("should map golang purl type back to go ecosystem", () => {
165
+ const component = {
166
+ type: "library",
167
+ name: "github.com/gin-gonic/gin",
168
+ version: "1.9.1",
169
+ purl: "pkg:golang/github.com/gin-gonic/gin@1.9.1"
170
+ };
171
+ const dep = (0, import_serialization.deserializeComponentToDependency)(component);
172
+ (0, import_vitest.expect)(dep.ecosystem).toBe("go");
173
+ (0, import_vitest.expect)(dep.package_name).toBe("github.com/gin-gonic/gin");
174
+ });
175
+ (0, import_vitest.it)("should throw for missing purl", () => {
176
+ const component = {
177
+ type: "library",
178
+ name: "express",
179
+ version: "4.18.2",
180
+ purl: ""
181
+ };
182
+ (0, import_vitest.expect)(() => (0, import_serialization.deserializeComponentToDependency)(component)).toThrow("missing purl");
183
+ });
184
+ (0, import_vitest.it)("should throw for invalid purl format", () => {
185
+ const component = {
186
+ type: "library",
187
+ name: "express",
188
+ version: "4.18.2",
189
+ purl: "invalid-purl"
190
+ };
191
+ (0, import_vitest.expect)(() => (0, import_serialization.deserializeComponentToDependency)(component)).toThrow("Invalid purl format");
192
+ });
193
+ (0, import_vitest.it)("should throw for unsupported purl type", () => {
194
+ const component = {
195
+ type: "library",
196
+ name: "something",
197
+ version: "1.0.0",
198
+ purl: "pkg:nuget/something@1.0.0"
199
+ };
200
+ (0, import_vitest.expect)(() => (0, import_serialization.deserializeComponentToDependency)(component)).toThrow("Unsupported purl type");
201
+ });
202
+ (0, import_vitest.it)("should set default values for non-serialized fields", () => {
203
+ const component = {
204
+ type: "library",
205
+ name: "express",
206
+ version: "4.18.2",
207
+ purl: "pkg:npm/express@4.18.2"
208
+ };
209
+ const dep = (0, import_serialization.deserializeComponentToDependency)(component);
210
+ (0, import_vitest.expect)(dep.transitive_status).toBe("complete");
211
+ (0, import_vitest.expect)(dep.last_vuln_check).toBeNull();
212
+ (0, import_vitest.expect)(dep.vuln_data_stale).toBe(0);
213
+ (0, import_vitest.expect)(dep.vuln_data_stale_since).toBeNull();
214
+ (0, import_vitest.expect)(dep.source_manifests).toBe("[]");
215
+ });
216
+ });
217
+ (0, import_vitest.describe)("serializeDependencyToComponent \u2192 deserializeComponentToDependency round-trip", () => {
218
+ (0, import_vitest.it)("should preserve key fields through round-trip", () => {
219
+ const original = makeDependencyRow();
220
+ const component = (0, import_serialization.serializeDependencyToComponent)(original);
221
+ const restored = (0, import_serialization.deserializeComponentToDependency)(component);
222
+ (0, import_vitest.expect)(restored.package_name).toBe(original.package_name);
223
+ (0, import_vitest.expect)(restored.resolved_version).toBe(original.resolved_version);
224
+ (0, import_vitest.expect)(restored.ecosystem).toBe(original.ecosystem);
225
+ (0, import_vitest.expect)(restored.scope).toBe(original.scope);
226
+ (0, import_vitest.expect)(restored.declared_constraint).toBe(original.declared_constraint);
227
+ });
228
+ (0, import_vitest.it)("should preserve constraint when resolved_version is null", () => {
229
+ const original = makeDependencyRow({ resolved_version: null });
230
+ const component = (0, import_serialization.serializeDependencyToComponent)(original);
231
+ const restored = (0, import_serialization.deserializeComponentToDependency)(component);
232
+ (0, import_vitest.expect)(restored.declared_constraint).toBe(original.declared_constraint);
233
+ (0, import_vitest.expect)(restored.resolved_version).toBe(original.declared_constraint);
234
+ });
235
+ });
236
+ (0, import_vitest.describe)("serializeAll", () => {
237
+ (0, import_vitest.it)("should serialize all valid dependencies", () => {
238
+ const deps = [
239
+ makeDependencyRow({ package_name: "express", node_id: "dep:npm:express" }),
240
+ makeDependencyRow({ package_name: "lodash", node_id: "dep:npm:lodash" })
241
+ ];
242
+ const result = (0, import_serialization.serializeAll)(deps);
243
+ (0, import_vitest.expect)(result.components).toHaveLength(2);
244
+ (0, import_vitest.expect)(result.errors).toHaveLength(0);
245
+ });
246
+ (0, import_vitest.it)("should collect errors for failing nodes and continue with remaining", () => {
247
+ const deps = [
248
+ makeDependencyRow({ package_name: "express" }),
249
+ makeDependencyRow({ package_name: "bad-dep", ecosystem: "unsupported" }),
250
+ makeDependencyRow({ package_name: "lodash" })
251
+ ];
252
+ const result = (0, import_serialization.serializeAll)(deps);
253
+ (0, import_vitest.expect)(result.components).toHaveLength(2);
254
+ (0, import_vitest.expect)(result.errors).toHaveLength(1);
255
+ (0, import_vitest.expect)(result.errors[0].name).toBe("bad-dep");
256
+ (0, import_vitest.expect)(result.errors[0].reason).toContain("Unsupported ecosystem");
257
+ });
258
+ (0, import_vitest.it)("should handle empty input", () => {
259
+ const result = (0, import_serialization.serializeAll)([]);
260
+ (0, import_vitest.expect)(result.components).toHaveLength(0);
261
+ (0, import_vitest.expect)(result.errors).toHaveLength(0);
262
+ });
263
+ (0, import_vitest.it)("should handle all failures gracefully", () => {
264
+ const deps = [
265
+ makeDependencyRow({ ecosystem: "unknown1", package_name: "a" }),
266
+ makeDependencyRow({ ecosystem: "unknown2", package_name: "b" })
267
+ ];
268
+ const result = (0, import_serialization.serializeAll)(deps);
269
+ (0, import_vitest.expect)(result.components).toHaveLength(0);
270
+ (0, import_vitest.expect)(result.errors).toHaveLength(2);
271
+ });
272
+ });
273
+ (0, import_vitest.describe)("deserializeAll", () => {
274
+ (0, import_vitest.it)("should deserialize all valid components", () => {
275
+ const components = [
276
+ { type: "library", name: "express", version: "4.18.2", purl: "pkg:npm/express@4.18.2" },
277
+ { type: "library", name: "lodash", version: "4.17.21", purl: "pkg:npm/lodash@4.17.21" }
278
+ ];
279
+ const result = (0, import_serialization.deserializeAll)(components);
280
+ (0, import_vitest.expect)(result.deps).toHaveLength(2);
281
+ (0, import_vitest.expect)(result.errors).toHaveLength(0);
282
+ });
283
+ (0, import_vitest.it)("should collect errors for failing components and continue with remaining", () => {
284
+ const components = [
285
+ { type: "library", name: "express", version: "4.18.2", purl: "pkg:npm/express@4.18.2" },
286
+ { type: "library", name: "bad", version: "1.0.0", purl: "invalid-purl" },
287
+ { type: "library", name: "lodash", version: "4.17.21", purl: "pkg:npm/lodash@4.17.21" }
288
+ ];
289
+ const result = (0, import_serialization.deserializeAll)(components);
290
+ (0, import_vitest.expect)(result.deps).toHaveLength(2);
291
+ (0, import_vitest.expect)(result.errors).toHaveLength(1);
292
+ (0, import_vitest.expect)(result.errors[0].name).toBe("bad");
293
+ (0, import_vitest.expect)(result.errors[0].reason).toContain("Invalid purl format");
294
+ });
295
+ (0, import_vitest.it)("should handle empty input", () => {
296
+ const result = (0, import_serialization.deserializeAll)([]);
297
+ (0, import_vitest.expect)(result.deps).toHaveLength(0);
298
+ (0, import_vitest.expect)(result.errors).toHaveLength(0);
299
+ });
300
+ (0, import_vitest.it)("should handle all failures gracefully", () => {
301
+ const components = [
302
+ { type: "library", name: "a", version: "1.0", purl: "bad1" },
303
+ { type: "library", name: "b", version: "2.0", purl: "bad2" }
304
+ ];
305
+ const result = (0, import_serialization.deserializeAll)(components);
306
+ (0, import_vitest.expect)(result.deps).toHaveLength(0);
307
+ (0, import_vitest.expect)(result.errors).toHaveLength(2);
308
+ });
309
+ });
310
+ //# sourceMappingURL=serialization.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/security/export/serialization.test.ts"],
4
+ "sourcesContent": ["/**\n * Unit tests for CycloneDX serialization utilities.\n *\n * Tests serialize/deserialize for Dependency_Nodes to/from CycloneDX JSON\n * component format, including round-trip and partial failure resilience.\n */\nimport { describe, it, expect } from 'vitest';\nimport {\n serializeDependencyToComponent,\n deserializeComponentToDependency,\n serializeAll,\n deserializeAll,\n type DependencyRow,\n} from './serialization';\nimport type { CycloneDXComponent } from '../types';\n\nfunction makeDependencyRow(overrides?: Partial<DependencyRow>): DependencyRow {\n return {\n node_id: 'dep:npm:express',\n ecosystem: 'npm',\n package_name: 'express',\n declared_constraint: '^4.18.0',\n resolved_version: '4.18.2',\n scope: 'production',\n transitive_status: 'complete',\n last_vuln_check: null,\n vuln_data_stale: 0,\n vuln_data_stale_since: null,\n source_manifests: '[\"package.json\"]',\n ...overrides,\n };\n}\n\ndescribe('serializeDependencyToComponent', () => {\n it('should serialize an npm dependency to a CycloneDX component', () => {\n const dep = makeDependencyRow();\n const component = serializeDependencyToComponent(dep);\n\n expect(component.type).toBe('library');\n expect(component.name).toBe('express');\n expect(component.version).toBe('4.18.2');\n expect(component.purl).toBe('pkg:npm/express@4.18.2');\n expect(component.scope).toBe('required');\n expect(component.properties).toEqual([\n { name: 'kirograph:declaredConstraint', value: '^4.18.0' },\n ]);\n });\n\n it('should use declared_constraint as version when resolved_version is null', () => {\n const dep = makeDependencyRow({ resolved_version: null });\n const component = serializeDependencyToComponent(dep);\n\n expect(component.version).toBe('^4.18.0');\n expect(component.purl).toBe('pkg:npm/express@^4.18.0');\n });\n\n it('should map production scope to required', () => {\n const dep = makeDependencyRow({ scope: 'production' });\n const component = serializeDependencyToComponent(dep);\n expect(component.scope).toBe('required');\n });\n\n it('should map development scope to optional', () => {\n const dep = makeDependencyRow({ scope: 'development' });\n const component = serializeDependencyToComponent(dep);\n expect(component.scope).toBe('optional');\n });\n\n it('should map optional scope to optional', () => {\n const dep = makeDependencyRow({ scope: 'optional' });\n const component = serializeDependencyToComponent(dep);\n expect(component.scope).toBe('optional');\n });\n\n it('should correctly map maven ecosystem to purl type', () => {\n const dep = makeDependencyRow({\n node_id: 'dep:maven:log4j-core',\n ecosystem: 'maven',\n package_name: 'org.apache.logging.log4j/log4j-core',\n resolved_version: '2.17.0',\n });\n const component = serializeDependencyToComponent(dep);\n expect(component.purl).toBe('pkg:maven/org.apache.logging.log4j/log4j-core@2.17.0');\n });\n\n it('should correctly map go ecosystem to golang purl type', () => {\n const dep = makeDependencyRow({\n node_id: 'dep:go:github.com/gin-gonic/gin',\n ecosystem: 'go',\n package_name: 'github.com/gin-gonic/gin',\n resolved_version: '1.9.1',\n });\n const component = serializeDependencyToComponent(dep);\n expect(component.purl).toBe('pkg:golang/github.com/gin-gonic/gin@1.9.1');\n });\n\n it('should correctly map pypi ecosystem', () => {\n const dep = makeDependencyRow({\n node_id: 'dep:pypi:django',\n ecosystem: 'pypi',\n package_name: 'django',\n resolved_version: '4.2.0',\n });\n const component = serializeDependencyToComponent(dep);\n expect(component.purl).toBe('pkg:pypi/django@4.2.0');\n });\n\n it('should correctly map cargo ecosystem', () => {\n const dep = makeDependencyRow({\n node_id: 'dep:cargo:serde',\n ecosystem: 'cargo',\n package_name: 'serde',\n resolved_version: '1.0.188',\n });\n const component = serializeDependencyToComponent(dep);\n expect(component.purl).toBe('pkg:cargo/serde@1.0.188');\n });\n\n it('should throw for unsupported ecosystem', () => {\n const dep = makeDependencyRow({ ecosystem: 'unknown' });\n expect(() => serializeDependencyToComponent(dep)).toThrow('Unsupported ecosystem: unknown');\n });\n\n it('should throw when both version and constraint are empty', () => {\n const dep = makeDependencyRow({\n resolved_version: null,\n declared_constraint: '',\n });\n expect(() => serializeDependencyToComponent(dep)).toThrow(\n 'No version or constraint available',\n );\n });\n\n it('should throw when package_name is empty', () => {\n const dep = makeDependencyRow({ package_name: '' });\n expect(() => serializeDependencyToComponent(dep)).toThrow(\n 'Dependency package_name is required',\n );\n });\n});\n\ndescribe('deserializeComponentToDependency', () => {\n it('should deserialize a CycloneDX component to a dependency row', () => {\n const component: CycloneDXComponent = {\n type: 'library',\n name: 'express',\n version: '4.18.2',\n purl: 'pkg:npm/express@4.18.2',\n scope: 'required',\n properties: [{ name: 'kirograph:declaredConstraint', value: '^4.18.0' }],\n };\n\n const dep = deserializeComponentToDependency(component);\n\n expect(dep.ecosystem).toBe('npm');\n expect(dep.package_name).toBe('express');\n expect(dep.resolved_version).toBe('4.18.2');\n expect(dep.declared_constraint).toBe('^4.18.0');\n expect(dep.scope).toBe('production');\n expect(dep.node_id).toBe('dep:npm:express');\n });\n\n it('should use version as declared_constraint when property is missing', () => {\n const component: CycloneDXComponent = {\n type: 'library',\n name: 'express',\n version: '4.18.2',\n purl: 'pkg:npm/express@4.18.2',\n };\n\n const dep = deserializeComponentToDependency(component);\n expect(dep.declared_constraint).toBe('4.18.2');\n });\n\n it('should map optional scope back to optional', () => {\n const component: CycloneDXComponent = {\n type: 'library',\n name: 'jest',\n version: '29.0.0',\n purl: 'pkg:npm/jest@29.0.0',\n scope: 'optional',\n };\n\n const dep = deserializeComponentToDependency(component);\n expect(dep.scope).toBe('optional');\n });\n\n it('should map required scope back to production', () => {\n const component: CycloneDXComponent = {\n type: 'library',\n name: 'express',\n version: '4.18.2',\n purl: 'pkg:npm/express@4.18.2',\n scope: 'required',\n };\n\n const dep = deserializeComponentToDependency(component);\n expect(dep.scope).toBe('production');\n });\n\n it('should map golang purl type back to go ecosystem', () => {\n const component: CycloneDXComponent = {\n type: 'library',\n name: 'github.com/gin-gonic/gin',\n version: '1.9.1',\n purl: 'pkg:golang/github.com/gin-gonic/gin@1.9.1',\n };\n\n const dep = deserializeComponentToDependency(component);\n expect(dep.ecosystem).toBe('go');\n expect(dep.package_name).toBe('github.com/gin-gonic/gin');\n });\n\n it('should throw for missing purl', () => {\n const component = {\n type: 'library',\n name: 'express',\n version: '4.18.2',\n purl: '',\n } as CycloneDXComponent;\n\n expect(() => deserializeComponentToDependency(component)).toThrow('missing purl');\n });\n\n it('should throw for invalid purl format', () => {\n const component: CycloneDXComponent = {\n type: 'library',\n name: 'express',\n version: '4.18.2',\n purl: 'invalid-purl',\n };\n\n expect(() => deserializeComponentToDependency(component)).toThrow('Invalid purl format');\n });\n\n it('should throw for unsupported purl type', () => {\n const component: CycloneDXComponent = {\n type: 'library',\n name: 'something',\n version: '1.0.0',\n purl: 'pkg:nuget/something@1.0.0',\n };\n\n expect(() => deserializeComponentToDependency(component)).toThrow('Unsupported purl type');\n });\n\n it('should set default values for non-serialized fields', () => {\n const component: CycloneDXComponent = {\n type: 'library',\n name: 'express',\n version: '4.18.2',\n purl: 'pkg:npm/express@4.18.2',\n };\n\n const dep = deserializeComponentToDependency(component);\n expect(dep.transitive_status).toBe('complete');\n expect(dep.last_vuln_check).toBeNull();\n expect(dep.vuln_data_stale).toBe(0);\n expect(dep.vuln_data_stale_since).toBeNull();\n expect(dep.source_manifests).toBe('[]');\n });\n});\n\ndescribe('serializeDependencyToComponent \u2192 deserializeComponentToDependency round-trip', () => {\n it('should preserve key fields through round-trip', () => {\n const original = makeDependencyRow();\n const component = serializeDependencyToComponent(original);\n const restored = deserializeComponentToDependency(component);\n\n expect(restored.package_name).toBe(original.package_name);\n expect(restored.resolved_version).toBe(original.resolved_version);\n expect(restored.ecosystem).toBe(original.ecosystem);\n expect(restored.scope).toBe(original.scope);\n expect(restored.declared_constraint).toBe(original.declared_constraint);\n });\n\n it('should preserve constraint when resolved_version is null', () => {\n const original = makeDependencyRow({ resolved_version: null });\n const component = serializeDependencyToComponent(original);\n const restored = deserializeComponentToDependency(component);\n\n expect(restored.declared_constraint).toBe(original.declared_constraint);\n // When no resolved version, the version in purl is the constraint\n expect(restored.resolved_version).toBe(original.declared_constraint);\n });\n});\n\ndescribe('serializeAll', () => {\n it('should serialize all valid dependencies', () => {\n const deps = [\n makeDependencyRow({ package_name: 'express', node_id: 'dep:npm:express' }),\n makeDependencyRow({ package_name: 'lodash', node_id: 'dep:npm:lodash' }),\n ];\n\n const result = serializeAll(deps);\n expect(result.components).toHaveLength(2);\n expect(result.errors).toHaveLength(0);\n });\n\n it('should collect errors for failing nodes and continue with remaining', () => {\n const deps = [\n makeDependencyRow({ package_name: 'express' }),\n makeDependencyRow({ package_name: 'bad-dep', ecosystem: 'unsupported' }),\n makeDependencyRow({ package_name: 'lodash' }),\n ];\n\n const result = serializeAll(deps);\n expect(result.components).toHaveLength(2);\n expect(result.errors).toHaveLength(1);\n expect(result.errors[0].name).toBe('bad-dep');\n expect(result.errors[0].reason).toContain('Unsupported ecosystem');\n });\n\n it('should handle empty input', () => {\n const result = serializeAll([]);\n expect(result.components).toHaveLength(0);\n expect(result.errors).toHaveLength(0);\n });\n\n it('should handle all failures gracefully', () => {\n const deps = [\n makeDependencyRow({ ecosystem: 'unknown1', package_name: 'a' }),\n makeDependencyRow({ ecosystem: 'unknown2', package_name: 'b' }),\n ];\n\n const result = serializeAll(deps);\n expect(result.components).toHaveLength(0);\n expect(result.errors).toHaveLength(2);\n });\n});\n\ndescribe('deserializeAll', () => {\n it('should deserialize all valid components', () => {\n const components: CycloneDXComponent[] = [\n { type: 'library', name: 'express', version: '4.18.2', purl: 'pkg:npm/express@4.18.2' },\n { type: 'library', name: 'lodash', version: '4.17.21', purl: 'pkg:npm/lodash@4.17.21' },\n ];\n\n const result = deserializeAll(components);\n expect(result.deps).toHaveLength(2);\n expect(result.errors).toHaveLength(0);\n });\n\n it('should collect errors for failing components and continue with remaining', () => {\n const components: CycloneDXComponent[] = [\n { type: 'library', name: 'express', version: '4.18.2', purl: 'pkg:npm/express@4.18.2' },\n { type: 'library', name: 'bad', version: '1.0.0', purl: 'invalid-purl' },\n { type: 'library', name: 'lodash', version: '4.17.21', purl: 'pkg:npm/lodash@4.17.21' },\n ];\n\n const result = deserializeAll(components);\n expect(result.deps).toHaveLength(2);\n expect(result.errors).toHaveLength(1);\n expect(result.errors[0].name).toBe('bad');\n expect(result.errors[0].reason).toContain('Invalid purl format');\n });\n\n it('should handle empty input', () => {\n const result = deserializeAll([]);\n expect(result.deps).toHaveLength(0);\n expect(result.errors).toHaveLength(0);\n });\n\n it('should handle all failures gracefully', () => {\n const components: CycloneDXComponent[] = [\n { type: 'library', name: 'a', version: '1.0', purl: 'bad1' },\n { type: 'library', name: 'b', version: '2.0', purl: 'bad2' },\n ];\n\n const result = deserializeAll(components);\n expect(result.deps).toHaveLength(0);\n expect(result.errors).toHaveLength(2);\n });\n});\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }