Skip to content

Commit e71702d

Browse files
committed
Refactored relationship validation to include type validation and partial matches
1 parent ee1fa6f commit e71702d

File tree

10 files changed

+1606
-1881
lines changed

10 files changed

+1606
-1881
lines changed

plan.md

Lines changed: 0 additions & 1619 deletions
This file was deleted.

src/packages/dumbo/src/core/schema/components/databaseSchemaSchemaComponent.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,26 +12,28 @@ import {
1212
} from './tableSchemaComponent';
1313

1414
export type DatabaseSchemaURNType = 'sc:dumbo:database_schema';
15-
export type DatabaseSchemaURN = `${DatabaseSchemaURNType}:${string}`;
15+
export type DatabaseSchemaURN<SchemaName extends string = string> =
16+
`${DatabaseSchemaURNType}:${SchemaName}`;
1617

1718
export const DatabaseSchemaURNType: DatabaseSchemaURNType =
1819
'sc:dumbo:database_schema';
19-
export const DatabaseSchemaURN = ({
20+
export const DatabaseSchemaURN = <SchemaName extends string = string>({
2021
name,
2122
}: {
22-
name: string;
23-
}): DatabaseSchemaURN => `${DatabaseSchemaURNType}:${name}`;
23+
name: SchemaName;
24+
}): DatabaseSchemaURN<SchemaName> => `${DatabaseSchemaURNType}:${name}`;
2425

2526
export type DatabaseSchemaTables<
2627
Tables extends AnyTableSchemaComponent = AnyTableSchemaComponent,
2728
> = Record<string, Tables>;
2829

2930
export type DatabaseSchemaSchemaComponent<
3031
Tables extends DatabaseSchemaTables = DatabaseSchemaTables,
32+
SchemaName extends string = string,
3133
> = SchemaComponent<
32-
DatabaseSchemaURN,
34+
DatabaseSchemaURN<SchemaName>,
3335
Readonly<{
34-
schemaName: string;
36+
schemaName: SchemaName;
3537
tables: ReadonlyMap<string, TableSchemaComponent> & Tables;
3638
addTable: (table: string | TableSchemaComponent) => TableSchemaComponent;
3739
}>
@@ -42,15 +44,19 @@ export type AnyDatabaseSchemaSchemaComponent =
4244
DatabaseSchemaSchemaComponent<any>;
4345

4446
export const databaseSchemaSchemaComponent = <
45-
Tables extends DatabaseSchemaTables = DatabaseSchemaTables,
47+
const Tables extends DatabaseSchemaTables = DatabaseSchemaTables,
48+
const SchemaName extends string = string,
4649
>({
4750
schemaName,
4851
tables,
4952
...migrationsOrComponents
5053
}: {
51-
schemaName: string;
54+
schemaName: SchemaName;
5255
tables?: Tables;
53-
} & SchemaComponentOptions): DatabaseSchemaSchemaComponent<Tables> => {
56+
} & SchemaComponentOptions): DatabaseSchemaSchemaComponent<
57+
Tables,
58+
SchemaName
59+
> => {
5460
const base = schemaComponent(DatabaseSchemaURN({ name: schemaName }), {
5561
migrations: migrationsOrComponents.migrations ?? [],
5662
components: [

src/packages/dumbo/src/core/schema/components/relationships/relationshipTypes.ts

Lines changed: 116 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ import type {
88
TableColumnNames,
99
TableColumns,
1010
TableSchemaComponent,
11+
Writable,
1112
} from '..';
13+
import type { ColumnTypeToken } from '../../../sql/tokens/columnTokens';
1214

1315
export type ExtractSchemaNames<DB> =
1416
DB extends DatabaseSchemaComponent<infer Schemas extends DatabaseSchemas>
@@ -27,24 +29,124 @@ export type ExtractColumnNames<Table extends AnyTableSchemaComponent> =
2729
? TableColumnNames<TableSchemaComponent<Columns>>
2830
: never;
2931

30-
export type AllColumnReferences<DB> =
31-
DB extends DatabaseSchemaComponent<infer Schemas extends DatabaseSchemas>
32+
export type ExtractColumnTypeName<T> =
33+
T extends ColumnTypeToken<
34+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
35+
any,
36+
infer TypeName,
37+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
38+
any,
39+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
40+
any
41+
>
42+
? Uppercase<TypeName & string>
43+
: never;
44+
45+
export type AllColumnTypes<Schemas extends DatabaseSchemas> = {
46+
[SchemaName in keyof Schemas]: Schemas[SchemaName] extends DatabaseSchemaSchemaComponent<
47+
infer Tables
48+
>
49+
? Writable<{
50+
[TableName in keyof Tables]: Tables[TableName] extends TableSchemaComponent<
51+
infer Columns
52+
>
53+
? Writable<{
54+
[ColumnName in keyof Columns]: {
55+
columnTypeName: ExtractColumnTypeName<
56+
Columns[ColumnName]['type']
57+
>;
58+
};
59+
}>
60+
: never;
61+
}>
62+
: never;
63+
};
64+
65+
export type AllColumnReferences<Schemas extends DatabaseSchemas> = {
66+
[SchemaName in keyof Schemas]: Schemas[SchemaName] extends DatabaseSchemaSchemaComponent<
67+
infer Tables
68+
>
69+
? {
70+
[TableName in keyof Tables]: Tables[TableName] extends TableSchemaComponent<
71+
infer Columns
72+
>
73+
? {
74+
[ColumnName in keyof Columns]: `${SchemaName &
75+
string}.${TableName & string}.${ColumnName & string}`;
76+
}[keyof Columns]
77+
: never;
78+
}[keyof Tables]
79+
: never;
80+
}[keyof Schemas];
81+
82+
export type AllColumnTypesInSchema<
83+
Schema extends AnyDatabaseSchemaSchemaComponent,
84+
> =
85+
Schema extends DatabaseSchemaSchemaComponent<infer Tables>
86+
? {
87+
[TableName in keyof Tables]: Tables[TableName] extends TableSchemaComponent<
88+
infer Columns
89+
>
90+
? {
91+
[ColumnName in keyof Columns]: {
92+
columnTypeName: ExtractColumnTypeName<
93+
Columns[ColumnName]['type']
94+
>;
95+
};
96+
}
97+
: never;
98+
}
99+
: never;
100+
101+
export type AllColumnReferencesInSchema<
102+
Schema extends AnyDatabaseSchemaSchemaComponent,
103+
SchemaName extends string,
104+
> =
105+
Schema extends DatabaseSchemaSchemaComponent<infer Tables>
32106
? {
33-
[SchemaName in keyof Schemas]: Schemas[SchemaName] extends DatabaseSchemaSchemaComponent<
34-
infer Tables
107+
[TableName in keyof Tables]: Tables[TableName] extends TableSchemaComponent<
108+
infer Columns
35109
>
36110
? {
37-
[TableName in keyof Tables]: Tables[TableName] extends TableSchemaComponent<
38-
infer Columns
39-
>
40-
? {
41-
[ColumnName in keyof Columns]: `${SchemaName &
42-
string}.${TableName & string}.${ColumnName & string}`;
43-
}[keyof Columns]
44-
: never;
45-
}[keyof Tables]
111+
[ColumnName in keyof Columns]: `${SchemaName & string}.${TableName &
112+
string}.${ColumnName & string}`;
113+
}[keyof Columns]
46114
: never;
47-
}[keyof Schemas]
115+
}[keyof Tables]
116+
: never;
117+
118+
export type NormalizeReferencePath<
119+
Path extends string,
120+
CurrentSchema extends string,
121+
CurrentTable extends string,
122+
> = Path extends `${infer Schema}.${infer Table}.${infer Column}`
123+
? `${Schema}.${Table}.${Column}`
124+
: Path extends `${infer Table}.${infer Column}`
125+
? `${CurrentSchema}.${Table}.${Column}`
126+
: Path extends string
127+
? `${CurrentSchema}.${CurrentTable}.${Path}`
128+
: never;
129+
130+
export type ParseReferencePath<Path extends string> =
131+
Path extends `${infer Schema}.${infer Table}.${infer Column}`
132+
? { schema: Schema; table: Table; column: Column }
133+
: never;
134+
135+
export type LookupColumnType<AllTypes, Path extends string> =
136+
ParseReferencePath<Path> extends {
137+
schema: infer S;
138+
table: infer T;
139+
column: infer C;
140+
}
141+
? S extends keyof AllTypes
142+
? T extends keyof AllTypes[S]
143+
? C extends keyof AllTypes[S][T]
144+
? AllTypes[S][T][C] extends { columnTypeName: infer TypeName }
145+
? TypeName
146+
: never
147+
: never
148+
: never
149+
: never
48150
: never;
49151

50152
export type RelationshipType =

0 commit comments

Comments
 (0)