@plumile/filter-query 0.1.17

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 (82) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +202 -0
  3. package/lib/errors.d.ts +39 -0
  4. package/lib/errors.d.ts.map +1 -0
  5. package/lib/errors.js +2 -0
  6. package/lib/esm/errors.d.ts +39 -0
  7. package/lib/esm/errors.d.ts.map +1 -0
  8. package/lib/esm/errors.js +2 -0
  9. package/lib/esm/index.d.ts +7 -0
  10. package/lib/esm/index.d.ts.map +1 -0
  11. package/lib/esm/index.js +5 -0
  12. package/lib/esm/mutate.d.ts +6 -0
  13. package/lib/esm/mutate.d.ts.map +1 -0
  14. package/lib/esm/mutate.js +88 -0
  15. package/lib/esm/parse.d.ts +3 -0
  16. package/lib/esm/parse.d.ts.map +1 -0
  17. package/lib/esm/parse.js +164 -0
  18. package/lib/esm/schema.d.ts +5 -0
  19. package/lib/esm/schema.d.ts.map +1 -0
  20. package/lib/esm/schema.js +55 -0
  21. package/lib/esm/stringify.d.ts +3 -0
  22. package/lib/esm/stringify.d.ts.map +1 -0
  23. package/lib/esm/stringify.js +50 -0
  24. package/lib/esm/types.d.ts +43 -0
  25. package/lib/esm/types.d.ts.map +1 -0
  26. package/lib/esm/types.js +2 -0
  27. package/lib/index.d.ts +7 -0
  28. package/lib/index.d.ts.map +1 -0
  29. package/lib/index.js +5 -0
  30. package/lib/mutate.d.ts +6 -0
  31. package/lib/mutate.d.ts.map +1 -0
  32. package/lib/mutate.js +88 -0
  33. package/lib/parse.d.ts +3 -0
  34. package/lib/parse.d.ts.map +1 -0
  35. package/lib/parse.js +164 -0
  36. package/lib/schema.d.ts +5 -0
  37. package/lib/schema.d.ts.map +1 -0
  38. package/lib/schema.js +55 -0
  39. package/lib/stringify.d.ts +3 -0
  40. package/lib/stringify.d.ts.map +1 -0
  41. package/lib/stringify.js +50 -0
  42. package/lib/tsconfig.esm.tsbuildinfo +1 -0
  43. package/lib/types/errors.d.ts +39 -0
  44. package/lib/types/errors.d.ts.map +1 -0
  45. package/lib/types/index.d.ts +7 -0
  46. package/lib/types/index.d.ts.map +1 -0
  47. package/lib/types/mutate.d.ts +6 -0
  48. package/lib/types/mutate.d.ts.map +1 -0
  49. package/lib/types/parse.d.ts +3 -0
  50. package/lib/types/parse.d.ts.map +1 -0
  51. package/lib/types/schema.d.ts +5 -0
  52. package/lib/types/schema.d.ts.map +1 -0
  53. package/lib/types/stringify.d.ts +3 -0
  54. package/lib/types/stringify.d.ts.map +1 -0
  55. package/lib/types/types.d.ts +43 -0
  56. package/lib/types/types.d.ts.map +1 -0
  57. package/lib/types.d.ts +43 -0
  58. package/lib/types.d.ts.map +1 -0
  59. package/lib/types.js +2 -0
  60. package/package.json +43 -0
  61. package/src/__tests__/additional-coverage.test.ts +82 -0
  62. package/src/__tests__/list-edge.test.ts +26 -0
  63. package/src/__tests__/mutate.test.ts +33 -0
  64. package/src/__tests__/parse-stringify.test.ts +104 -0
  65. package/src/__tests__/remove-filter.test.ts +46 -0
  66. package/src/__tests__/schema-edge.test.ts +46 -0
  67. package/src/__tests__/schema-infer.test-d.ts +24 -0
  68. package/src/__tests__/stability-and-diagnostics.test.ts +40 -0
  69. package/src/errors.ts +46 -0
  70. package/src/index.ts +6 -0
  71. package/src/mutate.ts +132 -0
  72. package/src/parse.ts +221 -0
  73. package/src/schema.ts +81 -0
  74. package/src/stringify.ts +60 -0
  75. package/src/types.ts +88 -0
  76. package/tools/build-package.sh +5 -0
  77. package/tools/test-build-package.sh +4 -0
  78. package/tsconfig.build.json +8 -0
  79. package/tsconfig.esm.json +7 -0
  80. package/tsconfig.json +8 -0
  81. package/tsconfig.types.json +9 -0
  82. package/vitest.config.ts +7 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Plumile and its affiliates.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,202 @@
1
+ # @plumile/filter-query
2
+
3
+ Typed, schema‑driven filter query string parser / serializer with immutable helpers and strong TypeScript inference. Zero runtime dependencies.
4
+
5
+ ## Why?
6
+
7
+ Applications often encode complex filter state (numbers, ranges, multi-selects, text searches) into a URL query string. Ad‑hoc solutions easily drift: inconsistent operator names, ambiguous serialization, lost type safety, brittle parsing, and noisy re-renders. `@plumile/filter-query` gives you:
8
+
9
+ - A mandatory schema (single source of truth) declaring fields and allowed operators.
10
+ - Deterministic, canonical string generation (stable ordering for cache keys & SSR).
11
+ - Strong TypeScript inference for the shape of `filters` (no manual typings).
12
+ - Non‑blocking diagnostics instead of exceptions (you decide how to surface issues).
13
+ - Immutable, reference‑stable mutation helpers (minimize React renders / memo churn).
14
+ - Simple, explicit operator semantics (predictable merging & precedence rules).
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install @plumile/filter-query
20
+ ```
21
+
22
+ ## Core Concepts
23
+
24
+ | Concept | Description |
25
+ | ---------------- | --------------------------------------------------------------------------------- |
26
+ | Schema | Object produced by `defineSchema({ field: numberField(), ... })`. Required. |
27
+ | Field Descriptor | `numberField()` or `stringField()` optionally with a custom operator whitelist. |
28
+ | Filters Object | Parsed result shape inferred from the schema (operators become optional keys). |
29
+ | Diagnostics | Array of non-blocking issues (unknown field/op, invalid value, etc.). |
30
+ | Mutation Helpers | Pure functions returning new filter objects (or the same reference if no change). |
31
+
32
+ ## Supported Operators
33
+
34
+ | Category | Operators | Syntax | Notes |
35
+ | ------------------ | ------------------------------------- | -------------------------- | --------------------------------------------------------------------------------- |
36
+ | Numeric comparison | `gt`, `gte`, `lt`, `lte`, `eq`, `neq` | `price.gt=10` | Last write wins per operator. |
37
+ | Textual comparison | `eq`, `neq` | `title.eq=foo` | Works for strings too. |
38
+ | Text search | `contains`, `sw`, `ew` | `title.contains=foo%20bar` | Raw values URL-decoded. |
39
+ | Range | `between` | `price.between=10,100` | Only first valid occurrence kept; duplicates yield `DuplicateBetween` diagnostic. |
40
+ | Inclusion lists | `in` | `id.in=1,2,3` | Multi-occurrences merge: `id.in=1,2&id.in=3` → `[1,2,3]`. |
41
+ | Exclusion lists | `nin` | `id.nin=4,5&...` | Same merging logic as `in`. |
42
+
43
+ ### Value Parsing Rules
44
+
45
+ - Number field: attempts `Number()`, rejects `NaN` / `Infinity`.
46
+ - String field: raw decoded string (empty string allowed, but not produced by numeric parse).
47
+ - Lists: split by comma; invalid members emit `InvalidValue` and are skipped; empty result discards whole operator.
48
+ - Between: must have exactly 2 comma‑separated values; otherwise `InvalidArity`.
49
+ - Duplicate `between`: first valid stored, later ones produce `DuplicateBetween`.
50
+
51
+ ## Quick Start
52
+
53
+ ```ts
54
+ import {
55
+ defineSchema,
56
+ numberField,
57
+ stringField,
58
+ parse,
59
+ stringify,
60
+ setFilter,
61
+ } from '@plumile/filter-query';
62
+
63
+ const schema = defineSchema({
64
+ price: numberField(),
65
+ title: stringField(),
66
+ });
67
+
68
+ // Parse URL search (leading '?' optional)
69
+ const { filters, diagnostics } = parse(
70
+ 'price.gt=10&title.contains=foo%20bar',
71
+ schema,
72
+ );
73
+ // filters.price?.gt === 10, filters.title?.contains === 'foo bar'
74
+ // diagnostics: []
75
+
76
+ // Apply immutable mutation
77
+ const updated = setFilter(filters, schema, 'price', 'between', [10, 100]);
78
+
79
+ // Serialize back (canonical ordering: schema field order, then operator order)
80
+ const qs = stringify(updated, schema);
81
+ // => price.gt=10&price.between=10,100&title.contains=foo%20bar
82
+ ```
83
+
84
+ ## Schema Definition
85
+
86
+ ```ts
87
+ const schema = defineSchema({
88
+ price: numberField(), // full numeric operator set
89
+ title: stringField(['contains', 'sw']), // restrict to subset
90
+ });
91
+ ```
92
+
93
+ Both helpers accept an optional operator list to _whitelist_ allowed operators (anything not listed becomes `UnknownOperator` if present in input).
94
+
95
+ ### Operator Defaults
96
+
97
+ - `numberField()` default: `gt,gte,lt,lte,eq,neq,between,in,nin`
98
+ - `stringField()` default: `contains,sw,ew,eq,neq,in,nin`
99
+
100
+ ## Diagnostics
101
+
102
+ Returned shape:
103
+
104
+ ```ts
105
+ interface DiagnosticBase {
106
+ kind: string;
107
+ field?: string;
108
+ operator?: string;
109
+ detail?: string;
110
+ }
111
+ // Kinds: 'UnknownField' | 'UnknownOperator' | 'InvalidValue' | 'InvalidArity' | 'DuplicateBetween' | 'DecodeError'
112
+ ```
113
+
114
+ Parsing never throws for content errors; all issues are accumulated. You decide how to surface them (log panel, dev overlay, UI badges, etc.).
115
+
116
+ ## Filters Object & Type Inference
117
+
118
+ From a schema:
119
+
120
+ ```ts
121
+ const schema = defineSchema({ price: numberField(), title: stringField() });
122
+ ```
123
+
124
+ The inferred `filters` type is roughly:
125
+
126
+ ```ts
127
+ {
128
+ price?: {
129
+ gt?: number; gte?: number; lt?: number; lte?: number; eq?: number; neq?: number;
130
+ between?: readonly [number, number];
131
+ in?: readonly number[]; nin?: readonly number[];
132
+ };
133
+ title?: {
134
+ contains?: string; sw?: string; ew?: string; eq?: string; neq?: string;
135
+ in?: readonly string[]; nin?: readonly string[];
136
+ };
137
+ }
138
+ ```
139
+
140
+ Everything is optional so you can build partial filters progressively.
141
+
142
+ ## Mutation Helpers
143
+
144
+ ```ts
145
+ setFilter(filters, schema, 'price', 'gt', 10); // add/update value
146
+ setFilter(filters, schema, 'price', 'gt', undefined); // remove operator key
147
+ removeFilter(filters, 'price'); // drop entire field
148
+ removeFilter(filters, 'price', 'gt'); // drop one operator
149
+ mergeFilters(base, patch); // shallow merge per field
150
+ ```
151
+
152
+ ### Reference Stability
153
+
154
+ - If a mutation results in no semantic change → the _same_ object reference is returned.
155
+ - Enables cheap memoization (`useMemo`, React context selectors, etc.).
156
+
157
+ ## Serialization Rules
158
+
159
+ 1. Field iteration order = schema object key order (stable in modern JS for own string keys).
160
+ 2. Operator order = `descriptor.operators` order.
161
+ 3. Operators with no value / empty arrays are skipped.
162
+ 4. List operators keep insertion order across multi-occurrences.
163
+ 5. Output omits leading `?` (caller decides how to prefix).
164
+
165
+ ## Edge Cases & Examples
166
+
167
+ | Input | Result | Diagnostics |
168
+ | ------------------------------------- | -------------------------- | ------------------------------------------- |
169
+ | `price.gt=abc` | `filters.price?.gt` absent | `InvalidValue` |
170
+ | `price.between=1,2,3` | none stored | `InvalidArity` |
171
+ | `price.between=1,5&price.between=2,6` | `[1,5]` | `DuplicateBetween` |
172
+ | `price.in=` | ignored | none (empty split produces no valid values) |
173
+ | `unknown.gt=5` | ignored | `UnknownField` |
174
+ | `price.xyz=5` | ignored | `UnknownOperator` |
175
+ | `title.contains=x%ZZ` | ignored | `DecodeError` + maybe others |
176
+
177
+ ## Custom Operator Subsets
178
+
179
+ ```ts
180
+ const minimal = defineSchema({ price: numberField(['gt', 'lt']) });
181
+ // parse('price.eq=5', minimal) → diagnostics: UnknownOperator
182
+ ```
183
+
184
+ ## Performance Notes
185
+
186
+ - Parsing is single pass over pairs; only allocates for: decoded strings, filter field objects when first used, diagnostics entries.
187
+ - Mutations avoid cloning unchanged branches (shallow one-level cloning only when something changes).
188
+
189
+ ## FAQ
190
+
191
+ **Q: Why not support arbitrary operator names?**
192
+ To keep type inference precise and predictable. Add new core operators via a PR if they are broadly useful.
193
+
194
+ **Q: How do I clear everything?**
195
+ Just use an empty object `{}` or parse an empty string and replace your state reference.
196
+
197
+ **Q: Does order of repeated list operators matter?**
198
+ Yes, items are appended in encounter order, preserving user intent (e.g. prioritized IDs).
199
+
200
+ ## License
201
+
202
+ MIT
@@ -0,0 +1,39 @@
1
+ export type Diagnostic = UnknownFieldDiagnostic | UnknownOperatorDiagnostic | InvalidValueDiagnostic | InvalidArityDiagnostic | DuplicateBetweenDiagnostic | DecodeErrorDiagnostic;
2
+ export interface BaseDiagnostic {
3
+ readonly kind: string;
4
+ readonly field?: string;
5
+ readonly operator?: string;
6
+ readonly detail?: string;
7
+ }
8
+ export interface UnknownFieldDiagnostic extends BaseDiagnostic {
9
+ kind: 'UnknownField';
10
+ field: string;
11
+ }
12
+ export interface UnknownOperatorDiagnostic extends BaseDiagnostic {
13
+ kind: 'UnknownOperator';
14
+ field: string;
15
+ operator: string;
16
+ }
17
+ export interface InvalidValueDiagnostic extends BaseDiagnostic {
18
+ kind: 'InvalidValue';
19
+ field: string;
20
+ operator: string;
21
+ detail?: string;
22
+ }
23
+ export interface InvalidArityDiagnostic extends BaseDiagnostic {
24
+ kind: 'InvalidArity';
25
+ field: string;
26
+ operator: string;
27
+ detail: string;
28
+ }
29
+ export interface DuplicateBetweenDiagnostic extends BaseDiagnostic {
30
+ kind: 'DuplicateBetween';
31
+ field: string;
32
+ }
33
+ export interface DecodeErrorDiagnostic extends BaseDiagnostic {
34
+ kind: 'DecodeError';
35
+ field: string;
36
+ operator: string;
37
+ detail: string;
38
+ }
39
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAClB,sBAAsB,GACtB,yBAAyB,GACzB,sBAAsB,GACtB,sBAAsB,GACtB,0BAA0B,GAC1B,qBAAqB,CAAC;AAE1B,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,sBAAuB,SAAQ,cAAc;IAC5D,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AACD,MAAM,WAAW,yBAA0B,SAAQ,cAAc;IAC/D,IAAI,EAAE,iBAAiB,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AACD,MAAM,WAAW,sBAAuB,SAAQ,cAAc;IAC5D,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AACD,MAAM,WAAW,sBAAuB,SAAQ,cAAc;IAC5D,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AACD,MAAM,WAAW,0BAA2B,SAAQ,cAAc;IAChE,IAAI,EAAE,kBAAkB,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACf;AACD,MAAM,WAAW,qBAAsB,SAAQ,cAAc;IAC3D,IAAI,EAAE,aAAa,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB"}
package/lib/errors.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3JzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2Vycm9ycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHR5cGUgRGlhZ25vc3RpYyA9XG4gIHwgVW5rbm93bkZpZWxkRGlhZ25vc3RpY1xuICB8IFVua25vd25PcGVyYXRvckRpYWdub3N0aWNcbiAgfCBJbnZhbGlkVmFsdWVEaWFnbm9zdGljXG4gIHwgSW52YWxpZEFyaXR5RGlhZ25vc3RpY1xuICB8IER1cGxpY2F0ZUJldHdlZW5EaWFnbm9zdGljXG4gIHwgRGVjb2RlRXJyb3JEaWFnbm9zdGljO1xuXG5leHBvcnQgaW50ZXJmYWNlIEJhc2VEaWFnbm9zdGljIHtcbiAgcmVhZG9ubHkga2luZDogc3RyaW5nO1xuICByZWFkb25seSBmaWVsZD86IHN0cmluZztcbiAgcmVhZG9ubHkgb3BlcmF0b3I/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGRldGFpbD86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBVbmtub3duRmllbGREaWFnbm9zdGljIGV4dGVuZHMgQmFzZURpYWdub3N0aWMge1xuICBraW5kOiAnVW5rbm93bkZpZWxkJztcbiAgZmllbGQ6IHN0cmluZztcbn1cbmV4cG9ydCBpbnRlcmZhY2UgVW5rbm93bk9wZXJhdG9yRGlhZ25vc3RpYyBleHRlbmRzIEJhc2VEaWFnbm9zdGljIHtcbiAga2luZDogJ1Vua25vd25PcGVyYXRvcic7XG4gIGZpZWxkOiBzdHJpbmc7XG4gIG9wZXJhdG9yOiBzdHJpbmc7XG59XG5leHBvcnQgaW50ZXJmYWNlIEludmFsaWRWYWx1ZURpYWdub3N0aWMgZXh0ZW5kcyBCYXNlRGlhZ25vc3RpYyB7XG4gIGtpbmQ6ICdJbnZhbGlkVmFsdWUnO1xuICBmaWVsZDogc3RyaW5nO1xuICBvcGVyYXRvcjogc3RyaW5nO1xuICBkZXRhaWw/OiBzdHJpbmc7XG59XG5leHBvcnQgaW50ZXJmYWNlIEludmFsaWRBcml0eURpYWdub3N0aWMgZXh0ZW5kcyBCYXNlRGlhZ25vc3RpYyB7XG4gIGtpbmQ6ICdJbnZhbGlkQXJpdHknO1xuICBmaWVsZDogc3RyaW5nO1xuICBvcGVyYXRvcjogc3RyaW5nO1xuICBkZXRhaWw6IHN0cmluZzsgLy8gZXhwZWN0ZWQgYXJpdHkgaW5mb1xufVxuZXhwb3J0IGludGVyZmFjZSBEdXBsaWNhdGVCZXR3ZWVuRGlhZ25vc3RpYyBleHRlbmRzIEJhc2VEaWFnbm9zdGljIHtcbiAga2luZDogJ0R1cGxpY2F0ZUJldHdlZW4nO1xuICBmaWVsZDogc3RyaW5nO1xufVxuZXhwb3J0IGludGVyZmFjZSBEZWNvZGVFcnJvckRpYWdub3N0aWMgZXh0ZW5kcyBCYXNlRGlhZ25vc3RpYyB7XG4gIGtpbmQ6ICdEZWNvZGVFcnJvcic7XG4gIGZpZWxkOiBzdHJpbmc7XG4gIG9wZXJhdG9yOiBzdHJpbmc7XG4gIGRldGFpbDogc3RyaW5nO1xufVxuIl19
@@ -0,0 +1,39 @@
1
+ export type Diagnostic = UnknownFieldDiagnostic | UnknownOperatorDiagnostic | InvalidValueDiagnostic | InvalidArityDiagnostic | DuplicateBetweenDiagnostic | DecodeErrorDiagnostic;
2
+ export interface BaseDiagnostic {
3
+ readonly kind: string;
4
+ readonly field?: string;
5
+ readonly operator?: string;
6
+ readonly detail?: string;
7
+ }
8
+ export interface UnknownFieldDiagnostic extends BaseDiagnostic {
9
+ kind: 'UnknownField';
10
+ field: string;
11
+ }
12
+ export interface UnknownOperatorDiagnostic extends BaseDiagnostic {
13
+ kind: 'UnknownOperator';
14
+ field: string;
15
+ operator: string;
16
+ }
17
+ export interface InvalidValueDiagnostic extends BaseDiagnostic {
18
+ kind: 'InvalidValue';
19
+ field: string;
20
+ operator: string;
21
+ detail?: string;
22
+ }
23
+ export interface InvalidArityDiagnostic extends BaseDiagnostic {
24
+ kind: 'InvalidArity';
25
+ field: string;
26
+ operator: string;
27
+ detail: string;
28
+ }
29
+ export interface DuplicateBetweenDiagnostic extends BaseDiagnostic {
30
+ kind: 'DuplicateBetween';
31
+ field: string;
32
+ }
33
+ export interface DecodeErrorDiagnostic extends BaseDiagnostic {
34
+ kind: 'DecodeError';
35
+ field: string;
36
+ operator: string;
37
+ detail: string;
38
+ }
39
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAClB,sBAAsB,GACtB,yBAAyB,GACzB,sBAAsB,GACtB,sBAAsB,GACtB,0BAA0B,GAC1B,qBAAqB,CAAC;AAE1B,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,sBAAuB,SAAQ,cAAc;IAC5D,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AACD,MAAM,WAAW,yBAA0B,SAAQ,cAAc;IAC/D,IAAI,EAAE,iBAAiB,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AACD,MAAM,WAAW,sBAAuB,SAAQ,cAAc;IAC5D,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AACD,MAAM,WAAW,sBAAuB,SAAQ,cAAc;IAC5D,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AACD,MAAM,WAAW,0BAA2B,SAAQ,cAAc;IAChE,IAAI,EAAE,kBAAkB,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACf;AACD,MAAM,WAAW,qBAAsB,SAAQ,cAAc;IAC3D,IAAI,EAAE,aAAa,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3JzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Vycm9ycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHR5cGUgRGlhZ25vc3RpYyA9XG4gIHwgVW5rbm93bkZpZWxkRGlhZ25vc3RpY1xuICB8IFVua25vd25PcGVyYXRvckRpYWdub3N0aWNcbiAgfCBJbnZhbGlkVmFsdWVEaWFnbm9zdGljXG4gIHwgSW52YWxpZEFyaXR5RGlhZ25vc3RpY1xuICB8IER1cGxpY2F0ZUJldHdlZW5EaWFnbm9zdGljXG4gIHwgRGVjb2RlRXJyb3JEaWFnbm9zdGljO1xuXG5leHBvcnQgaW50ZXJmYWNlIEJhc2VEaWFnbm9zdGljIHtcbiAgcmVhZG9ubHkga2luZDogc3RyaW5nO1xuICByZWFkb25seSBmaWVsZD86IHN0cmluZztcbiAgcmVhZG9ubHkgb3BlcmF0b3I/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGRldGFpbD86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBVbmtub3duRmllbGREaWFnbm9zdGljIGV4dGVuZHMgQmFzZURpYWdub3N0aWMge1xuICBraW5kOiAnVW5rbm93bkZpZWxkJztcbiAgZmllbGQ6IHN0cmluZztcbn1cbmV4cG9ydCBpbnRlcmZhY2UgVW5rbm93bk9wZXJhdG9yRGlhZ25vc3RpYyBleHRlbmRzIEJhc2VEaWFnbm9zdGljIHtcbiAga2luZDogJ1Vua25vd25PcGVyYXRvcic7XG4gIGZpZWxkOiBzdHJpbmc7XG4gIG9wZXJhdG9yOiBzdHJpbmc7XG59XG5leHBvcnQgaW50ZXJmYWNlIEludmFsaWRWYWx1ZURpYWdub3N0aWMgZXh0ZW5kcyBCYXNlRGlhZ25vc3RpYyB7XG4gIGtpbmQ6ICdJbnZhbGlkVmFsdWUnO1xuICBmaWVsZDogc3RyaW5nO1xuICBvcGVyYXRvcjogc3RyaW5nO1xuICBkZXRhaWw/OiBzdHJpbmc7XG59XG5leHBvcnQgaW50ZXJmYWNlIEludmFsaWRBcml0eURpYWdub3N0aWMgZXh0ZW5kcyBCYXNlRGlhZ25vc3RpYyB7XG4gIGtpbmQ6ICdJbnZhbGlkQXJpdHknO1xuICBmaWVsZDogc3RyaW5nO1xuICBvcGVyYXRvcjogc3RyaW5nO1xuICBkZXRhaWw6IHN0cmluZzsgLy8gZXhwZWN0ZWQgYXJpdHkgaW5mb1xufVxuZXhwb3J0IGludGVyZmFjZSBEdXBsaWNhdGVCZXR3ZWVuRGlhZ25vc3RpYyBleHRlbmRzIEJhc2VEaWFnbm9zdGljIHtcbiAga2luZDogJ0R1cGxpY2F0ZUJldHdlZW4nO1xuICBmaWVsZDogc3RyaW5nO1xufVxuZXhwb3J0IGludGVyZmFjZSBEZWNvZGVFcnJvckRpYWdub3N0aWMgZXh0ZW5kcyBCYXNlRGlhZ25vc3RpYyB7XG4gIGtpbmQ6ICdEZWNvZGVFcnJvcic7XG4gIGZpZWxkOiBzdHJpbmc7XG4gIG9wZXJhdG9yOiBzdHJpbmc7XG4gIGRldGFpbDogc3RyaW5nO1xufVxuIl19
@@ -0,0 +1,7 @@
1
+ export type * from './types.js';
2
+ export * from './schema.js';
3
+ export type * from './errors.js';
4
+ export * from './parse.js';
5
+ export * from './stringify.js';
6
+ export * from './mutate.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,YAAY,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,mBAAmB,aAAa,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC"}
@@ -0,0 +1,5 @@
1
+ export * from './schema.js';
2
+ export * from './parse.js';
3
+ export * from './stringify.js';
4
+ export * from './mutate.js';
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsY0FBYyxhQUFhLENBQUM7QUFFNUIsY0FBYyxZQUFZLENBQUM7QUFDM0IsY0FBYyxnQkFBZ0IsQ0FBQztBQUMvQixjQUFjLGFBQWEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCB0eXBlICogZnJvbSAnLi90eXBlcy5qcyc7XG5leHBvcnQgKiBmcm9tICcuL3NjaGVtYS5qcyc7XG5leHBvcnQgdHlwZSAqIGZyb20gJy4vZXJyb3JzLmpzJztcbmV4cG9ydCAqIGZyb20gJy4vcGFyc2UuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9zdHJpbmdpZnkuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9tdXRhdGUuanMnO1xuIl19
@@ -0,0 +1,6 @@
1
+ import type { InferFilters, Schema } from './types.js';
2
+ export declare function setFilter<S extends Schema, F extends keyof S, O extends keyof NonNullable<InferFilters<S>[F]>>(filters: Readonly<InferFilters<S>>, _schema: S, field: F, operator: O, value: NonNullable<InferFilters<S>[F]>[O] | undefined): InferFilters<S>;
3
+ export declare function removeFilter<S extends Schema, F extends keyof S>(filters: Readonly<InferFilters<S>>, field: F, operator?: keyof NonNullable<InferFilters<S>[F]>): InferFilters<S>;
4
+ export declare function mergeFilters<S extends Schema>(base: Readonly<InferFilters<S>>, patch: Readonly<InferFilters<S>>): InferFilters<S>;
5
+ export declare function isEmpty<S extends Schema>(filters: Readonly<InferFilters<S>>): boolean;
6
+ //# sourceMappingURL=mutate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutate.d.ts","sourceRoot":"","sources":["../../src/mutate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAmCvD,wBAAgB,SAAS,CACvB,CAAC,SAAS,MAAM,EAChB,CAAC,SAAS,MAAM,CAAC,EACjB,CAAC,SAAS,MAAM,WAAW,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAE/C,OAAO,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAClC,OAAO,EAAE,CAAC,EACV,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,CAAC,EACX,KAAK,EAAE,WAAW,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,GACpD,YAAY,CAAC,CAAC,CAAC,CAwBjB;AAKD,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,CAAC,EAC9D,OAAO,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAClC,KAAK,EAAE,CAAC,EACR,QAAQ,CAAC,EAAE,MAAM,WAAW,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAC/C,YAAY,CAAC,CAAC,CAAC,CAkBjB;AAKD,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,EAC3C,IAAI,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAC/B,KAAK,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,GAC/B,YAAY,CAAC,CAAC,CAAC,CAoBjB;AAGD,wBAAgB,OAAO,CAAC,CAAC,SAAS,MAAM,EACtC,OAAO,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,GACjC,OAAO,CAET"}
@@ -0,0 +1,88 @@
1
+ function shallowEqual(a, b) {
2
+ if (a === b) {
3
+ return true;
4
+ }
5
+ if (typeof a !== 'object' ||
6
+ a === null ||
7
+ typeof b !== 'object' ||
8
+ b === null) {
9
+ return false;
10
+ }
11
+ const aObj = a;
12
+ const bObj = b;
13
+ const aKeys = Object.keys(aObj);
14
+ const bKeys = Object.keys(bObj);
15
+ if (aKeys.length !== bKeys.length) {
16
+ return false;
17
+ }
18
+ for (const k of aKeys) {
19
+ if (aObj[k] !== bObj[k]) {
20
+ return false;
21
+ }
22
+ }
23
+ return true;
24
+ }
25
+ export function setFilter(filters, _schema, field, operator, value) {
26
+ const currentField = filters[field];
27
+ if (value === undefined) {
28
+ if (currentField === undefined) {
29
+ return filters;
30
+ }
31
+ const { [operator]: _removed, ...rest } = currentField;
32
+ if (Object.keys(rest).length === 0) {
33
+ const { [field]: _f, ...clone } = filters;
34
+ return clone;
35
+ }
36
+ return { ...filters, [field]: rest };
37
+ }
38
+ const newField = {
39
+ ...currentField,
40
+ [operator]: value,
41
+ };
42
+ if (currentField !== undefined && shallowEqual(currentField, newField)) {
43
+ return filters;
44
+ }
45
+ return { ...filters, [field]: newField };
46
+ }
47
+ export function removeFilter(filters, field, operator) {
48
+ const currentField = filters[field];
49
+ if (currentField === undefined) {
50
+ return filters;
51
+ }
52
+ if (operator === undefined) {
53
+ const { [field]: _removed, ...clone } = filters;
54
+ return clone;
55
+ }
56
+ const { [operator]: _opRemoved, ...rest } = currentField;
57
+ if (Object.keys(rest).length === 0) {
58
+ const { [field]: _f, ...clone } = filters;
59
+ return clone;
60
+ }
61
+ return { ...filters, [field]: rest };
62
+ }
63
+ export function mergeFilters(base, patch) {
64
+ let changed = false;
65
+ const result = { ...base };
66
+ for (const key of Object.keys(patch)) {
67
+ const existing = base[key];
68
+ const incoming = patch[key];
69
+ if (incoming === undefined) {
70
+ }
71
+ else if (existing === undefined) {
72
+ result[key] = incoming;
73
+ changed = true;
74
+ }
75
+ else if (!shallowEqual(existing, incoming)) {
76
+ result[key] = incoming;
77
+ changed = true;
78
+ }
79
+ }
80
+ if (changed) {
81
+ return result;
82
+ }
83
+ return base;
84
+ }
85
+ export function isEmpty(filters) {
86
+ return Object.keys(filters).length === 0;
87
+ }
88
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXV0YXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL211dGF0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFLQSxTQUFTLFlBQVksQ0FBQyxDQUFVLEVBQUUsQ0FBVTtJQUMxQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUNaLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUNELElBQ0UsT0FBTyxDQUFDLEtBQUssUUFBUTtRQUNyQixDQUFDLEtBQUssSUFBSTtRQUNWLE9BQU8sQ0FBQyxLQUFLLFFBQVE7UUFDckIsQ0FBQyxLQUFLLElBQUksRUFDVixDQUFDO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBQ0QsTUFBTSxJQUFJLEdBQUcsQ0FBNEIsQ0FBQztJQUMxQyxNQUFNLElBQUksR0FBRyxDQUE0QixDQUFDO0lBQzFDLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDaEMsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNoQyxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2xDLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUNELEtBQUssTUFBTSxDQUFDLElBQUksS0FBSyxFQUFFLENBQUM7UUFDdEIsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDeEIsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO0lBQ0gsQ0FBQztJQUNELE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQztBQUtELE1BQU0sVUFBVSxTQUFTLENBS3ZCLE9BQWtDLEVBQ2xDLE9BQVUsRUFDVixLQUFRLEVBQ1IsUUFBVyxFQUNYLEtBQXFEO0lBRXJELE1BQU0sWUFBWSxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FB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QyxZQUFZLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxFQUFFLENBQUM7WUFDN0MsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLFFBQXVDLENBQUM7WUFDdEQsT0FBTyxHQUFHLElBQUksQ0FBQztRQUNqQixDQUFDO0lBQ0gsQ0FBQztJQUNELElBQUksT0FBTyxFQUFFLENBQUM7UUFDWixPQUFPLE1BQXlCLENBQUM7SUFDbkMsQ0FBQztJQUNELE9BQU8sSUFBdUIsQ0FBQztBQUNqQyxDQUFDO0FBR0QsTUFBTSxVQUFVLE9BQU8sQ0FDckIsT0FBa0M7SUFFbEMsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUM7QUFDM0MsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgSW5mZXJGaWx0ZXJzLCBTY2hlbWEgfSBmcm9tICcuL3R5cGVzLmpzJztcblxuLyoqXG4gKiBTaGFsbG93IG9iamVjdCBlcXVhbGl0eSAob3duIGVudW1lcmFibGUgc3RyaW5nIGtleXMgb25seSkuXG4gKi9cbmZ1bmN0aW9uIHNoYWxsb3dFcXVhbChhOiB1bmtub3duLCBiOiB1bmtub3duKTogYm9vbGVhbiB7XG4gIGlmIChhID09PSBiKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKFxuICAgIHR5cGVvZiBhICE9PSAnb2JqZWN0JyB8fFxuICAgIGEgPT09IG51bGwgfHxcbiAgICB0eXBlb2YgYiAhPT0gJ29iamVjdCcgfHxcbiAgICBiID09PSBudWxsXG4gICkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBjb25zdCBhT2JqID0gYSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgY29uc3QgYk9iaiA9IGIgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIGNvbnN0IGFLZXlzID0gT2JqZWN0LmtleXMoYU9iaik7XG4gIGNvbnN0IGJLZXlzID0gT2JqZWN0LmtleXMoYk9iaik7XG4gIGlmIChhS2V5cy5sZW5ndGggIT09IGJLZXlzLmxlbmd0aCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBmb3IgKGNvbnN0IGsgb2YgYUtleXMpIHtcbiAgICBpZiAoYU9ialtrXSAhPT0gYk9ialtrXSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBTZXQgb3IgdW5zZXQgYSBzcGVjaWZpYyBvcGVyYXRvciB2YWx1ZSBmb3IgYSBmaWVsZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldEZpbHRlcjxcbiAgUyBleHRlbmRzIFNjaGVtYSxcbiAgRiBleHRlbmRzIGtleW9mIFMsXG4gIE8gZXh0ZW5kcyBrZXlvZiBOb25OdWxsYWJsZTxJbmZlckZpbHRlcnM8Uz5bRl0+LFxuPihcbiAgZmlsdGVyczogUmVhZG9ubHk8SW5mZXJGaWx0ZXJzPFM+PixcbiAgX3NjaGVtYTogUywgLy8gcmVzZXJ2ZWQgZm9yIGZ1dHVyZSB2YWxpZGF0aW9uIGhvb2tzXG4gIGZpZWxkOiBGLFxuICBvcGVyYXRvcjogTyxcbiAgdmFsdWU6IE5vbk51bGxhYmxlPEluZmVyRmlsdGVyczxTPltGXT5bT10gfCB1bmRlZmluZWQsXG4pOiBJbmZlckZpbHRlcnM8Uz4ge1xuICBjb25zdCBjdXJyZW50RmllbGQgPSBmaWx0ZXJzW2ZpZWxkXTtcbiAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICBpZiAoY3VycmVudEZpZWxkID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBmaWx0ZXJzIGFzIEluZmVyRmlsdGVyczxTPjtcbiAgICB9XG4gICAgY29uc3QgeyBbb3BlcmF0b3JdOiBfcmVtb3ZlZCwgLi4ucmVzdCB9ID0gY3VycmVudEZpZWxkIGFzIFJlY29yZDxcbiAgICAgIHN0cmluZyxcbiAgICAgIHVua25vd25cbiAgICA+O1xuICAgIGlmIChPYmplY3Qua2V5cyhyZXN0KS5sZW5ndGggPT09IDApIHtcbiAgICAgIGNvbnN0IHsgW2ZpZWxkXTogX2YsIC4uLmNsb25lIH0gPSBmaWx0ZXJzIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAgICAgcmV0dXJuIGNsb25lIGFzIEluZmVyRmlsdGVyczxTPjtcbiAgICB9XG4gICAgcmV0dXJuIHsgLi4uZmlsdGVycywgW2ZpZWxkXTogcmVzdCB9IGFzIEluZmVyRmlsdGVyczxTPjtcbiAgfVxuICBjb25zdCBuZXdGaWVsZCA9IHtcbiAgICAuLi4oY3VycmVudEZpZWxkIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgdW5kZWZpbmVkKSxcbiAgICBbb3BlcmF0b3JdOiB2YWx1ZSxcbiAgfTtcbiAgaWYgKGN1cnJlbnRGaWVsZCAhPT0gdW5kZWZpbmVkICYmIHNoYWxsb3dFcXVhbChjdXJyZW50RmllbGQsIG5ld0ZpZWxkKSkge1xuICAgIHJldHVybiBmaWx0ZXJzIGFzIEluZmVyRmlsdGVyczxTPjtcbiAgfVxuICByZXR1cm4geyAuLi5maWx0ZXJzLCBbZmllbGRdOiBuZXdGaWVsZCB9IGFzIEluZmVyRmlsdGVyczxTPjtcbn1cblxuLyoqXG4gKiBSZW1vdmUgZWl0aGVyIGFuIGVudGlyZSBmaWVsZCBvciBhIHNwZWNpZmljIG9wZXJhdG9yIGluc2lkZSBhIGZpZWxkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlRmlsdGVyPFMgZXh0ZW5kcyBTY2hlbWEsIEYgZXh0ZW5kcyBrZXlvZiBTPihcbiAgZmlsdGVyczogUmVhZG9ubHk8SW5mZXJGaWx0ZXJzPFM+PixcbiAgZmllbGQ6IEYsXG4gIG9wZXJhdG9yPzoga2V5b2YgTm9uTnVsbGFibGU8SW5mZXJGaWx0ZXJzPFM+W0ZdPixcbik6IEluZmVyRmlsdGVyczxTPiB7XG4gIGNvbnN0IGN1cnJlbnRGaWVsZCA9IGZpbHRlcnNbZmllbGRdO1xuICBpZiAoY3VycmVudEZpZWxkID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gZmlsdGVycyBhcyBJbmZlckZpbHRlcnM8Uz47XG4gIH1cbiAgaWYgKG9wZXJhdG9yID09PSB1bmRlZmluZWQpIHtcbiAgICBjb25zdCB7IFtmaWVsZF06IF9yZW1vdmVkLCAuLi5jbG9uZSB9ID0gZmlsdGVycyBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICByZXR1cm4gY2xvbmUgYXMgSW5mZXJGaWx0ZXJzPFM+O1xuICB9XG4gIGNvbnN0IHsgW29wZXJhdG9yXTogX29wUmVtb3ZlZCwgLi4ucmVzdCB9ID0gY3VycmVudEZpZWxkIGFzIFJlY29yZDxcbiAgICBzdHJpbmcsXG4gICAgdW5rbm93blxuICA+O1xuICBpZiAoT2JqZWN0LmtleXMocmVzdCkubGVuZ3RoID09PSAwKSB7XG4gICAgY29uc3QgeyBbZmllbGRdOiBfZiwgLi4uY2xvbmUgfSA9IGZpbHRlcnMgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgcmV0dXJuIGNsb25lIGFzIEluZmVyRmlsdGVyczxTPjtcbiAgfVxuICByZXR1cm4geyAuLi5maWx0ZXJzLCBbZmllbGRdOiByZXN0IH0gYXMgSW5mZXJGaWx0ZXJzPFM+O1xufVxuXG4vKipcbiAqIE1lcmdlIHR3byBmaWx0ZXJzIG9iamVjdHMgcHJlc2VydmluZyByZWZlcmVuY2UgaWRlbnRpdHkgZm9yIHVuY2hhbmdlZCBmaWVsZHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtZXJnZUZpbHRlcnM8UyBleHRlbmRzIFNjaGVtYT4oXG4gIGJhc2U6IFJlYWRvbmx5PEluZmVyRmlsdGVyczxTPj4sXG4gIHBhdGNoOiBSZWFkb25seTxJbmZlckZpbHRlcnM8Uz4+LFxuKTogSW5mZXJGaWx0ZXJzPFM+IHtcbiAgbGV0IGNoYW5nZWQgPSBmYWxzZTtcbiAgY29uc3QgcmVzdWx0OiBQYXJ0aWFsPEluZmVyRmlsdGVyczxTPj4gPSB7IC4uLmJhc2UgfTtcbiAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMocGF0Y2gpIGFzIChrZXlvZiBTKVtdKSB7XG4gICAgY29uc3QgZXhpc3RpbmcgPSBiYXNlW2tleV07XG4gICAgY29uc3QgaW5jb21pbmcgPSBwYXRjaFtrZXldO1xuICAgIGlmIChpbmNvbWluZyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAvLyBza2lwIHVuZGVmaW5lZCBpbmNvbWluZ1xuICAgIH0gZWxzZSBpZiAoZXhpc3RpbmcgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmVzdWx0W2tleV0gPSBpbmNvbWluZyBhcyBJbmZlckZpbHRlcnM8Uz5bdHlwZW9mIGtleV07XG4gICAgICBjaGFuZ2VkID0gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKCFzaGFsbG93RXF1YWwoZXhpc3RpbmcsIGluY29taW5nKSkge1xuICAgICAgcmVzdWx0W2tleV0gPSBpbmNvbWluZyBhcyBJbmZlckZpbHRlcnM8Uz5bdHlwZW9mIGtleV07XG4gICAgICBjaGFuZ2VkID0gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgaWYgKGNoYW5nZWQpIHtcbiAgICByZXR1cm4gcmVzdWx0IGFzIEluZmVyRmlsdGVyczxTPjtcbiAgfVxuICByZXR1cm4gYmFzZSBhcyBJbmZlckZpbHRlcnM8Uz47XG59XG5cbi8qKiBEZXRlcm1pbmUgaWYgdGhlIGZpbHRlcnMgb2JqZWN0IGlzIGVtcHR5IChubyBmaWVsZHMpLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRW1wdHk8UyBleHRlbmRzIFNjaGVtYT4oXG4gIGZpbHRlcnM6IFJlYWRvbmx5PEluZmVyRmlsdGVyczxTPj4sXG4pOiBib29sZWFuIHtcbiAgcmV0dXJuIE9iamVjdC5rZXlzKGZpbHRlcnMpLmxlbmd0aCA9PT0gMDtcbn1cbiJdfQ==
@@ -0,0 +1,3 @@
1
+ import type { Schema, ParseResult } from './types.js';
2
+ export declare function parse<S extends Schema>(rawSearch: string, schema: S): ParseResult<S>;
3
+ //# sourceMappingURL=parse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/parse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EAMN,WAAW,EACZ,MAAM,YAAY,CAAC;AAmKpB,wBAAgB,KAAK,CAAC,CAAC,SAAS,MAAM,EACpC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,CAAC,GACR,WAAW,CAAC,CAAC,CAAC,CA8ChB"}