@vaultgradient/pipequery-lang 1.12.2 → 1.13.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.
@@ -0,0 +1,458 @@
1
+ import { E as Expression, O as Operation, P as Pipeline, C as CompiledQuery, D as DataContext } from '../types-CukH_v-n.cjs';
2
+
3
+ /**
4
+ * Compile-time types of the builder. Nothing here exists at runtime except three
5
+ * phantom symbols: every expression is an `Expr` instance, these interfaces are
6
+ * only views that decide which methods and positions type-check.
7
+ *
8
+ * An expression carries:
9
+ * - a value type (`NumExpr`, `StrExpr`, `BoolExpr`, `GenericExpr<T>`)
10
+ * - a scope: `'row'` (plain fields and operators), `'agg'` (contains an aggregate) or
11
+ * `'win'` (contains a window function). Scopes are unioned when expressions combine,
12
+ * so `where` and `sort`, which accept `'row'` only, reject both.
13
+ * - whether it is aliased (`.as(name)`). Aliased expressions cannot go where the
14
+ * grammar forbids `as` (sort, groupBy, distinct, ...).
15
+ */
16
+
17
+ declare const TYPE: unique symbol;
18
+ declare const SCOPE: unique symbol;
19
+ declare const ALIAS: unique symbol;
20
+ declare const NULLISH: unique symbol;
21
+ type Scope = 'row' | 'agg' | 'win';
22
+ type IsAny<T> = 0 extends 1 & T ? true : false;
23
+ /** What every expression looks like to positions that take any of them (aliased or not). */
24
+ interface ExprBase<T = any, S extends Scope = Scope> {
25
+ readonly [TYPE]?: T;
26
+ readonly [SCOPE]?: S;
27
+ readonly [ALIAS]?: boolean;
28
+ }
29
+ /** An expression that is not aliased. */
30
+ type Plain<T = any, S extends Scope = Scope> = ExprBase<T, S> & {
31
+ readonly [ALIAS]?: false;
32
+ };
33
+ /** `expr.as('name')`: usable in `select`, `map`, `rollup` and `pivot`, and nowhere that forbids `as`. */
34
+ interface AliasedExpr<N extends string = string, T = any, S extends Scope = Scope> extends ExprBase<T, S> {
35
+ readonly [ALIAS]: true;
36
+ /** Phantom: the output column name. */
37
+ readonly __name?: N;
38
+ }
39
+ type Nullish = null | undefined;
40
+ /** Operands also accept nullable expressions (a nullable field is still a number/string/boolean field). */
41
+ type NumOperand<B extends Scope = 'row'> = number | Plain<number | Nullish, B>;
42
+ type StrOperand<B extends Scope = 'row'> = string | Plain<string | Nullish, B>;
43
+ type BoolOperand<B extends Scope = 'row'> = boolean | Plain<boolean | Nullish, B>;
44
+ /**
45
+ * Phantom marker for expressions that may be `null`/`undefined` (nullable or optional fields,
46
+ * `win.lag`, ...). The kind interfaces (`NumExpr`, ...) stay the same so operators and positions
47
+ * are unaffected; only `ValueOf`, and so the output row types, see it.
48
+ */
49
+ type WithNull<E, N> = [N] extends [never] ? E : E & {
50
+ readonly [NULLISH]: N;
51
+ };
52
+ type NullOf<X> = X extends {
53
+ readonly [NULLISH]: infer N;
54
+ } ? N : never;
55
+ type Undef<N> = [N] extends [never] ? never : undefined;
56
+ interface Common<T, S extends Scope> extends ExprBase<T, S> {
57
+ readonly [ALIAS]?: false;
58
+ eq<O extends T | Nullish | Plain<T | Nullish, Scope>>(other: O): BoolExpr<S | ScopeOf<O>>;
59
+ ne<O extends T | Nullish | Plain<T | Nullish, Scope>>(other: O): BoolExpr<S | ScopeOf<O>>;
60
+ /** First non-null value of this expression and the fallbacks. */
61
+ coalesce<O extends T | Plain<T | Nullish, Scope>>(...rest: O[]): ExprFor<T, S | ScopeOf<O>>;
62
+ as<N extends string>(name: N): AliasedExpr<N, T, S>;
63
+ asc(): SortKey<S>;
64
+ desc(): SortKey<S>;
65
+ }
66
+ /** An expression of a type with no dedicated operators (arrays, `unknown`, mixed unions). */
67
+ interface GenericExpr<T = unknown, S extends Scope = 'row'> extends Common<T, S> {
68
+ }
69
+ interface NumExpr<S extends Scope = 'row'> extends Common<number, S> {
70
+ gt<O extends NumOperand<Scope>>(other: O): BoolExpr<S | ScopeOf<O>>;
71
+ gte<O extends NumOperand<Scope>>(other: O): BoolExpr<S | ScopeOf<O>>;
72
+ lt<O extends NumOperand<Scope>>(other: O): BoolExpr<S | ScopeOf<O>>;
73
+ lte<O extends NumOperand<Scope>>(other: O): BoolExpr<S | ScopeOf<O>>;
74
+ plus<O extends NumOperand<Scope>>(other: O): NumExpr<S | ScopeOf<O>>;
75
+ minus<O extends NumOperand<Scope>>(other: O): NumExpr<S | ScopeOf<O>>;
76
+ times<O extends NumOperand<Scope>>(other: O): NumExpr<S | ScopeOf<O>>;
77
+ div<O extends NumOperand<Scope>>(other: O): NumExpr<S | ScopeOf<O>>;
78
+ mod<O extends NumOperand<Scope>>(other: O): NumExpr<S | ScopeOf<O>>;
79
+ neg(): NumExpr<S>;
80
+ abs(): NumExpr<S>;
81
+ round<O extends NumOperand<Scope> = number>(precision?: O): NumExpr<S | ScopeOf<O>>;
82
+ }
83
+ interface StrExpr<S extends Scope = 'row'> extends Common<string, S> {
84
+ gt<O extends StrOperand<Scope>>(other: O): BoolExpr<S | ScopeOf<O>>;
85
+ gte<O extends StrOperand<Scope>>(other: O): BoolExpr<S | ScopeOf<O>>;
86
+ lt<O extends StrOperand<Scope>>(other: O): BoolExpr<S | ScopeOf<O>>;
87
+ lte<O extends StrOperand<Scope>>(other: O): BoolExpr<S | ScopeOf<O>>;
88
+ lower(): StrExpr<S>;
89
+ upper(): StrExpr<S>;
90
+ trim(): StrExpr<S>;
91
+ len(): NumExpr<S>;
92
+ concat<A extends Array<string | number | boolean | Plain<any, Scope>>>(...rest: A): StrExpr<S | ScopeOf<A[number]>>;
93
+ contains<O extends StrOperand<Scope>>(search: O): BoolExpr<S | ScopeOf<O>>;
94
+ startsWith<O extends StrOperand<Scope>>(prefix: O): BoolExpr<S | ScopeOf<O>>;
95
+ endsWith<O extends StrOperand<Scope>>(suffix: O): BoolExpr<S | ScopeOf<O>>;
96
+ substring<N1 extends NumOperand<Scope>, N2 extends NumOperand<Scope> = number>(start: N1, length?: N2): StrExpr<S | ScopeOf<N1 | N2>>;
97
+ replace<A extends StrOperand<Scope>, B extends StrOperand<Scope>>(search: A, replacement: B): StrExpr<S | ScopeOf<A | B>>;
98
+ }
99
+ interface BoolExpr<S extends Scope = 'row'> extends Common<boolean, S> {
100
+ and<O extends BoolOperand<Scope>>(other: O): BoolExpr<S | ScopeOf<O>>;
101
+ /** Logical or. Printed as `if(a, true, b)`, because the lexer cannot read `||`. */
102
+ or<O extends BoolOperand<Scope>>(other: O): BoolExpr<S | ScopeOf<O>>;
103
+ not(): BoolExpr<S>;
104
+ }
105
+ /** The expression type for a value type `T` in scope `S`. `any` stays `any`. */
106
+ type ExprFor<T, S extends Scope = 'row'> = 0 extends 1 & T ? any : [T] extends [number] ? NumExpr<S> : [T] extends [string] ? StrExpr<S> : [T] extends [boolean] ? BoolExpr<S> : GenericExpr<T, S>;
107
+ /** Like `ExprFor`, but `null`/`undefined` in `V` become the nullish marker instead of being dropped. */
108
+ type ExprOf<V, S extends Scope = 'row'> = 0 extends 1 & V ? any : [NonNullable<V>] extends [never] ? GenericExpr<V, S> : WithNull<ExprFor<NonNullable<V>, S>, Extract<V, Nullish>>;
109
+ /** The value type of an expression (or of a JS literal used as an operand). */
110
+ type ValueOf<X> = 0 extends 1 & X ? any : X extends number ? number : X extends string ? string : X extends boolean ? boolean : X extends null ? null : X extends ExprBase<infer T, any> ? T | NullOf<X> : unknown;
111
+ /** The scope of an expression (`'row'` for literals). */
112
+ type ScopeOf<X> = IsAny<X> extends true ? 'row' : X extends number | string | boolean | null ? 'row' : X extends ExprBase<any, infer S> ? IsAny<S> extends true ? 'row' : S : 'row';
113
+ /** Names that exist on `Expr` at runtime, so a nested field of that name is not addressable as `o.a.name`. */
114
+ type Clashes = keyof Expr | 'constructor' | 'valueOf' | 'toLocaleString' | 'hasOwnProperty' | 'isPrototypeOf' | 'propertyIsEnumerable';
115
+ /** A nested object is itself an expression of type `V`, so it can be selected, grouped or compared as a whole. */
116
+ type NestedFields<V, N = never> = Plain<V, 'row'> & {
117
+ readonly [K in keyof V & string as K extends Clashes ? never : K]-?: FieldOf<V[K], N>;
118
+ } & {
119
+ /** Reach a nested field whose name clashes with an expression method: `o.meta.$('len')`. */
120
+ $(...segments: string[]): any;
121
+ };
122
+ /** The expression (or nested proxy) for a field of type `V`. */
123
+ type FieldOf<V, P = never> = 0 extends 1 & V ? any : unknown extends V ? GenericExpr<unknown, 'row'> : [NonNullable<V>] extends [never] ? GenericExpr<V, 'row'> : WithNull<[
124
+ NonNullable<V>
125
+ ] extends [number | string | boolean] ? ExprFor<NonNullable<V>, 'row'> : [NonNullable<V>] extends [readonly unknown[] | Date] ? GenericExpr<NonNullable<V>, 'row'> : [NonNullable<V>] extends [object] ? NestedFields<NonNullable<V>, Undef<Extract<V, Nullish> | P>> : GenericExpr<NonNullable<V>, 'row'>, Extract<V, Nullish> | Undef<P>>;
126
+ /**
127
+ * The row object handed to builder callbacks: `o.total` is a `NumExpr` when the row's
128
+ * `total` is a number, `o.customer.name` follows nested objects. For `Row = any` every field is `any`.
129
+ */
130
+ type Fields<Row = any> = 0 extends 1 & Row ? Record<string, any> : {
131
+ readonly [K in keyof Row & string]-?: FieldOf<Row[K]>;
132
+ };
133
+ /** A field argument of an aggregate or window function: a row expression or a raw pipequery expression. */
134
+ type NumField = string | Plain<number | Nullish, 'row'>;
135
+ type AnyField = string | Plain<any, 'row'>;
136
+ /** A branch/fallback value: expression or JS literal. */
137
+ type Branch = ExprBase<any, Scope> | string | number | boolean | null;
138
+ type Def<T> = NonNullable<T>;
139
+ /** The 24 aggregates as expression builders: `agg.sum(o.total)`, `agg.count()`. */
140
+ interface AggregateHelpers {
141
+ sum(field: NumField): NumExpr<'agg'>;
142
+ avg(field: NumField): NumExpr<'agg'>;
143
+ median(field: NumField): NumExpr<'agg'>;
144
+ stddev(field: NumField): NumExpr<'agg'>;
145
+ var(field: NumField): NumExpr<'agg'>;
146
+ skew(field: NumField): NumExpr<'agg'>;
147
+ kurt(field: NumField): NumExpr<'agg'>;
148
+ drawdown(field: NumField): NumExpr<'agg'>;
149
+ pct(field: NumField): NumExpr<'agg'>;
150
+ sharpe(field: NumField): NumExpr<'agg'>;
151
+ calmar(field: NumField): NumExpr<'agg'>;
152
+ sortino(field: NumField): NumExpr<'agg'>;
153
+ sum_abs(field: NumField): NumExpr<'agg'>;
154
+ abs_sum(field: NumField): NumExpr<'agg'>;
155
+ distinct_count(field: AnyField): NumExpr<'agg'>;
156
+ count(field?: AnyField): NumExpr<'agg'>;
157
+ min<E extends Plain<any, 'row'>>(field: E | string): ExprFor<Def<ValueOf<E>>, 'agg'>;
158
+ max<E extends Plain<any, 'row'>>(field: E | string): ExprFor<Def<ValueOf<E>>, 'agg'>;
159
+ first_value<E extends Plain<any, 'row'>>(field: E | string): ExprFor<Def<ValueOf<E>>, 'agg'>;
160
+ last_value<E extends Plain<any, 'row'>>(field: E | string): ExprFor<Def<ValueOf<E>>, 'agg'>;
161
+ percentile(field: NumField, p: number | Plain<number, 'row'>): NumExpr<'agg'>;
162
+ vwap(price: NumField, volume: NumField): NumExpr<'agg'>;
163
+ wavg(value: NumField, weight: NumField): NumExpr<'agg'>;
164
+ info_ratio(returns: NumField, benchmark: NumField): NumExpr<'agg'>;
165
+ }
166
+ /** Window functions. Valid as a top-level (optionally aliased) field of `select` outside `groupBy`. */
167
+ interface WindowHelpers {
168
+ running_sum(field: NumField): NumExpr<'win'>;
169
+ running_avg(field: NumField): NumExpr<'win'>;
170
+ running_min(field: NumField): NumExpr<'win'>;
171
+ running_max(field: NumField): NumExpr<'win'>;
172
+ running_count(field?: AnyField): NumExpr<'win'>;
173
+ row_number(): NumExpr<'win'>;
174
+ /** `null` at the edges of the window, so the value is typed `T | null`. */
175
+ lag<E extends Plain<any, 'row'>>(field: E | string, offset?: number): ExprOf<ValueOf<E> | null, 'win'>;
176
+ lead<E extends Plain<any, 'row'>>(field: E | string, offset?: number): ExprOf<ValueOf<E> | null, 'win'>;
177
+ }
178
+ /** Scalar functions as free functions. A string argument is a string literal. */
179
+ interface FnHelpers {
180
+ if<C extends BoolOperand<Scope>, X extends Branch = Branch, Y extends Branch = null>(cond: C, then: X, otherwise?: Y): ExprOf<ValueOf<X> | ValueOf<Y>, ScopeOf<C> | ScopeOf<X> | ScopeOf<Y>>;
181
+ coalesce<A extends Branch[]>(...args: A): ExprFor<Def<ValueOf<A[number]>>, ScopeOf<A[number]>>;
182
+ lower<O extends StrOperand<Scope>>(value: O): StrExpr<ScopeOf<O>>;
183
+ upper<O extends StrOperand<Scope>>(value: O): StrExpr<ScopeOf<O>>;
184
+ trim<O extends StrOperand<Scope>>(value: O): StrExpr<ScopeOf<O>>;
185
+ len<O extends StrOperand<Scope>>(value: O): NumExpr<ScopeOf<O>>;
186
+ abs<O extends NumOperand<Scope>>(value: O): NumExpr<ScopeOf<O>>;
187
+ round<V extends NumOperand<Scope>, P extends NumOperand<Scope> = number>(value: V, precision?: P): NumExpr<ScopeOf<V | P>>;
188
+ concat<A extends Array<string | number | boolean | Plain<any, Scope>>>(...args: A): StrExpr<ScopeOf<A[number]>>;
189
+ contains<V extends StrOperand<Scope>, A extends StrOperand<Scope>>(value: V, search: A): BoolExpr<ScopeOf<V | A>>;
190
+ startsWith<V extends StrOperand<Scope>, A extends StrOperand<Scope>>(value: V, prefix: A): BoolExpr<ScopeOf<V | A>>;
191
+ endsWith<V extends StrOperand<Scope>, A extends StrOperand<Scope>>(value: V, suffix: A): BoolExpr<ScopeOf<V | A>>;
192
+ substring<V extends StrOperand<Scope>, N1 extends NumOperand<Scope>, N2 extends NumOperand<Scope> = number>(value: V, start: N1, length?: N2): StrExpr<ScopeOf<V | N1 | N2>>;
193
+ replace<V extends StrOperand<Scope>, A extends StrOperand<Scope>, B extends StrOperand<Scope>>(value: V, search: A, replacement: B): StrExpr<ScopeOf<V | A | B>>;
194
+ }
195
+ type Simplify<T> = {
196
+ [K in keyof T]: T[K];
197
+ } & {};
198
+ /** The row type of `select({ a: expr, ... })`. */
199
+ type Shape<R> = Simplify<{
200
+ [K in keyof R]: ValueOf<R[K]>;
201
+ }>;
202
+ /**
203
+ * The row type of a `select`/`map` object literal after `groupBy`. The engine evaluates fields
204
+ * against `{ ...keyColumns, _group }`: key columns are named after the last path segment (or `key`),
205
+ * so any row-scope field may be missing. Aggregate-only values stay precise; JS literals too.
206
+ */
207
+ type GroupedShape<R> = Simplify<{
208
+ [K in keyof R]: R[K] extends number | string | boolean | null ? ValueOf<R[K]> : 'row' extends ScopeOf<R[K]> ? ValueOf<R[K]> | undefined : ValueOf<R[K]>;
209
+ }>;
210
+ /** Row type after `map`/`join`: the right keys win. `any` on either side gives `any`. */
211
+ type Merge<A, B> = 0 extends 1 & A ? any : 0 extends 1 & B ? any : Simplify<Omit<A, keyof B> & B>;
212
+
213
+ declare const NODE: unique symbol;
214
+
215
+ /** Values accepted as operands: expressions or JS literals (strings are always string literals). */
216
+ type Operand = Expr | string | number | boolean | null;
217
+ /** Field positions of aggregates / window functions: an expression, or a raw pipequery expression string. */
218
+ type FieldInput = Expr | string;
219
+ /** A sort key from `asc()`/`desc()`. The scope is a compile-time tag: `sort` accepts `'row'` keys only. */
220
+ declare class SortKey<S extends Scope = 'row'> {
221
+ readonly expression: Expression;
222
+ readonly direction: 'asc' | 'desc';
223
+ readonly __scope?: S;
224
+ constructor(expression: Expression, direction: 'asc' | 'desc');
225
+ }
226
+ /** The AST node behind an expression. */
227
+ declare function toAst(value: unknown, what?: string): Expression;
228
+ /**
229
+ * A pipequery expression. Immutable: every method returns a new expression.
230
+ *
231
+ * Inside builder callbacks, `o.total` is an `Expr` (a field access) whose unknown
232
+ * property names extend the path: `o.customer.name`. Names that collide with an
233
+ * `Expr` method (`len`, `round`, `replace`, ...) are reached with `.$('len')` or `col()`.
234
+ */
235
+ declare class Expr {
236
+ readonly [NODE]: Expression;
237
+ readonly [TYPE]?: any;
238
+ readonly [SCOPE]?: 'row';
239
+ readonly [ALIAS]?: false;
240
+ constructor(node: Expression);
241
+ gt(other: Operand): Expr;
242
+ gte(other: Operand): Expr;
243
+ lt(other: Operand): Expr;
244
+ lte(other: Operand): Expr;
245
+ eq(other: Operand): Expr;
246
+ ne(other: Operand): Expr;
247
+ and(other: Operand): Expr;
248
+ /**
249
+ * Logical or. The AST uses `if(a, true, b)` for proven boolean `a`, and
250
+ * `if(a, a, b)` otherwise: the lexer cannot parse `||` (it reads two PIPE tokens).
251
+ * Both forms have the engine's `a || b` value semantics and round-trip through
252
+ * `parseQuery`. In the latter, `a` is evaluated twice; expressions are pure.
253
+ *
254
+ * Unknown-valued chains stay linear by associating right: `a.or(b).or(c)`
255
+ * becomes `if(a, a, if(b, b, c))`.
256
+ */
257
+ or(other: Operand): Expr;
258
+ not(): Expr;
259
+ plus(other: Operand): Expr;
260
+ minus(other: Operand): Expr;
261
+ times(other: Operand): Expr;
262
+ div(other: Operand): Expr;
263
+ mod(other: Operand): Expr;
264
+ neg(): Expr;
265
+ lower(): Expr;
266
+ upper(): Expr;
267
+ len(): Expr;
268
+ abs(): Expr;
269
+ round(precision?: Operand): Expr;
270
+ trim(): Expr;
271
+ concat(...rest: Operand[]): Expr;
272
+ coalesce(...rest: Operand[]): Expr;
273
+ contains(search: Operand): Expr;
274
+ startsWith(prefix: Operand): Expr;
275
+ endsWith(suffix: Operand): Expr;
276
+ substring(start: Operand, length?: Operand): Expr;
277
+ replace(search: Operand, replacement: Operand): Expr;
278
+ /** `expr as name`. Re-aliasing replaces the previous alias. */
279
+ as<N extends string>(name: N): AliasedExpr<N, any, 'row'>;
280
+ asc(): SortKey;
281
+ desc(): SortKey;
282
+ /** Extend a field path with names that collide with `Expr` methods: `o.customer.$('len')`. */
283
+ $(...segments: string[]): Expr;
284
+ /** The pipequery text of this expression. */
285
+ toString(): string;
286
+ }
287
+ /**
288
+ * Field access from a dotted path: `col('customer.name')` or `col('customer', 'name')`.
289
+ * Give the field's type to get typed operators: `col<number>('total').gt(1)`.
290
+ */
291
+ declare function col<V = any>(...path: string[]): FieldOf<V>;
292
+ /** A literal value (strings are string literals, never field names). */
293
+ declare function lit(value: number): NumExpr;
294
+ declare function lit(value: string): StrExpr;
295
+ declare function lit(value: boolean): BoolExpr;
296
+ declare function lit(value: null): GenericExpr<null>;
297
+
298
+ declare const agg: AggregateHelpers;
299
+ declare const fn: FnHelpers;
300
+ declare const win: WindowHelpers;
301
+
302
+ /** Row-scope expression without alias: the position of where/sort/groupBy keys and join conditions. */
303
+ type RowExpr = Plain<any, 'row'> | Expr;
304
+ /** A single expression: raw pipequery string, expression, or a callback receiving the row. */
305
+ type ExprInput<Row = any, X = ExprBase> = string | X | Expr | ((o: Fields<Row>) => X | Expr);
306
+ /** One or more expressions. */
307
+ type ExprListInput<Row = any, X = ExprBase> = string | X | Expr | ((o: Fields<Row>) => X | X[] | Expr | Expr[]);
308
+ /** Values of an object literal passed to `select`/`map`. */
309
+ type SelectValue<S extends Scope = Scope> = string | number | boolean | null | ExprBase<any, S>;
310
+ /** `select`/`map` item: also accepts `{ alias: expression }` objects. */
311
+ type SelectInput<Row = any, S extends Scope = Scope> = string | ExprBase<any, S> | Record<string, SelectValue<S>> | ((o: Fields<Row>) => ExprBase<any, S> | ExprBase<any, S>[] | Record<string, SelectValue<S>>);
312
+ type SortInput<Row = any> = string | RowExpr | SortKey | ((o: Fields<Row>) => RowExpr | SortKey | Array<RowExpr | SortKey>);
313
+ /** A join condition: raw string, expression, `(left, right) => expression`, or `{ on: [left, right] }`. */
314
+ type JoinInput<Row = any, Right = any> = string | BoolExpr<'row'> | Expr | ((left: Fields<Row>, right: Fields<Right>) => BoolExpr<'row'> | Expr) | {
315
+ on: [string | RowExpr, string | RowExpr];
316
+ };
317
+ /** Rows seen by operations that follow `groupBy`: `{ ...keys, _group }`, so untyped. */
318
+ type Cur<Row, G extends boolean> = G extends true ? any : Row;
319
+ /** Scopes `select` accepts: aggregates after `groupBy`, window functions otherwise. */
320
+ type SelectScope<G extends boolean> = G extends true ? 'row' | 'agg' : 'row' | 'win';
321
+ /** Scopes `map` accepts: aggregates after `groupBy`, plain row expressions otherwise. */
322
+ type MapScope<G extends boolean> = G extends true ? 'row' | 'agg' : 'row';
323
+ type NumArg<Row> = NumField | ((o: Fields<Row>) => Plain<number, 'row'>);
324
+ type AnyArg<Row> = AnyField | ((o: Fields<Row>) => Plain<any, 'row'>);
325
+ type ScalarOf<E> = Scalar<ValueOf<E> | null>;
326
+ /** Terminal aggregates exist only before `groupBy` (after it they are `never`). */
327
+ type Ungrouped<G extends boolean, F> = G extends true ? never : F;
328
+ type NumericAggregate = 'sum' | 'avg' | 'median' | 'stddev' | 'var' | 'skew' | 'kurt' | 'drawdown' | 'pct' | 'sharpe' | 'calmar' | 'sortino' | 'sum_abs' | 'abs_sum';
329
+ type AnyAggregate = 'min' | 'max' | 'first_value' | 'last_value';
330
+ /**
331
+ * Terminal aggregate methods. They end the pipeline and return a `Scalar`.
332
+ * After `groupBy` they are `never`: use `select`, `map`, `rollup` or `pivot` there.
333
+ */
334
+ type TerminalAggregates<Row = any, G extends boolean = false> = {
335
+ [K in NumericAggregate]: Ungrouped<G, (field: NumArg<Row>) => Scalar<number>>;
336
+ } & {
337
+ [K in AnyAggregate]: Ungrouped<G, <E extends Plain<any, 'row'>>(field: E | string | ((o: Fields<Row>) => E)) => ScalarOf<E>>;
338
+ } & {
339
+ distinct_count: Ungrouped<G, (field: AnyArg<Row>) => Scalar<number>>;
340
+ count: Ungrouped<G, (field?: AnyArg<Row>) => Scalar<number>>;
341
+ percentile: Ungrouped<G, (field: NumArg<Row>, p: number | Plain<number, 'row'>) => Scalar<number>>;
342
+ vwap: Ungrouped<G, (price: NumArg<Row>, volume: NumArg<Row>) => Scalar<number>>;
343
+ wavg: Ungrouped<G, (value: NumArg<Row>, weight: NumArg<Row>) => Scalar<number>>;
344
+ info_ratio: Ungrouped<G, (returns: NumArg<Row>, benchmark: NumArg<Row>) => Scalar<number>>;
345
+ };
346
+ declare abstract class Built {
347
+ protected readonly sourceName: string;
348
+ protected readonly ops: readonly Operation[];
349
+ protected constructor(sourceName: string, ops: readonly Operation[]);
350
+ private compiled?;
351
+ /** The pipeline AST (a fresh object each time; expression nodes are shared). */
352
+ get ast(): Pipeline;
353
+ /** Canonical pipequery text, via `printQuery`. */
354
+ toString(): string;
355
+ /** Compile the AST directly (no print + re-parse). */
356
+ compile(): CompiledQuery;
357
+ protected execute(context: DataContext | readonly unknown[]): unknown;
358
+ }
359
+ /** The result of a terminal operation (`sum`, `count`, `reduce`, ...): one value, no further ops. */
360
+ declare class Scalar<T = unknown> extends Built {
361
+ /** @internal */
362
+ constructor(source: string, ops: readonly Operation[]);
363
+ /** Run against `{ source: rows, ... }` or, for plain arrays, the rows of this query's source. */
364
+ run(context: DataContext | readonly unknown[]): T;
365
+ }
366
+ interface Query<Row = any, G extends boolean = false> extends TerminalAggregates<Row, G> {
367
+ }
368
+ /**
369
+ * Immutable fluent pipeline. Every method returns a new `Query` (or a `Scalar` for
370
+ * terminal operations), validated as it is added.
371
+ */
372
+ declare class Query<Row = any, G extends boolean = false> extends Built {
373
+ /** @internal use `from()` */
374
+ constructor(source: string, ops?: readonly Operation[]);
375
+ private isGrouped;
376
+ /** Validate and append operations. */
377
+ private extend;
378
+ private terminal;
379
+ /** Run against `{ source: rows, ... }` or, for plain arrays, the rows of this query's source. */
380
+ run<T = Cur<Row, G>[]>(context: DataContext | readonly unknown[]): T;
381
+ /** Rows matching the condition. Aggregates and window functions are not allowed here. */
382
+ where(condition: ExprInput<Cur<Row, G>, BoolExpr<'row'>>): Query<Cur<Row, G>, false>;
383
+ /**
384
+ * Pick fields. An object literal gives a typed output row:
385
+ * `select((o) => ({ id: o.id, name: o.customer.name }))`. Aggregates are allowed after
386
+ * `groupBy`, window functions (`win.*`) before it. Other forms give untyped rows.
387
+ */
388
+ select<R extends Record<string, SelectValue<SelectScope<G>>>>(fields: R | ((o: Fields<Row>) => R)): Query<G extends true ? GroupedShape<R> : Shape<R>, false>;
389
+ select(...fields: SelectInput<Row, SelectScope<G>>[]): Query<any, false>;
390
+ /** Sort keys must be row expressions: no aliases, no aggregates. */
391
+ sort(...keys: SortInput<Cur<Row, G>>[]): Query<Cur<Row, G>, false>;
392
+ /**
393
+ * Group rows. Follow with `select`/`map` (aggregates allowed), `rollup` or `pivot`.
394
+ * A bare `groupBy` yields `{ ...keys, _group }` rows and is rarely what you want to run.
395
+ * No keys groups everything into one group.
396
+ */
397
+ groupBy(...keys: ExprListInput<Row, RowExpr>[]): Query<Row, true>;
398
+ /**
399
+ * Join with another source from the run context. The engine merges rows as
400
+ * `{ ...left, ...right }`, so on a name collision the right value wins.
401
+ * `FieldAccess == FieldAccess` conditions (also `{ on: [left, right] }`) use the hash join.
402
+ * In callbacks both arguments are plain row proxies; for non-equi conditions the
403
+ * condition sees the merged row, so qualify nothing and avoid colliding names.
404
+ */
405
+ join<Right = any>(right: string, on: JoinInput<Cur<Row, G>, Right>): Query<Merge<Cur<Row, G>, Right>, false>;
406
+ first(count: number): Query<Cur<Row, G>, false>;
407
+ /**
408
+ * The last `count` rows. Engine quirk, passed through unchanged: `last(0)` returns
409
+ * every row (the engine does `slice(-0)`), unlike `first(0)` which returns none.
410
+ */
411
+ last(count: number): Query<Cur<Row, G>, false>;
412
+ /** Distinct rows, or distinct by the given fields. */
413
+ distinct(...fields: ExprListInput<Cur<Row, G>, RowExpr>[]): Query<Cur<Row, G>, false>;
414
+ /** Flatten nested arrays, or the array held in `field`. */
415
+ flatten(field?: ExprInput<Cur<Row, G>, RowExpr>): Query<any, false>;
416
+ transpose(headerField?: ExprInput<Cur<Row, G>, RowExpr>): Query<any, false>;
417
+ /**
418
+ * Group keys first, then at least one aggregate:
419
+ * `rollup('region', agg.sum(o.total).as('total'))`.
420
+ */
421
+ rollup(...items: ExprListInput<Cur<Row, G>, ExprBase<any, 'row' | 'agg'>>[]): Query<any, false>;
422
+ /** Pivot on `field`, computing the given aggregates for each pivot value. */
423
+ pivot(field: ExprInput<Cur<Row, G>, RowExpr>, ...aggregates: ExprListInput<Cur<Row, G>, ExprBase<any, 'agg'>>[]): Query<any, false>;
424
+ /** Add or overwrite fields, keeping the others (unlike `select`). */
425
+ /**
426
+ * With an object literal the output row is typed: the input row with the new fields on top.
427
+ * After `groupBy` rows are untyped and aggregates are allowed (the query stays grouped).
428
+ */
429
+ map<R extends Record<string, SelectValue<MapScope<G>>>>(fields: R | ((o: Fields<Row>) => R)): Query<Merge<Cur<Row, G>, Shape<R>>, G>;
430
+ map(...fields: SelectInput<Row, MapScope<G>>[]): Query<any, G>;
431
+ /**
432
+ * Fold rows into one value. `initial` cannot reference fields; the accumulator sees the
433
+ * row's fields plus `_acc`: `reduce(0, (o) => o._acc.plus(o.total))`.
434
+ * Strings are raw pipequery fragments; use `lit()` for string literals.
435
+ */
436
+ reduce<T = any>(initial: Operand | ExprInput<Row, RowExpr>, accumulator: ExprInput<Row & {
437
+ _acc: T;
438
+ }, RowExpr>): Scalar<T>;
439
+ /**
440
+ * Escape hatch: splice raw pipequery operations, parsed with the real parser.
441
+ * Accepts `'where(x > 1)'`, `'where(x > 1) | first(3)'` (optional leading `|`), or an AST operation.
442
+ */
443
+ pipe(raw: string | Operation): Query<any, boolean>;
444
+ /** @internal used by the terminal aggregate methods installed below. */
445
+ protected aggregate(name: string, args: unknown[]): Scalar<any>;
446
+ }
447
+ /**
448
+ * Start a query. `from<Order>('orders')` reads from the `orders` source; with no name the
449
+ * query reads from `_data`, the source the engine uses for plain row arrays.
450
+ */
451
+ declare function from<Row = any>(source?: string): Query<Row, false>;
452
+
453
+ /** Error thrown by the builder for invalid input (bad names, arities, misplaced expressions). */
454
+ declare class BuilderError extends Error {
455
+ constructor(message: string);
456
+ }
457
+
458
+ export { type AggregateHelpers, type AliasedExpr, type BoolExpr, BuilderError, Expr, type ExprBase, type ExprFor, type ExprInput, type ExprListInput, type ExprOf, Expression, type FieldInput, type FieldOf, type Fields, type FnHelpers, type GenericExpr, type GroupedShape, type JoinInput, type Merge, type Nullish, type NumExpr, type Operand, Operation, Pipeline, type Plain, Query, Scalar, type Scope, type SelectInput, type SelectValue, type Shape, type SortInput, SortKey, type StrExpr, type TerminalAggregates, type ValueOf, type WindowHelpers, agg, col, fn, from, lit, toAst, win };