@jarenjs/json 0.9.2

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.
Files changed (57) hide show
  1. package/ARCHITECTURE.md +175 -0
  2. package/LICENSE +21 -0
  3. package/README.md +471 -0
  4. package/dist/types/basic.d.ts +32 -0
  5. package/dist/types/index.d.ts +4 -0
  6. package/dist/types/jslt/dispatch.d.ts +11 -0
  7. package/dist/types/jslt/errors.d.ts +18 -0
  8. package/dist/types/jslt/index.d.ts +53 -0
  9. package/dist/types/jslt/stylesheet.d.ts +8 -0
  10. package/dist/types/jtlt/desugar.d.ts +19 -0
  11. package/dist/types/jtlt/errors.d.ts +18 -0
  12. package/dist/types/jtlt/index.d.ts +57 -0
  13. package/dist/types/jtlt/template.d.ts +8 -0
  14. package/dist/types/jtlt/writer.d.ts +6 -0
  15. package/dist/types/path.d.ts +235 -0
  16. package/dist/types/pointer.d.ts +114 -0
  17. package/dist/types/query/compile.d.ts +21 -0
  18. package/dist/types/query/errors.d.ts +18 -0
  19. package/dist/types/query/index.d.ts +70 -0
  20. package/dist/types/query/normalize.d.ts +68 -0
  21. package/dist/types/query/operators.d.ts +424 -0
  22. package/dist/types/query/runtime.d.ts +93 -0
  23. package/dist/types/segments.d.ts +62 -0
  24. package/dist/types/xquery/index.d.ts +19 -0
  25. package/dist/types/xquery/parse.d.ts +20 -0
  26. package/docs/JSLT-FORMAT.md +861 -0
  27. package/docs/JSLT-PRELUDE.md +159 -0
  28. package/docs/JTLT-FORMAT.md +659 -0
  29. package/docs/QUERY-FORMAT.md +1221 -0
  30. package/docs/XQUERY-FRONTEND.md +321 -0
  31. package/package.json +81 -0
  32. package/schemas/jaren-jslt.draft-07.schema.json +776 -0
  33. package/schemas/jaren-jslt.schema.json +776 -0
  34. package/schemas/jaren-query.draft-07.schema.json +613 -0
  35. package/schemas/jaren-query.schema.json +375 -0
  36. package/src/basic.js +300 -0
  37. package/src/index.js +4 -0
  38. package/src/jslt/dispatch.js +934 -0
  39. package/src/jslt/errors.js +34 -0
  40. package/src/jslt/index.js +121 -0
  41. package/src/jslt/stylesheet.js +234 -0
  42. package/src/jtlt/desugar.js +231 -0
  43. package/src/jtlt/errors.js +34 -0
  44. package/src/jtlt/index.js +155 -0
  45. package/src/jtlt/template.js +130 -0
  46. package/src/jtlt/writer.js +110 -0
  47. package/src/path.js +977 -0
  48. package/src/pointer.js +453 -0
  49. package/src/query/compile.js +817 -0
  50. package/src/query/errors.js +33 -0
  51. package/src/query/index.js +150 -0
  52. package/src/query/normalize.js +1047 -0
  53. package/src/query/operators.js +1253 -0
  54. package/src/query/runtime.js +233 -0
  55. package/src/segments.js +627 -0
  56. package/src/xquery/index.js +35 -0
  57. package/src/xquery/parse.js +1647 -0
@@ -0,0 +1,57 @@
1
+ export { JtltCompileError, JtltRuntimeError } from './errors.js';
2
+ /**
3
+ * Compile a Jaren JTLT 0.1 template into a reusable renderer.
4
+ *
5
+ * The returned function renders any input document to a string in the
6
+ * template's output method ('text' by default, 'xml' for markup with
7
+ * escaped interpolation). Metadata:
8
+ *
9
+ * - `render.externals` - user parameter names in first-appearance order
10
+ * (`root` and `path` are engine-bound and excluded)
11
+ * - `render.output` - the resolved output method
12
+ * - `render.doc` - an independent, deeply frozen template copy
13
+ * - `render.stylesheet` - the frozen JSLT stylesheet it compiled to
14
+ *
15
+ * @param {any} doc - a bare rule array or `{"$jtlt":"0.1","output":...,
16
+ * "rules":[]}` template envelope
17
+ * @param {object} [options] - compile options, passed to the JSLT layer
18
+ * @param {(schemaJson: any, docPath: string) => ((value: any) => boolean)}
19
+ * [options.compileTypeTest] - validator-agnostic hook for schema
20
+ * matches and schema operators inside segment expressions
21
+ * @param {number} [options.maxDepth=1024] - maximum dispatch nesting depth
22
+ * @returns {function} reusable `render(data, externals?)` function
23
+ * @throws {JtltCompileError} when compilation fails
24
+ * @example
25
+ * const render = compileJtltStylesheet([
26
+ * { match: '$.items[*]', body: ['- ', '$.name', '\n'] },
27
+ * ]);
28
+ * render({ items: [{ name: 'a' }, { name: 'b' }] });
29
+ * // '- a\n- b\n'
30
+ */
31
+ export declare function compileJtltStylesheet(doc: any, options?: {
32
+ compileTypeTest?: (schemaJson: any, docPath: string) => ((value: any) => boolean);
33
+ maxDepth?: number;
34
+ }): Function;
35
+ /**
36
+ * Render a JSON value with a JTLT template in one call. Object/array
37
+ * template documents are compiled once and cached by identity in a
38
+ * WeakMap.
39
+ * @param {any} template - JTLT template document
40
+ * @param {any} data - input JSON value
41
+ * @param {object} [externals] - user parameter bindings
42
+ * @param {object} [options] - compile options used on a cache miss
43
+ * @param {(schemaJson: any, docPath: string) => ((value: any) => boolean)}
44
+ * [options.compileTypeTest] - schema type-test compiler
45
+ * @param {number} [options.maxDepth=1024] - maximum dispatch nesting depth
46
+ * @returns {string} the rendered output text
47
+ * @throws {JtltCompileError} when compilation fails
48
+ * @throws {JtltRuntimeError} when rendering fails
49
+ * @example
50
+ * renderText([{ match: '$.name', body: ['Hello ', '$', '!'] }],
51
+ * { name: 'world' });
52
+ * // 'Hello world!'
53
+ */
54
+ export declare function renderText(template: any, data: any, externals?: object, options?: {
55
+ compileTypeTest?: (schemaJson: any, docPath: string) => ((value: any) => boolean);
56
+ maxDepth?: number;
57
+ }): string;
@@ -0,0 +1,8 @@
1
+ export declare const RESERVED_PRIORITY_FLOOR = -1e+307;
2
+ /**
3
+ * Normalize a frozen JTLT template document into a frozen model.
4
+ * @param {any} doc - deeply frozen template document
5
+ * @returns {object} frozen template model
6
+ * @throws {JtltCompileError} on TL0001-TL0003 and TL0006 shape errors
7
+ */
8
+ export declare function normalizeJtltTemplate(doc: any): object;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Create the serializer for one output method.
3
+ * @param {'text' | 'xml'} method - the template's output method
4
+ * @returns {(value: any) => string} segment-stream serializer
5
+ */
6
+ export declare function createWriter(method: 'text' | 'xml'): (value: any) => string;
@@ -0,0 +1,235 @@
1
+ /**
2
+ * Sentinel for the absence of a value ("Nothing" in RFC 9535 terms), as
3
+ * distinct from the JSON value `null`.
4
+ */
5
+ export declare const JSONPATH_NOTHING: symbol;
6
+ /**
7
+ * Error thrown when a JSONPath query is not valid RFC 9535 syntax
8
+ * (including queries that are not well-typed per section 2.4.3).
9
+ */
10
+ export declare class JSONPathSyntaxError extends SyntaxError {
11
+ source: any;
12
+ position: any;
13
+ constructor(message: any, source: any, position: any);
14
+ }
15
+ export type JSONPathNameSelector = {
16
+ /**
17
+ * - Discriminator
18
+ */
19
+ kind: 'name';
20
+ /**
21
+ * - The member name to select
22
+ */
23
+ name: string;
24
+ };
25
+ export type JSONPathWildcardSelector = {
26
+ /**
27
+ * - Discriminator
28
+ */
29
+ kind: 'wildcard';
30
+ };
31
+ export type JSONPathIndexSelector = {
32
+ /**
33
+ * - Discriminator
34
+ */
35
+ kind: 'index';
36
+ /**
37
+ * - The array index to select
38
+ */
39
+ index: number;
40
+ };
41
+ export type JSONPathSliceSelector = {
42
+ /**
43
+ * - Discriminator
44
+ */
45
+ kind: 'slice';
46
+ /**
47
+ * - Slice start, or null when omitted
48
+ */
49
+ start: number | null;
50
+ /**
51
+ * - Slice end (exclusive), or null when omitted
52
+ */
53
+ end: number | null;
54
+ /**
55
+ * - Slice step, or null when omitted
56
+ */
57
+ step: number | null;
58
+ };
59
+ export type JSONPathFilterSelector = {
60
+ /**
61
+ * - Discriminator
62
+ */
63
+ kind: 'filter';
64
+ /**
65
+ * - The parsed filter expression tree
66
+ */
67
+ expr: object;
68
+ };
69
+ export type JSONPathSelector = JSONPathNameSelector | JSONPathWildcardSelector | JSONPathIndexSelector | JSONPathSliceSelector | JSONPathFilterSelector;
70
+ export type JSONPathSegment = {
71
+ /**
72
+ * - True for a descendant (`..`) segment
73
+ */
74
+ descendant: boolean;
75
+ /**
76
+ * - The segment's selectors
77
+ */
78
+ selectors: JSONPathSelector[];
79
+ };
80
+ export type JSONPathAst = {
81
+ /**
82
+ * - True for a relative query (`@`), false for a root query (`$`)
83
+ */
84
+ relative: boolean;
85
+ /**
86
+ * - The query's segments in order
87
+ */
88
+ segments: JSONPathSegment[];
89
+ };
90
+ export type JSONPathNode = {
91
+ /**
92
+ * - The normalized path (e.g. `$['store']['book'][0]`)
93
+ */
94
+ path: string;
95
+ /**
96
+ * - The matched value
97
+ */
98
+ value: any;
99
+ };
100
+ export type JSONPathQuery = ((data: any) => any[]) & {
101
+ values: (data: any) => any[];
102
+ first: (data: any) => any;
103
+ exists: (data: any) => boolean;
104
+ nodes: (data: any) => JSONPathNode[];
105
+ paths: (data: any) => string[];
106
+ source: string;
107
+ ast: JSONPathAst;
108
+ };
109
+ /**
110
+ * Selects a named object member (RFC 9535 name selector).
111
+ * @typedef {Object} JSONPathNameSelector
112
+ * @property {'name'} kind - Discriminator
113
+ * @property {string} name - The member name to select
114
+ */
115
+ /**
116
+ * Selects all members of an object / all elements of an array
117
+ * (RFC 9535 wildcard selector).
118
+ * @typedef {Object} JSONPathWildcardSelector
119
+ * @property {'wildcard'} kind - Discriminator
120
+ */
121
+ /**
122
+ * Selects an array element by index; negative indexes count from the end
123
+ * (RFC 9535 index selector).
124
+ * @typedef {Object} JSONPathIndexSelector
125
+ * @property {'index'} kind - Discriminator
126
+ * @property {number} index - The array index to select
127
+ */
128
+ /**
129
+ * Selects a range of array elements (RFC 9535 array slice selector).
130
+ * `null` means the bound was omitted in the query.
131
+ * @typedef {Object} JSONPathSliceSelector
132
+ * @property {'slice'} kind - Discriminator
133
+ * @property {number | null} start - Slice start, or null when omitted
134
+ * @property {number | null} end - Slice end (exclusive), or null when omitted
135
+ * @property {number | null} step - Slice step, or null when omitted
136
+ */
137
+ /**
138
+ * Selects children for which a filter expression yields a truthy result
139
+ * (RFC 9535 filter selector).
140
+ * @typedef {Object} JSONPathFilterSelector
141
+ * @property {'filter'} kind - Discriminator
142
+ * @property {object} expr - The parsed filter expression tree
143
+ */
144
+ /**
145
+ * Any RFC 9535 selector, discriminated by its `kind` property.
146
+ * @typedef {JSONPathNameSelector | JSONPathWildcardSelector | JSONPathIndexSelector | JSONPathSliceSelector | JSONPathFilterSelector} JSONPathSelector
147
+ */
148
+ /**
149
+ * One segment of a JSONPath query: a child (`.` / `[...]`) or descendant
150
+ * (`..`) step holding one or more selectors.
151
+ * @typedef {Object} JSONPathSegment
152
+ * @property {boolean} descendant - True for a descendant (`..`) segment
153
+ * @property {JSONPathSelector[]} selectors - The segment's selectors
154
+ */
155
+ /**
156
+ * The parsed AST of a JSONPath query.
157
+ * @typedef {Object} JSONPathAst
158
+ * @property {boolean} relative - True for a relative query (`@`), false for a root query (`$`)
159
+ * @property {JSONPathSegment[]} segments - The query's segments in order
160
+ */
161
+ /**
162
+ * One result of a JSONPath query in nodes mode: the matched value together
163
+ * with its normalized path (RFC 9535 section 2.7).
164
+ * @typedef {Object} JSONPathNode
165
+ * @property {string} path - The normalized path (e.g. `$['store']['book'][0]`)
166
+ * @property {any} value - The matched value
167
+ */
168
+ /**
169
+ * A compiled JSONPath query. Calling it returns the matched values; the
170
+ * attached methods expose the other result modes, and `source`/`ast`
171
+ * expose the original query string and its parsed (deeply frozen) AST.
172
+ * @typedef {((data: any) => any[]) & {
173
+ * values: (data: any) => any[],
174
+ * first: (data: any) => any,
175
+ * exists: (data: any) => boolean,
176
+ * nodes: (data: any) => JSONPathNode[],
177
+ * paths: (data: any) => string[],
178
+ * source: string,
179
+ * ast: JSONPathAst,
180
+ * }} JSONPathQuery
181
+ */
182
+ /**
183
+ * Parse a JSONPath query string into an AST.
184
+ * @param {string} source - The JSONPath expression (e.g. `$.store.book[?@.price < 10].title`)
185
+ * @returns {JSONPathAst} The parsed query AST
186
+ * @throws {JSONPathSyntaxError} When the query violates the RFC 9535 grammar
187
+ */
188
+ export declare function parseJSONPath(source: string): JSONPathAst;
189
+ /**
190
+ * Compile a JSONPath query (RFC 9535) into a reusable query function.
191
+ *
192
+ * The returned function applies the query to a JSON value and returns
193
+ * the resulting nodelist as an array of values. It also carries helper
194
+ * methods:
195
+ *
196
+ * - `query(data)` / `query.values(data)` - array of matched values
197
+ * - `query.first(data)` - first matched value, or `undefined`
198
+ * - `query.exists(data)` - true when the query selects at least one node
199
+ * - `query.nodes(data)` - array of `{ path, value }` with normalized paths
200
+ * - `query.paths(data)` - array of normalized paths (RFC 9535 section 2.7)
201
+ * - `query.source` - the original query string
202
+ * - `query.ast` - the parsed query AST (deeply frozen; the lazily
203
+ * compiled path mode must agree with the eagerly compiled value mode)
204
+ *
205
+ * @param {string} source - The JSONPath expression
206
+ * @returns {JSONPathQuery} The compiled query function
207
+ * @throws {JSONPathSyntaxError} When the query is not valid RFC 9535
208
+ * @example
209
+ * const q = compileJSONPath('$.store.book[?@.price < 10].title');
210
+ * q(data); // ['Sayings of the Century', 'Moby Dick']
211
+ * q.paths(data); // ["$['store']['book'][0]['title']", ...]
212
+ */
213
+ export declare function compileJSONPath(source: string): JSONPathQuery;
214
+ /**
215
+ * Apply a JSONPath query to a JSON value in one call. Compiled queries
216
+ * are cached (FIFO, 512 entries), so repeated calls with the same query
217
+ * string reuse the compiled function.
218
+ * @param {string} source - The JSONPath expression
219
+ * @param {any} data - The JSON value to query
220
+ * @returns {any[]} Array of matched values
221
+ * @throws {JSONPathSyntaxError} When the query is not valid RFC 9535
222
+ */
223
+ export declare function queryJSONPath(source: string, data: any): any[];
224
+ /**
225
+ * Validates a JSONPath expression strictly against the RFC 9535 grammar,
226
+ * including well-typedness of function expressions. Unlike the heuristic
227
+ * `isValidJSONPath` in basic.js, this uses the full parser.
228
+ * @param {string} str - The JSONPath expression to validate
229
+ * @returns {boolean} True when the string is a valid RFC 9535 query
230
+ * @example
231
+ * isValidJSONPathStrict('$.store.book[?@.price < 10]'); // true
232
+ * isValidJSONPathStrict('$.store.book[0 5]'); // false
233
+ * isValidJSONPathStrict('@.name'); // false (queries start at $)
234
+ */
235
+ export declare function isValidJSONPathStrict(str: string): boolean;
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Sentinel for the absence of a value, as distinct from the JSON value
3
+ * `null`. This is the same sentinel as `JSONPATH_NOTHING` in path.js, so
4
+ * pointer and path results can share checks.
5
+ */
6
+ export declare const JSONPOINTER_NOTHING: symbol;
7
+ /**
8
+ * Error thrown when a (relative) JSON Pointer is not valid RFC 6901 /
9
+ * draft-luff-relative-json-pointer syntax.
10
+ */
11
+ export declare class JSONPointerSyntaxError extends SyntaxError {
12
+ source: any;
13
+ position: any;
14
+ constructor(message: any, source: any, position: any);
15
+ }
16
+ /**
17
+ * Parse a JSON Pointer strictly per RFC 6901 into its decoded segments.
18
+ * @param {string} pointer - The JSON Pointer (e.g. `/store/book/0`)
19
+ * @returns {string[]} Array of decoded reference tokens
20
+ * @throws {JSONPointerSyntaxError} When the pointer violates the grammar
21
+ */
22
+ export declare function parseJSONPointer(pointer: string): string[];
23
+ export type RelativeJsonPointer = {
24
+ /**
25
+ * - Number of levels to ascend from the current location
26
+ */
27
+ levels: number;
28
+ /**
29
+ * - True for the `#` form, which addresses the member name or array index itself
30
+ */
31
+ hash: boolean;
32
+ /**
33
+ * - Decoded reference tokens applied after ascending
34
+ */
35
+ segments: string[];
36
+ };
37
+ export type JsonPointerGetter = (root: any) => any;
38
+ export type RelativeJsonPointerResolver = (dataRoot: any, dataPath: string) => any;
39
+ /**
40
+ * A parsed Relative JSON Pointer (draft-luff-relative-json-pointer).
41
+ * @typedef {Object} RelativeJsonPointer
42
+ * @property {number} levels - Number of levels to ascend from the current location
43
+ * @property {boolean} hash - True for the `#` form, which addresses the member name or array index itself
44
+ * @property {string[]} segments - Decoded reference tokens applied after ascending
45
+ */
46
+ /**
47
+ * A compiled JSON Pointer: returns the value addressed in `root`, or the
48
+ * `JSONPOINTER_NOTHING` sentinel when the pointer does not address a location.
49
+ * @typedef {(root: any) => any} JsonPointerGetter
50
+ */
51
+ /**
52
+ * A compiled Relative JSON Pointer / data reference: resolves against the
53
+ * RFC 6901 location `dataPath` inside `dataRoot`, returning the addressed
54
+ * value or the `JSONPOINTER_NOTHING` sentinel.
55
+ * @typedef {(dataRoot: any, dataPath: string) => any} RelativeJsonPointerResolver
56
+ */
57
+ /**
58
+ * Parse a Relative JSON Pointer strictly per
59
+ * draft-luff-relative-json-pointer: a non-negative integer without
60
+ * leading zeros, followed by `#` or a JSON Pointer.
61
+ * @param {string} pointer - The relative pointer (e.g. `1/sibling`, `0#`)
62
+ * @returns {RelativeJsonPointer} The parsed relative pointer
63
+ * @throws {JSONPointerSyntaxError} When the pointer violates the grammar
64
+ */
65
+ export declare function parseRelativeJSONPointer(pointer: string): RelativeJsonPointer;
66
+ /**
67
+ * Compile a JSON Pointer (RFC 6901) into a reusable getter.
68
+ *
69
+ * All decisions are taken at compile time: member names are pre-decoded,
70
+ * array indexes pre-parsed, and the getter is specialized by segment
71
+ * count. Resolution allocates nothing.
72
+ *
73
+ * @param {string} pointer - The JSON Pointer (e.g. `/store/book/0`)
74
+ * @returns {JsonPointerGetter} getter returning the addressed value, or
75
+ * `JSONPOINTER_NOTHING` when the pointer does not address a location
76
+ * @throws {JSONPointerSyntaxError} When the pointer is not valid RFC 6901
77
+ * @example
78
+ * const get = compileJSONPointer('/limits/min');
79
+ * get({ limits: { min: 2 } }); // 2
80
+ * get({}); // JSONPOINTER_NOTHING
81
+ */
82
+ export declare function compileJSONPointer(pointer: string): JsonPointerGetter;
83
+ /**
84
+ * Compile a Relative JSON Pointer into a reusable resolver.
85
+ *
86
+ * The relative part (level count, `#` form, trailing segments) compiles
87
+ * once; per call only `dataPath` - the current location in `dataRoot` as
88
+ * an RFC 6901 pointer - varies. The `#` form resolves to the member name
89
+ * or array index of the location **as a string** (`''` at the root),
90
+ * matching the historical behavior relied on by the validator's `$data`
91
+ * keyword.
92
+ *
93
+ * @param {string} pointer - The relative pointer (e.g. `1/sibling`, `0#`)
94
+ * @returns {RelativeJsonPointerResolver} resolver returning
95
+ * the addressed value, or `JSONPOINTER_NOTHING`
96
+ * @throws {JSONPointerSyntaxError} When the pointer is not valid
97
+ * @example
98
+ * const resolve = compileRelativeJSONPointer('1/limits');
99
+ * resolve({ limits: { min: 2 } , value: 5 }, '/value'); // { min: 2 }
100
+ */
101
+ export declare function compileRelativeJSONPointer(pointer: string): RelativeJsonPointerResolver;
102
+ /**
103
+ * Compile a data reference - the accepted forms of the validator's
104
+ * `data`/`$data` keywords - into a reusable resolver. The dispatch is
105
+ * decided once at compile time: a leading digit is a Relative JSON
106
+ * Pointer, a leading `/` an absolute JSON Pointer, and `''` the root.
107
+ *
108
+ * @param {string} ref - The reference string
109
+ * @returns {RelativeJsonPointerResolver} resolver returning
110
+ * the addressed value, or `JSONPOINTER_NOTHING`
111
+ * @throws {JSONPointerSyntaxError} When the reference is none of the
112
+ * accepted forms
113
+ */
114
+ export declare function compileDataRef(ref: string): RelativeJsonPointerResolver;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Sentinel stored in the frame slot of an external parameter the caller
3
+ * did not bind; evaluating a reference to it raises JQ2006.
4
+ */
5
+ export declare const UNBOUND: unique symbol;
6
+ /**
7
+ * Existence-only compilation for `$exists`/`$empty` (and any future
8
+ * boolean context): paths never materialize a result sequence (the
9
+ * analogue of path.js's compileExists). Takes the operand AST node -
10
+ * this is why registry `compile` functions receive arg nodes, not just
11
+ * getters.
12
+ * @param {object} node - a frozen AST node from normalize.js
13
+ * @returns {(frame: any[]) => boolean}
14
+ */
15
+ export declare function compileExistsTest(node: object): (frame: any[]) => boolean;
16
+ /**
17
+ * Compile a normalized AST node into its getter closure.
18
+ * @param {object} node - a frozen AST node from normalize.js
19
+ * @returns {(frame: any[]) => any} getter returning an item, EMPTY, or a Seq
20
+ */
21
+ export declare function compileNode(node: object): (frame: any[]) => any;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Error thrown when a query document is rejected at compile time
3
+ * (`JQ0xxx` codes, QUERY-FORMAT.md section 10.2).
4
+ */
5
+ export declare class JsonQueryCompileError extends Error {
6
+ code: any;
7
+ docPath: any;
8
+ constructor(code: any, message: any, docPath: any);
9
+ }
10
+ /**
11
+ * Error thrown when evaluating a compiled query fails
12
+ * (`JQ2xxx` codes, QUERY-FORMAT.md section 10.3).
13
+ */
14
+ export declare class JsonQueryRuntimeError extends Error {
15
+ code: any;
16
+ docPath: any;
17
+ constructor(code: any, message: any, docPath: any);
18
+ }
@@ -0,0 +1,70 @@
1
+ export { JsonQueryCompileError, JsonQueryRuntimeError } from './errors.js';
2
+ /**
3
+ * Compile a Jaren JSON Query document into a reusable query function.
4
+ *
5
+ * The returned function applies the query to a JSON value and returns the
6
+ * result as plain JSON: `undefined` for the empty sequence, the item
7
+ * itself for a singleton result, an array of items for a longer sequence.
8
+ * It also carries helper methods and metadata:
9
+ *
10
+ * - `query(data, externals?)` - the query result as described above
11
+ * - `query.first(data, externals?)` - first item of the result, or `undefined`
12
+ * - `query.exists(data, externals?)` - true when the result is non-empty
13
+ * - `query.ebv(data, externals?)` - the effective boolean value of the
14
+ * result per the EBV table (section 2.2): empty -> false, a singleton
15
+ * per its type (array/object -> true, D3), two or more items ->
16
+ * `JsonQueryRuntimeError` JQ2003. Computed on the internal sequence
17
+ * value, before the plain-JSON mapping - the mapped result is ambiguous
18
+ * there (an array is both a multi-item sequence and one array item).
19
+ * - `query.externals` - names of the external parameters (section 9), in
20
+ * order of first appearance; bind them via the `externals` argument
21
+ * (`{ name: value, ... }`). Evaluating a reference to an unbound
22
+ * external raises `JQ2006`.
23
+ * - `query.doc` - a deeply frozen copy of the query document (the
24
+ * caller's object is never frozen)
25
+ *
26
+ * @param {any} doc - the query document (any JSON value; a bare RFC 9535
27
+ * JSONPath string is the degenerate query)
28
+ * @param {object} [options] - compile options
29
+ * @param {(schemaJson: any, docPath: string) => ((value: any) => boolean)}
30
+ * [options.compileTypeTest] - hook compiling a JSON Schema literal into
31
+ * a boolean item predicate, called once per schema literal at query
32
+ * compile time (QUERY-FORMAT.md section 8.11). `@jarenjs/validate/query`
33
+ * exports `createTypeTestCompiler()` producing one; any conforming
34
+ * implementation works - this package never imports the validator.
35
+ * Without a hook, the schema operators `$valid`/`$assert`/`$as` are
36
+ * compile error JQ0008.
37
+ * @param {object} [options.extensions] - package-internal operator
38
+ * extension point, the operator analogue of `compileTypeTest` (used by
39
+ * the JSLT layer; not a public contract). A plain object of
40
+ * `name -> entry` following the operator registry contract; see
41
+ * normalizeQuery in normalize.js for the full shape. The published
42
+ * format vocabulary is unchanged: without extensions, documents using
43
+ * such operators fail JQ0002.
44
+ * @returns {function} the compiled query function
45
+ * @throws {JsonQueryCompileError} when the document violates the format
46
+ * @example
47
+ * const q = compileJsonQuery({
48
+ * "$let": { "b": "$.store.book[0]" },
49
+ * "$return": { "title": "$b.title", "cheap": { "$lt": ["$b.price", "$max"] } }
50
+ * });
51
+ * q.externals; // ['max']
52
+ * q(data, { max: 10 }); // { title: 'Sayings of the Century', cheap: true }
53
+ */
54
+ export declare function compileJsonQuery(doc: any, options?: {
55
+ compileTypeTest?: (schemaJson: any, docPath: string) => ((value: any) => boolean);
56
+ extensions?: object;
57
+ }): Function;
58
+ /**
59
+ * Apply a Jaren JSON Query document to a JSON value in one call.
60
+ * Compiled queries are cached: object documents by identity (WeakMap),
61
+ * string documents (the degenerate JSONPath case) by value (FIFO, 512
62
+ * entries - the same pattern as `queryJSONPath`).
63
+ * @param {any} doc - the query document
64
+ * @param {any} data - the JSON value to query
65
+ * @param {object} [externals] - external parameter bindings (`{ name: value }`)
66
+ * @returns {any} the query result (undefined | item | array of items)
67
+ * @throws {JsonQueryCompileError} when the document violates the format
68
+ * @throws {JsonQueryRuntimeError} on any JQ2xxx runtime condition
69
+ */
70
+ export declare function queryJson(doc: any, data: any, externals?: object): any;
@@ -0,0 +1,68 @@
1
+ /** Statically empty (the node always evaluates to the empty sequence). */
2
+ export declare const CARD_ZERO = 0;
3
+ /** Always exactly one item; compile.js skips all sequence checks. */
4
+ export declare const CARD_ONE = 1;
5
+ /** Zero or one item. */
6
+ export declare const CARD_OPT = 2;
7
+ /** Any number of items (the analysis top). */
8
+ export declare const CARD_MANY = 3;
9
+ /**
10
+ * join = least upper bound over {ZERO, ONE, OPT, MANY}: the cardinality
11
+ * of "one of the two branches" ($if).
12
+ * @param {number} a - a CARD_* value
13
+ * @param {number} b - a CARD_* value
14
+ * @returns {number}
15
+ */
16
+ export declare function joinCard(a: number, b: number): number;
17
+ /**
18
+ * sum = cardinality of two concatenated sequences ($seq); two non-empty
19
+ * contributions can exceed one item, which only MANY can express.
20
+ * @param {number} a - a CARD_* value
21
+ * @param {number} b - a CARD_* value
22
+ * @returns {number}
23
+ */
24
+ export declare function sumCard(a: number, b: number): number;
25
+ /**
26
+ * Deep-copy a JSON value and freeze every object/array in the copy.
27
+ * Used for `$const` values and the compiled query's `.doc` property, so
28
+ * the engine never freezes (or shares mutable state with) caller objects.
29
+ * @param {any} value - a JSON value
30
+ * @returns {any} an independent, deeply frozen copy
31
+ */
32
+ export declare function deepFreezeCopy(value: any): any;
33
+ /**
34
+ * Normalize a query document into the internal AST.
35
+ * @param {any} doc - the query document (any JSON value)
36
+ * @param {object} [options] - compile options
37
+ * @param {(schemaJson: any, docPath: string) => ((value: any) => boolean)}
38
+ * [options.compileTypeTest] - host hook compiling a JSON Schema literal
39
+ * into a boolean item predicate (QUERY-FORMAT.md section 8.11). Called
40
+ * once per schema literal, at query compile time. Without it, schema
41
+ * operators ($valid/$assert/$as) are compile error JQ0008.
42
+ * @param {object} [options.extensions] - package-internal operator
43
+ * extension point, the operator analogue of `compileTypeTest` (used by
44
+ * the JSLT layer; not a public contract). A plain object of
45
+ * `name -> entry`, where entry follows the operator registry contract
46
+ * (`params`/`result`/`compile`, operators.js header) plus an optional
47
+ * `normalize(arg, docPath, opPath, scope, ctx, helpers) -> {args, card?}`
48
+ * override for polymorphic value shapes. Names must start with '$' and
49
+ * must not collide with the core vocabulary (TypeError - a host
50
+ * programming error, not a JQ0xxx document error). The published format
51
+ * and its schema are unchanged: without extensions, the same documents
52
+ * fail JQ0002.
53
+ * @returns {{ root: object, frameSize: number, externals: {name: string, slot: number}[] }}
54
+ * the AST root, the frame size, and the external parameters in order of
55
+ * first appearance (slot order)
56
+ * @throws {JsonQueryCompileError} on any JQ0xxx condition
57
+ */
58
+ export declare function normalizeQuery(doc: any, options?: {
59
+ compileTypeTest?: (schemaJson: any, docPath: string) => ((value: any) => boolean);
60
+ extensions?: object;
61
+ }): {
62
+ root: object;
63
+ frameSize: number;
64
+ externals: {
65
+ name: string;
66
+ slot: number;
67
+ }[];
68
+ };