Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions packages/core/postgrest-js/src/select-query-parser/result.ts
Original file line number Diff line number Diff line change
Expand Up @@ -308,14 +308,17 @@ type ResolveJsonPathType<
? PathResult extends string
? // Use the result if it's a string as we know that even with the string accessor ->> it's a valid type
PathResult
: IsStringUnion<PathResult> extends true
? // Use the result if it's a union of strings
: IsStringUnion<Exclude<PathResult, null>> extends true
? // Use the result if it's a union of strings (even if nullable)
PathResult
: CastType extends 'json'
? // If the type is not a string, ensure it was accessed with json accessor ->
: IsStringUnion<PathResult> extends true
? // Use the result if it's a union of strings (non-nullable)
PathResult
: // Otherwise it means non-string value accessed with string accessor ->> use the TypeScriptTypes result
TypeScriptTypes<CastType>
: CastType extends 'json'
? // If the type is not a string, ensure it was accessed with json accessor ->
PathResult
: // Otherwise it means non-string value accessed with string accessor ->> use the TypeScriptTypes result
TypeScriptTypes<CastType>
: TypeScriptTypes<CastType>
: // No json path, use regular type casting
TypeScriptTypes<CastType>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -618,7 +618,7 @@ export type JsonPathToAccessor<Path extends string> = Path extends `${infer P1}-
export type JsonPathToType<T, Path extends string> = Path extends ''
? T
: ContainsNull<T> extends true
? JsonPathToType<Exclude<T, null>, Path>
? JsonPathToType<Exclude<T, null>, Path> | null
: Path extends `${infer Key}.${infer Rest}`
? Key extends keyof T
? JsonPathToType<T[Key], Rest>
Expand Down
46 changes: 45 additions & 1 deletion packages/core/postgrest-js/test/advanced_rpc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1169,7 +1169,8 @@ describe('advanced rpc', () => {
"age_range": "[20,30)",
"catchphrase": "'json' 'test'",
"data": {
"foo": {
"foo": "string value",
"fooRecord": {
"bar": {
"nested": "value",
},
Expand All @@ -1179,6 +1180,49 @@ describe('advanced rpc', () => {
"status": "ONLINE",
"username": "jsonuser",
},
{
"age_range": "[20,30)",
"catchphrase": "'json' 'null' 'test'",
"data": {
"bar": null,
"en": "ONE",
"foo": "string value",
"fooRecord": {
"bar": null,
"baz": "string value",
},
},
"status": "ONLINE",
"username": "jsonusernull",
},
{
"age_range": "[20,30)",
"catchphrase": "'json' 'obj' 'test'",
"data": {
"bar": {
"baz": 42,
},
"en": "TWO",
"fooRecord": {
"bar": {
"nested": "deep",
},
"baz": "test",
},
},
"status": "ONLINE",
"username": "jsonuserobj",
},
{
"age_range": "[20,30)",
"catchphrase": "'json' 'missing' 'test'",
"data": {
"en": "THREE",
"foo": "string",
},
"status": "ONLINE",
"username": "jsonusermissing",
},
],
"error": null,
"status": 200,
Expand Down
204 changes: 196 additions & 8 deletions packages/core/postgrest-js/test/basic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ test('basic select table', async () => {
"age_range": "[20,30)",
"catchphrase": "'json' 'test'",
"data": {
"foo": {
"foo": "string value",
"fooRecord": {
"bar": {
"nested": "value",
},
Expand All @@ -52,6 +53,49 @@ test('basic select table', async () => {
"status": "ONLINE",
"username": "jsonuser",
},
{
"age_range": "[20,30)",
"catchphrase": "'json' 'null' 'test'",
"data": {
"bar": null,
"en": "ONE",
"foo": "string value",
"fooRecord": {
"bar": null,
"baz": "string value",
},
},
"status": "ONLINE",
"username": "jsonusernull",
},
{
"age_range": "[20,30)",
"catchphrase": "'json' 'obj' 'test'",
"data": {
"bar": {
"baz": 42,
},
"en": "TWO",
"fooRecord": {
"bar": {
"nested": "deep",
},
"baz": "test",
},
},
"status": "ONLINE",
"username": "jsonuserobj",
},
{
"age_range": "[20,30)",
"catchphrase": "'json' 'missing' 'test'",
"data": {
"en": "THREE",
"foo": "string",
},
"status": "ONLINE",
"username": "jsonusermissing",
},
],
"error": null,
"status": 200,
Expand Down Expand Up @@ -98,7 +142,8 @@ test('basic select returns types override', async () => {
"age_range": "[20,30)",
"catchphrase": "'json' 'test'",
"data": {
"foo": {
"foo": "string value",
"fooRecord": {
"bar": {
"nested": "value",
},
Expand All @@ -108,6 +153,49 @@ test('basic select returns types override', async () => {
"status": "ONLINE",
"username": "jsonuser",
},
{
"age_range": "[20,30)",
"catchphrase": "'json' 'null' 'test'",
"data": {
"bar": null,
"en": "ONE",
"foo": "string value",
"fooRecord": {
"bar": null,
"baz": "string value",
},
},
"status": "ONLINE",
"username": "jsonusernull",
},
{
"age_range": "[20,30)",
"catchphrase": "'json' 'obj' 'test'",
"data": {
"bar": {
"baz": 42,
},
"en": "TWO",
"fooRecord": {
"bar": {
"nested": "deep",
},
"baz": "test",
},
},
"status": "ONLINE",
"username": "jsonuserobj",
},
{
"age_range": "[20,30)",
"catchphrase": "'json' 'missing' 'test'",
"data": {
"en": "THREE",
"foo": "string",
},
"status": "ONLINE",
"username": "jsonusermissing",
},
],
"error": null,
"status": 200,
Expand Down Expand Up @@ -172,7 +260,7 @@ test('basic select with maybeSingle yielding more than one result', async () =>
"data": null,
"error": {
"code": "PGRST116",
"details": "Results contain 5 rows, application/vnd.pgrst.object+json requires 1 row",
"details": "Results contain 8 rows, application/vnd.pgrst.object+json requires 1 row",
"hint": null,
"message": "JSON object requested, multiple (or no) rows returned",
},
Expand All @@ -190,7 +278,7 @@ test('basic select with single yielding more than one result', async () => {
"data": null,
"error": {
"code": "PGRST116",
"details": "The result contains 5 rows",
"details": "The result contains 8 rows",
"hint": null,
"message": "Cannot coerce the result to a single JSON object",
},
Expand Down Expand Up @@ -226,6 +314,18 @@ test('basic select view', async () => {
"non_updatable_column": 1,
"username": "jsonuser",
},
{
"non_updatable_column": 1,
"username": "jsonusernull",
},
{
"non_updatable_column": 1,
"username": "jsonuserobj",
},
{
"non_updatable_column": 1,
"username": "jsonusermissing",
},
],
"error": null,
"status": 200,
Expand Down Expand Up @@ -1039,7 +1139,8 @@ test('allow ordering on JSON column', async () => {
"age_range": "[20,30)",
"catchphrase": "'json' 'test'",
"data": {
"foo": {
"foo": "string value",
"fooRecord": {
"bar": {
"nested": "value",
},
Expand All @@ -1049,6 +1150,49 @@ test('allow ordering on JSON column', async () => {
"status": "ONLINE",
"username": "jsonuser",
},
{
"age_range": "[20,30)",
"catchphrase": "'json' 'null' 'test'",
"data": {
"bar": null,
"en": "ONE",
"foo": "string value",
"fooRecord": {
"bar": null,
"baz": "string value",
},
},
"status": "ONLINE",
"username": "jsonusernull",
},
{
"age_range": "[20,30)",
"catchphrase": "'json' 'obj' 'test'",
"data": {
"bar": {
"baz": 42,
},
"en": "TWO",
"fooRecord": {
"bar": {
"nested": "deep",
},
"baz": "test",
},
},
"status": "ONLINE",
"username": "jsonuserobj",
},
{
"age_range": "[20,30)",
"catchphrase": "'json' 'missing' 'test'",
"data": {
"en": "THREE",
"foo": "string",
},
"status": "ONLINE",
"username": "jsonusermissing",
},
{
"age_range": "[20,30)",
"catchphrase": "'fat' 'rat'",
Expand Down Expand Up @@ -1084,7 +1228,7 @@ test('select with head:true, count:exact', async () => {
const res = await postgrest.from('users').select('*', { head: true, count: 'exact' })
expect(res).toMatchInlineSnapshot(`
{
"count": 5,
"count": 8,
"data": null,
"error": null,
"status": 200,
Expand Down Expand Up @@ -1133,7 +1277,7 @@ test('select with count:exact', async () => {
const res = await postgrest.from('users').select('*', { count: 'exact' })
expect(res).toMatchInlineSnapshot(`
{
"count": 5,
"count": 8,
"data": [
{
"age_range": "[1,2)",
Expand All @@ -1160,7 +1304,8 @@ test('select with count:exact', async () => {
"age_range": "[20,30)",
"catchphrase": "'json' 'test'",
"data": {
"foo": {
"foo": "string value",
"fooRecord": {
"bar": {
"nested": "value",
},
Expand All @@ -1170,6 +1315,49 @@ test('select with count:exact', async () => {
"status": "ONLINE",
"username": "jsonuser",
},
{
"age_range": "[20,30)",
"catchphrase": "'json' 'null' 'test'",
"data": {
"bar": null,
"en": "ONE",
"foo": "string value",
"fooRecord": {
"bar": null,
"baz": "string value",
},
},
"status": "ONLINE",
"username": "jsonusernull",
},
{
"age_range": "[20,30)",
"catchphrase": "'json' 'obj' 'test'",
"data": {
"bar": {
"baz": 42,
},
"en": "TWO",
"fooRecord": {
"bar": {
"nested": "deep",
},
"baz": "test",
},
},
"status": "ONLINE",
"username": "jsonuserobj",
},
{
"age_range": "[20,30)",
"catchphrase": "'json' 'missing' 'test'",
"data": {
"en": "THREE",
"foo": "string",
},
"status": "ONLINE",
"username": "jsonusermissing",
},
{
"age_range": "[20,30)",
"catchphrase": "'fat' 'rat'",
Expand Down
Loading
Loading