import { GenericSchema, Prettify } from './types'; declare type Whitespace = ' ' | '\n' | '\t'; declare type LowerAlphabet = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z'; declare type Alphabet = LowerAlphabet | Uppercase; declare type Digit = '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '0'; declare type Letter = Alphabet | Digit | '_'; declare type Json = string | number | boolean | null | { [key: string]: Json; } | Json[]; /** * Parser errors. */ declare type ParserError = { error: true; } & Message; declare type GenericStringError = ParserError<'Received a generic string'>; export declare type SelectQueryError = { error: true; } & Message; /** * Trims whitespace from the left of the input. */ declare type EatWhitespace = string extends Input ? GenericStringError : Input extends `${Whitespace}${infer Remainder}` ? EatWhitespace : Input; declare type HasFKey = Relationships extends [infer R] ? R extends { foreignKeyName: FKeyName; } ? true : false : Relationships extends [infer R, ...infer Rest] ? HasFKey extends true ? true : HasFKey : false; declare type HasUniqueFKey = Relationships extends [infer R] ? R extends { foreignKeyName: FKeyName; isOneToOne: true; } ? true : false : Relationships extends [infer R, ...infer Rest] ? HasUniqueFKey extends true ? true : HasUniqueFKey : false; declare type HasFKeyToFRel = Relationships extends [infer R] ? R extends { referencedRelation: FRelName; } ? true : false : Relationships extends [infer R, ...infer Rest] ? HasFKeyToFRel extends true ? true : HasFKeyToFRel : false; declare type HasUniqueFKeyToFRel = Relationships extends [infer R] ? R extends { referencedRelation: FRelName; isOneToOne: true; } ? true : false : Relationships extends [infer R, ...infer Rest] ? HasUniqueFKeyToFRel extends true ? true : HasUniqueFKeyToFRel : false; /** * Constructs a type definition for a single field of an object. * * @param Definitions Record of definitions, possibly generated from PostgREST's OpenAPI spec. * @param Name Name of the table being queried. * @param Field Single field parsed by `ParseQuery`. */ declare type ConstructFieldDefinition, RelationName, Relationships, Field> = Field extends { star: true; } ? Row : Field extends { name: string; original: string; hint: string; children: unknown[]; } ? { [_ in Field['name']]: GetResultHelper extends infer Child ? HasUniqueFKey extends true ? Child | null : Relationships extends unknown[] ? HasFKey extends true ? Child | null : Child[] : Child[] : never; } : Field extends { name: string; original: string; children: unknown[]; } ? { [_ in Field['name']]: GetResultHelper extends infer Child ? HasUniqueFKeyToFRel extends true ? Child | null : Relationships extends unknown[] ? HasFKeyToFRel extends true ? Child | null : Child[] : Child[] : never; } : Field extends { name: string; original: string; } ? Field['original'] extends keyof Row ? { [K in Field['name']]: Row[Field['original']]; } : SelectQueryError<`Referencing missing column \`${Field['original']}\``> : Field extends { name: string; type: infer T; } ? { [K in Field['name']]: T; } : Record; /** * Notes: all `Parse*` types assume that their input strings have their whitespace * removed. They return tuples of ["Return Value", "Remainder of text"] or * a `ParserError`. */ /** * Reads a consecutive sequence of more than 1 letter, * where letters are `[0-9a-zA-Z_]`. */ declare type ReadLetters = string extends Input ? GenericStringError : ReadLettersHelper extends [`${infer Letters}`, `${infer Remainder}`] ? Letters extends '' ? ParserError<`Expected letter at \`${Input}\``> : [Letters, Remainder] : ReadLettersHelper; declare type ReadLettersHelper = string extends Input ? GenericStringError : Input extends `${infer L}${infer Remainder}` ? L extends Letter ? ReadLettersHelper : [Acc, Input] : [Acc, '']; /** * Reads a consecutive sequence of more than 1 double-quoted letters, * where letters are `[^"]`. */ declare type ReadQuotedLetters = string extends Input ? GenericStringError : Input extends `"${infer Remainder}` ? ReadQuotedLettersHelper extends [`${infer Letters}`, `${infer Remainder}`] ? Letters extends '' ? ParserError<`Expected string at \`${Remainder}\``> : [Letters, Remainder] : ReadQuotedLettersHelper : ParserError<`Not a double-quoted string at \`${Input}\``>; declare type ReadQuotedLettersHelper = string extends Input ? GenericStringError : Input extends `${infer L}${infer Remainder}` ? L extends '"' ? [Acc, Remainder] : ReadQuotedLettersHelper : ParserError<`Missing closing double-quote in \`"${Acc}${Input}\``>; /** * Parses a (possibly double-quoted) identifier. * For now, identifiers are just sequences of more than 1 letter. */ declare type ParseIdentifier = ReadLetters extends [ infer Name, `${infer Remainder}` ] ? [Name, `${Remainder}`] : ReadQuotedLetters extends [infer Name, `${infer Remainder}`] ? [Name, `${Remainder}`] : ParserError<`No (possibly double-quoted) identifier at \`${Input}\``>; /** * Parses a node. * A node is one of the following: * - `*` * - `field` * - `field->json...` * - `field(nodes)` * - `field!hint(nodes)` * - `field!inner(nodes)` * - `field!hint!inner(nodes)` * - `renamed_field:field` * - `renamed_field:field->json...` * - `renamed_field:field(nodes)` * - `renamed_field:field!hint(nodes)` * - `renamed_field:field!inner(nodes)` * - `renamed_field:field!hint!inner(nodes)` * * TODO: casting operators `::text`, more support for JSON operators `->`, `->>`. */ declare type ParseNode = Input extends '' ? ParserError<'Empty string'> : Input extends `*${infer Remainder}` ? [{ star: true; }, EatWhitespace] : ParseIdentifier extends [infer Name, `${infer Remainder}`] ? EatWhitespace extends `!inner${infer Remainder}` ? ParseEmbeddedResource> extends [infer Fields, `${infer Remainder}`] ? [ { name: Name; original: Name; children: Fields; }, EatWhitespace ] : ParseEmbeddedResource> extends ParserError ? ParseEmbeddedResource> : ParserError<'Expected embedded resource after `!inner`'> : EatWhitespace extends `!${infer Remainder}` ? ParseIdentifier> extends [infer Hint, `${infer Remainder}`] ? EatWhitespace extends `!inner${infer Remainder}` ? ParseEmbeddedResource> extends [ infer Fields, `${infer Remainder}` ] ? [ { name: Name; original: Name; hint: Hint; children: Fields; }, EatWhitespace ] : ParseEmbeddedResource> extends ParserError ? ParseEmbeddedResource> : ParserError<'Expected embedded resource after `!inner`'> : ParseEmbeddedResource> extends [ infer Fields, `${infer Remainder}` ] ? [ { name: Name; original: Name; hint: Hint; children: Fields; }, EatWhitespace ] : ParseEmbeddedResource> extends ParserError ? ParseEmbeddedResource> : ParserError<'Expected embedded resource after `!hint`'> : ParserError<'Expected identifier after `!`'> : EatWhitespace extends `:${infer Remainder}` ? ParseIdentifier> extends [infer OriginalName, `${infer Remainder}`] ? EatWhitespace extends `!inner${infer Remainder}` ? ParseEmbeddedResource> extends [ infer Fields, `${infer Remainder}` ] ? [ { name: Name; original: OriginalName; children: Fields; }, EatWhitespace ] : ParseEmbeddedResource> extends ParserError ? ParseEmbeddedResource> : ParserError<'Expected embedded resource after `!inner`'> : EatWhitespace extends `!${infer Remainder}` ? ParseIdentifier> extends [infer Hint, `${infer Remainder}`] ? EatWhitespace extends `!inner${infer Remainder}` ? ParseEmbeddedResource> extends [ infer Fields, `${infer Remainder}` ] ? [ { name: Name; original: OriginalName; hint: Hint; children: Fields; }, EatWhitespace ] : ParseEmbeddedResource> extends ParserError ? ParseEmbeddedResource> : ParserError<'Expected embedded resource after `!inner`'> : ParseEmbeddedResource> extends [ infer Fields, `${infer Remainder}` ] ? [ { name: Name; original: OriginalName; hint: Hint; children: Fields; }, EatWhitespace ] : ParseEmbeddedResource> extends ParserError ? ParseEmbeddedResource> : ParserError<'Expected embedded resource after `!hint`'> : ParserError<'Expected identifier after `!`'> : ParseEmbeddedResource> extends [ infer Fields, `${infer Remainder}` ] ? [ { name: Name; original: OriginalName; children: Fields; }, EatWhitespace ] : ParseJsonAccessor> extends [ infer _PropertyName, infer PropertyType, `${infer Remainder}` ] ? [ { name: Name; type: PropertyType; }, EatWhitespace ] : ParseEmbeddedResource> extends ParserError ? ParseEmbeddedResource> : [ { name: Name; original: OriginalName; }, EatWhitespace ] : ParseIdentifier> : ParseEmbeddedResource> extends [infer Fields, `${infer Remainder}`] ? [ { name: Name; original: Name; children: Fields; }, EatWhitespace ] : ParseJsonAccessor> extends [ infer PropertyName, infer PropertyType, `${infer Remainder}` ] ? [ { name: PropertyName; type: PropertyType; }, EatWhitespace ] : ParseEmbeddedResource> extends ParserError ? ParseEmbeddedResource> : [ { name: Name; original: Name; }, EatWhitespace ] : ParserError<`Expected identifier at \`${Input}\``>; /** * Parses a JSON property accessor of the shape `->a->b->c`. The last accessor in * the series may convert to text by using the ->> operator instead of ->. * * Returns a tuple of ["Last property name", "Last property type", "Remainder of text"] * or the original string input indicating that no opening `->` was found. */ declare type ParseJsonAccessor = Input extends `->${infer Remainder}` ? Remainder extends `>${infer Remainder}` ? ParseIdentifier extends [infer Name, `${infer Remainder}`] ? [Name, string, EatWhitespace] : ParserError<'Expected property name after `->>`'> : ParseIdentifier extends [infer Name, `${infer Remainder}`] ? ParseJsonAccessor extends [ infer PropertyName, infer PropertyType, `${infer Remainder}` ] ? [PropertyName, PropertyType, EatWhitespace] : [Name, Json, EatWhitespace] : ParserError<'Expected property name after `->`'> : Input; /** * Parses an embedded resource, which is an opening `(`, followed by a sequence of * nodes, separated by `,`, then a closing `)`. * * Returns a tuple of ["Parsed fields", "Remainder of text"], an error, * or the original string input indicating that no opening `(` was found. */ declare type ParseEmbeddedResource = Input extends `(${infer Remainder}` ? ParseNodes> extends [infer Fields, `${infer Remainder}`] ? EatWhitespace extends `)${infer Remainder}` ? Fields extends [] ? ParserError<'Expected fields after `(`'> : [Fields, EatWhitespace] : ParserError<`Expected ")"`> : ParseNodes> : Input; /** * Parses a sequence of nodes, separated by `,`. * * Returns a tuple of ["Parsed fields", "Remainder of text"] or an error. */ declare type ParseNodes = string extends Input ? GenericStringError : ParseNodesHelper; declare type ParseNodesHelper = ParseNode extends [ infer Field, `${infer Remainder}` ] ? EatWhitespace extends `,${infer Remainder}` ? ParseNodesHelper, [Field, ...Fields]> : [[Field, ...Fields], EatWhitespace] : ParseNode; /** * Parses a query. * A query is a sequence of nodes, separated by `,`, ensuring that there is * no remaining input after all nodes have been parsed. * * Returns an array of parsed nodes, or an error. */ declare type ParseQuery = string extends Query ? GenericStringError : ParseNodes> extends [infer Fields, `${infer Remainder}`] ? EatWhitespace extends '' ? Fields : ParserError<`Unexpected input: ${Remainder}`> : ParseNodes>; declare type GetResultHelper, RelationName, Relationships, Fields extends unknown[], Acc> = Fields extends [infer R] ? ConstructFieldDefinition extends SelectQueryError ? SelectQueryError : GetResultHelper & Acc> : Fields extends [infer R, ...infer Rest] ? ConstructFieldDefinition extends SelectQueryError ? SelectQueryError : GetResultHelper & Acc> : Prettify; /** * Constructs a type definition for an object based on a given PostgREST query. * * @param Row Record. * @param Query Select query string literal to parse. */ export declare type GetResult, RelationName, Relationships, Query extends string> = ParseQuery extends unknown[] ? GetResultHelper, unknown> : ParseQuery; export {}; //# sourceMappingURL=select-query-parser.d.ts.map