@cdxgen/cdxgen 13.6.0 → 13.7.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 (264) hide show
  1. package/README.md +15 -8
  2. package/bin/audit.js +7 -4
  3. package/bin/cdxgen.js +256 -37
  4. package/bin/convert.js +146 -22
  5. package/bin/evinse.js +25 -3
  6. package/bin/repl.js +47 -3
  7. package/bin/sign.js +211 -34
  8. package/bin/tracebom.js +18 -6
  9. package/bin/validate.js +18 -3
  10. package/bin/verify.js +113 -5
  11. package/data/behavior-taxonomy.schema.json +1491 -0
  12. package/data/cyclonedx-2.0-bundled.schema.json +18606 -5528
  13. package/data/cyclonedx-2.0-cryptography-defs.schema.json +857 -0
  14. package/data/pqc-migration.json +239 -0
  15. package/data/remediations.json +52 -0
  16. package/data/rules/cbom-security.yaml +4 -3
  17. package/data/rules/package-integrity.yaml +28 -0
  18. package/lib/audit/index.js +25 -3
  19. package/lib/cli/bomAssembly.js +80 -1
  20. package/lib/cli/cliOptions.js +121 -17
  21. package/lib/cli/index.js +609 -898
  22. package/lib/cli/jsBom.js +3 -0
  23. package/lib/cli/jvmBom.js +365 -40
  24. package/lib/cli/managedBom.js +19 -3
  25. package/lib/cli/nativeBom.js +10 -0
  26. package/lib/core/env.js +26 -0
  27. package/lib/core/fs.js +126 -3
  28. package/lib/core/globPatterns.js +218 -0
  29. package/lib/core/processTree.js +99 -12
  30. package/lib/core/projectConfig.js +332 -25
  31. package/lib/core/toolRegistry.js +15 -1
  32. package/lib/ecosystems/denoutils.js +2 -2
  33. package/lib/ecosystems/golem.js +3 -8
  34. package/lib/ecosystems/gradleutils.js +1082 -6
  35. package/lib/ecosystems/jsEvidence.js +90 -38
  36. package/lib/ecosystems/kosi.js +3 -5
  37. package/lib/ecosystems/npmVersionResolution.js +376 -0
  38. package/lib/ecosystems/parsers-python.js +89 -28
  39. package/lib/ecosystems/parsers-rust.js +117 -15
  40. package/lib/ecosystems/remote/huggingface.js +22 -0
  41. package/lib/ecosystems/rusi.js +2 -4
  42. package/lib/ecosystems/scalasem.js +2 -1
  43. package/lib/evinser/evinser.js +196 -34
  44. package/lib/evinser/scalasem.js +5 -1
  45. package/lib/helpers/agenticToolutils.js +112 -1
  46. package/lib/helpers/bomSigner.js +43 -9
  47. package/lib/helpers/jssSigner.js +1276 -0
  48. package/lib/inventory/agentBlueprint.js +193 -0
  49. package/lib/inventory/agentToolNames.js +145 -0
  50. package/lib/inventory/aiCollector.js +153 -7
  51. package/lib/inventory/aiInventory.js +44 -8
  52. package/lib/inventory/aiProviders.js +324 -0
  53. package/lib/inventory/bomUtils.js +8 -1
  54. package/lib/inventory/ciParsers/githubActionsLock.js +821 -0
  55. package/lib/inventory/citations.js +31 -2
  56. package/lib/inventory/communityAiConfigParser.js +978 -80
  57. package/lib/inventory/cyclonedx20.js +152 -0
  58. package/lib/inventory/cyclonedx20Common.js +286 -0
  59. package/lib/inventory/cyclonedx20Derived.js +159 -0
  60. package/lib/inventory/cyclonedx20Parties.js +552 -0
  61. package/lib/inventory/cyclonedx20Read.js +768 -0
  62. package/lib/inventory/cyclonedx20ReadCommon.js +374 -0
  63. package/lib/inventory/cyclonedx20ReadComponents.js +692 -0
  64. package/lib/inventory/cyclonedx20ReadContext.js +380 -0
  65. package/lib/inventory/cyclonedx20ReadEvidence.js +466 -0
  66. package/lib/inventory/cyclonedx20ReadSections.js +599 -0
  67. package/lib/inventory/cyclonedx20Render.js +766 -0
  68. package/lib/inventory/cyclonedx20RenderComponents.js +716 -0
  69. package/lib/inventory/cyclonedx20RenderDefinitions.js +405 -0
  70. package/lib/inventory/cyclonedx20RenderEvidence.js +726 -0
  71. package/lib/inventory/cyclonedx20RenderHardware.js +203 -0
  72. package/lib/inventory/cyclonedx20RenderPatents.js +174 -0
  73. package/lib/inventory/cyclonedx20RenderRefIds.js +314 -0
  74. package/lib/inventory/cyclonedx20RenderSections.js +499 -0
  75. package/lib/inventory/cyclonedx20Tables.js +594 -0
  76. package/lib/inventory/deps.js +106 -13
  77. package/lib/inventory/dosai.js +236 -1
  78. package/lib/inventory/dosaiParsers.js +3 -6
  79. package/lib/inventory/dotnetRuntime.js +164 -14
  80. package/lib/inventory/ecosystemFormulationParsers.js +979 -0
  81. package/lib/inventory/envcontext.js +132 -38
  82. package/lib/inventory/evidenceUtils.js +2 -1
  83. package/lib/inventory/formulationParsers.js +95 -13
  84. package/lib/inventory/hbom.js +45 -6
  85. package/lib/inventory/hbomLoader.js +166 -0
  86. package/lib/inventory/mcpConfigParser.js +5 -0
  87. package/lib/inventory/occurrenceKey.js +90 -0
  88. package/lib/inventory/pqcMigration.js +426 -0
  89. package/lib/inventory/rustFormulationParser.js +21 -10
  90. package/lib/inventory/source.js +65 -6
  91. package/lib/parsers/huggingfaceManifest.js +9 -1
  92. package/lib/parsers/huggingfaceUtils.js +18 -0
  93. package/lib/parsers/kiroPermissions.js +166 -0
  94. package/lib/server/server.js +36 -34
  95. package/lib/stages/postgen/postgen.js +41 -1
  96. package/lib/stages/postgen/specVersionCompat.js +76 -0
  97. package/lib/validator/bomValidator.js +8 -1
  98. package/lib/validator/complianceEngine.js +30 -3
  99. package/lib/validator/complianceRules.js +1416 -4
  100. package/lib/validator/generated/validate-2.0.mjs +57554 -13851
  101. package/lib/validator/index.js +48 -7
  102. package/lib/validator/reporters/json.js +6 -0
  103. package/package.json +9 -9
  104. package/types/bin/repl.d.ts.map +1 -1
  105. package/types/lib/audit/index.d.ts +6 -2
  106. package/types/lib/audit/index.d.ts.map +1 -1
  107. package/types/lib/cli/bomAssembly.d.ts +16 -0
  108. package/types/lib/cli/bomAssembly.d.ts.map +1 -1
  109. package/types/lib/cli/cliOptions.d.ts +6 -0
  110. package/types/lib/cli/cliOptions.d.ts.map +1 -1
  111. package/types/lib/cli/index.d.ts.map +1 -1
  112. package/types/lib/cli/jsBom.d.ts +2 -1
  113. package/types/lib/cli/jsBom.d.ts.map +1 -1
  114. package/types/lib/cli/jvmBom.d.ts +15 -0
  115. package/types/lib/cli/jvmBom.d.ts.map +1 -1
  116. package/types/lib/cli/managedBom.d.ts.map +1 -1
  117. package/types/lib/cli/nativeBom.d.ts.map +1 -1
  118. package/types/lib/core/boundedFile.d.ts +30 -0
  119. package/types/lib/core/boundedFile.d.ts.map +1 -1
  120. package/types/lib/core/env.d.ts +10 -0
  121. package/types/lib/core/env.d.ts.map +1 -1
  122. package/types/lib/core/fs.d.ts +4 -0
  123. package/types/lib/core/fs.d.ts.map +1 -1
  124. package/types/lib/core/globPatterns.d.ts +70 -0
  125. package/types/lib/core/globPatterns.d.ts.map +1 -0
  126. package/types/lib/core/paths.d.ts +9 -0
  127. package/types/lib/core/paths.d.ts.map +1 -1
  128. package/types/lib/core/processTree.d.ts +16 -5
  129. package/types/lib/core/processTree.d.ts.map +1 -1
  130. package/types/lib/core/projectConfig.d.ts +47 -8
  131. package/types/lib/core/projectConfig.d.ts.map +1 -1
  132. package/types/lib/core/toolRegistry.d.ts.map +1 -1
  133. package/types/lib/ecosystems/golem.d.ts.map +1 -1
  134. package/types/lib/ecosystems/gradleutils.d.ts +248 -8
  135. package/types/lib/ecosystems/gradleutils.d.ts.map +1 -1
  136. package/types/lib/ecosystems/jsEvidence.d.ts +14 -1
  137. package/types/lib/ecosystems/jsEvidence.d.ts.map +1 -1
  138. package/types/lib/ecosystems/kosi.d.ts.map +1 -1
  139. package/types/lib/ecosystems/npmVersionResolution.d.ts +119 -0
  140. package/types/lib/ecosystems/npmVersionResolution.d.ts.map +1 -0
  141. package/types/lib/ecosystems/parsers-python.d.ts.map +1 -1
  142. package/types/lib/ecosystems/parsers-rust.d.ts.map +1 -1
  143. package/types/lib/ecosystems/pythonutils.d.ts +1 -1
  144. package/types/lib/ecosystems/remote/huggingface.d.ts.map +1 -1
  145. package/types/lib/ecosystems/rusi.d.ts.map +1 -1
  146. package/types/lib/ecosystems/scalasem.d.ts +58 -16
  147. package/types/lib/ecosystems/scalasem.d.ts.map +1 -1
  148. package/types/lib/evinser/evinser.d.ts +61 -9
  149. package/types/lib/evinser/evinser.d.ts.map +1 -1
  150. package/types/lib/evinser/scalasem.d.ts.map +1 -1
  151. package/types/lib/helpers/agenticToolutils.d.ts +53 -19
  152. package/types/lib/helpers/agenticToolutils.d.ts.map +1 -1
  153. package/types/lib/helpers/bomSigner.d.ts +20 -3
  154. package/types/lib/helpers/bomSigner.d.ts.map +1 -1
  155. package/types/lib/helpers/jssSigner.d.ts +288 -0
  156. package/types/lib/helpers/jssSigner.d.ts.map +1 -0
  157. package/types/lib/helpers/vsixutils.d.ts +303 -19
  158. package/types/lib/helpers/vsixutils.d.ts.map +1 -1
  159. package/types/lib/inventory/agentBlueprint.d.ts +70 -0
  160. package/types/lib/inventory/agentBlueprint.d.ts.map +1 -0
  161. package/types/lib/inventory/agentToolNames.d.ts +51 -0
  162. package/types/lib/inventory/agentToolNames.d.ts.map +1 -0
  163. package/types/lib/inventory/aiCollector.d.ts.map +1 -1
  164. package/types/lib/inventory/aiInventory.d.ts.map +1 -1
  165. package/types/lib/inventory/aiProviders.d.ts +85 -0
  166. package/types/lib/inventory/aiProviders.d.ts.map +1 -0
  167. package/types/lib/inventory/bomUtils.d.ts.map +1 -1
  168. package/types/lib/inventory/ciParsers/githubActionsLock.d.ts +101 -0
  169. package/types/lib/inventory/ciParsers/githubActionsLock.d.ts.map +1 -0
  170. package/types/lib/inventory/citations.d.ts +5 -0
  171. package/types/lib/inventory/citations.d.ts.map +1 -1
  172. package/types/lib/inventory/communityAiConfigParser.d.ts.map +1 -1
  173. package/types/lib/inventory/cyclonedx20.d.ts +99 -0
  174. package/types/lib/inventory/cyclonedx20.d.ts.map +1 -0
  175. package/types/lib/inventory/cyclonedx20Common.d.ts +102 -0
  176. package/types/lib/inventory/cyclonedx20Common.d.ts.map +1 -0
  177. package/types/lib/inventory/cyclonedx20Derived.d.ts +74 -0
  178. package/types/lib/inventory/cyclonedx20Derived.d.ts.map +1 -0
  179. package/types/lib/inventory/cyclonedx20Parties.d.ts +91 -0
  180. package/types/lib/inventory/cyclonedx20Parties.d.ts.map +1 -0
  181. package/types/lib/inventory/cyclonedx20Read.d.ts +51 -0
  182. package/types/lib/inventory/cyclonedx20Read.d.ts.map +1 -0
  183. package/types/lib/inventory/cyclonedx20ReadCommon.d.ts +69 -0
  184. package/types/lib/inventory/cyclonedx20ReadCommon.d.ts.map +1 -0
  185. package/types/lib/inventory/cyclonedx20ReadComponents.d.ts +77 -0
  186. package/types/lib/inventory/cyclonedx20ReadComponents.d.ts.map +1 -0
  187. package/types/lib/inventory/cyclonedx20ReadContext.d.ts +118 -0
  188. package/types/lib/inventory/cyclonedx20ReadContext.d.ts.map +1 -0
  189. package/types/lib/inventory/cyclonedx20ReadEvidence.d.ts +40 -0
  190. package/types/lib/inventory/cyclonedx20ReadEvidence.d.ts.map +1 -0
  191. package/types/lib/inventory/cyclonedx20ReadSections.d.ts +45 -0
  192. package/types/lib/inventory/cyclonedx20ReadSections.d.ts.map +1 -0
  193. package/types/lib/inventory/cyclonedx20Render.d.ts +53 -0
  194. package/types/lib/inventory/cyclonedx20Render.d.ts.map +1 -0
  195. package/types/lib/inventory/cyclonedx20RenderComponents.d.ts +73 -0
  196. package/types/lib/inventory/cyclonedx20RenderComponents.d.ts.map +1 -0
  197. package/types/lib/inventory/cyclonedx20RenderDefinitions.d.ts +29 -0
  198. package/types/lib/inventory/cyclonedx20RenderDefinitions.d.ts.map +1 -0
  199. package/types/lib/inventory/cyclonedx20RenderEvidence.d.ts +110 -0
  200. package/types/lib/inventory/cyclonedx20RenderEvidence.d.ts.map +1 -0
  201. package/types/lib/inventory/cyclonedx20RenderHardware.d.ts +42 -0
  202. package/types/lib/inventory/cyclonedx20RenderHardware.d.ts.map +1 -0
  203. package/types/lib/inventory/cyclonedx20RenderPatents.d.ts +26 -0
  204. package/types/lib/inventory/cyclonedx20RenderPatents.d.ts.map +1 -0
  205. package/types/lib/inventory/cyclonedx20RenderRefIds.d.ts +55 -0
  206. package/types/lib/inventory/cyclonedx20RenderRefIds.d.ts.map +1 -0
  207. package/types/lib/inventory/cyclonedx20RenderSections.d.ts +45 -0
  208. package/types/lib/inventory/cyclonedx20RenderSections.d.ts.map +1 -0
  209. package/types/lib/inventory/cyclonedx20Tables.d.ts +134 -0
  210. package/types/lib/inventory/cyclonedx20Tables.d.ts.map +1 -0
  211. package/types/lib/inventory/deps.d.ts +35 -2
  212. package/types/lib/inventory/deps.d.ts.map +1 -1
  213. package/types/lib/inventory/dosai.d.ts +19 -0
  214. package/types/lib/inventory/dosai.d.ts.map +1 -1
  215. package/types/lib/inventory/dosaiParsers.d.ts.map +1 -1
  216. package/types/lib/inventory/dotnetRuntime.d.ts +51 -4
  217. package/types/lib/inventory/dotnetRuntime.d.ts.map +1 -1
  218. package/types/lib/inventory/ecosystemFormulationParsers.d.ts +73 -0
  219. package/types/lib/inventory/ecosystemFormulationParsers.d.ts.map +1 -0
  220. package/types/lib/inventory/envcontext.d.ts +22 -6
  221. package/types/lib/inventory/envcontext.d.ts.map +1 -1
  222. package/types/lib/inventory/evidenceUtils.d.ts.map +1 -1
  223. package/types/lib/inventory/formulationParsers.d.ts.map +1 -1
  224. package/types/lib/inventory/hbom.d.ts +11 -0
  225. package/types/lib/inventory/hbom.d.ts.map +1 -1
  226. package/types/lib/inventory/hbomLoader.d.ts +54 -0
  227. package/types/lib/inventory/hbomLoader.d.ts.map +1 -1
  228. package/types/lib/inventory/jvmLocalRepos.d.ts +5 -1
  229. package/types/lib/inventory/jvmLocalRepos.d.ts.map +1 -1
  230. package/types/lib/inventory/mcpConfigParser.d.ts.map +1 -1
  231. package/types/lib/inventory/occurrenceKey.d.ts +52 -0
  232. package/types/lib/inventory/occurrenceKey.d.ts.map +1 -0
  233. package/types/lib/inventory/pqcMigration.d.ts +84 -0
  234. package/types/lib/inventory/pqcMigration.d.ts.map +1 -0
  235. package/types/lib/inventory/rustFormulationParser.d.ts +7 -2
  236. package/types/lib/inventory/rustFormulationParser.d.ts.map +1 -1
  237. package/types/lib/inventory/scalaCoords.d.ts.map +1 -1
  238. package/types/lib/inventory/scalaDedupe.d.ts +43 -0
  239. package/types/lib/inventory/scalaDedupe.d.ts.map +1 -0
  240. package/types/lib/inventory/source.d.ts +15 -0
  241. package/types/lib/inventory/source.d.ts.map +1 -1
  242. package/types/lib/parsers/huggingfaceManifest.d.ts +10 -1
  243. package/types/lib/parsers/huggingfaceManifest.d.ts.map +1 -1
  244. package/types/lib/parsers/huggingfaceUtils.d.ts +12 -0
  245. package/types/lib/parsers/huggingfaceUtils.d.ts.map +1 -1
  246. package/types/lib/parsers/kiroPermissions.d.ts +62 -0
  247. package/types/lib/parsers/kiroPermissions.d.ts.map +1 -0
  248. package/types/lib/parsers/vscodeExtensionId.d.ts +48 -0
  249. package/types/lib/parsers/vscodeExtensionId.d.ts.map +1 -0
  250. package/types/lib/server/server.d.ts.map +1 -1
  251. package/types/lib/stages/postgen/postgen.d.ts +7 -0
  252. package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
  253. package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -1
  254. package/types/lib/stages/postgen/specVersionCompat.d.ts +25 -0
  255. package/types/lib/stages/postgen/specVersionCompat.d.ts.map +1 -1
  256. package/types/lib/validator/bomValidator.d.ts +5 -1
  257. package/types/lib/validator/bomValidator.d.ts.map +1 -1
  258. package/types/lib/validator/complianceEngine.d.ts +4 -4
  259. package/types/lib/validator/complianceEngine.d.ts.map +1 -1
  260. package/types/lib/validator/complianceRules.d.ts +14 -2
  261. package/types/lib/validator/complianceRules.d.ts.map +1 -1
  262. package/types/lib/validator/index.d.ts +10 -0
  263. package/types/lib/validator/index.d.ts.map +1 -1
  264. package/types/lib/validator/reporters/json.d.ts.map +1 -1
@@ -0,0 +1,374 @@
1
+ /**
2
+ * Reader converters for the CycloneDX 2.0 common objects
3
+ * (#/$defs/cyclonedx-common-2.0, #/$defs/cyclonedx-license-2.0,
4
+ * #/$defs/cyclonedx-release-notes-2.0) back to their 1.x shapes. Each frozen
5
+ * spec is the allowlist of the members 1.x carries; anything else is a loss.
6
+ */
7
+
8
+ import {
9
+ clone,
10
+ isNonEmptyString,
11
+ isObjectRecord,
12
+ } from "./cyclonedx20Common.js";
13
+ import {
14
+ addLoss,
15
+ jsonPointer,
16
+ listOf,
17
+ objectOf,
18
+ reverseList,
19
+ reverseObject,
20
+ } from "./cyclonedx20ReadContext.js";
21
+ import { EXTERNAL_REFERENCE_TYPES_1X } from "./cyclonedx20Tables.js";
22
+
23
+ const HASH_SPEC = Object.freeze({ alg: true, content: true });
24
+
25
+ /** hash (#/$defs/cyclonedx-common-2.0/$defs/hash) → 1.x hash. */
26
+ export function reverseHash(ctx, value, pointer) {
27
+ return reverseObject(ctx, "hash", value, pointer, HASH_SPEC);
28
+ }
29
+
30
+ /** A list of hashes. */
31
+ export const HASHES_RULE = listOf(reverseHash);
32
+
33
+ const PROPERTY_SPEC = Object.freeze({ name: true, value: true });
34
+
35
+ /** property (#/$defs/cyclonedx-common-2.0/$defs/property) → 1.x property. */
36
+ export function reverseProperty(ctx, value, pointer) {
37
+ return reverseObject(ctx, "property", value, pointer, PROPERTY_SPEC);
38
+ }
39
+
40
+ /** A list of properties. */
41
+ export const PROPERTIES_RULE = listOf(reverseProperty);
42
+
43
+ /**
44
+ * externalReference type: 2.0 adds types 1.7 does not list; those become
45
+ * `other` and are reported.
46
+ */
47
+ function reverseExternalReferenceType(ctx, value, pointer) {
48
+ if (EXTERNAL_REFERENCE_TYPES_1X.has(value)) {
49
+ return value;
50
+ }
51
+ addLoss(
52
+ ctx,
53
+ pointer,
54
+ `externalReference.type '${value}' is not a 1.x type; written as 'other'`,
55
+ );
56
+ return "other";
57
+ }
58
+
59
+ const EXTERNAL_REFERENCE_SPEC = Object.freeze({
60
+ url: true,
61
+ comment: true,
62
+ type: Object.freeze({ convert: reverseExternalReferenceType }),
63
+ hashes: HASHES_RULE,
64
+ properties: PROPERTIES_RULE,
65
+ });
66
+
67
+ /** externalReference → 1.x externalReference. */
68
+ export function reverseExternalReference(ctx, value, pointer) {
69
+ return reverseObject(
70
+ ctx,
71
+ "externalReference",
72
+ value,
73
+ pointer,
74
+ EXTERNAL_REFERENCE_SPEC,
75
+ );
76
+ }
77
+
78
+ /** A list of external references. */
79
+ export const EXTERNAL_REFERENCES_RULE = listOf(reverseExternalReference);
80
+
81
+ const ATTACHMENT_SPEC = Object.freeze({
82
+ mediaType: "contentType",
83
+ encoding: true,
84
+ content: true,
85
+ });
86
+
87
+ /** attachment: `mediaType` is the 1.x `contentType`. */
88
+ export function reverseAttachment(ctx, value, pointer) {
89
+ return reverseObject(ctx, "attachment", value, pointer, ATTACHMENT_SPEC);
90
+ }
91
+
92
+ /** An attachment-valued member. */
93
+ export const ATTACHMENT_RULE = Object.freeze({ convert: reverseAttachment });
94
+
95
+ const ADDRESS_SPEC = Object.freeze({
96
+ refId: "bom-ref",
97
+ country: true,
98
+ region: true,
99
+ locality: true,
100
+ postOfficeBoxNumber: true,
101
+ postalCode: true,
102
+ streetAddress: true,
103
+ });
104
+
105
+ /** postalAddress (common or party) → 1.x postalAddress. */
106
+ export function reverseAddress(ctx, value, pointer) {
107
+ return reverseObject(ctx, "postalAddress", value, pointer, ADDRESS_SPEC);
108
+ }
109
+
110
+ const CONTACT_SPEC = Object.freeze({
111
+ refId: "bom-ref",
112
+ name: true,
113
+ email: true,
114
+ phone: true,
115
+ });
116
+
117
+ /** organizationalContact → 1.x organizationalContact. */
118
+ export function reverseContact(ctx, value, pointer) {
119
+ return reverseObject(
120
+ ctx,
121
+ "organizationalContact",
122
+ value,
123
+ pointer,
124
+ CONTACT_SPEC,
125
+ );
126
+ }
127
+
128
+ const ENTITY_SPEC = Object.freeze({
129
+ refId: "bom-ref",
130
+ name: true,
131
+ url: true,
132
+ address: Object.freeze({ convert: reverseAddress }),
133
+ contact: listOf(reverseContact),
134
+ });
135
+
136
+ /** organizationalEntity (common) → 1.x organizationalEntity. */
137
+ export function reverseEntity(ctx, value, pointer) {
138
+ return reverseObject(
139
+ ctx,
140
+ "organizationalEntity",
141
+ value,
142
+ pointer,
143
+ ENTITY_SPEC,
144
+ );
145
+ }
146
+
147
+ const LICENSING_PARTY_SPEC = Object.freeze({
148
+ organization: Object.freeze({ convert: reverseEntity }),
149
+ individual: Object.freeze({ convert: reverseContact }),
150
+ });
151
+
152
+ const LICENSING_SPEC = Object.freeze({
153
+ altIds: true,
154
+ licensor: objectOf("licensing.licensor", LICENSING_PARTY_SPEC),
155
+ licensee: objectOf("licensing.licensee", LICENSING_PARTY_SPEC),
156
+ purchaser: objectOf("licensing.purchaser", LICENSING_PARTY_SPEC),
157
+ purchaseOrder: true,
158
+ licenseTypes: true,
159
+ lastRenewal: true,
160
+ expiration: true,
161
+ });
162
+
163
+ const LICENSE_SPEC = Object.freeze({
164
+ refId: "bom-ref",
165
+ id: true,
166
+ name: true,
167
+ acknowledgement: true,
168
+ text: ATTACHMENT_RULE,
169
+ url: true,
170
+ licensing: objectOf("licensing", LICENSING_SPEC),
171
+ properties: PROPERTIES_RULE,
172
+ });
173
+
174
+ const EXPRESSION_DETAIL_SPEC = Object.freeze({
175
+ licenseIdentifier: true,
176
+ refId: "bom-ref",
177
+ text: ATTACHMENT_RULE,
178
+ url: true,
179
+ });
180
+
181
+ const EXPRESSION_SPEC = Object.freeze({
182
+ expression: true,
183
+ expressionDetails: listOf((ctx, value, pointer) =>
184
+ reverseObject(
185
+ ctx,
186
+ "expressionDetail",
187
+ value,
188
+ pointer,
189
+ EXPRESSION_DETAIL_SPEC,
190
+ ),
191
+ ),
192
+ acknowledgement: true,
193
+ refId: "bom-ref",
194
+ licensing: objectOf("licensing", LICENSING_SPEC),
195
+ properties: PROPERTIES_RULE,
196
+ });
197
+
198
+ const LICENSE_CHOICE_SPEC = Object.freeze({
199
+ license: objectOf("license", LICENSE_SPEC),
200
+ });
201
+
202
+ /**
203
+ * One licenseChoice entry. A licenseReference (`{ref}`) resolves against
204
+ * definitions.licenses; 1.x has no license references, so the declaration
205
+ * is inlined and the reference itself reported.
206
+ */
207
+ export function reverseLicenseChoice(ctx, value, pointer) {
208
+ if (!isObjectRecord(value)) {
209
+ addLoss(ctx, pointer, "license entry is not an object");
210
+ return undefined;
211
+ }
212
+ if (typeof value.ref === "string") {
213
+ const declared = ctx.licenseIndex.get(value.ref)?.entry;
214
+ addLoss(
215
+ ctx,
216
+ jsonPointer(pointer, "ref"),
217
+ declared
218
+ ? "license reference has no 1.x form; the declaration is inlined"
219
+ : `license reference '${value.ref}' could not be resolved`,
220
+ );
221
+ if (!declared) {
222
+ return undefined;
223
+ }
224
+ // The inlined copy drops the declaration's refId: it may be inlined in
225
+ // several places, and a 1.x bom-ref must be unique.
226
+ const declaration = clone(declared);
227
+ delete declaration.refId;
228
+ if (isObjectRecord(declaration.license)) {
229
+ delete declaration.license.refId;
230
+ }
231
+ return reverseLicenseChoice(
232
+ ctx,
233
+ declaration,
234
+ ctx.licenseIndex.get(value.ref).pointer,
235
+ );
236
+ }
237
+ if (value.license !== undefined) {
238
+ return reverseObject(ctx, "license", value, pointer, LICENSE_CHOICE_SPEC);
239
+ }
240
+ return reverseObject(
241
+ ctx,
242
+ "licenseExpression",
243
+ value,
244
+ pointer,
245
+ EXPRESSION_SPEC,
246
+ );
247
+ }
248
+
249
+ /** A licenses member. */
250
+ export const LICENSES_RULE = listOf(reverseLicenseChoice);
251
+
252
+ /**
253
+ * Issues a patch or release resolves. 1.x lists issues only; a reference to a
254
+ * weakness, vulnerability or requirement has no 1.x form.
255
+ */
256
+ export const RESOLVES_RULE = listOf((ctx, value, pointer) => {
257
+ if (isObjectRecord(value) && typeof value.ref === "string") {
258
+ addLoss(ctx, pointer, "a resolved reference has no 1.x form");
259
+ return undefined;
260
+ }
261
+ return clone(value);
262
+ });
263
+
264
+ const NOTE_SPEC = Object.freeze({ locale: true, text: ATTACHMENT_RULE });
265
+
266
+ const RELEASE_NOTES_SPEC = Object.freeze({
267
+ type: true,
268
+ title: true,
269
+ featuredImage: true,
270
+ socialImage: true,
271
+ description: true,
272
+ timestamp: true,
273
+ aliases: true,
274
+ tags: true,
275
+ resolves: RESOLVES_RULE,
276
+ notes: listOf((ctx, value, pointer) =>
277
+ reverseObject(ctx, "note", value, pointer, NOTE_SPEC),
278
+ ),
279
+ properties: PROPERTIES_RULE,
280
+ });
281
+
282
+ /**
283
+ * releaseNotes, inline or a releaseNotesReference resolved against
284
+ * definitions.releaseNotes (1.x has no reference form).
285
+ */
286
+ export function reverseReleaseNotes(ctx, value, pointer) {
287
+ if (isObjectRecord(value) && typeof value.ref === "string") {
288
+ const notes = Array.isArray(ctx.doc.definitions?.releaseNotes)
289
+ ? ctx.doc.definitions.releaseNotes
290
+ : [];
291
+ const index = notes.findIndex(
292
+ (entry) => isObjectRecord(entry) && entry.refId === value.ref,
293
+ );
294
+ const declared = index >= 0 ? notes[index] : undefined;
295
+ addLoss(
296
+ ctx,
297
+ jsonPointer(pointer, "ref"),
298
+ declared
299
+ ? "release notes reference has no 1.x form; the notes are inlined"
300
+ : `release notes reference '${value.ref}' could not be resolved`,
301
+ );
302
+ return declared
303
+ ? reverseObject(
304
+ ctx,
305
+ "releaseNotes",
306
+ declared,
307
+ jsonPointer("/definitions/releaseNotes", index),
308
+ RELEASE_NOTES_SPEC,
309
+ )
310
+ : undefined;
311
+ }
312
+ return reverseObject(ctx, "releaseNotes", value, pointer, RELEASE_NOTES_SPEC);
313
+ }
314
+
315
+ /**
316
+ * patentAssertions: the 2.0 asserter is a party reference string or party
317
+ * object; 1.x takes a refLink string, an organizationalEntity or a contact.
318
+ */
319
+ function reversePatentAsserter(ctx, value, pointer) {
320
+ if (isNonEmptyString(value)) {
321
+ return value;
322
+ }
323
+ if (isObjectRecord(value)) {
324
+ // organizationalEntity and organizationalContact are both allowed; the
325
+ // members say which one this is.
326
+ const isContact =
327
+ value.email !== undefined ||
328
+ (value.phone !== undefined &&
329
+ value.contact === undefined &&
330
+ value.url === undefined &&
331
+ value.address === undefined);
332
+ return isContact
333
+ ? reverseContact(ctx, value, pointer)
334
+ : reverseEntity(ctx, value, pointer);
335
+ }
336
+ addLoss(ctx, pointer, "patentAssertion.asserter has no 1.x form");
337
+ return undefined;
338
+ }
339
+
340
+ const PATENT_ASSERTION_SPEC = Object.freeze({
341
+ refId: "bom-ref",
342
+ assertionType: true,
343
+ patentRefs: Object.freeze({
344
+ convert: (ctx, value, pointer) =>
345
+ reverseList(ctx, value, pointer, (_ctx, ref, refPointer) => {
346
+ if (isNonEmptyString(ref)) {
347
+ return ref;
348
+ }
349
+ if (isNonEmptyString(ref?.ref)) {
350
+ return ref.ref;
351
+ }
352
+ addLoss(ctx, refPointer, "patent reference has no 1.x form");
353
+ return undefined;
354
+ }),
355
+ }),
356
+ asserter: Object.freeze({ convert: reversePatentAsserter }),
357
+ notes: true,
358
+ });
359
+
360
+ /** A patentAssertions member; 1.x requires `asserter` and `assertionType`. */
361
+ export const PATENT_ASSERTIONS_RULE = listOf((ctx, value, pointer) => {
362
+ const assertion = reverseObject(
363
+ ctx,
364
+ "patentAssertion",
365
+ value,
366
+ pointer,
367
+ PATENT_ASSERTION_SPEC,
368
+ );
369
+ if (assertion && assertion.asserter === undefined) {
370
+ addLoss(ctx, pointer, "a 1.x patent assertion needs an asserter; dropped");
371
+ return undefined;
372
+ }
373
+ return assertion;
374
+ });