@spooky-sync/query-builder 0.0.1-canary.21 → 0.0.1-canary.210
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/AGENTS.md +63 -0
- package/dist/index.d.mts +149 -8
- package/dist/index.d.mts.map +1 -1
- package/dist/index.d.ts +149 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +208 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +207 -13
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/skills/{spooky-query-builder → sp00ky-query-builder}/SKILL.md +9 -9
- package/src/index.ts +11 -0
- package/src/query-builder.test.ts +213 -4
- package/src/query-builder.ts +343 -20
- package/src/repro_relationship.test.ts +1 -1
- package/src/table-schema.ts +38 -3
- package/src/types.ts +110 -5
- /package/skills/{spooky-query-builder → sp00ky-query-builder}/references/type-helpers.md +0 -0
package/src/types.ts
CHANGED
|
@@ -23,6 +23,79 @@ export interface QueryInfo {
|
|
|
23
23
|
query: string;
|
|
24
24
|
hash: number;
|
|
25
25
|
vars?: Record<string, unknown>;
|
|
26
|
+
/**
|
|
27
|
+
* Engine-neutral description of the same SELECT, used by non-SurrealQL local
|
|
28
|
+
* cache backends (e.g. SQLite) that cannot parse the `query` string. Only
|
|
29
|
+
* populated for `SELECT` (undefined for LIVE/UPDATE/DELETE). See `QueryPlan`.
|
|
30
|
+
*/
|
|
31
|
+
plan?: QueryPlan;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* A single WHERE comparison. `value` is the resolved value (string IDs already
|
|
36
|
+
* converted to `RecordId`); when `paramRef` is set the condition references an
|
|
37
|
+
* existing query param verbatim (`$name`) instead of an inline value. `swap`
|
|
38
|
+
* flips the operands (`value op field`), mirroring `ComparisonOp._swap`.
|
|
39
|
+
*/
|
|
40
|
+
export interface WhereComparison {
|
|
41
|
+
field: string;
|
|
42
|
+
op: ComparisonOp['_op'];
|
|
43
|
+
value: unknown;
|
|
44
|
+
paramRef?: string;
|
|
45
|
+
swap?: boolean;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** A parenthesised `(c1 OR c2 …)` group, from a `_or` fragment. */
|
|
49
|
+
export interface WhereOr {
|
|
50
|
+
or: WhereComparison[];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Engine-neutral WHERE: a top-level conjunction (AND) of comparisons and/or
|
|
55
|
+
* OR-groups. Mirrors `buildQueryFromOptions`'s condition assembly exactly.
|
|
56
|
+
*/
|
|
57
|
+
export type WhereNode = WhereComparison | WhereOr;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Engine-neutral description of a SELECT query. Backends render it to their own
|
|
61
|
+
* dialect (SurrealQL, SQLite, …). Relations are resolved by the caller via
|
|
62
|
+
* level-ordered decomposition rather than nested projection, so `relations`
|
|
63
|
+
* carries the tree rather than a flattened subquery string.
|
|
64
|
+
*/
|
|
65
|
+
export interface QueryPlan {
|
|
66
|
+
table: string;
|
|
67
|
+
/** Projection field names; undefined means all (`*`). */
|
|
68
|
+
select?: string[];
|
|
69
|
+
where?: WhereNode[];
|
|
70
|
+
orderBy?: [field: string, direction: 'asc' | 'desc'][];
|
|
71
|
+
limit?: number;
|
|
72
|
+
offset?: number;
|
|
73
|
+
relations?: RelationPlan[];
|
|
74
|
+
/**
|
|
75
|
+
* Window materialization: when set, the base rows are EXACTLY these record
|
|
76
|
+
* ids (the window the SSP already computed), ignoring `where`/`limit`/
|
|
77
|
+
* `offset`. `orderBy`, `select` and `relations` still apply. Set by
|
|
78
|
+
* {@link buildWindowMaterializationPlan}; see `window-query.ts`.
|
|
79
|
+
*/
|
|
80
|
+
ids?: unknown[];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* One `.related()` edge in a {@link QueryPlan}. Correlation:
|
|
85
|
+
* - `one` → parent[`foreignKeyField`] = child.id (attach `bucket[0] ?? null`)
|
|
86
|
+
* - `many` → child[`foreignKeyField`] = parent.id (attach `bucket`)
|
|
87
|
+
* `limit`/`orderBy` are applied PER PARENT during decomposition.
|
|
88
|
+
*/
|
|
89
|
+
export interface RelationPlan {
|
|
90
|
+
alias: string;
|
|
91
|
+
table: string;
|
|
92
|
+
cardinality: 'one' | 'many';
|
|
93
|
+
foreignKeyField: string;
|
|
94
|
+
select?: string[];
|
|
95
|
+
where?: WhereNode[];
|
|
96
|
+
orderBy?: [field: string, direction: 'asc' | 'desc'][];
|
|
97
|
+
limit?: number;
|
|
98
|
+
relations?: RelationPlan[];
|
|
26
99
|
}
|
|
27
100
|
|
|
28
101
|
export interface RelatedQuery {
|
|
@@ -36,9 +109,40 @@ export interface RelatedQuery {
|
|
|
36
109
|
cardinality: 'one' | 'many';
|
|
37
110
|
}
|
|
38
111
|
|
|
112
|
+
/**
|
|
113
|
+
* Comparison-operator descriptor for a single WHERE field, e.g.
|
|
114
|
+
* `{ _op: '<=', _val: 5 }` → `field <= $field`. A `$`-prefixed string `_val`
|
|
115
|
+
* references an existing query param verbatim; `_swap: true` flips the operands
|
|
116
|
+
* (`$val _op field`). Plain values still mean equality (`field = $field`).
|
|
117
|
+
*/
|
|
118
|
+
export interface ComparisonOp {
|
|
119
|
+
_op: '=' | '!=' | '>' | '>=' | '<' | '<=' | (string & {});
|
|
120
|
+
_val: unknown;
|
|
121
|
+
_swap?: boolean;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** A single WHERE field value: an equality value or a comparison descriptor. */
|
|
125
|
+
export type WhereFieldValue<V> = V | ComparisonOp;
|
|
126
|
+
|
|
127
|
+
/** A flat conjunction of field conditions (equality or comparison). */
|
|
128
|
+
export type WhereConditions<TModel extends GenericModel> = {
|
|
129
|
+
[K in keyof TModel]?: WhereFieldValue<TModel[K]>;
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* WHERE input for `.where()`. Supports equality (`{ field: value }`), comparison
|
|
134
|
+
* operators (`{ field: { _op, _val } }`), and a single top-level `_or` group of
|
|
135
|
+
* condition fragments that compile to a parenthesised `(... OR ...)` conjunct —
|
|
136
|
+
* e.g. `{ _or: [{ white: x }, { black: x }] }` → `(white = $white__or0 OR black = $black__or1)`.
|
|
137
|
+
* Backward-compatible with plain `Partial<TModel>` equality objects.
|
|
138
|
+
*/
|
|
139
|
+
export type WhereInput<TModel extends GenericModel> = WhereConditions<TModel> & {
|
|
140
|
+
_or?: WhereConditions<TModel>[];
|
|
141
|
+
};
|
|
142
|
+
|
|
39
143
|
export interface QueryOptions<TModel extends GenericModel, IsOne extends boolean> {
|
|
40
144
|
select?: ((keyof TModel & string) | '*')[];
|
|
41
|
-
where?:
|
|
145
|
+
where?: WhereInput<TModel>;
|
|
42
146
|
limit?: number;
|
|
43
147
|
offset?: number;
|
|
44
148
|
orderBy?: Partial<Record<keyof TModel, 'asc' | 'desc'>>;
|
|
@@ -47,10 +151,10 @@ export interface QueryOptions<TModel extends GenericModel, IsOne extends boolean
|
|
|
47
151
|
isOne?: IsOne;
|
|
48
152
|
}
|
|
49
153
|
|
|
50
|
-
export
|
|
154
|
+
export type LiveQueryOptions<TModel extends GenericModel> = Omit<
|
|
51
155
|
QueryOptions<TModel, boolean>,
|
|
52
156
|
'orderBy'
|
|
53
|
-
|
|
157
|
+
>;
|
|
54
158
|
|
|
55
159
|
// Import schema types for schema-aware modifiers
|
|
56
160
|
import type {
|
|
@@ -78,7 +182,7 @@ export type SchemaAwareQueryModifier<
|
|
|
78
182
|
|
|
79
183
|
// Simplified query builder interface for modifying subqueries
|
|
80
184
|
export interface QueryModifierBuilder<TModel extends GenericModel> {
|
|
81
|
-
where(conditions:
|
|
185
|
+
where(conditions: WhereInput<TModel>): this;
|
|
82
186
|
select(...fields: ((keyof TModel & string) | '*')[]): this;
|
|
83
187
|
limit(count: number): this;
|
|
84
188
|
offset(count: number): this;
|
|
@@ -93,7 +197,7 @@ export interface SchemaAwareQueryModifierBuilder<
|
|
|
93
197
|
TableName extends TableNames<S>,
|
|
94
198
|
RelatedFields extends Record<string, any> = {},
|
|
95
199
|
> {
|
|
96
|
-
where(conditions:
|
|
200
|
+
where(conditions: WhereInput<TableModel<GetTable<S, TableName>>>): this;
|
|
97
201
|
select(...fields: ((keyof TableModel<GetTable<S, TableName>> & string) | '*')[]): this;
|
|
98
202
|
limit(count: number): this;
|
|
99
203
|
offset(count: number): this;
|
|
@@ -139,6 +243,7 @@ export type RelationshipFields<TModel extends GenericModel> = {
|
|
|
139
243
|
* Simplified to directly access the nested structure
|
|
140
244
|
*/
|
|
141
245
|
export type InferRelatedModelFromMetadata<
|
|
246
|
+
// oxlint-disable-next-line no-unused-vars -- Schema is used as a generic constraint
|
|
142
247
|
Schema extends GenericSchema,
|
|
143
248
|
TableName extends string,
|
|
144
249
|
FieldName extends string,
|
|
File without changes
|