@osqd/jql 0.1.1

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 (115) hide show
  1. package/CHANGELOG.md +220 -0
  2. package/LICENSE +102 -0
  3. package/README.md +84 -0
  4. package/bin/jql.mjs +5 -0
  5. package/conformance/cases.json +290 -0
  6. package/dist/array.d.ts +11 -0
  7. package/dist/async.d.ts +44 -0
  8. package/dist/canonical.d.ts +18 -0
  9. package/dist/cjs/array.d.ts +11 -0
  10. package/dist/cjs/async.d.ts +44 -0
  11. package/dist/cjs/canonical.d.ts +18 -0
  12. package/dist/cjs/cli.d.ts +15 -0
  13. package/dist/cjs/collections.d.ts +34 -0
  14. package/dist/cjs/core.d.ts +117 -0
  15. package/dist/cjs/errors.d.ts +17 -0
  16. package/dist/cjs/explain.d.ts +30 -0
  17. package/dist/cjs/global.d.ts +90 -0
  18. package/dist/cjs/group.d.ts +47 -0
  19. package/dist/cjs/index.d.ts +25 -0
  20. package/dist/cjs/internal/closest.d.ts +9 -0
  21. package/dist/cjs/internal/duration.d.ts +15 -0
  22. package/dist/cjs/internal/equal.d.ts +34 -0
  23. package/dist/cjs/internal/glob.d.ts +30 -0
  24. package/dist/cjs/internal/order.d.ts +24 -0
  25. package/dist/cjs/internal/path.d.ts +109 -0
  26. package/dist/cjs/internal/record.d.ts +18 -0
  27. package/dist/cjs/internal/values.d.ts +41 -0
  28. package/dist/cjs/limits.d.ts +64 -0
  29. package/dist/cjs/operators.d.ts +81 -0
  30. package/dist/cjs/package.json +3 -0
  31. package/dist/cjs/plan.d.ts +79 -0
  32. package/dist/cjs/search.d.ts +42 -0
  33. package/dist/cjs/targets/mongo.d.ts +55 -0
  34. package/dist/cjs/text/index.d.ts +12 -0
  35. package/dist/cjs/text/parse.d.ts +91 -0
  36. package/dist/cjs/text/suggest.d.ts +16 -0
  37. package/dist/cjs/text/write.d.ts +34 -0
  38. package/dist/cjs/types.d.ts +236 -0
  39. package/dist/cjs/vocabulary.d.ts +106 -0
  40. package/dist/cli.d.ts +15 -0
  41. package/dist/cli.js +2729 -0
  42. package/dist/cli.js.map +1 -0
  43. package/dist/collections.d.ts +34 -0
  44. package/dist/core.d.ts +117 -0
  45. package/dist/errors.d.ts +17 -0
  46. package/dist/explain.d.ts +30 -0
  47. package/dist/global.cjs +1953 -0
  48. package/dist/global.cjs.map +1 -0
  49. package/dist/global.d.ts +90 -0
  50. package/dist/global.js +1950 -0
  51. package/dist/global.js.map +1 -0
  52. package/dist/group.d.ts +47 -0
  53. package/dist/index.cjs +2529 -0
  54. package/dist/index.cjs.map +1 -0
  55. package/dist/index.d.ts +25 -0
  56. package/dist/index.js +2495 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/internal/closest.d.ts +9 -0
  59. package/dist/internal/duration.d.ts +15 -0
  60. package/dist/internal/equal.d.ts +34 -0
  61. package/dist/internal/glob.d.ts +30 -0
  62. package/dist/internal/order.d.ts +24 -0
  63. package/dist/internal/path.d.ts +109 -0
  64. package/dist/internal/record.d.ts +18 -0
  65. package/dist/internal/values.d.ts +41 -0
  66. package/dist/limits.d.ts +64 -0
  67. package/dist/mongo.cjs +357 -0
  68. package/dist/mongo.cjs.map +1 -0
  69. package/dist/mongo.js +354 -0
  70. package/dist/mongo.js.map +1 -0
  71. package/dist/operators.d.ts +81 -0
  72. package/dist/plan.d.ts +79 -0
  73. package/dist/search.d.ts +42 -0
  74. package/dist/targets/mongo.d.ts +55 -0
  75. package/dist/text/index.d.ts +12 -0
  76. package/dist/text/parse.d.ts +91 -0
  77. package/dist/text/suggest.d.ts +16 -0
  78. package/dist/text/write.d.ts +34 -0
  79. package/dist/text.cjs +674 -0
  80. package/dist/text.cjs.map +1 -0
  81. package/dist/text.js +667 -0
  82. package/dist/text.js.map +1 -0
  83. package/dist/types.d.ts +236 -0
  84. package/dist/vocabulary.d.ts +106 -0
  85. package/docs/course/01-first-query.md +217 -0
  86. package/docs/course/02-operators.md +285 -0
  87. package/docs/course/03-arrays-and-paths.md +239 -0
  88. package/docs/course/04-combining.md +221 -0
  89. package/docs/course/05-dates.md +214 -0
  90. package/docs/course/06-typed-queries.md +240 -0
  91. package/docs/course/07-requests.md +261 -0
  92. package/docs/course/08-grouping.md +210 -0
  93. package/docs/course/09-explaining.md +171 -0
  94. package/docs/course/10-vocabulary.md +276 -0
  95. package/docs/course/11-the-search-box.md +349 -0
  96. package/docs/course/12-untrusted.md +257 -0
  97. package/docs/course/13-saved-filters.md +199 -0
  98. package/docs/course/14-streams-and-cli.md +276 -0
  99. package/docs/course/15-pushdown.md +240 -0
  100. package/docs/course/16-extending.md +199 -0
  101. package/docs/course/index.md +185 -0
  102. package/docs/design/decisions.md +198 -0
  103. package/docs/design/performance.md +102 -0
  104. package/docs/guides/adopting.md +81 -0
  105. package/docs/guides/pushdown.md +147 -0
  106. package/docs/guides/typescript.md +115 -0
  107. package/docs/guides/untrusted-input.md +86 -0
  108. package/docs/index.md +102 -0
  109. package/docs/reference/api.md +266 -0
  110. package/docs/reference/cli.md +103 -0
  111. package/docs/reference/index.md +12 -0
  112. package/docs/reference/specification.md +549 -0
  113. package/docs/reference/text-syntax.md +152 -0
  114. package/docs/start/quick-start.md +84 -0
  115. package/package.json +136 -0
@@ -0,0 +1,9 @@
1
+ /**
2
+ * "Did you mean" for names that almost exist.
3
+ *
4
+ * An unknown operator is refused either way; naming the one that was probably meant turns
5
+ * a lookup in the documentation into a one-character fix.
6
+ */
7
+ export declare function closest(word: string, candidates: Iterable<string>): string | undefined;
8
+ /** The suffix of an error sentence that offers the likely name, or nothing. */
9
+ export declare function didYouMean(word: string, candidates: Iterable<string>): string;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Durations, for the relative dates a saved filter is written with.
3
+ *
4
+ * `"1h"`, `"30m"`, `"1h30m"`, `"7d"`. Written as one or more counts with a unit, largest
5
+ * first by convention but in any order, because a filter is typed by a person and
6
+ * `"30m1h"` means what it says.
7
+ *
8
+ * Months and years are deliberately absent: neither has a fixed length, so `"1mo"` would
9
+ * mean something slightly different in February, and a filter whose window changes size
10
+ * with the calendar is one nobody can reason about. Use days or weeks.
11
+ */
12
+ /** The unit names, for an error that says what is accepted. */
13
+ export declare const DURATION_UNITS: string[];
14
+ /** A duration in milliseconds, or `undefined` when the text is not one. */
15
+ export declare function parseDuration(text: string): number | undefined;
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Equality between a document value and a query literal.
3
+ *
4
+ * Built once per literal rather than called generically, because the literal is known at
5
+ * compile time and the document value is the only thing that changes: a primitive
6
+ * literal becomes one `===`, and only an object or array literal pays for a walk.
7
+ *
8
+ * The rules, which the specification states and every implementation must share:
9
+ * objects are equal when they have the same keys with equal values, **in any order**
10
+ * (JSON does not promise key order, so a comparison that depended on it would depend on
11
+ * whoever serialised the query); a key whose value is `undefined` counts as absent;
12
+ * arrays are equal element by element, in order; a `$date` literal equals any value that
13
+ * reads as the same instant.
14
+ */
15
+ export type Equals = (value: unknown) => boolean;
16
+ /**
17
+ * The same whole number as a big integer, when a literal is one and could be written either
18
+ * way.
19
+ *
20
+ * Settled once, when the query compiles, so the comparison stays a single `===` against a
21
+ * value prepared in advance. Only a whole number gets one: nothing is a big integer and a
22
+ * fraction, and a string or a boolean can never be one either.
23
+ */
24
+ export declare function alsoBig(literal: unknown): bigint | undefined;
25
+ export declare function equalsLiteral(literal: unknown, now: number, ignoreCase?: boolean): Equals;
26
+ /**
27
+ * Equality between two values that both came out of a document, for `$field` references.
28
+ *
29
+ * The same rules as equality with a literal — same type, arrays in order, objects in any
30
+ * key order — but neither side is known when the query compiles, so nothing can be
31
+ * prepared. Missing is not equal to anything, including itself: a reference that reaches
32
+ * nothing matches nothing.
33
+ */
34
+ export declare function valuesEqual(a: unknown, b: unknown): boolean;
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Glob matching: `*`, `?`, and `\` to escape either of them.
3
+ *
4
+ * What people mean when they reach for a pattern in a search box — `/api/*`,
5
+ * `*.example.com` — and the reason it is not `$regex` with the sharp edges filed off: this
6
+ * runs without a regular-expression engine, so it is available when patterns are turned
7
+ * off for untrusted callers, and it cannot backtrack exponentially.
8
+ *
9
+ * No character classes. `[a-z]` is a literal `[a-z]`, because half a class syntax is worse
10
+ * than none: somebody would write `[!abc]` expecting negation and get a match against those
11
+ * four characters instead, with nothing to say so.
12
+ *
13
+ * **A pattern is taken apart once and becomes the narrowest matcher that fits it.** Nearly
14
+ * every real glob is a prefix, a suffix, something in the middle, or a run of literals
15
+ * separated by stars, and each of those is one or two native string calls per value. Only a
16
+ * pattern with `?` in it walks character by character, and only that walk pays for splitting
17
+ * the text into characters — which, measured against `startsWith`, was four times the cost of
18
+ * the whole comparison.
19
+ */
20
+ export type GlobMatcher = (text: string) => boolean;
21
+ export declare function compileGlob(pattern: string): GlobMatcher;
22
+ /**
23
+ * The same glob as the body of a regular expression, for a target that speaks patterns
24
+ * rather than running the matcher — a store this query is being pushed down to.
25
+ *
26
+ * It shares the tokenizer with the matcher on purpose: an escape read one way here and
27
+ * another way there would mean a query that found different things depending on which half
28
+ * of the system answered it.
29
+ */
30
+ export declare function compileGlobPattern(pattern: string, quoteLiteral: (text: string) => string): string;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * One total order over every value a document can hold.
3
+ *
4
+ * A sort has to put *something* first when one item's field is a number and another's is
5
+ * a string, or missing. The order is fixed and written down in the specification, so two
6
+ * implementations sort a shared result the same way:
7
+ *
8
+ * missing and null < numbers < strings < objects < booleans < dates
9
+ *
10
+ * Strings compare by UTF-16 code unit, not by locale. A locale-aware sort would put a
11
+ * shared link's rows in a different order for each reader, which is worse than an order
12
+ * that is merely unidiomatic for some of them. Objects compare equal to one another, so
13
+ * their order is the order they arrived in.
14
+ */
15
+ export declare function compareValues(a: unknown, b: unknown): number;
16
+ /**
17
+ * The value an item sorts by, from everything its path reached.
18
+ *
19
+ * A path that reaches an array — or fans out over one — reaches several values. Ascending
20
+ * sorts by the smallest of them and descending by the largest: an order
21
+ * by "tags" puts first whatever has the tag that sorts first. Arrays nested past sixteen
22
+ * levels are passed over, so an array that contains itself ends the walk.
23
+ */
24
+ export declare function sortValue(values: readonly unknown[], descending: boolean, depth?: number): unknown;
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Reaching a field inside a document.
3
+ *
4
+ * A path is dot-separated: `address.city`, `items.id`, `items.0.id`. Three rules:
5
+ *
6
+ * - **An array is seen through.** `items.id` reaches the `id` of every element, and a
7
+ * condition on it holds when it holds for any of them.
8
+ * - **A numeric segment on an array is a position.** `items.0.id` is the first element's.
9
+ * - **A `Map` is read by key**, so a document that keeps a lookup table in a `Map` can be
10
+ * queried the same way as one that keeps it in an object.
11
+ *
12
+ * Only own properties are read. `{ constructor: { $exists: true } }` would otherwise match
13
+ * every object ever made, and `__proto__` would reach somewhere a query has no business
14
+ * being. The check costs a `hasOwn` call, so it is paid only for the handful of names
15
+ * `Object.prototype` and `Map.prototype` actually have — every other name is read
16
+ * directly. `Map.prototype` is on the list because a `Map` document read directly would
17
+ * answer `size` or `get` with its own method rather than with the entry of that name.
18
+ */
19
+ /**
20
+ * Calls `test` with each value the path reaches, stopping at the first `true`.
21
+ *
22
+ * A path that reaches nothing calls `test(undefined)` once, so "missing" is a value a
23
+ * condition can ask about: that is how `{ field: null }` and `$exists: false` see it.
24
+ */
25
+ export type Reach = (document: unknown, test: (value: unknown) => boolean) => boolean;
26
+ /** A single-valued read, for paths that cannot fan out. Absent when the path can. */
27
+ export type Read = (document: unknown) => unknown;
28
+ /** What a probe returns when the path met an array before its last segment, and so may reach several values. */
29
+ export declare const FANOUT: unique symbol;
30
+ /**
31
+ * A straight read of a multi-segment path: the one value it reaches, or `FANOUT` if an
32
+ * array stood in the way and only `Reach` can answer.
33
+ *
34
+ * The point is the common case. `address.city` on a record with no arrays on the way has
35
+ * exactly one value, and reading it directly lets the engine test it the way a hand-written
36
+ * `p.address.city === "x"` would — one read, one comparison — instead of through a walk and
37
+ * a callback. A missing or primitive step reads as `undefined`, the same as `Reach` sees it.
38
+ */
39
+ export type Probe = (document: unknown) => unknown;
40
+ /** Whether a name could be found on a plain object's prototype, and so must always be asked for carefully. */
41
+ export declare function needsGuard(key: string): boolean;
42
+ /**
43
+ * What a plain object's prototype is, for the cheapest plainness test there is.
44
+ *
45
+ * `document.__proto__ === PLAIN` is a map check — about as fast as reading a field — where
46
+ * `Object.getPrototypeOf` is a call and `Object.hasOwn` is a second lookup. Reading it is
47
+ * safe in both directions: a document carrying its own `__proto__` field (which is what
48
+ * `JSON.parse` makes of one) simply fails the test and takes the careful path, and so does
49
+ * anything with a prototype of its own.
50
+ */
51
+ export declare const PLAIN: Object;
52
+ /**
53
+ * One field of one value: own properties and `Map` entries, nothing else.
54
+ *
55
+ * Ownership is checked **before** the read, not after, and for every name rather than for a
56
+ * list of known-inherited ones. The list was only ever `Object.prototype` and
57
+ * `Map.prototype`, so a document that was a class instance answered `{ role: "admin" }` from
58
+ * its prototype — and `{ secret: … }` by *running* an inherited getter, which is a query
59
+ * executing code the document's author wrote. Asking first is also why no accessor outside
60
+ * the item can run at all.
61
+ */
62
+ export declare function readOwn(value: object, key: string): unknown;
63
+ /**
64
+ * The value at a single-segment path.
65
+ *
66
+ * The overwhelmingly common case — `{ id: 2 }` — so it is written out: a direct property
67
+ * read, with the `Map` check paid only when the read found nothing, which a plain object
68
+ * with the field never does.
69
+ */
70
+ export declare function readKey(key: string): Read;
71
+ /** The whole document, for queries that are conditions on the value itself. */
72
+ export declare const readSelf: Read;
73
+ /**
74
+ * Builds the walk for a multi-segment path.
75
+ *
76
+ * A loop while the path meets only objects, which is nearly always, and the recursive
77
+ * fan-out only from the first array it meets. `address.city` on a record with no arrays in
78
+ * it costs two property reads and one call.
79
+ */
80
+ export declare function reachPath(keys: readonly string[]): Reach;
81
+ /** Builds the straight read for a multi-segment path. */
82
+ export declare function probePath(keys: readonly string[]): Probe;
83
+ /** The same, from a value some other accessor produced. */
84
+ export declare function probeFrom(read: Read, keys: readonly string[]): Probe;
85
+ /** Continues a walk from a value some other accessor produced. */
86
+ export declare function reachFrom(read: Read, keys: readonly string[]): Reach;
87
+ /**
88
+ * How many segments a path may have.
89
+ *
90
+ * The same number as the document depth above, and for the same reason: a path longer than
91
+ * the deepest document a walk will follow can reach nothing anyway, so refusing it costs a
92
+ * query nothing real. What it buys is two things. A field name is the one part of a query
93
+ * whose size the node count does not bound — `{"a.a.a…": 1}` is a single node however long
94
+ * it is — and each segment becomes an object and a step in a walk, so a field name pasted
95
+ * from somewhere could turn a small query into a large one.
96
+ *
97
+ * And it makes the same path mean the same thing everywhere. Projection walked its own tree
98
+ * of segments and stopped at sixty-four, silently, so a query matched on a path that
99
+ * `fields` then dropped from the result: the filter and the projection disagreed about a
100
+ * path they were both given.
101
+ */
102
+ export declare const MAX_PATH_SEGMENTS = 512;
103
+ /**
104
+ * Splits a field name into segments, refusing the ones that can reach nothing.
105
+ *
106
+ * Returns the reason as a sentence for the caller to raise, so this module stays free of
107
+ * the error type and its location bookkeeping.
108
+ */
109
+ export declare function splitPath(path: string): string[] | string;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Writing a field onto a result object.
3
+ *
4
+ * `target[key] = value` looks harmless until the key is `__proto__`. Assignment goes
5
+ * through the setter inherited from `Object.prototype`, which *replaces the object's
6
+ * prototype* instead of adding a property — so the field the caller asked for is missing
7
+ * and the object answers to names nobody put on it.
8
+ *
9
+ * It is reachable from data rather than from code: `JSON.parse('{"__proto__": …}')` makes
10
+ * an own `__proto__` property, so any document read from a file, a request body or a store
11
+ * can carry one. Projecting such a document used to lose that field and hand back a result
12
+ * whose prototype was whatever the document said, which the projection's own test could not
13
+ * see because the property it was looking for was genuinely there — on the prototype.
14
+ *
15
+ * Defining the property puts it where it was meant to go. Every other key takes the plain
16
+ * assignment, so the guard costs one comparison on the path that builds results.
17
+ */
18
+ export declare function setField(target: Record<string, unknown>, key: string, value: unknown): void;
@@ -0,0 +1,41 @@
1
+ import type { DateLiteral, FieldReference, TypeName } from "../types.js";
2
+ /** An object literal or a JSON-parsed object: what a query document is made of. */
3
+ export declare function isPlainObject(value: unknown): value is Record<string, unknown>;
4
+ /** `{ $date: … }` and nothing else. */
5
+ export declare function isDateLiteral(value: unknown): value is DateLiteral;
6
+ /** `{ $field: "path" }` and nothing else: a comparison with another field of the same item. */
7
+ export declare function isFieldReference(value: unknown): value is FieldReference;
8
+ /**
9
+ * The instant a `$date` literal stands for, in epoch milliseconds, or `NaN`.
10
+ *
11
+ * `now` is passed in rather than read here, because a query holding `{ "$ago": "1h" }` has
12
+ * to resolve against one instant for the whole run: reading the clock per comparison would
13
+ * let the window move while a scan is in progress, so two items a second apart could be
14
+ * judged against different hours. It is also what makes a relative filter testable without
15
+ * waiting.
16
+ */
17
+ export declare function resolveDate(value: unknown, now: number): number;
18
+ /**
19
+ * An instant from a string, read the same way on every machine.
20
+ *
21
+ * JavaScript reads a date-only string as midnight **UTC** and a timestamp with no offset as
22
+ * **local time** — so `"2026-01-01T12:00:00"` was a different instant in Tokyo and in London,
23
+ * and a query and a document that both held one answered differently depending on where the
24
+ * process happened to be running. That is the failure the language already rules out for
25
+ * `"12/31/2020"`: the same query meaning two things. A missing offset is UTC here, which is
26
+ * the rule the date-only form already follows.
27
+ */
28
+ export declare function instant(text: string): number;
29
+ export declare function toTime(value: unknown): number;
30
+ /** The type names `$type` knows, in one list, so the error for a wrong one can offer the right one. */
31
+ export declare const TYPE_NAMES: readonly TypeName[];
32
+ /** Whether a document value is of the named type. A missing value is of no type. */
33
+ export declare function isOfType(value: unknown, type: TypeName): boolean;
34
+ /**
35
+ * A readable name for a value in an error sentence.
36
+ *
37
+ * Specific about what it was given, because "a query is an object, not an object" — which
38
+ * is what a `Map`, a `Set` and a class instance all used to produce — tells the reader
39
+ * nothing at all about the thing they passed.
40
+ */
41
+ export declare function describe(value: unknown): string;
@@ -0,0 +1,64 @@
1
+ /**
2
+ * How much of a query the engine will take.
3
+ *
4
+ * Queries arrive from places the caller does not control — a URL, a request body, a
5
+ * saved filter somebody else wrote — and every limit here is a way such a query could
6
+ * otherwise cost more than the data it filters. Each one refuses with a `JqlError` rather
7
+ * than truncating, because a query that was quietly cut short answers a different
8
+ * question from the one that was asked.
9
+ *
10
+ * The defaults are far past anything a person writes and far short of anything that
11
+ * hurts. The caps are exported so a caller can say what it accepts in its own
12
+ * documentation and refuse a query before it is even parsed.
13
+ */
14
+ export interface Limits {
15
+ /** How deep operators may nest. Default 32: recursion over pasted input must stop well short of the stack. */
16
+ readonly maxDepth: number;
17
+ /** How many operators and fields a query may hold in total. Default 10 000. `$in` lists do not count: they cost one set lookup each. */
18
+ readonly maxNodes: number;
19
+ /** The longest `$regex` pattern. Default 1024. */
20
+ readonly maxPatternLength: number;
21
+ /**
22
+ * The longest `$glob`. Default 1024, and 256 for untrusted input.
23
+ *
24
+ * A glob cannot backtrack exponentially, but matching one holding `?` is the length of the
25
+ * pattern times the length of the value — so a megabyte of `?` against a megabyte of text
26
+ * is hours per document. It has a cap of its own because `$regex` is turned *off* for
27
+ * untrusted callers while `$glob` stays on, which is exactly when the cap has to hold.
28
+ */
29
+ readonly maxGlobLength: number;
30
+ /** How deep `$text` looks into a document. Default 16: past that a document is a graph, not a record. */
31
+ readonly maxTextDepth: number;
32
+ /**
33
+ * Which operators a query may use. Default `"all"`.
34
+ *
35
+ * An allowlist, because a public endpoint's answer to "what may a caller ask?" should be
36
+ * a list it wrote rather than everything the language grows later. `$text` walks a whole
37
+ * document and `$elemMatch` carries a query of its own; an endpoint that needs neither can
38
+ * say so once, here, instead of discovering later which of them somebody found.
39
+ *
40
+ * Names are checked when the query compiles: an operator outside the list is refused by
41
+ * name, never ignored. `$options` and `$comment` are exempt — they modify and annotate
42
+ * rather than ask anything — and `$field` counts as an operator, because comparing two
43
+ * fields is a capability in its own right.
44
+ */
45
+ readonly allowOperators: readonly string[] | "all";
46
+ /**
47
+ * Whether `$regex` is accepted at all. Default `true`.
48
+ *
49
+ * Turn it off for queries from untrusted callers. No engine can tell a pattern that
50
+ * backtracks for a minute from one that does not without running it, and the string
51
+ * operators (`$contains`, `$startsWith`, `$endsWith`, `$word`) answer almost every
52
+ * question a pattern would, in linear time.
53
+ */
54
+ readonly allowRegex: boolean;
55
+ }
56
+ /** The defaults, frozen, so they can be spread and never edited in place. */
57
+ export declare const DEFAULT_LIMITS: Readonly<Limits>;
58
+ /**
59
+ * What an untrusted query gets: no patterns, and a tighter size.
60
+ *
61
+ * Public so a service taking queries from a URL can use the same answer as every other
62
+ * service in the project, rather than each one picking its own numbers.
63
+ */
64
+ export declare const UNTRUSTED_LIMITS: Readonly<Limits>;