nukak
Version:
flexible and efficient ORM, with declarative JSON syntax and smart type-safety
416 lines (415 loc) • 11 kB
TypeScript
import type { FieldKey, IdValue, Key, RelationKey } from './entity.js';
import type { BooleanLike, ExpandScalar, Scalar, Type, Unpacked } from './utility.js';
export type QueryOptions = {
/**
* use or omit `softDelete` attribute.
*/
readonly softDelete?: boolean;
/**
* prefix the query with this.
*/
readonly prefix?: string;
/**
* automatically infer the prefix for the query.
*/
readonly autoPrefix?: boolean;
};
export type QuerySelectOptions = {
/**
* prefix the query with this.
*/
readonly prefix?: string;
/**
* automatically add the prefix for the alias.
*/
readonly autoPrefixAlias?: boolean;
};
/**
* query selection as an array.
*/
export type QuerySelectArray<E> = readonly (Key<E> | QueryRaw)[];
/**
* query selection as a map.
*/
export type QuerySelectMap<E> = QuerySelectFieldMap<E> | QuerySelectRelationMap<E>;
/**
* query selection.
*/
export type QuerySelect<E> = QuerySelectArray<E> | QuerySelectMap<E>;
/**
* query selection of fields as a map.
*/
export type QuerySelectFieldMap<E> = {
readonly [K in FieldKey<E>]?: BooleanLike;
};
/**
* query conflict paths map.
*/
export type QueryConflictPathsMap<E> = {
readonly [K in FieldKey<E>]?: true;
};
/**
* query conflict paths.
*/
export type QueryConflictPaths<E> = QueryConflictPathsMap<E>;
/**
* query selection of relations as a map.
*/
export type QuerySelectRelationMap<E> = {
readonly [K in RelationKey<E>]?: BooleanLike | readonly Key<Unpacked<E[K]>>[] | QuerySelectRelationOptions<E[K]>;
};
/**
* options to select a relation.
*/
export type QuerySelectRelationOptions<E> = (E extends unknown[] ? Query<Unpacked<E>> : QueryUnique<Unpacked<E>>) & {
readonly $required?: boolean;
};
/**
* options for full-text-search operator.
*/
export type QueryTextSearchOptions<E> = {
/**
* text to search for.
*/
readonly $value: string;
/**
* list of fields to search on.
*/
readonly $fields?: readonly FieldKey<E>[];
};
/**
* comparison by fields.
*/
export type QueryWhereFieldMap<E> = {
readonly [K in FieldKey<E>]?: QueryWhereFieldValue<E[K]>;
};
/**
* complex operators.
*/
export type QueryWhereMap<E> = QueryWhereFieldMap<E> & QueryWhereRootOperator<E>;
export type QueryWhereRootOperator<E> = {
/**
* joins query clauses with a logical `AND`, returns records that match all the clauses.
*/
readonly $and?: QueryWhereArray<E>;
/**
* joins query clauses with a logical `OR`, returns records that match any of the clauses.
*/
readonly $or?: QueryWhereArray<E>;
/**
* joins query clauses with a logical `AND`, returns records that do not match all the clauses.
*/
readonly $not?: QueryWhereArray<E>;
/**
* joins query clauses with a logical `OR`, returns records that do not match any of the clauses.
*/
readonly $nor?: QueryWhereArray<E>;
/**
* whether the specified fields match against a full-text search of the given string.
*/
readonly $text?: QueryTextSearchOptions<E>;
/**
* whether the record exists in the given sub-query.
*/
readonly $exists?: QueryRaw;
/**
* whether the record does not exists in the given sub-query.
*/
readonly $nexists?: QueryRaw;
};
export type QueryWhereFieldOperatorMap<T> = {
/**
* whether a value is equal to the given value.
*/
readonly $eq?: ExpandScalar<T>;
/**
* whether a value is not equal to the given value.
*/
readonly $ne?: ExpandScalar<T>;
/**
* negates the given comparison.
*/
readonly $not?: QueryWhereFieldValue<T>;
/**
* whether a value is less than the given value.
*/
readonly $lt?: ExpandScalar<T>;
/**
* whether a value is less than or equal to the given value.
*/
readonly $lte?: ExpandScalar<T>;
/**
* whether a value is greater than the given value.
*/
readonly $gt?: ExpandScalar<T>;
/**
* whether a value is greater than or equal to the given value.
*/
readonly $gte?: ExpandScalar<T>;
/**
* whether a string begins with the given string (case sensitive).
*/
readonly $startsWith?: string;
/**
* whether a string begins with the given string (case insensitive).
*/
readonly $istartsWith?: string;
/**
* whether a string ends with the given string (case sensitive).
*/
readonly $endsWith?: string;
/**
* whether a string ends with the given string (case insensitive).
*/
readonly $iendsWith?: string;
/**
* whether a string is contained within the given string (case sensitive).
*/
readonly $includes?: string;
/**
* whether a string is contained within the given string (case insensitive).
*/
readonly $iincludes?: string;
/**
* whether a string fulfills the given pattern (case sensitive).
*/
readonly $like?: string;
/**
* whether a string fulfills the given pattern (case insensitive).
*/
readonly $ilike?: string;
/**
* whether a string matches the given regular expression.
*/
readonly $regex?: string;
/**
* whether a value matches any of the given values.
*/
readonly $in?: readonly ExpandScalar<T>[];
/**
* whether a value does not match any of the given values.
*/
readonly $nin?: readonly ExpandScalar<T>[];
};
/**
* Value for a field comparison.
*/
export type QueryWhereFieldValue<T> = T | readonly T[] | QueryWhereFieldOperatorMap<T> | QueryRaw;
/**
* query single filter.
*/
export type QueryWhereSingle<E> = IdValue<E> | readonly IdValue<E>[] | QueryWhereMap<E> | QueryRaw;
/**
* query filter array.
*/
export type QueryWhereArray<E> = readonly QueryWhereSingle<E>[];
/**
* query filter.
*/
export type QueryWhere<E> = QueryWhereSingle<E> | QueryWhereArray<E>;
/**
* direction for the sort.
*/
export type QuerySortDirection = -1 | 1 | 'asc' | 'desc';
/**
* sort by tuples
*/
export type QuerySortTuples<E> = readonly [FieldKey<E>, QuerySortDirection][];
/**
* sort by objects.
*/
export type QuerySortObjects<E> = readonly {
readonly field: FieldKey<E>;
readonly sort: QuerySortDirection;
}[];
/**
* sort by fields.
*/
export type QuerySortFieldMap<E> = {
readonly [K in FieldKey<E>]?: QuerySortDirection;
};
/**
* sort by relations fields.
*/
export type QuerySortRelationMap<E> = {
readonly [K in RelationKey<E>]?: QuerySortMap<Unpacked<E[K]>>;
};
/**
* sort by map.
*/
export type QuerySortMap<E> = QuerySortFieldMap<E> | QuerySortRelationMap<E>;
/**
* sort options.
*/
export type QuerySort<E> = QuerySortMap<E> | QuerySortTuples<E> | QuerySortObjects<E>;
/**
* pager options.
*/
export type QueryPager = {
/**
* Index from where start the search
*/
$skip?: number;
/**
* Max number of records to retrieve
*/
$limit?: number;
};
/**
* search options.
*/
export type QuerySearch<E> = {
/**
* filtering options.
*/
$where?: QueryWhere<E>;
/**
* sorting options.
*/
$sort?: QuerySort<E>;
} & QueryPager;
/**
* criteria one options.
*/
export type QuerySearchOne<E> = Omit<QuerySearch<E>, '$limit'>;
/**
* query options.
*/
export type Query<E> = {
/**
* selection options.
*/
$select?: QuerySelect<E>;
} & QuerySearch<E>;
/**
* options to get a single record.
*/
export type QueryOne<E> = Omit<Query<E>, '$limit'>;
/**
* options to get an unique record.
*/
export type QueryUnique<E> = Pick<QueryOne<E>, '$select' | '$where'>;
/**
* stringified query.
*/
export type QueryStringified = {
readonly [K in keyof Query<unknown>]?: string;
};
/**
* result of an update operation.
*/
export type QueryUpdateResult = {
/**
* number of affected records.
*/
readonly changes?: number;
/**
* the inserted IDs.
*/
readonly ids?: readonly number[] | readonly string[];
/**
* first inserted ID.
*/
readonly firstId?: number | string;
};
/**
* options for the `raw` function.
*/
export type QueryRawFnOptions = {
/**
* the current dialect.
*/
readonly dialect?: QueryDialect;
/**
* the prefix.
*/
readonly prefix?: string;
/**
* the escaped prefix.
*/
readonly escapedPrefix?: string;
};
/**
* a `raw` function
*/
export type QueryRawFn = (opts?: QueryRawFnOptions) => string;
export declare class QueryRaw {
readonly value: Scalar | QueryRawFn;
readonly alias?: string;
constructor(value: Scalar | QueryRawFn, alias?: string);
}
/**
* comparison options.
*/
export type QueryComparisonOptions = QueryOptions & {
/**
* use precedence for the comparison or not.
*/
readonly usePrecedence?: boolean;
};
/**
* query filter options.
*/
export type QueryWhereOptions = QueryComparisonOptions & {
/**
* clause to be used in the filter.
*/
readonly clause?: 'WHERE' | false;
};
export interface QueryDialect {
/**
* obtains the records matching the given search parameters.
* @param entity the target entity
* @param q the criteria options
* @param opts the query options
*/
find<E>(entity: Type<E>, q: Query<E>, opts?: QueryOptions): string;
/**
* counts the number of records matching the given search parameters.
* @param entity the target entity
* @param q the criteria options
* @param opts the query options
*/
count<E>(entity: Type<E>, q: QuerySearch<E>, opts?: QueryOptions): string;
/**
* insert records.
* @param entity the target entity
* @param qm the criteria options
* @param opts the query options
*/
insert<E>(entity: Type<E>, payload: E | readonly E[], opts?: QueryOptions): string;
/**
* update records.
* @param entity the target entity
* @param q the criteria options
* @param payload
* @param opts the query options
*/
update<E>(entity: Type<E>, q: QuerySearch<E>, payload: E, opts?: QueryOptions): string;
/**
* upsert records.
* @param entity the target entity
* @param conflictPaths the conflict paths
* @param payload
*/
upsert<E>(entity: Type<E>, conflictPaths: QueryConflictPaths<E>, payload: E): string;
/**
* delete records.
* @param entity the target entity
* @param q the criteria options
* @param opts the query options
*/
delete<E>(entity: Type<E>, q: QuerySearch<E>, opts?: QueryOptions): string;
/**
* escape an identifier.
* @param val the value to be escaped
* @param forbidQualified don't escape dots
* @param addDot use a dot as suffix
*/
escapeId(val: string, forbidQualified?: boolean, addDot?: boolean): string;
/**
* escape a value.
* @param val the value to escape
*/
escape(val: unknown): string;
}