Skip to content

Commit 5091fe8

Browse files
gulfarazsoedirgo
authored andcommitted
fix: array types should not unknown fixes supabase#581
1 parent a4df508 commit 5091fe8

File tree

5 files changed

+46
-63
lines changed

5 files changed

+46
-63
lines changed

Diff for: src/server/routes/generators/typescript.ts

+1-2
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
})

Diff for: src/server/server.ts

+1-2
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
)

Diff for: src/server/templates/typescript.ts

+17-57
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[]>(
@@ -102,12 +100,9 @@ export type Database = {
102100
...schemaFunctions
103101
.filter((fn) => fn.argument_types === table.name)
104102
.map((fn) => {
105-
const type = types.find(({ id }) => id === fn.return_type_id)
106-
let tsType = 'unknown'
107-
if (type) {
108-
tsType = pgTypeToTsType(type.name, types, schemas)
109-
}
110-
return `${JSON.stringify(fn.name)}: ${tsType} | null`
103+
const pgType = types.find(({ id }) => id === fn.return_type_id)
104+
const type = pgTypeToTsType(pgType?.name, types, schemas)
105+
return `${JSON.stringify(fn.name)}: ${type} | null`
111106
}),
112107
]}
113108
}
@@ -289,25 +284,9 @@ export type Database = {
289284
}
290285
291286
const argsNameAndType = inArgs.map(({ name, type_id, has_default }) => {
292-
let type = arrayTypes.find(({ id }) => id === type_id)
293-
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-
}
309-
}
310-
return { name, type: 'unknown', has_default }
287+
const pgType = types.find(({ id }) => id === type_id)
288+
const type = pgTypeToTsType(pgType?.name, types, schemas)
289+
return { name, type, has_default }
311290
})
312291
313292
return `{
@@ -322,20 +301,9 @@ export type Database = {
322301
const tableArgs = args.filter(({ mode }) => mode === 'table')
323302
if (tableArgs.length > 0) {
324303
const argsNameAndType = tableArgs.map(({ name, type_id }) => {
325-
let type = arrayTypes.find(({ id }) => id === type_id)
326-
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-
}
333-
}
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' }
304+
const pgType = types.find(({ id }) => id === type_id)
305+
const type = pgTypeToTsType(pgType?.name, types, schemas)
306+
return { name, type }
339307
})
340308
341309
return `{
@@ -364,11 +332,7 @@ export type Database = {
364332
365333
// Case 3: returns base/composite/enum type.
366334
const type = types.find(({ id }) => id === return_type_id)
367-
if (type) {
368-
return pgTypeToTsType(type.name, types, schemas)
369-
}
370-
371-
return 'unknown'
335+
return pgTypeToTsType(type?.name, types, schemas)
372336
})()})${is_set_returning_function ? '[]' : ''}
373337
}`
374338
)
@@ -398,15 +362,9 @@ export type Database = {
398362
({ name, attributes }) =>
399363
`${JSON.stringify(name)}: {
400364
${attributes.map(({ name, type_id }) => {
401-
const type = types.find(({ id }) => id === type_id)
402-
if (type) {
403-
return `${JSON.stringify(name)}: ${pgTypeToTsType(
404-
type.name,
405-
types,
406-
schemas
407-
)}`
408-
}
409-
return `${JSON.stringify(name)}: unknown`
365+
const pgType = types.find(({ id }) => id === type_id)
366+
const type = pgTypeToTsType(pgType?.name, types, schemas)
367+
return `${JSON.stringify(name)}: ${type}`
410368
})}
411369
}`
412370
)
@@ -506,11 +464,13 @@ export type Enums<
506464

507465
// TODO: Make this more robust. Currently doesn't handle range types - returns them as unknown.
508466
const pgTypeToTsType = (
509-
pgType: string,
467+
pgType: string | undefined,
510468
types: PostgresType[],
511469
schemas: PostgresSchema[]
512470
): string => {
513-
if (pgType === 'bool') {
471+
if (pgType === undefined) {
472+
return 'unknown'
473+
} else if (pgType === 'bool') {
514474
return 'boolean'
515475
} else if (['int2', 'int4', 'int8', 'float4', 'float8', 'numeric'].includes(pgType)) {
516476
return 'number'

Diff for: test/db/00-init.sql

+7
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 array_type 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');

Diff for: test/server/typegen.ts

+20-2
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+
array_type: {
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+
array_type: {
858+
my_text_array: string[]
859+
}
842860
}
843861
}
844862
}

0 commit comments

Comments
 (0)