Skip to content

Commit 87557ef

Browse files
committed
wip
1 parent 96bd800 commit 87557ef

9 files changed

+492
-1685
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
"test:types:watch": "run-s build && tsd --files 'test/**/*.test-d.ts' --watch",
4545
"db:clean": "cd test/db && docker compose down --volumes",
4646
"db:run": "cd test/db && docker compose up --detach && wait-for-localhost 3000",
47-
"db:generate-test-types": "cd test/db && docker compose up --detach && wait-for-localhost 8080 && curl --location 'http://0.0.0.0:8080/generators/typescript?included_schemas=public,personal&detect_one_to_one_relationships=true' > ../types.generated.ts && sed -i 's/export type Json = .*/export type Json = unknown;/' ../types.generated.ts"
47+
"db:generate-test-types": "cd test/db && docker compose up --detach && wait-for-localhost 8080 && curl --location 'http://0.0.0.0:8080/generators/typescript?included_schemas=public,personal&detect_one_to_one_relationships=true' > ../types.generated.ts && node ../scripts/update-json-type.js"
4848
},
4949
"dependencies": {
5050
"@supabase/node-fetch": "^2.6.14"

src/select-query-parser/utils.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { GenericSetofOption } from '../types'
1+
import { GenericFunction, GenericSetofOption } from '../types'
22
import { Ast } from './parser'
33
import {
44
AggregateFunctions,
@@ -654,8 +654,8 @@ type MatchingFunctionBySetofFrom<
654654
> = Fn['SetofOptions'] extends GenericSetofOption
655655
? TableName extends Fn['SetofOptions']['from']
656656
? Fn
657-
: false
658-
: false
657+
: never
658+
: never
659659

660660
type FindMatchingFunctionBySetofFrom<
661661
FnUnion,

test/db/00-schema.sql

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,11 @@ RETURNS user_status AS $$
115115
RETURNING status;
116116
$$ LANGUAGE SQL VOLATILE;
117117

118+
CREATE FUNCTION public.set_users_offline(name_param text)
119+
RETURNS SETOF users AS $$
120+
UPDATE users SET status = 'OFFLINE' WHERE username LIKE name_param RETURNING *;
121+
$$ LANGUAGE SQL;
122+
118123
CREATE FUNCTION public.void_func()
119124
RETURNS void AS $$
120125
$$ LANGUAGE SQL;
@@ -197,7 +202,6 @@ AS $$
197202
SELECT * FROM public.messages WHERE username = user_row.username;
198203
$$;
199204

200-
201205
-- Create a view based on users table
202206
CREATE VIEW public.active_users AS
203207
SELECT * FROM public.users WHERE status = 'ONLINE'::public.user_status;

test/embeded_functions_join.test-d.ts

Lines changed: 0 additions & 159 deletions
This file was deleted.

test/embeded_functions_join.test.ts

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
import { PostgrestClient } from '../src/index'
2+
import { Database } from './types.override'
3+
import { expectType } from 'tsd'
4+
import { TypeEqual } from 'ts-expect'
5+
6+
const REST_URL = 'http://localhost:3000'
7+
export const postgrest = new PostgrestClient<Database>(REST_URL)
8+
9+
type Schema = Database['public']
10+
11+
describe('embeded functions select', () => {
12+
test('function returning a setof embeded table', async () => {
13+
const res = await postgrest.from('channels').select('id, all_channels_messages:get_messages(*)')
14+
expect(res).toMatchInlineSnapshot(``)
15+
let result: Exclude<typeof res.data, null>
16+
let expected: Array<{
17+
id: number
18+
all_channels_messages: Array<Schema['Tables']['messages']['Row']>
19+
}>
20+
expectType<TypeEqual<typeof result, typeof expected>>(true)
21+
})
22+
23+
test('function returning a setof embeded table with fields selection', async () => {
24+
const res = await postgrest
25+
.from('channels')
26+
.select('id, all_channels_messages:get_messages(id,message)')
27+
expect(res).toMatchInlineSnapshot(``)
28+
let result: Exclude<typeof res.data, null>
29+
let expected: Array<{
30+
id: number
31+
all_channels_messages: Array<Pick<Schema['Tables']['messages']['Row'], 'id' | 'message'>>
32+
}>
33+
expectType<TypeEqual<typeof result, typeof expected>>(true)
34+
})
35+
36+
test('function double definition returning a setof embeded table', async () => {
37+
const res = await postgrest.from('users').select('username, all_user_messages:get_messages(*)')
38+
expect(res).toMatchInlineSnapshot(``)
39+
let result: Exclude<typeof res.data, null>
40+
let expected: Array<{
41+
username: string
42+
all_user_messages: Array<Schema['Tables']['messages']['Row']>
43+
}>
44+
expectType<TypeEqual<typeof result, typeof expected>>(true)
45+
})
46+
47+
test('function double definition returning a setof embeded table with fields selection', async () => {
48+
const res = await postgrest
49+
.from('users')
50+
.select('username, all_user_messages:get_messages(id,message)')
51+
expect(res).toMatchInlineSnapshot(``)
52+
let result: Exclude<typeof res.data, null>
53+
let expected: Array<{
54+
username: string
55+
all_user_messages: Array<Pick<Schema['Tables']['messages']['Row'], 'id' | 'message'>>
56+
}>
57+
expectType<TypeEqual<typeof result, typeof expected>>(true)
58+
})
59+
60+
test('function returning a single row embeded table', async () => {
61+
const res = await postgrest
62+
.from('users')
63+
.select('username, user_called_profile:get_user_profile(*)')
64+
expect(res).toMatchInlineSnapshot(``)
65+
let result: Exclude<typeof res.data, null>
66+
let expected: Array<{
67+
username: string
68+
user_called_profile: Schema['Tables']['user_profiles']['Row'] | null
69+
}>
70+
expectType<TypeEqual<typeof result, typeof expected>>(true)
71+
})
72+
73+
test('function returning a single row embeded table with fields selection', async () => {
74+
const res = await postgrest
75+
.from('users')
76+
.select('username, user_called_profile:get_user_profile(username)')
77+
expect(res).toMatchInlineSnapshot(``)
78+
let result: Exclude<typeof res.data, null>
79+
let expected: Array<{
80+
username: string
81+
user_called_profile_not_null: Schema['Tables']['user_profiles']['Row']
82+
}>
83+
expectType<TypeEqual<typeof result, typeof expected>>(true)
84+
})
85+
86+
test('function embedded table with fields selection and sub linking', async () => {
87+
const res = await postgrest
88+
.from('channels')
89+
.select('id, all_channels_messages:get_messages(id,message,channels(id,slug))')
90+
expect(res).toMatchInlineSnapshot(``)
91+
let result: Exclude<typeof res.data, null>
92+
let expected: Array<{
93+
username: string
94+
user_called_profile: Pick<Schema['Tables']['user_profiles']['Row'], 'username'> | null
95+
}>
96+
expectType<TypeEqual<typeof result, typeof expected>>(true)
97+
})
98+
99+
test('function with table row input', async () => {
100+
const res = await postgrest.from('users').select('username, user_messages:get_user_messages(*)')
101+
expect(res).toMatchInlineSnapshot(``)
102+
let result: Exclude<typeof res.data, null>
103+
let expected: Array<{
104+
id: number
105+
all_channels_messages: Array<{
106+
id: number
107+
message: string | null
108+
channels: {
109+
id: number
110+
slug: string | null
111+
}
112+
}>
113+
}>
114+
expectType<TypeEqual<typeof result, typeof expected>>(true)
115+
})
116+
117+
test('function with view row input', async () => {
118+
const res = await postgrest
119+
.from('active_users')
120+
.select('username, active_user_messages:get_active_user_messages(*)')
121+
expect(res).toMatchInlineSnapshot(``)
122+
let result: Exclude<typeof res.data, null>
123+
let expected: Array<{
124+
username: string
125+
user_messages: Array<Schema['Tables']['messages']['Row']>
126+
}>
127+
expectType<TypeEqual<typeof result, typeof expected>>(true)
128+
})
129+
130+
test('function returning view', async () => {
131+
const res = await postgrest
132+
.from('users')
133+
.select('username, recent_messages:get_user_recent_messages(*)')
134+
expect(res).toMatchInlineSnapshot(``)
135+
let result: Exclude<typeof res.data, null>
136+
let expected: Array<{
137+
username: string | null
138+
active_user_messages: Array<Schema['Tables']['messages']['Row']>
139+
}>
140+
expectType<TypeEqual<typeof result, typeof expected>>(true)
141+
})
142+
143+
test('function with view input returning view', async () => {
144+
const res = await postgrest
145+
.from('active_users')
146+
.select('username, recent_messages:get_user_recent_messages(*)')
147+
expect(res).toMatchInlineSnapshot(``)
148+
let result: Exclude<typeof res.data, null>
149+
let expected: Array<{
150+
username: string
151+
recent_messages: Array<Schema['Views']['recent_messages']['Row']>
152+
}>
153+
expectType<TypeEqual<typeof result, typeof expected>>(true)
154+
})
155+
156+
test('function with blurb_message', async () => {
157+
const res = await postgrest
158+
.from('users')
159+
.select('username, user_messages:get_user_messages(id,message,blurb_message)')
160+
expect(res).toMatchInlineSnapshot(``)
161+
let result: Exclude<typeof res.data, null>
162+
let expected: Array<{
163+
username: string
164+
user_messages: Array<
165+
Pick<Schema['Tables']['messages']['Row'], 'id' | 'message' | 'blurb_message'>
166+
>
167+
}>
168+
expectType<TypeEqual<typeof result, typeof expected>>(true)
169+
})
170+
171+
test('function returning row', async () => {
172+
const res = await postgrest.from('channels').select('id, user:function_returning_row(*)')
173+
expect(res).toMatchInlineSnapshot(``)
174+
let result: Exclude<typeof res.data, null>
175+
let expected: never[]
176+
expectType<TypeEqual<typeof result, typeof expected>>(true)
177+
})
178+
179+
test('function returning set of rows', async () => {
180+
const res = await postgrest
181+
.from('channels')
182+
.select('id, users:function_returning_set_of_rows(*)')
183+
expect(res).toMatchInlineSnapshot(``)
184+
let result: Exclude<typeof res.data, null>
185+
let expected: never[]
186+
expectType<TypeEqual<typeof result, typeof expected>>(true)
187+
})
188+
})

0 commit comments

Comments
 (0)