agnostic-query
Version:
Type-safe fluent builder for portable query schemas. Runtime-agnostic, database-agnostic — the same QuerySchema drives Drizzle, Kysely, db0, or raw SQL.
81 lines (80 loc) • 7.91 kB
TypeScript
import type { ArrayKeyOf, FieldPathByShape, GetPathType, SchemaShape } from './schema.js';
export type { ArrayKeyOf };
export declare const unaryComparisonOps: readonly ['=', '>', '>=', '<', '<=', 'like', 'ilike'];
export type UnaryComparisonOp = (typeof unaryComparisonOps)[number];
export declare const multiComparisonOps: readonly ['in'];
export declare const setComparisonOps: readonly ['@>', '<@', '&&'];
export type SetComparisonOp = (typeof setComparisonOps)[number];
export type WhereComparisonOp = UnaryComparisonOp | 'is null' | 'in' | SetComparisonOp;
export declare const predicateOps: readonly ['is null'];
export type PredicateOp = (typeof predicateOps)[number];
export declare const multiLogicalWhereOps: readonly ['and', 'or'];
export type MultiLogicalWhereOp = (typeof multiLogicalWhereOps)[number];
export declare const unaryLogicalWhereOp = "not";
export type UnaryLogicalWhereOp = typeof unaryLogicalWhereOp;
export type WhereOp = UnaryComparisonOp | SetComparisonOp | 'in' | PredicateOp | MultiLogicalWhereOp | UnaryLogicalWhereOp;
export type UnaryComparisonWhere<TShape extends SchemaShape = SchemaShape, TField extends FieldPathByShape<TShape> = FieldPathByShape<TShape>> = {
field: TField;
op: UnaryComparisonOp;
value: GetPathType<TShape, TField>;
};
export type SetComparisonWhere<TShape extends SchemaShape = SchemaShape, TField extends FieldPathByShape<TShape> = FieldPathByShape<TShape>> = {
field: TField;
op: SetComparisonOp;
value: GetPathType<TShape, TField>;
};
export type ToMultiComparisonWhere<TShape extends SchemaShape = SchemaShape, TField extends FieldPathByShape<TShape> = FieldPathByShape<TShape>> = {
field: TField;
op: 'in';
values: GetPathType<TShape, TField>[];
};
export type PredicateWhere<TShape extends SchemaShape = SchemaShape, TField extends FieldPathByShape<TShape> = FieldPathByShape<TShape>> = {
field: TField;
op: PredicateOp;
};
export type ComparisonWhere<TShape extends SchemaShape = SchemaShape, TField extends FieldPathByShape<TShape> = FieldPathByShape<TShape>> = PredicateWhere<TShape, TField> | UnaryComparisonWhere<TShape, TField> | SetComparisonWhere<TShape, TField> | ToMultiComparisonWhere<TShape, TField>;
export type ComparisonWhereValue<TShape extends SchemaShape, Col extends (keyof TShape & string) | FieldPathByShape<TShape>, Op extends WhereComparisonOp> = Op extends 'in' ? Col extends keyof TShape & string ? TShape[Col] extends readonly any[] ? 'in is not allowed on array fields' : TShape[Col][] : Col extends FieldPathByShape<TShape> ? GetPathType<TShape, Col> extends readonly any[] ? 'in is not allowed on array fields' : GetPathType<TShape, Col>[] : never : Op extends SetComparisonOp ? Col extends keyof TShape & string ? TShape[Col] extends readonly any[] ? TShape[Col] : 'set ops require array fields' : Col extends FieldPathByShape<TShape> ? GetPathType<TShape, Col> extends readonly any[] ? GetPathType<TShape, Col> : 'set ops require array fields' : never : Op extends PredicateOp ? never : Col extends keyof TShape & string ? TShape[Col] : Col extends FieldPathByShape<TShape> ? GetPathType<TShape, Col> : never;
export declare const newComparisonWhere: <TShape extends SchemaShape>() => <Col extends FieldPathByShape<TShape> | (keyof TShape & string), Op extends WhereComparisonOp>(col: Col, op: Op, value: ComparisonWhereValue<TShape, Col, Op>) => ComparisonWhere<TShape, FieldPathByShape<TShape>>;
export declare const buildInputWhere: <TShape extends SchemaShape>(col: string | readonly any[], op: string, value: unknown) => ComparisonWhere<TShape>;
export declare const mergeWhere: <TShape extends SchemaShape>(existing: QueryWhere<TShape> | null | undefined, next: ComparisonWhere<TShape>) => QueryWhere<TShape>;
/**
* 类型守卫:将 `QueryWhere` 收窄为 `ComparisonWhere`。
*
* TS 无法通过 `op === 'and' || op === 'or'` 的否定方向消除
* `MultiLogicalWhere`(其 discriminant `op` 是 `'and' | 'or'` 联合类型),
* 导致 `field` / `value` / `values` 在后继代码中不可被类型访问。
* 此守卫通过显式排除逻辑运算符来绕过该限制。
*/
export declare const isComparisonWhere: <TShape extends SchemaShape>(where: QueryWhere<TShape>) => where is ComparisonWhere<TShape>;
export type UnaryLogicalWhere<TShape extends SchemaShape = SchemaShape, TField extends FieldPathByShape<TShape> = FieldPathByShape<TShape>> = {
op: 'not';
condition: QueryWhere<TShape, TField>;
};
export type MultiLogicalWhere<TShape extends SchemaShape = SchemaShape, TField extends FieldPathByShape<TShape> = FieldPathByShape<TShape>> = {
op: MultiLogicalWhereOp;
conditions: QueryWhere<TShape, TField>[];
};
export type QueryWhere<TShape extends SchemaShape = SchemaShape, TField extends FieldPathByShape<TShape> = FieldPathByShape<TShape>> = UnaryComparisonWhere<TShape, TField> | SetComparisonWhere<TShape, TField> | ToMultiComparisonWhere<TShape, TField> | PredicateWhere<TShape, TField> | MultiLogicalWhere<TShape, TField> | UnaryLogicalWhere<TShape, TField>;
export interface WhereExpr<TShape extends SchemaShape> {
_q: QueryWhere<TShape> | null;
where<Col extends FieldPathByShape<TShape> | (keyof TShape & string), Op extends WhereComparisonOp>(col: Col, op: Op, value: ComparisonWhereValue<TShape, Col, Op>): WhereExpr<TShape>;
where<Col extends FieldPathByShape<TShape> | (keyof TShape & string), Op extends PredicateOp>(col: Col, op: Op): WhereExpr<TShape>;
where(where?: QueryWhere<TShape> | null): WhereExpr<TShape>;
and(conditions: WhereExpr<TShape>[]): WhereExpr<TShape>;
or(conditions: WhereExpr<TShape>[]): WhereExpr<TShape>;
not(condition: WhereExpr<TShape>): WhereExpr<TShape>;
}
export declare const createExpr: <TShape extends SchemaShape>(q?: QueryWhere<TShape> | null) => WhereExpr<TShape>;
interface NewWhere<TShape extends SchemaShape = SchemaShape> {
toJSON(): QueryWhere<TShape> | null | undefined;
where(cb: (eb: WhereExpr<TShape>) => WhereExpr<TShape>): NewWhere<TShape>;
where<Col extends FieldPathByShape<TShape> | (keyof TShape & string), Op extends WhereComparisonOp>(col: Col, op: Op, value: ComparisonWhereValue<TShape, Col, Op>): NewWhere<TShape>;
where<Col extends FieldPathByShape<TShape> | (keyof TShape & string), Op extends PredicateOp>(col: Col, op: Op): NewWhere<TShape>;
where(where?: QueryWhere<TShape> | null): NewWhere<TShape>;
}
export declare const newWhere: <TShape extends SchemaShape>(state?: QueryWhere<TShape> | null | undefined) => NewWhere<TShape>;
export declare const findWhere: <TShape extends SchemaShape>(where?: QueryWhere<TShape> | null) => {
eq: <TField extends FieldPathByShape<TShape>>(field: TField) => UnaryComparisonWhere<TShape, (TField extends FieldPathByShape<TShape> ? TField : [TField] & FieldPathByShape<TShape>) & FieldPathByShape<TShape>> | undefined;
in: <TField extends FieldPathByShape<TShape>>(field: TField) => ToMultiComparisonWhere<TShape, (TField extends FieldPathByShape<TShape> ? TField : [TField] & FieldPathByShape<TShape>) & FieldPathByShape<TShape>> | undefined;
find: <TField extends FieldPathByShape<TShape> | (keyof TShape & string), Op extends WhereComparisonOp>(field: TField, op?: Op) => (Op extends "in" ? ToMultiComparisonWhere<TShape, (TField extends FieldPathByShape<TShape> ? TField : [TField] & FieldPathByShape<TShape>) & FieldPathByShape<TShape>> : Op extends "&&" | "<@" | "@>" ? SetComparisonWhere<TShape, (TField extends FieldPathByShape<TShape> ? TField : [TField] & FieldPathByShape<TShape>) & FieldPathByShape<TShape>> : Op extends "is null" ? PredicateWhere<TShape, (TField extends FieldPathByShape<TShape> ? TField : [TField] & FieldPathByShape<TShape>) & FieldPathByShape<TShape>> : UnaryComparisonWhere<TShape, (TField extends FieldPathByShape<TShape> ? TField : [TField] & FieldPathByShape<TShape>) & FieldPathByShape<TShape>>) | undefined;
};