@@ -36,7 +36,7 @@ import {
3636} from './algebraic_type' ;
3737import type RawScopedTypeNameV9 from './autogen/raw_scoped_type_name_v_9_type' ;
3838import type { CamelCase } from './type_util' ;
39- import type { TableSchema } from './table_schema' ;
39+ import type { UntypedTableSchema } from './table_schema' ;
4040import { toCamelCase } from './util' ;
4141import {
4242 defineView ,
@@ -45,8 +45,7 @@ import {
4545 type ViewOpts ,
4646 type ViewReturnTypeBuilder ,
4747} from './views' ;
48- import RawIndexDefV9 from './autogen/raw_index_def_v_9_type' ;
49- import type { IndexOpts } from './indexes' ;
48+ import type { UntypedIndex } from './indexes' ;
5049import { procedure , type ProcedureFn } from './procedures' ;
5150
5251export type TableNamesOf < S extends UntypedSchemaDef > =
@@ -71,76 +70,63 @@ export function getRegisteredSchema(): UntypedSchemaDef {
7170/**
7271 * Helper type to convert an array of TableSchema into a schema definition
7372 */
74- type TablesToSchema < T extends readonly TableSchema < any , any , any > [ ] > = {
73+ type TablesToSchema < T extends readonly UntypedTableSchema [ ] > = {
7574 tables : {
76- /** @type {UntypedTableDef } */
77- readonly [ i in keyof T ] : {
78- name : T [ i ] [ 'tableName' ] ;
79- accessorName : CamelCase < T [ i ] [ 'tableName' ] > ;
80- columns : T [ i ] [ 'rowType' ] [ 'row' ] ;
81- rowType : T [ i ] [ 'rowSpacetimeType' ] ;
82- indexes : T [ i ] [ 'idxs' ] ;
83- constraints : T [ i ] [ 'constraints' ] ;
84- } ;
75+ readonly [ i in keyof T ] : TableToSchema < T [ i ] > ;
8576 } ;
8677} ;
8778
88- export function tablesToSchema <
89- const T extends readonly TableSchema < any , any , readonly any [ ] > [ ] ,
90- > ( tables : T ) : TablesToSchema < T > {
91- const result = {
92- tables : tables . map ( schema => {
93- const colNameList : string [ ] = [ ] ;
94- schema . rowType . algebraicType . value . elements . forEach ( elem => {
95- colNameList . push ( elem . name ) ;
96- } ) ;
79+ interface TableToSchema < T extends UntypedTableSchema > extends UntypedTableDef {
80+ name : T [ 'tableName' ] ;
81+ accessorName : CamelCase < T [ 'tableName' ] > ;
82+ columns : T [ 'rowType' ] [ 'row' ] ;
83+ rowType : T [ 'rowSpacetimeType' ] ;
84+ indexes : T [ 'idxs' ] ;
85+ constraints : T [ 'constraints' ] ;
86+ }
87+
88+ export function tablesToSchema < const T extends readonly UntypedTableSchema [ ] > (
89+ tables : T
90+ ) : TablesToSchema < T > {
91+ return { tables : tables . map ( tableToSchema ) as TablesToSchema < T > [ 'tables' ] } ;
92+ }
9793
94+ function tableToSchema < T extends UntypedTableSchema > (
95+ schema : T
96+ ) : TableToSchema < T > {
97+ const getColName = ( i : number ) =>
98+ schema . rowType . algebraicType . value . elements [ i ] . name ;
99+
100+ type AllowedCol = keyof T [ 'rowType' ] [ 'row' ] & string ;
101+ return {
102+ name : schema . tableName ,
103+ accessorName : toCamelCase ( schema . tableName as T [ 'tableName' ] ) ,
104+ columns : schema . rowType . row , // typed as T[i]['rowType']['row'] under TablesToSchema<T>
105+ rowType : schema . rowSpacetimeType ,
106+ constraints : schema . tableDef . constraints . map ( c => ( {
107+ name : c . name ,
108+ constraint : 'unique' ,
109+ columns : c . data . value . columns . map ( getColName ) as [ string ] ,
110+ } ) ) ,
111+ // TODO: horrible horrible horrible. we smuggle this `Array<UntypedIndex>`
112+ // by casting it to an `Array<IndexOpts>` as `TableToSchema` expects.
113+ // This is then used in `TableCacheImpl.constructor` and who knows where else.
114+ // We should stop lying about our types.
115+ indexes : schema . tableDef . indexes . map ( ( idx ) : UntypedIndex < AllowedCol > => {
116+ const columnIds =
117+ idx . algorithm . tag === 'Direct'
118+ ? [ idx . algorithm . value ]
119+ : idx . algorithm . value ;
98120 return {
99- name : schema . tableName ,
100- accessorName : toCamelCase ( schema . tableName ) ,
101- columns : schema . rowType . row , // typed as T[i]['rowType']['row'] under TablesToSchema<T>
102- rowType : schema . rowSpacetimeType ,
103- constraints : [
104- ...schema . tableDef . constraints . map ( c => ( {
105- name : c . name ,
106- constraint : 'unique' as const ,
107- columns : Array . from ( c . data . value . columns . map ( i => colNameList [ i ] ) ) ,
108- } ) ) ,
109- ] ,
110- // UntypedTableDef expects mutable array; idxs are readonly, spread to copy.
111- indexes : [
112- ...schema . idxs . map (
113- ( idx : Infer < typeof RawIndexDefV9 > ) : IndexOpts < any > => {
114- const columnIds =
115- idx . algorithm . tag === 'Direct'
116- ? [ idx . algorithm . value ]
117- : idx . algorithm . value ;
118- const columns = columnIds . map ( i => colNameList [ i ] ) ;
119- return {
120- name : idx . accessorName ,
121- unique : schema . tableDef . constraints . some ( c =>
122- c . data . value . columns . every ( col => columnIds . includes ( col ) )
123- ) ,
124- algorithm : idx . algorithm . tag . toLowerCase ( ) as 'btree' ,
125- columns,
126- } as IndexOpts < any > ;
127- }
128- ) ,
129- ] ,
130- } as const ;
131- } ) as {
132- // preserve tuple indices so the return type matches `[i in keyof T]`
133- readonly [ I in keyof T ] : {
134- name : T [ I ] [ 'tableName' ] ;
135- accessorName : CamelCase < T [ I ] [ 'tableName' ] > ;
136- columns : T [ I ] [ 'rowType' ] [ 'row' ] ;
137- rowType : T [ I ] [ 'rowSpacetimeType' ] ;
138- indexes : T [ I ] [ 'idxs' ] ;
139- constraints : T [ I ] [ 'constraints' ] ;
121+ name : idx . accessorName ! ,
122+ unique : schema . tableDef . constraints . some ( c =>
123+ c . data . value . columns . every ( col => columnIds . includes ( col ) )
124+ ) ,
125+ algorithm : idx . algorithm . tag . toLowerCase ( ) as 'btree' ,
126+ columns : columnIds . map ( getColName ) ,
140127 } ;
141- } ,
142- } satisfies TablesToSchema < T > ;
143- return result ;
128+ } ) as T [ 'idxs' ] ,
129+ } ;
144130}
145131
146132/**
@@ -333,7 +319,7 @@ class Schema<S extends UntypedSchemaDef> {
333319 constructor (
334320 tables : Infer < typeof RawTableDefV9 > [ ] ,
335321 typespace : Infer < typeof Typespace > ,
336- handles : readonly TableSchema < any , any , any > [ ]
322+ handles : readonly UntypedTableSchema [ ]
337323 ) {
338324 this . tablesDef = { tables } ;
339325 this . typespace = typespace ;
@@ -597,7 +583,7 @@ export type InferSchema<SchemaDef extends Schema<any>> =
597583 * );
598584 * ```
599585 */
600- export function schema < const H extends readonly TableSchema < any , any , any > [ ] > (
586+ export function schema < const H extends readonly UntypedTableSchema [ ] > (
601587 ...handles : H
602588) : Schema < TablesToSchema < H > > ;
603589
@@ -606,7 +592,7 @@ export function schema<const H extends readonly TableSchema<any, any, any>[]>(
606592 * @param handles - Array of table handles created by table() function
607593 * @returns ColumnBuilder representing the complete database schema
608594 */
609- export function schema < const H extends readonly TableSchema < any , any , any > [ ] > (
595+ export function schema < const H extends readonly UntypedTableSchema [ ] > (
610596 handles : H
611597) : Schema < TablesToSchema < H > > ;
612598
@@ -622,7 +608,7 @@ export function schema<const H extends readonly TableSchema<any, any, any>[]>(
622608 * );
623609 * ```
624610 */
625- export function schema < const H extends readonly TableSchema < any , any , any > [ ] > (
611+ export function schema < const H extends readonly UntypedTableSchema [ ] > (
626612 ...args : [ H ] | H
627613) : Schema < TablesToSchema < H > > {
628614 const handles = (
0 commit comments