@mitre/hdf-utilities 3.4.3 → 3.5.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.
package/README.md CHANGED
@@ -69,22 +69,22 @@ Generate and verify cryptographic hashes for data integrity:
69
69
  ```typescript
70
70
  import { sha256, sha512, generateHash, hashObject, verifyHash } from '@mitre/hdf-utilities';
71
71
 
72
- // Quick SHA-256 hash
73
- const hash = sha256('content to hash');
72
+ // Quick SHA-256 hash (hash functions are async)
73
+ const hash = await sha256('content to hash');
74
74
  console.log(hash); // hex-encoded hash
75
75
 
76
76
  // Hash with custom options
77
- const customHash = generateHash('data', {
77
+ const customHash = await generateHash('data', {
78
78
  algorithm: 'sha512',
79
79
  encoding: 'base64'
80
80
  });
81
81
 
82
82
  // Hash JavaScript objects (deterministic JSON serialization)
83
83
  const baseline = { name: 'My Baseline', version: '1.0' };
84
- const objectHash = hashObject(baseline, { algorithm: 'sha256' });
84
+ const objectHash = await hashObject(baseline, { algorithm: 'sha256' });
85
85
 
86
86
  // Verify data integrity
87
- const isValid = verifyHash('original data', hash, { algorithm: 'sha256' });
87
+ const isValid = await verifyHash('original data', hash, { algorithm: 'sha256' });
88
88
  if (!isValid) {
89
89
  console.error('Data integrity check failed!');
90
90
  }
@@ -229,42 +229,42 @@ Check if string can be parsed as JSON.
229
229
 
230
230
  ### Hash Utilities
231
231
 
232
- #### `sha256(data: string): string`
232
+ #### `sha256(data: string): Promise<string>`
233
233
 
234
234
  Generate SHA-256 hash (hex-encoded).
235
235
 
236
236
  - **Parameters:**
237
237
  - `data` - String to hash
238
- - **Returns:** Hex-encoded hash string
238
+ - **Returns:** Promise resolving to a hex-encoded hash string
239
239
 
240
- #### `sha512(data: string): string`
240
+ #### `sha512(data: string): Promise<string>`
241
241
 
242
242
  Generate SHA-512 hash (hex-encoded).
243
243
 
244
244
  - **Parameters:**
245
245
  - `data` - String to hash
246
- - **Returns:** Hex-encoded hash string
246
+ - **Returns:** Promise resolving to a hex-encoded hash string
247
247
 
248
- #### `generateHash(data: string, options?: HashOptions): string`
248
+ #### `generateHash(data: string, options?: HashOptions): Promise<string>`
249
249
 
250
250
  Generate hash with custom algorithm and encoding.
251
251
 
252
252
  - **Parameters:**
253
253
  - `data` - String to hash
254
254
  - `options.algorithm` - Hash algorithm: `'sha256'` | `'sha512'` (default: `'sha256'`)
255
- - `options.encoding` - Output encoding: `'hex'` | `'base64'` | `'base64url'` (default: `'hex'`)
256
- - **Returns:** Encoded hash string
255
+ - `options.encoding` - Output encoding: `'hex'` | `'base64'` (default: `'hex'`)
256
+ - **Returns:** Promise resolving to the encoded hash string
257
257
 
258
- #### `hashObject(obj: unknown, options?: HashOptions): string`
258
+ #### `hashObject(obj: unknown, options?: HashOptions): Promise<string>`
259
259
 
260
260
  Generate deterministic hash of JavaScript object.
261
261
 
262
262
  - **Parameters:**
263
263
  - `obj` - Object to hash (will be JSON-stringified)
264
264
  - `options` - Same as `generateHash`
265
- - **Returns:** Hash of serialized object
265
+ - **Returns:** Promise resolving to the hash of the serialized object
266
266
 
267
- #### `verifyHash(data: string, expectedHash: string, options?: HashOptions): boolean`
267
+ #### `verifyHash(data: string, expectedHash: string, options?: HashOptions): Promise<boolean>`
268
268
 
269
269
  Verify data matches expected hash.
270
270
 
@@ -272,7 +272,7 @@ Verify data matches expected hash.
272
272
  - `data` - Original data to verify
273
273
  - `expectedHash` - Expected hash value
274
274
  - `options` - Same hash options used during generation
275
- - **Returns:** `true` if hash matches, `false` otherwise
275
+ - **Returns:** Promise resolving to `true` if the hash matches, `false` otherwise
276
276
 
277
277
  ### XML Utilities
278
278
 
package/dist/index.d.ts CHANGED
@@ -28,6 +28,15 @@ import { formatTimestamp, formatTimestampSeconds, normalizeHdfTimestamps, parseT
28
28
  declare function severityToImpact(severity: null): null;
29
29
  declare function severityToImpact(severity: string): number;
30
30
  declare function severityToImpact(severity: string | null): number | null;
31
+ /**
32
+ * Round an HDF impact value to 2 decimal places — its canonical precision —
33
+ * eliminating the representation noise that binary float division leaves behind
34
+ * (e.g. 9.8 / 10 = 0.9800000000000001). Impact is defined on 0.0–1.0 with a
35
+ * natural 0.01 grid (a 1-decimal CVSS score / 10), so this is lossless in
36
+ * intent. Use it wherever impact is COMPUTED (divided or otherwise
37
+ * arithmetically derived), not when assigned from a literal band.
38
+ */
39
+ declare function roundImpact(x: number): number;
31
40
  /**
32
41
  * Map an impact score to a severity string.
33
42
  *
@@ -56,6 +65,80 @@ declare function impactToSeverity(impact: number | null): string | null;
56
65
  */
57
66
  declare function cvssScoreToSeverity(score: number): 'none' | 'low' | 'medium' | 'high' | 'critical';
58
67
  //#endregion
68
+ //#region src/status/index.d.ts
69
+ /**
70
+ * Canonical HDF result-status ordering and effective-status computation.
71
+ *
72
+ * This is the single source of truth for worst-wins roll-up and
73
+ * effective-status selection across hdf-libs (mirrored in Go as
74
+ * hdf-utilities/go status.go). The precedence rules are published in
75
+ * site/docs/architecture/status-determination.md; do not re-implement them.
76
+ */
77
+ /** Canonical worst-wins ordering, worst first. */
78
+ declare const STATUS_SEVERITY_ORDER: readonly string[];
79
+ /** Severity rank of a status: higher = worse. Unknown statuses rank -1. */
80
+ declare function statusRank(status: string): number;
81
+ /**
82
+ * Rolls a list of result statuses up to the worst one. An empty list (or a
83
+ * list of only unknown statuses) rolls up to "notReviewed".
84
+ */
85
+ declare function worstStatus(statuses: readonly string[]): string;
86
+ /**
87
+ * Neutral shape of a status override for effective-status computation.
88
+ * Callers map their concrete types (schema objects or raw JSON) onto it.
89
+ */
90
+ interface StatusOverrideInput {
91
+ /** Empty/undefined means the override carries no status and never governs. */
92
+ status?: string;
93
+ /** RFC3339 timestamp; undefined sorts earliest. */
94
+ appliedAt?: string;
95
+ /** RFC3339 timestamp; undefined means the override never expires. */
96
+ expiresAt?: string;
97
+ }
98
+ /**
99
+ * Selects the override that governs a requirement: the most recently applied
100
+ * (by appliedAt) non-expired override that carries a status — matching the
101
+ * schema's definition of disposition ("the most recent non-expired
102
+ * override"). Returns undefined when no override governs.
103
+ */
104
+ declare function governingStatusOverride(overrides: readonly StatusOverrideInput[], referenceTimestamp?: string): StatusOverrideInput | undefined;
105
+ /**
106
+ * Returns the index of the most recently applied (by appliedAt) non-expired
107
+ * override among those for which `eligible` returns true, or -1 when none
108
+ * qualifies. Generalizes governing-override selection to per-field
109
+ * eligibility: the schema defines effectiveStatus, effectiveImpact, and
110
+ * disposition each as "the most recent non-expired override" carrying the
111
+ * relevant field, so callers pass the field-presence check as the predicate.
112
+ */
113
+ declare function governingOverrideIndex(overrides: readonly StatusOverrideInput[], eligible: (index: number) => boolean, referenceTimestamp?: string): number;
114
+ /**
115
+ * Index variant of {@link governingStatusOverride}: returns -1 when no
116
+ * override governs. Callers holding richer concrete override types use the
117
+ * index to recover their own object.
118
+ */
119
+ declare function governingStatusOverrideIndex(overrides: readonly StatusOverrideInput[], referenceTimestamp?: string): number;
120
+ /** Neutral shape of a requirement for effective-status computation. */
121
+ interface EffectiveStatusInput {
122
+ impact: number;
123
+ /** The stored effectiveStatus field; undefined means unset. */
124
+ effectiveStatus?: string;
125
+ resultStatuses?: readonly string[];
126
+ overrides?: readonly StatusOverrideInput[];
127
+ }
128
+ /**
129
+ * Determines a requirement's effective status — the single canonical
130
+ * implementation of the precedence in status-determination.md:
131
+ *
132
+ * 1. impact === 0 → "notApplicable", regardless of results or overrides
133
+ * 2. the governing (most recent non-expired) status override's status
134
+ * 3. the stored effectiveStatus, honored only when NO overrides are present —
135
+ * effectiveStatus is state derived from overrides, so when every override
136
+ * has expired it is stale and the result roll-up wins
137
+ * 4. worst-wins roll-up of the result statuses
138
+ * 5. no results → "notReviewed"
139
+ */
140
+ declare function computeEffectiveStatus(input: EffectiveStatusInput, referenceTimestamp?: string): string;
141
+ //#endregion
59
142
  //#region src/cvss/index.d.ts
60
143
  /**
61
144
  * CVSS vector parsing and validation utilities.
@@ -108,6 +191,42 @@ declare function parseCvssVector(vector: string): ParsedCvssVector;
108
191
  * @returns `{ valid, errors[] }` — never throws
109
192
  */
110
193
  declare function validateCvssVector(vector: string, version?: string): CvssValidationResult;
194
+ /** A computed CVSS score. */
195
+ interface CvssScore {
196
+ /** CVSS major.minor version the score was computed under (currently always "3.1"). */
197
+ version: string;
198
+ /** Base score (0.0–10.0). */
199
+ baseScore: number;
200
+ /**
201
+ * Temporal (Threat) score (0.0–10.0). Equals baseScore when no temporal
202
+ * metrics (E/RL/RC) are present, per the CVSS 3.1 spec.
203
+ */
204
+ temporalScore: number;
205
+ }
206
+ /**
207
+ * Compute the CVSS 3.1 Base and Temporal (Threat) scores for a vector string.
208
+ *
209
+ * Only CVSS 3.1 is supported here — CVSS 4.0's MacroVector engine lives
210
+ * separately — so any other version throws rather than returning a wrong number.
211
+ * The peer of the Go `ComputeCvssScore` (kept byte-identical via shared fixtures).
212
+ *
213
+ * @throws if the version is not 3.1, a required base metric is missing, or any
214
+ * metric value is out of the 3.1 enum.
215
+ */
216
+ declare function computeCvssScore(vector: string): CvssScore;
217
+ /** Parse a CVSS 4.0 vector and return its MacroVector string. */
218
+ declare function cvss40MacroVector(vector: string): string;
219
+ /**
220
+ * Compute the CVSS 4.0 score for a vector string, split into a Base score
221
+ * (`baseScore`, with Exploit Maturity stripped to its worst-case default E:A) and
222
+ * a Threat score (`temporalScore`, with the E value present in the vector). For a
223
+ * base-only vector the two are equal. The peer of the Go `ComputeCvss40Score`,
224
+ * kept byte-identical via the shared data file and parity fixture.
225
+ *
226
+ * @throws if the version is not 4.0, a required base metric is missing, or any
227
+ * metric value is out of the 4.0 enum.
228
+ */
229
+ declare function computeCvss40Score(vector: string): CvssScore;
111
230
  //#endregion
112
231
  //#region src/cpe/index.d.ts
113
232
  /**
@@ -237,5 +356,5 @@ interface ParsedPurl {
237
356
  */
238
357
  declare function parsePurl(purlStr: string): ParsedPurl | null;
239
358
  //#endregion
240
- export { type CpePart, type CsvBuildOptions, type CsvParseOptions, type CvssValidationResult, type HashAlgorithm, type HashEncoding, type HashOptions, type ParsedCpe, type ParsedCvssVector, type ParsedPurl, type StringifyOptions, buildCsv, buildCsvArray, buildXml, cvssScoreToSeverity, extractColumn, extractColumn as extractCsvColumn, extractTextFromXml, findRows as findCsvRows, findRows, findValuesByKey as findJsonValues, findValuesByKey, findValuesByKey as findXmlValues, formatTimestamp, formatTimestampSeconds, generateHash, hashObject, impactToSeverity, isValidCsv, isValidJSON, isValidXml, normalizeHdfTimestamps, parseCpe, parseCsv, parseCsvArray, parseCvssVector, parseJSON, parsePurl, parseTimestamp, parseXml, parseXmlWithArrays, sanitizeCsvArray, sanitizeCsvObject, sanitizeCsvValue, severityToImpact, sha256, sha512, stringifyJSON, stripHtml, trimUtcFraction, validateCvssVector, verifyHash };
359
+ export { type CpePart, type CsvBuildOptions, type CsvParseOptions, type CvssScore, type CvssValidationResult, type EffectiveStatusInput, type HashAlgorithm, type HashEncoding, type HashOptions, type ParsedCpe, type ParsedCvssVector, type ParsedPurl, STATUS_SEVERITY_ORDER, type StatusOverrideInput, type StringifyOptions, buildCsv, buildCsvArray, buildXml, computeCvss40Score, computeCvssScore, computeEffectiveStatus, cvss40MacroVector, cvssScoreToSeverity, extractColumn, extractColumn as extractCsvColumn, extractTextFromXml, findRows as findCsvRows, findRows, findValuesByKey as findJsonValues, findValuesByKey, findValuesByKey as findXmlValues, formatTimestamp, formatTimestampSeconds, generateHash, governingOverrideIndex, governingStatusOverride, governingStatusOverrideIndex, hashObject, impactToSeverity, isValidCsv, isValidJSON, isValidXml, normalizeHdfTimestamps, parseCpe, parseCsv, parseCsvArray, parseCvssVector, parseJSON, parsePurl, parseTimestamp, parseXml, parseXmlWithArrays, roundImpact, sanitizeCsvArray, sanitizeCsvObject, sanitizeCsvValue, severityToImpact, sha256, sha512, statusRank, stringifyJSON, stripHtml, trimUtcFraction, validateCvssVector, verifyHash, worstStatus };
241
360
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/severity/index.ts","../src/cvss/index.ts","../src/cpe/index.ts","../src/purl/index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgCgB,iBAAiB;iBACjB,iBAAiB;iBACjB,iBAAiB;;;;;;;iBAajB,iBAAiB;iBACjB,iBAAiB;iBACjB,iBAAiB;;;;;;;;;;;;;;;;;;iBA2BjB,oBACd;;;;;;;;;;;;;;;UChEe;;EAEf;;EAEA,SAAS;;UAGM;EACf;EACA;;;;;;;;;;;;iBA2Ic,gBAAgB,iBAAiB;;;;;;;;;;;;;;;;;;iBA4DjC,mBACd,gBACA,mBACC;;;;;;;;;;;;;;;;;;KChNS;;;;;;;;UASK;;EAEf;;EAEA,MAAM;EACN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAuEc,SAAS,iBAAiB;;;;;;;;;;;;;;;;;;;UC/FzB;;EAEf;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA,YAAY;;EAEZ;;EAEA;;;;;;;;;;;;;;;;;;;;;iBAwBc,UAAU,kBAAkB"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/severity/index.ts","../src/status/index.ts","../src/cvss/index.ts","../src/cpe/index.ts","../src/purl/index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgCgB,iBAAiB;iBACjB,iBAAiB;iBACjB,iBAAiB;;;;;;;;;iBAejB,YAAY;;;;;;;iBAUZ,iBAAiB;iBACjB,iBAAiB;iBACjB,iBAAiB;;;;;;;;;;;;;;;;;;iBA2BjB,oBACd;;;;;;;;;;;;cC7EW;;iBASG,WAAW;;;;;iBASX,YAAY;;;;;UAiBX;;EAEf;;EAEA;;EAEA;;;;;;;;iBAiBc,wBACd,oBAAoB,uBACpB,8BACC;;;;;;;;;iBAaa,uBACd,oBAAoB,uBACpB,WAAW,2BACX;;;;;;iBAmBc,6BACd,oBAAoB,uBACpB;;UAgBe;EACf;;EAEA;EACA;EACA,qBAAqB;;;;;;;;;;;;;;iBAeP,uBACd,OAAO,sBACP;;;;;;;;;;;;;;;UCrIe;;EAEf;;EAEA,SAAS;;UAGM;EACf;EACA;;;;;;;;;;;;iBA2Ic,gBAAgB,iBAAiB;;;;;;;;;;;;;;;;;;iBA4DjC,mBACd,gBACA,mBACC;;UAsCc;;EAEf;;EAEA;;;;;EAKA;;;;;;;;;;;;iBAsDc,iBAAiB,iBAAiB;;iBA6KlC,kBAAkB;;;;;;;;;;;iBAiMlB,mBAAmB,iBAAiB;;;;;;;;;;;;;;;;;;KCrqBxC;;;;;;;;UASK;;EAEf;;EAEA,MAAM;EACN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAuEc,SAAS,iBAAiB;;;;;;;;;;;;;;;;;;;UC/FzB;;EAEf;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA,YAAY;;EAEZ;;EAEA;;;;;;;;;;;;;;;;;;;;;iBAwBc,UAAU,kBAAkB"}