slonik-trpc
Version:
Slonik tRPC loader
438 lines (437 loc) • 29.1 kB
TypeScript
import { CommonQueryMethods, QuerySqlToken, SqlFragment, FragmentSqlToken } from "slonik";
import { z } from 'zod';
import { FilterOptions, Interpretors, RecursiveFilterConditions } from "./queryFilter";
import type { Plugin } from "./plugins/types";
import { PromiseOrValue } from "../helpers/types";
import { BuildView } from "./buildView";
declare const orderDirection: z.ZodEnum<["ASC", "DESC"]>;
declare type OrderDirection = z.infer<typeof orderDirection>;
declare type SortField = string | [string, string] | [string, string, string] | FragmentSqlToken | {
field: FragmentSqlToken;
nullsLast?: boolean;
nullable?: boolean;
};
declare type OptionalArray<T> = readonly T[] | T;
declare type GetNonEmptyKeys<TFilter extends Record<string, z.ZodTypeAny> = never, TSortable extends string = never> = ([TFilter] extends [never] ? "take" : [keyof TFilter] extends [never] ? "take" : "where") | ([TSortable] extends [never] ? "take" : ("orderBy" | "searchAfter" | "takeCursors" | "cursor" | "distinctOn")) | "take" | "skip" | "select" | "ctx" | "selectGroups";
export declare type LoadParameters<TFilter, TContext, TObject extends Record<string, any>, TSelect extends keyof TObject, TSortable extends string = never, TGroupSelectable extends string = never, TTakeCursors extends boolean = false, TDisabledFilters extends "AND" | "OR" | "NOT" = never> = {
/** The fields that should be included. If `select` and `selectGroups` are unspecified, all fields are returned. */
select?: readonly TSelect[];
/** The amount of rows to query.
* If take is a negative value, it will try to reverse the sort order and paginate backwards.
* So
* ```ts
* take: -25,
* orderBy: ["createdAt", "ASC"]
* ```
* Will be converted to
* ```
* take: 25,
* orderBy: ["createdAt", "DESC"]
* ```
* automatically, and you'll get the last page's items.
* Doesn't do anything if you don't specify orderBy though.
* */
take?: number;
/** The amount of items to skip, usually (currentPage - 1) * take.
* Used for offset-based pagination
* */
skip?: number;
/**
* Cursor-based pagination requires you to sort by a sequential, unique column such as an ID or a timestamp.
* You can use this or `cursor` to pass the current item sortable values, after which you'd like to load.
* E.g.
* ```ts
* searchAfter: {
* id: lastPageItemId
* }
* orderBy: [["id", "ASC"]]
* ```
* Or with multiple column sorting
* ```ts
* searchAfter: {
* createdAt: lastItemTimestamp,
* id: lastItemId,
* },
* orderBy: [["createdAt", "DESC"], ["id", "ASC"]]
* ```
* searchAfter parameters will take precedence over `cursor`, if both are specified.
* However this should be avoided, only use searchAfter if you'd like finer control over cursor-based pagination,
* as it's generally harder to use than cursor.
* */
searchAfter?: {
[x in TSortable]?: string | number | boolean | null;
};
/**
* If you specify the cursor string, it will act like an opaque searchAfter for searching after items.
* Use in conjunction with takeCursors: true if you want an opaque implementation of cursor-based pagination.
* Very useful especially if you have complex sorting requirements that don't match the returned fields.
* Get the cursor from startCursor or endCursor from the loadPagination result, then use a positive or negative take.
* */
cursor?: string;
/**
* If specified true, a startCursor and endCursor is returned with loadPagination.
* */
takeCursors?: TTakeCursors;
/** The `columnGroups` you want to select.
* If `selectGroups` and `select` are unspecified, all columns will be selected.
* If specified, will select the columns in that group.
* E.g. if columnGroups are declared like this
* ```ts
* columnGroups: {
* basic: ["id", "name", "email"],
* }
* ```
* You can specify
* ```ts
* selectGroups: ["basic"]
* ```
* To select all 3 columns
* */
selectGroups?: readonly TGroupSelectable[];
/**
* Specify the sorting order using sortable column aliases
* The columns need to be allowed through the `sortableColumns` option
* E.g.
* ```ts
* [["createdAt", "DESC"], ["id", "ASC"]]
* ```
* Or
* ```ts
* ["id", "ASC"]
* ```
* */
orderBy?: OptionalArray<readonly [TSortable, 'ASC' | 'DESC' | 'ASC NULLS LAST' | 'DESC NULLS LAST']> | null;
/** The DISTINCT ON part of the query.
* If not null, it will automatically reorder the orderBy fragments, to put distinct fields in front of orderBy.
* If the fields aren't specified in orderBy, they will be added in front, with ascending order.
*
* Use this with postgres only to select distinct rows based on a column.
* E.g.
* ```ts
* distinctOn: ["id"]
* ```
* Will generate
* ```sql
* SELECT DISTINCT ON ("id") * FROM ...
* ```
*
* If specified `true`, only distinct rows are returned `SELECT DISTINCT`
* */
distinctOn?: OptionalArray<TSortable> | null;
ctx?: TContext;
where?: RecursiveFilterConditions<TFilter, TDisabledFilters>;
};
export declare type ResultType<TObject extends z.AnyZodObject, TVirtuals extends Record<string, any>, TGroupSelected extends keyof (TVirtuals & z.infer<TObject>), TSelect extends keyof (TVirtuals & z.infer<TObject>)> = Pick<TVirtuals & Omit<z.infer<TObject>, keyof TVirtuals>, // Virtual fields can overwrite real fields
[
TSelect
] extends [never] ? [
TGroupSelected
] extends [never] ? keyof (TVirtuals & z.infer<TObject>) : (TGroupSelected) : (TSelect | TGroupSelected)>;
export declare function makeQueryLoader<TContextZod extends z.ZodTypeAny, TFragment extends SqlFragment | QuerySqlToken, TView extends BuildView, TManualFilterTypes extends Record<string, any> = never, TFilterTypes extends Record<string, any> = TView extends BuildView<infer T> ? [
TManualFilterTypes
] extends [never] ? T : T & TManualFilterTypes : TManualFilterTypes, TObject extends z.AnyZodObject = TFragment extends QuerySqlToken<infer T> ? T : any, TVirtuals extends Record<string, any> = z.infer<TObject>, TSortable extends string = never, TGroups extends {
[x: string]: readonly [Exclude<keyof (z.infer<TObject> & TVirtuals), number | symbol>, ...(Exclude<keyof (z.infer<TObject> & TVirtuals), number | symbol>)[]];
} = Record<string, never>, TSelectable extends Exclude<keyof (z.infer<TObject> & TVirtuals), number | symbol> = Exclude<keyof (z.infer<TObject> & TVirtuals), number | symbol>, TContext = z.infer<TContextZod>, TFilterOrEnabled extends boolean = false, TSortableDefault extends TSortable = TSortable>(options: {
query: {
/** The select query (without including FROM) */
select: TFragment;
/** The FROM part of the query. Should start with `FROM` */
from?: SqlFragment;
/** The view from buildView utility. Used to provide filters and the FROM clause. */
view?: TView;
/** The GROUP BY part of the query. Don't include `GROUP BY` */
groupBy?: SqlFragment | ((args: LoadParameters<Partial<TFilterTypes>, TContext, TVirtuals & z.infer<TObject>, (keyof (TVirtuals & z.infer<TObject>)) & TSelectable, TSortable, Exclude<keyof TGroups, number | symbol>, boolean, TFilterOrEnabled extends true ? never : "OR">) => SqlFragment);
};
plugins?: readonly Plugin<any>[];
/** Optional parameter that can be used to override the slonik query parser.
* Doesn't need to be used if you use sql.type when declaring the query parameter.
* */
type?: TObject;
/**
* Optional parameter that can be used to verify the passed context.
* Use this if you want to make sure the context always has a specific shape, e.g. when using it for authorization.
* */
contextParser?: TContextZod;
/**
* Optional function that can be used to create the context.
* Use this if you want to add default values to every context.
* */
contextFactory?: (userContext?: z.infer<TContextZod>) => TContext;
db?: Pick<CommonQueryMethods, "any">;
/**
* DEPRECATED: Use `view` instead.
* You can use the {@link buildView} to build relations with their own filters.
* */
filters?: {
filters: TManualFilterTypes;
interpreters: Interpretors<TManualFilterTypes, TContext>;
options?: FilterOptions<TManualFilterTypes, TContext>;
};
/**
* You can add any hardcoded conditions here, to be used for authorization.
* Any conditions you return will be appended to the overall AND conditions, and cannot be bypassed.
*
* E.g.
*
* ```ts
* constraints(ctx) {
* if (!ctx.userId) return sql.fragment`FALSE`; // Disable querying for unknown users.
*
* return sql.fragment`posts.author=${ctx.userId}`;
* }
* ```
*
* This will let users query only their own posts, if the posts table is in the query.
* */
constraints?: (ctx: TContext) => PromiseOrValue<SqlFragment | SqlFragment[] | null | undefined>;
/**
* Specify aliases for sortable columns. Can either be a single column, or a tuple of table name + column.
* E.g.
* ```ts
* {
* createdDate: ["users", "created_at"],
* name: "fullName",
* }
* ```
* */
sortableColumns?: {
[key in TSortable]: SortField;
};
/**
* This option is convenient for fetching related columns together.
* Column groups that are specified here can be fetched together with the `selectGroups` option when loading.
* E.g.
* ```ts
* columnGroups: {
* basic: ["id", "name", "email"],
* }
* ```
* Then when loading you can simply do
* ```ts
* selectGroups: ["basic"]
* ```
* To select all 3 columns.
* */
columnGroups?: TGroups;
/**
* You can narrow the types that are allowed to be selected with this option.
* */
selectableColumns?: readonly [TSelectable, ...TSelectable[]];
/**
* Specify a mapping of virtual fields, with their dependencies
* */
virtualFields?: {
[x in keyof TVirtuals]?: {
/**
* Use this to load data more efficiently in batches.
* The resolver function has access to the result of this function
* */
load?: (rows: readonly z.infer<TObject>[], args: LoadParameters<TFilterTypes, TContext, z.infer<TObject>, keyof z.infer<TObject> & TSelectable, TSortable, Exclude<keyof TGroups, number | symbol>, boolean, TFilterOrEnabled extends true ? never : 'OR'>) => any;
/** Return the virtual field */
resolve: (row: z.infer<TObject>, args: LoadParameters<TFilterTypes, z.infer<TContextZod>, z.infer<TObject>, (keyof (z.infer<TObject>)) & TSelectable, TSortable, Exclude<keyof TGroups, number | symbol>, boolean, TFilterOrEnabled extends true ? never : "OR"> & {
index: number;
}, remoteLoadResult?: any) => PromiseLike<TVirtuals[x]> | TVirtuals[x];
dependencies: readonly (keyof z.infer<TObject>)[];
};
};
options?: {
/**
* OR filters are disabled by default.
* Specify true to enable them.
* */
orFilterEnabled?: TFilterOrEnabled;
/**
* This allows you to transform the column names of the selected object, before they're used to create the SQL query.
* Useful if you've got a [slonik interceptor for camelCase columns.](https://github.com/gajus/slonik-interceptor-field-name-transformation)
*
* So in case you have a interceptor that converts snake case to camelCase, you have to do the reverse here, like this:
*
* ```
* import { snakeCase } from 'changeCase';
* transformColumns: (field) => snakeCase(field)
* ```
*
* By converting a camelCase back to snake_case you ensure the SQL query will be correct.
* You can also use an object map if you need, or some other method.
* This is mostly to be used as an escape hatch for slonik interceptors that transform rows.
* */
transformColumns?: (column: TSelectable) => string;
/**
* EXPERIMENTAL SUPPORT
*
* If specified true, the engine will try to use SQLite syntax instead of PostgreSQL syntax.
* */
useSqlite?: boolean;
/** The max limit when querying loadPagination. Can be increased from the default 1000 */
maxLimit?: number;
/** Whether you want to run the specified zod parser for the returned rows.
* Used in `loadPagination` and `load`.
*
* NOTE: This can affect performance negatively, depending on the parser you use, and is unnecessary if you're using zod parsing in slonik's interceptor
* @default false
* */
runtimeCheck?: boolean;
/** Used when calculating virtual fields that return promises.
* 50 by default, lower this if you don't want your rows virtual fields to be processed all at once
* */
runConcurrency?: number;
};
defaults?: {
orderBy?: OptionalArray<readonly [TSortableDefault, 'ASC' | 'DESC' | 'ASC NULLS LAST' | 'DESC NULLS LAST']> | null;
take?: number;
};
}): {
_columnGroups: TGroups | undefined;
getSelectableFields: () => [TSelectable, ...TSelectable[]];
getLoadArgs: <TFields extends string = TSelectable, TSort extends TSortable = TSortable, TFiltersDisabled extends {
AND?: boolean | undefined;
OR?: boolean | undefined;
NOT?: boolean | undefined;
} = never>({ sortableColumns, selectableColumns, disabledFilters, transformSortColumns, }?: {
/** You can remove specific sortable columns to disallow sorting by them */
sortableColumns?: [TSort, ...TSort[]] | undefined;
selectableColumns?: readonly [TFields, ...TFields[]] | undefined;
disabledFilters?: TFiltersDisabled | undefined;
/**
* You can enforce sorting constraints with this function.
* E.g. ensure only certain columns are sortable, or with particular directions.
* */
transformSortColumns?: ((columns?: [TSort, "ASC" | "DESC"][] | null | undefined) => [TSort, "ASC" | "DESC"][] | null | undefined) | undefined;
}) => z.ZodObject<{
select: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodEnum<[TFields, ...TFields[]]>, "many">>>;
take: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
skip: z.ZodOptional<z.ZodDefault<z.ZodOptional<z.ZodNumber>>>;
takeCount: z.ZodOptional<z.ZodOptional<z.ZodBoolean>>;
takeCursors: z.ZodOptional<z.ZodOptional<z.ZodBoolean>>;
cursor: z.ZodOptional<z.ZodOptional<z.ZodString>>;
takeNextPages: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
selectGroups: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodEnum<[Exclude<keyof TGroups, number | symbol>, ...Exclude<keyof TGroups, number | symbol>[]]>, "many">>>;
searchAfter: z.ZodOptional<z.ZodOptional<z.ZodObject<{ [k in keyof { [x in TSort]: z.ZodTypeAny; }]: z.ZodOptional<{ [x in TSort]: z.ZodTypeAny; }[k]>; }, "strip", z.ZodTypeAny, { [k_2 in keyof z.objectUtil.addQuestionMarks<{ [k_1 in keyof { [k in keyof { [x in TSort]: z.ZodTypeAny; }]: z.ZodOptional<{ [x in TSort]: z.ZodTypeAny; }[k]>; }]: { [k in keyof { [x in TSort]: z.ZodTypeAny; }]: z.ZodOptional<{ [x in TSort]: z.ZodTypeAny; }[k]>; }[k_1]["_output"]; }>]: z.objectUtil.addQuestionMarks<{ [k_1 in keyof { [k in keyof { [x in TSort]: z.ZodTypeAny; }]: z.ZodOptional<{ [x in TSort]: z.ZodTypeAny; }[k]>; }]: { [k in keyof { [x in TSort]: z.ZodTypeAny; }]: z.ZodOptional<{ [x in TSort]: z.ZodTypeAny; }[k]>; }[k_1]["_output"]; }>[k_2]; }, { [k_4 in keyof z.objectUtil.addQuestionMarks<{ [k_3 in keyof { [k in keyof { [x in TSort]: z.ZodTypeAny; }]: z.ZodOptional<{ [x in TSort]: z.ZodTypeAny; }[k]>; }]: { [k in keyof { [x in TSort]: z.ZodTypeAny; }]: z.ZodOptional<{ [x in TSort]: z.ZodTypeAny; }[k]>; }[k_3]["_input"]; }>]: z.objectUtil.addQuestionMarks<{ [k_3 in keyof { [k in keyof { [x in TSort]: z.ZodTypeAny; }]: z.ZodOptional<{ [x in TSort]: z.ZodTypeAny; }[k]>; }]: { [k in keyof { [x in TSort]: z.ZodTypeAny; }]: z.ZodOptional<{ [x in TSort]: z.ZodTypeAny; }[k]>; }[k_3]["_input"]; }>[k_4]; }>>>;
orderBy: z.ZodOptional<z.ZodNullable<z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodTuple<[z.ZodEnum<[TSort, ...TSort[]]>, z.ZodEnum<["ASC", "DESC"]>], null>, "many">, z.ZodTuple<[z.ZodEnum<[TSort, ...TSort[]]>, z.ZodEnum<["ASC", "DESC"]>], null>]>>>>;
where: z.ZodOptional<z.ZodType<[TFilterTypes] extends [never] ? never : [keyof TFilterTypes] extends [never] ? never : RecursiveFilterConditions<{ [x_1 in keyof TFilterTypes]?: (TFilterTypes[x_1] extends z.ZodTypeAny ? z.TypeOf<TFilterTypes[x_1]> : TFilterTypes[x_1]) | undefined; }, (TFilterOrEnabled extends true ? never : "OR") | Extract<keyof TFiltersDisabled, "AND" | "OR" | "NOT">>, z.ZodTypeDef, [TFilterTypes] extends [never] ? never : [keyof TFilterTypes] extends [never] ? never : RecursiveFilterConditions<{ [x_1 in keyof TFilterTypes]?: (TFilterTypes[x_1] extends z.ZodTypeAny ? z.TypeOf<TFilterTypes[x_1]> : TFilterTypes[x_1]) | undefined; }, (TFilterOrEnabled extends true ? never : "OR") | Extract<keyof TFiltersDisabled, "AND" | "OR" | "NOT">>>>;
}, "strip", z.ZodTypeAny, { [k_5 in keyof z.objectUtil.addQuestionMarks<{
select: TFields[] | undefined;
take: number | undefined;
skip: number | undefined;
takeCount: boolean | undefined;
takeCursors: boolean | undefined;
cursor: string | undefined;
takeNextPages: number | undefined;
selectGroups: Exclude<keyof TGroups, number | symbol>[] | undefined;
searchAfter: { [k_2 in keyof z.objectUtil.addQuestionMarks<{ [k_1 in keyof { [k in keyof { [x in TSort]: z.ZodTypeAny; }]: z.ZodOptional<{ [x in TSort]: z.ZodTypeAny; }[k]>; }]: { [k in keyof { [x in TSort]: z.ZodTypeAny; }]: z.ZodOptional<{ [x in TSort]: z.ZodTypeAny; }[k]>; }[k_1]["_output"]; }>]: z.objectUtil.addQuestionMarks<{ [k_1 in keyof { [k in keyof { [x in TSort]: z.ZodTypeAny; }]: z.ZodOptional<{ [x in TSort]: z.ZodTypeAny; }[k]>; }]: { [k in keyof { [x in TSort]: z.ZodTypeAny; }]: z.ZodOptional<{ [x in TSort]: z.ZodTypeAny; }[k]>; }[k_1]["_output"]; }>[k_2]; } | undefined;
orderBy: [TSort, "ASC" | "DESC"] | [TSort, "ASC" | "DESC"][] | null | undefined;
where: ([TFilterTypes] extends [never] ? never : [keyof TFilterTypes] extends [never] ? never : RecursiveFilterConditions<{ [x_1 in keyof TFilterTypes]?: (TFilterTypes[x_1] extends z.ZodTypeAny ? z.TypeOf<TFilterTypes[x_1]> : TFilterTypes[x_1]) | undefined; }, (TFilterOrEnabled extends true ? never : "OR") | Extract<keyof TFiltersDisabled, "AND" | "OR" | "NOT">>) | undefined;
}>]: z.objectUtil.addQuestionMarks<{
select: TFields[] | undefined;
take: number | undefined;
skip: number | undefined;
takeCount: boolean | undefined;
takeCursors: boolean | undefined;
cursor: string | undefined;
takeNextPages: number | undefined;
selectGroups: Exclude<keyof TGroups, number | symbol>[] | undefined;
searchAfter: { [k_2 in keyof z.objectUtil.addQuestionMarks<{ [k_1 in keyof { [k in keyof { [x in TSort]: z.ZodTypeAny; }]: z.ZodOptional<{ [x in TSort]: z.ZodTypeAny; }[k]>; }]: { [k in keyof { [x in TSort]: z.ZodTypeAny; }]: z.ZodOptional<{ [x in TSort]: z.ZodTypeAny; }[k]>; }[k_1]["_output"]; }>]: z.objectUtil.addQuestionMarks<{ [k_1 in keyof { [k in keyof { [x in TSort]: z.ZodTypeAny; }]: z.ZodOptional<{ [x in TSort]: z.ZodTypeAny; }[k]>; }]: { [k in keyof { [x in TSort]: z.ZodTypeAny; }]: z.ZodOptional<{ [x in TSort]: z.ZodTypeAny; }[k]>; }[k_1]["_output"]; }>[k_2]; } | undefined;
orderBy: [TSort, "ASC" | "DESC"] | [TSort, "ASC" | "DESC"][] | null | undefined;
where: ([TFilterTypes] extends [never] ? never : [keyof TFilterTypes] extends [never] ? never : RecursiveFilterConditions<{ [x_1 in keyof TFilterTypes]?: (TFilterTypes[x_1] extends z.ZodTypeAny ? z.TypeOf<TFilterTypes[x_1]> : TFilterTypes[x_1]) | undefined; }, (TFilterOrEnabled extends true ? never : "OR") | Extract<keyof TFiltersDisabled, "AND" | "OR" | "NOT">>) | undefined;
}>[k_5]; }, { [k_6 in keyof z.objectUtil.addQuestionMarks<{
select: TFields[] | undefined;
take: number | undefined;
skip: number | undefined;
takeCount: boolean | undefined;
takeCursors: boolean | undefined;
cursor: string | undefined;
takeNextPages: number | undefined;
selectGroups: Exclude<keyof TGroups, number | symbol>[] | undefined;
searchAfter: { [k_4 in keyof z.objectUtil.addQuestionMarks<{ [k_3 in keyof { [k in keyof { [x in TSort]: z.ZodTypeAny; }]: z.ZodOptional<{ [x in TSort]: z.ZodTypeAny; }[k]>; }]: { [k in keyof { [x in TSort]: z.ZodTypeAny; }]: z.ZodOptional<{ [x in TSort]: z.ZodTypeAny; }[k]>; }[k_3]["_input"]; }>]: z.objectUtil.addQuestionMarks<{ [k_3 in keyof { [k in keyof { [x in TSort]: z.ZodTypeAny; }]: z.ZodOptional<{ [x in TSort]: z.ZodTypeAny; }[k]>; }]: { [k in keyof { [x in TSort]: z.ZodTypeAny; }]: z.ZodOptional<{ [x in TSort]: z.ZodTypeAny; }[k]>; }[k_3]["_input"]; }>[k_4]; } | undefined;
orderBy: [TSort, "ASC" | "DESC"] | [TSort, "ASC" | "DESC"][] | null | undefined;
where: ([TFilterTypes] extends [never] ? never : [keyof TFilterTypes] extends [never] ? never : RecursiveFilterConditions<{ [x_1 in keyof TFilterTypes]?: (TFilterTypes[x_1] extends z.ZodTypeAny ? z.TypeOf<TFilterTypes[x_1]> : TFilterTypes[x_1]) | undefined; }, (TFilterOrEnabled extends true ? never : "OR") | Extract<keyof TFiltersDisabled, "AND" | "OR" | "NOT">>) | undefined;
}>]: z.objectUtil.addQuestionMarks<{
select: TFields[] | undefined;
take: number | undefined;
skip: number | undefined;
takeCount: boolean | undefined;
takeCursors: boolean | undefined;
cursor: string | undefined;
takeNextPages: number | undefined;
selectGroups: Exclude<keyof TGroups, number | symbol>[] | undefined;
searchAfter: { [k_4 in keyof z.objectUtil.addQuestionMarks<{ [k_3 in keyof { [k in keyof { [x in TSort]: z.ZodTypeAny; }]: z.ZodOptional<{ [x in TSort]: z.ZodTypeAny; }[k]>; }]: { [k in keyof { [x in TSort]: z.ZodTypeAny; }]: z.ZodOptional<{ [x in TSort]: z.ZodTypeAny; }[k]>; }[k_3]["_input"]; }>]: z.objectUtil.addQuestionMarks<{ [k_3 in keyof { [k in keyof { [x in TSort]: z.ZodTypeAny; }]: z.ZodOptional<{ [x in TSort]: z.ZodTypeAny; }[k]>; }]: { [k in keyof { [x in TSort]: z.ZodTypeAny; }]: z.ZodOptional<{ [x in TSort]: z.ZodTypeAny; }[k]>; }[k_3]["_input"]; }>[k_4]; } | undefined;
orderBy: [TSort, "ASC" | "DESC"] | [TSort, "ASC" | "DESC"][] | null | undefined;
where: ([TFilterTypes] extends [never] ? never : [keyof TFilterTypes] extends [never] ? never : RecursiveFilterConditions<{ [x_1 in keyof TFilterTypes]?: (TFilterTypes[x_1] extends z.ZodTypeAny ? z.TypeOf<TFilterTypes[x_1]> : TFilterTypes[x_1]) | undefined; }, (TFilterOrEnabled extends true ? never : "OR") | Extract<keyof TFiltersDisabled, "AND" | "OR" | "NOT">>) | undefined;
}>[k_6]; }>;
getQuery: <TSelect extends keyof z.TypeOf<TObject> | keyof TVirtuals = string, TGroupSelected extends Exclude<keyof TGroups, number | symbol> = never, TTakeCursors extends boolean = false>(allArgs: LoadParameters<{ [x_1 in keyof TFilterTypes]?: (TFilterTypes[x_1] extends z.ZodTypeAny ? z.TypeOf<TFilterTypes[x_1]> : TFilterTypes[x_1]) | undefined; }, z.TypeOf<TContextZod>, TVirtuals & z.TypeOf<TObject>, TSelect & TSelectable, TSortable, TGroupSelected, TTakeCursors, TFilterOrEnabled extends true ? never : "OR">) => Promise<Readonly<{
parser: z.ZodType<ResultType<TObject, TVirtuals, TGroups[TGroupSelected][number], TSelect>, z.ZodTypeDef, ResultType<TObject, TVirtuals, TGroups[TGroupSelected][number], TSelect>>;
type: "SLONIK_TOKEN_QUERY";
sql: string;
values: import("slonik").PrimitiveValueExpression[];
}>>;
load<TSelect_1 extends keyof z.TypeOf<TObject> | keyof TVirtuals = never, TGroupSelected_1 extends Exclude<keyof TGroups, number | symbol> = never>(args: Pick<LoadParameters<{ [x_1 in keyof TFilterTypes]?: (TFilterTypes[x_1] extends z.ZodTypeAny ? z.TypeOf<TFilterTypes[x_1]> : TFilterTypes[x_1]) | undefined; }, z.TypeOf<TContextZod>, TVirtuals & z.TypeOf<TObject>, TSelect_1 & TSelectable, TSortable, TGroupSelected_1, false, TFilterOrEnabled extends true ? never : "OR">, "take" | "skip" | "select" | "ctx" | "selectGroups" | Exclude<[TFilterTypes] extends [never] ? "take" : [keyof TFilterTypes] extends [never] ? "take" : "where", "takeCursors"> | Exclude<[TSortable] extends [never] ? "take" : "takeCursors" | "searchAfter" | "cursor" | "orderBy" | "distinctOn", "takeCursors">>, database?: Pick<CommonQueryMethods, "any"> | undefined): Promise<readonly ResultType<TObject, TVirtuals, TGroups[TGroupSelected_1][number], TSelect_1>[]>;
/**
* Returns the data in a pagination-convenient form.
* Specify takeCount: true to query the overall count as if no limit had been specified.
* Otherwise, count will be null.
* `take` is limited to 1000 items when using loadPagination, as it's meant to be used for loading only a few pages at a time.
* */
loadPagination<TSelect_2 extends keyof z.TypeOf<TObject> | keyof TVirtuals = never, TGroupSelected_2 extends Exclude<keyof TGroups, number | symbol> = never, TTakeCursors_1 extends boolean = false>(args: Pick<LoadParameters<{ [x_1 in keyof TFilterTypes]?: (TFilterTypes[x_1] extends z.ZodTypeAny ? z.TypeOf<TFilterTypes[x_1]> : TFilterTypes[x_1]) | undefined; }, z.TypeOf<TContextZod>, TVirtuals & z.TypeOf<TObject>, TSelect_2 & TSelectable, TSortable, TGroupSelected_2, TTakeCursors_1, TFilterOrEnabled extends true ? never : "OR">, GetNonEmptyKeys<TFilterTypes, TSortable>> & {
/**
* If true, a count query is called to fetch all the rows as if no `take` limit had been specified.
* And the `count` field will return a number.
* Otherwise `count` will be null.
* @default false
* */
takeCount?: boolean | undefined;
/**
* If you specify this parameter, N extra items will be fetched and minimumCount will be returned
* Useful if you want to know whether there are two next pages, simply specify
* ```ts
* take: 25,
* takeNextPages: 2
* ```
* Then minimumCount will be 51, if there are at least 1*25+1 items after the current one.
* @default 1
* @max 4
* */
takeNextPages?: number | undefined;
}, database?: Pick<CommonQueryMethods, "any"> | undefined): Promise<LoadPaginationResult<ResultType<TObject, TVirtuals, TGroups[TGroupSelected_2][number], TSelect_2>>>;
};
export declare type LoadPaginationResult<T> = {
nodes: readonly T[];
cursors?: (string | null)[];
pageInfo: {
hasPreviousPage: boolean;
hasNextPage: boolean;
minimumCount: number;
startCursor?: string;
endCursor?: string;
count: number | null;
};
};
export declare type InferPayload<TLoader extends {
load: (...args: any) => any;
}, TArgs extends TLoader extends {
loadPagination: (...args: readonly [infer A]) => any;
} ? Omit<A, "ctx" | "orderBy" | "searchAfter" | "skip" | "take" | "takeCount" | "takeNextPages" | "where" | "cursor" | "distinctOn" | "takeCursors"> : never = never, TResult extends Record<string, any> = TLoader extends {
load: (...args: any) => PromiseLike<ArrayLike<infer A>>;
} ? A extends Record<string, any> ? Exclude<A, "cursor"> : never : any, TSelect extends Exclude<keyof TResult, number | symbol> = TArgs extends {
select: ArrayLike<infer A>;
} ? A extends Exclude<keyof TResult, number | symbol> ? A : never : never, TGroups extends {
[x: string]: ArrayLike<Exclude<keyof TResult, number | symbol>>;
} = TLoader extends {
_columnGroups: infer A;
} ? A extends {
[x: string]: ArrayLike<Exclude<keyof TResult, number | symbol>>;
} ? A : never : never, TGroupSelected extends keyof TGroups = TArgs extends {
selectGroups: ArrayLike<infer A>;
} ? A extends keyof TGroups ? A : never : never> = Pick<TResult, [
TSelect
] extends [never] ? [
TGroupSelected
] extends [never] ? keyof TResult : (TGroups[TGroupSelected][number]) : (TSelect | TGroups[TGroupSelected][number])>;
declare type Mutable<T> = T & {
-readonly [P in keyof T]: Mutable<T[P]>;
};
export declare type InferArgs<TLoader extends {
load: (...args: any) => any;
}, TArgs = TLoader extends {
loadPagination: (...args: readonly [infer A]) => any;
} ? A : any> = Mutable<Omit<TArgs, "ctx">>;
export {};