turbine-orm 0.50.0 → 0.51.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/README.md +66 -66
- package/dist/adapters/cockroachdb.d.ts +5 -5
- package/dist/adapters/cockroachdb.js +10 -10
- package/dist/adapters/index.d.ts +5 -5
- package/dist/adapters/index.js +7 -7
- package/dist/adapters/yugabytedb.d.ts +7 -7
- package/dist/adapters/yugabytedb.js +10 -10
- package/dist/cjs/adapters/cockroachdb.d.ts +5 -5
- package/dist/cjs/adapters/cockroachdb.js +10 -10
- package/dist/cjs/adapters/index.d.ts +5 -5
- package/dist/cjs/adapters/index.js +7 -7
- package/dist/cjs/adapters/yugabytedb.d.ts +7 -7
- package/dist/cjs/adapters/yugabytedb.js +10 -10
- package/dist/cjs/cli/config.d.ts +13 -2
- package/dist/cjs/cli/config.js +3 -2
- package/dist/cjs/cli/destructive.d.ts +1 -1
- package/dist/cjs/cli/destructive.js +1 -1
- package/dist/cjs/cli/index.d.ts +10 -10
- package/dist/cjs/cli/index.js +49 -45
- package/dist/cjs/cli/loader.d.ts +7 -7
- package/dist/cjs/cli/loader.js +9 -9
- package/dist/cjs/cli/mcp.js +4 -4
- package/dist/cjs/cli/migrate.d.ts +5 -5
- package/dist/cjs/cli/migrate.js +11 -11
- package/dist/cjs/cli/studio-ui.generated.js +1 -1
- package/dist/cjs/cli/ui.d.ts +2 -2
- package/dist/cjs/cli/ui.js +2 -2
- package/dist/cjs/client.d.ts +49 -38
- package/dist/cjs/client.js +57 -56
- package/dist/cjs/dialect.d.ts +62 -18
- package/dist/cjs/dialect.js +40 -2
- package/dist/cjs/errors.d.ts +5 -5
- package/dist/cjs/errors.js +11 -11
- package/dist/cjs/generate.d.ts +6 -6
- package/dist/cjs/generate.js +31 -29
- package/dist/cjs/index-advisor.d.ts +5 -5
- package/dist/cjs/index-advisor.js +0 -0
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/index.js +7 -7
- package/dist/cjs/introspect.d.ts +35 -9
- package/dist/cjs/introspect.js +83 -32
- package/dist/cjs/mssql.d.ts +11 -11
- package/dist/cjs/mssql.js +64 -29
- package/dist/cjs/mysql.d.ts +8 -8
- package/dist/cjs/mysql.js +61 -23
- package/dist/cjs/nested-write.d.ts +21 -2
- package/dist/cjs/nested-write.js +51 -14
- package/dist/cjs/optional-peer-import.cjs +7 -7
- package/dist/cjs/optional-peer-import.d.cts +7 -7
- package/dist/cjs/pipeline-submittable.d.ts +2 -2
- package/dist/cjs/pipeline-submittable.js +6 -6
- package/dist/cjs/pipeline.d.ts +1 -1
- package/dist/cjs/pipeline.js +4 -4
- package/dist/cjs/powdb-introspect.d.ts +1 -1
- package/dist/cjs/powdb-introspect.js +1 -1
- package/dist/cjs/powdb.d.ts +28 -28
- package/dist/cjs/powdb.js +66 -66
- package/dist/cjs/powql.d.ts +27 -27
- package/dist/cjs/powql.js +73 -52
- package/dist/cjs/query/aggregates.d.ts +1 -1
- package/dist/cjs/query/aggregates.js +5 -5
- package/dist/cjs/query/batched-loader.d.ts +11 -11
- package/dist/cjs/query/batched-loader.js +24 -24
- package/dist/cjs/query/builder.d.ts +39 -21
- package/dist/cjs/query/builder.js +99 -57
- package/dist/cjs/query/compound-unique.d.ts +1 -1
- package/dist/cjs/query/compound-unique.js +0 -0
- package/dist/cjs/query/deferred.d.ts +12 -6
- package/dist/cjs/query/deferred.js +1 -1
- package/dist/cjs/query/filters.d.ts +31 -11
- package/dist/cjs/query/filters.js +67 -14
- package/dist/cjs/query/index.d.ts +1 -1
- package/dist/cjs/query/index.js +1 -1
- package/dist/cjs/query/relations.d.ts +9 -9
- package/dist/cjs/query/relations.js +164 -57
- package/dist/cjs/query/types.d.ts +86 -35
- package/dist/cjs/query/types.js +1 -1
- package/dist/cjs/query/utils.d.ts +27 -10
- package/dist/cjs/query/utils.js +86 -14
- package/dist/cjs/query/where.d.ts +47 -28
- package/dist/cjs/query/where.js +130 -31
- package/dist/cjs/query/writes.d.ts +24 -5
- package/dist/cjs/query/writes.js +102 -13
- package/dist/cjs/realtime.d.ts +7 -7
- package/dist/cjs/realtime.js +9 -9
- package/dist/cjs/schema-builder.d.ts +18 -7
- package/dist/cjs/schema-builder.js +17 -10
- package/dist/cjs/schema-metadata.d.ts +3 -3
- package/dist/cjs/schema-metadata.js +9 -9
- package/dist/cjs/schema-sql.d.ts +9 -9
- package/dist/cjs/schema-sql.js +20 -20
- package/dist/cjs/schema.d.ts +19 -9
- package/dist/cjs/schema.js +6 -6
- package/dist/cjs/serverless.d.ts +15 -15
- package/dist/cjs/serverless.js +16 -16
- package/dist/cjs/sqlite.d.ts +8 -8
- package/dist/cjs/sqlite.js +53 -22
- package/dist/cjs/typed-sql.d.ts +4 -4
- package/dist/cjs/typed-sql.js +5 -5
- package/dist/cli/config.d.ts +13 -2
- package/dist/cli/config.js +3 -2
- package/dist/cli/destructive.d.ts +1 -1
- package/dist/cli/destructive.js +1 -1
- package/dist/cli/index.d.ts +10 -10
- package/dist/cli/index.js +49 -45
- package/dist/cli/loader.d.ts +7 -7
- package/dist/cli/loader.js +9 -9
- package/dist/cli/mcp.js +4 -4
- package/dist/cli/migrate.d.ts +5 -5
- package/dist/cli/migrate.js +11 -11
- package/dist/cli/studio-ui.generated.js +1 -1
- package/dist/cli/ui.d.ts +2 -2
- package/dist/cli/ui.js +2 -2
- package/dist/client.d.ts +49 -38
- package/dist/client.js +57 -56
- package/dist/dialect.d.ts +62 -18
- package/dist/dialect.js +40 -2
- package/dist/errors.d.ts +5 -5
- package/dist/errors.js +11 -11
- package/dist/generate.d.ts +6 -6
- package/dist/generate.js +31 -29
- package/dist/index-advisor.d.ts +5 -5
- package/dist/index-advisor.js +0 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +7 -7
- package/dist/introspect.d.ts +35 -9
- package/dist/introspect.js +82 -32
- package/dist/mssql.d.ts +11 -11
- package/dist/mssql.js +64 -29
- package/dist/mysql.d.ts +8 -8
- package/dist/mysql.js +61 -23
- package/dist/nested-write.d.ts +21 -2
- package/dist/nested-write.js +51 -14
- package/dist/optional-peer-import.cjs +7 -7
- package/dist/optional-peer-import.d.cts +7 -7
- package/dist/pipeline-submittable.d.ts +2 -2
- package/dist/pipeline-submittable.js +6 -6
- package/dist/pipeline.d.ts +1 -1
- package/dist/pipeline.js +4 -4
- package/dist/powdb-introspect.d.ts +1 -1
- package/dist/powdb-introspect.js +1 -1
- package/dist/powdb.d.ts +28 -28
- package/dist/powdb.js +66 -66
- package/dist/powql.d.ts +27 -27
- package/dist/powql.js +73 -52
- package/dist/query/aggregates.d.ts +1 -1
- package/dist/query/aggregates.js +5 -5
- package/dist/query/batched-loader.d.ts +11 -11
- package/dist/query/batched-loader.js +24 -24
- package/dist/query/builder.d.ts +39 -21
- package/dist/query/builder.js +100 -58
- package/dist/query/compound-unique.d.ts +1 -1
- package/dist/query/compound-unique.js +0 -0
- package/dist/query/deferred.d.ts +12 -6
- package/dist/query/deferred.js +1 -1
- package/dist/query/filters.d.ts +31 -11
- package/dist/query/filters.js +66 -13
- package/dist/query/index.d.ts +1 -1
- package/dist/query/index.js +1 -1
- package/dist/query/relations.d.ts +9 -9
- package/dist/query/relations.js +165 -58
- package/dist/query/types.d.ts +86 -35
- package/dist/query/types.js +1 -1
- package/dist/query/utils.d.ts +27 -10
- package/dist/query/utils.js +84 -14
- package/dist/query/where.d.ts +47 -28
- package/dist/query/where.js +129 -32
- package/dist/query/writes.d.ts +24 -5
- package/dist/query/writes.js +101 -13
- package/dist/realtime.d.ts +7 -7
- package/dist/realtime.js +9 -9
- package/dist/schema-builder.d.ts +18 -7
- package/dist/schema-builder.js +17 -10
- package/dist/schema-metadata.d.ts +3 -3
- package/dist/schema-metadata.js +9 -9
- package/dist/schema-sql.d.ts +9 -9
- package/dist/schema-sql.js +20 -20
- package/dist/schema.d.ts +19 -9
- package/dist/schema.js +6 -6
- package/dist/serverless.d.ts +15 -15
- package/dist/serverless.js +16 -16
- package/dist/sqlite.d.ts +8 -8
- package/dist/sqlite.js +53 -22
- package/dist/typed-sql.d.ts +4 -4
- package/dist/typed-sql.js +5 -5
- package/package.json +2 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* turbine-orm
|
|
2
|
+
* turbine-orm, Where-filter type guards and shape helpers
|
|
3
3
|
*
|
|
4
4
|
* Pure detection / fingerprint utilities used by the query builder's WHERE
|
|
5
5
|
* compiler. Kept out of builder.ts so the class file stays about SQL assembly
|
|
@@ -10,7 +10,7 @@ import type { ArrayFilter, ColumnRef, JsonFilter, JsonPathOrderBy, OrderBySpec,
|
|
|
10
10
|
export declare function isWhereOperator(value: unknown): value is WhereOperator;
|
|
11
11
|
/**
|
|
12
12
|
* True for a *plain object literal* that reached an equality fallthrough
|
|
13
|
-
* without matching any known filter shape
|
|
13
|
+
* without matching any known filter shape, the misspelled-operator case.
|
|
14
14
|
* Class instances (Buffer for bytea, Decimal wrappers, ...) are legitimate
|
|
15
15
|
* bind values and return false, as do arrays and Dates.
|
|
16
16
|
*/
|
|
@@ -31,7 +31,7 @@ export declare function isColumnRef(value: unknown): value is ColumnRef;
|
|
|
31
31
|
/**
|
|
32
32
|
* Fingerprint the SHAPE of a where-operator object. Null-valued `equals` /
|
|
33
33
|
* `not` compile to parameterless `IS NULL` / `IS NOT NULL` (different SQL, no
|
|
34
|
-
* param pushed), so null-ness is part of the shape
|
|
34
|
+
* param pushed), so null-ness is part of the shape, without it a cache entry
|
|
35
35
|
* warmed by `{ not: 5 }` would serve `{ not: null }` with a desynced param list.
|
|
36
36
|
*
|
|
37
37
|
* Column references ({@link ColumnRef}) compile the referenced column into the
|
|
@@ -44,7 +44,7 @@ export declare function fingerprintOperatorShape(value: WhereOperator): string;
|
|
|
44
44
|
/**
|
|
45
45
|
* Guard for the value of an `equals` operator reaching the plain-equality
|
|
46
46
|
* operator path. A plain object literal can only legitimately be an equality
|
|
47
|
-
* value on a json/jsonb column
|
|
47
|
+
* value on a json/jsonb column, and those route to the JSONB filter branch
|
|
48
48
|
* BEFORE the operator branch, so any plain object that reaches here is a
|
|
49
49
|
* mistake (e.g. `{ equals: { foo: 1 } }` on a text column). Shared by the
|
|
50
50
|
* SQL-build path and the cache-hit param-collect path so a warmed cache can
|
|
@@ -56,16 +56,21 @@ export declare function assertBindableEqualsOperand(value: unknown, column: stri
|
|
|
56
56
|
* cache fingerprint. The SQL-build and cache-hit param-collect paths MUST
|
|
57
57
|
* enumerate object keys in this exact order: fingerprints sort keys, so two
|
|
58
58
|
* where clauses with the same fields in different insertion order share one
|
|
59
|
-
* cache entry
|
|
59
|
+
* cache entry, if build/collect iterated insertion order, the cached SQL's
|
|
60
60
|
* `$N` placeholders would bind the wrong values (cross-tenant-leak class).
|
|
61
61
|
* Array order (OR/AND members) is positional and is never sorted.
|
|
62
62
|
*/
|
|
63
63
|
export declare function sortedKeys(obj: Record<string, unknown>): string[];
|
|
64
64
|
/** {@link sortedKeys}, but yielding `[key, value]` pairs. */
|
|
65
65
|
export declare function sortedEntries<V>(obj: Record<string, V>): [string, V][];
|
|
66
|
-
/** Known atomic-update operator keys
|
|
66
|
+
/** Known atomic-update operator keys, used to detect operator objects vs plain JSON values */
|
|
67
67
|
export declare const UPDATE_OPERATOR_KEYS: Set<string>;
|
|
68
|
-
/**
|
|
68
|
+
/**
|
|
69
|
+
* Known JSONB operator keys. `stringContains` / `stringStartsWith` /
|
|
70
|
+
* `stringEndsWith` are appended below, once {@link JSON_STRING_OPERATORS} is
|
|
71
|
+
* declared: they have no `WhereOperator` counterpart, so their presence is an
|
|
72
|
+
* unambiguous JSON-filter signal.
|
|
73
|
+
*/
|
|
69
74
|
export declare const JSONB_OPERATOR_KEYS: Set<string>;
|
|
70
75
|
/**
|
|
71
76
|
* JSON range comparison operators → SQL comparison tokens, in the FIXED order
|
|
@@ -77,16 +82,31 @@ export declare const JSONB_OPERATOR_KEYS: Set<string>;
|
|
|
77
82
|
* and they always require `path`.
|
|
78
83
|
*/
|
|
79
84
|
export declare const JSON_RANGE_OPERATORS: Record<'gt' | 'gte' | 'lt' | 'lte', string>;
|
|
85
|
+
/**
|
|
86
|
+
* JSON substring operators → the LIKE pattern each one builds around its
|
|
87
|
+
* escaped operand, in the FIXED order the build and collect paths iterate
|
|
88
|
+
* them. These compare the TEXT at `path` (which every one of them requires),
|
|
89
|
+
* so they are the JSON counterpart of the scalar `contains` / `startsWith` /
|
|
90
|
+
* `endsWith` operators rather than of jsonb containment.
|
|
91
|
+
*
|
|
92
|
+
* They are deliberately NOT named `contains` / `startsWith` / `endsWith`:
|
|
93
|
+
* `contains` on a JSON column already means whole-document containment
|
|
94
|
+
* (`@>`), and silently changing that would break every existing caller.
|
|
95
|
+
*/
|
|
96
|
+
export declare const JSON_STRING_OPERATORS: Record<'stringContains' | 'stringStartsWith' | 'stringEndsWith', (escaped: string) => string>;
|
|
97
|
+
export declare const JSON_FILTER_KEYS: ReadonlySet<string>;
|
|
80
98
|
/**
|
|
81
99
|
* Value-invariant shape fingerprint for a {@link JsonFilter}. Range operators
|
|
82
100
|
* are annotated with the comparison value's kind (`#n` numeric / `#s` string)
|
|
83
|
-
* because a numeric comparison compiles to a `::numeric` cast
|
|
84
|
-
* SQL text than the text comparison
|
|
85
|
-
* SQL entry.
|
|
101
|
+
* because a numeric comparison compiles to a `::numeric` cast, a different
|
|
102
|
+
* SQL text than the text comparison, so the two must never share a cached
|
|
103
|
+
* SQL entry. `mode` is part of the shape for the same reason: it selects
|
|
104
|
+
* between `LIKE` and the dialect's case-insensitive form, which is different
|
|
105
|
+
* SQL text.
|
|
86
106
|
*/
|
|
87
107
|
export declare function fingerprintJsonFilterShape(filter: JsonFilter): string;
|
|
88
108
|
/**
|
|
89
|
-
* JSONB operator keys that are *unique* to {@link JsonFilter}
|
|
109
|
+
* JSONB operator keys that are *unique* to {@link JsonFilter}, they cannot
|
|
90
110
|
* appear in any other where-filter shape, so the presence of one of these is
|
|
91
111
|
* an unambiguous signal that the user meant a JSON filter. Used by the
|
|
92
112
|
* strict-validation path so that `{ contains: 'foo' }` (which is also a valid
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* turbine-orm
|
|
3
|
+
* turbine-orm, Where-filter type guards and shape helpers
|
|
4
4
|
*
|
|
5
5
|
* Pure detection / fingerprint utilities used by the query builder's WHERE
|
|
6
6
|
* compiler. Kept out of builder.ts so the class file stays about SQL assembly
|
|
7
7
|
* and execution rather than filter-shape bookkeeping.
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.VECTOR_DISTANCE_COMPARATORS = exports.VECTOR_METRIC_OPERATORS = exports.TEXT_SEARCH_KEYS = exports.ARRAY_UNIQUE_KEYS = exports.ARRAY_OPERATOR_KEYS = exports.JSONB_UNIQUE_KEYS = exports.JSON_RANGE_OPERATORS = exports.JSONB_OPERATOR_KEYS = exports.UPDATE_OPERATOR_KEYS = exports.COLUMN_REF_OPERATORS = void 0;
|
|
10
|
+
exports.VECTOR_DISTANCE_COMPARATORS = exports.VECTOR_METRIC_OPERATORS = exports.TEXT_SEARCH_KEYS = exports.ARRAY_UNIQUE_KEYS = exports.ARRAY_OPERATOR_KEYS = exports.JSONB_UNIQUE_KEYS = exports.JSON_FILTER_KEYS = exports.JSON_STRING_OPERATORS = exports.JSON_RANGE_OPERATORS = exports.JSONB_OPERATOR_KEYS = exports.UPDATE_OPERATOR_KEYS = exports.COLUMN_REF_OPERATORS = void 0;
|
|
11
11
|
exports.isWhereOperator = isWhereOperator;
|
|
12
12
|
exports.isUnmatchedPlainObject = isUnmatchedPlainObject;
|
|
13
13
|
exports.isColumnRef = isColumnRef;
|
|
@@ -49,7 +49,7 @@ function isWhereOperator(value) {
|
|
|
49
49
|
}
|
|
50
50
|
/**
|
|
51
51
|
* True for a *plain object literal* that reached an equality fallthrough
|
|
52
|
-
* without matching any known filter shape
|
|
52
|
+
* without matching any known filter shape, the misspelled-operator case.
|
|
53
53
|
* Class instances (Buffer for bytea, Decimal wrappers, ...) are legitimate
|
|
54
54
|
* bind values and return false, as do arrays and Dates.
|
|
55
55
|
*/
|
|
@@ -82,7 +82,7 @@ function isColumnRef(value) {
|
|
|
82
82
|
/**
|
|
83
83
|
* Fingerprint the SHAPE of a where-operator object. Null-valued `equals` /
|
|
84
84
|
* `not` compile to parameterless `IS NULL` / `IS NOT NULL` (different SQL, no
|
|
85
|
-
* param pushed), so null-ness is part of the shape
|
|
85
|
+
* param pushed), so null-ness is part of the shape, without it a cache entry
|
|
86
86
|
* warmed by `{ not: 5 }` would serve `{ not: null }` with a desynced param list.
|
|
87
87
|
*
|
|
88
88
|
* Column references ({@link ColumnRef}) compile the referenced column into the
|
|
@@ -110,7 +110,7 @@ function fingerprintOperatorShape(value) {
|
|
|
110
110
|
/**
|
|
111
111
|
* Guard for the value of an `equals` operator reaching the plain-equality
|
|
112
112
|
* operator path. A plain object literal can only legitimately be an equality
|
|
113
|
-
* value on a json/jsonb column
|
|
113
|
+
* value on a json/jsonb column, and those route to the JSONB filter branch
|
|
114
114
|
* BEFORE the operator branch, so any plain object that reaches here is a
|
|
115
115
|
* mistake (e.g. `{ equals: { foo: 1 } }` on a text column). Shared by the
|
|
116
116
|
* SQL-build path and the cache-hit param-collect path so a warmed cache can
|
|
@@ -128,7 +128,7 @@ function assertBindableEqualsOperand(value, column) {
|
|
|
128
128
|
* cache fingerprint. The SQL-build and cache-hit param-collect paths MUST
|
|
129
129
|
* enumerate object keys in this exact order: fingerprints sort keys, so two
|
|
130
130
|
* where clauses with the same fields in different insertion order share one
|
|
131
|
-
* cache entry
|
|
131
|
+
* cache entry, if build/collect iterated insertion order, the cached SQL's
|
|
132
132
|
* `$N` placeholders would bind the wrong values (cross-tenant-leak class).
|
|
133
133
|
* Array order (OR/AND members) is positional and is never sorted.
|
|
134
134
|
*/
|
|
@@ -142,9 +142,14 @@ function sortedEntries(obj) {
|
|
|
142
142
|
// ---------------------------------------------------------------------------
|
|
143
143
|
// Atomic-update / JSONB / Array / text-search / vector key sets
|
|
144
144
|
// ---------------------------------------------------------------------------
|
|
145
|
-
/** Known atomic-update operator keys
|
|
145
|
+
/** Known atomic-update operator keys, used to detect operator objects vs plain JSON values */
|
|
146
146
|
exports.UPDATE_OPERATOR_KEYS = new Set(['set', 'increment', 'decrement', 'multiply', 'divide']);
|
|
147
|
-
/**
|
|
147
|
+
/**
|
|
148
|
+
* Known JSONB operator keys. `stringContains` / `stringStartsWith` /
|
|
149
|
+
* `stringEndsWith` are appended below, once {@link JSON_STRING_OPERATORS} is
|
|
150
|
+
* declared: they have no `WhereOperator` counterpart, so their presence is an
|
|
151
|
+
* unambiguous JSON-filter signal.
|
|
152
|
+
*/
|
|
148
153
|
exports.JSONB_OPERATOR_KEYS = new Set(['path', 'equals', 'contains', 'hasKey']);
|
|
149
154
|
/**
|
|
150
155
|
* JSON range comparison operators → SQL comparison tokens, in the FIXED order
|
|
@@ -161,23 +166,71 @@ exports.JSON_RANGE_OPERATORS = {
|
|
|
161
166
|
lt: '<',
|
|
162
167
|
lte: '<=',
|
|
163
168
|
};
|
|
169
|
+
/**
|
|
170
|
+
* JSON substring operators → the LIKE pattern each one builds around its
|
|
171
|
+
* escaped operand, in the FIXED order the build and collect paths iterate
|
|
172
|
+
* them. These compare the TEXT at `path` (which every one of them requires),
|
|
173
|
+
* so they are the JSON counterpart of the scalar `contains` / `startsWith` /
|
|
174
|
+
* `endsWith` operators rather than of jsonb containment.
|
|
175
|
+
*
|
|
176
|
+
* They are deliberately NOT named `contains` / `startsWith` / `endsWith`:
|
|
177
|
+
* `contains` on a JSON column already means whole-document containment
|
|
178
|
+
* (`@>`), and silently changing that would break every existing caller.
|
|
179
|
+
*/
|
|
180
|
+
exports.JSON_STRING_OPERATORS = {
|
|
181
|
+
stringContains: (escaped) => `%${escaped}%`,
|
|
182
|
+
stringStartsWith: (escaped) => `${escaped}%`,
|
|
183
|
+
stringEndsWith: (escaped) => `%${escaped}`,
|
|
184
|
+
};
|
|
185
|
+
/**
|
|
186
|
+
* Every key a {@link JsonFilter} may carry. Used by the strict-key check so an
|
|
187
|
+
* unrecognized operator is REFUSED rather than dropped.
|
|
188
|
+
*
|
|
189
|
+
* This existed as tribal knowledge spread across `buildJsonFilterClauses` and
|
|
190
|
+
* `collectJsonFilterParams`: each simply ignored what it did not recognize, so
|
|
191
|
+
* `{ path: ['title'], string_contains: 'x' }` (the Prisma spelling) compiled to
|
|
192
|
+
* no predicate at all and returned every row of the table. The scalar operator
|
|
193
|
+
* path has always thrown on an unknown key; this set is what lets the JSON path
|
|
194
|
+
* behave the same way.
|
|
195
|
+
*/
|
|
196
|
+
for (const k of Object.keys(exports.JSON_STRING_OPERATORS))
|
|
197
|
+
exports.JSONB_OPERATOR_KEYS.add(k);
|
|
198
|
+
exports.JSON_FILTER_KEYS = new Set([
|
|
199
|
+
'path',
|
|
200
|
+
'equals',
|
|
201
|
+
'contains',
|
|
202
|
+
'hasKey',
|
|
203
|
+
'mode',
|
|
204
|
+
...Object.keys(exports.JSON_RANGE_OPERATORS),
|
|
205
|
+
...Object.keys(exports.JSON_STRING_OPERATORS),
|
|
206
|
+
]);
|
|
164
207
|
/**
|
|
165
208
|
* Value-invariant shape fingerprint for a {@link JsonFilter}. Range operators
|
|
166
209
|
* are annotated with the comparison value's kind (`#n` numeric / `#s` string)
|
|
167
|
-
* because a numeric comparison compiles to a `::numeric` cast
|
|
168
|
-
* SQL text than the text comparison
|
|
169
|
-
* SQL entry.
|
|
210
|
+
* because a numeric comparison compiles to a `::numeric` cast, a different
|
|
211
|
+
* SQL text than the text comparison, so the two must never share a cached
|
|
212
|
+
* SQL entry. `mode` is part of the shape for the same reason: it selects
|
|
213
|
+
* between `LIKE` and the dialect's case-insensitive form, which is different
|
|
214
|
+
* SQL text.
|
|
170
215
|
*/
|
|
171
216
|
function fingerprintJsonFilterShape(filter) {
|
|
172
217
|
const obj = filter;
|
|
173
218
|
const parts = Object.keys(obj)
|
|
174
219
|
.filter((k) => obj[k] !== undefined)
|
|
175
220
|
.sort()
|
|
176
|
-
.map((k) =>
|
|
221
|
+
.map((k) => {
|
|
222
|
+
if (k in exports.JSON_RANGE_OPERATORS)
|
|
223
|
+
return `${k}#${typeof obj[k] === 'number' ? 'n' : 's'}`;
|
|
224
|
+
// `mode` carries its VALUE, not just its presence: 'insensitive' and any
|
|
225
|
+
// other spelling select different SQL, so they must not share an entry.
|
|
226
|
+
if (k === 'mode')
|
|
227
|
+
return `mode#${String(obj[k])}`;
|
|
228
|
+
return k;
|
|
229
|
+
});
|
|
177
230
|
return `json(${parts.join(',')})`;
|
|
178
231
|
}
|
|
179
232
|
/**
|
|
180
|
-
* JSONB operator keys that are *unique* to {@link JsonFilter}
|
|
233
|
+
* JSONB operator keys that are *unique* to {@link JsonFilter}, they cannot
|
|
181
234
|
* appear in any other where-filter shape, so the presence of one of these is
|
|
182
235
|
* an unambiguous signal that the user meant a JSON filter. Used by the
|
|
183
236
|
* strict-validation path so that `{ contains: 'foo' }` (which is also a valid
|
|
@@ -185,7 +238,7 @@ function fingerprintJsonFilterShape(filter) {
|
|
|
185
238
|
* set: on non-JSON columns it is a plain equality operator (`WhereOperator`),
|
|
186
239
|
* so it must fall through instead of throwing.
|
|
187
240
|
*/
|
|
188
|
-
exports.JSONB_UNIQUE_KEYS = new Set(['path', 'hasKey']);
|
|
241
|
+
exports.JSONB_UNIQUE_KEYS = new Set(['path', 'hasKey', ...Object.keys(exports.JSON_STRING_OPERATORS)]);
|
|
189
242
|
/** Check if a value is a JSONB filter object */
|
|
190
243
|
function isJsonFilter(value) {
|
|
191
244
|
if (value === null ||
|
package/dist/cjs/query/index.js
CHANGED
|
@@ -21,11 +21,11 @@ import type { BuilderCtx } from './where.js';
|
|
|
21
21
|
* generation (see {@link buildRelationShape}) and consumed by the
|
|
22
22
|
* transform to map key-less positional arrays back to keyed objects.
|
|
23
23
|
*
|
|
24
|
-
* - `keys
|
|
24
|
+
* - `keys`, camelCase field names in emitted array position, INCLUDING nested
|
|
25
25
|
* relation slots (a nested relation occupies one more position after the
|
|
26
26
|
* scalar columns, in `sortedEntries(with)` order).
|
|
27
|
-
* - `nested
|
|
28
|
-
* - `cardinality
|
|
27
|
+
* - `nested`, sub-shape for each key in `keys` that is itself a relation slot.
|
|
28
|
+
* - `cardinality`, `'one'` (belongsTo/hasOne, a single positional array or
|
|
29
29
|
* null) vs `'many'` (an array of positional arrays).
|
|
30
30
|
*/
|
|
31
31
|
export interface RelationShape {
|
|
@@ -58,7 +58,7 @@ export declare function collectRelationSubqueryParams(qi: BuilderCtx, relDef: Re
|
|
|
58
58
|
* Value-shape fingerprint for a single orderBy entry, so two queries whose
|
|
59
59
|
* ORDER BY differs only in nulls placement, vector metric, or relation-count
|
|
60
60
|
* vs relation-column never collide on one cached SQL string. Captures the
|
|
61
|
-
* SQL-shaping bits (direction, nulls, metric, relation keys)
|
|
61
|
+
* SQL-shaping bits (direction, nulls, metric, relation keys), never values.
|
|
62
62
|
*/
|
|
63
63
|
export declare function orderByEntryFingerprint(qi: BuilderCtx, d: unknown, targetTable?: string): string;
|
|
64
64
|
export declare function buildOrderBy(qi: BuilderCtx, orderBy: OrderByClause, params?: unknown[], lateralSink?: string[]): string;
|
|
@@ -70,7 +70,7 @@ export declare function buildOrderBy(qi: BuilderCtx, orderBy: OrderByClause, par
|
|
|
70
70
|
export declare function isRelationOrderByValue(_qi: BuilderCtx, value: unknown): boolean;
|
|
71
71
|
/**
|
|
72
72
|
* Render the ` NULLS FIRST` / ` NULLS LAST` suffix for a column ordering.
|
|
73
|
-
* Only PostgreSQL and SQLite support the `NULLS FIRST/LAST` grammar
|
|
73
|
+
* Only PostgreSQL and SQLite support the `NULLS FIRST/LAST` grammar, on any
|
|
74
74
|
* other engine a caller asking for explicit nulls placement gets a clear
|
|
75
75
|
* {@link UnsupportedFeatureError} (E017) instead of broken SQL.
|
|
76
76
|
*/
|
|
@@ -225,7 +225,7 @@ export declare function collectManyToManyTargetGlobalFilter(qi: BuilderCtx, relD
|
|
|
225
225
|
/**
|
|
226
226
|
* Param-collect mirror of {@link buildRelationCountExpr}'s global-filter
|
|
227
227
|
* params (hasMany direct filter, or manyToMany EXISTS-on-target). Only pushes
|
|
228
|
-
* when a filter applies
|
|
228
|
+
* when a filter applies, no-op otherwise.
|
|
229
229
|
*/
|
|
230
230
|
export declare function collectRelationCountParams(qi: BuilderCtx, relDef: RelationDef, params: unknown[]): void;
|
|
231
231
|
export declare function getCamelDateFields(qi: BuilderCtx, table: string, meta: TableMetadata): Set<string>;
|
|
@@ -277,7 +277,7 @@ export declare function makeNestedParser(qi: BuilderCtx, withClause: WithClause,
|
|
|
277
277
|
/**
|
|
278
278
|
* Return a shallow copy of a top-level row with each relation column decoded
|
|
279
279
|
* from its positional array(s) into the object representation. Only relation
|
|
280
|
-
* columns are positional
|
|
280
|
+
* columns are positional, base scalar columns stay object-keyed, so the
|
|
281
281
|
* result is exactly what the object encoding would have handed parseNestedRow.
|
|
282
282
|
*/
|
|
283
283
|
export declare function decodePositionalRelations(qi: BuilderCtx, row: Record<string, unknown>, shapes: Record<string, RelationShape>): Record<string, unknown>;
|
|
@@ -319,7 +319,7 @@ export interface FlattenNode {
|
|
|
319
319
|
alias: string;
|
|
320
320
|
/** Alias of the real target table inside the derived table (`f0s`). */
|
|
321
321
|
srcAlias: string;
|
|
322
|
-
/** Target-side correlation columns (provably unique
|
|
322
|
+
/** Target-side correlation columns (provably unique, see {@link provableUniqueTargetKey}). */
|
|
323
323
|
keyColumns: string[];
|
|
324
324
|
/**
|
|
325
325
|
* Match discriminator. A top-level node projects the constant `1` (its
|
|
@@ -394,7 +394,7 @@ export declare function provableUniqueTargetKey(relDef: RelationDef, targetMeta:
|
|
|
394
394
|
* it emits today, down to the cache key).
|
|
395
395
|
*
|
|
396
396
|
* The plan is a pure function of the schema, the `with` clause shape and
|
|
397
|
-
* `includePii
|
|
397
|
+
* `includePii`, never of any bound value, so the build path, the cache-hit
|
|
398
398
|
* param-collect path and the row assembler can each recompute it and agree.
|
|
399
399
|
*/
|
|
400
400
|
export declare function planFlattenWith(qi: BuilderCtx, table: string, withClause: WithClause, includePii?: boolean): FlattenPlan | null;
|