Skip to content

Commit 4364d40

Browse files
gulfarazsoedirgo
andauthored
fix(typegen): array types are unknown in computed fields & composite types (#703)
* fix: array types should not unknown fixes #581 * chore: update test random ids * chore: keep pgType arg non-undefined It should be the resposibility of the caller to make sure the argument is defined * chore: clarify type name --------- Co-authored-by: Bobbie Soedirgo <[email protected]>
1 parent a4df508 commit 4364d40

File tree

8 files changed

+59
-62
lines changed

8 files changed

+59
-62
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
"db:clean": "cd test/db && docker-compose down",
3030
"db:run": "cd test/db && docker-compose up --detach && sleep 5",
3131
"test:run": "vitest run",
32-
"test:update": "run-s db:clean db:run && vitest run && run-s db:clean"
32+
"test:update": "run-s db:clean db:run && vitest run --update && run-s db:clean"
3333
},
3434
"engines": {
3535
"node": ">=20",

src/server/routes/generators/typescript.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,7 @@ export default async (fastify: FastifyInstance) => {
111111
functions: functions.filter(
112112
({ return_type }) => !['trigger', 'event_trigger'].includes(return_type)
113113
),
114-
types: types.filter(({ name }) => name[0] !== '_'),
115-
arrayTypes: types.filter(({ name }) => name[0] === '_'),
114+
types,
116115
detectOneToOneRelationships,
117116
})
118117
})

src/server/server.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,7 @@ if (EXPORT_DOCS) {
120120
functions: functions!.filter(
121121
({ return_type }) => !['trigger', 'event_trigger'].includes(return_type)
122122
),
123-
types: types!.filter(({ name }) => name[0] !== '_'),
124-
arrayTypes: types!.filter(({ name }) => name[0] === '_'),
123+
types: types!,
125124
detectOneToOneRelationships: GENERATE_TYPES_DETECT_ONE_TO_ONE_RELATIONSHIPS,
126125
})
127126
)

src/server/templates/typescript.ts

Lines changed: 12 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ export const apply = async ({
1919
relationships,
2020
functions,
2121
types,
22-
arrayTypes,
2322
detectOneToOneRelationships,
2423
}: {
2524
schemas: PostgresSchema[]
@@ -30,7 +29,6 @@ export const apply = async ({
3029
relationships: PostgresRelationship[]
3130
functions: PostgresFunction[]
3231
types: PostgresType[]
33-
arrayTypes: PostgresType[]
3432
detectOneToOneRelationships: boolean
3533
}): Promise<string> => {
3634
const columnsByTableId = Object.fromEntries<PostgresColumn[]>(
@@ -289,25 +287,12 @@ export type Database = {
289287
}
290288
291289
const argsNameAndType = inArgs.map(({ name, type_id, has_default }) => {
292-
let type = arrayTypes.find(({ id }) => id === type_id)
290+
const type = types.find(({ id }) => id === type_id)
291+
let tsType = 'unknown'
293292
if (type) {
294-
// If it's an array type, the name looks like `_int8`.
295-
const elementTypeName = type.name.substring(1)
296-
return {
297-
name,
298-
type: `(${pgTypeToTsType(elementTypeName, types, schemas)})[]`,
299-
has_default,
300-
}
301-
}
302-
type = types.find(({ id }) => id === type_id)
303-
if (type) {
304-
return {
305-
name,
306-
type: pgTypeToTsType(type.name, types, schemas),
307-
has_default,
308-
}
293+
tsType = pgTypeToTsType(type.name, types, schemas)
309294
}
310-
return { name, type: 'unknown', has_default }
295+
return { name, type: tsType, has_default }
311296
})
312297
313298
return `{
@@ -322,20 +307,12 @@ export type Database = {
322307
const tableArgs = args.filter(({ mode }) => mode === 'table')
323308
if (tableArgs.length > 0) {
324309
const argsNameAndType = tableArgs.map(({ name, type_id }) => {
325-
let type = arrayTypes.find(({ id }) => id === type_id)
310+
const type = types.find(({ id }) => id === type_id)
311+
let tsType = 'unknown'
326312
if (type) {
327-
// If it's an array type, the name looks like `_int8`.
328-
const elementTypeName = type.name.substring(1)
329-
return {
330-
name,
331-
type: `(${pgTypeToTsType(elementTypeName, types, schemas)})[]`,
332-
}
313+
tsType = pgTypeToTsType(type.name, types, schemas)
333314
}
334-
type = types.find(({ id }) => id === type_id)
335-
if (type) {
336-
return { name, type: pgTypeToTsType(type.name, types, schemas) }
337-
}
338-
return { name, type: 'unknown' }
315+
return { name, type: tsType }
339316
})
340317
341318
return `{
@@ -362,7 +339,7 @@ export type Database = {
362339
}`
363340
}
364341
365-
// Case 3: returns base/composite/enum type.
342+
// Case 3: returns base/array/composite/enum type.
366343
const type = types.find(({ id }) => id === return_type_id)
367344
if (type) {
368345
return pgTypeToTsType(type.name, types, schemas)
@@ -399,14 +376,11 @@ export type Database = {
399376
`${JSON.stringify(name)}: {
400377
${attributes.map(({ name, type_id }) => {
401378
const type = types.find(({ id }) => id === type_id)
379+
let tsType = 'unknown'
402380
if (type) {
403-
return `${JSON.stringify(name)}: ${pgTypeToTsType(
404-
type.name,
405-
types,
406-
schemas
407-
)}`
381+
tsType = pgTypeToTsType(type.name, types, schemas)
408382
}
409-
return `${JSON.stringify(name)}: unknown`
383+
return `${JSON.stringify(name)}: ${tsType}`
410384
})}
411385
}`
412386
)

test/db/00-init.sql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
-- Tables for testing
44

55
CREATE TYPE public.user_status AS ENUM ('ACTIVE', 'INACTIVE');
6+
CREATE TYPE composite_type_with_array_attribute AS (my_text_array text[]);
7+
68
CREATE TABLE public.users (
79
id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
810
name text,
@@ -76,6 +78,11 @@ $$
7678
select $1.details_length > 20;
7779
$$ language sql stable;
7880

81+
create function public.details_words(public.todos) returns text[] as
82+
$$
83+
select string_to_array($1.details, ' ');
84+
$$ language sql stable;
85+
7986
create extension postgres_fdw;
8087
create server foreign_server foreign data wrapper postgres_fdw options (host 'localhost', port '5432', dbname 'postgres');
8188
create user mapping for postgres server foreign_server options (user 'postgres', password 'postgres');

test/lib/views.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ test('list', async () => {
1515
"default_value": null,
1616
"enums": [],
1717
"format": "int8",
18-
"id": "16420.1",
18+
"id": "16423.1",
1919
"identity_generation": null,
2020
"is_generated": false,
2121
"is_identity": false,
@@ -26,7 +26,7 @@ test('list', async () => {
2626
"ordinal_position": 1,
2727
"schema": "public",
2828
"table": "todos_view",
29-
"table_id": 16420,
29+
"table_id": 16423,
3030
},
3131
{
3232
"check": null,
@@ -35,7 +35,7 @@ test('list', async () => {
3535
"default_value": null,
3636
"enums": [],
3737
"format": "text",
38-
"id": "16420.2",
38+
"id": "16423.2",
3939
"identity_generation": null,
4040
"is_generated": false,
4141
"is_identity": false,
@@ -46,7 +46,7 @@ test('list', async () => {
4646
"ordinal_position": 2,
4747
"schema": "public",
4848
"table": "todos_view",
49-
"table_id": 16420,
49+
"table_id": 16423,
5050
},
5151
{
5252
"check": null,
@@ -55,7 +55,7 @@ test('list', async () => {
5555
"default_value": null,
5656
"enums": [],
5757
"format": "int8",
58-
"id": "16420.3",
58+
"id": "16423.3",
5959
"identity_generation": null,
6060
"is_generated": false,
6161
"is_identity": false,
@@ -66,7 +66,7 @@ test('list', async () => {
6666
"ordinal_position": 3,
6767
"schema": "public",
6868
"table": "todos_view",
69-
"table_id": 16420,
69+
"table_id": 16423,
7070
},
7171
],
7272
"comment": null,
@@ -112,7 +112,7 @@ test('retrieve', async () => {
112112
"default_value": null,
113113
"enums": [],
114114
"format": "int8",
115-
"id": "16420.1",
115+
"id": "16423.1",
116116
"identity_generation": null,
117117
"is_generated": false,
118118
"is_identity": false,
@@ -123,7 +123,7 @@ test('retrieve', async () => {
123123
"ordinal_position": 1,
124124
"schema": "public",
125125
"table": "todos_view",
126-
"table_id": 16420,
126+
"table_id": 16423,
127127
},
128128
{
129129
"check": null,
@@ -132,7 +132,7 @@ test('retrieve', async () => {
132132
"default_value": null,
133133
"enums": [],
134134
"format": "text",
135-
"id": "16420.2",
135+
"id": "16423.2",
136136
"identity_generation": null,
137137
"is_generated": false,
138138
"is_identity": false,
@@ -143,7 +143,7 @@ test('retrieve', async () => {
143143
"ordinal_position": 2,
144144
"schema": "public",
145145
"table": "todos_view",
146-
"table_id": 16420,
146+
"table_id": 16423,
147147
},
148148
{
149149
"check": null,
@@ -152,7 +152,7 @@ test('retrieve', async () => {
152152
"default_value": null,
153153
"enums": [],
154154
"format": "int8",
155-
"id": "16420.3",
155+
"id": "16423.3",
156156
"identity_generation": null,
157157
"is_generated": false,
158158
"is_identity": false,
@@ -163,7 +163,7 @@ test('retrieve', async () => {
163163
"ordinal_position": 3,
164164
"schema": "public",
165165
"table": "todos_view",
166-
"table_id": 16420,
166+
"table_id": 16423,
167167
},
168168
],
169169
"comment": null,

test/server/indexes.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ test('list indexes', async () => {
1818
"class": "3124",
1919
"collation": "0",
2020
"comment": null,
21-
"id": 16396,
21+
"id": 16399,
2222
"index_attributes": [
2323
{
2424
"attribute_name": "id",
@@ -42,14 +42,14 @@ test('list indexes', async () => {
4242
"number_of_key_attributes": 1,
4343
"options": "0",
4444
"schema": "public",
45-
"table_id": 16390,
45+
"table_id": 16393,
4646
}
4747
`
4848
)
4949
})
5050

5151
test('retrieve index', async () => {
52-
const res = await app.inject({ method: 'GET', path: '/indexes/16396' })
52+
const res = await app.inject({ method: 'GET', path: '/indexes/16399' })
5353
const index = res.json<PostgresIndex>()
5454
expect(index).toMatchInlineSnapshot(
5555
`
@@ -59,7 +59,7 @@ test('retrieve index', async () => {
5959
"class": "3124",
6060
"collation": "0",
6161
"comment": null,
62-
"id": 16396,
62+
"id": 16399,
6363
"index_attributes": [
6464
{
6565
"attribute_name": "id",
@@ -83,7 +83,7 @@ test('retrieve index', async () => {
8383
"number_of_key_attributes": 1,
8484
"options": "0",
8585
"schema": "public",
86-
"table_id": 16390,
86+
"table_id": 16393,
8787
}
8888
`
8989
)

test/server/typegen.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ test('typegen', async () => {
7979
blurb_varchar: string | null
8080
details_is_long: boolean | null
8181
details_length: number | null
82+
details_words: string[] | null
8283
}
8384
Insert: {
8485
details?: string | null
@@ -306,6 +307,12 @@ test('typegen', async () => {
306307
}
307308
Returns: number
308309
}
310+
details_words: {
311+
Args: {
312+
"": unknown
313+
}
314+
Returns: string[]
315+
}
309316
function_returning_row: {
310317
Args: Record<PropertyKey, never>
311318
Returns: {
@@ -366,7 +373,9 @@ test('typegen', async () => {
366373
user_status: "ACTIVE" | "INACTIVE"
367374
}
368375
CompositeTypes: {
369-
[_ in never]: never
376+
composite_type_with_array_attribute: {
377+
my_text_array: string[]
378+
}
370379
}
371380
}
372381
}
@@ -539,6 +548,7 @@ test('typegen w/ one-to-one relationships', async () => {
539548
blurb_varchar: string | null
540549
details_is_long: boolean | null
541550
details_length: number | null
551+
details_words: string[] | null
542552
}
543553
Insert: {
544554
details?: string | null
@@ -778,6 +788,12 @@ test('typegen w/ one-to-one relationships', async () => {
778788
}
779789
Returns: number
780790
}
791+
details_words: {
792+
Args: {
793+
"": unknown
794+
}
795+
Returns: string[]
796+
}
781797
function_returning_row: {
782798
Args: Record<PropertyKey, never>
783799
Returns: {
@@ -838,7 +854,9 @@ test('typegen w/ one-to-one relationships', async () => {
838854
user_status: "ACTIVE" | "INACTIVE"
839855
}
840856
CompositeTypes: {
841-
[_ in never]: never
857+
composite_type_with_array_attribute: {
858+
my_text_array: string[]
859+
}
842860
}
843861
}
844862
}

0 commit comments

Comments
 (0)