Skip to content

Commit

Permalink
fix(typegen): array types are unknown in computed fields & composit…
Browse files Browse the repository at this point in the history
…e 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]>
  • Loading branch information
gulfaraz and soedirgo authored Mar 6, 2024
1 parent a4df508 commit 4364d40
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 62 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"db:clean": "cd test/db && docker-compose down",
"db:run": "cd test/db && docker-compose up --detach && sleep 5",
"test:run": "vitest run",
"test:update": "run-s db:clean db:run && vitest run && run-s db:clean"
"test:update": "run-s db:clean db:run && vitest run --update && run-s db:clean"
},
"engines": {
"node": ">=20",
Expand Down
3 changes: 1 addition & 2 deletions src/server/routes/generators/typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,7 @@ export default async (fastify: FastifyInstance) => {
functions: functions.filter(
({ return_type }) => !['trigger', 'event_trigger'].includes(return_type)
),
types: types.filter(({ name }) => name[0] !== '_'),
arrayTypes: types.filter(({ name }) => name[0] === '_'),
types,
detectOneToOneRelationships,
})
})
Expand Down
3 changes: 1 addition & 2 deletions src/server/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,7 @@ if (EXPORT_DOCS) {
functions: functions!.filter(
({ return_type }) => !['trigger', 'event_trigger'].includes(return_type)
),
types: types!.filter(({ name }) => name[0] !== '_'),
arrayTypes: types!.filter(({ name }) => name[0] === '_'),
types: types!,
detectOneToOneRelationships: GENERATE_TYPES_DETECT_ONE_TO_ONE_RELATIONSHIPS,
})
)
Expand Down
50 changes: 12 additions & 38 deletions src/server/templates/typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ export const apply = async ({
relationships,
functions,
types,
arrayTypes,
detectOneToOneRelationships,
}: {
schemas: PostgresSchema[]
Expand All @@ -30,7 +29,6 @@ export const apply = async ({
relationships: PostgresRelationship[]
functions: PostgresFunction[]
types: PostgresType[]
arrayTypes: PostgresType[]
detectOneToOneRelationships: boolean
}): Promise<string> => {
const columnsByTableId = Object.fromEntries<PostgresColumn[]>(
Expand Down Expand Up @@ -289,25 +287,12 @@ export type Database = {
}
const argsNameAndType = inArgs.map(({ name, type_id, has_default }) => {
let type = arrayTypes.find(({ id }) => id === type_id)
const type = types.find(({ id }) => id === type_id)
let tsType = 'unknown'
if (type) {
// If it's an array type, the name looks like `_int8`.
const elementTypeName = type.name.substring(1)
return {
name,
type: `(${pgTypeToTsType(elementTypeName, types, schemas)})[]`,
has_default,
}
}
type = types.find(({ id }) => id === type_id)
if (type) {
return {
name,
type: pgTypeToTsType(type.name, types, schemas),
has_default,
}
tsType = pgTypeToTsType(type.name, types, schemas)
}
return { name, type: 'unknown', has_default }
return { name, type: tsType, has_default }
})
return `{
Expand All @@ -322,20 +307,12 @@ export type Database = {
const tableArgs = args.filter(({ mode }) => mode === 'table')
if (tableArgs.length > 0) {
const argsNameAndType = tableArgs.map(({ name, type_id }) => {
let type = arrayTypes.find(({ id }) => id === type_id)
const type = types.find(({ id }) => id === type_id)
let tsType = 'unknown'
if (type) {
// If it's an array type, the name looks like `_int8`.
const elementTypeName = type.name.substring(1)
return {
name,
type: `(${pgTypeToTsType(elementTypeName, types, schemas)})[]`,
}
tsType = pgTypeToTsType(type.name, types, schemas)
}
type = types.find(({ id }) => id === type_id)
if (type) {
return { name, type: pgTypeToTsType(type.name, types, schemas) }
}
return { name, type: 'unknown' }
return { name, type: tsType }
})
return `{
Expand All @@ -362,7 +339,7 @@ export type Database = {
}`
}
// Case 3: returns base/composite/enum type.
// Case 3: returns base/array/composite/enum type.
const type = types.find(({ id }) => id === return_type_id)
if (type) {
return pgTypeToTsType(type.name, types, schemas)
Expand Down Expand Up @@ -399,14 +376,11 @@ export type Database = {
`${JSON.stringify(name)}: {
${attributes.map(({ name, type_id }) => {
const type = types.find(({ id }) => id === type_id)
let tsType = 'unknown'
if (type) {
return `${JSON.stringify(name)}: ${pgTypeToTsType(
type.name,
types,
schemas
)}`
tsType = pgTypeToTsType(type.name, types, schemas)
}
return `${JSON.stringify(name)}: unknown`
return `${JSON.stringify(name)}: ${tsType}`
})}
}`
)
Expand Down
7 changes: 7 additions & 0 deletions test/db/00-init.sql
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
-- Tables for testing

CREATE TYPE public.user_status AS ENUM ('ACTIVE', 'INACTIVE');
CREATE TYPE composite_type_with_array_attribute AS (my_text_array text[]);

CREATE TABLE public.users (
id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
name text,
Expand Down Expand Up @@ -76,6 +78,11 @@ $$
select $1.details_length > 20;
$$ language sql stable;

create function public.details_words(public.todos) returns text[] as
$$
select string_to_array($1.details, ' ');
$$ language sql stable;

create extension postgres_fdw;
create server foreign_server foreign data wrapper postgres_fdw options (host 'localhost', port '5432', dbname 'postgres');
create user mapping for postgres server foreign_server options (user 'postgres', password 'postgres');
Expand Down
24 changes: 12 additions & 12 deletions test/lib/views.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ test('list', async () => {
"default_value": null,
"enums": [],
"format": "int8",
"id": "16420.1",
"id": "16423.1",
"identity_generation": null,
"is_generated": false,
"is_identity": false,
Expand All @@ -26,7 +26,7 @@ test('list', async () => {
"ordinal_position": 1,
"schema": "public",
"table": "todos_view",
"table_id": 16420,
"table_id": 16423,
},
{
"check": null,
Expand All @@ -35,7 +35,7 @@ test('list', async () => {
"default_value": null,
"enums": [],
"format": "text",
"id": "16420.2",
"id": "16423.2",
"identity_generation": null,
"is_generated": false,
"is_identity": false,
Expand All @@ -46,7 +46,7 @@ test('list', async () => {
"ordinal_position": 2,
"schema": "public",
"table": "todos_view",
"table_id": 16420,
"table_id": 16423,
},
{
"check": null,
Expand All @@ -55,7 +55,7 @@ test('list', async () => {
"default_value": null,
"enums": [],
"format": "int8",
"id": "16420.3",
"id": "16423.3",
"identity_generation": null,
"is_generated": false,
"is_identity": false,
Expand All @@ -66,7 +66,7 @@ test('list', async () => {
"ordinal_position": 3,
"schema": "public",
"table": "todos_view",
"table_id": 16420,
"table_id": 16423,
},
],
"comment": null,
Expand Down Expand Up @@ -112,7 +112,7 @@ test('retrieve', async () => {
"default_value": null,
"enums": [],
"format": "int8",
"id": "16420.1",
"id": "16423.1",
"identity_generation": null,
"is_generated": false,
"is_identity": false,
Expand All @@ -123,7 +123,7 @@ test('retrieve', async () => {
"ordinal_position": 1,
"schema": "public",
"table": "todos_view",
"table_id": 16420,
"table_id": 16423,
},
{
"check": null,
Expand All @@ -132,7 +132,7 @@ test('retrieve', async () => {
"default_value": null,
"enums": [],
"format": "text",
"id": "16420.2",
"id": "16423.2",
"identity_generation": null,
"is_generated": false,
"is_identity": false,
Expand All @@ -143,7 +143,7 @@ test('retrieve', async () => {
"ordinal_position": 2,
"schema": "public",
"table": "todos_view",
"table_id": 16420,
"table_id": 16423,
},
{
"check": null,
Expand All @@ -152,7 +152,7 @@ test('retrieve', async () => {
"default_value": null,
"enums": [],
"format": "int8",
"id": "16420.3",
"id": "16423.3",
"identity_generation": null,
"is_generated": false,
"is_identity": false,
Expand All @@ -163,7 +163,7 @@ test('retrieve', async () => {
"ordinal_position": 3,
"schema": "public",
"table": "todos_view",
"table_id": 16420,
"table_id": 16423,
},
],
"comment": null,
Expand Down
10 changes: 5 additions & 5 deletions test/server/indexes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ test('list indexes', async () => {
"class": "3124",
"collation": "0",
"comment": null,
"id": 16396,
"id": 16399,
"index_attributes": [
{
"attribute_name": "id",
Expand All @@ -42,14 +42,14 @@ test('list indexes', async () => {
"number_of_key_attributes": 1,
"options": "0",
"schema": "public",
"table_id": 16390,
"table_id": 16393,
}
`
)
})

test('retrieve index', async () => {
const res = await app.inject({ method: 'GET', path: '/indexes/16396' })
const res = await app.inject({ method: 'GET', path: '/indexes/16399' })
const index = res.json<PostgresIndex>()
expect(index).toMatchInlineSnapshot(
`
Expand All @@ -59,7 +59,7 @@ test('retrieve index', async () => {
"class": "3124",
"collation": "0",
"comment": null,
"id": 16396,
"id": 16399,
"index_attributes": [
{
"attribute_name": "id",
Expand All @@ -83,7 +83,7 @@ test('retrieve index', async () => {
"number_of_key_attributes": 1,
"options": "0",
"schema": "public",
"table_id": 16390,
"table_id": 16393,
}
`
)
Expand Down
22 changes: 20 additions & 2 deletions test/server/typegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ test('typegen', async () => {
blurb_varchar: string | null
details_is_long: boolean | null
details_length: number | null
details_words: string[] | null
}
Insert: {
details?: string | null
Expand Down Expand Up @@ -306,6 +307,12 @@ test('typegen', async () => {
}
Returns: number
}
details_words: {
Args: {
"": unknown
}
Returns: string[]
}
function_returning_row: {
Args: Record<PropertyKey, never>
Returns: {
Expand Down Expand Up @@ -366,7 +373,9 @@ test('typegen', async () => {
user_status: "ACTIVE" | "INACTIVE"
}
CompositeTypes: {
[_ in never]: never
composite_type_with_array_attribute: {
my_text_array: string[]
}
}
}
}
Expand Down Expand Up @@ -539,6 +548,7 @@ test('typegen w/ one-to-one relationships', async () => {
blurb_varchar: string | null
details_is_long: boolean | null
details_length: number | null
details_words: string[] | null
}
Insert: {
details?: string | null
Expand Down Expand Up @@ -778,6 +788,12 @@ test('typegen w/ one-to-one relationships', async () => {
}
Returns: number
}
details_words: {
Args: {
"": unknown
}
Returns: string[]
}
function_returning_row: {
Args: Record<PropertyKey, never>
Returns: {
Expand Down Expand Up @@ -838,7 +854,9 @@ test('typegen w/ one-to-one relationships', async () => {
user_status: "ACTIVE" | "INACTIVE"
}
CompositeTypes: {
[_ in never]: never
composite_type_with_array_attribute: {
my_text_array: string[]
}
}
}
}
Expand Down

0 comments on commit 4364d40

Please sign in to comment.