@cyclonedx/cdxgen 12.1.5 → 12.2.1

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 (193) hide show
  1. package/README.md +51 -40
  2. package/bin/cdxgen.js +194 -97
  3. package/bin/evinse.js +4 -4
  4. package/bin/repl.js +1 -1
  5. package/bin/sign.js +102 -0
  6. package/bin/validate.js +233 -0
  7. package/bin/verify.js +69 -28
  8. package/data/queries.json +1 -1
  9. package/data/rules/ci-permissions.yaml +186 -0
  10. package/data/rules/dependency-sources.yaml +123 -0
  11. package/data/rules/package-integrity.yaml +135 -0
  12. package/data/rules/vscode-extensions.yaml +228 -0
  13. package/lib/cli/index.js +449 -429
  14. package/lib/cli/index.poku.js +117 -0
  15. package/lib/evinser/db.js +137 -0
  16. package/lib/{helpers → evinser}/db.poku.js +2 -6
  17. package/lib/evinser/evinser.js +2 -14
  18. package/lib/helpers/analyzer.js +606 -3
  19. package/lib/helpers/analyzer.poku.js +230 -0
  20. package/lib/helpers/bomSigner.js +312 -0
  21. package/lib/helpers/bomSigner.poku.js +156 -0
  22. package/lib/helpers/ciParsers/azurePipelines.js +295 -0
  23. package/lib/helpers/ciParsers/azurePipelines.poku.js +253 -0
  24. package/lib/helpers/ciParsers/circleCi.js +286 -0
  25. package/lib/helpers/ciParsers/circleCi.poku.js +230 -0
  26. package/lib/helpers/ciParsers/common.js +24 -0
  27. package/lib/helpers/ciParsers/githubActions.js +636 -0
  28. package/lib/helpers/ciParsers/githubActions.poku.js +802 -0
  29. package/lib/helpers/ciParsers/gitlabCi.js +213 -0
  30. package/lib/helpers/ciParsers/gitlabCi.poku.js +247 -0
  31. package/lib/helpers/ciParsers/jenkins.js +181 -0
  32. package/lib/helpers/ciParsers/jenkins.poku.js +197 -0
  33. package/lib/helpers/depsUtils.js +219 -0
  34. package/lib/helpers/depsUtils.poku.js +207 -0
  35. package/lib/helpers/display.js +426 -5
  36. package/lib/helpers/envcontext.js +18 -3
  37. package/lib/helpers/formulationParsers.js +351 -0
  38. package/lib/helpers/logger.js +14 -0
  39. package/lib/helpers/protobom.js +9 -9
  40. package/lib/helpers/pythonutils.js +9 -0
  41. package/lib/helpers/remote/dependency-track.js +84 -0
  42. package/lib/helpers/remote/dependency-track.poku.js +119 -0
  43. package/lib/helpers/table.js +384 -0
  44. package/lib/helpers/table.poku.js +186 -0
  45. package/lib/helpers/utils.js +865 -416
  46. package/lib/helpers/utils.poku.js +172 -265
  47. package/lib/helpers/versutils.js +202 -0
  48. package/lib/helpers/versutils.poku.js +315 -0
  49. package/lib/helpers/vsixutils.js +1061 -0
  50. package/lib/helpers/vsixutils.poku.js +2247 -0
  51. package/lib/managers/binary.js +19 -19
  52. package/lib/managers/docker.js +108 -1
  53. package/lib/managers/oci.js +10 -0
  54. package/lib/managers/piptree.js +3 -9
  55. package/lib/parsers/npmrc.js +17 -13
  56. package/lib/parsers/npmrc.poku.js +41 -5
  57. package/lib/server/openapi.yaml +34 -1
  58. package/lib/server/server.js +50 -13
  59. package/lib/server/server.poku.js +332 -144
  60. package/lib/stages/postgen/annotator.js +1 -1
  61. package/lib/stages/postgen/auditBom.js +196 -0
  62. package/lib/stages/postgen/auditBom.poku.js +378 -0
  63. package/lib/stages/postgen/postgen.js +54 -1
  64. package/lib/stages/postgen/postgen.poku.js +90 -1
  65. package/lib/stages/postgen/ruleEngine.js +369 -0
  66. package/lib/stages/pregen/envAudit.js +299 -0
  67. package/lib/stages/pregen/envAudit.poku.js +572 -0
  68. package/lib/stages/pregen/pregen.js +12 -8
  69. package/lib/{helpers/validator.js → validator/bomValidator.js} +107 -47
  70. package/lib/validator/complianceEngine.js +241 -0
  71. package/lib/validator/complianceEngine.poku.js +168 -0
  72. package/lib/validator/complianceRules.js +1610 -0
  73. package/lib/validator/complianceRules.poku.js +328 -0
  74. package/lib/validator/index.js +222 -0
  75. package/lib/validator/index.poku.js +144 -0
  76. package/lib/validator/reporters/annotations.js +121 -0
  77. package/lib/validator/reporters/console.js +149 -0
  78. package/lib/validator/reporters/index.js +41 -0
  79. package/lib/validator/reporters/json.js +37 -0
  80. package/lib/validator/reporters/sarif.js +184 -0
  81. package/lib/validator/reporters.poku.js +150 -0
  82. package/package.json +8 -9
  83. package/types/bin/sign.d.ts +3 -0
  84. package/types/bin/sign.d.ts.map +1 -0
  85. package/types/bin/validate.d.ts +3 -0
  86. package/types/bin/validate.d.ts.map +1 -0
  87. package/types/helpers/utils.d.ts +0 -1
  88. package/types/lib/cli/index.d.ts +49 -52
  89. package/types/lib/cli/index.d.ts.map +1 -1
  90. package/types/lib/evinser/db.d.ts +34 -0
  91. package/types/lib/evinser/db.d.ts.map +1 -0
  92. package/types/lib/evinser/evinser.d.ts +63 -16
  93. package/types/lib/evinser/evinser.d.ts.map +1 -1
  94. package/types/lib/helpers/analyzer.d.ts.map +1 -1
  95. package/types/lib/helpers/bomSigner.d.ts +27 -0
  96. package/types/lib/helpers/bomSigner.d.ts.map +1 -0
  97. package/types/lib/helpers/ciParsers/azurePipelines.d.ts +17 -0
  98. package/types/lib/helpers/ciParsers/azurePipelines.d.ts.map +1 -0
  99. package/types/lib/helpers/ciParsers/circleCi.d.ts +17 -0
  100. package/types/lib/helpers/ciParsers/circleCi.d.ts.map +1 -0
  101. package/types/lib/helpers/ciParsers/common.d.ts +11 -0
  102. package/types/lib/helpers/ciParsers/common.d.ts.map +1 -0
  103. package/types/lib/helpers/ciParsers/githubActions.d.ts +34 -0
  104. package/types/lib/helpers/ciParsers/githubActions.d.ts.map +1 -0
  105. package/types/lib/helpers/ciParsers/gitlabCi.d.ts +17 -0
  106. package/types/lib/helpers/ciParsers/gitlabCi.d.ts.map +1 -0
  107. package/types/lib/helpers/ciParsers/jenkins.d.ts +17 -0
  108. package/types/lib/helpers/ciParsers/jenkins.d.ts.map +1 -0
  109. package/types/lib/helpers/depsUtils.d.ts +21 -0
  110. package/types/lib/helpers/depsUtils.d.ts.map +1 -0
  111. package/types/lib/helpers/display.d.ts +111 -11
  112. package/types/lib/helpers/display.d.ts.map +1 -1
  113. package/types/lib/helpers/envcontext.d.ts +19 -7
  114. package/types/lib/helpers/envcontext.d.ts.map +1 -1
  115. package/types/lib/helpers/formulationParsers.d.ts +50 -0
  116. package/types/lib/helpers/formulationParsers.d.ts.map +1 -0
  117. package/types/lib/helpers/logger.d.ts +15 -1
  118. package/types/lib/helpers/logger.d.ts.map +1 -1
  119. package/types/lib/helpers/protobom.d.ts +2 -2
  120. package/types/lib/helpers/pythonutils.d.ts +10 -1
  121. package/types/lib/helpers/pythonutils.d.ts.map +1 -1
  122. package/types/lib/helpers/remote/dependency-track.d.ts +16 -0
  123. package/types/lib/helpers/remote/dependency-track.d.ts.map +1 -0
  124. package/types/lib/helpers/table.d.ts +6 -0
  125. package/types/lib/helpers/table.d.ts.map +1 -0
  126. package/types/lib/helpers/utils.d.ts +533 -128
  127. package/types/lib/helpers/utils.d.ts.map +1 -1
  128. package/types/lib/helpers/versutils.d.ts +8 -0
  129. package/types/lib/helpers/versutils.d.ts.map +1 -0
  130. package/types/lib/helpers/vsixutils.d.ts +130 -0
  131. package/types/lib/helpers/vsixutils.d.ts.map +1 -0
  132. package/types/lib/managers/docker.d.ts +12 -31
  133. package/types/lib/managers/docker.d.ts.map +1 -1
  134. package/types/lib/managers/oci.d.ts +11 -1
  135. package/types/lib/managers/oci.d.ts.map +1 -1
  136. package/types/lib/managers/piptree.d.ts.map +1 -1
  137. package/types/lib/parsers/npmrc.d.ts +4 -1
  138. package/types/lib/parsers/npmrc.d.ts.map +1 -1
  139. package/types/lib/server/server.d.ts +22 -2
  140. package/types/lib/server/server.d.ts.map +1 -1
  141. package/types/lib/stages/postgen/auditBom.d.ts +20 -0
  142. package/types/lib/stages/postgen/auditBom.d.ts.map +1 -0
  143. package/types/lib/stages/postgen/postgen.d.ts +8 -1
  144. package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
  145. package/types/lib/stages/postgen/ruleEngine.d.ts +18 -0
  146. package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -0
  147. package/types/lib/stages/pregen/envAudit.d.ts +8 -0
  148. package/types/lib/stages/pregen/envAudit.d.ts.map +1 -0
  149. package/types/lib/stages/pregen/pregen.d.ts.map +1 -1
  150. package/types/lib/{helpers/validator.d.ts → validator/bomValidator.d.ts} +1 -1
  151. package/types/lib/validator/bomValidator.d.ts.map +1 -0
  152. package/types/lib/validator/complianceEngine.d.ts +66 -0
  153. package/types/lib/validator/complianceEngine.d.ts.map +1 -0
  154. package/types/lib/validator/complianceRules.d.ts +70 -0
  155. package/types/lib/validator/complianceRules.d.ts.map +1 -0
  156. package/types/lib/validator/index.d.ts +70 -0
  157. package/types/lib/validator/index.d.ts.map +1 -0
  158. package/types/lib/validator/reporters/annotations.d.ts +31 -0
  159. package/types/lib/validator/reporters/annotations.d.ts.map +1 -0
  160. package/types/lib/validator/reporters/console.d.ts +30 -0
  161. package/types/lib/validator/reporters/console.d.ts.map +1 -0
  162. package/types/lib/validator/reporters/index.d.ts +21 -0
  163. package/types/lib/validator/reporters/index.d.ts.map +1 -0
  164. package/types/lib/validator/reporters/json.d.ts +11 -0
  165. package/types/lib/validator/reporters/json.d.ts.map +1 -0
  166. package/types/lib/validator/reporters/sarif.d.ts +16 -0
  167. package/types/lib/validator/reporters/sarif.d.ts.map +1 -0
  168. package/lib/helpers/db.js +0 -162
  169. package/lib/stages/pregen/env-audit.js +0 -34
  170. package/lib/stages/pregen/env-audit.poku.js +0 -290
  171. package/types/helpers/db.d.ts +0 -35
  172. package/types/helpers/db.d.ts.map +0 -1
  173. package/types/lib/helpers/db.d.ts +0 -35
  174. package/types/lib/helpers/db.d.ts.map +0 -1
  175. package/types/lib/helpers/validator.d.ts.map +0 -1
  176. package/types/lib/stages/pregen/env-audit.d.ts +0 -2
  177. package/types/lib/stages/pregen/env-audit.d.ts.map +0 -1
  178. package/types/managers/binary.d.ts +0 -37
  179. package/types/managers/binary.d.ts.map +0 -1
  180. package/types/managers/docker.d.ts +0 -56
  181. package/types/managers/docker.d.ts.map +0 -1
  182. package/types/managers/oci.d.ts +0 -2
  183. package/types/managers/oci.d.ts.map +0 -1
  184. package/types/managers/piptree.d.ts +0 -2
  185. package/types/managers/piptree.d.ts.map +0 -1
  186. package/types/server/server.d.ts +0 -34
  187. package/types/server/server.d.ts.map +0 -1
  188. package/types/stages/postgen/annotator.d.ts +0 -27
  189. package/types/stages/postgen/annotator.d.ts.map +0 -1
  190. package/types/stages/postgen/postgen.d.ts +0 -51
  191. package/types/stages/postgen/postgen.d.ts.map +0 -1
  192. package/types/stages/pregen/pregen.d.ts +0 -59
  193. package/types/stages/pregen/pregen.d.ts.map +0 -1
@@ -7,6 +7,7 @@ import { assert, describe, it, test } from "poku";
7
7
  import { parse } from "ssri";
8
8
  import { parse as loadYaml } from "yaml";
9
9
 
10
+ import { validateRefs } from "../validator/bomValidator.js";
10
11
  import {
11
12
  buildObjectForCocoaPod,
12
13
  buildObjectForGradleModule,
@@ -113,7 +114,6 @@ import {
113
114
  toGemModuleNames,
114
115
  yarnLockToIdentMap,
115
116
  } from "./utils.js";
116
- import { validateRefs } from "./validator.js";
117
117
 
118
118
  it("SSRI test", () => {
119
119
  // gopkg.lock hash
@@ -2596,12 +2596,15 @@ it("parse mix lock data", () => {
2596
2596
  it("parse github actions workflow data", () => {
2597
2597
  assert.deepStrictEqual(parseGitHubWorkflowData(null), []);
2598
2598
  let dep_list = parseGitHubWorkflowData("./.github/workflows/nodejs.yml");
2599
- assert.deepStrictEqual(dep_list.length, 8);
2599
+ assert.deepStrictEqual(dep_list.length, 13);
2600
2600
  assert.deepStrictEqual(dep_list[0], {
2601
+ "bom-ref":
2602
+ "pkg:github/actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd",
2603
+ type: "application",
2601
2604
  group: "actions",
2602
2605
  name: "checkout",
2603
- version: "6.0.2",
2604
- purl: "pkg:github/actions/checkout@6.0.2?commit=de0fac2e4500dabe0009e67214ff5f5447ce83dd",
2606
+ version: "de0fac2e4500dabe0009e67214ff5f5447ce83dd",
2607
+ purl: "pkg:github/actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd",
2605
2608
  properties: [
2606
2609
  {
2607
2610
  name: "SrcFile",
@@ -2611,6 +2614,10 @@ it("parse github actions workflow data", () => {
2611
2614
  name: "cdx:github:workflow:name",
2612
2615
  value: "Node CI",
2613
2616
  },
2617
+ {
2618
+ name: "cdx:github:workflow:file",
2619
+ value: "./.github/workflows/nodejs.yml",
2620
+ },
2614
2621
  {
2615
2622
  name: "cdx:github:job:name",
2616
2623
  value: "read-node-versions",
@@ -2631,277 +2638,40 @@ it("parse github actions workflow data", () => {
2631
2638
  name: "cdx:github:action:isShaPinned",
2632
2639
  value: "true",
2633
2640
  },
2634
- {
2635
- name: "cdx:github:workflow:concurrencyGroup",
2636
- value:
2637
- "${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}",
2638
- },
2639
2641
  {
2640
2642
  name: "cdx:actions:isOfficial",
2641
2643
  value: "true",
2642
2644
  },
2645
+ {
2646
+ name: "cdx:github:checkout:persistCredentials",
2647
+ value: "false",
2648
+ },
2643
2649
  {
2644
2650
  name: "cdx:github:workflow:triggers",
2645
2651
  value: "pull_request,push,workflow_dispatch",
2646
2652
  },
2647
2653
  ],
2654
+ scope: "required",
2648
2655
  evidence: {
2649
- identity: {
2650
- field: "purl",
2651
- confidence: 0.7,
2652
- methods: [
2653
- {
2654
- technique: "source-code-analysis",
2655
- confidence: 0.7,
2656
- value: "./.github/workflows/nodejs.yml",
2657
- },
2658
- ],
2659
- },
2660
- },
2661
- });
2662
- dep_list = parseGitHubWorkflowData("./test/data/github-actions-tj.yaml");
2663
- assert.deepStrictEqual(dep_list.length, 4);
2664
- assert.deepStrictEqual(dep_list, [
2665
- {
2666
- group: "pixel",
2667
- name: "steamcmd",
2668
- version: "1.2.7",
2669
- purl: "pkg:github/pixel/steamcmd@1.2.7?commit=foo",
2670
- properties: [
2671
- {
2672
- name: "SrcFile",
2673
- value: "./test/data/github-actions-tj.yaml",
2674
- },
2675
- {
2676
- name: "cdx:github:workflow:name",
2677
- value: "Testing",
2678
- },
2679
- {
2680
- name: "cdx:github:job:name",
2681
- value: "vulnerable-actions",
2682
- },
2683
- {
2684
- name: "cdx:github:job:runner",
2685
- value: "ubuntu-latest",
2686
- },
2687
- {
2688
- name: "cdx:github:action:uses",
2689
- value: "pixel/steamcmd@foo",
2690
- },
2691
- {
2692
- name: "cdx:github:action:versionPinningType",
2693
- value: "tag",
2694
- },
2695
- {
2696
- name: "cdx:github:action:isShaPinned",
2697
- value: "false",
2698
- },
2699
- {
2700
- name: "cdx:github:step:name",
2701
- value: "Test action 1",
2702
- },
2703
- {
2704
- name: "cdx:github:workflow:triggers",
2705
- value: "push,pull_request_target",
2706
- },
2707
- ],
2708
- evidence: {
2709
- identity: {
2710
- field: "purl",
2711
- confidence: 0.7,
2712
- methods: [
2713
- {
2714
- technique: "source-code-analysis",
2715
- confidence: 0.7,
2716
- value: "./test/data/github-actions-tj.yaml",
2717
- },
2718
- ],
2719
- },
2720
- },
2721
- },
2722
- {
2723
- group: "tj",
2724
- name: "branch",
2725
- version: "8.2.0",
2726
- purl: "pkg:github/tj/branch@8.2.0?commit=47dd",
2727
- properties: [
2728
- {
2729
- name: "SrcFile",
2730
- value: "./test/data/github-actions-tj.yaml",
2731
- },
2732
- {
2733
- name: "cdx:github:workflow:name",
2734
- value: "Testing",
2735
- },
2736
- {
2737
- name: "cdx:github:job:name",
2738
- value: "vulnerable-actions",
2739
- },
2740
- {
2741
- name: "cdx:github:job:runner",
2742
- value: "ubuntu-latest",
2743
- },
2744
- {
2745
- name: "cdx:github:action:uses",
2746
- value: "tj/branch@47dd",
2747
- },
2748
- {
2749
- name: "cdx:github:action:versionPinningType",
2750
- value: "tag",
2751
- },
2752
- {
2753
- name: "cdx:github:action:isShaPinned",
2754
- value: "false",
2755
- },
2756
- {
2757
- name: "cdx:github:step:name",
2758
- value: "Test action 2",
2759
- },
2760
- {
2761
- name: "cdx:github:workflow:triggers",
2762
- value: "push,pull_request_target",
2763
- },
2764
- ],
2765
- evidence: {
2766
- identity: {
2767
- field: "purl",
2768
- confidence: 0.7,
2769
- methods: [
2770
- {
2771
- technique: "source-code-analysis",
2772
- confidence: 0.7,
2773
- value: "./test/data/github-actions-tj.yaml",
2774
- },
2775
- ],
2776
- },
2777
- },
2778
- },
2779
- {
2780
- group: "tj",
2781
- name: "branch2",
2782
- version: "08",
2783
- purl: "pkg:github/tj/branch2@08?tag=v0.0.18",
2784
- properties: [
2785
- {
2786
- name: "SrcFile",
2787
- value: "./test/data/github-actions-tj.yaml",
2788
- },
2789
- {
2790
- name: "cdx:github:workflow:name",
2791
- value: "Testing",
2792
- },
2793
- {
2794
- name: "cdx:github:job:name",
2795
- value: "vulnerable-actions",
2796
- },
2797
- {
2798
- name: "cdx:github:job:runner",
2799
- value: "ubuntu-latest",
2800
- },
2656
+ identity: [
2801
2657
  {
2802
- name: "cdx:github:action:uses",
2803
- value: "tj/branch2@v0.0.18",
2804
- },
2805
- {
2806
- name: "cdx:github:action:versionPinningType",
2807
- value: "tag",
2808
- },
2809
- {
2810
- name: "cdx:github:action:isShaPinned",
2811
- value: "false",
2812
- },
2813
- {
2814
- name: "cdx:github:step:name",
2815
- value: "Test action 3",
2816
- },
2817
- {
2818
- name: "cdx:github:workflow:triggers",
2819
- value: "push,pull_request_target",
2820
- },
2821
- ],
2822
- evidence: {
2823
- identity: {
2824
2658
  field: "purl",
2825
- confidence: 0.7,
2659
+ confidence: 0.5,
2826
2660
  methods: [
2827
2661
  {
2828
2662
  technique: "source-code-analysis",
2829
- confidence: 0.7,
2830
- value: "./test/data/github-actions-tj.yaml",
2663
+ confidence: 0.5,
2664
+ value: "./.github/workflows/nodejs.yml",
2831
2665
  },
2832
2666
  ],
2833
2667
  },
2834
- },
2835
- },
2836
- {
2837
- group: "github/codeql-action",
2838
- name: "upload-sarif",
2839
- version: "3.30.3",
2840
- purl: "pkg:github/github/codeql-action/upload-sarif@3.30.3?commit=192325c86100d080feab897ff886c34abd4c83a3",
2841
- properties: [
2842
- {
2843
- name: "SrcFile",
2844
- value: "./test/data/github-actions-tj.yaml",
2845
- },
2846
- {
2847
- name: "cdx:github:workflow:name",
2848
- value: "Testing",
2849
- },
2850
- {
2851
- name: "cdx:github:job:name",
2852
- value: "vulnerable-actions",
2853
- },
2854
- {
2855
- name: "cdx:github:job:runner",
2856
- value: "ubuntu-latest",
2857
- },
2858
- {
2859
- name: "cdx:github:action:uses",
2860
- value:
2861
- "github/codeql-action/upload-sarif@192325c86100d080feab897ff886c34abd4c83a3",
2862
- },
2863
- {
2864
- name: "cdx:github:action:versionPinningType",
2865
- value: "sha",
2866
- },
2867
- {
2868
- name: "cdx:github:action:isShaPinned",
2869
- value: "true",
2870
- },
2871
- {
2872
- name: "cdx:github:step:name",
2873
- value: "Upload to code-scanning",
2874
- },
2875
- {
2876
- name: "cdx:actions:isOfficial",
2877
- value: "true",
2878
- },
2879
- {
2880
- name: "cdx:actions:isVerified",
2881
- value: "true",
2882
- },
2883
- {
2884
- name: "cdx:github:workflow:triggers",
2885
- value: "push,pull_request_target",
2886
- },
2887
2668
  ],
2888
- evidence: {
2889
- identity: {
2890
- field: "purl",
2891
- confidence: 0.7,
2892
- methods: [
2893
- {
2894
- technique: "source-code-analysis",
2895
- confidence: 0.7,
2896
- value: "./test/data/github-actions-tj.yaml",
2897
- },
2898
- ],
2899
- },
2900
- },
2901
2669
  },
2902
- ]);
2670
+ });
2671
+ dep_list = parseGitHubWorkflowData("./test/data/github-actions-tj.yaml");
2672
+ assert.deepStrictEqual(dep_list.length, 4);
2903
2673
  dep_list = parseGitHubWorkflowData("./.github/workflows/repotests.yml");
2904
- assert.deepStrictEqual(dep_list.length, 17);
2674
+ assert.deepStrictEqual(dep_list.length, 91);
2905
2675
  });
2906
2676
  // biome-ignore-end lint/suspicious/noTemplateCurlyInString: fp
2907
2677
 
@@ -3805,6 +3575,23 @@ it("get licenses", () => {
3805
3575
  },
3806
3576
  ]);
3807
3577
 
3578
+ licenses = getLicenses({
3579
+ license: [
3580
+ {
3581
+ type: "MIT",
3582
+ url: "https://github.com/harvesthq/chosen/blob/master/LICENSE.md",
3583
+ },
3584
+ ],
3585
+ });
3586
+ assert.deepStrictEqual(licenses, [
3587
+ {
3588
+ license: {
3589
+ id: "MIT",
3590
+ url: "https://github.com/harvesthq/chosen/blob/master/LICENSE.md",
3591
+ },
3592
+ },
3593
+ ]);
3594
+
3808
3595
  licenses = getLicenses({
3809
3596
  license: "GPL-2.0+",
3810
3597
  });
@@ -3907,6 +3694,30 @@ it("parsePkgLock v2", async () => {
3907
3694
  ],
3908
3695
  },
3909
3696
  });
3697
+ const devOnlyPkg = deps.find(
3698
+ (pkg) => pkg["bom-ref"] === "pkg:npm/@types/shelljs@0.8.11",
3699
+ );
3700
+ assert.ok(devOnlyPkg);
3701
+ assert.deepStrictEqual(devOnlyPkg.scope, "optional");
3702
+ assert.ok(
3703
+ devOnlyPkg.properties.some(
3704
+ (property) =>
3705
+ property.name === "cdx:npm:package:development" &&
3706
+ property.value === "true",
3707
+ ),
3708
+ );
3709
+ const devOptionalPkg = deps.find(
3710
+ (pkg) => pkg["bom-ref"] === "pkg:npm/@esbuild/android-arm@0.15.12",
3711
+ );
3712
+ assert.ok(devOptionalPkg);
3713
+ assert.deepStrictEqual(devOptionalPkg.scope, "optional");
3714
+ assert.ok(
3715
+ devOptionalPkg.properties.some(
3716
+ (property) =>
3717
+ property.name === "cdx:npm:package:development" &&
3718
+ property.value === "true",
3719
+ ),
3720
+ );
3910
3721
  assert.deepStrictEqual(parsedList.dependenciesList.length, 134);
3911
3722
  });
3912
3723
 
@@ -4095,10 +3906,8 @@ it("parsePnpmLock", async () => {
4095
3906
  type: "library",
4096
3907
  version: "7.16.7",
4097
3908
  properties: [
4098
- {
4099
- name: "SrcFile",
4100
- value: "./test/data/pnpm-lock.yaml",
4101
- },
3909
+ { name: "SrcFile", value: "./test/data/pnpm-lock.yaml" },
3910
+ { name: "cdx:npm:package:development", value: "true" },
4102
3911
  ],
4103
3912
  evidence: {
4104
3913
  identity: {
@@ -4200,7 +4009,10 @@ it("parsePnpmLock", async () => {
4200
4009
  type: "library",
4201
4010
  _integrity:
4202
4011
  "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
4203
- properties: [{ name: "SrcFile", value: "./test/data/pnpm-lock6.yaml" }],
4012
+ properties: [
4013
+ { name: "SrcFile", value: "./test/data/pnpm-lock6.yaml" },
4014
+ { name: "cdx:npm:package:development", value: "true" },
4015
+ ],
4204
4016
  evidence: {
4205
4017
  identity: {
4206
4018
  field: "purl",
@@ -4225,7 +4037,10 @@ it("parsePnpmLock", async () => {
4225
4037
  type: "library",
4226
4038
  _integrity:
4227
4039
  "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==",
4228
- properties: [{ name: "SrcFile", value: "./test/data/pnpm-lock6.yaml" }],
4040
+ properties: [
4041
+ { name: "SrcFile", value: "./test/data/pnpm-lock6.yaml" },
4042
+ { name: "cdx:npm:package:development", value: "true" },
4043
+ ],
4229
4044
  evidence: {
4230
4045
  identity: {
4231
4046
  field: "purl",
@@ -4253,7 +4068,10 @@ it("parsePnpmLock", async () => {
4253
4068
  type: "library",
4254
4069
  _integrity:
4255
4070
  "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
4256
- properties: [{ name: "SrcFile", value: "./test/data/pnpm-lock6a.yaml" }],
4071
+ properties: [
4072
+ { name: "SrcFile", value: "./test/data/pnpm-lock6a.yaml" },
4073
+ { name: "cdx:npm:package:development", value: "true" },
4074
+ ],
4257
4075
  evidence: {
4258
4076
  identity: {
4259
4077
  field: "purl",
@@ -4268,6 +4086,18 @@ it("parsePnpmLock", async () => {
4268
4086
  },
4269
4087
  },
4270
4088
  });
4089
+ const pnpmDevOptionalPkg = parsedList.pkgList.find(
4090
+ (pkg) => pkg["bom-ref"] === "pkg:npm/@cyclonedx/cdxgen-plugins-bin@1.0.5",
4091
+ );
4092
+ assert.ok(pnpmDevOptionalPkg);
4093
+ assert.deepStrictEqual(pnpmDevOptionalPkg.scope, "optional");
4094
+ assert.ok(
4095
+ pnpmDevOptionalPkg.properties.some(
4096
+ (property) =>
4097
+ property.name === "cdx:npm:package:development" &&
4098
+ property.value === "true",
4099
+ ),
4100
+ );
4271
4101
  // Test case to see if parsePnpmLock is finding all root deps
4272
4102
  const dummpyParent = {
4273
4103
  name: "rush",
@@ -4309,7 +4139,15 @@ it("parsePnpmLock", async () => {
4309
4139
  assert.deepStrictEqual(parsedList.pkgList.length, 1007);
4310
4140
  assert.deepStrictEqual(parsedList.dependenciesList.length, 1006);
4311
4141
  assert.deepStrictEqual(
4312
- parsedList.pkgList.filter((pkg) => !pkg.scope).length,
4142
+ parsedList.pkgList.filter(
4143
+ (pkg) =>
4144
+ !pkg.scope &&
4145
+ !pkg.properties?.some(
4146
+ (property) =>
4147
+ property.name === "cdx:npm:package:development" &&
4148
+ property.value === "true",
4149
+ ),
4150
+ ).length,
4313
4151
  0,
4314
4152
  );
4315
4153
  parsedList = await parsePnpmLock("./test/data/pnpm-lock9b.yaml", {
@@ -4319,7 +4157,15 @@ it("parsePnpmLock", async () => {
4319
4157
  assert.deepStrictEqual(parsedList.pkgList.length, 1366);
4320
4158
  assert.deepStrictEqual(parsedList.dependenciesList.length, 1353);
4321
4159
  assert.deepStrictEqual(
4322
- parsedList.pkgList.filter((pkg) => !pkg.scope).length,
4160
+ parsedList.pkgList.filter(
4161
+ (pkg) =>
4162
+ !pkg.scope &&
4163
+ !pkg.properties?.some(
4164
+ (property) =>
4165
+ property.name === "cdx:npm:package:development" &&
4166
+ property.value === "true",
4167
+ ),
4168
+ ).length,
4323
4169
  12,
4324
4170
  );
4325
4171
  parsedList = await parsePnpmLock("./test/data/pnpm-lock9c.yaml", {
@@ -4329,9 +4175,40 @@ it("parsePnpmLock", async () => {
4329
4175
  assert.deepStrictEqual(parsedList.pkgList.length, 461);
4330
4176
  assert.deepStrictEqual(parsedList.dependenciesList.length, 462);
4331
4177
  assert.deepStrictEqual(
4332
- parsedList.pkgList.filter((pkg) => !pkg.scope).length,
4178
+ parsedList.pkgList.filter(
4179
+ (pkg) =>
4180
+ !pkg.scope &&
4181
+ !pkg.properties?.some(
4182
+ (property) =>
4183
+ property.name === "cdx:npm:package:development" &&
4184
+ property.value === "true",
4185
+ ),
4186
+ ).length,
4333
4187
  3,
4334
4188
  );
4189
+ parsedList = await parsePnpmLock(
4190
+ "./test/data/pnpm-lock-dev-propagation.yaml",
4191
+ );
4192
+ assert.deepStrictEqual(parsedList.pkgList.length, 4);
4193
+ assert.deepStrictEqual(parsedList.dependenciesList.length, 4);
4194
+ assert.deepStrictEqual(
4195
+ parsedList.pkgList.filter(
4196
+ (pkg) =>
4197
+ pkg.scope === "optional" &&
4198
+ pkg.properties?.some(
4199
+ (property) =>
4200
+ property.name === "cdx:npm:package:development" &&
4201
+ property.value === "true",
4202
+ ),
4203
+ ).length,
4204
+ 4,
4205
+ );
4206
+ assert.ok(
4207
+ parsedList.pkgList.find((pkg) => pkg["bom-ref"] === "pkg:npm/gamma@1.0.0"),
4208
+ );
4209
+ assert.ok(
4210
+ parsedList.pkgList.find((pkg) => pkg["bom-ref"] === "pkg:npm/delta@1.0.0"),
4211
+ );
4335
4212
  parsedList = await parsePnpmLock(
4336
4213
  "./test/data/pnpm_locks/bytemd-pnpm-lock.yaml",
4337
4214
  );
@@ -4472,7 +4349,10 @@ it("pnpmMetadata with scoped packages", async () => {
4472
4349
  it("pnpmMetadata integration with parsePnpmLock", async () => {
4473
4350
  // Test that the integration works by parsing a real pnpm lock file
4474
4351
  const parsedList = await parsePnpmLock("./pnpm-lock.yaml");
4475
-
4352
+ const externalRefDistPackages = parsedList.pkgList.filter((pkg) =>
4353
+ pkg.externalReferences?.some((p) => p.type === "distribution"),
4354
+ );
4355
+ assert.ok(externalRefDistPackages.length > 0);
4476
4356
  // Check that some packages have been enhanced with LocalNodeModulesPath
4477
4357
  const enhancedPackages = parsedList.pkgList.filter((pkg) =>
4478
4358
  pkg.properties?.some((p) => p.name === "LocalNodeModulesPath"),
@@ -5694,6 +5574,33 @@ it("parseComposerLock", () => {
5694
5574
  ref: "pkg:composer/doctrine/annotations@v1.2.1",
5695
5575
  dependsOn: ["pkg:composer/doctrine/lexer@v1.0"],
5696
5576
  });
5577
+
5578
+ // Platform requirements (php, ext-*) must not appear in rootList
5579
+ const platformRootRequires = {
5580
+ php: "^7.1.3|^8",
5581
+ "ext-SimpleXML": "*",
5582
+ "ext-dom": "*",
5583
+ "amphp/amp": "^2.1",
5584
+ "amphp/byte-stream": "^1.5",
5585
+ };
5586
+ retMap = parseComposerLock(
5587
+ "./test/data/composer-2.lock",
5588
+ platformRootRequires,
5589
+ );
5590
+ assert.ok(
5591
+ !retMap.rootList.some((p) => p.name === "php"),
5592
+ "php must not be in rootList",
5593
+ );
5594
+ assert.ok(
5595
+ !retMap.rootList.some((p) => p.name?.startsWith("ext-")),
5596
+ "ext-* must not be in rootList",
5597
+ );
5598
+ // Regular packages that are in rootRequires should still be in rootList
5599
+ // Note: apkg.name is basename(pkg.name), so "amphp/amp" → name "amp"
5600
+ assert.ok(
5601
+ retMap.rootList.some((p) => p.name === "amp"),
5602
+ "amphp/amp should be in rootList",
5603
+ );
5697
5604
  });
5698
5605
 
5699
5606
  it("parseComposerJson", () => {