UNPKG

ts-sql-query

Version:

Type-safe SQL query builder like QueryDSL or JOOQ in Java or Linq in .Net for TypeScript with MariaDB, MySql, Oracle, PostgreSql, Sqlite and SqlServer support.

272 lines (271 loc) 19 kB
import { double, int, LocalDate, LocalDateTime, LocalTime, stringDouble, stringInt, uuid } from "ts-extended-types"; import { AnyValueSource, BooleanValueSource, IAggregatedArrayValueSource, IAnyBooleanValueSource, IBigintValueSource, IBooleanValueSource, IComparableValueSource, ICustomDoubleValueSource, ICustomIntValueSource, ICustomLocalDateTimeValueSource, ICustomLocalDateValueSource, ICustomLocalTimeValueSource, ICustomUuidValueSource, IDateTimeValueSource, IDateValueSource, IDoubleValueSource, IEqualableValueSource, IIntValueSource, ILocalDateTimeValueSource, ILocalDateValueSource, ILocalTimeValueSource, INullableValueSource, INumberValueSource, IStringDoubleValueSource, IStringIntValueSource, IStringNumberValueSource, IStringValueSource, ITimeValueSource, ITypeSafeBigintValueSource, ITypeSafeStringValueSource, ITypeSafeUuidValueSource, IUuidValueSource, IValueSource, MergeOptionalUnion, ValueSourceOf } from "./values"; export interface Filter { } export interface NullableFilter extends Filter { isNull?: boolean; isNotNull?: boolean; } export interface EqualableFilter<TYPE> extends NullableFilter { equalsIfValue?: TYPE | null | undefined; equals?: TYPE; notEqualsIfValue?: TYPE | null | undefined; notEquals?: TYPE; isIfValue?: TYPE | null | undefined; is?: TYPE | null | undefined; isNotIfValue?: TYPE | null | undefined; isNot?: TYPE | null | undefined; inIfValue?: TYPE[] | null | undefined; in?: TYPE[]; notInIfValue?: TYPE[] | null | undefined; notIn?: TYPE[]; } export interface ComparableFilter<TYPE> extends EqualableFilter<TYPE> { lessThanIfValue?: TYPE | null | undefined; lessThan?: TYPE; greaterThanIfValue?: TYPE | null | undefined; greaterThan?: TYPE; lessOrEqualsIfValue?: TYPE | null | undefined; lessOrEquals?: TYPE; greaterOrEqualsIfValue?: TYPE | null | undefined; greaterOrEquals?: TYPE; /** @deprecated use lessThanIfValue instead */ smallerIfValue?: TYPE | null | undefined; /** @deprecated use lessThan instead */ smaller?: TYPE; /** @deprecated use greaterThanIfValue instead */ largerIfValue?: TYPE | null | undefined; /** @deprecated use greaterThan instead */ larger?: TYPE; /** @deprecated use lessOrEqualsIfValue instead */ smallAsIfValue?: TYPE | null | undefined; /** @deprecated use lessOrEquals instead */ smallAs?: TYPE; /** @deprecated use greaterOrEqualsIfValue instead */ largeAsIfValue?: TYPE | null | undefined; /** @deprecated use greaterOrEquals instead */ largeAs?: TYPE; } export interface BooleanFilter extends EqualableFilter<boolean> { } export interface NumberFilter extends ComparableFilter<number> { } export interface StringNumberFilter extends ComparableFilter<number | string> { } export interface IntFilter extends ComparableFilter<int> { } export interface DoubleFilter extends ComparableFilter<double> { } export interface BigintFilter extends ComparableFilter<bigint> { } export interface StringIntFilter extends ComparableFilter<stringInt> { } export interface StringDoubleFilter extends ComparableFilter<stringDouble> { } export interface CustomIntFilter<TYPE> extends ComparableFilter<TYPE> { } export interface CustomDoubleFilter<TYPE> extends ComparableFilter<TYPE> { } export interface StringFilter extends ComparableFilter<string> { equalsInsensitiveIfValue?: string | null | undefined; equalsInsensitive?: string; notEqualsInsensitiveIfValue?: string | null | undefined; notEqualsInsensitive?: string; likeIfValue?: string | null | undefined; like?: string; notLikeIfValue?: string | null | undefined; notLike?: string; likeInsensitiveIfValue?: string | null | undefined; likeInsensitive?: string; notLikeInsensitiveIfValue?: string | null | undefined; notLikeInsensitive?: string; startsWithIfValue?: string | null | undefined; startsWith?: string; notStartsWithIfValue?: string | null | undefined; notStartsWith?: string; endsWithIfValue?: string | null | undefined; endsWith?: string; notEndsWithIfValue?: string | null | undefined; notEndsWith?: string; startsWithInsensitiveIfValue?: string | null | undefined; startsWithInsensitive?: string; notStartsWithInsensitiveIfValue?: string | null | undefined; notStartsWithInsensitive?: string; endsWithInsensitiveIfValue?: string | null | undefined; endsWithInsensitive?: string; notEndsWithInsensitiveIfValue?: string | null | undefined; notEndsWithInsensitive?: string; containsIfValue?: string | null | undefined; contains?: string; notContainsIfValue?: string | null | undefined; notContains?: string; containsInsensitiveIfValue?: string | null | undefined; containsInsensitive?: string; notContainsInsensitiveIfValue?: string | null | undefined; notContainsInsensitive?: string; } export interface DateFilter extends ComparableFilter<Date> { } export interface TimeFilter extends ComparableFilter<Date> { } export interface DateTimeFilter extends ComparableFilter<Date> { } export interface LocalDateFilter extends ComparableFilter<LocalDate> { } export interface LocalTimeFilter extends ComparableFilter<LocalTime> { } export interface LocalDateTimeFilter extends ComparableFilter<LocalDateTime> { } export interface CustomLocalDateFilter<TYPE> extends ComparableFilter<TYPE> { } export interface CustomLocalTimeFilter<TYPE> extends ComparableFilter<TYPE> { } export interface CustomLocalDateTimeFilter<TYPE> extends ComparableFilter<TYPE> { } export interface UuidFilter extends ComparableFilter<uuid> { equalsInsensitiveIfValue?: string | null | undefined; equalsInsensitive?: string; notEqualsInsensitiveIfValue?: string | null | undefined; likeIfValue?: string | null | undefined; like?: string; notLikeIfValue?: string | null | undefined; notLike?: string; likeInsensitiveIfValue?: string | null | undefined; likeInsensitive?: string; notLikeInsensitiveIfValue?: string | null | undefined; notLikeInsensitive?: string; startsWithIfValue?: string | null | undefined; startsWith?: string; notStartsWithIfValue?: string | null | undefined; notStartsWith?: string; endsWithIfValue?: string | null | undefined; endsWith?: string; notEndsWithIfValue?: string | null | undefined; notEndsWith?: string; startsWithInsensitiveIfValue?: string | null | undefined; startsWithInsensitive?: string; notStartsWithInsensitiveIfValue?: string | null | undefined; notStartsWithInsensitive?: string; endsWithInsensitiveIfValue?: string | null | undefined; endsWithInsensitive?: string; notEndsWithInsensitiveIfValue?: string | null | undefined; notEndsWithInsensitive?: string; containsIfValue?: string | null | undefined; contains?: string; notContainsIfValue?: string | null | undefined; notContains?: string; containsInsensitiveIfValue?: string | null | undefined; containsInsensitive?: string; notContainsInsensitiveIfValue?: string | null | undefined; notContainsInsensitive?: string; } export interface CustomUuidFilter<TYPE> extends ComparableFilter<TYPE> { equalsInsensitiveIfValue?: TYPE | null | undefined; equalsInsensitive?: TYPE; notEqualsInsensitiveIfValue?: TYPE | null | undefined; likeIfValue?: TYPE | null | undefined; like?: TYPE; notLikeIfValue?: TYPE | null | undefined; notLike?: TYPE; likeInsensitiveIfValue?: TYPE | null | undefined; likeInsensitive?: TYPE; notLikeInsensitiveIfValue?: TYPE | null | undefined; notLikeInsensitive?: TYPE; startsWithIfValue?: TYPE | null | undefined; startsWith?: TYPE; notStartsWithIfValue?: TYPE | null | undefined; notStartsWith?: TYPE; endsWithIfValue?: TYPE | null | undefined; endsWith?: TYPE; notEndsWithIfValue?: TYPE | null | undefined; notEndsWith?: TYPE; startsWithInsensitiveIfValue?: TYPE | null | undefined; startsWithInsensitive?: TYPE; notStartsWithInsensitiveIfValue?: TYPE | null | undefined; notStartsWithInsensitive?: TYPE; endsWithInsensitiveIfValue?: TYPE | null | undefined; endsWithInsensitive?: TYPE; notEndsWithInsensitiveIfValue?: TYPE | null | undefined; notEndsWithInsensitive?: TYPE; containsIfValue?: TYPE | null | undefined; contains?: TYPE; notContainsIfValue?: TYPE | null | undefined; notContains?: TYPE; containsInsensitiveIfValue?: TYPE | null | undefined; containsInsensitive?: TYPE; notContainsInsensitiveIfValue?: TYPE | null | undefined; notContainsInsensitive?: TYPE; } export type FilterTypeOf<TYPE> = TYPE extends 'boolean' ? BooleanFilter : TYPE extends 'stringInt' ? StringNumberFilter : TYPE extends 'int' ? NumberFilter : TYPE extends 'bigint' ? BigintFilter : TYPE extends 'stringDouble' ? StringNumberFilter : TYPE extends 'double' ? NumberFilter : TYPE extends 'string' ? StringFilter : TYPE extends 'uuid' ? StringFilter : TYPE extends 'localDate' ? DateFilter : TYPE extends 'localTime' ? TimeFilter : TYPE extends 'localDateTime' ? DateTimeFilter : TYPE extends ['customInt', infer T] ? CustomIntFilter<T> : TYPE extends ['customDouble', infer T] ? CustomDoubleFilter<T> : TYPE extends ['customUuid', infer T] ? CustomUuidFilter<T> : TYPE extends ['customLocalDate', infer T] ? CustomLocalDateFilter<T> : TYPE extends ['customLocalTime', infer T] ? CustomLocalTimeFilter<T> : TYPE extends ['customLocalDateTime', infer T] ? CustomLocalDateTimeFilter<T> : TYPE extends ['enum', infer T] ? EqualableFilter<T> : TYPE extends ['custom', infer T] ? EqualableFilter<T> : TYPE extends ['customComparable', infer T] ? ComparableFilter<T> : MapValueSourceToFilter<TYPE>; /** * @deprecated Use custom types instead and the FilterTypeOf type */ export type TypeSafeFilterTypeOf<TYPE> = TYPE extends 'boolean' ? BooleanFilter : TYPE extends 'stringInt' ? StringIntFilter : TYPE extends 'int' ? IntFilter : TYPE extends 'bigint' ? BigintFilter : TYPE extends 'stringDouble' ? StringDoubleFilter : TYPE extends 'double' ? DoubleFilter : TYPE extends 'string' ? StringFilter : TYPE extends 'uuid' ? UuidFilter : TYPE extends 'localDate' ? LocalDateFilter : TYPE extends 'localTime' ? LocalTimeFilter : TYPE extends 'localDateTime' ? LocalDateTimeFilter : TYPE extends ['customInt', infer T] ? CustomIntFilter<T> : TYPE extends ['customDouble', infer T] ? CustomDoubleFilter<T> : TYPE extends ['customUuid', infer T] ? CustomUuidFilter<T> : TYPE extends ['customLocalDate', infer T] ? CustomLocalDateFilter<T> : TYPE extends ['customLocalTime', infer T] ? CustomLocalTimeFilter<T> : TYPE extends ['customLocalDateTime', infer T] ? CustomLocalDateTimeFilter<T> : TYPE extends ['enum', infer T] ? EqualableFilter<T> : TYPE extends ['custom', infer T] ? EqualableFilter<T> : TYPE extends ['customComparable', infer T] ? ComparableFilter<T> : MapValueSourceToFilter<TYPE>; export type DynamicColumnType<T> = 'boolean' | 'stringInt' | 'int' | 'bigint' | 'stringDouble' | 'double' | 'string' | 'uuid' | 'localDate' | 'localTime' | 'localDateTime' | [ 'customInt', T ] | ['customDouble', T] | ['customUuid', T] | ['customLocalDate', T] | ['customLocalTime', T] | ['customLocalDateTime', T] | [ 'enum', T ] | ['custom', T] | ['customComparable', T]; export type DynamicDefinition = { [key: string]: AnyValueSource | DynamicColumnType<any> | DynamicDefinition; }; export type DynamicCondition<DEFINITION extends DynamicDefinition, EXTENSION extends DinamicConditionExtension = never> = { not?: DynamicCondition<DEFINITION, EXTENSION>; and?: Array<DynamicCondition<DEFINITION, EXTENSION> | undefined>; or?: Array<DynamicCondition<DEFINITION, EXTENSION> | undefined>; } & { [KEY in NonReplacedField<DEFINITION, EXTENSION>]?: KEY extends keyof EXTENSION ? (DEFINITION[KEY] extends DynamicColumnType<any> ? ExtendDefinition<FilterTypeOf<DEFINITION[KEY]>, EXTENSION[KEY]> : DEFINITION[KEY] extends AnyValueSource ? ExtendDefinition<FilterTypeOf<DEFINITION[KEY]>, EXTENSION[KEY]> : DEFINITION[KEY] extends DynamicDefinition ? (EXTENSION[KEY] extends DinamicConditionExtension ? DynamicCondition<DEFINITION[KEY], EXTENSION[KEY]> : DynamicCondition<DEFINITION[KEY], never>) : never) : (DEFINITION[KEY] extends DynamicColumnType<any> ? FilterTypeOf<DEFINITION[KEY]> : DEFINITION[KEY] extends AnyValueSource ? FilterTypeOf<DEFINITION[KEY]> : DEFINITION[KEY] extends DynamicDefinition ? DynamicCondition<DEFINITION[KEY], never> : never); } & { [KEY in DynamicConditionExtensionKeys<EXTENSION>]?: EXTENSION[KEY] extends DynamicConditionRule<infer TYPE> ? TYPE : never; }; export type TypeSafeDynamicCondition<DEFINITION extends DynamicDefinition, EXTENSION extends DinamicConditionExtension = never> = { not?: TypeSafeDynamicCondition<DEFINITION, EXTENSION>; and?: Array<TypeSafeDynamicCondition<DEFINITION, EXTENSION> | undefined>; or?: Array<TypeSafeDynamicCondition<DEFINITION, EXTENSION> | undefined>; } & { [KEY in NonReplacedField<DEFINITION, EXTENSION>]?: KEY extends keyof EXTENSION ? (DEFINITION[KEY] extends DynamicColumnType<any> ? ExtendDefinition<TypeSafeFilterTypeOf<DEFINITION[KEY]>, EXTENSION[KEY]> : DEFINITION[KEY] extends AnyValueSource ? ExtendDefinition<TypeSafeFilterTypeOf<DEFINITION[KEY]>, EXTENSION[KEY]> : DEFINITION[KEY] extends DynamicDefinition ? (EXTENSION[KEY] extends DinamicConditionExtension ? TypeSafeDynamicCondition<DEFINITION[KEY], EXTENSION[KEY]> : TypeSafeDynamicCondition<DEFINITION[KEY], never>) : never) : (DEFINITION[KEY] extends DynamicColumnType<any> ? FilterTypeOf<DEFINITION[KEY]> : DEFINITION[KEY] extends AnyValueSource ? FilterTypeOf<DEFINITION[KEY]> : DEFINITION[KEY] extends DynamicDefinition ? TypeSafeDynamicCondition<DEFINITION[KEY], never> : never); } & { [KEY in DynamicConditionExtensionKeys<EXTENSION>]: EXTENSION[KEY] extends DynamicConditionRule<infer TYPE> ? TYPE : never; }; export type MapValueSourceToFilter<TYPE> = TYPE extends IValueSource<any, infer T, any, any> ? (TYPE extends IBooleanValueSource<any, any> ? BooleanFilter : TYPE extends IStringIntValueSource<any, any> ? StringIntFilter : TYPE extends IIntValueSource<any, any> ? IntFilter : TYPE extends IStringDoubleValueSource<any, any> ? StringDoubleFilter : TYPE extends IDoubleValueSource<any, any> ? DoubleFilter : TYPE extends ITypeSafeBigintValueSource<any, any> ? BigintFilter : TYPE extends IBigintValueSource<any, any> ? BigintFilter : TYPE extends IStringNumberValueSource<any, any> ? StringNumberFilter : TYPE extends INumberValueSource<any, any> ? NumberFilter : TYPE extends ITypeSafeStringValueSource<any, any> ? StringFilter : TYPE extends IStringValueSource<any, any> ? StringFilter : TYPE extends ITypeSafeUuidValueSource<any, any> ? UuidFilter : TYPE extends IUuidValueSource<any, any> ? StringFilter : TYPE extends ILocalDateTimeValueSource<any, any> ? LocalDateTimeFilter : TYPE extends IDateTimeValueSource<any, any> ? DateTimeFilter : TYPE extends ILocalDateValueSource<any, any> ? LocalDateFilter : TYPE extends IDateValueSource<any, any> ? DateFilter : TYPE extends ILocalTimeValueSource<any, any> ? LocalTimeFilter : TYPE extends ITimeValueSource<any, any> ? TimeFilter : TYPE extends ICustomIntValueSource<any, any, any, any> ? CustomIntFilter<T> : TYPE extends ICustomDoubleValueSource<any, any, any, any> ? CustomDoubleFilter<T> : TYPE extends ICustomUuidValueSource<any, any, any, any> ? CustomUuidFilter<T> : TYPE extends ICustomLocalDateValueSource<any, any, any, any> ? CustomLocalDateFilter<T> : TYPE extends ICustomLocalTimeValueSource<any, any, any, any> ? CustomLocalTimeFilter<T> : TYPE extends ICustomLocalDateTimeValueSource<any, any, any, any> ? CustomLocalDateTimeFilter<T> : TYPE extends IComparableValueSource<any, any, any, any> ? ComparableFilter<T> : TYPE extends IEqualableValueSource<any, any, any, any> ? EqualableFilter<T> : TYPE extends INullableValueSource<any, any, any, any> ? NullableFilter : TYPE extends IAggregatedArrayValueSource<any, any, any> ? Filter | Array<Filter> : Filter) : never; export type Filterable = { [key: string]: AnyValueSource | Filterable; }; export type DinamicConditionExtension = { [key: string]: DynamicConditionRule<any> | DinamicConditionExtension; }; export type DynamicConditionRule<T> = (rule: T) => IAnyBooleanValueSource<any, any>; type NonReplacedField<DEFINITION, EXTENSION> = Exclude<keyof DEFINITION, DynamicConditionExtensionKeys<EXTENSION>>; type DynamicConditionExtensionKeys<EXTENSION> = { [K in keyof EXTENSION]: EXTENSION[K] extends DynamicConditionRule<any> ? K : never; }[keyof EXTENSION]; type ExtendDefinition<T, EXTENSION> = Omit<T, DynamicConditionExtensionKeys<EXTENSION>> & { [KEY in DynamicConditionExtensionKeys<EXTENSION>]?: EXTENSION[KEY] extends DynamicConditionRule<infer TYPE> ? TYPE : never; }; export type DynamicFilter<DEFINITION extends Filterable> = { not?: DynamicFilter<DEFINITION>; and?: Array<DynamicFilter<DEFINITION> | undefined>; or?: Array<DynamicFilter<DEFINITION> | undefined>; } & { [KEY in keyof DEFINITION]?: DEFINITION[KEY] extends AnyValueSource ? MapValueSourceToFilter<DEFINITION[KEY]> : DEFINITION[KEY] extends Filterable ? DynamicFilter<DEFINITION[KEY]> : never; }; export interface DynamicConditionExpression<DEFINITION extends Filterable, EXTENSION extends DinamicConditionExtension> { withValues(filter: DynamicFilter<DEFINITION>): BooleanValueSource<TableOfCondition<DEFINITION> | TableOfConditionExtention<EXTENSION>, BooleanOptionalTypeOfCondition<DEFINITION> | BooleanOptionalTypeOfConditionExtension<EXTENSION>>; } export type TableOfValueSource<TYPE> = TYPE extends ValueSourceOf<infer T> ? T : never; export type OptionalTypeOfValueSource<TYPE> = TYPE extends IValueSource<any, any, any, infer T> ? T : never; type BooleanOptionalTypeOfCondition<DEFINITION extends Filterable> = MergeOptionalUnion<({ [KEY in keyof DEFINITION]: DEFINITION[KEY] extends AnyValueSource ? OptionalTypeOfValueSource<DEFINITION[KEY]> : DEFINITION[KEY] extends Filterable ? BooleanOptionalTypeOfCondition<DEFINITION[KEY]> : never; })[keyof DEFINITION]>; type TableOfCondition<DEFINITION extends Filterable> = ({ [KEY in keyof DEFINITION]: DEFINITION[KEY] extends AnyValueSource ? TableOfValueSource<DEFINITION[KEY]> : DEFINITION[KEY] extends Filterable ? TableOfCondition<DEFINITION[KEY]> : never; })[keyof DEFINITION]; type BooleanOptionalTypeOfConditionExtension<EXTENSION extends DinamicConditionExtension> = MergeOptionalUnion<({ [KEY in keyof EXTENSION]: EXTENSION[KEY] extends DynamicConditionRule<infer RULE_RESULT> ? OptionalTypeOfValueSource<RULE_RESULT> : never; })[keyof EXTENSION]>; type TableOfConditionExtention<EXTENSION extends DinamicConditionExtension> = ({ [KEY in keyof EXTENSION]: EXTENSION[KEY] extends DynamicConditionRule<infer RULE_RESULT> ? TableOfValueSource<RULE_RESULT> : never; })[keyof EXTENSION]; export {};