import PostgrestError from '../PostgrestError' import { ContainsNull } from '../select-query-parser/types' import { SelectQueryError } from '../select-query-parser/utils' import { ClientServerOptions } from './common/common' /** * Response format * * {@link https://github.com/supabase/supabase-js/issues/32} */ interface PostgrestResponseBase { status: number statusText: string } export interface PostgrestResponseSuccess extends PostgrestResponseBase { success: true error: null data: T count: number | null } export interface PostgrestResponseFailure extends PostgrestResponseBase { success: false error: PostgrestError data: null count: null } // TODO: in v3: // - remove PostgrestResponse and PostgrestMaybeSingleResponse // - rename PostgrestSingleResponse to PostgrestResponse export type PostgrestSingleResponse = PostgrestResponseSuccess | PostgrestResponseFailure export type PostgrestMaybeSingleResponse = PostgrestSingleResponse export type PostgrestResponse = PostgrestSingleResponse export type DatabaseWithOptions = { db: Database options: Options } // https://twitter.com/mattpocockuk/status/1622730173446557697 export type Prettify = { [K in keyof T]: T[K] } & {} // Rejects excess properties that aren't in Base. // Works around TypeScript not checking excess properties on generic parameters. export type RejectExcessProperties = Row & { [K in Exclude]: never } // https://github.com/sindresorhus/type-fest export type SimplifyDeep = ConditionalSimplifyDeep< Type, ExcludeType | NonRecursiveType | Set | Map, object > type ConditionalSimplifyDeep< Type, ExcludeType = never, IncludeType = unknown, > = Type extends ExcludeType ? Type : Type extends IncludeType ? { [TypeKey in keyof Type]: ConditionalSimplifyDeep } : Type type NonRecursiveType = BuiltIns | Function | (new (...arguments_: any[]) => unknown) type BuiltIns = Primitive | void | Date | RegExp type Primitive = null | undefined | string | number | boolean | symbol | bigint export type IsValidResultOverride = Result extends any[] ? NewResult extends any[] ? // Both are arrays - valid true : ErrorResult : NewResult extends any[] ? ErrorNewResult : // Neither are arrays - valid true /** * Utility type to check if array types match between Result and NewResult. * Returns either the valid NewResult type or an error message type. */ export type CheckMatchingArrayTypes = // If the result is a QueryError we allow the user to override anyway Result extends SelectQueryError ? NewResult : IsValidResultOverride< Result, NewResult, { Error: 'Type mismatch: Cannot cast array result to a single object. Use .overrideTypes> or .returns> (deprecated) for array results or .single() to convert the result to a single object' }, { Error: 'Type mismatch: Cannot cast single object to array type. Remove Array wrapper from return type or make sure you are not using .single() up in the calling chain' } > extends infer ValidationResult ? ValidationResult extends true ? // Preserve the optionality of the result if the overriden type is an object (case of chaining with `maybeSingle`) ContainsNull extends true ? NewResult | null : NewResult : // contains the error ValidationResult : never type Simplify = T extends object ? { [K in keyof T]: T[K] } : T // Extract only explicit (non-index-signature) keys. type ExplicitKeys = { [K in keyof T]: string extends K ? never : K }[keyof T] type MergeExplicit = { // We merge all the explicit keys which allows merge and override of types like // { [key: string]: unknown } and { someSpecificKey: boolean } [K in ExplicitKeys | ExplicitKeys]: K extends keyof New ? K extends keyof Row ? Row[K] extends SelectQueryError ? New[K] : // Check if the override is on a embedded relation (array) New[K] extends any[] ? Row[K] extends any[] ? Array, NonNullable>>> : New[K] : // Check if both properties are objects omitting a potential null union IsPlainObject> extends true ? IsPlainObject> extends true ? // If they are, use the new override as source of truth for the optionality ContainsNull extends true ? // If the override wants to preserve optionality Simplify, NonNullable>> | null : // If the override wants to enforce non-null result Simplify>> : New[K] // Override with New type if Row isn't an object : New[K] // Override primitives with New type : New[K] // Add new properties from New : K extends keyof Row ? Row[K] // Keep existing properties not in New : never } type MergeDeep = Simplify< MergeExplicit & // Intersection here is to restore dynamic keys into the merging result // eg: // {[key: number]: string} // or Record (string extends keyof Row ? { [K: string]: Row[string] } : {}) > // Helper to check if a type is a plain object (not an array) type IsPlainObject = T extends any[] ? false : T extends object ? true : false // Merge the new result with the original (Result) when merge option is true. // If NewResult is an array, merge each element. export type MergePartialResult = Options extends { merge: true } ? Result extends any[] ? NewResult extends any[] ? Array>> : never : Simplify> : NewResult