@quario/xlsx 0.5.0 → 0.7.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,85 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.7.0] - 2026-09-07
11
+
12
+ ### Added
13
+
14
+ - **Styled runs become rich text.** A cell of more than one styled run is written
15
+ as rich text, each run's font merged over the cell's — so bold, italic,
16
+ underline, strikethrough, size, face and colour survive into the grid. A
17
+ run-level `background` is not read: a spreadsheet's rich-text runs carry fonts
18
+ only, and filling the cell would colour text nobody asked to colour. A cell of
19
+ exactly one run stays a typed cell, so a single styled amount is still a
20
+ number.
21
+
22
+ - **A run inside a sentence presents its value.** A run holding one
23
+ interpolation under a `format` shows the same decimals here as on the page,
24
+ where a mixed cell used to show the bare value.
25
+
26
+ ## [0.6.0] - 2026-09-07
27
+
28
+ ### Added
29
+
30
+ - **A date cell's number format follows the `form` its report declares.** The
31
+ four forms map to `dd/mm/yy`, `dd mmm yyyy`, `dd mmmm yyyy` and
32
+ `dddd, dd mmmm yyyy`. The shape is the document's; the language a month or
33
+ weekday name is spelled in stays the reader's, because that is what a
34
+ spreadsheet application supplies and pinning it would stop the file reading
35
+ naturally for whoever opens it.
36
+
37
+ - **A declared digit count builds the pattern.** A `number` cell asking for
38
+ three digits writes `#,##0.000`, and a `currency` cell asking for none writes
39
+ `"EUR"#,##0` — the same count the page presents, taken off the declaration
40
+ the engine resolved rather than computed here.
41
+
42
+ - **A cell's own `currency` code picks the number format**, ahead of the
43
+ instance's default: `"JPY"#,##0` where the row says `JPY`, since the code
44
+ decides the digits too. The cell stays a number either way. A code the engine
45
+ could not accept writes no number format at all, rather than labelling the
46
+ cell in the instance's currency.
47
+
48
+ ### Changed
49
+
50
+ - **A `date` cell with no declared form now writes `dd mmm yyyy`, not
51
+ `yyyy-mm-dd`.** A bare `date` means the `medium` form throughout, so the grid
52
+ agrees with the page. A report that wants the ISO shape has no form for it;
53
+ the nearest is `{ "kind": "date", "form": "short" }`, which writes
54
+ `dd/mm/yy`. The cell is still a real typed date either way.
55
+
56
+ - **A cell's number format now comes from the engine's fraction-digit count
57
+ rather than from four patterns this target held of its own.** The visible
58
+ change is `currency`: the pattern followed the currency's own minor units,
59
+ so an amount in a currency with none — JPY — is `"JPY"#,##0` where it was
60
+ `"JPY"#,##0.00`, and one with three is `"BHD"#,##0.000`. `number`
61
+ (`#,##0.00`), `percent` (`0.00%`) and `date` (`yyyy-mm-dd`) are unchanged in
62
+ a worksheet; what changed for those is that HTML and PDF now show the same
63
+ decimals the grid always did, instead of their own.
64
+
65
+ - A `currency` code that is not a readable currency no longer produces a number
66
+ format at all. The cell keeps its value; before, the code was pasted straight
67
+ into a pattern while every other target fell back to the unformatted value.
68
+
69
+ Only the digit count is shared. The grouping separator and the symbol's
70
+ position still come from the application that opens the file, which is what
71
+ lets one workbook read naturally wherever it is opened.
72
+
73
+ ### Fixed
74
+
75
+ - A `format` kind reaching this target from an `=` expression is now looked up
76
+ as an own key. Before, a kind resolving to the name of a built-in object
77
+ member threw out of the render (`valueOf`, `hasOwnProperty`) or wrote
78
+ `[object Undefined]` into the cell's number format (`toString`). A literal
79
+ was never affected: it is checked against the four kinds.
80
+
81
+ ### Fixed
82
+
83
+ - **An image whose size cannot be read now names the item that asked for it.**
84
+ The failure said only that the size could not be read from the bytes, so a
85
+ report with two pictures gave no way to tell which one was bad. The message
86
+ now begins with the item's `source` path, as every other render error does
87
+ and as it does from every other target.
88
+
10
89
  ## [0.5.0] - 2026-09-05
11
90
 
12
91
  ### Added
package/README.md CHANGED
@@ -74,10 +74,13 @@ host. Render-time failures reject with located errors.
74
74
 
75
75
  One worksheet, named `Report`, with the banded walk flattened onto it as rows in render order:
76
76
  report-header items, then per group instance its header items, nested content, and footer items,
77
- then the table's header row, data rows, and total row, then report-footer items. Grouping shows up
78
- as that order alone. Group boundaries add no rows of their own, and `break: "page"` is ignored.
77
+ then the table's header row, data rows, and total rows, then report-footer items. Grouping shows up
78
+ as that order alone. Group boundaries add no rows of their own, and `break: "page"` and
79
+ `reset: "page"` are ignored, as are `page.margin` and a report header's `height`.
79
80
 
80
- Each item takes one row with its cell in the first column, unmerged. Two band roles carry an
81
+ Each item takes one row with its cell in the first column, unmerged; a split takes one row with its
82
+ slots as the cells across it (slot widths withdrawn, a slot rendering nothing an empty cell), and a
83
+ spanning header or total cell is a merged range. Two band roles carry an
81
84
  omakase default that the author's own style always overrides: report-header items render bold at
82
85
  size 14, group-header items render bold.
83
86
 
@@ -92,11 +95,23 @@ inert literal text: no formula-injection surface, and no apostrophe mangling eit
92
95
 
93
96
  A hidden cell keeps its column slot as an empty cell that retains its style.
94
97
 
98
+ ### Number formats
99
+
100
+ `format` writes a number format so the grid presents what the other targets do. `date` builds
101
+ its pattern from the cell's `form` (`dd mmm yyyy` undeclared), with month and weekday names
102
+ spelled by the reader's application; the number kinds build theirs from the declaration's
103
+ fraction-digit count — an undeclared `number` is `#,##0.00`, `percent` is `0.00%`,
104
+ `{ "kind": "number", "digits": 3 }` is `#,##0.000` — and `currency` is the code the cell wears
105
+ — its own `currency` when it declares one, else the instance's — over that currency's minor
106
+ units unless `digits` says otherwise: `"USD"#,##0.00`, `"JPY"#,##0`, `"BHD"#,##0.000`. A kind
107
+ on the wrong type, or a code the engine cannot read, writes no format.
108
+
95
109
  ### Images
96
110
 
97
111
  An image item is not a cell: it takes one worksheet row as its anchor and floats over the sheet as a
98
- drawing at its natural pixel size. Placement here is best-effort. `fit`, `alt`, and `style` go
99
- unread, and all of it may change without a breaking change.
112
+ drawing at its natural pixel size. Placement here is best-effort. `fit`, `alt`, and `style` are
113
+ unused, and all of it may change without a breaking change. Bytes too short to carry a size reject
114
+ the render rather than vanish.
100
115
 
101
116
  ### Styles
102
117
 
@@ -107,8 +122,13 @@ unread, and all of it may change without a breaking change.
107
122
  | `color`, `background` | Font colour, solid fill |
108
123
  | `align` | Horizontal alignment |
109
124
  | `valign` | Vertical alignment; undeclared writes nothing, so the spreadsheet application keeps its own default |
125
+ | `border*` | Cell borders (`solid` → `thin`, `dashed`, `dotted`; width approximated); a row's borders arrive on its cells already |
126
+ | `format`, `currency` | A number format — see [Number formats](#number-formats) |
127
+ | `uppercase`, `padding*`, `spaceBefore`, `spaceAfter` | Not read: a grid has no text-transform, no cell inset of its own, and no flow |
110
128
 
111
- Style blocks layer row under cell, as everywhere in quario.
129
+ Style blocks layer row under cell, as everywhere in quario, with the report default outermost.
130
+ Every cell is written at 10 points unless something declares otherwise, and a cell whose display
131
+ contains a newline wraps.
112
132
 
113
133
  ### Freeze
114
134
 
@@ -116,14 +136,14 @@ The first table's header row anchors the frozen view. Everything from that row u
116
136
  while the body scrolls, the spreadsheet analogue of the PDF target's repeated headers. A report
117
137
  without a table freezes nothing. This is normative.
118
138
 
119
- ### Widths are not read
139
+ ### Widths are withdrawn
120
140
 
121
141
  Column `width` percentages size nothing here, and every worksheet column keeps the application
122
142
  default. A width is a share of the _table_ width, and a worksheet's columns are global to the sheet.
123
143
  Column A carries the flattened band item rows and the table's first column alike, so there is no
124
144
  table for a share to be a share of.
125
145
 
126
- ### Page columns are not read
146
+ ### Page columns are withdrawn
127
147
 
128
148
  A page column count sizes and splits nothing here, and will not change, as `break: "page"` is
129
149
  ignored. Page columns are strips of a page, and this target has no page to strip.
package/lib/cell.js CHANGED
@@ -2,43 +2,84 @@
2
2
  * From an event cell to a plain cell descriptor `{ value, format }`, built on
3
3
  * the engine's `typed` stream rule. `value` is a native number, boolean, or
4
4
  * Date when the cell is one bare interpolation (so numbers stay computable in
5
- * the sheet), and the display-text join otherwise. `format` is the resolved
6
- * cell-level formatting from the style module. Display text that contains a
7
- * newline gains `wrapText` so the break is visible in the grid.
5
+ * the sheet), the worksheet's rich-text shape when the cell holds more than
6
+ * one styled run, and the display-text join otherwise. `format` is the
7
+ * resolved cell-level formatting from the style module. Display text that
8
+ * contains a newline gains `wrapText` so the break is visible in the grid.
8
9
  */
9
- import { text, typed } from "quario";
10
- import { format as look, merge } from "./style.js";
10
+ import { currencyOf, display, format as present, styledRuns, text, typed } from "quario";
11
+ import { font, format as look, merge } from "./style.js";
12
+
13
+ // The digit count is the engine's, never this target's: it rides on the
14
+ // resolved declaration the stream carries, the same one HTML and PDF
15
+ // stringify from, so a cell shows the same decimals in the grid as it does on
16
+ // the page (docs/adr/0054, docs/adr/0056). What stays this target's own is
17
+ // the form — the reader's application supplies the grouping separator, the
18
+ // symbol's place, and the language a month name is spelled in.
19
+ /** @type {(digits: number | undefined) => string} */
20
+ let places = (digits) => (digits ? "." + "0".repeat(digits) : "");
11
21
 
12
22
  /** @type {(value: any, fmt: string) => string | null} */
13
23
  let whenNum = (value, fmt) => (typeof value === "number" ? fmt : null);
14
- /** @type {(value: any) => string | null} */
15
- let whenDate = (value) => (value instanceof Date ? "yyyy-mm-dd" : null);
16
- /** @type {(value: any, currency: any) => string | null} */
17
- let whenMoney = (value, currency) =>
18
- typeof value === "number" && typeof currency === "string" && currency
19
- ? '"' + currency + '"#,##0.00'
20
- : null;
21
- /** @type {Record<string, (value: any, currency: any) => string | null>} */
22
- let NUMFMT = {
23
- number: (value) => whenNum(value, "#,##0.00"),
24
- percent: (value) => whenNum(value, "0.00%"),
25
- date: (value) => whenDate(value),
26
- currency: (value, currency) => whenMoney(value, currency),
24
+ // A date's form is honoured as far as a sheet can honour one: the *shape* is
25
+ // the author's, and the language of a month or weekday name is the reader's,
26
+ // because Excel spells `mmmm` and `dddd` in whoever opens the file's
27
+ // application language. Pinning that would take a `[$-...]` locale prefix and
28
+ // would stop the sheet following its reader, which docs/adr/0054 refuses. The
29
+ // day-first ordering is the author's here too, and that is the second half of
30
+ // the same approximation (CONTEXT.md, "Form").
31
+ /** @type {Record<string, string>} */
32
+ let DATE_FMT = {
33
+ short: "dd/mm/yy",
34
+ medium: "dd mmm yyyy",
35
+ long: "dd mmmm yyyy",
36
+ full: "dddd, dd mmmm yyyy",
27
37
  };
28
- /** @type {(kind: any, value: any, currency: any) => string | null} */
29
- let numFmtOf = (kind, value, currency) => {
30
- let rule = NUMFMT[kind];
31
- return rule ? rule(value, currency) : null;
38
+ /** @type {(value: any, decl: any) => string | null} */
39
+ let whenDate = (value, decl) =>
40
+ value instanceof Date && Object.hasOwn(DATE_FMT, decl.form) ? DATE_FMT[decl.form] : null;
41
+ /** @type {(value: any, decl: any, currency: any) => string | null} */
42
+ let whenMoney = (value, decl, currency) => {
43
+ // The value first: a text cell in a money column would otherwise pay for a
44
+ // pattern it cannot wear. Then the count — a code the engine will not read
45
+ // resolved to no digits at all, so the cell keeps its value and gains no
46
+ // number format, the same withdrawal `format()` makes.
47
+ if (typeof value !== "number" || decl.digits === undefined) return null;
48
+ return '"' + currency + '"#,##0' + places(decl.digits);
32
49
  };
50
+ /** @type {Record<string, (value: any, decl: any, currency: any) => string | null>} */
51
+ let NUMFMT = {
52
+ number: (value, decl) => whenNum(value, "#,##0" + places(decl.digits)),
53
+ percent: (value, decl) => whenNum(value, "0" + places(decl.digits) + "%"),
54
+ date: whenDate,
55
+ currency: whenMoney,
56
+ };
57
+ // Own-key lookup, as everywhere a resolved declaration indexes a table: the
58
+ // declaration reaches here having been resolved from author data, and
59
+ // `valueOf` or `toString` as a kind would otherwise reach a member of
60
+ // `Object.prototype` and either throw out of the render or write its return
61
+ // value as a number format.
62
+ /** @type {(decl: any, value: any, currency: any) => string | null} */
63
+ let numFmtOf = (decl, value, currency) =>
64
+ !!decl && typeof decl === "object" && Object.hasOwn(NUMFMT, decl.kind)
65
+ ? NUMFMT[decl.kind](value, decl, currency)
66
+ : null;
33
67
 
34
- /** @type {(cell: { tokens: any[] }, kind: any) => any} */
35
- let shownOf = (cell, kind) => {
36
- let value = typed(cell.tokens, kind);
68
+ /** @type {(cell: { tokens: any[] }, decl: any) => any} */
69
+ let shownOf = (cell, decl) => {
70
+ let value = typed(cell.tokens, decl);
37
71
  return value !== undefined ? value : text(cell.tokens);
38
72
  };
73
+ // The code is spliced into the format string rather than looked up as a
74
+ // symbol, so it must be a code and nothing else. It is: the engine gates a
75
+ // resolved `currency` before it crosses, which is why an author-data code
76
+ // (`currency: "=@.ccy"`) can reach a number format at all (docs/adr/0041).
77
+ // Which code wins is the engine's rule too, taken from `currencyOf` rather
78
+ // than restated: this target needs the code itself where the display targets
79
+ // need presented text, and the two must not drift apart about a denomination.
39
80
  /** @type {(out: any, resolved: any, shown: any, intl: any) => void} */
40
81
  let paintFmt = (out, resolved, shown, intl) => {
41
- let numFmt = numFmtOf(resolved?.format, shown, intl?.currency);
82
+ let numFmt = numFmtOf(resolved?.format, shown, currencyOf(resolved, intl));
42
83
  if (numFmt) out.numFmt = numFmt;
43
84
  };
44
85
  /** @type {(out: any, shown: any) => void} */
@@ -47,14 +88,62 @@ let paintWrap = (out, shown) => {
47
88
  out.alignment = { ...out.alignment, wrapText: true };
48
89
  };
49
90
 
91
+ // One run's presented text: literals verbatim, every value through the
92
+ // declaration that run resolved. A run holding a single value token presents
93
+ // it, so a formatted amount inside a sentence reads the same here as it does
94
+ // on the page -- SCHEMA.md pins that the fraction digits are the same in every
95
+ // target that presents, and this target presents (ADR 0061). A run the engine
96
+ // withdrew the declaration from has nothing to present with and falls to
97
+ // display text, which is what the whole cell used to do.
98
+ /** @type {(tokens: any[], style: any, intl: any) => string} */
99
+ let shownText = (tokens, style, intl) => {
100
+ let out = "";
101
+ for (let token of tokens)
102
+ out +=
103
+ "literal" in token
104
+ ? token.literal
105
+ : (present(token.value, style, intl) ?? display(token.value));
106
+ return out;
107
+ };
108
+
109
+ // A cell of more than one styled run takes the worksheet's rich-text shape:
110
+ // each run's **font half** merged over the cell font, and nothing else. A
111
+ // run-level `background` is inert -- spreadsheet rich-text runs carry fonts
112
+ // only, and filling the cell would colour text the author did not name -- and
113
+ // so is a run-level number format, since a cell has one and this cell is text.
114
+ // No typed cell is lost: a cell of more than one run holds more than one token
115
+ // and was display text already.
116
+ /** @type {(cell: any, styled: any[], under: any, intl: any) => any} */
117
+ let rich = (cell, styled, under, intl) => {
118
+ let base = merge(under, cell.style);
119
+ let out = look(base);
120
+ let parts = styled.map((one) => {
121
+ let style = one.style ? merge(base, one.style) : base;
122
+ return { font: font(style), text: shownText(one.tokens, style, intl) };
123
+ });
124
+ paintWrap(out, parts.map((part) => part.text).join(""));
125
+ return { value: { richText: parts }, format: out };
126
+ };
127
+
128
+ // The style a cell of one styled run wears: that run's resolved answer, which
129
+ // already carries the cell's own declarations, or the cell's where it has no
130
+ // run at all.
131
+ /** @type {(cell: any, styled: any[]) => any} */
132
+ let soleStyle = (cell, styled) => styled[0]?.style ?? cell.style;
133
+
50
134
  /**
51
135
  * Resolve one event cell against its enclosing style (a row's style, or an
52
136
  * item's band-role default — the layer under the cell's own).
53
137
  *
138
+ * A cell of exactly one styled run wears that run's answer whole, so a single
139
+ * styled amount is still a number in the grid.
140
+ *
54
141
  * @type {(cell: { tokens: any[], style?: any }, under: any, intl?: any) => { value: any, format: any }}
55
142
  */
56
143
  let field = (cell, under, intl) => {
57
- let resolved = merge(under, cell.style);
144
+ let styled = styledRuns(cell.tokens);
145
+ if (styled.length > 1) return rich(cell, styled, under, intl);
146
+ let resolved = merge(under, soleStyle(cell, styled));
58
147
  let shown = shownOf(cell, resolved?.format);
59
148
  let out = look(resolved);
60
149
  paintFmt(out, resolved, shown, intl);
package/lib/index.js CHANGED
@@ -15,7 +15,7 @@
15
15
  * the packing time. Byte-for-byte output is a goal for the writer that will
16
16
  * replace `workbook.js`.
17
17
  */
18
- import { walk } from "quario";
18
+ import { imageError, walk } from "quario";
19
19
  import { field } from "./cell.js";
20
20
  import { merge as under } from "./style.js";
21
21
  import { pixels } from "./image.js";
@@ -27,19 +27,24 @@ import { append, create, embed, freeze, mark, place, save, sheet, span } from ".
27
27
 
28
28
  // Band-role omakase defaults, applied under the author's own style so a
29
29
  // declared style always wins. Only the headline roles carry one; every other
30
- // band writes plain cells. The PDF target carries the same two, byte-identical,
31
- // in its own `style.js` SCHEMA.md states the pair for both, so they move
32
- // together, and a target imports only public engine helpers so there is nowhere
33
- // to share them from.
30
+ // band writes plain cells. SCHEMA.md states the pair, and a target imports only
31
+ // public engine helpers so there is nowhere to share them from.
34
32
  //
35
33
  // `@quario/html` deliberately carries none of them: its consumer has a
36
34
  // stylesheet and the `q-*` classes are the seam, where a worksheet has neither.
37
35
  // The rule is docs/adr/0014-a-target-supplies-defaults-only-where-its-consumer-has-no-seam.md —
38
36
  // a target supplies defaults only where its consumer has no seam to supply
39
- // them. `@quario/html/style.css` and `packages/viewer/lib/style.js` supply them for
40
- // that target; keep all four in agreement.
37
+ // them.
38
+ //
39
+ // `test/omakase-defaults.test.js` is what holds the copies in agreement. This
40
+ // comment names the gate rather than listing the files, because the list is
41
+ // what rotted: it used to name `packages/viewer/lib/style.js` and a `style.js`
42
+ // of the PDF target's own, and neither file exists.
41
43
  /** @type {Record<string, any>} */
42
- let ROLES = { "report-header": { bold: true, size: 14 }, "group-header": { bold: true } };
44
+ let ROLES = {
45
+ "report-header": { bold: true, size: 14 },
46
+ "group-header": { bold: true },
47
+ };
43
48
 
44
49
  // This target's baseline type size, written into every cell rather than left
45
50
  // to the writer's own 11. The PDF target carries the same 10, and once a report
@@ -138,7 +143,11 @@ export function xlsx(options) {
138
143
  // The report default over this target's baseline. The marking is
139
144
  // written under the baseline alone: an author's `style` must not be
140
145
  // able to resize it (docs/adr/0002).
141
- intl = { locale: event.locale, currency: event.currency, timeZone: event.timeZone };
146
+ intl = {
147
+ locale: event.locale,
148
+ currency: event.currency,
149
+ timeZone: event.timeZone,
150
+ };
142
151
  if (event.style) base = under(BASELINE, event.style);
143
152
  if (event.marking) {
144
153
  mark(workbook, event.marking);
@@ -163,7 +172,11 @@ export function xlsx(options) {
163
172
  "split-start": (event) => {
164
173
  // The split's own style layers over its band-role default, so a styled
165
174
  // split keeps the weight a plain item in the same band would have.
166
- split = { fields: [], images: [], under: under(roleOf(event), event.style) };
175
+ split = {
176
+ fields: [],
177
+ images: [],
178
+ under: under(roleOf(event), event.style),
179
+ };
167
180
  },
168
181
  "split-end": () => {
169
182
  // The engine emits the bracket as one array, so a `split-end` always
@@ -188,8 +201,10 @@ export function xlsx(options) {
188
201
  // The engine vouched for the magic numbers, not for the rest of the
189
202
  // file. A header too short to carry a size leaves nothing to place a
190
203
  // drawing at, and failing beats dropping the picture in silence
191
- // (SCHEMA.md, "Image item").
192
- if (!size) throw Error("image: could not read the image's size from its bytes");
204
+ // (SCHEMA.md, "Image item"). Named on the item through the engine's
205
+ // own mint, so this failure reads the same from here as it does from
206
+ // a target that paints or embeds.
207
+ if (!size) throw imageError(event.path, "could not read the image's size from its bytes");
193
208
  known = { ...size, id: embed(workbook, event.bytes, event.format) };
194
209
  images.set(event.bytes, known);
195
210
  }
@@ -205,12 +220,7 @@ export function xlsx(options) {
205
220
  place(worksheet, known.id, known, append(worksheet, []));
206
221
  },
207
222
  "table-start": (event) => {
208
- let row = merged(
209
- event.columns
210
- .filter((/** @type {any} */ column) => column.header)
211
- .map((/** @type {any} */ column) => column.header),
212
- event.style,
213
- );
223
+ let row = merged(event.header.cells, event.header.style);
214
224
  if (!frozen) {
215
225
  freeze(worksheet, row);
216
226
  frozen = true;
package/lib/style.js CHANGED
@@ -138,4 +138,4 @@ let format = (style) => {
138
138
  return put(out, "alignment", alignment(style));
139
139
  };
140
140
 
141
- export { format, merge };
141
+ export { font, format, merge };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quario/xlsx",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "The spreadsheet render target for quario — in the makings, not yet released",
5
5
  "homepage": "https://getquario.com",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -42,12 +42,12 @@
42
42
  "@arethetypeswrong/cli": "^0.18.3",
43
43
  "@size-limit/preset-small-lib": "^13.0.3",
44
44
  "@types/node": "^22.20.1",
45
- "quario": "^0.5.0",
45
+ "quario": "^0.7.0",
46
46
  "size-limit": "^13.0.3",
47
47
  "typescript": "^7.0.2"
48
48
  },
49
49
  "peerDependencies": {
50
- "quario": "^0.5.0"
50
+ "quario": "^0.7.0"
51
51
  },
52
52
  "size-limit": [
53
53
  {