quario 0.12.0 → 0.14.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
@@ -1,5 +1,165 @@
1
1
  # quario
2
2
 
3
+ ## 0.14.0
4
+
5
+ ### Minor Changes
6
+
7
+ - **`quario(options)` now refuses an option it does not understand, like every target factory.** Before, the engine read the keys it knew and ignored the rest. A typo such as `quario({ licence })` therefore marked every render as unlicensed, and nothing said why. Now an unknown key, a value of the wrong type, or an `options` that is not an object throws a `TypeError` at the call. The message names the option path, such as `options.license`.
8
+
9
+ **`locale`, `timeZone` and `currency` are now checked at the call.** Before, a value that `Intl` refused did not fail. Every formatted cell showed its raw value instead. Now `quario({ locale: "en_US" })` and `quario({ timeZone: "Europe/Amsterdm" })` throw a `TypeError`. `currency` must be three upper-case letters, the same rule that a cell's own `currency` declaration follows. A cell's own `currency` still fails soft.
10
+
11
+ **The `query` budgets are now checked at the call.** Before, the engine checked them only when a report compiled its first query. A report with no query never reported a bad budget. The error still comes from padvinder, in its own words.
12
+
13
+ **`plan(schema, functions, options)` now refuses an unknown key in `options`.** Before, `{ target: [...] }` checked nothing and said nothing. A `targets` that is not an array also throws a `TypeError`.
14
+
15
+ **A bad `schemes` allowlist now throws a `TypeError`, not an `Error`.** The message starts with `options.schemes:`, not `schemes:`. A `null` allowlist still throws.
16
+
17
+ **What this changes for you.** An options object that carries keys for another consumer stops working when you pass it to `quario()`. Pass `quario()` only the six keys it takes: `query`, `license`, `locale`, `currency`, `timeZone` and `schemes`.
18
+
19
+ - **A group can now order and cut its instances.** Declare `instances` beside `sort`, with an optional `sort` and an optional `take` inside it. They order and cut the group's instances, as the group's own `sort` and `take` order and cut the rows inside each instance. Each `instances.sort` key reads the group's own handle once per instance, so `instances: { sort: [{ by: "=region.subtotal", dir: "desc" }], take: 5 }` keeps the five regions with the largest subtotals, largest first. `@` and `run` are unbound there. A dropped instance never renders, and no running value steps over it. The totals around the group still count it, as they count a row that a group's `take` drops. A group without `instances` renders every instance in first-seen order, so existing reports render as before.
20
+ - **An image item now accepts SVG bytes.** Before, `source` had to yield PNG or JPEG bytes, and SVG bytes were a render error. Now the engine also names UTF-8 text whose root element is `<svg` as an SVG, and the image event carries `format: "svg"`. The engine reads the size from the root's `width` and `height` when both are absolute lengths, and else from its `viewBox`. An SVG that states no size this way is the same render error as a PNG that is too short to state its size. The message for bytes that are not an image now says "PNG, JPEG or SVG".
21
+
22
+ The HTML target puts an SVG in an `<img>` under `data:image/svg+xml`, so the SVG never becomes markup in the fragment. The PDF target draws an SVG as vector paths. It draws no picture that the SVG names, and it fetches nothing. SVG `<text>` draws in the standard Helvetica. The viewer paints an SVG through a `data:` URI, so a page that shows one needs the Content Security Policy grant `img-src data:`. A PNG or a JPEG still needs no grant there. The XLSX and DOCX targets cannot draw an SVG, so an SVG image is a render error that names the item.
23
+
24
+ ### Patch Changes
25
+
26
+ - **The package now carries edition 1.1 of the Quario License Agreement.** A license now covers one production deployment, not one developer. Each deployment needs one license key. Development, staging, CI and test environments need no key. A key covers every release dated up to one year after you buy it, and those releases stay licensed for good. A key is not a subscription, and it never renews automatically. A refunded or reversed payment voids the keys it bought. Software that your customers install or resell needs separate OEM terms.
27
+
28
+ ## 0.13.0
29
+
30
+ ### Minor Changes
31
+
32
+ - A band gains a `grid` item: splits that share one column geometry.
33
+
34
+ A statement is twenty lines of a label and an amount, on the same two widths. As splits, each line restated its widths:
35
+
36
+ ```jsonc
37
+ { "type": "split", "slots": [
38
+ { "type": "text", "value": "Opening", "width": 70 },
39
+ { "type": "text", "value": "{{ @.opening }}", "width": 30, "style": { "align": "right" } }
40
+ ] }
41
+ ```
42
+
43
+ A grid states the widths, and each column's style, once:
44
+
45
+ ```jsonc
46
+ {
47
+ "type": "grid",
48
+ "columns": [{ "width": 70 }, { "width": 30, "style": { "align": "right" } }],
49
+ "rows": [
50
+ { "slots": [{ "type": "text", "value": "Opening" }, { "type": "text", "value": "{{ @.opening }}" }] },
51
+ {},
52
+ { "slots": [{ "type": "text", "value": "Total" }, { "type": "text", "value": "{{ @.total }}" }], "style": { "bold": true } }
53
+ ]
54
+ }
55
+ ```
56
+
57
+ A row is a split without `type`, and it keeps every rule a split has. A column's `style` is the layer under each of its slots, and a slot's own declarations win. A row that names fewer slots than there are columns leaves the rest empty, so `{}` is a spacer line and a one-slot row is a label-only line.
58
+
59
+ Each row reaches a target as the split it is, so the event stream does not change and no target needed an update. No existing report changes.
60
+
61
+ - The package now ships a JSON Schema of the report document.
62
+
63
+ The file is `lib/schema.json`, and the package exports it as `quario/schema.json`. Point `$schema` at the installed copy, and an editor checks the document and shows the documentation for each key:
64
+
65
+ ```jsonc
66
+ { "$schema": "./node_modules/quario/lib/schema.json", "data": "$.orders[*]" }
67
+ ```
68
+
69
+ A report document accepts one new top-level key, `$schema`. Its value must be a string. The engine checks the type and reads nothing else, so a document keeps its `$schema` through an upgrade. Anywhere below the top level, `$schema` stays an unknown key.
70
+
71
+ The JSON Schema proves the shape of each value, and `validate()` still proves the document. A document can pass the JSON Schema and fail `validate()`: a rule across two values, a reserved name, or an expression that does not compile. The strict structured-output modes of OpenAI and Anthropic do not accept the file, because a report document leaves most of its keys out.
72
+
73
+ The TypeScript declarations are stricter in one place. A parameter's value under `params` is now typed as any JSON value except a plain object. The engine always read a plain object there as a declaration, so a document that the new type refuses was never the document it looked like.
74
+
75
+ - **A license key has an end date and no start date.** A key covers every version released on or before its `to` date. Before, a key also named a `from` date, and a version released before that date stayed marked. The engine now ignores a `from` in a key. When a key ends before the release date of the installed version, the warning names both dates.
76
+ - A value the runtime has no text form for is now a located render error rather than `[object Object]` in the document.
77
+
78
+ A cell reaches its reader through `String(value)`. A plain object, a `Map` and a `Set` have no text form of their own, so that falls back to a tag: `[object Object]`, `[object Map]`, `[object Set]`. A tag lays out, paginates and lands in a worksheet cell, and the document is wrong. A few values have no text form at all, and `String()` throws on them — an object with no prototype, a boxed symbol. The engine now refuses both kinds and names the cell:
79
+
80
+ ```
81
+ detail[0].value [{{ @.address }}]: a value with no text form, which would print as [object Object]
82
+ ```
83
+
84
+ The rule reads the value, not its source, so a registered function's result and a data field answer to it alike. A value that says what it is still prints it: a class with its own `toString`, an array (`[1, 2]` prints `1,2`), a `Date`. An absent read still prints nothing. A computed property is outside the rule, because a group's `by` is an identity rather than text — `by: "=@"` makes each row its own instance — and a `where` and a `visible` are read for truth.
85
+
86
+ Every entry in the function registry must be a function. `plan` reports one that is not at `functions.<name>`, where before it raised an unhandled `TypeError` out of `plan` itself at a caller who had only asked a question.
87
+
88
+ A report that printed `[object Object]` stops rendering. It was printing a value no reader could use.
89
+
90
+ - A document may now name its paper and turn it, and its margin may name each side.
91
+
92
+ ```jsonc
93
+ {
94
+ "page": {
95
+ "size": "letter",
96
+ "orientation": "landscape",
97
+ "margin": { "top": 36, "right": 29, "bottom": 36, "left": 29 }
98
+ }
99
+ }
100
+ ```
101
+
102
+ `page.size` takes `"A4"` or `"letter"`. A `[width, height]` pair stays a target option. `page.orientation` takes `"portrait"` or `"landscape"`, and it turns whichever paper is in force. `page.margin` still takes one number for all four sides.
103
+
104
+ The rule `page.margin` already followed now covers all three keys. The document's key wins where it declares one, a target option applies where it does not, and both declaring the same key is a render error. `orientation` in a document beside a target's `size` is not both.
105
+
106
+ Each target writes the paper: the PDF and the layout draw on it, HTML writes an `@page` size and per-side margin, and DOCX writes `pgSz` with `w:orient` and `pgMar` per side. XLSX writes the paper code, the orientation and each print margin. CSV withdraws all three.
107
+
108
+ The capability descriptors gain `page.size` and `page.orientation`, and both are names a document may mark `required`.
109
+
110
+ A target's margin error now reads `expected a non-negative number, or { top, right, bottom, left }, that leaves the page room`.
111
+
112
+ - `params` is now what the report declares it needs, and a render may supply one.
113
+
114
+ A bare value under `params` still **is** the parameter's value, so a document of constants reads the way it always did:
115
+
116
+ ```jsonc
117
+ { "params": { "year": 2025, "branded": true } }
118
+ ```
119
+
120
+ A plain object is a **declaration** instead, closed at `default` and `type`:
121
+
122
+ ```jsonc
123
+ {
124
+ "params": {
125
+ "year": { "type": "number", "default": 2025 },
126
+ "region": { "type": "string" }
127
+ }
128
+ }
129
+ ```
130
+
131
+ `type` names a JSON kind — `string`, `number`, `boolean`, `array`, `object` — because a parameter is a JSON value. There is no `date` and no `enum`.
132
+
133
+ **`default` absent makes the parameter required.** The engine rejects a render that supplies no value for it, before any expression runs. That is the main thing declaring buys: a report that states what it needs hears about it when a render does not bring it.
134
+
135
+ A host supplies values as the last argument to `render` and to `stream`:
136
+
137
+ ```js
138
+ await report.render(html(), data, { region: "EU" });
139
+ ```
140
+
141
+ Only a declared key may be supplied, a supplied value answers to the declared `type`, and values stay JSON and deep-frozen — now per render rather than once at compile.
142
+
143
+ **One kind of document changes meaning.** The engine reads an object-valued parameter as a declaration, so a document that wrote one for its value wraps it:
144
+
145
+ ```jsonc
146
+ { "params": { "config": { "default": { "retries": 3 } } } }
147
+ ```
148
+
149
+ An empty object is the sharpest case. `{ "config": {} }` now declares a parameter with no default, so every render of that document is refused until one supplies a value, or until the document wraps it.
150
+
151
+ Nothing else moves. A bare string, number, boolean or array is untouched.
152
+
153
+ A declaration may also carry a `label`, the text a person reads for the parameter. A labelled parameter is one a person supplies, so a host panel shows only those. The engine never renders a label.
154
+
155
+ A `null` default beside a `type` makes a typed parameter optional, and a render may then supply `null`:
156
+
157
+ ```jsonc
158
+ { "params": { "branch": { "type": "string", "default": null, "label": "Branch" } } }
159
+ ```
160
+
161
+ A host reads what a document declares from `report.params` and from `plan(...).params`: one frozen `{ name, required, type?, default?, label? }` per parameter, in declaration order. A plan carries them whether or not the document compiled, so an editor can render a panel beside the problems.
162
+
3
163
  ## 0.12.0
4
164
 
5
165
  ### Minor Changes
package/LICENSE CHANGED
@@ -1,179 +1,200 @@
1
1
  # Quario License Agreement
2
2
 
3
3
  > **In short:** Quario is commercial software with visible source.
4
- > Evaluate it free for as long as you like. Evaluation output is
5
- > watermarked. Anything else needs a per-developer license, after
6
- > which deployment is unlimited and royalty-free. This summary is not
7
- > the license; the full terms below govern.
4
+ > You may evaluate it and develop with it free, for as long as you
5
+ > like. The Software marks output that no license key covers. Each
6
+ > production deployment needs one license key. A key covers one year
7
+ > of releases, and those releases stay licensed for good. This summary
8
+ > is not the license. The full terms below govern.
8
9
 
9
- Version 1.0, August 2026
10
+ Version 1.1, October 2026
10
11
 
11
12
  This agreement is between you and Webstronauts, trading as Quario,
12
- established in the Netherlands ("we", "us"), and governs the Software
13
+ established in the Netherlands ("we", "us"). It governs the Software
13
14
  defined below.
14
15
 
15
16
  Quario is commercial software. Its packages ship with readable source
16
- code, but it is not open source. No rights are granted beyond those in
17
- this agreement.
17
+ code, but it is not open source. This agreement grants no rights
18
+ beyond those it states.
18
19
 
19
20
  ## 1. Definitions
20
21
 
21
22
  - The **Software** is any software we publish under the Quario name,
22
23
  including the `quario` and `@quario/*` packages, except where a
23
24
  product states its own terms. Each release states the edition of this
24
- agreement that governs it.
25
- - **You** means the individual exercising rights under this agreement
26
- and, where that individual acts for a company or other organization,
27
- that organization. In that case the organization is the licensee, and
28
- the rights and limits in this agreement apply to it as a whole.
25
+ agreement that governs it. A license key bought under this edition
26
+ licenses every release it covers under this edition, including
27
+ releases that shipped with an earlier edition.
28
+ - **You** means the individual who exercises rights under this
29
+ agreement. Where that individual acts for a company or other
30
+ organization, **you** also means that organization. In that case the
31
+ organization is the licensee, and the rights and limits in this
32
+ agreement apply to it as a whole.
29
33
  - An **Application** is software you create that incorporates the
30
- Software and adds substantial functionality beyond it. A
31
- licensee-operated service that embeds the Software and renders
32
- reports for your End Users is an Application under this agreement,
33
- even if it does little more than render.
34
- - A **Developer** is any individual (employee or contractor working on
35
- your behalf) who writes or maintains code that uses the Software's
36
- APIs, or who creates or maintains report definitions for use with the
37
- Software. That includes people who never install or run the Software
38
- themselves, when their definitions are rendered by a service that
39
- embeds it.
40
- - A **Seat** is a paid license for one named Developer, purchased from
41
- us or an authorized reseller.
34
+ Software and adds substantial functionality beyond it. A service you
35
+ operate that embeds the Software and renders reports for your End
36
+ Users is an Application, even if it does little more than render.
37
+ - A **Deployment** is one production service, application, bot, worker
38
+ or MCP server that runs the Software under your control. All replicas
39
+ of it together are one Deployment. A service that only passes render
40
+ requests to another service does not run the Software, so it is not
41
+ a Deployment. A service that a host or contractor operates on your
42
+ behalf stays under your control. Development, staging, CI and test
43
+ environments are not Deployments. We never count the people, agents
44
+ or renders that a Deployment serves.
45
+ - A **License Key** is the signed key that evidences the license of
46
+ one Deployment. You buy it from us or from an authorized reseller.
42
47
  - **End Users** are people who interact with the Software only through
43
- an Application: running it, viewing the reports it produces, or
44
- supplying parameters or other input to existing report definitions
45
- the Application provides. Creating or maintaining report definitions
46
- makes someone a Developer. End Users do not purchase a license; their
47
- rights come from section 5.
48
+ an Application that runs in a Deployment. They run it, view the
49
+ reports it produces, or supply parameters, input or report
50
+ definitions to it. End Users do not buy a license. Their rights come
51
+ from section 5.
48
52
 
49
53
  ## 2. Acceptance
50
54
 
51
- This file is our standing offer. Anyone who exercises the evaluation
52
- rights in section 3 accepts them, subject to their conditions. All
53
- other rights arise when Seats are purchased. Where a purchase is made
54
- for an organization, the person completing it confirms that they are
55
- authorized to accept this agreement on the organization's behalf, and
56
- acceptance covers the whole organization. If you do not accept this
55
+ This file is our standing offer. Anyone who exercises the rights in
56
+ section 3 accepts them, subject to their conditions. All other rights
57
+ start when you buy a License Key. Where a person buys for an
58
+ organization, that person states that they have the authority to
59
+ accept this agreement on the organization's behalf. The acceptance
60
+ then covers the whole organization. If you do not accept this
57
61
  agreement, do not use the Software.
58
62
 
59
- ## 3. Evaluation
60
-
61
- You may download, install, and use the Software free of charge to
62
- evaluate it: assessing whether it suits your purposes, and building
63
- prototypes or proofs of concept. Evaluation covers the full feature
64
- set, needs no key, and has no fixed time limit. The Software marks
65
- evaluation output as described in section 6.
66
-
67
- Evaluation is limited to assessment: you may not distribute any
68
- Application containing the Software, use the Software in live business
69
- operations, or expose it in services offered to third parties. The
70
- moment your use goes beyond evaluating the Software, it requires Seats
71
- under section 4.
72
-
73
- ## 4. Developer licenses
74
-
75
- Any use of the Software beyond section 3 requires a Seat for every
76
- Developer, whether or not an Application has shipped. With those Seats
77
- in place:
78
-
79
- - Each licensed Developer may install and use the Software on any number
80
- of machines for developing Applications.
81
- - Automated build, test, and CI systems do not consume Seats.
82
- - Seats are per named individual. They may be reassigned when a
83
- Developer stops working with the Software, but not shared or pooled
84
- between concurrently active Developers. Contractors' work for you is
85
- covered by your Seats; work they do for other clients is not.
86
-
87
- ## 5. Distribution and runtime
88
-
89
- With Seats under section 4 in place, you may deploy and operate your
90
- Applications yourself, and distribute the Software as an embedded part
91
- of them, **royalty-free**: no additional fees or per-deployment
92
- licenses are required for any number of servers, copies, or End Users.
93
- You may embed your license key in an Application and ship it at no
94
- charge, so section 6 does not mark that Application's output.
95
-
96
- For that purpose, we grant you the right to pass through to each End
97
- User, and to anyone who distributes or operates your Application on your
98
- behalf, a limited, non-exclusive, non-transferable right to execute the
99
- Software only as embedded in the Application. You must not permit them
100
- to extract the Software from the Application or use it to develop
101
- software of their own.
102
-
103
- If you operate a service that embeds the Software and renders reports
104
- for your End Users, that service is an Application under section 1. You
105
- may run it royalty-free under this section, and you may put your license
106
- key in it as in any Application. Calling applications that only request
107
- renders from it need not incorporate the Software. People who use those
108
- applications only as End Users under section 1 get the pass-through
109
- rights above.
63
+ ## 3. Evaluation and development
110
64
 
111
- You may not:
65
+ You may download, install and use the Software free of charge in any
66
+ environment that is not a Deployment. That includes evaluation,
67
+ prototypes, proofs of concept, and the development, staging, CI and
68
+ test environments of an Application. This right covers the full
69
+ feature set, needs no key, and has no time limit. The Software marks
70
+ output that no License Key covers, as section 6 describes.
112
71
 
113
- - distribute the Software on its own, or as part of a product whose
114
- primary purpose is to provide report-engine, report-design, or
115
- document-generation capability to third-party developers;
116
- - expose the Software's APIs to third parties as a development tool or
117
- service that substitutes for those parties buying their own Seats. A
118
- licensee-operated service that embeds the Software and renders for
119
- your own End Users falls outside that ban;
120
- - fork, mirror, repackage, rename, or wrap the Software, or republish
121
- it on any package registry or code-hosting platform, other than as
122
- embedded in an Application.
72
+ This right does not let you use the Software in live business
73
+ operations, or expose it in services that third parties use. Each
74
+ Deployment needs a License Key under section 4.
75
+
76
+ ## 4. Deployment licenses
123
77
 
124
- For as long as this agreement is in force, you may not create any tool,
125
- library, product, or service that competes with the Software or any
126
- other Quario product, whether the competition is direct or indirect;
127
- this restriction does not survive termination. You may not remove or
128
- alter copyright or license notices in the Software. If your Application
129
- is itself a closed development product for third-party developers (OEM
130
- redistribution), contact us for separate terms.
78
+ Each Deployment needs its own License Key, from the first day it runs
79
+ in production. With that key in place:
131
80
 
132
- ## 6. License keys and output marking
81
+ - You may set the key in that Deployment and in the development,
82
+ staging, CI and test copies of that Deployment. The key then removes
83
+ the marking there too.
84
+ - One key never covers two Deployments at the same time.
85
+ - You may move a key to a new Deployment after the old Deployment no longer
86
+ runs the Software in production.
87
+ - Contractors who work for you may use your keys for that work. They
88
+ may not use your keys for work they do for other clients.
133
89
 
134
- The Software accepts a license key that evidences your Seats under
135
- section 4. Key checks run offline.
90
+ ## 5. Use and pass-through
136
91
 
137
- Without a valid key, or with a key whose validity period does not cover
138
- the installed version's release date, the Software runs with its full
139
- feature set but marks its output as unlicensed. Using a key you are not
140
- entitled to is a material breach of this agreement.
92
+ With a License Key under section 4 in place, you may operate the
93
+ Application in its Deployment **royalty-free**. We charge no fees for
94
+ servers, replicas, requests, renders, agents or End Users. You may
95
+ embed your License Key in the Application.
141
96
 
142
- You may not remove, disable, or circumvent the key check or the output
97
+ We grant you the right to pass through to each End User a limited,
98
+ non-exclusive, non-transferable right to use the Software only as
99
+ embedded in the Application that runs in your Deployment. You must not
100
+ let End Users extract the Software from the Application or use it to
101
+ develop software of their own.
102
+
103
+ Calling applications that only request renders from your Deployment do
104
+ not need to incorporate the Software. People who use those applications
105
+ only as End Users get the pass-through rights above.
106
+
107
+ You may not:
108
+
109
+ - Distribute the Software on its own, or as part of a product whose
110
+ primary purpose is to give report-engine, report-design or
111
+ document-generation capability to third-party developers.
112
+ - Expose the Software's APIs to third parties as a development tool or
113
+ service that replaces their own License Keys. A service you operate
114
+ that embeds the Software and renders for your own End Users is not
115
+ such a tool.
116
+ - Fork, mirror, repackage, rename or wrap the Software, or republish it
117
+ on any package registry or code-hosting platform, other than as
118
+ embedded in an Application.
119
+
120
+ **OEM distribution.** An Application that your customers install,
121
+ embed or resell, and that runs the Software outside your control, is
122
+ OEM distribution. A License Key does not cover OEM distribution, for
123
+ any number of copies. Contact us for separate terms. When you render
124
+ documents for your customers from a product that you host yourself,
125
+ that product is a Deployment, not OEM distribution.
126
+
127
+ While this agreement is in force, you may not create any tool,
128
+ library, product or service that competes with the Software or with
129
+ any other Quario product, directly or indirectly. This restriction
130
+ ends when this agreement terminates. You may not remove or change
131
+ copyright or license notices in the Software.
132
+
133
+ ## 6. License Keys and output marking
134
+
135
+ The Software accepts a License Key as evidence of a Deployment's
136
+ license under section 4. Key checks run offline.
137
+
138
+ Each License Key states an end date. A key covers every release of the
139
+ Software dated on or before that end date. Without a valid key, or with
140
+ a key that does not cover the installed release, the Software runs with
141
+ its full feature set but marks its output as unlicensed. A key that is
142
+ void under section 7 licenses nothing, even where the installed
143
+ release still accepts it. Use of a key that you have no right to use
144
+ is a material breach of this agreement.
145
+
146
+ A later release may refuse a key that we revoked. We revoke a key when
147
+ we refund its payment, or when a chargeback or similar process
148
+ reverses its payment. We also revoke a key that
149
+ someone publishes for reuse by others. In that case, we give the
150
+ licensee a free replacement key with the same end date. When you embed a
151
+ key in your Application under section 5, that embedding alone does not
152
+ publish the key for reuse.
153
+
154
+ You may not remove, disable or bypass the key check or the output
143
155
  marking, or distribute anything that does.
144
156
 
145
- ## 7. Term, updates, and perpetual fallback
157
+ ## 7. Term, updates and refunds
158
+
159
+ **No subscription.** You pay once for each License Key. The key covers
160
+ every release dated up to one year after you bought it, and you get
161
+ support until that end date. We give support through our issue tracker
162
+ and by email, with commercially reasonable effort. We do not guarantee
163
+ response times.
164
+
165
+ **Perpetual license.** Your license to the releases that a key covers
166
+ is **perpetual**. The Deployment may keep using those releases, and
167
+ the Application may keep running them, forever, at no further cost.
168
+ Releases dated after the key's end date need a new key.
146
169
 
147
- Seats are sold as an annual subscription. While the subscription is
148
- active, licensed Developers receive all Software versions we release,
149
- and support for the Software through our issue tracker and by email. We
150
- provide support with commercially reasonable effort; we do not guarantee
151
- specific response times.
170
+ **Renewal.** Renewal is a new purchase of a new key. It never occurs
171
+ automatically, and we never charge you without a new order.
152
172
 
153
- If the subscription lapses, your license to the versions released during
154
- your subscription is **perpetual, for the number of Seats held at the
155
- lapse**: up to that many Developers may keep using those versions, and
156
- your Applications may keep shipping them, forever, at no further cost.
157
- Versions released after the lapse require renewal. We encode this rule
158
- in purchased keys: a key remains valid for every version released
159
- during its validity period, with no end date.
173
+ **Refunds and reversals.** If we refund a payment, or a chargeback or
174
+ similar process reverses a payment, each key that the payment
175
+ bought is void. A partial refund states the keys that it voids. A void
176
+ key gives you no rights, including no perpetual license. You keep the
177
+ rights of section 3, and this agreement continues. Use of a void key in
178
+ a Deployment is a material breach of this agreement. Keys that the
179
+ refund or reversal does not void stay valid. If a payment dispute is
180
+ decided in our favour, we restore the license with a reissued key.
160
181
 
161
182
  ## 8. Source availability
162
183
 
163
- The Software's packages ship with readable source code so that you can
184
+ The Software's packages ship with readable source code, so you can
164
185
  review and debug what you run. Readable source does not grant extra
165
- rights: this agreement governs all use of the source, and you may
166
- publish the Software (modified or not) only as part of an Application
167
- under section 5.
186
+ rights. This agreement governs all use of the source. You may publish
187
+ the Software, modified or not, only as part of an Application under
188
+ section 5.
168
189
 
169
- ## 9. Ownership, trademarks, and feedback
190
+ ## 9. Ownership, trademarks and feedback
170
191
 
171
- We license the Software; we retain all intellectual property rights in
172
- it. Report definitions, data, and output you create with the Software
173
- are yours. "Quario" and the Quario logo are our trademarks; this
174
- agreement grants no rights to use them beyond identifying the Software.
175
- If you send us feedback or suggestions, we may use them without
176
- obligation.
192
+ We license the Software. We keep all intellectual property rights in
193
+ it. The report definitions, data and output that you create with the
194
+ Software are yours. "Quario" and the Quario logo are our trademarks.
195
+ This agreement grants no rights to use them, except to identify the
196
+ Software. If you send us feedback or suggestions, we may use them
197
+ without obligation.
177
198
 
178
199
  ## 10. Warranty and liability
179
200
 
@@ -181,11 +202,11 @@ We provide the Software as is. To the fullest extent the law allows, we
181
202
  disclaim all warranties and conditions, express or implied, including
182
203
  merchantability, fitness for a particular purpose, and non-infringement.
183
204
 
184
- To the fullest extent the law allows: we are not liable for indirect or
205
+ To the fullest extent the law allows, we are not liable for indirect or
185
206
  consequential damages, loss of profits, loss of data, or business
186
- interruption; and our total aggregate liability under this agreement is
207
+ interruption. Our total aggregate liability under this agreement is
187
208
  limited to the greater of EUR 100 and the fees you paid us in the
188
- twelve months preceding the event giving rise to the claim. These
209
+ twelve months before the event that gave rise to the claim. These
189
210
  limitations do not apply where the damage results from the intent or
190
211
  deliberate recklessness (opzet of bewuste roekeloosheid) of us or our
191
212
  management, or where mandatory law does not permit them.
@@ -193,23 +214,24 @@ management, or where mandatory law does not permit them.
193
214
  ## 11. Termination and survival
194
215
 
195
216
  If you materially breach this agreement, we may terminate it by notice.
196
- If the breach can be remedied, we will first allow 30 days from that
197
- notice to remedy it, and termination takes effect only if the breach
198
- remains. On termination, the licenses granted here end.
199
- Perpetual-fallback rights under section 7 survive termination only if
200
- they arose from a lapse that predates the breach, and section 5
201
- survives with them to the extent needed to keep exercising them.
202
- Sections 8 through 12 survive any termination.
217
+ If you can remedy the breach, we first give you 30 days from that
218
+ notice to remedy it. Termination then occurs only if the breach
219
+ continues. On termination, the licenses that this agreement grants end.
220
+ The perpetual license to the releases that a key covers survives
221
+ termination only if the end date of that key passed before the breach.
222
+ Section 5 survives with it, as far as you need section 5 to use that
223
+ license. Sections 8 through 12 survive any termination.
203
224
 
204
225
  ## 12. General
205
226
 
206
- Dutch law governs this agreement. Disputes go to the competent court for
207
- our registered office. You may not assign this agreement without our
208
- consent, except to a successor of your whole business; we may assign it
209
- to a successor of ours. If a provision is unenforceable, the remainder
210
- stays in force. Failure to enforce a provision does not waive it. This
211
- agreement, together with your order for Seats, is the entire agreement
212
- about the Software, unless we agree otherwise in writing.
227
+ Dutch law governs this agreement. The competent court for our
228
+ registered office decides disputes. You may not assign this agreement
229
+ without our consent, except to a successor of your whole business. We
230
+ may assign it to a successor of ours. If a provision is unenforceable,
231
+ the remainder stays in force. If we do not enforce a provision, we do
232
+ not waive it. This agreement, together with your order for License
233
+ Keys, is the entire agreement about the Software, unless we agree
234
+ otherwise in writing.
213
235
 
214
236
  ---
215
237
 
package/README.md CHANGED
@@ -70,8 +70,8 @@ key verification as `{ licensed, licensee?, id? }`.
70
70
 
71
71
  ### `report(schema, functions?)`
72
72
 
73
- Compiles a report and returns the compiled report. `stream(data)` is the raw event generator.
74
- `render(target, data)` takes a self-naming `{ name, compile }` object from a target factory
73
+ Compiles a report and returns the compiled report. `stream(data, params)` is the raw event generator, and `params` are the values this render supplies for what the document declares.
74
+ `render(target, data, params)` takes a self-naming `{ name, compile }` object from a target factory
75
75
  (e.g. `html()` from `@quario/html`) or your own.
76
76
 
77
77
  A render is async: quario awaits key verification before the target sees its first event. A
@@ -209,6 +209,33 @@ validate({ data: "$.o[*]", sort: [{ by: "=@.a", dir: "up" }] });
209
209
  `report()` throws on the first problem instead. Validation and compilation share one traversal,
210
210
  so `validate()` can never disagree with what `report()` accepts.
211
211
 
212
+ ### JSON Schema
213
+
214
+ The package ships a JSON Schema of the report document. Point `$schema` at the installed copy,
215
+ and your editor checks the document and shows the documentation for each key:
216
+
217
+ ```json
218
+ {
219
+ "$schema": "./node_modules/quario/lib/schema.json",
220
+ "data": "$.orders[*]",
221
+ "detail": [{ "type": "text", "value": "{{ @.product }}" }]
222
+ }
223
+ ```
224
+
225
+ The path is relative to the report file. The engine accepts the `$schema` key and does not read
226
+ it.
227
+
228
+ Code reads the same file through the package export:
229
+
230
+ ```js
231
+ import schema from "quario/schema.json" with { type: "json" };
232
+ ```
233
+
234
+ The JSON Schema proves the shape of each value. It does not replace `validate()`. Rules that
235
+ join two or more values, and every expression and template, stay with `validate()`. Use the
236
+ JSON Schema to constrain what an editor or a model writes. Use `validate()` to accept a
237
+ document.
238
+
212
239
  ### `quario().plan(schema, functions?, { targets }?)`
213
240
 
214
241
  The one traversal, whole — for hosts that validate and render in a loop, like an editor. Returns
package/lib/format.js CHANGED
@@ -94,7 +94,7 @@ let asMoney = (value, locale, decl, options, style) => {
94
94
  //
95
95
  // The form is Intl's own `dateStyle`, and it is always present: a declaration
96
96
  // that named none resolved to `medium` (docs/adr/0056). This is the half that
97
- // does not converge — the worksheet approximates it (CONTEXT.md, "Form").
97
+ // does not converge — the worksheet approximates it (GLOSSARY.md, "Form").
98
98
  // `date` leads for the same reason the number kinds do, so the two key shapes
99
99
  // live beside each other and "one piece at a time" is auditable in one place.
100
100
  /** @type {(locale: string, decl: any, zone: string) => string} */