@quario/csv 0.1.0 → 0.2.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 CHANGED
@@ -7,6 +7,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.2.0] - 2026-09-01
11
+
12
+ ### Added
13
+
14
+ - **A split is one record, its slots the fields.** Slots are values beside
15
+ each other, which is what a record is. Slot widths go unread, as every width
16
+ is here. Images stay unread too, but a slot holding one still writes an
17
+ empty field, so the fields either side keep their positions.
18
+
19
+ ### Changed
20
+
21
+ - **Display-text `Date`s join as ISO 8601 UTC.** A `Date` inside a mixed
22
+ cell (literal text plus interpolation) joined through `String(date)`, so
23
+ the field carried the host's timezone and locale. It now joins through the
24
+ engine's shared display rule as `toISOString()` text — the same form a
25
+ typed single-`Date` field has always used, so every `Date` in a CSV now
26
+ reads the same way.
27
+
10
28
  ## [0.1.0] - 2026-08-27
11
29
 
12
30
  ### Added
package/lib/index.js CHANGED
@@ -7,7 +7,7 @@
7
7
  * then RFC 4180 quoting. Styles, widths, page bands, and images go unread.
8
8
  * The unlicensed marking is a trailing line, so record 1 stays the report's.
9
9
  */
10
- import { text, typed, walk } from "quario";
10
+ import { display, text, typed, walk } from "quario";
11
11
 
12
12
  /** Formula guard, then RFC 4180 quoting. Typed fields skip this.
13
13
  * @type {(s: string) => string} */
@@ -19,8 +19,9 @@ let format = (s) => {
19
19
  /** @type {(cell: { tokens: any[] }) => string} */
20
20
  let field = (cell) => {
21
21
  let value = typed(cell.tokens);
22
+ // The typed branch only skips the formula guard; display() owns the text.
22
23
  if (value === undefined) return format(text(cell.tokens));
23
- return value instanceof Date ? value.toISOString() : String(value);
24
+ return display(value);
24
25
  };
25
26
 
26
27
  /**
@@ -39,6 +40,12 @@ export function csv() {
39
40
  let out = "";
40
41
  /** @type {string | undefined} */
41
42
  let marking;
43
+ // The fields of the split being filled, if any. A split is one record of
44
+ // its own -- the slots are values beside each other, which is what a
45
+ // record is -- so its items are collected here instead of each taking a
46
+ // record. Splits never nest, so one buffer is enough.
47
+ /** @type {string[] | null} */
48
+ let split = null;
42
49
  let record = (/** @type {any} */ event) => {
43
50
  out += event.cells.map(field).join(",") + "\n";
44
51
  };
@@ -47,7 +54,23 @@ export function csv() {
47
54
  if (event.marking) marking = event.marking;
48
55
  },
49
56
  item: (event) => {
50
- out += field(event) + "\n";
57
+ if (split) split.push(field(event));
58
+ else out += field(event) + "\n";
59
+ },
60
+ // Images go unread by this target, but a slot holding one still holds
61
+ // its place in the record, so the fields either side of it stay in
62
+ // their columns.
63
+ image: () => {
64
+ if (split) split.push("");
65
+ },
66
+ "split-start": () => {
67
+ split = [];
68
+ },
69
+ "split-end": () => {
70
+ // The engine emits the bracket as one array, so a `split-end` always
71
+ // has its opening and `split` is never null here.
72
+ out += /** @type {string[]} */ (split).join(",") + "\n";
73
+ split = null;
51
74
  },
52
75
  "table-start": (event) => {
53
76
  out +=
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quario/csv",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "The CSV render target for quario — in the makings, not yet released",
5
5
  "homepage": "https://getquario.com",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -38,12 +38,12 @@
38
38
  "devDependencies": {
39
39
  "@arethetypeswrong/cli": "^0.18.3",
40
40
  "@size-limit/preset-small-lib": "^13.0.3",
41
- "quario": "^0.1.0",
41
+ "quario": "^0.2.0",
42
42
  "size-limit": "^13.0.3",
43
43
  "typescript": "^7.0.2"
44
44
  },
45
45
  "peerDependencies": {
46
- "quario": "^0.1.0"
46
+ "quario": "^0.2.0"
47
47
  },
48
48
  "size-limit": [
49
49
  {