pqb 0.71.1 → 0.71.2
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/dist/index.d.ts +264 -246
- package/dist/index.js +19 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +19 -7
- package/dist/index.mjs.map +1 -1
- package/dist/internal.d.ts +260 -242
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -5361,11 +5361,11 @@ interface DbSqlQuery {
|
|
|
5361
5361
|
*/
|
|
5362
5362
|
getOptional<T>(...args: SQLQueryArgs): Promise<T | undefined>;
|
|
5363
5363
|
}
|
|
5364
|
-
interface RawSqlBase extends Expression {
|
|
5364
|
+
interface RawSqlBase<T extends Column.Pick.QueryColumn = Column.Pick.QueryColumn> extends Expression<T> {
|
|
5365
5365
|
_sql: string | TemplateLiteralArgs;
|
|
5366
5366
|
_values?: RawSQLValues;
|
|
5367
5367
|
}
|
|
5368
|
-
interface RawSql<T extends Column.Pick.QueryColumn, ColumnTypes> extends Expression<T>, RawSqlBase
|
|
5368
|
+
interface RawSql<T extends Column.Pick.QueryColumn, ColumnTypes> extends Expression<T>, RawSqlBase<T>, ExpressionTypeMethod {}
|
|
5369
5369
|
declare class RawSql<T extends Column.Pick.QueryColumn = Column.Pick.QueryColumn, ColumnTypes = DefaultColumnTypes<ColumnSchemaConfig>> extends Expression<T> {
|
|
5370
5370
|
result: {
|
|
5371
5371
|
value: T;
|
|
@@ -5919,6 +5919,250 @@ declare const Operators: {
|
|
|
5919
5919
|
json: OperatorsJson;
|
|
5920
5920
|
array: OperatorsArray<unknown>;
|
|
5921
5921
|
};
|
|
5922
|
+
interface ColumnsShape {
|
|
5923
|
+
[K: string]: Column;
|
|
5924
|
+
}
|
|
5925
|
+
declare namespace ColumnsShape {
|
|
5926
|
+
export type DefaultSelectKeys<S extends Column.QueryColumnsInit> = { [K in keyof S]: S[K]['data']['explicitSelect'] extends true | undefined ? never : K }[keyof S];
|
|
5927
|
+
export type DefaultOutput<Set extends Column.QueryColumnsInit> = { [K in DefaultSelectKeys<Set>]: Set[K]['__outputType'] };
|
|
5928
|
+
export type Input<Shape extends Column.QueryColumnsInit, AppReadOnly = { [K in keyof Shape]: Shape[K]['data']['appReadOnly'] extends true ? K : never }[keyof Shape], Optional extends keyof Shape = { [K in keyof Shape]: Shape[K]['data']['optional'] extends true ? K : never }[keyof Shape]> = { [K in Exclude<keyof Shape, AppReadOnly | Optional>]: Shape[K]['__inputType'] } & { [K in Exclude<Optional, AppReadOnly>]?: Shape[K]['__inputType'] };
|
|
5929
|
+
export type InputPartial<Shape extends Column.QueryColumnsInit> = { [K in keyof Shape]?: Shape[K]['__inputType'] };
|
|
5930
|
+
export type Output<Shape extends Column.QueryColumns> = { [K in keyof Shape]: Shape[K]['__outputType'] };
|
|
5931
|
+
export type DefaultSelectOutput<Shape extends Column.QueryColumnsInit> = { [K in { [K in keyof Shape]: Shape[K]['data']['explicitSelect'] extends true | undefined ? never : K }[keyof Shape]]: Shape[K]['__outputType'] };
|
|
5932
|
+
export interface MapToObjectColumn<Shape extends Column.QueryColumns> {
|
|
5933
|
+
dataType: 'object';
|
|
5934
|
+
__type: { [K in keyof Shape]: Shape[K]['__type'] };
|
|
5935
|
+
__outputType: ShallowSimplify<ObjectOutput<Shape>>;
|
|
5936
|
+
__queryType: { [K in keyof Shape]: Shape[K]['__queryType'] };
|
|
5937
|
+
operators: OperatorsAny;
|
|
5938
|
+
}
|
|
5939
|
+
export interface MapToNullableObjectColumn<Shape extends Column.QueryColumns> {
|
|
5940
|
+
dataType: 'object';
|
|
5941
|
+
__type: { [K in keyof Shape]: Shape[K]['__type'] };
|
|
5942
|
+
__outputType: ShallowSimplify<ObjectOutput<Shape>> | undefined;
|
|
5943
|
+
__queryType: { [K in keyof Shape]: Shape[K]['__queryType'] } | null;
|
|
5944
|
+
operators: OperatorsAny;
|
|
5945
|
+
}
|
|
5946
|
+
export interface MapToPluckColumn<Shape extends Column.QueryColumns> {
|
|
5947
|
+
dataType: 'array';
|
|
5948
|
+
__type: Shape['pluck']['__type'][];
|
|
5949
|
+
__outputType: Shape['pluck']['__outputType'][];
|
|
5950
|
+
__queryType: Shape['pluck']['__queryType'][];
|
|
5951
|
+
operators: OperatorsAny;
|
|
5952
|
+
}
|
|
5953
|
+
export interface MapToObjectArrayColumn<Shape extends Column.QueryColumns> {
|
|
5954
|
+
dataType: 'array';
|
|
5955
|
+
__type: { [K in keyof Shape]: Shape[K]['__type'] }[];
|
|
5956
|
+
__outputType: ShallowSimplify<ObjectOutput<Shape>>[];
|
|
5957
|
+
__queryType: { [K in keyof Shape]: Shape[K]['__queryType'] }[];
|
|
5958
|
+
operators: OperatorsAny;
|
|
5959
|
+
}
|
|
5960
|
+
type ObjectOutput<Shape extends Column.QueryColumns> = { [K in keyof Shape]: Shape[K]['__outputType'] };
|
|
5961
|
+
export {};
|
|
5962
|
+
}
|
|
5963
|
+
interface SelectSelf extends PickQuerySelectable, PickQueryHasSelect, PickQueryDefaultSelect, PickQueryShape, PickQueryRelations, PickQueryResult, PickQueryReturnType, PickQueryWithData {}
|
|
5964
|
+
type SelectArgs<T extends SelectSelf> = ('*' | keyof T['__selectable'])[];
|
|
5965
|
+
interface SubQueryAddition<T extends PickQueryWithData> extends IsSubQuery {
|
|
5966
|
+
withData: T['withData'];
|
|
5967
|
+
}
|
|
5968
|
+
type SelectAsFnArg<T extends PickQueryRelationsWithData> = EmptyObject extends T['relations'] ? T : { [K in keyof T['relations'] | keyof T]: K extends keyof T['relations'] ? RelationQueryMaybeSingle<T['relations'][K]> & SubQueryAddition<T> : K extends keyof T ? T[K] : never };
|
|
5969
|
+
interface SelectAsArg<T extends SelectSelf> {
|
|
5970
|
+
[K: string]: keyof T['__selectable'] | Expression | ((q: SelectAsFnArg<T>) => unknown);
|
|
5971
|
+
}
|
|
5972
|
+
type SelectAsFnReturnType = {
|
|
5973
|
+
result: Column.QueryColumns;
|
|
5974
|
+
returnType: Exclude<QueryReturnType, 'rows'>;
|
|
5975
|
+
} | Expression;
|
|
5976
|
+
interface SelectAsCheckReturnTypes {
|
|
5977
|
+
[K: string]: PropertyKey | Expression | ((q: never) => SelectAsFnReturnType);
|
|
5978
|
+
}
|
|
5979
|
+
type SelectReturnType<T extends PickQueryReturnType> = T['returnType'] extends 'valueOrThrow' ? 'oneOrThrow' : T extends 'value' ? 'one' : T['returnType'] extends 'pluck' ? 'all' : T['returnType'];
|
|
5980
|
+
type SelectResult<T extends SelectSelf, Columns extends PropertyKey[]> = { [K in keyof T]: K extends '__hasSelect' ? true : K extends 'result' ? { [K in '*' extends Columns[number] ? Exclude<Columns[number], '*'> | T['__defaultSelect'] : Columns[number] as T['__selectable'][K]['as']]: T['__selectable'][K]['column'] } & (T['__hasSelect'] extends (T['returnType'] extends 'value' | 'valueOrThrow' ? never : true) ? Omit<T['result'], Columns[number]> : unknown) : K extends 'returnType' ? SelectReturnType<T> : K extends 'then' ? QueryThenByReturnType<SelectReturnType<T>, { [K in '*' extends Columns[number] ? Exclude<Columns[number], '*'> | T['__defaultSelect'] : Columns[number] as T['__selectable'][K]['as']]: T['__selectable'][K]['column'] } & (T['__hasSelect'] extends (T['returnType'] extends 'value' | 'valueOrThrow' ? never : true) ? Omit<T['result'], Columns[number]> : unknown)> : T[K] };
|
|
5981
|
+
type SelectResultObj<T extends SelectSelf, Obj> = Obj extends SelectAsCheckReturnTypes ? { [K in keyof T]: K extends '__hasSelect' ? true : K extends '__selectable' ? T['__selectable'] & SelectAsSelectable<Obj> : K extends 'result' ? { [K in T['__hasSelect'] extends (T['returnType'] extends 'value' | 'valueOrThrow' ? never : true) ? keyof Obj | keyof T['result'] : keyof Obj]: K extends keyof Obj ? SelectAsValueResult<T, Obj[K]> : K extends keyof T['result'] ? T['result'][K] : never } : K extends 'returnType' ? SelectReturnType<T> : K extends 'then' ? QueryThenByReturnType<SelectReturnType<T>, { [K in T['__hasSelect'] extends (T['returnType'] extends 'value' | 'valueOrThrow' ? never : true) ? keyof Obj | keyof T['result'] : keyof Obj]: K extends keyof Obj ? SelectAsValueResult<T, Obj[K]> : K extends keyof T['result'] ? T['result'][K] : never }> : T[K] } : `Invalid return type of ${{ [K in keyof Obj]: Obj[K] extends ((...args: any[]) => any) ? ReturnType<Obj[K]> extends SelectAsFnReturnType ? never : K : never }[keyof Obj] & string}`;
|
|
5982
|
+
type SelectResultColumnsAndObj<T extends SelectSelf, Columns extends PropertyKey[], Obj> = { [K in keyof T]: K extends '__hasSelect' ? true : K extends '__selectable' ? T['__selectable'] & SelectAsSelectable<Obj> : K extends 'result' ? // Combine previously selected items, all columns if * was provided,
|
|
5983
|
+
{ [K in ('*' extends Columns[number] ? Exclude<Columns[number], '*'> | T['__defaultSelect'] : Columns[number]) | keyof Obj as K extends Columns[number] ? T['__selectable'][K]['as'] : K]: K extends keyof Obj ? SelectAsValueResult<T, Obj[K]> : T['__selectable'][K]['column'] } & (T['__hasSelect'] extends (T['returnType'] extends 'value' | 'valueOrThrow' ? never : true) ? Omit<T['result'], Columns[number]> : unknown) : K extends 'returnType' ? SelectReturnType<T> : K extends 'then' ? QueryThenByReturnType<SelectReturnType<T>, { [K in ('*' extends Columns[number] ? Exclude<Columns[number], '*'> | T['__defaultSelect'] : Columns[number]) | keyof Obj as K extends Columns[number] ? T['__selectable'][K]['as'] : K]: K extends keyof Obj ? SelectAsValueResult<T, Obj[K]> : T['__selectable'][K]['column'] } & (T['__hasSelect'] extends (T['returnType'] extends 'value' | 'valueOrThrow' ? never : true) ? Omit<T['result'], Columns[number]> : unknown)> : T[K] };
|
|
5984
|
+
interface AllowedRelationOneQueryForSelectable extends IsSubQuery {
|
|
5985
|
+
result: Column.QueryColumns;
|
|
5986
|
+
returnType: 'value' | 'valueOrThrow' | 'one' | 'oneOrThrow';
|
|
5987
|
+
}
|
|
5988
|
+
type SelectAsSelectable<Obj> = UnionToIntersection<{ [K in keyof Obj]: Obj[K] extends ((q: never) => infer R extends AllowedRelationOneQueryForSelectable) ? { [C in R['returnType'] extends 'value' | 'valueOrThrow' ? K : keyof R['result'] as R['returnType'] extends 'value' | 'valueOrThrow' ? K : `${K & string}.${C & string}`]: {
|
|
5989
|
+
as: C;
|
|
5990
|
+
column: R['returnType'] extends 'value' | 'valueOrThrow' ? R['result']['value'] : R['result'][C & keyof R['result']];
|
|
5991
|
+
} } : never }[keyof Obj]>;
|
|
5992
|
+
type SelectAsValueResult<T extends SelectSelf, Arg> = Arg extends keyof T['__selectable'] ? T['__selectable'][Arg]['column'] : Arg extends Expression ? Arg['result']['value'] : Arg extends ((q: never) => IsQuery) ? SelectSubQueryResult<ReturnType<Arg>> : Arg extends ((q: never) => Expression) ? ReturnType<Arg>['result']['value'] : Arg extends ((q: never) => IsQuery | Expression) ? SelectSubQueryResult<Exclude<ReturnType<Arg>, Expression>> | Exclude<ReturnType<Arg>, IsQuery>['result']['value'] : never;
|
|
5993
|
+
type SelectSubQueryResult<Arg extends SelectSelf> = Arg['returnType'] extends undefined | 'all' ? ColumnsShape.MapToObjectArrayColumn<Arg['result']> : Arg['returnType'] extends 'value' | 'valueOrThrow' ? Arg['result']['value'] : Arg['returnType'] extends 'pluck' ? ColumnsShape.MapToPluckColumn<Arg['result']> : Arg['returnType'] extends 'one' ? ColumnsShape.MapToNullableObjectColumn<Arg['result']> : ColumnsShape.MapToObjectColumn<Arg['result']>;
|
|
5994
|
+
declare function _querySelect<T extends SelectSelf, Columns extends SelectArgs<T>>(q: T, columns: Columns): SelectResult<T, Columns>;
|
|
5995
|
+
declare function _querySelect<T extends SelectSelf, Obj extends SelectAsArg<T>>(q: T, obj: Obj): SelectResultObj<T, Obj>;
|
|
5996
|
+
declare function _querySelect<T extends SelectSelf, Columns extends SelectArgs<T>, Obj extends SelectAsArg<T>>(q: T, args: [...columns: Columns, obj: Obj]): SelectResultColumnsAndObj<T, Columns, Obj>;
|
|
5997
|
+
declare class Select {
|
|
5998
|
+
/**
|
|
5999
|
+
* Takes a list of columns to be selected, and by default, the query builder will select all columns of the table.
|
|
6000
|
+
*
|
|
6001
|
+
* The last argument can be an object. Keys of the object are column aliases, value can be a column name, sub-query, or raw SQL expression.
|
|
6002
|
+
*
|
|
6003
|
+
* ```ts
|
|
6004
|
+
* import { sql } from './baseTable'
|
|
6005
|
+
*
|
|
6006
|
+
* // select columns of the table:
|
|
6007
|
+
* db.table.select('id', 'name', { idAlias: 'id' });
|
|
6008
|
+
*
|
|
6009
|
+
* // accepts columns with table names:
|
|
6010
|
+
* db.table.select('user.id', 'user.name', { nameAlias: 'user.name' });
|
|
6011
|
+
*
|
|
6012
|
+
* // table name may refer to the current table or a joined table:
|
|
6013
|
+
* db.table
|
|
6014
|
+
* .join(db.message, 'authorId', 'user.id')
|
|
6015
|
+
* .select('user.name', 'message.text', { textAlias: 'message.text' });
|
|
6016
|
+
*
|
|
6017
|
+
* // select value from the sub-query,
|
|
6018
|
+
* // this sub-query should return a single record and a single column:
|
|
6019
|
+
* db.table.select({
|
|
6020
|
+
* subQueryResult: Otherdb.table.select('column').take(),
|
|
6021
|
+
* });
|
|
6022
|
+
*
|
|
6023
|
+
* // select raw SQL value, specify the returning type via <generic> syntax:
|
|
6024
|
+
* db.table.select({
|
|
6025
|
+
* raw: sql<number>`1 + 2`,
|
|
6026
|
+
* });
|
|
6027
|
+
*
|
|
6028
|
+
* // select raw SQL value, the resulting type can be set by providing a column type in such way:
|
|
6029
|
+
* db.table.select({
|
|
6030
|
+
* raw: sql`1 + 2`.type((t) => t.integer()),
|
|
6031
|
+
* });
|
|
6032
|
+
*
|
|
6033
|
+
* // same raw SQL query as above, but the sql is returned from a callback
|
|
6034
|
+
* db.table.select({
|
|
6035
|
+
* raw: () => sql`1 + 2`.type((t) => t.integer()),
|
|
6036
|
+
* });
|
|
6037
|
+
* ```
|
|
6038
|
+
*
|
|
6039
|
+
* When you use the ORM and defined relations, `select` can also accept callbacks with related table queries:
|
|
6040
|
+
*
|
|
6041
|
+
* ```ts
|
|
6042
|
+
* await db.author.select({
|
|
6043
|
+
* allBooks: (q) => q.books,
|
|
6044
|
+
* firstBook: (q) => q.books.order({ createdAt: 'ASC' }).take(),
|
|
6045
|
+
* booksCount: (q) => q.books.count(),
|
|
6046
|
+
* });
|
|
6047
|
+
* ```
|
|
6048
|
+
*
|
|
6049
|
+
* When you're selecting a relation that's connected via `belongsTo` or `hasOne`, it becomes available to use in `order` or in `where`:
|
|
6050
|
+
*
|
|
6051
|
+
* ```ts
|
|
6052
|
+
* // select books with their authors included, order by author name and filter by author column:
|
|
6053
|
+
* await db.books
|
|
6054
|
+
* .select({
|
|
6055
|
+
* author: (q) => q.author,
|
|
6056
|
+
* })
|
|
6057
|
+
* .order('author.name')
|
|
6058
|
+
* .where({ 'author.isPopular': true });
|
|
6059
|
+
* ```
|
|
6060
|
+
*/
|
|
6061
|
+
select<T extends SelectSelf, Columns extends SelectArgs<T>>(this: T, ...args: Columns): SelectResult<T, Columns>;
|
|
6062
|
+
select<T extends SelectSelf, Obj extends SelectAsArg<T>>(this: T, obj: Obj): SelectResultObj<T, Obj>;
|
|
6063
|
+
select<T extends SelectSelf, Columns extends SelectArgs<T>, Obj extends SelectAsArg<T>>(this: T, ...args: [...columns: Columns, obj: Obj]): SelectResultColumnsAndObj<T, Columns, Obj>;
|
|
6064
|
+
/**
|
|
6065
|
+
* When querying the table or creating records, all columns are selected by default,
|
|
6066
|
+
* but updating and deleting queries are returning affected row counts by default.
|
|
6067
|
+
*
|
|
6068
|
+
* Use `selectAll` to select all columns. If the `.select` method was applied before it will be discarded.
|
|
6069
|
+
*
|
|
6070
|
+
* ```ts
|
|
6071
|
+
* const selectFull = await db.table
|
|
6072
|
+
* .select('id', 'name') // discarded by `selectAll`
|
|
6073
|
+
* .selectAll();
|
|
6074
|
+
*
|
|
6075
|
+
* const updatedFull = await db.table.selectAll().where(conditions).update(data);
|
|
6076
|
+
*
|
|
6077
|
+
* const deletedFull = await db.table.selectAll().where(conditions).delete();
|
|
6078
|
+
* ```
|
|
6079
|
+
*/
|
|
6080
|
+
selectAll<T extends SelectSelf>(this: T): SelectResult<T, ['*']>;
|
|
6081
|
+
}
|
|
6082
|
+
type SelectItem = string | SelectAs | Expression | undefined;
|
|
6083
|
+
interface SelectAs {
|
|
6084
|
+
selectAs: SelectAsValue;
|
|
6085
|
+
}
|
|
6086
|
+
interface SelectAsValue {
|
|
6087
|
+
[K: string]: string | Query | Expression | undefined;
|
|
6088
|
+
}
|
|
6089
|
+
declare const getShapeFromSelect: (q: IsQuery, isSubQuery?: boolean) => Column.QueryColumns;
|
|
6090
|
+
type QueryDataTransform = QueryDataTransformFn | {
|
|
6091
|
+
map: (record: unknown, index: number, array: unknown) => unknown;
|
|
6092
|
+
thisArg?: unknown;
|
|
6093
|
+
};
|
|
6094
|
+
interface QueryDataTransformFn {
|
|
6095
|
+
(data: unknown, queryData: unknown): unknown;
|
|
6096
|
+
}
|
|
6097
|
+
/**
|
|
6098
|
+
* See `transform` query method.
|
|
6099
|
+
* This helper applies all transform functions to a result.
|
|
6100
|
+
*
|
|
6101
|
+
* @param queryData - query data
|
|
6102
|
+
* @param returnType - return type of the query, for proper `map` handling
|
|
6103
|
+
* @param fns - array of transform functions, can be undefined
|
|
6104
|
+
* @param result - query result to transform
|
|
6105
|
+
*/
|
|
6106
|
+
declare class QueryTransform {
|
|
6107
|
+
/**
|
|
6108
|
+
* Transform the result of the query right after loading it.
|
|
6109
|
+
*
|
|
6110
|
+
* `transform` method should be called in the last order, other methods can't be chained after calling it.
|
|
6111
|
+
*
|
|
6112
|
+
* It is meant to transform the whole result of a query, for transforming individual records consider using {@link QueryMap.map}.
|
|
6113
|
+
*
|
|
6114
|
+
* The [hooks](/guide/hooks.html) that are going to run after the query will receive the query result **before** transferring.
|
|
6115
|
+
*
|
|
6116
|
+
* Consider the following example of a cursor-based pagination by `id`:
|
|
6117
|
+
*
|
|
6118
|
+
* ```ts
|
|
6119
|
+
* const lastId: number | undefined = req.query.cursor;
|
|
6120
|
+
*
|
|
6121
|
+
* type Result = {
|
|
6122
|
+
* nodes: { id: number; text: string }[];
|
|
6123
|
+
* cursor?: number;
|
|
6124
|
+
* };
|
|
6125
|
+
*
|
|
6126
|
+
* // result is only for demo, it will be inferred
|
|
6127
|
+
* const posts: Result = await db.post
|
|
6128
|
+
* .select('id', 'text')
|
|
6129
|
+
* .where({ id: { lt: lastId } })
|
|
6130
|
+
* .order({ id: 'DESC' })
|
|
6131
|
+
* .limit(100)
|
|
6132
|
+
* .transform((nodes) => ({ nodes, cursor: nodes.at(-1)?.id }));
|
|
6133
|
+
* ```
|
|
6134
|
+
*
|
|
6135
|
+
* You can also use the `tranform` on nested sub-queries:
|
|
6136
|
+
*
|
|
6137
|
+
* ```ts
|
|
6138
|
+
* type Result = {
|
|
6139
|
+
* nodes: {
|
|
6140
|
+
* id: number;
|
|
6141
|
+
* text: string;
|
|
6142
|
+
* comments: { nodes: { id: number; text: string }[]; cursor?: number };
|
|
6143
|
+
* }[];
|
|
6144
|
+
* cursor?: number;
|
|
6145
|
+
* };
|
|
6146
|
+
*
|
|
6147
|
+
* const postsWithComments: Result = await db.post
|
|
6148
|
+
* .select('id', 'text')
|
|
6149
|
+
* .select({
|
|
6150
|
+
* comments: (q) =>
|
|
6151
|
+
* q.comments
|
|
6152
|
+
* .select('id', 'text')
|
|
6153
|
+
* .transform((nodes) => ({ nodes, cursor: nodes.at(-1)?.id })),
|
|
6154
|
+
* })
|
|
6155
|
+
* .transform((nodes) => ({ nodes, cursor: nodes.at(-1)?.id }));
|
|
6156
|
+
* ```
|
|
6157
|
+
*
|
|
6158
|
+
* @param fn - function to transform query result with
|
|
6159
|
+
*/
|
|
6160
|
+
transform<T extends IsQuery, Result>(this: T, fn: (input: T extends {
|
|
6161
|
+
then: QueryThen<infer Data>;
|
|
6162
|
+
} ? Data : never, queryData: QueryData) => Result): { [K in keyof T]: K extends 'returnType' ? 'valueOrThrow' : K extends 'result' ? {
|
|
6163
|
+
value: Column.Pick.QueryColumnOfType<Result>;
|
|
6164
|
+
} : K extends 'then' ? QueryThen<Result> : T[K] };
|
|
6165
|
+
}
|
|
5922
6166
|
type SelectableOrExpression<T extends PickQuerySelectable = PickQuerySelectable, C extends Column.Pick.QueryColumn = Column.Pick.QueryColumn> = '*' | keyof T['__selectable'] | Expression<C>;
|
|
5923
6167
|
type SelectableOrExpressions<T extends PickQuerySelectable = PickQuerySelectable, C extends Column.Pick.QueryColumn = Column.Pick.QueryColumn> = ('*' | keyof T['__selectable'] | Expression<C>)[];
|
|
5924
6168
|
type ExpressionOutput<T extends PickQuerySelectable, Expr extends SelectableOrExpression<T>> = Expr extends keyof T['__selectable'] ? T['__selectable'][Expr]['column'] : Expr extends Expression ? Expr['result']['value'] : never;
|
|
@@ -5929,6 +6173,7 @@ interface ExpressionData extends HasBeforeAndBeforeSet {
|
|
|
5929
6173
|
before?: QueryBeforeHook[];
|
|
5930
6174
|
dynamicBefore?: boolean;
|
|
5931
6175
|
getColumn?: Column;
|
|
6176
|
+
transform?: QueryDataTransform[];
|
|
5932
6177
|
}
|
|
5933
6178
|
declare abstract class Expression<T extends Column.Pick.QueryColumn = Column.Pick.QueryColumn> {
|
|
5934
6179
|
abstract result: {
|
|
@@ -5939,6 +6184,23 @@ declare abstract class Expression<T extends Column.Pick.QueryColumn = Column.Pic
|
|
|
5939
6184
|
kind: 'select';
|
|
5940
6185
|
};
|
|
5941
6186
|
toSQL(ctx: ToSqlValues, quotedAs?: string): string;
|
|
6187
|
+
/**
|
|
6188
|
+
* Transform the expression value after loading it.
|
|
6189
|
+
*
|
|
6190
|
+
* It is meant to transform expressions selected by a query.
|
|
6191
|
+
*
|
|
6192
|
+
* @param fn - function to transform expression value with
|
|
6193
|
+
*/
|
|
6194
|
+
transform<Self extends {
|
|
6195
|
+
result: {
|
|
6196
|
+
value: Column.Pick.QueryColumn;
|
|
6197
|
+
};
|
|
6198
|
+
q: ExpressionData;
|
|
6199
|
+
}, Result>(this: Self, fn: (input: Self['result']['value']['__type'], queryData: ExpressionData) => Result): Omit<Self, 'result'> & {
|
|
6200
|
+
result: {
|
|
6201
|
+
value: Column.Pick.QueryColumnOfType<Result>;
|
|
6202
|
+
};
|
|
6203
|
+
};
|
|
5942
6204
|
abstract makeSQL(ctx: ToSqlValues, quotedAs?: string): string;
|
|
5943
6205
|
}
|
|
5944
6206
|
declare const isExpression: (arg: unknown) => arg is Expression;
|
|
@@ -6291,174 +6553,6 @@ declare class QueryTransaction {
|
|
|
6291
6553
|
*/
|
|
6292
6554
|
recoverable<T>(this: T): T;
|
|
6293
6555
|
}
|
|
6294
|
-
interface ColumnsShape {
|
|
6295
|
-
[K: string]: Column;
|
|
6296
|
-
}
|
|
6297
|
-
declare namespace ColumnsShape {
|
|
6298
|
-
export type DefaultSelectKeys<S extends Column.QueryColumnsInit> = { [K in keyof S]: S[K]['data']['explicitSelect'] extends true | undefined ? never : K }[keyof S];
|
|
6299
|
-
export type DefaultOutput<Set extends Column.QueryColumnsInit> = { [K in DefaultSelectKeys<Set>]: Set[K]['__outputType'] };
|
|
6300
|
-
export type Input<Shape extends Column.QueryColumnsInit, AppReadOnly = { [K in keyof Shape]: Shape[K]['data']['appReadOnly'] extends true ? K : never }[keyof Shape], Optional extends keyof Shape = { [K in keyof Shape]: Shape[K]['data']['optional'] extends true ? K : never }[keyof Shape]> = { [K in Exclude<keyof Shape, AppReadOnly | Optional>]: Shape[K]['__inputType'] } & { [K in Exclude<Optional, AppReadOnly>]?: Shape[K]['__inputType'] };
|
|
6301
|
-
export type InputPartial<Shape extends Column.QueryColumnsInit> = { [K in keyof Shape]?: Shape[K]['__inputType'] };
|
|
6302
|
-
export type Output<Shape extends Column.QueryColumns> = { [K in keyof Shape]: Shape[K]['__outputType'] };
|
|
6303
|
-
export type DefaultSelectOutput<Shape extends Column.QueryColumnsInit> = { [K in { [K in keyof Shape]: Shape[K]['data']['explicitSelect'] extends true | undefined ? never : K }[keyof Shape]]: Shape[K]['__outputType'] };
|
|
6304
|
-
export interface MapToObjectColumn<Shape extends Column.QueryColumns> {
|
|
6305
|
-
dataType: 'object';
|
|
6306
|
-
__type: { [K in keyof Shape]: Shape[K]['__type'] };
|
|
6307
|
-
__outputType: ShallowSimplify<ObjectOutput<Shape>>;
|
|
6308
|
-
__queryType: { [K in keyof Shape]: Shape[K]['__queryType'] };
|
|
6309
|
-
operators: OperatorsAny;
|
|
6310
|
-
}
|
|
6311
|
-
export interface MapToNullableObjectColumn<Shape extends Column.QueryColumns> {
|
|
6312
|
-
dataType: 'object';
|
|
6313
|
-
__type: { [K in keyof Shape]: Shape[K]['__type'] };
|
|
6314
|
-
__outputType: ShallowSimplify<ObjectOutput<Shape>> | undefined;
|
|
6315
|
-
__queryType: { [K in keyof Shape]: Shape[K]['__queryType'] } | null;
|
|
6316
|
-
operators: OperatorsAny;
|
|
6317
|
-
}
|
|
6318
|
-
export interface MapToPluckColumn<Shape extends Column.QueryColumns> {
|
|
6319
|
-
dataType: 'array';
|
|
6320
|
-
__type: Shape['pluck']['__type'][];
|
|
6321
|
-
__outputType: Shape['pluck']['__outputType'][];
|
|
6322
|
-
__queryType: Shape['pluck']['__queryType'][];
|
|
6323
|
-
operators: OperatorsAny;
|
|
6324
|
-
}
|
|
6325
|
-
export interface MapToObjectArrayColumn<Shape extends Column.QueryColumns> {
|
|
6326
|
-
dataType: 'array';
|
|
6327
|
-
__type: { [K in keyof Shape]: Shape[K]['__type'] }[];
|
|
6328
|
-
__outputType: ShallowSimplify<ObjectOutput<Shape>>[];
|
|
6329
|
-
__queryType: { [K in keyof Shape]: Shape[K]['__queryType'] }[];
|
|
6330
|
-
operators: OperatorsAny;
|
|
6331
|
-
}
|
|
6332
|
-
type ObjectOutput<Shape extends Column.QueryColumns> = { [K in keyof Shape]: Shape[K]['__outputType'] };
|
|
6333
|
-
export {};
|
|
6334
|
-
}
|
|
6335
|
-
interface SelectSelf extends PickQuerySelectable, PickQueryHasSelect, PickQueryDefaultSelect, PickQueryShape, PickQueryRelations, PickQueryResult, PickQueryReturnType, PickQueryWithData {}
|
|
6336
|
-
type SelectArgs<T extends SelectSelf> = ('*' | keyof T['__selectable'])[];
|
|
6337
|
-
interface SubQueryAddition<T extends PickQueryWithData> extends IsSubQuery {
|
|
6338
|
-
withData: T['withData'];
|
|
6339
|
-
}
|
|
6340
|
-
type SelectAsFnArg<T extends PickQueryRelationsWithData> = EmptyObject extends T['relations'] ? T : { [K in keyof T['relations'] | keyof T]: K extends keyof T['relations'] ? RelationQueryMaybeSingle<T['relations'][K]> & SubQueryAddition<T> : K extends keyof T ? T[K] : never };
|
|
6341
|
-
interface SelectAsArg<T extends SelectSelf> {
|
|
6342
|
-
[K: string]: keyof T['__selectable'] | Expression | ((q: SelectAsFnArg<T>) => unknown);
|
|
6343
|
-
}
|
|
6344
|
-
type SelectAsFnReturnType = {
|
|
6345
|
-
result: Column.QueryColumns;
|
|
6346
|
-
returnType: Exclude<QueryReturnType, 'rows'>;
|
|
6347
|
-
} | Expression;
|
|
6348
|
-
interface SelectAsCheckReturnTypes {
|
|
6349
|
-
[K: string]: PropertyKey | Expression | ((q: never) => SelectAsFnReturnType);
|
|
6350
|
-
}
|
|
6351
|
-
type SelectReturnType<T extends PickQueryReturnType> = T['returnType'] extends 'valueOrThrow' ? 'oneOrThrow' : T extends 'value' ? 'one' : T['returnType'] extends 'pluck' ? 'all' : T['returnType'];
|
|
6352
|
-
type SelectResult<T extends SelectSelf, Columns extends PropertyKey[]> = { [K in keyof T]: K extends '__hasSelect' ? true : K extends 'result' ? { [K in '*' extends Columns[number] ? Exclude<Columns[number], '*'> | T['__defaultSelect'] : Columns[number] as T['__selectable'][K]['as']]: T['__selectable'][K]['column'] } & (T['__hasSelect'] extends (T['returnType'] extends 'value' | 'valueOrThrow' ? never : true) ? Omit<T['result'], Columns[number]> : unknown) : K extends 'returnType' ? SelectReturnType<T> : K extends 'then' ? QueryThenByReturnType<SelectReturnType<T>, { [K in '*' extends Columns[number] ? Exclude<Columns[number], '*'> | T['__defaultSelect'] : Columns[number] as T['__selectable'][K]['as']]: T['__selectable'][K]['column'] } & (T['__hasSelect'] extends (T['returnType'] extends 'value' | 'valueOrThrow' ? never : true) ? Omit<T['result'], Columns[number]> : unknown)> : T[K] };
|
|
6353
|
-
type SelectResultObj<T extends SelectSelf, Obj> = Obj extends SelectAsCheckReturnTypes ? { [K in keyof T]: K extends '__hasSelect' ? true : K extends '__selectable' ? T['__selectable'] & SelectAsSelectable<Obj> : K extends 'result' ? { [K in T['__hasSelect'] extends (T['returnType'] extends 'value' | 'valueOrThrow' ? never : true) ? keyof Obj | keyof T['result'] : keyof Obj]: K extends keyof Obj ? SelectAsValueResult<T, Obj[K]> : K extends keyof T['result'] ? T['result'][K] : never } : K extends 'returnType' ? SelectReturnType<T> : K extends 'then' ? QueryThenByReturnType<SelectReturnType<T>, { [K in T['__hasSelect'] extends (T['returnType'] extends 'value' | 'valueOrThrow' ? never : true) ? keyof Obj | keyof T['result'] : keyof Obj]: K extends keyof Obj ? SelectAsValueResult<T, Obj[K]> : K extends keyof T['result'] ? T['result'][K] : never }> : T[K] } : `Invalid return type of ${{ [K in keyof Obj]: Obj[K] extends ((...args: any[]) => any) ? ReturnType<Obj[K]> extends SelectAsFnReturnType ? never : K : never }[keyof Obj] & string}`;
|
|
6354
|
-
type SelectResultColumnsAndObj<T extends SelectSelf, Columns extends PropertyKey[], Obj> = { [K in keyof T]: K extends '__hasSelect' ? true : K extends '__selectable' ? T['__selectable'] & SelectAsSelectable<Obj> : K extends 'result' ? // Combine previously selected items, all columns if * was provided,
|
|
6355
|
-
{ [K in ('*' extends Columns[number] ? Exclude<Columns[number], '*'> | T['__defaultSelect'] : Columns[number]) | keyof Obj as K extends Columns[number] ? T['__selectable'][K]['as'] : K]: K extends keyof Obj ? SelectAsValueResult<T, Obj[K]> : T['__selectable'][K]['column'] } & (T['__hasSelect'] extends (T['returnType'] extends 'value' | 'valueOrThrow' ? never : true) ? Omit<T['result'], Columns[number]> : unknown) : K extends 'returnType' ? SelectReturnType<T> : K extends 'then' ? QueryThenByReturnType<SelectReturnType<T>, { [K in ('*' extends Columns[number] ? Exclude<Columns[number], '*'> | T['__defaultSelect'] : Columns[number]) | keyof Obj as K extends Columns[number] ? T['__selectable'][K]['as'] : K]: K extends keyof Obj ? SelectAsValueResult<T, Obj[K]> : T['__selectable'][K]['column'] } & (T['__hasSelect'] extends (T['returnType'] extends 'value' | 'valueOrThrow' ? never : true) ? Omit<T['result'], Columns[number]> : unknown)> : T[K] };
|
|
6356
|
-
interface AllowedRelationOneQueryForSelectable extends IsSubQuery {
|
|
6357
|
-
result: Column.QueryColumns;
|
|
6358
|
-
returnType: 'value' | 'valueOrThrow' | 'one' | 'oneOrThrow';
|
|
6359
|
-
}
|
|
6360
|
-
type SelectAsSelectable<Obj> = UnionToIntersection<{ [K in keyof Obj]: Obj[K] extends ((q: never) => infer R extends AllowedRelationOneQueryForSelectable) ? { [C in R['returnType'] extends 'value' | 'valueOrThrow' ? K : keyof R['result'] as R['returnType'] extends 'value' | 'valueOrThrow' ? K : `${K & string}.${C & string}`]: {
|
|
6361
|
-
as: C;
|
|
6362
|
-
column: R['returnType'] extends 'value' | 'valueOrThrow' ? R['result']['value'] : R['result'][C & keyof R['result']];
|
|
6363
|
-
} } : never }[keyof Obj]>;
|
|
6364
|
-
type SelectAsValueResult<T extends SelectSelf, Arg> = Arg extends keyof T['__selectable'] ? T['__selectable'][Arg]['column'] : Arg extends Expression ? Arg['result']['value'] : Arg extends ((q: never) => IsQuery) ? SelectSubQueryResult<ReturnType<Arg>> : Arg extends ((q: never) => Expression) ? ReturnType<Arg>['result']['value'] : Arg extends ((q: never) => IsQuery | Expression) ? SelectSubQueryResult<Exclude<ReturnType<Arg>, Expression>> | Exclude<ReturnType<Arg>, IsQuery>['result']['value'] : never;
|
|
6365
|
-
type SelectSubQueryResult<Arg extends SelectSelf> = Arg['returnType'] extends undefined | 'all' ? ColumnsShape.MapToObjectArrayColumn<Arg['result']> : Arg['returnType'] extends 'value' | 'valueOrThrow' ? Arg['result']['value'] : Arg['returnType'] extends 'pluck' ? ColumnsShape.MapToPluckColumn<Arg['result']> : Arg['returnType'] extends 'one' ? ColumnsShape.MapToNullableObjectColumn<Arg['result']> : ColumnsShape.MapToObjectColumn<Arg['result']>;
|
|
6366
|
-
declare function _querySelect<T extends SelectSelf, Columns extends SelectArgs<T>>(q: T, columns: Columns): SelectResult<T, Columns>;
|
|
6367
|
-
declare function _querySelect<T extends SelectSelf, Obj extends SelectAsArg<T>>(q: T, obj: Obj): SelectResultObj<T, Obj>;
|
|
6368
|
-
declare function _querySelect<T extends SelectSelf, Columns extends SelectArgs<T>, Obj extends SelectAsArg<T>>(q: T, args: [...columns: Columns, obj: Obj]): SelectResultColumnsAndObj<T, Columns, Obj>;
|
|
6369
|
-
declare class Select {
|
|
6370
|
-
/**
|
|
6371
|
-
* Takes a list of columns to be selected, and by default, the query builder will select all columns of the table.
|
|
6372
|
-
*
|
|
6373
|
-
* The last argument can be an object. Keys of the object are column aliases, value can be a column name, sub-query, or raw SQL expression.
|
|
6374
|
-
*
|
|
6375
|
-
* ```ts
|
|
6376
|
-
* import { sql } from './baseTable'
|
|
6377
|
-
*
|
|
6378
|
-
* // select columns of the table:
|
|
6379
|
-
* db.table.select('id', 'name', { idAlias: 'id' });
|
|
6380
|
-
*
|
|
6381
|
-
* // accepts columns with table names:
|
|
6382
|
-
* db.table.select('user.id', 'user.name', { nameAlias: 'user.name' });
|
|
6383
|
-
*
|
|
6384
|
-
* // table name may refer to the current table or a joined table:
|
|
6385
|
-
* db.table
|
|
6386
|
-
* .join(db.message, 'authorId', 'user.id')
|
|
6387
|
-
* .select('user.name', 'message.text', { textAlias: 'message.text' });
|
|
6388
|
-
*
|
|
6389
|
-
* // select value from the sub-query,
|
|
6390
|
-
* // this sub-query should return a single record and a single column:
|
|
6391
|
-
* db.table.select({
|
|
6392
|
-
* subQueryResult: Otherdb.table.select('column').take(),
|
|
6393
|
-
* });
|
|
6394
|
-
*
|
|
6395
|
-
* // select raw SQL value, specify the returning type via <generic> syntax:
|
|
6396
|
-
* db.table.select({
|
|
6397
|
-
* raw: sql<number>`1 + 2`,
|
|
6398
|
-
* });
|
|
6399
|
-
*
|
|
6400
|
-
* // select raw SQL value, the resulting type can be set by providing a column type in such way:
|
|
6401
|
-
* db.table.select({
|
|
6402
|
-
* raw: sql`1 + 2`.type((t) => t.integer()),
|
|
6403
|
-
* });
|
|
6404
|
-
*
|
|
6405
|
-
* // same raw SQL query as above, but the sql is returned from a callback
|
|
6406
|
-
* db.table.select({
|
|
6407
|
-
* raw: () => sql`1 + 2`.type((t) => t.integer()),
|
|
6408
|
-
* });
|
|
6409
|
-
* ```
|
|
6410
|
-
*
|
|
6411
|
-
* When you use the ORM and defined relations, `select` can also accept callbacks with related table queries:
|
|
6412
|
-
*
|
|
6413
|
-
* ```ts
|
|
6414
|
-
* await db.author.select({
|
|
6415
|
-
* allBooks: (q) => q.books,
|
|
6416
|
-
* firstBook: (q) => q.books.order({ createdAt: 'ASC' }).take(),
|
|
6417
|
-
* booksCount: (q) => q.books.count(),
|
|
6418
|
-
* });
|
|
6419
|
-
* ```
|
|
6420
|
-
*
|
|
6421
|
-
* When you're selecting a relation that's connected via `belongsTo` or `hasOne`, it becomes available to use in `order` or in `where`:
|
|
6422
|
-
*
|
|
6423
|
-
* ```ts
|
|
6424
|
-
* // select books with their authors included, order by author name and filter by author column:
|
|
6425
|
-
* await db.books
|
|
6426
|
-
* .select({
|
|
6427
|
-
* author: (q) => q.author,
|
|
6428
|
-
* })
|
|
6429
|
-
* .order('author.name')
|
|
6430
|
-
* .where({ 'author.isPopular': true });
|
|
6431
|
-
* ```
|
|
6432
|
-
*/
|
|
6433
|
-
select<T extends SelectSelf, Columns extends SelectArgs<T>>(this: T, ...args: Columns): SelectResult<T, Columns>;
|
|
6434
|
-
select<T extends SelectSelf, Obj extends SelectAsArg<T>>(this: T, obj: Obj): SelectResultObj<T, Obj>;
|
|
6435
|
-
select<T extends SelectSelf, Columns extends SelectArgs<T>, Obj extends SelectAsArg<T>>(this: T, ...args: [...columns: Columns, obj: Obj]): SelectResultColumnsAndObj<T, Columns, Obj>;
|
|
6436
|
-
/**
|
|
6437
|
-
* When querying the table or creating records, all columns are selected by default,
|
|
6438
|
-
* but updating and deleting queries are returning affected row counts by default.
|
|
6439
|
-
*
|
|
6440
|
-
* Use `selectAll` to select all columns. If the `.select` method was applied before it will be discarded.
|
|
6441
|
-
*
|
|
6442
|
-
* ```ts
|
|
6443
|
-
* const selectFull = await db.table
|
|
6444
|
-
* .select('id', 'name') // discarded by `selectAll`
|
|
6445
|
-
* .selectAll();
|
|
6446
|
-
*
|
|
6447
|
-
* const updatedFull = await db.table.selectAll().where(conditions).update(data);
|
|
6448
|
-
*
|
|
6449
|
-
* const deletedFull = await db.table.selectAll().where(conditions).delete();
|
|
6450
|
-
* ```
|
|
6451
|
-
*/
|
|
6452
|
-
selectAll<T extends SelectSelf>(this: T): SelectResult<T, ['*']>;
|
|
6453
|
-
}
|
|
6454
|
-
type SelectItem = string | SelectAs | Expression | undefined;
|
|
6455
|
-
interface SelectAs {
|
|
6456
|
-
selectAs: SelectAsValue;
|
|
6457
|
-
}
|
|
6458
|
-
interface SelectAsValue {
|
|
6459
|
-
[K: string]: string | Query | Expression | undefined;
|
|
6460
|
-
}
|
|
6461
|
-
declare const getShapeFromSelect: (q: IsQuery, isSubQuery?: boolean) => Column.QueryColumns;
|
|
6462
6556
|
type AfterHook<Select extends PropertyKey[], Shape extends Column.QueryColumns> = QueryAfterHook<{ [K in Select[number]]: K extends keyof Shape ? Shape[K]['__outputType'] : never }[]>;
|
|
6463
6557
|
type HookSelectArg<T extends PickQueryShape> = (keyof T['shape'] & string)[];
|
|
6464
6558
|
declare const _hookSelectColumns: (query: Query, columns: string[], asFn: (as: string[]) => void) => void;
|
|
@@ -8821,82 +8915,6 @@ interface QueryComputedArg<ColumnTypes, Shape extends Column.QueryColumns> exten
|
|
|
8821
8915
|
column: Column.Pick.QueryColumn;
|
|
8822
8916
|
} };
|
|
8823
8917
|
}
|
|
8824
|
-
type QueryDataTransform = QueryDataTransformFn | {
|
|
8825
|
-
map: (record: unknown, index: number, array: unknown) => unknown;
|
|
8826
|
-
thisArg?: unknown;
|
|
8827
|
-
};
|
|
8828
|
-
interface QueryDataTransformFn {
|
|
8829
|
-
(data: unknown, queryData: unknown): unknown;
|
|
8830
|
-
}
|
|
8831
|
-
/**
|
|
8832
|
-
* See `transform` query method.
|
|
8833
|
-
* This helper applies all transform functions to a result.
|
|
8834
|
-
*
|
|
8835
|
-
* @param queryData - query data
|
|
8836
|
-
* @param returnType - return type of the query, for proper `map` handling
|
|
8837
|
-
* @param fns - array of transform functions, can be undefined
|
|
8838
|
-
* @param result - query result to transform
|
|
8839
|
-
*/
|
|
8840
|
-
declare class QueryTransform {
|
|
8841
|
-
/**
|
|
8842
|
-
* Transform the result of the query right after loading it.
|
|
8843
|
-
*
|
|
8844
|
-
* `transform` method should be called in the last order, other methods can't be chained after calling it.
|
|
8845
|
-
*
|
|
8846
|
-
* It is meant to transform the whole result of a query, for transforming individual records consider using {@link QueryMap.map}.
|
|
8847
|
-
*
|
|
8848
|
-
* The [hooks](/guide/hooks.html) that are going to run after the query will receive the query result **before** transferring.
|
|
8849
|
-
*
|
|
8850
|
-
* Consider the following example of a cursor-based pagination by `id`:
|
|
8851
|
-
*
|
|
8852
|
-
* ```ts
|
|
8853
|
-
* const lastId: number | undefined = req.query.cursor;
|
|
8854
|
-
*
|
|
8855
|
-
* type Result = {
|
|
8856
|
-
* nodes: { id: number; text: string }[];
|
|
8857
|
-
* cursor?: number;
|
|
8858
|
-
* };
|
|
8859
|
-
*
|
|
8860
|
-
* // result is only for demo, it will be inferred
|
|
8861
|
-
* const posts: Result = await db.post
|
|
8862
|
-
* .select('id', 'text')
|
|
8863
|
-
* .where({ id: { lt: lastId } })
|
|
8864
|
-
* .order({ id: 'DESC' })
|
|
8865
|
-
* .limit(100)
|
|
8866
|
-
* .transform((nodes) => ({ nodes, cursor: nodes.at(-1)?.id }));
|
|
8867
|
-
* ```
|
|
8868
|
-
*
|
|
8869
|
-
* You can also use the `tranform` on nested sub-queries:
|
|
8870
|
-
*
|
|
8871
|
-
* ```ts
|
|
8872
|
-
* type Result = {
|
|
8873
|
-
* nodes: {
|
|
8874
|
-
* id: number;
|
|
8875
|
-
* text: string;
|
|
8876
|
-
* comments: { nodes: { id: number; text: string }[]; cursor?: number };
|
|
8877
|
-
* }[];
|
|
8878
|
-
* cursor?: number;
|
|
8879
|
-
* };
|
|
8880
|
-
*
|
|
8881
|
-
* const postsWithComments: Result = await db.post
|
|
8882
|
-
* .select('id', 'text')
|
|
8883
|
-
* .select({
|
|
8884
|
-
* comments: (q) =>
|
|
8885
|
-
* q.comments
|
|
8886
|
-
* .select('id', 'text')
|
|
8887
|
-
* .transform((nodes) => ({ nodes, cursor: nodes.at(-1)?.id })),
|
|
8888
|
-
* })
|
|
8889
|
-
* .transform((nodes) => ({ nodes, cursor: nodes.at(-1)?.id }));
|
|
8890
|
-
* ```
|
|
8891
|
-
*
|
|
8892
|
-
* @param fn - function to transform query result with
|
|
8893
|
-
*/
|
|
8894
|
-
transform<T extends IsQuery, Result>(this: T, fn: (input: T extends {
|
|
8895
|
-
then: QueryThen<infer Data>;
|
|
8896
|
-
} ? Data : never, queryData: QueryData) => Result): { [K in keyof T]: K extends 'returnType' ? 'valueOrThrow' : K extends 'result' ? {
|
|
8897
|
-
value: Column.Pick.QueryColumnOfType<Result>;
|
|
8898
|
-
} : K extends 'then' ? QueryThen<Result> : T[K] };
|
|
8899
|
-
}
|
|
8900
8918
|
type WhereItem = {
|
|
8901
8919
|
[K: string]: unknown | {
|
|
8902
8920
|
[K: string]: unknown | SubQueryForSql | Expression;
|
package/dist/index.js
CHANGED
|
@@ -319,6 +319,17 @@ var Expression = class {
|
|
|
319
319
|
}
|
|
320
320
|
return sql;
|
|
321
321
|
}
|
|
322
|
+
/**
|
|
323
|
+
* Transform the expression value after loading it.
|
|
324
|
+
*
|
|
325
|
+
* It is meant to transform expressions selected by a query.
|
|
326
|
+
*
|
|
327
|
+
* @param fn - function to transform expression value with
|
|
328
|
+
*/
|
|
329
|
+
transform(fn) {
|
|
330
|
+
pushOrNewArrayToObjectImmutable(this.q, "transform", fn);
|
|
331
|
+
return this;
|
|
332
|
+
}
|
|
322
333
|
};
|
|
323
334
|
const isExpression = (arg) => arg instanceof Expression;
|
|
324
335
|
const isTemplateLiteralArgs = (args) => Array.isArray(args[0]) && "raw" in args[0] && Array.isArray(args[0].raw);
|
|
@@ -391,7 +402,7 @@ const templateLiteralToSQL = (template, ctx, quotedAs) => {
|
|
|
391
402
|
for (let last = parts.length - 1; i < last; i++) {
|
|
392
403
|
sql += parts[i];
|
|
393
404
|
const value = template[i + 1];
|
|
394
|
-
if (value
|
|
405
|
+
if (isExpression(value)) sql += value.toSQL(ctx, quotedAs);
|
|
395
406
|
else {
|
|
396
407
|
values.push(value);
|
|
397
408
|
literalValues.push(sql.length);
|
|
@@ -7666,7 +7677,7 @@ const encodeRow = (ctx, values, QueryClass, row, runtimeDefaults, quotedAs, hook
|
|
|
7666
7677
|
};
|
|
7667
7678
|
const encodeValue = (ctx, values, QueryClass, value, quotedAs) => {
|
|
7668
7679
|
if (value && typeof value === "object") {
|
|
7669
|
-
if (value
|
|
7680
|
+
if (isExpression(value)) return value.toSQL(ctx, quotedAs);
|
|
7670
7681
|
else if (value instanceof QueryClass) return `(${moveMutativeQueryToCte(ctx, value)})`;
|
|
7671
7682
|
else if ("fromHook" in value) return value.fromHook;
|
|
7672
7683
|
}
|
|
@@ -7985,7 +7996,7 @@ var FnExpression = class extends Expression {
|
|
|
7985
7996
|
const q = this.q;
|
|
7986
7997
|
sql.push(this.args.map((arg) => {
|
|
7987
7998
|
if (typeof arg === "string") return arg === "*" ? "*" : fnArgToSql(ctx, q, arg, quotedAs);
|
|
7988
|
-
else if (arg
|
|
7999
|
+
else if (isExpression(arg)) return arg.toSQL(ctx, quotedAs);
|
|
7989
8000
|
else if ("pairs" in arg) {
|
|
7990
8001
|
const args = [];
|
|
7991
8002
|
const { pairs } = arg;
|
|
@@ -10989,7 +11000,8 @@ const processSelectAsArg = (q, selectAs, as, key, arg, columnAlias, outerReturnT
|
|
|
10989
11000
|
}
|
|
10990
11001
|
if (isExpression(value)) column = value.result.value;
|
|
10991
11002
|
else {
|
|
10992
|
-
|
|
11003
|
+
const isSelfReferencingQuery = value.q.subQuery === 1;
|
|
11004
|
+
if (isRelationQuery(value) && !isSelfReferencingQuery) {
|
|
10993
11005
|
joinQuery = true;
|
|
10994
11006
|
setSelectRelation(query.q);
|
|
10995
11007
|
value = value.joinQuery(value, q);
|
|
@@ -11010,17 +11022,17 @@ const processSelectAsArg = (q, selectAs, as, key, arg, columnAlias, outerReturnT
|
|
|
11010
11022
|
if (as) value.q.joinedForSelect = _copyQueryAliasToQuery(value, q, as);
|
|
11011
11023
|
}
|
|
11012
11024
|
if (value.q.getColumn?.data.skipValueToArray) value.q.notFoundDefault ??= null;
|
|
11013
|
-
else if (!value.q.type && (value.q.returnType === "value" || value.q.returnType === "valueOrThrow")) {
|
|
11025
|
+
else if (!value.q.type && (value.q.returnType === "value" || value.q.returnType === "valueOrThrow") && !isSelfReferencingQuery) {
|
|
11014
11026
|
const column = Object.create(value.q.getColumn || UnknownColumn.instance);
|
|
11015
11027
|
column.data = {
|
|
11016
11028
|
...column.data,
|
|
11017
|
-
name: void 0,
|
|
11018
11029
|
valueToArray: true
|
|
11019
11030
|
};
|
|
11031
|
+
if (joinQuery) column.data.name = void 0;
|
|
11020
11032
|
value.q.getColumn = column;
|
|
11021
11033
|
if (value.q.expr) value.q.expr.q.getColumn = column;
|
|
11022
11034
|
}
|
|
11023
|
-
if (outerReturnType === "value" && value.q.returnType === "valueOrThrow") value.q.returnType = "value";
|
|
11035
|
+
if ((outerReturnType === "value" || isSelfReferencingQuery) && value.q.returnType === "valueOrThrow") value.q.returnType = "value";
|
|
11024
11036
|
column = value.q.getColumn;
|
|
11025
11037
|
value = prepareSubQueryForSql(q, value);
|
|
11026
11038
|
}
|