import { CollectionNameFromModels, Models } from '../../schema/types/models.js'; import { StringKey, Unalias } from '../../utils/types.js'; import { Decoded, ModelPaths, ModelRelationshipPaths, PathFiltered, ResolveRelationshipPath, SchemaPaths } from '../../schema/index.js'; /** * All possible queries for a schema, keyed by collection name. */ export type SchemaQueries = Models> = { [CN in CollectionNameFromModels]: CollectionQuery; }; /** * A selection of queries for a schema, returning a union if there are multiple matches */ export type SchemaQuery = Models, CN extends CollectionNameFromModels = CollectionNameFromModels> = SchemaQueries[CN]; /** * A prepared query, which is used internally by the query engine */ export interface PreparedQuery { collectionName: string; select?: string[]; where?: PreparedWhere; order?: PreparedOrder; limit?: number; after?: QueryAfter; include?: PreparedInclusions; } /** * A user defined query on the database, which may reference the schema or other database objects. */ export interface CollectionQuery = Models, CN extends CollectionNameFromModels = CollectionNameFromModels> { collectionName: CN; select?: QuerySelection[]; where?: QueryWhere; order?: QueryOrder; limit?: number; after?: QueryAfter; vars?: Record; include?: QueryInclusions; } /** * Cardinality of a query result: * - 'one' - a single result * - 'many' - multiple results */ export type QueryResultCardinality = 'one' | 'many'; export type QuerySelectionFromQuery> = Q extends CollectionQuery ? QuerySelection : never; export type QuerySelection = Models, CN extends CollectionNameFromModels = CollectionNameFromModels> = SchemaPaths; /** * A query filter, which is a collection of many filters. */ export type QueryWhere = Models, CN extends CollectionNameFromModels = CollectionNameFromModels> = WhereFilter[]; /** * A single filter, which may have various structures. */ export type WhereFilter = Models, CN extends CollectionNameFromModels = CollectionNameFromModels> = FilterStatement | FilterGroup | SubQueryFilter | RelationshipExistsFilter | boolean; export type ModelFilterStatements = Models, CN extends CollectionNameFromModels = CollectionNameFromModels> = { [K in ModelPaths]: FilterStatement; }; export type ModelFilterStatement = Models, CN extends CollectionNameFromModels = CollectionNameFromModels, K extends ModelPaths = ModelPaths> = ModelFilterStatements[K]; /** * A single filter statement of the shape [path, operator, value]. */ export type FilterStatement = Models, CN extends CollectionNameFromModels = CollectionNameFromModels, K extends ModelPaths = ModelPaths> = readonly [ K, string, any ]; export type PreparedWhere = PreparedWhereFilter[]; export type PreparedWhereFilter = FilterStatement | PreparedFilterGroup | PreparedSubQueryFilter | boolean; export type PreparedFilterGroup = FilterGroup, PreparedWhere>; export type PreparedSubQueryFilter = { exists: PreparedQuery; }; /** * A set of filters specified to be combined with AND or OR. */ export type FilterGroup = Models, CN extends CollectionNameFromModels = CollectionNameFromModels, W extends QueryWhere | PreparedWhere = QueryWhere | PreparedWhere> = AndFilterGroup | OrFilterGroup; export type QueryFilterGroup = Models, CN extends CollectionNameFromModels = CollectionNameFromModels> = FilterGroup>; /** * A group of filters combined with AND. */ export type AndFilterGroup = Models, CN extends CollectionNameFromModels = CollectionNameFromModels, W extends QueryWhere | PreparedWhere = QueryWhere | PreparedWhere> = { mod: 'and'; filters: W; }; /** * A group of filters combined with OR. */ export type OrFilterGroup = Models, CN extends CollectionNameFromModels = CollectionNameFromModels, W extends QueryWhere | PreparedWhere = QueryWhere | PreparedWhere> = { mod: 'or'; filters: W; }; /** * An exists filter that will check if a subquery returns any results. */ export type SubQueryFilter = Models, SQ extends SchemaQuery = SchemaQuery> = { exists: SQ; }; /** * An exists filter that will check if a relationship in the schema returns any results. */ export type RelationshipRef = Models, CN extends CollectionNameFromModels = CollectionNameFromModels> = StringKey>; export type IsRelationshipRef, CN extends CollectionNameFromModels, Ref extends string> = Ref extends RelationshipRef ? true : false; export type RelationshipExistsFilter = Models, CN extends CollectionNameFromModels = CollectionNameFromModels, P extends ModelRelationshipPaths = ModelRelationshipPaths, Ext extends RelationshipExistsExtension = RelationshipExistsExtension> = { exists: Ext & { _extends: P; }; }; export type RelationshipExistsExtension = Models, CN extends CollectionNameFromModels = CollectionNameFromModels, P extends ModelRelationshipPaths = ModelRelationshipPaths> = Pick['query']['collectionName']>, 'where'>; export type PreparedOrder = PreparedOrderStatement[]; export type PreparedOrderStatement = OrderStatement | RelationalOrderStatement; export type RelationalOrderStatement = Models, CN extends CollectionNameFromModels = CollectionNameFromModels> = [ property: ModelPaths, direction: 'ASC' | 'DESC', subquery: PreparedRelationSubquery<'one'> ]; /** * A query order, which is a collection of many orders. */ export type QueryOrder = Models, CN extends CollectionNameFromModels = CollectionNameFromModels> = OrderStatement[]; /** * A single order statement of the shape [path, direction]. */ export type OrderStatement = Models, CN extends CollectionNameFromModels = CollectionNameFromModels> = [property: ModelPaths, direction: 'ASC' | 'DESC']; export type QueryAfter = [cursor: ValueCursor, inclusive: boolean]; export type ValueCursor = [ value: QueryValuePrimitive, ...values: QueryValuePrimitive[] ]; /** * A map of prepared inclusions, keyed by alias. */ export type PreparedInclusions = { [K in string]: PreparedInclusion; }; /** * A possible inclusion value in a query. */ export type PreparedInclusion = PreparedRelationSubquery; /** * A subquery definition for a prepared query. */ export type PreparedRelationSubquery = { subquery: PreparedQuery; cardinality: Cardinality; }; /** * A map of inclusions, keyed by alias. */ export type QueryInclusions = Models, CN extends CollectionNameFromModels = CollectionNameFromModels> = { [K in string]: QueryInclusion; }; /** * A possible inclusion value in a query. */ export type QueryInclusion = Models, CN extends CollectionNameFromModels = CollectionNameFromModels> = RefShorthand | RelationSubquery | RefSubquery; /** * A shorthand for including a reference. */ export type RefShorthand = true | null; export type RefSubquery = Models, CN extends CollectionNameFromModels = CollectionNameFromModels, Ref extends RelationshipRef = RelationshipRef> = { _extends: Ref; } & RefQueryExtension; /** * An extension of a referential subquery, specifying additional query parameters. */ export type RefQueryExtension = Models, CN extends CollectionNameFromModels = CollectionNameFromModels, Ref extends RelationshipRef = RelationshipRef> = Pick>, 'select' | 'include' | 'limit' | 'where' | 'order'>; export type RefDefinition, CN extends CollectionNameFromModels, Ref extends RelationshipRef> = NonNullable[Ref]; export type RefQuery, CN extends CollectionNameFromModels, Ref extends RelationshipRef> = RefDefinition['query']; export type RefCollectionName, CN extends CollectionNameFromModels, Ref extends RelationshipRef> = RefQuery['collectionName']; /** * A subquery defining a relationship, specifying the subquery and cardinality of the result. */ export type RelationSubquery = Models, Q extends SchemaQuery = SchemaQuery, Cardinality extends QueryResultCardinality = QueryResultCardinality> = { subquery: Q; cardinality: Cardinality; }; type QueryValuePrimitive = number | string | boolean | Date | null; /** * Possible values that can be passed into a the query engine by a user */ export type QueryValue = QueryValuePrimitive | NonNullable[]; export type FetchResult, Q extends SchemaQuery, C extends QueryResultCardinality> = Unalias>; export type AliasedFetchResult, Q extends SchemaQuery, C extends QueryResultCardinality> = C extends 'one' ? AliasedQueryResult | null : AliasedQueryResult[]; type AliasedQueryResult, Q extends SchemaQuery> = Q extends CollectionQuery ? (Q['select'] extends ReadonlyArray ? PathFiltered, S extends string ? S : never> : Decoded) & { [K in StringKey]: InclusionResult; } : never; type InclusionResult, CN extends CollectionNameFromModels, Alias extends string, Inclusion extends QueryInclusion> = Inclusion extends RelationSubquery ? AliasedFetchResult : Inclusion extends RefSubquery ? AliasedFetchResult & Omit, RefDefinition['cardinality']> : Inclusion extends RefShorthand ? Alias extends RelationshipRef ? AliasedFetchResult['query'], RefDefinition['cardinality']> : never : never; export type WithSelection, Selection extends QuerySelectionFromQuery> = Omit & { select: Selection[]; }; export type WithInclusion, Inclusion extends Q extends CollectionQuery ? QueryInclusions : never> = Omit & { include: Inclusion; }; export type WithInclusionRaw = Omit & { include: Inclusion; }; export {};