@forthtilliath/ts-kit 0.6.0 → 0.8.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 +13 -0
- package/dist/array/index.d.ts +1 -0
- package/dist/array/index.d.ts.map +1 -1
- package/dist/array/index.js +1 -0
- package/dist/array/swapItems.d.ts +16 -0
- package/dist/array/swapItems.d.ts.map +1 -0
- package/dist/array/swapItems.js +24 -0
- package/dist/csv/downloadCsv.d.ts +11 -0
- package/dist/csv/downloadCsv.d.ts.map +1 -0
- package/dist/csv/downloadCsv.js +13 -0
- package/dist/csv/index.d.ts +4 -0
- package/dist/csv/index.d.ts.map +1 -0
- package/dist/csv/index.js +3 -0
- package/dist/csv/parseCsvLine.d.ts +15 -0
- package/dist/csv/parseCsvLine.d.ts.map +1 -0
- package/dist/csv/parseCsvLine.js +38 -0
- package/dist/csv/toCsv.d.ts +14 -0
- package/dist/csv/toCsv.d.ts.map +1 -0
- package/dist/csv/toCsv.js +19 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -46,6 +46,9 @@ import { chunk } from "@forthtilliath/ts-kit/array/chunk";
|
|
|
46
46
|
- `rankByNameMatch(items, query, getName)` — ranks `items` by relevance to
|
|
47
47
|
`query`: earlier match position first, then shorter name — for a
|
|
48
48
|
search-as-you-type list.
|
|
49
|
+
- `swapItems(items, i, j)` — copy of `items` with the elements at `i` and `j`
|
|
50
|
+
swapped (e.g. moving an item up/down) — a plain copy if either position is
|
|
51
|
+
out of bounds.
|
|
49
52
|
|
|
50
53
|
### `async`
|
|
51
54
|
|
|
@@ -81,6 +84,16 @@ import { chunk } from "@forthtilliath/ts-kit/array/chunk";
|
|
|
81
84
|
rarely needed since `FArray` is already assignable to `T[]` anywhere a
|
|
82
85
|
plain array is expected, but useful when the runtime type matters too.
|
|
83
86
|
|
|
87
|
+
### `csv`
|
|
88
|
+
|
|
89
|
+
- `parseCsvLine(line, delimiter?)` — splits one CSV line into trimmed cells;
|
|
90
|
+
quoted cells may contain the delimiter, `""` stands for a literal quote.
|
|
91
|
+
Delimiter defaults to `","`.
|
|
92
|
+
- `toCsv(rows, delimiter?)` — serializes rows to CSV, every cell quoted and
|
|
93
|
+
escaped, rows joined with `\n`.
|
|
94
|
+
- `downloadCsv(filename, content)` — browser download as `text/csv`, with a
|
|
95
|
+
UTF-8 BOM so Excel reads accented characters.
|
|
96
|
+
|
|
84
97
|
### `date`
|
|
85
98
|
|
|
86
99
|
- `startOfDay(date?)` — returns a new `Date` at local midnight.
|
package/dist/array/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/array/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/array/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC"}
|
package/dist/array/index.js
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns a copy of `items` with the elements at positions `i` and `j`
|
|
3
|
+
* swapped (e.g. moving an item up or down in a reorderable list). Never
|
|
4
|
+
* mutates `items`, and stays sound under `noUncheckedIndexedAccess`.
|
|
5
|
+
*
|
|
6
|
+
* @param items - The array to copy.
|
|
7
|
+
* @param i - The position of the first element.
|
|
8
|
+
* @param j - The position of the second element.
|
|
9
|
+
* @returns A new array with both elements swapped, or a plain copy if either
|
|
10
|
+
* position is out of bounds.
|
|
11
|
+
* @example
|
|
12
|
+
* swapItems(["a", "b", "c"], 0, 2); // => ["c", "b", "a"]
|
|
13
|
+
* swapItems(["a", "b", "c"], 0, 5); // => ["a", "b", "c"]
|
|
14
|
+
*/
|
|
15
|
+
export declare function swapItems<T>(items: readonly T[], i: number, j: number): T[];
|
|
16
|
+
//# sourceMappingURL=swapItems.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"swapItems.d.ts","sourceRoot":"","sources":["../../src/array/swapItems.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE,CAQ3E"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns a copy of `items` with the elements at positions `i` and `j`
|
|
3
|
+
* swapped (e.g. moving an item up or down in a reorderable list). Never
|
|
4
|
+
* mutates `items`, and stays sound under `noUncheckedIndexedAccess`.
|
|
5
|
+
*
|
|
6
|
+
* @param items - The array to copy.
|
|
7
|
+
* @param i - The position of the first element.
|
|
8
|
+
* @param j - The position of the second element.
|
|
9
|
+
* @returns A new array with both elements swapped, or a plain copy if either
|
|
10
|
+
* position is out of bounds.
|
|
11
|
+
* @example
|
|
12
|
+
* swapItems(["a", "b", "c"], 0, 2); // => ["c", "b", "a"]
|
|
13
|
+
* swapItems(["a", "b", "c"], 0, 5); // => ["a", "b", "c"]
|
|
14
|
+
*/
|
|
15
|
+
export function swapItems(items, i, j) {
|
|
16
|
+
const next = [...items];
|
|
17
|
+
const a = next[i];
|
|
18
|
+
const b = next[j];
|
|
19
|
+
if (a === undefined || b === undefined)
|
|
20
|
+
return next;
|
|
21
|
+
next[i] = b;
|
|
22
|
+
next[j] = a;
|
|
23
|
+
return next;
|
|
24
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Downloads CSV content as a file. Prepends a UTF-8 byte order mark so Excel
|
|
3
|
+
* reads accented characters correctly instead of guessing a legacy encoding.
|
|
4
|
+
*
|
|
5
|
+
* @param filename - The filename to save to.
|
|
6
|
+
* @param content - The CSV content (see `toCsv`).
|
|
7
|
+
* @example
|
|
8
|
+
* downloadCsv("members.csv", toCsv([["name"], ["Zoé"]]));
|
|
9
|
+
*/
|
|
10
|
+
export declare function downloadCsv(filename: string, content: string): void;
|
|
11
|
+
//# sourceMappingURL=downloadCsv.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"downloadCsv.d.ts","sourceRoot":"","sources":["../../src/csv/downloadCsv.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAEnE"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { downloadTextBlob } from "../files/downloadText.js";
|
|
2
|
+
/**
|
|
3
|
+
* Downloads CSV content as a file. Prepends a UTF-8 byte order mark so Excel
|
|
4
|
+
* reads accented characters correctly instead of guessing a legacy encoding.
|
|
5
|
+
*
|
|
6
|
+
* @param filename - The filename to save to.
|
|
7
|
+
* @param content - The CSV content (see `toCsv`).
|
|
8
|
+
* @example
|
|
9
|
+
* downloadCsv("members.csv", toCsv([["name"], ["Zoé"]]));
|
|
10
|
+
*/
|
|
11
|
+
export function downloadCsv(filename, content) {
|
|
12
|
+
downloadTextBlob(filename, "" + content, "text/csv");
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/csv/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Splits a single CSV line into its cells. A cell wrapped in double quotes may
|
|
3
|
+
* contain the delimiter, and a doubled double quote (`""`) inside it stands for
|
|
4
|
+
* a literal one. Every cell is trimmed.
|
|
5
|
+
*
|
|
6
|
+
* @param line - One line of CSV (no line break).
|
|
7
|
+
* @param delimiter - The cell separator. Defaults to `","`.
|
|
8
|
+
* @returns The cells of the line, unquoted and trimmed.
|
|
9
|
+
* @example
|
|
10
|
+
* parseCsvLine('a, "b, c" ,d'); // => ["a", "b, c", "d"]
|
|
11
|
+
* parseCsvLine('"He said ""hi"""'); // => ['He said "hi"']
|
|
12
|
+
* parseCsvLine("a;b", ";"); // => ["a", "b"]
|
|
13
|
+
*/
|
|
14
|
+
export declare function parseCsvLine(line: string, delimiter?: string): string[];
|
|
15
|
+
//# sourceMappingURL=parseCsvLine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parseCsvLine.d.ts","sourceRoot":"","sources":["../../src/csv/parseCsvLine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,SAAM,GAAG,MAAM,EAAE,CAoBpE"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Splits a single CSV line into its cells. A cell wrapped in double quotes may
|
|
3
|
+
* contain the delimiter, and a doubled double quote (`""`) inside it stands for
|
|
4
|
+
* a literal one. Every cell is trimmed.
|
|
5
|
+
*
|
|
6
|
+
* @param line - One line of CSV (no line break).
|
|
7
|
+
* @param delimiter - The cell separator. Defaults to `","`.
|
|
8
|
+
* @returns The cells of the line, unquoted and trimmed.
|
|
9
|
+
* @example
|
|
10
|
+
* parseCsvLine('a, "b, c" ,d'); // => ["a", "b, c", "d"]
|
|
11
|
+
* parseCsvLine('"He said ""hi"""'); // => ['He said "hi"']
|
|
12
|
+
* parseCsvLine("a;b", ";"); // => ["a", "b"]
|
|
13
|
+
*/
|
|
14
|
+
export function parseCsvLine(line, delimiter = ",") {
|
|
15
|
+
const cells = [];
|
|
16
|
+
let current = "";
|
|
17
|
+
let inQuotes = false;
|
|
18
|
+
for (let i = 0; i < line.length; i++) {
|
|
19
|
+
const ch = line.charAt(i);
|
|
20
|
+
if (ch === '"') {
|
|
21
|
+
if (inQuotes && line.charAt(i + 1) === '"') {
|
|
22
|
+
current += '"';
|
|
23
|
+
i++;
|
|
24
|
+
}
|
|
25
|
+
else
|
|
26
|
+
inQuotes = !inQuotes;
|
|
27
|
+
}
|
|
28
|
+
else if (ch === delimiter && !inQuotes) {
|
|
29
|
+
cells.push(current.trim());
|
|
30
|
+
current = "";
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
current += ch;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
cells.push(current.trim());
|
|
37
|
+
return cells;
|
|
38
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serializes rows to CSV. Every cell is wrapped in double quotes (any internal
|
|
3
|
+
* double quote doubled), so delimiters and line breaks inside a cell are safe.
|
|
4
|
+
* Rows are joined with `\n`.
|
|
5
|
+
*
|
|
6
|
+
* @param rows - The rows to serialize, header row included if any.
|
|
7
|
+
* @param delimiter - The cell separator. Defaults to `","`.
|
|
8
|
+
* @returns The CSV content.
|
|
9
|
+
* @example
|
|
10
|
+
* toCsv([["name", "age"], ["Ann", 32]]); // => '"name","age"\n"Ann","32"'
|
|
11
|
+
* toCsv([['say "hi"']]); // => '"say ""hi"""'
|
|
12
|
+
*/
|
|
13
|
+
export declare function toCsv(rows: readonly (readonly (string | number)[])[], delimiter?: string): string;
|
|
14
|
+
//# sourceMappingURL=toCsv.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toCsv.d.ts","sourceRoot":"","sources":["../../src/csv/toCsv.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,wBAAgB,KAAK,CACnB,IAAI,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC,EAAE,EAC/C,SAAS,SAAM,GACd,MAAM,CAQR"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serializes rows to CSV. Every cell is wrapped in double quotes (any internal
|
|
3
|
+
* double quote doubled), so delimiters and line breaks inside a cell are safe.
|
|
4
|
+
* Rows are joined with `\n`.
|
|
5
|
+
*
|
|
6
|
+
* @param rows - The rows to serialize, header row included if any.
|
|
7
|
+
* @param delimiter - The cell separator. Defaults to `","`.
|
|
8
|
+
* @returns The CSV content.
|
|
9
|
+
* @example
|
|
10
|
+
* toCsv([["name", "age"], ["Ann", 32]]); // => '"name","age"\n"Ann","32"'
|
|
11
|
+
* toCsv([['say "hi"']]); // => '"say ""hi"""'
|
|
12
|
+
*/
|
|
13
|
+
export function toCsv(rows, delimiter = ",") {
|
|
14
|
+
return rows
|
|
15
|
+
.map((row) => row
|
|
16
|
+
.map((cell) => `"${String(cell).replace(/"/g, '""')}"`)
|
|
17
|
+
.join(delimiter))
|
|
18
|
+
.join("\n");
|
|
19
|
+
}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC"}
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forthtilliath/ts-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"publishConfig": {
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"jsdom": "^29.1.1",
|
|
27
27
|
"typescript": "^5.9.3",
|
|
28
28
|
"vitest": "^4.1.10",
|
|
29
|
-
"@forthtilliath/eslint-config": "0.
|
|
30
|
-
"@forthtilliath/typescript-config": "0.
|
|
29
|
+
"@forthtilliath/eslint-config": "0.7.0",
|
|
30
|
+
"@forthtilliath/typescript-config": "0.1.1"
|
|
31
31
|
},
|
|
32
32
|
"scripts": {
|
|
33
33
|
"dev": "tsc --watch -p tsconfig.build.json",
|