Skip to content

Commit ce26465

Browse files
committed
fix: handle type generations functions override logic add tests
1 parent 2aa4dbc commit ce26465

File tree

4 files changed

+754
-240
lines changed

4 files changed

+754
-240
lines changed

src/server/templates/typescript.ts

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export const apply = async ({
3737
acc[type.id] = type
3838
return acc
3939
},
40-
{} as Record<string, (typeof types)[number]>
40+
{} as Record<number, (typeof types)[number]>
4141
)
4242

4343
const getReturnType = (fn: PostgresFunction): string => {
@@ -46,7 +46,7 @@ export const apply = async ({
4646
if (tableArgs.length > 0) {
4747
const argsNameAndType = tableArgs
4848
.map(({ name, type_id }) => {
49-
const type = types.find(({ id }) => id === type_id)
49+
const type = typesById[type_id]
5050
let tsType = 'unknown'
5151
if (type) {
5252
tsType = pgTypeToTsType(type.name, { types, schemas, tables, views })
@@ -80,7 +80,7 @@ export const apply = async ({
8080
}
8181

8282
// Case 3: returns base/array/composite/enum type.
83-
const type = types.find(({ id }) => id === fn.return_type_id)
83+
const type = typesById[fn.return_type_id]
8484
if (type) {
8585
return pgTypeToTsType(type.name, { types, schemas, tables, views })
8686
}
@@ -116,7 +116,7 @@ export type Database = {
116116
// Either:
117117
// 1. All input args are be named, or
118118
// 2. There is only one input arg which is unnamed
119-
const inArgs = func.args.filter(({ mode }) => ['in', 'inout', 'variadic'].includes(mode))
119+
const inArgs = func.args.filter(({ mode }) => VALID_FUNCTION_ARGS_MODE.has(mode))
120120
121121
if (!inArgs.some(({ name }) => name === '')) {
122122
return true
@@ -323,7 +323,6 @@ export type Database = {
323323
const schemaFunctionsGroupedByName = schemaFunctions
324324
.filter((func) => {
325325
// Get all input args (in, inout, variadic modes)
326-
327326
const inArgs = func.args.filter(({ mode }) => VALID_FUNCTION_ARGS_MODE.has(mode))
328327
// Case 1: Function has no parameters
329328
if (inArgs.length === 0) {
@@ -419,7 +418,12 @@ export type Database = {
419418
const allSignatures: string[] = []
420419
421420
// First check if we have a no-param function
422-
const noParamFns = fns.filter((fn) => fn.args.length === 0)
421+
const noParamFns = fns.filter(
422+
(fn) =>
423+
fn.args.length === 0 ||
424+
// If all the params of a function have non potgrest proxyable arguments
425+
fn.args.every((arg) => !VALID_FUNCTION_ARGS_MODE.has(arg.mode))
426+
)
423427
const unnamedFns = fns.filter((fn) => {
424428
// Only include unnamed functions that:
425429
// 1. Have a single unnamed parameter
@@ -435,7 +439,7 @@ export type Database = {
435439
})
436440
437441
// Special case: one no-param function and unnamed param function exist
438-
if (noParamFns.length === 1) {
442+
if (noParamFns.length > 0) {
439443
const noParamFn = noParamFns[0]
440444
const unnamedWithDefaultsFn = unnamedFns.find((fn) =>
441445
fn.args.every((arg) => arg.has_default)
@@ -588,7 +592,7 @@ export type Database = {
588592
({ name, attributes }) =>
589593
`${JSON.stringify(name)}: {
590594
${attributes.map(({ name, type_id }) => {
591-
const type = types.find(({ id }) => id === type_id)
595+
const type = typesById[type_id]
592596
let tsType = 'unknown'
593597
if (type) {
594598
tsType = `${pgTypeToTsType(type.name, { types, schemas, tables, views })} | null`
@@ -729,11 +733,16 @@ export const Constants = {
729733
} as const
730734
`
731735

732-
output = await prettier.format(output, {
733-
parser: 'typescript',
734-
semi: false,
735-
})
736-
return output
736+
try {
737+
return await prettier.format(output, {
738+
parser: 'typescript',
739+
semi: false,
740+
})
741+
} catch (error) {
742+
console.log('Error: ', output)
743+
console.log(error)
744+
throw error
745+
}
737746
}
738747

739748
// TODO: Make this more robust. Currently doesn't handle range types - returns them as unknown.

test/db/00-init.sql

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,15 @@ as $$
127127
select id, name from public.users;
128128
$$;
129129

130+
create or replace function public.function_returning_table_with_args(user_id int)
131+
returns table (id int, name text)
132+
language sql
133+
stable
134+
as $$
135+
select id, name from public.users WHERE id = user_id;
136+
$$;
137+
138+
130139
create or replace function public.polymorphic_function(text) returns void language sql as '';
131140
create or replace function public.polymorphic_function(bool) returns void language sql as '';
132141

@@ -295,11 +304,27 @@ create function postgrest_resolvable_with_override_function(user_row users) retu
295304
SELECT * FROM todos WHERE "user-id" = user_row.id;
296305
$$;
297306

298-
create or replace function public.polymorphic_function_with_different_return(text) returns void language sql as '';
299307
create or replace function public.polymorphic_function_with_different_return(bool) returns int language sql as 'SELECT 1';
308+
create or replace function public.polymorphic_function_with_different_return(int) returns int language sql as 'SELECT 2';
309+
create or replace function public.polymorphic_function_with_different_return(text) returns text language sql as $$ SELECT 'foo' $$;
300310

311+
create or replace function public.polymorphic_function_with_no_params_or_unnamed() returns int language sql as 'SELECT 1';
312+
create or replace function public.polymorphic_function_with_no_params_or_unnamed(bool) returns int language sql as 'SELECT 2';
313+
create or replace function public.polymorphic_function_with_no_params_or_unnamed(text) returns text language sql as $$ SELECT 'foo' $$;
301314
-- Function with a single unnamed params that isn't a json/jsonb/text should never appears in the type gen as it won't be in postgrest schema
302315
create or replace function public.polymorphic_function_with_unnamed_integer(int) returns int language sql as 'SELECT 1';
303316
create or replace function public.polymorphic_function_with_unnamed_json(json) returns int language sql as 'SELECT 1';
304317
create or replace function public.polymorphic_function_with_unnamed_jsonb(jsonb) returns int language sql as 'SELECT 1';
305-
create or replace function public.polymorphic_function_with_unnamed_text(text) returns int language sql as 'SELECT 1';
318+
create or replace function public.polymorphic_function_with_unnamed_text(text) returns int language sql as 'SELECT 1';
319+
320+
-- Functions with unnamed parameters that have default values
321+
create or replace function public.polymorphic_function_with_unnamed_default() returns int language sql as 'SELECT 1';
322+
create or replace function public.polymorphic_function_with_unnamed_default(int default 42) returns int language sql as 'SELECT 2';
323+
create or replace function public.polymorphic_function_with_unnamed_default(text default 'default') returns text language sql as $$ SELECT 'foo' $$;
324+
325+
-- Functions with unnamed parameters that have default values and multiple overloads
326+
create or replace function public.polymorphic_function_with_unnamed_default_overload() returns int language sql as 'SELECT 1';
327+
create or replace function public.polymorphic_function_with_unnamed_default_overload(int default 42) returns int language sql as 'SELECT 2';
328+
create or replace function public.polymorphic_function_with_unnamed_default_overload(text default 'default') returns text language sql as $$ SELECT 'foo' $$;
329+
create or replace function public.polymorphic_function_with_unnamed_default_overload(bool default true) returns int language sql as 'SELECT 3';
330+

test/lib/functions.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ test('list set-returning function with single object limit', async () => {
8080
"definition": "
8181
SELECT * FROM public.users_audit WHERE user_id = user_row.id;
8282
",
83-
"id": 16502,
83+
"id": 16503,
8484
"identity_argument_types": "user_row users",
8585
"is_set_returning_function": true,
8686
"language": "sql",
@@ -126,7 +126,7 @@ test('list set-returning function with multiples definitions', async () => {
126126
"definition": "
127127
SELECT * FROM public.todos WHERE "user-id" = user_row.id;
128128
",
129-
"id": 16503,
129+
"id": 16504,
130130
"identity_argument_types": "user_row users",
131131
"is_set_returning_function": true,
132132
"language": "sql",
@@ -164,7 +164,7 @@ test('list set-returning function with multiples definitions', async () => {
164164
"definition": "
165165
SELECT * FROM public.todos WHERE "user-id" = todo_row."user-id";
166166
",
167-
"id": 16504,
167+
"id": 16505,
168168
"identity_argument_types": "todo_row todos",
169169
"is_set_returning_function": true,
170170
"language": "sql",

0 commit comments

Comments
 (0)