From 15bdb1a14618f285235f5b21509e2c951227aaea Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Fri, 14 Oct 2022 13:04:06 +0800 Subject: [PATCH 001/110] docs: fix typedoc link --- README.md | 2 +- docs/v1/index.html | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) 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 + From 4081771fd301312770fec7ec723d48f0860d7214 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Tue, 18 Oct 2022 16:18:29 +0800 Subject: [PATCH 002/110] feat: allow overriding result types --- package-lock.json | 1120 ++++++++++++++++++++++++++++-- package.json | 12 +- src/PostgrestBuilder.ts | 2 +- src/PostgrestClient.ts | 11 +- src/PostgrestFilterBuilder.ts | 4 +- src/PostgrestQueryBuilder.ts | 19 +- src/PostgrestTransformBuilder.ts | 23 +- src/select-query-parser.ts | 62 +- 8 files changed, 1143 insertions(+), 110 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4f4e2619..65c6d6d5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,8 +20,9 @@ "rimraf": "^3.0.2", "semantic-release-plugin-update-version-in-files": "^1.1.0", "ts-jest": "^28.0.3", + "tsd": "^0.24.1", "typedoc": "^0.22.16", - "typescript": "~4.7", + "typescript": "~4.8", "wait-for-localhost-cli": "^3.0.0" } }, @@ -970,6 +971,41 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "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": { "version": "0.23.5", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.23.5.tgz", @@ -994,6 +1030,12 @@ "@sinonjs/commons": "^1.7.0" } }, + "node_modules/@tsd/typescript": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/@tsd/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-WMFNVstwWGyDuZP2LGPRZ+kPHxZLmhO+2ormstDvnXiyoBPtW1qq9XhhrkI4NVtxgs+2ZiUTl9AG7nNIRq/uCg==", + "dev": true + }, "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 +1083,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 +1142,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", @@ -1191,6 +1255,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", @@ -1678,6 +1751,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,6 +1865,34 @@ "node": ">=0.8.0" } }, + "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, + "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", @@ -1963,12 +2085,37 @@ "integrity": "sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==", "dev": true }, + "node_modules/fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "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", @@ -2088,6 +2235,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 +2256,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 +2345,15 @@ "node": ">=10.17.0" } }, + "node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "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 +2410,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 +2461,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 +2488,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 +2560,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", @@ -3477,6 +3707,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", @@ -3653,6 +3899,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", @@ -4132,6 +4387,21 @@ "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", @@ -4186,6 +4456,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 +4728,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 +4753,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", @@ -4829,83 +5152,338 @@ "node": ">=4" } }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/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, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ts-jest": { + "version": "28.0.3", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-28.0.3.tgz", + "integrity": "sha512-HzgbEDQ2KgVtDmpXToqAcKTyGHdHsG23i/iUjfxji92G5eT09S1m9UHZd7csF0Bfgh9txM4JzwHnv7r1waFPlw==", + "dev": true, + "dependencies": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^28.0.0", + "json5": "^2.2.1", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "7.x", + "yargs-parser": "^20.x" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@types/jest": "^27.0.0", + "babel-jest": "^28.0.0", + "jest": "^28.0.0", + "typescript": ">=4.3" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@types/jest": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "node_modules/ts-jest/node_modules/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tsd": { + "version": "0.24.1", + "resolved": "https://registry.npmjs.org/tsd/-/tsd-0.24.1.tgz", + "integrity": "sha512-sD+s81/2aM4RRhimCDttd4xpBNbUFWnoMSHk/o8kC8Ek23jljeRNWjsxFJmOmYLuLTN9swRt1b6iXfUXTcTiIA==", + "dev": true, + "dependencies": { + "@tsd/typescript": "~4.8.3", + "eslint-formatter-pretty": "^4.1.0", + "globby": "^11.0.1", + "meow": "^9.0.0", + "path-exists": "^4.0.0", + "read-pkg-up": "^7.0.0" + }, + "bin": { + "tsd": "dist/cli.js" + }, + "engines": { + "node": ">=14.16" + } + }, + "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/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/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/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/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": { - "is-number": "^7.0.0" + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" }, "engines": { - "node": ">=8.0" + "node": ">=8" } }, - "node_modules/trim-newlines": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-4.0.2.tgz", - "integrity": "sha512-GJtWyq9InR/2HRiLZgpIKv+ufIKrVrvjQWEj7PxAXNc5dwbNJkqhAUoAGgzRmULAnoOM5EIpveYd3J2VeSAIew==", + "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, - "engines": { - "node": ">=12" + "dependencies": { + "lru-cache": "^6.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "node_modules/ts-jest": { - "version": "28.0.3", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-28.0.3.tgz", - "integrity": "sha512-HzgbEDQ2KgVtDmpXToqAcKTyGHdHsG23i/iUjfxji92G5eT09S1m9UHZd7csF0Bfgh9txM4JzwHnv7r1waFPlw==", + "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": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^28.0.0", - "json5": "^2.2.1", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "7.x", - "yargs-parser": "^20.x" - }, - "bin": { - "ts-jest": "cli.js" + "min-indent": "^1.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - }, - "peerDependencies": { - "@babel/core": ">=7.0.0-beta.0 <8", - "@types/jest": "^27.0.0", - "babel-jest": "^28.0.0", - "jest": "^28.0.0", - "typescript": ">=4.3" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "@types/jest": { - "optional": true - }, - "babel-jest": { - "optional": true - }, - "esbuild": { - "optional": true - } + "node": ">=8" } }, - "node_modules/ts-jest/node_modules/semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "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, - "bin": { - "semver": "bin/semver.js" - }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/type-detect": { @@ -4992,9 +5570,9 @@ } }, "node_modules/typescript": { - "version": "4.7.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", - "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -5924,6 +6502,32 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "@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": { "version": "0.23.5", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.23.5.tgz", @@ -5948,6 +6552,12 @@ "@sinonjs/commons": "^1.7.0" } }, + "@tsd/typescript": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/@tsd/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-WMFNVstwWGyDuZP2LGPRZ+kPHxZLmhO+2ormstDvnXiyoBPtW1qq9XhhrkI4NVtxgs+2ZiUTl9AG7nNIRq/uCg==", + "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 +6605,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 +6664,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", @@ -6127,6 +6759,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", @@ -6483,6 +7121,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 +7207,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 +7370,34 @@ } } }, + "fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "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", @@ -6784,12 +7483,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 +7563,12 @@ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true + }, "import-local": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", @@ -6879,6 +7607,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 +7640,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 +7658,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 +7703,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", @@ -7830,6 +8585,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", @@ -7959,6 +8724,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", @@ -8333,6 +9104,15 @@ "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", @@ -8368,6 +9148,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 +9320,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 +9335,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", @@ -8876,6 +9677,195 @@ } } }, + "tsd": { + "version": "0.24.1", + "resolved": "https://registry.npmjs.org/tsd/-/tsd-0.24.1.tgz", + "integrity": "sha512-sD+s81/2aM4RRhimCDttd4xpBNbUFWnoMSHk/o8kC8Ek23jljeRNWjsxFJmOmYLuLTN9swRt1b6iXfUXTcTiIA==", + "dev": true, + "requires": { + "@tsd/typescript": "~4.8.3", + "eslint-formatter-pretty": "^4.1.0", + "globby": "^11.0.1", + "meow": "^9.0.0", + "path-exists": "^4.0.0", + "read-pkg-up": "^7.0.0" + }, + "dependencies": { + "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 + }, + "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 + }, + "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" + } + }, + "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 + }, + "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", @@ -8935,9 +9925,9 @@ } }, "typescript": { - "version": "4.7.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", - "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", "dev": true }, "v8-to-istanbul": { diff --git a/package.json b/package.json index 3ffdae4b..2db2671c 100644 --- a/package.json +++ b/package.json @@ -26,9 +26,12 @@ "build:module": "tsc -p tsconfig.module.json", "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 test:types db:clean db:run test:run db:clean", + "test:run": "jest --runInBand", + "test:update": "run-s db:clean db:run && jest --runInBand --updateSnapshot && run-s db:clean", + "test:types": "run-s build:module && 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" @@ -42,8 +45,9 @@ "rimraf": "^3.0.2", "semantic-release-plugin-update-version-in-files": "^1.1.0", "ts-jest": "^28.0.3", + "tsd": "^0.24.1", "typedoc": "^0.22.16", - "typescript": "~4.7", + "typescript": "~4.8", "wait-for-localhost-cli": "^3.0.0" } } diff --git a/src/PostgrestBuilder.ts b/src/PostgrestBuilder.ts index fe4d6577..c1529e91 100644 --- a/src/PostgrestBuilder.ts +++ b/src/PostgrestBuilder.ts @@ -82,7 +82,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 diff --git a/src/PostgrestClient.ts b/src/PostgrestClient.ts index f3fcc705..2e14a12f 100644 --- a/src/PostgrestClient.ts +++ b/src/PostgrestClient.ts @@ -64,14 +64,14 @@ export default class PostgrestClient< 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 + from(relation: string): PostgrestQueryBuilder + 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, fetch: this.fetch, @@ -113,6 +113,7 @@ export default class PostgrestClient< count?: 'exact' | 'planned' | 'estimated' } = {} ): PostgrestFilterBuilder< + Schema, Function_['Returns'] extends any[] ? Function_['Returns'][number] extends Record ? Function_['Returns'][number] diff --git a/src/PostgrestFilterBuilder.ts b/src/PostgrestFilterBuilder.ts index 23ece29b..bab03de5 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,10 @@ type FilterOperator = | 'wfts' export default class PostgrestFilterBuilder< + Schema extends GenericSchema, Row extends Record, Result -> extends PostgrestTransformBuilder { +> extends PostgrestTransformBuilder { /** * Match only rows where `column` is equal to `value`. * diff --git a/src/PostgrestQueryBuilder.ts b/src/PostgrestQueryBuilder.ts index cc1338ed..d25966f9 100644 --- a/src/PostgrestQueryBuilder.ts +++ b/src/PostgrestQueryBuilder.ts @@ -1,9 +1,12 @@ import PostgrestBuilder from './PostgrestBuilder' import PostgrestFilterBuilder from './PostgrestFilterBuilder' import { GetResult } from './select-query-parser' -import { Fetch, GenericTable, GenericView } from './types' +import { Fetch, GenericSchema, GenericTable, GenericView } from './types' -export default class PostgrestQueryBuilder { +export default class PostgrestQueryBuilder< + Schema extends GenericSchema, + Relation extends GenericTable | GenericView +> { url: URL headers: Record schema?: string @@ -51,7 +54,7 @@ export default class PostgrestQueryBuilder + Result = GetResult >( columns?: Query, { @@ -61,7 +64,7 @@ export default class PostgrestQueryBuilder { + ): PostgrestFilterBuilder { const method = head ? 'HEAD' : 'GET' // Remove whitespaces except when quoted let quoted = false @@ -121,7 +124,7 @@ export default class PostgrestQueryBuilder { + ): PostgrestFilterBuilder { const method = 'POST' const prefersHeaders = [] @@ -197,7 +200,7 @@ export default class PostgrestQueryBuilder { + ): PostgrestFilterBuilder { const method = 'POST' const prefersHeaders = [`resolution=${ignoreDuplicates ? 'ignore' : 'merge'}-duplicates`] @@ -251,7 +254,7 @@ export default class PostgrestQueryBuilder { + ): PostgrestFilterBuilder { const method = 'PATCH' const prefersHeaders = [] const body = values @@ -297,7 +300,7 @@ export default class PostgrestQueryBuilder { + } = {}): PostgrestFilterBuilder { const method = 'DELETE' const prefersHeaders = [] if (count) { diff --git a/src/PostgrestTransformBuilder.ts b/src/PostgrestTransformBuilder.ts index de41ab77..c4f97812 100644 --- a/src/PostgrestTransformBuilder.ts +++ b/src/PostgrestTransformBuilder.ts @@ -1,8 +1,14 @@ import PostgrestBuilder from './PostgrestBuilder' import { GetResult } from './select-query-parser' -import { PostgrestMaybeSingleResponse, PostgrestResponse, PostgrestSingleResponse } from './types' +import { + GenericSchema, + PostgrestMaybeSingleResponse, + PostgrestResponse, + PostgrestSingleResponse, +} from './types' export default class PostgrestTransformBuilder< + Schema extends GenericSchema, Row extends Record, Result > extends PostgrestBuilder { @@ -15,9 +21,9 @@ export default class PostgrestTransformBuilder< * * @param columns - The columns to retrieve, separated by commas */ - select>( + select>( columns?: Query - ): PostgrestTransformBuilder { + ): PostgrestTransformBuilder { // Remove whitespaces except when quoted let quoted = false const cleanedColumns = (columns ?? '*') @@ -37,7 +43,7 @@ export default class PostgrestTransformBuilder< this.headers['Prefer'] += ',' } this.headers['Prefer'] += 'return=representation' - return this as unknown as PostgrestTransformBuilder + return this as unknown as PostgrestTransformBuilder } /** @@ -234,4 +240,13 @@ export default class PostgrestTransformBuilder< } return this } + + /** + * Override the type of the returned `data`. + * + * @typeParam NewResult - The new result type to override with + */ + returns(): PostgrestTransformBuilder { + return this as unknown as PostgrestTransformBuilder + } } diff --git a/src/select-query-parser.ts b/src/select-query-parser.ts index 0b60ab7e..b23e7d0f 100644 --- a/src/select-query-parser.ts +++ b/src/select-query-parser.ts @@ -1,5 +1,7 @@ // Credits to @bnjmnt4n (https://www.npmjs.com/package/postgrest-query) +import { GenericSchema } from './types' + type Whitespace = ' ' | '\n' | '\t' type LowerAlphabet = @@ -67,12 +69,25 @@ type EatWhitespace = string extends Input * @param Name Name of the table being queried. * @param Field Single field parsed by `ParseQuery`. */ -type ConstructFieldDefinition, Field> = Field extends { +type ConstructFieldDefinition< + Schema extends GenericSchema, + Row extends Record, + Field +> = Field extends { star: true } ? Row - : Field extends { name: string; foreignTable: true } - ? { [K in Field['name']]: unknown } + : Field extends { name: string; original: string; children: unknown[] } + ? { + [_ in Field['name']]: GetResultHelper< + Schema, + (Schema['Tables'] & Schema['Views'])[Field['original']]['Row'], + Field['children'], + unknown + > extends infer Child + ? Child | Child[] | null + : never + } : Field extends { name: string; original: string } ? { [K in Field['name']]: Row[Field['original']] } : Record @@ -135,9 +150,9 @@ type ParseNode = Input extends '' ? [{ star: true }, EatWhitespace] : ParseIdentifier extends [infer Name, `${infer Remainder}`] ? EatWhitespace extends `!inner${infer Remainder}` - ? ParseEmbeddedResource> extends [infer _Fields, `${infer Remainder}`] + ? ParseEmbeddedResource> extends [infer Fields, `${infer Remainder}`] ? // `field!inner(nodes)` - [{ name: Name; foreignTable: true }, EatWhitespace] + [{ name: Name; original: Name; children: Fields }, EatWhitespace] : ParseEmbeddedResource> extends ParserError ? ParseEmbeddedResource> : ParserError<'Expected embedded resource after `!inner`'> @@ -145,20 +160,20 @@ type ParseNode = Input extends '' ? ParseIdentifier> extends [infer _Hint, `${infer Remainder}`] ? EatWhitespace extends `!inner${infer Remainder}` ? ParseEmbeddedResource> extends [ - infer _Fields, + infer Fields, `${infer Remainder}` ] ? // `field!hint!inner(nodes)` - [{ name: Name; foreignTable: true }, EatWhitespace] + [{ name: Name; original: Name; children: Fields }, EatWhitespace] : ParseEmbeddedResource> extends ParserError ? ParseEmbeddedResource> : ParserError<'Expected embedded resource after `!inner`'> : ParseEmbeddedResource> extends [ - infer _Fields, + infer Fields, `${infer Remainder}` ] ? // `field!hint(nodes)` - [{ name: Name; foreignTable: true }, EatWhitespace] + [{ name: Name; original: Name; children: Fields }, EatWhitespace] : ParseEmbeddedResource> extends ParserError ? ParseEmbeddedResource> : ParserError<'Expected embedded resource after `!hint`'> @@ -167,11 +182,11 @@ type ParseNode = Input extends '' ? ParseIdentifier> extends [infer OriginalName, `${infer Remainder}`] ? EatWhitespace extends `!inner${infer Remainder}` ? ParseEmbeddedResource> extends [ - infer _Fields, + infer Fields, `${infer Remainder}` ] ? // `renamed_field:field!inner(nodes)` - [{ name: Name; foreignTable: true }, EatWhitespace] + [{ name: Name; original: OriginalName; children: Fields }, EatWhitespace] : ParseEmbeddedResource> extends ParserError ? ParseEmbeddedResource> : ParserError<'Expected embedded resource after `!inner`'> @@ -179,23 +194,24 @@ type ParseNode = Input extends '' ? ParseIdentifier> extends [infer _Hint, `${infer Remainder}`] ? EatWhitespace extends `!inner${infer Remainder}` ? ParseEmbeddedResource> extends [ - infer _Fields, + infer Fields, `${infer Remainder}` ] ? // `renamed_field:field!hint!inner(nodes)` - [{ name: Name; foreignTable: true }, EatWhitespace] + [{ name: Name; original: OriginalName; children: Fields }, EatWhitespace] : ParseEmbeddedResource> extends ParserError ? ParseEmbeddedResource> : ParserError<'Expected embedded resource after `!inner`'> : ParseEmbeddedResource> extends [ - infer _Fields, + infer Fields, `${infer Remainder}` ] ? // `renamed_field:field!hint(nodes)` [ { name: Name - foreignTable: true + original: OriginalName + children: Fields }, EatWhitespace ] @@ -204,19 +220,19 @@ type ParseNode = Input extends '' : ParserError<'Expected embedded resource after `!hint`'> : ParserError<'Expected identifier after `!`'> : ParseEmbeddedResource> extends [ - infer _Fields, + infer Fields, `${infer Remainder}` ] ? // `renamed_field:field(nodes)` - [{ name: Name; foreignTable: true }, EatWhitespace] + [{ name: Name; original: OriginalName; children: Fields }, EatWhitespace] : ParseEmbeddedResource> extends ParserError ? ParseEmbeddedResource> : // `renamed_field:field` [{ name: Name; original: OriginalName }, EatWhitespace] : ParseIdentifier> - : ParseEmbeddedResource> extends [infer _Fields, `${infer Remainder}`] + : ParseEmbeddedResource> extends [infer Fields, `${infer Remainder}`] ? // `field(nodes)` - [{ name: Name; foreignTable: true }, EatWhitespace] + [{ name: Name; original: Name; children: Fields }, EatWhitespace] : ParseEmbeddedResource> extends ParserError ? ParseEmbeddedResource> : // `field` @@ -274,13 +290,14 @@ type ParseQuery = string extends Query : ParseNodes> type GetResultHelper< + Schema extends GenericSchema, Row extends Record, Fields extends unknown[], Acc > = Fields extends [infer R] - ? GetResultHelper & Acc> + ? GetResultHelper & Acc> : Fields extends [infer R, ...infer Rest] - ? GetResultHelper & Acc> + ? GetResultHelper & Acc> : Acc /** @@ -290,8 +307,9 @@ type GetResultHelper< * @param Query Select query string literal to parse. */ export type GetResult< + Schema extends GenericSchema, Row extends Record, Query extends string > = ParseQuery extends unknown[] - ? GetResultHelper, unknown> + ? GetResultHelper, unknown> : ParseQuery From ebe94e7282bd4c12f775594dba933004ba6e6d38 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Tue, 18 Oct 2022 16:18:48 +0800 Subject: [PATCH 003/110] test: allow overriding result types --- test/basic.ts | 27 --------------------------- test/index.test-d.ts | 44 ++++++++++++++++++++++++++++++++++++++++++++ tsconfig.json | 1 - 3 files changed, 44 insertions(+), 28 deletions(-) create mode 100644 test/index.test-d.ts diff --git a/test/basic.ts b/test/basic.ts index 82479ce1..d67c09ee 100644 --- a/test/basic.ts +++ b/test/basic.ts @@ -178,11 +178,6 @@ describe('basic insert, update, delete', () => { }) }) -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 @@ -275,18 +270,6 @@ 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() @@ -440,13 +423,3 @@ test('select with no match', async () => { } `) }) - -test('cannot update non-updatable views', () => { - // @ts-expect-error TS2345 - postgrest.from('non_updatable_view').update({}) -}) - -test('cannot update non-updatable columns', () => { - // @ts-expect-error TS2322 - postgrest.from('updatable_view').update({ non_updatable_column: 0 }) -}) diff --git a/test/index.test-d.ts b/test/index.test-d.ts new file mode 100644 index 00000000..1eb80768 --- /dev/null +++ b/test/index.test-d.ts @@ -0,0 +1,44 @@ +import { expectError, expectType } from 'tsd' +import { PostgrestClient } from '../src/index' +import { Database } from './types' + +const REST_URL = 'http://localhost:3000' +const postgrest = new PostgrestClient(REST_URL) + +// table invalid type +{ + expectError(postgrest.from(42)) +} + +// 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 })) +} diff --git a/tsconfig.json b/tsconfig.json index fabd608d..49bb53aa 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,7 +5,6 @@ "declarationMap": true, "module": "CommonJS", "outDir": "dist/main", - "rootDir": "src", "sourceMap": true, "target": "ES2015", From 4aa24d548b61df00e2aeb17b66d39205144fbd0c Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Tue, 18 Oct 2022 16:22:51 +0800 Subject: [PATCH 004/110] chore(deps-dev): bump typedoc --- package-lock.json | 112 ++++++++++++++++------------------------------ package.json | 2 +- 2 files changed, 40 insertions(+), 74 deletions(-) diff --git a/package-lock.json b/package-lock.json index 65c6d6d5..6b321563 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,7 +21,7 @@ "semantic-release-plugin-update-version-in-files": "^1.1.0", "ts-jest": "^28.0.3", "tsd": "^0.24.1", - "typedoc": "^0.22.16", + "typedoc": "^0.23.17", "typescript": "~4.8", "wait-for-localhost-cli": "^3.0.0" } @@ -3605,9 +3605,9 @@ } }, "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/kind-of": { @@ -3793,9 +3793,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" @@ -4829,14 +4829,14 @@ "dev": true }, "node_modules/shiki": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.10.1.tgz", - "integrity": "sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==", + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.11.1.tgz", + "integrity": "sha512-EugY9VASFuDqOexOgXR18ZV+TbFrQHeCpEYaXamO+SZlsnT/2LxuLBX25GGtIrwaEVFXUAbUQ601SWE2rMwWHA==", "dev": true, "dependencies": { "jsonc-parser": "^3.0.0", "vscode-oniguruma": "^1.6.1", - "vscode-textmate": "5.2.0" + "vscode-textmate": "^6.0.0" } }, "node_modules/signal-exit": { @@ -5508,25 +5508,24 @@ } }, "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.23.17", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.23.17.tgz", + "integrity": "sha512-3rtNubo1dK0pvs6ixpMAq4pESULd5/JNUqJbdyZoeilI14reb1RNVomN4fMgIadd0RMX1aenYjJSSMBOJ+/+0Q==", "dev": true, "dependencies": { - "glob": "^8.0.3", "lunr": "^2.3.9", - "marked": "^4.0.16", + "marked": "^4.0.19", "minimatch": "^5.1.0", - "shiki": "^0.10.1" + "shiki": "^0.11.1" }, "bin": { "typedoc": "bin/typedoc" }, "engines": { - "node": ">= 12.10.0" + "node": ">= 14.14" }, "peerDependencies": { - "typescript": "4.0.x || 4.1.x || 4.2.x || 4.3.x || 4.4.x || 4.5.x || 4.6.x || 4.7.x" + "typescript": "4.6.x || 4.7.x || 4.8.x" } }, "node_modules/typedoc/node_modules/brace-expansion": { @@ -5538,25 +5537,6 @@ "balanced-match": "^1.0.0" } }, - "node_modules/typedoc/node_modules/glob": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", - "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/typedoc/node_modules/minimatch": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", @@ -5613,9 +5593,9 @@ "dev": true }, "node_modules/vscode-textmate": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.2.0.tgz", - "integrity": "sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-6.0.0.tgz", + "integrity": "sha512-gu73tuZfJgu+mvCSy4UZwd2JXykjK9zAZsfmDeut5dx/1a7FeTk0XwJsSuqQn+cuMCGVbIBfl+s53X4T19DnzQ==", "dev": true }, "node_modules/wait-for-localhost": { @@ -8505,9 +8485,9 @@ "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 }, "kind-of": { @@ -8649,9 +8629,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": { @@ -9388,14 +9368,14 @@ "dev": true }, "shiki": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.10.1.tgz", - "integrity": "sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==", + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.11.1.tgz", + "integrity": "sha512-EugY9VASFuDqOexOgXR18ZV+TbFrQHeCpEYaXamO+SZlsnT/2LxuLBX25GGtIrwaEVFXUAbUQ601SWE2rMwWHA==", "dev": true, "requires": { "jsonc-parser": "^3.0.0", "vscode-oniguruma": "^1.6.1", - "vscode-textmate": "5.2.0" + "vscode-textmate": "^6.0.0" } }, "signal-exit": { @@ -9879,16 +9859,15 @@ "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.23.17", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.23.17.tgz", + "integrity": "sha512-3rtNubo1dK0pvs6ixpMAq4pESULd5/JNUqJbdyZoeilI14reb1RNVomN4fMgIadd0RMX1aenYjJSSMBOJ+/+0Q==", "dev": true, "requires": { - "glob": "^8.0.3", "lunr": "^2.3.9", - "marked": "^4.0.16", + "marked": "^4.0.19", "minimatch": "^5.1.0", - "shiki": "^0.10.1" + "shiki": "^0.11.1" }, "dependencies": { "brace-expansion": { @@ -9900,19 +9879,6 @@ "balanced-match": "^1.0.0" } }, - "glob": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", - "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - } - }, "minimatch": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", @@ -9958,9 +9924,9 @@ "dev": true }, "vscode-textmate": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.2.0.tgz", - "integrity": "sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-6.0.0.tgz", + "integrity": "sha512-gu73tuZfJgu+mvCSy4UZwd2JXykjK9zAZsfmDeut5dx/1a7FeTk0XwJsSuqQn+cuMCGVbIBfl+s53X4T19DnzQ==", "dev": true }, "wait-for-localhost": { diff --git a/package.json b/package.json index 2db2671c..e9fba797 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "semantic-release-plugin-update-version-in-files": "^1.1.0", "ts-jest": "^28.0.3", "tsd": "^0.24.1", - "typedoc": "^0.22.16", + "typedoc": "^0.23.17", "typescript": "~4.8", "wait-for-localhost-cli": "^3.0.0" } From 6c1902eefc2e03d84d933b6ef09d265eee639e2d Mon Sep 17 00:00:00 2001 From: Copple <10214025+kiwicopple@users.noreply.github.com> Date: Wed, 19 Oct 2022 18:04:36 +0200 Subject: [PATCH 005/110] fix v1 spec --- docs/spec.json | 12990 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 12990 insertions(+) create mode 100644 docs/spec.json diff --git a/docs/spec.json b/docs/spec.json new file mode 100644 index 00000000..a3bcd1af --- /dev/null +++ b/docs/spec.json @@ -0,0 +1,12990 @@ +{ + "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] + } + ] +} From 84f151834a4e305508cd246cba9ea33e6affc0f2 Mon Sep 17 00:00:00 2001 From: Copple <10214025+kiwicopple@users.noreply.github.com> Date: Wed, 19 Oct 2022 18:50:08 +0200 Subject: [PATCH 006/110] move v1 to correct repo --- docs/spec.json | 12990 ------------------------------------------- docs/v1/spec.json | 13023 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 12989 insertions(+), 13024 deletions(-) delete mode 100644 docs/spec.json diff --git a/docs/spec.json b/docs/spec.json deleted file mode 100644 index a3bcd1af..00000000 --- a/docs/spec.json +++ /dev/null @@ -1,12990 +0,0 @@ -{ - "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/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] + } + ] +} From 6132a323b78739df18620c8a1e31e29d5443db35 Mon Sep 17 00:00:00 2001 From: Terry Sutton Date: Tue, 8 Nov 2022 09:12:26 -0330 Subject: [PATCH 007/110] Roll back to previous typedoc version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e9fba797..2db2671c 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "semantic-release-plugin-update-version-in-files": "^1.1.0", "ts-jest": "^28.0.3", "tsd": "^0.24.1", - "typedoc": "^0.23.17", + "typedoc": "^0.22.16", "typescript": "~4.8", "wait-for-localhost-cli": "^3.0.0" } From a42dcf74a6107d37a18fd854202c29c4bfe7b4b2 Mon Sep 17 00:00:00 2001 From: Terry Sutton Date: Tue, 8 Nov 2022 09:13:50 -0330 Subject: [PATCH 008/110] Add package lock --- package-lock.json | 91 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 62 insertions(+), 29 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6b321563..51da0187 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,7 +21,7 @@ "semantic-release-plugin-update-version-in-files": "^1.1.0", "ts-jest": "^28.0.3", "tsd": "^0.24.1", - "typedoc": "^0.23.17", + "typedoc": "^0.22.16", "typescript": "~4.8", "wait-for-localhost-cli": "^3.0.0" } @@ -4829,14 +4829,14 @@ "dev": true }, "node_modules/shiki": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.11.1.tgz", - "integrity": "sha512-EugY9VASFuDqOexOgXR18ZV+TbFrQHeCpEYaXamO+SZlsnT/2LxuLBX25GGtIrwaEVFXUAbUQ601SWE2rMwWHA==", + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.10.1.tgz", + "integrity": "sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==", "dev": true, "dependencies": { "jsonc-parser": "^3.0.0", "vscode-oniguruma": "^1.6.1", - "vscode-textmate": "^6.0.0" + "vscode-textmate": "5.2.0" } }, "node_modules/signal-exit": { @@ -5508,24 +5508,25 @@ } }, "node_modules/typedoc": { - "version": "0.23.17", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.23.17.tgz", - "integrity": "sha512-3rtNubo1dK0pvs6ixpMAq4pESULd5/JNUqJbdyZoeilI14reb1RNVomN4fMgIadd0RMX1aenYjJSSMBOJ+/+0Q==", + "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", "lunr": "^2.3.9", - "marked": "^4.0.19", + "marked": "^4.0.16", "minimatch": "^5.1.0", - "shiki": "^0.11.1" + "shiki": "^0.10.1" }, "bin": { "typedoc": "bin/typedoc" }, "engines": { - "node": ">= 14.14" + "node": ">= 12.10.0" }, "peerDependencies": { - "typescript": "4.6.x || 4.7.x || 4.8.x" + "typescript": "4.0.x || 4.1.x || 4.2.x || 4.3.x || 4.4.x || 4.5.x || 4.6.x || 4.7.x" } }, "node_modules/typedoc/node_modules/brace-expansion": { @@ -5537,6 +5538,25 @@ "balanced-match": "^1.0.0" } }, + "node_modules/typedoc/node_modules/glob": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", + "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/typedoc/node_modules/minimatch": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", @@ -5593,9 +5613,9 @@ "dev": true }, "node_modules/vscode-textmate": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-6.0.0.tgz", - "integrity": "sha512-gu73tuZfJgu+mvCSy4UZwd2JXykjK9zAZsfmDeut5dx/1a7FeTk0XwJsSuqQn+cuMCGVbIBfl+s53X4T19DnzQ==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.2.0.tgz", + "integrity": "sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==", "dev": true }, "node_modules/wait-for-localhost": { @@ -8155,8 +8175,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true, - "requires": {} + "dev": true }, "jest-regex-util": { "version": "28.0.2", @@ -9368,14 +9387,14 @@ "dev": true }, "shiki": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.11.1.tgz", - "integrity": "sha512-EugY9VASFuDqOexOgXR18ZV+TbFrQHeCpEYaXamO+SZlsnT/2LxuLBX25GGtIrwaEVFXUAbUQ601SWE2rMwWHA==", + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.10.1.tgz", + "integrity": "sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==", "dev": true, "requires": { "jsonc-parser": "^3.0.0", "vscode-oniguruma": "^1.6.1", - "vscode-textmate": "^6.0.0" + "vscode-textmate": "5.2.0" } }, "signal-exit": { @@ -9859,15 +9878,16 @@ "dev": true }, "typedoc": { - "version": "0.23.17", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.23.17.tgz", - "integrity": "sha512-3rtNubo1dK0pvs6ixpMAq4pESULd5/JNUqJbdyZoeilI14reb1RNVomN4fMgIadd0RMX1aenYjJSSMBOJ+/+0Q==", + "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", "lunr": "^2.3.9", - "marked": "^4.0.19", + "marked": "^4.0.16", "minimatch": "^5.1.0", - "shiki": "^0.11.1" + "shiki": "^0.10.1" }, "dependencies": { "brace-expansion": { @@ -9879,6 +9899,19 @@ "balanced-match": "^1.0.0" } }, + "glob": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", + "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + } + }, "minimatch": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", @@ -9924,9 +9957,9 @@ "dev": true }, "vscode-textmate": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-6.0.0.tgz", - "integrity": "sha512-gu73tuZfJgu+mvCSy4UZwd2JXykjK9zAZsfmDeut5dx/1a7FeTk0XwJsSuqQn+cuMCGVbIBfl+s53X4T19DnzQ==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.2.0.tgz", + "integrity": "sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==", "dev": true }, "wait-for-localhost": { From c3871df5e523d1de5de8537c8780f3902539e911 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Tue, 15 Nov 2022 12:39:35 +0800 Subject: [PATCH 009/110] chore(deps): fix conflict --- package-lock.json | 17 +++++++++-------- package.json | 2 +- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 51da0187..5cf93adf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,7 @@ "ts-jest": "^28.0.3", "tsd": "^0.24.1", "typedoc": "^0.22.16", - "typescript": "~4.8", + "typescript": "~4.7", "wait-for-localhost-cli": "^3.0.0" } }, @@ -5570,9 +5570,9 @@ } }, "node_modules/typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", + "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -8175,7 +8175,8 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true + "dev": true, + "requires": {} }, "jest-regex-util": { "version": "28.0.2", @@ -9924,9 +9925,9 @@ } }, "typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", + "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", "dev": true }, "v8-to-istanbul": { diff --git a/package.json b/package.json index 2db2671c..0e051492 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "ts-jest": "^28.0.3", "tsd": "^0.24.1", "typedoc": "^0.22.16", - "typescript": "~4.8", + "typescript": "~4.7", "wait-for-localhost-cli": "^3.0.0" } } From ebd3690f61380d7e18d4be405c4ad921ca3b571c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Nov 2022 04:56:34 +0000 Subject: [PATCH 010/110] chore(deps): bump minimatch from 3.0.4 to 3.1.2 Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.0.4 to 3.1.2. - [Release notes](https://github.com/isaacs/minimatch/releases) - [Commits](https://github.com/isaacs/minimatch/compare/v3.0.4...v3.1.2) --- updated-dependencies: - dependency-name: minimatch dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5cf93adf..e7908077 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3940,9 +3940,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" @@ -8753,9 +8753,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" From 933b4d622ac1ef12b7cb19a8c163a4db4a8721d4 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Wed, 23 Nov 2022 13:58:31 +0800 Subject: [PATCH 011/110] docs: move doc comments to func impl This makes the doc comments show up for all the function signatures, instead of just the first one. --- src/PostgrestClient.ts | 10 +-- src/PostgrestFilterBuilder.ts | 144 +++++++++++++++---------------- src/PostgrestQueryBuilder.ts | 5 +- src/PostgrestTransformBuilder.ts | 16 ++-- 4 files changed, 86 insertions(+), 89 deletions(-) diff --git a/src/PostgrestClient.ts b/src/PostgrestClient.ts index 2e14a12f..9e331104 100644 --- a/src/PostgrestClient.ts +++ b/src/PostgrestClient.ts @@ -56,11 +56,6 @@ export default class PostgrestClient< 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] @@ -69,6 +64,11 @@ export default class PostgrestClient< relation: ViewName ): PostgrestQueryBuilder from(relation: string): 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, { diff --git a/src/PostgrestFilterBuilder.ts b/src/PostgrestFilterBuilder.ts index bab03de5..1e227786 100644 --- a/src/PostgrestFilterBuilder.ts +++ b/src/PostgrestFilterBuilder.ts @@ -30,6 +30,8 @@ export default class PostgrestFilterBuilder< Row extends Record, Result > extends PostgrestTransformBuilder { + eq(column: ColumnName, value: Row[ColumnName]): this + eq(column: string, value: unknown): this /** * Match only rows where `column` is equal to `value`. * @@ -38,104 +40,107 @@ 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 } + 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: ColumnName, pattern: string): this - ilike(column: string, pattern: string): this ilike(column: string, pattern: string): this { this.url.searchParams.append(column, `ilike.${pattern}`) 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`. * @@ -148,24 +153,19 @@ 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: Row[ColumnName][]): this + in(column: string, values: 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 .map((s) => { @@ -179,6 +179,11 @@ export default class PostgrestFilterBuilder< return this } + contains( + column: ColumnName, + value: string | Row[ColumnName][] | Record + ): this + contains(column: string, value: string | unknown[] | Record): this /** * Only relevant for jsonb, array, and range columns. Match only rows where * `column` contains every element appearing in `value`. @@ -186,11 +191,6 @@ 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 { if (typeof value === 'string') { // range types can be inclusive '[', ']' or exclusive '(', ')' so just @@ -206,6 +206,11 @@ export default class PostgrestFilterBuilder< return this } + containedBy( + column: ColumnName, + value: string | Row[ColumnName][] | Record + ): this + containedBy(column: string, value: string | unknown[] | Record): this /** * Only relevant for jsonb, array, and range columns. Match only rows where * every element appearing in `column` is contained by `value`. @@ -213,11 +218,6 @@ 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 { if (typeof value === 'string') { // range @@ -232,6 +232,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`. @@ -239,13 +241,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 @@ -254,13 +256,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`. @@ -268,13 +270,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 @@ -283,13 +285,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 @@ -298,13 +300,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 | Row[ColumnName][] + ): this + overlaps(column: string, value: string | unknown[]): this /** * Only relevant for array and range columns. Match only rows where * `column` and `value` have an element in common. @@ -312,11 +317,6 @@ 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 { if (typeof value === 'string') { // range @@ -328,16 +328,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, @@ -348,6 +338,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, @@ -366,6 +366,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. @@ -373,8 +375,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}`) @@ -382,6 +382,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. * @@ -395,12 +401,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 @@ -425,6 +425,12 @@ export default class PostgrestFilterBuilder< 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. @@ -438,12 +444,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 d25966f9..453a7789 100644 --- a/src/PostgrestQueryBuilder.ts +++ b/src/PostgrestQueryBuilder.ts @@ -52,10 +52,7 @@ export default class PostgrestQueryBuilder< * `"estimated"`: Uses exact count for low numbers and planned count for high * numbers. */ - select< - Query extends string = '*', - Result = GetResult - >( + select>( columns?: Query, { head = false, diff --git a/src/PostgrestTransformBuilder.ts b/src/PostgrestTransformBuilder.ts index c4f97812..624a47f8 100644 --- a/src/PostgrestTransformBuilder.ts +++ b/src/PostgrestTransformBuilder.ts @@ -46,6 +46,14 @@ export default class PostgrestTransformBuilder< return this as unknown as PostgrestTransformBuilder } + order( + column: ColumnName, + options?: { ascending?: boolean; nullsFirst?: boolean; foreignTable?: undefined } + ): this + order( + column: string, + options?: { ascending?: boolean; nullsFirst?: boolean; foreignTable: string } + ): this /** * Order the query result by `column`. * @@ -62,14 +70,6 @@ export default class PostgrestTransformBuilder< * @param options.foreignTable - Set this to order a foreign table by foreign * columns */ - 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, { From cc257053e1da5aabd6a5e5a0e34f2e18c5c4c47e Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Fri, 16 Dec 2022 18:58:18 +0800 Subject: [PATCH 012/110] fix: wrong response on update w/o match --- src/PostgrestBuilder.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/PostgrestBuilder.ts b/src/PostgrestBuilder.ts index c1529e91..829508ee 100644 --- a/src/PostgrestBuilder.ts +++ b/src/PostgrestBuilder.ts @@ -106,9 +106,23 @@ export default abstract class PostgrestBuilder 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, + } } } From 1e00cbc7a36a01c74fcbf68d63f1702eef5df274 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Fri, 16 Dec 2022 19:54:19 +0800 Subject: [PATCH 013/110] test: update with no match --- test/basic.ts | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/test/basic.ts b/test/basic.ts index d67c09ee..1b4d4907 100644 --- a/test/basic.ts +++ b/test/basic.ts @@ -423,3 +423,29 @@ test('select with no match', async () => { } `) }) + +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", + } + `) +}) From 281ffe0c89525d1dc76df0932905ca2f364ee793 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Jan 2023 10:11:29 +0000 Subject: [PATCH 014/110] chore(deps): bump json5 from 2.2.1 to 2.2.3 Bumps [json5](https://github.com/json5/json5) from 2.2.1 to 2.2.3. - [Release notes](https://github.com/json5/json5/releases) - [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md) - [Commits](https://github.com/json5/json5/compare/v2.2.1...v2.2.3) --- updated-dependencies: - dependency-name: json5 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index e7908077..ce1f8542 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3593,9 +3593,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" @@ -8499,9 +8499,9 @@ "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": { From a0e4db78be5733b22ce8b457f74b569fa191fbf9 Mon Sep 17 00:00:00 2001 From: Marshall Polaris Date: Tue, 17 Jan 2023 01:45:57 -0800 Subject: [PATCH 015/110] feat: support `->`/`->>` for column names --- src/select-query-parser.ts | 48 ++++++++++++++++++++++++++++++++++++-- test/index.test-d.ts | 14 ++++++++++- 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/src/select-query-parser.ts b/src/select-query-parser.ts index b23e7d0f..dc90ec78 100644 --- a/src/select-query-parser.ts +++ b/src/select-query-parser.ts @@ -38,6 +38,8 @@ type Digit = '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '0' type Letter = Alphabet | Digit | '_' +type Json = string | number | boolean | null | { [key: string]: Json } | Json[] + // /** // * Parsed node types. // * Currently only `*` and all other fields. @@ -45,7 +47,8 @@ type Letter = Alphabet | Digit | '_' // type ParsedNode = // | { star: true } // | { name: string; original: string } -// | { name: string; foreignTable: true }; +// | { name: string; foreignTable: true } +// | { name: string; type: T }; /** * Parser errors. @@ -90,6 +93,8 @@ type ConstructFieldDefinition< } : Field extends { name: string; original: string } ? { [K in Field['name']]: Row[Field['original']] } + : Field extends { name: string; type: infer T } + ? { [K in Field['name']]: T } : Record /** @@ -131,17 +136,19 @@ type ParseIdentifier = ReadLetters * A node is one of the following: * - `*` * - `field` + * - `field->json...` * - `field(nodes)` * - `field!hint(nodes)` * - `field!inner(nodes)` * - `field!hint!inner(nodes)` * - `renamed_field:field` + * - `renamed_field:field->json...` * - `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 `->`, `->>`. + * TODO: casting operators `::text`, more support for JSON operators `->`, `->>`. */ type ParseNode = Input extends '' ? ParserError<'Empty string'> @@ -225,6 +232,13 @@ type ParseNode = Input extends '' ] ? // `renamed_field:field(nodes)` [{ name: Name; original: OriginalName; children: Fields }, EatWhitespace] + : ParseJsonAccessor> extends [ + infer _PropertyName, + infer PropertyType, + `${infer Remainder}` + ] + ? // `renamed_field:field->json...` + [{ name: Name; type: PropertyType }, EatWhitespace] : ParseEmbeddedResource> extends ParserError ? ParseEmbeddedResource> : // `renamed_field:field` @@ -233,12 +247,42 @@ type ParseNode = Input extends '' : ParseEmbeddedResource> extends [infer Fields, `${infer Remainder}`] ? // `field(nodes)` [{ name: Name; original: Name; children: Fields }, EatWhitespace] + : ParseJsonAccessor> extends [ + infer PropertyName, + infer PropertyType, + `${infer Remainder}` + ] + ? // `field->json...` + [{ name: PropertyName; type: PropertyType }, EatWhitespace] : ParseEmbeddedResource> extends ParserError ? ParseEmbeddedResource> : // `field` [{ name: Name; original: Name }, EatWhitespace] : 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"] + * or the original string input indicating that no opening `->` was found. + */ +type ParseJsonAccessor = Input extends `->${infer Remainder}` + ? Remainder extends `>${infer Remainder}` + ? ParseIdentifier extends [infer Name, `${infer Remainder}`] + ? [Name, string, 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 `->`'> + : Input + /** * Parses an embedded resource, which is an opening `(`, followed by a sequence of * nodes, separated by `,`, then a closing `)`. diff --git a/test/index.test-d.ts b/test/index.test-d.ts index 1eb80768..732a2193 100644 --- a/test/index.test-d.ts +++ b/test/index.test-d.ts @@ -1,6 +1,6 @@ import { expectError, expectType } from 'tsd' import { PostgrestClient } from '../src/index' -import { Database } from './types' +import { Database, Json } from './types' const REST_URL = 'http://localhost:3000' const postgrest = new PostgrestClient(REST_URL) @@ -42,3 +42,15 @@ const postgrest = new PostgrestClient(REST_URL) { expectError(postgrest.from('updatable_view').update({ non_updatable_column: 0 })) } + +// 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) + } + expectType<{ bar: Json } & { baz: string }>(data) +} From 8f49667db2f7008833f9fce25372cdcea9ed050c Mon Sep 17 00:00:00 2001 From: Marshall Polaris Date: Tue, 17 Jan 2023 19:39:55 -0800 Subject: [PATCH 016/110] feat: target ES2017 in tsconfig (#391) --- tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index 49bb53aa..248dc3b0 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,7 +6,7 @@ "module": "CommonJS", "outDir": "dist/main", "sourceMap": true, - "target": "ES2015", + "target": "ES2017", "strict": true, From e3788a692a9a8ff8b72d7bc9ece50829c028cd72 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Fri, 3 Feb 2023 17:42:25 +0800 Subject: [PATCH 017/110] test: replace toMatchSnapshot -> toMatchInlineSnapshot --- test/__snapshots__/index.test.ts.snap | 1388 ------------------------- test/basic.ts | 940 ++++++++++++++++- test/resource-embedding.ts | 283 ++++- test/transforms.ts | 184 +++- 4 files changed, 1346 insertions(+), 1449 deletions(-) delete mode 100644 test/__snapshots__/index.test.ts.snap 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 1b4d4907..15059ec4 100644 --- a/test/basic.ts +++ b/test/basic.ts @@ -6,7 +6,44 @@ 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", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('basic select view', async () => { @@ -41,12 +78,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 () => { @@ -101,7 +154,46 @@ 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('on_conflict insert', async () => { @@ -109,7 +201,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": 201, + "statusText": "Created", + } + `) }) test('ignoreDuplicates upsert', async () => { @@ -117,7 +225,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 +242,56 @@ 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": 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": 1, + "data": null, + "id": 3, + "message": "foo", + "username": "supabot", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('upsert', async () => { @@ -137,10 +299,56 @@ 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": 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": 2, + "data": null, + "id": 3, + "message": "foo", + "username": "supabot", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('bulk insert', async () => { @@ -151,10 +359,77 @@ 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": 4, + "message": "foo", + "username": "supabot", + }, + 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": 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", + } + `) }) test('basic update', async () => { @@ -163,18 +438,145 @@ 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": 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", + } + `) 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": 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", + } + `) }) 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": 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", + } + `) 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", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) }) @@ -184,7 +586,14 @@ test('throwOnError throws errors instead of returning them', async () => { try { await postgrest.from('missing_table').select().throwOnError() } catch (error) { - expect(error).toMatchSnapshot() + expect(error).toMatchInlineSnapshot(` + Object { + "code": "42P01", + "details": null, + "hint": null, + "message": "relation \\"public.missing_table\\" does not exist", + } + `) isErrorCaught = true } @@ -199,7 +608,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 // } @@ -214,7 +623,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 // } @@ -227,7 +636,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) // }) @@ -273,7 +682,7 @@ test('maybeSingle w/ throwOnError', async () => { 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 () => { @@ -281,48 +690,162 @@ 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": "'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": 4, + "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": 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", + } + `) }) 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 () => { @@ -331,7 +854,15 @@ 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", + } + `) }) describe("insert, update, delete with count: 'exact'", () => { @@ -340,10 +871,56 @@ 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": 6, + "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": 1, + "data": null, + "id": 6, + "message": "foo", + "username": "supabot", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test("upsert with count: 'exact'", async () => { @@ -351,10 +928,63 @@ 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": 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", + } + `) }) test("bulk insert with count: 'exact'", async () => { @@ -368,10 +998,84 @@ 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": 7, + "message": "foo", + "username": "supabot", + }, + 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": 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", + } + `) }) test("update with count: 'exact'", async () => { @@ -380,10 +1084,98 @@ 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": 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", + } + `) 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": 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", + } + `) }) test("basic delete count: 'exact'", async () => { @@ -392,10 +1184,70 @@ 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": 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", + } + `) 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", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) }) diff --git a/test/resource-embedding.ts b/test/resource-embedding.ts index d211dff4..08887be0 100644 --- a/test/resource-embedding.ts +++ b/test/resource-embedding.ts @@ -5,7 +5,43 @@ 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 { + "messages": Array [], + }, + Object { + "messages": Array [], + }, + Object { + "messages": Array [], + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) describe('embedded filters', () => { @@ -15,14 +51,79 @@ 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 [], + }, + ], + "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 [], + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('embedded or with and', async () => { const res = await postgrest @@ -31,7 +132,43 @@ 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 [], + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) }) @@ -41,7 +178,43 @@ 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": 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", + } + `) }) test('embedded order on multiple columns', async () => { @@ -50,7 +223,43 @@ 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": 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", + } + `) }) test('embedded limit', async () => { @@ -58,7 +267,36 @@ 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 [], + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('embedded range', async () => { @@ -66,6 +304,35 @@ 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 [], + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) }) diff --git a/test/transforms.ts b/test/transforms.ts index 98b310cc..fe5c9234 100644 --- a/test/transforms.ts +++ b/test/transforms.ts @@ -7,7 +7,44 @@ 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": "'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 +53,156 @@ 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": 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": "'fat' 'rat'", + "data": null, + "status": "ONLINE", + "username": "dragarcia", + }, + ], + "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('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 +211,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 () => { From 7fddd755890da18d2125fda6727bbbef70860302 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Sat, 4 Feb 2023 17:42:23 +0800 Subject: [PATCH 018/110] test: update images --- test/db/docker-compose.yml | 5 +++-- test/transforms.ts | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/test/db/docker-compose.yml b/test/db/docker-compose.yml index 6cfd933b..7dcb8c15 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:v10.1.2 ports: - '3000:3000' environment: @@ -16,7 +16,7 @@ services: depends_on: - db db: - image: supabase/postgres:14.1.0.34 + image: supabase/postgres:15.1.0.37 ports: - '5432:5432' volumes: @@ -25,4 +25,5 @@ services: POSTGRES_DB: postgres POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres + POSTGRES_HOST: /var/run/postgresql POSTGRES_PORT: 5432 diff --git a/test/transforms.ts b/test/transforms.ts index fe5c9234..8d82fa66 100644 --- a/test/transforms.ts +++ b/test/transforms.ts @@ -366,7 +366,7 @@ test('explain with options', async () => { "Strategy": "Plain", "Total Cost": 17.68, }, - "Query Identifier": -8888327821402777000, + "Query Identifier": -6192475787150577000, "Settings": Object { "effective_cache_size": "128MB", "search_path": "\\"public\\", \\"extensions\\"", From 7891ef9306006545b536ddde235c411fa9005b18 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Sat, 4 Feb 2023 17:42:43 +0800 Subject: [PATCH 019/110] refactor: Postgrest*Response typings --- src/types.ts | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/types.ts b/src/types.ts index 07cc656f..233988a2 100644 --- a/src/types.ts +++ b/src/types.ts @@ -21,10 +21,9 @@ interface PostgrestResponseBase { status: number statusText: string } - -interface PostgrestResponseSuccess extends PostgrestResponseBase { +interface PostgrestSingleResponseSuccess extends PostgrestResponseBase { error: null - data: T[] + data: T count: number | null } interface PostgrestResponseFailure extends PostgrestResponseBase { @@ -32,17 +31,15 @@ interface PostgrestResponseFailure extends PostgrestResponseBase { data: null count: null } -export type PostgrestResponse = PostgrestResponseSuccess | PostgrestResponseFailure -interface PostgrestSingleResponseSuccess extends PostgrestResponseBase { - error: null - data: T - count: number | null -} +// TODO: in v3: +// - remove PostgrestResponse and PostgrestMaybeSingleResponse +// - rename PostgrestSingleResponse to PostgrestResponse export type PostgrestSingleResponse = | PostgrestSingleResponseSuccess | PostgrestResponseFailure export type PostgrestMaybeSingleResponse = PostgrestSingleResponse +export type PostgrestResponse = PostgrestSingleResponse export type GenericTable = { Row: Record From 9c1ddd0520ddac2cd94d97dc934b85adbfc8214c Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Sat, 4 Feb 2023 17:44:31 +0800 Subject: [PATCH 020/110] fix: rpc return type RPC return types aren't getting propagated properly. E.g. if a function returns `boolean`, the `data` will be typed as `boolean[]`. To fix this, we change PostgrestBuilder's type parameter to be the actual type of `data`, instead of the element type of `data` (which assumes `data` is always an array, which is incorrect). In doing so we effectively remove all usage of `PostgrestResponse` and `PostgrestMaybeSingleResponse`. We can stop exporting these on the next major version. This also fixes the behavior of `.returns()`, which was inconsistent with the documentation (i.e. `data` was typed as `NewResult[]` instead of `NewResult`). --- src/PostgrestBuilder.ts | 8 +++---- src/PostgrestQueryBuilder.ts | 6 ++--- src/PostgrestTransformBuilder.ts | 41 +++++++++++++++----------------- test/index.test-d.ts | 13 ++++++++-- 4 files changed, 37 insertions(+), 31 deletions(-) diff --git a/src/PostgrestBuilder.ts b/src/PostgrestBuilder.ts index 829508ee..78d7c214 100644 --- a/src/PostgrestBuilder.ts +++ b/src/PostgrestBuilder.ts @@ -1,9 +1,9 @@ import crossFetch from 'cross-fetch' -import type { Fetch, PostgrestResponse } from './types' +import type { Fetch, PostgrestSingleResponse } from './types' export default abstract class PostgrestBuilder - implements PromiseLike> + implements PromiseLike> { protected method: 'GET' | 'HEAD' | 'POST' | 'PATCH' | 'DELETE' protected url: URL @@ -45,9 +45,9 @@ export default abstract class PostgrestBuilder return this } - then, TResult2 = never>( + then, TResult2 = never>( onfulfilled?: - | ((value: PostgrestResponse) => TResult1 | PromiseLike) + | ((value: PostgrestSingleResponse) => TResult1 | PromiseLike) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null diff --git a/src/PostgrestQueryBuilder.ts b/src/PostgrestQueryBuilder.ts index 453a7789..ab00f2e0 100644 --- a/src/PostgrestQueryBuilder.ts +++ b/src/PostgrestQueryBuilder.ts @@ -52,7 +52,7 @@ export default class PostgrestQueryBuilder< * `"estimated"`: Uses exact count for low numbers and planned count for high * numbers. */ - select>( + select>( columns?: Query, { head = false, @@ -61,7 +61,7 @@ export default class PostgrestQueryBuilder< head?: boolean count?: 'exact' | 'planned' | 'estimated' } = {} - ): PostgrestFilterBuilder { + ): PostgrestFilterBuilder { const method = head ? 'HEAD' : 'GET' // Remove whitespaces except when quoted let quoted = false @@ -89,7 +89,7 @@ export default class PostgrestQueryBuilder< schema: this.schema, fetch: this.fetch, allowEmpty: false, - } as unknown as PostgrestBuilder) + } as unknown as PostgrestBuilder) } /** diff --git a/src/PostgrestTransformBuilder.ts b/src/PostgrestTransformBuilder.ts index 624a47f8..646e85ab 100644 --- a/src/PostgrestTransformBuilder.ts +++ b/src/PostgrestTransformBuilder.ts @@ -1,11 +1,6 @@ import PostgrestBuilder from './PostgrestBuilder' import { GetResult } from './select-query-parser' -import { - GenericSchema, - PostgrestMaybeSingleResponse, - PostgrestResponse, - PostgrestSingleResponse, -} from './types' +import { GenericSchema } from './types' export default class PostgrestTransformBuilder< Schema extends GenericSchema, @@ -21,9 +16,9 @@ export default class PostgrestTransformBuilder< * * @param columns - The columns to retrieve, separated by commas */ - select>( + select>( columns?: Query - ): PostgrestTransformBuilder { + ): PostgrestTransformBuilder { // Remove whitespaces except when quoted let quoted = false const cleanedColumns = (columns ?? '*') @@ -43,7 +38,7 @@ export default class PostgrestTransformBuilder< this.headers['Prefer'] += ',' } this.headers['Prefer'] += 'return=representation' - return this as unknown as PostgrestTransformBuilder + return this as unknown as PostgrestTransformBuilder } order( @@ -138,9 +133,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 } /** @@ -149,26 +146,28 @@ export default class PostgrestTransformBuilder< * Query result must be zero or one row (e.g. using `.limit(1)`), otherwise * this returns an error. */ - maybeSingle(): PromiseLike> { + maybeSingle< + ResultOne = Result extends (infer ResultOne)[] ? ResultOne : never + >(): PostgrestBuilder { this.headers['Accept'] = 'application/vnd.pgrst.object+json' this.allowEmpty = true - return this as PromiseLike> + 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> } /** @@ -206,9 +205,7 @@ export default class PostgrestTransformBuilder< buffers?: boolean wal?: boolean format?: 'json' | 'text' - } = {}): - | PromiseLike>> - | PromiseLike> { + } = {}): PostgrestBuilder[]> | PostgrestBuilder { const options = [ analyze ? 'analyze' : null, verbose ? 'verbose' : null, @@ -223,8 +220,8 @@ export default class PostgrestTransformBuilder< 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 } /** diff --git a/test/index.test-d.ts b/test/index.test-d.ts index 732a2193..cec1a1ae 100644 --- a/test/index.test-d.ts +++ b/test/index.test-d.ts @@ -15,7 +15,7 @@ const postgrest = new PostgrestClient(REST_URL) const { data, error } = await postgrest .from('users') .select('*, messages(*)') - .returns<{ messages: { foo: 'bar' }[] }>() + .returns<{ messages: { foo: 'bar' }[] }[]>() if (error) { throw new Error(error.message) } @@ -26,7 +26,7 @@ const postgrest = new PostgrestClient(REST_URL) .from('users') .insert({ username: 'foo' }) .select('*, messages(*)') - .returns<{ messages: { foo: 'bar' }[] }>() + .returns<{ messages: { foo: 'bar' }[] }[]>() if (error) { throw new Error(error.message) } @@ -54,3 +54,12 @@ const postgrest = new PostgrestClient(REST_URL) } expectType<{ bar: Json } & { baz: string }>(data) } + +// rpc return type +{ + const { data, error } = await postgrest.rpc('get_status') + if (error) { + throw new Error(error.message) + } + expectType<'ONLINE' | 'OFFLINE'>(data) +} From 860387eddf35224543ccb0f7ccdd5c056792bb35 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Sat, 4 Feb 2023 17:58:28 +0800 Subject: [PATCH 021/110] fix: use `null` if `return=minimal` --- src/PostgrestQueryBuilder.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/PostgrestQueryBuilder.ts b/src/PostgrestQueryBuilder.ts index ab00f2e0..55952c0b 100644 --- a/src/PostgrestQueryBuilder.ts +++ b/src/PostgrestQueryBuilder.ts @@ -121,7 +121,7 @@ export default class PostgrestQueryBuilder< }: { count?: 'exact' | 'planned' | 'estimated' } = {} - ): PostgrestFilterBuilder { + ): PostgrestFilterBuilder { const method = 'POST' const prefersHeaders = [] @@ -150,7 +150,7 @@ export default class PostgrestQueryBuilder< body, fetch: this.fetch, allowEmpty: false, - } as unknown as PostgrestBuilder) + } as unknown as PostgrestBuilder) } /** @@ -197,7 +197,7 @@ export default class PostgrestQueryBuilder< ignoreDuplicates?: boolean count?: 'exact' | 'planned' | 'estimated' } = {} - ): PostgrestFilterBuilder { + ): PostgrestFilterBuilder { const method = 'POST' const prefersHeaders = [`resolution=${ignoreDuplicates ? 'ignore' : 'merge'}-duplicates`] @@ -220,7 +220,7 @@ export default class PostgrestQueryBuilder< body, fetch: this.fetch, allowEmpty: false, - } as unknown as PostgrestBuilder) + } as unknown as PostgrestBuilder) } /** @@ -251,7 +251,7 @@ export default class PostgrestQueryBuilder< }: { count?: 'exact' | 'planned' | 'estimated' } = {} - ): PostgrestFilterBuilder { + ): PostgrestFilterBuilder { const method = 'PATCH' const prefersHeaders = [] const body = values @@ -271,7 +271,7 @@ export default class PostgrestQueryBuilder< body, fetch: this.fetch, allowEmpty: false, - } as unknown as PostgrestBuilder) + } as unknown as PostgrestBuilder) } /** @@ -297,7 +297,7 @@ export default class PostgrestQueryBuilder< count, }: { count?: 'exact' | 'planned' | 'estimated' - } = {}): PostgrestFilterBuilder { + } = {}): PostgrestFilterBuilder { const method = 'DELETE' const prefersHeaders = [] if (count) { @@ -315,6 +315,6 @@ export default class PostgrestQueryBuilder< schema: this.schema, fetch: this.fetch, allowEmpty: false, - } as unknown as PostgrestBuilder) + } as unknown as PostgrestBuilder) } } From 8ce5da43e4129eed0fdf919b03ef5a1ccf223dd2 Mon Sep 17 00:00:00 2001 From: Kevin Rocker Date: Wed, 8 Feb 2023 04:08:27 +0000 Subject: [PATCH 022/110] feat(types): export PostgrestResponseSuccess and PostgrestResponseFailure (#396) --- src/index.ts | 2 ++ src/types.ts | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/index.ts b/src/index.ts index 1dff039f..9fb4cb78 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,6 +5,8 @@ export { default as PostgrestTransformBuilder } from './PostgrestTransformBuilde export { default as PostgrestBuilder } from './PostgrestBuilder' export { PostgrestResponse, + PostgrestResponseFailure, + PostgrestResponseSuccess, PostgrestSingleResponse, PostgrestMaybeSingleResponse, PostgrestError, diff --git a/src/types.ts b/src/types.ts index 233988a2..f9bbf662 100644 --- a/src/types.ts +++ b/src/types.ts @@ -21,12 +21,12 @@ interface PostgrestResponseBase { status: number statusText: string } -interface PostgrestSingleResponseSuccess extends PostgrestResponseBase { +export interface PostgrestResponseSuccess extends PostgrestResponseBase { error: null data: T count: number | null } -interface PostgrestResponseFailure extends PostgrestResponseBase { +export interface PostgrestResponseFailure extends PostgrestResponseBase { error: PostgrestError data: null count: null @@ -36,7 +36,7 @@ interface PostgrestResponseFailure extends PostgrestResponseBase { // - remove PostgrestResponse and PostgrestMaybeSingleResponse // - rename PostgrestSingleResponse to PostgrestResponse export type PostgrestSingleResponse = - | PostgrestSingleResponseSuccess + | PostgrestResponseSuccess | PostgrestResponseFailure export type PostgrestMaybeSingleResponse = PostgrestSingleResponse export type PostgrestResponse = PostgrestSingleResponse From 1946c721eafe05ecc9db4e8a61d16877e5e51d98 Mon Sep 17 00:00:00 2001 From: Yann <17554280+yannxaver@users.noreply.github.com> Date: Sat, 11 Feb 2023 13:00:21 +0100 Subject: [PATCH 023/110] Update PostgrestQueryBuilder.ts --- src/PostgrestQueryBuilder.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PostgrestQueryBuilder.ts b/src/PostgrestQueryBuilder.ts index 55952c0b..f610f37b 100644 --- a/src/PostgrestQueryBuilder.ts +++ b/src/PostgrestQueryBuilder.ts @@ -34,7 +34,7 @@ export default class PostgrestQueryBuilder< /** * Perform a SELECT query on the table or view. * - * @param columns - The columns to retrieve, separated by commas + * @param columns - The columns to retrieve, separated by commas. Map a column to a custom key by writing `key:column` * * @param options - Named parameters * From c3a8bf5d54a87be398d9e76335ea9559f9d314f0 Mon Sep 17 00:00:00 2001 From: Yann <17554280+yannxaver@users.noreply.github.com> Date: Sat, 11 Feb 2023 13:06:17 +0100 Subject: [PATCH 024/110] Update PostgrestQueryBuilder.ts --- src/PostgrestQueryBuilder.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PostgrestQueryBuilder.ts b/src/PostgrestQueryBuilder.ts index f610f37b..53c3d461 100644 --- a/src/PostgrestQueryBuilder.ts +++ b/src/PostgrestQueryBuilder.ts @@ -34,7 +34,7 @@ export default class PostgrestQueryBuilder< /** * Perform a SELECT query on the table or view. * - * @param columns - The columns to retrieve, separated by commas. Map a column to a custom key by writing `key:column` + * @param columns - The columns to retrieve, separated by commas. Columns can be renamed when returned with `customName:columnName` * * @param options - Named parameters * From 9fb56c7e73cd4b7e81e2c8ee4ce5dab55a2f0147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20H=C3=BCbelbauer?= Date: Tue, 21 Feb 2023 07:59:01 +0100 Subject: [PATCH 025/110] fix: prettify intersected types when selecting multiple columns (#399) * Prettify intersected types when selecting multiple columns Resolves #398 * update type test --------- Co-authored-by: Bobbie Soedirgo --- src/select-query-parser.ts | 4 ++-- src/types.ts | 3 +++ test/index.test-d.ts | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/select-query-parser.ts b/src/select-query-parser.ts index dc90ec78..5f8c5a74 100644 --- a/src/select-query-parser.ts +++ b/src/select-query-parser.ts @@ -1,6 +1,6 @@ // Credits to @bnjmnt4n (https://www.npmjs.com/package/postgrest-query) -import { GenericSchema } from './types' +import { GenericSchema, Prettify } from './types' type Whitespace = ' ' | '\n' | '\t' @@ -342,7 +342,7 @@ type GetResultHelper< ? GetResultHelper & Acc> : Fields extends [infer R, ...infer Rest] ? GetResultHelper & Acc> - : Acc + : Prettify /** * Constructs a type definition for an object based on a given PostgREST query. diff --git a/src/types.ts b/src/types.ts index f9bbf662..480e8260 100644 --- a/src/types.ts +++ b/src/types.ts @@ -69,3 +69,6 @@ export type GenericSchema = { Views: Record Functions: Record } + +// https://twitter.com/mattpocockuk/status/1622730173446557697 +export type Prettify = { [K in keyof T]: T[K] } & {} diff --git a/test/index.test-d.ts b/test/index.test-d.ts index cec1a1ae..b6d388d0 100644 --- a/test/index.test-d.ts +++ b/test/index.test-d.ts @@ -52,7 +52,7 @@ const postgrest = new PostgrestClient(REST_URL) if (error) { throw new Error(error.message) } - expectType<{ bar: Json } & { baz: string }>(data) + expectType<{ bar: Json, baz: string }>(data) } // rpc return type From c69ef50e633e5bf96da8856d769b9f9a11b0e34d Mon Sep 17 00:00:00 2001 From: tvogel Date: Fri, 31 Mar 2023 13:22:43 +0200 Subject: [PATCH 026/110] feat: Support for double-quoted identifiers in queries (#415) --- src/select-query-parser.ts | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/src/select-query-parser.ts b/src/select-query-parser.ts index 5f8c5a74..f5c02fda 100644 --- a/src/select-query-parser.ts +++ b/src/select-query-parser.ts @@ -124,12 +124,39 @@ type ReadLettersHelper = string extend : [Acc, ''] /** - * Parses an identifier. + * Reads a consecutive sequence of more than 1 double-quoted letters, + * where letters are `[^"]`. + */ +type ReadQuotedLetters = string extends Input + ? GenericStringError + : Input extends `"${infer Remainder}` + ? ReadQuotedLettersHelper extends [`${infer Letters}`, `${infer Remainder}`] + ? Letters extends '' + ? ParserError<`Expected string at \`${Remainder}\``> + : [Letters, Remainder] + : ReadQuotedLettersHelper + : ParserError<`Not a double-quoted string at \`${Input}\``> + +type ReadQuotedLettersHelper = string extends Input + ? GenericStringError + : Input extends `${infer L}${infer Remainder}` + ? L extends '"' + ? [Acc, Remainder] + : ReadQuotedLettersHelper + : ParserError<`Missing closing double-quote in \`"${Acc}${Input}\``> + +/** + * Parses a (possibly double-quoted) identifier. * For now, identifiers are just sequences of more than 1 letter. - * - * TODO: allow for double quoted strings. */ -type ParseIdentifier = ReadLetters +type ParseIdentifier = ReadLetters extends [ + infer Name, + `${infer Remainder}` +] + ? [Name, `${Remainder}`] + : ReadQuotedLetters extends [infer Name, `${infer Remainder}`] + ? [Name, `${Remainder}`] + : ParserError<`No (possibly double-quoted) identifier at \`${Input}\``> /** * Parses a node. From 320ac92ea7b86e3c77a2a248483c330603607a02 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Apr 2023 09:39:52 +0000 Subject: [PATCH 027/110] chore(deps): bump shell-quote from 1.7.2 to 1.8.0 Bumps [shell-quote](https://github.com/ljharb/shell-quote) from 1.7.2 to 1.8.0. - [Release notes](https://github.com/ljharb/shell-quote/releases) - [Changelog](https://github.com/ljharb/shell-quote/blob/main/CHANGELOG.md) - [Commits](https://github.com/ljharb/shell-quote/compare/v1.7.2...v1.8.0) --- updated-dependencies: - dependency-name: shell-quote dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index ce1f8542..08caf537 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4823,10 +4823,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", @@ -9382,9 +9385,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": { From 76a9a94afc88c4346de7fed7c8196080a52a575f Mon Sep 17 00:00:00 2001 From: steve-chavez Date: Sat, 8 Apr 2023 17:10:23 -0500 Subject: [PATCH 028/110] test: postgrest 11 pre-release --- test/db/docker-compose.yml | 2 +- test/transforms.ts | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/db/docker-compose.yml b/test/db/docker-compose.yml index 7dcb8c15..ac61a3b1 100644 --- a/test/db/docker-compose.yml +++ b/test/db/docker-compose.yml @@ -3,7 +3,7 @@ version: '3' services: rest: - image: postgrest/postgrest:v10.1.2 + image: postgrest/postgrest:v10.2.0.20230407 ports: - '3000:3000' environment: diff --git a/test/transforms.ts b/test/transforms.ts index 8d82fa66..c1074cc8 100644 --- a/test/transforms.ts +++ b/test/transforms.ts @@ -298,7 +298,7 @@ test('explain with json/text format', async () => { ], "Startup Cost": 17.65, "Strategy": "Plain", - "Total Cost": 17.68, + "Total Cost": 17.67, }, }, ], @@ -310,7 +310,7 @@ test('explain with json/text format', async () => { const res2 = await postgrest.from('users').select().explain() expect(res2.data).toMatch( - `Aggregate (cost=17.65..17.68 rows=1 width=112) + `Aggregate (cost=17.65..17.67 rows=1 width=112) -> Seq Scan on users (cost=0.00..15.10 rows=510 width=132) ` ) @@ -332,7 +332,7 @@ test('explain with options', async () => { "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", + "COALESCE(json_agg(ROW(users.username, users.data, users.age_range, users.status, users.catchphrase)), '[]'::json)", "NULLIF(current_setting('response.headers'::text, true), ''::text)", "NULLIF(current_setting('response.status'::text, true), ''::text)", ], @@ -364,9 +364,9 @@ test('explain with options', async () => { ], "Startup Cost": 17.65, "Strategy": "Plain", - "Total Cost": 17.68, + "Total Cost": 17.67, }, - "Query Identifier": -6192475787150577000, + "Query Identifier": 3302819211508333000, "Settings": Object { "effective_cache_size": "128MB", "search_path": "\\"public\\", \\"extensions\\"", From 62b49e10caacca11e5b1cdb59d2fa220e849c204 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Fri, 14 Apr 2023 17:53:46 +0800 Subject: [PATCH 029/110] feat: bulk inserts/upserts w/ column defaults --- src/PostgrestQueryBuilder.ts | 39 ++++++++++++++++++++++++------------ test/basic.ts | 18 +++++++++++++++++ 2 files changed, 44 insertions(+), 13 deletions(-) diff --git a/src/PostgrestQueryBuilder.ts b/src/PostgrestQueryBuilder.ts index 53c3d461..d779d54b 100644 --- a/src/PostgrestQueryBuilder.ts +++ b/src/PostgrestQueryBuilder.ts @@ -113,24 +113,31 @@ export default class PostgrestQueryBuilder< * * `"estimated"`: Uses exact count for low numbers and planned count for high * numbers. + * + * @param options.defaultToNull - Make missing fields default to `null`. + * Otherwise, use the default value for the column. */ insert( values: Row | Row[], { count, + defaultToNull = true, }: { count?: 'exact' | 'planned' | 'estimated' + defaultToNull?: boolean } = {} ): 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,7 +154,7 @@ export default class PostgrestQueryBuilder< url: this.url, headers: this.headers, schema: this.schema, - body, + body: values, fetch: this.fetch, allowEmpty: false, } as unknown as PostgrestBuilder) @@ -185,6 +192,9 @@ export default class PostgrestQueryBuilder< * * `"estimated"`: Uses exact count for low numbers and planned count for high * numbers. + * + * @param options.defaultToNull - Make missing fields default to `null`. + * Otherwise, use the default value for the column. */ upsert( values: Row | Row[], @@ -192,10 +202,12 @@ export default class PostgrestQueryBuilder< onConflict, ignoreDuplicates = false, count, + defaultToNull = true, }: { onConflict?: string ignoreDuplicates?: boolean count?: 'exact' | 'planned' | 'estimated' + defaultToNull?: boolean } = {} ): PostgrestFilterBuilder { const method = 'POST' @@ -203,12 +215,14 @@ export default class PostgrestQueryBuilder< 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(',') @@ -217,7 +231,7 @@ export default class PostgrestQueryBuilder< url: this.url, headers: this.headers, schema: this.schema, - body, + body: values, fetch: this.fetch, allowEmpty: false, } as unknown as PostgrestBuilder) @@ -254,13 +268,12 @@ 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,7 +281,7 @@ export default class PostgrestQueryBuilder< url: this.url, headers: this.headers, schema: this.schema, - body, + body: values, fetch: this.fetch, allowEmpty: false, } as unknown as PostgrestBuilder) diff --git a/test/basic.ts b/test/basic.ts index 15059ec4..6fb2c9be 100644 --- a/test/basic.ts +++ b/test/basic.ts @@ -1078,6 +1078,24 @@ describe("insert, update, delete with count: 'exact'", () => { `) }) + 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() + }) + + 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() + }) + test("update with count: 'exact'", async () => { let res = await postgrest .from('messages') From adf4839e87779df24616e407e325de05db1c40dd Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Fri, 14 Apr 2023 18:32:06 +0800 Subject: [PATCH 030/110] test: make snapshots more deterministic --- src/types.ts | 4 +- test/index.test-d.ts | 2 +- test/transforms.ts | 102 ++++++++++++------------------------------- 3 files changed, 29 insertions(+), 79 deletions(-) diff --git a/src/types.ts b/src/types.ts index 480e8260..5379b271 100644 --- a/src/types.ts +++ b/src/types.ts @@ -35,9 +35,7 @@ export interface PostgrestResponseFailure extends PostgrestResponseBase { // TODO: in v3: // - remove PostgrestResponse and PostgrestMaybeSingleResponse // - rename PostgrestSingleResponse to PostgrestResponse -export type PostgrestSingleResponse = - | PostgrestResponseSuccess - | PostgrestResponseFailure +export type PostgrestSingleResponse = PostgrestResponseSuccess | PostgrestResponseFailure export type PostgrestMaybeSingleResponse = PostgrestSingleResponse export type PostgrestResponse = PostgrestSingleResponse diff --git a/test/index.test-d.ts b/test/index.test-d.ts index b6d388d0..b8bc95c7 100644 --- a/test/index.test-d.ts +++ b/test/index.test-d.ts @@ -52,7 +52,7 @@ const postgrest = new PostgrestClient(REST_URL) if (error) { throw new Error(error.message) } - expectType<{ bar: Json, baz: string }>(data) + expectType<{ bar: Json; baz: string }>(data) } // rpc return type diff --git a/test/transforms.ts b/test/transforms.ts index c1074cc8..b50d7728 100644 --- a/test/transforms.ts +++ b/test/transforms.ts @@ -270,50 +270,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.67, - }, + "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.67 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 () => { @@ -321,52 +302,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)", - "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.67, - }, - "Query Identifier": 3302819211508333000, + "Plan": Any, + "Query Identifier": Any, "Settings": Object { "effective_cache_size": "128MB", "search_path": "\\"public\\", \\"extensions\\"", @@ -377,7 +328,8 @@ test('explain with options', async () => { "status": 200, "statusText": "OK", } - `) + ` + ) }) test('rollback insert/upsert', async () => { From 5ad7562c5a115647e86f41f0e0756c53e168348a Mon Sep 17 00:00:00 2001 From: Steve Chavez Date: Sun, 16 Apr 2023 17:16:36 -0500 Subject: [PATCH 031/110] Update docker-compose.yml to postgrest v11 --- test/db/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/db/docker-compose.yml b/test/db/docker-compose.yml index ac61a3b1..fd8da688 100644 --- a/test/db/docker-compose.yml +++ b/test/db/docker-compose.yml @@ -3,7 +3,7 @@ version: '3' services: rest: - image: postgrest/postgrest:v10.2.0.20230407 + image: postgrest/postgrest:v11.0.0 ports: - '3000:3000' environment: From a9c3629698e25e6571436c60ed4bb5b15fb1357d Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Mon, 17 Apr 2023 16:34:30 +0800 Subject: [PATCH 032/110] fix: use `?columns=` on upsert --- src/PostgrestQueryBuilder.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/PostgrestQueryBuilder.ts b/src/PostgrestQueryBuilder.ts index d779d54b..956d473a 100644 --- a/src/PostgrestQueryBuilder.ts +++ b/src/PostgrestQueryBuilder.ts @@ -194,7 +194,9 @@ export default class PostgrestQueryBuilder< * numbers. * * @param options.defaultToNull - Make missing fields default to `null`. - * Otherwise, use the default value for the column. + * Otherwise, use the default value for the column. This only applies when + * inserting new rows, not when merging with existing rows under + * `ignoreDuplicates: false`. */ upsert( values: Row | Row[], @@ -226,6 +228,14 @@ export default class PostgrestQueryBuilder< } 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, From 05577526fa3126f8923dbecd828527d48f36fa15 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Mon, 17 Apr 2023 16:35:46 +0800 Subject: [PATCH 033/110] test: update snapshots --- test/basic.ts | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/test/basic.ts b/test/basic.ts index 6fb2c9be..9e7951fd 100644 --- a/test/basic.ts +++ b/test/basic.ts @@ -1084,7 +1084,26 @@ describe("insert, update, delete with count: 'exact'", () => { .insert([{ id: 100 }, { slug: 'test-slug' }], { defaultToNull: false }) .select() .rollback() - expect(res).toMatchInlineSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "data": null, + "id": 100, + "slug": null, + }, + Object { + "data": null, + "id": 4, + "slug": "test-slug", + }, + ], + "error": null, + "status": 201, + "statusText": "Created", + } + `) }) test('bulk upsert with column defaults', async () => { @@ -1093,7 +1112,26 @@ describe("insert, update, delete with count: 'exact'", () => { .upsert([{ id: 1 }, { slug: 'test-slug' }], { defaultToNull: false }) .select() .rollback() - expect(res).toMatchInlineSnapshot() + expect(res).toMatchInlineSnapshot(` + Object { + "count": null, + "data": Array [ + Object { + "data": null, + "id": 1, + "slug": null, + }, + Object { + "data": null, + "id": 6, + "slug": "test-slug", + }, + ], + "error": null, + "status": 201, + "statusText": "Created", + } + `) }) test("update with count: 'exact'", async () => { From d4e03a005d68c2d73ac344951a455e4ef95ebeef Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Mon, 17 Apr 2023 17:14:30 +0800 Subject: [PATCH 034/110] feat(filters): likeAllOf, likeAnyOf, ilikeAllOf, ilikeAnyOf --- src/PostgrestFilterBuilder.ts | 52 +++++++++++++++++++++ test/filters.ts | 86 +++++++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+) diff --git a/src/PostgrestFilterBuilder.ts b/src/PostgrestFilterBuilder.ts index 1e227786..6c93b969 100644 --- a/src/PostgrestFilterBuilder.ts +++ b/src/PostgrestFilterBuilder.ts @@ -123,6 +123,32 @@ export default class PostgrestFilterBuilder< return this } + likeAllOf(column: ColumnName, patterns: string[]): this + likeAllOf(column: string, patterns: string[]): this + /** + * Match only rows where `column` matches all of `patterns` case-sensitively. + * + * @param column - The column to filter on + * @param patterns - The patterns to match with + */ + likeAllOf(column: string, patterns: string[]): this { + this.url.searchParams.append(column, `like(all).{${patterns.join(',')}}`) + return this + } + + likeAnyOf(column: ColumnName, patterns: string[]): this + likeAnyOf(column: string, patterns: 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: 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 /** @@ -136,6 +162,32 @@ export default class PostgrestFilterBuilder< return this } + ilikeAllOf(column: ColumnName, patterns: string[]): this + ilikeAllOf(column: string, patterns: 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: string[]): this { + this.url.searchParams.append(column, `ilike(all).{${patterns.join(',')}}`) + return this + } + + ilikeAnyOf(column: ColumnName, patterns: string[]): this + ilikeAnyOf(column: string, patterns: 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: string[]): this { + this.url.searchParams.append(column, `ilike(any).{${patterns.join(',')}}`) + return this + } + is( column: ColumnName, value: Row[ColumnName] & (boolean | null) diff --git a/test/filters.ts b/test/filters.ts index 5ec35b86..ac91a935 100644 --- a/test/filters.ts +++ b/test/filters.ts @@ -182,6 +182,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 +242,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(` From 1e2981f1d06f54dae08c279a92006cb974b749a6 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Tue, 18 Apr 2023 13:12:28 +0800 Subject: [PATCH 035/110] fix: populate `details` on FetchError --- src/PostgrestBuilder.ts | 6 +++--- test/transforms.ts | 11 +++++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/PostgrestBuilder.ts b/src/PostgrestBuilder.ts index 78d7c214..ad3ca1ff 100644 --- a/src/PostgrestBuilder.ts +++ b/src/PostgrestBuilder.ts @@ -150,10 +150,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/test/transforms.ts b/test/transforms.ts index 8d82fa66..4d7456c8 100644 --- a/test/transforms.ts +++ b/test/transforms.ts @@ -247,20 +247,23 @@ 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: { details: expect.any(String) } }, + ` Object { "count": null, "data": null, "error": Object { "code": "", - "details": "", + "details": Any, "hint": "", - "message": "FetchError: The user aborted a request.", + "message": "AbortError: The user aborted a request.", }, "status": 0, "statusText": "", } - `) + ` + ) }) // test('geojson', async () => { From 8030cc0e269d763e7d24ee04e7305dcf72f56c51 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Thu, 11 May 2023 13:06:49 +0800 Subject: [PATCH 036/110] fix: partial fix for maybeSingle logging 406s --- package.json | 3 ++- src/PostgrestBuilder.ts | 28 +++++++++++++++++++++++++--- src/PostgrestTransformBuilder.ts | 10 ++++++++-- test/transforms.ts | 22 ++++++++++++++++++++++ 4 files changed, 57 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 0e051492..933528a2 100644 --- a/package.json +++ b/package.json @@ -21,12 +21,13 @@ "scripts": { "clean": "rimraf dist docs/v2", "format": "prettier --write \"{src,test}/**/*.ts\"", + "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", "docs": "typedoc src/index.ts --out docs/v2", "docs:json": "typedoc --json docs/v2/spec.json --excludeExternals src/index.ts", - "test": "run-s test:types db:clean db:run test:run db:clean", + "test": "run-s format:check test:types db:clean db:run test:run db:clean", "test:run": "jest --runInBand", "test:update": "run-s db:clean db:run && jest --runInBand --updateSnapshot && run-s db:clean", "test:types": "run-s build:module && tsd --files test/*.test-d.ts", diff --git a/src/PostgrestBuilder.ts b/src/PostgrestBuilder.ts index ad3ca1ff..e48d69f0 100644 --- a/src/PostgrestBuilder.ts +++ b/src/PostgrestBuilder.ts @@ -13,7 +13,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,7 +23,7 @@ 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 @@ -101,6 +101,28 @@ 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() @@ -126,7 +148,7 @@ export default abstract class PostgrestBuilder } } - if (error && this.allowEmpty && error?.details?.includes('Results contain 0 rows')) { + if (error && this.isMaybeSingle && error?.details?.includes('Results contain 0 rows')) { error = null status = 200 statusText = 'OK' diff --git a/src/PostgrestTransformBuilder.ts b/src/PostgrestTransformBuilder.ts index 646e85ab..9055d394 100644 --- a/src/PostgrestTransformBuilder.ts +++ b/src/PostgrestTransformBuilder.ts @@ -149,8 +149,14 @@ export default class PostgrestTransformBuilder< maybeSingle< ResultOne = Result extends (infer ResultOne)[] ? ResultOne : never >(): PostgrestBuilder { - this.headers['Accept'] = 'application/vnd.pgrst.object+json' - this.allowEmpty = true + // 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 } diff --git a/test/transforms.ts b/test/transforms.ts index 7036a9a2..cce8e227 100644 --- a/test/transforms.ts +++ b/test/transforms.ts @@ -188,6 +188,28 @@ test('maybeSingle', async () => { `) }) +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": "Results contain 2 rows, application/vnd.pgrst.object+json requires 1 row", + "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).toMatchInlineSnapshot(` From 578fe56449b220818af1c53978bf4989423b8160 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Thu, 18 May 2023 14:59:18 +0800 Subject: [PATCH 037/110] chore(test): regenerate types --- test/types.ts | 123 ++++++++++++++++++++++++++++---------------------- 1 file changed, 70 insertions(+), 53 deletions(-) diff --git a/test/types.ts b/test/types.ts index 5a24428e..2d5e86d8 100644 --- a/test/types.ts +++ b/test/types.ts @@ -5,22 +5,22 @@ export interface Database { 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 } } } @@ -29,94 +29,99 @@ 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: { + channels: { Row: { + data: Json | null id: number - address: string | null - shop_geom: unknown | null + slug: string | null } Insert: { - id: number - address?: string | null - shop_geom?: unknown | null + data?: Json | null + id?: number + slug?: string | null } Update: { + data?: Json | null id?: number - address?: string | null - shop_geom?: unknown | null + slug?: string | null } } - users: { + messages: { Row: { - username: string + channel_id: number data: Json | null - age_range: unknown | null - catchphrase: unknown | null - status: Database['public']['Enums']['user_status'] | null + id: number + message: string | null + username: string } Insert: { - username: string + channel_id: number data?: Json | null - age_range?: unknown | null - catchphrase?: unknown | null - status?: Database['public']['Enums']['user_status'] | null + id?: number + message?: string | null + username: string } Update: { - username?: string + channel_id?: number data?: Json | null - age_range?: unknown | null - catchphrase?: unknown | null - status?: Database['public']['Enums']['user_status'] | null + id?: number + message?: string | null + username?: string } } - channels: { + shops: { Row: { + address: string | null id: number - data: Json | null - slug: string | null + shop_geom: unknown | null } Insert: { - id?: number - data?: Json | null - slug?: string | null + address?: string | null + id: number + shop_geom?: unknown | null } Update: { + address?: string | null id?: number - data?: Json | null - slug?: string | null + shop_geom?: unknown | null } } - messages: { + users: { Row: { - id: number + age_range: unknown | null + catchphrase: unknown | null data: Json | null - message: string | null + status: Database['public']['Enums']['user_status'] | null username: string - channel_id: number } Insert: { - id?: number + age_range?: unknown | null + catchphrase?: unknown | null data?: Json | null - message?: string | null + status?: Database['public']['Enums']['user_status'] | null username: string - channel_id: number } Update: { - id?: number + age_range?: unknown | null + catchphrase?: unknown | null data?: Json | null - message?: string | null + status?: Database['public']['Enums']['user_status'] | null username?: string - channel_id?: number } } } @@ -128,30 +133,39 @@ export interface Database { } 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 } } } Functions: { 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 +176,8 @@ export interface Database { Enums: { user_status: 'ONLINE' | 'OFFLINE' } + CompositeTypes: { + [_ in never]: never + } } } From fc59958fe1ad0ba39b9245f7a2fb2433b9938e21 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Fri, 26 May 2023 16:47:46 +0800 Subject: [PATCH 038/110] feat(types): determine relationship cardinality --- src/PostgrestFilterBuilder.ts | 5 +- src/PostgrestQueryBuilder.ts | 18 ++++--- src/PostgrestTransformBuilder.ts | 13 ++--- src/select-query-parser.ts | 86 +++++++++++++++++++++++++++----- test/index.test-d.ts | 18 +++++++ test/types.ts | 18 +++++++ 6 files changed, 131 insertions(+), 27 deletions(-) diff --git a/src/PostgrestFilterBuilder.ts b/src/PostgrestFilterBuilder.ts index 6c93b969..cb6beeeb 100644 --- a/src/PostgrestFilterBuilder.ts +++ b/src/PostgrestFilterBuilder.ts @@ -28,8 +28,9 @@ type FilterOperator = export default class PostgrestFilterBuilder< Schema extends GenericSchema, Row extends Record, - Result -> extends PostgrestTransformBuilder { + Result, + Relationships = unknown +> extends PostgrestTransformBuilder { eq(column: ColumnName, value: Row[ColumnName]): this eq(column: string, value: unknown): this /** diff --git a/src/PostgrestQueryBuilder.ts b/src/PostgrestQueryBuilder.ts index 956d473a..d94c4c4c 100644 --- a/src/PostgrestQueryBuilder.ts +++ b/src/PostgrestQueryBuilder.ts @@ -5,7 +5,8 @@ import { Fetch, GenericSchema, GenericTable, GenericView } from './types' export default class PostgrestQueryBuilder< Schema extends GenericSchema, - Relation extends GenericTable | GenericView + Relation extends GenericTable | GenericView, + Relationships = Relation extends { Relationships: infer R } ? R : unknown > { url: URL headers: Record @@ -52,7 +53,10 @@ export default class PostgrestQueryBuilder< * `"estimated"`: Uses exact count for low numbers and planned count for high * numbers. */ - select>( + select< + Query extends string = '*', + ResultOne = GetResult + >( columns?: Query, { head = false, @@ -61,7 +65,7 @@ export default class PostgrestQueryBuilder< head?: boolean count?: 'exact' | 'planned' | 'estimated' } = {} - ): PostgrestFilterBuilder { + ): PostgrestFilterBuilder { const method = head ? 'HEAD' : 'GET' // Remove whitespaces except when quoted let quoted = false @@ -126,7 +130,7 @@ export default class PostgrestQueryBuilder< count?: 'exact' | 'planned' | 'estimated' defaultToNull?: boolean } = {} - ): PostgrestFilterBuilder { + ): PostgrestFilterBuilder { const method = 'POST' const prefersHeaders = [] @@ -211,7 +215,7 @@ export default class PostgrestQueryBuilder< count?: 'exact' | 'planned' | 'estimated' defaultToNull?: boolean } = {} - ): PostgrestFilterBuilder { + ): PostgrestFilterBuilder { const method = 'POST' const prefersHeaders = [`resolution=${ignoreDuplicates ? 'ignore' : 'merge'}-duplicates`] @@ -275,7 +279,7 @@ export default class PostgrestQueryBuilder< }: { count?: 'exact' | 'planned' | 'estimated' } = {} - ): PostgrestFilterBuilder { + ): PostgrestFilterBuilder { const method = 'PATCH' const prefersHeaders = [] if (this.headers['Prefer']) { @@ -320,7 +324,7 @@ export default class PostgrestQueryBuilder< count, }: { count?: 'exact' | 'planned' | 'estimated' - } = {}): PostgrestFilterBuilder { + } = {}): PostgrestFilterBuilder { const method = 'DELETE' const prefersHeaders = [] if (count) { diff --git a/src/PostgrestTransformBuilder.ts b/src/PostgrestTransformBuilder.ts index 9055d394..35e7c45c 100644 --- a/src/PostgrestTransformBuilder.ts +++ b/src/PostgrestTransformBuilder.ts @@ -5,7 +5,8 @@ import { GenericSchema } from './types' export default class PostgrestTransformBuilder< Schema extends GenericSchema, Row extends Record, - Result + Result, + Relationships = unknown > extends PostgrestBuilder { /** * Perform a SELECT on the query result. @@ -16,9 +17,9 @@ export default class PostgrestTransformBuilder< * * @param columns - The columns to retrieve, separated by commas */ - select>( + select>( columns?: Query - ): PostgrestTransformBuilder { + ): PostgrestTransformBuilder { // Remove whitespaces except when quoted let quoted = false const cleanedColumns = (columns ?? '*') @@ -38,7 +39,7 @@ export default class PostgrestTransformBuilder< this.headers['Prefer'] += ',' } this.headers['Prefer'] += 'return=representation' - return this as unknown as PostgrestTransformBuilder + return this as unknown as PostgrestTransformBuilder } order( @@ -249,7 +250,7 @@ export default class PostgrestTransformBuilder< * * @typeParam NewResult - The new result type to override with */ - returns(): PostgrestTransformBuilder { - return this as unknown as PostgrestTransformBuilder + returns(): PostgrestTransformBuilder { + return this as unknown as PostgrestTransformBuilder } } diff --git a/src/select-query-parser.ts b/src/select-query-parser.ts index f5c02fda..2179d280 100644 --- a/src/select-query-parser.ts +++ b/src/select-query-parser.ts @@ -65,6 +65,26 @@ type EatWhitespace = string extends Input ? EatWhitespace : Input +type HasFKey = Relationships extends [infer R] + ? R extends { foreignKeyName: FKeyName } + ? true + : false + : Relationships extends [infer R, ...infer Rest] + ? HasFKey extends true + ? true + : HasFKey + : false + +type HasFKeyToFRel = Relationships extends [infer R] + ? R extends { referencedRelation: FRelName } + ? true + : false + : Relationships extends [infer R, ...infer Rest] + ? HasFKeyToFRel extends true + ? true + : HasFKeyToFRel + : false + /** * Constructs a type definition for a single field of an object. * @@ -75,20 +95,44 @@ type EatWhitespace = string extends Input type ConstructFieldDefinition< Schema extends GenericSchema, Row extends Record, + Relationships, Field -> = Field extends { - star: true -} +> = Field extends { star: true } ? Row + : Field extends { name: string; original: string; hint: string; children: unknown[] } + ? { + [_ in Field['name']]: GetResultHelper< + Schema, + (Schema['Tables'] & Schema['Views'])[Field['original']]['Row'], + (Schema['Tables'] & Schema['Views'])[Field['original']] extends { Relationships: infer R } + ? R + : unknown, + Field['children'], + unknown + > extends infer Child + ? Relationships extends unknown[] + ? HasFKey extends true + ? Child | null + : Child[] + : Child[] + : never + } : Field extends { name: string; original: string; children: unknown[] } ? { [_ in Field['name']]: GetResultHelper< Schema, (Schema['Tables'] & Schema['Views'])[Field['original']]['Row'], + (Schema['Tables'] & Schema['Views'])[Field['original']] extends { Relationships: infer R } + ? R + : unknown, Field['children'], unknown > extends infer Child - ? Child | Child[] | null + ? Relationships extends unknown[] + ? HasFKeyToFRel extends true + ? Child | null + : Child[] + : Child[] : never } : Field extends { name: string; original: string } @@ -191,14 +235,14 @@ type ParseNode = Input extends '' ? ParseEmbeddedResource> : ParserError<'Expected embedded resource after `!inner`'> : EatWhitespace extends `!${infer Remainder}` - ? ParseIdentifier> extends [infer _Hint, `${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; original: Name; children: Fields }, EatWhitespace] + [{ name: Name; original: Name; hint: Hint; children: Fields }, EatWhitespace] : ParseEmbeddedResource> extends ParserError ? ParseEmbeddedResource> : ParserError<'Expected embedded resource after `!inner`'> @@ -207,7 +251,7 @@ type ParseNode = Input extends '' `${infer Remainder}` ] ? // `field!hint(nodes)` - [{ name: Name; original: Name; children: Fields }, EatWhitespace] + [{ name: Name; original: Name; hint: Hint; children: Fields }, EatWhitespace] : ParseEmbeddedResource> extends ParserError ? ParseEmbeddedResource> : ParserError<'Expected embedded resource after `!hint`'> @@ -225,14 +269,17 @@ type ParseNode = Input extends '' ? ParseEmbeddedResource> : ParserError<'Expected embedded resource after `!inner`'> : EatWhitespace extends `!${infer Remainder}` - ? ParseIdentifier> extends [infer _Hint, `${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; original: OriginalName; children: Fields }, EatWhitespace] + [ + { name: Name; original: OriginalName; hint: Hint; children: Fields }, + EatWhitespace + ] : ParseEmbeddedResource> extends ParserError ? ParseEmbeddedResource> : ParserError<'Expected embedded resource after `!inner`'> @@ -245,6 +292,7 @@ type ParseNode = Input extends '' { name: Name original: OriginalName + hint: Hint children: Fields }, EatWhitespace @@ -363,12 +411,25 @@ type ParseQuery = string extends Query type GetResultHelper< Schema extends GenericSchema, Row extends Record, + Relationships, Fields extends unknown[], Acc > = Fields extends [infer R] - ? GetResultHelper & Acc> + ? GetResultHelper< + Schema, + Row, + Relationships, + [], + ConstructFieldDefinition & Acc + > : Fields extends [infer R, ...infer Rest] - ? GetResultHelper & Acc> + ? GetResultHelper< + Schema, + Row, + Relationships, + Rest, + ConstructFieldDefinition & Acc + > : Prettify /** @@ -380,7 +441,8 @@ type GetResultHelper< export type GetResult< Schema extends GenericSchema, Row extends Record, + Relationships, Query extends string > = ParseQuery extends unknown[] - ? GetResultHelper, unknown> + ? GetResultHelper, unknown> : ParseQuery diff --git a/test/index.test-d.ts b/test/index.test-d.ts index b8bc95c7..2bf27671 100644 --- a/test/index.test-d.ts +++ b/test/index.test-d.ts @@ -63,3 +63,21 @@ const postgrest = new PostgrestClient(REST_URL) } expectType<'ONLINE' | 'OFFLINE'>(data) } + +// many-to-one relationship +{ + const { data: message, error } = await postgrest.from('messages').select('user:users(*)').single() + if (error) { + throw new Error(error.message) + } + expectType(message.user) +} + +// one-to-many relationship +{ + const { data: user, error } = await postgrest.from('users').select('messages(*)').single() + if (error) { + throw new Error(error.message) + } + expectType(user.messages) +} diff --git a/test/types.ts b/test/types.ts index 2d5e86d8..74fd1e07 100644 --- a/test/types.ts +++ b/test/types.ts @@ -22,6 +22,7 @@ export interface Database { status?: Database['public']['Enums']['user_status'] | null username?: string } + Relationships: [] } } Views: { @@ -60,6 +61,7 @@ export interface Database { id?: number slug?: string | null } + Relationships: [] } messages: { Row: { @@ -83,6 +85,20 @@ export interface Database { message?: string | null username?: string } + Relationships: [ + { + foreignKeyName: 'messages_username_fkey' + columns: ['username'] + referencedRelation: 'users' + referencedColumns: ['username'] + }, + { + foreignKeyName: 'messages_channel_id_fkey' + columns: ['channel_id'] + referencedRelation: 'channels' + referencedColumns: ['id'] + } + ] } shops: { Row: { @@ -100,6 +116,7 @@ export interface Database { id?: number shop_geom?: unknown | null } + Relationships: [] } users: { Row: { @@ -123,6 +140,7 @@ export interface Database { status?: Database['public']['Enums']['user_status'] | null username?: string } + Relationships: [] } } Views: { From aeb2ce9f1bdca64d0a0d12812c777b0e76df24ae Mon Sep 17 00:00:00 2001 From: Ryuya Date: Wed, 14 Jun 2023 12:28:19 +0900 Subject: [PATCH 039/110] fix: return SelectQueryError when referencing missing columns (#436) * Returns 'never' if a column that does not exist in the schema * fix: return SelectQueryError when referencing missing columns --------- Co-authored-by: Bobbie Soedirgo --- src/select-query-parser.ts | 37 ++++++++++++++++++++++--------------- test/index.test-d.ts | 9 ++++++++- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/select-query-parser.ts b/src/select-query-parser.ts index 2179d280..f7580e83 100644 --- a/src/select-query-parser.ts +++ b/src/select-query-parser.ts @@ -55,6 +55,7 @@ type Json = string | number | boolean | null | { [key: string]: Json } | Json[] */ type ParserError = { error: true } & Message type GenericStringError = ParserError<'Received a generic string'> +export type SelectQueryError = { error: true } & Message /** * Trims whitespace from the left of the input. @@ -136,7 +137,9 @@ type ConstructFieldDefinition< : never } : Field extends { name: string; original: string } - ? { [K in Field['name']]: Row[Field['original']] } + ? Field['original'] extends keyof Row + ? { [K in Field['name']]: Row[Field['original']] } + : SelectQueryError<`Referencing missing column \`${Field['original']}\``> : Field extends { name: string; type: infer T } ? { [K in Field['name']]: T } : Record @@ -415,21 +418,25 @@ type GetResultHelper< Fields extends unknown[], Acc > = Fields extends [infer R] - ? GetResultHelper< - Schema, - Row, - Relationships, - [], - ConstructFieldDefinition & Acc - > + ? ConstructFieldDefinition extends SelectQueryError + ? SelectQueryError + : GetResultHelper< + Schema, + Row, + Relationships, + [], + ConstructFieldDefinition & Acc + > : Fields extends [infer R, ...infer Rest] - ? GetResultHelper< - Schema, - Row, - Relationships, - Rest, - ConstructFieldDefinition & Acc - > + ? ConstructFieldDefinition extends SelectQueryError + ? SelectQueryError + : GetResultHelper< + Schema, + Row, + Relationships, + Rest, + ConstructFieldDefinition & Acc + > : Prettify /** diff --git a/test/index.test-d.ts b/test/index.test-d.ts index 2bf27671..d2407856 100644 --- a/test/index.test-d.ts +++ b/test/index.test-d.ts @@ -1,5 +1,6 @@ import { expectError, expectType } from 'tsd' -import { PostgrestClient } from '../src/index' +import { PostgrestClient, PostgrestSingleResponse } from '../src/index' +import { SelectQueryError } from '../src/select-query-parser' import { Database, Json } from './types' const REST_URL = 'http://localhost:3000' @@ -81,3 +82,9 @@ const postgrest = new PostgrestClient(REST_URL) } expectType(user.messages) } + +// referencing missing column +{ + const res = await postgrest.from('users').select('username, dat') + expectType[]>>(res) +} From cb94a8d267379a3e1ca42a35c005653cba6b3304 Mon Sep 17 00:00:00 2001 From: Dave Iverson Date: Thu, 22 Jun 2023 22:02:23 -0500 Subject: [PATCH 040/110] docs: improve tsdoc for the `range()` method (#439) * Documentation improvements for the `range()` method These updates are based on feedback in issue #15222 (https://github.com/supabase/supabase/issues/15222) The original docs state that "range" takes a starting index and ending index and returns the values between them. This implies that it's using the primary ID. But it actually works more like limit + offset. --------- Co-authored-by: Bobbie Soedirgo --- src/PostgrestTransformBuilder.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/PostgrestTransformBuilder.ts b/src/PostgrestTransformBuilder.ts index 35e7c45c..4a416098 100644 --- a/src/PostgrestTransformBuilder.ts +++ b/src/PostgrestTransformBuilder.ts @@ -101,7 +101,11 @@ export default class PostgrestTransformBuilder< } /** - * Limit the query result by `from` and `to` inclusively. + * Limit the query result by starting at an offset (`from`) and ending at the offset (`from + 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 From c95035a752882e8ba7e34ab9ebc13d257e0559c6 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Fri, 7 Jul 2023 15:13:00 +0800 Subject: [PATCH 041/110] fix: type error when ordering on json[b] columns --- src/PostgrestTransformBuilder.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PostgrestTransformBuilder.ts b/src/PostgrestTransformBuilder.ts index 4a416098..8cbf87a1 100644 --- a/src/PostgrestTransformBuilder.ts +++ b/src/PostgrestTransformBuilder.ts @@ -48,7 +48,7 @@ export default class PostgrestTransformBuilder< ): this order( column: string, - options?: { ascending?: boolean; nullsFirst?: boolean; foreignTable: string } + options?: { ascending?: boolean; nullsFirst?: boolean; foreignTable?: string } ): this /** * Order the query result by `column`. From 2f4df8724cab27d836431f69846c0dbb110bb697 Mon Sep 17 00:00:00 2001 From: Joonas Date: Mon, 17 Jul 2023 07:07:48 +0300 Subject: [PATCH 042/110] chore: Mark array filter values readonly (#443) --- src/PostgrestFilterBuilder.ts | 63 ++++++++++++++++++++++------------- test/filters.ts | 3 +- 2 files changed, 41 insertions(+), 25 deletions(-) diff --git a/src/PostgrestFilterBuilder.ts b/src/PostgrestFilterBuilder.ts index cb6beeeb..9f4c0807 100644 --- a/src/PostgrestFilterBuilder.ts +++ b/src/PostgrestFilterBuilder.ts @@ -124,28 +124,34 @@ export default class PostgrestFilterBuilder< return this } - likeAllOf(column: ColumnName, patterns: string[]): this - likeAllOf(column: string, patterns: string[]): this + likeAllOf( + column: ColumnName, + patterns: readonly string[] + ): this + likeAllOf(column: string, patterns: readonly string[]): this /** * Match only rows where `column` matches all of `patterns` case-sensitively. * * @param column - The column to filter on * @param patterns - The patterns to match with */ - likeAllOf(column: string, patterns: string[]): this { + likeAllOf(column: string, patterns: readonly string[]): this { this.url.searchParams.append(column, `like(all).{${patterns.join(',')}}`) return this } - likeAnyOf(column: ColumnName, patterns: string[]): this - likeAnyOf(column: string, patterns: string[]): 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: string[]): this { + likeAnyOf(column: string, patterns: readonly string[]): this { this.url.searchParams.append(column, `like(any).{${patterns.join(',')}}`) return this } @@ -163,28 +169,34 @@ export default class PostgrestFilterBuilder< return this } - ilikeAllOf(column: ColumnName, patterns: string[]): this - ilikeAllOf(column: string, patterns: string[]): 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: string[]): this { + ilikeAllOf(column: string, patterns: readonly string[]): this { this.url.searchParams.append(column, `ilike(all).{${patterns.join(',')}}`) return this } - ilikeAnyOf(column: ColumnName, patterns: string[]): this - ilikeAnyOf(column: string, patterns: string[]): 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: string[]): this { + ilikeAnyOf(column: string, patterns: readonly string[]): this { this.url.searchParams.append(column, `ilike(any).{${patterns.join(',')}}`) return this } @@ -211,15 +223,18 @@ export default class PostgrestFilterBuilder< return this } - in(column: ColumnName, values: Row[ColumnName][]): this - in(column: string, values: unknown[]): 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: string, values: unknown[]): this { + in(column: string, values: readonly unknown[]): this { const cleanedValues = values .map((s) => { // handle postgrest reserved characters @@ -234,9 +249,9 @@ export default class PostgrestFilterBuilder< contains( column: ColumnName, - value: string | Row[ColumnName][] | Record + value: string | ReadonlyArray | Record ): this - contains(column: string, value: string | unknown[] | 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`. @@ -244,7 +259,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: 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 @@ -261,9 +276,9 @@ export default class PostgrestFilterBuilder< containedBy( column: ColumnName, - value: string | Row[ColumnName][] | Record + value: string | ReadonlyArray | Record ): this - containedBy(column: string, value: string | unknown[] | 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`. @@ -271,7 +286,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: 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}`) @@ -360,9 +375,9 @@ export default class PostgrestFilterBuilder< overlaps( column: ColumnName, - value: string | Row[ColumnName][] + value: string | ReadonlyArray ): this - overlaps(column: string, value: string | unknown[]): 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. @@ -370,7 +385,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: 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}`) diff --git a/test/filters.ts b/test/filters.ts index ac91a935..98a76e4d 100644 --- a/test/filters.ts +++ b/test/filters.ts @@ -312,7 +312,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, From 32e220c85245fb9f91b5037ff37c020bd7bd1131 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Fri, 21 Jul 2023 15:05:54 +0800 Subject: [PATCH 043/110] chore(docs): add note re: defaultToNull --- src/PostgrestQueryBuilder.ts | 37 ++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src/PostgrestQueryBuilder.ts b/src/PostgrestQueryBuilder.ts index d94c4c4c..26776e87 100644 --- a/src/PostgrestQueryBuilder.ts +++ b/src/PostgrestQueryBuilder.ts @@ -96,6 +96,20 @@ 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. * @@ -119,7 +133,8 @@ export default class PostgrestQueryBuilder< * numbers. * * @param options.defaultToNull - Make missing fields default to `null`. - * Otherwise, use the default value for the column. + * Otherwise, use the default value for the column. Only applies for bulk + * inserts. */ insert( values: Row | Row[], @@ -164,6 +179,24 @@ 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 @@ -200,7 +233,7 @@ export default class PostgrestQueryBuilder< * @param options.defaultToNull - Make missing fields default to `null`. * Otherwise, use the default value for the column. This only applies when * inserting new rows, not when merging with existing rows under - * `ignoreDuplicates: false`. + * `ignoreDuplicates: false`. This also only applies when doing bulk upserts. */ upsert( values: Row | Row[], From 8d3f1e9461ff1625108ef5e819b885c5376e267f Mon Sep 17 00:00:00 2001 From: Spencer Jones Date: Sat, 5 Aug 2023 11:26:28 -0500 Subject: [PATCH 044/110] feat: add dynamic schema to postgrest client Resolves https://github.com/supabase/postgrest-js/issues/280 --- src/PostgrestClient.ts | 33 +++++++++++++++++++++--- test/basic.ts | 58 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 4 deletions(-) diff --git a/src/PostgrestClient.ts b/src/PostgrestClient.ts index 9e331104..e7d9678a 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,7 +52,7 @@ export default class PostgrestClient< ) { this.url = url this.headers = { ...DEFAULT_HEADERS, ...headers } - this.schema = schema + this.schemaName = schema this.fetch = fetch } @@ -73,7 +73,32 @@ export default class PostgrestClient< const url = new URL(`${this.url}/${relation}`) 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< + Database, + DynamicSchema, + Database[DynamicSchema] extends GenericSchema ? Database[DynamicSchema] : any + >(this.url, { + headers: this.headers, + schema, fetch: this.fetch, }) } @@ -143,7 +168,7 @@ export default class PostgrestClient< method, url, headers, - schema: this.schema, + schema: this.schemaName, body, fetch: this.fetch, allowEmpty: false, diff --git a/test/basic.ts b/test/basic.ts index 9e7951fd..0c948828 100644 --- a/test/basic.ts +++ b/test/basic.ts @@ -196,6 +196,51 @@ test('switch schema', async () => { `) }) +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 () => { const res = await postgrest .from('users') @@ -865,6 +910,19 @@ test('rpc with head:true, count:exact', async () => { `) }) +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'", () => { test("insert with count: 'exact'", async () => { let res = await postgrest From d7b7eaf54f47006cf784fc3f2617de0a25f9aae6 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Tue, 22 Aug 2023 15:01:36 +0800 Subject: [PATCH 045/110] fix: use @supabase/node-fetch --- package-lock.json | 131 ++++++++++++++++++---------------------- package.json | 2 +- src/PostgrestBuilder.ts | 5 +- 3 files changed, 62 insertions(+), 76 deletions(-) diff --git a/package-lock.json b/package-lock.json index 08caf537..f4695833 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.0-automated", "license": "MIT", "dependencies": { - "cross-fetch": "^3.1.5" + "@supabase/node-fetch": "^2.6.13" }, "devDependencies": { "@types/jest": "^27.5.1", @@ -1030,6 +1030,17 @@ "@sinonjs/commons": "^1.7.0" } }, + "node_modules/@supabase/node-fetch": { + "version": "2.6.13", + "resolved": "https://registry.npmjs.org/@supabase/node-fetch/-/node-fetch-2.6.13.tgz", + "integrity": "sha512-rEHQaDVzxLZMCK3p+JW2nzEsK4AJpOQhetppaqAzrFum0Ub8wcnoM/8f1dWRZSulY5fRDP6rJaWT/8X3VleCzg==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + } + }, "node_modules/@tsd/typescript": { "version": "4.8.4", "resolved": "https://registry.npmjs.org/@tsd/typescript/-/typescript-4.8.4.tgz", @@ -1621,14 +1632,6 @@ "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==", - "dependencies": { - "node-fetch": "2.6.7" - } - }, "node_modules/cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -3989,33 +3992,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", @@ -5167,6 +5143,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", @@ -5661,6 +5642,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", @@ -6555,6 +6550,14 @@ "@sinonjs/commons": "^1.7.0" } }, + "@supabase/node-fetch": { + "version": "2.6.13", + "resolved": "https://registry.npmjs.org/@supabase/node-fetch/-/node-fetch-2.6.13.tgz", + "integrity": "sha512-rEHQaDVzxLZMCK3p+JW2nzEsK4AJpOQhetppaqAzrFum0Ub8wcnoM/8f1dWRZSulY5fRDP6rJaWT/8X3VleCzg==", + "requires": { + "whatwg-url": "^5.0.0" + } + }, "@tsd/typescript": { "version": "4.8.4", "resolved": "https://registry.npmjs.org/@tsd/typescript/-/typescript-4.8.4.tgz", @@ -7031,14 +7034,6 @@ "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==", - "requires": { - "node-fetch": "2.6.7" - } - }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -8799,35 +8794,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", @@ -9650,6 +9616,11 @@ "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", @@ -9991,6 +9962,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 933528a2..550bda67 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "db:run": "cd test/db && docker-compose up --detach && wait-for-localhost 3000" }, "dependencies": { - "cross-fetch": "^3.1.5" + "@supabase/node-fetch": "^2.6.13" }, "devDependencies": { "@types/jest": "^27.5.1", diff --git a/src/PostgrestBuilder.ts b/src/PostgrestBuilder.ts index e48d69f0..b068e83c 100644 --- a/src/PostgrestBuilder.ts +++ b/src/PostgrestBuilder.ts @@ -1,4 +1,5 @@ -import crossFetch from 'cross-fetch' +// @ts-ignore +import nodeFetch from '@supabase/node-fetch' import type { Fetch, PostgrestSingleResponse } from './types' @@ -28,7 +29,7 @@ export default abstract class PostgrestBuilder if (builder.fetch) { this.fetch = builder.fetch } else if (typeof fetch === 'undefined') { - this.fetch = crossFetch + this.fetch = nodeFetch } else { this.fetch = fetch } From be421d9c519ed157a8d9f65a7068ade0272e5b0c Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Wed, 23 Aug 2023 23:27:20 +0800 Subject: [PATCH 046/110] fix: revert using @supabase/node-fetch --- package-lock.json | 64 ++++++++++++++++++++++++++++------------- package.json | 2 +- src/PostgrestBuilder.ts | 5 ++-- 3 files changed, 47 insertions(+), 24 deletions(-) diff --git a/package-lock.json b/package-lock.json index f4695833..5d5b7fd2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.0-automated", "license": "MIT", "dependencies": { - "@supabase/node-fetch": "^2.6.13" + "cross-fetch": "^3.1.8" }, "devDependencies": { "@types/jest": "^27.5.1", @@ -1030,17 +1030,6 @@ "@sinonjs/commons": "^1.7.0" } }, - "node_modules/@supabase/node-fetch": { - "version": "2.6.13", - "resolved": "https://registry.npmjs.org/@supabase/node-fetch/-/node-fetch-2.6.13.tgz", - "integrity": "sha512-rEHQaDVzxLZMCK3p+JW2nzEsK4AJpOQhetppaqAzrFum0Ub8wcnoM/8f1dWRZSulY5fRDP6rJaWT/8X3VleCzg==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - } - }, "node_modules/@tsd/typescript": { "version": "4.8.4", "resolved": "https://registry.npmjs.org/@tsd/typescript/-/typescript-4.8.4.tgz", @@ -1632,6 +1621,14 @@ "safe-buffer": "~5.1.1" } }, + "node_modules/cross-fetch": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", + "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", + "dependencies": { + "node-fetch": "^2.6.12" + } + }, "node_modules/cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -3992,6 +3989,25 @@ "integrity": "sha512-/ujIVxthRs+7q6hsdjHMaj8hRG9NuWmwrz+JdRwZ14jdFoKSkm+vDsCbF9PLpnSqjaWQJuTmVtcWHNLr+vrOFw==", "dev": true }, + "node_modules/node-fetch": { + "version": "2.6.13", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.13.tgz", + "integrity": "sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -6550,14 +6566,6 @@ "@sinonjs/commons": "^1.7.0" } }, - "@supabase/node-fetch": { - "version": "2.6.13", - "resolved": "https://registry.npmjs.org/@supabase/node-fetch/-/node-fetch-2.6.13.tgz", - "integrity": "sha512-rEHQaDVzxLZMCK3p+JW2nzEsK4AJpOQhetppaqAzrFum0Ub8wcnoM/8f1dWRZSulY5fRDP6rJaWT/8X3VleCzg==", - "requires": { - "whatwg-url": "^5.0.0" - } - }, "@tsd/typescript": { "version": "4.8.4", "resolved": "https://registry.npmjs.org/@tsd/typescript/-/typescript-4.8.4.tgz", @@ -7034,6 +7042,14 @@ "safe-buffer": "~5.1.1" } }, + "cross-fetch": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", + "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", + "requires": { + "node-fetch": "^2.6.12" + } + }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -8794,6 +8810,14 @@ "integrity": "sha512-/ujIVxthRs+7q6hsdjHMaj8hRG9NuWmwrz+JdRwZ14jdFoKSkm+vDsCbF9PLpnSqjaWQJuTmVtcWHNLr+vrOFw==", "dev": true }, + "node-fetch": { + "version": "2.6.13", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.13.tgz", + "integrity": "sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA==", + "requires": { + "whatwg-url": "^5.0.0" + } + }, "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", diff --git a/package.json b/package.json index 550bda67..760af86c 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "db:run": "cd test/db && docker-compose up --detach && wait-for-localhost 3000" }, "dependencies": { - "@supabase/node-fetch": "^2.6.13" + "cross-fetch": "^3.1.8" }, "devDependencies": { "@types/jest": "^27.5.1", diff --git a/src/PostgrestBuilder.ts b/src/PostgrestBuilder.ts index b068e83c..e48d69f0 100644 --- a/src/PostgrestBuilder.ts +++ b/src/PostgrestBuilder.ts @@ -1,5 +1,4 @@ -// @ts-ignore -import nodeFetch from '@supabase/node-fetch' +import crossFetch from 'cross-fetch' import type { Fetch, PostgrestSingleResponse } from './types' @@ -29,7 +28,7 @@ export default abstract class PostgrestBuilder if (builder.fetch) { this.fetch = builder.fetch } else if (typeof fetch === 'undefined') { - this.fetch = nodeFetch + this.fetch = crossFetch } else { this.fetch = fetch } From fbeb24c25e085d63720b82e7b9c9e1d93f13c8d4 Mon Sep 17 00:00:00 2001 From: Joonas Date: Tue, 22 Aug 2023 13:01:25 +0300 Subject: [PATCH 047/110] enforce non-null parameter to .eq --- src/PostgrestFilterBuilder.ts | 7 +++++-- test/index.test-d.ts | 9 +++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/PostgrestFilterBuilder.ts b/src/PostgrestFilterBuilder.ts index 9f4c0807..e8da9a98 100644 --- a/src/PostgrestFilterBuilder.ts +++ b/src/PostgrestFilterBuilder.ts @@ -31,8 +31,11 @@ export default class PostgrestFilterBuilder< Result, Relationships = unknown > extends PostgrestTransformBuilder { - eq(column: ColumnName, value: Row[ColumnName]): this - eq(column: string, value: unknown): this + eq( + column: ColumnName, + value: NonNullable + ): this + eq(column: string, value: NonNullable): this /** * Match only rows where `column` is equal to `value`. * diff --git a/test/index.test-d.ts b/test/index.test-d.ts index d2407856..f88daec3 100644 --- a/test/index.test-d.ts +++ b/test/index.test-d.ts @@ -11,6 +11,15 @@ const postgrest = new PostgrestClient(REST_URL) expectError(postgrest.from(42)) } +// test filters +{ + 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 3811585141d66da58a78a93d9514db50341d8c6c Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Thu, 24 Aug 2023 15:13:20 +0800 Subject: [PATCH 048/110] fix: trigger release --- test/index.test-d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/index.test-d.ts b/test/index.test-d.ts index f88daec3..23ea6b72 100644 --- a/test/index.test-d.ts +++ b/test/index.test-d.ts @@ -11,7 +11,7 @@ const postgrest = new PostgrestClient(REST_URL) expectError(postgrest.from(42)) } -// test filters +// `null` can't be used with `.eq()` { postgrest.from('users').select().eq('username', 'foo') expectError(postgrest.from('users').select().eq('username', null)) From 7b0a69660e20ac11d7c3720604e338adb2e33d0a Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Tue, 22 Aug 2023 15:01:36 +0800 Subject: [PATCH 049/110] fix: use @supabase/node-fetch --- package-lock.json | 64 +++++++++++++---------------------------- package.json | 2 +- src/PostgrestBuilder.ts | 5 ++-- 3 files changed, 24 insertions(+), 47 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5d5b7fd2..1724fae3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.0-automated", "license": "MIT", "dependencies": { - "cross-fetch": "^3.1.8" + "@supabase/node-fetch": "^2.6.14" }, "devDependencies": { "@types/jest": "^27.5.1", @@ -1030,6 +1030,17 @@ "@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": "4.8.4", "resolved": "https://registry.npmjs.org/@tsd/typescript/-/typescript-4.8.4.tgz", @@ -1621,14 +1632,6 @@ "safe-buffer": "~5.1.1" } }, - "node_modules/cross-fetch": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", - "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", - "dependencies": { - "node-fetch": "^2.6.12" - } - }, "node_modules/cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -3989,25 +3992,6 @@ "integrity": "sha512-/ujIVxthRs+7q6hsdjHMaj8hRG9NuWmwrz+JdRwZ14jdFoKSkm+vDsCbF9PLpnSqjaWQJuTmVtcWHNLr+vrOFw==", "dev": true }, - "node_modules/node-fetch": { - "version": "2.6.13", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.13.tgz", - "integrity": "sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -6566,6 +6550,14 @@ "@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": "4.8.4", "resolved": "https://registry.npmjs.org/@tsd/typescript/-/typescript-4.8.4.tgz", @@ -7042,14 +7034,6 @@ "safe-buffer": "~5.1.1" } }, - "cross-fetch": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", - "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", - "requires": { - "node-fetch": "^2.6.12" - } - }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -8810,14 +8794,6 @@ "integrity": "sha512-/ujIVxthRs+7q6hsdjHMaj8hRG9NuWmwrz+JdRwZ14jdFoKSkm+vDsCbF9PLpnSqjaWQJuTmVtcWHNLr+vrOFw==", "dev": true }, - "node-fetch": { - "version": "2.6.13", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.13.tgz", - "integrity": "sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA==", - "requires": { - "whatwg-url": "^5.0.0" - } - }, "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", diff --git a/package.json b/package.json index 760af86c..8d000807 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "db:run": "cd test/db && docker-compose up --detach && wait-for-localhost 3000" }, "dependencies": { - "cross-fetch": "^3.1.8" + "@supabase/node-fetch": "^2.6.14" }, "devDependencies": { "@types/jest": "^27.5.1", diff --git a/src/PostgrestBuilder.ts b/src/PostgrestBuilder.ts index e48d69f0..b068e83c 100644 --- a/src/PostgrestBuilder.ts +++ b/src/PostgrestBuilder.ts @@ -1,4 +1,5 @@ -import crossFetch from 'cross-fetch' +// @ts-ignore +import nodeFetch from '@supabase/node-fetch' import type { Fetch, PostgrestSingleResponse } from './types' @@ -28,7 +29,7 @@ export default abstract class PostgrestBuilder if (builder.fetch) { this.fetch = builder.fetch } else if (typeof fetch === 'undefined') { - this.fetch = crossFetch + this.fetch = nodeFetch } else { this.fetch = fetch } From 18f580c83d4ceefbcd5360e3df229f3547d610a8 Mon Sep 17 00:00:00 2001 From: Steve Chavez Date: Tue, 10 Oct 2023 22:36:43 -0300 Subject: [PATCH 050/110] fix: detection of maybeSingle On PostgREST 11.2.0, the format of the error got changed on PostgREST/postgrest#2876 to "The result contains 0 rows". Change the detection to "0 rows". This should be backwards compatible. --- src/PostgrestBuilder.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PostgrestBuilder.ts b/src/PostgrestBuilder.ts index b068e83c..23e397f1 100644 --- a/src/PostgrestBuilder.ts +++ b/src/PostgrestBuilder.ts @@ -149,7 +149,7 @@ export default abstract class PostgrestBuilder } } - if (error && this.isMaybeSingle && error?.details?.includes('Results contain 0 rows')) { + if (error && this.isMaybeSingle && error?.details?.includes('0 rows')) { error = null status = 200 statusText = 'OK' From 7eabd65d40e4ccc1ea480cd0422bfb339fce2d58 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Thu, 2 Nov 2023 12:12:22 +0800 Subject: [PATCH 051/110] chore: `foreignTable` -> `referencedTable` --- src/PostgrestFilterBuilder.ts | 16 ++++++-- src/PostgrestTransformBuilder.ts | 70 +++++++++++++++++++++++++------- src/select-query-parser.ts | 10 ----- 3 files changed, 67 insertions(+), 29 deletions(-) diff --git a/src/PostgrestFilterBuilder.ts b/src/PostgrestFilterBuilder.ts index e8da9a98..cdc6d496 100644 --- a/src/PostgrestFilterBuilder.ts +++ b/src/PostgrestFilterBuilder.ts @@ -487,11 +487,19 @@ 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 } diff --git a/src/PostgrestTransformBuilder.ts b/src/PostgrestTransformBuilder.ts index 8cbf87a1..f8db193a 100644 --- a/src/PostgrestTransformBuilder.ts +++ b/src/PostgrestTransformBuilder.ts @@ -42,10 +42,24 @@ export default class PostgrestTransformBuilder< return this as unknown as PostgrestTransformBuilder } + 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 } @@ -55,16 +69,18 @@ export default class PostgrestTransformBuilder< * * 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: string, @@ -72,9 +88,15 @@ export default class PostgrestTransformBuilder< 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( @@ -91,11 +113,19 @@ 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 } @@ -110,12 +140,22 @@ export default class PostgrestTransformBuilder< * @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}`) diff --git a/src/select-query-parser.ts b/src/select-query-parser.ts index f7580e83..2b4ed31e 100644 --- a/src/select-query-parser.ts +++ b/src/select-query-parser.ts @@ -40,16 +40,6 @@ type Letter = Alphabet | Digit | '_' type Json = string | number | boolean | null | { [key: string]: Json } | Json[] -// /** -// * Parsed node types. -// * Currently only `*` and all other fields. -// */ -// type ParsedNode = -// | { star: true } -// | { name: string; original: string } -// | { name: string; foreignTable: true } -// | { name: string; type: T }; - /** * Parser errors. */ From 858e23ee84301d1aecab71fb8872992a449fdac0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Nov 2023 08:57:12 +0800 Subject: [PATCH 052/110] chore(deps-dev): bump @babel/traverse from 7.18.2 to 7.23.2 (#487) Bumps [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) from 7.18.2 to 7.23.2. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.23.2/packages/babel-traverse) --- updated-dependencies: - dependency-name: "@babel/traverse" dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Bobbie Soedirgo --- package-lock.json | 431 ++++++++++++++++++++++++++++++---------------- 1 file changed, 283 insertions(+), 148 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1724fae3..96f94b08 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,17 +40,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", @@ -100,13 +163,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": { @@ -114,12 +178,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" }, @@ -155,34 +219,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" @@ -241,21 +305,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" @@ -285,13 +358,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": { @@ -361,9 +434,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" @@ -535,33 +608,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" }, @@ -570,12 +643,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": { @@ -938,9 +1012,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" @@ -956,19 +1030,19 @@ } }, "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": { @@ -5780,12 +5854,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": { @@ -5826,23 +5953,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" } @@ -5870,28 +5998,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": { @@ -5935,18 +6063,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": { @@ -5967,13 +6101,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": { @@ -6030,9 +6164,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": { @@ -6153,41 +6287,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" } }, @@ -6473,9 +6608,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": { @@ -6485,19 +6620,19 @@ "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": { From 3816371b59aa1322c45222f8839dbfc6e46a7392 Mon Sep 17 00:00:00 2001 From: Laurence Isla Date: Fri, 17 Nov 2023 14:47:27 -0500 Subject: [PATCH 053/110] chore: update docker-compose to postgrest v11.2.2 --- test/db/docker-compose.yml | 2 +- test/transforms.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/db/docker-compose.yml b/test/db/docker-compose.yml index fd8da688..13e9d2d7 100644 --- a/test/db/docker-compose.yml +++ b/test/db/docker-compose.yml @@ -3,7 +3,7 @@ version: '3' services: rest: - image: postgrest/postgrest:v11.0.0 + image: postgrest/postgrest:v11.2.2 ports: - '3000:3000' environment: diff --git a/test/transforms.ts b/test/transforms.ts index cce8e227..a7ca4e76 100644 --- a/test/transforms.ts +++ b/test/transforms.ts @@ -200,7 +200,7 @@ test('maybeSingle', async () => { "data": null, "error": Object { "code": "PGRST116", - "details": "Results contain 2 rows, application/vnd.pgrst.object+json requires 1 row", + "details": "The result contains 2 rows", "hint": null, "message": "JSON object requested, multiple (or no) rows returned", }, From 5e7dbdcdc57bdd2f3a57c2aa65eff1c941ab1ec6 Mon Sep 17 00:00:00 2001 From: Laurence Isla Date: Fri, 17 Nov 2023 20:05:34 -0500 Subject: [PATCH 054/110] fix: `explain()` always returning an error It sends `for="application/json"` as media type by default, instead of `for="undefined"`. --- src/PostgrestTransformBuilder.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PostgrestTransformBuilder.ts b/src/PostgrestTransformBuilder.ts index f8db193a..d73ba9fc 100644 --- a/src/PostgrestTransformBuilder.ts +++ b/src/PostgrestTransformBuilder.ts @@ -267,7 +267,7 @@ 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};` From f0ec2e9134f256d5719debda7f57c6789aadb086 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Tue, 31 Oct 2023 19:30:15 +0800 Subject: [PATCH 055/110] chore: update generated types --- test/db/00-schema.sql | 5 +++++ test/index.test-d.ts | 5 ++++- test/types.ts | 47 ++++++++++++++++++++++++++++++++++++++----- 3 files changed, 51 insertions(+), 6 deletions(-) diff --git a/test/db/00-schema.sql b/test/db/00-schema.sql index 776b8c94..fa43dc8a 100644 --- a/test/db/00-schema.sql +++ b/test/db/00-schema.sql @@ -25,6 +25,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, diff --git a/test/index.test-d.ts b/test/index.test-d.ts index 23ea6b72..4d48b35a 100644 --- a/test/index.test-d.ts +++ b/test/index.test-d.ts @@ -62,7 +62,10 @@ const postgrest = new PostgrestClient(REST_URL) if (error) { throw new Error(error.message) } - expectType<{ bar: Json; baz: string }>(data) + // 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 diff --git a/test/types.ts b/test/types.ts index 74fd1e07..a398bba8 100644 --- a/test/types.ts +++ b/test/types.ts @@ -1,4 +1,4 @@ -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 { personal: { @@ -45,6 +45,29 @@ export interface Database { } public: { Tables: { + channel_details: { + Row: { + details: string | null + id: number + } + Insert: { + details?: string | null + id: number + } + Update: { + details?: string | null + id?: number + } + Relationships: [ + { + foreignKeyName: 'channel_details_id_fkey' + columns: ['id'] + isOneToOne: true + referencedRelation: 'channels' + referencedColumns: ['id'] + } + ] + } channels: { Row: { data: Json | null @@ -86,6 +109,12 @@ export interface Database { username?: string } Relationships: [ + { + foreignKeyName: 'messages_channel_id_fkey' + columns: ['channel_id'] + referencedRelation: 'channels' + referencedColumns: ['id'] + }, { foreignKeyName: 'messages_username_fkey' columns: ['username'] @@ -93,10 +122,16 @@ export interface Database { referencedColumns: ['username'] }, { - foreignKeyName: 'messages_channel_id_fkey' - columns: ['channel_id'] - referencedRelation: 'channels' - referencedColumns: ['id'] + foreignKeyName: 'messages_username_fkey' + columns: ['username'] + referencedRelation: 'non_updatable_view' + referencedColumns: ['username'] + }, + { + foreignKeyName: 'messages_username_fkey' + columns: ['username'] + referencedRelation: 'updatable_view' + referencedColumns: ['username'] } ] } @@ -148,6 +183,7 @@ export interface Database { Row: { username: string | null } + Relationships: [] } updatable_view: { Row: { @@ -162,6 +198,7 @@ export interface Database { non_updatable_column?: never username?: string | null } + Relationships: [] } } Functions: { From f91aa2944f52da3aefc77a6712990731fff16252 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Wed, 22 Nov 2023 16:44:02 +0800 Subject: [PATCH 056/110] feat: detect one-to-one relationships --- src/PostgrestClient.ts | 16 +++----- src/PostgrestFilterBuilder.ts | 3 +- src/PostgrestQueryBuilder.ts | 21 ++++++----- src/PostgrestTransformBuilder.ts | 32 +++++++++++++--- src/select-query-parser.ts | 65 ++++++++++++++++++++++++++++---- test/index.test-d.ts | 14 +++++++ 6 files changed, 118 insertions(+), 33 deletions(-) diff --git a/src/PostgrestClient.ts b/src/PostgrestClient.ts index e7d9678a..d6f99f90 100644 --- a/src/PostgrestClient.ts +++ b/src/PostgrestClient.ts @@ -59,19 +59,19 @@ export default class PostgrestClient< 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 + ): PostgrestQueryBuilder + from(relation: string): PostgrestQueryBuilder /** * Perform a query on a table or a view. * * @param relation - The table or view name to query */ - from(relation: string): PostgrestQueryBuilder { + from(relation: string): PostgrestQueryBuilder { const url = new URL(`${this.url}/${relation}`) - return new PostgrestQueryBuilder(url, { + return new PostgrestQueryBuilder(url, { headers: { ...this.headers }, schema: this.schemaName, fetch: this.fetch, @@ -92,11 +92,7 @@ export default class PostgrestClient< DynamicSchema, Database[DynamicSchema] extends GenericSchema ? Database[DynamicSchema] : any > { - return new PostgrestClient< - Database, - DynamicSchema, - Database[DynamicSchema] extends GenericSchema ? Database[DynamicSchema] : any - >(this.url, { + return new PostgrestClient(this.url, { headers: this.headers, schema, fetch: this.fetch, diff --git a/src/PostgrestFilterBuilder.ts b/src/PostgrestFilterBuilder.ts index cdc6d496..db06e631 100644 --- a/src/PostgrestFilterBuilder.ts +++ b/src/PostgrestFilterBuilder.ts @@ -29,8 +29,9 @@ export default class PostgrestFilterBuilder< Schema extends GenericSchema, Row extends Record, Result, + RelationName = unknown, Relationships = unknown -> extends PostgrestTransformBuilder { +> extends PostgrestTransformBuilder { eq( column: ColumnName, value: NonNullable diff --git a/src/PostgrestQueryBuilder.ts b/src/PostgrestQueryBuilder.ts index 26776e87..8f6db3f5 100644 --- a/src/PostgrestQueryBuilder.ts +++ b/src/PostgrestQueryBuilder.ts @@ -6,6 +6,7 @@ import { Fetch, GenericSchema, GenericTable, GenericView } from './types' export default class PostgrestQueryBuilder< Schema extends GenericSchema, Relation extends GenericTable | GenericView, + RelationName = unknown, Relationships = Relation extends { Relationships: infer R } ? R : unknown > { url: URL @@ -55,7 +56,7 @@ export default class PostgrestQueryBuilder< */ select< Query extends string = '*', - ResultOne = GetResult + ResultOne = GetResult >( columns?: Query, { @@ -65,7 +66,7 @@ export default class PostgrestQueryBuilder< head?: boolean count?: 'exact' | 'planned' | 'estimated' } = {} - ): PostgrestFilterBuilder { + ): PostgrestFilterBuilder { const method = head ? 'HEAD' : 'GET' // Remove whitespaces except when quoted let quoted = false @@ -102,14 +103,14 @@ export default class PostgrestQueryBuilder< options?: { count?: 'exact' | 'planned' | 'estimated' } - ): PostgrestFilterBuilder + ): PostgrestFilterBuilder insert( values: Row[], options?: { count?: 'exact' | 'planned' | 'estimated' defaultToNull?: boolean } - ): PostgrestFilterBuilder + ): PostgrestFilterBuilder /** * Perform an INSERT into the table or view. * @@ -145,7 +146,7 @@ export default class PostgrestQueryBuilder< count?: 'exact' | 'planned' | 'estimated' defaultToNull?: boolean } = {} - ): PostgrestFilterBuilder { + ): PostgrestFilterBuilder { const method = 'POST' const prefersHeaders = [] @@ -187,7 +188,7 @@ export default class PostgrestQueryBuilder< ignoreDuplicates?: boolean count?: 'exact' | 'planned' | 'estimated' } - ): PostgrestFilterBuilder + ): PostgrestFilterBuilder upsert( values: Row[], options?: { @@ -196,7 +197,7 @@ export default class PostgrestQueryBuilder< count?: 'exact' | 'planned' | 'estimated' defaultToNull?: boolean } - ): PostgrestFilterBuilder + ): 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 @@ -248,7 +249,7 @@ export default class PostgrestQueryBuilder< count?: 'exact' | 'planned' | 'estimated' defaultToNull?: boolean } = {} - ): PostgrestFilterBuilder { + ): PostgrestFilterBuilder { const method = 'POST' const prefersHeaders = [`resolution=${ignoreDuplicates ? 'ignore' : 'merge'}-duplicates`] @@ -312,7 +313,7 @@ export default class PostgrestQueryBuilder< }: { count?: 'exact' | 'planned' | 'estimated' } = {} - ): PostgrestFilterBuilder { + ): PostgrestFilterBuilder { const method = 'PATCH' const prefersHeaders = [] if (this.headers['Prefer']) { @@ -357,7 +358,7 @@ export default class PostgrestQueryBuilder< count, }: { count?: 'exact' | 'planned' | 'estimated' - } = {}): PostgrestFilterBuilder { + } = {}): PostgrestFilterBuilder { const method = 'DELETE' const prefersHeaders = [] if (count) { diff --git a/src/PostgrestTransformBuilder.ts b/src/PostgrestTransformBuilder.ts index d73ba9fc..1cb562bc 100644 --- a/src/PostgrestTransformBuilder.ts +++ b/src/PostgrestTransformBuilder.ts @@ -6,6 +6,7 @@ export default class PostgrestTransformBuilder< Schema extends GenericSchema, Row extends Record, Result, + RelationName = unknown, Relationships = unknown > extends PostgrestBuilder { /** @@ -17,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 ?? '*') @@ -39,7 +43,13 @@ 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( @@ -294,7 +304,19 @@ export default class PostgrestTransformBuilder< * * @typeParam NewResult - The new result type to override with */ - returns(): PostgrestTransformBuilder { - return this as unknown as PostgrestTransformBuilder + returns(): PostgrestTransformBuilder< + Schema, + Row, + NewResult, + RelationName, + Relationships + > { + return this as unknown as PostgrestTransformBuilder< + Schema, + Row, + NewResult, + RelationName, + Relationships + > } } diff --git a/src/select-query-parser.ts b/src/select-query-parser.ts index 2b4ed31e..39be31bb 100644 --- a/src/select-query-parser.ts +++ b/src/select-query-parser.ts @@ -66,6 +66,16 @@ type HasFKey = Relationships extends [infer R] : HasFKey : false +type HasUniqueFKey = Relationships extends [infer R] + ? R extends { foreignKeyName: FKeyName; isOneToOne: true } + ? true + : false + : Relationships extends [infer R, ...infer Rest] + ? HasUniqueFKey extends true + ? true + : HasUniqueFKey + : false + type HasFKeyToFRel = Relationships extends [infer R] ? R extends { referencedRelation: FRelName } ? true @@ -76,6 +86,16 @@ type HasFKeyToFRel = Relationships extends [infer R] : HasFKeyToFRel : false +type HasUniqueFKeyToFRel = Relationships extends [infer R] + ? R extends { referencedRelation: FRelName; isOneToOne: true } + ? true + : false + : Relationships extends [infer R, ...infer Rest] + ? HasUniqueFKeyToFRel extends true + ? true + : HasUniqueFKeyToFRel + : false + /** * Constructs a type definition for a single field of an object. * @@ -86,6 +106,7 @@ type HasFKeyToFRel = Relationships extends [infer R] type ConstructFieldDefinition< Schema extends GenericSchema, Row extends Record, + RelationName, Relationships, Field > = Field extends { star: true } @@ -95,13 +116,24 @@ type ConstructFieldDefinition< [_ in Field['name']]: GetResultHelper< Schema, (Schema['Tables'] & Schema['Views'])[Field['original']]['Row'], + Field['original'], (Schema['Tables'] & Schema['Views'])[Field['original']] extends { Relationships: infer R } ? R : unknown, Field['children'], unknown > extends infer Child - ? Relationships extends unknown[] + ? // One-to-one relationship - referencing column(s) has unique/pkey constraint. + HasUniqueFKey< + Field['hint'], + (Schema['Tables'] & Schema['Views'])[Field['original']] extends { + Relationships: infer R + } + ? R + : unknown + > extends true + ? Child | null + : Relationships extends unknown[] ? HasFKey extends true ? Child | null : Child[] @@ -113,13 +145,24 @@ type ConstructFieldDefinition< [_ in Field['name']]: GetResultHelper< Schema, (Schema['Tables'] & Schema['Views'])[Field['original']]['Row'], + Field['original'], (Schema['Tables'] & Schema['Views'])[Field['original']] extends { Relationships: infer R } ? R : unknown, Field['children'], unknown > extends infer Child - ? Relationships extends unknown[] + ? // One-to-one relationship - referencing column(s) has unique/pkey constraint. + HasUniqueFKeyToFRel< + RelationName, + (Schema['Tables'] & Schema['Views'])[Field['original']] extends { + Relationships: infer R + } + ? R + : unknown + > extends true + ? Child | null + : Relationships extends unknown[] ? HasFKeyToFRel extends true ? Child | null : Child[] @@ -404,28 +447,35 @@ type ParseQuery = string extends Query type GetResultHelper< Schema extends GenericSchema, Row extends Record, + RelationName, Relationships, Fields extends unknown[], Acc > = Fields extends [infer R] - ? ConstructFieldDefinition extends SelectQueryError + ? ConstructFieldDefinition extends SelectQueryError< + infer E + > ? SelectQueryError : GetResultHelper< Schema, Row, + RelationName, Relationships, [], - ConstructFieldDefinition & Acc + ConstructFieldDefinition & Acc > : Fields extends [infer R, ...infer Rest] - ? ConstructFieldDefinition extends SelectQueryError + ? ConstructFieldDefinition extends SelectQueryError< + infer E + > ? SelectQueryError : GetResultHelper< Schema, Row, + RelationName, Relationships, Rest, - ConstructFieldDefinition & Acc + ConstructFieldDefinition & Acc > : Prettify @@ -438,8 +488,9 @@ type GetResultHelper< export type GetResult< Schema extends GenericSchema, Row extends Record, + RelationName, Relationships, Query extends string > = ParseQuery extends unknown[] - ? GetResultHelper, unknown> + ? GetResultHelper, unknown> : ParseQuery diff --git a/test/index.test-d.ts b/test/index.test-d.ts index 4d48b35a..68c6350e 100644 --- a/test/index.test-d.ts +++ b/test/index.test-d.ts @@ -100,3 +100,17 @@ const postgrest = new PostgrestClient(REST_URL) const res = await postgrest.from('users').select('username, dat') expectType[]>>(res) } + +// one-to-one relationship +{ + const { data: channels, error } = await postgrest + .from('channels') + .select('channel_details(*)') + .single() + if (error) { + throw new Error(error.message) + } + expectType( + channels.channel_details + ) +} From 197b4d29930d18c47803156997a9cfed6266a5d2 Mon Sep 17 00:00:00 2001 From: Tyler Date: Tue, 2 Jan 2024 21:30:52 +0900 Subject: [PATCH 057/110] fix: add link on how to enable explain on the explain() method (#507) * add link on how to enable explain on the explain() method * Update src/PostgrestTransformBuilder.ts Co-authored-by: Tyler * keep docs link --------- Co-authored-by: Bobbie Soedirgo --- src/PostgrestTransformBuilder.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/PostgrestTransformBuilder.ts b/src/PostgrestTransformBuilder.ts index 1cb562bc..219ccd79 100644 --- a/src/PostgrestTransformBuilder.ts +++ b/src/PostgrestTransformBuilder.ts @@ -234,6 +234,10 @@ export default class PostgrestTransformBuilder< /** * 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 From f730aa793fbc8650de8bf914c816e943eba42844 Mon Sep 17 00:00:00 2001 From: Julian Meyer Date: Sun, 14 Jan 2024 21:16:38 -0800 Subject: [PATCH 058/110] fix: Ensure thrown errors have a stack trace (#502) * Ensure thrown errors have a stack trace * chore: stricter typing * chore: update snapshot --------- Co-authored-by: Bobbie Soedirgo --- src/PostgrestBuilder.ts | 3 ++- src/PostgrestError.ts | 15 +++++++++++++++ test/basic.ts | 20 ++++++++++++-------- 3 files changed, 29 insertions(+), 9 deletions(-) create mode 100644 src/PostgrestError.ts diff --git a/src/PostgrestBuilder.ts b/src/PostgrestBuilder.ts index 23e397f1..96a8bc55 100644 --- a/src/PostgrestBuilder.ts +++ b/src/PostgrestBuilder.ts @@ -2,6 +2,7 @@ import nodeFetch from '@supabase/node-fetch' import type { Fetch, PostgrestSingleResponse } from './types' +import PostgrestError from './PostgrestError' export default abstract class PostgrestBuilder implements PromiseLike> @@ -156,7 +157,7 @@ export default abstract class PostgrestBuilder } if (error && this.shouldThrowOnError) { - throw error + throw new PostgrestError(error) } } 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/test/basic.ts b/test/basic.ts index 0c948828..9a170019 100644 --- a/test/basic.ts +++ b/test/basic.ts @@ -631,20 +631,24 @@ test('throwOnError throws errors instead of returning them', async () => { try { await postgrest.from('missing_table').select().throwOnError() } catch (error) { - expect(error).toMatchInlineSnapshot(` - Object { - "code": "42P01", - "details": null, - "hint": null, - "message": "relation \\"public.missing_table\\" does not exist", - } - `) + 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 { + 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 }) From a79d78cec39608b2d03f9fcd7ff6cfccca7e0dc6 Mon Sep 17 00:00:00 2001 From: travis-humata <151555156+travis-humata@users.noreply.github.com> Date: Tue, 6 Feb 2024 19:05:40 -0600 Subject: [PATCH 059/110] feat: dedup values passed to PostgrestFilterBuilder.in (#517) --- src/PostgrestFilterBuilder.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PostgrestFilterBuilder.ts b/src/PostgrestFilterBuilder.ts index db06e631..21cc4090 100644 --- a/src/PostgrestFilterBuilder.ts +++ b/src/PostgrestFilterBuilder.ts @@ -239,7 +239,7 @@ export default class PostgrestFilterBuilder< * @param values - The values array to filter with */ in(column: string, values: readonly unknown[]): this { - const cleanedValues = values + const cleanedValues = Array.from(new Set(values)) .map((s) => { // handle postgrest reserved characters // https://postgrest.org/en/v7.0.0/api.html#reserved-characters From 4525dc46fe29607ccc9ce631fdf613298dba42b6 Mon Sep 17 00:00:00 2001 From: Ozan Date: Wed, 7 Feb 2024 17:06:41 +0100 Subject: [PATCH 060/110] feat: add support for type casting (id::text) (#429) This change adds support for type casting in select queries. For example an id column with the type bigint can be casted to text by "id::text". Equivalent PostgreSQL type for TypeScript type is based on the type generator pgTypeToTsType function https://github.com/supabase/postgres-meta//blob/80809c71d78d875524d7d9865c2458136207aa10/src/server/templates/typescript.ts#L421 --- src/select-query-parser.ts | 84 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 81 insertions(+), 3 deletions(-) diff --git a/src/select-query-parser.ts b/src/select-query-parser.ts index 39be31bb..07fa8ceb 100644 --- a/src/select-query-parser.ts +++ b/src/select-query-parser.ts @@ -40,6 +40,68 @@ type Letter = Alphabet | Digit | '_' type Json = string | number | boolean | null | { [key: string]: Json } | Json[] +type SingleValuePostgreSQLTypes = + | 'bool' + | 'int2' + | 'int4' + | 'int8' + | 'float4' + | 'float8' + | 'numeric' + | 'bytea' + | 'bpchar' + | 'varchar' + | 'date' + | 'text' + | 'citext' + | 'time' + | 'timetz' + | 'timestamp' + | 'timestamptz' + | 'uuid' + | 'vector' + | 'json' + | 'jsonb' + | 'void' + | 'record' + | string + +type ArrayPostgreSQLTypes = `_${SingleValuePostgreSQLTypes}` + +type PostgreSQLTypes = SingleValuePostgreSQLTypes | ArrayPostgreSQLTypes + +type TypeScriptSingleValueTypes = T extends 'bool' + ? boolean + : T extends 'int2' | 'int4' | 'int8' | 'float4' | 'float8' | 'numeric' + ? number + : T extends + | 'bytea' + | 'bpchar' + | 'varchar' + | 'date' + | 'text' + | 'citext' + | 'time' + | 'timetz' + | 'timestamp' + | 'timestamptz' + | 'uuid' + | 'vector' + ? string + : T extends 'json' | 'jsonb' + ? Json + : T extends 'void' + ? undefined + : T extends 'record' + ? Record + : unknown + +type StripUnderscore = T extends `_${infer U}` ? U : T + +type TypeScriptTypes = T extends ArrayPostgreSQLTypes + ? TypeScriptSingleValueTypes>>[] + : TypeScriptSingleValueTypes + /** * Parser errors. */ @@ -243,19 +305,21 @@ type ParseIdentifier = ReadLetters extends [ * A node is one of the following: * - `*` * - `field` + * - `field::type` * - `field->json...` * - `field(nodes)` * - `field!hint(nodes)` * - `field!inner(nodes)` * - `field!hint!inner(nodes)` * - `renamed_field:field` + * - `renamed_field:field::type` * - `renamed_field:field->json...` * - `renamed_field:field(nodes)` * - `renamed_field:field!hint(nodes)` * - `renamed_field:field!inner(nodes)` * - `renamed_field:field!hint!inner(nodes)` * - * TODO: casting operators `::text`, more support for JSON operators `->`, `->>`. + * TODO: more support for JSON operators `->`, `->>`. */ type ParseNode = Input extends '' ? ParserError<'Empty string'> @@ -263,7 +327,14 @@ type ParseNode = Input extends '' Input extends `*${infer Remainder}` ? [{ star: true }, EatWhitespace] : ParseIdentifier extends [infer Name, `${infer Remainder}`] - ? EatWhitespace extends `!inner${infer Remainder}` + ? EatWhitespace extends `::${infer Remainder}` + ? ParseIdentifier extends [infer CastType, `${infer Remainder}`] + ? // `field::type` + CastType extends PostgreSQLTypes + ? [{ name: Name; type: TypeScriptTypes }, EatWhitespace] + : never + : ParserError<`Unexpected type cast at \`${Input}\``> + : EatWhitespace extends `!inner${infer Remainder}` ? ParseEmbeddedResource> extends [infer Fields, `${infer Remainder}`] ? // `field!inner(nodes)` [{ name: Name; original: Name; children: Fields }, EatWhitespace] @@ -294,7 +365,14 @@ type ParseNode = Input extends '' : ParserError<'Expected identifier after `!`'> : EatWhitespace extends `:${infer Remainder}` ? ParseIdentifier> extends [infer OriginalName, `${infer Remainder}`] - ? EatWhitespace extends `!inner${infer Remainder}` + ? EatWhitespace extends `::${infer Remainder}` + ? ParseIdentifier extends [infer CastType, `${infer Remainder}`] + ? // `renamed_field:field::type` + CastType extends PostgreSQLTypes + ? [{ name: Name; type: TypeScriptTypes }, EatWhitespace] + : never + : ParserError<`Unexpected type cast at \`${Input}\``> + : EatWhitespace extends `!inner${infer Remainder}` ? ParseEmbeddedResource> extends [ infer Fields, `${infer Remainder}` From c9cebf8a0a5a3c8dff4a511d70fd53079781f563 Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Fri, 9 Feb 2024 01:43:13 +0800 Subject: [PATCH 061/110] refactor: query parser cleanup (#496) * Improve comments * Add parser error helper * Add `ParseField` helper This removes the duplication of parsing required for renamed fields and non-renamed fields. --- src/select-query-parser.ts | 193 ++++++++++++++++--------------------- 1 file changed, 81 insertions(+), 112 deletions(-) diff --git a/src/select-query-parser.ts b/src/select-query-parser.ts index 07fa8ceb..114d59d5 100644 --- a/src/select-query-parser.ts +++ b/src/select-query-parser.ts @@ -109,6 +109,13 @@ type ParserError = { error: true } & Message type GenericStringError = ParserError<'Received a generic string'> export type SelectQueryError = { error: true } & Message +/** + * Creates a new {@link ParserError} if the given input is not already a parser error. + */ +type CreateParserErrorIfRequired = Input extends ParserError + ? Input + : ParserError + /** * Trims whitespace from the left of the input. */ @@ -118,6 +125,9 @@ type EatWhitespace = string extends Input ? EatWhitespace : Input +/** + * Returns a boolean representing whether there is a foreign key with the given name. + */ type HasFKey = Relationships extends [infer R] ? R extends { foreignKeyName: FKeyName } ? true @@ -128,6 +138,9 @@ type HasFKey = Relationships extends [infer R] : HasFKey : false +/** + * Returns a boolean representing whether there the foreign key has a unique constraint. + */ type HasUniqueFKey = Relationships extends [infer R] ? R extends { foreignKeyName: FKeyName; isOneToOne: true } ? true @@ -138,6 +151,10 @@ type HasUniqueFKey = Relationships extends [infer R] : HasUniqueFKey : 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 @@ -161,8 +178,9 @@ type HasUniqueFKeyToFRel = Relationships extends [infer /** * 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 Schema Database schema. + * @param Row Type of a row in the given table. + * @param Relationships Relationships between different tables in the database. * @param Field Single field parsed by `ParseQuery`. */ type ConstructFieldDefinition< @@ -231,12 +249,12 @@ type ConstructFieldDefinition< : Child[] : never } + : Field extends { name: string; type: infer T } + ? { [K in Field['name']]: T } : Field extends { name: string; original: string } ? Field['original'] extends keyof Row ? { [K in Field['name']]: Row[Field['original']] } : SelectQueryError<`Referencing missing column \`${Field['original']}\``> - : Field extends { name: string; type: infer T } - ? { [K in Field['name']]: T } : Record /** @@ -246,8 +264,7 @@ type ConstructFieldDefinition< */ /** - * Reads a consecutive sequence of more than 1 letter, - * where letters are `[0-9a-zA-Z_]`. + * Reads a consecutive sequence of 1 or more letter, where letters are `[0-9a-zA-Z_]`. */ type ReadLetters = string extends Input ? GenericStringError @@ -266,7 +283,7 @@ type ReadLettersHelper = string extend : [Acc, ''] /** - * Reads a consecutive sequence of more than 1 double-quoted letters, + * Reads a consecutive sequence of 1 or more double-quoted letters, * where letters are `[^"]`. */ type ReadQuotedLetters = string extends Input @@ -289,7 +306,7 @@ type ReadQuotedLettersHelper = string /** * Parses a (possibly double-quoted) identifier. - * For now, identifiers are just sequences of more than 1 letter. + * Identifiers are sequences of 1 or more letters. */ type ParseIdentifier = ReadLetters extends [ infer Name, @@ -301,9 +318,8 @@ type ParseIdentifier = ReadLetters extends [ : ParserError<`No (possibly double-quoted) identifier at \`${Input}\``> /** - * Parses a node. - * A node is one of the following: - * - `*` + * Parses a field without preceding field renaming. + * A field is one of the following: * - `field` * - `field::type` * - `field->json...` @@ -311,36 +327,20 @@ type ParseIdentifier = ReadLetters extends [ * - `field!hint(nodes)` * - `field!inner(nodes)` * - `field!hint!inner(nodes)` - * - `renamed_field:field` - * - `renamed_field:field::type` - * - `renamed_field:field->json...` - * - `renamed_field:field(nodes)` - * - `renamed_field:field!hint(nodes)` - * - `renamed_field:field!inner(nodes)` - * - `renamed_field:field!hint!inner(nodes)` * - * TODO: more support for JSON operators `->`, `->>`. + * TODO: support type casting of JSON operators `a->b::type`, `a->>b::type`. */ -type ParseNode = Input extends '' +type ParseField = Input extends '' ? ParserError<'Empty string'> - : // `*` - Input extends `*${infer Remainder}` - ? [{ star: true }, EatWhitespace] : ParseIdentifier extends [infer Name, `${infer Remainder}`] - ? EatWhitespace extends `::${infer Remainder}` - ? ParseIdentifier extends [infer CastType, `${infer Remainder}`] - ? // `field::type` - CastType extends PostgreSQLTypes - ? [{ name: Name; type: TypeScriptTypes }, EatWhitespace] - : never - : ParserError<`Unexpected type cast at \`${Input}\``> - : EatWhitespace extends `!inner${infer Remainder}` + ? EatWhitespace extends `!inner${infer Remainder}` ? ParseEmbeddedResource> extends [infer Fields, `${infer Remainder}`] ? // `field!inner(nodes)` [{ name: Name; original: Name; children: Fields }, EatWhitespace] - : ParseEmbeddedResource> extends ParserError - ? ParseEmbeddedResource> - : ParserError<'Expected embedded resource after `!inner`'> + : CreateParserErrorIfRequired< + ParseEmbeddedResource>, + 'Expected embedded resource after `!inner`' + > : EatWhitespace extends `!${infer Remainder}` ? ParseIdentifier> extends [infer Hint, `${infer Remainder}`] ? EatWhitespace extends `!inner${infer Remainder}` @@ -350,89 +350,21 @@ type ParseNode = Input extends '' ] ? // `field!hint!inner(nodes)` [{ name: Name; original: Name; hint: Hint; children: Fields }, EatWhitespace] - : ParseEmbeddedResource> extends ParserError - ? ParseEmbeddedResource> - : ParserError<'Expected embedded resource after `!inner`'> + : CreateParserErrorIfRequired< + ParseEmbeddedResource>, + 'Expected embedded resource after `!inner`' + > : ParseEmbeddedResource> extends [ infer Fields, `${infer Remainder}` ] ? // `field!hint(nodes)` [{ name: Name; original: Name; hint: Hint; children: Fields }, EatWhitespace] - : ParseEmbeddedResource> extends ParserError - ? ParseEmbeddedResource> - : ParserError<'Expected embedded resource after `!hint`'> + : CreateParserErrorIfRequired< + ParseEmbeddedResource>, + 'Expected embedded resource after `!hint`' + > : ParserError<'Expected identifier after `!`'> - : EatWhitespace extends `:${infer Remainder}` - ? ParseIdentifier> extends [infer OriginalName, `${infer Remainder}`] - ? EatWhitespace extends `::${infer Remainder}` - ? ParseIdentifier extends [infer CastType, `${infer Remainder}`] - ? // `renamed_field:field::type` - CastType extends PostgreSQLTypes - ? [{ name: Name; type: TypeScriptTypes }, EatWhitespace] - : never - : ParserError<`Unexpected type cast at \`${Input}\``> - : EatWhitespace extends `!inner${infer Remainder}` - ? ParseEmbeddedResource> extends [ - infer Fields, - `${infer Remainder}` - ] - ? // `renamed_field:field!inner(nodes)` - [{ name: Name; original: OriginalName; children: Fields }, 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; original: OriginalName; hint: Hint; children: Fields }, - EatWhitespace - ] - : ParseEmbeddedResource> extends ParserError - ? ParseEmbeddedResource> - : ParserError<'Expected embedded resource after `!inner`'> - : ParseEmbeddedResource> extends [ - infer Fields, - `${infer Remainder}` - ] - ? // `renamed_field:field!hint(nodes)` - [ - { - name: Name - original: OriginalName - hint: Hint - children: Fields - }, - 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; original: OriginalName; children: Fields }, EatWhitespace] - : ParseJsonAccessor> extends [ - infer _PropertyName, - infer PropertyType, - `${infer Remainder}` - ] - ? // `renamed_field:field->json...` - [{ name: Name; type: PropertyType }, EatWhitespace] - : ParseEmbeddedResource> extends ParserError - ? ParseEmbeddedResource> - : // `renamed_field:field` - [{ name: Name; original: OriginalName }, EatWhitespace] - : ParseIdentifier> : ParseEmbeddedResource> extends [infer Fields, `${infer Remainder}`] ? // `field(nodes)` [{ name: Name; original: Name; children: Fields }, EatWhitespace] @@ -442,13 +374,48 @@ type ParseNode = Input extends '' `${infer Remainder}` ] ? // `field->json...` - [{ name: PropertyName; type: PropertyType }, EatWhitespace] + [{ name: PropertyName; original: PropertyName; type: PropertyType }, EatWhitespace] : ParseEmbeddedResource> extends ParserError ? ParseEmbeddedResource> + : EatWhitespace extends `::${infer Remainder}` + ? ParseIdentifier extends [`${infer CastType}`, `${infer Remainder}`] + ? // `field::type` + CastType extends PostgreSQLTypes + ? [{ name: Name; type: TypeScriptTypes }, EatWhitespace] + : ParserError<`Invalid type for \`::\` operator \`${CastType}\``> + : ParserError<`Invalid type for \`::\` operator at \`${Remainder}\``> : // `field` [{ name: Name; original: Name }, EatWhitespace] : ParserError<`Expected identifier at \`${Input}\``> +/** + * Parses a node. + * A node is one of the following: + * - `*` + * - a field, as defined above + * - a renamed field, `renamed_field:field` + */ +type ParseNode = Input extends '' + ? ParserError<'Empty string'> + : // `*` + Input extends `*${infer Remainder}` + ? [{ star: true }, EatWhitespace] + : ParseIdentifier extends [infer Name, `${infer Remainder}`] + ? EatWhitespace extends `::${infer _Remainder}` + ? // `field::` + // Special case to detect type-casting before renaming. + ParseField + : EatWhitespace extends `:${infer Remainder}` + ? // `renamed_field:` + ParseField> extends [infer Field, `${infer Remainder}`] + ? Field extends { name: string } + ? [Prettify & { name: Name }>, EatWhitespace] + : ParserError<`Unable to parse renamed field`> + : ParserError<`Unable to parse renamed field`> + : // Otherwise, just parse it as a field without renaming. + ParseField + : 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 ->. @@ -560,7 +527,9 @@ type GetResultHelper< /** * Constructs a type definition for an object based on a given PostgREST query. * - * @param Row Record. + * @param Schema Database schema. + * @param Row Type of a row in the given table. + * @param Relationships Relationships between different tables in the database. * @param Query Select query string literal to parse. */ export type GetResult< From e6a64c6d94b6f6cd0e9cda37c4dc11689d99e7da Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Thu, 8 Feb 2024 20:19:59 +0800 Subject: [PATCH 062/110] Add support for `...` spread operator --- src/select-query-parser.ts | 19 +++++++++++++++++++ test/index.test-d.ts | 26 ++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/src/select-query-parser.ts b/src/select-query-parser.ts index 114d59d5..e44e1e44 100644 --- a/src/select-query-parser.ts +++ b/src/select-query-parser.ts @@ -191,6 +191,17 @@ type ConstructFieldDefinition< Field > = Field extends { star: true } ? Row + : Field extends { spread: true; original: string; children: unknown[] } + ? GetResultHelper< + Schema, + (Schema['Tables'] & Schema['Views'])[Field['original']]['Row'], + Field['original'], + (Schema['Tables'] & Schema['Views'])[Field['original']] extends { Relationships: infer R } + ? R + : unknown, + Field['children'], + unknown + > : Field extends { name: string; original: string; hint: string; children: unknown[] } ? { [_ in Field['name']]: GetResultHelper< @@ -394,12 +405,20 @@ type ParseField = Input extends '' * - `*` * - 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}` ? [{ star: true }, EatWhitespace] + : // `...field` + Input extends `...${infer Remainder}` + ? ParseField> extends [infer Field, `${infer Remainder}`] + ? Field extends { children: unknown[] } + ? [Prettify<{ spread: true } & Field>, EatWhitespace] + : ParserError<'Unable to parse spread resource'> + : ParserError<'Unable to parse spread resource'> : ParseIdentifier extends [infer Name, `${infer Remainder}`] ? EatWhitespace extends `::${infer _Remainder}` ? // `field::` diff --git a/test/index.test-d.ts b/test/index.test-d.ts index 68c6350e..0129f5bd 100644 --- a/test/index.test-d.ts +++ b/test/index.test-d.ts @@ -1,6 +1,7 @@ import { expectError, expectType } from 'tsd' import { PostgrestClient, PostgrestSingleResponse } from '../src/index' import { SelectQueryError } from '../src/select-query-parser' +import { Prettify } from '../src/types' import { Database, Json } from './types' const REST_URL = 'http://localhost:3000' @@ -53,6 +54,31 @@ const postgrest = new PostgrestClient(REST_URL) 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 + ) +} + // json accessor in select query { const { data, error } = await postgrest From 14910bf7bbaf0b19459d4b961ff3bcce8f64a6c5 Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Thu, 8 Feb 2024 20:40:38 +0800 Subject: [PATCH 063/110] feat: query parser: handle empty embedded resources `()` Closes #445. --- src/select-query-parser.ts | 15 ++++++++++----- test/index.test-d.ts | 9 +++++++++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/select-query-parser.ts b/src/select-query-parser.ts index e44e1e44..2e798e29 100644 --- a/src/select-query-parser.ts +++ b/src/select-query-parser.ts @@ -202,6 +202,8 @@ type ConstructFieldDefinition< Field['children'], unknown > + : Field extends { children: [] } + ? {} : Field extends { name: string; original: string; hint: string; children: unknown[] } ? { [_ in Field['name']]: GetResultHelper< @@ -460,7 +462,7 @@ type ParseJsonAccessor = Input extends `->${infer Remainde /** * Parses an embedded resource, which is an opening `(`, followed by a sequence of - * nodes, separated by `,`, then a closing `)`. + * 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. @@ -468,11 +470,14 @@ type ParseJsonAccessor = Input extends `->${infer Remainde type ParseEmbeddedResource = Input extends `(${infer Remainder}` ? ParseNodes> extends [infer Fields, `${infer Remainder}`] ? EatWhitespace extends `)${infer Remainder}` - ? Fields extends [] - ? ParserError<'Expected fields after `(`'> - : [Fields, EatWhitespace] + ? [Fields, EatWhitespace] : ParserError<`Expected ")"`> - : ParseNodes> + : // If no nodes were detected, check for `)` for empty embedded resources `()`. + ParseNodes> extends ParserError + ? EatWhitespace extends `)${infer Remainder}` + ? [[], EatWhitespace] + : ParseNodes> + : ParserError<'Expected embedded resource fields or `)`'> : Input /** diff --git a/test/index.test-d.ts b/test/index.test-d.ts index 0129f5bd..3bd61e23 100644 --- a/test/index.test-d.ts +++ b/test/index.test-d.ts @@ -79,6 +79,15 @@ const postgrest = new PostgrestClient(REST_URL) ) } +// embedded resource with no fields +{ + const { data, error } = await postgrest.from('messages').select('message, users()').single() + if (error) { + throw new Error(error.message) + } + expectType<{ message: string | null }>(data) +} + // json accessor in select query { const { data, error } = await postgrest From 5ea51635a9cfc75368c085eabe86e7386f87db35 Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Mon, 4 Mar 2024 06:14:01 +0800 Subject: [PATCH 064/110] feat: query parser: add types for `count` (#498) Closes #447, #479. --- src/select-query-parser.ts | 2 ++ test/index.test-d.ts | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/src/select-query-parser.ts b/src/select-query-parser.ts index 2e798e29..155b3247 100644 --- a/src/select-query-parser.ts +++ b/src/select-query-parser.ts @@ -267,6 +267,8 @@ type ConstructFieldDefinition< : Field extends { name: string; original: string } ? Field['original'] extends keyof Row ? { [K in Field['name']]: Row[Field['original']] } + : Field['original'] extends 'count' + ? { count: number } : SelectQueryError<`Referencing missing column \`${Field['original']}\``> : Record diff --git a/test/index.test-d.ts b/test/index.test-d.ts index 3bd61e23..a3194bf3 100644 --- a/test/index.test-d.ts +++ b/test/index.test-d.ts @@ -88,6 +88,15 @@ const postgrest = new PostgrestClient(REST_URL) expectType<{ message: string | null }>(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 } | null }>(data) +} + // json accessor in select query { const { data, error } = await postgrest From e5257516abb6e51b7a476e46bfb651ff3e657ed7 Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Tue, 5 Mar 2024 22:28:43 +0800 Subject: [PATCH 065/110] Parser: Split parsing of non-embedded fields out of `ParseField` --- src/select-query-parser.ts | 47 +++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/src/select-query-parser.ts b/src/select-query-parser.ts index 155b3247..834e030e 100644 --- a/src/select-query-parser.ts +++ b/src/select-query-parser.ts @@ -1,4 +1,5 @@ // 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 { GenericSchema, Prettify } from './types' @@ -335,15 +336,12 @@ type ParseIdentifier = ReadLetters extends [ /** * Parses a field without preceding field renaming. * A field is one of the following: - * - `field` - * - `field::type` - * - `field->json...` - * - `field(nodes)` - * - `field!hint(nodes)` - * - `field!inner(nodes)` - * - `field!hint!inner(nodes)` - * - * TODO: support type casting of JSON operators `a->b::type`, `a->>b::type`. + * - a field with an embedded resource + * - `field(nodes)` + * - `field!hint(nodes)` + * - `field!inner(nodes)` + * - `field!hint!inner(nodes)` + * - a field without an embedded resource (see {@link ParseFieldWithoutEmbeddedResource}) */ type ParseField = Input extends '' ? ParserError<'Empty string'> @@ -383,15 +381,32 @@ type ParseField = Input extends '' : ParseEmbeddedResource> extends [infer Fields, `${infer Remainder}`] ? // `field(nodes)` [{ name: Name; original: Name; children: Fields }, EatWhitespace] - : ParseJsonAccessor> extends [ - infer PropertyName, - infer PropertyType, - `${infer Remainder}` - ] + : ParseEmbeddedResource> extends ParserError + ? // Return error if start of embedded resource was detected but not found. + ParseEmbeddedResource> + : // Otherwise try to match a field without embedded resource. + ParseFieldWithoutEmbeddedResource + : ParserError<`Expected identifier at \`${Input}\``> + +/** + * Parses a field excluding embedded resources, without preceding field renaming. + * This is one of the following: + * - `field` + * - `field::type` + * - `field->json...` + * + * TODO: support type casting of JSON operators `a->b::type`, `a->>b::type`. + */ +type ParseFieldWithoutEmbeddedResource = Input extends '' + ? ParserError<'Empty string'> + : ParseIdentifier extends [infer Name, `${infer Remainder}`] + ? ParseJsonAccessor> extends [ + infer PropertyName, + infer PropertyType, + `${infer Remainder}` + ] ? // `field->json...` [{ name: PropertyName; original: PropertyName; type: PropertyType }, EatWhitespace] - : ParseEmbeddedResource> extends ParserError - ? ParseEmbeddedResource> : EatWhitespace extends `::${infer Remainder}` ? ParseIdentifier extends [`${infer CastType}`, `${infer Remainder}`] ? // `field::type` From f30fcc2618f80c364c739d29d7f4117aab92d4b5 Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Tue, 5 Mar 2024 22:28:43 +0800 Subject: [PATCH 066/110] Parser: Split parsing of type casts into separate helper --- src/select-query-parser.ts | 61 +++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 18 deletions(-) diff --git a/src/select-query-parser.ts b/src/select-query-parser.ts index 834e030e..44c23e6a 100644 --- a/src/select-query-parser.ts +++ b/src/select-query-parser.ts @@ -394,30 +394,55 @@ type ParseField = Input extends '' * - `field` * - `field::type` * - `field->json...` - * - * TODO: support type casting of JSON operators `a->b::type`, `a->>b::type`. + * - `field->json...::type` */ type ParseFieldWithoutEmbeddedResource = Input extends '' ? ParserError<'Empty string'> - : ParseIdentifier extends [infer Name, `${infer Remainder}`] - ? ParseJsonAccessor> extends [ - infer PropertyName, - infer PropertyType, - `${infer Remainder}` - ] - ? // `field->json...` - [{ name: PropertyName; original: PropertyName; type: PropertyType }, EatWhitespace] - : EatWhitespace extends `::${infer Remainder}` - ? ParseIdentifier extends [`${infer CastType}`, `${infer Remainder}`] - ? // `field::type` - CastType extends PostgreSQLTypes - ? [{ name: Name; type: TypeScriptTypes }, EatWhitespace] - : ParserError<`Invalid type for \`::\` operator \`${CastType}\``> - : ParserError<`Invalid type for \`::\` operator at \`${Remainder}\``> + : ParseFieldWithoutEmbeddedResourceAndTypeCast extends [infer Field, `${infer Remainder}`] + ? ParseFieldTypeCast> extends [infer Type, `${infer Remainder}`] + ? // `field::type` + [Field & { type: Type }, EatWhitespace] + : ParseFieldTypeCast> extends ParserError + ? ParseFieldTypeCast> : // `field` - [{ name: Name; original: Name }, EatWhitespace] + [Field, EatWhitespace] : ParserError<`Expected identifier at \`${Input}\``> +/** + * Parses a field excluding embedded resources or typecasting, without preceding field renaming. + * This is one of the following: + * - `field` + * - `field->json...` + */ +type ParseFieldWithoutEmbeddedResourceAndTypeCast = + ParseIdentifier extends [infer Name, `${infer Remainder}`] + ? ParseJsonAccessor> extends [ + infer PropertyName, + infer PropertyType, + `${infer Remainder}` + ] + ? // `field->json...` + [ + { name: PropertyName; original: PropertyName; type: PropertyType }, + EatWhitespace + ] + : // `field` + [{ name: Name; original: Name }, EatWhitespace] + : ParserError<`Expected field at \`${Input}\``> + +/** + * Parses a field typecast (`::type`), returning a tuple of ["Type", "Remainder of text"] + * or the original string input indicating that no typecast was found. + */ +type ParseFieldTypeCast = EatWhitespace extends `::${infer Remainder}` + ? ParseIdentifier> extends [`${infer CastType}`, `${infer Remainder}`] + ? // Ensure that `CastType` is a valid type. + CastType extends PostgreSQLTypes + ? [TypeScriptTypes, EatWhitespace] + : ParserError<`Invalid type for \`::\` operator \`${CastType}\``> + : ParserError<`Invalid type for \`::\` operator at \`${Remainder}\``> + : Input + /** * Parses a node. * A node is one of the following: From 6f5d5709d5da48eda9dc682aab8261eee13dbfca Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Tue, 5 Mar 2024 22:28:43 +0800 Subject: [PATCH 067/110] Parser: Add support for aggregate functions --- src/select-query-parser.ts | 96 +++++++++++++++++++++++++++++++++----- test/index.test-d.ts | 19 ++++++++ 2 files changed, 104 insertions(+), 11 deletions(-) diff --git a/src/select-query-parser.ts b/src/select-query-parser.ts index 44c23e6a..5c682117 100644 --- a/src/select-query-parser.ts +++ b/src/select-query-parser.ts @@ -97,6 +97,8 @@ type TypeScriptSingleValueTypes = T extend ? Record : unknown +type AggregateFunctions = 'count' | 'sum' | 'avg' | 'min' | 'max' + type StripUnderscore = T extends `_${infer U}` ? U : T type TypeScriptTypes = T extends ArrayPostgreSQLTypes @@ -392,21 +394,74 @@ type ParseField = Input extends '' * 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 ParseFieldWithoutEmbeddedResource = + ParseFieldWithoutEmbeddedResourceAndAggregation extends [infer Field, `${infer Remainder}`] + ? ParseFieldAggregation> extends [ + `${infer AggregateFunction}`, + `${infer Remainder}` + ] + ? ParseFieldTypeCast> extends [infer Type, `${infer Remainder}`] + ? // `field.aggregate()::type` + [ + Omit & { + name: AggregateFunction + original: AggregateFunction + type: Type + }, + EatWhitespace + ] + : ParseFieldTypeCast> extends ParserError + ? ParseFieldTypeCast> + : // `field.aggregate()` + [ + Omit & { + name: AggregateFunction + original: AggregateFunction + }, + EatWhitespace + ] + : ParseFieldAggregation> extends ParserError + ? ParseFieldAggregation> + : // `field` + [Field, EatWhitespace] + : CreateParserErrorIfRequired< + ParseFieldWithoutEmbeddedResourceAndAggregation, + `Expected field at \`${Input}\`` + > + +/** + * Parses a field excluding embedded resources or aggregation, without preceding field renaming. + * This is one of the following: + * - `field` * - `field::type` * - `field->json...` * - `field->json...::type` */ -type ParseFieldWithoutEmbeddedResource = Input extends '' - ? ParserError<'Empty string'> - : ParseFieldWithoutEmbeddedResourceAndTypeCast extends [infer Field, `${infer Remainder}`] - ? ParseFieldTypeCast> extends [infer Type, `${infer Remainder}`] - ? // `field::type` - [Field & { type: Type }, EatWhitespace] - : ParseFieldTypeCast> extends ParserError - ? ParseFieldTypeCast> - : // `field` - [Field, EatWhitespace] - : ParserError<`Expected identifier at \`${Input}\``> +type ParseFieldWithoutEmbeddedResourceAndAggregation = + ParseFieldWithoutEmbeddedResourceAndTypeCast extends [infer Field, `${infer Remainder}`] + ? ParseFieldTypeCast> extends [infer Type, `${infer Remainder}`] + ? // `field::type` or `field->json...::type` + [Omit & { type: Type }, EatWhitespace] + : ParseFieldTypeCast> extends ParserError + ? ParseFieldTypeCast> + : // `field` or `field->json...` + [Field, EatWhitespace] + : CreateParserErrorIfRequired< + ParseFieldWithoutEmbeddedResourceAndTypeCast, + `Expected field at \`${Input}\`` + > /** * Parses a field excluding embedded resources or typecasting, without preceding field renaming. @@ -443,6 +498,25 @@ type ParseFieldTypeCast = EatWhitespace extends `:: : ParserError<`Invalid type for \`::\` operator at \`${Remainder}\``> : Input +/** + * Parses a field aggregation (`.max()`), returning a tuple of ["Aggregate function", "Remainder of text"] + * or the original string input indicating that no aggregation was found. + */ +type ParseFieldAggregation = + EatWhitespace extends `.${infer Remainder}` + ? ParseIdentifier> extends [ + `${infer FunctionName}`, + `${infer Remainder}` + ] + ? // Ensure that aggregation function is valid. + FunctionName extends AggregateFunctions + ? EatWhitespace extends `()${infer Remainder}` + ? [FunctionName, EatWhitespace] + : ParserError<`Expected \`()\` after \`.\` operator \`${FunctionName}\``> + : ParserError<`Invalid type for \`.\` operator \`${FunctionName}\``> + : ParserError<`Invalid type for \`.\` operator at \`${Remainder}\``> + : Input + /** * Parses a node. * A node is one of the following: diff --git a/test/index.test-d.ts b/test/index.test-d.ts index a3194bf3..b9c24c16 100644 --- a/test/index.test-d.ts +++ b/test/index.test-d.ts @@ -112,6 +112,25 @@ const postgrest = new PostgrestClient(REST_URL) expectType(data.baz) } +// typecasting and aggregate functions +{ + const { data, error } = await postgrest + .from('messages') + .select( + 'message, users.count(), casted_message:message::int4, casted_count:users.count()::text' + ) + .single() + if (error) { + throw new Error(error.message) + } + expectType<{ + message: string | null + count: number + casted_message: number + casted_count: string + }>(data) +} + // rpc return type { const { data, error } = await postgrest.rpc('get_status') From e26266ada6b8f636bfadb074ec6fb723c6f2eac2 Mon Sep 17 00:00:00 2001 From: Joonas Date: Wed, 13 Mar 2024 04:02:45 +0200 Subject: [PATCH 068/110] non-nullable relationship if inner join (#458) --- src/select-query-parser.ts | 15 +++++++++++---- test/index.test-d.ts | 12 ++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/select-query-parser.ts b/src/select-query-parser.ts index 5c682117..9567b1c9 100644 --- a/src/select-query-parser.ts +++ b/src/select-query-parser.ts @@ -231,7 +231,9 @@ type ConstructFieldDefinition< ? Child | null : Relationships extends unknown[] ? HasFKey extends true - ? Child | null + ? Field extends { inner: true } + ? Child + : Child | null : Child[] : Child[] : never @@ -260,7 +262,9 @@ type ConstructFieldDefinition< ? Child | null : Relationships extends unknown[] ? HasFKeyToFRel extends true - ? Child | null + ? Field extends { inner: true } + ? Child + : Child | null : Child[] : Child[] : never @@ -351,7 +355,7 @@ type ParseField = Input extends '' ? EatWhitespace extends `!inner${infer Remainder}` ? ParseEmbeddedResource> extends [infer Fields, `${infer Remainder}`] ? // `field!inner(nodes)` - [{ name: Name; original: Name; children: Fields }, EatWhitespace] + [{ name: Name; original: Name; children: Fields; inner: true }, EatWhitespace] : CreateParserErrorIfRequired< ParseEmbeddedResource>, 'Expected embedded resource after `!inner`' @@ -364,7 +368,10 @@ type ParseField = Input extends '' `${infer Remainder}` ] ? // `field!hint!inner(nodes)` - [{ name: Name; original: Name; hint: Hint; children: Fields }, EatWhitespace] + [ + { name: Name; original: Name; hint: Hint; children: Fields; inner: true }, + EatWhitespace + ] : CreateParserErrorIfRequired< ParseEmbeddedResource>, 'Expected embedded resource after `!inner`' diff --git a/test/index.test-d.ts b/test/index.test-d.ts index b9c24c16..54ee54f3 100644 --- a/test/index.test-d.ts +++ b/test/index.test-d.ts @@ -149,6 +149,18 @@ const postgrest = new PostgrestClient(REST_URL) expectType(message.user) } +// !inner relationship +{ + const { data: message, error } = await postgrest + .from('messages') + .select('user:users!inner(*)') + .single() + if (error) { + throw new Error(error.message) + } + expectType(message.user) +} + // one-to-many relationship { const { data: user, error } = await postgrest.from('users').select('messages(*)').single() From 9dd41d9c17a5d1b82144451d3eaf5729f2921758 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Thu, 28 Mar 2024 18:15:12 +0800 Subject: [PATCH 069/110] feat: typecheck table names in `.from()` (#528) --- src/PostgrestClient.ts | 1 - test/basic.ts | 2 ++ test/index.test-d.ts | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/PostgrestClient.ts b/src/PostgrestClient.ts index d6f99f90..c30981d0 100644 --- a/src/PostgrestClient.ts +++ b/src/PostgrestClient.ts @@ -63,7 +63,6 @@ export default class PostgrestClient< from( relation: ViewName ): PostgrestQueryBuilder - from(relation: string): PostgrestQueryBuilder /** * Perform a query on a table or a view. * diff --git a/test/basic.ts b/test/basic.ts index 9a170019..3191f969 100644 --- a/test/basic.ts +++ b/test/basic.ts @@ -629,6 +629,7 @@ 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).toMatchInlineSnapshot( @@ -642,6 +643,7 @@ test('throwOnError throws errors instead of returning them', async () => { 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) diff --git a/test/index.test-d.ts b/test/index.test-d.ts index 54ee54f3..066892d2 100644 --- a/test/index.test-d.ts +++ b/test/index.test-d.ts @@ -10,6 +10,7 @@ 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()` From 7c3dd21fb962c35e88b88cc7a789fcfcb692af42 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Thu, 28 Mar 2024 12:20:40 +0700 Subject: [PATCH 070/110] feat: `.rpc()` with GET --- src/PostgrestClient.ts | 11 ++++++++++- test/basic.ts | 17 +++++++++++++++++ test/transforms.ts | 12 +++++++++--- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/PostgrestClient.ts b/src/PostgrestClient.ts index c30981d0..f4955062 100644 --- a/src/PostgrestClient.ts +++ b/src/PostgrestClient.ts @@ -106,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). @@ -127,9 +129,11 @@ export default class PostgrestClient< args: Function_['Args'] = {}, { head = false, + get = false, count, }: { head?: boolean + get?: boolean count?: 'exact' | 'planned' | 'estimated' } = {} ): PostgrestFilterBuilder< @@ -141,7 +145,7 @@ export default class PostgrestClient< : never, Function_['Returns'] > { - let method: 'HEAD' | 'POST' + let method: 'HEAD' | 'GET' | 'POST' const url = new URL(`${this.url}/rpc/${fn}`) let body: unknown | undefined if (head) { @@ -149,6 +153,11 @@ export default class PostgrestClient< Object.entries(args).forEach(([name, value]) => { url.searchParams.append(name, `${value}`) }) + } else if (get) { + method = 'GET' + Object.entries(args).forEach(([name, value]) => { + url.searchParams.append(name, `${value}`) + }) } else { method = 'POST' body = args diff --git a/test/basic.ts b/test/basic.ts index 3191f969..c1ddc690 100644 --- a/test/basic.ts +++ b/test/basic.ts @@ -916,6 +916,23 @@ test('rpc with head:true, count:exact', async () => { `) }) +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 dynamic schema', async () => { const res = await postgrest.schema('personal').rpc('get_status', { name_param: 'kiwicopple' }) expect(res).toMatchInlineSnapshot(` diff --git a/test/transforms.ts b/test/transforms.ts index a7ca4e76..b0d0bce5 100644 --- a/test/transforms.ts +++ b/test/transforms.ts @@ -270,16 +270,22 @@ test('abort signal', async () => { ac.abort() const res = await postgrest.from('users').select().abortSignal(ac.signal) expect(res).toMatchInlineSnapshot( - { error: { details: expect.any(String) } }, + { + error: { + code: expect.any(String), + details: expect.any(String), + message: expect.stringMatching(/^AbortError:/), + }, + }, ` Object { "count": null, "data": null, "error": Object { - "code": "", + "code": Any, "details": Any, "hint": "", - "message": "AbortError: The user aborted a request.", + "message": StringMatching /\\^AbortError:/, }, "status": 0, "statusText": "", From 2895b7762f40c5b9b81aa42fae878bd72dfce247 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Thu, 11 Apr 2024 15:38:58 +0700 Subject: [PATCH 071/110] fix: ignore undefined args when using rpc with head/get --- src/PostgrestClient.ts | 16 +++++--- test/basic.ts | 17 ++++++++ test/db/00-schema.sql | 5 +++ test/types.ts | 92 ++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 120 insertions(+), 10 deletions(-) diff --git a/src/PostgrestClient.ts b/src/PostgrestClient.ts index f4955062..8939f3fc 100644 --- a/src/PostgrestClient.ts +++ b/src/PostgrestClient.ts @@ -150,14 +150,18 @@ export default class PostgrestClient< let body: unknown | undefined if (head) { method = 'HEAD' - Object.entries(args).forEach(([name, value]) => { - url.searchParams.append(name, `${value}`) - }) + Object.entries(args) + .filter(([_, value]) => value !== undefined) + .forEach(([name, value]) => { + url.searchParams.append(name, `${value}`) + }) } else if (get) { method = 'GET' - Object.entries(args).forEach(([name, value]) => { - url.searchParams.append(name, `${value}`) - }) + Object.entries(args) + .filter(([_, value]) => value !== undefined) + .forEach(([name, value]) => { + url.searchParams.append(name, `${value}`) + }) } else { method = 'POST' body = args diff --git a/test/basic.ts b/test/basic.ts index c1ddc690..8ad589d5 100644 --- a/test/basic.ts +++ b/test/basic.ts @@ -933,6 +933,23 @@ test('rpc with get:true, count:exact', async () => { `) }) +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 dynamic schema', async () => { const res = await postgrest.schema('personal').rpc('get_status', { name_param: 'kiwicopple' }) expect(res).toMatchInlineSnapshot(` diff --git a/test/db/00-schema.sql b/test/db/00-schema.sql index fa43dc8a..f2d9db01 100644 --- a/test/db/00-schema.sql +++ b/test/db/00-schema.sql @@ -91,3 +91,8 @@ 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; diff --git a/test/types.ts b/test/types.ts index a398bba8..ded93530 100644 --- a/test/types.ts +++ b/test/types.ts @@ -1,6 +1,6 @@ export type Json = string | number | boolean | null | { [key: string]: Json | undefined } | Json[] -export interface Database { +export type Database = { personal: { Tables: { users: { @@ -112,25 +112,29 @@ export interface Database { { foreignKeyName: 'messages_channel_id_fkey' columns: ['channel_id'] + isOneToOne: false referencedRelation: 'channels' referencedColumns: ['id'] }, { foreignKeyName: 'messages_username_fkey' columns: ['username'] - referencedRelation: 'users' + isOneToOne: false + referencedRelation: 'non_updatable_view' referencedColumns: ['username'] }, { foreignKeyName: 'messages_username_fkey' columns: ['username'] - referencedRelation: 'non_updatable_view' + isOneToOne: false + referencedRelation: 'updatable_view' referencedColumns: ['username'] }, { foreignKeyName: 'messages_username_fkey' columns: ['username'] - referencedRelation: 'updatable_view' + isOneToOne: false + referencedRelation: 'users' referencedColumns: ['username'] } ] @@ -202,6 +206,12 @@ export interface Database { } } Functions: { + function_with_optional_param: { + Args: { + param?: string + } + Returns: string + } get_status: { Args: { name_param: string @@ -236,3 +246,77 @@ export interface Database { } } } + +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 From ec0762c1db39f2f7793dfd6d0fb4311266056f72 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Thu, 11 Apr 2024 15:42:15 +0700 Subject: [PATCH 072/110] chore: Function -> Fn, like supabase-js --- src/PostgrestClient.ts | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/PostgrestClient.ts b/src/PostgrestClient.ts index 8939f3fc..793e0788 100644 --- a/src/PostgrestClient.ts +++ b/src/PostgrestClient.ts @@ -121,12 +121,9 @@ 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, @@ -138,12 +135,12 @@ export default class PostgrestClient< } = {} ): PostgrestFilterBuilder< Schema, - Function_['Returns'] extends any[] - ? Function_['Returns'][number] extends Record - ? Function_['Returns'][number] + Fn['Returns'] extends any[] + ? Fn['Returns'][number] extends Record + ? Fn['Returns'][number] : never : never, - Function_['Returns'] + Fn['Returns'] > { let method: 'HEAD' | 'GET' | 'POST' const url = new URL(`${this.url}/rpc/${fn}`) @@ -180,6 +177,6 @@ export default class PostgrestClient< body, fetch: this.fetch, allowEmpty: false, - } as unknown as PostgrestBuilder) + } as unknown as PostgrestBuilder) } } From 03a811da4e16ff76baa2eb96891770c5b8ee5ac9 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Fri, 12 Apr 2024 03:45:35 +0700 Subject: [PATCH 073/110] fix: rpc w/ HEAD/GET w/ array param --- src/PostgrestClient.ts | 17 +++++++---------- test/basic.ts | 17 +++++++++++++++++ test/db/00-schema.sql | 3 +++ test/types.ts | 6 ++++++ 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/PostgrestClient.ts b/src/PostgrestClient.ts index 793e0788..915ddc16 100644 --- a/src/PostgrestClient.ts +++ b/src/PostgrestClient.ts @@ -145,19 +145,16 @@ export default class PostgrestClient< let method: 'HEAD' | 'GET' | 'POST' const url = new URL(`${this.url}/rpc/${fn}`) let body: unknown | undefined - if (head) { - method = 'HEAD' + 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 if (get) { - method = 'GET' - Object.entries(args) - .filter(([_, value]) => value !== undefined) - .forEach(([name, value]) => { - url.searchParams.append(name, `${value}`) + url.searchParams.append(name, value) }) } else { method = 'POST' diff --git a/test/basic.ts b/test/basic.ts index 8ad589d5..ba57ac23 100644 --- a/test/basic.ts +++ b/test/basic.ts @@ -950,6 +950,23 @@ test('rpc with get:true, optional param', async () => { `) }) +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(` diff --git a/test/db/00-schema.sql b/test/db/00-schema.sql index f2d9db01..902862b6 100644 --- a/test/db/00-schema.sql +++ b/test/db/00-schema.sql @@ -96,3 +96,6 @@ 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/types.ts b/test/types.ts index ded93530..629d3c3e 100644 --- a/test/types.ts +++ b/test/types.ts @@ -206,6 +206,12 @@ export type Database = { } } Functions: { + function_with_array_param: { + Args: { + param: string[] + } + Returns: undefined + } function_with_optional_param: { Args: { param?: string From 2c4e846c8f697f760e15e06a60014e8b93bf3b34 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Tue, 21 May 2024 22:36:08 +0800 Subject: [PATCH 074/110] fix: use proper dual-packaging Support CommonJS & ESM. Previously the ESM build (dist/module) is broken - it's recognized as CommonJS. For more on dual-packaging: https://nodejs.org/api/packages.html#dual-commonjses-module-packages --- package-lock.json | 420 +++++++++++++++++++++++++++++++++++++++++-- package.json | 19 +- src/index.ts | 1 + tsconfig.json | 2 +- tsconfig.module.json | 7 - wrapper.mjs | 5 + 6 files changed, 427 insertions(+), 27 deletions(-) delete mode 100644 tsconfig.module.json create mode 100644 wrapper.mjs diff --git a/package-lock.json b/package-lock.json index 96f94b08..652f5736 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ }, "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", @@ -1278,6 +1279,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", @@ -1646,6 +1663,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", @@ -1706,6 +1750,119 @@ "safe-buffer": "~5.1.1" } }, + "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": { + "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": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -2163,9 +2320,9 @@ "dev": true }, "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "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", @@ -2423,9 +2580,9 @@ } }, "node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "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" @@ -3687,6 +3844,18 @@ "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", @@ -4054,6 +4223,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", @@ -4278,6 +4453,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", @@ -4305,6 +4525,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", @@ -6856,6 +7100,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", @@ -7116,6 +7370,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", @@ -7169,6 +7440,78 @@ "safe-buffer": "~5.1.1" } }, + "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": { + "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": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -7504,9 +7847,9 @@ } }, "fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "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", @@ -7697,9 +8040,9 @@ "dev": true }, "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "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": { @@ -8643,6 +8986,12 @@ "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": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -8917,6 +9266,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", @@ -9098,6 +9453,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", @@ -9116,6 +9500,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", diff --git a/package.json b/package.json index 8d000807..cc26fec6 100644 --- a/package.json +++ b/package.json @@ -14,23 +14,27 @@ "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": "./dist/esm/wrapper.mjs", + "require": "./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 format:check test:types db:clean db:run test:run db:clean", "test:run": "jest --runInBand", "test:update": "run-s db:clean db:run && jest --runInBand --updateSnapshot && run-s db:clean", - "test:types": "run-s build:module && tsd --files test/*.test-d.ts", + "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" }, @@ -39,6 +43,7 @@ }, "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", diff --git a/src/index.ts b/src/index.ts index 9fb4cb78..52e2d062 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,4 @@ +// Always update wrapper.mjs when updating this file. export { default as PostgrestClient } from './PostgrestClient' export { default as PostgrestQueryBuilder } from './PostgrestQueryBuilder' export { default as PostgrestFilterBuilder } from './PostgrestFilterBuilder' diff --git a/tsconfig.json b/tsconfig.json index 248dc3b0..27ce6487 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,7 @@ "declaration": true, "declarationMap": true, "module": "CommonJS", - "outDir": "dist/main", + "outDir": "dist/cjs", "sourceMap": true, "target": "ES2017", 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..cb31ba60 --- /dev/null +++ b/wrapper.mjs @@ -0,0 +1,5 @@ +export { default as PostgrestClient } from '../cjs/PostgrestClient.js' +export { default as PostgrestQueryBuilder } from '../cjs/PostgrestQueryBuilder.js' +export { default as PostgrestFilterBuilder } from '../cjs/PostgrestFilterBuilder.js' +export { default as PostgrestTransformBuilder } from '../cjs/PostgrestTransformBuilder.js' +export { default as PostgrestBuilder } from '../cjs/PostgrestBuilder.js' From dc420875fcd8f1b76d03920ece03f951e5610665 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Thu, 23 May 2024 13:04:25 +0800 Subject: [PATCH 075/110] Revert "fix: use proper dual-packaging" This reverts commit 2c4e846c8f697f760e15e06a60014e8b93bf3b34. --- package-lock.json | 420 ++----------------------------------------- package.json | 19 +- src/index.ts | 1 - tsconfig.json | 2 +- tsconfig.module.json | 7 + wrapper.mjs | 5 - 6 files changed, 27 insertions(+), 427 deletions(-) create mode 100644 tsconfig.module.json delete mode 100644 wrapper.mjs diff --git a/package-lock.json b/package-lock.json index 652f5736..96f94b08 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,6 @@ }, "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", @@ -1279,22 +1278,6 @@ "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", @@ -1663,33 +1646,6 @@ "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", @@ -1750,119 +1706,6 @@ "safe-buffer": "~5.1.1" } }, - "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": { - "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": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -2320,9 +2163,9 @@ "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==", + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -2580,9 +2423,9 @@ } }, "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true, "engines": { "node": ">= 4" @@ -3844,18 +3687,6 @@ "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", @@ -4223,12 +4054,6 @@ "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", @@ -4453,51 +4278,6 @@ "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", @@ -4525,30 +4305,6 @@ "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", @@ -7100,16 +6856,6 @@ "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", @@ -7370,23 +7116,6 @@ "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", @@ -7440,78 +7169,6 @@ "safe-buffer": "~5.1.1" } }, - "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": { - "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": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -7847,9 +7504,9 @@ } }, "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==", + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -8040,9 +7697,9 @@ "dev": true }, "ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true }, "import-local": { @@ -8986,12 +8643,6 @@ "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": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -9266,12 +8917,6 @@ "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", @@ -9453,35 +9098,6 @@ "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", @@ -9500,18 +9116,6 @@ "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", diff --git a/package.json b/package.json index cc26fec6..8d000807 100644 --- a/package.json +++ b/package.json @@ -14,27 +14,23 @@ "dist", "src" ], - "main": "dist/cjs/index.js", - "module": "dist/esm/wrapper.mjs", - "exports": { - "import": "./dist/esm/wrapper.mjs", - "require": "./dist/cjs/index.js" - }, - "types": "dist/cjs/index.d.ts", + "main": "dist/main/index.js", + "module": "dist/module/index.js", + "types": "dist/module/index.d.ts", "repository": "supabase/postgrest-js", "scripts": { "clean": "rimraf dist docs/v2", - "format": "prettier --write \"{src,test}/**/*.ts\" wrapper.mjs", + "format": "prettier --write \"{src,test}/**/*.ts\"", "format:check": "prettier --check \"{src,test}/**/*.ts\"", "build": "run-s clean format build:*", - "build:cjs": "tsc -p tsconfig.json", - "build:esm": "cpy wrapper.mjs dist/esm/", + "build:main": "tsc -p tsconfig.json", + "build:module": "tsc -p tsconfig.module.json", "docs": "typedoc src/index.ts --out docs/v2", "docs:json": "typedoc --json docs/v2/spec.json --excludeExternals src/index.ts", "test": "run-s format:check test:types db:clean db:run test:run db:clean", "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", + "test:types": "run-s build:module && 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" }, @@ -43,7 +39,6 @@ }, "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", diff --git a/src/index.ts b/src/index.ts index 52e2d062..9fb4cb78 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,3 @@ -// Always update wrapper.mjs when updating this file. export { default as PostgrestClient } from './PostgrestClient' export { default as PostgrestQueryBuilder } from './PostgrestQueryBuilder' export { default as PostgrestFilterBuilder } from './PostgrestFilterBuilder' diff --git a/tsconfig.json b/tsconfig.json index 27ce6487..248dc3b0 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,7 @@ "declaration": true, "declarationMap": true, "module": "CommonJS", - "outDir": "dist/cjs", + "outDir": "dist/main", "sourceMap": true, "target": "ES2017", diff --git a/tsconfig.module.json b/tsconfig.module.json new file mode 100644 index 00000000..8726ca43 --- /dev/null +++ b/tsconfig.module.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig", + "compilerOptions": { + "module": "ES2020", + "outDir": "dist/module" + } +} diff --git a/wrapper.mjs b/wrapper.mjs deleted file mode 100644 index cb31ba60..00000000 --- a/wrapper.mjs +++ /dev/null @@ -1,5 +0,0 @@ -export { default as PostgrestClient } from '../cjs/PostgrestClient.js' -export { default as PostgrestQueryBuilder } from '../cjs/PostgrestQueryBuilder.js' -export { default as PostgrestFilterBuilder } from '../cjs/PostgrestFilterBuilder.js' -export { default as PostgrestTransformBuilder } from '../cjs/PostgrestTransformBuilder.js' -export { default as PostgrestBuilder } from '../cjs/PostgrestBuilder.js' From 7fc5fcb84593d8e500bdce1636a8667183db3b82 Mon Sep 17 00:00:00 2001 From: Joonas Date: Wed, 29 May 2024 12:22:40 +0300 Subject: [PATCH 076/110] fix: detect !inner in one-to-one relationships (#530) --- src/select-query-parser.ts | 8 ++++++-- test/index.test-d.ts | 10 ++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/select-query-parser.ts b/src/select-query-parser.ts index 9567b1c9..7ba70a69 100644 --- a/src/select-query-parser.ts +++ b/src/select-query-parser.ts @@ -228,7 +228,9 @@ type ConstructFieldDefinition< ? R : unknown > extends true - ? Child | null + ? Field extends { inner: true } + ? Child + : Child | null : Relationships extends unknown[] ? HasFKey extends true ? Field extends { inner: true } @@ -259,7 +261,9 @@ type ConstructFieldDefinition< ? R : unknown > extends true - ? Child | null + ? Field extends { inner: true } + ? Child + : Child | null : Relationships extends unknown[] ? HasFKeyToFRel extends true ? Field extends { inner: true } diff --git a/test/index.test-d.ts b/test/index.test-d.ts index 066892d2..a41b6cb8 100644 --- a/test/index.test-d.ts +++ b/test/index.test-d.ts @@ -154,12 +154,18 @@ const postgrest = new PostgrestClient(REST_URL) { const { data: message, error } = await postgrest .from('messages') - .select('user:users!inner(*)') + .select('channels!inner(*, channel_details!inner(*))') .single() if (error) { throw new Error(error.message) } - expectType(message.user) + type ExpectedType = Prettify< + Database['public']['Tables']['channels']['Row'] & { + channel_details: Database['public']['Tables']['channel_details']['Row'] + } + > + + expectType(message.channels) } // one-to-many relationship From 24dcbde8fcb5d4543d6f91d7ed5a637b44ce5520 Mon Sep 17 00:00:00 2001 From: Aakash Bhadu <66458518+abhadu@users.noreply.github.com> Date: Wed, 29 May 2024 17:35:33 +0530 Subject: [PATCH 077/110] chore: offset should be `to + 1` not `from + to` in function documentation. (#516) * Update PostgrestTransformBuilder.ts * Update PostgrestTransformBuilder.ts --------- Co-authored-by: Bobbie Soedirgo <31685197+soedirgo@users.noreply.github.com> --- src/PostgrestTransformBuilder.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PostgrestTransformBuilder.ts b/src/PostgrestTransformBuilder.ts index 219ccd79..87b7a4fa 100644 --- a/src/PostgrestTransformBuilder.ts +++ b/src/PostgrestTransformBuilder.ts @@ -141,7 +141,7 @@ export default class PostgrestTransformBuilder< } /** - * Limit the query result by starting at an offset (`from`) and ending at the offset (`from + to`). + * 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 From 63d32e5a79be93dab826245853564667feaa1347 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 16 Jun 2024 10:30:58 +0000 Subject: [PATCH 078/110] chore(deps-dev): bump braces from 3.0.2 to 3.0.3 Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3. - [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md) - [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3) --- updated-dependencies: - dependency-name: braces dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index 96f94b08..d7d4adcd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1466,12 +1466,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" @@ -2203,9 +2203,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" @@ -6999,12 +6999,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": { @@ -7541,9 +7541,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" From 541cd5d64bcdf4d01e715921ff30803f0a17d280 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Tue, 25 Jun 2024 08:17:04 +0200 Subject: [PATCH 079/110] fix: Reland ESM fix (#540) * fix: use proper dual-packaging Support CommonJS & ESM. Previously the ESM build (dist/module) is broken - it's recognized as CommonJS. For more on dual-packaging: https://nodejs.org/api/packages.html#dual-commonjses-module-packages * Fix and add smoke tests --------- Co-authored-by: Bobbie Soedirgo --- package-lock.json | 420 +++++++++++++++++++++++++++++++++++++++++-- package.json | 21 ++- src/index.ts | 3 +- test/smoke.cjs | 10 ++ test/smoke.mjs | 15 ++ tsconfig.json | 2 +- tsconfig.module.json | 7 - wrapper.mjs | 25 +++ 8 files changed, 474 insertions(+), 29 deletions(-) create mode 100644 test/smoke.cjs create mode 100644 test/smoke.mjs delete mode 100644 tsconfig.module.json create mode 100644 wrapper.mjs diff --git a/package-lock.json b/package-lock.json index 96f94b08..652f5736 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ }, "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", @@ -1278,6 +1279,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", @@ -1646,6 +1663,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", @@ -1706,6 +1750,119 @@ "safe-buffer": "~5.1.1" } }, + "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": { + "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": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -2163,9 +2320,9 @@ "dev": true }, "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "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", @@ -2423,9 +2580,9 @@ } }, "node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "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" @@ -3687,6 +3844,18 @@ "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", @@ -4054,6 +4223,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", @@ -4278,6 +4453,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", @@ -4305,6 +4525,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", @@ -6856,6 +7100,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", @@ -7116,6 +7370,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", @@ -7169,6 +7440,78 @@ "safe-buffer": "~5.1.1" } }, + "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": { + "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": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -7504,9 +7847,9 @@ } }, "fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "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", @@ -7697,9 +8040,9 @@ "dev": true }, "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "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": { @@ -8643,6 +8986,12 @@ "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": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -8917,6 +9266,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", @@ -9098,6 +9453,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", @@ -9116,6 +9500,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", diff --git a/package.json b/package.json index 8d000807..01f0d775 100644 --- a/package.json +++ b/package.json @@ -14,23 +14,27 @@ "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": "./dist/esm/wrapper.mjs", + "require": "./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 format:check test:types db:clean db:run test:run db:clean", + "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:module && tsd --files test/*.test-d.ts", + "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" }, @@ -39,6 +43,7 @@ }, "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", diff --git a/src/index.ts b/src/index.ts index 9fb4cb78..79c38dde 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,9 +1,10 @@ +// Always update wrapper.mjs when updating this file. 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' -export { +export type { PostgrestResponse, PostgrestResponseFailure, PostgrestResponseSuccess, diff --git a/test/smoke.cjs b/test/smoke.cjs new file mode 100644 index 00000000..1a5b0079 --- /dev/null +++ b/test/smoke.cjs @@ -0,0 +1,10 @@ +// 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 === "undefined"); diff --git a/test/smoke.mjs b/test/smoke.mjs new file mode 100644 index 00000000..f34eb565 --- /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/tsconfig.json b/tsconfig.json index 248dc3b0..27ce6487 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,7 @@ "declaration": true, "declarationMap": true, "module": "CommonJS", - "outDir": "dist/main", + "outDir": "dist/cjs", "sourceMap": true, "target": "ES2017", 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, +} From 7b8c974cf805fd583d7efce77152412ce46ab9c9 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo <31685197+soedirgo@users.noreply.github.com> Date: Thu, 27 Jun 2024 21:18:34 +0800 Subject: [PATCH 080/110] fix: esm typings (#547) --- package.json | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 01f0d775..889606af 100644 --- a/package.json +++ b/package.json @@ -17,10 +17,16 @@ "main": "dist/cjs/index.js", "module": "dist/esm/wrapper.mjs", "exports": { - "import": "./dist/esm/wrapper.mjs", - "require": "./dist/cjs/index.js" + "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", + "types": "./dist/cjs/index.d.ts", "repository": "supabase/postgrest-js", "scripts": { "clean": "rimraf dist docs/v2", From 7b5922f1a3983b42fa0c3aa04c701c35f03fa4c4 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Thu, 4 Jul 2024 21:11:42 +0800 Subject: [PATCH 081/110] fix: imports not working w/ Metro bundler --- src/index.ts | 25 ++++++++++++++++++++----- test/smoke.cjs | 7 ++++++- test/smoke.mjs | 2 +- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/index.ts b/src/index.ts index 79c38dde..f20eb74f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,9 +1,24 @@ // Always update wrapper.mjs when updating this file. -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' +import PostgrestClient from './PostgrestClient' +import PostgrestQueryBuilder from './PostgrestQueryBuilder' +import PostgrestFilterBuilder from './PostgrestFilterBuilder' +import PostgrestTransformBuilder from './PostgrestTransformBuilder' +import PostgrestBuilder from './PostgrestBuilder' + +export { + PostgrestClient, + PostgrestQueryBuilder, + PostgrestFilterBuilder, + PostgrestTransformBuilder, + PostgrestBuilder, +} +export default { + PostgrestClient, + PostgrestQueryBuilder, + PostgrestFilterBuilder, + PostgrestTransformBuilder, + PostgrestBuilder, +} export type { PostgrestResponse, PostgrestResponseFailure, diff --git a/test/smoke.cjs b/test/smoke.cjs index 1a5b0079..610dacfa 100644 --- a/test/smoke.cjs +++ b/test/smoke.cjs @@ -7,4 +7,9 @@ assert(typeof postgrestjs.PostgrestQueryBuilder === "function"); assert(typeof postgrestjs.PostgrestFilterBuilder === "function"); assert(typeof postgrestjs.PostgrestTransformBuilder === "function"); assert(typeof postgrestjs.PostgrestBuilder === "function"); -assert(typeof postgrestjs.default === "undefined"); +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 index f34eb565..caf22bbe 100644 --- a/test/smoke.mjs +++ b/test/smoke.mjs @@ -12,4 +12,4 @@ 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') +assert(typeof postgrestjs.default.PostgrestBuilder === 'function'); From 9f91e72c4c02ea55d647e15ed865791cf90eb50e Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Wed, 17 Jul 2024 16:53:38 +0800 Subject: [PATCH 082/110] feat: allow setting headers on a per-call basis --- src/PostgrestBuilder.ts | 9 +++++++++ test/basic.ts | 9 +++++++++ test/index.test-d.ts | 9 +++++++++ 3 files changed, 27 insertions(+) diff --git a/src/PostgrestBuilder.ts b/src/PostgrestBuilder.ts index 96a8bc55..621785c9 100644 --- a/src/PostgrestBuilder.ts +++ b/src/PostgrestBuilder.ts @@ -47,6 +47,15 @@ export default abstract class PostgrestBuilder return this } + /** + * 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: PostgrestSingleResponse) => TResult1 | PromiseLike) diff --git a/test/basic.ts b/test/basic.ts index ba57ac23..7583fd7a 100644 --- a/test/basic.ts +++ b/test/basic.ts @@ -107,6 +107,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, { diff --git a/test/index.test-d.ts b/test/index.test-d.ts index a41b6cb8..e467d2fd 100644 --- a/test/index.test-d.ts +++ b/test/index.test-d.ts @@ -196,3 +196,12 @@ const postgrest = new PostgrestClient(REST_URL) channels.channel_details ) } + +// 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) +} From c2049b21de87aeeb47cd8dfb61e9477430b021f6 Mon Sep 17 00:00:00 2001 From: Andrew Valleteau Date: Tue, 10 Sep 2024 19:38:48 +0200 Subject: [PATCH 083/110] fix(select-query-parser): support `!left` * test: reproduce type error with left join reproduction based on https://github.com/supabase/supabase/issues/29086 * chore: add ts-expect-error comment * test: add left join one to many select test * test: add 1-1 nullable and 1-N relations tests * wip: fix left join result type builder * wip: found misplassed nullable * chore: revert unwanted biome fixes * fix: query types parser * chore: remove unwanted styling * chore: add comment * fix: rollback tests * fix: tests * fix: tests comments * chore: fix docker-compose ci Chore docker-compose in ci and replace it by docker compose as recommended by: https://github.blog/changelog/2024-04-10-github-hosted-runner-images-deprecation-notice-docker-compose-v1/ * Update test/db/01-dummy-data.sql --------- Co-authored-by: Bobbie Soedirgo <31685197+soedirgo@users.noreply.github.com> --- package.json | 4 +- src/select-query-parser.ts | 12 ++ test/basic.ts | 236 +++++++++++++++++++++++++++++++++++++ test/db/00-schema.sql | 18 +++ test/db/01-dummy-data.sql | 15 +++ test/index.test-d.ts | 80 +++++++++++++ test/types.ts | 108 +++++++++++++++++ 7 files changed, 471 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 889606af..fc30dd3e 100644 --- a/package.json +++ b/package.json @@ -41,8 +41,8 @@ "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" + "db:clean": "cd test/db && docker compose down --volumes", + "db:run": "cd test/db && docker compose up --detach && wait-for-localhost 3000" }, "dependencies": { "@supabase/node-fetch": "^2.6.14" diff --git a/src/select-query-parser.ts b/src/select-query-parser.ts index 7ba70a69..0c5c40f1 100644 --- a/src/select-query-parser.ts +++ b/src/select-query-parser.ts @@ -268,6 +268,9 @@ type ConstructFieldDefinition< ? HasFKeyToFRel extends true ? Field extends { inner: true } ? Child + : Field extends { left: true } + ? // TODO: This should return null only if the column is actually nullable + Child | null : Child | null : Child[] : Child[] @@ -350,6 +353,7 @@ type ParseIdentifier = ReadLetters extends [ * - `field(nodes)` * - `field!hint(nodes)` * - `field!inner(nodes)` + * - `field!left(nodes)` * - `field!hint!inner(nodes)` * - a field without an embedded resource (see {@link ParseFieldWithoutEmbeddedResource}) */ @@ -364,6 +368,14 @@ type ParseField = Input extends '' ParseEmbeddedResource>, 'Expected embedded resource after `!inner`' > + : EatWhitespace extends `!left${infer Remainder}` + ? ParseEmbeddedResource> extends [infer Fields, `${infer Remainder}`] + ? // `field!left(nodes)` + [{ name: Name; original: Name; children: Fields; left: true }, EatWhitespace] + : CreateParserErrorIfRequired< + ParseEmbeddedResource>, + 'Expected embedded resource after `!left`' + > : EatWhitespace extends `!${infer Remainder}` ? ParseIdentifier> extends [infer Hint, `${infer Remainder}`] ? EatWhitespace extends `!inner${infer Remainder}` diff --git a/test/basic.ts b/test/basic.ts index 7583fd7a..6b46d50f 100644 --- a/test/basic.ts +++ b/test/basic.ts @@ -1481,3 +1481,239 @@ test('update with no match - return=representation', async () => { } `) }) + +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", + }, + ], + }, + "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('!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 902862b6..21d49a7e 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, diff --git a/test/db/01-dummy-data.sql b/test/db/01-dummy-data.sql index d425163a..7ff4f94e 100644 --- a/test/db/01-dummy-data.sql +++ b/test/db/01-dummy-data.sql @@ -30,3 +30,18 @@ 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); diff --git a/test/index.test-d.ts b/test/index.test-d.ts index e467d2fd..c1fb9ba0 100644 --- a/test/index.test-d.ts +++ b/test/index.test-d.ts @@ -205,3 +205,83 @@ const postgrest = new PostgrestClient(REST_URL) expectType(y) expectType(z) } + +// !left oneToOne +{ + const { data: oneToOne, error } = await postgrest + .from('channel_details') + .select('channels!left(*)') + .single() + + if (error) { + throw new Error(error.message) + } + + // TODO: this should never be nullable + expectType(oneToOne.channels) +} + +// !left oneToMany +{ + const { data: oneToMany, error } = await postgrest + .from('users') + .select('messages!left(*)') + .single() + + if (error) { + throw new Error(error.message) + } + + expectType>(oneToMany.messages) +} + +// !left zeroToOne +{ + const { data: zeroToOne, error } = await postgrest + .from('user_profiles') + .select('users!left(*)') + .single() + + if (error) { + throw new Error(error.message) + } + + expectType(zeroToOne.users) +} + +// join over a 1-1 relation with both nullables and non-nullables fields +{ + const { data: bestFriends, error } = 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(*)' + ) + .single() + + if (error) { + throw new Error(error.message) + } + + // TODO: Those two fields shouldn't be nullables + expectType(bestFriends.first_user) + expectType(bestFriends.second_user) + // The third wheel should be nullable + expectType(bestFriends.third_wheel) +} +// join over a 1-M relation with both nullables and non-nullables fields +{ + const { data: users, error } = 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(*)` + ) + .single() + + if (error) { + throw new Error(error.message) + } + // TODO: type properly the result for this kind of queries + expectType>(users.first_friend_of) +} diff --git a/test/types.ts b/test/types.ts index 629d3c3e..deed0fa9 100644 --- a/test/types.ts +++ b/test/types.ts @@ -45,6 +45,77 @@ export type Database = { } public: { Tables: { + best_friends: { + Row: { + first_user: string + id: number + second_user: string + third_wheel: string | null + } + Insert: { + first_user: string + id?: number + second_user: string + third_wheel?: string | null + } + Update: { + first_user?: string + id?: number + second_user?: string + third_wheel?: string | null + } + Relationships: [ + { + 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'] + } + ] + } channel_details: { Row: { details: string | null @@ -181,6 +252,43 @@ export type Database = { } 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: { non_updatable_view: { From 5ea6d90bcad23de597862df5d7537971fe240deb Mon Sep 17 00:00:00 2001 From: avallete Date: Fri, 27 Sep 2024 22:17:54 +0200 Subject: [PATCH 084/110] chore: upgrade postgrest tests image add some more test data --- test/basic.ts | 257 +++++++++++++++++++++++++++++-------- test/db/01-dummy-data.sql | 22 ++-- test/db/docker-compose.yml | 3 +- test/filters.ts | 21 +++ test/resource-embedding.ts | 45 +++++++ test/transforms.ts | 35 ++++- 6 files changed, 319 insertions(+), 64 deletions(-) diff --git a/test/basic.ts b/test/basic.ts index 6b46d50f..bb0ab768 100644 --- a/test/basic.ts +++ b/test/basic.ts @@ -38,6 +38,20 @@ test('basic select table', async () => { "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, @@ -68,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, @@ -268,8 +286,8 @@ test('on_conflict insert', async () => { }, ], "error": null, - "status": 201, - "statusText": "Created", + "status": 200, + "statusText": "OK", } `) }) @@ -303,7 +321,7 @@ describe('basic insert, update, delete', () => { Object { "channel_id": 1, "data": null, - "id": 3, + "id": 5, "message": "foo", "username": "supabot", }, @@ -334,9 +352,23 @@ describe('basic insert, update, delete', () => { "username": "supabot", }, Object { - "channel_id": 1, + "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", }, @@ -366,8 +398,8 @@ describe('basic insert, update, delete', () => { }, ], "error": null, - "status": 201, - "statusText": "Created", + "status": 200, + "statusText": "OK", } `) @@ -390,6 +422,20 @@ describe('basic insert, update, delete', () => { "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, @@ -420,14 +466,14 @@ describe('basic insert, update, delete', () => { Object { "channel_id": 1, "data": null, - "id": 4, + "id": 6, "message": "foo", "username": "supabot", }, Object { "channel_id": 1, "data": null, - "id": 5, + "id": 7, "message": "foo", "username": "supabot", }, @@ -457,6 +503,20 @@ describe('basic insert, update, delete', () => { "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, @@ -467,14 +527,14 @@ describe('basic insert, update, delete', () => { Object { "channel_id": 1, "data": null, - "id": 4, + "id": 6, "message": "foo", "username": "supabot", }, Object { "channel_id": 1, "data": null, - "id": 5, + "id": 7, "message": "foo", "username": "supabot", }, @@ -496,6 +556,13 @@ describe('basic insert, update, delete', () => { Object { "count": null, "data": Array [ + Object { + "channel_id": 2, + "data": null, + "id": 5, + "message": "foo", + "username": "supabot", + }, Object { "channel_id": 2, "data": null, @@ -506,14 +573,14 @@ describe('basic insert, update, delete', () => { Object { "channel_id": 2, "data": null, - "id": 4, + "id": 6, "message": "foo", "username": "supabot", }, Object { "channel_id": 2, "data": null, - "id": 5, + "id": 7, "message": "foo", "username": "supabot", }, @@ -543,6 +610,20 @@ describe('basic insert, update, delete', () => { "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, @@ -553,14 +634,14 @@ describe('basic insert, update, delete', () => { Object { "channel_id": 2, "data": null, - "id": 4, + "id": 6, "message": "foo", "username": "supabot", }, Object { "channel_id": 2, "data": null, - "id": 5, + "id": 7, "message": "foo", "username": "supabot", }, @@ -578,6 +659,13 @@ describe('basic insert, update, delete', () => { Object { "count": null, "data": Array [ + Object { + "channel_id": 2, + "data": null, + "id": 5, + "message": "foo", + "username": "supabot", + }, Object { "channel_id": 2, "data": null, @@ -588,14 +676,14 @@ describe('basic insert, update, delete', () => { Object { "channel_id": 2, "data": null, - "id": 4, + "id": 6, "message": "foo", "username": "supabot", }, Object { "channel_id": 2, "data": null, - "id": 5, + "id": 7, "message": "foo", "username": "supabot", }, @@ -625,6 +713,13 @@ describe('basic insert, update, delete', () => { "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, @@ -773,6 +868,20 @@ test('allow ordering on JSON column', async () => { "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'", @@ -808,7 +917,7 @@ test('select with head:true, count:exact', async () => { const res = await postgrest.from('users').select('*', { head: true, count: 'exact' }) expect(res).toMatchInlineSnapshot(` Object { - "count": 4, + "count": 5, "data": null, "error": null, "status": 200, @@ -857,7 +966,7 @@ test('select with count:exact', async () => { const res = await postgrest.from('users').select('*', { count: 'exact' }) expect(res).toMatchInlineSnapshot(` Object { - "count": 4, + "count": 5, "data": Array [ Object { "age_range": "[1,2)", @@ -880,6 +989,20 @@ test('select with count:exact', async () => { "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'", @@ -1002,7 +1125,7 @@ describe("insert, update, delete with count: 'exact'", () => { Object { "channel_id": 1, "data": null, - "id": 6, + "id": 8, "message": "foo", "username": "supabot", }, @@ -1032,10 +1155,17 @@ describe("insert, update, delete with count: 'exact'", () => { "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": 6, + "id": 8, "message": "foo", "username": "supabot", }, @@ -1089,10 +1219,17 @@ describe("insert, update, delete with count: 'exact'", () => { "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": 6, + "id": 8, "message": "foo", "username": "supabot", }, @@ -1129,14 +1266,14 @@ describe("insert, update, delete with count: 'exact'", () => { Object { "channel_id": 1, "data": null, - "id": 7, + "id": 9, "message": "foo", "username": "supabot", }, Object { "channel_id": 1, "data": null, - "id": 8, + "id": 10, "message": "foo", "username": "supabot", }, @@ -1166,10 +1303,17 @@ describe("insert, update, delete with count: 'exact'", () => { "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": 6, + "id": 8, "message": "foo", "username": "supabot", }, @@ -1183,14 +1327,14 @@ describe("insert, update, delete with count: 'exact'", () => { Object { "channel_id": 1, "data": null, - "id": 7, + "id": 9, "message": "foo", "username": "supabot", }, Object { "channel_id": 1, "data": null, - "id": 8, + "id": 10, "message": "foo", "username": "supabot", }, @@ -1211,21 +1355,15 @@ describe("insert, update, delete with count: 'exact'", () => { expect(res).toMatchInlineSnapshot(` Object { "count": null, - "data": Array [ - Object { - "data": null, - "id": 100, - "slug": null, - }, - Object { - "data": null, - "id": 4, - "slug": "test-slug", - }, - ], - "error": null, - "status": 201, - "statusText": "Created", + "data": null, + "error": Object { + "code": "23505", + "details": "Key (id)=(2) already exists.", + "hint": null, + "message": "duplicate key value violates unique constraint \\"channels_pkey\\"", + }, + "status": 409, + "statusText": "Conflict", } `) }) @@ -1247,7 +1385,7 @@ describe("insert, update, delete with count: 'exact'", () => { }, Object { "data": null, - "id": 6, + "id": 4, "slug": "test-slug", }, ], @@ -1271,7 +1409,7 @@ describe("insert, update, delete with count: 'exact'", () => { Object { "channel_id": 2, "data": null, - "id": 6, + "id": 8, "message": "foo", "username": "supabot", }, @@ -1285,14 +1423,14 @@ describe("insert, update, delete with count: 'exact'", () => { Object { "channel_id": 2, "data": null, - "id": 7, + "id": 9, "message": "foo", "username": "supabot", }, Object { "channel_id": 2, "data": null, - "id": 8, + "id": 10, "message": "foo", "username": "supabot", }, @@ -1322,10 +1460,17 @@ describe("insert, update, delete with count: 'exact'", () => { "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": 6, + "id": 8, "message": "foo", "username": "supabot", }, @@ -1339,14 +1484,14 @@ describe("insert, update, delete with count: 'exact'", () => { Object { "channel_id": 2, "data": null, - "id": 7, + "id": 9, "message": "foo", "username": "supabot", }, Object { "channel_id": 2, "data": null, - "id": 8, + "id": 10, "message": "foo", "username": "supabot", }, @@ -1371,7 +1516,7 @@ describe("insert, update, delete with count: 'exact'", () => { Object { "channel_id": 2, "data": null, - "id": 6, + "id": 8, "message": "foo", "username": "supabot", }, @@ -1385,14 +1530,14 @@ describe("insert, update, delete with count: 'exact'", () => { Object { "channel_id": 2, "data": null, - "id": 7, + "id": 9, "message": "foo", "username": "supabot", }, Object { "channel_id": 2, "data": null, - "id": 8, + "id": 10, "message": "foo", "username": "supabot", }, @@ -1422,6 +1567,13 @@ describe("insert, update, delete with count: 'exact'", () => { "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, @@ -1516,6 +1668,9 @@ test('!left join on one to many relation', async () => { Object { "username": "supabot", }, + Object { + "username": "supabot", + }, ], }, "error": null, diff --git a/test/db/01-dummy-data.sql b/test/db/01-dummy-data.sql index 7ff4f94e..8ed5e04c 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) + public.channels (id, slug) VALUES - ('public'), - ('random'); + (1, 'public'), + (2, 'random'), + (3, '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) diff --git a/test/db/docker-compose.yml b/test/db/docker-compose.yml index 13e9d2d7..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:v11.2.2 + image: postgrest/postgrest:v12.2.0 ports: - '3000:3000' environment: @@ -13,6 +13,7 @@ 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: diff --git a/test/filters.ts b/test/filters.ts index 98a76e4d..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, @@ -330,6 +342,9 @@ test('in', async () => { Object { "status": "ONLINE", }, + Object { + "status": "ONLINE", + }, ], "error": null, "status": 200, @@ -424,6 +439,9 @@ test('rangeGte', async () => { Object { "age_range": "[20,30)", }, + Object { + "age_range": "[20,30)", + }, ], "error": null, "status": 200, @@ -481,6 +499,9 @@ test('overlaps', async () => { Object { "age_range": "[20,30)", }, + Object { + "age_range": "[20,30)", + }, ], "error": null, "status": 200, diff --git a/test/resource-embedding.ts b/test/resource-embedding.ts index 08887be0..b3cca1a8 100644 --- a/test/resource-embedding.ts +++ b/test/resource-embedding.ts @@ -25,6 +25,13 @@ test('embedded select', async () => { "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 { @@ -36,6 +43,9 @@ test('embedded select', async () => { Object { "messages": Array [], }, + Object { + "messages": Array [], + }, ], "error": null, "status": 200, @@ -75,6 +85,9 @@ describe('embedded filters', () => { Object { "messages": Array [], }, + Object { + "messages": Array [], + }, ], "error": null, "status": 200, @@ -118,6 +131,9 @@ describe('embedded filters', () => { Object { "messages": Array [], }, + Object { + "messages": Array [], + }, ], "error": null, "status": 200, @@ -163,6 +179,9 @@ describe('embedded filters', () => { Object { "messages": Array [], }, + Object { + "messages": Array [], + }, ], "error": null, "status": 200, @@ -184,6 +203,13 @@ describe('embedded transforms', () => { "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, @@ -209,6 +235,9 @@ describe('embedded transforms', () => { Object { "messages": Array [], }, + Object { + "messages": Array [], + }, ], "error": null, "status": 200, @@ -229,6 +258,13 @@ describe('embedded transforms', () => { "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, @@ -254,6 +290,9 @@ describe('embedded transforms', () => { Object { "messages": Array [], }, + Object { + "messages": Array [], + }, ], "error": null, "status": 200, @@ -291,6 +330,9 @@ describe('embedded transforms', () => { Object { "messages": Array [], }, + Object { + "messages": Array [], + }, ], "error": null, "status": 200, @@ -328,6 +370,9 @@ describe('embedded transforms', () => { Object { "messages": Array [], }, + Object { + "messages": Array [], + }, ], "error": null, "status": 200, diff --git a/test/transforms.ts b/test/transforms.ts index b0d0bce5..e6518910 100644 --- a/test/transforms.ts +++ b/test/transforms.ts @@ -25,6 +25,20 @@ test('order', async () => { "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'", @@ -57,6 +71,13 @@ test('order on multiple columns', async () => { 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, @@ -122,10 +143,17 @@ test('range', async () => { }, Object { "age_range": "[20,30)", - "catchphrase": "'fat' 'rat'", - "data": null, + "catchphrase": "'json' 'test'", + "data": Object { + "foo": Object { + "bar": Object { + "nested": "value", + }, + "baz": "string value", + }, + }, "status": "ONLINE", - "username": "dragarcia", + "username": "jsonuser", }, ], "error": null, @@ -257,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, From df9274ee9946521a126bdec3f6e31fc75f05fe0d Mon Sep 17 00:00:00 2001 From: avallete Date: Fri, 27 Sep 2024 22:44:38 +0200 Subject: [PATCH 085/110] chore: add more runtime tests coverage for selection create tests cases to assert postgrest runtime behavior across large typology of queries. Prepare for future testing against result infered types --- test/index.test-d.ts | 19 - test/index.test.ts | 1 + test/relationships.ts | 1716 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1717 insertions(+), 19 deletions(-) create mode 100644 test/relationships.ts diff --git a/test/index.test-d.ts b/test/index.test-d.ts index c1fb9ba0..ffe2112a 100644 --- a/test/index.test-d.ts +++ b/test/index.test-d.ts @@ -113,25 +113,6 @@ const postgrest = new PostgrestClient(REST_URL) expectType(data.baz) } -// typecasting and aggregate functions -{ - const { data, error } = await postgrest - .from('messages') - .select( - 'message, users.count(), casted_message:message::int4, casted_count:users.count()::text' - ) - .single() - if (error) { - throw new Error(error.message) - } - expectType<{ - message: string | null - count: number - casted_message: number - casted_count: string - }>(data) -} - // rpc return type { const { data, error } = await postgrest.rpc('get_status') diff --git a/test/index.test.ts b/test/index.test.ts index ad4e4ee7..6a18f85d 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -1,4 +1,5 @@ import './basic' +import './relationships' import './filters' import './resource-embedding' import './transforms' diff --git a/test/relationships.ts b/test/relationships.ts new file mode 100644 index 00000000..4d8b612d --- /dev/null +++ b/test/relationships.ts @@ -0,0 +1,1716 @@ +import { PostgrestClient } from '../src/index' +import { Database } from './types' + +const REST_URL = 'http://localhost:3000' +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', + }, +} 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), +} 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", + } +`) +}) From 31d594b0d13bd0079714b5ce330739398530b913 Mon Sep 17 00:00:00 2001 From: avallete Date: Wed, 11 Sep 2024 21:38:47 +0200 Subject: [PATCH 086/110] feat: write select-query-parser v2 - Rewrite select-query-parser - Add tests for all runtime queries and expected output --- package-lock.json | 219 ++- package.json | 3 +- src/PostgrestQueryBuilder.ts | 2 +- src/PostgrestTransformBuilder.ts | 2 +- src/select-query-parser.ts | 706 --------- src/select-query-parser/parser/ast.ts | 29 + src/select-query-parser/parser/parser.ts | 506 ++++++ src/select-query-parser/parser/utils.ts | 103 ++ src/select-query-parser/result.ts | 249 +++ src/select-query-parser/types.ts | 115 ++ src/select-query-parser/utils.ts | 433 ++++++ src/types.ts | 11 + test/basic.ts | 750 ++++----- test/db/01-dummy-data.sql | 22 +- test/db/docker-compose.yml | 3 +- test/filters.ts | 187 ++- test/index.test-d.ts | 171 +- test/index.test.ts | 1 + test/relationships.ts | 1716 +++++++++++++++++++++ test/resource-embedding.ts | 563 +++---- test/select-query-parser/parser.test-d.ts | 570 +++++++ test/select-query-parser/result.test-d.ts | 56 + test/select-query-parser/select.test-d.ts | 689 +++++++++ test/select-query-parser/types.test-d.ts | 180 +++ test/transforms.ts | 179 ++- test/types.ts | 1 - 26 files changed, 5722 insertions(+), 1744 deletions(-) delete mode 100644 src/select-query-parser.ts create mode 100644 src/select-query-parser/parser/ast.ts create mode 100644 src/select-query-parser/parser/parser.ts create mode 100644 src/select-query-parser/parser/utils.ts create mode 100644 src/select-query-parser/result.ts create mode 100644 src/select-query-parser/types.ts create mode 100644 src/select-query-parser/utils.ts create mode 100644 test/relationships.ts create mode 100644 test/select-query-parser/parser.test-d.ts create mode 100644 test/select-query-parser/result.test-d.ts create mode 100644 test/select-query-parser/select.test-d.ts create mode 100644 test/select-query-parser/types.test-d.ts diff --git a/package-lock.json b/package-lock.json index 092e9877..5200b488 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,8 +20,9 @@ "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.24.1", + "tsd": "^0.31.2", "typedoc": "^0.22.16", "typescript": "~4.7", "wait-for-localhost-cli": "^3.0.0" @@ -1117,10 +1118,14 @@ } }, "node_modules/@tsd/typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/@tsd/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-WMFNVstwWGyDuZP2LGPRZ+kPHxZLmhO+2ormstDvnXiyoBPtW1qq9XhhrkI4NVtxgs+2ZiUTl9AG7nNIRq/uCg==", - "dev": true + "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", @@ -4697,10 +4702,11 @@ } }, "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" }, @@ -5478,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", @@ -5534,14 +5547,16 @@ } }, "node_modules/tsd": { - "version": "0.24.1", - "resolved": "https://registry.npmjs.org/tsd/-/tsd-0.24.1.tgz", - "integrity": "sha512-sD+s81/2aM4RRhimCDttd4xpBNbUFWnoMSHk/o8kC8Ek23jljeRNWjsxFJmOmYLuLTN9swRt1b6iXfUXTcTiIA==", + "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": "~4.8.3", + "@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" @@ -5553,6 +5568,39 @@ "node": ">=14.16" } }, + "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, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "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", @@ -5579,6 +5627,16 @@ "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", @@ -5600,6 +5658,32 @@ "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", @@ -5641,6 +5725,21 @@ "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", @@ -5650,6 +5749,13 @@ "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", @@ -6938,9 +7044,9 @@ } }, "@tsd/typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/@tsd/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-WMFNVstwWGyDuZP2LGPRZ+kPHxZLmhO+2ormstDvnXiyoBPtW1qq9XhhrkI4NVtxgs+2ZiUTl9AG7nNIRq/uCg==", + "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": { @@ -9614,9 +9720,9 @@ } }, "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": { @@ -10158,6 +10264,12 @@ "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", @@ -10183,19 +10295,41 @@ } }, "tsd": { - "version": "0.24.1", - "resolved": "https://registry.npmjs.org/tsd/-/tsd-0.24.1.tgz", - "integrity": "sha512-sD+s81/2aM4RRhimCDttd4xpBNbUFWnoMSHk/o8kC8Ek23jljeRNWjsxFJmOmYLuLTN9swRt1b6iXfUXTcTiIA==", + "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": "~4.8.3", + "@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", @@ -10213,6 +10347,12 @@ "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", @@ -10228,6 +10368,24 @@ "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", @@ -10260,12 +10418,29 @@ "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", diff --git a/package.json b/package.json index fc30dd3e..61e91cca 100644 --- a/package.json +++ b/package.json @@ -56,8 +56,9 @@ "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.24.1", + "tsd": "^0.31.2", "typedoc": "^0.22.16", "typescript": "~4.7", "wait-for-localhost-cli": "^3.0.0" diff --git a/src/PostgrestQueryBuilder.ts b/src/PostgrestQueryBuilder.ts index 8f6db3f5..44e7320a 100644 --- a/src/PostgrestQueryBuilder.ts +++ b/src/PostgrestQueryBuilder.ts @@ -1,6 +1,6 @@ import PostgrestBuilder from './PostgrestBuilder' import PostgrestFilterBuilder from './PostgrestFilterBuilder' -import { GetResult } from './select-query-parser' +import { GetResult } from './select-query-parser/result' import { Fetch, GenericSchema, GenericTable, GenericView } from './types' export default class PostgrestQueryBuilder< diff --git a/src/PostgrestTransformBuilder.ts b/src/PostgrestTransformBuilder.ts index 87b7a4fa..4791702c 100644 --- a/src/PostgrestTransformBuilder.ts +++ b/src/PostgrestTransformBuilder.ts @@ -1,5 +1,5 @@ import PostgrestBuilder from './PostgrestBuilder' -import { GetResult } from './select-query-parser' +import { GetResult } from './select-query-parser/result' import { GenericSchema } from './types' export default class PostgrestTransformBuilder< diff --git a/src/select-query-parser.ts b/src/select-query-parser.ts deleted file mode 100644 index 0c5c40f1..00000000 --- a/src/select-query-parser.ts +++ /dev/null @@ -1,706 +0,0 @@ -// 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 { GenericSchema, Prettify } from './types' - -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 | '_' - -type Json = string | number | boolean | null | { [key: string]: Json } | Json[] - -type SingleValuePostgreSQLTypes = - | 'bool' - | 'int2' - | 'int4' - | 'int8' - | 'float4' - | 'float8' - | 'numeric' - | 'bytea' - | 'bpchar' - | 'varchar' - | 'date' - | 'text' - | 'citext' - | 'time' - | 'timetz' - | 'timestamp' - | 'timestamptz' - | 'uuid' - | 'vector' - | 'json' - | 'jsonb' - | 'void' - | 'record' - | string - -type ArrayPostgreSQLTypes = `_${SingleValuePostgreSQLTypes}` - -type PostgreSQLTypes = SingleValuePostgreSQLTypes | ArrayPostgreSQLTypes - -type TypeScriptSingleValueTypes = T extends 'bool' - ? boolean - : T extends 'int2' | 'int4' | 'int8' | 'float4' | 'float8' | 'numeric' - ? number - : T extends - | 'bytea' - | 'bpchar' - | 'varchar' - | 'date' - | 'text' - | 'citext' - | 'time' - | 'timetz' - | 'timestamp' - | 'timestamptz' - | 'uuid' - | 'vector' - ? string - : T extends 'json' | 'jsonb' - ? Json - : T extends 'void' - ? undefined - : T extends 'record' - ? Record - : unknown - -type AggregateFunctions = 'count' | 'sum' | 'avg' | 'min' | 'max' - -type StripUnderscore = T extends `_${infer U}` ? U : T - -type TypeScriptTypes = T extends ArrayPostgreSQLTypes - ? TypeScriptSingleValueTypes>>[] - : TypeScriptSingleValueTypes - -/** - * Parser errors. - */ -type ParserError = { error: true } & Message -type GenericStringError = ParserError<'Received a generic string'> -export type SelectQueryError = { error: true } & Message - -/** - * Creates a new {@link ParserError} if the given input is not already a parser error. - */ -type CreateParserErrorIfRequired = Input extends ParserError - ? Input - : ParserError - -/** - * Trims whitespace from the left of the input. - */ -type EatWhitespace = string extends Input - ? GenericStringError - : Input extends `${Whitespace}${infer Remainder}` - ? EatWhitespace - : Input - -/** - * Returns a boolean representing whether there is a foreign key with the given name. - */ -type HasFKey = Relationships extends [infer R] - ? R extends { foreignKeyName: FKeyName } - ? true - : false - : Relationships extends [infer R, ...infer Rest] - ? HasFKey extends true - ? true - : HasFKey - : false - -/** - * Returns a boolean representing whether there the foreign key has a unique constraint. - */ -type HasUniqueFKey = Relationships extends [infer R] - ? R extends { foreignKeyName: FKeyName; isOneToOne: true } - ? true - : false - : Relationships extends [infer R, ...infer Rest] - ? HasUniqueFKey extends true - ? true - : HasUniqueFKey - : 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 - -type HasUniqueFKeyToFRel = Relationships extends [infer R] - ? R extends { referencedRelation: FRelName; isOneToOne: true } - ? true - : false - : Relationships extends [infer R, ...infer Rest] - ? HasUniqueFKeyToFRel extends true - ? true - : HasUniqueFKeyToFRel - : false - -/** - * Constructs a type definition for a single field of an object. - * - * @param Schema Database schema. - * @param Row Type of a row in the given table. - * @param Relationships Relationships between different tables in the database. - * @param Field Single field parsed by `ParseQuery`. - */ -type ConstructFieldDefinition< - Schema extends GenericSchema, - Row extends Record, - RelationName, - Relationships, - Field -> = Field extends { star: true } - ? Row - : Field extends { spread: true; original: string; children: unknown[] } - ? GetResultHelper< - Schema, - (Schema['Tables'] & Schema['Views'])[Field['original']]['Row'], - Field['original'], - (Schema['Tables'] & Schema['Views'])[Field['original']] extends { Relationships: infer R } - ? R - : unknown, - Field['children'], - unknown - > - : Field extends { children: [] } - ? {} - : Field extends { name: string; original: string; hint: string; children: unknown[] } - ? { - [_ in Field['name']]: GetResultHelper< - Schema, - (Schema['Tables'] & Schema['Views'])[Field['original']]['Row'], - Field['original'], - (Schema['Tables'] & Schema['Views'])[Field['original']] extends { Relationships: infer R } - ? R - : unknown, - Field['children'], - unknown - > extends infer Child - ? // One-to-one relationship - referencing column(s) has unique/pkey constraint. - HasUniqueFKey< - Field['hint'], - (Schema['Tables'] & Schema['Views'])[Field['original']] extends { - Relationships: infer R - } - ? R - : unknown - > extends true - ? Field extends { inner: true } - ? Child - : Child | null - : Relationships extends unknown[] - ? HasFKey extends true - ? Field extends { inner: true } - ? Child - : Child | null - : Child[] - : Child[] - : never - } - : Field extends { name: string; original: string; children: unknown[] } - ? { - [_ in Field['name']]: GetResultHelper< - Schema, - (Schema['Tables'] & Schema['Views'])[Field['original']]['Row'], - Field['original'], - (Schema['Tables'] & Schema['Views'])[Field['original']] extends { Relationships: infer R } - ? R - : unknown, - Field['children'], - unknown - > extends infer Child - ? // One-to-one relationship - referencing column(s) has unique/pkey constraint. - HasUniqueFKeyToFRel< - RelationName, - (Schema['Tables'] & Schema['Views'])[Field['original']] extends { - Relationships: infer R - } - ? R - : unknown - > extends true - ? Field extends { inner: true } - ? Child - : Child | null - : Relationships extends unknown[] - ? HasFKeyToFRel extends true - ? Field extends { inner: true } - ? Child - : Field extends { left: true } - ? // TODO: This should return null only if the column is actually nullable - Child | null - : Child | null - : Child[] - : Child[] - : never - } - : Field extends { name: string; type: infer T } - ? { [K in Field['name']]: T } - : Field extends { name: string; original: string } - ? Field['original'] extends keyof Row - ? { [K in Field['name']]: Row[Field['original']] } - : Field['original'] extends 'count' - ? { count: number } - : SelectQueryError<`Referencing missing column \`${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 1 or more 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, ''] - -/** - * Reads a consecutive sequence of 1 or more double-quoted letters, - * where letters are `[^"]`. - */ -type ReadQuotedLetters = string extends Input - ? GenericStringError - : Input extends `"${infer Remainder}` - ? ReadQuotedLettersHelper extends [`${infer Letters}`, `${infer Remainder}`] - ? Letters extends '' - ? ParserError<`Expected string at \`${Remainder}\``> - : [Letters, Remainder] - : ReadQuotedLettersHelper - : ParserError<`Not a double-quoted string at \`${Input}\``> - -type ReadQuotedLettersHelper = string extends Input - ? GenericStringError - : Input extends `${infer L}${infer Remainder}` - ? L extends '"' - ? [Acc, Remainder] - : ReadQuotedLettersHelper - : ParserError<`Missing closing double-quote in \`"${Acc}${Input}\``> - -/** - * Parses a (possibly double-quoted) identifier. - * Identifiers are sequences of 1 or more letters. - */ -type ParseIdentifier = ReadLetters extends [ - infer Name, - `${infer Remainder}` -] - ? [Name, `${Remainder}`] - : ReadQuotedLetters extends [infer Name, `${infer Remainder}`] - ? [Name, `${Remainder}`] - : ParserError<`No (possibly double-quoted) identifier at \`${Input}\``> - -/** - * Parses a field without preceding field renaming. - * A field is one of the following: - * - a field with an embedded resource - * - `field(nodes)` - * - `field!hint(nodes)` - * - `field!inner(nodes)` - * - `field!left(nodes)` - * - `field!hint!inner(nodes)` - * - a field without an embedded resource (see {@link ParseFieldWithoutEmbeddedResource}) - */ -type ParseField = Input extends '' - ? ParserError<'Empty string'> - : ParseIdentifier extends [infer Name, `${infer Remainder}`] - ? EatWhitespace extends `!inner${infer Remainder}` - ? ParseEmbeddedResource> extends [infer Fields, `${infer Remainder}`] - ? // `field!inner(nodes)` - [{ name: Name; original: Name; children: Fields; inner: true }, EatWhitespace] - : CreateParserErrorIfRequired< - ParseEmbeddedResource>, - 'Expected embedded resource after `!inner`' - > - : EatWhitespace extends `!left${infer Remainder}` - ? ParseEmbeddedResource> extends [infer Fields, `${infer Remainder}`] - ? // `field!left(nodes)` - [{ name: Name; original: Name; children: Fields; left: true }, EatWhitespace] - : CreateParserErrorIfRequired< - ParseEmbeddedResource>, - 'Expected embedded resource after `!left`' - > - : 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; original: Name; hint: Hint; children: Fields; inner: true }, - EatWhitespace - ] - : CreateParserErrorIfRequired< - ParseEmbeddedResource>, - 'Expected embedded resource after `!inner`' - > - : ParseEmbeddedResource> extends [ - infer Fields, - `${infer Remainder}` - ] - ? // `field!hint(nodes)` - [{ name: Name; original: Name; hint: Hint; children: Fields }, EatWhitespace] - : CreateParserErrorIfRequired< - ParseEmbeddedResource>, - 'Expected embedded resource after `!hint`' - > - : ParserError<'Expected identifier after `!`'> - : ParseEmbeddedResource> extends [infer Fields, `${infer Remainder}`] - ? // `field(nodes)` - [{ name: Name; original: Name; children: Fields }, EatWhitespace] - : ParseEmbeddedResource> extends ParserError - ? // Return error if start of embedded resource was detected but not found. - ParseEmbeddedResource> - : // Otherwise try to match a field without embedded resource. - ParseFieldWithoutEmbeddedResource - : ParserError<`Expected identifier 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 ParseFieldWithoutEmbeddedResource = - ParseFieldWithoutEmbeddedResourceAndAggregation extends [infer Field, `${infer Remainder}`] - ? ParseFieldAggregation> extends [ - `${infer AggregateFunction}`, - `${infer Remainder}` - ] - ? ParseFieldTypeCast> extends [infer Type, `${infer Remainder}`] - ? // `field.aggregate()::type` - [ - Omit & { - name: AggregateFunction - original: AggregateFunction - type: Type - }, - EatWhitespace - ] - : ParseFieldTypeCast> extends ParserError - ? ParseFieldTypeCast> - : // `field.aggregate()` - [ - Omit & { - name: AggregateFunction - original: AggregateFunction - }, - EatWhitespace - ] - : ParseFieldAggregation> extends ParserError - ? ParseFieldAggregation> - : // `field` - [Field, EatWhitespace] - : CreateParserErrorIfRequired< - ParseFieldWithoutEmbeddedResourceAndAggregation, - `Expected field at \`${Input}\`` - > - -/** - * Parses a field excluding embedded resources or aggregation, without preceding field renaming. - * This is one of the following: - * - `field` - * - `field::type` - * - `field->json...` - * - `field->json...::type` - */ -type ParseFieldWithoutEmbeddedResourceAndAggregation = - ParseFieldWithoutEmbeddedResourceAndTypeCast extends [infer Field, `${infer Remainder}`] - ? ParseFieldTypeCast> extends [infer Type, `${infer Remainder}`] - ? // `field::type` or `field->json...::type` - [Omit & { type: Type }, EatWhitespace] - : ParseFieldTypeCast> extends ParserError - ? ParseFieldTypeCast> - : // `field` or `field->json...` - [Field, EatWhitespace] - : CreateParserErrorIfRequired< - ParseFieldWithoutEmbeddedResourceAndTypeCast, - `Expected field at \`${Input}\`` - > - -/** - * Parses a field excluding embedded resources or typecasting, without preceding field renaming. - * This is one of the following: - * - `field` - * - `field->json...` - */ -type ParseFieldWithoutEmbeddedResourceAndTypeCast = - ParseIdentifier extends [infer Name, `${infer Remainder}`] - ? ParseJsonAccessor> extends [ - infer PropertyName, - infer PropertyType, - `${infer Remainder}` - ] - ? // `field->json...` - [ - { name: PropertyName; original: PropertyName; type: PropertyType }, - EatWhitespace - ] - : // `field` - [{ name: Name; original: Name }, EatWhitespace] - : ParserError<`Expected field at \`${Input}\``> - -/** - * Parses a field typecast (`::type`), returning a tuple of ["Type", "Remainder of text"] - * or the original string input indicating that no typecast was found. - */ -type ParseFieldTypeCast = EatWhitespace extends `::${infer Remainder}` - ? ParseIdentifier> extends [`${infer CastType}`, `${infer Remainder}`] - ? // Ensure that `CastType` is a valid type. - CastType extends PostgreSQLTypes - ? [TypeScriptTypes, EatWhitespace] - : ParserError<`Invalid type for \`::\` operator \`${CastType}\``> - : ParserError<`Invalid type for \`::\` operator at \`${Remainder}\``> - : Input - -/** - * Parses a field aggregation (`.max()`), returning a tuple of ["Aggregate function", "Remainder of text"] - * or the original string input indicating that no aggregation was found. - */ -type ParseFieldAggregation = - EatWhitespace extends `.${infer Remainder}` - ? ParseIdentifier> extends [ - `${infer FunctionName}`, - `${infer Remainder}` - ] - ? // Ensure that aggregation function is valid. - FunctionName extends AggregateFunctions - ? EatWhitespace extends `()${infer Remainder}` - ? [FunctionName, EatWhitespace] - : ParserError<`Expected \`()\` after \`.\` operator \`${FunctionName}\``> - : ParserError<`Invalid type for \`.\` operator \`${FunctionName}\``> - : ParserError<`Invalid type for \`.\` operator at \`${Remainder}\``> - : Input - -/** - * 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}` - ? [{ star: true }, EatWhitespace] - : // `...field` - Input extends `...${infer Remainder}` - ? ParseField> extends [infer Field, `${infer Remainder}`] - ? Field extends { children: unknown[] } - ? [Prettify<{ spread: true } & Field>, EatWhitespace] - : ParserError<'Unable to parse spread resource'> - : ParserError<'Unable to parse spread resource'> - : ParseIdentifier extends [infer Name, `${infer Remainder}`] - ? EatWhitespace extends `::${infer _Remainder}` - ? // `field::` - // Special case to detect type-casting before renaming. - ParseField - : EatWhitespace extends `:${infer Remainder}` - ? // `renamed_field:` - ParseField> extends [infer Field, `${infer Remainder}`] - ? Field extends { name: string } - ? [Prettify & { name: Name }>, EatWhitespace] - : ParserError<`Unable to parse renamed field`> - : ParserError<`Unable to parse renamed field`> - : // Otherwise, just parse it as a field without renaming. - ParseField - : 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"] - * or the original string input indicating that no opening `->` was found. - */ -type ParseJsonAccessor = Input extends `->${infer Remainder}` - ? Remainder extends `>${infer Remainder}` - ? ParseIdentifier extends [infer Name, `${infer Remainder}`] - ? [Name, string, 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 `->`'> - : 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}` - ? ParseNodes> extends [infer Fields, `${infer Remainder}`] - ? EatWhitespace extends `)${infer Remainder}` - ? [Fields, EatWhitespace] - : ParserError<`Expected ")"`> - : // If no nodes were detected, check for `)` for empty embedded resources `()`. - ParseNodes> extends ParserError - ? EatWhitespace extends `)${infer Remainder}` - ? [[], EatWhitespace] - : ParseNodes> - : ParserError<'Expected embedded resource fields or `)`'> - : 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< - Schema extends GenericSchema, - Row extends Record, - RelationName, - Relationships, - Fields extends unknown[], - Acc -> = Fields extends [infer R] - ? ConstructFieldDefinition extends SelectQueryError< - infer E - > - ? SelectQueryError - : GetResultHelper< - Schema, - Row, - RelationName, - Relationships, - [], - ConstructFieldDefinition & Acc - > - : Fields extends [infer R, ...infer Rest] - ? ConstructFieldDefinition extends SelectQueryError< - infer E - > - ? SelectQueryError - : GetResultHelper< - Schema, - Row, - RelationName, - Relationships, - Rest, - ConstructFieldDefinition & Acc - > - : Prettify - -/** - * Constructs a type definition for an object based on a given PostgREST query. - * - * @param Schema Database schema. - * @param Row Type of a row in the given table. - * @param Relationships Relationships between different tables in the database. - * @param Query Select query string literal to parse. - */ -export type GetResult< - Schema extends GenericSchema, - Row extends Record, - RelationName, - Relationships, - Query extends string -> = ParseQuery extends unknown[] - ? GetResultHelper, unknown> - : ParseQuery diff --git a/src/select-query-parser/parser/ast.ts b/src/select-query-parser/parser/ast.ts new file mode 100644 index 00000000..9633a2cd --- /dev/null +++ b/src/select-query-parser/parser/ast.ts @@ -0,0 +1,29 @@ +import { AggregateFunctions, PostgreSQLTypes } from '../types' + +export interface IdentifierNode { + type: 'Identifier' + name: string +} + +export interface FieldNode { + type: 'Field' + name: string + alias?: string + hint?: unknown + inner?: boolean + left?: boolean + children?: unknown + aggregateFunction?: AggregateFunctions + castType?: PostgreSQLTypes +} + +export interface StarNode { + type: 'Star' +} + +export interface SpreadNode { + type: 'Spread' + target: FieldNode +} + +export type Node = IdentifierNode | FieldNode | StarNode | SpreadNode diff --git a/src/select-query-parser/parser/parser.ts b/src/select-query-parser/parser/parser.ts new file mode 100644 index 00000000..905806d9 --- /dev/null +++ b/src/select-query-parser/parser/parser.ts @@ -0,0 +1,506 @@ +import type { FieldNode, IdentifierNode, Node, SpreadNode, StarNode } from './ast' +import type { AggregateFunctions, AggregateWithoutColumnFunctions, PostgreSQLTypes } from '../types' +import type { + CreateParserErrorIfRequired, + EatWhitespace, + GenericStringError, + ParserError, + ReadLetters, + ReadQuotedLetters, +} from './utils' + +/** + * Parses a (possibly double-quoted) identifier. + * Identifiers are sequences of 1 or more letters. + */ +type ParseIdentifier = ReadLetters extends [ + infer Name extends string, + `${infer Remainder}` +] + ? [{ type: 'Identifier'; name: Name }, `${Remainder}`] + : ReadQuotedLetters extends [infer Name extends string, `${infer Remainder}`] + ? [{ type: 'Identifier'; name: Name }, `${Remainder}`] + : ParserError<`No (possibly double-quoted) identifier at \`${Input}\``> + +/** + * Parses a field without preceding field renaming. + * A field is one of the following: + * - a field with an embedded resource + * - `field(nodes)` + * - `field!hint(nodes)` + * - `field!inner(nodes)` + * - `field!left(nodes)` + * - `field!hint!inner(nodes)` + * - a field without an embedded resource (see {@link ParseFieldWithoutEmbeddedResource}) + */ +type ParseField = Input extends '' + ? ParserError<'Empty string'> + : ParseIdentifier extends [infer IdNode extends IdentifierNode, `${infer Remainder}`] + ? EatWhitespace extends `!inner${infer Rest}` + ? ParseEmbeddedResource> extends [ + infer Children extends Node[], + `${infer Remainder}` + ] + ? [ + FieldNode & { + type: 'Field' + name: IdNode['name'] + inner: true + children: Children + }, + EatWhitespace + ] + : CreateParserErrorIfRequired< + ParseEmbeddedResource>, + 'Expected embedded resource after `!inner`' + > + : EatWhitespace extends `!left${infer Rest}` + ? ParseEmbeddedResource> extends [ + infer Children extends Node[], + `${infer Remainder}` + ] + ? [ + FieldNode & { + type: 'Field' + name: IdNode['name'] + left: true + children: Children + }, + EatWhitespace + ] + : CreateParserErrorIfRequired< + ParseEmbeddedResource>, + 'Expected embedded resource after `!left`' + > + : EatWhitespace extends `!${infer Rest}` + ? ParseIdentifier> extends [ + infer HintIdNode extends IdentifierNode, + `${infer Remainder}` + ] + ? EatWhitespace extends `!inner${infer InnerRest}` + ? ParseEmbeddedResource> extends [ + infer Children extends Node[], + `${infer Remainder}` + ] + ? [ + FieldNode & { + type: 'Field' + name: IdNode['name'] + hint: HintIdNode['name'] + inner: true + children: Children + }, + EatWhitespace + ] + : CreateParserErrorIfRequired< + ParseEmbeddedResource>, + 'Expected embedded resource after `!inner`' + > + : ParseEmbeddedResource> extends [ + infer Children extends Node[], + `${infer Remainder}` + ] + ? [ + FieldNode & { + type: 'Field' + name: IdNode['name'] + hint: HintIdNode['name'] + children: Children + }, + EatWhitespace + ] + : CreateParserErrorIfRequired< + ParseEmbeddedResource>, + 'Expected embedded resource after `!hint`' + > + : ParserError<`Expected identifier after '!' at ${Rest}`> + : ParseEmbeddedResource> extends [ + infer Children extends Node[], + `${infer Remainder}` + ] + ? [ + FieldNode & { + type: 'Field' + name: IdNode['name'] + children: Children + }, + EatWhitespace + ] + : ParseEmbeddedResource> extends ParserError + ? // Return error if start of embedded resource was detected but not found. + ParseEmbeddedResource> + : // Otherwise try to match a field without embedded resource. + ParseFieldWithoutEmbeddedResource + : ParserError<`Expected identifier 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 ParseFieldWithoutEmbeddedResource = + ParseFieldWithoutEmbeddedResourceAndAggregation extends [ + infer Field extends FieldNode, + `${infer Remainder}` + ] + ? ParseFieldAggregation, false> extends [ + infer AggregateFunction extends AggregateFunctions, + `${infer Remainder}` + ] + ? [ + FieldNode & { + type: 'Field' + name: AggregateFunction + aggregateFunction: AggregateFunction + }, + EatWhitespace + ] + : ParseFieldAggregation, true> extends [ + infer AggregateFunction extends AggregateFunctions, + `${infer Remainder}` + ] + ? ParseFieldTypeCast> extends [ + infer CastType extends PostgreSQLTypes, + `${infer Remainder}` + ] + ? [ + FieldNode & { + type: 'Field' + name: Field['name'] + alias?: Field['alias'] + hint?: Field['hint'] + inner?: Field['inner'] + left?: Field['left'] + children?: Field['children'] + aggregateFunction: AggregateFunction + castType: CastType + }, + EatWhitespace + ] + : ParseFieldTypeCast> extends ParserError + ? ParserError + : [ + FieldNode & { + type: 'Field' + name: Field['name'] + alias?: Field['alias'] + hint?: Field['hint'] + inner?: Field['inner'] + left?: Field['left'] + children?: Field['children'] + aggregateFunction: AggregateFunction + }, + EatWhitespace + ] + : ParseFieldAggregation, true> extends ParserError + ? ParserError + : [Field, EatWhitespace] + : CreateParserErrorIfRequired< + ParseFieldWithoutEmbeddedResourceAndAggregation, + `Expected field at \`${Input}\`` + > + +/** + * Parses a field excluding embedded resources or aggregation, without preceding field renaming. + * This is one of the following: + * - `field` + * - `field::type` + * - `field->json...` + * - `field->json...::type` + */ +type ParseFieldWithoutEmbeddedResourceAndAggregation = + ParseFieldWithoutEmbeddedResourceAndTypeCast extends [ + infer Field extends FieldNode, + `${infer Remainder}` + ] + ? ParseFieldTypeCast> extends [ + infer CastType extends PostgreSQLTypes, + `${infer Remainder}` + ] + ? [ + FieldNode & { + type: 'Field' + name: Field['name'] + alias?: Field['alias'] + hint?: Field['hint'] + inner?: Field['inner'] + left?: Field['left'] + children?: Field['children'] + castType: CastType + }, + EatWhitespace + ] + : ParseFieldTypeCast> extends ParserError + ? ParseFieldTypeCast> + : [Field, EatWhitespace] + : CreateParserErrorIfRequired< + ParseFieldWithoutEmbeddedResourceAndTypeCast, + `Expected field at \`${Input}\`` + > + +/** + * Parses a field excluding embedded resources or typecasting, without preceding field renaming. + * This is one of the following: + * - `field` + * - `field->json...` + */ +type ParseFieldWithoutEmbeddedResourceAndTypeCast = + ParseIdentifier extends [infer IdNode extends IdentifierNode, `${infer Remainder}`] + ? ParseJsonAccessor> extends [ + infer JsonFieldName extends string, + infer JsonFieldType, + `${infer Remainder}` + ] + ? [ + FieldNode & { + type: 'Field' + name: IdNode['name'] + alias: JsonFieldName + castType: JsonFieldType + }, + EatWhitespace + ] + : [ + FieldNode & { + type: 'Field' + name: IdNode['name'] + }, + EatWhitespace + ] + : ParserError<`Expected field at \`${Input}\``> + +/** + * Parses a field typecast (`::type`), returning a tuple of [CastType, Remainder] + * or the original string input indicating that no typecast was found. + */ +type ParseFieldTypeCast = EatWhitespace extends `::${infer Remainder}` + ? ParseIdentifier> extends [ + infer TypeIdNode extends IdentifierNode, + `${infer Remainder}` + ] + ? // Ensure that `CastType` is a valid PostgreSQL type. + TypeIdNode['name'] extends PostgreSQLTypes + ? [TypeIdNode['name'], EatWhitespace] + : // We will never enter those conditions as PostgresSQLTypes have string in the union + // that will match anything for custom types handling + // TODO: extract the custom_types from the database and check that the + // cast is actually a valid type + ParserError<`Invalid type for \`::\` operator \`${TypeIdNode['name']}\``> + : ParserError<`Invalid type for \`::\` operator at \`${Remainder}\``> + : Input + +/** + * Parses a field aggregation (`.max()`), returning a tuple of [AggregateFunction, Remainder] + * or the original string input indicating that no aggregation was found. + */ +type ParseFieldAggregation< + Input extends string, + IsField extends boolean = false +> = IsField extends true + ? EatWhitespace extends `.${infer Remainder}` + ? ParseIdentifier> extends [ + infer FuncIdNode extends IdentifierNode, + `${infer Remainder}` + ] + ? FuncIdNode['name'] extends AggregateFunctions + ? EatWhitespace extends `()${infer Remainder}` + ? [FuncIdNode['name'], EatWhitespace] + : ParserError<`Expected \`()\` after \`.\` operator \`${FuncIdNode['name']}\``> + : ParserError<`Invalid function for \`.\` operator \`${FuncIdNode['name']}\``> + : ParserError<`Invalid function for \`.\` operator at \`${Remainder}\``> + : Input + : // Check if the function is just count or count() + ParseIdentifier extends [infer FuncIdNode extends IdentifierNode, `${infer Remainder}`] + ? FuncIdNode['name'] extends AggregateWithoutColumnFunctions + ? EatWhitespace extends `()${infer Remainder}` + ? [FuncIdNode['name'], EatWhitespace] + : [FuncIdNode['name'], EatWhitespace] + : Input + : Input + +/** + * Parses a node. + * A node is one of the following: + * - `*` + * - a field, as defined above + * - a renamed field, `alias:field` + * - a spread field, `...field` + */ +type ParseNode = Input extends '' + ? ParserError<'Empty string'> + : Input extends `*${infer Remainder}` + ? [ + StarNode & { + type: 'Star' + }, + EatWhitespace + ] + : Input extends `...${infer Rest}` + ? ParseField> extends [ + infer TargetField extends FieldNode, + `${infer Remainder}` + ] + ? [ + SpreadNode & { + type: 'Spread' + target: TargetField + }, + EatWhitespace + ] + : ParserError<`Unable to parse spread resource at ${NodesInput}`> + : ParseIdentifier extends [infer AliasIdNode extends IdentifierNode, `${infer Remainder}`] + ? EatWhitespace extends `::${infer _Rest}` + ? // If we find '::', it's a type cast, so treat it as part of the field + ParseField + : EatWhitespace extends `:${infer Rest}` + ? // This is for the case where the aggregate function is count since it can be + // called at top level withtout any mention of a column we need to repeat it to + // preserve the aggregateFunction litteral + ParseFieldAggregation extends [ + infer AggregateFunction extends AggregateFunctions, + `${infer Remainder}` + ] + ? [ + { + type: 'Field' + name: AggregateFunction + alias: AliasIdNode['name'] + aggregateFunction: AggregateFunction + }, + EatWhitespace + ] + : ParseField> extends [ + infer Field extends FieldNode, + `${infer Remainder}` + ] + ? [ + FieldNode & { + type: 'Field' + name: Field['name'] + alias: AliasIdNode['name'] + hint?: Field['hint'] + inner?: Field['inner'] + left?: Field['left'] + children?: Field['children'] + castType?: Field['castType'] + aggregateFunction?: Field['aggregateFunction'] + }, + EatWhitespace + ] + : ParserError<`Unable to parse renamed field at ${NodesInput}`> + : // This is for the case where the aggregate function is count since it can be + // called at top level withtout any mention of a column + ParseFieldAggregation extends [ + infer AggregateFunction extends AggregateFunctions, + `${infer Remainder}` + ] + ? [ + { + type: 'Field' + name: AggregateFunction + aggregateFunction: AggregateFunction + }, + EatWhitespace + ] + : ParseField + : ParserError<`Expected identifier at \`${NodesInput}\``> + +/** + * 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 [PropertyName, PropertyType, Remainder] + * or the original string input indicating that no opening `->` was found. + */ +type ParseJsonAccessor = EatWhitespace extends `->${infer Remainder}` + ? EatWhitespace extends `>${infer Rest}` + ? ParseIdentifier> extends [ + infer NameIdNode extends IdentifierNode, + `${infer Remainder}` + ] + ? // In the case of a ->> the result will be casted as text by default + [NameIdNode['name'], 'text', EatWhitespace] + : ParserError<`Expected property name after '->>'${Rest}`> + : ParseIdentifier> extends [ + infer NameIdNode extends IdentifierNode, + `${infer Remainder}` + ] + ? ParseJsonAccessor extends [ + infer PropertyName extends string, + infer PropertyType, + `${infer Remainder}` + ] + ? [PropertyName, PropertyType, EatWhitespace] + : // With a -> accessor result will be casted as Json type + [NameIdNode['name'], 'json', EatWhitespace] + : ParserError<`Expected property name after '->' at ${Remainder}`> + : 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 [Fields, Remainder], an error, + * or the original string input indicating that no opening `(` was found. + */ +type ParseEmbeddedResource = + EatWhitespace extends `(${infer Remainder}` + ? ParseNodes> extends [ + infer Nodes extends Node[], + `${infer Remainder}` + ] + ? EatWhitespace extends `)${infer Remainder}` + ? [Nodes, EatWhitespace] + : ParserError<`Expected ')' at ${Remainder}`> + : // If no nodes were detected, check for `)` for empty embedded resources `()`. + ParseNodes> extends ParserError + ? EatWhitespace extends `)${infer Remainder}` + ? [[], EatWhitespace] + : ParseNodes> + : ParserError<`Expected embedded resource fields or ')' at ${Remainder}`> + : Input + +/** + * Parses a sequence of nodes, separated by `,`. + * + * Returns a tuple of [Nodes, Remainder] or an error. + */ +type ParseNodes = string extends Input + ? GenericStringError + : ParseNodesHelper + +type ParseNodesHelper< + Input extends string, + Nodes extends Node[], + NodesInput extends string +> = ParseNode extends [infer NodeResult extends Node, `${infer Remainder}`] + ? EatWhitespace extends `,${infer Rest}` + ? ParseNodesHelper, [...Nodes, NodeResult], NodesInput> + : [[...Nodes, NodeResult], 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. + */ +export type ParseQuery = string extends Query + ? GenericStringError + : ParseNodes> extends [infer Nodes extends Node[], `${infer Remainder}`] + ? EatWhitespace extends '' + ? Nodes + : ParserError<`Unexpected input: ${Remainder}`> + : ParseNodes> diff --git a/src/select-query-parser/parser/utils.ts b/src/select-query-parser/parser/utils.ts new file mode 100644 index 00000000..619f97b0 --- /dev/null +++ b/src/select-query-parser/parser/utils.ts @@ -0,0 +1,103 @@ +// Some utils type for the ParseQuery parser logic +// Count is a special case where an aggregate function won't need a column to be run against +// see: https://postgrest.org/en/v12/references/api/aggregate_functions.html#the-case-of-count + +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 | '_' + +/** + * Reads a consecutive sequence of 1 or more letters, where letters are `[0-9a-zA-Z_]`. + */ +export 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, ''] + +/** + * Reads a consecutive sequence of 1 or more double-quoted letters, + * where letters are `[^"]`. + */ +export type ReadQuotedLetters = string extends Input + ? GenericStringError + : Input extends `"${infer Remainder}` + ? ReadQuotedLettersHelper extends [`${infer Letters}`, `${infer Remainder}`] + ? Letters extends '' + ? ParserError<`Expected string at \`${Remainder}\``> + : [Letters, Remainder] + : ReadQuotedLettersHelper + : ParserError<`Not a double-quoted string at \`${Input}\``> + +type ReadQuotedLettersHelper = string extends Input + ? GenericStringError + : Input extends `${infer L}${infer Remainder}` + ? L extends '"' + ? [Acc, Remainder] + : ReadQuotedLettersHelper + : ParserError<`Missing closing double-quote in \`"${Acc}${Input}\``> + +/** + * Parser errors. + */ +export type ParserError = { error: true } & Message +export type GenericStringError = ParserError<'Received a generic string'> + +/** + * Creates a new {@link ParserError} if the given input is not already a parser error. + */ +export type CreateParserErrorIfRequired< + Input, + Message extends string +> = Input extends ParserError ? Input : ParserError + +type Whitespace = ' ' | '\n' | '\t' + +/** + * Trims whitespace from the left of the input. + */ +export type EatWhitespace = string extends Input + ? GenericStringError + : Input extends `${Whitespace}${infer Remainder}` + ? EatWhitespace + : Input diff --git a/src/select-query-parser/result.ts b/src/select-query-parser/result.ts new file mode 100644 index 00000000..e2aa1ce7 --- /dev/null +++ b/src/select-query-parser/result.ts @@ -0,0 +1,249 @@ +import { GenericTable } from '../types' +import { ContainsNull, GenericRelationship, PostgreSQLTypes } from './types' +import { FieldNode, Node, SpreadNode, StarNode } from './parser/ast' +import { ParseQuery } from './parser/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 +> = ParseQuery extends infer ParsedQuery + ? ParsedQuery extends Node[] + ? RelationName extends string + ? Relationships extends GenericRelationship[] + ? ProcessNodes + : SelectQueryError<'Invalid Relationships cannot infer result type'> + : SelectQueryError<'Invalid RelationName cannot infer restult type'> + : ParsedQuery + : never + +/** + * 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 Node[], + Acc extends Record = {} // Acc is now an object +> = CheckDuplicateEmbededReference extends false + ? Nodes extends [infer FirstNode extends Node, ...infer RestNodes extends 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 Node +> = NodeType extends StarNode // If the selection is * + ? Row + : NodeType extends SpreadNode // If the selection is a ...spread + ? ProcessSpreadNode + : NodeType extends 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. + */ +export type ProcessFieldNode< + Schema extends GenericSchema, + Row extends Record, + RelationName extends string, + Relationships extends GenericRelationship[], + Field extends 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. + */ +export type ProcessSimpleField< + Row extends Record, + RelationName extends string, + Field extends FieldNode +> = 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 + } + : [Field['name']] extends [keyof Row] + ? { + // 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 FieldNode, + CurrentTableOrView extends keyof TablesAndViews +> = ResolveRelationship extends infer Resolved + ? Resolved extends { + referencedTable: GenericTable + relation: GenericRelationship + direction: string + } + ? ProcessEmbeddedResourceResult + : { [K in GetFieldNodeResultName]: Resolved & string } + : { + [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: GenericTable + relation: GenericRelationship + direction: string + }, + Field extends FieldNode, + CurrentTableOrView extends keyof TablesAndViews +> = ProcessNodes< + Schema, + Resolved['referencedTable']['Row'], + Field['name'], + Resolved['referencedTable']['Relationships'], + Field['children'] extends undefined + ? [] + : Exclude extends Node[] + ? Exclude + : [] +> extends infer ProcessedChildren + ? { + [K in GetFieldNodeResultName]: Resolved['direction'] extends 'forward' + ? Field extends { inner: true } + ? ProcessedChildren + : Resolved['relation']['isOneToOne'] extends true + ? ProcessedChildren | null + : ProcessedChildren[] + : 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. + */ +export type ProcessSpreadNode< + Schema extends GenericSchema, + Row extends Record, + RelationName extends string, + Relationships extends GenericRelationship[], + Spread extends 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..7618450e --- /dev/null +++ b/src/select-query-parser/utils.ts @@ -0,0 +1,433 @@ +import { FieldNode, Node, SpreadNode } from './parser/ast' +import { + AggregateFunctions, + ContainsNull, + GenericRelationship, + GenericSchema, + GenericTable, + IsNonEmptyArray, + TablesAndViews, + UnionToArray, +} from './types' + +export type SelectQueryError = { error: true } & Message + +export type ProcessedNodeResult = Record | SelectQueryError + +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 SpreadNode + ? Nodes[K]['target'] + : Nodes[K] extends FieldNode + ? IsNonEmptyArray extends true + ? Nodes[K] + : never + : never + }[number] +> + +type ResolveRelationships< + Schema extends GenericSchema, + RelationName extends string, + Relationships extends GenericRelationship[], + Nodes extends 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 Node[] +> = FilterRelationNodes extends infer RelationsNodes extends 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 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 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 + +// Utility type to find embeded relationships by all their possibles references +export type FindMatchingRelationships< + value extends string, + Relationships extends GenericRelationship[] +> = Relationships extends [infer R, ...infer Rest extends GenericRelationship[]] + ? R extends { foreignKeyName: value } + ? R + : R extends { referencedRelation: value } + ? R + : R extends { columns: [value] } + ? R + : FindMatchingRelationships + : 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 + +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 FieldNode, + CurrentTableOrView extends keyof TablesAndViews +> = FindFieldMatchingRelationships< + Schema, + TablesAndViews[Field['name']]['Relationships'], + 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 FieldNode +> = Field extends { hint?: infer Hint extends string } + ? FindMatchingTableRelationships< + Schema, + Relationships, + Hint + > extends infer TableRelationViaHint extends GenericRelationship + ? TableRelationViaHint & { + branch: 'found-in-table-via-hint' + hint: Field['hint'] + } + : FindMatchingViewRelationships< + Schema, + Relationships, + Hint + > 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 5379b271..704d306d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -39,20 +39,31 @@ export type PostgrestSingleResponse = PostgrestResponseSuccess | Postgrest 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 diff --git a/test/basic.ts b/test/basic.ts index 6b46d50f..a064b107 100644 --- a/test/basic.ts +++ b/test/basic.ts @@ -7,73 +7,91 @@ const postgrest = new PostgrestClient(REST_URL) test('basic select table', async () => { const res = await postgrest.from('users').select() expect(res).toMatchInlineSnapshot(` +Object { + "count": null, + "data": Array [ 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", + "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", }, - ], - "error": null, - "status": 200, - "statusText": "OK", - } - `) + }, + "status": "ONLINE", + "username": "jsonuser", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", +} +`) }) test('basic select view', async () => { const res = await postgrest.from('updatable_view').select() expect(res).toMatchInlineSnapshot(` +Object { + "count": null, + "data": Array [ Object { - "count": null, - "data": Array [ - Object { - "non_updatable_column": 1, - "username": "supabot", - }, - Object { - "non_updatable_column": 1, - "username": "kiwicopple", - }, - Object { - "non_updatable_column": 1, - "username": "awailas", - }, - Object { - "non_updatable_column": 1, - "username": "dragarcia", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", - } - `) + "non_updatable_column": 1, + "username": "supabot", + }, + Object { + "non_updatable_column": 1, + "username": "kiwicopple", + }, + Object { + "non_updatable_column": 1, + "username": "awailas", + }, + Object { + "non_updatable_column": 1, + "username": "dragarcia", + }, + Object { + "non_updatable_column": 1, + "username": "jsonuser", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", +} +`) }) test('rpc', async () => { @@ -268,8 +286,8 @@ test('on_conflict insert', async () => { }, ], "error": null, - "status": 201, - "statusText": "Created", + "status": 200, + "statusText": "OK", } `) }) @@ -303,7 +321,7 @@ describe('basic insert, update, delete', () => { Object { "channel_id": 1, "data": null, - "id": 3, + "id": 5, "message": "foo", "username": "supabot", }, @@ -334,9 +352,23 @@ describe('basic insert, update, delete', () => { "username": "supabot", }, Object { - "channel_id": 1, + "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", }, @@ -366,8 +398,8 @@ describe('basic insert, update, delete', () => { }, ], "error": null, - "status": 201, - "statusText": "Created", + "status": 200, + "statusText": "OK", } `) @@ -390,6 +422,20 @@ describe('basic insert, update, delete', () => { "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, @@ -420,14 +466,14 @@ describe('basic insert, update, delete', () => { Object { "channel_id": 1, "data": null, - "id": 4, + "id": 6, "message": "foo", "username": "supabot", }, Object { "channel_id": 1, "data": null, - "id": 5, + "id": 7, "message": "foo", "username": "supabot", }, @@ -457,6 +503,20 @@ describe('basic insert, update, delete', () => { "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, @@ -467,14 +527,14 @@ describe('basic insert, update, delete', () => { Object { "channel_id": 1, "data": null, - "id": 4, + "id": 6, "message": "foo", "username": "supabot", }, Object { "channel_id": 1, "data": null, - "id": 5, + "id": 7, "message": "foo", "username": "supabot", }, @@ -496,6 +556,13 @@ describe('basic insert, update, delete', () => { Object { "count": null, "data": Array [ + Object { + "channel_id": 2, + "data": null, + "id": 5, + "message": "foo", + "username": "supabot", + }, Object { "channel_id": 2, "data": null, @@ -506,14 +573,14 @@ describe('basic insert, update, delete', () => { Object { "channel_id": 2, "data": null, - "id": 4, + "id": 6, "message": "foo", "username": "supabot", }, Object { "channel_id": 2, "data": null, - "id": 5, + "id": 7, "message": "foo", "username": "supabot", }, @@ -543,6 +610,20 @@ describe('basic insert, update, delete', () => { "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, @@ -553,14 +634,14 @@ describe('basic insert, update, delete', () => { Object { "channel_id": 2, "data": null, - "id": 4, + "id": 6, "message": "foo", "username": "supabot", }, Object { "channel_id": 2, "data": null, - "id": 5, + "id": 7, "message": "foo", "username": "supabot", }, @@ -578,6 +659,13 @@ describe('basic insert, update, delete', () => { Object { "count": null, "data": Array [ + Object { + "channel_id": 2, + "data": null, + "id": 5, + "message": "foo", + "username": "supabot", + }, Object { "channel_id": 2, "data": null, @@ -588,14 +676,14 @@ describe('basic insert, update, delete', () => { Object { "channel_id": 2, "data": null, - "id": 4, + "id": 6, "message": "foo", "username": "supabot", }, Object { "channel_id": 2, "data": null, - "id": 5, + "id": 7, "message": "foo", "username": "supabot", }, @@ -625,6 +713,13 @@ describe('basic insert, update, delete', () => { "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, @@ -751,37 +846,51 @@ test('allow ordering on JSON column', async () => { .select() .order('data->something' as any) 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": "'fat' 'rat'", - "data": null, - "status": "ONLINE", - "username": "dragarcia", +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 () => { @@ -807,14 +916,14 @@ test('select with head:true', async () => { test('select with head:true, count:exact', async () => { const res = await postgrest.from('users').select('*', { head: true, count: 'exact' }) expect(res).toMatchInlineSnapshot(` - Object { - "count": 4, - "data": null, - "error": null, - "status": 200, - "statusText": "OK", - } - `) +Object { + "count": 5, + "data": null, + "error": null, + "status": 200, + "statusText": "OK", +} +`) }) test('select with head:true, count:planned', async () => { @@ -856,43 +965,57 @@ test('select with head:true, count:estimated', async () => { test('select with count:exact', async () => { const res = await postgrest.from('users').select('*', { count: 'exact' }) expect(res).toMatchInlineSnapshot(` +Object { + "count": 5, + "data": Array [ 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", + "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", }, - ], - "error": null, - "status": 200, - "statusText": "OK", - } - `) + }, + "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 () => { @@ -1002,7 +1125,7 @@ describe("insert, update, delete with count: 'exact'", () => { Object { "channel_id": 1, "data": null, - "id": 6, + "id": 8, "message": "foo", "username": "supabot", }, @@ -1032,10 +1155,17 @@ describe("insert, update, delete with count: 'exact'", () => { "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": 6, + "id": 8, "message": "foo", "username": "supabot", }, @@ -1089,10 +1219,17 @@ describe("insert, update, delete with count: 'exact'", () => { "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": 6, + "id": 8, "message": "foo", "username": "supabot", }, @@ -1129,14 +1266,14 @@ describe("insert, update, delete with count: 'exact'", () => { Object { "channel_id": 1, "data": null, - "id": 7, + "id": 9, "message": "foo", "username": "supabot", }, Object { "channel_id": 1, "data": null, - "id": 8, + "id": 10, "message": "foo", "username": "supabot", }, @@ -1166,10 +1303,17 @@ describe("insert, update, delete with count: 'exact'", () => { "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": 6, + "id": 8, "message": "foo", "username": "supabot", }, @@ -1183,14 +1327,14 @@ describe("insert, update, delete with count: 'exact'", () => { Object { "channel_id": 1, "data": null, - "id": 7, + "id": 9, "message": "foo", "username": "supabot", }, Object { "channel_id": 1, "data": null, - "id": 8, + "id": 10, "message": "foo", "username": "supabot", }, @@ -1211,21 +1355,15 @@ describe("insert, update, delete with count: 'exact'", () => { expect(res).toMatchInlineSnapshot(` Object { "count": null, - "data": Array [ - Object { - "data": null, - "id": 100, - "slug": null, - }, - Object { - "data": null, - "id": 4, - "slug": "test-slug", - }, - ], - "error": null, - "status": 201, - "statusText": "Created", + "data": null, + "error": Object { + "code": "23505", + "details": "Key (id)=(2) already exists.", + "hint": null, + "message": "duplicate key value violates unique constraint \\"channels_pkey\\"", + }, + "status": 409, + "statusText": "Conflict", } `) }) @@ -1247,7 +1385,7 @@ describe("insert, update, delete with count: 'exact'", () => { }, Object { "data": null, - "id": 6, + "id": 4, "slug": "test-slug", }, ], @@ -1271,7 +1409,7 @@ describe("insert, update, delete with count: 'exact'", () => { Object { "channel_id": 2, "data": null, - "id": 6, + "id": 8, "message": "foo", "username": "supabot", }, @@ -1285,14 +1423,14 @@ describe("insert, update, delete with count: 'exact'", () => { Object { "channel_id": 2, "data": null, - "id": 7, + "id": 9, "message": "foo", "username": "supabot", }, Object { "channel_id": 2, "data": null, - "id": 8, + "id": 10, "message": "foo", "username": "supabot", }, @@ -1322,10 +1460,17 @@ describe("insert, update, delete with count: 'exact'", () => { "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": 6, + "id": 8, "message": "foo", "username": "supabot", }, @@ -1339,14 +1484,14 @@ describe("insert, update, delete with count: 'exact'", () => { Object { "channel_id": 2, "data": null, - "id": 7, + "id": 9, "message": "foo", "username": "supabot", }, Object { "channel_id": 2, "data": null, - "id": 8, + "id": 10, "message": "foo", "username": "supabot", }, @@ -1371,7 +1516,7 @@ describe("insert, update, delete with count: 'exact'", () => { Object { "channel_id": 2, "data": null, - "id": 6, + "id": 8, "message": "foo", "username": "supabot", }, @@ -1385,14 +1530,14 @@ describe("insert, update, delete with count: 'exact'", () => { Object { "channel_id": 2, "data": null, - "id": 7, + "id": 9, "message": "foo", "username": "supabot", }, Object { "channel_id": 2, "data": null, - "id": 8, + "id": 10, "message": "foo", "username": "supabot", }, @@ -1422,6 +1567,13 @@ describe("insert, update, delete with count: 'exact'", () => { "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, @@ -1481,239 +1633,3 @@ test('update with no match - return=representation', async () => { } `) }) - -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", - }, - ], - }, - "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('!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/01-dummy-data.sql b/test/db/01-dummy-data.sql index 7ff4f94e..8ed5e04c 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) + public.channels (id, slug) VALUES - ('public'), - ('random'); + (1, 'public'), + (2, 'random'), + (3, '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) diff --git a/test/db/docker-compose.yml b/test/db/docker-compose.yml index 13e9d2d7..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:v11.2.2 + image: postgrest/postgrest:v12.2.0 ports: - '3000:3000' environment: @@ -13,6 +13,7 @@ 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: diff --git a/test/filters.ts b/test/filters.ts index 98a76e4d..964c533e 100644 --- a/test/filters.ts +++ b/test/filters.ts @@ -6,24 +6,27 @@ const postgrest = new PostgrestClient('http://localhost:3000') test('not', async () => { const res = await postgrest.from('users').select('status').not('status', 'eq', 'OFFLINE') expect(res).toMatchInlineSnapshot(` +Object { + "count": null, + "data": Array [ Object { - "count": null, - "data": Array [ - Object { - "status": "ONLINE", - }, - Object { - "status": "ONLINE", - }, - Object { - "status": "ONLINE", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", - } - `) + "status": "ONLINE", + }, + Object { + "status": "ONLINE", + }, + Object { + "status": "ONLINE", + }, + Object { + "status": "ONLINE", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", +} +`) }) test('or', async () => { @@ -71,24 +74,27 @@ test('eq', async () => { test('neq', async () => { const res = await postgrest.from('users').select('username').neq('username', 'supabot') expect(res).toMatchInlineSnapshot(` +Object { + "count": null, + "data": Array [ Object { - "count": null, - "data": Array [ - Object { - "username": "kiwicopple", - }, - Object { - "username": "awailas", - }, - Object { - "username": "dragarcia", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", - } - `) + "username": "kiwicopple", + }, + Object { + "username": "awailas", + }, + Object { + "username": "jsonuser", + }, + Object { + "username": "dragarcia", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", +} +`) }) test('gt', async () => { @@ -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, @@ -315,27 +327,30 @@ test('in', async () => { const statuses = ['ONLINE', 'OFFLINE'] as const const res = await postgrest.from('users').select('status').in('status', statuses) expect(res).toMatchInlineSnapshot(` +Object { + "count": null, + "data": Array [ Object { - "count": null, - "data": Array [ - Object { - "status": "ONLINE", - }, - Object { - "status": "OFFLINE", - }, - Object { - "status": "ONLINE", - }, - Object { - "status": "ONLINE", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", - } - `) + "status": "ONLINE", + }, + Object { + "status": "OFFLINE", + }, + Object { + "status": "ONLINE", + }, + Object { + "status": "ONLINE", + }, + Object { + "status": "ONLINE", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", +} +`) }) test('contains', async () => { @@ -412,24 +427,27 @@ test('rangeGt', async () => { test('rangeGte', async () => { const res = await postgrest.from('users').select('age_range').rangeGte('age_range', '[2,25)') expect(res).toMatchInlineSnapshot(` +Object { + "count": null, + "data": Array [ Object { - "count": null, - "data": Array [ - Object { - "age_range": "[25,35)", - }, - Object { - "age_range": "[25,35)", - }, - Object { - "age_range": "[20,30)", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", - } - `) + "age_range": "[25,35)", + }, + Object { + "age_range": "[25,35)", + }, + Object { + "age_range": "[20,30)", + }, + Object { + "age_range": "[20,30)", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", +} +`) }) test('rangeLte', async () => { @@ -475,18 +493,21 @@ test('rangeAdjacent', async () => { test('overlaps', async () => { const res = await postgrest.from('users').select('age_range').overlaps('age_range', '[2,25)') expect(res).toMatchInlineSnapshot(` - Object { - "count": null, - "data": Array [ - Object { - "age_range": "[20,30)", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", - } - `) +Object { + "count": null, + "data": Array [ + Object { + "age_range": "[20,30)", + }, + Object { + "age_range": "[20,30)", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", +} +`) }) test('textSearch', async () => { diff --git a/test/index.test-d.ts b/test/index.test-d.ts index c1fb9ba0..90c04d28 100644 --- a/test/index.test-d.ts +++ b/test/index.test-d.ts @@ -1,6 +1,5 @@ import { expectError, expectType } from 'tsd' -import { PostgrestClient, PostgrestSingleResponse } from '../src/index' -import { SelectQueryError } from '../src/select-query-parser' +import { PostgrestClient } from '../src/index' import { Prettify } from '../src/types' import { Database, Json } from './types' @@ -65,7 +64,7 @@ const postgrest = new PostgrestClient(REST_URL) throw new Error(error.message) } expectType<{ message: string | null; status: Database['public']['Enums']['user_status'] | null }>( - data + data, ) } @@ -76,19 +75,10 @@ const postgrest = new PostgrestClient(REST_URL) throw new Error(error.message) } expectType>( - data + data, ) } -// embedded resource with no fields -{ - const { data, error } = await postgrest.from('messages').select('message, users()').single() - if (error) { - throw new Error(error.message) - } - expectType<{ message: string | null }>(data) -} - // `count` in embedded resource { const { data, error } = await postgrest.from('messages').select('message, users(count)').single() @@ -113,25 +103,6 @@ const postgrest = new PostgrestClient(REST_URL) expectType(data.baz) } -// typecasting and aggregate functions -{ - const { data, error } = await postgrest - .from('messages') - .select( - 'message, users.count(), casted_message:message::int4, casted_count:users.count()::text' - ) - .single() - if (error) { - throw new Error(error.message) - } - expectType<{ - message: string | null - count: number - casted_message: number - casted_count: string - }>(data) -} - // rpc return type { const { data, error } = await postgrest.rpc('get_status') @@ -141,62 +112,6 @@ const postgrest = new PostgrestClient(REST_URL) expectType<'ONLINE' | 'OFFLINE'>(data) } -// many-to-one relationship -{ - const { data: message, error } = await postgrest.from('messages').select('user:users(*)').single() - if (error) { - throw new Error(error.message) - } - expectType(message.user) -} - -// !inner relationship -{ - const { data: message, error } = await postgrest - .from('messages') - .select('channels!inner(*, channel_details!inner(*))') - .single() - if (error) { - throw new Error(error.message) - } - type ExpectedType = Prettify< - Database['public']['Tables']['channels']['Row'] & { - channel_details: Database['public']['Tables']['channel_details']['Row'] - } - > - - expectType(message.channels) -} - -// one-to-many relationship -{ - const { data: user, error } = await postgrest.from('users').select('messages(*)').single() - if (error) { - throw new Error(error.message) - } - expectType(user.messages) -} - -// referencing missing column -{ - const res = await postgrest.from('users').select('username, dat') - expectType[]>>(res) -} - -// one-to-one relationship -{ - const { data: channels, error } = await postgrest - .from('channels') - .select('channel_details(*)') - .single() - if (error) { - throw new Error(error.message) - } - expectType( - channels.channel_details - ) -} - // PostgrestBuilder's children retains class when using inherited methods { const x = postgrest.from('channels').select() @@ -205,83 +120,3 @@ const postgrest = new PostgrestClient(REST_URL) expectType(y) expectType(z) } - -// !left oneToOne -{ - const { data: oneToOne, error } = await postgrest - .from('channel_details') - .select('channels!left(*)') - .single() - - if (error) { - throw new Error(error.message) - } - - // TODO: this should never be nullable - expectType(oneToOne.channels) -} - -// !left oneToMany -{ - const { data: oneToMany, error } = await postgrest - .from('users') - .select('messages!left(*)') - .single() - - if (error) { - throw new Error(error.message) - } - - expectType>(oneToMany.messages) -} - -// !left zeroToOne -{ - const { data: zeroToOne, error } = await postgrest - .from('user_profiles') - .select('users!left(*)') - .single() - - if (error) { - throw new Error(error.message) - } - - expectType(zeroToOne.users) -} - -// join over a 1-1 relation with both nullables and non-nullables fields -{ - const { data: bestFriends, error } = 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(*)' - ) - .single() - - if (error) { - throw new Error(error.message) - } - - // TODO: Those two fields shouldn't be nullables - expectType(bestFriends.first_user) - expectType(bestFriends.second_user) - // The third wheel should be nullable - expectType(bestFriends.third_wheel) -} -// join over a 1-M relation with both nullables and non-nullables fields -{ - const { data: users, error } = 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(*)` - ) - .single() - - if (error) { - throw new Error(error.message) - } - // TODO: type properly the result for this kind of queries - expectType>(users.first_friend_of) -} diff --git a/test/index.test.ts b/test/index.test.ts index ad4e4ee7..6a18f85d 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -1,4 +1,5 @@ import './basic' +import './relationships' import './filters' import './resource-embedding' import './transforms' diff --git a/test/relationships.ts b/test/relationships.ts new file mode 100644 index 00000000..4d8b612d --- /dev/null +++ b/test/relationships.ts @@ -0,0 +1,1716 @@ +import { PostgrestClient } from '../src/index' +import { Database } from './types' + +const REST_URL = 'http://localhost:3000' +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', + }, +} 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), +} 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", + } +`) +}) diff --git a/test/resource-embedding.ts b/test/resource-embedding.ts index 08887be0..50d73780 100644 --- a/test/resource-embedding.ts +++ b/test/resource-embedding.ts @@ -6,42 +6,52 @@ const postgrest = new PostgrestClient('http://localhost:3000') test('embedded select', async () => { const res = await postgrest.from('users').select('messages(*)') expect(res).toMatchInlineSnapshot(` +Object { + "count": null, + "data": Array [ Object { - "count": null, - "data": Array [ + "messages": 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", - }, - ], + "channel_id": 1, + "data": null, + "id": 1, + "message": "Hello World 👋", + "username": "supabot", }, Object { - "messages": Array [], + "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 [], + "channel_id": 3, + "data": null, + "id": 4, + "message": "Some message on channel wihtout details", + "username": "supabot", }, ], - "error": null, - "status": 200, - "statusText": "OK", - } - `) + }, + Object { + "messages": Array [], + }, + Object { + "messages": Array [], + }, + Object { + "messages": Array [], + }, + Object { + "messages": Array [], + }, + ], + "error": null, + "status": 200, + "statusText": "OK", +} +`) }) describe('embedded filters', () => { @@ -52,35 +62,38 @@ describe('embedded filters', () => { .select('messages(*)') .eq('messages.channel_id' as any, 1) 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 [], - }, - ], - "error": null, - "status": 200, - "statusText": "OK", - } - `) +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 @@ -88,42 +101,45 @@ describe('embedded filters', () => { .select('messages(*)') .or('channel_id.eq.2,message.eq.Hello World 👋', { foreignTable: 'messages' }) 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 [], - }, - ], - "error": null, - "status": 200, - "statusText": "OK", - } - `) +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 @@ -133,42 +149,45 @@ describe('embedded filters', () => { foreignTable: 'messages', }) 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 [], - }, - ], - "error": null, - "status": 200, - "statusText": "OK", - } - `) +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", +} +`) }) }) @@ -179,42 +198,52 @@ describe('embedded transforms', () => { .select('messages(*)') .order('channel_id' as any, { foreignTable: 'messages', ascending: false }) 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 { - "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", - } - `) +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 () => { @@ -224,42 +253,52 @@ describe('embedded transforms', () => { .order('channel_id' as any, { foreignTable: 'messages', ascending: false }) .order('username', { foreignTable: 'messages', ascending: false }) 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 { - "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", - } - `) +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 () => { @@ -268,35 +307,38 @@ describe('embedded transforms', () => { .select('messages(*)') .limit(1, { foreignTable: 'messages' }) 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 [], - }, - ], - "error": null, - "status": 200, - "statusText": "OK", - } - `) +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 () => { @@ -305,34 +347,37 @@ describe('embedded transforms', () => { .select('messages(*)') .range(1, 1, { foreignTable: 'messages' }) 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 [], - }, - ], - "error": null, - "status": 200, - "statusText": "OK", - } - `) +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/select-query-parser/parser.test-d.ts b/test/select-query-parser/parser.test-d.ts new file mode 100644 index 00000000..b0db2be3 --- /dev/null +++ b/test/select-query-parser/parser.test-d.ts @@ -0,0 +1,570 @@ +import { expectType } from 'tsd' +import type { ParseQuery } from '../../src/select-query-parser/parser/parser' +import type { ParserError } from '../../src/select-query-parser/parser/utils' +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', + children: [ + { type: 'Field', name: 'id' }, + { type: 'Field', name: 'title' }, + ], + inner: true, + }, + ]) +} + +// Select with left join +{ + expectType>([ + { + type: 'Field', + name: 'posts', + children: [ + { type: 'Field', name: 'id' }, + { type: 'Field', name: 'title' }, + ], + left: true, + }, + ]) +} + +// 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' }, + ], + }, + ], + left: true, + }, + { 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: [] }] }, + ]) +} + +// 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', + children: [ + { type: 'Field', name: 'id' }, + { type: 'Field', name: 'name' }, + ], + inner: true, + }, + { + type: 'Field', + name: 'posts', + children: [ + { type: 'Field', name: 'title' }, + { type: 'Field', name: 'content' }, + ], + left: true, + }, + ]) +} + +// 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 +{ + const r: ParserError<'Empty string'> = 'Empty string' as ParserError<'Empty string'> + expectType>(r) +} + +// Unexpected input at the end +{ + const r: ParserError<'Unexpected input: unexpected_input'> = + 'Unexpected input: unexpected_input' as ParserError<'Unexpected input: unexpected_input'> + expectType>(r) +} + +// Missing closing parenthesis +{ + const r: ParserError<"Expected ')' at "> = "Expected ')' at " as ParserError<"Expected ')' at "> + expectType>(r) +} + +// Incomplete JSON accessor +{ + const r: ParserError<'Unexpected input: ->'> = + 'Unexpected input: ->' as ParserError<'Unexpected input: ->'> + expectType'>>(r) +} + +// Invalid hint (missing identifier after !) +{ + const r: ParserError<"Expected identifier after '!' at (id, name)"> = + "Expected identifier after '!' at (id, name)" as ParserError<"Expected identifier after '!' at (id, name)"> + expectType>(r) +} + +// Invalid spread (missing field after ...) +{ + const r: ParserError<'Unable to parse spread resource at ...::'> = + 'Unable to parse spread resource at ...::' as ParserError<'Unable to parse spread resource at ...::'> + expectType>(r) +} + +// Invalid rename (missing field after :) +{ + const r: ParserError<'Unable to parse renamed field at new_name:'> = + 'Unable to parse renamed field at new_name:' as ParserError<'Unable to parse renamed field at new_name:'> + expectType>(r) +} + +// Incomplete quoted identifier +{ + const r: ParserError<'Expected identifier at `"incomplete`'> = + 'Expected identifier at `"incomplete`' as ParserError<'Expected identifier at `"incomplete`'> + expectType>(r) +} + +// Invalid combination of inner and left join +{ + const r: ParserError<'Expected embedded resource after `!inner`'> = + 'Expected embedded resource after `!inner`' as ParserError<'Expected embedded resource after `!inner`'> + expectType>(r) +} + +// Missing opening parenthesis after aggregate function +{ + const r: ParserError<'Expected `()` after `.` operator `avg`'> = + 'Expected `()` after `.` operator `avg`' as ParserError<'Expected `()` after `.` operator `avg`'> + expectType>(r) +} + +// Invalid nested JSON accessor +{ + const r: ParserError<'Unexpected input: ->->theme'> = + 'Unexpected input: ->->theme' as ParserError<'Unexpected input: ->->theme'> + expectTypepreferences->->theme'>>(r) +} 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..26c531f5 --- /dev/null +++ b/test/select-query-parser/result.test-d.ts @@ -0,0 +1,56 @@ +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) +} 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..b8935ed0 --- /dev/null +++ b/test/select-query-parser/select.test-d.ts @@ -0,0 +1,689 @@ +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) +} \ No newline at end of file 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..593a5275 --- /dev/null +++ b/test/select-query-parser/types.test-d.ts @@ -0,0 +1,180 @@ +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 { + FindMatchingRelationships, + FindMatchingTableRelationships, + IsRelationNullable, +} from '../../src/select-query-parser/utils' +import { Json } from '../../src/select-query-parser/types' +import { ParseQuery } from '../../src/select-query-parser/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 an non-existing relationship should return never +{ + let result: FindMatchingRelationships< + 'test', + Database['public']['Tables']['best_friends']['Relationships'] + > + let expected: false + expectType>(true) +} +// Searching for a relationship by direct foreignkey name +{ + let result: FindMatchingRelationships< + 'best_friends_first_user_fkey', + Database['public']['Tables']['best_friends']['Relationships'] + > + let expected: { + foreignKeyName: 'best_friends_first_user_fkey' + columns: ['first_user'] + isOneToOne: false + referencedRelation: 'users' + referencedColumns: ['username'] + } + expectType>(true) +} +// Searching for a relationship by column hoding the value reference +{ + let result: FindMatchingRelationships< + 'first_user', + Database['public']['Tables']['best_friends']['Relationships'] + > + let expected: { + foreignKeyName: 'best_friends_first_user_fkey' + columns: ['first_user'] + isOneToOne: false + referencedRelation: 'users' + referencedColumns: ['username'] + } + expectType>(true) +} +// Will find the first matching relationship +{ + let result: FindMatchingRelationships< + 'username', + Database['public']['Tables']['user_profiles']['Relationships'] + > + let expected: { + foreignKeyName: 'user_profiles_username_fkey' + columns: ['username'] + isOneToOne: false + referencedRelation: 'non_updatable_view' + referencedColumns: ['username'] + } + 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: FindMatchingRelationships< + 'users', + Database['public']['Tables']['messages']['Relationships'] + > + let expected: { + foreignKeyName: 'messages_username_fkey' + columns: ['username'] + isOneToOne: false + referencedRelation: 'users' + referencedColumns: ['username'] + } + expectType>(true) +} +{ + let result: FindMatchingRelationships< + 'channels', + Database['public']['Tables']['messages']['Relationships'] + > + let expected: { + foreignKeyName: 'messages_channel_id_fkey' + columns: ['channel_id'] + isOneToOne: false + referencedRelation: 'channels' + referencedColumns: ['id'] + } + expectType>(true) +} + +// IsRelationNullable +{ + type BestFriendsTable = Database['public']['Tables']['best_friends'] + type NonNullableRelation = FindMatchingRelationships< + 'best_friends_first_user_fkey', + BestFriendsTable['Relationships'] + > + type NullableRelation = FindMatchingRelationships< + 'best_friends_third_wheel_fkey', + BestFriendsTable['Relationships'] + > + 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 + } + } + expectType(expected!) + type r2 = ProcessNodes + expectType(expected!) +} diff --git a/test/transforms.ts b/test/transforms.ts index b0d0bce5..83086409 100644 --- a/test/transforms.ts +++ b/test/transforms.ts @@ -8,43 +8,57 @@ const postgrest = new PostgrestClient('http://localhost:3000') test('order', async () => { const res = await postgrest.from('users').select().order('username', { ascending: false }) expect(res).toMatchInlineSnapshot(` +Object { + "count": null, + "data": Array [ 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", + "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", }, - ], - "error": null, - "status": 200, - "statusText": "OK", - } - `) + }, + "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 () => { @@ -57,6 +71,13 @@ test('order on multiple columns', async () => { 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, @@ -103,36 +124,43 @@ test('limit', async () => { test('range', async () => { const res = await postgrest.from('users').select().range(1, 3) expect(res).toMatchInlineSnapshot(` +Object { + "count": null, + "data": Array [ 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", + "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", }, - ], - "error": null, - "status": 200, - "statusText": "OK", - } - `) + }, + "status": "ONLINE", + "username": "jsonuser", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", +} +`) }) test('single', async () => { @@ -251,18 +279,19 @@ test('select on rpc', async () => { test('csv', async () => { const res = await postgrest.from('users').select().csv() expect(res).toMatchInlineSnapshot(` - Object { - "count": null, - "data": "username,data,age_range,status,catchphrase - supabot,,\\"[1,2)\\",ONLINE,\\"'cat' 'fat'\\" - kiwicopple,,\\"[25,35)\\",OFFLINE,\\"'bat' 'cat'\\" - awailas,,\\"[25,35)\\",ONLINE,\\"'bat' 'rat'\\" - dragarcia,,\\"[20,30)\\",ONLINE,\\"'fat' 'rat'\\"", - "error": null, - "status": 200, - "statusText": "OK", - } - `) +Object { + "count": null, + "data": "username,data,age_range,status,catchphrase +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, + "statusText": "OK", +} +`) }) test('abort signal', async () => { diff --git a/test/types.ts b/test/types.ts index deed0fa9..92d18185 100644 --- a/test/types.ts +++ b/test/types.ts @@ -1,5 +1,4 @@ export type Json = string | number | boolean | null | { [key: string]: Json | undefined } | Json[] - export type Database = { personal: { Tables: { From 4d2df203e088e55d71d43c1d11f2703806167645 Mon Sep 17 00:00:00 2001 From: avallete Date: Fri, 27 Sep 2024 23:41:17 +0200 Subject: [PATCH 087/110] chore: prettify fix tests --- test/index.test-d.ts | 6 +++--- test/select-query-parser/parser.test-d.ts | 8 ++++---- test/select-query-parser/result.test-d.ts | 1 - test/select-query-parser/select.test-d.ts | 2 +- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/test/index.test-d.ts b/test/index.test-d.ts index 90c04d28..516529e9 100644 --- a/test/index.test-d.ts +++ b/test/index.test-d.ts @@ -64,7 +64,7 @@ const postgrest = new PostgrestClient(REST_URL) throw new Error(error.message) } expectType<{ message: string | null; status: Database['public']['Enums']['user_status'] | null }>( - data, + data ) } @@ -75,7 +75,7 @@ const postgrest = new PostgrestClient(REST_URL) throw new Error(error.message) } expectType>( - data, + data ) } @@ -85,7 +85,7 @@ const postgrest = new PostgrestClient(REST_URL) if (error) { throw new Error(error.message) } - expectType<{ message: string | null; users: { count: number } | null }>(data) + expectType<{ message: string | null; users: { count: number } }>(data) } // json accessor in select query diff --git a/test/select-query-parser/parser.test-d.ts b/test/select-query-parser/parser.test-d.ts index b0db2be3..5cbb1680 100644 --- a/test/select-query-parser/parser.test-d.ts +++ b/test/select-query-parser/parser.test-d.ts @@ -480,16 +480,16 @@ import { selectParams } from '../relationships' // select JSON accessor { expect>([ - { type: "Field", name: "data", alias: "bar", castType: "json" }, - { type: "Field", name: "data", alias: "baz", castType: "text" } + { 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: [] } + { type: 'Field', name: 'message' }, + { type: 'Field', name: 'users', children: [] }, ]) } diff --git a/test/select-query-parser/result.test-d.ts b/test/select-query-parser/result.test-d.ts index 26c531f5..6545c8b5 100644 --- a/test/select-query-parser/result.test-d.ts +++ b/test/select-query-parser/result.test-d.ts @@ -44,7 +44,6 @@ type SelectQueryFromTableResult< expectType>(true) } - // embed resource with no fields { const { from, select } = selectParams.selectEmbedRessourceWithNoFields diff --git a/test/select-query-parser/select.test-d.ts b/test/select-query-parser/select.test-d.ts index b8935ed0..13fcff2c 100644 --- a/test/select-query-parser/select.test-d.ts +++ b/test/select-query-parser/select.test-d.ts @@ -686,4 +686,4 @@ type Schema = Database['public'] let result: Exclude let expected: SelectQueryError<`column 'users' does not exist on 'messages'.`> expectType>(true) -} \ No newline at end of file +} From ea7dec12fb11d8c3c6dddbc025394ab7c4651eba Mon Sep 17 00:00:00 2001 From: avallete Date: Fri, 27 Sep 2024 22:17:54 +0200 Subject: [PATCH 088/110] chore: upgrade postgrest tests image add some more test data --- test/basic.ts | 502 ++++++++++++++++++++++++++------- test/filters.ts | 179 ++++++------ test/resource-embedding.ts | 563 +++++++++++++++++++------------------ test/transforms.ts | 128 +++++---- 4 files changed, 871 insertions(+), 501 deletions(-) diff --git a/test/basic.ts b/test/basic.ts index a064b107..8a4d5581 100644 --- a/test/basic.ts +++ b/test/basic.ts @@ -48,16 +48,47 @@ Object { }, "baz": "string value", }, - }, - "status": "ONLINE", - "username": "jsonuser", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`) + 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 () => { @@ -67,31 +98,34 @@ Object { "count": null, "data": Array [ Object { - "non_updatable_column": 1, - "username": "supabot", - }, - Object { - "non_updatable_column": 1, - "username": "kiwicopple", - }, - Object { - "non_updatable_column": 1, - "username": "awailas", - }, - Object { - "non_updatable_column": 1, - "username": "dragarcia", - }, - Object { - "non_updatable_column": 1, - "username": "jsonuser", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`) + "count": null, + "data": Array [ + Object { + "non_updatable_column": 1, + "username": "supabot", + }, + Object { + "non_updatable_column": 1, + "username": "kiwicopple", + }, + Object { + "non_updatable_column": 1, + "username": "awailas", + }, + Object { + "non_updatable_column": 1, + "username": "dragarcia", + }, + Object { + "non_updatable_column": 1, + "username": "jsonuser", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('rpc', async () => { @@ -878,19 +912,43 @@ Array [ }, "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' '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 () => { @@ -916,14 +974,14 @@ test('select with head:true', async () => { test('select with head:true, count:exact', async () => { const res = await postgrest.from('users').select('*', { head: true, count: 'exact' }) expect(res).toMatchInlineSnapshot(` -Object { - "count": 5, - "data": null, - "error": null, - "status": 200, - "statusText": "OK", -} -`) + Object { + "count": 5, + "data": null, + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('select with head:true, count:planned', async () => { @@ -969,53 +1027,56 @@ 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", + "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", + }, }, - "baz": "string value", + "status": "ONLINE", + "username": "jsonuser", }, - }, - "status": "ONLINE", - "username": "jsonuser", - }, - Object { - "age_range": "[20,30)", - "catchphrase": "'fat' 'rat'", - "data": null, - "status": "ONLINE", - "username": "dragarcia", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`) + 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 () => { @@ -1633,3 +1694,242 @@ test('update with no match - return=representation', async () => { } `) }) + +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('!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/filters.ts b/test/filters.ts index 964c533e..2c439666 100644 --- a/test/filters.ts +++ b/test/filters.ts @@ -10,23 +10,26 @@ Object { "count": null, "data": Array [ Object { - "status": "ONLINE", - }, - Object { - "status": "ONLINE", - }, - Object { - "status": "ONLINE", - }, - Object { - "status": "ONLINE", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`) + "count": null, + "data": Array [ + Object { + "status": "ONLINE", + }, + Object { + "status": "ONLINE", + }, + Object { + "status": "ONLINE", + }, + Object { + "status": "ONLINE", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('or', async () => { @@ -78,23 +81,26 @@ Object { "count": null, "data": Array [ Object { - "username": "kiwicopple", - }, - Object { - "username": "awailas", - }, - Object { - "username": "jsonuser", - }, - Object { - "username": "dragarcia", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`) + "count": null, + "data": Array [ + Object { + "username": "kiwicopple", + }, + Object { + "username": "awailas", + }, + Object { + "username": "jsonuser", + }, + Object { + "username": "dragarcia", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('gt', async () => { @@ -331,26 +337,29 @@ Object { "count": null, "data": Array [ Object { - "status": "ONLINE", - }, - Object { - "status": "OFFLINE", - }, - Object { - "status": "ONLINE", - }, - Object { - "status": "ONLINE", - }, - Object { - "status": "ONLINE", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`) + "count": null, + "data": Array [ + Object { + "status": "ONLINE", + }, + Object { + "status": "OFFLINE", + }, + Object { + "status": "ONLINE", + }, + Object { + "status": "ONLINE", + }, + Object { + "status": "ONLINE", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('contains', async () => { @@ -431,23 +440,26 @@ Object { "count": null, "data": Array [ Object { - "age_range": "[25,35)", - }, - Object { - "age_range": "[25,35)", - }, - Object { - "age_range": "[20,30)", - }, - Object { - "age_range": "[20,30)", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`) + "count": null, + "data": Array [ + Object { + "age_range": "[25,35)", + }, + Object { + "age_range": "[25,35)", + }, + Object { + "age_range": "[20,30)", + }, + Object { + "age_range": "[20,30)", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('rangeLte', async () => { @@ -497,17 +509,20 @@ Object { "count": null, "data": Array [ Object { - "age_range": "[20,30)", - }, - Object { - "age_range": "[20,30)", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`) + "count": null, + "data": Array [ + Object { + "age_range": "[20,30)", + }, + Object { + "age_range": "[20,30)", + }, + ], + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) test('textSearch', async () => { diff --git a/test/resource-embedding.ts b/test/resource-embedding.ts index 50d73780..a8de09b8 100644 --- a/test/resource-embedding.ts +++ b/test/resource-embedding.ts @@ -12,11 +12,29 @@ Object { Object { "messages": Array [ Object { - "channel_id": 1, - "data": null, - "id": 1, - "message": "Hello World 👋", - "username": "supabot", + "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 { "channel_id": 2, @@ -32,6 +50,9 @@ Object { "message": "Some message on channel wihtout details", "username": "supabot", }, + Object { + "messages": Array [], + }, ], }, Object { @@ -62,38 +83,38 @@ describe('embedded filters', () => { .select('messages(*)') .eq('messages.channel_id' as any, 1) 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", -} -`) + 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 @@ -101,45 +122,45 @@ Object { .select('messages(*)') .or('channel_id.eq.2,message.eq.Hello World 👋', { foreignTable: 'messages' }) 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", -} -`) + 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 @@ -149,45 +170,45 @@ Object { foreignTable: 'messages', }) 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", -} -`) + 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", + } + `) }) }) @@ -198,52 +219,52 @@ describe('embedded transforms', () => { .select('messages(*)') .order('channel_id' as any, { foreignTable: 'messages', ascending: false }) 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", -} -`) + 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 () => { @@ -253,52 +274,52 @@ Object { .order('channel_id' as any, { foreignTable: 'messages', ascending: false }) .order('username', { foreignTable: 'messages', ascending: false }) 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", -} -`) + 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 () => { @@ -307,38 +328,38 @@ Object { .select('messages(*)') .limit(1, { foreignTable: 'messages' }) 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", -} -`) + 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 () => { @@ -347,37 +368,37 @@ Object { .select('messages(*)') .range(1, 1, { foreignTable: 'messages' }) 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", -} -`) + 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/transforms.ts b/test/transforms.ts index 83086409..a1fab100 100644 --- a/test/transforms.ts +++ b/test/transforms.ts @@ -35,30 +35,47 @@ Object { }, "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", -} -`) + 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 () => { @@ -151,16 +168,33 @@ Object { }, "baz": "string value", }, - }, - "status": "ONLINE", - "username": "jsonuser", - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`) + 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 () => { @@ -279,19 +313,19 @@ test('select on rpc', async () => { test('csv', async () => { const res = await postgrest.from('users').select().csv() expect(res).toMatchInlineSnapshot(` -Object { - "count": null, - "data": "username,data,age_range,status,catchphrase -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, - "statusText": "OK", -} -`) + Object { + "count": null, + "data": "username,data,age_range,status,catchphrase + 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, + "statusText": "OK", + } + `) }) test('abort signal', async () => { From 82fc09966b2ae8a1c8ac60e43d57931c1ad42987 Mon Sep 17 00:00:00 2001 From: avallete Date: Sat, 28 Sep 2024 00:18:04 +0200 Subject: [PATCH 089/110] feat: make new select-query-parser available under next flag --- src/PostgrestClient.ts | 12 +- src/PostgrestFilterBuilder.ts | 5 +- src/PostgrestQueryBuilder.ts | 16 +- src/PostgrestTransformBuilder.ts | 10 +- src/select-query-parser.ts | 706 +++++++++++++++++++++++++++++++ test/basic.ts | 91 +--- test/filters.ts | 15 - test/index.test-d.ts | 2 +- test/relationships.ts | 3 +- test/resource-embedding.ts | 45 +- test/transforms.ts | 66 +-- 11 files changed, 778 insertions(+), 193 deletions(-) create mode 100644 src/select-query-parser.ts diff --git a/src/PostgrestClient.ts b/src/PostgrestClient.ts index 915ddc16..0c5d2481 100644 --- a/src/PostgrestClient.ts +++ b/src/PostgrestClient.ts @@ -21,7 +21,8 @@ export default class PostgrestClient< : string & keyof Database, Schema extends GenericSchema = Database[SchemaName] extends GenericSchema ? Database[SchemaName] - : any + : any, + TypesVersion extends "next" | undefined = undefined > { url: string headers: Record @@ -59,16 +60,16 @@ export default class PostgrestClient< from< TableName extends string & keyof Schema['Tables'], Table extends Schema['Tables'][TableName] - >(relation: TableName): PostgrestQueryBuilder + >(relation: TableName): PostgrestQueryBuilder from( relation: ViewName - ): PostgrestQueryBuilder + ): PostgrestQueryBuilder /** * Perform a query on a table or a view. * * @param relation - The table or view name to query */ - from(relation: string): PostgrestQueryBuilder { + from(relation: string): PostgrestQueryBuilder { const url = new URL(`${this.url}/${relation}`) return new PostgrestQueryBuilder(url, { headers: { ...this.headers }, @@ -140,7 +141,8 @@ export default class PostgrestClient< ? Fn['Returns'][number] : never : never, - Fn['Returns'] + Fn['Returns'], + TypesVersion > { let method: 'HEAD' | 'GET' | 'POST' const url = new URL(`${this.url}/rpc/${fn}`) diff --git a/src/PostgrestFilterBuilder.ts b/src/PostgrestFilterBuilder.ts index 21cc4090..ade97116 100644 --- a/src/PostgrestFilterBuilder.ts +++ b/src/PostgrestFilterBuilder.ts @@ -29,9 +29,10 @@ export default class PostgrestFilterBuilder< Schema extends GenericSchema, Row extends Record, Result, + TypesVersion, RelationName = unknown, - Relationships = unknown -> extends PostgrestTransformBuilder { + Relationships = unknown, +> extends PostgrestTransformBuilder { eq( column: ColumnName, value: NonNullable diff --git a/src/PostgrestQueryBuilder.ts b/src/PostgrestQueryBuilder.ts index 44e7320a..91dd688a 100644 --- a/src/PostgrestQueryBuilder.ts +++ b/src/PostgrestQueryBuilder.ts @@ -1,13 +1,15 @@ import PostgrestBuilder from './PostgrestBuilder' import PostgrestFilterBuilder from './PostgrestFilterBuilder' -import { GetResult } from './select-query-parser/result' +import { GetResult as GetResultV2 } from './select-query-parser/result' +import { GetResult } from './select-query-parser' import { Fetch, GenericSchema, GenericTable, GenericView } from './types' export default class PostgrestQueryBuilder< Schema extends GenericSchema, Relation extends GenericTable | GenericView, + TypesVersion, RelationName = unknown, - Relationships = Relation extends { Relationships: infer R } ? R : unknown + Relationships = Relation extends { Relationships: infer R } ? R : unknown, > { url: URL headers: Record @@ -56,7 +58,9 @@ export default class PostgrestQueryBuilder< */ select< Query extends string = '*', - ResultOne = GetResult + ResultOne = TypesVersion extends "next" + ? GetResultV2 + : GetResult >( columns?: Query, { @@ -66,7 +70,7 @@ export default class PostgrestQueryBuilder< head?: boolean count?: 'exact' | 'planned' | 'estimated' } = {} - ): PostgrestFilterBuilder { + ): PostgrestFilterBuilder { const method = head ? 'HEAD' : 'GET' // Remove whitespaces except when quoted let quoted = false @@ -103,14 +107,14 @@ export default class PostgrestQueryBuilder< options?: { count?: 'exact' | 'planned' | 'estimated' } - ): PostgrestFilterBuilder + ): PostgrestFilterBuilder insert( values: Row[], options?: { count?: 'exact' | 'planned' | 'estimated' defaultToNull?: boolean } - ): PostgrestFilterBuilder + ): PostgrestFilterBuilder /** * Perform an INSERT into the table or view. * diff --git a/src/PostgrestTransformBuilder.ts b/src/PostgrestTransformBuilder.ts index 4791702c..1d7094a5 100644 --- a/src/PostgrestTransformBuilder.ts +++ b/src/PostgrestTransformBuilder.ts @@ -1,5 +1,6 @@ import PostgrestBuilder from './PostgrestBuilder' -import { GetResult } from './select-query-parser/result' +import { GetResult as GetResultV2 } from './select-query-parser/result' +import { GetResult } from './select-query-parser' import { GenericSchema } from './types' export default class PostgrestTransformBuilder< @@ -7,7 +8,8 @@ export default class PostgrestTransformBuilder< Row extends Record, Result, RelationName = unknown, - Relationships = unknown + Relationships = unknown, + TypesVersion = unknown > extends PostgrestBuilder { /** * Perform a SELECT on the query result. @@ -20,7 +22,9 @@ export default class PostgrestTransformBuilder< */ select< Query extends string = '*', - NewResultOne = GetResult + NewResultOne = TypesVersion extends "next" + ? GetResultV2 + : GetResult >( columns?: Query ): PostgrestTransformBuilder { diff --git a/src/select-query-parser.ts b/src/select-query-parser.ts new file mode 100644 index 00000000..0c5c40f1 --- /dev/null +++ b/src/select-query-parser.ts @@ -0,0 +1,706 @@ +// 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 { GenericSchema, Prettify } from './types' + +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 | '_' + +type Json = string | number | boolean | null | { [key: string]: Json } | Json[] + +type SingleValuePostgreSQLTypes = + | 'bool' + | 'int2' + | 'int4' + | 'int8' + | 'float4' + | 'float8' + | 'numeric' + | 'bytea' + | 'bpchar' + | 'varchar' + | 'date' + | 'text' + | 'citext' + | 'time' + | 'timetz' + | 'timestamp' + | 'timestamptz' + | 'uuid' + | 'vector' + | 'json' + | 'jsonb' + | 'void' + | 'record' + | string + +type ArrayPostgreSQLTypes = `_${SingleValuePostgreSQLTypes}` + +type PostgreSQLTypes = SingleValuePostgreSQLTypes | ArrayPostgreSQLTypes + +type TypeScriptSingleValueTypes = T extends 'bool' + ? boolean + : T extends 'int2' | 'int4' | 'int8' | 'float4' | 'float8' | 'numeric' + ? number + : T extends + | 'bytea' + | 'bpchar' + | 'varchar' + | 'date' + | 'text' + | 'citext' + | 'time' + | 'timetz' + | 'timestamp' + | 'timestamptz' + | 'uuid' + | 'vector' + ? string + : T extends 'json' | 'jsonb' + ? Json + : T extends 'void' + ? undefined + : T extends 'record' + ? Record + : unknown + +type AggregateFunctions = 'count' | 'sum' | 'avg' | 'min' | 'max' + +type StripUnderscore = T extends `_${infer U}` ? U : T + +type TypeScriptTypes = T extends ArrayPostgreSQLTypes + ? TypeScriptSingleValueTypes>>[] + : TypeScriptSingleValueTypes + +/** + * Parser errors. + */ +type ParserError = { error: true } & Message +type GenericStringError = ParserError<'Received a generic string'> +export type SelectQueryError = { error: true } & Message + +/** + * Creates a new {@link ParserError} if the given input is not already a parser error. + */ +type CreateParserErrorIfRequired = Input extends ParserError + ? Input + : ParserError + +/** + * Trims whitespace from the left of the input. + */ +type EatWhitespace = string extends Input + ? GenericStringError + : Input extends `${Whitespace}${infer Remainder}` + ? EatWhitespace + : Input + +/** + * Returns a boolean representing whether there is a foreign key with the given name. + */ +type HasFKey = Relationships extends [infer R] + ? R extends { foreignKeyName: FKeyName } + ? true + : false + : Relationships extends [infer R, ...infer Rest] + ? HasFKey extends true + ? true + : HasFKey + : false + +/** + * Returns a boolean representing whether there the foreign key has a unique constraint. + */ +type HasUniqueFKey = Relationships extends [infer R] + ? R extends { foreignKeyName: FKeyName; isOneToOne: true } + ? true + : false + : Relationships extends [infer R, ...infer Rest] + ? HasUniqueFKey extends true + ? true + : HasUniqueFKey + : 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 + +type HasUniqueFKeyToFRel = Relationships extends [infer R] + ? R extends { referencedRelation: FRelName; isOneToOne: true } + ? true + : false + : Relationships extends [infer R, ...infer Rest] + ? HasUniqueFKeyToFRel extends true + ? true + : HasUniqueFKeyToFRel + : false + +/** + * Constructs a type definition for a single field of an object. + * + * @param Schema Database schema. + * @param Row Type of a row in the given table. + * @param Relationships Relationships between different tables in the database. + * @param Field Single field parsed by `ParseQuery`. + */ +type ConstructFieldDefinition< + Schema extends GenericSchema, + Row extends Record, + RelationName, + Relationships, + Field +> = Field extends { star: true } + ? Row + : Field extends { spread: true; original: string; children: unknown[] } + ? GetResultHelper< + Schema, + (Schema['Tables'] & Schema['Views'])[Field['original']]['Row'], + Field['original'], + (Schema['Tables'] & Schema['Views'])[Field['original']] extends { Relationships: infer R } + ? R + : unknown, + Field['children'], + unknown + > + : Field extends { children: [] } + ? {} + : Field extends { name: string; original: string; hint: string; children: unknown[] } + ? { + [_ in Field['name']]: GetResultHelper< + Schema, + (Schema['Tables'] & Schema['Views'])[Field['original']]['Row'], + Field['original'], + (Schema['Tables'] & Schema['Views'])[Field['original']] extends { Relationships: infer R } + ? R + : unknown, + Field['children'], + unknown + > extends infer Child + ? // One-to-one relationship - referencing column(s) has unique/pkey constraint. + HasUniqueFKey< + Field['hint'], + (Schema['Tables'] & Schema['Views'])[Field['original']] extends { + Relationships: infer R + } + ? R + : unknown + > extends true + ? Field extends { inner: true } + ? Child + : Child | null + : Relationships extends unknown[] + ? HasFKey extends true + ? Field extends { inner: true } + ? Child + : Child | null + : Child[] + : Child[] + : never + } + : Field extends { name: string; original: string; children: unknown[] } + ? { + [_ in Field['name']]: GetResultHelper< + Schema, + (Schema['Tables'] & Schema['Views'])[Field['original']]['Row'], + Field['original'], + (Schema['Tables'] & Schema['Views'])[Field['original']] extends { Relationships: infer R } + ? R + : unknown, + Field['children'], + unknown + > extends infer Child + ? // One-to-one relationship - referencing column(s) has unique/pkey constraint. + HasUniqueFKeyToFRel< + RelationName, + (Schema['Tables'] & Schema['Views'])[Field['original']] extends { + Relationships: infer R + } + ? R + : unknown + > extends true + ? Field extends { inner: true } + ? Child + : Child | null + : Relationships extends unknown[] + ? HasFKeyToFRel extends true + ? Field extends { inner: true } + ? Child + : Field extends { left: true } + ? // TODO: This should return null only if the column is actually nullable + Child | null + : Child | null + : Child[] + : Child[] + : never + } + : Field extends { name: string; type: infer T } + ? { [K in Field['name']]: T } + : Field extends { name: string; original: string } + ? Field['original'] extends keyof Row + ? { [K in Field['name']]: Row[Field['original']] } + : Field['original'] extends 'count' + ? { count: number } + : SelectQueryError<`Referencing missing column \`${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 1 or more 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, ''] + +/** + * Reads a consecutive sequence of 1 or more double-quoted letters, + * where letters are `[^"]`. + */ +type ReadQuotedLetters = string extends Input + ? GenericStringError + : Input extends `"${infer Remainder}` + ? ReadQuotedLettersHelper extends [`${infer Letters}`, `${infer Remainder}`] + ? Letters extends '' + ? ParserError<`Expected string at \`${Remainder}\``> + : [Letters, Remainder] + : ReadQuotedLettersHelper + : ParserError<`Not a double-quoted string at \`${Input}\``> + +type ReadQuotedLettersHelper = string extends Input + ? GenericStringError + : Input extends `${infer L}${infer Remainder}` + ? L extends '"' + ? [Acc, Remainder] + : ReadQuotedLettersHelper + : ParserError<`Missing closing double-quote in \`"${Acc}${Input}\``> + +/** + * Parses a (possibly double-quoted) identifier. + * Identifiers are sequences of 1 or more letters. + */ +type ParseIdentifier = ReadLetters extends [ + infer Name, + `${infer Remainder}` +] + ? [Name, `${Remainder}`] + : ReadQuotedLetters extends [infer Name, `${infer Remainder}`] + ? [Name, `${Remainder}`] + : ParserError<`No (possibly double-quoted) identifier at \`${Input}\``> + +/** + * Parses a field without preceding field renaming. + * A field is one of the following: + * - a field with an embedded resource + * - `field(nodes)` + * - `field!hint(nodes)` + * - `field!inner(nodes)` + * - `field!left(nodes)` + * - `field!hint!inner(nodes)` + * - a field without an embedded resource (see {@link ParseFieldWithoutEmbeddedResource}) + */ +type ParseField = Input extends '' + ? ParserError<'Empty string'> + : ParseIdentifier extends [infer Name, `${infer Remainder}`] + ? EatWhitespace extends `!inner${infer Remainder}` + ? ParseEmbeddedResource> extends [infer Fields, `${infer Remainder}`] + ? // `field!inner(nodes)` + [{ name: Name; original: Name; children: Fields; inner: true }, EatWhitespace] + : CreateParserErrorIfRequired< + ParseEmbeddedResource>, + 'Expected embedded resource after `!inner`' + > + : EatWhitespace extends `!left${infer Remainder}` + ? ParseEmbeddedResource> extends [infer Fields, `${infer Remainder}`] + ? // `field!left(nodes)` + [{ name: Name; original: Name; children: Fields; left: true }, EatWhitespace] + : CreateParserErrorIfRequired< + ParseEmbeddedResource>, + 'Expected embedded resource after `!left`' + > + : 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; original: Name; hint: Hint; children: Fields; inner: true }, + EatWhitespace + ] + : CreateParserErrorIfRequired< + ParseEmbeddedResource>, + 'Expected embedded resource after `!inner`' + > + : ParseEmbeddedResource> extends [ + infer Fields, + `${infer Remainder}` + ] + ? // `field!hint(nodes)` + [{ name: Name; original: Name; hint: Hint; children: Fields }, EatWhitespace] + : CreateParserErrorIfRequired< + ParseEmbeddedResource>, + 'Expected embedded resource after `!hint`' + > + : ParserError<'Expected identifier after `!`'> + : ParseEmbeddedResource> extends [infer Fields, `${infer Remainder}`] + ? // `field(nodes)` + [{ name: Name; original: Name; children: Fields }, EatWhitespace] + : ParseEmbeddedResource> extends ParserError + ? // Return error if start of embedded resource was detected but not found. + ParseEmbeddedResource> + : // Otherwise try to match a field without embedded resource. + ParseFieldWithoutEmbeddedResource + : ParserError<`Expected identifier 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 ParseFieldWithoutEmbeddedResource = + ParseFieldWithoutEmbeddedResourceAndAggregation extends [infer Field, `${infer Remainder}`] + ? ParseFieldAggregation> extends [ + `${infer AggregateFunction}`, + `${infer Remainder}` + ] + ? ParseFieldTypeCast> extends [infer Type, `${infer Remainder}`] + ? // `field.aggregate()::type` + [ + Omit & { + name: AggregateFunction + original: AggregateFunction + type: Type + }, + EatWhitespace + ] + : ParseFieldTypeCast> extends ParserError + ? ParseFieldTypeCast> + : // `field.aggregate()` + [ + Omit & { + name: AggregateFunction + original: AggregateFunction + }, + EatWhitespace + ] + : ParseFieldAggregation> extends ParserError + ? ParseFieldAggregation> + : // `field` + [Field, EatWhitespace] + : CreateParserErrorIfRequired< + ParseFieldWithoutEmbeddedResourceAndAggregation, + `Expected field at \`${Input}\`` + > + +/** + * Parses a field excluding embedded resources or aggregation, without preceding field renaming. + * This is one of the following: + * - `field` + * - `field::type` + * - `field->json...` + * - `field->json...::type` + */ +type ParseFieldWithoutEmbeddedResourceAndAggregation = + ParseFieldWithoutEmbeddedResourceAndTypeCast extends [infer Field, `${infer Remainder}`] + ? ParseFieldTypeCast> extends [infer Type, `${infer Remainder}`] + ? // `field::type` or `field->json...::type` + [Omit & { type: Type }, EatWhitespace] + : ParseFieldTypeCast> extends ParserError + ? ParseFieldTypeCast> + : // `field` or `field->json...` + [Field, EatWhitespace] + : CreateParserErrorIfRequired< + ParseFieldWithoutEmbeddedResourceAndTypeCast, + `Expected field at \`${Input}\`` + > + +/** + * Parses a field excluding embedded resources or typecasting, without preceding field renaming. + * This is one of the following: + * - `field` + * - `field->json...` + */ +type ParseFieldWithoutEmbeddedResourceAndTypeCast = + ParseIdentifier extends [infer Name, `${infer Remainder}`] + ? ParseJsonAccessor> extends [ + infer PropertyName, + infer PropertyType, + `${infer Remainder}` + ] + ? // `field->json...` + [ + { name: PropertyName; original: PropertyName; type: PropertyType }, + EatWhitespace + ] + : // `field` + [{ name: Name; original: Name }, EatWhitespace] + : ParserError<`Expected field at \`${Input}\``> + +/** + * Parses a field typecast (`::type`), returning a tuple of ["Type", "Remainder of text"] + * or the original string input indicating that no typecast was found. + */ +type ParseFieldTypeCast = EatWhitespace extends `::${infer Remainder}` + ? ParseIdentifier> extends [`${infer CastType}`, `${infer Remainder}`] + ? // Ensure that `CastType` is a valid type. + CastType extends PostgreSQLTypes + ? [TypeScriptTypes, EatWhitespace] + : ParserError<`Invalid type for \`::\` operator \`${CastType}\``> + : ParserError<`Invalid type for \`::\` operator at \`${Remainder}\``> + : Input + +/** + * Parses a field aggregation (`.max()`), returning a tuple of ["Aggregate function", "Remainder of text"] + * or the original string input indicating that no aggregation was found. + */ +type ParseFieldAggregation = + EatWhitespace extends `.${infer Remainder}` + ? ParseIdentifier> extends [ + `${infer FunctionName}`, + `${infer Remainder}` + ] + ? // Ensure that aggregation function is valid. + FunctionName extends AggregateFunctions + ? EatWhitespace extends `()${infer Remainder}` + ? [FunctionName, EatWhitespace] + : ParserError<`Expected \`()\` after \`.\` operator \`${FunctionName}\``> + : ParserError<`Invalid type for \`.\` operator \`${FunctionName}\``> + : ParserError<`Invalid type for \`.\` operator at \`${Remainder}\``> + : Input + +/** + * 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}` + ? [{ star: true }, EatWhitespace] + : // `...field` + Input extends `...${infer Remainder}` + ? ParseField> extends [infer Field, `${infer Remainder}`] + ? Field extends { children: unknown[] } + ? [Prettify<{ spread: true } & Field>, EatWhitespace] + : ParserError<'Unable to parse spread resource'> + : ParserError<'Unable to parse spread resource'> + : ParseIdentifier extends [infer Name, `${infer Remainder}`] + ? EatWhitespace extends `::${infer _Remainder}` + ? // `field::` + // Special case to detect type-casting before renaming. + ParseField + : EatWhitespace extends `:${infer Remainder}` + ? // `renamed_field:` + ParseField> extends [infer Field, `${infer Remainder}`] + ? Field extends { name: string } + ? [Prettify & { name: Name }>, EatWhitespace] + : ParserError<`Unable to parse renamed field`> + : ParserError<`Unable to parse renamed field`> + : // Otherwise, just parse it as a field without renaming. + ParseField + : 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"] + * or the original string input indicating that no opening `->` was found. + */ +type ParseJsonAccessor = Input extends `->${infer Remainder}` + ? Remainder extends `>${infer Remainder}` + ? ParseIdentifier extends [infer Name, `${infer Remainder}`] + ? [Name, string, 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 `->`'> + : 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}` + ? ParseNodes> extends [infer Fields, `${infer Remainder}`] + ? EatWhitespace extends `)${infer Remainder}` + ? [Fields, EatWhitespace] + : ParserError<`Expected ")"`> + : // If no nodes were detected, check for `)` for empty embedded resources `()`. + ParseNodes> extends ParserError + ? EatWhitespace extends `)${infer Remainder}` + ? [[], EatWhitespace] + : ParseNodes> + : ParserError<'Expected embedded resource fields or `)`'> + : 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< + Schema extends GenericSchema, + Row extends Record, + RelationName, + Relationships, + Fields extends unknown[], + Acc +> = Fields extends [infer R] + ? ConstructFieldDefinition extends SelectQueryError< + infer E + > + ? SelectQueryError + : GetResultHelper< + Schema, + Row, + RelationName, + Relationships, + [], + ConstructFieldDefinition & Acc + > + : Fields extends [infer R, ...infer Rest] + ? ConstructFieldDefinition extends SelectQueryError< + infer E + > + ? SelectQueryError + : GetResultHelper< + Schema, + Row, + RelationName, + Relationships, + Rest, + ConstructFieldDefinition & Acc + > + : Prettify + +/** + * Constructs a type definition for an object based on a given PostgREST query. + * + * @param Schema Database schema. + * @param Row Type of a row in the given table. + * @param Relationships Relationships between different tables in the database. + * @param Query Select query string literal to parse. + */ +export type GetResult< + Schema extends GenericSchema, + Row extends Record, + RelationName, + Relationships, + Query extends string +> = ParseQuery extends unknown[] + ? GetResultHelper, unknown> + : ParseQuery diff --git a/test/basic.ts b/test/basic.ts index 8a4d5581..bb0ab768 100644 --- a/test/basic.ts +++ b/test/basic.ts @@ -7,46 +7,15 @@ const postgrest = new PostgrestClient(REST_URL) test('basic select table', async () => { const res = await postgrest.from('users').select() 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", + "count": null, + "data": Array [ + Object { + "age_range": "[1,2)", + "catchphrase": "'cat' 'fat'", + "data": null, + "status": "ONLINE", + "username": "supabot", }, Object { "age_range": "[25,35)", @@ -94,9 +63,6 @@ Object { test('basic select view', async () => { const res = await postgrest.from('updatable_view').select() expect(res).toMatchInlineSnapshot(` -Object { - "count": null, - "data": Array [ Object { "count": null, "data": Array [ @@ -880,37 +846,13 @@ test('allow ordering on JSON column', async () => { .select() .order('data->something' as any) 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", + Array [ + Object { + "age_range": "[1,2)", + "catchphrase": "'cat' 'fat'", + "data": null, + "status": "ONLINE", + "username": "supabot", }, Object { "age_range": "[25,35)", @@ -1023,9 +965,6 @@ test('select with head:true, count:estimated', async () => { test('select with count:exact', async () => { const res = await postgrest.from('users').select('*', { count: 'exact' }) expect(res).toMatchInlineSnapshot(` -Object { - "count": 5, - "data": Array [ Object { "count": 5, "data": Array [ diff --git a/test/filters.ts b/test/filters.ts index 2c439666..8348f0a4 100644 --- a/test/filters.ts +++ b/test/filters.ts @@ -6,9 +6,6 @@ const postgrest = new PostgrestClient('http://localhost:3000') test('not', async () => { const res = await postgrest.from('users').select('status').not('status', 'eq', 'OFFLINE') expect(res).toMatchInlineSnapshot(` -Object { - "count": null, - "data": Array [ Object { "count": null, "data": Array [ @@ -77,9 +74,6 @@ test('eq', async () => { test('neq', async () => { const res = await postgrest.from('users').select('username').neq('username', 'supabot') expect(res).toMatchInlineSnapshot(` -Object { - "count": null, - "data": Array [ Object { "count": null, "data": Array [ @@ -333,9 +327,6 @@ test('in', async () => { const statuses = ['ONLINE', 'OFFLINE'] as const const res = await postgrest.from('users').select('status').in('status', statuses) expect(res).toMatchInlineSnapshot(` -Object { - "count": null, - "data": Array [ Object { "count": null, "data": Array [ @@ -436,9 +427,6 @@ test('rangeGt', async () => { test('rangeGte', async () => { const res = await postgrest.from('users').select('age_range').rangeGte('age_range', '[2,25)') expect(res).toMatchInlineSnapshot(` -Object { - "count": null, - "data": Array [ Object { "count": null, "data": Array [ @@ -505,9 +493,6 @@ test('rangeAdjacent', async () => { test('overlaps', async () => { const res = await postgrest.from('users').select('age_range').overlaps('age_range', '[2,25)') expect(res).toMatchInlineSnapshot(` -Object { - "count": null, - "data": Array [ Object { "count": null, "data": Array [ diff --git a/test/index.test-d.ts b/test/index.test-d.ts index 516529e9..65598031 100644 --- a/test/index.test-d.ts +++ b/test/index.test-d.ts @@ -85,7 +85,7 @@ const postgrest = new PostgrestClient(REST_URL) if (error) { throw new Error(error.message) } - expectType<{ message: string | null; users: { count: number } }>(data) + expectType<{ message: string | null; users: { count: number } | null }>(data) } // json accessor in select query diff --git a/test/relationships.ts b/test/relationships.ts index 4d8b612d..9a89100e 100644 --- a/test/relationships.ts +++ b/test/relationships.ts @@ -2,7 +2,7 @@ import { PostgrestClient } from '../src/index' import { Database } from './types' const REST_URL = 'http://localhost:3000' -const postgrest = new PostgrestClient(REST_URL) +const postgrest = new PostgrestClient(REST_URL) const userColumn: 'catchphrase' | 'username' = 'username' @@ -1048,7 +1048,6 @@ test('!left join on zero to one with valid relation', async () => { .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(` diff --git a/test/resource-embedding.ts b/test/resource-embedding.ts index a8de09b8..b3cca1a8 100644 --- a/test/resource-embedding.ts +++ b/test/resource-embedding.ts @@ -6,11 +6,9 @@ const postgrest = new PostgrestClient('http://localhost:3000') test('embedded select', async () => { const res = await postgrest.from('users').select('messages(*)') expect(res).toMatchInlineSnapshot(` -Object { - "count": null, - "data": Array [ Object { - "messages": Array [ + "count": null, + "data": Array [ Object { "messages": Array [ Object { @@ -37,42 +35,23 @@ Object { ], }, 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", + "messages": Array [], }, Object { - "channel_id": 3, - "data": null, - "id": 4, - "message": "Some message on channel wihtout details", - "username": "supabot", + "messages": Array [], + }, + Object { + "messages": Array [], }, Object { "messages": Array [], }, ], - }, - Object { - "messages": Array [], - }, - Object { - "messages": Array [], - }, - Object { - "messages": Array [], - }, - Object { - "messages": Array [], - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`) + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) describe('embedded filters', () => { diff --git a/test/transforms.ts b/test/transforms.ts index a1fab100..e6518910 100644 --- a/test/transforms.ts +++ b/test/transforms.ts @@ -8,32 +8,15 @@ const postgrest = new PostgrestClient('http://localhost:3000') test('order', async () => { const res = await postgrest.from('users').select().order('username', { ascending: false }) 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", + "count": null, + "data": Array [ + Object { + "age_range": "[1,2)", + "catchphrase": "'cat' 'fat'", + "data": null, + "status": "ONLINE", + "username": "supabot", }, Object { "age_range": "[25,35)", @@ -141,32 +124,15 @@ test('limit', async () => { test('range', async () => { const res = await postgrest.from('users').select().range(1, 3) 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", + "count": null, + "data": Array [ + Object { + "age_range": "[25,35)", + "catchphrase": "'bat' 'cat'", + "data": null, + "status": "OFFLINE", + "username": "kiwicopple", }, Object { "age_range": "[25,35)", From afc0cc997ba3e1e89e3a9fd95645f08de6cffe93 Mon Sep 17 00:00:00 2001 From: avallete Date: Sat, 28 Sep 2024 01:22:10 +0200 Subject: [PATCH 090/110] fix: prettier --- src/PostgrestClient.ts | 2 +- src/PostgrestFilterBuilder.ts | 11 ++++++++-- src/PostgrestQueryBuilder.ts | 35 +++++++++++++++++++++++++------- src/PostgrestTransformBuilder.ts | 6 +++--- test/relationships.ts | 3 ++- 5 files changed, 43 insertions(+), 14 deletions(-) diff --git a/src/PostgrestClient.ts b/src/PostgrestClient.ts index 0c5d2481..60708087 100644 --- a/src/PostgrestClient.ts +++ b/src/PostgrestClient.ts @@ -22,7 +22,7 @@ export default class PostgrestClient< Schema extends GenericSchema = Database[SchemaName] extends GenericSchema ? Database[SchemaName] : any, - TypesVersion extends "next" | undefined = undefined + TypesVersion extends 'next' | undefined = undefined > { url: string headers: Record diff --git a/src/PostgrestFilterBuilder.ts b/src/PostgrestFilterBuilder.ts index ade97116..10cb59b0 100644 --- a/src/PostgrestFilterBuilder.ts +++ b/src/PostgrestFilterBuilder.ts @@ -31,8 +31,15 @@ export default class PostgrestFilterBuilder< Result, TypesVersion, RelationName = unknown, - Relationships = unknown, -> extends PostgrestTransformBuilder { + Relationships = unknown +> extends PostgrestTransformBuilder< + Schema, + Row, + Result, + RelationName, + Relationships, + TypesVersion +> { eq( column: ColumnName, value: NonNullable diff --git a/src/PostgrestQueryBuilder.ts b/src/PostgrestQueryBuilder.ts index 91dd688a..daf55cbf 100644 --- a/src/PostgrestQueryBuilder.ts +++ b/src/PostgrestQueryBuilder.ts @@ -9,7 +9,7 @@ export default class PostgrestQueryBuilder< Relation extends GenericTable | GenericView, TypesVersion, RelationName = unknown, - Relationships = Relation extends { Relationships: infer R } ? R : unknown, + Relationships = Relation extends { Relationships: infer R } ? R : unknown > { url: URL headers: Record @@ -58,9 +58,9 @@ export default class PostgrestQueryBuilder< */ select< Query extends string = '*', - ResultOne = TypesVersion extends "next" - ? GetResultV2 - : GetResult + ResultOne = TypesVersion extends 'next' + ? GetResultV2 + : GetResult >( columns?: Query, { @@ -70,7 +70,14 @@ export default class PostgrestQueryBuilder< head?: boolean count?: 'exact' | 'planned' | 'estimated' } = {} - ): PostgrestFilterBuilder { + ): PostgrestFilterBuilder< + Schema, + Relation['Row'], + ResultOne[], + RelationName, + Relationships, + TypesVersion + > { const method = head ? 'HEAD' : 'GET' // Remove whitespaces except when quoted let quoted = false @@ -107,14 +114,28 @@ export default class PostgrestQueryBuilder< options?: { count?: 'exact' | 'planned' | 'estimated' } - ): PostgrestFilterBuilder + ): PostgrestFilterBuilder< + Schema, + Relation['Row'], + null, + RelationName, + Relationships, + TypesVersion + > insert( values: Row[], options?: { count?: 'exact' | 'planned' | 'estimated' defaultToNull?: boolean } - ): PostgrestFilterBuilder + ): PostgrestFilterBuilder< + Schema, + Relation['Row'], + null, + RelationName, + Relationships, + TypesVersion + > /** * Perform an INSERT into the table or view. * diff --git a/src/PostgrestTransformBuilder.ts b/src/PostgrestTransformBuilder.ts index 1d7094a5..db1b3049 100644 --- a/src/PostgrestTransformBuilder.ts +++ b/src/PostgrestTransformBuilder.ts @@ -22,9 +22,9 @@ export default class PostgrestTransformBuilder< */ select< Query extends string = '*', - NewResultOne = TypesVersion extends "next" - ? GetResultV2 - : GetResult + NewResultOne = TypesVersion extends 'next' + ? GetResultV2 + : GetResult >( columns?: Query ): PostgrestTransformBuilder { diff --git a/test/relationships.ts b/test/relationships.ts index 9a89100e..1aa06649 100644 --- a/test/relationships.ts +++ b/test/relationships.ts @@ -2,9 +2,10 @@ import { PostgrestClient } from '../src/index' import { Database } from './types' const REST_URL = 'http://localhost:3000' -const postgrest = new PostgrestClient(REST_URL) +const postgrest = new PostgrestClient(REST_URL) const userColumn: 'catchphrase' | 'username' = 'username' +let other: 'col1' | 'col2' = 'col1' export const selectParams = { manyToOne: { from: 'messages', select: 'user:users(*)' }, From d4d39261a33423823261c9df911c3eebf37b5c5b Mon Sep 17 00:00:00 2001 From: avallete Date: Sat, 28 Sep 2024 01:35:59 +0200 Subject: [PATCH 091/110] chore: fix typos --- test/relationships.ts | 1 - test/types.ts | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/test/relationships.ts b/test/relationships.ts index 1aa06649..6d9d8bb3 100644 --- a/test/relationships.ts +++ b/test/relationships.ts @@ -5,7 +5,6 @@ const REST_URL = 'http://localhost:3000' const postgrest = new PostgrestClient(REST_URL) const userColumn: 'catchphrase' | 'username' = 'username' -let other: 'col1' | 'col2' = 'col1' export const selectParams = { manyToOne: { from: 'messages', select: 'user:users(*)' }, diff --git a/test/types.ts b/test/types.ts index 92d18185..deed0fa9 100644 --- a/test/types.ts +++ b/test/types.ts @@ -1,4 +1,5 @@ export type Json = string | number | boolean | null | { [key: string]: Json | undefined } | Json[] + export type Database = { personal: { Tables: { From 237034a2c011c9f84f4050fd59d42003acd2882f Mon Sep 17 00:00:00 2001 From: avallete Date: Mon, 30 Sep 2024 21:32:19 +0200 Subject: [PATCH 092/110] Revert "feat: make new select-query-parser available under next flag" This reverts commit 82fc09966b2ae8a1c8ac60e43d57931c1ad42987. --- src/PostgrestClient.ts | 12 +- src/PostgrestFilterBuilder.ts | 10 +- src/PostgrestQueryBuilder.ts | 35 +- src/PostgrestTransformBuilder.ts | 10 +- src/select-query-parser.ts | 706 ------------------------------- test/basic.ts | 91 +++- test/filters.ts | 15 + test/index.test-d.ts | 2 +- test/relationships.ts | 3 +- test/resource-embedding.ts | 45 +- test/transforms.ts | 66 ++- 11 files changed, 191 insertions(+), 804 deletions(-) delete mode 100644 src/select-query-parser.ts diff --git a/src/PostgrestClient.ts b/src/PostgrestClient.ts index 60708087..915ddc16 100644 --- a/src/PostgrestClient.ts +++ b/src/PostgrestClient.ts @@ -21,8 +21,7 @@ export default class PostgrestClient< : string & keyof Database, Schema extends GenericSchema = Database[SchemaName] extends GenericSchema ? Database[SchemaName] - : any, - TypesVersion extends 'next' | undefined = undefined + : any > { url: string headers: Record @@ -60,16 +59,16 @@ export default class PostgrestClient< from< TableName extends string & keyof Schema['Tables'], Table extends Schema['Tables'][TableName] - >(relation: TableName): PostgrestQueryBuilder + >(relation: TableName): PostgrestQueryBuilder from( relation: ViewName - ): PostgrestQueryBuilder + ): PostgrestQueryBuilder /** * Perform a query on a table or a view. * * @param relation - The table or view name to query */ - from(relation: string): PostgrestQueryBuilder { + from(relation: string): PostgrestQueryBuilder { const url = new URL(`${this.url}/${relation}`) return new PostgrestQueryBuilder(url, { headers: { ...this.headers }, @@ -141,8 +140,7 @@ export default class PostgrestClient< ? Fn['Returns'][number] : never : never, - Fn['Returns'], - TypesVersion + Fn['Returns'] > { let method: 'HEAD' | 'GET' | 'POST' const url = new URL(`${this.url}/rpc/${fn}`) diff --git a/src/PostgrestFilterBuilder.ts b/src/PostgrestFilterBuilder.ts index 10cb59b0..21cc4090 100644 --- a/src/PostgrestFilterBuilder.ts +++ b/src/PostgrestFilterBuilder.ts @@ -29,17 +29,9 @@ export default class PostgrestFilterBuilder< Schema extends GenericSchema, Row extends Record, Result, - TypesVersion, RelationName = unknown, Relationships = unknown -> extends PostgrestTransformBuilder< - Schema, - Row, - Result, - RelationName, - Relationships, - TypesVersion -> { +> extends PostgrestTransformBuilder { eq( column: ColumnName, value: NonNullable diff --git a/src/PostgrestQueryBuilder.ts b/src/PostgrestQueryBuilder.ts index daf55cbf..44e7320a 100644 --- a/src/PostgrestQueryBuilder.ts +++ b/src/PostgrestQueryBuilder.ts @@ -1,13 +1,11 @@ import PostgrestBuilder from './PostgrestBuilder' import PostgrestFilterBuilder from './PostgrestFilterBuilder' -import { GetResult as GetResultV2 } from './select-query-parser/result' -import { GetResult } from './select-query-parser' +import { GetResult } from './select-query-parser/result' import { Fetch, GenericSchema, GenericTable, GenericView } from './types' export default class PostgrestQueryBuilder< Schema extends GenericSchema, Relation extends GenericTable | GenericView, - TypesVersion, RelationName = unknown, Relationships = Relation extends { Relationships: infer R } ? R : unknown > { @@ -58,9 +56,7 @@ export default class PostgrestQueryBuilder< */ select< Query extends string = '*', - ResultOne = TypesVersion extends 'next' - ? GetResultV2 - : GetResult + ResultOne = GetResult >( columns?: Query, { @@ -70,14 +66,7 @@ export default class PostgrestQueryBuilder< head?: boolean count?: 'exact' | 'planned' | 'estimated' } = {} - ): PostgrestFilterBuilder< - Schema, - Relation['Row'], - ResultOne[], - RelationName, - Relationships, - TypesVersion - > { + ): PostgrestFilterBuilder { const method = head ? 'HEAD' : 'GET' // Remove whitespaces except when quoted let quoted = false @@ -114,28 +103,14 @@ export default class PostgrestQueryBuilder< options?: { count?: 'exact' | 'planned' | 'estimated' } - ): PostgrestFilterBuilder< - Schema, - Relation['Row'], - null, - RelationName, - Relationships, - TypesVersion - > + ): PostgrestFilterBuilder insert( values: Row[], options?: { count?: 'exact' | 'planned' | 'estimated' defaultToNull?: boolean } - ): PostgrestFilterBuilder< - Schema, - Relation['Row'], - null, - RelationName, - Relationships, - TypesVersion - > + ): PostgrestFilterBuilder /** * Perform an INSERT into the table or view. * diff --git a/src/PostgrestTransformBuilder.ts b/src/PostgrestTransformBuilder.ts index db1b3049..4791702c 100644 --- a/src/PostgrestTransformBuilder.ts +++ b/src/PostgrestTransformBuilder.ts @@ -1,6 +1,5 @@ import PostgrestBuilder from './PostgrestBuilder' -import { GetResult as GetResultV2 } from './select-query-parser/result' -import { GetResult } from './select-query-parser' +import { GetResult } from './select-query-parser/result' import { GenericSchema } from './types' export default class PostgrestTransformBuilder< @@ -8,8 +7,7 @@ export default class PostgrestTransformBuilder< Row extends Record, Result, RelationName = unknown, - Relationships = unknown, - TypesVersion = unknown + Relationships = unknown > extends PostgrestBuilder { /** * Perform a SELECT on the query result. @@ -22,9 +20,7 @@ export default class PostgrestTransformBuilder< */ select< Query extends string = '*', - NewResultOne = TypesVersion extends 'next' - ? GetResultV2 - : GetResult + NewResultOne = GetResult >( columns?: Query ): PostgrestTransformBuilder { diff --git a/src/select-query-parser.ts b/src/select-query-parser.ts deleted file mode 100644 index 0c5c40f1..00000000 --- a/src/select-query-parser.ts +++ /dev/null @@ -1,706 +0,0 @@ -// 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 { GenericSchema, Prettify } from './types' - -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 | '_' - -type Json = string | number | boolean | null | { [key: string]: Json } | Json[] - -type SingleValuePostgreSQLTypes = - | 'bool' - | 'int2' - | 'int4' - | 'int8' - | 'float4' - | 'float8' - | 'numeric' - | 'bytea' - | 'bpchar' - | 'varchar' - | 'date' - | 'text' - | 'citext' - | 'time' - | 'timetz' - | 'timestamp' - | 'timestamptz' - | 'uuid' - | 'vector' - | 'json' - | 'jsonb' - | 'void' - | 'record' - | string - -type ArrayPostgreSQLTypes = `_${SingleValuePostgreSQLTypes}` - -type PostgreSQLTypes = SingleValuePostgreSQLTypes | ArrayPostgreSQLTypes - -type TypeScriptSingleValueTypes = T extends 'bool' - ? boolean - : T extends 'int2' | 'int4' | 'int8' | 'float4' | 'float8' | 'numeric' - ? number - : T extends - | 'bytea' - | 'bpchar' - | 'varchar' - | 'date' - | 'text' - | 'citext' - | 'time' - | 'timetz' - | 'timestamp' - | 'timestamptz' - | 'uuid' - | 'vector' - ? string - : T extends 'json' | 'jsonb' - ? Json - : T extends 'void' - ? undefined - : T extends 'record' - ? Record - : unknown - -type AggregateFunctions = 'count' | 'sum' | 'avg' | 'min' | 'max' - -type StripUnderscore = T extends `_${infer U}` ? U : T - -type TypeScriptTypes = T extends ArrayPostgreSQLTypes - ? TypeScriptSingleValueTypes>>[] - : TypeScriptSingleValueTypes - -/** - * Parser errors. - */ -type ParserError = { error: true } & Message -type GenericStringError = ParserError<'Received a generic string'> -export type SelectQueryError = { error: true } & Message - -/** - * Creates a new {@link ParserError} if the given input is not already a parser error. - */ -type CreateParserErrorIfRequired = Input extends ParserError - ? Input - : ParserError - -/** - * Trims whitespace from the left of the input. - */ -type EatWhitespace = string extends Input - ? GenericStringError - : Input extends `${Whitespace}${infer Remainder}` - ? EatWhitespace - : Input - -/** - * Returns a boolean representing whether there is a foreign key with the given name. - */ -type HasFKey = Relationships extends [infer R] - ? R extends { foreignKeyName: FKeyName } - ? true - : false - : Relationships extends [infer R, ...infer Rest] - ? HasFKey extends true - ? true - : HasFKey - : false - -/** - * Returns a boolean representing whether there the foreign key has a unique constraint. - */ -type HasUniqueFKey = Relationships extends [infer R] - ? R extends { foreignKeyName: FKeyName; isOneToOne: true } - ? true - : false - : Relationships extends [infer R, ...infer Rest] - ? HasUniqueFKey extends true - ? true - : HasUniqueFKey - : 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 - -type HasUniqueFKeyToFRel = Relationships extends [infer R] - ? R extends { referencedRelation: FRelName; isOneToOne: true } - ? true - : false - : Relationships extends [infer R, ...infer Rest] - ? HasUniqueFKeyToFRel extends true - ? true - : HasUniqueFKeyToFRel - : false - -/** - * Constructs a type definition for a single field of an object. - * - * @param Schema Database schema. - * @param Row Type of a row in the given table. - * @param Relationships Relationships between different tables in the database. - * @param Field Single field parsed by `ParseQuery`. - */ -type ConstructFieldDefinition< - Schema extends GenericSchema, - Row extends Record, - RelationName, - Relationships, - Field -> = Field extends { star: true } - ? Row - : Field extends { spread: true; original: string; children: unknown[] } - ? GetResultHelper< - Schema, - (Schema['Tables'] & Schema['Views'])[Field['original']]['Row'], - Field['original'], - (Schema['Tables'] & Schema['Views'])[Field['original']] extends { Relationships: infer R } - ? R - : unknown, - Field['children'], - unknown - > - : Field extends { children: [] } - ? {} - : Field extends { name: string; original: string; hint: string; children: unknown[] } - ? { - [_ in Field['name']]: GetResultHelper< - Schema, - (Schema['Tables'] & Schema['Views'])[Field['original']]['Row'], - Field['original'], - (Schema['Tables'] & Schema['Views'])[Field['original']] extends { Relationships: infer R } - ? R - : unknown, - Field['children'], - unknown - > extends infer Child - ? // One-to-one relationship - referencing column(s) has unique/pkey constraint. - HasUniqueFKey< - Field['hint'], - (Schema['Tables'] & Schema['Views'])[Field['original']] extends { - Relationships: infer R - } - ? R - : unknown - > extends true - ? Field extends { inner: true } - ? Child - : Child | null - : Relationships extends unknown[] - ? HasFKey extends true - ? Field extends { inner: true } - ? Child - : Child | null - : Child[] - : Child[] - : never - } - : Field extends { name: string; original: string; children: unknown[] } - ? { - [_ in Field['name']]: GetResultHelper< - Schema, - (Schema['Tables'] & Schema['Views'])[Field['original']]['Row'], - Field['original'], - (Schema['Tables'] & Schema['Views'])[Field['original']] extends { Relationships: infer R } - ? R - : unknown, - Field['children'], - unknown - > extends infer Child - ? // One-to-one relationship - referencing column(s) has unique/pkey constraint. - HasUniqueFKeyToFRel< - RelationName, - (Schema['Tables'] & Schema['Views'])[Field['original']] extends { - Relationships: infer R - } - ? R - : unknown - > extends true - ? Field extends { inner: true } - ? Child - : Child | null - : Relationships extends unknown[] - ? HasFKeyToFRel extends true - ? Field extends { inner: true } - ? Child - : Field extends { left: true } - ? // TODO: This should return null only if the column is actually nullable - Child | null - : Child | null - : Child[] - : Child[] - : never - } - : Field extends { name: string; type: infer T } - ? { [K in Field['name']]: T } - : Field extends { name: string; original: string } - ? Field['original'] extends keyof Row - ? { [K in Field['name']]: Row[Field['original']] } - : Field['original'] extends 'count' - ? { count: number } - : SelectQueryError<`Referencing missing column \`${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 1 or more 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, ''] - -/** - * Reads a consecutive sequence of 1 or more double-quoted letters, - * where letters are `[^"]`. - */ -type ReadQuotedLetters = string extends Input - ? GenericStringError - : Input extends `"${infer Remainder}` - ? ReadQuotedLettersHelper extends [`${infer Letters}`, `${infer Remainder}`] - ? Letters extends '' - ? ParserError<`Expected string at \`${Remainder}\``> - : [Letters, Remainder] - : ReadQuotedLettersHelper - : ParserError<`Not a double-quoted string at \`${Input}\``> - -type ReadQuotedLettersHelper = string extends Input - ? GenericStringError - : Input extends `${infer L}${infer Remainder}` - ? L extends '"' - ? [Acc, Remainder] - : ReadQuotedLettersHelper - : ParserError<`Missing closing double-quote in \`"${Acc}${Input}\``> - -/** - * Parses a (possibly double-quoted) identifier. - * Identifiers are sequences of 1 or more letters. - */ -type ParseIdentifier = ReadLetters extends [ - infer Name, - `${infer Remainder}` -] - ? [Name, `${Remainder}`] - : ReadQuotedLetters extends [infer Name, `${infer Remainder}`] - ? [Name, `${Remainder}`] - : ParserError<`No (possibly double-quoted) identifier at \`${Input}\``> - -/** - * Parses a field without preceding field renaming. - * A field is one of the following: - * - a field with an embedded resource - * - `field(nodes)` - * - `field!hint(nodes)` - * - `field!inner(nodes)` - * - `field!left(nodes)` - * - `field!hint!inner(nodes)` - * - a field without an embedded resource (see {@link ParseFieldWithoutEmbeddedResource}) - */ -type ParseField = Input extends '' - ? ParserError<'Empty string'> - : ParseIdentifier extends [infer Name, `${infer Remainder}`] - ? EatWhitespace extends `!inner${infer Remainder}` - ? ParseEmbeddedResource> extends [infer Fields, `${infer Remainder}`] - ? // `field!inner(nodes)` - [{ name: Name; original: Name; children: Fields; inner: true }, EatWhitespace] - : CreateParserErrorIfRequired< - ParseEmbeddedResource>, - 'Expected embedded resource after `!inner`' - > - : EatWhitespace extends `!left${infer Remainder}` - ? ParseEmbeddedResource> extends [infer Fields, `${infer Remainder}`] - ? // `field!left(nodes)` - [{ name: Name; original: Name; children: Fields; left: true }, EatWhitespace] - : CreateParserErrorIfRequired< - ParseEmbeddedResource>, - 'Expected embedded resource after `!left`' - > - : 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; original: Name; hint: Hint; children: Fields; inner: true }, - EatWhitespace - ] - : CreateParserErrorIfRequired< - ParseEmbeddedResource>, - 'Expected embedded resource after `!inner`' - > - : ParseEmbeddedResource> extends [ - infer Fields, - `${infer Remainder}` - ] - ? // `field!hint(nodes)` - [{ name: Name; original: Name; hint: Hint; children: Fields }, EatWhitespace] - : CreateParserErrorIfRequired< - ParseEmbeddedResource>, - 'Expected embedded resource after `!hint`' - > - : ParserError<'Expected identifier after `!`'> - : ParseEmbeddedResource> extends [infer Fields, `${infer Remainder}`] - ? // `field(nodes)` - [{ name: Name; original: Name; children: Fields }, EatWhitespace] - : ParseEmbeddedResource> extends ParserError - ? // Return error if start of embedded resource was detected but not found. - ParseEmbeddedResource> - : // Otherwise try to match a field without embedded resource. - ParseFieldWithoutEmbeddedResource - : ParserError<`Expected identifier 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 ParseFieldWithoutEmbeddedResource = - ParseFieldWithoutEmbeddedResourceAndAggregation extends [infer Field, `${infer Remainder}`] - ? ParseFieldAggregation> extends [ - `${infer AggregateFunction}`, - `${infer Remainder}` - ] - ? ParseFieldTypeCast> extends [infer Type, `${infer Remainder}`] - ? // `field.aggregate()::type` - [ - Omit & { - name: AggregateFunction - original: AggregateFunction - type: Type - }, - EatWhitespace - ] - : ParseFieldTypeCast> extends ParserError - ? ParseFieldTypeCast> - : // `field.aggregate()` - [ - Omit & { - name: AggregateFunction - original: AggregateFunction - }, - EatWhitespace - ] - : ParseFieldAggregation> extends ParserError - ? ParseFieldAggregation> - : // `field` - [Field, EatWhitespace] - : CreateParserErrorIfRequired< - ParseFieldWithoutEmbeddedResourceAndAggregation, - `Expected field at \`${Input}\`` - > - -/** - * Parses a field excluding embedded resources or aggregation, without preceding field renaming. - * This is one of the following: - * - `field` - * - `field::type` - * - `field->json...` - * - `field->json...::type` - */ -type ParseFieldWithoutEmbeddedResourceAndAggregation = - ParseFieldWithoutEmbeddedResourceAndTypeCast extends [infer Field, `${infer Remainder}`] - ? ParseFieldTypeCast> extends [infer Type, `${infer Remainder}`] - ? // `field::type` or `field->json...::type` - [Omit & { type: Type }, EatWhitespace] - : ParseFieldTypeCast> extends ParserError - ? ParseFieldTypeCast> - : // `field` or `field->json...` - [Field, EatWhitespace] - : CreateParserErrorIfRequired< - ParseFieldWithoutEmbeddedResourceAndTypeCast, - `Expected field at \`${Input}\`` - > - -/** - * Parses a field excluding embedded resources or typecasting, without preceding field renaming. - * This is one of the following: - * - `field` - * - `field->json...` - */ -type ParseFieldWithoutEmbeddedResourceAndTypeCast = - ParseIdentifier extends [infer Name, `${infer Remainder}`] - ? ParseJsonAccessor> extends [ - infer PropertyName, - infer PropertyType, - `${infer Remainder}` - ] - ? // `field->json...` - [ - { name: PropertyName; original: PropertyName; type: PropertyType }, - EatWhitespace - ] - : // `field` - [{ name: Name; original: Name }, EatWhitespace] - : ParserError<`Expected field at \`${Input}\``> - -/** - * Parses a field typecast (`::type`), returning a tuple of ["Type", "Remainder of text"] - * or the original string input indicating that no typecast was found. - */ -type ParseFieldTypeCast = EatWhitespace extends `::${infer Remainder}` - ? ParseIdentifier> extends [`${infer CastType}`, `${infer Remainder}`] - ? // Ensure that `CastType` is a valid type. - CastType extends PostgreSQLTypes - ? [TypeScriptTypes, EatWhitespace] - : ParserError<`Invalid type for \`::\` operator \`${CastType}\``> - : ParserError<`Invalid type for \`::\` operator at \`${Remainder}\``> - : Input - -/** - * Parses a field aggregation (`.max()`), returning a tuple of ["Aggregate function", "Remainder of text"] - * or the original string input indicating that no aggregation was found. - */ -type ParseFieldAggregation = - EatWhitespace extends `.${infer Remainder}` - ? ParseIdentifier> extends [ - `${infer FunctionName}`, - `${infer Remainder}` - ] - ? // Ensure that aggregation function is valid. - FunctionName extends AggregateFunctions - ? EatWhitespace extends `()${infer Remainder}` - ? [FunctionName, EatWhitespace] - : ParserError<`Expected \`()\` after \`.\` operator \`${FunctionName}\``> - : ParserError<`Invalid type for \`.\` operator \`${FunctionName}\``> - : ParserError<`Invalid type for \`.\` operator at \`${Remainder}\``> - : Input - -/** - * 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}` - ? [{ star: true }, EatWhitespace] - : // `...field` - Input extends `...${infer Remainder}` - ? ParseField> extends [infer Field, `${infer Remainder}`] - ? Field extends { children: unknown[] } - ? [Prettify<{ spread: true } & Field>, EatWhitespace] - : ParserError<'Unable to parse spread resource'> - : ParserError<'Unable to parse spread resource'> - : ParseIdentifier extends [infer Name, `${infer Remainder}`] - ? EatWhitespace extends `::${infer _Remainder}` - ? // `field::` - // Special case to detect type-casting before renaming. - ParseField - : EatWhitespace extends `:${infer Remainder}` - ? // `renamed_field:` - ParseField> extends [infer Field, `${infer Remainder}`] - ? Field extends { name: string } - ? [Prettify & { name: Name }>, EatWhitespace] - : ParserError<`Unable to parse renamed field`> - : ParserError<`Unable to parse renamed field`> - : // Otherwise, just parse it as a field without renaming. - ParseField - : 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"] - * or the original string input indicating that no opening `->` was found. - */ -type ParseJsonAccessor = Input extends `->${infer Remainder}` - ? Remainder extends `>${infer Remainder}` - ? ParseIdentifier extends [infer Name, `${infer Remainder}`] - ? [Name, string, 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 `->`'> - : 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}` - ? ParseNodes> extends [infer Fields, `${infer Remainder}`] - ? EatWhitespace extends `)${infer Remainder}` - ? [Fields, EatWhitespace] - : ParserError<`Expected ")"`> - : // If no nodes were detected, check for `)` for empty embedded resources `()`. - ParseNodes> extends ParserError - ? EatWhitespace extends `)${infer Remainder}` - ? [[], EatWhitespace] - : ParseNodes> - : ParserError<'Expected embedded resource fields or `)`'> - : 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< - Schema extends GenericSchema, - Row extends Record, - RelationName, - Relationships, - Fields extends unknown[], - Acc -> = Fields extends [infer R] - ? ConstructFieldDefinition extends SelectQueryError< - infer E - > - ? SelectQueryError - : GetResultHelper< - Schema, - Row, - RelationName, - Relationships, - [], - ConstructFieldDefinition & Acc - > - : Fields extends [infer R, ...infer Rest] - ? ConstructFieldDefinition extends SelectQueryError< - infer E - > - ? SelectQueryError - : GetResultHelper< - Schema, - Row, - RelationName, - Relationships, - Rest, - ConstructFieldDefinition & Acc - > - : Prettify - -/** - * Constructs a type definition for an object based on a given PostgREST query. - * - * @param Schema Database schema. - * @param Row Type of a row in the given table. - * @param Relationships Relationships between different tables in the database. - * @param Query Select query string literal to parse. - */ -export type GetResult< - Schema extends GenericSchema, - Row extends Record, - RelationName, - Relationships, - Query extends string -> = ParseQuery extends unknown[] - ? GetResultHelper, unknown> - : ParseQuery diff --git a/test/basic.ts b/test/basic.ts index bb0ab768..8a4d5581 100644 --- a/test/basic.ts +++ b/test/basic.ts @@ -7,15 +7,46 @@ const postgrest = new PostgrestClient(REST_URL) test('basic select table', async () => { const res = await postgrest.from('users').select() expect(res).toMatchInlineSnapshot(` +Object { + "count": null, + "data": Array [ Object { - "count": null, - "data": Array [ - Object { - "age_range": "[1,2)", - "catchphrase": "'cat' 'fat'", - "data": null, - "status": "ONLINE", - "username": "supabot", + "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", }, Object { "age_range": "[25,35)", @@ -63,6 +94,9 @@ test('basic select table', async () => { test('basic select view', async () => { const res = await postgrest.from('updatable_view').select() expect(res).toMatchInlineSnapshot(` +Object { + "count": null, + "data": Array [ Object { "count": null, "data": Array [ @@ -846,13 +880,37 @@ test('allow ordering on JSON column', async () => { .select() .order('data->something' as any) expect(data).toMatchInlineSnapshot(` - Array [ - Object { - "age_range": "[1,2)", - "catchphrase": "'cat' 'fat'", - "data": null, - "status": "ONLINE", - "username": "supabot", +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", }, Object { "age_range": "[25,35)", @@ -965,6 +1023,9 @@ test('select with head:true, count:estimated', async () => { test('select with count:exact', async () => { const res = await postgrest.from('users').select('*', { count: 'exact' }) expect(res).toMatchInlineSnapshot(` +Object { + "count": 5, + "data": Array [ Object { "count": 5, "data": Array [ diff --git a/test/filters.ts b/test/filters.ts index 8348f0a4..2c439666 100644 --- a/test/filters.ts +++ b/test/filters.ts @@ -6,6 +6,9 @@ const postgrest = new PostgrestClient('http://localhost:3000') test('not', async () => { const res = await postgrest.from('users').select('status').not('status', 'eq', 'OFFLINE') expect(res).toMatchInlineSnapshot(` +Object { + "count": null, + "data": Array [ Object { "count": null, "data": Array [ @@ -74,6 +77,9 @@ test('eq', async () => { test('neq', async () => { const res = await postgrest.from('users').select('username').neq('username', 'supabot') expect(res).toMatchInlineSnapshot(` +Object { + "count": null, + "data": Array [ Object { "count": null, "data": Array [ @@ -327,6 +333,9 @@ test('in', async () => { const statuses = ['ONLINE', 'OFFLINE'] as const const res = await postgrest.from('users').select('status').in('status', statuses) expect(res).toMatchInlineSnapshot(` +Object { + "count": null, + "data": Array [ Object { "count": null, "data": Array [ @@ -427,6 +436,9 @@ test('rangeGt', async () => { test('rangeGte', async () => { const res = await postgrest.from('users').select('age_range').rangeGte('age_range', '[2,25)') expect(res).toMatchInlineSnapshot(` +Object { + "count": null, + "data": Array [ Object { "count": null, "data": Array [ @@ -493,6 +505,9 @@ test('rangeAdjacent', async () => { test('overlaps', async () => { const res = await postgrest.from('users').select('age_range').overlaps('age_range', '[2,25)') expect(res).toMatchInlineSnapshot(` +Object { + "count": null, + "data": Array [ Object { "count": null, "data": Array [ diff --git a/test/index.test-d.ts b/test/index.test-d.ts index 65598031..516529e9 100644 --- a/test/index.test-d.ts +++ b/test/index.test-d.ts @@ -85,7 +85,7 @@ const postgrest = new PostgrestClient(REST_URL) if (error) { throw new Error(error.message) } - expectType<{ message: string | null; users: { count: number } | null }>(data) + expectType<{ message: string | null; users: { count: number } }>(data) } // json accessor in select query diff --git a/test/relationships.ts b/test/relationships.ts index 6d9d8bb3..4d8b612d 100644 --- a/test/relationships.ts +++ b/test/relationships.ts @@ -2,7 +2,7 @@ import { PostgrestClient } from '../src/index' import { Database } from './types' const REST_URL = 'http://localhost:3000' -const postgrest = new PostgrestClient(REST_URL) +const postgrest = new PostgrestClient(REST_URL) const userColumn: 'catchphrase' | 'username' = 'username' @@ -1048,6 +1048,7 @@ test('!left join on zero to one with valid relation', async () => { .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(` diff --git a/test/resource-embedding.ts b/test/resource-embedding.ts index b3cca1a8..a8de09b8 100644 --- a/test/resource-embedding.ts +++ b/test/resource-embedding.ts @@ -6,9 +6,11 @@ const postgrest = new PostgrestClient('http://localhost:3000') test('embedded select', async () => { const res = await postgrest.from('users').select('messages(*)') expect(res).toMatchInlineSnapshot(` +Object { + "count": null, + "data": Array [ Object { - "count": null, - "data": Array [ + "messages": Array [ Object { "messages": Array [ Object { @@ -35,23 +37,42 @@ test('embedded select', async () => { ], }, Object { - "messages": Array [], + "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 [], + "channel_id": 3, + "data": null, + "id": 4, + "message": "Some message on channel wihtout details", + "username": "supabot", }, Object { "messages": Array [], }, ], - "error": null, - "status": 200, - "statusText": "OK", - } - `) + }, + Object { + "messages": Array [], + }, + Object { + "messages": Array [], + }, + Object { + "messages": Array [], + }, + Object { + "messages": Array [], + }, + ], + "error": null, + "status": 200, + "statusText": "OK", +} +`) }) describe('embedded filters', () => { diff --git a/test/transforms.ts b/test/transforms.ts index e6518910..a1fab100 100644 --- a/test/transforms.ts +++ b/test/transforms.ts @@ -8,15 +8,32 @@ const postgrest = new PostgrestClient('http://localhost:3000') test('order', async () => { const res = await postgrest.from('users').select().order('username', { ascending: false }) expect(res).toMatchInlineSnapshot(` +Object { + "count": null, + "data": Array [ Object { - "count": null, - "data": Array [ - Object { - "age_range": "[1,2)", - "catchphrase": "'cat' 'fat'", - "data": null, - "status": "ONLINE", - "username": "supabot", + "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", }, Object { "age_range": "[25,35)", @@ -124,15 +141,32 @@ test('limit', async () => { test('range', async () => { const res = await postgrest.from('users').select().range(1, 3) expect(res).toMatchInlineSnapshot(` +Object { + "count": null, + "data": Array [ Object { - "count": null, - "data": Array [ - Object { - "age_range": "[25,35)", - "catchphrase": "'bat' 'cat'", - "data": null, - "status": "OFFLINE", - "username": "kiwicopple", + "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", }, Object { "age_range": "[25,35)", From 49ba6fd637c0d60b734325d7900483f8157636a8 Mon Sep 17 00:00:00 2001 From: avallete Date: Mon, 30 Sep 2024 22:37:31 +0200 Subject: [PATCH 093/110] chore: update tests --- test/basic.ts | 91 +++++++------------------------------- test/filters.ts | 15 ------- test/resource-embedding.ts | 45 +++++-------------- test/transforms.ts | 66 +++++++-------------------- 4 files changed, 43 insertions(+), 174 deletions(-) diff --git a/test/basic.ts b/test/basic.ts index 8a4d5581..bb0ab768 100644 --- a/test/basic.ts +++ b/test/basic.ts @@ -7,46 +7,15 @@ const postgrest = new PostgrestClient(REST_URL) test('basic select table', async () => { const res = await postgrest.from('users').select() 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", + "count": null, + "data": Array [ + Object { + "age_range": "[1,2)", + "catchphrase": "'cat' 'fat'", + "data": null, + "status": "ONLINE", + "username": "supabot", }, Object { "age_range": "[25,35)", @@ -94,9 +63,6 @@ Object { test('basic select view', async () => { const res = await postgrest.from('updatable_view').select() expect(res).toMatchInlineSnapshot(` -Object { - "count": null, - "data": Array [ Object { "count": null, "data": Array [ @@ -880,37 +846,13 @@ test('allow ordering on JSON column', async () => { .select() .order('data->something' as any) 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", + Array [ + Object { + "age_range": "[1,2)", + "catchphrase": "'cat' 'fat'", + "data": null, + "status": "ONLINE", + "username": "supabot", }, Object { "age_range": "[25,35)", @@ -1023,9 +965,6 @@ test('select with head:true, count:estimated', async () => { test('select with count:exact', async () => { const res = await postgrest.from('users').select('*', { count: 'exact' }) expect(res).toMatchInlineSnapshot(` -Object { - "count": 5, - "data": Array [ Object { "count": 5, "data": Array [ diff --git a/test/filters.ts b/test/filters.ts index 2c439666..8348f0a4 100644 --- a/test/filters.ts +++ b/test/filters.ts @@ -6,9 +6,6 @@ const postgrest = new PostgrestClient('http://localhost:3000') test('not', async () => { const res = await postgrest.from('users').select('status').not('status', 'eq', 'OFFLINE') expect(res).toMatchInlineSnapshot(` -Object { - "count": null, - "data": Array [ Object { "count": null, "data": Array [ @@ -77,9 +74,6 @@ test('eq', async () => { test('neq', async () => { const res = await postgrest.from('users').select('username').neq('username', 'supabot') expect(res).toMatchInlineSnapshot(` -Object { - "count": null, - "data": Array [ Object { "count": null, "data": Array [ @@ -333,9 +327,6 @@ test('in', async () => { const statuses = ['ONLINE', 'OFFLINE'] as const const res = await postgrest.from('users').select('status').in('status', statuses) expect(res).toMatchInlineSnapshot(` -Object { - "count": null, - "data": Array [ Object { "count": null, "data": Array [ @@ -436,9 +427,6 @@ test('rangeGt', async () => { test('rangeGte', async () => { const res = await postgrest.from('users').select('age_range').rangeGte('age_range', '[2,25)') expect(res).toMatchInlineSnapshot(` -Object { - "count": null, - "data": Array [ Object { "count": null, "data": Array [ @@ -505,9 +493,6 @@ test('rangeAdjacent', async () => { test('overlaps', async () => { const res = await postgrest.from('users').select('age_range').overlaps('age_range', '[2,25)') expect(res).toMatchInlineSnapshot(` -Object { - "count": null, - "data": Array [ Object { "count": null, "data": Array [ diff --git a/test/resource-embedding.ts b/test/resource-embedding.ts index a8de09b8..b3cca1a8 100644 --- a/test/resource-embedding.ts +++ b/test/resource-embedding.ts @@ -6,11 +6,9 @@ const postgrest = new PostgrestClient('http://localhost:3000') test('embedded select', async () => { const res = await postgrest.from('users').select('messages(*)') expect(res).toMatchInlineSnapshot(` -Object { - "count": null, - "data": Array [ Object { - "messages": Array [ + "count": null, + "data": Array [ Object { "messages": Array [ Object { @@ -37,42 +35,23 @@ Object { ], }, 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", + "messages": Array [], }, Object { - "channel_id": 3, - "data": null, - "id": 4, - "message": "Some message on channel wihtout details", - "username": "supabot", + "messages": Array [], + }, + Object { + "messages": Array [], }, Object { "messages": Array [], }, ], - }, - Object { - "messages": Array [], - }, - Object { - "messages": Array [], - }, - Object { - "messages": Array [], - }, - Object { - "messages": Array [], - }, - ], - "error": null, - "status": 200, - "statusText": "OK", -} -`) + "error": null, + "status": 200, + "statusText": "OK", + } + `) }) describe('embedded filters', () => { diff --git a/test/transforms.ts b/test/transforms.ts index a1fab100..e6518910 100644 --- a/test/transforms.ts +++ b/test/transforms.ts @@ -8,32 +8,15 @@ const postgrest = new PostgrestClient('http://localhost:3000') test('order', async () => { const res = await postgrest.from('users').select().order('username', { ascending: false }) 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", + "count": null, + "data": Array [ + Object { + "age_range": "[1,2)", + "catchphrase": "'cat' 'fat'", + "data": null, + "status": "ONLINE", + "username": "supabot", }, Object { "age_range": "[25,35)", @@ -141,32 +124,15 @@ test('limit', async () => { test('range', async () => { const res = await postgrest.from('users').select().range(1, 3) 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", + "count": null, + "data": Array [ + Object { + "age_range": "[25,35)", + "catchphrase": "'bat' 'cat'", + "data": null, + "status": "OFFLINE", + "username": "kiwicopple", }, Object { "age_range": "[25,35)", From 23943a6d83b1d50d5d2acd8535de8e6dc60ce89e Mon Sep 17 00:00:00 2001 From: Andrew Valleteau Date: Tue, 1 Oct 2024 00:58:56 +0200 Subject: [PATCH 094/110] chore: upgrade postgrest tests image add some more test data (#556) * chore: upgrade postgrest tests image add some more test data * chore: identity columns shouldn't be set manually --------- Co-authored-by: Bobbie Soedirgo --- test/basic.ts | 235 +++++++++++++++++++++++++++++++------ test/db/01-dummy-data.sql | 18 +-- test/db/docker-compose.yml | 3 +- test/filters.ts | 21 ++++ test/resource-embedding.ts | 45 +++++++ test/transforms.ts | 35 +++++- 6 files changed, 309 insertions(+), 48 deletions(-) diff --git a/test/basic.ts b/test/basic.ts index 6b46d50f..44daf354 100644 --- a/test/basic.ts +++ b/test/basic.ts @@ -38,6 +38,20 @@ test('basic select table', async () => { "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, @@ -68,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, @@ -268,8 +286,8 @@ test('on_conflict insert', async () => { }, ], "error": null, - "status": 201, - "statusText": "Created", + "status": 200, + "statusText": "OK", } `) }) @@ -303,7 +321,7 @@ describe('basic insert, update, delete', () => { Object { "channel_id": 1, "data": null, - "id": 3, + "id": 5, "message": "foo", "username": "supabot", }, @@ -334,9 +352,23 @@ describe('basic insert, update, delete', () => { "username": "supabot", }, Object { - "channel_id": 1, + "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", }, @@ -366,8 +398,8 @@ describe('basic insert, update, delete', () => { }, ], "error": null, - "status": 201, - "statusText": "Created", + "status": 200, + "statusText": "OK", } `) @@ -390,6 +422,20 @@ describe('basic insert, update, delete', () => { "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, @@ -420,14 +466,14 @@ describe('basic insert, update, delete', () => { Object { "channel_id": 1, "data": null, - "id": 4, + "id": 6, "message": "foo", "username": "supabot", }, Object { "channel_id": 1, "data": null, - "id": 5, + "id": 7, "message": "foo", "username": "supabot", }, @@ -457,6 +503,20 @@ describe('basic insert, update, delete', () => { "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, @@ -467,14 +527,14 @@ describe('basic insert, update, delete', () => { Object { "channel_id": 1, "data": null, - "id": 4, + "id": 6, "message": "foo", "username": "supabot", }, Object { "channel_id": 1, "data": null, - "id": 5, + "id": 7, "message": "foo", "username": "supabot", }, @@ -496,6 +556,13 @@ describe('basic insert, update, delete', () => { Object { "count": null, "data": Array [ + Object { + "channel_id": 2, + "data": null, + "id": 5, + "message": "foo", + "username": "supabot", + }, Object { "channel_id": 2, "data": null, @@ -506,14 +573,14 @@ describe('basic insert, update, delete', () => { Object { "channel_id": 2, "data": null, - "id": 4, + "id": 6, "message": "foo", "username": "supabot", }, Object { "channel_id": 2, "data": null, - "id": 5, + "id": 7, "message": "foo", "username": "supabot", }, @@ -543,6 +610,20 @@ describe('basic insert, update, delete', () => { "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, @@ -553,14 +634,14 @@ describe('basic insert, update, delete', () => { Object { "channel_id": 2, "data": null, - "id": 4, + "id": 6, "message": "foo", "username": "supabot", }, Object { "channel_id": 2, "data": null, - "id": 5, + "id": 7, "message": "foo", "username": "supabot", }, @@ -578,6 +659,13 @@ describe('basic insert, update, delete', () => { Object { "count": null, "data": Array [ + Object { + "channel_id": 2, + "data": null, + "id": 5, + "message": "foo", + "username": "supabot", + }, Object { "channel_id": 2, "data": null, @@ -588,14 +676,14 @@ describe('basic insert, update, delete', () => { Object { "channel_id": 2, "data": null, - "id": 4, + "id": 6, "message": "foo", "username": "supabot", }, Object { "channel_id": 2, "data": null, - "id": 5, + "id": 7, "message": "foo", "username": "supabot", }, @@ -625,6 +713,13 @@ describe('basic insert, update, delete', () => { "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, @@ -773,6 +868,20 @@ test('allow ordering on JSON column', async () => { "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'", @@ -808,7 +917,7 @@ test('select with head:true, count:exact', async () => { const res = await postgrest.from('users').select('*', { head: true, count: 'exact' }) expect(res).toMatchInlineSnapshot(` Object { - "count": 4, + "count": 5, "data": null, "error": null, "status": 200, @@ -857,7 +966,7 @@ test('select with count:exact', async () => { const res = await postgrest.from('users').select('*', { count: 'exact' }) expect(res).toMatchInlineSnapshot(` Object { - "count": 4, + "count": 5, "data": Array [ Object { "age_range": "[1,2)", @@ -880,6 +989,20 @@ test('select with count:exact', async () => { "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'", @@ -1002,7 +1125,7 @@ describe("insert, update, delete with count: 'exact'", () => { Object { "channel_id": 1, "data": null, - "id": 6, + "id": 8, "message": "foo", "username": "supabot", }, @@ -1032,10 +1155,17 @@ describe("insert, update, delete with count: 'exact'", () => { "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": 6, + "id": 8, "message": "foo", "username": "supabot", }, @@ -1089,10 +1219,17 @@ describe("insert, update, delete with count: 'exact'", () => { "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": 6, + "id": 8, "message": "foo", "username": "supabot", }, @@ -1129,14 +1266,14 @@ describe("insert, update, delete with count: 'exact'", () => { Object { "channel_id": 1, "data": null, - "id": 7, + "id": 9, "message": "foo", "username": "supabot", }, Object { "channel_id": 1, "data": null, - "id": 8, + "id": 10, "message": "foo", "username": "supabot", }, @@ -1166,10 +1303,17 @@ describe("insert, update, delete with count: 'exact'", () => { "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": 6, + "id": 8, "message": "foo", "username": "supabot", }, @@ -1183,14 +1327,14 @@ describe("insert, update, delete with count: 'exact'", () => { Object { "channel_id": 1, "data": null, - "id": 7, + "id": 9, "message": "foo", "username": "supabot", }, Object { "channel_id": 1, "data": null, - "id": 8, + "id": 10, "message": "foo", "username": "supabot", }, @@ -1219,7 +1363,7 @@ describe("insert, update, delete with count: 'exact'", () => { }, Object { "data": null, - "id": 4, + "id": 5, "slug": "test-slug", }, ], @@ -1247,7 +1391,7 @@ describe("insert, update, delete with count: 'exact'", () => { }, Object { "data": null, - "id": 6, + "id": 7, "slug": "test-slug", }, ], @@ -1271,7 +1415,7 @@ describe("insert, update, delete with count: 'exact'", () => { Object { "channel_id": 2, "data": null, - "id": 6, + "id": 8, "message": "foo", "username": "supabot", }, @@ -1285,14 +1429,14 @@ describe("insert, update, delete with count: 'exact'", () => { Object { "channel_id": 2, "data": null, - "id": 7, + "id": 9, "message": "foo", "username": "supabot", }, Object { "channel_id": 2, "data": null, - "id": 8, + "id": 10, "message": "foo", "username": "supabot", }, @@ -1322,10 +1466,17 @@ describe("insert, update, delete with count: 'exact'", () => { "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": 6, + "id": 8, "message": "foo", "username": "supabot", }, @@ -1339,14 +1490,14 @@ describe("insert, update, delete with count: 'exact'", () => { Object { "channel_id": 2, "data": null, - "id": 7, + "id": 9, "message": "foo", "username": "supabot", }, Object { "channel_id": 2, "data": null, - "id": 8, + "id": 10, "message": "foo", "username": "supabot", }, @@ -1371,7 +1522,7 @@ describe("insert, update, delete with count: 'exact'", () => { Object { "channel_id": 2, "data": null, - "id": 6, + "id": 8, "message": "foo", "username": "supabot", }, @@ -1385,14 +1536,14 @@ describe("insert, update, delete with count: 'exact'", () => { Object { "channel_id": 2, "data": null, - "id": 7, + "id": 9, "message": "foo", "username": "supabot", }, Object { "channel_id": 2, "data": null, - "id": 8, + "id": 10, "message": "foo", "username": "supabot", }, @@ -1422,6 +1573,13 @@ describe("insert, update, delete with count: 'exact'", () => { "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, @@ -1516,6 +1674,9 @@ test('!left join on one to many relation', async () => { Object { "username": "supabot", }, + Object { + "username": "supabot", + }, ], }, "error": null, diff --git a/test/db/01-dummy-data.sql b/test/db/01-dummy-data.sql index 7ff4f94e..8026b16d 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) diff --git a/test/db/docker-compose.yml b/test/db/docker-compose.yml index 13e9d2d7..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:v11.2.2 + image: postgrest/postgrest:v12.2.0 ports: - '3000:3000' environment: @@ -13,6 +13,7 @@ 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: diff --git a/test/filters.ts b/test/filters.ts index 98a76e4d..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, @@ -330,6 +342,9 @@ test('in', async () => { Object { "status": "ONLINE", }, + Object { + "status": "ONLINE", + }, ], "error": null, "status": 200, @@ -424,6 +439,9 @@ test('rangeGte', async () => { Object { "age_range": "[20,30)", }, + Object { + "age_range": "[20,30)", + }, ], "error": null, "status": 200, @@ -481,6 +499,9 @@ test('overlaps', async () => { Object { "age_range": "[20,30)", }, + Object { + "age_range": "[20,30)", + }, ], "error": null, "status": 200, diff --git a/test/resource-embedding.ts b/test/resource-embedding.ts index 08887be0..b3cca1a8 100644 --- a/test/resource-embedding.ts +++ b/test/resource-embedding.ts @@ -25,6 +25,13 @@ test('embedded select', async () => { "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 { @@ -36,6 +43,9 @@ test('embedded select', async () => { Object { "messages": Array [], }, + Object { + "messages": Array [], + }, ], "error": null, "status": 200, @@ -75,6 +85,9 @@ describe('embedded filters', () => { Object { "messages": Array [], }, + Object { + "messages": Array [], + }, ], "error": null, "status": 200, @@ -118,6 +131,9 @@ describe('embedded filters', () => { Object { "messages": Array [], }, + Object { + "messages": Array [], + }, ], "error": null, "status": 200, @@ -163,6 +179,9 @@ describe('embedded filters', () => { Object { "messages": Array [], }, + Object { + "messages": Array [], + }, ], "error": null, "status": 200, @@ -184,6 +203,13 @@ describe('embedded transforms', () => { "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, @@ -209,6 +235,9 @@ describe('embedded transforms', () => { Object { "messages": Array [], }, + Object { + "messages": Array [], + }, ], "error": null, "status": 200, @@ -229,6 +258,13 @@ describe('embedded transforms', () => { "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, @@ -254,6 +290,9 @@ describe('embedded transforms', () => { Object { "messages": Array [], }, + Object { + "messages": Array [], + }, ], "error": null, "status": 200, @@ -291,6 +330,9 @@ describe('embedded transforms', () => { Object { "messages": Array [], }, + Object { + "messages": Array [], + }, ], "error": null, "status": 200, @@ -328,6 +370,9 @@ describe('embedded transforms', () => { Object { "messages": Array [], }, + Object { + "messages": Array [], + }, ], "error": null, "status": 200, diff --git a/test/transforms.ts b/test/transforms.ts index b0d0bce5..e6518910 100644 --- a/test/transforms.ts +++ b/test/transforms.ts @@ -25,6 +25,20 @@ test('order', async () => { "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'", @@ -57,6 +71,13 @@ test('order on multiple columns', async () => { 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, @@ -122,10 +143,17 @@ test('range', async () => { }, Object { "age_range": "[20,30)", - "catchphrase": "'fat' 'rat'", - "data": null, + "catchphrase": "'json' 'test'", + "data": Object { + "foo": Object { + "bar": Object { + "nested": "value", + }, + "baz": "string value", + }, + }, "status": "ONLINE", - "username": "dragarcia", + "username": "jsonuser", }, ], "error": null, @@ -257,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, From 981fa4d3e559ea50c891977385acdfb52b0c01a5 Mon Sep 17 00:00:00 2001 From: Brice Lechatellier Date: Tue, 1 Oct 2024 09:04:35 +1000 Subject: [PATCH 095/110] fix: export PostgresError as a class (#555) * fix: export PostgresError * chore: prettier --------- Co-authored-by: Bobbie Soedirgo --- src/index.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index f20eb74f..06ac6622 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,6 +4,7 @@ import PostgrestQueryBuilder from './PostgrestQueryBuilder' import PostgrestFilterBuilder from './PostgrestFilterBuilder' import PostgrestTransformBuilder from './PostgrestTransformBuilder' import PostgrestBuilder from './PostgrestBuilder' +import PostgrestError from './PostgrestError' export { PostgrestClient, @@ -11,6 +12,7 @@ export { PostgrestFilterBuilder, PostgrestTransformBuilder, PostgrestBuilder, + PostgrestError, } export default { PostgrestClient, @@ -18,6 +20,7 @@ export default { PostgrestFilterBuilder, PostgrestTransformBuilder, PostgrestBuilder, + PostgrestError, } export type { PostgrestResponse, @@ -25,5 +28,4 @@ export type { PostgrestResponseSuccess, PostgrestSingleResponse, PostgrestMaybeSingleResponse, - PostgrestError, } from './types' From 0c53e4ba9044169cc6c36885e4521132896667f0 Mon Sep 17 00:00:00 2001 From: avallete Date: Thu, 3 Oct 2024 12:44:45 +0200 Subject: [PATCH 096/110] fix: make oneToOne optional --- src/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types.ts b/src/types.ts index 704d306d..a26a2eed 100644 --- a/src/types.ts +++ b/src/types.ts @@ -42,7 +42,7 @@ export type PostgrestResponse = PostgrestSingleResponse export type GenericRelationship = { foreignKeyName: string columns: string[] - isOneToOne: boolean + isOneToOne?: boolean referencedRelation: string referencedColumns: string[] } From 59e23a51c5dd35413c9d0b11a963e2629c625ed3 Mon Sep 17 00:00:00 2001 From: avallete Date: Thu, 3 Oct 2024 12:45:23 +0200 Subject: [PATCH 097/110] fix: update GenericTable usage to work with views --- src/select-query-parser/result.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/select-query-parser/result.ts b/src/select-query-parser/result.ts index e2aa1ce7..fee38e61 100644 --- a/src/select-query-parser/result.ts +++ b/src/select-query-parser/result.ts @@ -161,12 +161,13 @@ export type ProcessEmbeddedResource< CurrentTableOrView extends keyof TablesAndViews > = ResolveRelationship extends infer Resolved ? Resolved extends { - referencedTable: GenericTable + referencedTable: Pick relation: GenericRelationship direction: string } ? ProcessEmbeddedResourceResult - : { [K in GetFieldNodeResultName]: Resolved & string } + // Otherwise the Resolved is a SelectQueryError return it + : { [K in GetFieldNodeResultName]: Resolved } : { [K in GetFieldNodeResultName]: SelectQueryError<'Failed to resolve relationship.'> & string @@ -178,7 +179,7 @@ export type ProcessEmbeddedResource< type ProcessEmbeddedResourceResult< Schema extends GenericSchema, Resolved extends { - referencedTable: GenericTable + referencedTable: Pick relation: GenericRelationship direction: string }, From 4eea1780244842fee661ca0f5dce957f236279d9 Mon Sep 17 00:00:00 2001 From: avallete Date: Thu, 3 Oct 2024 12:46:04 +0200 Subject: [PATCH 098/110] fix: make hinting relationships use name as well as hint to avoid duplicates --- src/select-query-parser/utils.ts | 50 ++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/src/select-query-parser/utils.ts b/src/select-query-parser/utils.ts index 7618450e..e387573f 100644 --- a/src/select-query-parser/utils.ts +++ b/src/select-query-parser/utils.ts @@ -37,7 +37,7 @@ type FilterRelationNodes = UnionToArray< }[number] > -type ResolveRelationships< +export type ResolveRelationships< Schema extends GenericSchema, RelationName extends string, Relationships extends GenericRelationship[], @@ -301,6 +301,44 @@ export type 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'])[] @@ -393,19 +431,21 @@ export type FindFieldMatchingRelationships< Relationships extends GenericRelationship[], Field extends FieldNode > = Field extends { hint?: infer Hint extends string } - ? FindMatchingTableRelationships< + ? FindMatchingHintTableRelationships< Schema, Relationships, - Hint + Hint, + Field['name'] > extends infer TableRelationViaHint extends GenericRelationship ? TableRelationViaHint & { branch: 'found-in-table-via-hint' hint: Field['hint'] } - : FindMatchingViewRelationships< + : FindMatchingHintViewRelationships< Schema, Relationships, - Hint + Hint, + Field['name'] > extends infer TableViewViaHint extends GenericRelationship ? TableViewViaHint & { branch: 'found-in-view-via-hint' From 556bbc46422952c9e4347d2f2b148dac857b83a5 Mon Sep 17 00:00:00 2001 From: avallete Date: Thu, 3 Oct 2024 14:44:15 +0200 Subject: [PATCH 099/110] fix: rpc procedures call --- src/PostgrestClient.ts | 4 +++- src/select-query-parser/result.ts | 12 ++++++++---- test/relationships.ts | 2 +- test/select-query-parser/rpc.test-d.ts | 16 ++++++++++++++++ 4 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 test/select-query-parser/rpc.test-d.ts diff --git a/src/PostgrestClient.ts b/src/PostgrestClient.ts index 915ddc16..954ac7dc 100644 --- a/src/PostgrestClient.ts +++ b/src/PostgrestClient.ts @@ -140,7 +140,9 @@ export default class PostgrestClient< ? Fn['Returns'][number] : never : never, - Fn['Returns'] + Fn['Returns'], + null, + null > { let method: 'HEAD' | 'GET' | 'POST' const url = new URL(`${this.url}/rpc/${fn}`) diff --git a/src/select-query-parser/result.ts b/src/select-query-parser/result.ts index fee38e61..c9fe456b 100644 --- a/src/select-query-parser/result.ts +++ b/src/select-query-parser/result.ts @@ -34,13 +34,17 @@ export type GetResult< RelationName, Relationships, Query extends string -> = ParseQuery extends infer ParsedQuery + // For .rpc calls the passed relationships will be null + // in that case, the result will always be the function return type +> = Relationships extends null + ? Row + : ParseQuery extends infer ParsedQuery ? ParsedQuery extends Node[] ? RelationName extends string ? Relationships extends GenericRelationship[] ? ProcessNodes : SelectQueryError<'Invalid Relationships cannot infer result type'> - : SelectQueryError<'Invalid RelationName cannot infer restult type'> + : SelectQueryError<'Invalid RelationName cannot infer result type'> : ParsedQuery : never @@ -166,8 +170,8 @@ export type ProcessEmbeddedResource< direction: string } ? ProcessEmbeddedResourceResult - // Otherwise the Resolved is a SelectQueryError return it - : { [K in GetFieldNodeResultName]: Resolved } + : // Otherwise the Resolved is a SelectQueryError return it + { [K in GetFieldNodeResultName]: Resolved } : { [K in GetFieldNodeResultName]: SelectQueryError<'Failed to resolve relationship.'> & string diff --git a/test/relationships.ts b/test/relationships.ts index 4d8b612d..7a2706f7 100644 --- a/test/relationships.ts +++ b/test/relationships.ts @@ -2,7 +2,7 @@ import { PostgrestClient } from '../src/index' import { Database } from './types' const REST_URL = 'http://localhost:3000' -const postgrest = new PostgrestClient(REST_URL) +export const postgrest = new PostgrestClient(REST_URL) const userColumn: 'catchphrase' | 'username' = 'username' 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..9a076782 --- /dev/null +++ b/test/select-query-parser/rpc.test-d.ts @@ -0,0 +1,16 @@ +import { postgrest } from "../relationships" +import { Database } from "../types" +import { expectType } from 'tsd' +import { TypeEqual } from 'ts-expect' + +// rpc call result in the proper type +{ + const { data } = await postgrest + .rpc('get_username_and_status') + .select() + .single() + let result: Exclude + let expected: Database['public']['Functions']['get_username_and_status']['Returns'][number] + expectType>(true) + } + \ No newline at end of file From 7298b54d1f5de5f1738d243630315164bd778bef Mon Sep 17 00:00:00 2001 From: avallete Date: Thu, 3 Oct 2024 15:39:33 +0200 Subject: [PATCH 100/110] fix: inner join on many relationship --- src/select-query-parser/result.ts | 8 +++---- test/relationships.ts | 28 +++++++++++++++++++++++ test/select-query-parser/rpc.test-d.ts | 18 ++++++--------- test/select-query-parser/select.test-d.ts | 14 ++++++++++++ 4 files changed, 53 insertions(+), 15 deletions(-) diff --git a/src/select-query-parser/result.ts b/src/select-query-parser/result.ts index c9fe456b..a39bac2c 100644 --- a/src/select-query-parser/result.ts +++ b/src/select-query-parser/result.ts @@ -34,9 +34,7 @@ export type GetResult< RelationName, Relationships, Query extends string - // For .rpc calls the passed relationships will be null - // in that case, the result will always be the function return type -> = Relationships extends null +> = Relationships extends null // For .rpc calls the passed relationships will be null in that case, the result will always be the function return type ? Row : ParseQuery extends infer ParsedQuery ? ParsedQuery extends Node[] @@ -203,7 +201,9 @@ type ProcessEmbeddedResourceResult< ? { [K in GetFieldNodeResultName]: Resolved['direction'] extends 'forward' ? Field extends { inner: true } - ? ProcessedChildren + ? Resolved['relation']['isOneToOne'] extends true + ? ProcessedChildren + : ProcessedChildren[] : Resolved['relation']['isOneToOne'] extends true ? ProcessedChildren | null : ProcessedChildren[] diff --git a/test/relationships.ts b/test/relationships.ts index 7a2706f7..814ee3ef 100644 --- a/test/relationships.ts +++ b/test/relationships.ts @@ -165,6 +165,10 @@ export const selectParams = { select: 'message, users.count(), casted_message:message::int4, casted_count:users.count()::text', }, + innerJoinOnManyRelation: { + from: 'channels', + select: 'id, messages!channel_id!inner(id, username)', + }, } as const export const selectQueries = { @@ -328,6 +332,9 @@ export const selectQueries = { typecastingAndAggregate: postgrest .from(selectParams.typecastingAndAggregate.from) .select(selectParams.typecastingAndAggregate.select), + innerJoinOnManyRelation: postgrest + .from(selectParams.innerJoinOnManyRelation.from) + .select(selectParams.innerJoinOnManyRelation.select), } as const test('nested query with selective fields', async () => { @@ -1714,3 +1721,24 @@ test('typecasting and aggregate', async () => { } `) }) + +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", + } + `) +}) diff --git a/test/select-query-parser/rpc.test-d.ts b/test/select-query-parser/rpc.test-d.ts index 9a076782..a8325254 100644 --- a/test/select-query-parser/rpc.test-d.ts +++ b/test/select-query-parser/rpc.test-d.ts @@ -1,16 +1,12 @@ -import { postgrest } from "../relationships" -import { Database } from "../types" +import { postgrest } from '../relationships' +import { Database } from '../types' import { expectType } from 'tsd' import { TypeEqual } from 'ts-expect' // rpc call result in the proper type { - const { data } = await postgrest - .rpc('get_username_and_status') - .select() - .single() - let result: Exclude - let expected: Database['public']['Functions']['get_username_and_status']['Returns'][number] - expectType>(true) - } - \ No newline at end of file + const { data } = await postgrest.rpc('get_username_and_status').select().single() + let result: Exclude + let expected: Database['public']['Functions']['get_username_and_status']['Returns'][number] + expectType>(true) +} diff --git a/test/select-query-parser/select.test-d.ts b/test/select-query-parser/select.test-d.ts index 13fcff2c..eb2d8390 100644 --- a/test/select-query-parser/select.test-d.ts +++ b/test/select-query-parser/select.test-d.ts @@ -687,3 +687,17 @@ type Schema = Database['public'] 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) +} From ac6165cc109e1276e397b682ef62dd79c215f7d1 Mon Sep 17 00:00:00 2001 From: avallete Date: Fri, 4 Oct 2024 13:57:33 +0200 Subject: [PATCH 101/110] fix: errors with relationships duplicates --- src/select-query-parser/utils.ts | 34 ++++++++++++--- test/select-query-parser/types.test-d.ts | 54 ++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 6 deletions(-) diff --git a/src/select-query-parser/utils.ts b/src/select-query-parser/utils.ts index e387573f..bd411eb3 100644 --- a/src/select-query-parser/utils.ts +++ b/src/select-query-parser/utils.ts @@ -37,6 +37,22 @@ type FilterRelationNodes = UnionToArray< }[number] > +/* + ** Because of pg-meta types generation there is some cases where a same relationship can be duplicated + ** if the relation is across schemas and views this ensure that we dedup those relations and treat them + ** as postgrest would. + ** TODO: This is necessary to allow the check for required desambiguation but shouldn't if the + ** generated relationships were correct pointing out that each realation is actually toward a different schema + */ +export type DeduplicateRelationships = T extends readonly [ + infer First, + ...infer Rest +] + ? First extends Rest[number] + ? DeduplicateRelationships + : [First, ...DeduplicateRelationships] + : T + export type ResolveRelationships< Schema extends GenericSchema, RelationName extends string, @@ -110,7 +126,7 @@ export type CheckDuplicateEmbededReference< RelationsNodes > extends infer ResolvedRels ? ResolvedRels extends unknown[] - ? FindDuplicates extends infer Duplicates + ? FindDuplicates> extends infer Duplicates ? Duplicates extends never ? false : Duplicates extends { fieldName: infer FieldName extends string } @@ -127,7 +143,7 @@ export type CheckDuplicateEmbededReference< * Returns a boolean representing whether there is a foreign key referencing * a given relation. */ -type HasFKeyToFRel = Relationships extends [infer R] +export type HasFKeyToFRel = Relationships extends [infer R] ? R extends { referencedRelation: FRelName } ? true : false @@ -139,7 +155,7 @@ type HasFKeyToFRel = Relationships extends [infer R] /** * Checks if there is more than one relation to a given foreign relation name in the Relationships. */ -type HasMultipleFKeysToFRel = Relationships extends [ +export type HasMultipleFKeysToFRel = Relationships extends [ infer R, ...infer Rest ] @@ -166,7 +182,10 @@ type CheckRelationshipError< direction: 'reverse' } ? // We check if there is possible confusion with other relations with this table - HasMultipleFKeysToFRel extends true + HasMultipleFKeysToFRel< + RelatedRelationName, + DeduplicateRelationships + > extends true ? // If there is, postgrest will fail at runtime, and require desambiguation via hinting RequireHintingSelectQueryError< RelatedRelationName, @@ -184,7 +203,7 @@ type CheckRelationshipError< } ? HasMultipleFKeysToFRel< RelatedRelationName, - TablesAndViews[From]['Relationships'] + DeduplicateRelationships[From]['Relationships']> > extends true ? RequireHintingSelectQueryError : FoundRelation @@ -236,7 +255,10 @@ type ResolveReverseRelationship< from: CurrentTableOrView } : // If the relation was found via implicit relation naming, we must ensure there is no conflicting matches - HasMultipleFKeysToFRel extends true + HasMultipleFKeysToFRel< + RelatedRelationName, + DeduplicateRelationships + > extends true ? RequireHintingSelectQueryError< RelatedRelationName, CurrentTableOrView extends string ? CurrentTableOrView : 'unknown' diff --git a/test/select-query-parser/types.test-d.ts b/test/select-query-parser/types.test-d.ts index 593a5275..480d6490 100644 --- a/test/select-query-parser/types.test-d.ts +++ b/test/select-query-parser/types.test-d.ts @@ -8,6 +8,7 @@ import { import { expectType } from 'tsd' import { TypeEqual } from 'ts-expect' import { + DeduplicateRelationships, FindMatchingRelationships, FindMatchingTableRelationships, IsRelationNullable, @@ -178,3 +179,56 @@ import { ParseQuery } from '../../src/select-query-parser/parser/parser' type r2 = ProcessNodes expectType(expected!) } + +// Deduplicate exact sames relationships +{ + type rels = [ + { + foreignKeyName: 'test_fkey' + columns: ['project_id'] + referencedRelation: 'project_subscriptions' + referencedColumns: ['project_id'] + }, + { + foreignKeyName: 'test_fkey' + columns: ['project_id'] + referencedRelation: 'projects' + referencedColumns: ['id'] + }, + { + foreignKeyName: 'test_fkey' + columns: ['project_id'] + referencedRelation: 'projects' + referencedColumns: ['id'] + }, + { + foreignKeyName: 'test_fkey' + columns: ['project_id'] + referencedRelation: 'sls_physical_backups_monitoring' + referencedColumns: ['project_id'] + } + ] + type expected = [ + { + foreignKeyName: 'test_fkey' + columns: ['project_id'] + referencedRelation: 'project_subscriptions' + referencedColumns: ['project_id'] + }, + { + foreignKeyName: 'test_fkey' + columns: ['project_id'] + referencedRelation: 'projects' + referencedColumns: ['id'] + }, + { + foreignKeyName: 'test_fkey' + columns: ['project_id'] + referencedRelation: 'sls_physical_backups_monitoring' + referencedColumns: ['project_id'] + } + ] + + type result = DeduplicateRelationships + expectType>(true) +} From cd55433122dfbb14a97708de2b5dba3610c8d908 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Thu, 10 Oct 2024 03:45:24 +0800 Subject: [PATCH 102/110] Revert "fix: errors with relationships duplicates" This reverts commit ac6165cc109e1276e397b682ef62dd79c215f7d1. --- src/select-query-parser/utils.ts | 34 +++------------ test/select-query-parser/types.test-d.ts | 54 ------------------------ 2 files changed, 6 insertions(+), 82 deletions(-) diff --git a/src/select-query-parser/utils.ts b/src/select-query-parser/utils.ts index bd411eb3..e387573f 100644 --- a/src/select-query-parser/utils.ts +++ b/src/select-query-parser/utils.ts @@ -37,22 +37,6 @@ type FilterRelationNodes = UnionToArray< }[number] > -/* - ** Because of pg-meta types generation there is some cases where a same relationship can be duplicated - ** if the relation is across schemas and views this ensure that we dedup those relations and treat them - ** as postgrest would. - ** TODO: This is necessary to allow the check for required desambiguation but shouldn't if the - ** generated relationships were correct pointing out that each realation is actually toward a different schema - */ -export type DeduplicateRelationships = T extends readonly [ - infer First, - ...infer Rest -] - ? First extends Rest[number] - ? DeduplicateRelationships - : [First, ...DeduplicateRelationships] - : T - export type ResolveRelationships< Schema extends GenericSchema, RelationName extends string, @@ -126,7 +110,7 @@ export type CheckDuplicateEmbededReference< RelationsNodes > extends infer ResolvedRels ? ResolvedRels extends unknown[] - ? FindDuplicates> extends infer Duplicates + ? FindDuplicates extends infer Duplicates ? Duplicates extends never ? false : Duplicates extends { fieldName: infer FieldName extends string } @@ -143,7 +127,7 @@ export type CheckDuplicateEmbededReference< * Returns a boolean representing whether there is a foreign key referencing * a given relation. */ -export type HasFKeyToFRel = Relationships extends [infer R] +type HasFKeyToFRel = Relationships extends [infer R] ? R extends { referencedRelation: FRelName } ? true : false @@ -155,7 +139,7 @@ export type HasFKeyToFRel = Relationships extends [infe /** * Checks if there is more than one relation to a given foreign relation name in the Relationships. */ -export type HasMultipleFKeysToFRel = Relationships extends [ +type HasMultipleFKeysToFRel = Relationships extends [ infer R, ...infer Rest ] @@ -182,10 +166,7 @@ type CheckRelationshipError< direction: 'reverse' } ? // We check if there is possible confusion with other relations with this table - HasMultipleFKeysToFRel< - RelatedRelationName, - DeduplicateRelationships - > extends true + HasMultipleFKeysToFRel extends true ? // If there is, postgrest will fail at runtime, and require desambiguation via hinting RequireHintingSelectQueryError< RelatedRelationName, @@ -203,7 +184,7 @@ type CheckRelationshipError< } ? HasMultipleFKeysToFRel< RelatedRelationName, - DeduplicateRelationships[From]['Relationships']> + TablesAndViews[From]['Relationships'] > extends true ? RequireHintingSelectQueryError : FoundRelation @@ -255,10 +236,7 @@ type ResolveReverseRelationship< from: CurrentTableOrView } : // If the relation was found via implicit relation naming, we must ensure there is no conflicting matches - HasMultipleFKeysToFRel< - RelatedRelationName, - DeduplicateRelationships - > extends true + HasMultipleFKeysToFRel extends true ? RequireHintingSelectQueryError< RelatedRelationName, CurrentTableOrView extends string ? CurrentTableOrView : 'unknown' diff --git a/test/select-query-parser/types.test-d.ts b/test/select-query-parser/types.test-d.ts index 480d6490..593a5275 100644 --- a/test/select-query-parser/types.test-d.ts +++ b/test/select-query-parser/types.test-d.ts @@ -8,7 +8,6 @@ import { import { expectType } from 'tsd' import { TypeEqual } from 'ts-expect' import { - DeduplicateRelationships, FindMatchingRelationships, FindMatchingTableRelationships, IsRelationNullable, @@ -179,56 +178,3 @@ import { ParseQuery } from '../../src/select-query-parser/parser/parser' type r2 = ProcessNodes expectType(expected!) } - -// Deduplicate exact sames relationships -{ - type rels = [ - { - foreignKeyName: 'test_fkey' - columns: ['project_id'] - referencedRelation: 'project_subscriptions' - referencedColumns: ['project_id'] - }, - { - foreignKeyName: 'test_fkey' - columns: ['project_id'] - referencedRelation: 'projects' - referencedColumns: ['id'] - }, - { - foreignKeyName: 'test_fkey' - columns: ['project_id'] - referencedRelation: 'projects' - referencedColumns: ['id'] - }, - { - foreignKeyName: 'test_fkey' - columns: ['project_id'] - referencedRelation: 'sls_physical_backups_monitoring' - referencedColumns: ['project_id'] - } - ] - type expected = [ - { - foreignKeyName: 'test_fkey' - columns: ['project_id'] - referencedRelation: 'project_subscriptions' - referencedColumns: ['project_id'] - }, - { - foreignKeyName: 'test_fkey' - columns: ['project_id'] - referencedRelation: 'projects' - referencedColumns: ['id'] - }, - { - foreignKeyName: 'test_fkey' - columns: ['project_id'] - referencedRelation: 'sls_physical_backups_monitoring' - referencedColumns: ['project_id'] - } - ] - - type result = DeduplicateRelationships - expectType>(true) -} From e099a47fa536eecf117a7e4a50b1923419f5cf0d Mon Sep 17 00:00:00 2001 From: avallete Date: Wed, 9 Oct 2024 23:36:58 +0200 Subject: [PATCH 103/110] fix: self-referencing relation corner case Related: https://github.com/supabase/postgrest-js/issues/509 --- src/select-query-parser/result.ts | 21 ++++++- src/select-query-parser/utils.ts | 14 ----- test/db/00-schema.sql | 14 +++++ test/db/01-dummy-data.sql | 9 +++ test/relationships.ts | 64 +++++++++++++++++++ test/select-query-parser/result.test-d.ts | 17 +++++ test/select-query-parser/select.test-d.ts | 35 +++++++++++ test/select-query-parser/types.test-d.ts | 76 +++++++++-------------- test/types.ts | 40 ++++++++++++ 9 files changed, 226 insertions(+), 64 deletions(-) diff --git a/src/select-query-parser/result.ts b/src/select-query-parser/result.ts index a39bac2c..097901a6 100644 --- a/src/select-query-parser/result.ts +++ b/src/select-query-parser/result.ts @@ -164,7 +164,7 @@ export type ProcessEmbeddedResource< > = ResolveRelationship extends infer Resolved ? Resolved extends { referencedTable: Pick - relation: GenericRelationship + relation: GenericRelationship & { match: 'refrel' | 'col' | 'fkname' } direction: string } ? ProcessEmbeddedResourceResult @@ -182,7 +182,7 @@ type ProcessEmbeddedResourceResult< Schema extends GenericSchema, Resolved extends { referencedTable: Pick - relation: GenericRelationship + relation: GenericRelationship & { match: 'refrel' | 'col' | 'fkname' } direction: string }, Field extends FieldNode, @@ -207,7 +207,22 @@ type ProcessEmbeddedResourceResult< : Resolved['relation']['isOneToOne'] extends true ? ProcessedChildren | null : ProcessedChildren[] - : IsRelationNullable< + : // 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 diff --git a/src/select-query-parser/utils.ts b/src/select-query-parser/utils.ts index e387573f..3ffa4657 100644 --- a/src/select-query-parser/utils.ts +++ b/src/select-query-parser/utils.ts @@ -251,20 +251,6 @@ type ResolveReverseRelationship< : false : false -// Utility type to find embeded relationships by all their possibles references -export type FindMatchingRelationships< - value extends string, - Relationships extends GenericRelationship[] -> = Relationships extends [infer R, ...infer Rest extends GenericRelationship[]] - ? R extends { foreignKeyName: value } - ? R - : R extends { referencedRelation: value } - ? R - : R extends { columns: [value] } - ? R - : FindMatchingRelationships - : false - export type FindMatchingTableRelationships< Schema extends GenericSchema, Relationships extends GenericRelationship[], diff --git a/test/db/00-schema.sql b/test/db/00-schema.sql index 21d49a7e..c06ed0b7 100644 --- a/test/db/00-schema.sql +++ b/test/db/00-schema.sql @@ -59,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 $$ diff --git a/test/db/01-dummy-data.sql b/test/db/01-dummy-data.sql index 8026b16d..dc73ecba 100644 --- a/test/db/01-dummy-data.sql +++ b/test/db/01-dummy-data.sql @@ -49,3 +49,12 @@ 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/relationships.ts b/test/relationships.ts index 814ee3ef..2a487d49 100644 --- a/test/relationships.ts +++ b/test/relationships.ts @@ -169,6 +169,14 @@ export const selectParams = { from: 'channels', select: 'id, messages!channel_id!inner(id, username)', }, + selfReferenceRelation: { + from: 'collections', + select: '*, collections(*)', + }, + selfReferenceRelationViaColumn: { + from: 'collections', + select: '*, parent_id(*)', + }, } as const export const selectQueries = { @@ -335,6 +343,12 @@ export const selectQueries = { 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), } as const test('nested query with selective fields', async () => { @@ -1742,3 +1756,53 @@ test('inner join on many relation', async () => { } `) }) + +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", + } + `) +}) diff --git a/test/select-query-parser/result.test-d.ts b/test/select-query-parser/result.test-d.ts index 6545c8b5..38dcccae 100644 --- a/test/select-query-parser/result.test-d.ts +++ b/test/select-query-parser/result.test-d.ts @@ -53,3 +53,20 @@ type SelectQueryFromTableResult< } 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/select.test-d.ts b/test/select-query-parser/select.test-d.ts index eb2d8390..e23de8a6 100644 --- a/test/select-query-parser/select.test-d.ts +++ b/test/select-query-parser/select.test-d.ts @@ -701,3 +701,38 @@ type Schema = Database['public'] } 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) +} diff --git a/test/select-query-parser/types.test-d.ts b/test/select-query-parser/types.test-d.ts index 593a5275..6021acbb 100644 --- a/test/select-query-parser/types.test-d.ts +++ b/test/select-query-parser/types.test-d.ts @@ -8,7 +8,6 @@ import { import { expectType } from 'tsd' import { TypeEqual } from 'ts-expect' import { - FindMatchingRelationships, FindMatchingTableRelationships, IsRelationNullable, } from '../../src/select-query-parser/utils' @@ -17,20 +16,13 @@ import { ParseQuery } from '../../src/select-query-parser/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 an non-existing relationship should return never -{ - let result: FindMatchingRelationships< - 'test', - Database['public']['Tables']['best_friends']['Relationships'] - > - let expected: false - expectType>(true) -} + // Searching for a relationship by direct foreignkey name { - let result: FindMatchingRelationships< - 'best_friends_first_user_fkey', - Database['public']['Tables']['best_friends']['Relationships'] + let result: FindMatchingTableRelationships< + Database['public'], + Database['public']['Tables']['best_friends']['Relationships'], + 'best_friends_first_user_fkey' > let expected: { foreignKeyName: 'best_friends_first_user_fkey' @@ -38,14 +30,15 @@ import { ParseQuery } from '../../src/select-query-parser/parser/parser' isOneToOne: false referencedRelation: 'users' referencedColumns: ['username'] - } + } & { match: 'fkname' } expectType>(true) } // Searching for a relationship by column hoding the value reference { - let result: FindMatchingRelationships< - 'first_user', - Database['public']['Tables']['best_friends']['Relationships'] + let result: FindMatchingTableRelationships< + Database['public'], + Database['public']['Tables']['best_friends']['Relationships'], + 'first_user' > let expected: { foreignKeyName: 'best_friends_first_user_fkey' @@ -53,22 +46,7 @@ import { ParseQuery } from '../../src/select-query-parser/parser/parser' isOneToOne: false referencedRelation: 'users' referencedColumns: ['username'] - } - expectType>(true) -} -// Will find the first matching relationship -{ - let result: FindMatchingRelationships< - 'username', - Database['public']['Tables']['user_profiles']['Relationships'] - > - let expected: { - foreignKeyName: 'user_profiles_username_fkey' - columns: ['username'] - isOneToOne: false - referencedRelation: 'non_updatable_view' - referencedColumns: ['username'] - } + } & { match: 'col' } expectType>(true) } // should return the relation matching the "Tables" references @@ -89,9 +67,10 @@ import { ParseQuery } from '../../src/select-query-parser/parser/parser' } // Searching for a relationship by referenced table name { - let result: FindMatchingRelationships< - 'users', - Database['public']['Tables']['messages']['Relationships'] + let result: FindMatchingTableRelationships< + Database['public'], + Database['public']['Tables']['messages']['Relationships'], + 'users' > let expected: { foreignKeyName: 'messages_username_fkey' @@ -99,13 +78,14 @@ import { ParseQuery } from '../../src/select-query-parser/parser/parser' isOneToOne: false referencedRelation: 'users' referencedColumns: ['username'] - } + } & { match: 'refrel' } expectType>(true) } { - let result: FindMatchingRelationships< - 'channels', - Database['public']['Tables']['messages']['Relationships'] + let result: FindMatchingTableRelationships< + Database['public'], + Database['public']['Tables']['messages']['Relationships'], + 'channels' > let expected: { foreignKeyName: 'messages_channel_id_fkey' @@ -113,20 +93,22 @@ import { ParseQuery } from '../../src/select-query-parser/parser/parser' isOneToOne: false referencedRelation: 'channels' referencedColumns: ['id'] - } + } & { match: 'refrel' } expectType>(true) } // IsRelationNullable { type BestFriendsTable = Database['public']['Tables']['best_friends'] - type NonNullableRelation = FindMatchingRelationships< - 'best_friends_first_user_fkey', - BestFriendsTable['Relationships'] + type NonNullableRelation = FindMatchingTableRelationships< + Database['public'], + BestFriendsTable['Relationships'], + 'best_friends_first_user_fkey' > - type NullableRelation = FindMatchingRelationships< - 'best_friends_third_wheel_fkey', - BestFriendsTable['Relationships'] + type NullableRelation = FindMatchingTableRelationships< + Database['public'], + BestFriendsTable['Relationships'], + 'best_friends_third_wheel_fkey' > let nonNullableResult: IsRelationNullable let nullableResult: IsRelationNullable diff --git a/test/types.ts b/test/types.ts index deed0fa9..2d601877 100644 --- a/test/types.ts +++ b/test/types.ts @@ -65,6 +65,20 @@ export type Database = { 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'] @@ -157,6 +171,32 @@ export type Database = { } Relationships: [] } + 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 From 2b30bb5d7e39c2d415dd10b3a35c2654671ea2ec Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Wed, 16 Oct 2024 23:19:25 +0800 Subject: [PATCH 104/110] chore: include all type tests --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 61e91cca..dda574d6 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "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", + "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" }, From a7108516ea6cf7df71556ab109b8888d6450ac62 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Fri, 11 Oct 2024 16:24:19 +0800 Subject: [PATCH 105/110] chore: simplify select-query-parser * move all parsing logic into one file to clearly delineate module boundaries (parsing vs. result type resolution) * collapse non-embedded resource parsing into one type * make `!left` a no-op * resolve all errors in parser.test-d.ts --- src/select-query-parser/parser.ts | 452 +++++++++++++++++++ src/select-query-parser/parser/ast.ts | 29 -- src/select-query-parser/parser/parser.ts | 506 ---------------------- src/select-query-parser/parser/utils.ts | 103 ----- src/select-query-parser/result.ts | 37 +- src/select-query-parser/utils.ts | 30 +- src/types.ts | 18 + test/select-query-parser/parser.test-d.ts | 304 +++++++------ test/select-query-parser/types.test-d.ts | 2 +- 9 files changed, 653 insertions(+), 828 deletions(-) create mode 100644 src/select-query-parser/parser.ts delete mode 100644 src/select-query-parser/parser/ast.ts delete mode 100644 src/select-query-parser/parser/parser.ts delete mode 100644 src/select-query-parser/parser/utils.ts 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/parser/ast.ts b/src/select-query-parser/parser/ast.ts deleted file mode 100644 index 9633a2cd..00000000 --- a/src/select-query-parser/parser/ast.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { AggregateFunctions, PostgreSQLTypes } from '../types' - -export interface IdentifierNode { - type: 'Identifier' - name: string -} - -export interface FieldNode { - type: 'Field' - name: string - alias?: string - hint?: unknown - inner?: boolean - left?: boolean - children?: unknown - aggregateFunction?: AggregateFunctions - castType?: PostgreSQLTypes -} - -export interface StarNode { - type: 'Star' -} - -export interface SpreadNode { - type: 'Spread' - target: FieldNode -} - -export type Node = IdentifierNode | FieldNode | StarNode | SpreadNode diff --git a/src/select-query-parser/parser/parser.ts b/src/select-query-parser/parser/parser.ts deleted file mode 100644 index 905806d9..00000000 --- a/src/select-query-parser/parser/parser.ts +++ /dev/null @@ -1,506 +0,0 @@ -import type { FieldNode, IdentifierNode, Node, SpreadNode, StarNode } from './ast' -import type { AggregateFunctions, AggregateWithoutColumnFunctions, PostgreSQLTypes } from '../types' -import type { - CreateParserErrorIfRequired, - EatWhitespace, - GenericStringError, - ParserError, - ReadLetters, - ReadQuotedLetters, -} from './utils' - -/** - * Parses a (possibly double-quoted) identifier. - * Identifiers are sequences of 1 or more letters. - */ -type ParseIdentifier = ReadLetters extends [ - infer Name extends string, - `${infer Remainder}` -] - ? [{ type: 'Identifier'; name: Name }, `${Remainder}`] - : ReadQuotedLetters extends [infer Name extends string, `${infer Remainder}`] - ? [{ type: 'Identifier'; name: Name }, `${Remainder}`] - : ParserError<`No (possibly double-quoted) identifier at \`${Input}\``> - -/** - * Parses a field without preceding field renaming. - * A field is one of the following: - * - a field with an embedded resource - * - `field(nodes)` - * - `field!hint(nodes)` - * - `field!inner(nodes)` - * - `field!left(nodes)` - * - `field!hint!inner(nodes)` - * - a field without an embedded resource (see {@link ParseFieldWithoutEmbeddedResource}) - */ -type ParseField = Input extends '' - ? ParserError<'Empty string'> - : ParseIdentifier extends [infer IdNode extends IdentifierNode, `${infer Remainder}`] - ? EatWhitespace extends `!inner${infer Rest}` - ? ParseEmbeddedResource> extends [ - infer Children extends Node[], - `${infer Remainder}` - ] - ? [ - FieldNode & { - type: 'Field' - name: IdNode['name'] - inner: true - children: Children - }, - EatWhitespace - ] - : CreateParserErrorIfRequired< - ParseEmbeddedResource>, - 'Expected embedded resource after `!inner`' - > - : EatWhitespace extends `!left${infer Rest}` - ? ParseEmbeddedResource> extends [ - infer Children extends Node[], - `${infer Remainder}` - ] - ? [ - FieldNode & { - type: 'Field' - name: IdNode['name'] - left: true - children: Children - }, - EatWhitespace - ] - : CreateParserErrorIfRequired< - ParseEmbeddedResource>, - 'Expected embedded resource after `!left`' - > - : EatWhitespace extends `!${infer Rest}` - ? ParseIdentifier> extends [ - infer HintIdNode extends IdentifierNode, - `${infer Remainder}` - ] - ? EatWhitespace extends `!inner${infer InnerRest}` - ? ParseEmbeddedResource> extends [ - infer Children extends Node[], - `${infer Remainder}` - ] - ? [ - FieldNode & { - type: 'Field' - name: IdNode['name'] - hint: HintIdNode['name'] - inner: true - children: Children - }, - EatWhitespace - ] - : CreateParserErrorIfRequired< - ParseEmbeddedResource>, - 'Expected embedded resource after `!inner`' - > - : ParseEmbeddedResource> extends [ - infer Children extends Node[], - `${infer Remainder}` - ] - ? [ - FieldNode & { - type: 'Field' - name: IdNode['name'] - hint: HintIdNode['name'] - children: Children - }, - EatWhitespace - ] - : CreateParserErrorIfRequired< - ParseEmbeddedResource>, - 'Expected embedded resource after `!hint`' - > - : ParserError<`Expected identifier after '!' at ${Rest}`> - : ParseEmbeddedResource> extends [ - infer Children extends Node[], - `${infer Remainder}` - ] - ? [ - FieldNode & { - type: 'Field' - name: IdNode['name'] - children: Children - }, - EatWhitespace - ] - : ParseEmbeddedResource> extends ParserError - ? // Return error if start of embedded resource was detected but not found. - ParseEmbeddedResource> - : // Otherwise try to match a field without embedded resource. - ParseFieldWithoutEmbeddedResource - : ParserError<`Expected identifier 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 ParseFieldWithoutEmbeddedResource = - ParseFieldWithoutEmbeddedResourceAndAggregation extends [ - infer Field extends FieldNode, - `${infer Remainder}` - ] - ? ParseFieldAggregation, false> extends [ - infer AggregateFunction extends AggregateFunctions, - `${infer Remainder}` - ] - ? [ - FieldNode & { - type: 'Field' - name: AggregateFunction - aggregateFunction: AggregateFunction - }, - EatWhitespace - ] - : ParseFieldAggregation, true> extends [ - infer AggregateFunction extends AggregateFunctions, - `${infer Remainder}` - ] - ? ParseFieldTypeCast> extends [ - infer CastType extends PostgreSQLTypes, - `${infer Remainder}` - ] - ? [ - FieldNode & { - type: 'Field' - name: Field['name'] - alias?: Field['alias'] - hint?: Field['hint'] - inner?: Field['inner'] - left?: Field['left'] - children?: Field['children'] - aggregateFunction: AggregateFunction - castType: CastType - }, - EatWhitespace - ] - : ParseFieldTypeCast> extends ParserError - ? ParserError - : [ - FieldNode & { - type: 'Field' - name: Field['name'] - alias?: Field['alias'] - hint?: Field['hint'] - inner?: Field['inner'] - left?: Field['left'] - children?: Field['children'] - aggregateFunction: AggregateFunction - }, - EatWhitespace - ] - : ParseFieldAggregation, true> extends ParserError - ? ParserError - : [Field, EatWhitespace] - : CreateParserErrorIfRequired< - ParseFieldWithoutEmbeddedResourceAndAggregation, - `Expected field at \`${Input}\`` - > - -/** - * Parses a field excluding embedded resources or aggregation, without preceding field renaming. - * This is one of the following: - * - `field` - * - `field::type` - * - `field->json...` - * - `field->json...::type` - */ -type ParseFieldWithoutEmbeddedResourceAndAggregation = - ParseFieldWithoutEmbeddedResourceAndTypeCast extends [ - infer Field extends FieldNode, - `${infer Remainder}` - ] - ? ParseFieldTypeCast> extends [ - infer CastType extends PostgreSQLTypes, - `${infer Remainder}` - ] - ? [ - FieldNode & { - type: 'Field' - name: Field['name'] - alias?: Field['alias'] - hint?: Field['hint'] - inner?: Field['inner'] - left?: Field['left'] - children?: Field['children'] - castType: CastType - }, - EatWhitespace - ] - : ParseFieldTypeCast> extends ParserError - ? ParseFieldTypeCast> - : [Field, EatWhitespace] - : CreateParserErrorIfRequired< - ParseFieldWithoutEmbeddedResourceAndTypeCast, - `Expected field at \`${Input}\`` - > - -/** - * Parses a field excluding embedded resources or typecasting, without preceding field renaming. - * This is one of the following: - * - `field` - * - `field->json...` - */ -type ParseFieldWithoutEmbeddedResourceAndTypeCast = - ParseIdentifier extends [infer IdNode extends IdentifierNode, `${infer Remainder}`] - ? ParseJsonAccessor> extends [ - infer JsonFieldName extends string, - infer JsonFieldType, - `${infer Remainder}` - ] - ? [ - FieldNode & { - type: 'Field' - name: IdNode['name'] - alias: JsonFieldName - castType: JsonFieldType - }, - EatWhitespace - ] - : [ - FieldNode & { - type: 'Field' - name: IdNode['name'] - }, - EatWhitespace - ] - : ParserError<`Expected field at \`${Input}\``> - -/** - * Parses a field typecast (`::type`), returning a tuple of [CastType, Remainder] - * or the original string input indicating that no typecast was found. - */ -type ParseFieldTypeCast = EatWhitespace extends `::${infer Remainder}` - ? ParseIdentifier> extends [ - infer TypeIdNode extends IdentifierNode, - `${infer Remainder}` - ] - ? // Ensure that `CastType` is a valid PostgreSQL type. - TypeIdNode['name'] extends PostgreSQLTypes - ? [TypeIdNode['name'], EatWhitespace] - : // We will never enter those conditions as PostgresSQLTypes have string in the union - // that will match anything for custom types handling - // TODO: extract the custom_types from the database and check that the - // cast is actually a valid type - ParserError<`Invalid type for \`::\` operator \`${TypeIdNode['name']}\``> - : ParserError<`Invalid type for \`::\` operator at \`${Remainder}\``> - : Input - -/** - * Parses a field aggregation (`.max()`), returning a tuple of [AggregateFunction, Remainder] - * or the original string input indicating that no aggregation was found. - */ -type ParseFieldAggregation< - Input extends string, - IsField extends boolean = false -> = IsField extends true - ? EatWhitespace extends `.${infer Remainder}` - ? ParseIdentifier> extends [ - infer FuncIdNode extends IdentifierNode, - `${infer Remainder}` - ] - ? FuncIdNode['name'] extends AggregateFunctions - ? EatWhitespace extends `()${infer Remainder}` - ? [FuncIdNode['name'], EatWhitespace] - : ParserError<`Expected \`()\` after \`.\` operator \`${FuncIdNode['name']}\``> - : ParserError<`Invalid function for \`.\` operator \`${FuncIdNode['name']}\``> - : ParserError<`Invalid function for \`.\` operator at \`${Remainder}\``> - : Input - : // Check if the function is just count or count() - ParseIdentifier extends [infer FuncIdNode extends IdentifierNode, `${infer Remainder}`] - ? FuncIdNode['name'] extends AggregateWithoutColumnFunctions - ? EatWhitespace extends `()${infer Remainder}` - ? [FuncIdNode['name'], EatWhitespace] - : [FuncIdNode['name'], EatWhitespace] - : Input - : Input - -/** - * Parses a node. - * A node is one of the following: - * - `*` - * - a field, as defined above - * - a renamed field, `alias:field` - * - a spread field, `...field` - */ -type ParseNode = Input extends '' - ? ParserError<'Empty string'> - : Input extends `*${infer Remainder}` - ? [ - StarNode & { - type: 'Star' - }, - EatWhitespace - ] - : Input extends `...${infer Rest}` - ? ParseField> extends [ - infer TargetField extends FieldNode, - `${infer Remainder}` - ] - ? [ - SpreadNode & { - type: 'Spread' - target: TargetField - }, - EatWhitespace - ] - : ParserError<`Unable to parse spread resource at ${NodesInput}`> - : ParseIdentifier extends [infer AliasIdNode extends IdentifierNode, `${infer Remainder}`] - ? EatWhitespace extends `::${infer _Rest}` - ? // If we find '::', it's a type cast, so treat it as part of the field - ParseField - : EatWhitespace extends `:${infer Rest}` - ? // This is for the case where the aggregate function is count since it can be - // called at top level withtout any mention of a column we need to repeat it to - // preserve the aggregateFunction litteral - ParseFieldAggregation extends [ - infer AggregateFunction extends AggregateFunctions, - `${infer Remainder}` - ] - ? [ - { - type: 'Field' - name: AggregateFunction - alias: AliasIdNode['name'] - aggregateFunction: AggregateFunction - }, - EatWhitespace - ] - : ParseField> extends [ - infer Field extends FieldNode, - `${infer Remainder}` - ] - ? [ - FieldNode & { - type: 'Field' - name: Field['name'] - alias: AliasIdNode['name'] - hint?: Field['hint'] - inner?: Field['inner'] - left?: Field['left'] - children?: Field['children'] - castType?: Field['castType'] - aggregateFunction?: Field['aggregateFunction'] - }, - EatWhitespace - ] - : ParserError<`Unable to parse renamed field at ${NodesInput}`> - : // This is for the case where the aggregate function is count since it can be - // called at top level withtout any mention of a column - ParseFieldAggregation extends [ - infer AggregateFunction extends AggregateFunctions, - `${infer Remainder}` - ] - ? [ - { - type: 'Field' - name: AggregateFunction - aggregateFunction: AggregateFunction - }, - EatWhitespace - ] - : ParseField - : ParserError<`Expected identifier at \`${NodesInput}\``> - -/** - * 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 [PropertyName, PropertyType, Remainder] - * or the original string input indicating that no opening `->` was found. - */ -type ParseJsonAccessor = EatWhitespace extends `->${infer Remainder}` - ? EatWhitespace extends `>${infer Rest}` - ? ParseIdentifier> extends [ - infer NameIdNode extends IdentifierNode, - `${infer Remainder}` - ] - ? // In the case of a ->> the result will be casted as text by default - [NameIdNode['name'], 'text', EatWhitespace] - : ParserError<`Expected property name after '->>'${Rest}`> - : ParseIdentifier> extends [ - infer NameIdNode extends IdentifierNode, - `${infer Remainder}` - ] - ? ParseJsonAccessor extends [ - infer PropertyName extends string, - infer PropertyType, - `${infer Remainder}` - ] - ? [PropertyName, PropertyType, EatWhitespace] - : // With a -> accessor result will be casted as Json type - [NameIdNode['name'], 'json', EatWhitespace] - : ParserError<`Expected property name after '->' at ${Remainder}`> - : 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 [Fields, Remainder], an error, - * or the original string input indicating that no opening `(` was found. - */ -type ParseEmbeddedResource = - EatWhitespace extends `(${infer Remainder}` - ? ParseNodes> extends [ - infer Nodes extends Node[], - `${infer Remainder}` - ] - ? EatWhitespace extends `)${infer Remainder}` - ? [Nodes, EatWhitespace] - : ParserError<`Expected ')' at ${Remainder}`> - : // If no nodes were detected, check for `)` for empty embedded resources `()`. - ParseNodes> extends ParserError - ? EatWhitespace extends `)${infer Remainder}` - ? [[], EatWhitespace] - : ParseNodes> - : ParserError<`Expected embedded resource fields or ')' at ${Remainder}`> - : Input - -/** - * Parses a sequence of nodes, separated by `,`. - * - * Returns a tuple of [Nodes, Remainder] or an error. - */ -type ParseNodes = string extends Input - ? GenericStringError - : ParseNodesHelper - -type ParseNodesHelper< - Input extends string, - Nodes extends Node[], - NodesInput extends string -> = ParseNode extends [infer NodeResult extends Node, `${infer Remainder}`] - ? EatWhitespace extends `,${infer Rest}` - ? ParseNodesHelper, [...Nodes, NodeResult], NodesInput> - : [[...Nodes, NodeResult], 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. - */ -export type ParseQuery = string extends Query - ? GenericStringError - : ParseNodes> extends [infer Nodes extends Node[], `${infer Remainder}`] - ? EatWhitespace extends '' - ? Nodes - : ParserError<`Unexpected input: ${Remainder}`> - : ParseNodes> diff --git a/src/select-query-parser/parser/utils.ts b/src/select-query-parser/parser/utils.ts deleted file mode 100644 index 619f97b0..00000000 --- a/src/select-query-parser/parser/utils.ts +++ /dev/null @@ -1,103 +0,0 @@ -// Some utils type for the ParseQuery parser logic -// Count is a special case where an aggregate function won't need a column to be run against -// see: https://postgrest.org/en/v12/references/api/aggregate_functions.html#the-case-of-count - -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 | '_' - -/** - * Reads a consecutive sequence of 1 or more letters, where letters are `[0-9a-zA-Z_]`. - */ -export 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, ''] - -/** - * Reads a consecutive sequence of 1 or more double-quoted letters, - * where letters are `[^"]`. - */ -export type ReadQuotedLetters = string extends Input - ? GenericStringError - : Input extends `"${infer Remainder}` - ? ReadQuotedLettersHelper extends [`${infer Letters}`, `${infer Remainder}`] - ? Letters extends '' - ? ParserError<`Expected string at \`${Remainder}\``> - : [Letters, Remainder] - : ReadQuotedLettersHelper - : ParserError<`Not a double-quoted string at \`${Input}\``> - -type ReadQuotedLettersHelper = string extends Input - ? GenericStringError - : Input extends `${infer L}${infer Remainder}` - ? L extends '"' - ? [Acc, Remainder] - : ReadQuotedLettersHelper - : ParserError<`Missing closing double-quote in \`"${Acc}${Input}\``> - -/** - * Parser errors. - */ -export type ParserError = { error: true } & Message -export type GenericStringError = ParserError<'Received a generic string'> - -/** - * Creates a new {@link ParserError} if the given input is not already a parser error. - */ -export type CreateParserErrorIfRequired< - Input, - Message extends string -> = Input extends ParserError ? Input : ParserError - -type Whitespace = ' ' | '\n' | '\t' - -/** - * Trims whitespace from the left of the input. - */ -export type EatWhitespace = string extends Input - ? GenericStringError - : Input extends `${Whitespace}${infer Remainder}` - ? EatWhitespace - : Input diff --git a/src/select-query-parser/result.ts b/src/select-query-parser/result.ts index 097901a6..0b89e36c 100644 --- a/src/select-query-parser/result.ts +++ b/src/select-query-parser/result.ts @@ -1,7 +1,6 @@ import { GenericTable } from '../types' import { ContainsNull, GenericRelationship, PostgreSQLTypes } from './types' -import { FieldNode, Node, SpreadNode, StarNode } from './parser/ast' -import { ParseQuery } from './parser/parser' +import { Ast, ParseQuery } from './parser' import { AggregateFunctions, ExtractFirstProperty, @@ -37,7 +36,7 @@ export type GetResult< > = Relationships extends null // For .rpc calls the passed relationships will be null in that case, the result will always be the function return type ? Row : ParseQuery extends infer ParsedQuery - ? ParsedQuery extends Node[] + ? ParsedQuery extends Ast.Node[] ? RelationName extends string ? Relationships extends GenericRelationship[] ? ProcessNodes @@ -61,10 +60,10 @@ export type ProcessNodes< Row extends Record, RelationName extends string, Relationships extends GenericRelationship[], - Nodes extends Node[], + Nodes extends Ast.Node[], Acc extends Record = {} // Acc is now an object > = CheckDuplicateEmbededReference extends false - ? Nodes extends [infer FirstNode extends Node, ...infer RestNodes extends Node[]] + ? Nodes extends [infer FirstNode extends Ast.Node, ...infer RestNodes extends Ast.Node[]] ? ProcessNode extends infer FieldResult ? FieldResult extends Record ? ProcessNodes @@ -89,12 +88,12 @@ export type ProcessNode< Row extends Record, RelationName extends string, Relationships extends GenericRelationship[], - NodeType extends Node -> = NodeType extends StarNode // If the selection is * + NodeType extends Ast.Node +> = NodeType extends Ast.StarNode // If the selection is * ? Row - : NodeType extends SpreadNode // If the selection is a ...spread + : NodeType extends Ast.SpreadNode // If the selection is a ...spread ? ProcessSpreadNode - : NodeType extends FieldNode + : NodeType extends Ast.FieldNode ? ProcessFieldNode : SelectQueryError<'Unsupported node type.'> @@ -107,12 +106,12 @@ export type ProcessNode< * @param Relationships - Relationships of the current table. * @param Field - The FieldNode to process. */ -export type ProcessFieldNode< +type ProcessFieldNode< Schema extends GenericSchema, Row extends Record, RelationName extends string, Relationships extends GenericRelationship[], - Field extends FieldNode + Field extends Ast.FieldNode > = Field['children'] extends [] ? {} : IsNonEmptyArray extends true // Has embedded resource? @@ -126,10 +125,10 @@ export type ProcessFieldNode< * @param RelationName - The name of the current table or view. * @param Field - The FieldNode to process. */ -export type ProcessSimpleField< +type ProcessSimpleField< Row extends Record, RelationName extends string, - Field extends FieldNode + Field extends Ast.FieldNode > = Field['aggregateFunction'] extends AggregateFunctions ? { // An aggregate function will always override the column name id.sum() will become sum @@ -159,7 +158,7 @@ export type ProcessSimpleField< export type ProcessEmbeddedResource< Schema extends GenericSchema, Relationships extends GenericRelationship[], - Field extends FieldNode, + Field extends Ast.FieldNode, CurrentTableOrView extends keyof TablesAndViews > = ResolveRelationship extends infer Resolved ? Resolved extends { @@ -185,7 +184,7 @@ type ProcessEmbeddedResourceResult< relation: GenericRelationship & { match: 'refrel' | 'col' | 'fkname' } direction: string }, - Field extends FieldNode, + Field extends Ast.FieldNode, CurrentTableOrView extends keyof TablesAndViews > = ProcessNodes< Schema, @@ -194,13 +193,13 @@ type ProcessEmbeddedResourceResult< Resolved['referencedTable']['Relationships'], Field['children'] extends undefined ? [] - : Exclude extends Node[] + : Exclude extends Ast.Node[] ? Exclude : [] > extends infer ProcessedChildren ? { [K in GetFieldNodeResultName]: Resolved['direction'] extends 'forward' - ? Field extends { inner: true } + ? Field extends { innerJoin: true } ? Resolved['relation']['isOneToOne'] extends true ? ProcessedChildren : ProcessedChildren[] @@ -243,12 +242,12 @@ type ProcessEmbeddedResourceResult< * @param Relationships - Relationships of the current table. * @param Spread - The SpreadNode to process. */ -export type ProcessSpreadNode< +type ProcessSpreadNode< Schema extends GenericSchema, Row extends Record, RelationName extends string, Relationships extends GenericRelationship[], - Spread extends SpreadNode + Spread extends Ast.SpreadNode > = ProcessNode extends infer Result ? Result extends SelectQueryError ? SelectQueryError diff --git a/src/select-query-parser/utils.ts b/src/select-query-parser/utils.ts index 3ffa4657..40dd3e20 100644 --- a/src/select-query-parser/utils.ts +++ b/src/select-query-parser/utils.ts @@ -1,4 +1,4 @@ -import { FieldNode, Node, SpreadNode } from './parser/ast' +import { Ast } from './parser' import { AggregateFunctions, ContainsNull, @@ -12,24 +12,22 @@ import { export type SelectQueryError = { error: true } & Message -export type ProcessedNodeResult = Record | SelectQueryError - 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 +export type GetFieldNodeResultName = Field['alias'] extends string ? Field['alias'] : Field['aggregateFunction'] extends AggregateFunctions ? Field['aggregateFunction'] : Field['name'] -type FilterRelationNodes = UnionToArray< +type FilterRelationNodes = UnionToArray< { - [K in keyof Nodes]: Nodes[K] extends SpreadNode + [K in keyof Nodes]: Nodes[K] extends Ast.SpreadNode ? Nodes[K]['target'] - : Nodes[K] extends FieldNode + : Nodes[K] extends Ast.FieldNode ? IsNonEmptyArray extends true ? Nodes[K] : never @@ -37,11 +35,11 @@ type FilterRelationNodes = UnionToArray< }[number] > -export type ResolveRelationships< +type ResolveRelationships< Schema extends GenericSchema, RelationName extends string, Relationships extends GenericRelationship[], - Nodes extends FieldNode[] + Nodes extends Ast.FieldNode[] > = UnionToArray<{ [K in keyof Nodes]: ResolveRelationship< Schema, @@ -101,8 +99,8 @@ export type CheckDuplicateEmbededReference< Schema extends GenericSchema, RelationName extends string, Relationships extends GenericRelationship[], - Nodes extends Node[] -> = FilterRelationNodes extends infer RelationsNodes extends FieldNode[] + Nodes extends Ast.Node[] +> = FilterRelationNodes extends infer RelationsNodes extends Ast.FieldNode[] ? ResolveRelationships< Schema, RelationName, @@ -196,7 +194,7 @@ type CheckRelationshipError< export type ResolveRelationship< Schema extends GenericSchema, Relationships extends GenericRelationship[], - Field extends FieldNode, + Field extends Ast.FieldNode, CurrentTableOrView extends keyof TablesAndViews > = ResolveReverseRelationship< Schema, @@ -220,7 +218,7 @@ export type ResolveRelationship< type ResolveReverseRelationship< Schema extends GenericSchema, Relationships extends GenericRelationship[], - Field extends FieldNode, + Field extends Ast.FieldNode, CurrentTableOrView extends keyof TablesAndViews > = FindFieldMatchingRelationships extends infer FoundRelation ? FoundRelation extends never @@ -376,12 +374,12 @@ type FilterRelationships = R extends readonly (infer Rel)[] // Find a relationship from the parent to the childrens type ResolveForwardRelationship< Schema extends GenericSchema, - Field extends FieldNode, + Field extends Ast.FieldNode, CurrentTableOrView extends keyof TablesAndViews > = FindFieldMatchingRelationships< Schema, TablesAndViews[Field['name']]['Relationships'], - FieldNode & { name: CurrentTableOrView; hint: Field['hint'] } + Ast.FieldNode & { name: CurrentTableOrView; hint: Field['hint'] } > extends infer FoundByName extends GenericRelationship ? { referencedTable: TablesAndViews[Field['name']] @@ -415,7 +413,7 @@ type ResolveForwardRelationship< export type FindFieldMatchingRelationships< Schema extends GenericSchema, Relationships extends GenericRelationship[], - Field extends FieldNode + Field extends Ast.FieldNode > = Field extends { hint?: infer Hint extends string } ? FindMatchingHintTableRelationships< Schema, diff --git a/src/types.ts b/src/types.ts index a26a2eed..88688144 100644 --- a/src/types.ts +++ b/src/types.ts @@ -81,3 +81,21 @@ export type GenericSchema = { // 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/select-query-parser/parser.test-d.ts b/test/select-query-parser/parser.test-d.ts index 5cbb1680..5f637511 100644 --- a/test/select-query-parser/parser.test-d.ts +++ b/test/select-query-parser/parser.test-d.ts @@ -1,6 +1,5 @@ import { expectType } from 'tsd' -import type { ParseQuery } from '../../src/select-query-parser/parser/parser' -import type { ParserError } from '../../src/select-query-parser/parser/utils' +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 @@ -9,25 +8,25 @@ import { selectParams } from '../relationships' // Basic select with multiple fields { expectType>([ - { type: 'Field', name: 'username' }, - { type: 'Field', name: 'email' }, - { type: 'Field', name: 'created_at' }, + { type: 'field', name: 'username' }, + { type: 'field', name: 'email' }, + { type: 'field', name: 'created_at' }, ]) } // Select with star { - expectType>([{ type: 'Star' }]) + expectType>([{ type: 'star' }]) } { - expectType>([{ type: 'Field', name: 'username' }, { type: 'Star' }]) + expectType>([{ type: 'field', name: 'username' }, { type: 'star' }]) } // Select with renamed field { expectType>([ - { type: 'Field', name: 'username', alias: 'display_name' }, + { type: 'field', name: 'username', alias: 'display_name' }, ]) } @@ -35,12 +34,12 @@ import { selectParams } from '../relationships' { expectType>([ { - type: 'Field', + type: 'field', name: 'posts', children: [ - { type: 'Field', name: 'id' }, - { type: 'Field', name: 'title' }, - { type: 'Field', name: 'content' }, + { type: 'field', name: 'id' }, + { type: 'field', name: 'title' }, + { type: 'field', name: 'content' }, ], }, ]) @@ -50,17 +49,17 @@ import { selectParams } from '../relationships' { expectType>([ { - type: 'Field', + type: 'field', name: 'posts', children: [ - { type: 'Field', name: 'id' }, - { type: 'Field', name: 'title' }, + { type: 'field', name: 'id' }, + { type: 'field', name: 'title' }, { - type: 'Field', + type: 'field', name: 'author', children: [ - { type: 'Field', name: 'name' }, - { type: 'Field', name: 'email' }, + { type: 'field', name: 'name' }, + { type: 'field', name: 'email' }, ], }, ], @@ -72,9 +71,9 @@ import { selectParams } from '../relationships' { expectType>([ { - type: 'Field', + type: 'field', name: 'posts', - children: [{ type: 'Field', name: 'count', aggregateFunction: 'count' }], + children: [{ type: 'field', name: 'count', aggregateFunction: 'count' }], }, ]) } @@ -82,14 +81,14 @@ import { selectParams } from '../relationships' // Select with JSON accessor { expectTypepreferences->theme'>>([ - { type: 'Field', name: 'data', alias: 'theme', castType: 'json' }, + { 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' }, + { type: 'field', name: 'data', alias: 'theme', castType: 'text' }, ]) } @@ -97,17 +96,17 @@ import { selectParams } from '../relationships' { expectType>([ { - type: 'Field', + type: 'field', name: 'username', }, { - type: 'Spread', + type: 'spread', target: { - type: 'Field', + type: 'field', name: 'posts', children: [ - { type: 'Field', name: 'id' }, - { type: 'Field', name: 'title' }, + { type: 'field', name: 'id' }, + { type: 'field', name: 'title' }, ], }, }, @@ -116,13 +115,13 @@ import { selectParams } from '../relationships' { expectType>([ { - type: 'Spread', + type: 'spread', target: { - type: 'Field', + type: 'field', name: 'users', children: [ - { type: 'Field', name: 'first_name' }, - { type: 'Field', name: 'last_name' }, + { type: 'field', name: 'first_name' }, + { type: 'field', name: 'last_name' }, ], }, }, @@ -133,13 +132,13 @@ import { selectParams } from '../relationships' { expectType>([ { - type: 'Field', + type: 'field', name: 'posts', + innerJoin: true, children: [ - { type: 'Field', name: 'id' }, - { type: 'Field', name: 'title' }, + { type: 'field', name: 'id' }, + { type: 'field', name: 'title' }, ], - inner: true, }, ]) } @@ -148,13 +147,12 @@ import { selectParams } from '../relationships' { expectType>([ { - type: 'Field', + type: 'field', name: 'posts', children: [ - { type: 'Field', name: 'id' }, - { type: 'Field', name: 'title' }, + { type: 'field', name: 'id' }, + { type: 'field', name: 'title' }, ], - left: true, }, ]) } @@ -163,13 +161,13 @@ import { selectParams } from '../relationships' { expectType>([ { - type: 'Field', + type: 'field', name: 'users', alias: 'author', hint: 'user_id', children: [ - { type: 'Field', name: 'id' }, - { type: 'Field', name: 'name' }, + { type: 'field', name: 'id' }, + { type: 'field', name: 'name' }, ], }, ]) @@ -180,26 +178,25 @@ import { selectParams } from '../relationships' 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: 'id' }, + { type: 'field', name: 'username' }, { - type: 'Field', + type: 'field', name: 'posts', children: [ - { type: 'Field', name: 'id' }, - { type: 'Field', name: 'title' }, + { type: 'field', name: 'id' }, + { type: 'field', name: 'title' }, { - type: 'Field', + type: 'field', name: 'comments', children: [ - { type: 'Field', name: 'id' }, - { type: 'Field', name: 'content' }, + { type: 'field', name: 'id' }, + { type: 'field', name: 'content' }, ], }, ], - left: true, }, - { type: 'Field', name: 'profile', alias: 'theme', castType: 'text' }, + { type: 'field', name: 'profile', alias: 'theme', castType: 'text' }, ]) } { @@ -208,61 +205,61 @@ import { selectParams } from '../relationships' type isCount = aggFunction extends 'count' ? true : false expectType(true) expectType>([ - { type: 'Field', name: 'id' }, + { type: 'field', name: 'id' }, { - type: 'Field', + type: 'field', name: 'posts', - children: [{ type: 'Field', name: 'count', aggregateFunction: 'count' }], + children: [{ type: 'field', name: 'count', aggregateFunction: 'count' }], }, { - type: 'Field', + type: 'field', name: 'comments', - children: [{ type: 'Field', alias: 'sum', name: 'id', aggregateFunction: 'sum' }], + children: [{ type: 'field', alias: 'sum', name: 'id', aggregateFunction: 'sum' }], }, ]) } { expectType>([ - { type: 'Field', name: 'id' }, + { type: 'field', name: 'id' }, { - type: 'Field', + type: 'field', name: 'posts', - children: [{ type: 'Field', name: 'count', aggregateFunction: 'count' }], + children: [{ type: 'field', name: 'count', aggregateFunction: 'count' }], }, { - type: 'Field', + type: 'field', name: 'comments', - children: [{ type: 'Field', name: 'id', aggregateFunction: 'sum' }], + children: [{ type: 'field', name: 'id', aggregateFunction: 'sum' }], }, ]) } { expectType>([ - { type: 'Field', name: 'id' }, + { type: 'field', name: 'id' }, { - type: 'Field', + type: 'field', name: 'posts', - children: [{ type: 'Field', name: 'id', aggregateFunction: 'count' }], + children: [{ type: 'field', name: 'id', aggregateFunction: 'count' }], }, ]) } { expectType>([ - { type: 'Field', name: 'id' }, + { type: 'field', name: 'id' }, { - type: 'Field', + type: 'field', name: 'posts', - children: [{ type: 'Field', name: 'id', alias: 'aliased', aggregateFunction: 'count' }], + children: [{ type: 'field', name: 'id', alias: 'aliased', aggregateFunction: 'count' }], }, ]) } { expectType>([ - { type: 'Field', name: 'id' }, + { type: 'field', name: 'id' }, { - type: 'Field', + type: 'field', name: 'posts', - children: [{ type: 'Field', name: 'count', aggregateFunction: 'count' }], + children: [{ type: 'field', name: 'count', aggregateFunction: 'count' }], }, ]) } @@ -272,12 +269,12 @@ import { selectParams } from '../relationships' type isCount = aggFunction extends 'count' ? true : false expectType(true) expectType>([ - { type: 'Field', name: 'id' }, + { type: 'field', name: 'id' }, { - type: 'Field', + type: 'field', name: 'posts', children: [ - { type: 'Field', alias: 'renamed_count', name: 'count', aggregateFunction: 'count' }, + { type: 'field', alias: 'renamed_count', name: 'count', aggregateFunction: 'count' }, ], }, ]) @@ -288,17 +285,17 @@ import { selectParams } from '../relationships' type isCount = aggFunction extends 'count' ? true : false expectType(true) expectType>([ - { type: 'Field', name: 'username' }, + { type: 'field', name: 'username' }, { - type: 'Field', + type: 'field', name: 'messages', children: [ { - type: 'Field', + type: 'field', name: 'channels', children: [ { - type: 'Field', + type: 'field', alias: 'channel_count', name: 'count', aggregateFunction: 'count', @@ -313,46 +310,50 @@ import { selectParams } from '../relationships' // should be a field like any other { expectType>([ - { type: 'Field', name: 'posts', children: [{ type: 'Field', name: 'sum' }] }, + { 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: [] }] }, + { + 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' }, + { type: 'field', name: 'data', alias: 'color', castType: 'json' }, ]) } // Select with multiple spreads { expectType>([ - { type: 'Field', name: 'id' }, + { type: 'field', name: 'id' }, { - type: 'Spread', + type: 'spread', target: { - type: 'Field', + type: 'field', name: 'profile', children: [ - { type: 'Field', name: 'name' }, - { type: 'Field', name: 'email' }, + { type: 'field', name: 'name' }, + { type: 'field', name: 'email' }, ], }, }, { - type: 'Spread', + type: 'spread', target: { - type: 'Field', + type: 'field', name: 'settings', children: [ - { type: 'Field', name: 'theme' }, - { type: 'Field', name: 'language' }, + { type: 'field', name: 'theme' }, + { type: 'field', name: 'language' }, ], }, }, @@ -363,22 +364,22 @@ import { selectParams } from '../relationships' { expectType>([ { - type: 'Field', + type: 'field', alias: 'author', name: 'users', hint: 'user_id', children: [ - { type: 'Field', name: 'id' }, - { type: 'Field', name: 'name' }, + { type: 'field', name: 'id' }, + { type: 'field', name: 'name' }, ], }, { - type: 'Field', + type: 'field', name: 'posts', hint: 'post_id', children: [ - { type: 'Field', name: 'title' }, - { type: 'Field', name: 'content' }, + { type: 'field', name: 'title' }, + { type: 'field', name: 'content' }, ], }, ]) @@ -388,22 +389,21 @@ import { selectParams } from '../relationships' { expectType>([ { - type: 'Field', + type: 'field', name: 'users', + innerJoin: true, children: [ - { type: 'Field', name: 'id' }, - { type: 'Field', name: 'name' }, + { type: 'field', name: 'id' }, + { type: 'field', name: 'name' }, ], - inner: true, }, { - type: 'Field', + type: 'field', name: 'posts', children: [ - { type: 'Field', name: 'title' }, - { type: 'Field', name: 'content' }, + { type: 'field', name: 'title' }, + { type: 'field', name: 'content' }, ], - left: true, }, ]) } @@ -411,12 +411,12 @@ import { selectParams } from '../relationships' // Select with quoted identifiers { expectType>([ - { type: 'Field', name: 'complex name', alias: 'user name' }, + { type: 'field', name: 'complex name', alias: 'user name' }, { - type: 'Field', + type: 'field', alias: 'post-title', name: 'posts', - children: [{ type: 'Field', name: 'content-body' }], + children: [{ type: 'field', name: 'content-body' }], }, ]) } @@ -425,17 +425,17 @@ import { selectParams } from '../relationships' { expectType>([ { - type: 'Field', + type: 'field', name: 'users', children: [ - { type: 'Field', name: 'id' }, + { type: 'field', name: 'id' }, { - type: 'Field', + type: 'field', name: 'posts', children: [ - { type: 'Field', name: 'count', castType: 'int', aggregateFunction: 'count' }, + { type: 'field', name: 'count', castType: 'int', aggregateFunction: 'count' }, { - type: 'Field', + type: 'field', alias: 'avg_likes', name: 'likes', castType: 'float', @@ -452,7 +452,7 @@ import { selectParams } from '../relationships' { expectType>([ { - type: 'Field', + type: 'field', name: 'id', castType: 'invalid_type', }, @@ -462,109 +462,105 @@ import { selectParams } from '../relationships' // 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' }, + { 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' }, + { 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' }, + { 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: [] }, + { type: 'field', name: 'message' }, + { type: 'field', name: 'users', children: [] }, ]) } // ParserError test cases // Empty string { - const r: ParserError<'Empty string'> = 'Empty string' as ParserError<'Empty string'> - expectType>(r) + expectType>(0 as any as ParserError<'Empty string'>) } // Unexpected input at the end { - const r: ParserError<'Unexpected input: unexpected_input'> = - 'Unexpected input: unexpected_input' as ParserError<'Unexpected input: unexpected_input'> - expectType>(r) + expectType>( + 0 as any as ParserError<'Unexpected input: unexpected_input'> + ) } // Missing closing parenthesis { - const r: ParserError<"Expected ')' at "> = "Expected ')' at " as ParserError<"Expected ')' at "> - expectType>(r) + expectType>(0 as any as ParserError<'Expected ")" at ``'>) } // Incomplete JSON accessor { - const r: ParserError<'Unexpected input: ->'> = - 'Unexpected input: ->' as ParserError<'Unexpected input: ->'> - expectType'>>(r) + expectType'>>(0 as any as ParserError<'Expected property name after `->`'>) } // Invalid hint (missing identifier after !) { - const r: ParserError<"Expected identifier after '!' at (id, name)"> = - "Expected identifier after '!' at (id, name)" as ParserError<"Expected identifier after '!' at (id, name)"> - expectType>(r) + expectType>( + 0 as any as ParserError<'Expected identifier after "!" at `(id, name)`'> + ) } // Invalid spread (missing field after ...) { - const r: ParserError<'Unable to parse spread resource at ...::'> = - 'Unable to parse spread resource at ...::' as ParserError<'Unable to parse spread resource at ...::'> - expectType>(r) + expectType>( + 0 as any as ParserError<'Unable to parse spread resource at `...::`'> + ) } // Invalid rename (missing field after :) { - const r: ParserError<'Unable to parse renamed field at new_name:'> = - 'Unable to parse renamed field at new_name:' as ParserError<'Unable to parse renamed field at new_name:'> - expectType>(r) + expectType>( + 0 as any as ParserError<'Unable to parse renamed field at `new_name:`'> + ) } // Incomplete quoted identifier { - const r: ParserError<'Expected identifier at `"incomplete`'> = - 'Expected identifier at `"incomplete`' as ParserError<'Expected identifier at `"incomplete`'> - expectType>(r) + expectType>( + 0 as any as ParserError<'Expected identifier at `"incomplete`'> + ) } // Invalid combination of inner and left join { - const r: ParserError<'Expected embedded resource after `!inner`'> = - 'Expected embedded resource after `!inner`' as ParserError<'Expected embedded resource after `!inner`'> - expectType>(r) + expectType>( + 0 as any as ParserError<'Expected "(" at `!left(id, name)`'> + ) } // Missing opening parenthesis after aggregate function { - const r: ParserError<'Expected `()` after `.` operator `avg`'> = - 'Expected `()` after `.` operator `avg`' as ParserError<'Expected `()` after `.` operator `avg`'> - expectType>(r) + expectType>( + 0 as any as ParserError<'Expected `()` after `.` operator `avg`'> + ) } // Invalid nested JSON accessor { - const r: ParserError<'Unexpected input: ->->theme'> = - 'Unexpected input: ->->theme' as ParserError<'Unexpected input: ->->theme'> - expectTypepreferences->->theme'>>(r) + expectTypepreferences->->theme'>>( + 0 as any as ParserError<'Unexpected input: ->->theme'> + ) } diff --git a/test/select-query-parser/types.test-d.ts b/test/select-query-parser/types.test-d.ts index 6021acbb..02f74cf7 100644 --- a/test/select-query-parser/types.test-d.ts +++ b/test/select-query-parser/types.test-d.ts @@ -12,7 +12,7 @@ import { IsRelationNullable, } from '../../src/select-query-parser/utils' import { Json } from '../../src/select-query-parser/types' -import { ParseQuery } from '../../src/select-query-parser/parser/parser' +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 From 05419fbf846ed788fff5f1cfdac49f1c3d1188e9 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Thu, 17 Oct 2024 00:00:47 +0800 Subject: [PATCH 106/110] chore: fix types.test-d.ts --- test/select-query-parser/types.test-d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/select-query-parser/types.test-d.ts b/test/select-query-parser/types.test-d.ts index 02f74cf7..9957e0e5 100644 --- a/test/select-query-parser/types.test-d.ts +++ b/test/select-query-parser/types.test-d.ts @@ -154,7 +154,7 @@ import { ParseQuery } from '../../src/select-query-parser/parser' data: Json | null status: Database['public']['Enums']['user_status'] | null username: string - } + } | null } expectType(expected!) type r2 = ProcessNodes From e7b35e9cf0e33ebd7ea9bd150fdfe44820fa1931 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Thu, 17 Oct 2024 00:03:46 +0800 Subject: [PATCH 107/110] chore: add test for selecting on an rpc call --- test/select-query-parser/rpc.test-d.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/select-query-parser/rpc.test-d.ts b/test/select-query-parser/rpc.test-d.ts index a8325254..f1dcddc0 100644 --- a/test/select-query-parser/rpc.test-d.ts +++ b/test/select-query-parser/rpc.test-d.ts @@ -10,3 +10,10 @@ import { TypeEqual } from 'ts-expect' let expected: Database['public']['Functions']['get_username_and_status']['Returns'][number] expectType>(true) } + +// select on an rpc call +{ + const { data, error } = await postgrest.rpc('get_username_and_status').select('username') + if (error) throw error + expectType<{ username: string }[]>(data) +} From 4adf2a5a25fc15dabe563098c0b16298e8672174 Mon Sep 17 00:00:00 2001 From: avallete Date: Wed, 16 Oct 2024 20:05:08 +0200 Subject: [PATCH 108/110] feat: handle select over RPC calls --- src/PostgrestClient.ts | 2 +- src/select-query-parser/result.ts | 38 +++++- test/index.test.ts | 1 + test/rpc.ts | 158 +++++++++++++++++++++++++ test/select-query-parser/rpc.test-d.ts | 71 +++++++++-- 5 files changed, 260 insertions(+), 10 deletions(-) create mode 100644 test/rpc.ts diff --git a/src/PostgrestClient.ts b/src/PostgrestClient.ts index 954ac7dc..8a37b09c 100644 --- a/src/PostgrestClient.ts +++ b/src/PostgrestClient.ts @@ -141,7 +141,7 @@ export default class PostgrestClient< : never : never, Fn['Returns'], - null, + FnName, null > { let method: 'HEAD' | 'GET' | 'POST' diff --git a/src/select-query-parser/result.ts b/src/select-query-parser/result.ts index 0b89e36c..3510a309 100644 --- a/src/select-query-parser/result.ts +++ b/src/select-query-parser/result.ts @@ -34,7 +34,9 @@ export type GetResult< 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 - ? Row + ? ParseQuery extends infer ParsedQuery extends Ast.Node[] + ? RPCCallNodes + : Row : ParseQuery extends infer ParsedQuery ? ParsedQuery extends Ast.Node[] ? RelationName extends string @@ -45,6 +47,40 @@ export type GetResult< : 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. * diff --git a/test/index.test.ts b/test/index.test.ts index 6a18f85d..a7f2ffc6 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -3,3 +3,4 @@ import './relationships' import './filters' import './resource-embedding' import './transforms' +import './rpc' 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/rpc.test-d.ts b/test/select-query-parser/rpc.test-d.ts index f1dcddc0..858434bf 100644 --- a/test/select-query-parser/rpc.test-d.ts +++ b/test/select-query-parser/rpc.test-d.ts @@ -1,19 +1,74 @@ -import { postgrest } from '../relationships' +import { postgrest, selectParams, RPC_NAME } from '../rpc' import { Database } from '../types' import { expectType } from 'tsd' import { TypeEqual } from 'ts-expect' -// rpc call result in the proper type +// RPC call with no params { - const { data } = await postgrest.rpc('get_username_and_status').select().single() + const { data } = await postgrest + .rpc(RPC_NAME, { name_param: 'supabot' }) + .select(selectParams.noParams) let result: Exclude - let expected: Database['public']['Functions']['get_username_and_status']['Returns'][number] + let expected: Database['public']['Functions'][typeof RPC_NAME]['Returns'] expectType>(true) } -// select on an rpc call +// RPC call with star select { - const { data, error } = await postgrest.rpc('get_username_and_status').select('username') - if (error) throw error - expectType<{ username: string }[]>(data) + 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) } From e01b7c2a32cbe58b8ab079213a186ba598743563 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Fri, 18 Oct 2024 14:41:43 +0800 Subject: [PATCH 109/110] fix: hint matching --- src/select-query-parser/utils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/select-query-parser/utils.ts b/src/select-query-parser/utils.ts index 40dd3e20..eff2b1fc 100644 --- a/src/select-query-parser/utils.ts +++ b/src/select-query-parser/utils.ts @@ -226,7 +226,7 @@ type ResolveReverseRelationship< : 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 } + FoundRelation extends { hint: string } ? { referencedTable: TablesAndViews[RelatedRelationName] relation: FoundRelation @@ -414,7 +414,7 @@ export type FindFieldMatchingRelationships< Schema extends GenericSchema, Relationships extends GenericRelationship[], Field extends Ast.FieldNode -> = Field extends { hint?: infer Hint extends string } +> = Field extends { hint: infer Hint extends string } ? FindMatchingHintTableRelationships< Schema, Relationships, From c6c279564321febd910de52fb326b3b8f5e7d635 Mon Sep 17 00:00:00 2001 From: Bobbie Soedirgo Date: Fri, 18 Oct 2024 14:56:39 +0800 Subject: [PATCH 110/110] fix(types): aggregate on a missing column with alias --- src/select-query-parser/result.ts | 30 +++++++++++------------ test/relationships.ts | 25 +++++++++++++++++++ test/select-query-parser/select.test-d.ts | 7 ++++++ 3 files changed, 47 insertions(+), 15 deletions(-) diff --git a/src/select-query-parser/result.ts b/src/select-query-parser/result.ts index 3510a309..07802c70 100644 --- a/src/select-query-parser/result.ts +++ b/src/select-query-parser/result.ts @@ -165,21 +165,21 @@ type ProcessSimpleField< Row extends Record, RelationName extends string, Field extends Ast.FieldNode -> = 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 - } - : [Field['name']] extends [keyof Row] - ? { - // 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']] - } +> = 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}'.`> /** diff --git a/test/relationships.ts b/test/relationships.ts index 2a487d49..2660b585 100644 --- a/test/relationships.ts +++ b/test/relationships.ts @@ -177,6 +177,10 @@ export const selectParams = { from: 'collections', select: '*, parent_id(*)', }, + aggregateOnMissingColumnWithAlias: { + from: 'users', + select: 'alias:missing_column.count()', + }, } as const export const selectQueries = { @@ -349,6 +353,9 @@ export const selectQueries = { 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 () => { @@ -1806,3 +1813,21 @@ test('self reference relation via column', async () => { } `) }) + +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/select-query-parser/select.test-d.ts b/test/select-query-parser/select.test-d.ts index e23de8a6..7849ea1f 100644 --- a/test/select-query-parser/select.test-d.ts +++ b/test/select-query-parser/select.test-d.ts @@ -736,3 +736,10 @@ type Schema = Database['public'] } expectType>(true) } + +// aggregate on missing column with alias +{ + const { data, error } = await selectQueries.aggregateOnMissingColumnWithAlias.limit(1).single() + if (error) throw error + expectType>(data) +}