@thi.ng/csv 2.4.5 → 2.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/CHANGELOG.md +10 -1
- package/README.md +2 -1
- package/api.d.ts +10 -1
- package/package.json +9 -8
- package/parse.js +31 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
- **Last updated**: 2025-
|
|
3
|
+
- **Last updated**: 2025-08-06T11:29:19Z
|
|
4
4
|
- **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
|
|
5
5
|
|
|
6
6
|
All notable changes to this project will be documented in this file.
|
|
@@ -11,6 +11,15 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
|
|
|
11
11
|
**Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
|
|
12
12
|
and/or version bumps of transitive dependencies.
|
|
13
13
|
|
|
14
|
+
## [2.5.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/csv@2.5.0) (2025-08-06)
|
|
15
|
+
|
|
16
|
+
#### 🚀 Features
|
|
17
|
+
|
|
18
|
+
- add support for column default values ([e105548](https://github.com/thi-ng/umbrella/commit/e105548))
|
|
19
|
+
- update `ColumnSpec`
|
|
20
|
+
- update `parseCSV()` to support & validate column specs w/ default values
|
|
21
|
+
- add tests
|
|
22
|
+
|
|
14
23
|
## [2.4.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/csv@2.4.0) (2025-07-12)
|
|
15
24
|
|
|
16
25
|
#### 🚀 Features
|
package/README.md
CHANGED
|
@@ -87,12 +87,13 @@ For Node.js REPL:
|
|
|
87
87
|
const csv = await import("@thi.ng/csv");
|
|
88
88
|
```
|
|
89
89
|
|
|
90
|
-
Package sizes (brotli'd, pre-treeshake): ESM: 1.
|
|
90
|
+
Package sizes (brotli'd, pre-treeshake): ESM: 1.71 KB
|
|
91
91
|
|
|
92
92
|
## Dependencies
|
|
93
93
|
|
|
94
94
|
- [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/develop/packages/api)
|
|
95
95
|
- [@thi.ng/checks](https://github.com/thi-ng/umbrella/tree/develop/packages/checks)
|
|
96
|
+
- [@thi.ng/errors](https://github.com/thi-ng/umbrella/tree/develop/packages/errors)
|
|
96
97
|
- [@thi.ng/strings](https://github.com/thi-ng/umbrella/tree/develop/packages/strings)
|
|
97
98
|
- [@thi.ng/transducers](https://github.com/thi-ng/umbrella/tree/develop/packages/transducers)
|
|
98
99
|
|
package/api.d.ts
CHANGED
|
@@ -16,7 +16,9 @@ export type CSVRecord = Record<string, any>;
|
|
|
16
16
|
export type CellTransform = Fn2<string, any, any>;
|
|
17
17
|
export interface ColumnSpec {
|
|
18
18
|
/**
|
|
19
|
-
* Rename column to given name in result objects.
|
|
19
|
+
* Rename column to given name in result objects. MUST be given if
|
|
20
|
+
* {@link ColumnSpec.default} is defined and column specs are provided to
|
|
21
|
+
* {@link parseCSV} as array (rather than as object).
|
|
20
22
|
*/
|
|
21
23
|
alias?: string;
|
|
22
24
|
/**
|
|
@@ -25,6 +27,13 @@ export interface ColumnSpec {
|
|
|
25
27
|
* actual value for the cell.
|
|
26
28
|
*/
|
|
27
29
|
tx?: CellTransform;
|
|
30
|
+
/**
|
|
31
|
+
* Default value to use if column is missing.
|
|
32
|
+
*
|
|
33
|
+
* @remarks
|
|
34
|
+
* Also see note about {@link ColumnSpec.alias}.
|
|
35
|
+
*/
|
|
36
|
+
default?: any;
|
|
28
37
|
}
|
|
29
38
|
export type ColumnSpecs = Record<string, ColumnSpec>;
|
|
30
39
|
export interface CommonCSVOpts {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/csv",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"description": "Customizable, transducer-based CSV parser/object mapper and transformer",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -39,15 +39,16 @@
|
|
|
39
39
|
"tool:tangle": "../../node_modules/.bin/tangle src/**/*.ts"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@thi.ng/api": "^8.
|
|
43
|
-
"@thi.ng/checks": "^3.7.
|
|
44
|
-
"@thi.ng/
|
|
45
|
-
"@thi.ng/
|
|
42
|
+
"@thi.ng/api": "^8.12.1",
|
|
43
|
+
"@thi.ng/checks": "^3.7.15",
|
|
44
|
+
"@thi.ng/errors": "^2.5.41",
|
|
45
|
+
"@thi.ng/strings": "^3.9.21",
|
|
46
|
+
"@thi.ng/transducers": "^9.6.6"
|
|
46
47
|
},
|
|
47
48
|
"devDependencies": {
|
|
48
49
|
"esbuild": "^0.25.8",
|
|
49
|
-
"typedoc": "^0.28.
|
|
50
|
-
"typescript": "^5.
|
|
50
|
+
"typedoc": "^0.28.9",
|
|
51
|
+
"typescript": "^5.9.2"
|
|
51
52
|
},
|
|
52
53
|
"keywords": [
|
|
53
54
|
"csv",
|
|
@@ -87,5 +88,5 @@
|
|
|
87
88
|
"thi.ng": {
|
|
88
89
|
"year": 2014
|
|
89
90
|
},
|
|
90
|
-
"gitHead": "
|
|
91
|
+
"gitHead": "c31170bdfc63c127350968b05341c0955b2b9d5f\n"
|
|
91
92
|
}
|
package/parse.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { isArray } from "@thi.ng/checks/is-array";
|
|
2
2
|
import { isFunction } from "@thi.ng/checks/is-function";
|
|
3
3
|
import { isIterable } from "@thi.ng/checks/is-iterable";
|
|
4
|
+
import { illegalArgs } from "@thi.ng/errors/illegal-arguments";
|
|
4
5
|
import { ESCAPES } from "@thi.ng/strings/escape";
|
|
5
6
|
import { split } from "@thi.ng/strings/split";
|
|
6
7
|
import { compR } from "@thi.ng/transducers/compr";
|
|
@@ -28,12 +29,16 @@ function parseCSV(opts, src) {
|
|
|
28
29
|
const reduce = rfn[2];
|
|
29
30
|
let index;
|
|
30
31
|
let revIndex;
|
|
32
|
+
let defaults;
|
|
31
33
|
let first = true;
|
|
32
34
|
let isQuoted = false;
|
|
33
35
|
let record = [];
|
|
34
36
|
const init = (header2) => {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
if (cols) {
|
|
38
|
+
index = __initIndex(header2, cols);
|
|
39
|
+
defaults = __initDefaults(cols);
|
|
40
|
+
}
|
|
41
|
+
if (all) revIndex = __initRevIndex(header2);
|
|
37
42
|
first = false;
|
|
38
43
|
};
|
|
39
44
|
const collectAll = (row) => record.reduce(
|
|
@@ -49,6 +54,10 @@ function parseCSV(opts, src) {
|
|
|
49
54
|
}
|
|
50
55
|
return acc;
|
|
51
56
|
}, row);
|
|
57
|
+
const collectDefaults = (row) => defaults.reduce((acc, { alias, default: val }) => {
|
|
58
|
+
if (acc[alias] === void 0) acc[alias] = val;
|
|
59
|
+
return acc;
|
|
60
|
+
}, row);
|
|
52
61
|
header && init(header);
|
|
53
62
|
return compR(rfn, (acc, line) => {
|
|
54
63
|
if ((!line.length || line.startsWith(comment)) && !isQuoted)
|
|
@@ -65,6 +74,7 @@ function parseCSV(opts, src) {
|
|
|
65
74
|
const row = {};
|
|
66
75
|
all && collectAll(row);
|
|
67
76
|
index && collectIndexed(row);
|
|
77
|
+
defaults && collectDefaults(row);
|
|
68
78
|
record = [];
|
|
69
79
|
return reduce(acc, row);
|
|
70
80
|
} else {
|
|
@@ -185,6 +195,25 @@ const __initIndex = (line, cols) => isArray(cols) ? cols.reduce((acc, spec, i) =
|
|
|
185
195
|
{}
|
|
186
196
|
);
|
|
187
197
|
const __initRevIndex = (line) => line.reduce((acc, x, i) => (acc[i] = x, acc), {});
|
|
198
|
+
const __initDefaults = (cols) => {
|
|
199
|
+
const defaults = isArray(cols) ? cols.filter((c) => {
|
|
200
|
+
if (!c || c.default == void 0) return false;
|
|
201
|
+
if (!c.alias)
|
|
202
|
+
illegalArgs(
|
|
203
|
+
`missing column alias for default: ${c.default}`
|
|
204
|
+
);
|
|
205
|
+
return true;
|
|
206
|
+
}) : Object.entries(cols).reduce((acc, [k, v]) => {
|
|
207
|
+
if (v.default !== void 0) {
|
|
208
|
+
acc.push({
|
|
209
|
+
alias: v.alias ?? k,
|
|
210
|
+
default: v.default
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
return acc;
|
|
214
|
+
}, []);
|
|
215
|
+
return defaults.length ? defaults : void 0;
|
|
216
|
+
};
|
|
188
217
|
export {
|
|
189
218
|
parseCSV,
|
|
190
219
|
parseCSVFromString,
|