diff --git a/README.md b/README.md index 9986f2f9..4b962dd3 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Isomorphic JavaScript client for [PostgREST](https://postgrest.org). The goal of this library is to make an "ORM-like" restful interface. -Full documentation can be found [here](https://supabase.github.io/postgrest-js/). +Full documentation can be found [here](https://supabase.github.io/postgrest-js/v2). ### Quick start diff --git a/docs/v1/index.html b/docs/v1/index.html index bd808263..95dd2986 100644 --- a/docs/v1/index.html +++ b/docs/v1/index.html @@ -71,7 +71,7 @@

postgrest-js

Package License: MIT

Isomorphic JavaScript client for PostgREST. The goal of this library is to make an "ORM-like" restful interface.

-

Full documentation can be found here.

+

Full documentation can be found here.

Quick start

@@ -164,4 +164,4 @@

Legend

- \ No newline at end of file + diff --git a/docs/v1/spec.json b/docs/v1/spec.json index 478c7f91..a3bcd1af 100644 --- a/docs/v1/spec.json +++ b/docs/v1/spec.json @@ -1,35 +1,12990 @@ { - "id": 0, - "name": "@supabase/postgrest-js", - "kind": 0, - "flags": {}, - "originalName": "", - "children": [ - { - "id": 1, - "name": "\"index\"", - "kind": 1, - "kindString": "Module", - "flags": { - "isExported": true - }, - "originalName": "/Users/copple/Projects/Supabase/postgrest-js/src/index.ts", - "sources": [ - { - "fileName": "index.ts", - "line": 1, - "character": 0 - } - ] - } - ], - "groups": [ - { - "title": "Modules", - "kind": 1, - "children": [ - 1 - ] - } - ] -} \ No newline at end of file + "id": 0, + "name": "@supabase/postgrest-js", + "kind": 0, + "flags": {}, + "originalName": "", + "children": [ + { + "id": 502, + "name": "\"PostgrestClient\"", + "kind": 1, + "kindString": "Module", + "flags": { + "isExported": true + }, + "originalName": "/Users/copple/Projects/Supabase/postgrest-js/src/PostgrestClient.ts", + "children": [ + { + "id": 503, + "name": "PostgrestClient", + "kind": 128, + "kindString": "Class", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 512, + "name": "constructor", + "kind": 512, + "kindString": "Constructor", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Creates a PostgREST client." + }, + "signatures": [ + { + "id": 513, + "name": "new PostgrestClient", + "kind": 16384, + "kindString": "Constructor signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Creates a PostgREST client." + }, + "parameters": [ + { + "id": 514, + "name": "url", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "URL of the PostgREST endpoint." + }, + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "id": 515, + "name": "__namedParameters", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "originalName": "__1", + "type": { + "type": "reflection", + "declaration": { + "id": 516, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 522, + "name": "fetch", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "PostgrestClient.ts", + "line": 26, + "character": 11 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "reference", + "id": 375, + "name": "fetch" + } + ] + } + }, + { + "id": 517, + "name": "headers", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "Custom headers." + }, + "sources": [ + { + "fileName": "PostgrestClient.ts", + "line": 24, + "character": 13 + } + ], + "type": { + "type": "reflection", + "declaration": { + "id": 518, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "indexSignature": [ + { + "id": 519, + "name": "__index", + "kind": 8192, + "kindString": "Index signature", + "flags": { + "isExported": true + }, + "parameters": [ + { + "id": 520, + "name": "key", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + } + }, + { + "id": 521, + "name": "schema", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "Postgres schema to switch to.\n" + }, + "sources": [ + { + "fileName": "PostgrestClient.ts", + "line": 25, + "character": 12 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + }, + { + "id": 523, + "name": "throwOnError", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "PostgrestClient.ts", + "line": 27, + "character": 18 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "false" + }, + { + "type": "intrinsic", + "name": "true" + } + ] + } + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [522, 517, 521, 523] + } + ], + "sources": [ + { + "fileName": "PostgrestClient.ts", + "line": 22, + "character": 16 + } + ] + } + }, + "defaultValue": "{}" + } + ], + "type": { + "type": "reference", + "id": 503, + "name": "PostgrestClient" + } + } + ], + "sources": [ + { + "fileName": "PostgrestClient.ts", + "line": 12, + "character": 30 + } + ] + }, + { + "id": 510, + "name": "fetch", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true, + "isOptional": true + }, + "sources": [ + { + "fileName": "PostgrestClient.ts", + "line": 11, + "character": 7 + } + ], + "type": { + "type": "reference", + "id": 59, + "name": "Fetch" + } + }, + { + "id": 505, + "name": "headers", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "PostgrestClient.ts", + "line": 9, + "character": 9 + } + ], + "type": { + "type": "reflection", + "declaration": { + "id": 506, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "indexSignature": [ + { + "id": 507, + "name": "__index", + "kind": 8192, + "kindString": "Index signature", + "flags": { + "isExported": true + }, + "parameters": [ + { + "id": 508, + "name": "key", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "sources": [ + { + "fileName": "PostgrestClient.ts", + "line": 9, + "character": 10 + } + ] + } + } + }, + { + "id": 509, + "name": "schema", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true, + "isOptional": true + }, + "sources": [ + { + "fileName": "PostgrestClient.ts", + "line": 10, + "character": 8 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + }, + { + "id": 511, + "name": "shouldThrowOnError", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true, + "isOptional": true + }, + "sources": [ + { + "fileName": "PostgrestClient.ts", + "line": 12, + "character": 20 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "false" + }, + { + "type": "intrinsic", + "name": "true" + } + ] + } + }, + { + "id": 504, + "name": "url", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "PostgrestClient.ts", + "line": 8, + "character": 5 + } + ], + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "id": 524, + "name": "auth", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 525, + "name": "auth", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Authenticates the request with JWT." + }, + "parameters": [ + { + "id": 526, + "name": "token", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The JWT token to use.\n" + }, + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "PostgrestClient.ts", + "line": 47, + "character": 6 + } + ] + }, + { + "id": 527, + "name": "from", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 528, + "name": "from", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Perform a table operation." + }, + "typeParameter": [ + { + "id": 529, + "name": "T", + "kind": 131072, + "kindString": "Type parameter", + "flags": { + "isExported": true + } + } + ], + "parameters": [ + { + "id": 530, + "name": "table", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The table name to operate on.\n" + }, + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "type": { + "type": "reference", + "id": 363, + "typeArguments": [ + { + "type": "typeParameter", + "name": "T", + "default": { + "type": "intrinsic", + "name": "any" + } + } + ], + "name": "PostgrestQueryBuilder" + } + } + ], + "sources": [ + { + "fileName": "PostgrestClient.ts", + "line": 57, + "character": 6 + } + ] + }, + { + "id": 531, + "name": "rpc", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 532, + "name": "rpc", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Perform a function call." + }, + "typeParameter": [ + { + "id": 533, + "name": "T", + "kind": 131072, + "kindString": "Type parameter", + "flags": { + "isExported": true + } + } + ], + "parameters": [ + { + "id": 534, + "name": "fn", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The function name to call." + }, + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "id": 535, + "name": "params", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true, + "isOptional": true + }, + "comment": { + "text": "The parameters to pass to the function call." + }, + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "object" + } + ] + } + }, + { + "id": 536, + "name": "__namedParameters", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "originalName": "__2", + "type": { + "type": "reflection", + "declaration": { + "id": 537, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 539, + "name": "count", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "Count algorithm to use to count rows in a table.\n" + }, + "sources": [ + { + "fileName": "PostgrestClient.ts", + "line": 80, + "character": 11 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "null" + }, + { + "type": "stringLiteral", + "value": "exact" + }, + { + "type": "stringLiteral", + "value": "planned" + }, + { + "type": "stringLiteral", + "value": "estimated" + } + ] + }, + "defaultValue": "null" + }, + { + "id": 538, + "name": "head", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "When set to true, no data will be returned." + }, + "sources": [ + { + "fileName": "PostgrestClient.ts", + "line": 79, + "character": 10 + } + ], + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "defaultValue": "false" + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [539, 538] + } + ], + "sources": [ + { + "fileName": "PostgrestClient.ts", + "line": 77, + "character": 20 + } + ] + } + }, + "defaultValue": "{}" + } + ], + "type": { + "type": "reference", + "id": 150, + "typeArguments": [ + { + "type": "typeParameter", + "name": "T", + "default": { + "type": "intrinsic", + "name": "any" + } + } + ], + "name": "PostgrestFilterBuilder" + } + } + ], + "sources": [ + { + "fileName": "PostgrestClient.ts", + "line": 75, + "character": 5 + } + ] + } + ], + "groups": [ + { + "title": "Constructors", + "kind": 512, + "children": [512] + }, + { + "title": "Properties", + "kind": 1024, + "children": [510, 505, 509, 511, 504] + }, + { + "title": "Methods", + "kind": 2048, + "children": [524, 527, 531] + } + ], + "sources": [ + { + "fileName": "PostgrestClient.ts", + "line": 7, + "character": 36 + } + ] + } + ], + "groups": [ + { + "title": "Classes", + "kind": 128, + "children": [503] + } + ], + "sources": [ + { + "fileName": "PostgrestClient.ts", + "line": 1, + "character": 0 + } + ] + }, + { + "id": 540, + "name": "\"index\"", + "kind": 1, + "kindString": "Module", + "flags": { + "isExported": true + }, + "originalName": "/Users/copple/Projects/Supabase/postgrest-js/src/index.ts", + "sources": [ + { + "fileName": "index.ts", + "line": 1, + "character": 0 + } + ] + }, + { + "id": 149, + "name": "\"lib/PostgrestFilterBuilder\"", + "kind": 1, + "kindString": "Module", + "flags": { + "isExported": true + }, + "originalName": "/Users/copple/Projects/Supabase/postgrest-js/src/lib/PostgrestFilterBuilder.ts", + "children": [ + { + "id": 150, + "name": "PostgrestFilterBuilder", + "kind": 128, + "kindString": "Class", + "flags": { + "isExported": true + }, + "typeParameter": [ + { + "id": 151, + "name": "T", + "kind": 131072, + "kindString": "Type parameter", + "flags": { + "isExported": true + } + } + ], + "children": [ + { + "id": 343, + "name": "constructor", + "kind": 512, + "kindString": "Constructor", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 344, + "name": "new PostgrestFilterBuilder", + "kind": 16384, + "kindString": "Constructor signature", + "flags": { + "isExported": true + }, + "parameters": [ + { + "id": 345, + "name": "builder", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "type": { + "type": "reference", + "id": 27, + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestBuilder" + } + } + ], + "type": { + "type": "reference", + "id": 150, + "name": "PostgrestFilterBuilder" + }, + "inheritedFrom": { + "type": "reference", + "id": 41, + "name": "PostgrestBuilder.__constructor" + } + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 60, + "character": 31 + } + ], + "inheritedFrom": { + "type": "reference", + "id": 41, + "name": "PostgrestBuilder.__constructor" + } + }, + { + "id": 237, + "name": "adj", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "comment": { + "tags": [ + { + "tag": "deprecated", + "text": "Use `rangeAdjacent()` instead." + } + ] + }, + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 328, + "character": 5 + } + ], + "type": { + "type": "reference", + "id": 233, + "name": "rangeAdjacent" + }, + "defaultValue": "this.rangeAdjacent" + }, + { + "id": 342, + "name": "allowEmpty", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 60, + "character": 22 + } + ], + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "inheritedFrom": { + "type": "reference", + "id": 40, + "name": "PostgrestBuilder.allowEmpty" + } + }, + { + "id": 338, + "name": "body", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true, + "isOptional": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 56, + "character": 16 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "Partial" + }, + { + "type": "array", + "elementType": { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "Partial" + } + } + ] + }, + "inheritedFrom": { + "type": "reference", + "id": 36, + "name": "PostgrestBuilder.body" + } + }, + { + "id": 212, + "name": "cd", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "comment": { + "tags": [ + { + "tag": "deprecated", + "text": "Use `containedBy()` instead." + } + ] + }, + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 253, + "character": 4 + } + ], + "type": { + "type": "reference", + "id": 208, + "name": "containedBy" + }, + "defaultValue": "this.containedBy" + }, + { + "id": 207, + "name": "cs", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "comment": { + "tags": [ + { + "tag": "deprecated", + "text": "Use `contains()` instead." + } + ] + }, + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 229, + "character": 4 + } + ], + "type": { + "type": "reference", + "id": 203, + "name": "contains" + }, + "defaultValue": "this.contains" + }, + { + "id": 341, + "name": "fetch", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 59, + "character": 17 + } + ], + "type": { + "type": "reference", + "id": 59, + "name": "Fetch" + }, + "inheritedFrom": { + "type": "reference", + "id": 39, + "name": "PostgrestBuilder.fetch" + } + }, + { + "id": 333, + "name": "headers", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 54, + "character": 19 + } + ], + "type": { + "type": "reflection", + "declaration": { + "id": 334, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "indexSignature": [ + { + "id": 335, + "name": "__index", + "kind": 8192, + "kindString": "Index signature", + "flags": { + "isExported": true + }, + "parameters": [ + { + "id": 336, + "name": "key", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 54, + "character": 21 + } + ] + } + }, + "inheritedFrom": { + "type": "reference", + "id": 31, + "name": "PostgrestBuilder.headers" + } + }, + { + "id": 331, + "name": "method", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 52, + "character": 18 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "stringLiteral", + "value": "GET" + }, + { + "type": "stringLiteral", + "value": "HEAD" + }, + { + "type": "stringLiteral", + "value": "POST" + }, + { + "type": "stringLiteral", + "value": "PATCH" + }, + { + "type": "stringLiteral", + "value": "DELETE" + } + ] + }, + "inheritedFrom": { + "type": "reference", + "id": 29, + "name": "PostgrestBuilder.method" + } + }, + { + "id": 227, + "name": "nxl", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "comment": { + "tags": [ + { + "tag": "deprecated", + "text": "Use `rangeGte()` instead." + } + ] + }, + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 298, + "character": 5 + } + ], + "type": { + "type": "reference", + "id": 223, + "name": "rangeGte" + }, + "defaultValue": "this.rangeGte" + }, + { + "id": 232, + "name": "nxr", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "comment": { + "tags": [ + { + "tag": "deprecated", + "text": "Use `rangeLte()` instead." + } + ] + }, + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 313, + "character": 5 + } + ], + "type": { + "type": "reference", + "id": 228, + "name": "rangeLte" + }, + "defaultValue": "this.rangeLte" + }, + { + "id": 242, + "name": "ov", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "comment": { + "tags": [ + { + "tag": "deprecated", + "text": "Use `overlaps()` instead." + } + ] + }, + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 349, + "character": 4 + } + ], + "type": { + "type": "reference", + "id": 238, + "name": "overlaps" + }, + "defaultValue": "this.overlaps" + }, + { + "id": 337, + "name": "schema", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true, + "isOptional": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 55, + "character": 18 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + }, + "inheritedFrom": { + "type": "reference", + "id": 35, + "name": "PostgrestBuilder.schema" + } + }, + { + "id": 339, + "name": "shouldThrowOnError", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 57, + "character": 30 + } + ], + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "inheritedFrom": { + "type": "reference", + "id": 37, + "name": "PostgrestBuilder.shouldThrowOnError" + } + }, + { + "id": 340, + "name": "signal", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true, + "isOptional": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 58, + "character": 18 + } + ], + "type": { + "type": "reference", + "name": "AbortSignal" + }, + "inheritedFrom": { + "type": "reference", + "id": 38, + "name": "PostgrestBuilder.signal" + } + }, + { + "id": 217, + "name": "sl", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "comment": { + "tags": [ + { + "tag": "deprecated", + "text": "Use `rangeLt()` instead." + } + ] + }, + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 268, + "character": 4 + } + ], + "type": { + "type": "reference", + "id": 213, + "name": "rangeLt" + }, + "defaultValue": "this.rangeLt" + }, + { + "id": 222, + "name": "sr", + "kind": 1024, + "kindString": "Property", + "flags": { + "isExported": true + }, + "comment": { + "tags": [ + { + "tag": "deprecated", + "text": "Use `rangeGt()` instead." + } + ] + }, + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 283, + "character": 4 + } + ], + "type": { + "type": "reference", + "id": 218, + "name": "rangeGt" + }, + "defaultValue": "this.rangeGt" + }, + { + "id": 332, + "name": "url", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 53, + "character": 15 + } + ], + "type": { + "type": "reference", + "name": "URL" + }, + "inheritedFrom": { + "type": "reference", + "id": 30, + "name": "PostgrestBuilder.url" + } + }, + { + "id": 311, + "name": "abortSignal", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 312, + "name": "abortSignal", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Sets the AbortSignal for the fetch request." + }, + "parameters": [ + { + "id": 313, + "name": "signal", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "type": { + "type": "reference", + "name": "AbortSignal" + } + } + ], + "type": { + "type": "intrinsic", + "name": "this" + }, + "inheritedFrom": { + "type": "reference", + "id": 99, + "name": "PostgrestTransformBuilder.abortSignal" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 91, + "character": 13 + } + ], + "inheritedFrom": { + "type": "reference", + "id": 99, + "name": "PostgrestTransformBuilder.abortSignal" + } + }, + { + "id": 208, + "name": "containedBy", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 209, + "name": "containedBy", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Finds all rows whose json, array, or range value on the stated `column` is\ncontained by the specified `value`." + }, + "parameters": [ + { + "id": 210, + "name": "column", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The column to filter on." + }, + "type": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + } + }, + { + "id": 211, + "name": "value", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The value to filter with.\n" + }, + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "array", + "elementType": { + "type": "indexedAccess", + "indexType": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + }, + "objectType": { + "type": "typeParameter", + "name": "T" + } + } + }, + { + "type": "intrinsic", + "name": "object" + } + ] + } + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 238, + "character": 13 + } + ] + }, + { + "id": 203, + "name": "contains", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 204, + "name": "contains", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Finds all rows whose json, array, or range value on the stated `column`\ncontains the values specified in `value`." + }, + "parameters": [ + { + "id": 205, + "name": "column", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The column to filter on." + }, + "type": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + } + }, + { + "id": 206, + "name": "value", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The value to filter with.\n" + }, + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "array", + "elementType": { + "type": "indexedAccess", + "indexType": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + }, + "objectType": { + "type": "typeParameter", + "name": "T" + } + } + }, + { + "type": "intrinsic", + "name": "object" + } + ] + } + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 213, + "character": 10 + } + ] + }, + { + "id": 318, + "name": "csv", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 319, + "name": "csv", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Set the response type to CSV." + }, + "type": { + "type": "reference", + "typeArguments": [ + { + "type": "reference", + "id": 68, + "typeArguments": [ + { + "type": "intrinsic", + "name": "string" + } + ], + "name": "PostgrestSingleResponse" + } + ], + "name": "PromiseLike" + }, + "inheritedFrom": { + "type": "reference", + "id": 106, + "name": "PostgrestTransformBuilder.csv" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 119, + "character": 5 + } + ], + "inheritedFrom": { + "type": "reference", + "id": 106, + "name": "PostgrestTransformBuilder.csv" + } + }, + { + "id": 163, + "name": "eq", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 164, + "name": "eq", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Finds all rows whose value on the stated `column` exactly matches the\nspecified `value`." + }, + "parameters": [ + { + "id": 165, + "name": "column", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The column to filter on." + }, + "type": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + } + }, + { + "id": 166, + "name": "value", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The value to filter with.\n" + }, + "type": { + "type": "indexedAccess", + "indexType": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + }, + "objectType": { + "type": "typeParameter", + "name": "T" + } + } + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 85, + "character": 4 + } + ] + }, + { + "id": 322, + "name": "explain", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 323, + "name": "explain", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Obtains the EXPLAIN plan for this request." + }, + "parameters": [ + { + "id": 324, + "name": "__namedParameters", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "originalName": "__0", + "type": { + "type": "reflection", + "declaration": { + "id": 325, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 326, + "name": "analyze", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "If `true`, the query will be executed and the actual run time will be displayed." + }, + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 142, + "character": 11 + } + ], + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "defaultValue": "false" + }, + { + "id": 329, + "name": "buffers", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "If `true`, include information on buffer usage." + }, + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 145, + "character": 11 + } + ], + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "defaultValue": "false" + }, + { + "id": 328, + "name": "settings", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "If `true`, include information on configuration parameters that affect query planning." + }, + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 144, + "character": 12 + } + ], + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "defaultValue": "false" + }, + { + "id": 327, + "name": "verbose", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "If `true`, the query identifier will be displayed and the result will include the output columns of the query." + }, + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 143, + "character": 11 + } + ], + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "defaultValue": "false" + }, + { + "id": 330, + "name": "wal", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "If `true`, include information on WAL record generation\n" + }, + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 146, + "character": 7 + } + ], + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "defaultValue": "false" + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [326, 329, 328, 327, 330] + } + ], + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 141, + "character": 10 + } + ] + } + }, + "defaultValue": "{}" + } + ], + "type": { + "type": "reference", + "typeArguments": [ + { + "type": "reference", + "id": 66, + "typeArguments": [ + { + "type": "reference", + "typeArguments": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "intrinsic", + "name": "unknown" + } + ], + "name": "Record" + } + ], + "name": "PostgrestResponse" + } + ], + "name": "PromiseLike" + }, + "inheritedFrom": { + "type": "reference", + "id": 110, + "name": "PostgrestTransformBuilder.explain" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 141, + "character": 9 + } + ], + "inheritedFrom": { + "type": "reference", + "id": 110, + "name": "PostgrestTransformBuilder.explain" + } + }, + { + "id": 279, + "name": "filter", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 280, + "name": "filter", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Finds all rows whose `column` satisfies the filter." + }, + "parameters": [ + { + "id": 281, + "name": "column", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The column to filter on." + }, + "type": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + } + }, + { + "id": 282, + "name": "operator", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The operator to filter with." + }, + "type": { + "type": "reference", + "id": 361, + "name": "FilterOperator" + } + }, + { + "id": 283, + "name": "value", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The value to filter with.\n" + }, + "type": { + "type": "intrinsic", + "name": "any" + } + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 452, + "character": 8 + } + ] + }, + { + "id": 251, + "name": "fts", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 252, + "name": "fts", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Finds all rows whose tsvector value on the stated `column` matches\nto_tsquery(`query`).", + "tags": [ + { + "tag": "deprecated", + "text": "Use `textSearch()` instead.\n" + } + ] + }, + "parameters": [ + { + "id": 253, + "name": "column", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The column to filter on." + }, + "type": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + } + }, + { + "id": 254, + "name": "query", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The Postgres tsquery string to filter with." + }, + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "id": 255, + "name": "__namedParameters", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "originalName": "__2", + "type": { + "type": "reflection", + "declaration": { + "id": 256, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 257, + "name": "config", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "The text search configuration to use.\n" + }, + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 391, + "character": 46 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [257] + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 391, + "character": 37 + } + ] + } + }, + "defaultValue": "{}" + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 391, + "character": 5 + } + ] + }, + { + "id": 320, + "name": "geojson", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 321, + "name": "geojson", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Set the response type to GeoJSON." + }, + "type": { + "type": "reference", + "typeArguments": [ + { + "type": "reference", + "id": 68, + "typeArguments": [ + { + "type": "reference", + "typeArguments": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "intrinsic", + "name": "unknown" + } + ], + "name": "Record" + } + ], + "name": "PostgrestSingleResponse" + } + ], + "name": "PromiseLike" + }, + "inheritedFrom": { + "type": "reference", + "id": 108, + "name": "PostgrestTransformBuilder.geojson" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 127, + "character": 9 + } + ], + "inheritedFrom": { + "type": "reference", + "id": 108, + "name": "PostgrestTransformBuilder.geojson" + } + }, + { + "id": 171, + "name": "gt", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 172, + "name": "gt", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Finds all rows whose value on the stated `column` is greater than the\nspecified `value`." + }, + "parameters": [ + { + "id": 173, + "name": "column", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The column to filter on." + }, + "type": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + } + }, + { + "id": 174, + "name": "value", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The value to filter with.\n" + }, + "type": { + "type": "indexedAccess", + "indexType": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + }, + "objectType": { + "type": "typeParameter", + "name": "T" + } + } + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 109, + "character": 4 + } + ] + }, + { + "id": 175, + "name": "gte", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 176, + "name": "gte", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Finds all rows whose value on the stated `column` is greater than or\nequal to the specified `value`." + }, + "parameters": [ + { + "id": 177, + "name": "column", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The column to filter on." + }, + "type": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + } + }, + { + "id": 178, + "name": "value", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The value to filter with.\n" + }, + "type": { + "type": "indexedAccess", + "indexType": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + }, + "objectType": { + "type": "typeParameter", + "name": "T" + } + } + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 121, + "character": 5 + } + ] + }, + { + "id": 191, + "name": "ilike", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 192, + "name": "ilike", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Finds all rows whose value in the stated `column` matches the supplied\n`pattern` (case insensitive)." + }, + "parameters": [ + { + "id": 193, + "name": "column", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The column to filter on." + }, + "type": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + } + }, + { + "id": 194, + "name": "pattern", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The pattern to filter with.\n" + }, + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 169, + "character": 7 + } + ] + }, + { + "id": 199, + "name": "in", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 200, + "name": "in", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Finds all rows whose value on the stated `column` is found on the\nspecified `values`." + }, + "parameters": [ + { + "id": 201, + "name": "column", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The column to filter on." + }, + "type": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + } + }, + { + "id": 202, + "name": "values", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The values to filter with.\n" + }, + "type": { + "type": "array", + "elementType": { + "type": "indexedAccess", + "indexType": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + }, + "objectType": { + "type": "typeParameter", + "name": "T" + } + } + } + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 193, + "character": 4 + } + ] + }, + { + "id": 195, + "name": "is", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 196, + "name": "is", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "A check for exact equality (null, true, false), finds all rows whose\nvalue on the stated `column` exactly match the specified `value`." + }, + "parameters": [ + { + "id": 197, + "name": "column", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The column to filter on." + }, + "type": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + } + }, + { + "id": 198, + "name": "value", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The value to filter with.\n" + }, + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "boolean" + }, + { + "type": "intrinsic", + "name": "null" + } + ] + } + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 181, + "character": 4 + } + ] + }, + { + "id": 187, + "name": "like", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 188, + "name": "like", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Finds all rows whose value in the stated `column` matches the supplied\n`pattern` (case sensitive)." + }, + "parameters": [ + { + "id": 189, + "name": "column", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The column to filter on." + }, + "type": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + } + }, + { + "id": 190, + "name": "pattern", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The pattern to filter with.\n" + }, + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 157, + "character": 6 + } + ] + }, + { + "id": 298, + "name": "limit", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 299, + "name": "limit", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Limits the result with the specified `count`." + }, + "parameters": [ + { + "id": 300, + "name": "count", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The maximum no. of rows to limit to." + }, + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "id": 301, + "name": "__namedParameters", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "originalName": "__1", + "type": { + "type": "reflection", + "declaration": { + "id": 302, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 303, + "name": "foreignTable", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "The foreign table to use (for foreign columns).\n" + }, + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 66, + "character": 37 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [303] + } + ], + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 66, + "character": 22 + } + ] + } + }, + "defaultValue": "{}" + } + ], + "type": { + "type": "intrinsic", + "name": "this" + }, + "inheritedFrom": { + "type": "reference", + "id": 86, + "name": "PostgrestTransformBuilder.limit" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 66, + "character": 7 + } + ], + "inheritedFrom": { + "type": "reference", + "id": 86, + "name": "PostgrestTransformBuilder.limit" + } + }, + { + "id": 179, + "name": "lt", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 180, + "name": "lt", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Finds all rows whose value on the stated `column` is less than the\nspecified `value`." + }, + "parameters": [ + { + "id": 181, + "name": "column", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The column to filter on." + }, + "type": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + } + }, + { + "id": 182, + "name": "value", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The value to filter with.\n" + }, + "type": { + "type": "indexedAccess", + "indexType": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + }, + "objectType": { + "type": "typeParameter", + "name": "T" + } + } + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 133, + "character": 4 + } + ] + }, + { + "id": 183, + "name": "lte", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 184, + "name": "lte", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Finds all rows whose value on the stated `column` is less than or equal\nto the specified `value`." + }, + "parameters": [ + { + "id": 185, + "name": "column", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The column to filter on." + }, + "type": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + } + }, + { + "id": 186, + "name": "value", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The value to filter with.\n" + }, + "type": { + "type": "indexedAccess", + "indexType": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + }, + "objectType": { + "type": "typeParameter", + "name": "T" + } + } + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 145, + "character": 5 + } + ] + }, + { + "id": 284, + "name": "match", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 285, + "name": "match", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Finds all rows whose columns match the specified `query` object." + }, + "parameters": [ + { + "id": 286, + "name": "query", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The object to filter with, with column names as keys mapped\n to their filter values.\n" + }, + "type": { + "type": "reference", + "typeArguments": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "intrinsic", + "name": "unknown" + } + ], + "name": "Record" + } + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 463, + "character": 7 + } + ] + }, + { + "id": 316, + "name": "maybeSingle", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 317, + "name": "maybeSingle", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Retrieves at most one row from the result. Result must be at most one row\n(e.g. using `eq` on a UNIQUE column), otherwise this will result in an\nerror." + }, + "type": { + "type": "reference", + "typeArguments": [ + { + "type": "reference", + "id": 70, + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestMaybeSingleResponse" + } + ], + "name": "PromiseLike" + }, + "inheritedFrom": { + "type": "reference", + "id": 104, + "name": "PostgrestTransformBuilder.maybeSingle" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 110, + "character": 13 + } + ], + "inheritedFrom": { + "type": "reference", + "id": 104, + "name": "PostgrestTransformBuilder.maybeSingle" + } + }, + { + "id": 167, + "name": "neq", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 168, + "name": "neq", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Finds all rows whose value on the stated `column` doesn't match the\nspecified `value`." + }, + "parameters": [ + { + "id": 169, + "name": "column", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The column to filter on." + }, + "type": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + } + }, + { + "id": 170, + "name": "value", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The value to filter with.\n" + }, + "type": { + "type": "indexedAccess", + "indexType": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + }, + "objectType": { + "type": "typeParameter", + "name": "T" + } + } + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 97, + "character": 5 + } + ] + }, + { + "id": 152, + "name": "not", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 153, + "name": "not", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Finds all rows which doesn't satisfy the filter." + }, + "parameters": [ + { + "id": 154, + "name": "column", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The column to filter on." + }, + "type": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + } + }, + { + "id": 155, + "name": "operator", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The operator to filter with." + }, + "type": { + "type": "reference", + "id": 361, + "name": "FilterOperator" + } + }, + { + "id": 156, + "name": "value", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The value to filter with.\n" + }, + "type": { + "type": "intrinsic", + "name": "any" + } + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 61, + "character": 5 + } + ] + }, + { + "id": 157, + "name": "or", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 158, + "name": "or", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Finds all rows satisfying at least one of the filters." + }, + "parameters": [ + { + "id": 159, + "name": "filters", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The filters to use, separated by commas." + }, + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "id": 160, + "name": "__namedParameters", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "originalName": "__1", + "type": { + "type": "reflection", + "declaration": { + "id": 161, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 162, + "name": "foreignTable", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "The foreign table to use (if `column` is a foreign column).\n" + }, + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 72, + "character": 36 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [162] + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 72, + "character": 21 + } + ] + } + }, + "defaultValue": "{}" + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 72, + "character": 4 + } + ] + }, + { + "id": 290, + "name": "order", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 291, + "name": "order", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Orders the result with the specified `column`." + }, + "parameters": [ + { + "id": 292, + "name": "column", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The column to order on." + }, + "type": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + } + }, + { + "id": 293, + "name": "__namedParameters", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "originalName": "__1", + "type": { + "type": "reflection", + "declaration": { + "id": 294, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 295, + "name": "ascending", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "If `true`, the result will be in ascending order." + }, + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 43, + "character": 15 + } + ], + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "defaultValue": "true" + }, + { + "id": 297, + "name": "foreignTable", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "The foreign table to use (if `column` is a foreign column).\n" + }, + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 45, + "character": 18 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + }, + { + "id": 296, + "name": "nullsFirst", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "If `true`, `null`s appear first." + }, + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 44, + "character": 16 + } + ], + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "defaultValue": "false" + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [295, 297, 296] + } + ], + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 41, + "character": 20 + } + ] + } + }, + "defaultValue": "{}" + } + ], + "type": { + "type": "intrinsic", + "name": "this" + }, + "inheritedFrom": { + "type": "reference", + "id": 78, + "name": "PostgrestTransformBuilder.order" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 40, + "character": 7 + } + ], + "inheritedFrom": { + "type": "reference", + "id": 78, + "name": "PostgrestTransformBuilder.order" + } + }, + { + "id": 238, + "name": "overlaps", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 239, + "name": "overlaps", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Finds all rows whose array or range value on the stated `column` overlaps\n(has a value in common) with the specified `value`." + }, + "parameters": [ + { + "id": 240, + "name": "column", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The column to filter on." + }, + "type": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + } + }, + { + "id": 241, + "name": "value", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The value to filter with.\n" + }, + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "array", + "elementType": { + "type": "indexedAccess", + "indexType": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + }, + "objectType": { + "type": "typeParameter", + "name": "T" + } + } + } + ] + } + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 337, + "character": 10 + } + ] + }, + { + "id": 265, + "name": "phfts", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 266, + "name": "phfts", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Finds all rows whose tsvector value on the stated `column` matches\nphraseto_tsquery(`query`).", + "tags": [ + { + "tag": "deprecated", + "text": "Use `textSearch()` with `type: 'phrase'` instead.\n" + } + ] + }, + "parameters": [ + { + "id": 267, + "name": "column", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The column to filter on." + }, + "type": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + } + }, + { + "id": 268, + "name": "query", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The Postgres tsquery string to filter with." + }, + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "id": 269, + "name": "__namedParameters", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "originalName": "__2", + "type": { + "type": "reflection", + "declaration": { + "id": 270, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 271, + "name": "config", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "The text search configuration to use.\n" + }, + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 423, + "character": 48 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [271] + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 423, + "character": 39 + } + ] + } + }, + "defaultValue": "{}" + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 423, + "character": 7 + } + ] + }, + { + "id": 258, + "name": "plfts", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 259, + "name": "plfts", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Finds all rows whose tsvector value on the stated `column` matches\nplainto_tsquery(`query`).", + "tags": [ + { + "tag": "deprecated", + "text": "Use `textSearch()` with `type: 'plain'` instead.\n" + } + ] + }, + "parameters": [ + { + "id": 260, + "name": "column", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The column to filter on." + }, + "type": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + } + }, + { + "id": 261, + "name": "query", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The Postgres tsquery string to filter with." + }, + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "id": 262, + "name": "__namedParameters", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "originalName": "__2", + "type": { + "type": "reflection", + "declaration": { + "id": 263, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 264, + "name": "config", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "The text search configuration to use.\n" + }, + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 407, + "character": 48 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [264] + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 407, + "character": 39 + } + ] + } + }, + "defaultValue": "{}" + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 407, + "character": 7 + } + ] + }, + { + "id": 304, + "name": "range", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 305, + "name": "range", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Limits the result to rows within the specified range, inclusive." + }, + "parameters": [ + { + "id": 306, + "name": "from", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The starting index from which to limit the result, inclusive." + }, + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "id": 307, + "name": "to", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The last index to which to limit the result, inclusive." + }, + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "id": 308, + "name": "__namedParameters", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "originalName": "__2", + "type": { + "type": "reflection", + "declaration": { + "id": 309, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 310, + "name": "foreignTable", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "The foreign table to use (for foreign columns).\n" + }, + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 79, + "character": 48 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [310] + } + ], + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 79, + "character": 33 + } + ] + } + }, + "defaultValue": "{}" + } + ], + "type": { + "type": "intrinsic", + "name": "this" + }, + "inheritedFrom": { + "type": "reference", + "id": 92, + "name": "PostgrestTransformBuilder.range" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 79, + "character": 7 + } + ], + "inheritedFrom": { + "type": "reference", + "id": 92, + "name": "PostgrestTransformBuilder.range" + } + }, + { + "id": 233, + "name": "rangeAdjacent", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 234, + "name": "rangeAdjacent", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Finds all rows whose range value on the stated `column` is adjacent to\nthe specified `range`." + }, + "parameters": [ + { + "id": 235, + "name": "column", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The column to filter on." + }, + "type": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + } + }, + { + "id": 236, + "name": "range", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The range to filter with.\n" + }, + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 322, + "character": 15 + } + ] + }, + { + "id": 218, + "name": "rangeGt", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 219, + "name": "rangeGt", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Finds all rows whose range value on the stated `column` is strictly to\nthe right of the specified `range`." + }, + "parameters": [ + { + "id": 220, + "name": "column", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The column to filter on." + }, + "type": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + } + }, + { + "id": 221, + "name": "range", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The range to filter with.\n" + }, + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 277, + "character": 9 + } + ] + }, + { + "id": 223, + "name": "rangeGte", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 224, + "name": "rangeGte", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Finds all rows whose range value on the stated `column` does not extend\nto the left of the specified `range`." + }, + "parameters": [ + { + "id": 225, + "name": "column", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The column to filter on." + }, + "type": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + } + }, + { + "id": 226, + "name": "range", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The range to filter with.\n" + }, + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 292, + "character": 10 + } + ] + }, + { + "id": 213, + "name": "rangeLt", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 214, + "name": "rangeLt", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Finds all rows whose range value on the stated `column` is strictly to the\nleft of the specified `range`." + }, + "parameters": [ + { + "id": 215, + "name": "column", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The column to filter on." + }, + "type": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + } + }, + { + "id": 216, + "name": "range", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The range to filter with.\n" + }, + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 262, + "character": 9 + } + ] + }, + { + "id": 228, + "name": "rangeLte", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 229, + "name": "rangeLte", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Finds all rows whose range value on the stated `column` does not extend\nto the right of the specified `range`." + }, + "parameters": [ + { + "id": 230, + "name": "column", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The column to filter on." + }, + "type": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + } + }, + { + "id": 231, + "name": "range", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The range to filter with.\n" + }, + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 307, + "character": 10 + } + ] + }, + { + "id": 287, + "name": "select", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 288, + "name": "select", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Performs vertical filtering with SELECT." + }, + "parameters": [ + { + "id": 289, + "name": "columns", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The columns to retrieve, separated by commas.\n" + }, + "type": { + "type": "intrinsic", + "name": "string" + }, + "defaultValue": "\"*\"" + } + ], + "type": { + "type": "intrinsic", + "name": "this" + }, + "inheritedFrom": { + "type": "reference", + "id": 75, + "name": "PostgrestTransformBuilder.select" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 13, + "character": 8 + } + ], + "inheritedFrom": { + "type": "reference", + "id": 75, + "name": "PostgrestTransformBuilder.select" + } + }, + { + "id": 314, + "name": "single", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 315, + "name": "single", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Retrieves only one row from the result. Result must be one row (e.g. using\n`limit`), otherwise this will result in an error." + }, + "type": { + "type": "reference", + "typeArguments": [ + { + "type": "reference", + "id": 68, + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestSingleResponse" + } + ], + "name": "PromiseLike" + }, + "inheritedFrom": { + "type": "reference", + "id": 102, + "name": "PostgrestTransformBuilder.single" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 100, + "character": 8 + } + ], + "inheritedFrom": { + "type": "reference", + "id": 102, + "name": "PostgrestTransformBuilder.single" + } + }, + { + "id": 243, + "name": "textSearch", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 244, + "name": "textSearch", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Finds all rows whose text or tsvector value on the stated `column` matches\nthe tsquery in `query`." + }, + "parameters": [ + { + "id": 245, + "name": "column", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The column to filter on." + }, + "type": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + } + }, + { + "id": 246, + "name": "query", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The Postgres tsquery string to filter with." + }, + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "id": 247, + "name": "__namedParameters", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "originalName": "__2", + "type": { + "type": "reflection", + "declaration": { + "id": 248, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 249, + "name": "config", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "The text search configuration to use." + }, + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 364, + "character": 12 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + }, + { + "id": 250, + "name": "type", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "The type of tsquery conversion to use on `query`.\n" + }, + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 365, + "character": 10 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "null" + }, + { + "type": "stringLiteral", + "value": "plain" + }, + { + "type": "stringLiteral", + "value": "phrase" + }, + { + "type": "stringLiteral", + "value": "websearch" + } + ] + }, + "defaultValue": "null" + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [249, 250] + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 362, + "character": 18 + } + ] + } + }, + "defaultValue": "{}" + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 360, + "character": 12 + } + ] + }, + { + "id": 349, + "name": "then", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 350, + "name": "then", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "typeParameter": [ + { + "id": 351, + "name": "TResult1", + "kind": 131072, + "kindString": "Type parameter", + "flags": { + "isExported": true + } + }, + { + "id": 352, + "name": "TResult2", + "kind": 131072, + "kindString": "Type parameter", + "flags": { + "isExported": true + } + } + ], + "parameters": [ + { + "id": 353, + "name": "onfulfilled", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true, + "isOptional": true + }, + "type": { + "type": "union", + "types": [ + { + "type": "reflection", + "declaration": { + "id": 354, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 355, + "name": "__call", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "parameters": [ + { + "id": 356, + "name": "value", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "type": { + "type": "reference", + "id": 66, + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestResponse" + } + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "typeParameter", + "name": "TResult1", + "default": { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestResponse" + } + }, + { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "TResult1", + "default": { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestResponse" + } + } + ], + "name": "PromiseLike" + } + ] + } + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 93, + "character": 9 + } + ] + } + }, + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "null" + } + ] + } + }, + { + "id": 357, + "name": "onrejected", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true, + "isOptional": true + }, + "type": { + "type": "union", + "types": [ + { + "type": "reflection", + "declaration": { + "id": 358, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 359, + "name": "__call", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "parameters": [ + { + "id": 360, + "name": "reason", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "type": { + "type": "intrinsic", + "name": "any" + } + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "typeParameter", + "name": "TResult2", + "default": { + "type": "intrinsic", + "name": "never" + } + }, + { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "TResult2", + "default": { + "type": "intrinsic", + "name": "never" + } + } + ], + "name": "PromiseLike" + } + ] + } + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 96, + "character": 18 + } + ] + } + }, + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "null" + } + ] + } + } + ], + "type": { + "type": "reference", + "typeArguments": [ + { + "type": "union", + "types": [ + { + "type": "typeParameter", + "name": "TResult1", + "default": { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestResponse" + } + }, + { + "type": "typeParameter", + "name": "TResult2", + "default": { + "type": "intrinsic", + "name": "never" + } + } + ] + } + ], + "name": "PromiseLike" + }, + "inheritedFrom": { + "type": "reference", + "id": 47, + "name": "PostgrestBuilder.then" + } + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 91, + "character": 6 + } + ], + "inheritedFrom": { + "type": "reference", + "id": 47, + "name": "PostgrestBuilder.then" + } + }, + { + "id": 346, + "name": "throwOnError", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 347, + "name": "throwOnError", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "If there's an error with the query, throwOnError will reject the promise by\nthrowing the error instead of returning it as part of a successful response.", + "text": "{@link https://github.com/supabase/supabase-js/issues/92}\n" + }, + "parameters": [ + { + "id": 348, + "name": "throwOnError", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true, + "isOptional": true + }, + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "false" + }, + { + "type": "intrinsic", + "name": "true" + } + ] + } + } + ], + "type": { + "type": "intrinsic", + "name": "this" + }, + "inheritedFrom": { + "type": "reference", + "id": 44, + "name": "PostgrestBuilder.throwOnError" + } + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 83, + "character": 14 + } + ], + "inheritedFrom": { + "type": "reference", + "id": 44, + "name": "PostgrestBuilder.throwOnError" + } + }, + { + "id": 272, + "name": "wfts", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 273, + "name": "wfts", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Finds all rows whose tsvector value on the stated `column` matches\nwebsearch_to_tsquery(`query`).", + "tags": [ + { + "tag": "deprecated", + "text": "Use `textSearch()` with `type: 'websearch'` instead.\n" + } + ] + }, + "parameters": [ + { + "id": 274, + "name": "column", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The column to filter on." + }, + "type": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + } + }, + { + "id": 275, + "name": "query", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The Postgres tsquery string to filter with." + }, + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "id": 276, + "name": "__namedParameters", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "originalName": "__2", + "type": { + "type": "reflection", + "declaration": { + "id": 277, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 278, + "name": "config", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "The text search configuration to use.\n" + }, + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 439, + "character": 47 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [278] + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 439, + "character": 38 + } + ] + } + }, + "defaultValue": "{}" + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 439, + "character": 6 + } + ] + } + ], + "groups": [ + { + "title": "Constructors", + "kind": 512, + "children": [343] + }, + { + "title": "Properties", + "kind": 1024, + "children": [ + 237, + 342, + 338, + 212, + 207, + 341, + 333, + 331, + 227, + 232, + 242, + 337, + 339, + 340, + 217, + 222, + 332 + ] + }, + { + "title": "Methods", + "kind": 2048, + "children": [ + 311, + 208, + 203, + 318, + 163, + 322, + 279, + 251, + 320, + 171, + 175, + 191, + 199, + 195, + 187, + 298, + 179, + 183, + 284, + 316, + 167, + 152, + 157, + 290, + 238, + 265, + 258, + 304, + 233, + 218, + 223, + 213, + 228, + 287, + 314, + 243, + 349, + 346, + 272 + ] + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 53, + "character": 43 + } + ], + "extendedTypes": [ + { + "type": "reference", + "id": 73, + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestTransformBuilder" + } + ], + "implementedTypes": [ + { + "type": "reference", + "typeArguments": [ + { + "type": "reference", + "id": 66, + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestResponse" + } + ], + "name": "PromiseLike" + } + ] + }, + { + "id": 361, + "name": "FilterOperator", + "kind": 4194304, + "kindString": "Type alias", + "flags": {}, + "comment": { + "shortText": "Filters" + }, + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 7, + "character": 19 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "stringLiteral", + "value": "eq" + }, + { + "type": "stringLiteral", + "value": "neq" + }, + { + "type": "stringLiteral", + "value": "gt" + }, + { + "type": "stringLiteral", + "value": "gte" + }, + { + "type": "stringLiteral", + "value": "lt" + }, + { + "type": "stringLiteral", + "value": "lte" + }, + { + "type": "stringLiteral", + "value": "like" + }, + { + "type": "stringLiteral", + "value": "ilike" + }, + { + "type": "stringLiteral", + "value": "is" + }, + { + "type": "stringLiteral", + "value": "in" + }, + { + "type": "stringLiteral", + "value": "cs" + }, + { + "type": "stringLiteral", + "value": "cd" + }, + { + "type": "stringLiteral", + "value": "sl" + }, + { + "type": "stringLiteral", + "value": "sr" + }, + { + "type": "stringLiteral", + "value": "nxl" + }, + { + "type": "stringLiteral", + "value": "nxr" + }, + { + "type": "stringLiteral", + "value": "adj" + }, + { + "type": "stringLiteral", + "value": "ov" + }, + { + "type": "stringLiteral", + "value": "fts" + }, + { + "type": "stringLiteral", + "value": "plfts" + }, + { + "type": "stringLiteral", + "value": "phfts" + }, + { + "type": "stringLiteral", + "value": "wfts" + }, + { + "type": "stringLiteral", + "value": "not.eq" + }, + { + "type": "stringLiteral", + "value": "not.neq" + }, + { + "type": "stringLiteral", + "value": "not.gt" + }, + { + "type": "stringLiteral", + "value": "not.gte" + }, + { + "type": "stringLiteral", + "value": "not.lt" + }, + { + "type": "stringLiteral", + "value": "not.lte" + }, + { + "type": "stringLiteral", + "value": "not.like" + }, + { + "type": "stringLiteral", + "value": "not.ilike" + }, + { + "type": "stringLiteral", + "value": "not.is" + }, + { + "type": "stringLiteral", + "value": "not.in" + }, + { + "type": "stringLiteral", + "value": "not.cs" + }, + { + "type": "stringLiteral", + "value": "not.cd" + }, + { + "type": "stringLiteral", + "value": "not.sl" + }, + { + "type": "stringLiteral", + "value": "not.sr" + }, + { + "type": "stringLiteral", + "value": "not.nxl" + }, + { + "type": "stringLiteral", + "value": "not.nxr" + }, + { + "type": "stringLiteral", + "value": "not.adj" + }, + { + "type": "stringLiteral", + "value": "not.ov" + }, + { + "type": "stringLiteral", + "value": "not.fts" + }, + { + "type": "stringLiteral", + "value": "not.plfts" + }, + { + "type": "stringLiteral", + "value": "not.phfts" + }, + { + "type": "stringLiteral", + "value": "not.wfts" + } + ] + } + } + ], + "groups": [ + { + "title": "Classes", + "kind": 128, + "children": [150] + }, + { + "title": "Type aliases", + "kind": 4194304, + "children": [361] + } + ], + "sources": [ + { + "fileName": "lib/PostgrestFilterBuilder.ts", + "line": 1, + "character": 0 + } + ] + }, + { + "id": 362, + "name": "\"lib/PostgrestQueryBuilder\"", + "kind": 1, + "kindString": "Module", + "flags": { + "isExported": true + }, + "originalName": "/Users/copple/Projects/Supabase/postgrest-js/src/lib/PostgrestQueryBuilder.ts", + "children": [ + { + "id": 363, + "name": "PostgrestQueryBuilder", + "kind": 128, + "kindString": "Class", + "flags": { + "isExported": true + }, + "typeParameter": [ + { + "id": 364, + "name": "T", + "kind": 131072, + "kindString": "Type parameter", + "flags": { + "isExported": true + } + } + ], + "children": [ + { + "id": 365, + "name": "constructor", + "kind": 512, + "kindString": "Constructor", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 366, + "name": "new PostgrestQueryBuilder", + "kind": 16384, + "kindString": "Constructor signature", + "flags": { + "isExported": true + }, + "parameters": [ + { + "id": 367, + "name": "url", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "id": 368, + "name": "__namedParameters", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "originalName": "__1", + "type": { + "type": "reflection", + "declaration": { + "id": 369, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 375, + "name": "fetch", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 10, + "character": 11 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "reference", + "id": 375, + "name": "fetch" + } + ] + } + }, + { + "id": 370, + "name": "headers", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 8, + "character": 13 + } + ], + "type": { + "type": "reflection", + "declaration": { + "id": 371, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "indexSignature": [ + { + "id": 372, + "name": "__index", + "kind": 8192, + "kindString": "Index signature", + "flags": { + "isExported": true + }, + "parameters": [ + { + "id": 373, + "name": "key", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + } + }, + { + "id": 374, + "name": "schema", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 9, + "character": 12 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + }, + { + "id": 376, + "name": "shouldThrowOnError", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 11, + "character": 24 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "false" + }, + { + "type": "intrinsic", + "name": "true" + } + ] + } + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [375, 370, 374, 376] + } + ], + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 6, + "character": 16 + } + ] + } + }, + "defaultValue": "{}" + } + ], + "type": { + "type": "reference", + "id": 363, + "name": "PostgrestQueryBuilder" + }, + "overwrites": { + "type": "reference", + "id": 41, + "name": "PostgrestBuilder.__constructor" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 4, + "character": 75 + } + ], + "overwrites": { + "type": "reference", + "id": 41, + "name": "PostgrestBuilder.__constructor" + } + }, + { + "id": 432, + "name": "allowEmpty", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 60, + "character": 22 + } + ], + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "inheritedFrom": { + "type": "reference", + "id": 40, + "name": "PostgrestBuilder.allowEmpty" + } + }, + { + "id": 428, + "name": "body", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true, + "isOptional": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 56, + "character": 16 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "Partial" + }, + { + "type": "array", + "elementType": { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "Partial" + } + } + ] + }, + "inheritedFrom": { + "type": "reference", + "id": 36, + "name": "PostgrestBuilder.body" + } + }, + { + "id": 431, + "name": "fetch", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 59, + "character": 17 + } + ], + "type": { + "type": "reference", + "id": 59, + "name": "Fetch" + }, + "inheritedFrom": { + "type": "reference", + "id": 39, + "name": "PostgrestBuilder.fetch" + } + }, + { + "id": 423, + "name": "headers", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 54, + "character": 19 + } + ], + "type": { + "type": "reflection", + "declaration": { + "id": 424, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "indexSignature": [ + { + "id": 425, + "name": "__index", + "kind": 8192, + "kindString": "Index signature", + "flags": { + "isExported": true + }, + "parameters": [ + { + "id": 426, + "name": "key", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 54, + "character": 21 + } + ] + } + }, + "inheritedFrom": { + "type": "reference", + "id": 31, + "name": "PostgrestBuilder.headers" + } + }, + { + "id": 421, + "name": "method", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 52, + "character": 18 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "stringLiteral", + "value": "GET" + }, + { + "type": "stringLiteral", + "value": "HEAD" + }, + { + "type": "stringLiteral", + "value": "POST" + }, + { + "type": "stringLiteral", + "value": "PATCH" + }, + { + "type": "stringLiteral", + "value": "DELETE" + } + ] + }, + "inheritedFrom": { + "type": "reference", + "id": 29, + "name": "PostgrestBuilder.method" + } + }, + { + "id": 427, + "name": "schema", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true, + "isOptional": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 55, + "character": 18 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + }, + "inheritedFrom": { + "type": "reference", + "id": 35, + "name": "PostgrestBuilder.schema" + } + }, + { + "id": 429, + "name": "shouldThrowOnError", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 57, + "character": 30 + } + ], + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "inheritedFrom": { + "type": "reference", + "id": 37, + "name": "PostgrestBuilder.shouldThrowOnError" + } + }, + { + "id": 430, + "name": "signal", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true, + "isOptional": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 58, + "character": 18 + } + ], + "type": { + "type": "reference", + "name": "AbortSignal" + }, + "inheritedFrom": { + "type": "reference", + "id": 38, + "name": "PostgrestBuilder.signal" + } + }, + { + "id": 422, + "name": "url", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 53, + "character": 15 + } + ], + "type": { + "type": "reference", + "name": "URL" + }, + "inheritedFrom": { + "type": "reference", + "id": 30, + "name": "PostgrestBuilder.url" + } + }, + { + "id": 415, + "name": "delete", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 416, + "name": "delete", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Performs a DELETE on the table." + }, + "parameters": [ + { + "id": 417, + "name": "__namedParameters", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "originalName": "__0", + "type": { + "type": "reflection", + "declaration": { + "id": 418, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 420, + "name": "count", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "Count algorithm to use to count rows in a table.\n" + }, + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 214, + "character": 9 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "null" + }, + { + "type": "stringLiteral", + "value": "exact" + }, + { + "type": "stringLiteral", + "value": "planned" + }, + { + "type": "stringLiteral", + "value": "estimated" + } + ] + }, + "defaultValue": "null" + }, + { + "id": 419, + "name": "returning", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "If `true`, return the deleted row(s) in the response." + }, + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 213, + "character": 13 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "stringLiteral", + "value": "minimal" + }, + { + "type": "stringLiteral", + "value": "representation" + } + ] + }, + "defaultValue": "\"representation\"" + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [420, 419] + } + ], + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 212, + "character": 9 + } + ] + } + }, + "defaultValue": "{}" + } + ], + "type": { + "type": "reference", + "id": 150, + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestFilterBuilder" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 212, + "character": 8 + } + ] + }, + { + "id": 384, + "name": "insert", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 385, + "name": "insert", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Performs an INSERT into the table." + }, + "parameters": [ + { + "id": 386, + "name": "values", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The values to insert." + }, + "type": { + "type": "union", + "types": [ + { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "Partial" + }, + { + "type": "array", + "elementType": { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "Partial" + } + } + ] + } + }, + { + "id": 387, + "name": "options", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true, + "isOptional": true + }, + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "reflection", + "declaration": { + "id": 388, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 390, + "name": "count", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true, + "isOptional": true + }, + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 78, + "character": 11 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "null" + }, + { + "type": "stringLiteral", + "value": "exact" + }, + { + "type": "stringLiteral", + "value": "planned" + }, + { + "type": "stringLiteral", + "value": "estimated" + } + ] + } + }, + { + "id": 389, + "name": "returning", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true, + "isOptional": true + }, + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 77, + "character": 15 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "stringLiteral", + "value": "minimal" + }, + { + "type": "stringLiteral", + "value": "representation" + } + ] + } + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [390, 389] + } + ] + } + } + ] + } + } + ], + "type": { + "type": "reference", + "id": 150, + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestFilterBuilder" + } + }, + { + "id": 391, + "name": "insert", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "tags": [ + { + "tag": "deprecated", + "text": "Use `upsert()` instead.\n" + } + ] + }, + "parameters": [ + { + "id": 392, + "name": "values", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "type": { + "type": "union", + "types": [ + { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "Partial" + }, + { + "type": "array", + "elementType": { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "Partial" + } + } + ] + } + }, + { + "id": 393, + "name": "options", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true, + "isOptional": true + }, + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "reflection", + "declaration": { + "id": 394, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 398, + "name": "count", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true, + "isOptional": true + }, + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 90, + "character": 11 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "null" + }, + { + "type": "stringLiteral", + "value": "exact" + }, + { + "type": "stringLiteral", + "value": "planned" + }, + { + "type": "stringLiteral", + "value": "estimated" + } + ] + } + }, + { + "id": 396, + "name": "onConflict", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true, + "isOptional": true + }, + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 88, + "character": 16 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + }, + { + "id": 397, + "name": "returning", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true, + "isOptional": true + }, + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 89, + "character": 15 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "stringLiteral", + "value": "minimal" + }, + { + "type": "stringLiteral", + "value": "representation" + } + ] + } + }, + { + "id": 395, + "name": "upsert", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true, + "isOptional": true + }, + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 87, + "character": 12 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "false" + }, + { + "type": "intrinsic", + "name": "true" + } + ] + } + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [398, 396, 397, 395] + } + ] + } + } + ] + } + } + ], + "type": { + "type": "reference", + "id": 150, + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestFilterBuilder" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 74, + "character": 8 + }, + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 84, + "character": 8 + }, + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 93, + "character": 8 + } + ] + }, + { + "id": 377, + "name": "select", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 378, + "name": "select", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Performs vertical filtering with SELECT." + }, + "parameters": [ + { + "id": 379, + "name": "columns", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The columns to retrieve, separated by commas." + }, + "type": { + "type": "intrinsic", + "name": "string" + }, + "defaultValue": "\"*\"" + }, + { + "id": 380, + "name": "__namedParameters", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "originalName": "__1", + "type": { + "type": "reflection", + "declaration": { + "id": 381, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 383, + "name": "count", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "Count algorithm to use to count rows in a table.\n" + }, + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 36, + "character": 11 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "null" + }, + { + "type": "stringLiteral", + "value": "exact" + }, + { + "type": "stringLiteral", + "value": "planned" + }, + { + "type": "stringLiteral", + "value": "estimated" + } + ] + }, + "defaultValue": "null" + }, + { + "id": 382, + "name": "head", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "When set to true, select will void data." + }, + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 35, + "character": 10 + } + ], + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "defaultValue": "false" + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [383, 382] + } + ], + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 33, + "character": 18 + } + ] + } + }, + "defaultValue": "{}" + } + ], + "type": { + "type": "reference", + "id": 150, + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestFilterBuilder" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 32, + "character": 8 + } + ] + }, + { + "id": 436, + "name": "then", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 437, + "name": "then", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "typeParameter": [ + { + "id": 438, + "name": "TResult1", + "kind": 131072, + "kindString": "Type parameter", + "flags": { + "isExported": true + } + }, + { + "id": 439, + "name": "TResult2", + "kind": 131072, + "kindString": "Type parameter", + "flags": { + "isExported": true + } + } + ], + "parameters": [ + { + "id": 440, + "name": "onfulfilled", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true, + "isOptional": true + }, + "type": { + "type": "union", + "types": [ + { + "type": "reflection", + "declaration": { + "id": 441, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 442, + "name": "__call", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "parameters": [ + { + "id": 443, + "name": "value", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "type": { + "type": "reference", + "id": 66, + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestResponse" + } + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "typeParameter", + "name": "TResult1", + "default": { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestResponse" + } + }, + { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "TResult1", + "default": { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestResponse" + } + } + ], + "name": "PromiseLike" + } + ] + } + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 93, + "character": 9 + } + ] + } + }, + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "null" + } + ] + } + }, + { + "id": 444, + "name": "onrejected", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true, + "isOptional": true + }, + "type": { + "type": "union", + "types": [ + { + "type": "reflection", + "declaration": { + "id": 445, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 446, + "name": "__call", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "parameters": [ + { + "id": 447, + "name": "reason", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "type": { + "type": "intrinsic", + "name": "any" + } + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "typeParameter", + "name": "TResult2", + "default": { + "type": "intrinsic", + "name": "never" + } + }, + { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "TResult2", + "default": { + "type": "intrinsic", + "name": "never" + } + } + ], + "name": "PromiseLike" + } + ] + } + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 96, + "character": 18 + } + ] + } + }, + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "null" + } + ] + } + } + ], + "type": { + "type": "reference", + "typeArguments": [ + { + "type": "union", + "types": [ + { + "type": "typeParameter", + "name": "TResult1", + "default": { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestResponse" + } + }, + { + "type": "typeParameter", + "name": "TResult2", + "default": { + "type": "intrinsic", + "name": "never" + } + } + ] + } + ], + "name": "PromiseLike" + }, + "inheritedFrom": { + "type": "reference", + "id": 47, + "name": "PostgrestBuilder.then" + } + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 91, + "character": 6 + } + ], + "inheritedFrom": { + "type": "reference", + "id": 47, + "name": "PostgrestBuilder.then" + } + }, + { + "id": 433, + "name": "throwOnError", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 434, + "name": "throwOnError", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "If there's an error with the query, throwOnError will reject the promise by\nthrowing the error instead of returning it as part of a successful response.", + "text": "{@link https://github.com/supabase/supabase-js/issues/92}\n" + }, + "parameters": [ + { + "id": 435, + "name": "throwOnError", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true, + "isOptional": true + }, + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "false" + }, + { + "type": "intrinsic", + "name": "true" + } + ] + } + } + ], + "type": { + "type": "intrinsic", + "name": "this" + }, + "inheritedFrom": { + "type": "reference", + "id": 44, + "name": "PostgrestBuilder.throwOnError" + } + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 83, + "character": 14 + } + ], + "inheritedFrom": { + "type": "reference", + "id": 44, + "name": "PostgrestBuilder.throwOnError" + } + }, + { + "id": 408, + "name": "update", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 409, + "name": "update", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Performs an UPDATE on the table." + }, + "parameters": [ + { + "id": 410, + "name": "values", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The values to update." + }, + "type": { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "Partial" + } + }, + { + "id": 411, + "name": "__namedParameters", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "originalName": "__1", + "type": { + "type": "reflection", + "declaration": { + "id": 412, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 414, + "name": "count", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "Count algorithm to use to count rows in a table.\n" + }, + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 187, + "character": 11 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "null" + }, + { + "type": "stringLiteral", + "value": "exact" + }, + { + "type": "stringLiteral", + "value": "planned" + }, + { + "type": "stringLiteral", + "value": "estimated" + } + ] + }, + "defaultValue": "null" + }, + { + "id": 413, + "name": "returning", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "By default the updated record is returned. Set this to 'minimal' if you don't need this value." + }, + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 186, + "character": 15 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "stringLiteral", + "value": "minimal" + }, + { + "type": "stringLiteral", + "value": "representation" + } + ] + }, + "defaultValue": "\"representation\"" + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [414, 413] + } + ], + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 184, + "character": 23 + } + ] + } + }, + "defaultValue": "{}" + } + ], + "type": { + "type": "reference", + "id": 150, + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestFilterBuilder" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 183, + "character": 8 + } + ] + }, + { + "id": 399, + "name": "upsert", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 400, + "name": "upsert", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Performs an UPSERT into the table." + }, + "parameters": [ + { + "id": 401, + "name": "values", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The values to insert." + }, + "type": { + "type": "union", + "types": [ + { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "Partial" + }, + { + "type": "array", + "elementType": { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "Partial" + } + } + ] + } + }, + { + "id": 402, + "name": "__namedParameters", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "originalName": "__1", + "type": { + "type": "reflection", + "declaration": { + "id": 403, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 406, + "name": "count", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "Count algorithm to use to count rows in a table." + }, + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 147, + "character": 11 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "null" + }, + { + "type": "stringLiteral", + "value": "exact" + }, + { + "type": "stringLiteral", + "value": "planned" + }, + { + "type": "stringLiteral", + "value": "estimated" + } + ] + }, + "defaultValue": "null" + }, + { + "id": 407, + "name": "ignoreDuplicates", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "Specifies if duplicate rows should be ignored and not inserted.\n" + }, + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 148, + "character": 22 + } + ], + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "defaultValue": "false" + }, + { + "id": 404, + "name": "onConflict", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "By specifying the `on_conflict` query parameter, you can make UPSERT work on a column(s) that has a UNIQUE constraint." + }, + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 145, + "character": 16 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + }, + { + "id": 405, + "name": "returning", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "By default the new record is returned. Set this to 'minimal' if you don't need this value." + }, + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 146, + "character": 15 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "stringLiteral", + "value": "minimal" + }, + { + "type": "stringLiteral", + "value": "representation" + } + ] + }, + "defaultValue": "\"representation\"" + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [406, 407, 404, 405] + } + ], + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 143, + "character": 38 + } + ] + } + }, + "defaultValue": "{}" + } + ], + "type": { + "type": "reference", + "id": 150, + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestFilterBuilder" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 142, + "character": 8 + } + ] + } + ], + "groups": [ + { + "title": "Constructors", + "kind": 512, + "children": [365] + }, + { + "title": "Properties", + "kind": 1024, + "children": [432, 428, 431, 423, 421, 427, 429, 430, 422] + }, + { + "title": "Methods", + "kind": 2048, + "children": [415, 384, 377, 436, 433, 408, 399] + } + ], + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 4, + "character": 42 + } + ], + "extendedTypes": [ + { + "type": "reference", + "id": 27, + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestBuilder" + } + ], + "implementedTypes": [ + { + "type": "reference", + "typeArguments": [ + { + "type": "reference", + "id": 66, + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestResponse" + } + ], + "name": "PromiseLike" + } + ] + } + ], + "groups": [ + { + "title": "Classes", + "kind": 128, + "children": [363] + } + ], + "sources": [ + { + "fileName": "lib/PostgrestQueryBuilder.ts", + "line": 1, + "character": 0 + } + ] + }, + { + "id": 448, + "name": "\"lib/PostgrestRpcBuilder\"", + "kind": 1, + "kindString": "Module", + "flags": { + "isExported": true + }, + "originalName": "/Users/copple/Projects/Supabase/postgrest-js/src/lib/PostgrestRpcBuilder.ts", + "children": [ + { + "id": 449, + "name": "PostgrestRpcBuilder", + "kind": 128, + "kindString": "Class", + "flags": { + "isExported": true + }, + "typeParameter": [ + { + "id": 450, + "name": "T", + "kind": 131072, + "kindString": "Type parameter", + "flags": { + "isExported": true + } + } + ], + "children": [ + { + "id": 451, + "name": "constructor", + "kind": 512, + "kindString": "Constructor", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 452, + "name": "new PostgrestRpcBuilder", + "kind": 16384, + "kindString": "Constructor signature", + "flags": { + "isExported": true + }, + "parameters": [ + { + "id": 453, + "name": "url", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "id": 454, + "name": "__namedParameters", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "originalName": "__1", + "type": { + "type": "reflection", + "declaration": { + "id": 455, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 461, + "name": "fetch", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "lib/PostgrestRpcBuilder.ts", + "line": 10, + "character": 11 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "reference", + "id": 375, + "name": "fetch" + } + ] + } + }, + { + "id": 456, + "name": "headers", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "lib/PostgrestRpcBuilder.ts", + "line": 8, + "character": 13 + } + ], + "type": { + "type": "reflection", + "declaration": { + "id": 457, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "indexSignature": [ + { + "id": 458, + "name": "__index", + "kind": 8192, + "kindString": "Index signature", + "flags": { + "isExported": true + }, + "parameters": [ + { + "id": 459, + "name": "key", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + } + }, + { + "id": 460, + "name": "schema", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "lib/PostgrestRpcBuilder.ts", + "line": 9, + "character": 12 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + }, + { + "id": 462, + "name": "shouldThrowOnError", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "lib/PostgrestRpcBuilder.ts", + "line": 11, + "character": 24 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "false" + }, + { + "type": "intrinsic", + "name": "true" + } + ] + } + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [461, 456, 460, 462] + } + ], + "sources": [ + { + "fileName": "lib/PostgrestRpcBuilder.ts", + "line": 6, + "character": 16 + } + ] + } + }, + "defaultValue": "{}" + } + ], + "type": { + "type": "reference", + "id": 449, + "name": "PostgrestRpcBuilder" + }, + "overwrites": { + "type": "reference", + "id": 41, + "name": "PostgrestBuilder.__constructor" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestRpcBuilder.ts", + "line": 4, + "character": 73 + } + ], + "overwrites": { + "type": "reference", + "id": 41, + "name": "PostgrestBuilder.__constructor" + } + }, + { + "id": 481, + "name": "allowEmpty", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 60, + "character": 22 + } + ], + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "inheritedFrom": { + "type": "reference", + "id": 40, + "name": "PostgrestBuilder.allowEmpty" + } + }, + { + "id": 477, + "name": "body", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true, + "isOptional": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 56, + "character": 16 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "Partial" + }, + { + "type": "array", + "elementType": { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "Partial" + } + } + ] + }, + "inheritedFrom": { + "type": "reference", + "id": 36, + "name": "PostgrestBuilder.body" + } + }, + { + "id": 480, + "name": "fetch", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 59, + "character": 17 + } + ], + "type": { + "type": "reference", + "id": 59, + "name": "Fetch" + }, + "inheritedFrom": { + "type": "reference", + "id": 39, + "name": "PostgrestBuilder.fetch" + } + }, + { + "id": 472, + "name": "headers", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 54, + "character": 19 + } + ], + "type": { + "type": "reflection", + "declaration": { + "id": 473, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "indexSignature": [ + { + "id": 474, + "name": "__index", + "kind": 8192, + "kindString": "Index signature", + "flags": { + "isExported": true + }, + "parameters": [ + { + "id": 475, + "name": "key", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 54, + "character": 21 + } + ] + } + }, + "inheritedFrom": { + "type": "reference", + "id": 31, + "name": "PostgrestBuilder.headers" + } + }, + { + "id": 470, + "name": "method", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 52, + "character": 18 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "stringLiteral", + "value": "GET" + }, + { + "type": "stringLiteral", + "value": "HEAD" + }, + { + "type": "stringLiteral", + "value": "POST" + }, + { + "type": "stringLiteral", + "value": "PATCH" + }, + { + "type": "stringLiteral", + "value": "DELETE" + } + ] + }, + "inheritedFrom": { + "type": "reference", + "id": 29, + "name": "PostgrestBuilder.method" + } + }, + { + "id": 476, + "name": "schema", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true, + "isOptional": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 55, + "character": 18 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + }, + "inheritedFrom": { + "type": "reference", + "id": 35, + "name": "PostgrestBuilder.schema" + } + }, + { + "id": 478, + "name": "shouldThrowOnError", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 57, + "character": 30 + } + ], + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "inheritedFrom": { + "type": "reference", + "id": 37, + "name": "PostgrestBuilder.shouldThrowOnError" + } + }, + { + "id": 479, + "name": "signal", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true, + "isOptional": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 58, + "character": 18 + } + ], + "type": { + "type": "reference", + "name": "AbortSignal" + }, + "inheritedFrom": { + "type": "reference", + "id": 38, + "name": "PostgrestBuilder.signal" + } + }, + { + "id": 471, + "name": "url", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 53, + "character": 15 + } + ], + "type": { + "type": "reference", + "name": "URL" + }, + "inheritedFrom": { + "type": "reference", + "id": 30, + "name": "PostgrestBuilder.url" + } + }, + { + "id": 463, + "name": "rpc", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 464, + "name": "rpc", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Perform a function call." + }, + "parameters": [ + { + "id": 465, + "name": "params", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true, + "isOptional": true + }, + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "object" + } + ] + } + }, + { + "id": 466, + "name": "__namedParameters", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "originalName": "__1", + "type": { + "type": "reflection", + "declaration": { + "id": 467, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 469, + "name": "count", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "lib/PostgrestRpcBuilder.ts", + "line": 32, + "character": 11 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "null" + }, + { + "type": "stringLiteral", + "value": "exact" + }, + { + "type": "stringLiteral", + "value": "planned" + }, + { + "type": "stringLiteral", + "value": "estimated" + } + ] + }, + "defaultValue": "null" + }, + { + "id": 468, + "name": "head", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "lib/PostgrestRpcBuilder.ts", + "line": 31, + "character": 10 + } + ], + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "defaultValue": "false" + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [469, 468] + } + ], + "sources": [ + { + "fileName": "lib/PostgrestRpcBuilder.ts", + "line": 29, + "character": 20 + } + ] + } + }, + "defaultValue": "{}" + } + ], + "type": { + "type": "reference", + "id": 150, + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestFilterBuilder" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestRpcBuilder.ts", + "line": 28, + "character": 5 + } + ] + }, + { + "id": 485, + "name": "then", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 486, + "name": "then", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "typeParameter": [ + { + "id": 487, + "name": "TResult1", + "kind": 131072, + "kindString": "Type parameter", + "flags": { + "isExported": true + } + }, + { + "id": 488, + "name": "TResult2", + "kind": 131072, + "kindString": "Type parameter", + "flags": { + "isExported": true + } + } + ], + "parameters": [ + { + "id": 489, + "name": "onfulfilled", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true, + "isOptional": true + }, + "type": { + "type": "union", + "types": [ + { + "type": "reflection", + "declaration": { + "id": 490, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 491, + "name": "__call", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "parameters": [ + { + "id": 492, + "name": "value", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "type": { + "type": "reference", + "id": 66, + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestResponse" + } + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "typeParameter", + "name": "TResult1", + "default": { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestResponse" + } + }, + { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "TResult1", + "default": { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestResponse" + } + } + ], + "name": "PromiseLike" + } + ] + } + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 93, + "character": 9 + } + ] + } + }, + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "null" + } + ] + } + }, + { + "id": 493, + "name": "onrejected", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true, + "isOptional": true + }, + "type": { + "type": "union", + "types": [ + { + "type": "reflection", + "declaration": { + "id": 494, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 495, + "name": "__call", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "parameters": [ + { + "id": 496, + "name": "reason", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "type": { + "type": "intrinsic", + "name": "any" + } + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "typeParameter", + "name": "TResult2", + "default": { + "type": "intrinsic", + "name": "never" + } + }, + { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "TResult2", + "default": { + "type": "intrinsic", + "name": "never" + } + } + ], + "name": "PromiseLike" + } + ] + } + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 96, + "character": 18 + } + ] + } + }, + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "null" + } + ] + } + } + ], + "type": { + "type": "reference", + "typeArguments": [ + { + "type": "union", + "types": [ + { + "type": "typeParameter", + "name": "TResult1", + "default": { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestResponse" + } + }, + { + "type": "typeParameter", + "name": "TResult2", + "default": { + "type": "intrinsic", + "name": "never" + } + } + ] + } + ], + "name": "PromiseLike" + }, + "inheritedFrom": { + "type": "reference", + "id": 47, + "name": "PostgrestBuilder.then" + } + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 91, + "character": 6 + } + ], + "inheritedFrom": { + "type": "reference", + "id": 47, + "name": "PostgrestBuilder.then" + } + }, + { + "id": 482, + "name": "throwOnError", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 483, + "name": "throwOnError", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "If there's an error with the query, throwOnError will reject the promise by\nthrowing the error instead of returning it as part of a successful response.", + "text": "{@link https://github.com/supabase/supabase-js/issues/92}\n" + }, + "parameters": [ + { + "id": 484, + "name": "throwOnError", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true, + "isOptional": true + }, + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "false" + }, + { + "type": "intrinsic", + "name": "true" + } + ] + } + } + ], + "type": { + "type": "intrinsic", + "name": "this" + }, + "inheritedFrom": { + "type": "reference", + "id": 44, + "name": "PostgrestBuilder.throwOnError" + } + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 83, + "character": 14 + } + ], + "inheritedFrom": { + "type": "reference", + "id": 44, + "name": "PostgrestBuilder.throwOnError" + } + } + ], + "groups": [ + { + "title": "Constructors", + "kind": 512, + "children": [451] + }, + { + "title": "Properties", + "kind": 1024, + "children": [481, 477, 480, 472, 470, 476, 478, 479, 471] + }, + { + "title": "Methods", + "kind": 2048, + "children": [463, 485, 482] + } + ], + "sources": [ + { + "fileName": "lib/PostgrestRpcBuilder.ts", + "line": 4, + "character": 40 + } + ], + "extendedTypes": [ + { + "type": "reference", + "id": 27, + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestBuilder" + } + ], + "implementedTypes": [ + { + "type": "reference", + "typeArguments": [ + { + "type": "reference", + "id": 66, + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestResponse" + } + ], + "name": "PromiseLike" + } + ] + } + ], + "groups": [ + { + "title": "Classes", + "kind": 128, + "children": [449] + } + ], + "sources": [ + { + "fileName": "lib/PostgrestRpcBuilder.ts", + "line": 1, + "character": 0 + } + ] + }, + { + "id": 72, + "name": "\"lib/PostgrestTransformBuilder\"", + "kind": 1, + "kindString": "Module", + "flags": { + "isExported": true + }, + "originalName": "/Users/copple/Projects/Supabase/postgrest-js/src/lib/PostgrestTransformBuilder.ts", + "children": [ + { + "id": 73, + "name": "PostgrestTransformBuilder", + "kind": 128, + "kindString": "Class", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Post-filters (transforms)" + }, + "typeParameter": [ + { + "id": 74, + "name": "T", + "kind": 131072, + "kindString": "Type parameter", + "flags": { + "isExported": true + } + } + ], + "children": [ + { + "id": 131, + "name": "constructor", + "kind": 512, + "kindString": "Constructor", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 132, + "name": "new PostgrestTransformBuilder", + "kind": 16384, + "kindString": "Constructor signature", + "flags": { + "isExported": true + }, + "parameters": [ + { + "id": 133, + "name": "builder", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "type": { + "type": "reference", + "id": 27, + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestBuilder" + } + } + ], + "type": { + "type": "reference", + "id": 73, + "name": "PostgrestTransformBuilder" + }, + "inheritedFrom": { + "type": "reference", + "id": 41, + "name": "PostgrestBuilder.__constructor" + } + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 60, + "character": 31 + } + ], + "inheritedFrom": { + "type": "reference", + "id": 41, + "name": "PostgrestBuilder.__constructor" + } + }, + { + "id": 130, + "name": "allowEmpty", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 60, + "character": 22 + } + ], + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "inheritedFrom": { + "type": "reference", + "id": 40, + "name": "PostgrestBuilder.allowEmpty" + } + }, + { + "id": 126, + "name": "body", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true, + "isOptional": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 56, + "character": 16 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "Partial" + }, + { + "type": "array", + "elementType": { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "Partial" + } + } + ] + }, + "inheritedFrom": { + "type": "reference", + "id": 36, + "name": "PostgrestBuilder.body" + } + }, + { + "id": 129, + "name": "fetch", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 59, + "character": 17 + } + ], + "type": { + "type": "reference", + "id": 59, + "name": "Fetch" + }, + "inheritedFrom": { + "type": "reference", + "id": 39, + "name": "PostgrestBuilder.fetch" + } + }, + { + "id": 121, + "name": "headers", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 54, + "character": 19 + } + ], + "type": { + "type": "reflection", + "declaration": { + "id": 122, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "indexSignature": [ + { + "id": 123, + "name": "__index", + "kind": 8192, + "kindString": "Index signature", + "flags": { + "isExported": true + }, + "parameters": [ + { + "id": 124, + "name": "key", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 54, + "character": 21 + } + ] + } + }, + "inheritedFrom": { + "type": "reference", + "id": 31, + "name": "PostgrestBuilder.headers" + } + }, + { + "id": 119, + "name": "method", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 52, + "character": 18 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "stringLiteral", + "value": "GET" + }, + { + "type": "stringLiteral", + "value": "HEAD" + }, + { + "type": "stringLiteral", + "value": "POST" + }, + { + "type": "stringLiteral", + "value": "PATCH" + }, + { + "type": "stringLiteral", + "value": "DELETE" + } + ] + }, + "inheritedFrom": { + "type": "reference", + "id": 29, + "name": "PostgrestBuilder.method" + } + }, + { + "id": 125, + "name": "schema", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true, + "isOptional": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 55, + "character": 18 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + }, + "inheritedFrom": { + "type": "reference", + "id": 35, + "name": "PostgrestBuilder.schema" + } + }, + { + "id": 127, + "name": "shouldThrowOnError", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 57, + "character": 30 + } + ], + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "inheritedFrom": { + "type": "reference", + "id": 37, + "name": "PostgrestBuilder.shouldThrowOnError" + } + }, + { + "id": 128, + "name": "signal", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true, + "isOptional": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 58, + "character": 18 + } + ], + "type": { + "type": "reference", + "name": "AbortSignal" + }, + "inheritedFrom": { + "type": "reference", + "id": 38, + "name": "PostgrestBuilder.signal" + } + }, + { + "id": 120, + "name": "url", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 53, + "character": 15 + } + ], + "type": { + "type": "reference", + "name": "URL" + }, + "inheritedFrom": { + "type": "reference", + "id": 30, + "name": "PostgrestBuilder.url" + } + }, + { + "id": 99, + "name": "abortSignal", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 100, + "name": "abortSignal", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Sets the AbortSignal for the fetch request." + }, + "parameters": [ + { + "id": 101, + "name": "signal", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "type": { + "type": "reference", + "name": "AbortSignal" + } + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 91, + "character": 13 + } + ] + }, + { + "id": 106, + "name": "csv", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 107, + "name": "csv", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Set the response type to CSV." + }, + "type": { + "type": "reference", + "typeArguments": [ + { + "type": "reference", + "id": 68, + "typeArguments": [ + { + "type": "intrinsic", + "name": "string" + } + ], + "name": "PostgrestSingleResponse" + } + ], + "name": "PromiseLike" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 119, + "character": 5 + } + ] + }, + { + "id": 110, + "name": "explain", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 111, + "name": "explain", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Obtains the EXPLAIN plan for this request." + }, + "parameters": [ + { + "id": 112, + "name": "__namedParameters", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "originalName": "__0", + "type": { + "type": "reflection", + "declaration": { + "id": 113, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 114, + "name": "analyze", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "If `true`, the query will be executed and the actual run time will be displayed." + }, + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 142, + "character": 11 + } + ], + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "defaultValue": "false" + }, + { + "id": 117, + "name": "buffers", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "If `true`, include information on buffer usage." + }, + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 145, + "character": 11 + } + ], + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "defaultValue": "false" + }, + { + "id": 116, + "name": "settings", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "If `true`, include information on configuration parameters that affect query planning." + }, + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 144, + "character": 12 + } + ], + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "defaultValue": "false" + }, + { + "id": 115, + "name": "verbose", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "If `true`, the query identifier will be displayed and the result will include the output columns of the query." + }, + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 143, + "character": 11 + } + ], + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "defaultValue": "false" + }, + { + "id": 118, + "name": "wal", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "If `true`, include information on WAL record generation\n" + }, + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 146, + "character": 7 + } + ], + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "defaultValue": "false" + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [114, 117, 116, 115, 118] + } + ], + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 141, + "character": 10 + } + ] + } + }, + "defaultValue": "{}" + } + ], + "type": { + "type": "reference", + "typeArguments": [ + { + "type": "reference", + "id": 66, + "typeArguments": [ + { + "type": "reference", + "typeArguments": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "intrinsic", + "name": "unknown" + } + ], + "name": "Record" + } + ], + "name": "PostgrestResponse" + } + ], + "name": "PromiseLike" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 141, + "character": 9 + } + ] + }, + { + "id": 108, + "name": "geojson", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 109, + "name": "geojson", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Set the response type to GeoJSON." + }, + "type": { + "type": "reference", + "typeArguments": [ + { + "type": "reference", + "id": 68, + "typeArguments": [ + { + "type": "reference", + "typeArguments": [ + { + "type": "intrinsic", + "name": "string" + }, + { + "type": "intrinsic", + "name": "unknown" + } + ], + "name": "Record" + } + ], + "name": "PostgrestSingleResponse" + } + ], + "name": "PromiseLike" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 127, + "character": 9 + } + ] + }, + { + "id": 86, + "name": "limit", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 87, + "name": "limit", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Limits the result with the specified `count`." + }, + "parameters": [ + { + "id": 88, + "name": "count", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The maximum no. of rows to limit to." + }, + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "id": 89, + "name": "__namedParameters", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "originalName": "__1", + "type": { + "type": "reflection", + "declaration": { + "id": 90, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 91, + "name": "foreignTable", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "The foreign table to use (for foreign columns).\n" + }, + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 66, + "character": 37 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [91] + } + ], + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 66, + "character": 22 + } + ] + } + }, + "defaultValue": "{}" + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 66, + "character": 7 + } + ] + }, + { + "id": 104, + "name": "maybeSingle", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 105, + "name": "maybeSingle", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Retrieves at most one row from the result. Result must be at most one row\n(e.g. using `eq` on a UNIQUE column), otherwise this will result in an\nerror." + }, + "type": { + "type": "reference", + "typeArguments": [ + { + "type": "reference", + "id": 70, + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestMaybeSingleResponse" + } + ], + "name": "PromiseLike" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 110, + "character": 13 + } + ] + }, + { + "id": 78, + "name": "order", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 79, + "name": "order", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Orders the result with the specified `column`." + }, + "parameters": [ + { + "id": 80, + "name": "column", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The column to order on." + }, + "type": { + "type": "typeOperator", + "operator": "keyof", + "target": { + "type": "typeParameter", + "name": "T" + } + } + }, + { + "id": 81, + "name": "__namedParameters", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "originalName": "__1", + "type": { + "type": "reflection", + "declaration": { + "id": 82, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 83, + "name": "ascending", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "If `true`, the result will be in ascending order." + }, + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 43, + "character": 15 + } + ], + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "defaultValue": "true" + }, + { + "id": 85, + "name": "foreignTable", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "The foreign table to use (if `column` is a foreign column).\n" + }, + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 45, + "character": 18 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + }, + { + "id": 84, + "name": "nullsFirst", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "If `true`, `null`s appear first." + }, + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 44, + "character": 16 + } + ], + "type": { + "type": "intrinsic", + "name": "boolean" + }, + "defaultValue": "false" + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [83, 85, 84] + } + ], + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 41, + "character": 20 + } + ] + } + }, + "defaultValue": "{}" + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 40, + "character": 7 + } + ] + }, + { + "id": 92, + "name": "range", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 93, + "name": "range", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Limits the result to rows within the specified range, inclusive." + }, + "parameters": [ + { + "id": 94, + "name": "from", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The starting index from which to limit the result, inclusive." + }, + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "id": 95, + "name": "to", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The last index to which to limit the result, inclusive." + }, + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "id": 96, + "name": "__namedParameters", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "originalName": "__2", + "type": { + "type": "reflection", + "declaration": { + "id": 97, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 98, + "name": "foreignTable", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "comment": { + "text": "The foreign table to use (for foreign columns).\n" + }, + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 79, + "character": 48 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [98] + } + ], + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 79, + "character": 33 + } + ] + } + }, + "defaultValue": "{}" + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 79, + "character": 7 + } + ] + }, + { + "id": 75, + "name": "select", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 76, + "name": "select", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Performs vertical filtering with SELECT." + }, + "parameters": [ + { + "id": 77, + "name": "columns", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "comment": { + "text": "The columns to retrieve, separated by commas.\n" + }, + "type": { + "type": "intrinsic", + "name": "string" + }, + "defaultValue": "\"*\"" + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 13, + "character": 8 + } + ] + }, + { + "id": 102, + "name": "single", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 103, + "name": "single", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Retrieves only one row from the result. Result must be one row (e.g. using\n`limit`), otherwise this will result in an error." + }, + "type": { + "type": "reference", + "typeArguments": [ + { + "type": "reference", + "id": 68, + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestSingleResponse" + } + ], + "name": "PromiseLike" + } + } + ], + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 100, + "character": 8 + } + ] + }, + { + "id": 137, + "name": "then", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 138, + "name": "then", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "typeParameter": [ + { + "id": 139, + "name": "TResult1", + "kind": 131072, + "kindString": "Type parameter", + "flags": { + "isExported": true + } + }, + { + "id": 140, + "name": "TResult2", + "kind": 131072, + "kindString": "Type parameter", + "flags": { + "isExported": true + } + } + ], + "parameters": [ + { + "id": 141, + "name": "onfulfilled", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true, + "isOptional": true + }, + "type": { + "type": "union", + "types": [ + { + "type": "reflection", + "declaration": { + "id": 142, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 143, + "name": "__call", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "parameters": [ + { + "id": 144, + "name": "value", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "type": { + "type": "reference", + "id": 66, + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestResponse" + } + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "typeParameter", + "name": "TResult1", + "default": { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestResponse" + } + }, + { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "TResult1", + "default": { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestResponse" + } + } + ], + "name": "PromiseLike" + } + ] + } + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 93, + "character": 9 + } + ] + } + }, + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "null" + } + ] + } + }, + { + "id": 145, + "name": "onrejected", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true, + "isOptional": true + }, + "type": { + "type": "union", + "types": [ + { + "type": "reflection", + "declaration": { + "id": 146, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 147, + "name": "__call", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "parameters": [ + { + "id": 148, + "name": "reason", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "type": { + "type": "intrinsic", + "name": "any" + } + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "typeParameter", + "name": "TResult2", + "default": { + "type": "intrinsic", + "name": "never" + } + }, + { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "TResult2", + "default": { + "type": "intrinsic", + "name": "never" + } + } + ], + "name": "PromiseLike" + } + ] + } + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 96, + "character": 18 + } + ] + } + }, + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "null" + } + ] + } + } + ], + "type": { + "type": "reference", + "typeArguments": [ + { + "type": "union", + "types": [ + { + "type": "typeParameter", + "name": "TResult1", + "default": { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestResponse" + } + }, + { + "type": "typeParameter", + "name": "TResult2", + "default": { + "type": "intrinsic", + "name": "never" + } + } + ] + } + ], + "name": "PromiseLike" + }, + "inheritedFrom": { + "type": "reference", + "id": 47, + "name": "PostgrestBuilder.then" + } + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 91, + "character": 6 + } + ], + "inheritedFrom": { + "type": "reference", + "id": 47, + "name": "PostgrestBuilder.then" + } + }, + { + "id": 134, + "name": "throwOnError", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 135, + "name": "throwOnError", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "If there's an error with the query, throwOnError will reject the promise by\nthrowing the error instead of returning it as part of a successful response.", + "text": "{@link https://github.com/supabase/supabase-js/issues/92}\n" + }, + "parameters": [ + { + "id": 136, + "name": "throwOnError", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true, + "isOptional": true + }, + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "false" + }, + { + "type": "intrinsic", + "name": "true" + } + ] + } + } + ], + "type": { + "type": "intrinsic", + "name": "this" + }, + "inheritedFrom": { + "type": "reference", + "id": 44, + "name": "PostgrestBuilder.throwOnError" + } + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 83, + "character": 14 + } + ], + "inheritedFrom": { + "type": "reference", + "id": 44, + "name": "PostgrestBuilder.throwOnError" + } + } + ], + "groups": [ + { + "title": "Constructors", + "kind": 512, + "children": [131] + }, + { + "title": "Properties", + "kind": 1024, + "children": [130, 126, 129, 121, 119, 125, 127, 128, 120] + }, + { + "title": "Methods", + "kind": 2048, + "children": [99, 106, 110, 108, 86, 104, 78, 92, 75, 102, 137, 134] + } + ], + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 7, + "character": 46 + } + ], + "extendedTypes": [ + { + "type": "reference", + "id": 27, + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestBuilder" + } + ], + "extendedBy": [ + { + "type": "reference", + "id": 150, + "name": "PostgrestFilterBuilder" + } + ], + "implementedTypes": [ + { + "type": "reference", + "typeArguments": [ + { + "type": "reference", + "id": 66, + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestResponse" + } + ], + "name": "PromiseLike" + } + ] + } + ], + "groups": [ + { + "title": "Classes", + "kind": 128, + "children": [73] + } + ], + "sources": [ + { + "fileName": "lib/PostgrestTransformBuilder.ts", + "line": 1, + "character": 0 + } + ] + }, + { + "id": 499, + "name": "\"lib/constants\"", + "kind": 1, + "kindString": "Module", + "flags": { + "isExported": true + }, + "originalName": "/Users/copple/Projects/Supabase/postgrest-js/src/lib/constants.ts", + "children": [ + { + "id": 500, + "name": "DEFAULT_HEADERS", + "kind": 2097152, + "kindString": "Object literal", + "flags": { + "isExported": true, + "isConst": true + }, + "children": [ + { + "id": 501, + "name": "X-Client-Info", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "lib/constants.ts", + "line": 2, + "character": 48 + } + ], + "type": { + "type": "intrinsic", + "name": "string" + }, + "defaultValue": "`postgrest-js/${version}`" + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [501] + } + ], + "sources": [ + { + "fileName": "lib/constants.ts", + "line": 2, + "character": 28 + } + ], + "type": { + "type": "intrinsic", + "name": "object" + } + } + ], + "groups": [ + { + "title": "Object literals", + "kind": 2097152, + "children": [500] + } + ], + "sources": [ + { + "fileName": "lib/constants.ts", + "line": 1, + "character": 0 + } + ] + }, + { + "id": 1, + "name": "\"lib/types\"", + "kind": 1, + "kindString": "Module", + "flags": { + "isExported": true + }, + "originalName": "/Users/copple/Projects/Supabase/postgrest-js/src/lib/types.ts", + "children": [ + { + "id": 27, + "name": "PostgrestBuilder", + "kind": 128, + "kindString": "Class", + "flags": { + "isExported": true, + "isAbstract": true + }, + "typeParameter": [ + { + "id": 28, + "name": "T", + "kind": 131072, + "kindString": "Type parameter", + "flags": { + "isExported": true + } + } + ], + "children": [ + { + "id": 41, + "name": "constructor", + "kind": 512, + "kindString": "Constructor", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 42, + "name": "new PostgrestBuilder", + "kind": 16384, + "kindString": "Constructor signature", + "flags": { + "isExported": true + }, + "parameters": [ + { + "id": 43, + "name": "builder", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "type": { + "type": "reference", + "id": 27, + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestBuilder" + } + } + ], + "type": { + "type": "reference", + "id": 27, + "name": "PostgrestBuilder" + } + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 60, + "character": 31 + } + ] + }, + { + "id": 40, + "name": "allowEmpty", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 60, + "character": 22 + } + ], + "type": { + "type": "intrinsic", + "name": "boolean" + } + }, + { + "id": 36, + "name": "body", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true, + "isOptional": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 56, + "character": 16 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "Partial" + }, + { + "type": "array", + "elementType": { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "Partial" + } + } + ] + } + }, + { + "id": 39, + "name": "fetch", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 59, + "character": 17 + } + ], + "type": { + "type": "reference", + "id": 59, + "name": "Fetch" + } + }, + { + "id": 31, + "name": "headers", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 54, + "character": 19 + } + ], + "type": { + "type": "reflection", + "declaration": { + "id": 32, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "indexSignature": [ + { + "id": 33, + "name": "__index", + "kind": 8192, + "kindString": "Index signature", + "flags": { + "isExported": true + }, + "parameters": [ + { + "id": 34, + "name": "key", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 54, + "character": 21 + } + ] + } + } + }, + { + "id": 29, + "name": "method", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 52, + "character": 18 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "stringLiteral", + "value": "GET" + }, + { + "type": "stringLiteral", + "value": "HEAD" + }, + { + "type": "stringLiteral", + "value": "POST" + }, + { + "type": "stringLiteral", + "value": "PATCH" + }, + { + "type": "stringLiteral", + "value": "DELETE" + } + ] + } + }, + { + "id": 35, + "name": "schema", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true, + "isOptional": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 55, + "character": 18 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "string" + } + ] + } + }, + { + "id": 37, + "name": "shouldThrowOnError", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 57, + "character": 30 + } + ], + "type": { + "type": "intrinsic", + "name": "boolean" + } + }, + { + "id": 38, + "name": "signal", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true, + "isOptional": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 58, + "character": 18 + } + ], + "type": { + "type": "reference", + "name": "AbortSignal" + } + }, + { + "id": 30, + "name": "url", + "kind": 1024, + "kindString": "Property", + "flags": { + "isProtected": true, + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 53, + "character": 15 + } + ], + "type": { + "type": "reference", + "name": "URL" + } + }, + { + "id": 47, + "name": "then", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 48, + "name": "then", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "typeParameter": [ + { + "id": 49, + "name": "TResult1", + "kind": 131072, + "kindString": "Type parameter", + "flags": { + "isExported": true + } + }, + { + "id": 50, + "name": "TResult2", + "kind": 131072, + "kindString": "Type parameter", + "flags": { + "isExported": true + } + } + ], + "parameters": [ + { + "id": 51, + "name": "onfulfilled", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true, + "isOptional": true + }, + "type": { + "type": "union", + "types": [ + { + "type": "reflection", + "declaration": { + "id": 52, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 53, + "name": "__call", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "parameters": [ + { + "id": 54, + "name": "value", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "type": { + "type": "reference", + "id": 66, + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestResponse" + } + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "typeParameter", + "name": "TResult1", + "default": { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestResponse" + } + }, + { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "TResult1", + "default": { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestResponse" + } + } + ], + "name": "PromiseLike" + } + ] + } + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 93, + "character": 9 + } + ] + } + }, + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "null" + } + ] + } + }, + { + "id": 55, + "name": "onrejected", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true, + "isOptional": true + }, + "type": { + "type": "union", + "types": [ + { + "type": "reflection", + "declaration": { + "id": 56, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 57, + "name": "__call", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "parameters": [ + { + "id": 58, + "name": "reason", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true + }, + "type": { + "type": "intrinsic", + "name": "any" + } + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "typeParameter", + "name": "TResult2", + "default": { + "type": "intrinsic", + "name": "never" + } + }, + { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "TResult2", + "default": { + "type": "intrinsic", + "name": "never" + } + } + ], + "name": "PromiseLike" + } + ] + } + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 96, + "character": 18 + } + ] + } + }, + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "null" + } + ] + } + } + ], + "type": { + "type": "reference", + "typeArguments": [ + { + "type": "union", + "types": [ + { + "type": "typeParameter", + "name": "TResult1", + "default": { + "type": "reference", + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestResponse" + } + }, + { + "type": "typeParameter", + "name": "TResult2", + "default": { + "type": "intrinsic", + "name": "never" + } + } + ] + } + ], + "name": "PromiseLike" + } + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 91, + "character": 6 + } + ] + }, + { + "id": 44, + "name": "throwOnError", + "kind": 2048, + "kindString": "Method", + "flags": { + "isExported": true + }, + "signatures": [ + { + "id": 45, + "name": "throwOnError", + "kind": 4096, + "kindString": "Call signature", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "If there's an error with the query, throwOnError will reject the promise by\nthrowing the error instead of returning it as part of a successful response.", + "text": "{@link https://github.com/supabase/supabase-js/issues/92}\n" + }, + "parameters": [ + { + "id": 46, + "name": "throwOnError", + "kind": 32768, + "kindString": "Parameter", + "flags": { + "isExported": true, + "isOptional": true + }, + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "undefined" + }, + { + "type": "intrinsic", + "name": "false" + }, + { + "type": "intrinsic", + "name": "true" + } + ] + } + } + ], + "type": { + "type": "intrinsic", + "name": "this" + } + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 83, + "character": 14 + } + ] + } + ], + "groups": [ + { + "title": "Constructors", + "kind": 512, + "children": [41] + }, + { + "title": "Properties", + "kind": 1024, + "children": [40, 36, 39, 31, 29, 35, 37, 38, 30] + }, + { + "title": "Methods", + "kind": 2048, + "children": [47, 44] + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 51, + "character": 38 + } + ], + "extendedBy": [ + { + "type": "reference", + "id": 73, + "name": "PostgrestTransformBuilder" + }, + { + "type": "reference", + "id": 363, + "name": "PostgrestQueryBuilder" + }, + { + "type": "reference", + "id": 449, + "name": "PostgrestRpcBuilder" + } + ], + "implementedTypes": [ + { + "type": "reference", + "typeArguments": [ + { + "type": "reference", + "id": 66, + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestResponse" + } + ], + "name": "PromiseLike" + } + ] + }, + { + "id": 2, + "name": "PostgrestResponseBase", + "kind": 256, + "kindString": "Interface", + "flags": {}, + "comment": { + "shortText": "Response format", + "text": "{@link https://github.com/supabase/supabase-js/issues/32}\n" + }, + "children": [ + { + "id": 3, + "name": "status", + "kind": 1024, + "kindString": "Property", + "flags": {}, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 21, + "character": 8 + } + ], + "type": { + "type": "intrinsic", + "name": "number" + } + }, + { + "id": 4, + "name": "statusText", + "kind": 1024, + "kindString": "Property", + "flags": {}, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 22, + "character": 12 + } + ], + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "groups": [ + { + "title": "Properties", + "kind": 1024, + "children": [3, 4] + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 20, + "character": 31 + } + ], + "extendedBy": [ + { + "type": "reference", + "id": 5, + "name": "PostgrestResponseSuccess" + }, + { + "type": "reference", + "id": 13, + "name": "PostgrestResponseFailure" + }, + { + "type": "reference", + "id": 20, + "name": "PostgrestSingleResponseSuccess" + } + ] + }, + { + "id": 13, + "name": "PostgrestResponseFailure", + "kind": 256, + "kindString": "Interface", + "flags": {}, + "children": [ + { + "id": 16, + "name": "body", + "kind": 1024, + "kindString": "Property", + "flags": {}, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 35, + "character": 6 + } + ], + "type": { + "type": "intrinsic", + "name": "null" + } + }, + { + "id": 17, + "name": "count", + "kind": 1024, + "kindString": "Property", + "flags": {}, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 36, + "character": 7 + } + ], + "type": { + "type": "intrinsic", + "name": "null" + } + }, + { + "id": 15, + "name": "data", + "kind": 1024, + "kindString": "Property", + "flags": {}, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 33, + "character": 6 + } + ], + "type": { + "type": "intrinsic", + "name": "null" + } + }, + { + "id": 14, + "name": "error", + "kind": 1024, + "kindString": "Property", + "flags": {}, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 32, + "character": 7 + } + ], + "type": { + "type": "reference", + "id": 60, + "name": "PostgrestError" + } + }, + { + "id": 18, + "name": "status", + "kind": 1024, + "kindString": "Property", + "flags": {}, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 21, + "character": 8 + } + ], + "type": { + "type": "intrinsic", + "name": "number" + }, + "inheritedFrom": { + "type": "reference", + "id": 3, + "name": "PostgrestResponseBase.status" + } + }, + { + "id": 19, + "name": "statusText", + "kind": 1024, + "kindString": "Property", + "flags": {}, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 22, + "character": 12 + } + ], + "type": { + "type": "intrinsic", + "name": "string" + }, + "inheritedFrom": { + "type": "reference", + "id": 4, + "name": "PostgrestResponseBase.statusText" + } + } + ], + "groups": [ + { + "title": "Properties", + "kind": 1024, + "children": [16, 17, 15, 14, 18, 19] + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 31, + "character": 34 + } + ], + "extendedTypes": [ + { + "type": "reference", + "id": 2, + "name": "PostgrestResponseBase" + } + ] + }, + { + "id": 5, + "name": "PostgrestResponseSuccess", + "kind": 256, + "kindString": "Interface", + "flags": {}, + "typeParameter": [ + { + "id": 6, + "name": "T", + "kind": 131072, + "kindString": "Type parameter", + "flags": {} + } + ], + "children": [ + { + "id": 9, + "name": "body", + "kind": 1024, + "kindString": "Property", + "flags": {}, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 28, + "character": 6 + } + ], + "type": { + "type": "array", + "elementType": { + "type": "typeParameter", + "name": "T" + } + } + }, + { + "id": 10, + "name": "count", + "kind": 1024, + "kindString": "Property", + "flags": {}, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 29, + "character": 7 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "intrinsic", + "name": "number" + }, + { + "type": "intrinsic", + "name": "null" + } + ] + } + }, + { + "id": 8, + "name": "data", + "kind": 1024, + "kindString": "Property", + "flags": {}, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 27, + "character": 6 + } + ], + "type": { + "type": "array", + "elementType": { + "type": "typeParameter", + "name": "T" + } + } + }, + { + "id": 7, + "name": "error", + "kind": 1024, + "kindString": "Property", + "flags": {}, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 26, + "character": 7 + } + ], + "type": { + "type": "intrinsic", + "name": "null" + } + }, + { + "id": 11, + "name": "status", + "kind": 1024, + "kindString": "Property", + "flags": {}, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 21, + "character": 8 + } + ], + "type": { + "type": "intrinsic", + "name": "number" + }, + "inheritedFrom": { + "type": "reference", + "id": 3, + "name": "PostgrestResponseBase.status" + } + }, + { + "id": 12, + "name": "statusText", + "kind": 1024, + "kindString": "Property", + "flags": {}, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 22, + "character": 12 + } + ], + "type": { + "type": "intrinsic", + "name": "string" + }, + "inheritedFrom": { + "type": "reference", + "id": 4, + "name": "PostgrestResponseBase.statusText" + } + } + ], + "groups": [ + { + "title": "Properties", + "kind": 1024, + "children": [9, 10, 8, 7, 11, 12] + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 25, + "character": 34 + } + ], + "extendedTypes": [ + { + "type": "reference", + "id": 2, + "name": "PostgrestResponseBase" + } + ] + }, + { + "id": 20, + "name": "PostgrestSingleResponseSuccess", + "kind": 256, + "kindString": "Interface", + "flags": {}, + "typeParameter": [ + { + "id": 21, + "name": "T", + "kind": 131072, + "kindString": "Type parameter", + "flags": {} + } + ], + "children": [ + { + "id": 24, + "name": "body", + "kind": 1024, + "kindString": "Property", + "flags": {}, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 44, + "character": 6 + } + ], + "type": { + "type": "typeParameter", + "name": "T" + } + }, + { + "id": 23, + "name": "data", + "kind": 1024, + "kindString": "Property", + "flags": {}, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 42, + "character": 6 + } + ], + "type": { + "type": "typeParameter", + "name": "T" + } + }, + { + "id": 22, + "name": "error", + "kind": 1024, + "kindString": "Property", + "flags": {}, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 41, + "character": 7 + } + ], + "type": { + "type": "intrinsic", + "name": "null" + } + }, + { + "id": 25, + "name": "status", + "kind": 1024, + "kindString": "Property", + "flags": {}, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 21, + "character": 8 + } + ], + "type": { + "type": "intrinsic", + "name": "number" + }, + "inheritedFrom": { + "type": "reference", + "id": 3, + "name": "PostgrestResponseBase.status" + } + }, + { + "id": 26, + "name": "statusText", + "kind": 1024, + "kindString": "Property", + "flags": {}, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 22, + "character": 12 + } + ], + "type": { + "type": "intrinsic", + "name": "string" + }, + "inheritedFrom": { + "type": "reference", + "id": 4, + "name": "PostgrestResponseBase.statusText" + } + } + ], + "groups": [ + { + "title": "Properties", + "kind": 1024, + "children": [24, 23, 22, 25, 26] + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 40, + "character": 40 + } + ], + "extendedTypes": [ + { + "type": "reference", + "id": 2, + "name": "PostgrestResponseBase" + } + ] + }, + { + "id": 59, + "name": "Fetch", + "kind": 4194304, + "kindString": "Type alias", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 1, + "character": 17 + } + ], + "type": { + "type": "query", + "queryType": { + "type": "reference", + "id": 375, + "name": "fetch" + } + } + }, + { + "id": 60, + "name": "PostgrestError", + "kind": 4194304, + "kindString": "Type alias", + "flags": { + "isExported": true + }, + "comment": { + "shortText": "Error format", + "text": "{@link https://postgrest.org/en/stable/api.html?highlight=options#errors-and-http-status-codes}\n" + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 8, + "character": 26 + } + ], + "type": { + "type": "reflection", + "declaration": { + "id": 61, + "name": "__type", + "kind": 65536, + "kindString": "Type literal", + "flags": { + "isExported": true + }, + "children": [ + { + "id": 65, + "name": "code", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 12, + "character": 6 + } + ], + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "id": 63, + "name": "details", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 10, + "character": 9 + } + ], + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "id": 64, + "name": "hint", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 11, + "character": 6 + } + ], + "type": { + "type": "intrinsic", + "name": "string" + } + }, + { + "id": 62, + "name": "message", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true + }, + "sources": [ + { + "fileName": "lib/types.ts", + "line": 9, + "character": 9 + } + ], + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [65, 63, 64, 62] + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 8, + "character": 28 + } + ] + } + } + }, + { + "id": 70, + "name": "PostgrestMaybeSingleResponse", + "kind": 4194304, + "kindString": "Type alias", + "flags": { + "isExported": true + }, + "typeParameter": [ + { + "id": 71, + "name": "T", + "kind": 131072, + "kindString": "Type parameter", + "flags": { + "isExported": true + } + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 49, + "character": 40 + } + ], + "type": { + "type": "reference", + "id": 68, + "typeArguments": [ + { + "type": "union", + "types": [ + { + "type": "typeParameter", + "name": "T" + }, + { + "type": "intrinsic", + "name": "null" + } + ] + } + ], + "name": "PostgrestSingleResponse" + } + }, + { + "id": 66, + "name": "PostgrestResponse", + "kind": 4194304, + "kindString": "Type alias", + "flags": { + "isExported": true + }, + "typeParameter": [ + { + "id": 67, + "name": "T", + "kind": 131072, + "kindString": "Type parameter", + "flags": { + "isExported": true + } + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 38, + "character": 29 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "reference", + "id": 5, + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestResponseSuccess" + }, + { + "type": "reference", + "id": 13, + "name": "PostgrestResponseFailure" + } + ] + } + }, + { + "id": 68, + "name": "PostgrestSingleResponse", + "kind": 4194304, + "kindString": "Type alias", + "flags": { + "isExported": true + }, + "typeParameter": [ + { + "id": 69, + "name": "T", + "kind": 131072, + "kindString": "Type parameter", + "flags": { + "isExported": true + } + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 46, + "character": 35 + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "reference", + "id": 20, + "typeArguments": [ + { + "type": "typeParameter", + "name": "T" + } + ], + "name": "PostgrestSingleResponseSuccess" + }, + { + "type": "reference", + "id": 13, + "name": "PostgrestResponseFailure" + } + ] + } + } + ], + "groups": [ + { + "title": "Classes", + "kind": 128, + "children": [27] + }, + { + "title": "Interfaces", + "kind": 256, + "children": [2, 13, 5, 20] + }, + { + "title": "Type aliases", + "kind": 4194304, + "children": [59, 60, 70, 66, 68] + } + ], + "sources": [ + { + "fileName": "lib/types.ts", + "line": 1, + "character": 0 + } + ] + }, + { + "id": 497, + "name": "\"lib/version\"", + "kind": 1, + "kindString": "Module", + "flags": { + "isExported": true + }, + "originalName": "/Users/copple/Projects/Supabase/postgrest-js/src/lib/version.ts", + "children": [ + { + "id": 498, + "name": "version", + "kind": 32, + "kindString": "Variable", + "flags": { + "isExported": true, + "isConst": true + }, + "sources": [ + { + "fileName": "lib/version.ts", + "line": 2, + "character": 20 + } + ], + "type": { + "type": "stringLiteral", + "value": "0.0.0-automated" + }, + "defaultValue": "\"0.0.0-automated\"" + } + ], + "groups": [ + { + "title": "Variables", + "kind": 32, + "children": [498] + } + ], + "sources": [ + { + "fileName": "lib/version.ts", + "line": 1, + "character": 0 + } + ] + } + ], + "groups": [ + { + "title": "Modules", + "kind": 1, + "children": [502, 540, 149, 362, 448, 72, 499, 1, 497] + } + ] +} diff --git a/package-lock.json b/package-lock.json index 4f4e2619..5200b488 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,17 +9,20 @@ "version": "0.0.0-automated", "license": "MIT", "dependencies": { - "cross-fetch": "^3.1.5" + "@supabase/node-fetch": "^2.6.14" }, "devDependencies": { "@types/jest": "^27.5.1", + "cpy-cli": "^5.0.0", "jest": "^28.1.0", "node-abort-controller": "^3.0.1", "npm-run-all": "^4.1.5", "prettier": "^2.6.2", "rimraf": "^3.0.2", "semantic-release-plugin-update-version-in-files": "^1.1.0", + "ts-expect": "^1.3.0", "ts-jest": "^28.0.3", + "tsd": "^0.31.2", "typedoc": "^0.22.16", "typescript": "~4.7", "wait-for-localhost-cli": "^3.0.0" @@ -39,17 +42,80 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dev": true, "dependencies": { - "@babel/highlight": "^7.16.7" + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/compat-data": { "version": "7.17.10", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.10.tgz", @@ -99,13 +165,14 @@ } }, "node_modules/@babel/generator": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.2.tgz", - "integrity": "sha512-W1lG5vUwFvfMd8HVXqdfbuG7RuaSrTCCD8cl8fP8wOivdbtbIg2Db3IWUcgvfxKbbn6ZBGYRW/Zk1MIwK49mgw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", "dev": true, "dependencies": { - "@babel/types": "^7.18.2", - "@jridgewell/gen-mapping": "^0.3.0", + "@babel/types": "^7.23.0", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" }, "engines": { @@ -113,12 +180,12 @@ } }, "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.1.tgz", - "integrity": "sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.0.0", + "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.9" }, @@ -154,34 +221,34 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.2.tgz", - "integrity": "sha512-14GQKWkX9oJzPiQQ7/J36FTXcD4kSp8egKjO9nINlSKiHITRA9q/R74qu8S9xlc/b/yjsJItQUeeh3xnGN0voQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.17.9", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz", - "integrity": "sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "dependencies": { - "@babel/template": "^7.16.7", - "@babel/types": "^7.17.0" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", - "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dev": true, "dependencies": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -240,21 +307,30 @@ } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", - "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, "dependencies": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/helper-string-parser": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true, "engines": { "node": ">=6.9.0" @@ -284,13 +360,13 @@ } }, "node_modules/@babel/highlight": { - "version": "7.17.12", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.12.tgz", - "integrity": "sha512-7yykMVF3hfZY2jsHZEEgLc+3x4o1O+fYyULu11GynEUQNwB6lua+IIQn1FiJxNucd5UlyJryrwsOh8PL9Sn8Qg==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.16.7", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -360,9 +436,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.18.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.4.tgz", - "integrity": "sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -534,33 +610,33 @@ } }, "node_modules/@babel/template": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", - "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.16.7", - "@babel/parser": "^7.16.7", - "@babel/types": "^7.16.7" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.2.tgz", - "integrity": "sha512-9eNwoeovJ6KH9zcCNnENY7DMFwTU9JdGCFtqNLfUAqtUHRCOsTOqWoffosP8vKmNYeSBUv3yVJXjfd8ucwOjUA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.18.2", - "@babel/helper-environment-visitor": "^7.18.2", - "@babel/helper-function-name": "^7.17.9", - "@babel/helper-hoist-variables": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.18.0", - "@babel/types": "^7.18.2", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -569,12 +645,13 @@ } }, "node_modules/@babel/types": { - "version": "7.18.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.4.tgz", - "integrity": "sha512-ThN1mBcMq5pG/Vm2IcBmPPfyPXbd8S02rS+OBIDENdufvqC7Z/jHPCv9IcP01277aKtDI8g/2XysBN4hA8niiw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.16.7", + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { @@ -937,9 +1014,9 @@ } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz", - "integrity": "sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", "dev": true, "engines": { "node": ">=6.0.0" @@ -955,19 +1032,54 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.13", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz", - "integrity": "sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==", + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz", - "integrity": "sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w==", + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" } }, "node_modules/@sinclair/typebox": { @@ -994,6 +1106,27 @@ "@sinonjs/commons": "^1.7.0" } }, + "node_modules/@supabase/node-fetch": { + "version": "2.6.14", + "resolved": "https://registry.npmjs.org/@supabase/node-fetch/-/node-fetch-2.6.14.tgz", + "integrity": "sha512-w/Tsd22e/5fAeoxqQ4P2MX6EyF+iM6rc9kmlMVFkHuG0rAltt2TLhFbDJfemnHbtvnazWaRfy5KnFU/SYT37dQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + } + }, + "node_modules/@tsd/typescript": { + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/@tsd/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-saiCxzHRhUrRxQV2JhH580aQUZiKQUXI38FcAcikcfOomAil4G4lxT0RfrrKywoAYP/rqAdYXYmNRLppcd+hQQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.17" + } + }, "node_modules/@types/babel__core": { "version": "7.1.19", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", @@ -1041,6 +1174,22 @@ "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, + "node_modules/@types/eslint": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.29.0.tgz", + "integrity": "sha512-VNcvioYDH8/FxaeTKkM4/TiTwt6pBV9E3OfGmvaw8tPl0rrHCJ4Ll15HRT+pMiFAf/MLQvAzC+6RzUMEL9Ceng==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", + "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==", + "dev": true + }, "node_modules/@types/graceful-fs": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", @@ -1084,6 +1233,12 @@ "pretty-format": "^27.0.0" } }, + "node_modules/@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, "node_modules/@types/minimist": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", @@ -1129,6 +1284,22 @@ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", "dev": true }, + "node_modules/aggregate-error": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz", + "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==", + "dev": true, + "dependencies": { + "clean-stack": "^4.0.0", + "indent-string": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -1191,6 +1362,15 @@ "sprintf-js": "~1.0.2" } }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", @@ -1308,12 +1488,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -1488,6 +1668,33 @@ "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", "dev": true }, + "node_modules/clean-stack": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-4.2.0.tgz", + "integrity": "sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clean-stack/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -1548,12 +1755,117 @@ "safe-buffer": "~5.1.1" } }, - "node_modules/cross-fetch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", - "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "node_modules/cp-file": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-10.0.0.tgz", + "integrity": "sha512-vy2Vi1r2epK5WqxOLnskeKeZkdZvTKfFZQCplE3XWsP+SUJyd5XAUFC9lFgTjjXJF2GMne/UML14iEmkAaDfFg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.10", + "nested-error-stacks": "^2.1.1", + "p-event": "^5.0.1" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cpy": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/cpy/-/cpy-10.1.0.tgz", + "integrity": "sha512-VC2Gs20JcTyeQob6UViBLnyP0bYHkBh6EiKzot9vi2DmeGlFT9Wd7VG3NBrkNx/jYvFBeyDOMMHdHQhbtKLgHQ==", + "dev": true, + "dependencies": { + "arrify": "^3.0.0", + "cp-file": "^10.0.0", + "globby": "^13.1.4", + "junk": "^4.0.1", + "micromatch": "^4.0.5", + "nested-error-stacks": "^2.1.1", + "p-filter": "^3.0.0", + "p-map": "^6.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cpy-cli": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cpy-cli/-/cpy-cli-5.0.0.tgz", + "integrity": "sha512-fb+DZYbL9KHc0BC4NYqGRrDIJZPXUmjjtqdw4XRRg8iV8dIfghUX/WiL+q4/B/KFTy3sK6jsbUhBaz0/Hxg7IQ==", + "dev": true, + "dependencies": { + "cpy": "^10.1.0", + "meow": "^12.0.1" + }, + "bin": { + "cpy": "cli.js" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cpy-cli/node_modules/meow": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", + "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", + "dev": true, + "engines": { + "node": ">=16.10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cpy/node_modules/arrify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-3.0.0.tgz", + "integrity": "sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cpy/node_modules/globby": { + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", + "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", + "dev": true, "dependencies": { - "node-fetch": "2.6.7" + "dir-glob": "^3.0.1", + "fast-glob": "^3.3.0", + "ignore": "^5.2.4", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cpy/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/cross-spawn": { @@ -1678,6 +1990,27 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dir-glob/node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/electron-to-chromium": { "version": "1.4.142", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.142.tgz", @@ -1771,17 +2104,45 @@ "node": ">=0.8.0" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "node_modules/eslint-formatter-pretty": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-formatter-pretty/-/eslint-formatter-pretty-4.1.0.tgz", + "integrity": "sha512-IsUTtGxF1hrH6lMWiSl1WbGaiP01eT6kzywdY1U+zLc0MP+nwEnUiS9UI8IaOTUhTeQJLlCEWIbXINBH4YJbBQ==", "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" + "dependencies": { + "@types/eslint": "^7.2.13", + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.0", + "eslint-rule-docs": "^1.1.5", + "log-symbols": "^4.0.0", + "plur": "^4.0.0", + "string-width": "^4.2.0", + "supports-hyperlinks": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-rule-docs": { + "version": "1.1.235", + "resolved": "https://registry.npmjs.org/eslint-rule-docs/-/eslint-rule-docs-1.1.235.tgz", + "integrity": "sha512-+TQ+x4JdTnDoFEXXb3fDvfGOwnyNV7duH8fXWTPD1ieaBmB8omj7Gw/pMBBu4uI2uJCCU8APDaQJzWuXnTsH4A==", + "dev": true + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" } }, "node_modules/execa": { @@ -1963,12 +2324,37 @@ "integrity": "sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==", "dev": true }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, + "node_modules/fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, "node_modules/fb-watchman": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", @@ -1979,9 +2365,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" @@ -2088,6 +2474,18 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -2097,6 +2495,26 @@ "node": ">=4" } }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", @@ -2166,6 +2584,15 @@ "node": ">=10.17.0" } }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/import-local": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", @@ -2222,6 +2649,15 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "node_modules/irregular-plurals": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.3.0.tgz", + "integrity": "sha512-MVBLKUTangM3EfRPFROhmWQQKRDsrgI83J8GS3jXy+OwYqiR2/aoWndYQ5416jLE3uaGgLH7ncme3X9y09gZ3g==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -2264,6 +2700,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -2282,6 +2727,18 @@ "node": ">=6" } }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -2342,6 +2799,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -3363,9 +3832,9 @@ "dev": true }, "node_modules/json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, "bin": { "json5": "lib/cli.js" @@ -3375,11 +3844,23 @@ } }, "node_modules/jsonc-parser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz", - "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", "dev": true }, + "node_modules/junk": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/junk/-/junk-4.0.1.tgz", + "integrity": "sha512-Qush0uP+G8ZScpGMZvHUiRfI0YBWuB3gVBYlI0v0vvOJt5FLicco+IkP0a50LqTTQhmts/m6tP5SWE+USyIvcQ==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -3477,6 +3958,22 @@ "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", "dev": true }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -3547,9 +4044,9 @@ } }, "node_modules/marked": { - "version": "4.0.16", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.16.tgz", - "integrity": "sha512-wahonIQ5Jnyatt2fn8KqF/nIqZM8mh3oRu2+l5EANGMhu6RFjiSG52QNE2eWzFMI94HqYSgN184NurgNG6CztA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.1.1.tgz", + "integrity": "sha512-0cNMnTcUJPxbA6uWmCmjWz4NJRe/0Xfk2NhXCUHjew9qJzFN20krFnsUe7QynwqOwa5m1fZ4UDg0ycKFVC0ccw==", "dev": true, "bin": { "marked": "bin/marked.js" @@ -3653,6 +4150,15 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -3685,9 +4191,9 @@ } }, "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "dependencies": { "brace-expansion": "^1.1.7" @@ -3722,6 +4228,12 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node_modules/nested-error-stacks": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.1.tgz", + "integrity": "sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw==", + "dev": true + }, "node_modules/nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -3734,33 +4246,6 @@ "integrity": "sha512-/ujIVxthRs+7q6hsdjHMaj8hRG9NuWmwrz+JdRwZ14jdFoKSkm+vDsCbF9PLpnSqjaWQJuTmVtcWHNLr+vrOFw==", "dev": true }, - "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dependencies": { - "whatwg-url": "^5.0.0" - } - }, - "node_modules/node-fetch/node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" - }, - "node_modules/node-fetch/node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" - }, - "node_modules/node-fetch/node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -3973,6 +4458,51 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-event": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-5.0.1.tgz", + "integrity": "sha512-dd589iCQ7m1L0bmC5NLlVYfy3TbBEsMUfWx9PyAgPeIcFZ/E2yaTZ4Rz4MiBmmJShviiftHVXOqfnfzJ6kyMrQ==", + "dev": true, + "dependencies": { + "p-timeout": "^5.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-3.0.0.tgz", + "integrity": "sha512-QtoWLjXAW++uTX67HZQz1dbTpqBfiidsB6VtQUC9iR85S120+s0T5sO6s+B5MLzFcZkrEd/DGMmCjR+f2Qpxwg==", + "dev": true, + "dependencies": { + "p-map": "^5.1.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-filter/node_modules/p-map": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-5.5.0.tgz", + "integrity": "sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==", + "dev": true, + "dependencies": { + "aggregate-error": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -4000,6 +4530,30 @@ "node": ">=8" } }, + "node_modules/p-map": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-6.0.0.tgz", + "integrity": "sha512-T8BatKGY+k5rU+Q/GTYgrEf2r4xRMevAN5mtXc2aPc4rS1j3s+vWTaO2Wag94neXuCAUAs8cxBL9EeB5EA6diw==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-5.1.0.tgz", + "integrity": "sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -4132,11 +4686,27 @@ "node": ">=8" } }, + "node_modules/plur": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/plur/-/plur-4.0.0.tgz", + "integrity": "sha512-4UGewrYgqDFw9vV6zNV+ADmPAUAfJPKtGvb/VdpQAx25X5f3xXdGdyOEVFwkl8Hl/tl7+xbeHqSEM+D5/TirUg==", + "dev": true, + "dependencies": { + "irregular-plurals": "^3.2.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/prettier": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz", - "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==", + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true, + "license": "MIT", "bin": { "prettier": "bin-prettier.js" }, @@ -4186,6 +4756,26 @@ "node": ">= 6" } }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/quick-lru": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", @@ -4438,6 +5028,16 @@ "node": ">=10" } }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -4453,6 +5053,29 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -4500,10 +5123,13 @@ } }, "node_modules/shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", - "dev": true + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.0.tgz", + "integrity": "sha512-QHsz8GgQIGKlRi24yFc6a6lN69Idnx634w49ay6+jA5yFh7a1UY+4Rp6HPx/L/1zcEDPEij8cIsiqR6bQsE5VQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/shiki": { "version": "0.10.1", @@ -4841,6 +5467,11 @@ "node": ">=8.0" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, "node_modules/trim-newlines": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-4.0.2.tgz", @@ -4853,6 +5484,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/ts-expect": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-expect/-/ts-expect-1.3.0.tgz", + "integrity": "sha512-e4g0EJtAjk64xgnFPD6kTBUtpnMVzDrMb12N1YZV0VvSlhnVT3SGxiYTLdGy8Q5cYHOIC/FAHmZ10eGrAguicQ==", + "dev": true, + "license": "MIT" + }, "node_modules/ts-jest": { "version": "28.0.3", "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-28.0.3.tgz", @@ -4908,31 +5546,379 @@ "node": ">=10" } }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "node_modules/tsd": { + "version": "0.31.2", + "resolved": "https://registry.npmjs.org/tsd/-/tsd-0.31.2.tgz", + "integrity": "sha512-VplBAQwvYrHzVihtzXiUVXu5bGcr7uH1juQZ1lmKgkuGNGT+FechUCqmx9/zk7wibcqR2xaNEwCkDyKh+VVZnQ==", "dev": true, + "license": "MIT", + "dependencies": { + "@tsd/typescript": "~5.4.3", + "eslint-formatter-pretty": "^4.1.0", + "globby": "^11.0.1", + "jest-diff": "^29.0.3", + "meow": "^9.0.0", + "path-exists": "^4.0.0", + "read-pkg-up": "^7.0.0" + }, + "bin": { + "tsd": "dist/cli.js" + }, "engines": { - "node": ">=4" + "node": ">=14.16" } }, - "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "node_modules/tsd/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dev": true, - "engines": { - "node": ">=10" + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" }, - "funding": { + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/tsd/node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tsd/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/tsd/node_modules/camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tsd/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tsd/node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/tsd/node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tsd/node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/tsd/node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/tsd/node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/tsd/node_modules/meow": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", + "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", + "dev": true, + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize": "^1.2.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tsd/node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tsd/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/tsd/node_modules/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/tsd/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tsd/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tsd/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tsd/node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/tsd/node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/tsd/node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/tsd/node_modules/read-pkg/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/tsd/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/tsd/node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tsd/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tsd/node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tsd/node_modules/trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/tsd/node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/typedoc": { - "version": "0.22.16", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.16.tgz", - "integrity": "sha512-0Qf0/CsQe6JZTXoYwBM3Iql8gLAWLjQP7O/j9YzfkJp3G/WVGmIMRajKnldJuA/zVvhr+ifsHTgctQh5g2t4iw==", + "version": "0.22.18", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.18.tgz", + "integrity": "sha512-NK9RlLhRUGMvc6Rw5USEYgT4DVAUFk7IF7Q6MYfpJ88KnTZP7EneEa4RcP+tX1auAcz7QT1Iy0bUSZBYYHdoyA==", "dev": true, "dependencies": { "glob": "^8.0.3", @@ -5080,6 +6066,20 @@ "makeerror": "1.0.12" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -5204,12 +6204,65 @@ } }, "@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dev": true, "requires": { - "@babel/highlight": "^7.16.7" + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "@babel/compat-data": { @@ -5250,23 +6303,24 @@ } }, "@babel/generator": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.2.tgz", - "integrity": "sha512-W1lG5vUwFvfMd8HVXqdfbuG7RuaSrTCCD8cl8fP8wOivdbtbIg2Db3IWUcgvfxKbbn6ZBGYRW/Zk1MIwK49mgw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", "dev": true, "requires": { - "@babel/types": "^7.18.2", - "@jridgewell/gen-mapping": "^0.3.0", + "@babel/types": "^7.23.0", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" }, "dependencies": { "@jridgewell/gen-mapping": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.1.tgz", - "integrity": "sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", "dev": true, "requires": { - "@jridgewell/set-array": "^1.0.0", + "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.9" } @@ -5294,28 +6348,28 @@ } }, "@babel/helper-environment-visitor": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.2.tgz", - "integrity": "sha512-14GQKWkX9oJzPiQQ7/J36FTXcD4kSp8egKjO9nINlSKiHITRA9q/R74qu8S9xlc/b/yjsJItQUeeh3xnGN0voQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true }, "@babel/helper-function-name": { - "version": "7.17.9", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz", - "integrity": "sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "requires": { - "@babel/template": "^7.16.7", - "@babel/types": "^7.17.0" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" } }, "@babel/helper-hoist-variables": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", - "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dev": true, "requires": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.22.5" } }, "@babel/helper-module-imports": { @@ -5359,18 +6413,24 @@ } }, "@babel/helper-split-export-declaration": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", - "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, "requires": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.22.5" } }, + "@babel/helper-string-parser": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "dev": true + }, "@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true }, "@babel/helper-validator-option": { @@ -5391,13 +6451,13 @@ } }, "@babel/highlight": { - "version": "7.17.12", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.12.tgz", - "integrity": "sha512-7yykMVF3hfZY2jsHZEEgLc+3x4o1O+fYyULu11GynEUQNwB6lua+IIQn1FiJxNucd5UlyJryrwsOh8PL9Sn8Qg==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.16.7", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "dependencies": { @@ -5454,9 +6514,9 @@ } }, "@babel/parser": { - "version": "7.18.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.4.tgz", - "integrity": "sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", "dev": true }, "@babel/plugin-syntax-async-generators": { @@ -5577,41 +6637,42 @@ } }, "@babel/template": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", - "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, "requires": { - "@babel/code-frame": "^7.16.7", - "@babel/parser": "^7.16.7", - "@babel/types": "^7.16.7" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" } }, "@babel/traverse": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.2.tgz", - "integrity": "sha512-9eNwoeovJ6KH9zcCNnENY7DMFwTU9JdGCFtqNLfUAqtUHRCOsTOqWoffosP8vKmNYeSBUv3yVJXjfd8ucwOjUA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.18.2", - "@babel/helper-environment-visitor": "^7.18.2", - "@babel/helper-function-name": "^7.17.9", - "@babel/helper-hoist-variables": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.18.0", - "@babel/types": "^7.18.2", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.18.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.4.tgz", - "integrity": "sha512-ThN1mBcMq5pG/Vm2IcBmPPfyPXbd8S02rS+OBIDENdufvqC7Z/jHPCv9IcP01277aKtDI8g/2XysBN4hA8niiw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.16.7", + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" } }, @@ -5897,9 +6958,9 @@ } }, "@jridgewell/resolve-uri": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz", - "integrity": "sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", "dev": true }, "@jridgewell/set-array": { @@ -5909,19 +6970,45 @@ "dev": true }, "@jridgewell/sourcemap-codec": { - "version": "1.4.13", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz", - "integrity": "sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==", + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", "dev": true }, "@jridgewell/trace-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz", - "integrity": "sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w==", + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", "dev": true, "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" } }, "@sinclair/typebox": { @@ -5948,6 +7035,20 @@ "@sinonjs/commons": "^1.7.0" } }, + "@supabase/node-fetch": { + "version": "2.6.14", + "resolved": "https://registry.npmjs.org/@supabase/node-fetch/-/node-fetch-2.6.14.tgz", + "integrity": "sha512-w/Tsd22e/5fAeoxqQ4P2MX6EyF+iM6rc9kmlMVFkHuG0rAltt2TLhFbDJfemnHbtvnazWaRfy5KnFU/SYT37dQ==", + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "@tsd/typescript": { + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/@tsd/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-saiCxzHRhUrRxQV2JhH580aQUZiKQUXI38FcAcikcfOomAil4G4lxT0RfrrKywoAYP/rqAdYXYmNRLppcd+hQQ==", + "dev": true + }, "@types/babel__core": { "version": "7.1.19", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", @@ -5995,6 +7096,22 @@ "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, + "@types/eslint": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.29.0.tgz", + "integrity": "sha512-VNcvioYDH8/FxaeTKkM4/TiTwt6pBV9E3OfGmvaw8tPl0rrHCJ4Ll15HRT+pMiFAf/MLQvAzC+6RzUMEL9Ceng==", + "dev": true, + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/estree": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", + "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==", + "dev": true + }, "@types/graceful-fs": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", @@ -6038,6 +7155,12 @@ "pretty-format": "^27.0.0" } }, + "@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, "@types/minimist": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", @@ -6083,6 +7206,16 @@ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", "dev": true }, + "aggregate-error": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz", + "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==", + "dev": true, + "requires": { + "clean-stack": "^4.0.0", + "indent-string": "^5.0.0" + } + }, "ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -6127,6 +7260,12 @@ "sprintf-js": "~1.0.2" } }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", @@ -6220,12 +7359,12 @@ } }, "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "requires": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" } }, "browserslist": { @@ -6337,6 +7476,23 @@ "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", "dev": true }, + "clean-stack": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-4.2.0.tgz", + "integrity": "sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==", + "dev": true, + "requires": { + "escape-string-regexp": "5.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true + } + } + }, "cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -6390,12 +7546,76 @@ "safe-buffer": "~5.1.1" } }, - "cross-fetch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", - "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "cp-file": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-10.0.0.tgz", + "integrity": "sha512-vy2Vi1r2epK5WqxOLnskeKeZkdZvTKfFZQCplE3XWsP+SUJyd5XAUFC9lFgTjjXJF2GMne/UML14iEmkAaDfFg==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.10", + "nested-error-stacks": "^2.1.1", + "p-event": "^5.0.1" + } + }, + "cpy": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/cpy/-/cpy-10.1.0.tgz", + "integrity": "sha512-VC2Gs20JcTyeQob6UViBLnyP0bYHkBh6EiKzot9vi2DmeGlFT9Wd7VG3NBrkNx/jYvFBeyDOMMHdHQhbtKLgHQ==", + "dev": true, + "requires": { + "arrify": "^3.0.0", + "cp-file": "^10.0.0", + "globby": "^13.1.4", + "junk": "^4.0.1", + "micromatch": "^4.0.5", + "nested-error-stacks": "^2.1.1", + "p-filter": "^3.0.0", + "p-map": "^6.0.0" + }, + "dependencies": { + "arrify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-3.0.0.tgz", + "integrity": "sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==", + "dev": true + }, + "globby": { + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", + "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", + "dev": true, + "requires": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.3.0", + "ignore": "^5.2.4", + "merge2": "^1.4.1", + "slash": "^4.0.0" + } + }, + "slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true + } + } + }, + "cpy-cli": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cpy-cli/-/cpy-cli-5.0.0.tgz", + "integrity": "sha512-fb+DZYbL9KHc0BC4NYqGRrDIJZPXUmjjtqdw4XRRg8iV8dIfghUX/WiL+q4/B/KFTy3sK6jsbUhBaz0/Hxg7IQ==", + "dev": true, "requires": { - "node-fetch": "2.6.7" + "cpy": "^10.1.0", + "meow": "^12.0.1" + }, + "dependencies": { + "meow": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", + "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", + "dev": true + } } }, "cross-spawn": { @@ -6483,6 +7703,23 @@ "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", "dev": true }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + }, + "dependencies": { + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + } + } + }, "electron-to-chromium": { "version": "1.4.142", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.142.tgz", @@ -6552,6 +7789,28 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, + "eslint-formatter-pretty": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-formatter-pretty/-/eslint-formatter-pretty-4.1.0.tgz", + "integrity": "sha512-IsUTtGxF1hrH6lMWiSl1WbGaiP01eT6kzywdY1U+zLc0MP+nwEnUiS9UI8IaOTUhTeQJLlCEWIbXINBH4YJbBQ==", + "dev": true, + "requires": { + "@types/eslint": "^7.2.13", + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.0", + "eslint-rule-docs": "^1.1.5", + "log-symbols": "^4.0.0", + "plur": "^4.0.0", + "string-width": "^4.2.0", + "supports-hyperlinks": "^2.0.0" + } + }, + "eslint-rule-docs": { + "version": "1.1.235", + "resolved": "https://registry.npmjs.org/eslint-rule-docs/-/eslint-rule-docs-1.1.235.tgz", + "integrity": "sha512-+TQ+x4JdTnDoFEXXb3fDvfGOwnyNV7duH8fXWTPD1ieaBmB8omj7Gw/pMBBu4uI2uJCCU8APDaQJzWuXnTsH4A==", + "dev": true + }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", @@ -6693,12 +7952,34 @@ } } }, + "fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, + "fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, "fb-watchman": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", @@ -6709,9 +7990,9 @@ } }, "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "requires": { "to-regex-range": "^5.0.1" @@ -6784,12 +8065,35 @@ "path-is-absolute": "^1.0.0" } }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, "graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", @@ -6841,6 +8145,12 @@ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true }, + "ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true + }, "import-local": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", @@ -6879,6 +8189,12 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "irregular-plurals": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.3.0.tgz", + "integrity": "sha512-MVBLKUTangM3EfRPFROhmWQQKRDsrgI83J8GS3jXy+OwYqiR2/aoWndYQ5416jLE3uaGgLH7ncme3X9y09gZ3g==", + "dev": true + }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -6906,6 +8222,12 @@ "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", "dev": true }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -6918,6 +8240,15 @@ "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -6954,6 +8285,12 @@ "has-symbols": "^1.0.1" } }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -7744,15 +9081,21 @@ "dev": true }, "json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true }, "jsonc-parser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz", - "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true + }, + "junk": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/junk/-/junk-4.0.1.tgz", + "integrity": "sha512-Qush0uP+G8ZScpGMZvHUiRfI0YBWuB3gVBYlI0v0vvOJt5FLicco+IkP0a50LqTTQhmts/m6tP5SWE+USyIvcQ==", "dev": true }, "kind-of": { @@ -7830,6 +9173,16 @@ "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", "dev": true }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -7884,9 +9237,9 @@ "dev": true }, "marked": { - "version": "4.0.16", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.16.tgz", - "integrity": "sha512-wahonIQ5Jnyatt2fn8KqF/nIqZM8mh3oRu2+l5EANGMhu6RFjiSG52QNE2eWzFMI94HqYSgN184NurgNG6CztA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.1.1.tgz", + "integrity": "sha512-0cNMnTcUJPxbA6uWmCmjWz4NJRe/0Xfk2NhXCUHjew9qJzFN20krFnsUe7QynwqOwa5m1fZ4UDg0ycKFVC0ccw==", "dev": true }, "memorystream": { @@ -7959,6 +9312,12 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, "micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -7982,9 +9341,9 @@ "dev": true }, "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -8013,6 +9372,12 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "nested-error-stacks": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.1.tgz", + "integrity": "sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw==", + "dev": true + }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -8025,35 +9390,6 @@ "integrity": "sha512-/ujIVxthRs+7q6hsdjHMaj8hRG9NuWmwrz+JdRwZ14jdFoKSkm+vDsCbF9PLpnSqjaWQJuTmVtcWHNLr+vrOFw==", "dev": true }, - "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "requires": { - "whatwg-url": "^5.0.0" - }, - "dependencies": { - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - } - } - }, "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -8223,6 +9559,35 @@ "mimic-fn": "^2.1.0" } }, + "p-event": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-5.0.1.tgz", + "integrity": "sha512-dd589iCQ7m1L0bmC5NLlVYfy3TbBEsMUfWx9PyAgPeIcFZ/E2yaTZ4Rz4MiBmmJShviiftHVXOqfnfzJ6kyMrQ==", + "dev": true, + "requires": { + "p-timeout": "^5.0.2" + } + }, + "p-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-3.0.0.tgz", + "integrity": "sha512-QtoWLjXAW++uTX67HZQz1dbTpqBfiidsB6VtQUC9iR85S120+s0T5sO6s+B5MLzFcZkrEd/DGMmCjR+f2Qpxwg==", + "dev": true, + "requires": { + "p-map": "^5.1.0" + }, + "dependencies": { + "p-map": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-5.5.0.tgz", + "integrity": "sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==", + "dev": true, + "requires": { + "aggregate-error": "^4.0.0" + } + } + } + }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -8241,6 +9606,18 @@ "p-limit": "^2.2.0" } }, + "p-map": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-6.0.0.tgz", + "integrity": "sha512-T8BatKGY+k5rU+Q/GTYgrEf2r4xRMevAN5mtXc2aPc4rS1j3s+vWTaO2Wag94neXuCAUAs8cxBL9EeB5EA6diw==", + "dev": true + }, + "p-timeout": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-5.1.0.tgz", + "integrity": "sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==", + "dev": true + }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -8333,10 +9710,19 @@ "find-up": "^4.0.0" } }, + "plur": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/plur/-/plur-4.0.0.tgz", + "integrity": "sha512-4UGewrYgqDFw9vV6zNV+ADmPAUAfJPKtGvb/VdpQAx25X5f3xXdGdyOEVFwkl8Hl/tl7+xbeHqSEM+D5/TirUg==", + "dev": true, + "requires": { + "irregular-plurals": "^3.2.0" + } + }, "prettier": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz", - "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==", + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true }, "pretty-format": { @@ -8368,6 +9754,12 @@ "sisteransi": "^1.0.5" } }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, "quick-lru": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", @@ -8534,6 +9926,12 @@ "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", "dev": true }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -8543,6 +9941,15 @@ "glob": "^7.1.3" } }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -8581,9 +9988,9 @@ "dev": true }, "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.0.tgz", + "integrity": "sha512-QHsz8GgQIGKlRi24yFc6a6lN69Idnx634w49ay6+jA5yFh7a1UY+4Rp6HPx/L/1zcEDPEij8cIsiqR6bQsE5VQ==", "dev": true }, "shiki": { @@ -8846,12 +10253,23 @@ "is-number": "^7.0.0" } }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, "trim-newlines": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-4.0.2.tgz", "integrity": "sha512-GJtWyq9InR/2HRiLZgpIKv+ufIKrVrvjQWEj7PxAXNc5dwbNJkqhAUoAGgzRmULAnoOM5EIpveYd3J2VeSAIew==", "dev": true }, + "ts-expect": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-expect/-/ts-expect-1.3.0.tgz", + "integrity": "sha512-e4g0EJtAjk64xgnFPD6kTBUtpnMVzDrMb12N1YZV0VvSlhnVT3SGxiYTLdGy8Q5cYHOIC/FAHmZ10eGrAguicQ==", + "dev": true + }, "ts-jest": { "version": "28.0.3", "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-28.0.3.tgz", @@ -8876,6 +10294,258 @@ } } }, + "tsd": { + "version": "0.31.2", + "resolved": "https://registry.npmjs.org/tsd/-/tsd-0.31.2.tgz", + "integrity": "sha512-VplBAQwvYrHzVihtzXiUVXu5bGcr7uH1juQZ1lmKgkuGNGT+FechUCqmx9/zk7wibcqR2xaNEwCkDyKh+VVZnQ==", + "dev": true, + "requires": { + "@tsd/typescript": "~5.4.3", + "eslint-formatter-pretty": "^4.1.0", + "globby": "^11.0.1", + "jest-diff": "^29.0.3", + "meow": "^9.0.0", + "path-exists": "^4.0.0", + "read-pkg-up": "^7.0.0" + }, + "dependencies": { + "@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.27.8" + } + }, + "@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + }, + "camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true + }, + "diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true + }, + "hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + } + }, + "jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true + }, + "meow": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", + "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", + "dev": true, + "requires": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize": "^1.2.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + } + }, + "normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "requires": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + } + }, + "pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "requires": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + } + }, + "quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true + }, + "react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "dependencies": { + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, + "redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "requires": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + } + }, + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "requires": { + "min-indent": "^1.0.0" + } + }, + "trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true + }, + "type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true + } + } + }, "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -8889,9 +10559,9 @@ "dev": true }, "typedoc": { - "version": "0.22.16", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.16.tgz", - "integrity": "sha512-0Qf0/CsQe6JZTXoYwBM3Iql8gLAWLjQP7O/j9YzfkJp3G/WVGmIMRajKnldJuA/zVvhr+ifsHTgctQh5g2t4iw==", + "version": "0.22.18", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.18.tgz", + "integrity": "sha512-NK9RlLhRUGMvc6Rw5USEYgT4DVAUFk7IF7Q6MYfpJ88KnTZP7EneEa4RcP+tX1auAcz7QT1Iy0bUSZBYYHdoyA==", "dev": true, "requires": { "glob": "^8.0.3", @@ -8998,6 +10668,20 @@ "makeerror": "1.0.12" } }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", diff --git a/package.json b/package.json index 3ffdae4b..dda574d6 100644 --- a/package.json +++ b/package.json @@ -14,34 +14,51 @@ "dist", "src" ], - "main": "dist/main/index.js", - "module": "dist/module/index.js", - "types": "dist/module/index.d.ts", + "main": "dist/cjs/index.js", + "module": "dist/esm/wrapper.mjs", + "exports": { + "import": { + "types": "./dist/cjs/index.d.ts", + "default": "./dist/esm/wrapper.mjs" + }, + "require": { + "types": "./dist/cjs/index.d.ts", + "default": "./dist/cjs/index.js" + } + }, + "types": "./dist/cjs/index.d.ts", "repository": "supabase/postgrest-js", "scripts": { "clean": "rimraf dist docs/v2", - "format": "prettier --write \"{src,test}/**/*.ts\"", + "format": "prettier --write \"{src,test}/**/*.ts\" wrapper.mjs", + "format:check": "prettier --check \"{src,test}/**/*.ts\"", "build": "run-s clean format build:*", - "build:main": "tsc -p tsconfig.json", - "build:module": "tsc -p tsconfig.module.json", + "build:cjs": "tsc -p tsconfig.json", + "build:esm": "cpy wrapper.mjs dist/esm/", "docs": "typedoc src/index.ts --out docs/v2", "docs:json": "typedoc --json docs/v2/spec.json --excludeExternals src/index.ts", - "test": "run-s test:db && jest --runInBand", - "test:clean": "cd test/db && docker-compose down", - "test:db": "cd test/db && docker-compose down && docker-compose up -d && wait-for-localhost 3000" + "test": "run-s format:check test:types db:clean db:run test:run db:clean && node test/smoke.cjs && node test/smoke.mjs", + "test:run": "jest --runInBand", + "test:update": "run-s db:clean db:run && jest --runInBand --updateSnapshot && run-s db:clean", + "test:types": "run-s build && tsd --files 'test/**/*.test-d.ts'", + "db:clean": "cd test/db && docker compose down --volumes", + "db:run": "cd test/db && docker compose up --detach && wait-for-localhost 3000" }, "dependencies": { - "cross-fetch": "^3.1.5" + "@supabase/node-fetch": "^2.6.14" }, "devDependencies": { "@types/jest": "^27.5.1", + "cpy-cli": "^5.0.0", "jest": "^28.1.0", "node-abort-controller": "^3.0.1", "npm-run-all": "^4.1.5", "prettier": "^2.6.2", "rimraf": "^3.0.2", "semantic-release-plugin-update-version-in-files": "^1.1.0", + "ts-expect": "^1.3.0", "ts-jest": "^28.0.3", + "tsd": "^0.31.2", "typedoc": "^0.22.16", "typescript": "~4.7", "wait-for-localhost-cli": "^3.0.0" diff --git a/src/PostgrestBuilder.ts b/src/PostgrestBuilder.ts index fe4d6577..621785c9 100644 --- a/src/PostgrestBuilder.ts +++ b/src/PostgrestBuilder.ts @@ -1,9 +1,11 @@ -import crossFetch from 'cross-fetch' +// @ts-ignore +import nodeFetch from '@supabase/node-fetch' -import type { Fetch, PostgrestResponse } from './types' +import type { Fetch, PostgrestSingleResponse } from './types' +import PostgrestError from './PostgrestError' export default abstract class PostgrestBuilder - implements PromiseLike> + implements PromiseLike> { protected method: 'GET' | 'HEAD' | 'POST' | 'PATCH' | 'DELETE' protected url: URL @@ -13,7 +15,7 @@ export default abstract class PostgrestBuilder protected shouldThrowOnError = false protected signal?: AbortSignal protected fetch: Fetch - protected allowEmpty: boolean + protected isMaybeSingle: boolean constructor(builder: PostgrestBuilder) { this.method = builder.method @@ -23,12 +25,12 @@ export default abstract class PostgrestBuilder this.body = builder.body this.shouldThrowOnError = builder.shouldThrowOnError this.signal = builder.signal - this.allowEmpty = builder.allowEmpty + this.isMaybeSingle = builder.isMaybeSingle if (builder.fetch) { this.fetch = builder.fetch } else if (typeof fetch === 'undefined') { - this.fetch = crossFetch + this.fetch = nodeFetch } else { this.fetch = fetch } @@ -45,9 +47,18 @@ export default abstract class PostgrestBuilder return this } - then, TResult2 = never>( + /** + * Set an HTTP header for the request. + */ + setHeader(name: string, value: string): this { + this.headers = { ...this.headers } + this.headers[name] = value + return this + } + + then, TResult2 = never>( onfulfilled?: - | ((value: PostgrestResponse) => TResult1 | PromiseLike) + | ((value: PostgrestSingleResponse) => TResult1 | PromiseLike) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null @@ -82,7 +93,7 @@ export default abstract class PostgrestBuilder if (res.ok) { if (this.method !== 'HEAD') { const body = await res.text() - if (body === "") { + if (body === '') { // Prefer: return=minimal } else if (this.headers['Accept'] === 'text/csv') { data = body @@ -101,25 +112,61 @@ export default abstract class PostgrestBuilder if (countHeader && contentRange && contentRange.length > 1) { count = parseInt(contentRange[1]) } + + // Temporary partial fix for https://github.com/supabase/postgrest-js/issues/361 + // Issue persists e.g. for `.insert([...]).select().maybeSingle()` + if (this.isMaybeSingle && this.method === 'GET' && Array.isArray(data)) { + if (data.length > 1) { + error = { + // https://github.com/PostgREST/postgrest/blob/a867d79c42419af16c18c3fb019eba8df992626f/src/PostgREST/Error.hs#L553 + code: 'PGRST116', + details: `Results contain ${data.length} rows, application/vnd.pgrst.object+json requires 1 row`, + hint: null, + message: 'JSON object requested, multiple (or no) rows returned', + } + data = null + count = null + status = 406 + statusText = 'Not Acceptable' + } else if (data.length === 1) { + data = data[0] + } else { + data = null + } + } } else { const body = await res.text() try { error = JSON.parse(body) + + // Workaround for https://github.com/supabase/postgrest-js/issues/295 + if (Array.isArray(error) && res.status === 404) { + data = [] + error = null + status = 200 + statusText = 'OK' + } } catch { - error = { - message: body, + // Workaround for https://github.com/supabase/postgrest-js/issues/295 + if (res.status === 404 && body === '') { + status = 204 + statusText = 'No Content' + } else { + error = { + message: body, + } } } - if (error && this.allowEmpty && error?.details?.includes('Results contain 0 rows')) { + if (error && this.isMaybeSingle && error?.details?.includes('0 rows')) { error = null status = 200 statusText = 'OK' } if (error && this.shouldThrowOnError) { - throw error + throw new PostgrestError(error) } } @@ -136,10 +183,10 @@ export default abstract class PostgrestBuilder if (!this.shouldThrowOnError) { res = res.catch((fetchError) => ({ error: { - message: `FetchError: ${fetchError.message}`, - details: '', + message: `${fetchError?.name ?? 'FetchError'}: ${fetchError?.message}`, + details: `${fetchError?.stack ?? ''}`, hint: '', - code: fetchError.code || '', + code: `${fetchError?.code ?? ''}`, }, data: null, count: null, diff --git a/src/PostgrestClient.ts b/src/PostgrestClient.ts index f3fcc705..8a37b09c 100644 --- a/src/PostgrestClient.ts +++ b/src/PostgrestClient.ts @@ -25,7 +25,7 @@ export default class PostgrestClient< > { url: string headers: Record - schema?: SchemaName + schemaName?: SchemaName fetch?: Fetch // TODO: Add back shouldThrowOnError once we figure out the typings @@ -52,28 +52,48 @@ export default class PostgrestClient< ) { this.url = url this.headers = { ...DEFAULT_HEADERS, ...headers } - this.schema = schema + this.schemaName = schema this.fetch = fetch } - /** - * Perform a query on a table or a view. - * - * @param relation - The table or view name to query - */ from< TableName extends string & keyof Schema['Tables'], Table extends Schema['Tables'][TableName] - >(relation: TableName): PostgrestQueryBuilder + >(relation: TableName): PostgrestQueryBuilder from( relation: ViewName - ): PostgrestQueryBuilder - from(relation: string): PostgrestQueryBuilder - from(relation: string): PostgrestQueryBuilder { + ): PostgrestQueryBuilder + /** + * Perform a query on a table or a view. + * + * @param relation - The table or view name to query + */ + from(relation: string): PostgrestQueryBuilder { const url = new URL(`${this.url}/${relation}`) - return new PostgrestQueryBuilder(url, { + return new PostgrestQueryBuilder(url, { headers: { ...this.headers }, - schema: this.schema, + schema: this.schemaName, + fetch: this.fetch, + }) + } + + /** + * Select a schema to query or perform an function (rpc) call. + * + * The schema needs to be on the list of exposed schemas inside Supabase. + * + * @param schema - The schema to query + */ + schema( + schema: DynamicSchema + ): PostgrestClient< + Database, + DynamicSchema, + Database[DynamicSchema] extends GenericSchema ? Database[DynamicSchema] : any + > { + return new PostgrestClient(this.url, { + headers: this.headers, + schema, fetch: this.fetch, }) } @@ -86,6 +106,8 @@ export default class PostgrestClient< * @param options - Named parameters * @param options.head - When set to `true`, `data` will not be returned. * Useful if you only need the count. + * @param options.get - When set to `true`, the function will be called with + * read-only access mode. * @param options.count - Count algorithm to use to count rows returned by the * function. Only applicable for [set-returning * functions](https://www.postgresql.org/docs/current/functions-srf.html). @@ -99,35 +121,43 @@ export default class PostgrestClient< * `"estimated"`: Uses exact count for low numbers and planned count for high * numbers. */ - rpc< - FunctionName extends string & keyof Schema['Functions'], - Function_ extends Schema['Functions'][FunctionName] - >( - fn: FunctionName, - args: Function_['Args'] = {}, + rpc( + fn: FnName, + args: Fn['Args'] = {}, { head = false, + get = false, count, }: { head?: boolean + get?: boolean count?: 'exact' | 'planned' | 'estimated' } = {} ): PostgrestFilterBuilder< - Function_['Returns'] extends any[] - ? Function_['Returns'][number] extends Record - ? Function_['Returns'][number] + Schema, + Fn['Returns'] extends any[] + ? Fn['Returns'][number] extends Record + ? Fn['Returns'][number] : never : never, - Function_['Returns'] + Fn['Returns'], + FnName, + null > { - let method: 'HEAD' | 'POST' + let method: 'HEAD' | 'GET' | 'POST' const url = new URL(`${this.url}/rpc/${fn}`) let body: unknown | undefined - if (head) { - method = 'HEAD' - Object.entries(args).forEach(([name, value]) => { - url.searchParams.append(name, `${value}`) - }) + if (head || get) { + method = head ? 'HEAD' : 'GET' + Object.entries(args) + // params with undefined value needs to be filtered out, otherwise it'll + // show up as `?param=undefined` + .filter(([_, value]) => value !== undefined) + // array values need special syntax + .map(([name, value]) => [name, Array.isArray(value) ? `{${value.join(',')}}` : `${value}`]) + .forEach(([name, value]) => { + url.searchParams.append(name, value) + }) } else { method = 'POST' body = args @@ -142,10 +172,10 @@ export default class PostgrestClient< method, url, headers, - schema: this.schema, + schema: this.schemaName, body, fetch: this.fetch, allowEmpty: false, - } as unknown as PostgrestBuilder) + } as unknown as PostgrestBuilder) } } diff --git a/src/PostgrestError.ts b/src/PostgrestError.ts new file mode 100644 index 00000000..8253ae96 --- /dev/null +++ b/src/PostgrestError.ts @@ -0,0 +1,15 @@ +import type { PostgrestError as IPostgrestError } from './types' + +export default class PostgrestError extends Error implements IPostgrestError { + details: string + hint: string + code: string + + constructor(context: IPostgrestError) { + super(context.message) + this.name = 'PostgrestError' + this.details = context.details + this.hint = context.hint + this.code = context.code + } +} diff --git a/src/PostgrestFilterBuilder.ts b/src/PostgrestFilterBuilder.ts index 23ece29b..21cc4090 100644 --- a/src/PostgrestFilterBuilder.ts +++ b/src/PostgrestFilterBuilder.ts @@ -1,4 +1,5 @@ import PostgrestTransformBuilder from './PostgrestTransformBuilder' +import { GenericSchema } from './types' type FilterOperator = | 'eq' @@ -25,9 +26,17 @@ type FilterOperator = | 'wfts' export default class PostgrestFilterBuilder< + Schema extends GenericSchema, Row extends Record, - Result -> extends PostgrestTransformBuilder { + Result, + RelationName = unknown, + Relationships = unknown +> extends PostgrestTransformBuilder { + eq( + column: ColumnName, + value: NonNullable + ): this + eq(column: string, value: NonNullable): this /** * Match only rows where `column` is equal to `value`. * @@ -36,104 +45,171 @@ export default class PostgrestFilterBuilder< * @param column - The column to filter on * @param value - The value to filter with */ - eq(column: ColumnName, value: Row[ColumnName]): this - eq(column: string, value: unknown): this eq(column: string, value: unknown): this { this.url.searchParams.append(column, `eq.${value}`) return this } + neq(column: ColumnName, value: Row[ColumnName]): this + neq(column: string, value: unknown): this /** * Match only rows where `column` is not equal to `value`. * * @param column - The column to filter on * @param value - The value to filter with */ - neq(column: ColumnName, value: Row[ColumnName]): this - neq(column: string, value: unknown): this neq(column: string, value: unknown): this { this.url.searchParams.append(column, `neq.${value}`) return this } + gt(column: ColumnName, value: Row[ColumnName]): this + gt(column: string, value: unknown): this /** * Match only rows where `column` is greater than `value`. * * @param column - The column to filter on * @param value - The value to filter with */ - gt(column: ColumnName, value: Row[ColumnName]): this - gt(column: string, value: unknown): this gt(column: string, value: unknown): this { this.url.searchParams.append(column, `gt.${value}`) return this } + gte(column: ColumnName, value: Row[ColumnName]): this + gte(column: string, value: unknown): this /** * Match only rows where `column` is greater than or equal to `value`. * * @param column - The column to filter on * @param value - The value to filter with */ - gte(column: ColumnName, value: Row[ColumnName]): this - gte(column: string, value: unknown): this gte(column: string, value: unknown): this { this.url.searchParams.append(column, `gte.${value}`) return this } + lt(column: ColumnName, value: Row[ColumnName]): this + lt(column: string, value: unknown): this /** * Match only rows where `column` is less than `value`. * * @param column - The column to filter on * @param value - The value to filter with */ - lt(column: ColumnName, value: Row[ColumnName]): this - lt(column: string, value: unknown): this lt(column: string, value: unknown): this { this.url.searchParams.append(column, `lt.${value}`) return this } + lte(column: ColumnName, value: Row[ColumnName]): this + lte(column: string, value: unknown): this /** * Match only rows where `column` is less than or equal to `value`. * * @param column - The column to filter on * @param value - The value to filter with */ - lte(column: ColumnName, value: Row[ColumnName]): this - lte(column: string, value: unknown): this lte(column: string, value: unknown): this { this.url.searchParams.append(column, `lte.${value}`) return this } + like(column: ColumnName, pattern: string): this + like(column: string, pattern: string): this /** * Match only rows where `column` matches `pattern` case-sensitively. * * @param column - The column to filter on * @param pattern - The pattern to match with */ - like(column: ColumnName, pattern: string): this - like(column: string, pattern: string): this like(column: string, pattern: string): this { this.url.searchParams.append(column, `like.${pattern}`) return this } + likeAllOf( + column: ColumnName, + patterns: readonly string[] + ): this + likeAllOf(column: string, patterns: readonly string[]): this /** - * Match only rows where `column` matches `pattern` case-insensitively. + * Match only rows where `column` matches all of `patterns` case-sensitively. * * @param column - The column to filter on - * @param pattern - The pattern to match with + * @param patterns - The patterns to match with */ + likeAllOf(column: string, patterns: readonly string[]): this { + this.url.searchParams.append(column, `like(all).{${patterns.join(',')}}`) + return this + } + + likeAnyOf( + column: ColumnName, + patterns: readonly string[] + ): this + likeAnyOf(column: string, patterns: readonly string[]): this + /** + * Match only rows where `column` matches any of `patterns` case-sensitively. + * + * @param column - The column to filter on + * @param patterns - The patterns to match with + */ + likeAnyOf(column: string, patterns: readonly string[]): this { + this.url.searchParams.append(column, `like(any).{${patterns.join(',')}}`) + return this + } + ilike(column: ColumnName, pattern: string): this ilike(column: string, pattern: string): this + /** + * Match only rows where `column` matches `pattern` case-insensitively. + * + * @param column - The column to filter on + * @param pattern - The pattern to match with + */ ilike(column: string, pattern: string): this { this.url.searchParams.append(column, `ilike.${pattern}`) return this } + ilikeAllOf( + column: ColumnName, + patterns: readonly string[] + ): this + ilikeAllOf(column: string, patterns: readonly string[]): this + /** + * Match only rows where `column` matches all of `patterns` case-insensitively. + * + * @param column - The column to filter on + * @param patterns - The patterns to match with + */ + ilikeAllOf(column: string, patterns: readonly string[]): this { + this.url.searchParams.append(column, `ilike(all).{${patterns.join(',')}}`) + return this + } + + ilikeAnyOf( + column: ColumnName, + patterns: readonly string[] + ): this + ilikeAnyOf(column: string, patterns: readonly string[]): this + /** + * Match only rows where `column` matches any of `patterns` case-insensitively. + * + * @param column - The column to filter on + * @param patterns - The patterns to match with + */ + ilikeAnyOf(column: string, patterns: readonly string[]): this { + this.url.searchParams.append(column, `ilike(any).{${patterns.join(',')}}`) + return this + } + + is( + column: ColumnName, + value: Row[ColumnName] & (boolean | null) + ): this + is(column: string, value: boolean | null): this /** * Match only rows where `column` IS `value`. * @@ -146,26 +222,24 @@ export default class PostgrestFilterBuilder< * @param column - The column to filter on * @param value - The value to filter with */ - is( - column: ColumnName, - value: Row[ColumnName] & (boolean | null) - ): this - is(column: string, value: boolean | null): this is(column: string, value: boolean | null): this { this.url.searchParams.append(column, `is.${value}`) return this } + in( + column: ColumnName, + values: ReadonlyArray + ): this + in(column: string, values: readonly unknown[]): this /** * Match only rows where `column` is included in the `values` array. * * @param column - The column to filter on * @param values - The values array to filter with */ - in(column: ColumnName, values: Row[ColumnName][]): this - in(column: string, values: unknown[]): this - in(column: string, values: unknown[]): this { - const cleanedValues = values + in(column: string, values: readonly unknown[]): this { + const cleanedValues = Array.from(new Set(values)) .map((s) => { // handle postgrest reserved characters // https://postgrest.org/en/v7.0.0/api.html#reserved-characters @@ -177,6 +251,11 @@ export default class PostgrestFilterBuilder< return this } + contains( + column: ColumnName, + value: string | ReadonlyArray | Record + ): this + contains(column: string, value: string | readonly unknown[] | Record): this /** * Only relevant for jsonb, array, and range columns. Match only rows where * `column` contains every element appearing in `value`. @@ -184,12 +263,7 @@ export default class PostgrestFilterBuilder< * @param column - The jsonb, array, or range column to filter on * @param value - The jsonb, array, or range value to filter with */ - contains( - column: ColumnName, - value: string | Row[ColumnName][] | Record - ): this - contains(column: string, value: string | unknown[] | Record): this - contains(column: string, value: string | unknown[] | Record): this { + contains(column: string, value: string | readonly unknown[] | Record): this { if (typeof value === 'string') { // range types can be inclusive '[', ']' or exclusive '(', ')' so just // keep it simple and accept a string @@ -204,6 +278,11 @@ export default class PostgrestFilterBuilder< return this } + containedBy( + column: ColumnName, + value: string | ReadonlyArray | Record + ): this + containedBy(column: string, value: string | readonly unknown[] | Record): this /** * Only relevant for jsonb, array, and range columns. Match only rows where * every element appearing in `column` is contained by `value`. @@ -211,12 +290,7 @@ export default class PostgrestFilterBuilder< * @param column - The jsonb, array, or range column to filter on * @param value - The jsonb, array, or range value to filter with */ - containedBy( - column: ColumnName, - value: string | Row[ColumnName][] | Record - ): this - containedBy(column: string, value: string | unknown[] | Record): this - containedBy(column: string, value: string | unknown[] | Record): this { + containedBy(column: string, value: string | readonly unknown[] | Record): this { if (typeof value === 'string') { // range this.url.searchParams.append(column, `cd.${value}`) @@ -230,6 +304,8 @@ export default class PostgrestFilterBuilder< return this } + rangeGt(column: ColumnName, range: string): this + rangeGt(column: string, range: string): this /** * Only relevant for range columns. Match only rows where every element in * `column` is greater than any element in `range`. @@ -237,13 +313,13 @@ export default class PostgrestFilterBuilder< * @param column - The range column to filter on * @param range - The range to filter with */ - rangeGt(column: ColumnName, range: string): this - rangeGt(column: string, range: string): this rangeGt(column: string, range: string): this { this.url.searchParams.append(column, `sr.${range}`) return this } + rangeGte(column: ColumnName, range: string): this + rangeGte(column: string, range: string): this /** * Only relevant for range columns. Match only rows where every element in * `column` is either contained in `range` or greater than any element in @@ -252,13 +328,13 @@ export default class PostgrestFilterBuilder< * @param column - The range column to filter on * @param range - The range to filter with */ - rangeGte(column: ColumnName, range: string): this - rangeGte(column: string, range: string): this rangeGte(column: string, range: string): this { this.url.searchParams.append(column, `nxl.${range}`) return this } + rangeLt(column: ColumnName, range: string): this + rangeLt(column: string, range: string): this /** * Only relevant for range columns. Match only rows where every element in * `column` is less than any element in `range`. @@ -266,13 +342,13 @@ export default class PostgrestFilterBuilder< * @param column - The range column to filter on * @param range - The range to filter with */ - rangeLt(column: ColumnName, range: string): this - rangeLt(column: string, range: string): this rangeLt(column: string, range: string): this { this.url.searchParams.append(column, `sl.${range}`) return this } + rangeLte(column: ColumnName, range: string): this + rangeLte(column: string, range: string): this /** * Only relevant for range columns. Match only rows where every element in * `column` is either contained in `range` or less than any element in @@ -281,13 +357,13 @@ export default class PostgrestFilterBuilder< * @param column - The range column to filter on * @param range - The range to filter with */ - rangeLte(column: ColumnName, range: string): this - rangeLte(column: string, range: string): this rangeLte(column: string, range: string): this { this.url.searchParams.append(column, `nxr.${range}`) return this } + rangeAdjacent(column: ColumnName, range: string): this + rangeAdjacent(column: string, range: string): this /** * Only relevant for range columns. Match only rows where `column` is * mutually exclusive to `range` and there can be no element between the two @@ -296,13 +372,16 @@ export default class PostgrestFilterBuilder< * @param column - The range column to filter on * @param range - The range to filter with */ - rangeAdjacent(column: ColumnName, range: string): this - rangeAdjacent(column: string, range: string): this rangeAdjacent(column: string, range: string): this { this.url.searchParams.append(column, `adj.${range}`) return this } + overlaps( + column: ColumnName, + value: string | ReadonlyArray + ): this + overlaps(column: string, value: string | readonly unknown[]): this /** * Only relevant for array and range columns. Match only rows where * `column` and `value` have an element in common. @@ -310,12 +389,7 @@ export default class PostgrestFilterBuilder< * @param column - The array or range column to filter on * @param value - The array or range value to filter with */ - overlaps( - column: ColumnName, - value: string | Row[ColumnName][] - ): this - overlaps(column: string, value: string | unknown[]): this - overlaps(column: string, value: string | unknown[]): this { + overlaps(column: string, value: string | readonly unknown[]): this { if (typeof value === 'string') { // range this.url.searchParams.append(column, `ov.${value}`) @@ -326,16 +400,6 @@ export default class PostgrestFilterBuilder< return this } - /** - * Only relevant for text and tsvector columns. Match only rows where - * `column` matches the query string in `query`. - * - * @param column - The text or tsvector column to filter on - * @param query - The query text to match with - * @param options - Named parameters - * @param options.config - The text search configuration to use - * @param options.type - Change how the `query` text is interpreted - */ textSearch( column: ColumnName, query: string, @@ -346,6 +410,16 @@ export default class PostgrestFilterBuilder< query: string, options?: { config?: string; type?: 'plain' | 'phrase' | 'websearch' } ): this + /** + * Only relevant for text and tsvector columns. Match only rows where + * `column` matches the query string in `query`. + * + * @param column - The text or tsvector column to filter on + * @param query - The query text to match with + * @param options - Named parameters + * @param options.config - The text search configuration to use + * @param options.type - Change how the `query` text is interpreted + */ textSearch( column: string, query: string, @@ -364,6 +438,8 @@ export default class PostgrestFilterBuilder< return this } + match(query: Record): this + match(query: Record): this /** * Match only rows where each column in `query` keys is equal to its * associated value. Shorthand for multiple `.eq()`s. @@ -371,8 +447,6 @@ export default class PostgrestFilterBuilder< * @param query - The object to filter with, with column names as keys mapped * to their filter values */ - match(query: Record): this - match(query: Record): this match(query: Record): this { Object.entries(query).forEach(([column, value]) => { this.url.searchParams.append(column, `eq.${value}`) @@ -380,6 +454,12 @@ export default class PostgrestFilterBuilder< return this } + not( + column: ColumnName, + operator: FilterOperator, + value: Row[ColumnName] + ): this + not(column: string, operator: string, value: unknown): this /** * Match only rows which doesn't satisfy the filter. * @@ -393,12 +473,6 @@ export default class PostgrestFilterBuilder< * PostgREST syntax * @param value - The value to filter with, following PostgREST syntax */ - not( - column: ColumnName, - operator: FilterOperator, - value: Row[ColumnName] - ): this - not(column: string, operator: string, value: unknown): this not(column: string, operator: string, value: unknown): this { this.url.searchParams.append(column, `not.${operator}.${value}`) return this @@ -414,15 +488,29 @@ export default class PostgrestFilterBuilder< * It's currently not possible to do an `.or()` filter across multiple tables. * * @param filters - The filters to use, following PostgREST syntax - * @param foreignTable - Set this to filter on foreign tables instead of the - * current table + * @param options - Named parameters + * @param options.referencedTable - Set this to filter on referenced tables + * instead of the parent table + * @param options.foreignTable - Deprecated, use `referencedTable` instead */ - or(filters: string, { foreignTable }: { foreignTable?: string } = {}): this { - const key = foreignTable ? `${foreignTable}.or` : 'or' + or( + filters: string, + { + foreignTable, + referencedTable = foreignTable, + }: { foreignTable?: string; referencedTable?: string } = {} + ): this { + const key = referencedTable ? `${referencedTable}.or` : 'or' this.url.searchParams.append(key, `(${filters})`) return this } + filter( + column: ColumnName, + operator: `${'' | 'not.'}${FilterOperator}`, + value: unknown + ): this + filter(column: string, operator: string, value: unknown): this /** * Match only rows which satisfy the filter. This is an escape hatch - you * should use the specific filter methods wherever possible. @@ -436,12 +524,6 @@ export default class PostgrestFilterBuilder< * @param operator - The operator to filter with, following PostgREST syntax * @param value - The value to filter with, following PostgREST syntax */ - filter( - column: ColumnName, - operator: `${'' | 'not.'}${FilterOperator}`, - value: unknown - ): this - filter(column: string, operator: string, value: unknown): this filter(column: string, operator: string, value: unknown): this { this.url.searchParams.append(column, `${operator}.${value}`) return this diff --git a/src/PostgrestQueryBuilder.ts b/src/PostgrestQueryBuilder.ts index cc1338ed..44e7320a 100644 --- a/src/PostgrestQueryBuilder.ts +++ b/src/PostgrestQueryBuilder.ts @@ -1,9 +1,14 @@ import PostgrestBuilder from './PostgrestBuilder' import PostgrestFilterBuilder from './PostgrestFilterBuilder' -import { GetResult } from './select-query-parser' -import { Fetch, GenericTable, GenericView } from './types' +import { GetResult } from './select-query-parser/result' +import { Fetch, GenericSchema, GenericTable, GenericView } from './types' -export default class PostgrestQueryBuilder { +export default class PostgrestQueryBuilder< + Schema extends GenericSchema, + Relation extends GenericTable | GenericView, + RelationName = unknown, + Relationships = Relation extends { Relationships: infer R } ? R : unknown +> { url: URL headers: Record schema?: string @@ -31,7 +36,7 @@ export default class PostgrestQueryBuilder + ResultOne = GetResult >( columns?: Query, { @@ -61,7 +66,7 @@ export default class PostgrestQueryBuilder { + ): PostgrestFilterBuilder { const method = head ? 'HEAD' : 'GET' // Remove whitespaces except when quoted let quoted = false @@ -89,9 +94,23 @@ export default class PostgrestQueryBuilder) + } as unknown as PostgrestBuilder) } + // TODO(v3): Make `defaultToNull` consistent for both single & bulk inserts. + insert( + values: Row, + options?: { + count?: 'exact' | 'planned' | 'estimated' + } + ): PostgrestFilterBuilder + insert( + values: Row[], + options?: { + count?: 'exact' | 'planned' | 'estimated' + defaultToNull?: boolean + } + ): PostgrestFilterBuilder /** * Perform an INSERT into the table or view. * @@ -113,24 +132,32 @@ export default class PostgrestQueryBuilder( values: Row | Row[], { count, + defaultToNull = true, }: { count?: 'exact' | 'planned' | 'estimated' + defaultToNull?: boolean } = {} - ): PostgrestFilterBuilder { + ): PostgrestFilterBuilder { const method = 'POST' const prefersHeaders = [] - const body = values + if (this.headers['Prefer']) { + prefersHeaders.push(this.headers['Prefer']) + } if (count) { prefersHeaders.push(`count=${count}`) } - if (this.headers['Prefer']) { - prefersHeaders.unshift(this.headers['Prefer']) + if (!defaultToNull) { + prefersHeaders.push('missing=default') } this.headers['Prefer'] = prefersHeaders.join(',') @@ -147,12 +174,30 @@ export default class PostgrestQueryBuilder) + } as unknown as PostgrestBuilder) } + // TODO(v3): Make `defaultToNull` consistent for both single & bulk upserts. + upsert( + values: Row, + options?: { + onConflict?: string + ignoreDuplicates?: boolean + count?: 'exact' | 'planned' | 'estimated' + } + ): PostgrestFilterBuilder + upsert( + values: Row[], + options?: { + onConflict?: string + ignoreDuplicates?: boolean + count?: 'exact' | 'planned' | 'estimated' + defaultToNull?: boolean + } + ): PostgrestFilterBuilder /** * Perform an UPSERT on the table or view. Depending on the column(s) passed * to `onConflict`, `.upsert()` allows you to perform the equivalent of @@ -185,6 +230,11 @@ export default class PostgrestQueryBuilder( values: Row | Row[], @@ -192,35 +242,47 @@ export default class PostgrestQueryBuilder { + ): PostgrestFilterBuilder { const method = 'POST' const prefersHeaders = [`resolution=${ignoreDuplicates ? 'ignore' : 'merge'}-duplicates`] if (onConflict !== undefined) this.url.searchParams.set('on_conflict', onConflict) - const body = values + if (this.headers['Prefer']) { + prefersHeaders.push(this.headers['Prefer']) + } if (count) { prefersHeaders.push(`count=${count}`) } - if (this.headers['Prefer']) { - prefersHeaders.unshift(this.headers['Prefer']) + if (!defaultToNull) { + prefersHeaders.push('missing=default') } this.headers['Prefer'] = prefersHeaders.join(',') + if (Array.isArray(values)) { + const columns = values.reduce((acc, x) => acc.concat(Object.keys(x)), [] as string[]) + if (columns.length > 0) { + const uniqueColumns = [...new Set(columns)].map((column) => `"${column}"`) + this.url.searchParams.set('columns', uniqueColumns.join(',')) + } + } + return new PostgrestFilterBuilder({ method, url: this.url, headers: this.headers, schema: this.schema, - body, + body: values, fetch: this.fetch, allowEmpty: false, - } as unknown as PostgrestBuilder) + } as unknown as PostgrestBuilder) } /** @@ -251,16 +313,15 @@ export default class PostgrestQueryBuilder { + ): PostgrestFilterBuilder { const method = 'PATCH' const prefersHeaders = [] - const body = values + if (this.headers['Prefer']) { + prefersHeaders.push(this.headers['Prefer']) + } if (count) { prefersHeaders.push(`count=${count}`) } - if (this.headers['Prefer']) { - prefersHeaders.unshift(this.headers['Prefer']) - } this.headers['Prefer'] = prefersHeaders.join(',') return new PostgrestFilterBuilder({ @@ -268,10 +329,10 @@ export default class PostgrestQueryBuilder) + } as unknown as PostgrestBuilder) } /** @@ -297,7 +358,7 @@ export default class PostgrestQueryBuilder { + } = {}): PostgrestFilterBuilder { const method = 'DELETE' const prefersHeaders = [] if (count) { @@ -315,6 +376,6 @@ export default class PostgrestQueryBuilder) + } as unknown as PostgrestBuilder) } } diff --git a/src/PostgrestTransformBuilder.ts b/src/PostgrestTransformBuilder.ts index de41ab77..4791702c 100644 --- a/src/PostgrestTransformBuilder.ts +++ b/src/PostgrestTransformBuilder.ts @@ -1,10 +1,13 @@ import PostgrestBuilder from './PostgrestBuilder' -import { GetResult } from './select-query-parser' -import { PostgrestMaybeSingleResponse, PostgrestResponse, PostgrestSingleResponse } from './types' +import { GetResult } from './select-query-parser/result' +import { GenericSchema } from './types' export default class PostgrestTransformBuilder< + Schema extends GenericSchema, Row extends Record, - Result + Result, + RelationName = unknown, + Relationships = unknown > extends PostgrestBuilder { /** * Perform a SELECT on the query result. @@ -15,9 +18,12 @@ export default class PostgrestTransformBuilder< * * @param columns - The columns to retrieve, separated by commas */ - select>( + select< + Query extends string = '*', + NewResultOne = GetResult + >( columns?: Query - ): PostgrestTransformBuilder { + ): PostgrestTransformBuilder { // Remove whitespaces except when quoted let quoted = false const cleanedColumns = (columns ?? '*') @@ -37,42 +43,70 @@ export default class PostgrestTransformBuilder< this.headers['Prefer'] += ',' } this.headers['Prefer'] += 'return=representation' - return this as unknown as PostgrestTransformBuilder + return this as unknown as PostgrestTransformBuilder< + Schema, + Row, + NewResultOne[], + RelationName, + Relationships + > } + order( + column: ColumnName, + options?: { ascending?: boolean; nullsFirst?: boolean; referencedTable?: undefined } + ): this + order( + column: string, + options?: { ascending?: boolean; nullsFirst?: boolean; referencedTable?: string } + ): this + /** + * @deprecated Use `options.referencedTable` instead of `options.foreignTable` + */ + order( + column: ColumnName, + options?: { ascending?: boolean; nullsFirst?: boolean; foreignTable?: undefined } + ): this + /** + * @deprecated Use `options.referencedTable` instead of `options.foreignTable` + */ + order( + column: string, + options?: { ascending?: boolean; nullsFirst?: boolean; foreignTable?: string } + ): this /** * Order the query result by `column`. * * You can call this method multiple times to order by multiple columns. * - * You can order foreign tables, but it doesn't affect the ordering of the - * current table. + * You can order referenced tables, but it only affects the ordering of the + * parent table if you use `!inner` in the query. * * @param column - The column to order by * @param options - Named parameters * @param options.ascending - If `true`, the result will be in ascending order * @param options.nullsFirst - If `true`, `null`s appear first. If `false`, * `null`s appear last. - * @param options.foreignTable - Set this to order a foreign table by foreign - * columns + * @param options.referencedTable - Set this to order a referenced table by + * its columns + * @param options.foreignTable - Deprecated, use `options.referencedTable` + * instead */ - order( - column: ColumnName, - options?: { ascending?: boolean; nullsFirst?: boolean; foreignTable?: undefined } - ): this - order( - column: string, - options?: { ascending?: boolean; nullsFirst?: boolean; foreignTable: string } - ): this order( column: string, { ascending = true, nullsFirst, foreignTable, - }: { ascending?: boolean; nullsFirst?: boolean; foreignTable?: string } = {} + referencedTable = foreignTable, + }: { + ascending?: boolean + nullsFirst?: boolean + foreignTable?: string + referencedTable?: string + } = {} ): this { - const key = foreignTable ? `${foreignTable}.order` : 'order' + const key = referencedTable ? `${referencedTable}.order` : 'order' const existingOrder = this.url.searchParams.get(key) this.url.searchParams.set( @@ -89,27 +123,49 @@ export default class PostgrestTransformBuilder< * * @param count - The maximum number of rows to return * @param options - Named parameters - * @param options.foreignTable - Set this to limit rows of foreign tables - * instead of the current table + * @param options.referencedTable - Set this to limit rows of referenced + * tables instead of the parent table + * @param options.foreignTable - Deprecated, use `options.referencedTable` + * instead */ - limit(count: number, { foreignTable }: { foreignTable?: string } = {}): this { - const key = typeof foreignTable === 'undefined' ? 'limit' : `${foreignTable}.limit` + limit( + count: number, + { + foreignTable, + referencedTable = foreignTable, + }: { foreignTable?: string; referencedTable?: string } = {} + ): this { + const key = typeof referencedTable === 'undefined' ? 'limit' : `${referencedTable}.limit` this.url.searchParams.set(key, `${count}`) return this } /** - * Limit the query result by `from` and `to` inclusively. + * Limit the query result by starting at an offset `from` and ending at the offset `to`. + * Only records within this range are returned. + * This respects the query order and if there is no order clause the range could behave unexpectedly. + * The `from` and `to` values are 0-based and inclusive: `range(1, 3)` will include the second, third + * and fourth rows of the query. * * @param from - The starting index from which to limit the result * @param to - The last index to which to limit the result * @param options - Named parameters - * @param options.foreignTable - Set this to limit rows of foreign tables - * instead of the current table + * @param options.referencedTable - Set this to limit rows of referenced + * tables instead of the parent table + * @param options.foreignTable - Deprecated, use `options.referencedTable` + * instead */ - range(from: number, to: number, { foreignTable }: { foreignTable?: string } = {}): this { - const keyOffset = typeof foreignTable === 'undefined' ? 'offset' : `${foreignTable}.offset` - const keyLimit = typeof foreignTable === 'undefined' ? 'limit' : `${foreignTable}.limit` + range( + from: number, + to: number, + { + foreignTable, + referencedTable = foreignTable, + }: { foreignTable?: string; referencedTable?: string } = {} + ): this { + const keyOffset = + typeof referencedTable === 'undefined' ? 'offset' : `${referencedTable}.offset` + const keyLimit = typeof referencedTable === 'undefined' ? 'limit' : `${referencedTable}.limit` this.url.searchParams.set(keyOffset, `${from}`) // Range is inclusive, so add 1 this.url.searchParams.set(keyLimit, `${to - from + 1}`) @@ -132,9 +188,11 @@ export default class PostgrestTransformBuilder< * Query result must be one row (e.g. using `.limit(1)`), otherwise this * returns an error. */ - single(): PromiseLike> { + single< + ResultOne = Result extends (infer ResultOne)[] ? ResultOne : never + >(): PostgrestBuilder { this.headers['Accept'] = 'application/vnd.pgrst.object+json' - return this as PromiseLike> + return this as PostgrestBuilder } /** @@ -143,31 +201,43 @@ export default class PostgrestTransformBuilder< * Query result must be zero or one row (e.g. using `.limit(1)`), otherwise * this returns an error. */ - maybeSingle(): PromiseLike> { - this.headers['Accept'] = 'application/vnd.pgrst.object+json' - this.allowEmpty = true - return this as PromiseLike> + maybeSingle< + ResultOne = Result extends (infer ResultOne)[] ? ResultOne : never + >(): PostgrestBuilder { + // Temporary partial fix for https://github.com/supabase/postgrest-js/issues/361 + // Issue persists e.g. for `.insert([...]).select().maybeSingle()` + if (this.method === 'GET') { + this.headers['Accept'] = 'application/json' + } else { + this.headers['Accept'] = 'application/vnd.pgrst.object+json' + } + this.isMaybeSingle = true + return this as PostgrestBuilder } /** * Return `data` as a string in CSV format. */ - csv(): PromiseLike> { + csv(): PostgrestBuilder { this.headers['Accept'] = 'text/csv' - return this as PromiseLike> + return this as PostgrestBuilder } /** * Return `data` as an object in [GeoJSON](https://geojson.org) format. */ - geojson(): PromiseLike>> { + geojson(): PostgrestBuilder> { this.headers['Accept'] = 'application/geo+json' - return this as PromiseLike>> + return this as PostgrestBuilder> } /** * Return `data` as the EXPLAIN plan for the query. * + * You need to enable the + * [db_plan_enabled](https://supabase.com/docs/guides/database/debugging-performance#enabling-explain) + * setting before using this method. + * * @param options - Named parameters * * @param options.analyze - If `true`, the query will be executed and the @@ -200,9 +270,7 @@ export default class PostgrestTransformBuilder< buffers?: boolean wal?: boolean format?: 'json' | 'text' - } = {}): - | PromiseLike>> - | PromiseLike> { + } = {}): PostgrestBuilder[]> | PostgrestBuilder { const options = [ analyze ? 'analyze' : null, verbose ? 'verbose' : null, @@ -213,12 +281,12 @@ export default class PostgrestTransformBuilder< .filter(Boolean) .join('|') // An Accept header can carry multiple media types but postgrest-js always sends one - const forMediatype = this.headers['Accept'] + const forMediatype = this.headers['Accept'] ?? 'application/json' this.headers[ 'Accept' ] = `application/vnd.pgrst.plan+${format}; for="${forMediatype}"; options=${options};` - if (format === 'json') return this as PromiseLike>> - else return this as PromiseLike> + if (format === 'json') return this as PostgrestBuilder[]> + else return this as PostgrestBuilder } /** @@ -234,4 +302,25 @@ export default class PostgrestTransformBuilder< } return this } + + /** + * Override the type of the returned `data`. + * + * @typeParam NewResult - The new result type to override with + */ + returns(): PostgrestTransformBuilder< + Schema, + Row, + NewResult, + RelationName, + Relationships + > { + return this as unknown as PostgrestTransformBuilder< + Schema, + Row, + NewResult, + RelationName, + Relationships + > + } } diff --git a/src/index.ts b/src/index.ts index 1dff039f..06ac6622 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,11 +1,31 @@ -export { default as PostgrestClient } from './PostgrestClient' -export { default as PostgrestQueryBuilder } from './PostgrestQueryBuilder' -export { default as PostgrestFilterBuilder } from './PostgrestFilterBuilder' -export { default as PostgrestTransformBuilder } from './PostgrestTransformBuilder' -export { default as PostgrestBuilder } from './PostgrestBuilder' +// Always update wrapper.mjs when updating this file. +import PostgrestClient from './PostgrestClient' +import PostgrestQueryBuilder from './PostgrestQueryBuilder' +import PostgrestFilterBuilder from './PostgrestFilterBuilder' +import PostgrestTransformBuilder from './PostgrestTransformBuilder' +import PostgrestBuilder from './PostgrestBuilder' +import PostgrestError from './PostgrestError' + export { + PostgrestClient, + PostgrestQueryBuilder, + PostgrestFilterBuilder, + PostgrestTransformBuilder, + PostgrestBuilder, + PostgrestError, +} +export default { + PostgrestClient, + PostgrestQueryBuilder, + PostgrestFilterBuilder, + PostgrestTransformBuilder, + PostgrestBuilder, + PostgrestError, +} +export type { PostgrestResponse, + PostgrestResponseFailure, + PostgrestResponseSuccess, PostgrestSingleResponse, PostgrestMaybeSingleResponse, - PostgrestError, } from './types' diff --git a/src/select-query-parser.ts b/src/select-query-parser.ts deleted file mode 100644 index 0b60ab7e..00000000 --- a/src/select-query-parser.ts +++ /dev/null @@ -1,297 +0,0 @@ -// Credits to @bnjmnt4n (https://www.npmjs.com/package/postgrest-query) - -type Whitespace = ' ' | '\n' | '\t' - -type LowerAlphabet = - | 'a' - | 'b' - | 'c' - | 'd' - | 'e' - | 'f' - | 'g' - | 'h' - | 'i' - | 'j' - | 'k' - | 'l' - | 'm' - | 'n' - | 'o' - | 'p' - | 'q' - | 'r' - | 's' - | 't' - | 'u' - | 'v' - | 'w' - | 'x' - | 'y' - | 'z' - -type Alphabet = LowerAlphabet | Uppercase - -type Digit = '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '0' - -type Letter = Alphabet | Digit | '_' - -// /** -// * Parsed node types. -// * Currently only `*` and all other fields. -// */ -// type ParsedNode = -// | { star: true } -// | { name: string; original: string } -// | { name: string; foreignTable: true }; - -/** - * Parser errors. - */ -type ParserError = { error: true } & Message -type GenericStringError = ParserError<'Received a generic string'> - -/** - * Trims whitespace from the left of the input. - */ -type EatWhitespace = string extends Input - ? GenericStringError - : Input extends `${Whitespace}${infer Remainder}` - ? EatWhitespace - : Input - -/** - * Constructs a type definition for a single field of an object. - * - * @param Definitions Record of definitions, possibly generated from PostgREST's OpenAPI spec. - * @param Name Name of the table being queried. - * @param Field Single field parsed by `ParseQuery`. - */ -type ConstructFieldDefinition, Field> = Field extends { - star: true -} - ? Row - : Field extends { name: string; foreignTable: true } - ? { [K in Field['name']]: unknown } - : Field extends { name: string; original: string } - ? { [K in Field['name']]: Row[Field['original']] } - : Record - -/** - * Notes: all `Parse*` types assume that their input strings have their whitespace - * removed. They return tuples of ["Return Value", "Remainder of text"] or - * a `ParserError`. - */ - -/** - * Reads a consecutive sequence of more than 1 letter, - * where letters are `[0-9a-zA-Z_]`. - */ -type ReadLetters = string extends Input - ? GenericStringError - : ReadLettersHelper extends [`${infer Letters}`, `${infer Remainder}`] - ? Letters extends '' - ? ParserError<`Expected letter at \`${Input}\``> - : [Letters, Remainder] - : ReadLettersHelper - -type ReadLettersHelper = string extends Input - ? GenericStringError - : Input extends `${infer L}${infer Remainder}` - ? L extends Letter - ? ReadLettersHelper - : [Acc, Input] - : [Acc, ''] - -/** - * Parses an identifier. - * For now, identifiers are just sequences of more than 1 letter. - * - * TODO: allow for double quoted strings. - */ -type ParseIdentifier = ReadLetters - -/** - * Parses a node. - * A node is one of the following: - * - `*` - * - `field` - * - `field(nodes)` - * - `field!hint(nodes)` - * - `field!inner(nodes)` - * - `field!hint!inner(nodes)` - * - `renamed_field:field` - * - `renamed_field:field(nodes)` - * - `renamed_field:field!hint(nodes)` - * - `renamed_field:field!inner(nodes)` - * - `renamed_field:field!hint!inner(nodes)` - * - * TODO: casting operators `::text`, JSON operators `->`, `->>`. - */ -type ParseNode = Input extends '' - ? ParserError<'Empty string'> - : // `*` - Input extends `*${infer Remainder}` - ? [{ star: true }, EatWhitespace] - : ParseIdentifier extends [infer Name, `${infer Remainder}`] - ? EatWhitespace extends `!inner${infer Remainder}` - ? ParseEmbeddedResource> extends [infer _Fields, `${infer Remainder}`] - ? // `field!inner(nodes)` - [{ name: Name; foreignTable: true }, EatWhitespace] - : ParseEmbeddedResource> extends ParserError - ? ParseEmbeddedResource> - : ParserError<'Expected embedded resource after `!inner`'> - : EatWhitespace extends `!${infer Remainder}` - ? ParseIdentifier> extends [infer _Hint, `${infer Remainder}`] - ? EatWhitespace extends `!inner${infer Remainder}` - ? ParseEmbeddedResource> extends [ - infer _Fields, - `${infer Remainder}` - ] - ? // `field!hint!inner(nodes)` - [{ name: Name; foreignTable: true }, EatWhitespace] - : ParseEmbeddedResource> extends ParserError - ? ParseEmbeddedResource> - : ParserError<'Expected embedded resource after `!inner`'> - : ParseEmbeddedResource> extends [ - infer _Fields, - `${infer Remainder}` - ] - ? // `field!hint(nodes)` - [{ name: Name; foreignTable: true }, EatWhitespace] - : ParseEmbeddedResource> extends ParserError - ? ParseEmbeddedResource> - : ParserError<'Expected embedded resource after `!hint`'> - : ParserError<'Expected identifier after `!`'> - : EatWhitespace extends `:${infer Remainder}` - ? ParseIdentifier> extends [infer OriginalName, `${infer Remainder}`] - ? EatWhitespace extends `!inner${infer Remainder}` - ? ParseEmbeddedResource> extends [ - infer _Fields, - `${infer Remainder}` - ] - ? // `renamed_field:field!inner(nodes)` - [{ name: Name; foreignTable: true }, EatWhitespace] - : ParseEmbeddedResource> extends ParserError - ? ParseEmbeddedResource> - : ParserError<'Expected embedded resource after `!inner`'> - : EatWhitespace extends `!${infer Remainder}` - ? ParseIdentifier> extends [infer _Hint, `${infer Remainder}`] - ? EatWhitespace extends `!inner${infer Remainder}` - ? ParseEmbeddedResource> extends [ - infer _Fields, - `${infer Remainder}` - ] - ? // `renamed_field:field!hint!inner(nodes)` - [{ name: Name; foreignTable: true }, EatWhitespace] - : ParseEmbeddedResource> extends ParserError - ? ParseEmbeddedResource> - : ParserError<'Expected embedded resource after `!inner`'> - : ParseEmbeddedResource> extends [ - infer _Fields, - `${infer Remainder}` - ] - ? // `renamed_field:field!hint(nodes)` - [ - { - name: Name - foreignTable: true - }, - EatWhitespace - ] - : ParseEmbeddedResource> extends ParserError - ? ParseEmbeddedResource> - : ParserError<'Expected embedded resource after `!hint`'> - : ParserError<'Expected identifier after `!`'> - : ParseEmbeddedResource> extends [ - infer _Fields, - `${infer Remainder}` - ] - ? // `renamed_field:field(nodes)` - [{ name: Name; foreignTable: true }, EatWhitespace] - : ParseEmbeddedResource> extends ParserError - ? ParseEmbeddedResource> - : // `renamed_field:field` - [{ name: Name; original: OriginalName }, EatWhitespace] - : ParseIdentifier> - : ParseEmbeddedResource> extends [infer _Fields, `${infer Remainder}`] - ? // `field(nodes)` - [{ name: Name; foreignTable: true }, EatWhitespace] - : ParseEmbeddedResource> extends ParserError - ? ParseEmbeddedResource> - : // `field` - [{ name: Name; original: Name }, EatWhitespace] - : ParserError<`Expected identifier at \`${Input}\``> - -/** - * Parses an embedded resource, which is an opening `(`, followed by a sequence of - * nodes, separated by `,`, then a closing `)`. - * - * Returns a tuple of ["Parsed fields", "Remainder of text"], an error, - * or the original string input indicating that no opening `(` was found. - */ -type ParseEmbeddedResource = Input extends `(${infer Remainder}` - ? ParseNodes> extends [infer Fields, `${infer Remainder}`] - ? EatWhitespace extends `)${infer Remainder}` - ? Fields extends [] - ? ParserError<'Expected fields after `(`'> - : [Fields, EatWhitespace] - : ParserError<`Expected ")"`> - : ParseNodes> - : Input - -/** - * Parses a sequence of nodes, separated by `,`. - * - * Returns a tuple of ["Parsed fields", "Remainder of text"] or an error. - */ -type ParseNodes = string extends Input - ? GenericStringError - : ParseNodesHelper - -type ParseNodesHelper = ParseNode extends [ - infer Field, - `${infer Remainder}` -] - ? EatWhitespace extends `,${infer Remainder}` - ? ParseNodesHelper, [Field, ...Fields]> - : [[Field, ...Fields], EatWhitespace] - : ParseNode - -/** - * Parses a query. - * A query is a sequence of nodes, separated by `,`, ensuring that there is - * no remaining input after all nodes have been parsed. - * - * Returns an array of parsed nodes, or an error. - */ -type ParseQuery = string extends Query - ? GenericStringError - : ParseNodes> extends [infer Fields, `${infer Remainder}`] - ? EatWhitespace extends '' - ? Fields - : ParserError<`Unexpected input: ${Remainder}`> - : ParseNodes> - -type GetResultHelper< - Row extends Record, - Fields extends unknown[], - Acc -> = Fields extends [infer R] - ? GetResultHelper & Acc> - : Fields extends [infer R, ...infer Rest] - ? GetResultHelper & Acc> - : Acc - -/** - * Constructs a type definition for an object based on a given PostgREST query. - * - * @param Row Record. - * @param Query Select query string literal to parse. - */ -export type GetResult< - Row extends Record, - Query extends string -> = ParseQuery extends unknown[] - ? GetResultHelper, unknown> - : ParseQuery diff --git a/src/select-query-parser/parser.ts b/src/select-query-parser/parser.ts new file mode 100644 index 00000000..b5735f19 --- /dev/null +++ b/src/select-query-parser/parser.ts @@ -0,0 +1,452 @@ +// Credits to @bnjmnt4n (https://www.npmjs.com/package/postgrest-query) +// See https://github.com/PostgREST/postgrest/blob/2f91853cb1de18944a4556df09e52450b881cfb3/src/PostgREST/ApiRequest/QueryParams.hs#L282-L284 + +import { SimplifyDeep } from '../types' + +/** + * Parses a query. + * A query is a sequence of nodes, separated by `,`, ensuring that there is + * no remaining input after all nodes have been parsed. + * + * Returns an array of parsed nodes, or an error. + */ +export type ParseQuery = string extends Query + ? GenericStringError + : ParseNodes> extends [infer Nodes extends Ast.Node[], `${infer Remainder}`] + ? EatWhitespace extends '' + ? SimplifyDeep + : ParserError<`Unexpected input: ${Remainder}`> + : ParseNodes> + +/** + * Notes: all `Parse*` types assume that their input strings have their whitespace + * removed. They return tuples of ["Return Value", "Remainder of text"] or + * a `ParserError`. + */ + +/** + * Parses a sequence of nodes, separated by `,`. + * + * Returns a tuple of ["Parsed fields", "Remainder of text"] or an error. + */ +type ParseNodes = string extends Input + ? GenericStringError + : ParseNodesHelper + +type ParseNodesHelper = ParseNode extends [ + infer Node extends Ast.Node, + `${infer Remainder}` +] + ? EatWhitespace extends `,${infer Remainder}` + ? ParseNodesHelper, [...Nodes, Node]> + : [[...Nodes, Node], EatWhitespace] + : ParseNode + +/** + * Parses a node. + * A node is one of the following: + * - `*` + * - a field, as defined above + * - a renamed field, `renamed_field:field` + * - a spread field, `...field` + */ +type ParseNode = Input extends '' + ? ParserError<'Empty string'> + : // `*` + Input extends `*${infer Remainder}` + ? [Ast.StarNode, EatWhitespace] + : // `...field` + Input extends `...${infer Remainder}` + ? ParseField> extends [ + infer TargetField extends Ast.FieldNode, + `${infer Remainder}` + ] + ? [{ type: 'spread'; target: TargetField }, EatWhitespace] + : ParserError<`Unable to parse spread resource at \`${Input}\``> + : ParseIdentifier extends [infer NameOrAlias, `${infer Remainder}`] + ? EatWhitespace extends `::${infer _}` + ? // It's a type cast and not an alias, so treat it as part of the field. + ParseField + : EatWhitespace extends `:${infer Remainder}` + ? // `alias:` + ParseField> extends [ + infer Field extends Ast.FieldNode, + `${infer Remainder}` + ] + ? [Omit & { alias: NameOrAlias }, EatWhitespace] + : ParserError<`Unable to parse renamed field at \`${Input}\``> + : // Otherwise, just parse it as a field without alias. + ParseField + : ParserError<`Expected identifier at \`${Input}\``> + +/** + * Parses a field without preceding alias. + * A field is one of the following: + * - a top-level `count` field: https://docs.postgrest.org/en/v12/references/api/aggregate_functions.html#the-case-of-count + * - a field with an embedded resource + * - `field(nodes)` + * - `field!hint(nodes)` + * - `field!inner(nodes)` + * - `field!left(nodes)` + * - `field!hint!inner(nodes)` + * - `field!hint!left(nodes)` + * - a field without an embedded resource (see {@link ParseNonEmbeddedResourceField}) + */ +type ParseField = Input extends '' + ? ParserError<'Empty string'> + : ParseIdentifier extends [infer Name, `${infer Remainder}`] + ? Name extends 'count' + ? ParseCountField + : Remainder extends `!inner${infer Remainder}` + ? ParseEmbeddedResource extends [ + infer Children extends Ast.Node[], + `${infer Remainder}` + ] + ? // `field!inner(nodes)` + [{ type: 'field'; name: Name; innerJoin: true; children: Children }, Remainder] + : CreateParserErrorIfRequired< + ParseEmbeddedResource, + `Expected embedded resource after "!inner" at \`${Remainder}\`` + > + : EatWhitespace extends `!left${infer Remainder}` + ? ParseEmbeddedResource> extends [ + infer Children extends Ast.Node[], + `${infer Remainder}` + ] + ? // `field!left(nodes)` + // !left is a noise word - treat it the same way as a non-`!inner`. + [{ type: 'field'; name: Name; children: Children }, EatWhitespace] + : CreateParserErrorIfRequired< + ParseEmbeddedResource>, + `Expected embedded resource after "!left" at \`${EatWhitespace}\`` + > + : EatWhitespace extends `!${infer Remainder}` + ? ParseIdentifier> extends [infer Hint, `${infer Remainder}`] + ? EatWhitespace extends `!inner${infer Remainder}` + ? ParseEmbeddedResource> extends [ + infer Children extends Ast.Node[], + `${infer Remainder}` + ] + ? // `field!hint!inner(nodes)` + [ + { type: 'field'; name: Name; hint: Hint; innerJoin: true; children: Children }, + EatWhitespace + ] + : ParseEmbeddedResource> + : ParseEmbeddedResource> extends [ + infer Children extends Ast.Node[], + `${infer Remainder}` + ] + ? // `field!hint(nodes)` + [{ type: 'field'; name: Name; hint: Hint; children: Children }, EatWhitespace] + : ParseEmbeddedResource> + : ParserError<`Expected identifier after "!" at \`${EatWhitespace}\``> + : EatWhitespace extends `(${infer _}` + ? ParseEmbeddedResource> extends [ + infer Children extends Ast.Node[], + `${infer Remainder}` + ] + ? // `field(nodes)` + [{ type: 'field'; name: Name; children: Children }, EatWhitespace] + : // Return error if start of embedded resource was detected but not found. + ParseEmbeddedResource> + : // Otherwise it's a non-embedded resource field. + ParseNonEmbeddedResourceField + : ParserError<`Expected identifier at \`${Input}\``> + +type ParseCountField = ParseIdentifier extends [ + 'count', + `${infer Remainder}` +] + ? ( + EatWhitespace extends `()${infer Remainder_}` + ? EatWhitespace + : EatWhitespace + ) extends `${infer Remainder}` + ? Remainder extends `::${infer _}` + ? ParseFieldTypeCast extends [infer CastType, `${infer Remainder}`] + ? [ + { type: 'field'; name: 'count'; aggregateFunction: 'count'; castType: CastType }, + Remainder + ] + : ParseFieldTypeCast + : [{ type: 'field'; name: 'count'; aggregateFunction: 'count' }, Remainder] + : never + : ParserError<`Expected "count" at \`${Input}\``> + +/** + * Parses an embedded resource, which is an opening `(`, followed by a sequence of + * 0 or more nodes separated by `,`, then a closing `)`. + * + * Returns a tuple of ["Parsed fields", "Remainder of text"], an error, + * or the original string input indicating that no opening `(` was found. + */ +type ParseEmbeddedResource = Input extends `(${infer Remainder}` + ? EatWhitespace extends `)${infer Remainder}` + ? [[], EatWhitespace] + : ParseNodes> extends [ + infer Nodes extends Ast.Node[], + `${infer Remainder}` + ] + ? EatWhitespace extends `)${infer Remainder}` + ? [Nodes, EatWhitespace] + : ParserError<`Expected ")" at \`${EatWhitespace}\``> + : ParseNodes> + : ParserError<`Expected "(" at \`${Input}\``> + +/** + * Parses a field excluding embedded resources, without preceding field renaming. + * This is one of the following: + * - `field` + * - `field.aggregate()` + * - `field.aggregate()::type` + * - `field::type` + * - `field::type.aggregate()` + * - `field::type.aggregate()::type` + * - `field->json...` + * - `field->json.aggregate()` + * - `field->json.aggregate()::type` + * - `field->json::type` + * - `field->json::type.aggregate()` + * - `field->json::type.aggregate()::type` + */ +type ParseNonEmbeddedResourceField = ParseIdentifier extends [ + infer Name, + `${infer Remainder}` +] + ? // Parse optional JSON path. + ( + Remainder extends `->${infer _}` + ? ParseJsonAccessor extends [ + infer PropertyName, + infer PropertyType, + `${infer Remainder}` + ] + ? [{ type: 'field'; name: Name; alias: PropertyName; castType: PropertyType }, Remainder] + : ParseJsonAccessor + : [{ type: 'field'; name: Name }, Remainder] + ) extends infer Parsed + ? Parsed extends [infer Field, `${infer Remainder}`] + ? // Parse optional typecast or aggregate function input typecast. + ( + Remainder extends `::${infer _}` + ? ParseFieldTypeCast extends [infer CastType, `${infer Remainder}`] + ? [Omit & { castType: CastType }, Remainder] + : ParseFieldTypeCast + : [Field, Remainder] + ) extends infer Parsed + ? Parsed extends [infer Field, `${infer Remainder}`] + ? // Parse optional aggregate function. + Remainder extends `.${infer _}` + ? ParseFieldAggregation extends [ + infer AggregateFunction, + `${infer Remainder}` + ] + ? // Parse optional aggregate function output typecast. + Remainder extends `::${infer _}` + ? ParseFieldTypeCast extends [infer CastType, `${infer Remainder}`] + ? [ + Omit & { + aggregateFunction: AggregateFunction + castType: CastType + }, + Remainder + ] + : ParseFieldTypeCast + : [Field & { aggregateFunction: AggregateFunction }, Remainder] + : ParseFieldAggregation + : [Field, Remainder] + : Parsed + : never + : Parsed + : never + : ParserError<`Expected identifier at \`${Input}\``> + +/** + * Parses a JSON property accessor of the shape `->a->b->c`. The last accessor in + * the series may convert to text by using the ->> operator instead of ->. + * + * Returns a tuple of ["Last property name", "Last property type", "Remainder of text"] + */ +type ParseJsonAccessor = Input extends `->${infer Remainder}` + ? Remainder extends `>${infer Remainder}` + ? ParseIdentifier extends [infer Name, `${infer Remainder}`] + ? [Name, 'text', EatWhitespace] + : ParserError<'Expected property name after `->>`'> + : ParseIdentifier extends [infer Name, `${infer Remainder}`] + ? ParseJsonAccessor extends [ + infer PropertyName, + infer PropertyType, + `${infer Remainder}` + ] + ? [PropertyName, PropertyType, EatWhitespace] + : [Name, 'json', EatWhitespace] + : ParserError<'Expected property name after `->`'> + : ParserError<'Expected ->'> + +/** + * Parses a field typecast (`::type`), returning a tuple of ["Type", "Remainder of text"]. + */ +type ParseFieldTypeCast = EatWhitespace extends `::${infer Remainder}` + ? ParseIdentifier> extends [`${infer CastType}`, `${infer Remainder}`] + ? [CastType, EatWhitespace] + : ParserError<`Invalid type for \`::\` operator at \`${Remainder}\``> + : ParserError<'Expected ::'> + +/** + * Parses a field aggregation (`.max()`), returning a tuple of ["Aggregate function", "Remainder of text"] + */ +type ParseFieldAggregation = + EatWhitespace extends `.${infer Remainder}` + ? ParseIdentifier> extends [ + `${infer FunctionName}`, + `${infer Remainder}` + ] + ? // Ensure that aggregation function is valid. + FunctionName extends Token.AggregateFunction + ? EatWhitespace extends `()${infer Remainder}` + ? [FunctionName, EatWhitespace] + : ParserError<`Expected \`()\` after \`.\` operator \`${FunctionName}\``> + : ParserError<`Invalid type for \`.\` operator \`${FunctionName}\``> + : ParserError<`Invalid type for \`.\` operator at \`${Remainder}\``> + : ParserError<'Expected .'> + +/** + * Parses a (possibly double-quoted) identifier. + * Identifiers are sequences of 1 or more letters. + */ +type ParseIdentifier = ParseLetters extends [ + infer Name, + `${infer Remainder}` +] + ? [Name, EatWhitespace] + : ParseQuotedLetters extends [infer Name, `${infer Remainder}`] + ? [Name, EatWhitespace] + : ParserError<`No (possibly double-quoted) identifier at \`${Input}\``> + +/** + * Parse a consecutive sequence of 1 or more letter, where letters are `[0-9a-zA-Z_]`. + */ +type ParseLetters = string extends Input + ? GenericStringError + : ParseLettersHelper extends [`${infer Letters}`, `${infer Remainder}`] + ? Letters extends '' + ? ParserError<`Expected letter at \`${Input}\``> + : [Letters, Remainder] + : ParseLettersHelper + +type ParseLettersHelper = string extends Input + ? GenericStringError + : Input extends `${infer L}${infer Remainder}` + ? L extends Token.Letter + ? ParseLettersHelper + : [Acc, Input] + : [Acc, ''] + +/** + * Parse a consecutive sequence of 1 or more double-quoted letters, + * where letters are `[^"]`. + */ +type ParseQuotedLetters = string extends Input + ? GenericStringError + : Input extends `"${infer Remainder}` + ? ParseQuotedLettersHelper extends [`${infer Letters}`, `${infer Remainder}`] + ? Letters extends '' + ? ParserError<`Expected string at \`${Remainder}\``> + : [Letters, Remainder] + : ParseQuotedLettersHelper + : ParserError<`Not a double-quoted string at \`${Input}\``> + +type ParseQuotedLettersHelper = string extends Input + ? GenericStringError + : Input extends `${infer L}${infer Remainder}` + ? L extends '"' + ? [Acc, Remainder] + : ParseQuotedLettersHelper + : ParserError<`Missing closing double-quote in \`"${Acc}${Input}\``> + +/** + * Trims whitespace from the left of the input. + */ +type EatWhitespace = string extends Input + ? GenericStringError + : Input extends `${Token.Whitespace}${infer Remainder}` + ? EatWhitespace + : Input + +/** + * Creates a new {@link ParserError} if the given input is not already a parser error. + */ +type CreateParserErrorIfRequired = Input extends ParserError + ? Input + : ParserError + +/** + * Parser errors. + */ +export type ParserError = { error: true } & Message +type GenericStringError = ParserError<'Received a generic string'> + +export namespace Ast { + export type Node = FieldNode | StarNode | SpreadNode + + export type FieldNode = { + type: 'field' + name: string + alias?: string + hint?: string + innerJoin?: true + castType?: string + aggregateFunction?: Token.AggregateFunction + children?: Node[] + } + + export type StarNode = { + type: 'star' + } + + export type SpreadNode = { + type: 'spread' + target: FieldNode & { children: Node[] } + } +} + +namespace Token { + export type Whitespace = ' ' | '\n' | '\t' + + type LowerAlphabet = + | 'a' + | 'b' + | 'c' + | 'd' + | 'e' + | 'f' + | 'g' + | 'h' + | 'i' + | 'j' + | 'k' + | 'l' + | 'm' + | 'n' + | 'o' + | 'p' + | 'q' + | 'r' + | 's' + | 't' + | 'u' + | 'v' + | 'w' + | 'x' + | 'y' + | 'z' + + type Alphabet = LowerAlphabet | Uppercase + + type Digit = '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '0' + + export type Letter = Alphabet | Digit | '_' + + export type AggregateFunction = 'count' | 'sum' | 'avg' | 'min' | 'max' +} diff --git a/src/select-query-parser/result.ts b/src/select-query-parser/result.ts new file mode 100644 index 00000000..07802c70 --- /dev/null +++ b/src/select-query-parser/result.ts @@ -0,0 +1,304 @@ +import { GenericTable } from '../types' +import { ContainsNull, GenericRelationship, PostgreSQLTypes } from './types' +import { Ast, ParseQuery } from './parser' +import { + AggregateFunctions, + ExtractFirstProperty, + GenericSchema, + IsNonEmptyArray, + Prettify, + TablesAndViews, + TypeScriptTypes, +} from './types' +import { + CheckDuplicateEmbededReference, + GetFieldNodeResultName, + IsRelationNullable, + ResolveRelationship, + SelectQueryError, +} from './utils' + +/** + * Main entry point for constructing the result type of a PostgREST query. + * + * @param Schema - Database schema. + * @param Row - The type of a row in the current table. + * @param RelationName - The name of the current table or view. + * @param Relationships - Relationships of the current table. + * @param Query - The select query string literal to parse. + */ +export type GetResult< + Schema extends GenericSchema, + Row extends Record, + RelationName, + Relationships, + Query extends string +> = Relationships extends null // For .rpc calls the passed relationships will be null in that case, the result will always be the function return type + ? ParseQuery extends infer ParsedQuery extends Ast.Node[] + ? RPCCallNodes + : Row + : ParseQuery extends infer ParsedQuery + ? ParsedQuery extends Ast.Node[] + ? RelationName extends string + ? Relationships extends GenericRelationship[] + ? ProcessNodes + : SelectQueryError<'Invalid Relationships cannot infer result type'> + : SelectQueryError<'Invalid RelationName cannot infer result type'> + : ParsedQuery + : never + +/** + * Processes a single Node from a select chained after a rpc call + * + * @param Row - The type of a row in the current table. + * @param RelationName - The name of the current rpc function + * @param NodeType - The Node to process. + */ +export type ProcessRPCNode< + Row extends Record, + RelationName extends string, + NodeType extends Ast.Node +> = NodeType extends Ast.StarNode // If the selection is * + ? Row + : NodeType extends Ast.FieldNode + ? ProcessSimpleField + : SelectQueryError<'Unsupported node type.'> +/** + * Process select call that can be chained after an rpc call + */ +export type RPCCallNodes< + Nodes extends Ast.Node[], + RelationName extends string, + Row extends Record, + Acc extends Record = {} // Acc is now an object +> = Nodes extends [infer FirstNode extends Ast.Node, ...infer RestNodes extends Ast.Node[]] + ? ProcessRPCNode extends infer FieldResult + ? FieldResult extends Record + ? RPCCallNodes + : FieldResult extends SelectQueryError + ? SelectQueryError + : SelectQueryError<'Could not retrieve a valid record or error value'> + : SelectQueryError<'Processing node failed.'> + : Prettify + +/** + * Recursively processes an array of Nodes and accumulates the resulting TypeScript type. + * + * @param Schema - Database schema. + * @param Row - The type of a row in the current table. + * @param RelationName - The name of the current table or view. + * @param Relationships - Relationships of the current table. + * @param Nodes - An array of AST nodes to process. + * @param Acc - Accumulator for the constructed type. + */ +export type ProcessNodes< + Schema extends GenericSchema, + Row extends Record, + RelationName extends string, + Relationships extends GenericRelationship[], + Nodes extends Ast.Node[], + Acc extends Record = {} // Acc is now an object +> = CheckDuplicateEmbededReference extends false + ? Nodes extends [infer FirstNode extends Ast.Node, ...infer RestNodes extends Ast.Node[]] + ? ProcessNode extends infer FieldResult + ? FieldResult extends Record + ? ProcessNodes + : FieldResult extends SelectQueryError + ? SelectQueryError + : SelectQueryError<'Could not retrieve a valid record or error value'> + : SelectQueryError<'Processing node failed.'> + : Prettify + : Prettify> + +/** + * Processes a single Node and returns the resulting TypeScript type. + * + * @param Schema - Database schema. + * @param Row - The type of a row in the current table. + * @param RelationName - The name of the current table or view. + * @param Relationships - Relationships of the current table. + * @param NodeType - The Node to process. + */ +export type ProcessNode< + Schema extends GenericSchema, + Row extends Record, + RelationName extends string, + Relationships extends GenericRelationship[], + NodeType extends Ast.Node +> = NodeType extends Ast.StarNode // If the selection is * + ? Row + : NodeType extends Ast.SpreadNode // If the selection is a ...spread + ? ProcessSpreadNode + : NodeType extends Ast.FieldNode + ? ProcessFieldNode + : SelectQueryError<'Unsupported node type.'> + +/** + * Processes a FieldNode and returns the resulting TypeScript type. + * + * @param Schema - Database schema. + * @param Row - The type of a row in the current table. + * @param RelationName - The name of the current table or view. + * @param Relationships - Relationships of the current table. + * @param Field - The FieldNode to process. + */ +type ProcessFieldNode< + Schema extends GenericSchema, + Row extends Record, + RelationName extends string, + Relationships extends GenericRelationship[], + Field extends Ast.FieldNode +> = Field['children'] extends [] + ? {} + : IsNonEmptyArray extends true // Has embedded resource? + ? ProcessEmbeddedResource + : ProcessSimpleField + +/** + * Processes a simple field (without embedded resources). + * + * @param Row - The type of a row in the current table. + * @param RelationName - The name of the current table or view. + * @param Field - The FieldNode to process. + */ +type ProcessSimpleField< + Row extends Record, + RelationName extends string, + Field extends Ast.FieldNode +> = Field['name'] extends keyof Row | 'count' + ? Field['aggregateFunction'] extends AggregateFunctions + ? { + // An aggregate function will always override the column name id.sum() will become sum + // except if it has been aliased + [K in GetFieldNodeResultName]: Field['castType'] extends PostgreSQLTypes + ? TypeScriptTypes + : number + } + : { + // Aliases override the property name in the result + [K in GetFieldNodeResultName]: Field['castType'] extends PostgreSQLTypes // We apply the detected casted as the result type + ? TypeScriptTypes + : Row[Field['name']] + } + : SelectQueryError<`column '${Field['name']}' does not exist on '${RelationName}'.`> + +/** + * Processes an embedded resource (relation). + * + * @param Schema - Database schema. + * @param Row - The type of a row in the current table. + * @param RelationName - The name of the current table or view. + * @param Relationships - Relationships of the current table. + * @param Field - The FieldNode to process. + */ +export type ProcessEmbeddedResource< + Schema extends GenericSchema, + Relationships extends GenericRelationship[], + Field extends Ast.FieldNode, + CurrentTableOrView extends keyof TablesAndViews +> = ResolveRelationship extends infer Resolved + ? Resolved extends { + referencedTable: Pick + relation: GenericRelationship & { match: 'refrel' | 'col' | 'fkname' } + direction: string + } + ? ProcessEmbeddedResourceResult + : // Otherwise the Resolved is a SelectQueryError return it + { [K in GetFieldNodeResultName]: Resolved } + : { + [K in GetFieldNodeResultName]: SelectQueryError<'Failed to resolve relationship.'> & + string + } + +/** + * Helper type to process the result of an embedded resource. + */ +type ProcessEmbeddedResourceResult< + Schema extends GenericSchema, + Resolved extends { + referencedTable: Pick + relation: GenericRelationship & { match: 'refrel' | 'col' | 'fkname' } + direction: string + }, + Field extends Ast.FieldNode, + CurrentTableOrView extends keyof TablesAndViews +> = ProcessNodes< + Schema, + Resolved['referencedTable']['Row'], + Field['name'], + Resolved['referencedTable']['Relationships'], + Field['children'] extends undefined + ? [] + : Exclude extends Ast.Node[] + ? Exclude + : [] +> extends infer ProcessedChildren + ? { + [K in GetFieldNodeResultName]: Resolved['direction'] extends 'forward' + ? Field extends { innerJoin: true } + ? Resolved['relation']['isOneToOne'] extends true + ? ProcessedChildren + : ProcessedChildren[] + : Resolved['relation']['isOneToOne'] extends true + ? ProcessedChildren | null + : ProcessedChildren[] + : // If the relation is a self-reference it'll always be considered as reverse relationship + Resolved['relation']['referencedRelation'] extends CurrentTableOrView + ? // It can either be a reverse reference via a column inclusion (eg: parent_id(*)) + // in such case the result will be a single object + Resolved['relation']['match'] extends 'col' + ? IsRelationNullable< + TablesAndViews[CurrentTableOrView], + Resolved['relation'] + > extends true + ? ProcessedChildren | null + : ProcessedChildren + : // Or it can be a reference via the reference relation (eg: collections(*)) + // in such case, the result will be an array of all the values (all collection with parent_id being the current id) + ProcessedChildren[] + : // Otherwise if it's a non self-reference reverse relationship it's a single object + IsRelationNullable< + TablesAndViews[CurrentTableOrView], + Resolved['relation'] + > extends true + ? ProcessedChildren | null + : ProcessedChildren + } + : { + [K in GetFieldNodeResultName]: SelectQueryError<'Failed to process embedded resource nodes.'> & + string + } + +/** + * Processes a SpreadNode by processing its target node. + * + * @param Schema - Database schema. + * @param Row - The type of a row in the current table. + * @param RelationName - The name of the current table or view. + * @param Relationships - Relationships of the current table. + * @param Spread - The SpreadNode to process. + */ +type ProcessSpreadNode< + Schema extends GenericSchema, + Row extends Record, + RelationName extends string, + Relationships extends GenericRelationship[], + Spread extends Ast.SpreadNode +> = ProcessNode extends infer Result + ? Result extends SelectQueryError + ? SelectQueryError + : ExtractFirstProperty extends unknown[] + ? { + [K in Spread['target']['name']]: SelectQueryError<`"${RelationName}" and "${Spread['target']['name']}" do not form a many-to-one or one-to-one relationship spread not possible`> + } + : ProcessSpreadNodeResult + : never + +/** + * Helper type to process the result of a spread node. + */ +type ProcessSpreadNodeResult = ExtractFirstProperty extends infer SpreadedObject + ? ContainsNull extends true + ? Exclude<{ [K in keyof SpreadedObject]: SpreadedObject[K] | null }, null> + : Exclude<{ [K in keyof SpreadedObject]: SpreadedObject[K] }, null> + : SelectQueryError<'An error occurred spreading the object'> diff --git a/src/select-query-parser/types.ts b/src/select-query-parser/types.ts new file mode 100644 index 00000000..597ee0a9 --- /dev/null +++ b/src/select-query-parser/types.ts @@ -0,0 +1,115 @@ +import type { GenericRelationship, GenericSchema, GenericTable, Prettify } from '../types' + +export type { GenericRelationship, GenericSchema, GenericTable, Prettify } + +export type AggregateWithoutColumnFunctions = 'count' + +export type AggregateWithColumnFunctions = + | 'sum' + | 'avg' + | 'min' + | 'max' + | AggregateWithoutColumnFunctions + +export type AggregateFunctions = AggregateWithColumnFunctions + +export type Json = + | string + | number + | boolean + | null + | { + [key: string]: Json | undefined + } + | Json[] + +type PostgresSQLNumberTypes = 'int2' | 'int4' | 'int8' | 'float4' | 'float8' | 'numeric' + +type PostgresSQLStringTypes = + | 'bytea' + | 'bpchar' + | 'varchar' + | 'date' + | 'text' + | 'citext' + | 'time' + | 'timetz' + | 'timestamp' + | 'timestamptz' + | 'uuid' + | 'vector' + +type SingleValuePostgreSQLTypes = + | PostgresSQLNumberTypes + | PostgresSQLStringTypes + | 'bool' + | 'json' + | 'jsonb' + | 'void' + | 'record' + | string + +type ArrayPostgreSQLTypes = `_${SingleValuePostgreSQLTypes}` + +type TypeScriptSingleValueTypes = T extends 'bool' + ? boolean + : T extends PostgresSQLNumberTypes + ? number + : T extends PostgresSQLStringTypes + ? string + : T extends 'json' | 'jsonb' + ? Json + : T extends 'void' + ? undefined + : T extends 'record' + ? Record + : unknown + +type StripUnderscore = T extends `_${infer U}` ? U : T + +// Represents all possible PostgreSQL types, including array types, allow for custom types with 'string' in union +export type PostgreSQLTypes = SingleValuePostgreSQLTypes | ArrayPostgreSQLTypes + +// Helper type to convert PostgreSQL types to their TypeScript equivalents +export type TypeScriptTypes = T extends ArrayPostgreSQLTypes + ? TypeScriptSingleValueTypes>>[] + : TypeScriptSingleValueTypes + +// Utility types for working with unions +export type UnionToIntersection = (U extends any ? (k: U) => void : never) extends ( + k: infer I +) => void + ? I + : never + +export type LastOf = UnionToIntersection T : never> extends () => infer R + ? R + : never + +export type Push = [...T, V] + +// Converts a union type to a tuple type +export type UnionToTuple, N = [T] extends [never] ? true : false> = N extends true + ? [] + : Push>, L> + +export type UnionToArray = UnionToTuple + +// Extracts the type of the first property in an object type +export type ExtractFirstProperty = T extends { [K in keyof T]: infer U } ? U : never + +// Type predicates +export type ContainsNull = null extends T ? true : false + +export type IsNonEmptyArray = Exclude extends readonly [unknown, ...unknown[]] + ? true + : false + +// Types for working with database schemas +export type TablesAndViews = Schema['Tables'] & + Exclude + +export type GetTableRelationships< + Schema extends GenericSchema, + Tname extends string +> = TablesAndViews[Tname] extends { Relationships: infer R } ? R : false diff --git a/src/select-query-parser/utils.ts b/src/select-query-parser/utils.ts new file mode 100644 index 00000000..eff2b1fc --- /dev/null +++ b/src/select-query-parser/utils.ts @@ -0,0 +1,457 @@ +import { Ast } from './parser' +import { + AggregateFunctions, + ContainsNull, + GenericRelationship, + GenericSchema, + GenericTable, + IsNonEmptyArray, + TablesAndViews, + UnionToArray, +} from './types' + +export type SelectQueryError = { error: true } & Message + +type RequireHintingSelectQueryError< + DistantName extends string, + RelationName extends string +> = SelectQueryError<`Could not embed because more than one relationship was found for '${DistantName}' and '${RelationName}' you need to hint the column with ${DistantName}! ?`> + +export type GetFieldNodeResultName = Field['alias'] extends string + ? Field['alias'] + : Field['aggregateFunction'] extends AggregateFunctions + ? Field['aggregateFunction'] + : Field['name'] + +type FilterRelationNodes = UnionToArray< + { + [K in keyof Nodes]: Nodes[K] extends Ast.SpreadNode + ? Nodes[K]['target'] + : Nodes[K] extends Ast.FieldNode + ? IsNonEmptyArray extends true + ? Nodes[K] + : never + : never + }[number] +> + +type ResolveRelationships< + Schema extends GenericSchema, + RelationName extends string, + Relationships extends GenericRelationship[], + Nodes extends Ast.FieldNode[] +> = UnionToArray<{ + [K in keyof Nodes]: ResolveRelationship< + Schema, + Relationships, + Nodes[K], + RelationName + > extends infer Relation + ? Relation extends { + relation: { + referencedRelation: any + foreignKeyName: any + match: any + } + from: any + } + ? { + referencedTable: Relation['relation']['referencedRelation'] + fkName: Relation['relation']['foreignKeyName'] + from: Relation['from'] + match: Relation['relation']['match'] + fieldName: GetFieldNodeResultName + } + : never + : never +}>[0] + +/** + * Checks if a relation is implicitly referenced twice, requiring disambiguation + */ +type IsDoubleReference = T extends { + referencedTable: infer RT + fieldName: infer FN + match: infer M extends 'col' | 'refrel' +} + ? U extends { referencedTable: RT; fieldName: FN; match: M } + ? true + : false + : false + +/** + * Compares one element with all other elements in the array to find duplicates + */ +type CheckDuplicates = Arr extends [infer Head, ...infer Tail] + ? IsDoubleReference extends true + ? Head | CheckDuplicates // Return the Head if duplicate + : CheckDuplicates // Otherwise, continue checking + : never + +/** + * Iterates over the elements of the array to find duplicates + */ +type FindDuplicates = Arr extends [infer Head, ...infer Tail] + ? CheckDuplicates | FindDuplicates + : never + +export type CheckDuplicateEmbededReference< + Schema extends GenericSchema, + RelationName extends string, + Relationships extends GenericRelationship[], + Nodes extends Ast.Node[] +> = FilterRelationNodes extends infer RelationsNodes extends Ast.FieldNode[] + ? ResolveRelationships< + Schema, + RelationName, + Relationships, + RelationsNodes + > extends infer ResolvedRels + ? ResolvedRels extends unknown[] + ? FindDuplicates extends infer Duplicates + ? Duplicates extends never + ? false + : Duplicates extends { fieldName: infer FieldName extends string } + ? { + [K in FieldName]: SelectQueryError<`table "${RelationName}" specified more than once use hinting for desambiguation`> + } + : false + : false + : false + : false + : false + +/** + * Returns a boolean representing whether there is a foreign key referencing + * a given relation. + */ +type HasFKeyToFRel = Relationships extends [infer R] + ? R extends { referencedRelation: FRelName } + ? true + : false + : Relationships extends [infer R, ...infer Rest] + ? HasFKeyToFRel extends true + ? true + : HasFKeyToFRel + : false +/** + * Checks if there is more than one relation to a given foreign relation name in the Relationships. + */ +type HasMultipleFKeysToFRel = Relationships extends [ + infer R, + ...infer Rest +] + ? R extends { referencedRelation: FRelName } + ? HasFKeyToFRel extends true + ? true + : HasMultipleFKeysToFRel + : HasMultipleFKeysToFRel + : false + +type CheckRelationshipError< + Schema extends GenericSchema, + Relationships extends GenericRelationship[], + CurrentTableOrView extends keyof TablesAndViews, + FoundRelation +> = FoundRelation extends SelectQueryError + ? FoundRelation + : // If the relation is a reverse relation with no hint (matching by name) + FoundRelation extends { + relation: { + referencedRelation: infer RelatedRelationName extends string + name: string + } + direction: 'reverse' + } + ? // We check if there is possible confusion with other relations with this table + HasMultipleFKeysToFRel extends true + ? // If there is, postgrest will fail at runtime, and require desambiguation via hinting + RequireHintingSelectQueryError< + RelatedRelationName, + CurrentTableOrView extends string ? CurrentTableOrView : 'unknown' + > + : FoundRelation + : // Same check for forward relationships, but we must gather the relationships from the found relation + FoundRelation extends { + relation: { + referencedRelation: infer RelatedRelationName extends string + name: string + } + direction: 'forward' + from: infer From extends keyof TablesAndViews + } + ? HasMultipleFKeysToFRel< + RelatedRelationName, + TablesAndViews[From]['Relationships'] + > extends true + ? RequireHintingSelectQueryError + : FoundRelation + : FoundRelation + +/** + * Resolves relationships for embedded resources and retrieves the referenced Table + */ +export type ResolveRelationship< + Schema extends GenericSchema, + Relationships extends GenericRelationship[], + Field extends Ast.FieldNode, + CurrentTableOrView extends keyof TablesAndViews +> = ResolveReverseRelationship< + Schema, + Relationships, + Field, + CurrentTableOrView +> extends infer ReverseRelationship + ? ReverseRelationship extends false + ? CheckRelationshipError< + Schema, + Relationships, + CurrentTableOrView, + ResolveForwardRelationship + > + : CheckRelationshipError + : never + +/** + * Resolves reverse relationships (from children to parent) + */ +type ResolveReverseRelationship< + Schema extends GenericSchema, + Relationships extends GenericRelationship[], + Field extends Ast.FieldNode, + CurrentTableOrView extends keyof TablesAndViews +> = FindFieldMatchingRelationships extends infer FoundRelation + ? FoundRelation extends never + ? false + : FoundRelation extends { referencedRelation: infer RelatedRelationName extends string } + ? RelatedRelationName extends keyof TablesAndViews + ? // If the relation was found via hinting we just return it without any more checks + FoundRelation extends { hint: string } + ? { + referencedTable: TablesAndViews[RelatedRelationName] + relation: FoundRelation + direction: 'reverse' + from: CurrentTableOrView + } + : // If the relation was found via implicit relation naming, we must ensure there is no conflicting matches + HasMultipleFKeysToFRel extends true + ? RequireHintingSelectQueryError< + RelatedRelationName, + CurrentTableOrView extends string ? CurrentTableOrView : 'unknown' + > + : { + referencedTable: TablesAndViews[RelatedRelationName] + relation: FoundRelation + direction: 'reverse' + from: CurrentTableOrView + } + : SelectQueryError<`Relation '${RelatedRelationName}' not found in schema.`> + : false + : false + +export type FindMatchingTableRelationships< + Schema extends GenericSchema, + Relationships extends GenericRelationship[], + value extends string +> = Relationships extends [infer R, ...infer Rest extends GenericRelationship[]] + ? R extends { referencedRelation: infer ReferencedRelation } + ? ReferencedRelation extends keyof Schema['Tables'] + ? R extends { foreignKeyName: value } + ? R & { match: 'fkname' } + : R extends { referencedRelation: value } + ? R & { match: 'refrel' } + : R extends { columns: [value] } + ? R & { match: 'col' } + : FindMatchingTableRelationships + : FindMatchingTableRelationships + : false + : false + +export type FindMatchingViewRelationships< + Schema extends GenericSchema, + Relationships extends GenericRelationship[], + value extends string +> = Relationships extends [infer R, ...infer Rest extends GenericRelationship[]] + ? R extends { referencedRelation: infer ReferencedRelation } + ? ReferencedRelation extends keyof Schema['Views'] + ? R extends { foreignKeyName: value } + ? R & { match: 'fkname' } + : R extends { referencedRelation: value } + ? R & { match: 'refrel' } + : R extends { columns: [value] } + ? R & { match: 'col' } + : FindMatchingViewRelationships + : FindMatchingViewRelationships + : false + : false + +export type FindMatchingHintTableRelationships< + Schema extends GenericSchema, + Relationships extends GenericRelationship[], + hint extends string, + name extends string +> = Relationships extends [infer R, ...infer Rest extends GenericRelationship[]] + ? R extends { referencedRelation: infer ReferencedRelation } + ? ReferencedRelation extends name + ? R extends { foreignKeyName: hint } + ? R & { match: 'fkname' } + : R extends { referencedRelation: hint } + ? R & { match: 'refrel' } + : R extends { columns: [hint] } + ? R & { match: 'col' } + : FindMatchingHintTableRelationships + : FindMatchingHintTableRelationships + : false + : false + +export type FindMatchingHintViewRelationships< + Schema extends GenericSchema, + Relationships extends GenericRelationship[], + hint extends string, + name extends string +> = Relationships extends [infer R, ...infer Rest extends GenericRelationship[]] + ? R extends { referencedRelation: infer ReferencedRelation } + ? ReferencedRelation extends name + ? R extends { foreignKeyName: hint } + ? R & { match: 'fkname' } + : R extends { referencedRelation: hint } + ? R & { match: 'refrel' } + : R extends { columns: [hint] } + ? R & { match: 'col' } + : FindMatchingHintViewRelationships + : FindMatchingHintViewRelationships + : false + : false + +type IsColumnsNullable< + Table extends Pick, + Columns extends (keyof Table['Row'])[] +> = Columns extends [infer Column, ...infer Rest] + ? Column extends keyof Table['Row'] + ? ContainsNull extends true + ? true + : IsColumnsNullable + : false + : false + +// Check weither or not a 1-1 relation is nullable by checking against the type of the columns +export type IsRelationNullable< + Table extends GenericTable, + Relation extends GenericRelationship +> = IsColumnsNullable + +type TableForwardRelationships< + Schema extends GenericSchema, + TName +> = TName extends keyof TablesAndViews + ? UnionToArray< + RecursivelyFindRelationships> + > extends infer R extends (GenericRelationship & { from: keyof TablesAndViews })[] + ? R + : [] + : [] + +type RecursivelyFindRelationships< + Schema extends GenericSchema, + TName, + Keys extends keyof TablesAndViews +> = Keys extends infer K + ? K extends keyof TablesAndViews + ? FilterRelationships[K]['Relationships'], TName, K> extends never + ? RecursivelyFindRelationships> + : + | FilterRelationships[K]['Relationships'], TName, K> + | RecursivelyFindRelationships> + : false + : false + +type FilterRelationships = R extends readonly (infer Rel)[] + ? Rel extends { referencedRelation: TName } + ? Rel & { from: From } + : never + : never + +// Find a relationship from the parent to the childrens +type ResolveForwardRelationship< + Schema extends GenericSchema, + Field extends Ast.FieldNode, + CurrentTableOrView extends keyof TablesAndViews +> = FindFieldMatchingRelationships< + Schema, + TablesAndViews[Field['name']]['Relationships'], + Ast.FieldNode & { name: CurrentTableOrView; hint: Field['hint'] } +> extends infer FoundByName extends GenericRelationship + ? { + referencedTable: TablesAndViews[Field['name']] + relation: FoundByName + direction: 'forward' + from: Field['name'] + type: 'found-by-name' + } + : // The Field['name'] can sometimes be a reference to the related foreign key + // In that case, we can't use the Field['name'] to get back the relations, instead, we will find all relations pointing + // to our current table or view, and search if we can find a match in it + FindFieldMatchingRelationships< + Schema, + TableForwardRelationships, + Field + > extends infer FoundByMatch extends GenericRelationship & { + from: keyof TablesAndViews + } + ? { + referencedTable: TablesAndViews[FoundByMatch['from']] + relation: FoundByMatch + direction: 'forward' + from: CurrentTableOrView + type: 'found-my-match' + } + : SelectQueryError<'could not find the relation'> + +/** + * Finds a matching relationship based on the FieldNode's name and optional hint. + */ +export type FindFieldMatchingRelationships< + Schema extends GenericSchema, + Relationships extends GenericRelationship[], + Field extends Ast.FieldNode +> = Field extends { hint: infer Hint extends string } + ? FindMatchingHintTableRelationships< + Schema, + Relationships, + Hint, + Field['name'] + > extends infer TableRelationViaHint extends GenericRelationship + ? TableRelationViaHint & { + branch: 'found-in-table-via-hint' + hint: Field['hint'] + } + : FindMatchingHintViewRelationships< + Schema, + Relationships, + Hint, + Field['name'] + > extends infer TableViewViaHint extends GenericRelationship + ? TableViewViaHint & { + branch: 'found-in-view-via-hint' + hint: Field['hint'] + } + : SelectQueryError<'Failed to find matching relation via hint'> + : FindMatchingTableRelationships< + Schema, + Relationships, + Field['name'] + > extends infer TableRelationViaName extends GenericRelationship + ? TableRelationViaName & { + branch: 'found-in-table-via-name' + name: Field['name'] + } + : FindMatchingViewRelationships< + Schema, + Relationships, + Field['name'] + > extends infer ViewRelationViaName extends GenericRelationship + ? ViewRelationViaName & { + branch: 'found-in-view-via-name' + name: Field['name'] + } + : SelectQueryError<'Failed to find matching relation via name'> diff --git a/src/types.ts b/src/types.ts index 07cc656f..88688144 100644 --- a/src/types.ts +++ b/src/types.ts @@ -21,43 +21,49 @@ interface PostgrestResponseBase { status: number statusText: string } - -interface PostgrestResponseSuccess extends PostgrestResponseBase { +export interface PostgrestResponseSuccess extends PostgrestResponseBase { error: null - data: T[] + data: T count: number | null } -interface PostgrestResponseFailure extends PostgrestResponseBase { +export interface PostgrestResponseFailure extends PostgrestResponseBase { error: PostgrestError data: null count: null } -export type PostgrestResponse = PostgrestResponseSuccess | PostgrestResponseFailure -interface PostgrestSingleResponseSuccess extends PostgrestResponseBase { - error: null - data: T - count: number | null -} -export type PostgrestSingleResponse = - | PostgrestSingleResponseSuccess - | PostgrestResponseFailure +// TODO: in v3: +// - remove PostgrestResponse and PostgrestMaybeSingleResponse +// - rename PostgrestSingleResponse to PostgrestResponse +export type PostgrestSingleResponse = PostgrestResponseSuccess | PostgrestResponseFailure export type PostgrestMaybeSingleResponse = PostgrestSingleResponse +export type PostgrestResponse = PostgrestSingleResponse + +export type GenericRelationship = { + foreignKeyName: string + columns: string[] + isOneToOne?: boolean + referencedRelation: string + referencedColumns: string[] +} export type GenericTable = { Row: Record Insert: Record Update: Record + Relationships: GenericRelationship[] } export type GenericUpdatableView = { Row: Record Insert: Record Update: Record + Relationships: GenericRelationship[] } export type GenericNonUpdatableView = { Row: Record + Relationships: GenericRelationship[] } export type GenericView = GenericUpdatableView | GenericNonUpdatableView @@ -72,3 +78,24 @@ export type GenericSchema = { Views: Record Functions: Record } + +// https://twitter.com/mattpocockuk/status/1622730173446557697 +export type Prettify = { [K in keyof T]: T[K] } & {} +// https://github.com/sindresorhus/type-fest +export type SimplifyDeep = ConditionalSimplifyDeep< + Type, + ExcludeType | NonRecursiveType | Set | Map, + object +> +type ConditionalSimplifyDeep< + Type, + ExcludeType = never, + IncludeType = unknown +> = Type extends ExcludeType + ? Type + : Type extends IncludeType + ? { [TypeKey in keyof Type]: ConditionalSimplifyDeep } + : Type +type NonRecursiveType = BuiltIns | Function | (new (...arguments_: any[]) => unknown) +type BuiltIns = Primitive | void | Date | RegExp +type Primitive = null | undefined | string | number | boolean | symbol | bigint diff --git a/test/__snapshots__/index.test.ts.snap b/test/__snapshots__/index.test.ts.snap deleted file mode 100644 index 667618c5..00000000 --- a/test/__snapshots__/index.test.ts.snap +++ /dev/null @@ -1,1388 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Prefer: return=minimal 1`] = `null`; - -exports[`allow ordering on JSON column 1`] = ` -Array [ - Object { - "age_range": "[1,2)", - "catchphrase": "'cat' 'fat'", - "data": null, - "status": "ONLINE", - "username": "supabot", - }, - Object { - "age_range": "[25,35)", - "catchphrase": "'bat' 'cat'", - "data": null, - "status": "OFFLINE", - "username": "kiwicopple", - }, - Object { - "age_range": "[25,35)", - "catchphrase": "'bat' 'rat'", - "data": null, - "status": "ONLINE", - "username": "awailas", - }, - Object { - "age_range": "[20,30)", - "catchphrase": "'fat' 'rat'", - "data": null, - "status": "ONLINE", - "username": "dragarcia", - }, -] -`; - -exports[`basic insert, update, delete basic delete 1`] = ` -Object { - "count": null, - "data": Array [ - Object { - "channel_id": 2, - "data": null, - "id": 3, - "message": "foo", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 4, - "message": "foo", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 5, - "message": "foo", - "username": "supabot", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`basic insert, update, delete basic delete 2`] = ` -Object { - "count": null, - "data": Array [ - Object { - "channel_id": 1, - "data": null, - "id": 1, - "message": "Hello World 👋", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 2, - "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", - "username": "supabot", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`basic insert, update, delete basic insert 1`] = ` -Object { - "count": null, - "data": Array [ - Object { - "channel_id": 1, - "data": null, - "id": 3, - "message": "foo", - "username": "supabot", - }, - ], - "error": null, - "status": 201, - "statusText": "Created", -} -`; - -exports[`basic insert, update, delete basic insert 2`] = ` -Object { - "count": null, - "data": Array [ - Object { - "channel_id": 1, - "data": null, - "id": 1, - "message": "Hello World 👋", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 2, - "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", - "username": "supabot", - }, - Object { - "channel_id": 1, - "data": null, - "id": 3, - "message": "foo", - "username": "supabot", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`basic insert, update, delete basic update 1`] = ` -Object { - "count": null, - "data": Array [ - Object { - "channel_id": 2, - "data": null, - "id": 3, - "message": "foo", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 4, - "message": "foo", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 5, - "message": "foo", - "username": "supabot", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`basic insert, update, delete basic update 2`] = ` -Object { - "count": null, - "data": Array [ - Object { - "channel_id": 1, - "data": null, - "id": 1, - "message": "Hello World 👋", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 2, - "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 3, - "message": "foo", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 4, - "message": "foo", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 5, - "message": "foo", - "username": "supabot", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`basic insert, update, delete bulk insert 1`] = ` -Object { - "count": null, - "data": Array [ - Object { - "channel_id": 1, - "data": null, - "id": 4, - "message": "foo", - "username": "supabot", - }, - Object { - "channel_id": 1, - "data": null, - "id": 5, - "message": "foo", - "username": "supabot", - }, - ], - "error": null, - "status": 201, - "statusText": "Created", -} -`; - -exports[`basic insert, update, delete bulk insert 2`] = ` -Object { - "count": null, - "data": Array [ - Object { - "channel_id": 1, - "data": null, - "id": 1, - "message": "Hello World 👋", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 2, - "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 3, - "message": "foo", - "username": "supabot", - }, - Object { - "channel_id": 1, - "data": null, - "id": 4, - "message": "foo", - "username": "supabot", - }, - Object { - "channel_id": 1, - "data": null, - "id": 5, - "message": "foo", - "username": "supabot", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`basic insert, update, delete upsert 1`] = ` -Object { - "count": null, - "data": Array [ - Object { - "channel_id": 2, - "data": null, - "id": 3, - "message": "foo", - "username": "supabot", - }, - ], - "error": null, - "status": 201, - "statusText": "Created", -} -`; - -exports[`basic insert, update, delete upsert 2`] = ` -Object { - "count": null, - "data": Array [ - Object { - "channel_id": 1, - "data": null, - "id": 1, - "message": "Hello World 👋", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 2, - "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 3, - "message": "foo", - "username": "supabot", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`basic select table 1`] = ` -Object { - "count": null, - "data": Array [ - Object { - "age_range": "[1,2)", - "catchphrase": "'cat' 'fat'", - "data": null, - "status": "ONLINE", - "username": "supabot", - }, - Object { - "age_range": "[25,35)", - "catchphrase": "'bat' 'cat'", - "data": null, - "status": "OFFLINE", - "username": "kiwicopple", - }, - Object { - "age_range": "[25,35)", - "catchphrase": "'bat' 'rat'", - "data": null, - "status": "ONLINE", - "username": "awailas", - }, - Object { - "age_range": "[20,30)", - "catchphrase": "'fat' 'rat'", - "data": null, - "status": "ONLINE", - "username": "dragarcia", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`don't mutate PostgrestClient.headers 1`] = `null`; - -exports[`embedded filters embedded eq 1`] = ` -Object { - "count": null, - "data": Array [ - Object { - "messages": Array [ - Object { - "channel_id": 1, - "data": null, - "id": 1, - "message": "Hello World 👋", - "username": "supabot", - }, - ], - }, - Object { - "messages": Array [], - }, - Object { - "messages": Array [], - }, - Object { - "messages": Array [], - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`embedded filters embedded or 1`] = ` -Object { - "count": null, - "data": Array [ - Object { - "messages": Array [ - Object { - "channel_id": 1, - "data": null, - "id": 1, - "message": "Hello World 👋", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 2, - "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", - "username": "supabot", - }, - ], - }, - Object { - "messages": Array [], - }, - Object { - "messages": Array [], - }, - Object { - "messages": Array [], - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`embedded filters embedded or with and 1`] = ` -Object { - "count": null, - "data": Array [ - Object { - "messages": Array [ - Object { - "channel_id": 1, - "data": null, - "id": 1, - "message": "Hello World 👋", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 2, - "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", - "username": "supabot", - }, - ], - }, - Object { - "messages": Array [], - }, - Object { - "messages": Array [], - }, - Object { - "messages": Array [], - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`embedded select 1`] = ` -Object { - "count": null, - "data": Array [ - Object { - "messages": Array [ - Object { - "channel_id": 1, - "data": null, - "id": 1, - "message": "Hello World 👋", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 2, - "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", - "username": "supabot", - }, - ], - }, - Object { - "messages": Array [], - }, - Object { - "messages": Array [], - }, - Object { - "messages": Array [], - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`embedded transforms embedded limit 1`] = ` -Object { - "count": null, - "data": Array [ - Object { - "messages": Array [ - Object { - "channel_id": 1, - "data": null, - "id": 1, - "message": "Hello World 👋", - "username": "supabot", - }, - ], - }, - Object { - "messages": Array [], - }, - Object { - "messages": Array [], - }, - Object { - "messages": Array [], - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`embedded transforms embedded order 1`] = ` -Object { - "count": null, - "data": Array [ - Object { - "messages": Array [ - Object { - "channel_id": 2, - "data": null, - "id": 2, - "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", - "username": "supabot", - }, - Object { - "channel_id": 1, - "data": null, - "id": 1, - "message": "Hello World 👋", - "username": "supabot", - }, - ], - }, - Object { - "messages": Array [], - }, - Object { - "messages": Array [], - }, - Object { - "messages": Array [], - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`embedded transforms embedded order on multiple columns 1`] = ` -Object { - "count": null, - "data": Array [ - Object { - "messages": Array [ - Object { - "channel_id": 2, - "data": null, - "id": 2, - "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", - "username": "supabot", - }, - Object { - "channel_id": 1, - "data": null, - "id": 1, - "message": "Hello World 👋", - "username": "supabot", - }, - ], - }, - Object { - "messages": Array [], - }, - Object { - "messages": Array [], - }, - Object { - "messages": Array [], - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`embedded transforms embedded range 1`] = ` -Object { - "count": null, - "data": Array [ - Object { - "messages": Array [ - Object { - "channel_id": 2, - "data": null, - "id": 2, - "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", - "username": "supabot", - }, - ], - }, - Object { - "messages": Array [], - }, - Object { - "messages": Array [], - }, - Object { - "messages": Array [], - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`ignoreDuplicates upsert 1`] = ` -Object { - "count": null, - "data": Array [], - "error": null, - "status": 201, - "statusText": "Created", -} -`; - -exports[`insert, update, delete with count: 'exact' basic delete count: 'exact' 1`] = ` -Object { - "count": 4, - "data": Array [ - Object { - "channel_id": 2, - "data": null, - "id": 6, - "message": "foo", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 3, - "message": "foo", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 7, - "message": "foo", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 8, - "message": "foo", - "username": "supabot", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`insert, update, delete with count: 'exact' basic delete count: 'exact' 2`] = ` -Object { - "count": null, - "data": Array [ - Object { - "channel_id": 1, - "data": null, - "id": 1, - "message": "Hello World 👋", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 2, - "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", - "username": "supabot", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`insert, update, delete with count: 'exact' bulk insert with count: 'exact' 1`] = ` -Object { - "count": 2, - "data": Array [ - Object { - "channel_id": 1, - "data": null, - "id": 7, - "message": "foo", - "username": "supabot", - }, - Object { - "channel_id": 1, - "data": null, - "id": 8, - "message": "foo", - "username": "supabot", - }, - ], - "error": null, - "status": 201, - "statusText": "Created", -} -`; - -exports[`insert, update, delete with count: 'exact' bulk insert with count: 'exact' 2`] = ` -Object { - "count": null, - "data": Array [ - Object { - "channel_id": 1, - "data": null, - "id": 1, - "message": "Hello World 👋", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 2, - "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", - "username": "supabot", - }, - Object { - "channel_id": 1, - "data": null, - "id": 6, - "message": "foo", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 3, - "message": "foo", - "username": "supabot", - }, - Object { - "channel_id": 1, - "data": null, - "id": 7, - "message": "foo", - "username": "supabot", - }, - Object { - "channel_id": 1, - "data": null, - "id": 8, - "message": "foo", - "username": "supabot", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`insert, update, delete with count: 'exact' insert with count: 'exact' 1`] = ` -Object { - "count": 1, - "data": Array [ - Object { - "channel_id": 1, - "data": null, - "id": 6, - "message": "foo", - "username": "supabot", - }, - ], - "error": null, - "status": 201, - "statusText": "Created", -} -`; - -exports[`insert, update, delete with count: 'exact' insert with count: 'exact' 2`] = ` -Object { - "count": null, - "data": Array [ - Object { - "channel_id": 1, - "data": null, - "id": 1, - "message": "Hello World 👋", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 2, - "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", - "username": "supabot", - }, - Object { - "channel_id": 1, - "data": null, - "id": 6, - "message": "foo", - "username": "supabot", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`insert, update, delete with count: 'exact' update with count: 'exact' 1`] = ` -Object { - "count": 4, - "data": Array [ - Object { - "channel_id": 2, - "data": null, - "id": 6, - "message": "foo", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 3, - "message": "foo", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 7, - "message": "foo", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 8, - "message": "foo", - "username": "supabot", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`insert, update, delete with count: 'exact' update with count: 'exact' 2`] = ` -Object { - "count": null, - "data": Array [ - Object { - "channel_id": 1, - "data": null, - "id": 1, - "message": "Hello World 👋", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 2, - "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 6, - "message": "foo", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 3, - "message": "foo", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 7, - "message": "foo", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 8, - "message": "foo", - "username": "supabot", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`insert, update, delete with count: 'exact' upsert with count: 'exact' 1`] = ` -Object { - "count": 1, - "data": Array [ - Object { - "channel_id": 2, - "data": null, - "id": 3, - "message": "foo", - "username": "supabot", - }, - ], - "error": null, - "status": 201, - "statusText": "Created", -} -`; - -exports[`insert, update, delete with count: 'exact' upsert with count: 'exact' 2`] = ` -Object { - "count": null, - "data": Array [ - Object { - "channel_id": 1, - "data": null, - "id": 1, - "message": "Hello World 👋", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 2, - "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", - "username": "supabot", - }, - Object { - "channel_id": 1, - "data": null, - "id": 6, - "message": "foo", - "username": "supabot", - }, - Object { - "channel_id": 2, - "data": null, - "id": 3, - "message": "foo", - "username": "supabot", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`limit 1`] = ` -Object { - "count": null, - "data": Array [ - Object { - "age_range": "[1,2)", - "catchphrase": "'cat' 'fat'", - "data": null, - "status": "ONLINE", - "username": "supabot", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`maybeSingle 1`] = ` -Object { - "count": null, - "data": null, - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`on_conflict insert 1`] = ` -Object { - "count": null, - "data": Array [ - Object { - "age_range": "[20,30)", - "catchphrase": "'fat' 'rat'", - "data": null, - "status": "ONLINE", - "username": "dragarcia", - }, - ], - "error": null, - "status": 201, - "statusText": "Created", -} -`; - -exports[`order 1`] = ` -Object { - "count": null, - "data": Array [ - Object { - "age_range": "[1,2)", - "catchphrase": "'cat' 'fat'", - "data": null, - "status": "ONLINE", - "username": "supabot", - }, - Object { - "age_range": "[25,35)", - "catchphrase": "'bat' 'cat'", - "data": null, - "status": "OFFLINE", - "username": "kiwicopple", - }, - Object { - "age_range": "[20,30)", - "catchphrase": "'fat' 'rat'", - "data": null, - "status": "ONLINE", - "username": "dragarcia", - }, - Object { - "age_range": "[25,35)", - "catchphrase": "'bat' 'rat'", - "data": null, - "status": "ONLINE", - "username": "awailas", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`order on multiple columns 1`] = ` -Object { - "count": null, - "data": Array [ - Object { - "channel_id": 2, - "data": null, - "id": 2, - "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", - "username": "supabot", - }, - Object { - "channel_id": 1, - "data": null, - "id": 1, - "message": "Hello World 👋", - "username": "supabot", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`range 1`] = ` -Object { - "count": null, - "data": Array [ - Object { - "age_range": "[25,35)", - "catchphrase": "'bat' 'cat'", - "data": null, - "status": "OFFLINE", - "username": "kiwicopple", - }, - Object { - "age_range": "[25,35)", - "catchphrase": "'bat' 'rat'", - "data": null, - "status": "ONLINE", - "username": "awailas", - }, - Object { - "age_range": "[20,30)", - "catchphrase": "'fat' 'rat'", - "data": null, - "status": "ONLINE", - "username": "dragarcia", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`rpc 1`] = ` -Object { - "count": null, - "data": "ONLINE", - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`rpc returns void 1`] = ` -Object { - "count": null, - "data": null, - "error": null, - "status": 204, - "statusText": "No Content", -} -`; - -exports[`rpc with count: 'exact' 1`] = ` -Object { - "count": 1, - "data": "ONLINE", - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`rpc with head:true, count:exact 1`] = ` -Object { - "count": 1, - "data": null, - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`select on insert 1`] = ` -Object { - "count": null, - "data": Array [ - Object { - "status": "ONLINE", - }, - ], - "error": null, - "status": 201, - "statusText": "Created", -} -`; - -exports[`select on rpc 1`] = ` -Object { - "count": null, - "data": Array [ - Object { - "status": "ONLINE", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`select with count:exact 1`] = ` -Object { - "count": 4, - "data": Array [ - Object { - "age_range": "[1,2)", - "catchphrase": "'cat' 'fat'", - "data": null, - "status": "ONLINE", - "username": "supabot", - }, - Object { - "age_range": "[25,35)", - "catchphrase": "'bat' 'cat'", - "data": null, - "status": "OFFLINE", - "username": "kiwicopple", - }, - Object { - "age_range": "[25,35)", - "catchphrase": "'bat' 'rat'", - "data": null, - "status": "ONLINE", - "username": "awailas", - }, - Object { - "age_range": "[20,30)", - "catchphrase": "'fat' 'rat'", - "data": null, - "status": "ONLINE", - "username": "dragarcia", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`select with head:true 1`] = ` -Object { - "count": null, - "data": null, - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`select with head:true, count:estimated 1`] = ` -Object { - "count": Any, - "data": null, - "error": null, - "status": 206, - "statusText": "Partial Content", -} -`; - -exports[`select with head:true, count:exact 1`] = ` -Object { - "count": 4, - "data": null, - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`select with head:true, count:planned 1`] = ` -Object { - "count": Any, - "data": null, - "error": null, - "status": 206, - "statusText": "Partial Content", -} -`; - -exports[`single 1`] = ` -Object { - "count": null, - "data": Object { - "age_range": "[1,2)", - "catchphrase": "'cat' 'fat'", - "data": null, - "status": "ONLINE", - "username": "supabot", - }, - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`single on insert 1`] = ` -Object { - "count": null, - "data": Object { - "age_range": null, - "catchphrase": null, - "data": null, - "status": "ONLINE", - "username": "foo", - }, - "error": null, - "status": 201, - "statusText": "Created", -} -`; - -exports[`switch schema 1`] = ` -Object { - "count": null, - "data": Array [ - Object { - "age_range": "[1,2)", - "data": null, - "status": "ONLINE", - "username": "supabot", - }, - Object { - "age_range": "[25,35)", - "data": null, - "status": "OFFLINE", - "username": "kiwicopple", - }, - Object { - "age_range": "[25,35)", - "data": null, - "status": "ONLINE", - "username": "awailas", - }, - Object { - "age_range": "[20,30)", - "data": null, - "status": "ONLINE", - "username": "dragarcia", - }, - Object { - "age_range": "[20,40)", - "data": null, - "status": "ONLINE", - "username": "leroyjenkins", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`; - -exports[`throwOnError throws errors instead of returning them 1`] = ` -Object { - "code": "42P01", - "details": null, - "hint": null, - "message": "relation \\"public.missing_table\\" does not exist", -} -`; diff --git a/test/basic.ts b/test/basic.ts index 82479ce1..44daf354 100644 --- a/test/basic.ts +++ b/test/basic.ts @@ -6,7 +6,58 @@ const postgrest = new PostgrestClient(REST_URL) test('basic select table', async () => { const res = await postgrest.from('users').select() - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "age_range": "[1,2)", + "catchphrase": "'cat' 'fat'", + "data": null, + "status": "ONLINE", + "username": "supabot", + }, + Object { + "age_range": "[25,35)", + "catchphrase": "'bat' 'cat'", + "data": null, + "status": "OFFLINE", + "username": "kiwicopple", + }, + Object { + "age_range": "[25,35)", + "catchphrase": "'bat' 'rat'", + "data": null, + "status": "ONLINE", + "username": "awailas", + }, + Object { + "age_range": "[20,30)", + "catchphrase": "'fat' 'rat'", + "data": null, + "status": "ONLINE", + "username": "dragarcia", + }, + Object { + "age_range": "[20,30)", + "catchphrase": "'json' 'test'", + "data": Object { + "foo": Object { + "bar": Object { + "nested": "value", + }, + "baz": "string value", + }, + }, + "status": "ONLINE", + "username": "jsonuser", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('basic select view', async () => { @@ -31,6 +82,10 @@ test('basic select view', async () => { "non_updatable_column": 1, "username": "dragarcia", }, + Object { + "non_updatable_column": 1, + "username": "jsonuser", + }, ], "error": null, "status": 200, @@ -41,12 +96,28 @@ test('basic select view', async () => { test('rpc', async () => { const res = await postgrest.rpc('get_status', { name_param: 'supabot' }) - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": "ONLINE", + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('rpc returns void', async () => { const res = await postgrest.rpc('void_func') - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": null, + "error": null, + "status": 204, + "statusText": "No Content", + } + `) }) test('custom headers', async () => { @@ -54,6 +125,15 @@ test('custom headers', async () => { expect((postgrest.from('users').select() as any).headers['apikey']).toEqual('foo') }) +test('custom headers on a per-call basis', async () => { + const postgrest1 = new PostgrestClient(REST_URL, { headers: { apikey: 'foo' } }) + const postgrest2 = postgrest1.rpc('void_func').setHeader('apikey', 'bar') + // Original client object isn't affected + expect((postgrest1.from('users').select() as any).headers['apikey']).toEqual('foo') + // Derived client object uses new header value + expect((postgrest2 as any).headers['apikey']).toEqual('bar') +}) + describe('custom prefer headers with ', () => { test('insert', async () => { const postgrest = new PostgrestClient(REST_URL, { @@ -101,7 +181,91 @@ describe('custom prefer headers with ', () => { test('switch schema', async () => { const postgrest = new PostgrestClient(REST_URL, { schema: 'personal' }) const res = await postgrest.from('users').select() - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "age_range": "[1,2)", + "data": null, + "status": "ONLINE", + "username": "supabot", + }, + Object { + "age_range": "[25,35)", + "data": null, + "status": "OFFLINE", + "username": "kiwicopple", + }, + Object { + "age_range": "[25,35)", + "data": null, + "status": "ONLINE", + "username": "awailas", + }, + Object { + "age_range": "[20,30)", + "data": null, + "status": "ONLINE", + "username": "dragarcia", + }, + Object { + "age_range": "[20,40)", + "data": null, + "status": "ONLINE", + "username": "leroyjenkins", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('dynamic schema', async () => { + const postgrest = new PostgrestClient(REST_URL) + const res = await postgrest.schema('personal').from('users').select() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "age_range": "[1,2)", + "data": null, + "status": "ONLINE", + "username": "supabot", + }, + Object { + "age_range": "[25,35)", + "data": null, + "status": "OFFLINE", + "username": "kiwicopple", + }, + Object { + "age_range": "[25,35)", + "data": null, + "status": "ONLINE", + "username": "awailas", + }, + Object { + "age_range": "[20,30)", + "data": null, + "status": "ONLINE", + "username": "dragarcia", + }, + Object { + "age_range": "[20,40)", + "data": null, + "status": "ONLINE", + "username": "leroyjenkins", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('on_conflict insert', async () => { @@ -109,7 +273,23 @@ test('on_conflict insert', async () => { .from('users') .upsert({ username: 'dragarcia' }, { onConflict: 'username' }) .select() - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "age_range": "[20,30)", + "catchphrase": "'fat' 'rat'", + "data": null, + "status": "ONLINE", + "username": "dragarcia", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('ignoreDuplicates upsert', async () => { @@ -117,7 +297,15 @@ test('ignoreDuplicates upsert', async () => { .from('users') .upsert({ username: 'dragarcia' }, { onConflict: 'username', ignoreDuplicates: true }) .select() - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [], + "error": null, + "status": 201, + "statusText": "Created", + } + `) }) describe('basic insert, update, delete', () => { @@ -126,10 +314,70 @@ describe('basic insert, update, delete', () => { .from('messages') .insert({ message: 'foo', username: 'supabot', channel_id: 1 }) .select() - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "channel_id": 1, + "data": null, + "id": 5, + "message": "foo", + "username": "supabot", + }, + ], + "error": null, + "status": 201, + "statusText": "Created", + } + `) res = await postgrest.from('messages').select() - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "channel_id": 1, + "data": null, + "id": 1, + "message": "Hello World 👋", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 2, + "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", + "username": "supabot", + }, + Object { + "channel_id": 3, + "data": null, + "id": 3, + "message": "Some message on channel wihtout details", + "username": "supabot", + }, + Object { + "channel_id": 3, + "data": null, + "id": 4, + "message": "Some message on channel wihtout details", + "username": "supabot", + }, + Object { + "channel_id": 1, + "data": null, + "id": 5, + "message": "foo", + "username": "supabot", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('upsert', async () => { @@ -137,10 +385,70 @@ describe('basic insert, update, delete', () => { .from('messages') .upsert({ id: 3, message: 'foo', username: 'supabot', channel_id: 2 }) .select() - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "channel_id": 2, + "data": null, + "id": 3, + "message": "foo", + "username": "supabot", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) res = await postgrest.from('messages').select() - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "channel_id": 1, + "data": null, + "id": 1, + "message": "Hello World 👋", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 2, + "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", + "username": "supabot", + }, + Object { + "channel_id": 3, + "data": null, + "id": 4, + "message": "Some message on channel wihtout details", + "username": "supabot", + }, + Object { + "channel_id": 1, + "data": null, + "id": 5, + "message": "foo", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 3, + "message": "foo", + "username": "supabot", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('bulk insert', async () => { @@ -151,10 +459,91 @@ describe('basic insert, update, delete', () => { { message: 'foo', username: 'supabot', channel_id: 1 }, ]) .select() - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "channel_id": 1, + "data": null, + "id": 6, + "message": "foo", + "username": "supabot", + }, + Object { + "channel_id": 1, + "data": null, + "id": 7, + "message": "foo", + "username": "supabot", + }, + ], + "error": null, + "status": 201, + "statusText": "Created", + } + `) res = await postgrest.from('messages').select() - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "channel_id": 1, + "data": null, + "id": 1, + "message": "Hello World 👋", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 2, + "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", + "username": "supabot", + }, + Object { + "channel_id": 3, + "data": null, + "id": 4, + "message": "Some message on channel wihtout details", + "username": "supabot", + }, + Object { + "channel_id": 1, + "data": null, + "id": 5, + "message": "foo", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 3, + "message": "foo", + "username": "supabot", + }, + Object { + "channel_id": 1, + "data": null, + "id": 6, + "message": "foo", + "username": "supabot", + }, + Object { + "channel_id": 1, + "data": null, + "id": 7, + "message": "foo", + "username": "supabot", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('basic update', async () => { @@ -163,39 +552,209 @@ describe('basic insert, update, delete', () => { .update({ channel_id: 2 }) .eq('message', 'foo') .select() - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "channel_id": 2, + "data": null, + "id": 5, + "message": "foo", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 3, + "message": "foo", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 6, + "message": "foo", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 7, + "message": "foo", + "username": "supabot", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) res = await postgrest.from('messages').select() - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "channel_id": 1, + "data": null, + "id": 1, + "message": "Hello World 👋", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 2, + "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", + "username": "supabot", + }, + Object { + "channel_id": 3, + "data": null, + "id": 4, + "message": "Some message on channel wihtout details", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 5, + "message": "foo", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 3, + "message": "foo", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 6, + "message": "foo", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 7, + "message": "foo", + "username": "supabot", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('basic delete', async () => { let res = await postgrest.from('messages').delete().eq('message', 'foo').select() - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "channel_id": 2, + "data": null, + "id": 5, + "message": "foo", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 3, + "message": "foo", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 6, + "message": "foo", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 7, + "message": "foo", + "username": "supabot", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) res = await postgrest.from('messages').select() - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "channel_id": 1, + "data": null, + "id": 1, + "message": "Hello World 👋", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 2, + "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", + "username": "supabot", + }, + Object { + "channel_id": 3, + "data": null, + "id": 4, + "message": "Some message on channel wihtout details", + "username": "supabot", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) }) -test('table invalid type', async () => { - // @ts-expect-error table invalid type - postgrest.from(42) -}) - test('throwOnError throws errors instead of returning them', async () => { let isErrorCaught = false try { + // @ts-expect-error: nonexistent table await postgrest.from('missing_table').select().throwOnError() } catch (error) { - expect(error).toMatchSnapshot() + expect(error).toMatchInlineSnapshot( + `[PostgrestError: relation "public.missing_table" does not exist]` + ) isErrorCaught = true } expect(isErrorCaught).toBe(true) }) +test('throwOnError throws errors which include stack', async () => { + try { + // @ts-expect-error: nonexistent table + await postgrest.from('does_not_exist').select().throwOnError() + } catch (err) { + expect(err instanceof Error).toBe(true) + expect((err as Error).stack).not.toBeUndefined() + } +}) + // test('throwOnError setting at the client level - query', async () => { // let isErrorCaught = false // const postgrest_ = new PostgrestClient(REST_URL, { throwOnError: true }) @@ -204,7 +763,7 @@ test('throwOnError throws errors instead of returning them', async () => { // // @ts-expect-error missing table // await postgrest_.from('missing_table').select() // } catch (error) { -// expect(error).toMatchSnapshot() +// expect(error).toMatchInlineSnapshot() // isErrorCaught = true // } @@ -219,7 +778,7 @@ test('throwOnError throws errors instead of returning them', async () => { // // @ts-expect-error missing function // await postgrest_.rpc('missing_fn').select() // } catch (error) { -// expect(error).toMatchSnapshot() +// expect(error).toMatchInlineSnapshot() // isErrorCaught = true // } @@ -232,7 +791,7 @@ test('throwOnError throws errors instead of returning them', async () => { // // @ts-expect-error missing table // const { error } = await postgrest_.from('missing_table').select().throwOnError(false) -// expect(error).toMatchSnapshot() +// expect(error).toMatchInlineSnapshot() // expect(isErrorCaught).toBe(false) // }) @@ -275,22 +834,10 @@ test('maybeSingle w/ throwOnError', async () => { expect(passes).toEqual(true) }) -test('custom type', async () => { - const { data: users, error } = await postgrest.from('users').select().eq('username', 'supabot') - - if (error) { - throw new Error(error.message) - } - - const user = users[0] - // Autocomplete should show properties of user after '.' - user?.username -}) - test("don't mutate PostgrestClient.headers", async () => { await postgrest.from('users').select().limit(1).single() const { error } = await postgrest.from('users').select() - expect(error).toMatchSnapshot() + expect(error).toMatchInlineSnapshot(`null`) }) test('allow ordering on JSON column', async () => { @@ -298,48 +845,190 @@ test('allow ordering on JSON column', async () => { .from('users') .select() .order('data->something' as any) - expect(data).toMatchSnapshot() + expect(data).toMatchInlineSnapshot(` + Array [ + Object { + "age_range": "[1,2)", + "catchphrase": "'cat' 'fat'", + "data": null, + "status": "ONLINE", + "username": "supabot", + }, + Object { + "age_range": "[25,35)", + "catchphrase": "'bat' 'cat'", + "data": null, + "status": "OFFLINE", + "username": "kiwicopple", + }, + Object { + "age_range": "[25,35)", + "catchphrase": "'bat' 'rat'", + "data": null, + "status": "ONLINE", + "username": "awailas", + }, + Object { + "age_range": "[20,30)", + "catchphrase": "'json' 'test'", + "data": Object { + "foo": Object { + "bar": Object { + "nested": "value", + }, + "baz": "string value", + }, + }, + "status": "ONLINE", + "username": "jsonuser", + }, + Object { + "age_range": "[20,30)", + "catchphrase": "'fat' 'rat'", + "data": null, + "status": "ONLINE", + "username": "dragarcia", + }, + ] + `) }) test('Prefer: return=minimal', async () => { const { data } = await postgrest.from('users').insert({ username: 'bar' }) - expect(data).toMatchSnapshot() + expect(data).toMatchInlineSnapshot(`null`) await postgrest.from('users').delete().eq('username', 'bar') }) test('select with head:true', async () => { const res = await postgrest.from('users').select('*', { head: true }) - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": null, + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('select with head:true, count:exact', async () => { const res = await postgrest.from('users').select('*', { head: true, count: 'exact' }) - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": 5, + "data": null, + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('select with head:true, count:planned', async () => { const res = await postgrest.from('users').select('*', { head: true, count: 'planned' }) - expect(res).toMatchSnapshot({ - count: expect.any(Number), - }) + expect(res).toMatchInlineSnapshot( + { + count: expect.any(Number), + }, + ` + Object { + "count": Any, + "data": null, + "error": null, + "status": 206, + "statusText": "Partial Content", + } + ` + ) }) test('select with head:true, count:estimated', async () => { const res = await postgrest.from('users').select('*', { head: true, count: 'estimated' }) - expect(res).toMatchSnapshot({ - count: expect.any(Number), - }) + expect(res).toMatchInlineSnapshot( + { + count: expect.any(Number), + }, + ` + Object { + "count": Any, + "data": null, + "error": null, + "status": 206, + "statusText": "Partial Content", + } + ` + ) }) test('select with count:exact', async () => { const res = await postgrest.from('users').select('*', { count: 'exact' }) - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": 5, + "data": Array [ + Object { + "age_range": "[1,2)", + "catchphrase": "'cat' 'fat'", + "data": null, + "status": "ONLINE", + "username": "supabot", + }, + Object { + "age_range": "[25,35)", + "catchphrase": "'bat' 'cat'", + "data": null, + "status": "OFFLINE", + "username": "kiwicopple", + }, + Object { + "age_range": "[25,35)", + "catchphrase": "'bat' 'rat'", + "data": null, + "status": "ONLINE", + "username": "awailas", + }, + Object { + "age_range": "[20,30)", + "catchphrase": "'json' 'test'", + "data": Object { + "foo": Object { + "bar": Object { + "nested": "value", + }, + "baz": "string value", + }, + }, + "status": "ONLINE", + "username": "jsonuser", + }, + Object { + "age_range": "[20,30)", + "catchphrase": "'fat' 'rat'", + "data": null, + "status": "ONLINE", + "username": "dragarcia", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test("rpc with count: 'exact'", async () => { const res = await postgrest.rpc('get_status', { name_param: 'supabot' }, { count: 'exact' }) - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": 1, + "data": "ONLINE", + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('rpc with head:true, count:exact', async () => { @@ -348,7 +1037,79 @@ test('rpc with head:true, count:exact', async () => { { name_param: 'supabot' }, { head: true, count: 'exact' } ) - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": 1, + "data": null, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('rpc with get:true, count:exact', async () => { + const res = await postgrest.rpc( + 'get_status', + { name_param: 'supabot' }, + { get: true, count: 'exact' } + ) + expect(res).toMatchInlineSnapshot(` + Object { + "count": 1, + "data": "ONLINE", + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('rpc with get:true, optional param', async () => { + const res = await postgrest.rpc( + 'function_with_optional_param', + { param: undefined }, + { get: true } + ) + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": "", + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('rpc with get:true, array param', async () => { + const res = await postgrest.rpc( + 'function_with_array_param', + { param: ['00000000-0000-0000-0000-000000000000'] }, + { get: true } + ) + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": null, + "error": null, + "status": 204, + "statusText": "No Content", + } + `) +}) + +test('rpc with dynamic schema', async () => { + const res = await postgrest.schema('personal').rpc('get_status', { name_param: 'kiwicopple' }) + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": "OFFLINE", + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) describe("insert, update, delete with count: 'exact'", () => { @@ -357,10 +1118,63 @@ describe("insert, update, delete with count: 'exact'", () => { .from('messages') .insert({ message: 'foo', username: 'supabot', channel_id: 1 }, { count: 'exact' }) .select() - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": 1, + "data": Array [ + Object { + "channel_id": 1, + "data": null, + "id": 8, + "message": "foo", + "username": "supabot", + }, + ], + "error": null, + "status": 201, + "statusText": "Created", + } + `) res = await postgrest.from('messages').select() - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "channel_id": 1, + "data": null, + "id": 1, + "message": "Hello World 👋", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 2, + "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", + "username": "supabot", + }, + Object { + "channel_id": 3, + "data": null, + "id": 4, + "message": "Some message on channel wihtout details", + "username": "supabot", + }, + Object { + "channel_id": 1, + "data": null, + "id": 8, + "message": "foo", + "username": "supabot", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test("upsert with count: 'exact'", async () => { @@ -368,10 +1182,70 @@ describe("insert, update, delete with count: 'exact'", () => { .from('messages') .upsert({ id: 3, message: 'foo', username: 'supabot', channel_id: 2 }, { count: 'exact' }) .select() - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": 1, + "data": Array [ + Object { + "channel_id": 2, + "data": null, + "id": 3, + "message": "foo", + "username": "supabot", + }, + ], + "error": null, + "status": 201, + "statusText": "Created", + } + `) res = await postgrest.from('messages').select() - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "channel_id": 1, + "data": null, + "id": 1, + "message": "Hello World 👋", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 2, + "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", + "username": "supabot", + }, + Object { + "channel_id": 3, + "data": null, + "id": 4, + "message": "Some message on channel wihtout details", + "username": "supabot", + }, + Object { + "channel_id": 1, + "data": null, + "id": 8, + "message": "foo", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 3, + "message": "foo", + "username": "supabot", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test("bulk insert with count: 'exact'", async () => { @@ -385,10 +1259,147 @@ describe("insert, update, delete with count: 'exact'", () => { { count: 'exact' } ) .select() - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": 2, + "data": Array [ + Object { + "channel_id": 1, + "data": null, + "id": 9, + "message": "foo", + "username": "supabot", + }, + Object { + "channel_id": 1, + "data": null, + "id": 10, + "message": "foo", + "username": "supabot", + }, + ], + "error": null, + "status": 201, + "statusText": "Created", + } + `) res = await postgrest.from('messages').select() - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "channel_id": 1, + "data": null, + "id": 1, + "message": "Hello World 👋", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 2, + "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", + "username": "supabot", + }, + Object { + "channel_id": 3, + "data": null, + "id": 4, + "message": "Some message on channel wihtout details", + "username": "supabot", + }, + Object { + "channel_id": 1, + "data": null, + "id": 8, + "message": "foo", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 3, + "message": "foo", + "username": "supabot", + }, + Object { + "channel_id": 1, + "data": null, + "id": 9, + "message": "foo", + "username": "supabot", + }, + Object { + "channel_id": 1, + "data": null, + "id": 10, + "message": "foo", + "username": "supabot", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) + }) + + test('bulk insert with column defaults', async () => { + let res = await postgrest + .from('channels') + .insert([{ id: 100 }, { slug: 'test-slug' }], { defaultToNull: false }) + .select() + .rollback() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "data": null, + "id": 100, + "slug": null, + }, + Object { + "data": null, + "id": 5, + "slug": "test-slug", + }, + ], + "error": null, + "status": 201, + "statusText": "Created", + } + `) + }) + + test('bulk upsert with column defaults', async () => { + let res = await postgrest + .from('channels') + .upsert([{ id: 1 }, { slug: 'test-slug' }], { defaultToNull: false }) + .select() + .rollback() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "data": null, + "id": 1, + "slug": null, + }, + Object { + "data": null, + "id": 7, + "slug": "test-slug", + }, + ], + "error": null, + "status": 201, + "statusText": "Created", + } + `) }) test("update with count: 'exact'", async () => { @@ -397,10 +1408,105 @@ describe("insert, update, delete with count: 'exact'", () => { .update({ channel_id: 2 }, { count: 'exact' }) .eq('message', 'foo') .select() - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": 4, + "data": Array [ + Object { + "channel_id": 2, + "data": null, + "id": 8, + "message": "foo", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 3, + "message": "foo", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 9, + "message": "foo", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 10, + "message": "foo", + "username": "supabot", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) res = await postgrest.from('messages').select() - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "channel_id": 1, + "data": null, + "id": 1, + "message": "Hello World 👋", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 2, + "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", + "username": "supabot", + }, + Object { + "channel_id": 3, + "data": null, + "id": 4, + "message": "Some message on channel wihtout details", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 8, + "message": "foo", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 3, + "message": "foo", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 9, + "message": "foo", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 10, + "message": "foo", + "username": "supabot", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test("basic delete count: 'exact'", async () => { @@ -409,10 +1515,77 @@ describe("insert, update, delete with count: 'exact'", () => { .delete({ count: 'exact' }) .eq('message', 'foo') .select() - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": 4, + "data": Array [ + Object { + "channel_id": 2, + "data": null, + "id": 8, + "message": "foo", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 3, + "message": "foo", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 9, + "message": "foo", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 10, + "message": "foo", + "username": "supabot", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) res = await postgrest.from('messages').select() - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "channel_id": 1, + "data": null, + "id": 1, + "message": "Hello World 👋", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 2, + "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", + "username": "supabot", + }, + Object { + "channel_id": 3, + "data": null, + "id": 4, + "message": "Some message on channel wihtout details", + "username": "supabot", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) }) @@ -441,12 +1614,267 @@ test('select with no match', async () => { `) }) -test('cannot update non-updatable views', () => { - // @ts-expect-error TS2345 - postgrest.from('non_updatable_view').update({}) +test('update with no match - return=minimal', async () => { + const res = await postgrest.from('users').update({ data: '' }).eq('username', 'missing') + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": null, + "error": null, + "status": 204, + "statusText": "No Content", + } + `) +}) + +test('update with no match - return=representation', async () => { + const res = await postgrest.from('users').update({ data: '' }).eq('username', 'missing').select() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [], + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('!left join on one to one relation', async () => { + const res = await postgrest.from('channel_details').select('channels!left(id)').limit(1).single() + expect(Array.isArray(res.data?.channels)).toBe(false) + // TODO: This should not be nullable + expect(res.data?.channels?.id).not.toBeNull() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "channels": Object { + "id": 1, + }, + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('!left join on one to many relation', async () => { + const res = await postgrest.from('users').select('messages!left(username)').limit(1).single() + expect(Array.isArray(res.data?.messages)).toBe(true) + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "messages": Array [ + Object { + "username": "supabot", + }, + Object { + "username": "supabot", + }, + Object { + "username": "supabot", + }, + ], + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('!left join on one to 0-1 non-empty relation', async () => { + const res = await postgrest + .from('users') + .select('user_profiles!left(username)') + .eq('username', 'supabot') + .limit(1) + .single() + expect(Array.isArray(res.data?.user_profiles)).toBe(true) + expect(res.data?.user_profiles[0].username).not.toBeNull() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "user_profiles": Array [ + Object { + "username": "supabot", + }, + ], + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('!left join on zero to one with null relation', async () => { + const res = await postgrest + .from('user_profiles') + .select('*,users!left(*)') + .eq('id', 2) + .limit(1) + .single() + expect(Array.isArray(res.data?.users)).toBe(false) + expect(res.data?.users).toBeNull() + + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "id": 2, + "username": null, + "users": null, + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) -test('cannot update non-updatable columns', () => { - // @ts-expect-error TS2322 - postgrest.from('updatable_view').update({ non_updatable_column: 0 }) +test('!left join on zero to one with valid relation', async () => { + const res = await postgrest + .from('user_profiles') + .select('*,users!left(status)') + .eq('id', 1) + .limit(1) + .single() + expect(Array.isArray(res.data?.users)).toBe(false) + // TODO: This should be nullable indeed + expect(res.data?.users?.status).not.toBeNull() + + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "id": 1, + "username": "supabot", + "users": Object { + "status": "ONLINE", + }, + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('!left join on zero to one empty relation', async () => { + const res = await postgrest + .from('users') + .select('user_profiles!left(username)') + .eq('username', 'dragarcia') + .limit(1) + .single() + expect(Array.isArray(res.data?.user_profiles)).toBe(true) + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "user_profiles": Array [], + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('join on 1-M relation', async () => { + // TODO: This won't raise the proper types for "first_friend_of,..." results + const res = await postgrest + .from('users') + .select( + `first_friend_of:best_friends_first_user_fkey(*), + second_friend_of:best_friends_second_user_fkey(*), + third_wheel_of:best_friends_third_wheel_fkey(*)` + ) + .eq('username', 'supabot') + .limit(1) + .single() + expect(Array.isArray(res.data?.first_friend_of)).toBe(true) + expect(Array.isArray(res.data?.second_friend_of)).toBe(true) + expect(Array.isArray(res.data?.third_wheel_of)).toBe(true) + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "first_friend_of": Array [ + Object { + "first_user": "supabot", + "id": 1, + "second_user": "kiwicopple", + "third_wheel": "awailas", + }, + Object { + "first_user": "supabot", + "id": 2, + "second_user": "awailas", + "third_wheel": null, + }, + ], + "second_friend_of": Array [], + "third_wheel_of": Array [], + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('join on 1-1 relation with nullables', async () => { + const res = await postgrest + .from('best_friends') + .select( + 'first_user:users!best_friends_first_user_fkey(*), second_user:users!best_friends_second_user_fkey(*), third_wheel:users!best_friends_third_wheel_fkey(*)' + ) + .order('id') + .limit(1) + .single() + expect(Array.isArray(res.data?.first_user)).toBe(false) + expect(Array.isArray(res.data?.second_user)).toBe(false) + expect(Array.isArray(res.data?.third_wheel)).toBe(false) + // TODO: This should return null only if the column is actually nullable thoses are not + expect(res.data?.first_user?.username).not.toBeNull() + expect(res.data?.second_user?.username).not.toBeNull() + // TODO: This column however is nullable + expect(res.data?.third_wheel?.username).not.toBeNull() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "first_user": Object { + "age_range": "[1,2)", + "catchphrase": "'cat' 'fat'", + "data": null, + "status": "ONLINE", + "username": "supabot", + }, + "second_user": Object { + "age_range": "[25,35)", + "catchphrase": "'bat' 'cat'", + "data": null, + "status": "OFFLINE", + "username": "kiwicopple", + }, + "third_wheel": Object { + "age_range": "[25,35)", + "catchphrase": "'bat' 'rat'", + "data": null, + "status": "ONLINE", + "username": "awailas", + }, + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) diff --git a/test/db/00-schema.sql b/test/db/00-schema.sql index 776b8c94..c06ed0b7 100644 --- a/test/db/00-schema.sql +++ b/test/db/00-schema.sql @@ -16,6 +16,24 @@ CREATE TABLE public.users ( ALTER TABLE public.users REPLICA IDENTITY FULL; -- Send "previous data" to supabase COMMENT ON COLUMN public.users.data IS 'For unstructured data and prototyping.'; + +-- CREATE A ZERO-TO-ONE RELATIONSHIP (User can have profile, but not all of them do) +CREATE TABLE public.user_profiles ( + id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + username text REFERENCES users +); + +-- CREATE A TABLE WITH TWO RELATIONS TO SAME DESTINATION WHICH WILL NEED HINTING +CREATE TABLE public.best_friends ( + id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + -- Thoses relations should always be satisfied, never be null + first_user text REFERENCES users NOT NULL, + second_user text REFERENCES users NOT NULL, + -- This relation is nullable, it might be null + third_wheel text REFERENCES users +); + + -- CHANNELS CREATE TABLE public.channels ( id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, @@ -25,6 +43,11 @@ CREATE TABLE public.channels ( ALTER TABLE public.users REPLICA IDENTITY FULL; -- Send "previous data" to supabase COMMENT ON COLUMN public.channels.data IS 'For unstructured data and prototyping.'; +create table public.channel_details ( + id bigint primary key references channels(id), + details text default null +); + -- MESSAGES CREATE TABLE public.messages ( id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, @@ -36,6 +59,20 @@ CREATE TABLE public.messages ( ALTER TABLE public.messages REPLICA IDENTITY FULL; -- Send "previous data" to supabase COMMENT ON COLUMN public.messages.data IS 'For unstructured data and prototyping.'; +-- SELF REFERENCING TABLE +CREATE TABLE public.collections ( + id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + description text, + parent_id bigint +); +ALTER TABLE public.messages REPLICA IDENTITY FULL; -- Send "previous data" to supabase +-- SELF REFERENCE via parent_id +ALTER TABLE public.collections +ADD CONSTRAINT collections_parent_id_fkey +FOREIGN KEY (parent_id) +REFERENCES public.collections(id); +COMMENT ON COLUMN public.messages.data IS 'For unstructured data and prototyping.'; + -- STORED FUNCTION CREATE FUNCTION public.get_status(name_param text) RETURNS user_status AS $$ @@ -86,3 +123,11 @@ CREATE FUNCTION personal.get_status(name_param text) RETURNS user_status AS $$ SELECT status from users WHERE username=name_param; $$ LANGUAGE SQL IMMUTABLE; + +create function public.function_with_optional_param(param text default '') +returns text as $$ + select param; +$$ language sql immutable; + +create function public.function_with_array_param(param uuid[]) +returns void as '' language sql immutable; diff --git a/test/db/01-dummy-data.sql b/test/db/01-dummy-data.sql index d425163a..dc73ecba 100644 --- a/test/db/01-dummy-data.sql +++ b/test/db/01-dummy-data.sql @@ -1,22 +1,26 @@ INSERT INTO - public.users (username, status, age_range, catchphrase) + public.users (username, status, age_range, catchphrase, data) VALUES - ('supabot', 'ONLINE', '[1,2)'::int4range, 'fat cat'::tsvector), - ('kiwicopple', 'OFFLINE', '[25,35)'::int4range, 'cat bat'::tsvector), - ('awailas', 'ONLINE', '[25,35)'::int4range, 'bat rat'::tsvector), - ('dragarcia', 'ONLINE', '[20,30)'::int4range, 'rat fat'::tsvector); + ('supabot', 'ONLINE', '[1,2)'::int4range, 'fat cat'::tsvector, NULL), + ('kiwicopple', 'OFFLINE', '[25,35)'::int4range, 'cat bat'::tsvector, NUlL), + ('awailas', 'ONLINE', '[25,35)'::int4range, 'bat rat'::tsvector, NULL), + ('dragarcia', 'ONLINE', '[20,30)'::int4range, 'rat fat'::tsvector, NULL), + ('jsonuser', 'ONLINE', '[20,30)'::int4range, 'json test'::tsvector, '{"foo": {"bar": {"nested": "value"}, "baz": "string value"}}'::jsonb); INSERT INTO public.channels (slug) VALUES ('public'), - ('random'); + ('random'), + ('other'); INSERT INTO public.messages (message, channel_id, username) VALUES ('Hello World 👋', 1, 'supabot'), - ('Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.', 2, 'supabot'); + ('Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.', 2, 'supabot'), + ('Some message on channel wihtout details', 3, 'supabot'), + ('Some message on channel wihtout details', 3, 'supabot'); INSERT INTO personal.users (username, status, age_range) @@ -30,3 +34,27 @@ VALUES INSERT INTO shops(id, address, shop_geom) VALUES (1, '1369 Cambridge St', 'SRID=4326;POINT(-71.10044 42.373695)'); + +INSERT INTO public.channel_details (id, details) +VALUES + (1, 'Details for public channel'), + (2, 'Details for random channel'); + +INSERT INTO user_profiles (id, username) +VALUES + (1, 'supabot'), + (2, NULL); + +INSERT INTO best_friends(id, first_user, second_user, third_wheel) +VALUES + (1, 'supabot', 'kiwicopple', 'awailas'), + (2, 'supabot', 'awailas', NULL); + +INSERT INTO public.collections (id, description, parent_id) +VALUES + (1, 'Root Collection', NULL), + (2, 'Child of Root', 1), + (3, 'Another Child of Root', 1), + (4, 'Grandchild', 2), + (5, 'Sibling of Grandchild', 2), + (6, 'Child of Another Root', 3); diff --git a/test/db/docker-compose.yml b/test/db/docker-compose.yml index 6cfd933b..ac2f5e1c 100644 --- a/test/db/docker-compose.yml +++ b/test/db/docker-compose.yml @@ -3,7 +3,7 @@ version: '3' services: rest: - image: postgrest/postgrest:v9.0.1.20220802 + image: postgrest/postgrest:v12.2.0 ports: - '3000:3000' environment: @@ -13,10 +13,11 @@ services: PGRST_DB_ANON_ROLE: postgres PGRST_DB_PLAN_ENABLED: 1 PGRST_DB_TX_END: commit-allow-override + PGRST_DB_AGGREGATES_ENABLED: true depends_on: - db db: - image: supabase/postgres:14.1.0.34 + image: supabase/postgres:15.1.0.37 ports: - '5432:5432' volumes: @@ -25,4 +26,5 @@ services: POSTGRES_DB: postgres POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres + POSTGRES_HOST: /var/run/postgresql POSTGRES_PORT: 5432 diff --git a/test/filters.ts b/test/filters.ts index 5ec35b86..8348f0a4 100644 --- a/test/filters.ts +++ b/test/filters.ts @@ -18,6 +18,9 @@ test('not', async () => { Object { "status": "ONLINE", }, + Object { + "status": "ONLINE", + }, ], "error": null, "status": 200, @@ -80,6 +83,9 @@ test('neq', async () => { Object { "username": "awailas", }, + Object { + "username": "jsonuser", + }, Object { "username": "dragarcia", }, @@ -100,6 +106,9 @@ test('gt', async () => { Object { "id": 2, }, + Object { + "id": 4, + }, ], "error": null, "status": 200, @@ -120,6 +129,9 @@ test('gte', async () => { Object { "id": 2, }, + Object { + "id": 4, + }, ], "error": null, "status": 200, @@ -182,6 +194,49 @@ test('like', async () => { `) }) +test('likeAllOf', async () => { + const res = await postgrest + .from('users') + .select('username') + .likeAllOf('username', ['%supa%', '%bot%']) + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "username": "supabot", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('likeAnyOf', async () => { + const res = await postgrest + .from('users') + .select('username') + .likeAnyOf('username', ['%supa%', '%kiwi%']) + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "username": "supabot", + }, + Object { + "username": "kiwicopple", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + test('ilike', async () => { const res = await postgrest.from('users').select('username').ilike('username', '%SUPA%') expect(res).toMatchInlineSnapshot(` @@ -199,6 +254,49 @@ test('ilike', async () => { `) }) +test('ilikeAllOf', async () => { + const res = await postgrest + .from('users') + .select('username') + .ilikeAllOf('username', ['%SUPA%', '%bot%']) + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "username": "supabot", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('ilikeAnyOf', async () => { + const res = await postgrest + .from('users') + .select('username') + .ilikeAnyOf('username', ['%supa%', '%KIWI%']) + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "username": "supabot", + }, + Object { + "username": "kiwicopple", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + test('is', async () => { const res = await postgrest.from('users').select('data').is('data', null) expect(res).toMatchInlineSnapshot(` @@ -226,7 +324,8 @@ test('is', async () => { }) test('in', async () => { - const res = await postgrest.from('users').select('status').in('status', ['ONLINE', 'OFFLINE']) + const statuses = ['ONLINE', 'OFFLINE'] as const + const res = await postgrest.from('users').select('status').in('status', statuses) expect(res).toMatchInlineSnapshot(` Object { "count": null, @@ -243,6 +342,9 @@ test('in', async () => { Object { "status": "ONLINE", }, + Object { + "status": "ONLINE", + }, ], "error": null, "status": 200, @@ -337,6 +439,9 @@ test('rangeGte', async () => { Object { "age_range": "[20,30)", }, + Object { + "age_range": "[20,30)", + }, ], "error": null, "status": 200, @@ -394,6 +499,9 @@ test('overlaps', async () => { Object { "age_range": "[20,30)", }, + Object { + "age_range": "[20,30)", + }, ], "error": null, "status": 200, diff --git a/test/index.test-d.ts b/test/index.test-d.ts new file mode 100644 index 00000000..516529e9 --- /dev/null +++ b/test/index.test-d.ts @@ -0,0 +1,122 @@ +import { expectError, expectType } from 'tsd' +import { PostgrestClient } from '../src/index' +import { Prettify } from '../src/types' +import { Database, Json } from './types' + +const REST_URL = 'http://localhost:3000' +const postgrest = new PostgrestClient(REST_URL) + +// table invalid type +{ + expectError(postgrest.from(42)) + expectError(postgrest.from('nonexistent_table')) +} + +// `null` can't be used with `.eq()` +{ + postgrest.from('users').select().eq('username', 'foo') + expectError(postgrest.from('users').select().eq('username', null)) + + const nullableVar = 'foo' as string | null + expectError(postgrest.from('users').select().eq('username', nullableVar)) +} + +// can override result type +{ + const { data, error } = await postgrest + .from('users') + .select('*, messages(*)') + .returns<{ messages: { foo: 'bar' }[] }[]>() + if (error) { + throw new Error(error.message) + } + expectType<{ foo: 'bar' }[]>(data[0].messages) +} +{ + const { data, error } = await postgrest + .from('users') + .insert({ username: 'foo' }) + .select('*, messages(*)') + .returns<{ messages: { foo: 'bar' }[] }[]>() + if (error) { + throw new Error(error.message) + } + expectType<{ foo: 'bar' }[]>(data[0].messages) +} + +// cannot update non-updatable views +{ + expectError(postgrest.from('updatable_view').update({ non_updatable_column: 0 })) +} + +// cannot update non-updatable columns +{ + expectError(postgrest.from('updatable_view').update({ non_updatable_column: 0 })) +} + +// spread resource with single column in select query +{ + const { data, error } = await postgrest + .from('messages') + .select('message, ...users(status)') + .single() + if (error) { + throw new Error(error.message) + } + expectType<{ message: string | null; status: Database['public']['Enums']['user_status'] | null }>( + data + ) +} + +// spread resource with all columns in select query +{ + const { data, error } = await postgrest.from('messages').select('message, ...users(*)').single() + if (error) { + throw new Error(error.message) + } + expectType>( + data + ) +} + +// `count` in embedded resource +{ + const { data, error } = await postgrest.from('messages').select('message, users(count)').single() + if (error) { + throw new Error(error.message) + } + expectType<{ message: string | null; users: { count: number } }>(data) +} + +// json accessor in select query +{ + const { data, error } = await postgrest + .from('users') + .select('data->foo->bar, data->foo->>baz') + .single() + if (error) { + throw new Error(error.message) + } + // getting this w/o the cast, not sure why: + // Parameter type Json is declared too wide for argument type Json + expectType(data.bar as Json) + expectType(data.baz) +} + +// rpc return type +{ + const { data, error } = await postgrest.rpc('get_status') + if (error) { + throw new Error(error.message) + } + expectType<'ONLINE' | 'OFFLINE'>(data) +} + +// PostgrestBuilder's children retains class when using inherited methods +{ + const x = postgrest.from('channels').select() + const y = x.throwOnError() + const z = x.setHeader('', '') + expectType(y) + expectType(z) +} diff --git a/test/index.test.ts b/test/index.test.ts index ad4e4ee7..a7f2ffc6 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -1,4 +1,6 @@ import './basic' +import './relationships' import './filters' import './resource-embedding' import './transforms' +import './rpc' diff --git a/test/relationships.ts b/test/relationships.ts new file mode 100644 index 00000000..2660b585 --- /dev/null +++ b/test/relationships.ts @@ -0,0 +1,1833 @@ +import { PostgrestClient } from '../src/index' +import { Database } from './types' + +const REST_URL = 'http://localhost:3000' +export const postgrest = new PostgrestClient(REST_URL) + +const userColumn: 'catchphrase' | 'username' = 'username' + +export const selectParams = { + manyToOne: { from: 'messages', select: 'user:users(*)' }, + inner: { from: 'messages', select: 'channels!inner(*, channel_details!inner(*))' }, + oneToMany: { from: 'users', select: 'messages(*)' }, + oneToManySelective: { from: 'users', select: 'messages(data)' }, + oneToOne: { from: 'channels', select: 'channel_details(*)' }, + leftOneToOne: { from: 'channel_details', select: 'channels!left(*)' }, + leftOneToMany: { from: 'users', select: 'messages!left(*)' }, + leftZeroToOne: { from: 'user_profiles', select: 'users!left(*)' }, + leftOneToOneUsers: { from: 'users', select: 'user_profiles!left(username)' }, + oneToOneUsersColumnName: { from: 'users', select: 'user_profiles(username)' }, + leftZeroToOneUserProfiles: { from: 'user_profiles', select: '*,users!left(*)' }, + leftZeroToOneUserProfilesWithNullables: { from: 'user_profiles', select: '*,users!left(status)' }, + joinOneToOne: { from: 'channel_details', select: 'channels!left(id)' }, + joinOneToMany: { from: 'users', select: 'messages!left(username)' }, + joinZeroToOne: { from: 'user_profiles', select: 'users!left(status)' }, + joinOneToOneWithFkHint: { + from: 'best_friends', + select: + 'first_user:users!best_friends_first_user_fkey(*), second_user:users!best_friends_second_user_fkey(*), third_wheel:users!best_friends_third_wheel_fkey(*)', + }, + joinOneToManyWithFkHint: { + from: 'users', + select: `first_friend_of:best_friends!best_friends_first_user_fkey(*), + second_friend_of:best_friends!best_friends_second_user_fkey(*), + third_wheel_of:best_friends!best_friends_third_wheel_fkey(*)`, + }, + joinOneToManyUsersWithFkHint: { + from: 'users', + select: `first_friend_of:best_friends_first_user_fkey(*), + second_friend_of:best_friends_second_user_fkey(*), + third_wheel_of:best_friends_third_wheel_fkey(*)`, + }, + joinOneToManyUsersWithFkHintSelective: { + from: 'users', + select: `first_friend_of:best_friends_first_user_fkey(id), + second_friend_of:best_friends_second_user_fkey(*), + third_wheel_of:best_friends_third_wheel_fkey(*)`, + }, + joinOneToOneWithNullablesFkHint: { + from: 'best_friends', + select: + 'first_user:users!best_friends_first_user_fkey(*), second_user:users!best_friends_second_user_fkey(*), third_wheel:users!best_friends_third_wheel_fkey(*)', + }, + joinOneToOneWithNullablesNoHint: { + from: 'best_friends', + select: 'first_user:users(*), second_user:users(*), third_wheel:users(*)', + }, + joinOneToOneWithNullablesColumnHint: { + from: 'best_friends', + select: + 'first_user:users!first_user(*), second_user:users!second_user(*), third_wheel:users!third_wheel(*)', + }, + joinOneToManyWithNullablesNoHint: { + from: 'users', + select: + 'first_friend_of:best_friends(*), second_friend_of:best_friends(*), third_wheel_of:best_friends(*)', + }, + joinOneToManyWithNullablesColumnHint: { + from: 'users', + select: + 'first_friend_of:best_friends!first_user(*), second_friend_of:best_friends!second_user(*), third_wheel_of:best_friends!third_wheel(*)', + }, + joinOneToManyWithNullablesColumnHintOnNestedRelation: { + from: 'users', + select: + 'first_friend_of:best_friends!first_user(*, first_user:users!first_user(*)), second_friend_of:best_friends!second_user(*), third_wheel_of:best_friends!third_wheel(*)', + }, + joinOneToManyWithNullablesNoHintOnNestedRelation: { + from: 'users', + select: + 'first_friend_of:best_friends!first_user(*, first_user:users(*)), second_friend_of:best_friends!second_user(*), third_wheel_of:best_friends!third_wheel(*)', + }, + joinSelectViaColumn: { from: 'user_profiles', select: 'username(*)' }, + joinSelectViaColumnSelective: { from: 'user_profiles', select: 'username(status)' }, + joinSelectViaColumnAndAlias: { from: 'user_profiles', select: 'user:username(*)' }, + joinSelectViaUniqueTableRelationship: { from: 'user_profiles', select: 'users(*)' }, + joinSelectViaColumnHint: { from: 'best_friends', select: 'users!first_user(*)' }, + joinSelectViaColumnHintTwice: { + from: 'best_friends', + select: 'users!first_user(*), users!second_user(*)', + }, + typeCastingQuery: { from: 'best_friends', select: 'id::text' }, + joinSelectViaViewNameRelationship: { from: 'user_profiles', select: 'updatable_view(*)' }, + queryWithMultipleOneToManySelectives: { + from: 'users', + select: 'username, messages(id), user_profiles(id)', + }, + nestedQueryWithMultipleLevelsAndSelectiveFields: { + from: 'users', + select: 'username, messages(id, message, channels(id, slug))', + }, + nestedQueryWithSelectiveFields: { from: 'users', select: 'username, messages(id, message)' }, + selectionWithStringTemplating: { from: 'users', select: `status, ${userColumn}` }, + selectWithAggregateCountFunction: { from: 'users', select: 'username, messages(count)' }, + selectWithAggregateCountOnAColumnFunction: { + from: 'users', + select: 'username, messages(id.count())', + }, + selectWithAggregateSumFunctionWithoutColumn: { from: 'users', select: 'username, messages(sum)' }, + selectWithAggregateCountFunctionAndAlias: { + from: 'users', + select: 'username, messages(message_count:count())', + }, + selectWithAggregateNestedCountFunction: { + from: 'users', + select: 'username, messages(channels(count))', + }, + selectWithAggregateNestedCountFunctionAndAlias: { + from: 'users', + select: 'username, messages(channels(channel_count:count()))', + }, + selectWithAggregateCountAndSpread: { + from: 'users', + select: 'username, messages(channels(count(), ...channel_details(details)))', + }, + selectWithAggregateSumFunction: { from: 'users', select: 'username, messages(id.sum())' }, + selectWithAggregateAliasedSumFunction: { + from: 'users', + select: 'username, messages(sum_id:id.sum())', + }, + selectWithAggregateSumFunctionOnNestedRelation: { + from: 'users', + select: 'username, messages(channels(id.sum()))', + }, + selectWithAggregateSumAndSpread: { + from: 'users', + select: 'username, messages(channels(id.sum(), ...channel_details(details)))', + }, + selectWithAggregateSumAndSpreadOnNestedRelation: { + from: 'users', + select: + 'username, messages(channels(id.sum(), ...channel_details(details_sum:id.sum(), details)))', + }, + selectWithSpreadOnNestedRelation: { + from: 'messages', + select: 'id, channels(id, ...channel_details(details_id:id, details))', + }, + selectSpreadOnManyRelation: { + from: 'channels', + select: 'id, ...messages(id, message)', + }, + selectWithDuplicatesFields: { + from: 'channels', + select: 'id, id, id', + }, + selectEmbedRessourceWithNoFields: { + from: 'messages', + select: 'message, users()', + }, + selectJsonAccessor: { + from: 'users', + select: 'data->foo->bar, data->foo->>baz', + }, + typecastingAndAggregate: { + from: 'messages', + select: + 'message, users.count(), casted_message:message::int4, casted_count:users.count()::text', + }, + innerJoinOnManyRelation: { + from: 'channels', + select: 'id, messages!channel_id!inner(id, username)', + }, + selfReferenceRelation: { + from: 'collections', + select: '*, collections(*)', + }, + selfReferenceRelationViaColumn: { + from: 'collections', + select: '*, parent_id(*)', + }, + aggregateOnMissingColumnWithAlias: { + from: 'users', + select: 'alias:missing_column.count()', + }, +} as const + +export const selectQueries = { + manyToOne: postgrest.from(selectParams.manyToOne.from).select(selectParams.manyToOne.select), + inner: postgrest.from(selectParams.inner.from).select(selectParams.inner.select), + oneToMany: postgrest.from(selectParams.oneToMany.from).select(selectParams.oneToMany.select), + oneToManySelective: postgrest + .from(selectParams.oneToManySelective.from) + .select(selectParams.oneToManySelective.select), + oneToOne: postgrest.from(selectParams.oneToOne.from).select(selectParams.oneToOne.select), + leftOneToOne: postgrest + .from(selectParams.leftOneToOne.from) + .select(selectParams.leftOneToOne.select), + leftOneToMany: postgrest + .from(selectParams.leftOneToMany.from) + .select(selectParams.leftOneToMany.select), + leftZeroToOne: postgrest + .from(selectParams.leftZeroToOne.from) + .select(selectParams.leftZeroToOne.select), + leftOneToOneUsers: postgrest + .from(selectParams.leftOneToOneUsers.from) + .select(selectParams.leftOneToOneUsers.select), + oneToOneUsersColumnName: postgrest + .from(selectParams.oneToOneUsersColumnName.from) + .select(selectParams.oneToOneUsersColumnName.select), + leftZeroToOneUserProfiles: postgrest + .from(selectParams.leftZeroToOneUserProfiles.from) + .select(selectParams.leftZeroToOneUserProfiles.select), + leftZeroToOneUserProfilesWithNullables: postgrest + .from(selectParams.leftZeroToOneUserProfilesWithNullables.from) + .select(selectParams.leftZeroToOneUserProfilesWithNullables.select), + joinOneToOne: postgrest + .from(selectParams.joinOneToOne.from) + .select(selectParams.joinOneToOne.select), + joinOneToMany: postgrest + .from(selectParams.joinOneToMany.from) + .select(selectParams.joinOneToMany.select), + joinZeroToOne: postgrest + .from(selectParams.joinZeroToOne.from) + .select(selectParams.joinZeroToOne.select), + joinOneToOneWithFkHint: postgrest + .from(selectParams.joinOneToOneWithFkHint.from) + .select(selectParams.joinOneToOneWithFkHint.select), + joinOneToManyWithFkHint: postgrest + .from(selectParams.joinOneToManyWithFkHint.from) + .select(selectParams.joinOneToManyWithFkHint.select), + joinOneToManyUsersWithFkHint: postgrest + .from(selectParams.joinOneToManyUsersWithFkHint.from) + .select(selectParams.joinOneToManyUsersWithFkHint.select), + joinOneToManyUsersWithFkHintSelective: postgrest + .from(selectParams.joinOneToManyUsersWithFkHintSelective.from) + .select(selectParams.joinOneToManyUsersWithFkHintSelective.select), + joinOneToOneWithNullablesFkHint: postgrest + .from(selectParams.joinOneToOneWithNullablesFkHint.from) + .select(selectParams.joinOneToOneWithNullablesFkHint.select), + joinOneToOneWithNullablesNoHint: postgrest + .from(selectParams.joinOneToOneWithNullablesNoHint.from) + .select(selectParams.joinOneToOneWithNullablesNoHint.select), + joinOneToOneWithNullablesColumnHint: postgrest + .from(selectParams.joinOneToOneWithNullablesColumnHint.from) + .select(selectParams.joinOneToOneWithNullablesColumnHint.select), + joinOneToManyWithNullablesNoHint: postgrest + .from(selectParams.joinOneToManyWithNullablesNoHint.from) + .select(selectParams.joinOneToManyWithNullablesNoHint.select), + joinOneToManyWithNullablesColumnHint: postgrest + .from(selectParams.joinOneToManyWithNullablesColumnHint.from) + .select(selectParams.joinOneToManyWithNullablesColumnHint.select), + joinOneToManyWithNullablesColumnHintOnNestedRelation: postgrest + .from(selectParams.joinOneToManyWithNullablesColumnHintOnNestedRelation.from) + .select(selectParams.joinOneToManyWithNullablesColumnHintOnNestedRelation.select), + joinOneToManyWithNullablesNoHintOnNestedRelation: postgrest + .from(selectParams.joinOneToManyWithNullablesNoHintOnNestedRelation.from) + .select(selectParams.joinOneToManyWithNullablesNoHintOnNestedRelation.select), + joinSelectViaColumn: postgrest + .from(selectParams.joinSelectViaColumn.from) + .select(selectParams.joinSelectViaColumn.select), + joinSelectViaColumnSelective: postgrest + .from(selectParams.joinSelectViaColumnSelective.from) + .select(selectParams.joinSelectViaColumnSelective.select), + joinSelectViaColumnAndAlias: postgrest + .from(selectParams.joinSelectViaColumnAndAlias.from) + .select(selectParams.joinSelectViaColumnAndAlias.select), + joinSelectViaUniqueTableRelationship: postgrest + .from(selectParams.joinSelectViaUniqueTableRelationship.from) + .select(selectParams.joinSelectViaUniqueTableRelationship.select), + joinSelectViaColumnHint: postgrest + .from(selectParams.joinSelectViaColumnHint.from) + .select(selectParams.joinSelectViaColumnHint.select), + joinSelectViaColumnHintTwice: postgrest + .from(selectParams.joinSelectViaColumnHintTwice.from) + .select(selectParams.joinSelectViaColumnHintTwice.select), + typeCastingQuery: postgrest + .from(selectParams.typeCastingQuery.from) + .select(selectParams.typeCastingQuery.select), + joinSelectViaViewNameRelationship: postgrest + .from(selectParams.joinSelectViaViewNameRelationship.from) + .select(selectParams.joinSelectViaViewNameRelationship.select), + queryWithMultipleOneToManySelectives: postgrest + .from(selectParams.queryWithMultipleOneToManySelectives.from) + .select(selectParams.queryWithMultipleOneToManySelectives.select), + nestedQueryWithMultipleLevelsAndSelectiveFields: postgrest + .from(selectParams.nestedQueryWithMultipleLevelsAndSelectiveFields.from) + .select(selectParams.nestedQueryWithMultipleLevelsAndSelectiveFields.select), + nestedQueryWithSelectiveFields: postgrest + .from(selectParams.nestedQueryWithSelectiveFields.from) + .select(selectParams.nestedQueryWithSelectiveFields.select), + selectionWithStringTemplating: postgrest + .from(selectParams.selectionWithStringTemplating.from) + .select(selectParams.selectionWithStringTemplating.select), + selectWithAggregateCountFunction: postgrest + .from(selectParams.selectWithAggregateCountFunction.from) + .select(selectParams.selectWithAggregateCountFunction.select), + selectWithAggregateCountOnAColumnFunction: postgrest + .from(selectParams.selectWithAggregateCountOnAColumnFunction.from) + .select(selectParams.selectWithAggregateCountOnAColumnFunction.select), + selectWithAggregateSumFunctionWithoutColumn: postgrest + .from(selectParams.selectWithAggregateSumFunctionWithoutColumn.from) + .select(selectParams.selectWithAggregateSumFunctionWithoutColumn.select), + selectWithAggregateCountFunctionAndAlias: postgrest + .from(selectParams.selectWithAggregateCountFunctionAndAlias.from) + .select(selectParams.selectWithAggregateCountFunctionAndAlias.select), + selectWithAggregateNestedCountFunction: postgrest + .from(selectParams.selectWithAggregateNestedCountFunction.from) + .select(selectParams.selectWithAggregateNestedCountFunction.select), + selectWithAggregateNestedCountFunctionAndAlias: postgrest + .from(selectParams.selectWithAggregateNestedCountFunctionAndAlias.from) + .select(selectParams.selectWithAggregateNestedCountFunctionAndAlias.select), + selectWithAggregateCountAndSpread: postgrest + .from(selectParams.selectWithAggregateCountAndSpread.from) + .select(selectParams.selectWithAggregateCountAndSpread.select), + selectWithAggregateSumFunction: postgrest + .from(selectParams.selectWithAggregateSumFunction.from) + .select(selectParams.selectWithAggregateSumFunction.select), + selectWithAggregateAliasedSumFunction: postgrest + .from(selectParams.selectWithAggregateAliasedSumFunction.from) + .select(selectParams.selectWithAggregateAliasedSumFunction.select), + selectWithAggregateSumFunctionOnNestedRelation: postgrest + .from(selectParams.selectWithAggregateSumFunctionOnNestedRelation.from) + .select(selectParams.selectWithAggregateSumFunctionOnNestedRelation.select), + selectWithAggregateSumAndSpread: postgrest + .from(selectParams.selectWithAggregateSumAndSpread.from) + .select(selectParams.selectWithAggregateSumAndSpread.select), + selectWithAggregateSumAndSpreadOnNestedRelation: postgrest + .from(selectParams.selectWithAggregateSumAndSpreadOnNestedRelation.from) + .select(selectParams.selectWithAggregateSumAndSpreadOnNestedRelation.select), + selectWithSpreadOnNestedRelation: postgrest + .from(selectParams.selectWithSpreadOnNestedRelation.from) + .select(selectParams.selectWithSpreadOnNestedRelation.select), + selectSpreadOnManyRelation: postgrest + .from(selectParams.selectSpreadOnManyRelation.from) + .select(selectParams.selectSpreadOnManyRelation.select), + selectWithDuplicatesFields: postgrest + .from(selectParams.selectWithDuplicatesFields.from) + .select(selectParams.selectWithDuplicatesFields.select), + selectEmbedRessourceWithNoFields: postgrest + .from(selectParams.selectEmbedRessourceWithNoFields.from) + .select(selectParams.selectEmbedRessourceWithNoFields.select), + selectJsonAccessor: postgrest + .from(selectParams.selectJsonAccessor.from) + .select(selectParams.selectJsonAccessor.select), + typecastingAndAggregate: postgrest + .from(selectParams.typecastingAndAggregate.from) + .select(selectParams.typecastingAndAggregate.select), + innerJoinOnManyRelation: postgrest + .from(selectParams.innerJoinOnManyRelation.from) + .select(selectParams.innerJoinOnManyRelation.select), + selfReferenceRelation: postgrest + .from(selectParams.selfReferenceRelation.from) + .select(selectParams.selfReferenceRelation.select), + selfReferenceRelationViaColumn: postgrest + .from(selectParams.selfReferenceRelationViaColumn.from) + .select(selectParams.selfReferenceRelationViaColumn.select), + aggregateOnMissingColumnWithAlias: postgrest + .from(selectParams.aggregateOnMissingColumnWithAlias.from) + .select(selectParams.aggregateOnMissingColumnWithAlias.select), +} as const + +test('nested query with selective fields', async () => { + const res = await selectQueries.nestedQueryWithSelectiveFields.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "messages": Array [ + Object { + "id": 1, + "message": "Hello World 👋", + }, + Object { + "id": 2, + "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", + }, + Object { + "id": 4, + "message": "Some message on channel wihtout details", + }, + ], + "username": "supabot", + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('nested query with multiple levels and selective fields', async () => { + const res = await selectQueries.nestedQueryWithMultipleLevelsAndSelectiveFields.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "messages": Array [ + Object { + "channels": Object { + "id": 1, + "slug": "public", + }, + "id": 1, + "message": "Hello World 👋", + }, + Object { + "channels": Object { + "id": 2, + "slug": "random", + }, + "id": 2, + "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", + }, + Object { + "channels": Object { + "id": 3, + "slug": "other", + }, + "id": 4, + "message": "Some message on channel wihtout details", + }, + ], + "username": "supabot", + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('query with multiple one-to-many relationships', async () => { + const res = await selectQueries.queryWithMultipleOneToManySelectives.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "messages": Array [ + Object { + "id": 1, + }, + Object { + "id": 2, + }, + Object { + "id": 4, + }, + ], + "user_profiles": Array [ + Object { + "id": 1, + }, + ], + "username": "supabot", + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('many-to-one relationship', async () => { + const res = await selectQueries.manyToOne.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "user": Object { + "age_range": "[1,2)", + "catchphrase": "'cat' 'fat'", + "data": null, + "status": "ONLINE", + "username": "supabot", + }, + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('!inner relationship', async () => { + const res = await selectQueries.inner.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "channels": Object { + "channel_details": Object { + "details": "Details for public channel", + "id": 1, + }, + "data": null, + "id": 1, + "slug": "public", + }, + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('one-to-many relationship', async () => { + const res = await selectQueries.oneToMany.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "messages": Array [ + Object { + "channel_id": 1, + "data": null, + "id": 1, + "message": "Hello World 👋", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 2, + "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", + "username": "supabot", + }, + Object { + "channel_id": 3, + "data": null, + "id": 4, + "message": "Some message on channel wihtout details", + "username": "supabot", + }, + ], + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('one-to-many relationship with selective columns', async () => { + const res = await selectQueries.oneToManySelective.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "messages": Array [ + Object { + "data": null, + }, + Object { + "data": null, + }, + Object { + "data": null, + }, + ], + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('one-to-one relationship', async () => { + const res = await selectQueries.oneToOne.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "channel_details": Object { + "details": "Details for public channel", + "id": 1, + }, + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('!left oneToOne', async () => { + const res = await selectQueries.leftOneToOne.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "channels": Object { + "data": null, + "id": 1, + "slug": "public", + }, + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('!left oneToMany', async () => { + const res = await selectQueries.leftOneToMany.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "messages": Array [ + Object { + "channel_id": 1, + "data": null, + "id": 1, + "message": "Hello World 👋", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 2, + "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", + "username": "supabot", + }, + Object { + "channel_id": 3, + "data": null, + "id": 4, + "message": "Some message on channel wihtout details", + "username": "supabot", + }, + ], + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('!left zeroToOne', async () => { + const res = await selectQueries.leftZeroToOne.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "users": Object { + "age_range": "[1,2)", + "catchphrase": "'cat' 'fat'", + "data": null, + "status": "ONLINE", + "username": "supabot", + }, + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('join over a 1-1 relation with both nullables and non-nullables fields using foreign key name for hinting', async () => { + const res = await selectQueries.joinOneToOneWithFkHint.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "first_user": Object { + "age_range": "[1,2)", + "catchphrase": "'cat' 'fat'", + "data": null, + "status": "ONLINE", + "username": "supabot", + }, + "second_user": Object { + "age_range": "[25,35)", + "catchphrase": "'bat' 'cat'", + "data": null, + "status": "OFFLINE", + "username": "kiwicopple", + }, + "third_wheel": Object { + "age_range": "[25,35)", + "catchphrase": "'bat' 'rat'", + "data": null, + "status": "ONLINE", + "username": "awailas", + }, + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('join over a 1-M relation with both nullables and non-nullables fields using foreign key name for hinting', async () => { + const res = await selectQueries.joinOneToManyWithFkHint.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "first_friend_of": Array [ + Object { + "first_user": "supabot", + "id": 1, + "second_user": "kiwicopple", + "third_wheel": "awailas", + }, + Object { + "first_user": "supabot", + "id": 2, + "second_user": "awailas", + "third_wheel": null, + }, + ], + "second_friend_of": Array [], + "third_wheel_of": Array [], + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('join on 1-M relation', async () => { + const res = await selectQueries.joinOneToManyUsersWithFkHint + .eq('username', 'supabot') + .limit(1) + .single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "first_friend_of": Array [ + Object { + "first_user": "supabot", + "id": 1, + "second_user": "kiwicopple", + "third_wheel": "awailas", + }, + Object { + "first_user": "supabot", + "id": 2, + "second_user": "awailas", + "third_wheel": null, + }, + ], + "second_friend_of": Array [], + "third_wheel_of": Array [], + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('join on 1-1 relation with nullables', async () => { + const res = await selectQueries.joinOneToOneWithNullablesFkHint.order('id').limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "first_user": Object { + "age_range": "[1,2)", + "catchphrase": "'cat' 'fat'", + "data": null, + "status": "ONLINE", + "username": "supabot", + }, + "second_user": Object { + "age_range": "[25,35)", + "catchphrase": "'bat' 'cat'", + "data": null, + "status": "OFFLINE", + "username": "kiwicopple", + }, + "third_wheel": Object { + "age_range": "[25,35)", + "catchphrase": "'bat' 'rat'", + "data": null, + "status": "ONLINE", + "username": "awailas", + }, + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('join over a 1-1 relation with both nullables and non-nullables fields with no hinting', async () => { + const res = await selectQueries.joinOneToOneWithNullablesNoHint.single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": null, + "error": Object { + "code": "PGRST201", + "details": Array [ + Object { + "cardinality": "many-to-one", + "embedding": "best_friends with users", + "relationship": "best_friends_first_user_fkey using best_friends(first_user) and users(username)", + }, + Object { + "cardinality": "many-to-one", + "embedding": "best_friends with users", + "relationship": "best_friends_second_user_fkey using best_friends(second_user) and users(username)", + }, + Object { + "cardinality": "many-to-one", + "embedding": "best_friends with users", + "relationship": "best_friends_third_wheel_fkey using best_friends(third_wheel) and users(username)", + }, + ], + "hint": "Try changing 'users' to one of the following: 'users!best_friends_first_user_fkey', 'users!best_friends_second_user_fkey', 'users!best_friends_third_wheel_fkey'. Find the desired relationship in the 'details' key.", + "message": "Could not embed because more than one relationship was found for 'best_friends' and 'users'", + }, + "status": 300, + "statusText": "Multiple Choices", + } + `) +}) + +test('join over a 1-1 relation with both nullablesand non-nullables fields with column name hinting', async () => { + const res = await selectQueries.joinOneToOneWithNullablesColumnHint.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "first_user": Object { + "age_range": "[1,2)", + "catchphrase": "'cat' 'fat'", + "data": null, + "status": "ONLINE", + "username": "supabot", + }, + "second_user": Object { + "age_range": "[25,35)", + "catchphrase": "'bat' 'cat'", + "data": null, + "status": "OFFLINE", + "username": "kiwicopple", + }, + "third_wheel": Object { + "age_range": "[25,35)", + "catchphrase": "'bat' 'rat'", + "data": null, + "status": "ONLINE", + "username": "awailas", + }, + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('join over a 1-M relation with both nullables and non-nullables fields with no hinting', async () => { + const res = await selectQueries.joinOneToManyWithNullablesNoHint.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": null, + "error": Object { + "code": "PGRST201", + "details": Array [ + Object { + "cardinality": "one-to-many", + "embedding": "users with best_friends", + "relationship": "best_friends_first_user_fkey using users(username) and best_friends(first_user)", + }, + Object { + "cardinality": "one-to-many", + "embedding": "users with best_friends", + "relationship": "best_friends_second_user_fkey using users(username) and best_friends(second_user)", + }, + Object { + "cardinality": "one-to-many", + "embedding": "users with best_friends", + "relationship": "best_friends_third_wheel_fkey using users(username) and best_friends(third_wheel)", + }, + ], + "hint": "Try changing 'best_friends' to one of the following: 'best_friends!best_friends_first_user_fkey', 'best_friends!best_friends_second_user_fkey', 'best_friends!best_friends_third_wheel_fkey'. Find the desired relationship in the 'details' key.", + "message": "Could not embed because more than one relationship was found for 'users' and 'best_friends'", + }, + "status": 300, + "statusText": "Multiple Choices", + } + `) +}) + +test('join over a 1-M relation with both nullables and non-nullables fields using column name for hinting', async () => { + const res = await selectQueries.joinOneToManyWithNullablesColumnHint.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "first_friend_of": Array [ + Object { + "first_user": "supabot", + "id": 1, + "second_user": "kiwicopple", + "third_wheel": "awailas", + }, + Object { + "first_user": "supabot", + "id": 2, + "second_user": "awailas", + "third_wheel": null, + }, + ], + "second_friend_of": Array [], + "third_wheel_of": Array [], + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('join over a 1-M relation with both nullables and non-nullables fields using column name hinting on nested relation', async () => { + const res = await selectQueries.joinOneToManyWithNullablesColumnHintOnNestedRelation + .limit(1) + .single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "first_friend_of": Array [ + Object { + "first_user": Object { + "age_range": "[1,2)", + "catchphrase": "'cat' 'fat'", + "data": null, + "status": "ONLINE", + "username": "supabot", + }, + "id": 1, + "second_user": "kiwicopple", + "third_wheel": "awailas", + }, + Object { + "first_user": Object { + "age_range": "[1,2)", + "catchphrase": "'cat' 'fat'", + "data": null, + "status": "ONLINE", + "username": "supabot", + }, + "id": 2, + "second_user": "awailas", + "third_wheel": null, + }, + ], + "second_friend_of": Array [], + "third_wheel_of": Array [], + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('join over a 1-M relation with both nullables and non-nullables fields using no hinting on nested relation', async () => { + const res = await selectQueries.joinOneToManyWithNullablesNoHintOnNestedRelation.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": null, + "error": Object { + "code": "PGRST201", + "details": Array [ + Object { + "cardinality": "many-to-one", + "embedding": "best_friends with users", + "relationship": "best_friends_first_user_fkey using best_friends(first_user) and users(username)", + }, + Object { + "cardinality": "many-to-one", + "embedding": "best_friends with users", + "relationship": "best_friends_second_user_fkey using best_friends(second_user) and users(username)", + }, + Object { + "cardinality": "many-to-one", + "embedding": "best_friends with users", + "relationship": "best_friends_third_wheel_fkey using best_friends(third_wheel) and users(username)", + }, + ], + "hint": "Try changing 'users' to one of the following: 'users!best_friends_first_user_fkey', 'users!best_friends_second_user_fkey', 'users!best_friends_third_wheel_fkey'. Find the desired relationship in the 'details' key.", + "message": "Could not embed because more than one relationship was found for 'best_friends' and 'users'", + }, + "status": 300, + "statusText": "Multiple Choices", + } + `) +}) + +test('!left join on one to 0-1 non-empty relation', async () => { + const res = await selectQueries.leftOneToOneUsers.eq('username', 'supabot').limit(1).single() + expect(Array.isArray(res.data?.user_profiles)).toBe(true) + expect(res.data?.user_profiles[0].username).not.toBeNull() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "user_profiles": Array [ + Object { + "username": "supabot", + }, + ], + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('join on one to 0-1 non-empty relation via column name', async () => { + const res = await selectQueries.oneToOneUsersColumnName + .eq('username', 'supabot') + .limit(1) + .single() + expect(res.error).toBeNull() + expect(Array.isArray(res.data?.user_profiles)).toBe(true) + expect(res.data?.user_profiles[0].username).not.toBeNull() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "user_profiles": Array [ + Object { + "username": "supabot", + }, + ], + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('!left join on zero to one with null relation', async () => { + const res = await selectQueries.leftZeroToOneUserProfiles.eq('id', 2).limit(1).single() + expect(Array.isArray(res.data?.users)).toBe(false) + expect(res.data?.users).toBeNull() + + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "id": 2, + "username": null, + "users": null, + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('!left join on zero to one with valid relation', async () => { + const res = await selectQueries.leftZeroToOneUserProfilesWithNullables + .eq('id', 1) + .limit(1) + .single() + expect(Array.isArray(res.data?.users)).toBe(false) + // TODO: This should be nullable indeed + expect(res.data?.users?.status).not.toBeNull() + + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "id": 1, + "username": "supabot", + "users": Object { + "status": "ONLINE", + }, + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('!left join on zero to one empty relation', async () => { + const res = await selectQueries.leftOneToOneUsers.eq('username', 'dragarcia').limit(1).single() + expect(res.data).toBeNull() +}) + +test('join on 1-M relation with selective fk hinting', async () => { + const res = await selectQueries.joinOneToManyUsersWithFkHintSelective.limit(1).single() + expect(Array.isArray(res.data?.first_friend_of)).toBe(true) + expect(Array.isArray(res.data?.second_friend_of)).toBe(true) + expect(Array.isArray(res.data?.third_wheel_of)).toBe(true) + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "first_friend_of": Array [ + Object { + "id": 1, + }, + Object { + "id": 2, + }, + ], + "second_friend_of": Array [], + "third_wheel_of": Array [], + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('join select via column', async () => { + const res = await selectQueries.joinSelectViaColumn.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "username": Object { + "age_range": "[1,2)", + "catchphrase": "'cat' 'fat'", + "data": null, + "status": "ONLINE", + "username": "supabot", + }, + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('join select via column selective', async () => { + const res = await selectQueries.joinSelectViaColumnSelective.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "username": Object { + "status": "ONLINE", + }, + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('join select via column and alias', async () => { + const res = await selectQueries.joinSelectViaColumnAndAlias.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "user": Object { + "age_range": "[1,2)", + "catchphrase": "'cat' 'fat'", + "data": null, + "status": "ONLINE", + "username": "supabot", + }, + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('join select via unique table relationship', async () => { + const res = await selectQueries.joinSelectViaUniqueTableRelationship.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "users": Object { + "age_range": "[1,2)", + "catchphrase": "'cat' 'fat'", + "data": null, + "status": "ONLINE", + "username": "supabot", + }, + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) +test('join select via view name relationship', async () => { + const res = await selectQueries.joinSelectViaViewNameRelationship.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "updatable_view": Object { + "non_updatable_column": 1, + "username": "supabot", + }, + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('join select via column with string templating', async () => { + const res = await selectQueries.selectionWithStringTemplating.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "status": "ONLINE", + "username": "supabot", + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('select with aggregate count function', async () => { + const res = await selectQueries.selectWithAggregateCountFunction.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "messages": Array [ + Object { + "count": 3, + }, + ], + "username": "supabot", + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('select with aggregate count on a column function', async () => { + const res = await selectQueries.selectWithAggregateCountOnAColumnFunction.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "messages": Array [ + Object { + "count": 3, + }, + ], + "username": "supabot", + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('select with aggregate sum function without column should error', async () => { + const res = await selectQueries.selectWithAggregateSumFunctionWithoutColumn.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": null, + "error": Object { + "code": "42703", + "details": null, + "hint": null, + "message": "column messages_1.sum does not exist", + }, + "status": 400, + "statusText": "Bad Request", + } + `) +}) + +test('select with aggregate count function and alias', async () => { + const res = await selectQueries.selectWithAggregateCountFunctionAndAlias.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "messages": Array [ + Object { + "message_count": 3, + }, + ], + "username": "supabot", + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('select with aggregate nested count function', async () => { + const res = await selectQueries.selectWithAggregateNestedCountFunction.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "messages": Array [ + Object { + "channels": Object { + "count": 1, + }, + }, + Object { + "channels": Object { + "count": 1, + }, + }, + Object { + "channels": Object { + "count": 1, + }, + }, + ], + "username": "supabot", + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('select with aggregate nested count function and alias', async () => { + const res = await selectQueries.selectWithAggregateNestedCountFunctionAndAlias.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "messages": Array [ + Object { + "channels": Object { + "channel_count": 1, + }, + }, + Object { + "channels": Object { + "channel_count": 1, + }, + }, + Object { + "channels": Object { + "channel_count": 1, + }, + }, + ], + "username": "supabot", + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('select with aggregate count and spread', async () => { + const res = await selectQueries.selectWithAggregateCountAndSpread.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "messages": Array [ + Object { + "channels": Object { + "count": 1, + "details": "Details for public channel", + }, + }, + Object { + "channels": Object { + "count": 1, + "details": "Details for random channel", + }, + }, + Object { + "channels": Object { + "count": 1, + "details": null, + }, + }, + ], + "username": "supabot", + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('select with aggregate sum function', async () => { + const res = await selectQueries.selectWithAggregateSumFunction.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "messages": Array [ + Object { + "sum": 7, + }, + ], + "username": "supabot", + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('select with aggregate aliased sum function', async () => { + const res = await selectQueries.selectWithAggregateAliasedSumFunction.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "messages": Array [ + Object { + "sum_id": 7, + }, + ], + "username": "supabot", + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('select with aggregate sum function on nested relation', async () => { + const res = await selectQueries.selectWithAggregateSumFunctionOnNestedRelation.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "messages": Array [ + Object { + "channels": Object { + "sum": 1, + }, + }, + Object { + "channels": Object { + "sum": 2, + }, + }, + Object { + "channels": Object { + "sum": 3, + }, + }, + ], + "username": "supabot", + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('select with aggregate sum and spread', async () => { + const res = await selectQueries.selectWithAggregateSumAndSpread.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "messages": Array [ + Object { + "channels": Object { + "details": "Details for public channel", + "sum": 1, + }, + }, + Object { + "channels": Object { + "details": "Details for random channel", + "sum": 2, + }, + }, + Object { + "channels": Object { + "details": null, + "sum": 3, + }, + }, + ], + "username": "supabot", + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('select with aggregate sum and spread on nested relation', async () => { + const res = await selectQueries.selectWithAggregateSumAndSpreadOnNestedRelation.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "messages": Array [ + Object { + "channels": Object { + "details": "Details for public channel", + "details_sum": 1, + "sum": 1, + }, + }, + Object { + "channels": Object { + "details": "Details for random channel", + "details_sum": 2, + "sum": 2, + }, + }, + Object { + "channels": Object { + "details": null, + "details_sum": null, + "sum": 3, + }, + }, + ], + "username": "supabot", + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('select with spread on nested relation', async () => { + const res = await selectQueries.selectWithSpreadOnNestedRelation + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "channels": Object { + "details": "Details for public channel", + "details_id": 1, + "id": 1, + }, + "id": 1, + }, + Object { + "channels": Object { + "details": "Details for random channel", + "details_id": 2, + "id": 2, + }, + "id": 2, + }, + Object { + "channels": Object { + "details": null, + "details_id": null, + "id": 3, + }, + "id": 4, + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('select with type casting query', async () => { + const res = await selectQueries.typeCastingQuery.limit(1).single() + + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "id": "1", + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('join with column hinting', async () => { + const res = await selectQueries.joinSelectViaColumnHint.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "users": Object { + "age_range": "[1,2)", + "catchphrase": "'cat' 'fat'", + "data": null, + "status": "ONLINE", + "username": "supabot", + }, + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('join with same dest twice column hinting', async () => { + const res = await selectQueries.joinSelectViaColumnHintTwice.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": null, + "error": Object { + "code": "42712", + "details": null, + "hint": null, + "message": "table name \\"best_friends_users_1\\" specified more than once", + }, + "status": 400, + "statusText": "Bad Request", + } + `) +}) + +test('join with same dest twice column hinting', async () => { + const res = await selectQueries.selectSpreadOnManyRelation.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": null, + "error": Object { + "code": "PGRST119", + "details": "'channels' and 'messages' do not form a many-to-one or one-to-one relationship", + "hint": null, + "message": "A spread operation on 'messages' is not possible", + }, + "status": 400, + "statusText": "Bad Request", + } + `) +}) + +test('multiple times the same column in selection', async () => { + const res = await selectQueries.selectWithDuplicatesFields.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "id": 1, + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('embed resource with no fields', async () => { + const res = await selectQueries.selectEmbedRessourceWithNoFields.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "message": "Hello World 👋", + }, + "error": null, + "status": 200, + "statusText": "OK", + } +`) +}) + +test('select JSON accessor', async () => { + const res = await selectQueries.selectJsonAccessor + .limit(1) + .filter('username', 'eq', 'jsonuser') + .single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "bar": Object { + "nested": "value", + }, + "baz": "string value", + }, + "error": null, + "status": 200, + "statusText": "OK", + } +`) +}) + +test('typecasting and aggregate', async () => { + const res = await selectQueries.typecastingAndAggregate.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": null, + "error": Object { + "code": "42703", + "details": null, + "hint": null, + "message": "column messages.users does not exist", + }, + "status": 400, + "statusText": "Bad Request", + } +`) +}) + +test('inner join on many relation', async () => { + const res = await selectQueries.innerJoinOnManyRelation.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "id": 1, + "messages": Array [ + Object { + "id": 1, + "username": "supabot", + }, + ], + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('self reference relation', async () => { + const res = await selectQueries.selfReferenceRelation.limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "collections": Array [ + Object { + "description": "Child of Root", + "id": 2, + "parent_id": 1, + }, + Object { + "description": "Another Child of Root", + "id": 3, + "parent_id": 1, + }, + ], + "description": "Root Collection", + "id": 1, + "parent_id": null, + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('self reference relation via column', async () => { + const res = await selectQueries.selfReferenceRelationViaColumn.eq('id', 2).limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "description": "Child of Root", + "id": 2, + "parent_id": Object { + "description": "Root Collection", + "id": 1, + "parent_id": null, + }, + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('aggregate on missing column with alias', async () => { + const res = await selectQueries.aggregateOnMissingColumnWithAlias.eq('id', 1).limit(1).single() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": null, + "error": Object { + "code": "42703", + "details": null, + "hint": null, + "message": "column users.missing_column does not exist", + }, + "status": 400, + "statusText": "Bad Request", + } + `) +}) diff --git a/test/resource-embedding.ts b/test/resource-embedding.ts index d211dff4..b3cca1a8 100644 --- a/test/resource-embedding.ts +++ b/test/resource-embedding.ts @@ -5,7 +5,53 @@ const postgrest = new PostgrestClient('http://localhost:3000') test('embedded select', async () => { const res = await postgrest.from('users').select('messages(*)') - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "messages": Array [ + Object { + "channel_id": 1, + "data": null, + "id": 1, + "message": "Hello World 👋", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 2, + "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", + "username": "supabot", + }, + Object { + "channel_id": 3, + "data": null, + "id": 4, + "message": "Some message on channel wihtout details", + "username": "supabot", + }, + ], + }, + Object { + "messages": Array [], + }, + Object { + "messages": Array [], + }, + Object { + "messages": Array [], + }, + Object { + "messages": Array [], + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) describe('embedded filters', () => { @@ -15,14 +61,85 @@ describe('embedded filters', () => { .from('users') .select('messages(*)') .eq('messages.channel_id' as any, 1) - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "messages": Array [ + Object { + "channel_id": 1, + "data": null, + "id": 1, + "message": "Hello World 👋", + "username": "supabot", + }, + ], + }, + Object { + "messages": Array [], + }, + Object { + "messages": Array [], + }, + Object { + "messages": Array [], + }, + Object { + "messages": Array [], + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('embedded or', async () => { const res = await postgrest .from('users') .select('messages(*)') .or('channel_id.eq.2,message.eq.Hello World 👋', { foreignTable: 'messages' }) - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "messages": Array [ + Object { + "channel_id": 1, + "data": null, + "id": 1, + "message": "Hello World 👋", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 2, + "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", + "username": "supabot", + }, + ], + }, + Object { + "messages": Array [], + }, + Object { + "messages": Array [], + }, + Object { + "messages": Array [], + }, + Object { + "messages": Array [], + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('embedded or with and', async () => { const res = await postgrest @@ -31,7 +148,46 @@ describe('embedded filters', () => { .or('channel_id.eq.2,and(message.eq.Hello World 👋,username.eq.supabot)', { foreignTable: 'messages', }) - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "messages": Array [ + Object { + "channel_id": 1, + "data": null, + "id": 1, + "message": "Hello World 👋", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 2, + "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", + "username": "supabot", + }, + ], + }, + Object { + "messages": Array [], + }, + Object { + "messages": Array [], + }, + Object { + "messages": Array [], + }, + Object { + "messages": Array [], + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) }) @@ -41,7 +197,53 @@ describe('embedded transforms', () => { .from('users') .select('messages(*)') .order('channel_id' as any, { foreignTable: 'messages', ascending: false }) - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "messages": Array [ + Object { + "channel_id": 3, + "data": null, + "id": 4, + "message": "Some message on channel wihtout details", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 2, + "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", + "username": "supabot", + }, + Object { + "channel_id": 1, + "data": null, + "id": 1, + "message": "Hello World 👋", + "username": "supabot", + }, + ], + }, + Object { + "messages": Array [], + }, + Object { + "messages": Array [], + }, + Object { + "messages": Array [], + }, + Object { + "messages": Array [], + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('embedded order on multiple columns', async () => { @@ -50,7 +252,53 @@ describe('embedded transforms', () => { .select('messages(*)') .order('channel_id' as any, { foreignTable: 'messages', ascending: false }) .order('username', { foreignTable: 'messages', ascending: false }) - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "messages": Array [ + Object { + "channel_id": 3, + "data": null, + "id": 4, + "message": "Some message on channel wihtout details", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 2, + "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", + "username": "supabot", + }, + Object { + "channel_id": 1, + "data": null, + "id": 1, + "message": "Hello World 👋", + "username": "supabot", + }, + ], + }, + Object { + "messages": Array [], + }, + Object { + "messages": Array [], + }, + Object { + "messages": Array [], + }, + Object { + "messages": Array [], + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('embedded limit', async () => { @@ -58,7 +306,39 @@ describe('embedded transforms', () => { .from('users') .select('messages(*)') .limit(1, { foreignTable: 'messages' }) - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "messages": Array [ + Object { + "channel_id": 1, + "data": null, + "id": 1, + "message": "Hello World 👋", + "username": "supabot", + }, + ], + }, + Object { + "messages": Array [], + }, + Object { + "messages": Array [], + }, + Object { + "messages": Array [], + }, + Object { + "messages": Array [], + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('embedded range', async () => { @@ -66,6 +346,38 @@ describe('embedded transforms', () => { .from('users') .select('messages(*)') .range(1, 1, { foreignTable: 'messages' }) - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "messages": Array [ + Object { + "channel_id": 2, + "data": null, + "id": 2, + "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", + "username": "supabot", + }, + ], + }, + Object { + "messages": Array [], + }, + Object { + "messages": Array [], + }, + Object { + "messages": Array [], + }, + Object { + "messages": Array [], + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) }) diff --git a/test/rpc.ts b/test/rpc.ts new file mode 100644 index 00000000..8e1e263f --- /dev/null +++ b/test/rpc.ts @@ -0,0 +1,158 @@ +import { PostgrestClient } from '../src/index' +import { Database } from './types' + +const REST_URL = 'http://localhost:3000' +export const postgrest = new PostgrestClient(REST_URL) + +export const RPC_NAME = 'get_username_and_status' + +export const selectParams = { + noParams: undefined, + starSelect: '*', + fieldSelect: 'username', + fieldsSelect: 'username, status', + fieldAliasing: 'name:username', + fieldCasting: 'status::text', + fieldAggregate: 'username.count(), status', +} as const + +export const selectQueries = { + noParams: postgrest.rpc(RPC_NAME, { name_param: 'supabot' }).select(selectParams.noParams), + starSelect: postgrest.rpc(RPC_NAME, { name_param: 'supabot' }).select(selectParams.starSelect), + fieldSelect: postgrest.rpc(RPC_NAME, { name_param: 'supabot' }).select(selectParams.fieldSelect), + fieldsSelect: postgrest + .rpc(RPC_NAME, { name_param: 'supabot' }) + .select(selectParams.fieldsSelect), + fieldAliasing: postgrest + .rpc(RPC_NAME, { name_param: 'supabot' }) + .select(selectParams.fieldAliasing), + fieldCasting: postgrest + .rpc(RPC_NAME, { name_param: 'supabot' }) + .select(selectParams.fieldCasting), + fieldAggregate: postgrest + .rpc(RPC_NAME, { name_param: 'supabot' }) + .select(selectParams.fieldAggregate), +} as const + +test('RPC call with no params', async () => { + const res = await selectQueries.noParams + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "status": "ONLINE", + "username": "supabot", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('RPC call with star select', async () => { + const res = await selectQueries.starSelect + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "status": "ONLINE", + "username": "supabot", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('RPC call with single field select', async () => { + const res = await selectQueries.fieldSelect + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "username": "supabot", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('RPC call with multiple fields select', async () => { + const res = await selectQueries.fieldsSelect + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "status": "ONLINE", + "username": "supabot", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('RPC call with field aliasing', async () => { + const res = await selectQueries.fieldAliasing + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "name": "supabot", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('RPC call with field casting', async () => { + const res = await selectQueries.fieldCasting + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "status": "ONLINE", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('RPC call with field aggregate', async () => { + const res = await selectQueries.fieldAggregate + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "count": 1, + "status": "ONLINE", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) diff --git a/test/select-query-parser/parser.test-d.ts b/test/select-query-parser/parser.test-d.ts new file mode 100644 index 00000000..5f637511 --- /dev/null +++ b/test/select-query-parser/parser.test-d.ts @@ -0,0 +1,566 @@ +import { expectType } from 'tsd' +import type { ParseQuery, ParserError } from '../../src/select-query-parser/parser' +import { selectParams } from '../relationships' + +// This test file is here to ensure some of our perser behave as expected +// it's useful to track down if the result type of a query is invalid becase of bad parsing +// or because of invalid matching against the final database type +// Basic select with multiple fields +{ + expectType>([ + { type: 'field', name: 'username' }, + { type: 'field', name: 'email' }, + { type: 'field', name: 'created_at' }, + ]) +} + +// Select with star +{ + expectType>([{ type: 'star' }]) +} + +{ + expectType>([{ type: 'field', name: 'username' }, { type: 'star' }]) +} + +// Select with renamed field +{ + expectType>([ + { type: 'field', name: 'username', alias: 'display_name' }, + ]) +} + +// Select with embedded resource +{ + expectType>([ + { + type: 'field', + name: 'posts', + children: [ + { type: 'field', name: 'id' }, + { type: 'field', name: 'title' }, + { type: 'field', name: 'content' }, + ], + }, + ]) +} + +// Select with nested embedded resources +{ + expectType>([ + { + type: 'field', + name: 'posts', + children: [ + { type: 'field', name: 'id' }, + { type: 'field', name: 'title' }, + { + type: 'field', + name: 'author', + children: [ + { type: 'field', name: 'name' }, + { type: 'field', name: 'email' }, + ], + }, + ], + }, + ]) +} + +// Select with aggregation +{ + expectType>([ + { + type: 'field', + name: 'posts', + children: [{ type: 'field', name: 'count', aggregateFunction: 'count' }], + }, + ]) +} + +// Select with JSON accessor +{ + expectTypepreferences->theme'>>([ + { type: 'field', name: 'data', alias: 'theme', castType: 'json' }, + ]) +} + +// Select with JSON accessor and text conversion +{ + expectTypepreferences->>theme'>>([ + { type: 'field', name: 'data', alias: 'theme', castType: 'text' }, + ]) +} + +// Select with spread +{ + expectType>([ + { + type: 'field', + name: 'username', + }, + { + type: 'spread', + target: { + type: 'field', + name: 'posts', + children: [ + { type: 'field', name: 'id' }, + { type: 'field', name: 'title' }, + ], + }, + }, + ]) +} +{ + expectType>([ + { + type: 'spread', + target: { + type: 'field', + name: 'users', + children: [ + { type: 'field', name: 'first_name' }, + { type: 'field', name: 'last_name' }, + ], + }, + }, + ]) +} + +// Select with inner join +{ + expectType>([ + { + type: 'field', + name: 'posts', + innerJoin: true, + children: [ + { type: 'field', name: 'id' }, + { type: 'field', name: 'title' }, + ], + }, + ]) +} + +// Select with left join +{ + expectType>([ + { + type: 'field', + name: 'posts', + children: [ + { type: 'field', name: 'id' }, + { type: 'field', name: 'title' }, + ], + }, + ]) +} + +// Select with rename and hint +{ + expectType>([ + { + type: 'field', + name: 'users', + alias: 'author', + hint: 'user_id', + children: [ + { type: 'field', name: 'id' }, + { type: 'field', name: 'name' }, + ], + }, + ]) +} + +// Complex select combining multiple features +{ + expectType< + ParseQuery<'id, username, posts!left(id, title, comments(id, content)), profile->settings->>theme::text'> + >([ + { type: 'field', name: 'id' }, + { type: 'field', name: 'username' }, + { + type: 'field', + name: 'posts', + children: [ + { type: 'field', name: 'id' }, + { type: 'field', name: 'title' }, + { + type: 'field', + name: 'comments', + children: [ + { type: 'field', name: 'id' }, + { type: 'field', name: 'content' }, + ], + }, + ], + }, + { type: 'field', name: 'profile', alias: 'theme', castType: 'text' }, + ]) +} +{ + type t = ParseQuery<'id, posts(count), comments(sum:id.sum())'> + type aggFunction = t[1]['children'][0]['aggregateFunction'] + type isCount = aggFunction extends 'count' ? true : false + expectType(true) + expectType>([ + { type: 'field', name: 'id' }, + { + type: 'field', + name: 'posts', + children: [{ type: 'field', name: 'count', aggregateFunction: 'count' }], + }, + { + type: 'field', + name: 'comments', + children: [{ type: 'field', alias: 'sum', name: 'id', aggregateFunction: 'sum' }], + }, + ]) +} +{ + expectType>([ + { type: 'field', name: 'id' }, + { + type: 'field', + name: 'posts', + children: [{ type: 'field', name: 'count', aggregateFunction: 'count' }], + }, + { + type: 'field', + name: 'comments', + children: [{ type: 'field', name: 'id', aggregateFunction: 'sum' }], + }, + ]) +} +{ + expectType>([ + { type: 'field', name: 'id' }, + { + type: 'field', + name: 'posts', + children: [{ type: 'field', name: 'id', aggregateFunction: 'count' }], + }, + ]) +} +{ + expectType>([ + { type: 'field', name: 'id' }, + { + type: 'field', + name: 'posts', + children: [{ type: 'field', name: 'id', alias: 'aliased', aggregateFunction: 'count' }], + }, + ]) +} +{ + expectType>([ + { type: 'field', name: 'id' }, + { + type: 'field', + name: 'posts', + children: [{ type: 'field', name: 'count', aggregateFunction: 'count' }], + }, + ]) +} +{ + type t = ParseQuery<'id, posts(renamed_count:count())'> + type aggFunction = t[1]['children'][0]['aggregateFunction'] + type isCount = aggFunction extends 'count' ? true : false + expectType(true) + expectType>([ + { type: 'field', name: 'id' }, + { + type: 'field', + name: 'posts', + children: [ + { type: 'field', alias: 'renamed_count', name: 'count', aggregateFunction: 'count' }, + ], + }, + ]) +} +{ + type t = ParseQuery<'username, messages(channels(channel_count:count()))'> + type aggFunction = t[1]['children'][0]['children'][0]['aggregateFunction'] + type isCount = aggFunction extends 'count' ? true : false + expectType(true) + expectType>([ + { type: 'field', name: 'username' }, + { + type: 'field', + name: 'messages', + children: [ + { + type: 'field', + name: 'channels', + children: [ + { + type: 'field', + alias: 'channel_count', + name: 'count', + aggregateFunction: 'count', + }, + ], + }, + ], + }, + ]) +} +// Other than count aggregation function without column name +// should be a field like any other +{ + expectType>([ + { type: 'field', name: 'posts', children: [{ type: 'field', name: 'sum' }] }, + ]) +} +// Should be considered embeded with parenthesis +{ + expectType>([ + { + type: 'field', + name: 'posts', + children: [{ type: 'field', name: 'sum', children: [] as [] }], + }, + ]) +} + +// Select with nested JSON accessors +{ + expectTypepreferences->theme->color'>>([ + { type: 'field', name: 'data', alias: 'color', castType: 'json' }, + ]) +} + +// Select with multiple spreads +{ + expectType>([ + { type: 'field', name: 'id' }, + { + type: 'spread', + target: { + type: 'field', + name: 'profile', + children: [ + { type: 'field', name: 'name' }, + { type: 'field', name: 'email' }, + ], + }, + }, + { + type: 'spread', + target: { + type: 'field', + name: 'settings', + children: [ + { type: 'field', name: 'theme' }, + { type: 'field', name: 'language' }, + ], + }, + }, + ]) +} + +// Select with multiple hints +{ + expectType>([ + { + type: 'field', + alias: 'author', + name: 'users', + hint: 'user_id', + children: [ + { type: 'field', name: 'id' }, + { type: 'field', name: 'name' }, + ], + }, + { + type: 'field', + name: 'posts', + hint: 'post_id', + children: [ + { type: 'field', name: 'title' }, + { type: 'field', name: 'content' }, + ], + }, + ]) +} + +// Select with combination of inner and left joins +{ + expectType>([ + { + type: 'field', + name: 'users', + innerJoin: true, + children: [ + { type: 'field', name: 'id' }, + { type: 'field', name: 'name' }, + ], + }, + { + type: 'field', + name: 'posts', + children: [ + { type: 'field', name: 'title' }, + { type: 'field', name: 'content' }, + ], + }, + ]) +} + +// Select with quoted identifiers +{ + expectType>([ + { type: 'field', name: 'complex name', alias: 'user name' }, + { + type: 'field', + alias: 'post-title', + name: 'posts', + children: [{ type: 'field', name: 'content-body' }], + }, + ]) +} + +// Select with nested aggregations and type castings +{ + expectType>([ + { + type: 'field', + name: 'users', + children: [ + { type: 'field', name: 'id' }, + { + type: 'field', + name: 'posts', + children: [ + { type: 'field', name: 'count', castType: 'int', aggregateFunction: 'count' }, + { + type: 'field', + alias: 'avg_likes', + name: 'likes', + castType: 'float', + aggregateFunction: 'avg', + }, + ], + }, + ], + }, + ]) +} + +// Invalid type cast +{ + expectType>([ + { + type: 'field', + name: 'id', + castType: 'invalid_type', + }, + ]) +} + +// Select with multiple type castings +{ + expectTypeage::int'>>([ + { type: 'field', name: 'id', castType: 'text' }, + { type: 'field', name: 'created_at', castType: 'date' }, + { type: 'field', name: 'data', alias: 'age', castType: 'int' }, + ]) +} + +// Select with type casting +{ + expectType>([ + { type: 'field', name: 'id', castType: 'text' }, + { type: 'field', name: 'created_at', castType: 'date' }, + { type: 'field', name: 'other', castType: 'int' }, + ]) +} + +// select JSON accessor +{ + expect>([ + { type: 'field', name: 'data', alias: 'bar', castType: 'json' }, + { type: 'field', name: 'data', alias: 'baz', castType: 'text' }, + ]) +} + +// embed resource with no fields +{ + expect>([ + { type: 'field', name: 'message' }, + { type: 'field', name: 'users', children: [] }, + ]) +} + +// ParserError test cases +// Empty string +{ + expectType>(0 as any as ParserError<'Empty string'>) +} + +// Unexpected input at the end +{ + expectType>( + 0 as any as ParserError<'Unexpected input: unexpected_input'> + ) +} + +// Missing closing parenthesis +{ + expectType>(0 as any as ParserError<'Expected ")" at ``'>) +} + +// Incomplete JSON accessor +{ + expectType'>>(0 as any as ParserError<'Expected property name after `->`'>) +} + +// Invalid hint (missing identifier after !) +{ + expectType>( + 0 as any as ParserError<'Expected identifier after "!" at `(id, name)`'> + ) +} + +// Invalid spread (missing field after ...) +{ + expectType>( + 0 as any as ParserError<'Unable to parse spread resource at `...::`'> + ) +} + +// Invalid rename (missing field after :) +{ + expectType>( + 0 as any as ParserError<'Unable to parse renamed field at `new_name:`'> + ) +} + +// Incomplete quoted identifier +{ + expectType>( + 0 as any as ParserError<'Expected identifier at `"incomplete`'> + ) +} + +// Invalid combination of inner and left join +{ + expectType>( + 0 as any as ParserError<'Expected "(" at `!left(id, name)`'> + ) +} + +// Missing opening parenthesis after aggregate function +{ + expectType>( + 0 as any as ParserError<'Expected `()` after `.` operator `avg`'> + ) +} + +// Invalid nested JSON accessor +{ + expectTypepreferences->->theme'>>( + 0 as any as ParserError<'Unexpected input: ->->theme'> + ) +} diff --git a/test/select-query-parser/result.test-d.ts b/test/select-query-parser/result.test-d.ts new file mode 100644 index 00000000..38dcccae --- /dev/null +++ b/test/select-query-parser/result.test-d.ts @@ -0,0 +1,72 @@ +import { Database, Json } from '../types' +import { selectParams } from '../relationships' +import { GetResult } from '../../src/select-query-parser/result' +import { expectType } from 'tsd' +import { TypeEqual } from 'ts-expect' + +type SelectQueryFromTableResult< + TableName extends keyof Database['public']['Tables'], + Q extends string +> = GetResult< + Database['public'], + Database['public']['Tables'][TableName]['Row'], + TableName, + Database['public']['Tables'][TableName]['Relationships'], + Q +> + +// This test file is here to help develop, debug and maintain the GetResult +// type inference, it can be useful to identify weither a type error come from the +// result inference or functions chaining down the line in the client (.filter(), ...) + +// nested query with selective fields +{ + const { from, select } = selectParams.nestedQueryWithSelectiveFields + let result: SelectQueryFromTableResult + let expected: { + username: string + messages: { + id: number + message: string | null + }[] + } + expectType>(true) +} + +// select JSON accessor +{ + const { from, select } = selectParams.selectJsonAccessor + let result: SelectQueryFromTableResult + let expected: { + bar: Json + baz: string + } + expectType>(true) +} + +// embed resource with no fields +{ + const { from, select } = selectParams.selectEmbedRessourceWithNoFields + let result: SelectQueryFromTableResult + let expected: { + message: string | null + } + expectType>(true) +} + +// Self referencing relation +{ + const { from, select } = selectParams.selfReferenceRelation + let result: SelectQueryFromTableResult + let expected: { + id: number + description: string | null + parent_id: number | null + collections: { + id: number + description: string | null + parent_id: number | null + }[] + } + expectType>(true) +} diff --git a/test/select-query-parser/rpc.test-d.ts b/test/select-query-parser/rpc.test-d.ts new file mode 100644 index 00000000..858434bf --- /dev/null +++ b/test/select-query-parser/rpc.test-d.ts @@ -0,0 +1,74 @@ +import { postgrest, selectParams, RPC_NAME } from '../rpc' +import { Database } from '../types' +import { expectType } from 'tsd' +import { TypeEqual } from 'ts-expect' + +// RPC call with no params +{ + const { data } = await postgrest + .rpc(RPC_NAME, { name_param: 'supabot' }) + .select(selectParams.noParams) + let result: Exclude + let expected: Database['public']['Functions'][typeof RPC_NAME]['Returns'] + expectType>(true) +} + +// RPC call with star select +{ + const { data } = await postgrest + .rpc(RPC_NAME, { name_param: 'supabot' }) + .select(selectParams.starSelect) + let result: Exclude + let expected: Database['public']['Functions'][typeof RPC_NAME]['Returns'] + expectType>(true) +} + +// RPC call with single field select +{ + const { data } = await postgrest + .rpc(RPC_NAME, { name_param: 'supabot' }) + .select(selectParams.fieldSelect) + let result: Exclude + let expected: { username: string }[] + expectType>(true) +} + +// RPC call with multiple fields select +{ + const { data } = await postgrest + .rpc(RPC_NAME, { name_param: 'supabot' }) + .select(selectParams.fieldsSelect) + let result: Exclude + let expected: Database['public']['Functions'][typeof RPC_NAME]['Returns'] + expectType>(true) +} + +// RPC call with field aliasing +{ + const { data } = await postgrest + .rpc(RPC_NAME, { name_param: 'supabot' }) + .select(selectParams.fieldAliasing) + let result: Exclude + let expected: { name: string }[] + expectType>(true) +} + +// RPC call with field casting +{ + const { data } = await postgrest + .rpc(RPC_NAME, { name_param: 'supabot' }) + .select(selectParams.fieldCasting) + let result: Exclude + let expected: { status: string }[] + expectType>(true) +} + +// RPC call with field aggregate +{ + const { data } = await postgrest + .rpc(RPC_NAME, { name_param: 'supabot' }) + .select(selectParams.fieldAggregate) + let result: Exclude + let expected: { count: number; status: 'ONLINE' | 'OFFLINE' }[] + expectType>(true) +} diff --git a/test/select-query-parser/select.test-d.ts b/test/select-query-parser/select.test-d.ts new file mode 100644 index 00000000..7849ea1f --- /dev/null +++ b/test/select-query-parser/select.test-d.ts @@ -0,0 +1,745 @@ +import { expectType } from 'tsd' +import { TypeEqual } from 'ts-expect' +import { Json } from '../../src/select-query-parser/types' +import { SelectQueryError } from '../../src/select-query-parser/utils' +import { Prettify } from '../../src/types' +import { Database } from '../types' +import { selectQueries } from '../relationships' + +// This test file is here to ensure that for a query against a specfic datatabase +// our type inference for the result is correct and matching postgrest behavior at runtime +// it'll test the actual type inference AND query chaining (limit(), single(), ...) +// IMPORTANT: It shoudl be kept in sync with "test/relationships.ts" which test the actual runtime +// behavior of those queries using the same parameters + +type Schema = Database['public'] + +// nested query with selective fields +{ + const { data } = await selectQueries.nestedQueryWithSelectiveFields.limit(1).single() + let result: Exclude + let expected: { + username: string + messages: { + id: number + message: string | null + }[] + } + expectType>(true) +} + +// nested query with multiple levels and selective fields +{ + const { data } = await selectQueries.nestedQueryWithMultipleLevelsAndSelectiveFields + .limit(1) + .single() + let result: Exclude + let expected: { + messages: Array<{ + id: number + message: string | null + channels: { + id: number + slug: string | null + } + }> + username: string + } + expectType>(true) +} + +// query with multiple one-to-many relationships +{ + const { data } = await selectQueries.queryWithMultipleOneToManySelectives.limit(1).single() + let result: Exclude + let expected: { + username: string + messages: Array> + user_profiles: Array> + } + expectType>(true) +} + +// many-to-one relationship +{ + const { data } = await selectQueries.manyToOne.limit(1).single() + let result: Exclude + let expected: { + user: Database['public']['Tables']['users']['Row'] + } + expectType>(true) +} + +// !inner relationship +{ + const { data } = await selectQueries.inner.limit(1).single() + let result: Exclude + type ExpectedType = Prettify< + Database['public']['Tables']['channels']['Row'] & { + channel_details: Database['public']['Tables']['channel_details']['Row'] + } + > + let expected: { + channels: ExpectedType + } + expectType>(true) +} + +// one-to-many relationship +{ + const { data } = await selectQueries.oneToMany.limit(1).single() + let result: Exclude + let expected: { + messages: Database['public']['Tables']['messages']['Row'][] + } + expectType>(true) +} + +// one-to-many relationship with selective columns +{ + const { data } = await selectQueries.oneToManySelective.limit(1).single() + let result: Exclude + let expected: { + messages: Array> + } + expectType>(true) +} + +// one-to-one relationship +{ + const { data } = await selectQueries.oneToOne.limit(1).single() + let result: Exclude + let expected: { + channel_details: Database['public']['Tables']['channel_details']['Row'] | null + } + expectType>(true) +} + +// !left oneToOne +{ + const { data } = await selectQueries.leftOneToOne.limit(1).single() + let result: Exclude + let expected: { + channels: Database['public']['Tables']['channels']['Row'] + } + expectType>(true) +} + +// !left oneToMany +{ + const { data } = await selectQueries.leftOneToMany.limit(1).single() + let result: Exclude + let expected: { + messages: Array + } + expectType>(true) +} + +// !left zeroToOne +{ + const { data } = await selectQueries.leftZeroToOne.limit(1).single() + let result: Exclude + let expected: { + users: Database['public']['Tables']['users']['Row'] | null + } + expectType>(true) +} + +// join over a 1-1 relation with both nullables and non-nullables fields using foreign key name for hinting +{ + const { data } = await selectQueries.joinOneToOneWithFkHint.limit(1).single() + let result: Exclude + let expected: { + first_user: Database['public']['Tables']['users']['Row'] + second_user: Database['public']['Tables']['users']['Row'] + third_wheel: Database['public']['Tables']['users']['Row'] | null + } + expectType>(true) +} + +// join over a 1-M relation with both nullables and non-nullables fields using foreign key name for hinting +{ + const { data } = await selectQueries.joinOneToManyWithFkHint.limit(1).single() + let result: Exclude + let expected: { + first_friend_of: Array + second_friend_of: Array + third_wheel_of: Array + } + expectType>(true) +} + +// join on 1-M relation +{ + const { data } = await selectQueries.joinOneToManyUsersWithFkHint.limit(1).single() + let result: Exclude + let expected: { + first_friend_of: Array + second_friend_of: Array + third_wheel_of: Array + } + expectType>(true) +} + +// join on 1-1 relation with nullables +{ + const { data } = await selectQueries.joinOneToOneWithNullablesFkHint.limit(1).single() + let result: Exclude + let expected: { + first_user: Database['public']['Tables']['users']['Row'] + second_user: Database['public']['Tables']['users']['Row'] + third_wheel: Database['public']['Tables']['users']['Row'] | null + } + expectType>(true) +} + +// join over a 1-1 relation with both nullables and non-nullables fields with no hinting +{ + const { data } = await selectQueries.joinOneToOneWithNullablesNoHint.limit(1).single() + let result: Exclude + let expected: { + first_user: SelectQueryError<"Could not embed because more than one relationship was found for 'users' and 'best_friends' you need to hint the column with users! ?"> + second_user: SelectQueryError<"Could not embed because more than one relationship was found for 'users' and 'best_friends' you need to hint the column with users! ?"> + third_wheel: SelectQueryError<"Could not embed because more than one relationship was found for 'users' and 'best_friends' you need to hint the column with users! ?"> + } + expectType>(true) +} + +// join over a 1-1 relation with both nullablesand non-nullables fields with column name hinting +{ + const { data } = await selectQueries.joinOneToOneWithNullablesColumnHint.limit(1).single() + let result: Exclude + let expected: { + first_user: Database['public']['Tables']['users']['Row'] + second_user: Database['public']['Tables']['users']['Row'] + third_wheel: Database['public']['Tables']['users']['Row'] | null + } + expectType>(true) +} + +// join over a 1-M relation with both nullables and non-nullables fields with no hinting +{ + const { data } = await selectQueries.joinOneToManyWithNullablesNoHint.limit(1).single() + let result: Exclude + let expected: { + first_friend_of: SelectQueryError<"Could not embed because more than one relationship was found for 'best_friends' and 'users' you need to hint the column with best_friends! ?"> + second_friend_of: SelectQueryError<"Could not embed because more than one relationship was found for 'best_friends' and 'users' you need to hint the column with best_friends! ?"> + third_wheel_of: SelectQueryError<"Could not embed because more than one relationship was found for 'best_friends' and 'users' you need to hint the column with best_friends! ?"> + } + expectType>(true) +} + +// join over a 1-M relation with both nullables and non-nullables fields using column name for hinting +{ + const { data } = await selectQueries.joinOneToManyWithNullablesColumnHint.limit(1).single() + let result: Exclude + let expected: { + first_friend_of: Array + second_friend_of: Array + third_wheel_of: Array + } + expectType>(true) +} + +// join over a 1-M relation with both nullables and non-nullables fields using column name hinting on nested relation +{ + const { data } = await selectQueries.joinOneToManyWithNullablesColumnHintOnNestedRelation + .limit(1) + .single() + let result: Exclude + type ExpectedType = Prettify< + Database['public']['Tables']['best_friends']['Row'] & { + first_user: string & Database['public']['Tables']['users']['Row'] + } + > + let expected: { + first_friend_of: ExpectedType[] + second_friend_of: Array + third_wheel_of: Array + } + expectType>(true) +} + +// join over a 1-M relation with both nullables and non-nullables fields using no hinting on nested relation +{ + const { data } = await selectQueries.joinOneToManyWithNullablesNoHintOnNestedRelation + .limit(1) + .single() + let result: Exclude + let expected: { + first_friend_of: Array<{ + id: number + second_user: string + third_wheel: string | null + first_user: SelectQueryError<"Could not embed because more than one relationship was found for 'users' and 'best_friends' you need to hint the column with users! ?"> + }> + second_friend_of: Array + third_wheel_of: Array + } + expectType>(true) +} + +// !left join on one to 0-1 non-empty relation +{ + const { data } = await selectQueries.leftOneToOneUsers.limit(1).single() + let result: Exclude + let expected: { + user_profiles: Array> + } + expectType>(true) +} + +// join on one to 0-1 non-empty relation via column name +{ + const { data } = await selectQueries.oneToOneUsersColumnName.limit(1).single() + let result: Exclude + let expected: { + user_profiles: Array> + } + expectType>(true) +} + +// !left join on zero to one with null relation +{ + const { data } = await selectQueries.leftZeroToOneUserProfiles.limit(1).single() + let result: Exclude + let expected: { + id: number + username: string | null + users: Database['public']['Tables']['users']['Row'] | null + } + expectType>(true) +} + +// !left join on zero to one with valid relation +{ + const { data } = await selectQueries.leftZeroToOneUserProfilesWithNullables.limit(1).single() + let result: Exclude + let expected: { + id: number + username: string | null + users: Pick | null + } + expectType>(true) +} + +// !left join on zero to one empty relation +{ + const { data } = await selectQueries.leftOneToOneUsers.limit(1).single() + let result: Exclude + let expected: { + user_profiles: Array> + } + expectType>(true) +} + +// join on 1-M relation with selective fk hinting +{ + const { data } = await selectQueries.joinOneToManyUsersWithFkHintSelective.limit(1).single() + let result: Exclude + let expected: { + first_friend_of: Array> + second_friend_of: Array + third_wheel_of: Array + } + expectType>(true) +} + +// join select via column +{ + const { data } = await selectQueries.joinSelectViaColumn.limit(1).single() + let result: Exclude + let expected: { + username: Database['public']['Tables']['users']['Row'] | null + } + expectType>(true) +} + +// join select via column selective +{ + const { data } = await selectQueries.joinSelectViaColumnSelective.limit(1).single() + let result: Exclude + let expected: { + username: { + status: Schema['Enums']['user_status'] | null + } | null + } + expectType>(true) +} + +// join select via column and alias +{ + const { data } = await selectQueries.joinSelectViaColumnAndAlias.limit(1).single() + let result: Exclude + let expected: { + user: Database['public']['Tables']['users']['Row'] | null + } + expectType>(true) +} + +// join select via unique table relationship +{ + const { data } = await selectQueries.joinSelectViaUniqueTableRelationship.limit(1).single() + let result: Exclude + let expected: { + users: Database['public']['Tables']['users']['Row'] | null + } + expectType>(true) +} + +// join select via view name relationship +{ + const { data } = await selectQueries.joinSelectViaViewNameRelationship.limit(1).single() + let result: Exclude + let expected: { + updatable_view: Database['public']['Views']['updatable_view']['Row'] | null + } + expectType>(true) +} + +// join select via column with string templating +{ + const { data } = await selectQueries.selectionWithStringTemplating.limit(1).single() + let result: Exclude + let expected: { + status: Schema['Enums']['user_status'] | null + username: string + } + expectType>(true) +} + +// select with aggregate count function +{ + const { data } = await selectQueries.selectWithAggregateCountFunction.limit(1).single() + let result: Exclude + let expected: { + username: string + messages: Array<{ + count: number + }> + } + expectType>(true) +} + +// select with aggregate count on a column function +{ + const { data } = await selectQueries.selectWithAggregateCountOnAColumnFunction.limit(1).single() + let result: Exclude + let expected: { + username: string + messages: Array<{ + count: number + }> + } + expectType>(true) +} + +// select with aggregate sum function without column should error +{ + const { data } = await selectQueries.selectWithAggregateSumFunctionWithoutColumn.limit(1).single() + let result: Exclude + let expected: { + username: string + messages: SelectQueryError<"column 'sum' does not exist on 'messages'.">[] + } + expectType>(true) +} + +// select with aggregate count function and alias +{ + const { data } = await selectQueries.selectWithAggregateCountFunctionAndAlias.limit(1).single() + let result: Exclude + let expected: { + username: string + messages: Array<{ + message_count: number + }> + } + expectType>(true) +} + +// select with aggregate nested count function +{ + const { data } = await selectQueries.selectWithAggregateNestedCountFunction.limit(1).single() + let result: Exclude + let expected: { + username: string + messages: Array<{ + channels: { + count: number + } + }> + } + expectType>(true) +} + +// select with aggregate nested count function and alias +{ + const { data } = await selectQueries.selectWithAggregateNestedCountFunctionAndAlias + .limit(1) + .single() + let result: Exclude + let expected: { + username: string + messages: Array<{ + channels: { + channel_count: number + } + }> + } + expectType>(true) +} + +// select with aggregate count and spread +{ + const { data } = await selectQueries.selectWithAggregateCountAndSpread.limit(1).single() + let result: Exclude + let expected: { + username: string + messages: Array<{ + channels: { + count: number + details: string | null + } + }> + } + expectType>(true) +} + +// select with aggregate sum function +{ + const { data } = await selectQueries.selectWithAggregateSumFunction.limit(1).single() + let result: Exclude + let expected: { + username: string + messages: Array<{ + sum: number + }> + } + expectType>(true) +} + +// select with aggregate aliased sum function +{ + const { data } = await selectQueries.selectWithAggregateAliasedSumFunction.limit(1).single() + let result: Exclude + let expected: { + username: string + messages: Array<{ + sum_id: number + }> + } + expectType>(true) +} + +// select with aggregate sum function on nested relation +{ + const { data } = await selectQueries.selectWithAggregateSumFunctionOnNestedRelation + .limit(1) + .single() + let result: Exclude + let expected: { + username: string + messages: Array<{ + channels: { + sum: number + } + }> + } + expectType>(true) +} + +// select with aggregate sum and spread +{ + const { data } = await selectQueries.selectWithAggregateSumAndSpread.limit(1).single() + let result: Exclude + let expected: { + username: string + messages: Array<{ + channels: { + sum: number + details: string | null + } + }> + } + expectType>(true) +} + +// select with aggregate sum and spread on nested relation +{ + const { data } = await selectQueries.selectWithAggregateSumAndSpreadOnNestedRelation + .limit(1) + .single() + let result: Exclude + let expected: { + username: string + messages: Array<{ + channels: { + sum: number + details_sum: number | null + details: string | null + } + }> + } + expectType>(true) +} + +// select with spread on nested relation +{ + const { data } = await selectQueries.selectWithSpreadOnNestedRelation.limit(1).single() + let result: Exclude + let expected: { + id: number + channels: { + id: number + details_id: number | null + details: string | null + } + } + expectType>(true) +} + +// select with type casting query +{ + const { data } = await selectQueries.typeCastingQuery.limit(1).single() + let result: Exclude + let expected: { + id: string + } + expectType>(true) +} + +// join with column hinting +{ + const { data } = await selectQueries.joinSelectViaColumnHint.limit(1).single() + let result: Exclude + let expected: { + users: { + age_range: unknown | null + catchphrase: unknown | null + data: Json | null + status: Database['public']['Enums']['user_status'] | null + username: string + } + } + expectType>(true) +} + +// join with same dest twice column hinting +{ + const { data } = await selectQueries.joinSelectViaColumnHintTwice.limit(1).single() + let result: Exclude + let expected: { + users: SelectQueryError<'table "best_friends" specified more than once use hinting for desambiguation'> + } + expectType>(true) +} + +// join with same dest twice column hinting +{ + const { data } = await selectQueries.selectSpreadOnManyRelation.limit(1).single() + let result: Exclude + let expected: { + id: number + messages: SelectQueryError<'"channels" and "messages" do not form a many-to-one or one-to-one relationship spread not possible'> + } + expectType>(true) +} + +// multiple times the same column in selection +{ + const { data } = await selectQueries.selectWithDuplicatesFields.limit(1).single() + let result: Exclude + let expected: { + id: number + } + expectType>(true) +} + +// embed resource with no fields +{ + const { data } = await selectQueries.selectEmbedRessourceWithNoFields.limit(1).single() + let result: Exclude + let expected: { + message: string | null + } + expectType>(true) +} + +// select JSON accessor +{ + const { data } = await selectQueries.selectJsonAccessor + .limit(1) + .filter('username', 'eq', 'jsonuser') + .single() + let result: Exclude + let expected: { + bar: Json + baz: string + } + expectType>(true) +} + +// typecasting and aggregate +{ + const { data } = await selectQueries.typecastingAndAggregate.limit(1).single() + let result: Exclude + let expected: SelectQueryError<`column 'users' does not exist on 'messages'.`> + expectType>(true) +} + +// inner join on many relation +{ + const { data } = await selectQueries.innerJoinOnManyRelation.limit(1).single() + let result: Exclude + let expected: { + id: number + messages: { + id: number + username: string + }[] + } + expectType>(true) +} + +// self reference relation +{ + const { data } = await selectQueries.selfReferenceRelation.limit(1).single() + let result: Exclude + let expected: { + id: number + description: string | null + parent_id: number | null + collections: { + id: number + description: string | null + parent_id: number | null + }[] + } + expectType>(true) +} + +// self reference relation via column +{ + const { data } = await selectQueries.selfReferenceRelationViaColumn.limit(1).single() + let result: Exclude + let expected: { + description: string | null + id: number + parent_id: + | (number & { + description: string | null + id: number + parent_id: number | null + }) + | null + } + expectType>(true) +} + +// aggregate on missing column with alias +{ + const { data, error } = await selectQueries.aggregateOnMissingColumnWithAlias.limit(1).single() + if (error) throw error + expectType>(data) +} diff --git a/test/select-query-parser/types.test-d.ts b/test/select-query-parser/types.test-d.ts new file mode 100644 index 00000000..9957e0e5 --- /dev/null +++ b/test/select-query-parser/types.test-d.ts @@ -0,0 +1,162 @@ +import { Database } from '../types' +import { selectParams } from '../relationships' +import { + ProcessEmbeddedResource, + ProcessNode, + ProcessNodes, +} from '../../src/select-query-parser/result' +import { expectType } from 'tsd' +import { TypeEqual } from 'ts-expect' +import { + FindMatchingTableRelationships, + IsRelationNullable, +} from '../../src/select-query-parser/utils' +import { Json } from '../../src/select-query-parser/types' +import { ParseQuery } from '../../src/select-query-parser/parser' + +// This test file is here to ensure some of our helpers behave as expected for ease of development +// and debugging purposes + +// Searching for a relationship by direct foreignkey name +{ + let result: FindMatchingTableRelationships< + Database['public'], + Database['public']['Tables']['best_friends']['Relationships'], + 'best_friends_first_user_fkey' + > + let expected: { + foreignKeyName: 'best_friends_first_user_fkey' + columns: ['first_user'] + isOneToOne: false + referencedRelation: 'users' + referencedColumns: ['username'] + } & { match: 'fkname' } + expectType>(true) +} +// Searching for a relationship by column hoding the value reference +{ + let result: FindMatchingTableRelationships< + Database['public'], + Database['public']['Tables']['best_friends']['Relationships'], + 'first_user' + > + let expected: { + foreignKeyName: 'best_friends_first_user_fkey' + columns: ['first_user'] + isOneToOne: false + referencedRelation: 'users' + referencedColumns: ['username'] + } & { match: 'col' } + expectType>(true) +} +// should return the relation matching the "Tables" references +{ + let result: FindMatchingTableRelationships< + Database['public'], + Database['public']['Tables']['user_profiles']['Relationships'], + 'username' + > + let expected: { + foreignKeyName: 'user_profiles_username_fkey' + columns: ['username'] + isOneToOne: false + referencedRelation: 'users' + referencedColumns: ['username'] + } & { match: 'col' } + expectType>(true) +} +// Searching for a relationship by referenced table name +{ + let result: FindMatchingTableRelationships< + Database['public'], + Database['public']['Tables']['messages']['Relationships'], + 'users' + > + let expected: { + foreignKeyName: 'messages_username_fkey' + columns: ['username'] + isOneToOne: false + referencedRelation: 'users' + referencedColumns: ['username'] + } & { match: 'refrel' } + expectType>(true) +} +{ + let result: FindMatchingTableRelationships< + Database['public'], + Database['public']['Tables']['messages']['Relationships'], + 'channels' + > + let expected: { + foreignKeyName: 'messages_channel_id_fkey' + columns: ['channel_id'] + isOneToOne: false + referencedRelation: 'channels' + referencedColumns: ['id'] + } & { match: 'refrel' } + expectType>(true) +} + +// IsRelationNullable +{ + type BestFriendsTable = Database['public']['Tables']['best_friends'] + type NonNullableRelation = FindMatchingTableRelationships< + Database['public'], + BestFriendsTable['Relationships'], + 'best_friends_first_user_fkey' + > + type NullableRelation = FindMatchingTableRelationships< + Database['public'], + BestFriendsTable['Relationships'], + 'best_friends_third_wheel_fkey' + > + let nonNullableResult: IsRelationNullable + let nullableResult: IsRelationNullable + expectType(false) + expectType(true) +} + +// Test nodes relations crawling utils +{ + const { from, select } = selectParams.nestedQueryWithSelectiveFields + type Schema = Database['public'] + type RelationName = typeof from + type Row = Schema['Tables'][RelationName]['Row'] + type Relationships = Schema['Tables'][RelationName]['Relationships'] + type ParsedQuery = ParseQuery + // First field of the query is username and is properly parsed + type f1 = ParsedQuery[0] + type r1 = ProcessNode + expectType>(true) + type f2 = ParsedQuery[1] + type r2 = ProcessNodes + // fail because result for messages is ({id: string} | {message: string | null })[] + expectType< + TypeEqual + >(true) + type f3 = ParsedQuery[1] + type r3 = ProcessEmbeddedResource + expectType>(true) +} +// Select from the column holding the relation (0-1 relation) +{ + const { from, select } = selectParams.joinSelectViaColumn + type Schema = Database['public'] + type RelationName = typeof from + type Row = Schema['Tables'][RelationName]['Row'] + type Relationships = Schema['Tables'][RelationName]['Relationships'] + type ParsedQuery = ParseQuery + type r1 = ProcessNode + let expected: { + username: { + age_range: unknown | null + catchphrase: unknown | null + data: Json | null + status: Database['public']['Enums']['user_status'] | null + username: string + } | null + } + expectType(expected!) + type r2 = ProcessNodes + expectType(expected!) +} diff --git a/test/smoke.cjs b/test/smoke.cjs new file mode 100644 index 00000000..610dacfa --- /dev/null +++ b/test/smoke.cjs @@ -0,0 +1,15 @@ +// Check that the ESM build works as expected (namely has the same exports as the CJS build when imported via ESM). +const assert = require("node:assert"); +const postgrestjs = require("@supabase/postgrest-js"); + +assert(typeof postgrestjs.PostgrestClient === "function"); +assert(typeof postgrestjs.PostgrestQueryBuilder === "function"); +assert(typeof postgrestjs.PostgrestFilterBuilder === "function"); +assert(typeof postgrestjs.PostgrestTransformBuilder === "function"); +assert(typeof postgrestjs.PostgrestBuilder === "function"); +assert(typeof postgrestjs.default === 'object'); +assert(typeof postgrestjs.default.PostgrestClient === 'function'); +assert(typeof postgrestjs.default.PostgrestQueryBuilder === 'function'); +assert(typeof postgrestjs.default.PostgrestFilterBuilder === 'function'); +assert(typeof postgrestjs.default.PostgrestTransformBuilder === 'function'); +assert(typeof postgrestjs.default.PostgrestBuilder === 'function'); diff --git a/test/smoke.mjs b/test/smoke.mjs new file mode 100644 index 00000000..caf22bbe --- /dev/null +++ b/test/smoke.mjs @@ -0,0 +1,15 @@ +// Check that the ESM build works as expected (namely has the same exports as the CJS build when imported via ESM). +import assert from "node:assert"; +import * as postgrestjs from "@supabase/postgrest-js"; + +assert(typeof postgrestjs.PostgrestClient === 'function'); +assert(typeof postgrestjs.PostgrestQueryBuilder === 'function'); +assert(typeof postgrestjs.PostgrestFilterBuilder === 'function'); +assert(typeof postgrestjs.PostgrestTransformBuilder === 'function'); +assert(typeof postgrestjs.PostgrestBuilder === 'function'); +assert(typeof postgrestjs.default === 'object'); +assert(typeof postgrestjs.default.PostgrestClient === 'function'); +assert(typeof postgrestjs.default.PostgrestQueryBuilder === 'function'); +assert(typeof postgrestjs.default.PostgrestFilterBuilder === 'function'); +assert(typeof postgrestjs.default.PostgrestTransformBuilder === 'function'); +assert(typeof postgrestjs.default.PostgrestBuilder === 'function'); diff --git a/test/transforms.ts b/test/transforms.ts index 98b310cc..e6518910 100644 --- a/test/transforms.ts +++ b/test/transforms.ts @@ -7,7 +7,58 @@ const postgrest = new PostgrestClient('http://localhost:3000') test('order', async () => { const res = await postgrest.from('users').select().order('username', { ascending: false }) - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "age_range": "[1,2)", + "catchphrase": "'cat' 'fat'", + "data": null, + "status": "ONLINE", + "username": "supabot", + }, + Object { + "age_range": "[25,35)", + "catchphrase": "'bat' 'cat'", + "data": null, + "status": "OFFLINE", + "username": "kiwicopple", + }, + Object { + "age_range": "[20,30)", + "catchphrase": "'json' 'test'", + "data": Object { + "foo": Object { + "bar": Object { + "nested": "value", + }, + "baz": "string value", + }, + }, + "status": "ONLINE", + "username": "jsonuser", + }, + Object { + "age_range": "[20,30)", + "catchphrase": "'fat' 'rat'", + "data": null, + "status": "ONLINE", + "username": "dragarcia", + }, + Object { + "age_range": "[25,35)", + "catchphrase": "'bat' 'rat'", + "data": null, + "status": "ONLINE", + "username": "awailas", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('order on multiple columns', async () => { @@ -16,39 +67,192 @@ test('order on multiple columns', async () => { .select() .order('channel_id', { ascending: false }) .order('username', { ascending: false }) - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "channel_id": 3, + "data": null, + "id": 4, + "message": "Some message on channel wihtout details", + "username": "supabot", + }, + Object { + "channel_id": 2, + "data": null, + "id": 2, + "message": "Perfection is attained, not when there is nothing more to add, but when there is nothing left to take away.", + "username": "supabot", + }, + Object { + "channel_id": 1, + "data": null, + "id": 1, + "message": "Hello World 👋", + "username": "supabot", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('limit', async () => { const res = await postgrest.from('users').select().limit(1) - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "age_range": "[1,2)", + "catchphrase": "'cat' 'fat'", + "data": null, + "status": "ONLINE", + "username": "supabot", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('range', async () => { const res = await postgrest.from('users').select().range(1, 3) - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "age_range": "[25,35)", + "catchphrase": "'bat' 'cat'", + "data": null, + "status": "OFFLINE", + "username": "kiwicopple", + }, + Object { + "age_range": "[25,35)", + "catchphrase": "'bat' 'rat'", + "data": null, + "status": "ONLINE", + "username": "awailas", + }, + Object { + "age_range": "[20,30)", + "catchphrase": "'json' 'test'", + "data": Object { + "foo": Object { + "bar": Object { + "nested": "value", + }, + "baz": "string value", + }, + }, + "status": "ONLINE", + "username": "jsonuser", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('single', async () => { const res = await postgrest.from('users').select().limit(1).single() - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "age_range": "[1,2)", + "catchphrase": "'cat' 'fat'", + "data": null, + "status": "ONLINE", + "username": "supabot", + }, + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('single on insert', async () => { const res = await postgrest.from('users').insert({ username: 'foo' }).select().single() - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Object { + "age_range": null, + "catchphrase": null, + "data": null, + "status": "ONLINE", + "username": "foo", + }, + "error": null, + "status": 201, + "statusText": "Created", + } + `) await postgrest.from('users').delete().eq('username', 'foo') }) test('maybeSingle', async () => { const res = await postgrest.from('users').select().eq('username', 'goldstein').maybeSingle() - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": null, + "error": null, + "status": 200, + "statusText": "OK", + } + `) +}) + +test('maybeSingle', async () => { + const res = await postgrest + .from('users') + .insert([{ username: 'a' }, { username: 'b' }]) + .select() + .maybeSingle() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": null, + "error": Object { + "code": "PGRST116", + "details": "The result contains 2 rows", + "hint": null, + "message": "JSON object requested, multiple (or no) rows returned", + }, + "status": 406, + "statusText": "Not Acceptable", + } + `) }) test('select on insert', async () => { const res = await postgrest.from('users').insert({ username: 'foo' }).select('status') - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "status": "ONLINE", + }, + ], + "error": null, + "status": 201, + "statusText": "Created", + } + `) await postgrest.from('users').delete().eq('username', 'foo') }) @@ -57,7 +261,19 @@ test('select on rpc', async () => { const res = await postgrest .rpc('get_username_and_status', { name_param: 'supabot' }) .select('status') - expect(res).toMatchSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "status": "ONLINE", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('csv', async () => { @@ -69,6 +285,7 @@ test('csv', async () => { supabot,,\\"[1,2)\\",ONLINE,\\"'cat' 'fat'\\" kiwicopple,,\\"[25,35)\\",OFFLINE,\\"'bat' 'cat'\\" awailas,,\\"[25,35)\\",ONLINE,\\"'bat' 'rat'\\" + jsonuser,\\"{\\"\\"foo\\"\\": {\\"\\"bar\\"\\": {\\"\\"nested\\"\\": \\"\\"value\\"\\"}, \\"\\"baz\\"\\": \\"\\"string value\\"\\"}}\\",\\"[20,30)\\",ONLINE,\\"'json' 'test'\\" dragarcia,,\\"[20,30)\\",ONLINE,\\"'fat' 'rat'\\"", "error": null, "status": 200, @@ -81,20 +298,29 @@ test('abort signal', async () => { const ac = new AbortController() as globalThis.AbortController ac.abort() const res = await postgrest.from('users').select().abortSignal(ac.signal) - expect(res).toMatchInlineSnapshot(` + expect(res).toMatchInlineSnapshot( + { + error: { + code: expect.any(String), + details: expect.any(String), + message: expect.stringMatching(/^AbortError:/), + }, + }, + ` Object { "count": null, "data": null, "error": Object { - "code": "", - "details": "", + "code": Any, + "details": Any, "hint": "", - "message": "FetchError: The user aborted a request.", + "message": StringMatching /\\^AbortError:/, }, "status": 0, "statusText": "", } - `) + ` + ) }) // test('geojson', async () => { @@ -104,50 +330,31 @@ test('abort signal', async () => { test('explain with json/text format', async () => { const res1 = await postgrest.from('users').select().explain({ format: 'json' }) - expect(res1).toMatchInlineSnapshot(` + expect(res1).toMatchInlineSnapshot( + { + data: [ + { + Plan: expect.any(Object), + }, + ], + }, + ` Object { "count": null, "data": Array [ Object { - "Plan": Object { - "Async Capable": false, - "Node Type": "Aggregate", - "Parallel Aware": false, - "Partial Mode": "Simple", - "Plan Rows": 1, - "Plan Width": 112, - "Plans": Array [ - Object { - "Alias": "users", - "Async Capable": false, - "Node Type": "Seq Scan", - "Parallel Aware": false, - "Parent Relationship": "Outer", - "Plan Rows": 510, - "Plan Width": 132, - "Relation Name": "users", - "Startup Cost": 0, - "Total Cost": 15.1, - }, - ], - "Startup Cost": 17.65, - "Strategy": "Plain", - "Total Cost": 17.68, - }, + "Plan": Any, }, ], "error": null, "status": 200, "statusText": "OK", } - `) + ` + ) const res2 = await postgrest.from('users').select().explain() - expect(res2.data).toMatch( - `Aggregate (cost=17.65..17.68 rows=1 width=112) - -> Seq Scan on users (cost=0.00..15.10 rows=510 width=132) -` - ) + expect(res2.data).toMatch(/Aggregate \(cost=.*/) }) test('explain with options', async () => { @@ -155,52 +362,22 @@ test('explain with options', async () => { .from('users') .select() .explain({ verbose: true, settings: true, format: 'json' }) - expect(res).toMatchInlineSnapshot(` + expect(res).toMatchInlineSnapshot( + { + data: [ + { + Plan: expect.any(Object), + 'Query Identifier': expect.any(Number), + }, + ], + }, + ` Object { "count": null, "data": Array [ Object { - "Plan": Object { - "Async Capable": false, - "Node Type": "Aggregate", - "Output": Array [ - "NULL::bigint", - "count(ROW(users.username, users.data, users.age_range, users.status, users.catchphrase))", - "(COALESCE(json_agg(ROW(users.username, users.data, users.age_range, users.status, users.catchphrase)), '[]'::json))::character varying", - "NULLIF(current_setting('response.headers'::text, true), ''::text)", - "NULLIF(current_setting('response.status'::text, true), ''::text)", - ], - "Parallel Aware": false, - "Partial Mode": "Simple", - "Plan Rows": 1, - "Plan Width": 112, - "Plans": Array [ - Object { - "Alias": "users", - "Async Capable": false, - "Node Type": "Seq Scan", - "Output": Array [ - "users.username", - "users.data", - "users.age_range", - "users.status", - "users.catchphrase", - ], - "Parallel Aware": false, - "Parent Relationship": "Outer", - "Plan Rows": 510, - "Plan Width": 132, - "Relation Name": "users", - "Schema": "public", - "Startup Cost": 0, - "Total Cost": 15.1, - }, - ], - "Startup Cost": 17.65, - "Strategy": "Plain", - "Total Cost": 17.68, - }, - "Query Identifier": -8888327821402777000, + "Plan": Any, + "Query Identifier": Any, "Settings": Object { "effective_cache_size": "128MB", "search_path": "\\"public\\", \\"extensions\\"", @@ -211,7 +388,8 @@ test('explain with options', async () => { "status": 200, "statusText": "OK", } - `) + ` + ) }) test('rollback insert/upsert', async () => { diff --git a/test/types.ts b/test/types.ts index 5a24428e..2d601877 100644 --- a/test/types.ts +++ b/test/types.ts @@ -1,27 +1,28 @@ -export type Json = string | number | boolean | null | { [key: string]: Json } | Json[] +export type Json = string | number | boolean | null | { [key: string]: Json | undefined } | Json[] -export interface Database { +export type Database = { personal: { Tables: { users: { Row: { - username: string - data: Json | null age_range: unknown | null + data: Json | null status: Database['public']['Enums']['user_status'] | null + username: string } Insert: { - username: string - data?: Json | null age_range?: unknown | null + data?: Json | null status?: Database['public']['Enums']['user_status'] | null + username: string } Update: { - username?: string - data?: Json | null age_range?: unknown | null + data?: Json | null status?: Database['public']['Enums']['user_status'] | null + username?: string } + Relationships: [] } } Views: { @@ -29,95 +30,304 @@ export interface Database { } Functions: { get_status: { - Args: { name_param: string } + Args: { + name_param: string + } Returns: Database['public']['Enums']['user_status'] } } Enums: { user_status: 'ONLINE' | 'OFFLINE' } + CompositeTypes: { + [_ in never]: never + } } public: { Tables: { - shops: { + best_friends: { Row: { + first_user: string id: number - address: string | null - shop_geom: unknown | null + second_user: string + third_wheel: string | null } Insert: { - id: number - address?: string | null - shop_geom?: unknown | null + first_user: string + id?: number + second_user: string + third_wheel?: string | null } Update: { + first_user?: string id?: number - address?: string | null - shop_geom?: unknown | null + second_user?: string + third_wheel?: string | null } + Relationships: [ + { + foreignKeyName: 'best_friends_first_user_fkey' + columns: ['first_user'] + isOneToOne: false + referencedRelation: 'non_updatable_view' + referencedColumns: ['username'] + }, + { + foreignKeyName: 'best_friends_first_user_fkey' + columns: ['first_user'] + isOneToOne: false + referencedRelation: 'updatable_view' + referencedColumns: ['username'] + }, + { + foreignKeyName: 'best_friends_first_user_fkey' + columns: ['first_user'] + isOneToOne: false + referencedRelation: 'users' + referencedColumns: ['username'] + }, + { + foreignKeyName: 'best_friends_second_user_fkey' + columns: ['second_user'] + isOneToOne: false + referencedRelation: 'non_updatable_view' + referencedColumns: ['username'] + }, + { + foreignKeyName: 'best_friends_second_user_fkey' + columns: ['second_user'] + isOneToOne: false + referencedRelation: 'updatable_view' + referencedColumns: ['username'] + }, + { + foreignKeyName: 'best_friends_second_user_fkey' + columns: ['second_user'] + isOneToOne: false + referencedRelation: 'users' + referencedColumns: ['username'] + }, + { + foreignKeyName: 'best_friends_third_wheel_fkey' + columns: ['third_wheel'] + isOneToOne: false + referencedRelation: 'non_updatable_view' + referencedColumns: ['username'] + }, + { + foreignKeyName: 'best_friends_third_wheel_fkey' + columns: ['third_wheel'] + isOneToOne: false + referencedRelation: 'updatable_view' + referencedColumns: ['username'] + }, + { + foreignKeyName: 'best_friends_third_wheel_fkey' + columns: ['third_wheel'] + isOneToOne: false + referencedRelation: 'users' + referencedColumns: ['username'] + } + ] } - users: { + channel_details: { Row: { - username: string - data: Json | null - age_range: unknown | null - catchphrase: unknown | null - status: Database['public']['Enums']['user_status'] | null + details: string | null + id: number } Insert: { - username: string - data?: Json | null - age_range?: unknown | null - catchphrase?: unknown | null - status?: Database['public']['Enums']['user_status'] | null + details?: string | null + id: number } Update: { - username?: string - data?: Json | null - age_range?: unknown | null - catchphrase?: unknown | null - status?: Database['public']['Enums']['user_status'] | null + details?: string | null + id?: number } + Relationships: [ + { + foreignKeyName: 'channel_details_id_fkey' + columns: ['id'] + isOneToOne: true + referencedRelation: 'channels' + referencedColumns: ['id'] + } + ] } channels: { Row: { - id: number data: Json | null + id: number slug: string | null } Insert: { - id?: number data?: Json | null + id?: number slug?: string | null } Update: { - id?: number data?: Json | null + id?: number slug?: string | null } + Relationships: [] } - messages: { + collections: { Row: { + description: string | null id: number + parent_id: number | null + } + Insert: { + description?: string | null + id?: number + parent_id?: number | null + } + Update: { + description?: string | null + id?: number + parent_id?: number | null + } + Relationships: [ + { + foreignKeyName: 'collections_parent_id_fkey' + columns: ['parent_id'] + isOneToOne: false + referencedRelation: 'collections' + referencedColumns: ['id'] + } + ] + } + messages: { + Row: { + channel_id: number data: Json | null + id: number message: string | null username: string - channel_id: number } Insert: { - id?: number + channel_id: number data?: Json | null + id?: number message?: string | null username: string - channel_id: number } Update: { - id?: number + channel_id?: number data?: Json | null + id?: number message?: string | null username?: string - channel_id?: number } + Relationships: [ + { + foreignKeyName: 'messages_channel_id_fkey' + columns: ['channel_id'] + isOneToOne: false + referencedRelation: 'channels' + referencedColumns: ['id'] + }, + { + foreignKeyName: 'messages_username_fkey' + columns: ['username'] + isOneToOne: false + referencedRelation: 'non_updatable_view' + referencedColumns: ['username'] + }, + { + foreignKeyName: 'messages_username_fkey' + columns: ['username'] + isOneToOne: false + referencedRelation: 'updatable_view' + referencedColumns: ['username'] + }, + { + foreignKeyName: 'messages_username_fkey' + columns: ['username'] + isOneToOne: false + referencedRelation: 'users' + referencedColumns: ['username'] + } + ] + } + shops: { + Row: { + address: string | null + id: number + shop_geom: unknown | null + } + Insert: { + address?: string | null + id: number + shop_geom?: unknown | null + } + Update: { + address?: string | null + id?: number + shop_geom?: unknown | null + } + Relationships: [] + } + users: { + Row: { + age_range: unknown | null + catchphrase: unknown | null + data: Json | null + status: Database['public']['Enums']['user_status'] | null + username: string + } + Insert: { + age_range?: unknown | null + catchphrase?: unknown | null + data?: Json | null + status?: Database['public']['Enums']['user_status'] | null + username: string + } + Update: { + age_range?: unknown | null + catchphrase?: unknown | null + data?: Json | null + status?: Database['public']['Enums']['user_status'] | null + username?: string + } + Relationships: [] + } + user_profiles: { + Row: { + id: number + username: string | null + } + Insert: { + id?: number + username?: string | null + } + Update: { + id?: number + username?: string | null + } + Relationships: [ + { + foreignKeyName: 'user_profiles_username_fkey' + columns: ['username'] + isOneToOne: false + referencedRelation: 'non_updatable_view' + referencedColumns: ['username'] + }, + { + foreignKeyName: 'user_profiles_username_fkey' + columns: ['username'] + isOneToOne: false + referencedRelation: 'updatable_view' + referencedColumns: ['username'] + }, + { + foreignKeyName: 'user_profiles_username_fkey' + columns: ['username'] + isOneToOne: false + referencedRelation: 'users' + referencedColumns: ['username'] + } + ] } } Views: { @@ -125,33 +335,56 @@ export interface Database { Row: { username: string | null } + Relationships: [] } updatable_view: { Row: { - username: string | null non_updatable_column: number | null + username: string | null } Insert: { - username?: string | null non_updatable_column?: never + username?: string | null } Update: { - username?: string | null non_updatable_column?: never + username?: string | null } + Relationships: [] } } Functions: { + function_with_array_param: { + Args: { + param: string[] + } + Returns: undefined + } + function_with_optional_param: { + Args: { + param?: string + } + Returns: string + } get_status: { - Args: { name_param: string } + Args: { + name_param: string + } Returns: Database['public']['Enums']['user_status'] } get_username_and_status: { - Args: { name_param: string } - Returns: Record[] + Args: { + name_param: string + } + Returns: { + username: string + status: Database['public']['Enums']['user_status'] + }[] } offline_user: { - Args: { name_param: string } + Args: { + name_param: string + } Returns: Database['public']['Enums']['user_status'] } void_func: { @@ -162,5 +395,82 @@ export interface Database { Enums: { user_status: 'ONLINE' | 'OFFLINE' } + CompositeTypes: { + [_ in never]: never + } } } + +type PublicSchema = Database[Extract] + +export type Tables< + PublicTableNameOrOptions extends + | keyof (PublicSchema['Tables'] & PublicSchema['Views']) + | { schema: keyof Database }, + TableName extends PublicTableNameOrOptions extends { schema: keyof Database } + ? keyof (Database[PublicTableNameOrOptions['schema']]['Tables'] & + Database[PublicTableNameOrOptions['schema']]['Views']) + : never = never +> = PublicTableNameOrOptions extends { schema: keyof Database } + ? (Database[PublicTableNameOrOptions['schema']]['Tables'] & + Database[PublicTableNameOrOptions['schema']]['Views'])[TableName] extends { + Row: infer R + } + ? R + : never + : PublicTableNameOrOptions extends keyof (PublicSchema['Tables'] & PublicSchema['Views']) + ? (PublicSchema['Tables'] & PublicSchema['Views'])[PublicTableNameOrOptions] extends { + Row: infer R + } + ? R + : never + : never + +export type TablesInsert< + PublicTableNameOrOptions extends keyof PublicSchema['Tables'] | { schema: keyof Database }, + TableName extends PublicTableNameOrOptions extends { schema: keyof Database } + ? keyof Database[PublicTableNameOrOptions['schema']]['Tables'] + : never = never +> = PublicTableNameOrOptions extends { schema: keyof Database } + ? Database[PublicTableNameOrOptions['schema']]['Tables'][TableName] extends { + Insert: infer I + } + ? I + : never + : PublicTableNameOrOptions extends keyof PublicSchema['Tables'] + ? PublicSchema['Tables'][PublicTableNameOrOptions] extends { + Insert: infer I + } + ? I + : never + : never + +export type TablesUpdate< + PublicTableNameOrOptions extends keyof PublicSchema['Tables'] | { schema: keyof Database }, + TableName extends PublicTableNameOrOptions extends { schema: keyof Database } + ? keyof Database[PublicTableNameOrOptions['schema']]['Tables'] + : never = never +> = PublicTableNameOrOptions extends { schema: keyof Database } + ? Database[PublicTableNameOrOptions['schema']]['Tables'][TableName] extends { + Update: infer U + } + ? U + : never + : PublicTableNameOrOptions extends keyof PublicSchema['Tables'] + ? PublicSchema['Tables'][PublicTableNameOrOptions] extends { + Update: infer U + } + ? U + : never + : never + +export type Enums< + PublicEnumNameOrOptions extends keyof PublicSchema['Enums'] | { schema: keyof Database }, + EnumName extends PublicEnumNameOrOptions extends { schema: keyof Database } + ? keyof Database[PublicEnumNameOrOptions['schema']]['Enums'] + : never = never +> = PublicEnumNameOrOptions extends { schema: keyof Database } + ? Database[PublicEnumNameOrOptions['schema']]['Enums'][EnumName] + : PublicEnumNameOrOptions extends keyof PublicSchema['Enums'] + ? PublicSchema['Enums'][PublicEnumNameOrOptions] + : never diff --git a/tsconfig.json b/tsconfig.json index fabd608d..27ce6487 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,10 +4,9 @@ "declaration": true, "declarationMap": true, "module": "CommonJS", - "outDir": "dist/main", - "rootDir": "src", + "outDir": "dist/cjs", "sourceMap": true, - "target": "ES2015", + "target": "ES2017", "strict": true, diff --git a/tsconfig.module.json b/tsconfig.module.json deleted file mode 100644 index 8726ca43..00000000 --- a/tsconfig.module.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "./tsconfig", - "compilerOptions": { - "module": "ES2020", - "outDir": "dist/module" - } -} diff --git a/wrapper.mjs b/wrapper.mjs new file mode 100644 index 00000000..55629686 --- /dev/null +++ b/wrapper.mjs @@ -0,0 +1,25 @@ +import index from '../cjs/index.js' +const { + PostgrestClient, + PostgrestQueryBuilder, + PostgrestFilterBuilder, + PostgrestTransformBuilder, + PostgrestBuilder, +} = index + +export { + PostgrestBuilder, + PostgrestClient, + PostgrestFilterBuilder, + PostgrestQueryBuilder, + PostgrestTransformBuilder, +} + +// compatibility with CJS output +export default { + PostgrestClient, + PostgrestQueryBuilder, + PostgrestFilterBuilder, + PostgrestTransformBuilder, + PostgrestBuilder, +}