// Import new schema types export type { ValueType, ColumnSchema, TableSchemaMetadata, Cardinality, RelationshipMetadata, SchemaMetadataStructure, AccessDefinition, } from './table-schema'; // Model types (backward compatibility) export type GenericModel = Record; export type GenericSchema = Record; /** * Helper to constrain related field names based on relationships metadata */ export type RelatedField = GetRelationshipFields & string; // Query interfaces export interface QueryInfo { query: string; hash: number; vars?: Record; } export interface RelatedQuery { /** The name of the related table to query */ relatedTable: string; /** The alias for this subquery result (defaults to relatedTable name) */ alias?: string; /** Optional query modifier for the subquery */ modifier?: SchemaAwareQueryModifier; /** The cardinality of the relationship */ cardinality: 'one' | 'many'; } export interface QueryOptions { select?: ((keyof TModel & string) | '*')[]; where?: Partial; limit?: number; offset?: number; orderBy?: Partial>; /** Related tables to include via subqueries */ related?: RelatedQuery[]; isOne?: IsOne; } export interface LiveQueryOptions extends Omit< QueryOptions, 'orderBy' > {} // Import schema types for schema-aware modifiers import type { SchemaStructure, TableNames, GetTable, TableModel, TableRelationships, GetRelationship, } from './table-schema'; // Query modifier type for related queries - now schema-aware! export type QueryModifier = ( builder: QueryModifierBuilder ) => QueryModifierBuilder; // Schema-aware query modifier that knows about relationships export type SchemaAwareQueryModifier< S extends SchemaStructure, TableName extends TableNames, RelatedFields extends Record = {}, > = ( builder: SchemaAwareQueryModifierBuilder ) => SchemaAwareQueryModifierBuilder; // Simplified query builder interface for modifying subqueries export interface QueryModifierBuilder { where(conditions: Partial): this; select(...fields: ((keyof TModel & string) | '*')[]): this; limit(count: number): this; offset(count: number): this; orderBy(field: keyof TModel & string, direction?: 'asc' | 'desc'): this; related(relatedField: Field, modifier?: QueryModifier): this; _getOptions(): QueryOptions; } // Schema-aware query builder interface that understands relationships export interface SchemaAwareQueryModifierBuilder< S extends SchemaStructure, TableName extends TableNames, RelatedFields extends Record = {}, > { where(conditions: Partial>>): this; select(...fields: ((keyof TableModel> & string) | '*')[]): this; limit(count: number): this; offset(count: number): this; orderBy( field: keyof TableModel> & string, direction?: 'asc' | 'desc' ): this; related< Field extends TableRelationships['field'], Rel extends GetRelationship, RelatedFields2 extends Record = {}, >( relatedField: Field, modifier?: SchemaAwareQueryModifier ): SchemaAwareQueryModifierBuilder< S, TableName, RelatedFields & { [K in Field]: { to: Rel['to']; cardinality: Rel['cardinality']; relatedFields: RelatedFields2; }; } >; _getOptions(): QueryOptions>, boolean>; } /** * Extract fields from a model that are relationship fields (string or string[]) * Excludes common non-relationship fields like id, created_at, updated_at, etc. */ export type RelationshipFields = { [K in keyof TModel]: K extends 'id' | 'created_at' | 'updated_at' | 'deleted_at' ? never : TModel[K] extends string | string[] | null | undefined ? K : never; }[keyof TModel]; /** * Helper type to infer the related model type from a field name using Relationships metadata * Simplified to directly access the nested structure */ export type InferRelatedModelFromMetadata< Schema extends GenericSchema, TableName extends string, FieldName extends string, Relationships, > = Relationships extends Record> ? TableName extends keyof Relationships ? FieldName extends keyof Relationships[TableName] ? Relationships[TableName][FieldName]['model'] : any : any : any; /** * Get cardinality for a relationship field from metadata * Simplified to directly access the nested structure */ export type GetCardinality = Relationships extends Record> ? TableName extends keyof Relationships ? FieldName extends keyof Relationships[TableName] ? Relationships[TableName][FieldName]['cardinality'] : 'many' : 'many' : 'many'; /** * Type that transforms a Model by replacing a field with its related records * Uses Relationships metadata to determine cardinality and related table */ export type WithRelated< Schema extends GenericSchema, TModel extends Record, TableName extends string, FieldName extends string, Relationships, > = FieldName extends keyof TModel ? Omit & { [K in FieldName]: GetCardinality extends 'one' ? InferRelatedModelFromMetadata | null : InferRelatedModelFromMetadata[] | null; } : TModel; /** * Type to extract relationship fields from Relationships metadata * Now simplified to just get the keys of the nested object */ export type GetRelationshipFields = Relationships extends Record> ? TableName extends keyof Relationships ? keyof Relationships[TableName] & string : never : never; /** * Relationship metadata structure - now a nested object for better type safety * Example: * { * thread: { * author: { model: Schema["user"], table: "user", cardinality: "one" }, * comments: { model: Schema["comment"], table: "comment", cardinality: "many" } * } * } */ export interface RelationshipDefinition { /** The related model type */ model: Model; /** The related table name */ table: string; /** Whether this is a 1:1 or 1:many relationship */ cardinality: 'one' | 'many'; } export type RelationshipsMetadata = Record>;