-
-
Notifications
You must be signed in to change notification settings - Fork 138
fix(typescript): function only have union over args #914
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -277,88 +277,74 @@ export type Database = { | |
|
||
return Object.entries(schemaFunctionsGroupedByName).map( | ||
([fnName, fns]) => | ||
`${JSON.stringify(fnName)}: ${fns | ||
.map( | ||
({ | ||
args, | ||
return_type_id, | ||
return_type_relation_id, | ||
is_set_returning_function, | ||
}) => `{ | ||
Args: ${(() => { | ||
const inArgs = args.filter(({ mode }) => mode === 'in') | ||
|
||
if (inArgs.length === 0) { | ||
return 'Record<PropertyKey, never>' | ||
} | ||
|
||
const argsNameAndType = inArgs.map(({ name, type_id, has_default }) => { | ||
const type = types.find(({ id }) => id === type_id) | ||
let tsType = 'unknown' | ||
if (type) { | ||
tsType = pgTypeToTsType(type.name, { types, schemas, tables, views }) | ||
} | ||
return { name, type: tsType, has_default } | ||
}) | ||
`${JSON.stringify(fnName)}: { | ||
Args: ${fns | ||
.map(({ args }) => { | ||
const inArgs = args.filter(({ mode }) => mode === 'in') | ||
|
||
return `{ | ||
${argsNameAndType.map( | ||
({ name, type, has_default }) => | ||
`${JSON.stringify(name)}${has_default ? '?' : ''}: ${type}` | ||
)} | ||
}` | ||
})()} | ||
Returns: (${(() => { | ||
// Case 1: `returns table`. | ||
const tableArgs = args.filter(({ mode }) => mode === 'table') | ||
if (tableArgs.length > 0) { | ||
const argsNameAndType = tableArgs.map(({ name, type_id }) => { | ||
const type = types.find(({ id }) => id === type_id) | ||
let tsType = 'unknown' | ||
if (type) { | ||
tsType = pgTypeToTsType(type.name, { types, schemas, tables, views }) | ||
if (inArgs.length === 0) { | ||
return 'Record<PropertyKey, never>' | ||
} | ||
|
||
const argsNameAndType = inArgs.map(({ name, type_id, has_default }) => { | ||
const type = types.find(({ id }) => id === type_id) | ||
let tsType = 'unknown' | ||
if (type) { | ||
tsType = pgTypeToTsType(type.name, { types, schemas, tables, views }) | ||
} | ||
return { name, type: tsType, has_default } | ||
}) | ||
return `{ ${argsNameAndType.map(({ name, type, has_default }) => `${JSON.stringify(name)}${has_default ? '?' : ''}: ${type}`)} }` | ||
}) | ||
// A function can have multiples definitions with differents args, but will always return the same type | ||
.join(' | ')} | ||
Returns: ${(() => { | ||
// Case 1: `returns table`. | ||
const tableArgs = fns[0].args.filter(({ mode }) => mode === 'table') | ||
if (tableArgs.length > 0) { | ||
const argsNameAndType = tableArgs.map(({ name, type_id }) => { | ||
const type = types.find(({ id }) => id === type_id) | ||
let tsType = 'unknown' | ||
if (type) { | ||
tsType = pgTypeToTsType(type.name, { types, schemas, tables, views }) | ||
} | ||
return { name, type: tsType } | ||
}) | ||
|
||
return `{ | ||
${argsNameAndType.map( | ||
({ name, type }) => `${JSON.stringify(name)}: ${type}` | ||
)} | ||
}` | ||
Comment on lines
+301
to
+318
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. note Single |
||
} | ||
return { name, type: tsType } | ||
}) | ||
|
||
return `{ | ||
${argsNameAndType.map( | ||
({ name, type }) => `${JSON.stringify(name)}: ${type}` | ||
)} | ||
}` | ||
} | ||
|
||
// Case 2: returns a relation's row type. | ||
const relation = [...tables, ...views].find( | ||
({ id }) => id === return_type_relation_id | ||
) | ||
if (relation) { | ||
return `{ | ||
${columnsByTableId[relation.id].map( | ||
(column) => | ||
`${JSON.stringify(column.name)}: ${pgTypeToTsType(column.format, { | ||
types, | ||
schemas, | ||
tables, | ||
views, | ||
})} ${column.is_nullable ? '| null' : ''}` | ||
)} | ||
}` | ||
} | ||
// Case 2: returns a relation's row type. | ||
const relation = [...tables, ...views].find( | ||
({ id }) => id === fns[0].return_type_relation_id | ||
) | ||
if (relation) { | ||
return `{ | ||
${columnsByTableId[relation.id].map( | ||
(column) => | ||
`${JSON.stringify(column.name)}: ${pgTypeToTsType(column.format, { | ||
types, | ||
schemas, | ||
tables, | ||
views, | ||
})} ${column.is_nullable ? '| null' : ''}` | ||
)} | ||
}` | ||
} | ||
|
||
// 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, tables, views }) | ||
} | ||
// Case 3: returns base/array/composite/enum type. | ||
const type = types.find(({ id }) => id === fns[0].return_type_id) | ||
if (type) { | ||
return pgTypeToTsType(type.name, { types, schemas, tables, views }) | ||
} | ||
|
||
return 'unknown' | ||
})()})${is_set_returning_function ? '[]' : ''} | ||
}` | ||
) | ||
// We only sorted by name on schemaFunctions - here we sort by arg names, arg types, and return type. | ||
.sort() | ||
.join('|')}` | ||
return 'unknown' | ||
})()}${fns[0].is_set_returning_function ? '[]' : ''} | ||
}` | ||
) | ||
})()} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -159,3 +159,25 @@ second_user AS ( | |
) | ||
SELECT * from initial_user iu | ||
cross join second_user su; | ||
|
||
CREATE OR REPLACE FUNCTION public.get_user_audit_setof_single_row(user_row users) | ||
RETURNS SETOF users_audit | ||
LANGUAGE SQL STABLE | ||
ROWS 1 | ||
AS $$ | ||
SELECT * FROM public.users_audit WHERE user_id = user_row.id; | ||
$$; | ||
|
||
CREATE OR REPLACE FUNCTION public.get_todos_setof_rows(user_row users) | ||
RETURNS SETOF todos | ||
LANGUAGE SQL STABLE | ||
AS $$ | ||
SELECT * FROM public.todos WHERE "user-id" = user_row.id; | ||
$$; | ||
|
||
CREATE OR REPLACE FUNCTION public.get_todos_setof_rows(todo_row todos) | ||
RETURNS SETOF todos | ||
LANGUAGE SQL STABLE | ||
AS $$ | ||
SELECT * FROM public.todos WHERE "user-id" = todo_row."user-id"; | ||
$$; | ||
Comment on lines
+163
to
+183
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. note Those will also be used to improve the introspection to provide automatic types inferences for embeded functions select joins in follow-up PR's. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note
The loop is now at the
Args
level to unionize.