Skip to content

Commit 26a81fc

Browse files
committed
feat(typegen): add CompositeTypes
1 parent 9de4eac commit 26a81fc

File tree

2 files changed

+50
-13
lines changed

2 files changed

+50
-13
lines changed

src/server/templates/typescript.ts

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ export interface Database {
6060
const schemaEnums = types
6161
.filter((type) => type.schema === schema.name && type.enums.length > 0)
6262
.sort(({ name: a }, { name: b }) => a.localeCompare(b))
63+
const schemaCompositeTypes = types
64+
.filter((type) => type.schema === schema.name && type.attributes.length > 0)
65+
.sort(({ name: a }, { name: b }) => a.localeCompare(b))
6366
return `${JSON.stringify(schema.name)}: {
6467
Tables: {
6568
${
@@ -294,6 +297,28 @@ export interface Database {
294297
)
295298
}
296299
}
300+
CompositeTypes: {
301+
${
302+
schemaCompositeTypes.length === 0
303+
? '[_ in never]: never'
304+
: schemaCompositeTypes.map(
305+
({ name, attributes }) =>
306+
`${JSON.stringify(name)}: {
307+
${attributes.map(({ name, type_id }) => {
308+
const type = types.find(({ id }) => id === type_id)
309+
if (type) {
310+
return `${JSON.stringify(name)}: ${pgTypeToTsType(
311+
type.name,
312+
types,
313+
schemas
314+
)}`
315+
}
316+
return 'unknown'
317+
})}
318+
}`
319+
)
320+
}
321+
}
297322
}`
298323
})}
299324
}`
@@ -305,7 +330,7 @@ export interface Database {
305330
return output
306331
}
307332

308-
// TODO: Make this more robust. Currently doesn't handle composite types - returns them as unknown.
333+
// TODO: Make this more robust. Currently doesn't handle range types - returns them as unknown.
309334
const pgTypeToTsType = (
310335
pgType: string,
311336
types: PostgresType[],
@@ -340,12 +365,24 @@ const pgTypeToTsType = (
340365
} else if (pgType.startsWith('_')) {
341366
return `(${pgTypeToTsType(pgType.substring(1), types, schemas)})[]`
342367
} else {
343-
const type = types.find((type) => type.name === pgType && type.enums.length > 0)
344-
if (type) {
345-
if (schemas.some(({ name }) => name === type.schema)) {
346-
return `Database[${JSON.stringify(type.schema)}]['Enums'][${JSON.stringify(type.name)}]`
368+
const enumType = types.find((type) => type.name === pgType && type.enums.length > 0)
369+
if (enumType) {
370+
if (schemas.some(({ name }) => name === enumType.schema)) {
371+
return `Database[${JSON.stringify(enumType.schema)}]['Enums'][${JSON.stringify(
372+
enumType.name
373+
)}]`
374+
}
375+
return enumType.enums.map((variant) => JSON.stringify(variant)).join('|')
376+
}
377+
378+
const compositeType = types.find((type) => type.name === pgType && type.attributes.length > 0)
379+
if (compositeType) {
380+
if (schemas.some(({ name }) => name === compositeType.schema)) {
381+
return `Database[${JSON.stringify(
382+
compositeType.schema
383+
)}]['CompositeTypes'][${JSON.stringify(compositeType.name)}]`
347384
}
348-
return type.enums.map((variant) => JSON.stringify(variant)).join('|')
385+
return 'unknown'
349386
}
350387

351388
return 'unknown'

test/lib/types.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ test('list', async () => {
55
expect(res.data?.find(({ name }) => name === 'user_status')).toMatchInlineSnapshot(
66
{ id: expect.any(Number) },
77
`
8-
Object {
9-
"attributes": Array [],
8+
{
9+
"attributes": [],
1010
"comment": null,
1111
"enums": [
1212
"ACTIVE",
@@ -63,19 +63,19 @@ test('composite type attributes', async () => {
6363
expect(res.data?.find(({ name }) => name === 'test_composite')).toMatchInlineSnapshot(
6464
{ id: expect.any(Number) },
6565
`
66-
Object {
67-
"attributes": Array [
68-
Object {
66+
{
67+
"attributes": [
68+
{
6969
"name": "id",
7070
"type_id": 20,
7171
},
72-
Object {
72+
{
7373
"name": "data",
7474
"type_id": 25,
7575
},
7676
],
7777
"comment": null,
78-
"enums": Array [],
78+
"enums": [],
7979
"format": "test_composite",
8080
"id": Any<Number>,
8181
"name": "test_composite",

0 commit comments

Comments
 (0)