Skip to content

Commit 2cd2ebb

Browse files
committed
wip: nothing works
1 parent ce26465 commit 2cd2ebb

File tree

3 files changed

+290
-82
lines changed

3 files changed

+290
-82
lines changed

src/server/templates/typescript.ts

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,18 @@ export const apply = async ({
4040
{} as Record<number, (typeof types)[number]>
4141
)
4242

43+
const getTsReturnType = (fn: PostgresFunction, returnType: string) => {
44+
return `${returnType}${fn.is_set_returning_function && fn.returns_multiple_rows ? '[]' : ''}
45+
${
46+
fn.returns_set_of_table && fn.args.length === 1 && fn.args[0].table_name
47+
? `SetofOptions: {
48+
from: ${JSON.stringify(typesById[fn.args[0].type_id].format)}
49+
to: ${JSON.stringify(fn.return_table_name)}
50+
isOneToOne: ${fn.returns_multiple_rows ? false : true}
51+
}`
52+
: ''
53+
}`
54+
}
4355
const getReturnType = (fn: PostgresFunction): string => {
4456
// Case 1: `returns table`.
4557
const tableArgs = fn.args.filter(({ mode }) => mode === 'table')
@@ -343,9 +355,14 @@ export type Database = {
343355
// Exclude all functions definitions that have only one single argument unnamed argument that isn't
344356
// a json/jsonb/text as it won't be considered by PostgREST
345357
if (
346-
inArgs.length === 1 &&
347-
inArgs[0].name === '' &&
348-
VALID_UNNAMED_FUNCTION_ARG_TYPES.has(inArgs[0].type_id)
358+
(inArgs.length === 1 &&
359+
inArgs[0].name === '' &&
360+
VALID_UNNAMED_FUNCTION_ARG_TYPES.has(inArgs[0].type_id)) ||
361+
// OR if the function have a single unnamed args which is another table (embeded function)
362+
(inArgs.length === 1 &&
363+
inArgs[0].name === '' &&
364+
inArgs[0].table_name &&
365+
func.return_table_name)
349366
) {
350367
return true
351368
}
@@ -434,7 +451,8 @@ export type Database = {
434451
inArgs.length === 1 &&
435452
inArgs[0].name === '' &&
436453
(VALID_UNNAMED_FUNCTION_ARG_TYPES.has(inArgs[0].type_id) ||
437-
inArgs[0].has_default)
454+
inArgs[0].has_default) &&
455+
!fn.return_table_name
438456
)
439457
})
440458
@@ -463,7 +481,7 @@ export type Database = {
463481
// No conflict - just add the no params signature
464482
allSignatures.push(`{
465483
Args: Record<PropertyKey, never>
466-
Returns: ${getReturnType(noParamFn)}${noParamFn.is_set_returning_function && noParamFn.returns_multiple_rows ? '[]' : ''}
484+
Returns: ${getTsReturnType(noParamFn, getReturnType(noParamFn))}
467485
}`)
468486
}
469487
}
@@ -485,10 +503,25 @@ export type Database = {
485503
486504
allSignatures.push(`{
487505
Args: { "": ${tsType} }
488-
Returns: ${getReturnType(validUnnamedFn)}${validUnnamedFn.is_set_returning_function && validUnnamedFn.returns_multiple_rows ? '[]' : ''}
506+
Returns: ${getTsReturnType(validUnnamedFn, getReturnType(validUnnamedFn))}
489507
}`)
490508
}
491509
}
510+
const unnamedSetofFunctions = fns.filter((fn) => {
511+
// Only include unnamed functions that:
512+
// 1. Have a single unnamed parameter
513+
// 2. The parameter is of a valid type (json, jsonb, text)
514+
// 3. All parameters have default values
515+
const inArgs = fn.args.filter(({ mode }) => VALID_FUNCTION_ARGS_MODE.has(mode))
516+
return inArgs.length === 1 && inArgs[0].name === '' && fn.return_table_name
517+
})
518+
if (unnamedSetofFunctions.length > 0) {
519+
const unnamedEmbededFunctionsSignatures = unnamedSetofFunctions.map(
520+
(fn) =>
521+
`{ IsUnnamedEmbededTable: true, Args: Record<PropertyKey, never>, Returns: ${getTsReturnType(fn, getReturnType(fn))} }`
522+
)
523+
allSignatures.push(...unnamedEmbededFunctionsSignatures)
524+
}
492525
493526
// For functions with named parameters, generate all signatures
494527
const namedFns = fns.filter((fn) => !fn.args.some(({ name }) => name === ''))
@@ -545,20 +578,7 @@ export type Database = {
545578
})
546579
.sort()
547580
.join(', ')} }`}
548-
Returns: ${returnType}${fn.is_set_returning_function && fn.returns_multiple_rows ? '[]' : ''}
549-
${
550-
fn.returns_set_of_table
551-
? `SetofOptions: {
552-
from: ${
553-
fn.args.length > 0 && fn.args[0].table_name
554-
? JSON.stringify(typesById[fn.args[0].type_id].format)
555-
: '"*"'
556-
}
557-
to: ${JSON.stringify(fn.return_table_name)}
558-
isOneToOne: ${fn.returns_multiple_rows ? false : true}
559-
}`
560-
: ''
561-
}
581+
Returns: ${getTsReturnType(fn, returnType)}
562582
}`)
563583
}
564584
})
@@ -567,8 +587,13 @@ export type Database = {
567587
return Array.from(new Set(allSignatures)).sort()
568588
})()
569589
570-
// Remove duplicates, sort, and join with |
571-
return `${JSON.stringify(fnName)}: ${signatures.join('\n | ')}`
590+
if (signatures.length > 0) {
591+
// Remove duplicates, sort, and join with |
592+
return `${JSON.stringify(fnName)}: ${signatures.join('\n | ')}`
593+
} else {
594+
console.log('fns', fns)
595+
return `${JSON.stringify(fnName)}: ${fns.map((fn) => `{ Args: unknown, Returns: ${getTsReturnType(fn, getReturnType(fn))} }`).join('\n |')}`
596+
}
572597
})
573598
})()}
574599
}

test/db/00-init.sql

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,3 +328,60 @@ create or replace function public.polymorphic_function_with_unnamed_default_over
328328
create or replace function public.polymorphic_function_with_unnamed_default_overload(text default 'default') returns text language sql as $$ SELECT 'foo' $$;
329329
create or replace function public.polymorphic_function_with_unnamed_default_overload(bool default true) returns int language sql as 'SELECT 3';
330330

331+
-- Test function with unnamed row parameter returning setof
332+
CREATE OR REPLACE FUNCTION public.test_unnamed_row_setof(todos)
333+
RETURNS SETOF todos
334+
LANGUAGE SQL STABLE
335+
AS $$
336+
SELECT * FROM public.todos WHERE "user-id" = $1."user-id";
337+
$$;
338+
339+
CREATE OR REPLACE FUNCTION public.test_unnamed_row_setof(users)
340+
RETURNS SETOF todos
341+
LANGUAGE SQL STABLE
342+
AS $$
343+
SELECT * FROM public.todos WHERE "user-id" = $1."id";
344+
$$;
345+
346+
347+
CREATE OR REPLACE FUNCTION public.test_unnamed_row_setof(user_id bigint)
348+
RETURNS SETOF todos
349+
LANGUAGE SQL STABLE
350+
AS $$
351+
SELECT * FROM public.todos WHERE "user-id" = user_id;
352+
$$;
353+
354+
-- Test function with unnamed row parameter returning scalar
355+
CREATE OR REPLACE FUNCTION public.test_unnamed_row_scalar(todos)
356+
RETURNS integer
357+
LANGUAGE SQL STABLE
358+
AS $$
359+
SELECT COUNT(*) FROM public.todos WHERE "user-id" = $1."user-id";
360+
$$;
361+
362+
-- Test function with unnamed view row parameter
363+
CREATE OR REPLACE FUNCTION public.test_unnamed_view_row(todos_view)
364+
RETURNS SETOF todos
365+
LANGUAGE SQL STABLE
366+
AS $$
367+
SELECT * FROM public.todos WHERE "user-id" = $1."user-id";
368+
$$;
369+
370+
-- Test function with multiple unnamed row parameters
371+
CREATE OR REPLACE FUNCTION public.test_unnamed_multiple_rows(users, todos)
372+
RETURNS SETOF todos
373+
LANGUAGE SQL STABLE
374+
AS $$
375+
SELECT * FROM public.todos
376+
WHERE "user-id" = $1.id
377+
AND id = $2.id;
378+
$$;
379+
380+
-- Test function with unnamed row parameter returning composite
381+
CREATE OR REPLACE FUNCTION public.test_unnamed_row_composite(users)
382+
RETURNS composite_type_with_array_attribute
383+
LANGUAGE SQL STABLE
384+
AS $$
385+
SELECT ROW(ARRAY[$1.name])::composite_type_with_array_attribute;
386+
$$;
387+

0 commit comments

Comments
 (0)