/** * Supported value types in the schema */ export type ValueType = 'string' | 'number' | 'boolean' | 'null' | 'json'; /** * Column metadata defining the type and optionality of a field */ export interface ColumnSchema { readonly type: ValueType; readonly optional: boolean; readonly dateTime?: boolean; readonly recordId?: boolean; } /** * Table metadata containing columns and primary key information */ export interface TableSchemaMetadata { readonly name: string; readonly columns: { readonly [columnName: string]: ColumnSchema; }; readonly primaryKey: readonly string[]; } /** * Cardinality of a relationship: one-to-one or one-to-many */ export type Cardinality = 'one' | 'many'; /** * Relationship metadata defining how tables relate to each other */ export interface RelationshipMetadata { readonly model: string; readonly table: string; readonly cardinality: Cardinality; } /** * Complete schema metadata structure * Maps table names to their schemas and relationships */ export interface SchemaMetadataStructure { readonly tables: { readonly [tableName: string]: TableSchemaMetadata; }; readonly relationships: { readonly [tableName: string]: { readonly [fieldName: string]: RelationshipMetadata; }; }; } /** * Type mapping from ValueType to TypeScript types */ export type TypeNameToTypeMap = { string: string; number: number; boolean: boolean; null: null; json: unknown; }; /** * Convert a column type to its TypeScript type */ export type ColumnToTSType = T extends { optional: true; } ? TypeNameToTypeMap[T['type']] | null : TypeNameToTypeMap[T['type']]; /** * Helper to extract relationship field names for a table */ export type RelationshipFieldNames< Metadata extends SchemaMetadataStructure, TableName extends keyof Metadata['relationships'] & string, > = keyof Metadata['relationships'][TableName] & string; /** * Helper to get cardinality for a specific relationship */ export type GetRelationshipCardinality< Metadata extends SchemaMetadataStructure, TableName extends keyof Metadata['relationships'] & string, FieldName extends keyof Metadata['relationships'][TableName] & string, > = Metadata['relationships'][TableName][FieldName]['cardinality']; /** * Helper to get related table name for a relationship */ export type GetRelatedTable< Metadata extends SchemaMetadataStructure, TableName extends keyof Metadata['relationships'] & string, FieldName extends keyof Metadata['relationships'][TableName] & string, > = Metadata['relationships'][TableName][FieldName]['table']; // ============================================================================ // ACCESS SCHEMA HELPERS // ============================================================================ export interface AccessDefinition { readonly signIn: { readonly params: Record; }; readonly signup: { readonly params: Record; }; } // ============================================================================ // ARRAY-BASED SCHEMA TYPE HELPERS // ============================================================================ /** * Base schema structure for array-based schemas */ export interface SchemaStructure { readonly tables: readonly { readonly name: string; readonly columns: Record; readonly primaryKey: readonly string[]; }[]; readonly relationships: readonly { readonly from: string; readonly field: string; readonly to: string; readonly cardinality: Cardinality; }[]; readonly backends: Record; readonly access?: Record; } export interface HTTPOutboxBackendDefinition { readonly outboxTable: string; readonly routes: Record; } export interface HTTPBackendRouteDefinition { readonly args: Record; } export interface HTTPBackendRouteArgsDefinition { readonly type: ValueType; readonly optional: boolean; } // ============================================================================ // BACKEND / RUN TYPE HELPERS // ============================================================================ /** Extract all backend names from the schema */ export type BackendNames = keyof S['backends'] & string; /** Extract all route paths for a specific backend */ export type BackendRoutes< S extends SchemaStructure, B extends BackendNames, > = keyof S['backends'][B]['routes'] & string; /** Build the typed payload for a specific route */ export type RoutePayload< S extends SchemaStructure, B extends BackendNames, R extends BackendRoutes, > = [keyof RouteArgsDef] extends [never] ? Record : Prettify< { [K in RequiredRouteArgKeys]: TypeNameToTypeMap[RouteArgsDef[K]['type']] } & { [K in OptionalRouteArgKeys]?: TypeNameToTypeMap[RouteArgsDef[K]['type']] } >; type RouteArgsDef< S extends SchemaStructure, B extends BackendNames, R extends BackendRoutes, > = S['backends'][B]['routes'][R]['args']; type RequiredRouteArgKeys< S extends SchemaStructure, B extends BackendNames, R extends BackendRoutes, > = { [K in keyof RouteArgsDef]: RouteArgsDef[K]['optional'] extends true ? never : K; }[keyof RouteArgsDef] & string; type OptionalRouteArgKeys< S extends SchemaStructure, B extends BackendNames, R extends BackendRoutes, > = { [K in keyof RouteArgsDef]: RouteArgsDef[K]['optional'] extends true ? K : never; }[keyof RouteArgsDef] & string; type Prettify = { [K in keyof T]: T[K] } & {}; /** * Extract a specific table by name from the schema tables array */ export type GetTable> = Extract< S['tables'][number], { name: Name } >; /** * Extract all table names from the schema */ export type TableNames = S['tables'][number]['name']; /** * Extract all field names from a type */ export type TableFieldNames }> = keyof T['columns'] & string; /** * Convert table schema columns to a TypeScript model type */ export type TableModel }> = { [K in keyof T['columns']]: ColumnToTSType; }; /** * Extract all relationships for a specific table from relationships array */ export type TableRelationships = Extract< S['relationships'][number], { from: TableName } >; /** * Get relationship field names for a table */ export type RelationshipFields< S extends SchemaStructure, TableName extends string, > = TableRelationships['field']; /** * Get specific relationship by table and field */ export type GetRelationship< S extends SchemaStructure, TableName extends string, Field extends string, > = Extract, { field: Field }>; /** * Convert array-based schema to indexed format (for internal compatibility) */ export type SchemaToIndexed = { tables: { [K in S['tables'][number]['name']]: Extract; }; relationships: { [K in S['tables'][number]['name']]: { [R in Extract['field']]: Extract< Extract, { field: R } >; }; }; };