UNPKG

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
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; };