@mitre/hdf-schema 3.5.0 → 3.6.0-rc.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.
@@ -0,0 +1,228 @@
1
+ /**
2
+ * Test-only builders for minimal, schema-valid HDF Results documents.
3
+ *
4
+ * The TS peer of hdf-schema/testhdf/go — same defaults, same shape. Shipped as
5
+ * the '@mitre/hdf-schema/testhdf' subpath export (a package export must be in
6
+ * the published tarball, so it ships alongside the create* helpers; it is
7
+ * intended for tests but harmless to consumers). Use results(req(...)) for the
8
+ * common single-requirement case; reach for doc/baseline for multiple baselines.
9
+ */
10
+
11
+ const DEFAULT_START_TIME = '2020-01-01T00:00:00Z';
12
+
13
+ /**
14
+ * Build an EvaluatedRequirement with defaults: impact 0, empty tags, a single
15
+ * "default" description (data = id), and one notReviewed result.
16
+ *
17
+ * @param {string} id
18
+ * @param {Object} [opts]
19
+ * @param {string} [opts.severity]
20
+ * @param {number} [opts.impact]
21
+ * @param {string} [opts.status] - status of the (default) result
22
+ * @param {Object<string, unknown>} [opts.tags]
23
+ * @param {string} [opts.code]
24
+ * @param {string[]} [opts.cwe]
25
+ * @param {string} [opts.desc] - data for the default description
26
+ * @param {Array<[string, string]>} [opts.addDesc] - extra [label, data] descriptions
27
+ * @param {object[]} [opts.results] - replace results wholesale
28
+ * @returns {import('../dist/ts/hdf.js').EvaluatedRequirement}
29
+ */
30
+ export function req(id, opts = {}) {
31
+ const r = {
32
+ id,
33
+ impact: opts.impact ?? 0,
34
+ tags: opts.tags ?? {},
35
+ descriptions: [{ label: 'default', data: opts.desc ?? id }],
36
+ results: opts.results ?? [
37
+ { status: opts.status ?? 'notReviewed', codeDesc: id, startTime: DEFAULT_START_TIME },
38
+ ],
39
+ };
40
+ if (opts.severity !== undefined) r.severity = opts.severity;
41
+ if (opts.code !== undefined) r.code = opts.code;
42
+ if (opts.cwe !== undefined) r.cwe = opts.cwe;
43
+ if (opts.title !== undefined) r.title = opts.title;
44
+ if (opts.codeDesc !== undefined && r.results[0]) r.results[0].codeDesc = opts.codeDesc;
45
+ if (opts.startTime !== undefined && r.results[0]) r.results[0].startTime = opts.startTime;
46
+ for (const [label, data] of opts.addDesc ?? []) {
47
+ r.descriptions.push({ label, data });
48
+ }
49
+ return /** @type {import('../dist/ts/hdf.js').EvaluatedRequirement} */ (r);
50
+ }
51
+
52
+ /**
53
+ * Build an EvaluatedBaseline with the given name and requirements.
54
+ * @param {string} name
55
+ * @param {...import('../dist/ts/hdf.js').EvaluatedRequirement} reqs
56
+ * @returns {import('../dist/ts/hdf.js').EvaluatedBaseline}
57
+ */
58
+ export function baseline(name, ...reqs) {
59
+ return /** @type {import('../dist/ts/hdf.js').EvaluatedBaseline} */ ({ name, requirements: reqs });
60
+ }
61
+
62
+ /**
63
+ * Build an HDFResults from the given baselines, filling the required generator.
64
+ * @param {...import('../dist/ts/hdf.js').EvaluatedBaseline} baselines
65
+ * @returns {import('../dist/ts/hdf.js').HDFResults}
66
+ */
67
+ export function doc(...baselines) {
68
+ return /** @type {import('../dist/ts/hdf.js').HDFResults} */ ({
69
+ baselines,
70
+ generator: { name: 'testhdf', version: '0.0.0' },
71
+ });
72
+ }
73
+
74
+ /**
75
+ * Common shortcut: wrap the requirements in one "test" baseline.
76
+ * @param {...import('../dist/ts/hdf.js').EvaluatedRequirement} reqs
77
+ * @returns {import('../dist/ts/hdf.js').HDFResults}
78
+ */
79
+ export function results(...reqs) {
80
+ return doc(baseline('test', ...reqs));
81
+ }
82
+
83
+ const DEFAULT_EXPIRY = '2099-12-31T00:00:00Z';
84
+
85
+ // ===== HDF Baseline (requirements without results) =====
86
+
87
+ /**
88
+ * @param {string} id
89
+ * @param {{impact?:number, tags?:Object<string,unknown>, desc?:string}} [opts]
90
+ * @returns {import('../dist/ts/hdf.js').BaselineRequirement}
91
+ */
92
+ export function baselineReq(id, opts = {}) {
93
+ return /** @type {any} */ ({
94
+ id,
95
+ impact: opts.impact ?? 0,
96
+ tags: opts.tags ?? {},
97
+ descriptions: [{ label: 'default', data: opts.desc ?? id }],
98
+ });
99
+ }
100
+
101
+ /**
102
+ * @param {string} name
103
+ * @param {...import('../dist/ts/hdf.js').BaselineRequirement} reqs
104
+ * @returns {import('../dist/ts/hdf.js').HDFBaseline}
105
+ */
106
+ export function baselineDoc(name, ...reqs) {
107
+ return /** @type {any} */ ({ name, requirements: reqs });
108
+ }
109
+
110
+ // ===== HDF Amendments =====
111
+
112
+ /**
113
+ * @param {string} type - override type (waiver, falsePositive, poam, ...)
114
+ * @param {string} reqId
115
+ * @param {{status?:string, reason?:string, appliedBy?:object, milestones?:object[]}} [opts]
116
+ * @returns {import('../dist/ts/hdf.js').StandaloneOverride}
117
+ */
118
+ export function override(type, reqId, opts = {}) {
119
+ const o = {
120
+ type,
121
+ requirementId: reqId,
122
+ appliedAt: DEFAULT_START_TIME,
123
+ expiresAt: DEFAULT_EXPIRY,
124
+ appliedBy: opts.appliedBy ?? { type: 'simple', identifier: 'test' },
125
+ reason: opts.reason ?? 'test override',
126
+ };
127
+ if (opts.status !== undefined) o.status = opts.status;
128
+ if (opts.milestones !== undefined) o.milestones = opts.milestones;
129
+ return /** @type {any} */ (o);
130
+ }
131
+
132
+ /**
133
+ * @param {string} name
134
+ * @param {...import('../dist/ts/hdf.js').StandaloneOverride} overrides
135
+ * @returns {import('../dist/ts/hdf.js').HDFAmendments}
136
+ */
137
+ export function amendments(name, ...overrides) {
138
+ return /** @type {any} */ ({ name, overrides });
139
+ }
140
+
141
+ // ===== HDF System =====
142
+
143
+ /**
144
+ * @param {string} name
145
+ * @param {string} type - component type (host, application, cloudResource, ...)
146
+ * @param {object} [opts] - extra component fields (componentId, osName, ...)
147
+ * @returns {import('../dist/ts/hdf.js').Component}
148
+ */
149
+ export function component(name, type, opts = {}) {
150
+ return /** @type {any} */ ({ name, type, ...opts });
151
+ }
152
+
153
+ /**
154
+ * @param {string} name
155
+ * @param {...import('../dist/ts/hdf.js').Component} components
156
+ * @returns {import('../dist/ts/hdf.js').HDFSystem}
157
+ */
158
+ export function system(name, ...components) {
159
+ return /** @type {any} */ ({ name, components });
160
+ }
161
+
162
+ // ===== HDF Plan =====
163
+
164
+ /** @param {string} baselineRef @returns {import('../dist/ts/hdf.js').Assessment} */
165
+ export function assessment(baselineRef) {
166
+ return /** @type {any} */ ({ baselineRef });
167
+ }
168
+
169
+ /**
170
+ * @param {string} name
171
+ * @param {...import('../dist/ts/hdf.js').Assessment} assessments
172
+ * @returns {import('../dist/ts/hdf.js').HDFPlan}
173
+ */
174
+ export function plan(name, ...assessments) {
175
+ return /** @type {any} */ ({ name, assessments });
176
+ }
177
+
178
+ // ===== HDF Evidence Package =====
179
+
180
+ /** @param {string} uri @param {string} type @returns {import('../dist/ts/hdf.js').ContentReference} */
181
+ export function content(uri, type) {
182
+ return /** @type {any} */ ({ uri, type });
183
+ }
184
+
185
+ /**
186
+ * @param {string} name
187
+ * @param {...import('../dist/ts/hdf.js').ContentReference} contents
188
+ * @returns {import('../dist/ts/hdf.js').HDFEvidencePackage}
189
+ */
190
+ export function evidencePackage(name, ...contents) {
191
+ return /** @type {any} */ ({ name, contents });
192
+ }
193
+
194
+ // ===== HDF Requirement Change Event =====
195
+
196
+ /**
197
+ * @param {string} reqId
198
+ * @param {{state?:string, before?:unknown, after?:unknown, priorChecksum?:unknown}} [opts]
199
+ * @returns {import('../dist/ts/hdf.js').HDFRequirementChangeEvent}
200
+ */
201
+ export function changeEvent(reqId, opts = {}) {
202
+ return /** @type {any} */ ({
203
+ requirementId: reqId,
204
+ eventId: '00000000-0000-4000-8000-000000000001',
205
+ componentId: '00000000-0000-4000-8000-000000000002',
206
+ systemRef: 'test-system',
207
+ source: 'test',
208
+ sequence: 1,
209
+ timestamp: DEFAULT_START_TIME,
210
+ state: opts.state ?? 'new',
211
+ before: opts.before ?? null,
212
+ after: opts.after ?? req(reqId),
213
+ priorChecksum: opts.priorChecksum ?? null,
214
+ });
215
+ }
216
+
217
+ // ===== HDF Comparison =====
218
+
219
+ /** @param {string} mode @returns {import('../dist/ts/hdf.js').HDFComparison} */
220
+ export function comparison(mode) {
221
+ return /** @type {any} */ ({
222
+ comparisonMode: mode,
223
+ formatVersion: '1.0.0',
224
+ sources: [{ label: 'old', role: 'old' }, { label: 'new', role: 'new' }],
225
+ requirementDiffs: [],
226
+ summary: { total: 0, matchedCount: 0, unmatchedNewCount: 0, unmatchedOldCount: 0 },
227
+ });
228
+ }