@mitre/hdf-utilities 2.0.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/LICENSE.md +55 -0
- package/README.md +403 -0
- package/dist/csv/index.d.ts +100 -0
- package/dist/csv/index.d.ts.map +1 -0
- package/dist/csv/index.js +251 -0
- package/dist/csv/index.js.map +1 -0
- package/dist/hash/index.d.ts +95 -0
- package/dist/hash/index.d.ts.map +1 -0
- package/dist/hash/index.js +118 -0
- package/dist/hash/index.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/json/index.d.ts +32 -0
- package/dist/json/index.d.ts.map +1 -0
- package/dist/json/index.js +61 -0
- package/dist/json/index.js.map +1 -0
- package/dist/object/index.d.ts +41 -0
- package/dist/object/index.d.ts.map +1 -0
- package/dist/object/index.js +70 -0
- package/dist/object/index.js.map +1 -0
- package/dist/string/index.d.ts +50 -0
- package/dist/string/index.d.ts.map +1 -0
- package/dist/string/index.js +62 -0
- package/dist/string/index.js.map +1 -0
- package/dist/xml/index.d.ts +86 -0
- package/dist/xml/index.d.ts.map +1 -0
- package/dist/xml/index.js +187 -0
- package/dist/xml/index.js.map +1 -0
- package/package.json +82 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# License
|
|
2
|
+
|
|
3
|
+
Copyright © 2025 The MITRE Corporation.
|
|
4
|
+
|
|
5
|
+
Approved for Public Release; Distribution Unlimited. Case Number 18-3678.
|
|
6
|
+
|
|
7
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
8
|
+
not use this file except in compliance with the License. You may obtain a
|
|
9
|
+
copy of the License at
|
|
10
|
+
|
|
11
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
|
|
13
|
+
Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
15
|
+
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
16
|
+
License for the specific language governing permissions and limitations
|
|
17
|
+
under the License.
|
|
18
|
+
|
|
19
|
+
## Redistribution Terms
|
|
20
|
+
|
|
21
|
+
Redistribution and use in source and binary forms, with or without
|
|
22
|
+
modification, are permitted provided that the following conditions are
|
|
23
|
+
met:
|
|
24
|
+
|
|
25
|
+
- Redistributions of source code must retain the above copyright/digital
|
|
26
|
+
rights legend, this list of conditions and the following Notice.
|
|
27
|
+
- Redistributions in binary form must reproduce the above
|
|
28
|
+
copyright/digital rights legend, this list of conditions and the
|
|
29
|
+
following Notice in the documentation and/or other materials provided
|
|
30
|
+
with the distribution.
|
|
31
|
+
- Neither the name of The MITRE Corporation nor the names of its contributors
|
|
32
|
+
may be used to endorse or promote products derived from this software
|
|
33
|
+
without specific prior written permission.
|
|
34
|
+
|
|
35
|
+
## Notice
|
|
36
|
+
|
|
37
|
+
The MITRE Corporation grants permission to reproduce, distribute, modify, and
|
|
38
|
+
otherwise use this software to the extent permitted by the licensed terms
|
|
39
|
+
provided in the LICENSE file included with this project.
|
|
40
|
+
|
|
41
|
+
This software was produced by The MITRE Corporation for the U.S. Government
|
|
42
|
+
under contract. As such the U.S. Government has certain use and data
|
|
43
|
+
rights in this software. No use other than those granted to the U.S.
|
|
44
|
+
Government, or to those acting on behalf of the U.S. Government, under
|
|
45
|
+
these contract arrangements is authorized without the express written
|
|
46
|
+
permission of The MITRE Corporation.
|
|
47
|
+
|
|
48
|
+
Some files in this codebase were generated by generative AI, under the
|
|
49
|
+
direction and review of The MITRE Corporation employees, for the purpose of
|
|
50
|
+
development efficiency. All AI-generated code functionality was validated
|
|
51
|
+
by standard quality and assurance testing.
|
|
52
|
+
|
|
53
|
+
For further information, please contact The MITRE Corporation,
|
|
54
|
+
Contracts Management Office, 7515 Colshire Drive, McLean, VA 22102-7539,
|
|
55
|
+
(703) 983-6000.
|
package/README.md
ADDED
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
# @mitre/hdf-utilities
|
|
2
|
+
|
|
3
|
+
Generic utility functions for working with common data formats (JSON, XML, CSV) and cryptographic hashing. These utilities provide safe parsing, building, and validation operations used throughout the HDF library ecosystem.
|
|
4
|
+
|
|
5
|
+
## Scope and Responsibilities
|
|
6
|
+
|
|
7
|
+
**hdf-utilities** provides low-level format handling utilities:
|
|
8
|
+
- Parse and build JSON, XML, CSV documents
|
|
9
|
+
- Validate format syntax (well-formed XML, parseable JSON, etc.)
|
|
10
|
+
- Generate cryptographic hashes for data integrity
|
|
11
|
+
- Sanitize values for safe output
|
|
12
|
+
|
|
13
|
+
**What this library does NOT do:**
|
|
14
|
+
- Validate HDF document semantics (use `@mitre/hdf-validators` for schema validation)
|
|
15
|
+
- Parse HDF-specific structures (use `@mitre/hdf-parsers` for HDF traversal)
|
|
16
|
+
- Convert between security tool formats (use `@mitre/hdf-converters`)
|
|
17
|
+
|
|
18
|
+
### hdf-utilities vs. hdf-validators
|
|
19
|
+
|
|
20
|
+
| hdf-utilities | hdf-validators |
|
|
21
|
+
|---------------|----------------|
|
|
22
|
+
| Format syntax validation | Schema conformance validation |
|
|
23
|
+
| "Is this valid JSON?" | "Is this valid HDF?" |
|
|
24
|
+
| "Can this XML be parsed?" | "Does this HDF have required fields?" |
|
|
25
|
+
| Generic data format handling | HDF-specific semantic rules |
|
|
26
|
+
| No knowledge of HDF schema | Validates against JSON schemas |
|
|
27
|
+
|
|
28
|
+
**Example:**
|
|
29
|
+
- `isValidJSON('{"foo": "bar"}')` → `true` (hdf-utilities - syntax check)
|
|
30
|
+
- `validateHdfResults({baselines: []})` → validates against HDF schema (hdf-validators)
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install @mitre/hdf-utilities
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Usage
|
|
39
|
+
|
|
40
|
+
### JSON Utilities
|
|
41
|
+
|
|
42
|
+
Safe JSON parsing and stringification with better error handling:
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
import { parseJSON, stringifyJSON, isValidJSON } from '@mitre/hdf-utilities';
|
|
46
|
+
|
|
47
|
+
// Parse JSON with clear error messages
|
|
48
|
+
try {
|
|
49
|
+
const data = parseJSON<HdfResults>(jsonString);
|
|
50
|
+
console.log(data.baselines);
|
|
51
|
+
} catch (error) {
|
|
52
|
+
console.error('Invalid JSON:', error.message);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Stringify with pretty printing
|
|
56
|
+
const hdf = { baselines: [], targets: [] };
|
|
57
|
+
const json = stringifyJSON(hdf, { pretty: true, indent: 2 });
|
|
58
|
+
|
|
59
|
+
// Check if string is valid JSON before parsing
|
|
60
|
+
if (isValidJSON(userInput)) {
|
|
61
|
+
const data = parseJSON(userInput);
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Hash Utilities
|
|
66
|
+
|
|
67
|
+
Generate and verify cryptographic hashes for data integrity:
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import { sha256, sha512, generateHash, hashObject, verifyHash } from '@mitre/hdf-utilities';
|
|
71
|
+
|
|
72
|
+
// Quick SHA-256 hash
|
|
73
|
+
const hash = sha256('content to hash');
|
|
74
|
+
console.log(hash); // hex-encoded hash
|
|
75
|
+
|
|
76
|
+
// Hash with custom options
|
|
77
|
+
const customHash = generateHash('data', {
|
|
78
|
+
algorithm: 'sha512',
|
|
79
|
+
encoding: 'base64'
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// Hash JavaScript objects (deterministic JSON serialization)
|
|
83
|
+
const baseline = { name: 'My Baseline', version: '1.0' };
|
|
84
|
+
const objectHash = hashObject(baseline, { algorithm: 'sha256' });
|
|
85
|
+
|
|
86
|
+
// Verify data integrity
|
|
87
|
+
const isValid = verifyHash('original data', hash, { algorithm: 'sha256' });
|
|
88
|
+
if (!isValid) {
|
|
89
|
+
console.error('Data integrity check failed!');
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### XML Utilities
|
|
94
|
+
|
|
95
|
+
Parse and build XML documents with array handling:
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
import { parseXml, buildXml, parseXmlWithArrays, isValidXml, extractTextFromXml } from '@mitre/hdf-utilities';
|
|
99
|
+
|
|
100
|
+
// Parse XML to JavaScript object
|
|
101
|
+
const xml = '<root><item>value</item></root>';
|
|
102
|
+
const obj = parseXml(xml);
|
|
103
|
+
console.log(obj); // { root: { item: 'value' } }
|
|
104
|
+
|
|
105
|
+
// Build XML from object
|
|
106
|
+
const data = {
|
|
107
|
+
HdfResults: {
|
|
108
|
+
baselines: {
|
|
109
|
+
baseline: [
|
|
110
|
+
{ name: 'Baseline 1' },
|
|
111
|
+
{ name: 'Baseline 2' }
|
|
112
|
+
]
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
const xmlOutput = buildXml(data);
|
|
117
|
+
// <?xml version="1.0"?>
|
|
118
|
+
// <HdfResults>
|
|
119
|
+
// <baselines>
|
|
120
|
+
// <baseline><name>Baseline 1</name></baseline>
|
|
121
|
+
// <baseline><name>Baseline 2</name></baseline>
|
|
122
|
+
// </baselines>
|
|
123
|
+
// </HdfResults>
|
|
124
|
+
|
|
125
|
+
// Parse XML with automatic array detection
|
|
126
|
+
const nessusXml = '<Report><ReportHost>...</ReportHost><ReportHost>...</ReportHost></Report>';
|
|
127
|
+
const report = parseXmlWithArrays(nessusXml, {
|
|
128
|
+
arrayPaths: ['Report.ReportHost'] // Force these to always be arrays
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// Check if string is well-formed XML
|
|
132
|
+
if (isValidXml(userInput)) {
|
|
133
|
+
const parsed = parseXml(userInput);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Extract plain text from XML (strips all tags)
|
|
137
|
+
const plainText = extractTextFromXml('<p>Hello <b>world</b></p>');
|
|
138
|
+
console.log(plainText); // "Hello world"
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### CSV Utilities
|
|
142
|
+
|
|
143
|
+
Parse and build CSV documents with sanitization:
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
import {
|
|
147
|
+
parseCsv,
|
|
148
|
+
buildCsv,
|
|
149
|
+
isValidCsv,
|
|
150
|
+
sanitizeCsvValue,
|
|
151
|
+
sanitizeCsvArray,
|
|
152
|
+
sanitizeCsvObject
|
|
153
|
+
} from '@mitre/hdf-utilities';
|
|
154
|
+
|
|
155
|
+
// Parse CSV string to array of objects
|
|
156
|
+
const csv = 'name,age\nAlice,30\nBob,25';
|
|
157
|
+
const rows = parseCsv(csv);
|
|
158
|
+
console.log(rows);
|
|
159
|
+
// [
|
|
160
|
+
// { name: 'Alice', age: '30' },
|
|
161
|
+
// { name: 'Bob', age: '25' }
|
|
162
|
+
// ]
|
|
163
|
+
|
|
164
|
+
// Build CSV from array of objects
|
|
165
|
+
const data = [
|
|
166
|
+
{ id: 'REQ-001', status: 'passed', impact: 0.7 },
|
|
167
|
+
{ id: 'REQ-002', status: 'failed', impact: 0.9 }
|
|
168
|
+
];
|
|
169
|
+
const csvOutput = buildCsv(data);
|
|
170
|
+
// id,status,impact
|
|
171
|
+
// REQ-001,passed,0.7
|
|
172
|
+
// REQ-002,failed,0.9
|
|
173
|
+
|
|
174
|
+
// Validate CSV syntax
|
|
175
|
+
if (isValidCsv(fileContent)) {
|
|
176
|
+
const parsed = parseCsv(fileContent);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Sanitize individual values (escape special characters)
|
|
180
|
+
const safe = sanitizeCsvValue('Value with "quotes" and, commas');
|
|
181
|
+
console.log(safe); // "Value with ""quotes"" and, commas"
|
|
182
|
+
|
|
183
|
+
// Sanitize arrays
|
|
184
|
+
const tags = ['AC-1', 'AC-2', null, undefined];
|
|
185
|
+
const safeTags = sanitizeCsvArray(tags);
|
|
186
|
+
console.log(safeTags); // ['AC-1', 'AC-2', '', '']
|
|
187
|
+
|
|
188
|
+
// Sanitize entire objects
|
|
189
|
+
const requirement = {
|
|
190
|
+
id: 'REQ-001',
|
|
191
|
+
title: 'Title with "quotes"',
|
|
192
|
+
tags: ['AC-1', null]
|
|
193
|
+
};
|
|
194
|
+
const safeReq = sanitizeCsvObject(requirement);
|
|
195
|
+
// All string values escaped, nulls converted to empty strings
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## API Reference
|
|
199
|
+
|
|
200
|
+
### JSON Utilities
|
|
201
|
+
|
|
202
|
+
#### `parseJSON<T>(input: string): T`
|
|
203
|
+
|
|
204
|
+
Parse JSON string with clear error messages.
|
|
205
|
+
|
|
206
|
+
- **Parameters:**
|
|
207
|
+
- `input` - JSON string to parse
|
|
208
|
+
- **Returns:** Parsed JSON value with inferred type
|
|
209
|
+
- **Throws:** Error with descriptive message if JSON is invalid or empty
|
|
210
|
+
|
|
211
|
+
#### `stringifyJSON(value: unknown, options?: StringifyOptions): string`
|
|
212
|
+
|
|
213
|
+
Convert JavaScript value to JSON string.
|
|
214
|
+
|
|
215
|
+
- **Parameters:**
|
|
216
|
+
- `value` - Value to stringify
|
|
217
|
+
- `options.pretty` - Enable pretty printing (default: `false`)
|
|
218
|
+
- `options.indent` - Spaces for indentation (default: `2`)
|
|
219
|
+
- **Returns:** JSON string
|
|
220
|
+
- **Throws:** Error if value contains circular references
|
|
221
|
+
|
|
222
|
+
#### `isValidJSON(input: unknown): boolean`
|
|
223
|
+
|
|
224
|
+
Check if string can be parsed as JSON.
|
|
225
|
+
|
|
226
|
+
- **Parameters:**
|
|
227
|
+
- `input` - Value to check (must be string)
|
|
228
|
+
- **Returns:** `true` if valid JSON syntax, `false` otherwise
|
|
229
|
+
|
|
230
|
+
### Hash Utilities
|
|
231
|
+
|
|
232
|
+
#### `sha256(data: string): string`
|
|
233
|
+
|
|
234
|
+
Generate SHA-256 hash (hex-encoded).
|
|
235
|
+
|
|
236
|
+
- **Parameters:**
|
|
237
|
+
- `data` - String to hash
|
|
238
|
+
- **Returns:** Hex-encoded hash string
|
|
239
|
+
|
|
240
|
+
#### `sha512(data: string): string`
|
|
241
|
+
|
|
242
|
+
Generate SHA-512 hash (hex-encoded).
|
|
243
|
+
|
|
244
|
+
- **Parameters:**
|
|
245
|
+
- `data` - String to hash
|
|
246
|
+
- **Returns:** Hex-encoded hash string
|
|
247
|
+
|
|
248
|
+
#### `generateHash(data: string, options?: HashOptions): string`
|
|
249
|
+
|
|
250
|
+
Generate hash with custom algorithm and encoding.
|
|
251
|
+
|
|
252
|
+
- **Parameters:**
|
|
253
|
+
- `data` - String to hash
|
|
254
|
+
- `options.algorithm` - Hash algorithm: `'sha256'` | `'sha512'` (default: `'sha256'`)
|
|
255
|
+
- `options.encoding` - Output encoding: `'hex'` | `'base64'` | `'base64url'` (default: `'hex'`)
|
|
256
|
+
- **Returns:** Encoded hash string
|
|
257
|
+
|
|
258
|
+
#### `hashObject(obj: unknown, options?: HashOptions): string`
|
|
259
|
+
|
|
260
|
+
Generate deterministic hash of JavaScript object.
|
|
261
|
+
|
|
262
|
+
- **Parameters:**
|
|
263
|
+
- `obj` - Object to hash (will be JSON-stringified)
|
|
264
|
+
- `options` - Same as `generateHash`
|
|
265
|
+
- **Returns:** Hash of serialized object
|
|
266
|
+
|
|
267
|
+
#### `verifyHash(data: string, expectedHash: string, options?: HashOptions): boolean`
|
|
268
|
+
|
|
269
|
+
Verify data matches expected hash.
|
|
270
|
+
|
|
271
|
+
- **Parameters:**
|
|
272
|
+
- `data` - Original data to verify
|
|
273
|
+
- `expectedHash` - Expected hash value
|
|
274
|
+
- `options` - Same hash options used during generation
|
|
275
|
+
- **Returns:** `true` if hash matches, `false` otherwise
|
|
276
|
+
|
|
277
|
+
### XML Utilities
|
|
278
|
+
|
|
279
|
+
#### `parseXml(xml: string, options?: object): object`
|
|
280
|
+
|
|
281
|
+
Parse XML string to JavaScript object.
|
|
282
|
+
|
|
283
|
+
- **Parameters:**
|
|
284
|
+
- `xml` - XML string to parse
|
|
285
|
+
- `options` - fast-xml-parser options (optional)
|
|
286
|
+
- **Returns:** Parsed object
|
|
287
|
+
- **Throws:** Error if XML is malformed
|
|
288
|
+
|
|
289
|
+
#### `buildXml(obj: object, options?: object): string`
|
|
290
|
+
|
|
291
|
+
Build XML string from JavaScript object.
|
|
292
|
+
|
|
293
|
+
- **Parameters:**
|
|
294
|
+
- `obj` - Object to convert to XML
|
|
295
|
+
- `options` - fast-xml-parser builder options (optional)
|
|
296
|
+
- **Returns:** XML string with header
|
|
297
|
+
- **Throws:** Error if conversion fails
|
|
298
|
+
|
|
299
|
+
#### `parseXmlWithArrays(xml: string, options: { arrayPaths: string[] }): object`
|
|
300
|
+
|
|
301
|
+
Parse XML with specified paths forced as arrays.
|
|
302
|
+
|
|
303
|
+
- **Parameters:**
|
|
304
|
+
- `xml` - XML string to parse
|
|
305
|
+
- `options.arrayPaths` - Dot-notation paths to treat as arrays (e.g., `'Report.ReportHost'`)
|
|
306
|
+
- **Returns:** Parsed object with consistent arrays
|
|
307
|
+
- **Throws:** Error if XML is malformed
|
|
308
|
+
|
|
309
|
+
#### `isValidXml(xml: string): boolean`
|
|
310
|
+
|
|
311
|
+
Check if string is well-formed XML.
|
|
312
|
+
|
|
313
|
+
- **Parameters:**
|
|
314
|
+
- `xml` - String to validate
|
|
315
|
+
- **Returns:** `true` if valid XML syntax, `false` otherwise
|
|
316
|
+
|
|
317
|
+
#### `extractTextFromXml(xml: string): string`
|
|
318
|
+
|
|
319
|
+
Extract plain text content from XML (strips all tags).
|
|
320
|
+
|
|
321
|
+
- **Parameters:**
|
|
322
|
+
- `xml` - XML string
|
|
323
|
+
- **Returns:** Plain text content with whitespace normalized
|
|
324
|
+
|
|
325
|
+
### CSV Utilities
|
|
326
|
+
|
|
327
|
+
#### `parseCsv<T>(csv: string, options?: object): T[]`
|
|
328
|
+
|
|
329
|
+
Parse CSV string to array of objects.
|
|
330
|
+
|
|
331
|
+
- **Parameters:**
|
|
332
|
+
- `csv` - CSV string to parse
|
|
333
|
+
- `options` - PapaParse options (optional)
|
|
334
|
+
- **Returns:** Array of objects (headers become keys)
|
|
335
|
+
- **Throws:** Error if CSV is malformed
|
|
336
|
+
|
|
337
|
+
#### `buildCsv<T>(data: T[], options?: object): string`
|
|
338
|
+
|
|
339
|
+
Build CSV string from array of objects.
|
|
340
|
+
|
|
341
|
+
- **Parameters:**
|
|
342
|
+
- `data` - Array of objects to convert
|
|
343
|
+
- `options` - PapaParse unparse options (optional)
|
|
344
|
+
- **Returns:** CSV string with headers
|
|
345
|
+
|
|
346
|
+
#### `isValidCsv(csv: string): boolean`
|
|
347
|
+
|
|
348
|
+
Check if string can be parsed as CSV.
|
|
349
|
+
|
|
350
|
+
- **Parameters:**
|
|
351
|
+
- `csv` - String to validate
|
|
352
|
+
- **Returns:** `true` if parseable CSV, `false` otherwise
|
|
353
|
+
|
|
354
|
+
#### `sanitizeCsvValue(value: unknown): string`
|
|
355
|
+
|
|
356
|
+
Escape value for safe CSV output.
|
|
357
|
+
|
|
358
|
+
- **Parameters:**
|
|
359
|
+
- `value` - Value to sanitize
|
|
360
|
+
- **Returns:** Escaped string (quotes escaped, nulls → empty string)
|
|
361
|
+
|
|
362
|
+
#### `sanitizeCsvArray(values: unknown[]): string[]`
|
|
363
|
+
|
|
364
|
+
Sanitize array of values for CSV.
|
|
365
|
+
|
|
366
|
+
- **Parameters:**
|
|
367
|
+
- `values` - Array to sanitize
|
|
368
|
+
- **Returns:** Array of sanitized strings
|
|
369
|
+
|
|
370
|
+
#### `sanitizeCsvObject<T>(obj: T): T`
|
|
371
|
+
|
|
372
|
+
Recursively sanitize all string values in object.
|
|
373
|
+
|
|
374
|
+
- **Parameters:**
|
|
375
|
+
- `obj` - Object to sanitize
|
|
376
|
+
- **Returns:** New object with sanitized values
|
|
377
|
+
|
|
378
|
+
## Development
|
|
379
|
+
|
|
380
|
+
```bash
|
|
381
|
+
# Install dependencies
|
|
382
|
+
pnpm install
|
|
383
|
+
|
|
384
|
+
# Run tests
|
|
385
|
+
pnpm test
|
|
386
|
+
|
|
387
|
+
# Run tests with coverage
|
|
388
|
+
pnpm test:coverage
|
|
389
|
+
|
|
390
|
+
# Build the package
|
|
391
|
+
pnpm build
|
|
392
|
+
|
|
393
|
+
# Lint code
|
|
394
|
+
pnpm lint
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
## Test Coverage
|
|
398
|
+
|
|
399
|
+
All utilities maintain **>95% test coverage**. Run `pnpm test:coverage` to view current coverage report.
|
|
400
|
+
|
|
401
|
+
## License
|
|
402
|
+
|
|
403
|
+
Apache-2.0 © MITRE Corporation
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSV parsing and generation utilities using d3-dsv
|
|
3
|
+
*
|
|
4
|
+
* SECURITY WARNING: CSV files opened in Excel/LibreOffice may execute formulas.
|
|
5
|
+
* Use sanitization options when exporting data that may contain user-controlled content.
|
|
6
|
+
*/
|
|
7
|
+
export { extractColumn as extractCsvColumn, findRows as findCsvRows, } from '../object/index.js';
|
|
8
|
+
/**
|
|
9
|
+
* Options for parsing CSV
|
|
10
|
+
*/
|
|
11
|
+
export interface CsvParseOptions {
|
|
12
|
+
header?: boolean;
|
|
13
|
+
skipEmptyLines?: boolean;
|
|
14
|
+
transformHeader?: (header: string, index: number) => string;
|
|
15
|
+
dynamicTyping?: boolean;
|
|
16
|
+
delimiter?: string;
|
|
17
|
+
maxSize?: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Options for building CSV
|
|
21
|
+
*/
|
|
22
|
+
export interface CsvBuildOptions {
|
|
23
|
+
header?: boolean;
|
|
24
|
+
newline?: string;
|
|
25
|
+
skipEmptyLines?: boolean;
|
|
26
|
+
delimiter?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Parse CSV string into array of objects with headers as keys
|
|
30
|
+
* @param csv - CSV string to parse
|
|
31
|
+
* @param options - Optional parse configuration
|
|
32
|
+
* @returns Array of objects representing rows
|
|
33
|
+
* @throws Error if parsing fails
|
|
34
|
+
*/
|
|
35
|
+
export declare function parseCsv<T = Record<string, unknown>>(csv: string, options?: Partial<CsvParseOptions>): T[];
|
|
36
|
+
/**
|
|
37
|
+
* Parse CSV string into array of arrays without treating first row as headers
|
|
38
|
+
* @param csv - CSV string to parse
|
|
39
|
+
* @param options - Optional parse configuration
|
|
40
|
+
* @returns Array of arrays representing rows
|
|
41
|
+
* @throws Error if parsing fails
|
|
42
|
+
*/
|
|
43
|
+
export declare function parseCsvArray(csv: string, options?: Partial<CsvParseOptions>): string[][];
|
|
44
|
+
/**
|
|
45
|
+
* Build CSV string from array of objects
|
|
46
|
+
*
|
|
47
|
+
* SECURITY: Set sanitize=true when data may contain user-controlled content
|
|
48
|
+
* to prevent CSV formula injection attacks in Excel/LibreOffice.
|
|
49
|
+
*
|
|
50
|
+
* @param data - Array of objects to convert to CSV
|
|
51
|
+
* @param options - Optional build configuration and sanitize flag
|
|
52
|
+
* @returns CSV string
|
|
53
|
+
*/
|
|
54
|
+
export declare function buildCsv<T = Record<string, unknown>>(data: T[], options?: Partial<CsvBuildOptions> & {
|
|
55
|
+
sanitize?: boolean;
|
|
56
|
+
}): string;
|
|
57
|
+
/**
|
|
58
|
+
* Build CSV string from array of arrays
|
|
59
|
+
*
|
|
60
|
+
* SECURITY: Set sanitize=true when data may contain user-controlled content
|
|
61
|
+
* to prevent CSV formula injection attacks in Excel/LibreOffice.
|
|
62
|
+
*
|
|
63
|
+
* @param data - Array of arrays to convert to CSV
|
|
64
|
+
* @param options - Optional build configuration and sanitize flag
|
|
65
|
+
* @returns CSV string
|
|
66
|
+
*/
|
|
67
|
+
export declare function buildCsvArray(data: string[][], options?: Partial<CsvBuildOptions> & {
|
|
68
|
+
sanitize?: boolean;
|
|
69
|
+
}): string;
|
|
70
|
+
/**
|
|
71
|
+
* Validate CSV format
|
|
72
|
+
* @param csv - CSV string to validate
|
|
73
|
+
* @returns True if valid CSV, false otherwise
|
|
74
|
+
*/
|
|
75
|
+
export declare function isValidCsv(csv: string): boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Sanitize a single CSV value to prevent formula injection
|
|
78
|
+
*
|
|
79
|
+
* Prefixes values starting with =, +, -, @, |, or % with a single quote
|
|
80
|
+
* to prevent Excel/LibreOffice from interpreting them as formulas.
|
|
81
|
+
*
|
|
82
|
+
* @param value - Value to sanitize
|
|
83
|
+
* @returns Sanitized value
|
|
84
|
+
*/
|
|
85
|
+
export declare function sanitizeCsvValue(value: unknown): string;
|
|
86
|
+
/**
|
|
87
|
+
* Sanitize all values in an array to prevent formula injection
|
|
88
|
+
*
|
|
89
|
+
* @param values - Array of values to sanitize
|
|
90
|
+
* @returns Array with sanitized values
|
|
91
|
+
*/
|
|
92
|
+
export declare function sanitizeCsvArray(values: unknown[]): string[];
|
|
93
|
+
/**
|
|
94
|
+
* Sanitize all values in an object to prevent formula injection
|
|
95
|
+
*
|
|
96
|
+
* @param obj - Object with values to sanitize
|
|
97
|
+
* @returns New object with sanitized values
|
|
98
|
+
*/
|
|
99
|
+
export declare function sanitizeCsvObject<T extends Record<string, unknown>>(obj: T): Record<string, string>;
|
|
100
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/csv/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EACL,aAAa,IAAI,gBAAgB,EACjC,QAAQ,IAAI,WAAW,GACxB,MAAM,oBAAoB,CAAC;AAE5B;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAC5D,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAgED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClD,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,GACjC,CAAC,EAAE,CA2CL;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,GACjC,MAAM,EAAE,EAAE,CAoBZ;AAED;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClD,IAAI,EAAE,CAAC,EAAE,EACT,OAAO,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GAC1D,MAAM,CA8BR;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EAAE,EAAE,EAChB,OAAO,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GAC1D,MAAM,CAmBR;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAe/C;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAOvD;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,EAAE,CAE5D;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjE,GAAG,EAAE,CAAC,GACL,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAMxB"}
|