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.

103 lines (102 loc) 9.7 kB
import { AnyDB } from "../databases"; import type { AnyValueSource, IValueSource, OptionalType, OptionalTypeRequiredOrAny, RemapIValueSourceTypeWithOptionalType, ValueSourceOf, ValueSourceValueTypeForRequiredInOptionalObject, ValueSourceValueTypeForObjectResult, ValueSourceValueTypeForOptionalObjectResultSameOuterJoin, ValueSourceValueTypeForNullableObjectResult, ValueSourceValueTypeForRequiredInNullableOptionalObject, ValueSourceValueTypeForOptionalNullableObjectResultSameOuterJoin } from "../expressions/values"; import { NoTableOrViewRequired, OUTER_JOIN_SOURCE, ITableOrViewRef } from "./ITableOrView"; import { database } from "./symbols"; export type ResultObjectValues<COLUMNS> = FixOptionalProperties<{ [P in keyof COLUMNS]: COLUMNS[P] extends AnyValueSource | undefined ? ValueSourceValueTypeForObjectResult<NonNullable<COLUMNS[P]>> : InnerResultObjectValues<NonNullable<COLUMNS[P]>>; }>; export type ResultObjectValuesProjectedAsNullable<COLUMNS> = FixOptionalPropertiesProjectedAsNullable<{ [P in keyof COLUMNS]: COLUMNS[P] extends AnyValueSource | undefined ? ValueSourceValueTypeForNullableObjectResult<NonNullable<COLUMNS[P]>> : InnerResultNullableObjectValues<NonNullable<COLUMNS[P]>>; }>; export type RequiredColumnNames<T> = T extends AnyValueSource ? 'result' : 'any' extends T ? never : RequiredInnerColumnNames<T, ''>; type RequiredInnerColumnNames<T, PREFIX extends string> = { [K in keyof T]-?: K extends string ? T[K] extends AnyValueSource | undefined ? ({} extends Pick<T, K> ? never : `${PREFIX}${K}`) : RequiredInnerColumnNames<T[K], `${PREFIX}${K}.`> : never; }[keyof T]; export type RequiredKeysOfPickingColumns<T> = T extends AnyValueSource ? never : { [K in keyof T]-?: {} extends Pick<T, K> ? never : K; }[keyof T]; export type ColumnGuard<T> = T extends null | undefined ? never : [T] extends [never] ? never : T extends AnyValueSource ? never : unknown; export type GuidedObj<T> = T & { [K in keyof T as K extends string | number ? `${K}!` : never]-?: NonNullable<T[K]>; } & { [K in keyof T as K extends string | number ? `${K}?` : never]?: T[K]; }; export type GuidedPropName<T> = T extends `${infer Q}!` ? Q : T extends `${infer Q}?` ? Q : T; export type ValueOf<T> = T[keyof T]; type FixPickableObjectWhereCouldBeNotPicked<RESULT> = undefined extends string ? RESULT : {} extends RESULT ? RESULT | undefined : RESULT; export type FixOptionalProperties<RESULT> = undefined extends string ? RESULT : { [P in keyof OptionalMap<RESULT>]: true extends OptionalMap<RESULT> ? RESULT[P] : NonNullable<RESULT[P]>; }; type OptionalMap<TYPE> = { [P in MandatoryPropertiesOf<TYPE>]-?: true; } & { [P in OptionalPropertiesOf<TYPE>]?: false; }; export type MandatoryPropertiesOf<TYPE> = Exclude<keyof TYPE, OptionalPropertiesOf<TYPE>>; export type OptionalPropertiesOf<TYPE> = ({ [K in keyof TYPE]-?: null | undefined extends TYPE[K] ? K : (null extends TYPE[K] ? K : (undefined extends TYPE[K] ? K : never)); })[keyof TYPE]; type FixPickableObjectWhereCouldBeNotPickedProjectedAsNullable<RESULT> = undefined extends string ? RESULT : {} extends RESULT ? RESULT | undefined | (true extends ContainsNullableProperties<RESULT> ? null : never) : {} extends FixOptionalProperties<RESULT> ? RESULT | null : RESULT; type FixOptionalPropertiesProjectedAsNullable<RESULT> = undefined extends string ? RESULT : { [P in keyof OptionalMapProjectedAsNullable<RESULT>]: RESULT[P]; }; type OptionalMapProjectedAsNullable<TYPE> = { [P in AlwaysRequestedPropertiesOfProjectedAsNullable<TYPE>]-?: true; } & { [P in OmittablePropertiesOfProjectedAsNullable<TYPE>]?: false; }; type AlwaysRequestedPropertiesOfProjectedAsNullable<TYPE> = Exclude<keyof TYPE, OmittablePropertiesOfProjectedAsNullable<TYPE>>; type OmittablePropertiesOfProjectedAsNullable<TYPE> = ({ [K in keyof TYPE]-?: undefined extends TYPE[K] ? K : never; })[keyof TYPE]; export type ColumnsForCompound<TABLE_OR_VIEW extends ITableOrViewRef<AnyDB>, COLUMNS> = COLUMNS extends AnyValueSource ? RemapIValueSourceTypeWithOptionalType<TABLE_OR_VIEW, COLUMNS, CompoundColumnOptionalType<COLUMNS>> : InnerColumnsForCompound<TABLE_OR_VIEW, COLUMNS>; type InnerColumnsForCompound<TABLE_OR_VIEW extends ITableOrViewRef<AnyDB>, COLUMNS> = { [K in keyof COLUMNS]: COLUMNS[K] extends AnyValueSource | undefined ? RemapIValueSourceTypeWithOptionalType<TABLE_OR_VIEW, COLUMNS[K], CompoundColumnOptionalType<COLUMNS[K]>> : InnerColumnsForCompound<TABLE_OR_VIEW, COLUMNS[K]>; }; type CompoundColumnOptionalType<COLUMN> = COLUMN extends IValueSource<any, any, any, infer OPTIONAL_TYPE> ? OptionalTypeRequiredOrAny<OPTIONAL_TYPE> : never; type InnerResultObjectValues<COLUMNS> = FixPickableObjectWhereCouldBeNotPicked<ContainsRequiredInOptionalObject<COLUMNS> extends true ? FixOptionalProperties<{ [P in keyof COLUMNS]: COLUMNS[P] extends AnyValueSource | undefined ? ValueSourceValueTypeForRequiredInOptionalObject<NonNullable<COLUMNS[P]>> : InnerResultObjectValues<NonNullable<COLUMNS[P]>>; }> | undefined : AllFromSameLeftJoinWithOriginallyRequired<COLUMNS> extends true ? FixOptionalProperties<{ [P in keyof COLUMNS]: COLUMNS[P] extends AnyValueSource | undefined ? ValueSourceValueTypeForOptionalObjectResultSameOuterJoin<NonNullable<COLUMNS[P]>> : InnerResultObjectValues<NonNullable<COLUMNS[P]>>; }> | undefined : ContainsRequired<COLUMNS> extends true ? FixOptionalProperties<{ [P in keyof COLUMNS]: COLUMNS[P] extends AnyValueSource | undefined ? ValueSourceValueTypeForObjectResult<NonNullable<COLUMNS[P]>> : InnerResultObjectValues<NonNullable<COLUMNS[P]>>; }> : FixOptionalProperties<{ [P in keyof COLUMNS]: COLUMNS[P] extends AnyValueSource | undefined ? ValueSourceValueTypeForObjectResult<NonNullable<COLUMNS[P]>> : InnerResultObjectValues<NonNullable<COLUMNS[P]>>; }> | undefined>; type InnerResultNullableObjectValues<COLUMNS> = FixPickableObjectWhereCouldBeNotPickedProjectedAsNullable<ContainsRequiredInOptionalObject<COLUMNS> extends true ? FixOptionalPropertiesProjectedAsNullable<{ [P in keyof COLUMNS]: COLUMNS[P] extends AnyValueSource | undefined ? ValueSourceValueTypeForRequiredInNullableOptionalObject<NonNullable<COLUMNS[P]>> : InnerResultNullableObjectValues<NonNullable<COLUMNS[P]>>; }> | null : AllFromSameLeftJoinWithOriginallyRequired<COLUMNS> extends true ? FixOptionalPropertiesProjectedAsNullable<{ [P in keyof COLUMNS]: COLUMNS[P] extends AnyValueSource | undefined ? ValueSourceValueTypeForOptionalNullableObjectResultSameOuterJoin<NonNullable<COLUMNS[P]>> : InnerResultNullableObjectValues<NonNullable<COLUMNS[P]>>; }> | null : ContainsRequired<COLUMNS> extends true ? FixOptionalPropertiesProjectedAsNullable<{ [P in keyof COLUMNS]: COLUMNS[P] extends AnyValueSource | undefined ? ValueSourceValueTypeForNullableObjectResult<NonNullable<COLUMNS[P]>> : InnerResultNullableObjectValues<NonNullable<COLUMNS[P]>>; }> : FixOptionalPropertiesProjectedAsNullable<{ [P in keyof COLUMNS]: COLUMNS[P] extends AnyValueSource | undefined ? ValueSourceValueTypeForNullableObjectResult<NonNullable<COLUMNS[P]>> : InnerResultNullableObjectValues<NonNullable<COLUMNS[P]>>; }> | null>; export type InnerResultObjectValuesForAggregatedArray<COLUMNS> = NonNullable<InnerResultObjectValues<COLUMNS>>; export type InnerResultNullableObjectValuesForAggregatedArray<COLUMNS> = NonNullable<InnerResultNullableObjectValues<COLUMNS>>; type ContainsRequiredInOptionalObject<TYPE> = FalseWhenNever<({ [K in keyof TYPE]-?: TYPE[K] extends IValueSource<any, any, any, infer OPTIONAL_TYPE> | undefined ? IsRequiredInOptionalObject<OPTIONAL_TYPE> : never; })[keyof TYPE]>; type ContainsRequired<TYPE> = FalseWhenNever<({ [K in keyof TYPE]-?: TYPE[K] extends IValueSource<any, any, any, infer OPTIONAL_TYPE> | undefined ? IsRequired<OPTIONAL_TYPE> : InnerObjectIsRequired<TYPE[K]> extends true ? true : never; })[keyof TYPE]>; type InnerObjectIsRequired<TYPE> = ContainsRequiredInOptionalObject<TYPE> extends true ? false : AllFromSameLeftJoinWithOriginallyRequired<TYPE> extends true ? false : ContainsRequired<TYPE>; type AllFromSameLeftJoinWithOriginallyRequired<TYPE> = FalseWhenNever<({ [K in keyof TYPE]-?: TYPE[K] extends IValueSource<infer T, any, any, infer OPTIONAL_TYPE> | undefined ? OUTER_JOIN_SOURCE<any, any> extends T ? (InnerTables<TYPE> | NoTableOrViewRequired<T[typeof database]> extends T | NoTableOrViewRequired<T[typeof database]> ? IsOriginallyRequired<OPTIONAL_TYPE> : false) : T extends NoTableOrViewRequired<T[typeof database]> ? never : false : never; })[keyof TYPE]>; type InnerTables<TYPE> = ({ [K in keyof TYPE]-?: TYPE[K] extends ValueSourceOf<infer T> | undefined ? T : never; })[keyof TYPE]; type IsRequiredInOptionalObject<OPTIONAL_TYPE extends OptionalType> = 'any' extends OPTIONAL_TYPE ? never : 'requiredInOptionalObject' extends OPTIONAL_TYPE ? true : never; type IsOriginallyRequired<OPTIONAL_TYPE extends OptionalType> = 'any' extends OPTIONAL_TYPE ? never : 'originallyRequired' extends OPTIONAL_TYPE ? true : never; type IsRequired<OPTIONAL_TYPE extends OptionalType> = 'any' extends OPTIONAL_TYPE ? never : 'required' extends OPTIONAL_TYPE ? true : never; type ContainsNullableProperties<T> = FalseWhenNever<{ [P in keyof T]-?: null extends T[P] ? true : never; }[keyof T]>; type FalseWhenNever<T> = [T] extends [never] ? false : T; export {}; /** * Alternative solution that allows to expose the inner objects in the with, but typescript get frozen * This implementation doesn't deal when a inner property is used alone. See the case when in this view the inner property * is requiredInOptionalObject but that property is used in a way that flag make no sence any more */