Skip to content

Commit 4a9461d

Browse files
committed
feat(typegen): enums
Context: supabase/cli#422
1 parent 4a811f1 commit 4a9461d

File tree

1 file changed

+35
-12
lines changed

1 file changed

+35
-12
lines changed

src/server/templates/typescript.ts

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export interface Database {
2828
const schemaTables = tables.filter((table) => table.schema === schema.name)
2929
const schemaViews = views.filter((view) => view.schema === schema.name)
3030
const schemaFunctions = functions.filter((func) => func.schema === schema.name)
31+
const schemaEnums = types.filter((type) => type.schema === schema.name && type.enums.length > 0)
3132
return `${JSON.stringify(schema.name)}: {
3233
Tables: {
3334
${
@@ -38,9 +39,11 @@ export interface Database {
3839
Row: {
3940
${table.columns.map(
4041
(column) =>
41-
`${JSON.stringify(column.name)}: ${pgTypeToTsType(column.format, types)} ${
42-
column.is_nullable ? '| null' : ''
43-
}`
42+
`${JSON.stringify(column.name)}: ${pgTypeToTsType(
43+
column.format,
44+
types,
45+
schemas
46+
)} ${column.is_nullable ? '| null' : ''}`
4447
)}
4548
}
4649
Insert: {
@@ -61,7 +64,7 @@ export interface Database {
6164
output += ':'
6265
}
6366
64-
output += pgTypeToTsType(column.format, types)
67+
output += pgTypeToTsType(column.format, types, schemas)
6568
6669
if (column.is_nullable) {
6770
output += '| null'
@@ -78,7 +81,7 @@ export interface Database {
7881
return `${output}?: never`
7982
}
8083
81-
output += `?: ${pgTypeToTsType(column.format, types)}`
84+
output += `?: ${pgTypeToTsType(column.format, types, schemas)}`
8285
8386
if (column.is_nullable) {
8487
output += '| null'
@@ -102,7 +105,8 @@ export interface Database {
102105
(column) =>
103106
`${JSON.stringify(column.name)}: ${pgTypeToTsType(
104107
column.format,
105-
types
108+
types,
109+
schemas
106110
)} | null`
107111
)}
108112
}
@@ -116,7 +120,7 @@ export interface Database {
116120
return `${output}?: never`
117121
}
118122
119-
output += `?: ${pgTypeToTsType(column.format, types)} | null`
123+
output += `?: ${pgTypeToTsType(column.format, types, schemas)} | null`
120124
121125
return output
122126
})}
@@ -133,7 +137,7 @@ export interface Database {
133137
return `${output}?: never`
134138
}
135139
136-
output += `?: ${pgTypeToTsType(column.format, types)} | null`
140+
output += `?: ${pgTypeToTsType(column.format, types, schemas)} | null`
137141
138142
return output
139143
})}
@@ -177,20 +181,32 @@ export interface Database {
177181
if (!type) {
178182
return { name, type: 'unknown' }
179183
}
180-
return { name, type: pgTypeToTsType(type.name, types) }
184+
return { name, type: pgTypeToTsType(type.name, types, schemas) }
181185
})
182186
183187
return `{ ${argsNameAndType.map(
184188
({ name, type }) => `${JSON.stringify(name)}: ${type}`
185189
)} }`
186190
})()}
187-
Returns: ${pgTypeToTsType(fn.return_type, types)}
191+
Returns: ${pgTypeToTsType(fn.return_type, types, schemas)}
188192
}`
189193
)
190194
.join('|')}`
191195
)
192196
})()}
193197
}
198+
Enums: {
199+
${
200+
schemaEnums.length === 0
201+
? '[_ in never]: never'
202+
: schemaEnums.map(
203+
(enum_) =>
204+
`${JSON.stringify(enum_.name)}: ${enum_.enums
205+
.map((variant) => JSON.stringify(variant))
206+
.join('|')}`
207+
)
208+
}
209+
}
194210
}`
195211
})}
196212
}`
@@ -202,7 +218,11 @@ export interface Database {
202218
}
203219

204220
// TODO: Make this more robust. Currently doesn't handle composite types - returns them as unknown.
205-
const pgTypeToTsType = (pgType: string, types: PostgresType[]): string => {
221+
const pgTypeToTsType = (
222+
pgType: string,
223+
types: PostgresType[],
224+
schemas: PostgresSchema[]
225+
): string => {
206226
if (pgType === 'bool') {
207227
return 'boolean'
208228
} else if (['int2', 'int4', 'int8', 'float4', 'float8', 'numeric'].includes(pgType)) {
@@ -229,10 +249,13 @@ const pgTypeToTsType = (pgType: string, types: PostgresType[]): string => {
229249
} else if (pgType === 'record') {
230250
return 'Record<string, unknown>[]'
231251
} else if (pgType.startsWith('_')) {
232-
return `(${pgTypeToTsType(pgType.substring(1), types)})[]`
252+
return `(${pgTypeToTsType(pgType.substring(1), types, schemas)})[]`
233253
} else {
234254
const type = types.find((type) => type.name === pgType && type.enums.length > 0)
235255
if (type) {
256+
if (schemas.some(({ name }) => name === type.schema)) {
257+
return `Database[${JSON.stringify(type.schema)}]['Enums'][${JSON.stringify(type.name)}]`
258+
}
236259
return type.enums.map((variant) => JSON.stringify(variant)).join('|')
237260
}
238261

0 commit comments

Comments
 (0)