@supabase/postgrest-js
Version:
Isomorphic PostgREST client
222 lines • 9.28 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
// @ts-ignore
const node_fetch_1 = __importDefault(require("@supabase/node-fetch"));
const PostgrestError_1 = __importDefault(require("./PostgrestError"));
class PostgrestBuilder {
constructor(builder) {
var _a, _b;
this.shouldThrowOnError = false;
this.method = builder.method;
this.url = builder.url;
this.headers = new Headers(builder.headers);
this.schema = builder.schema;
this.body = builder.body;
this.shouldThrowOnError = (_a = builder.shouldThrowOnError) !== null && _a !== void 0 ? _a : false;
this.signal = builder.signal;
this.isMaybeSingle = (_b = builder.isMaybeSingle) !== null && _b !== void 0 ? _b : false;
if (builder.fetch) {
this.fetch = builder.fetch;
}
else if (typeof fetch === 'undefined') {
this.fetch = node_fetch_1.default;
}
else {
this.fetch = fetch;
}
}
/**
* If there's an error with the query, throwOnError will reject the promise by
* throwing the error instead of returning it as part of a successful response.
*
* {@link https://github.com/supabase/supabase-js/issues/92}
*/
throwOnError() {
this.shouldThrowOnError = true;
return this;
}
/**
* Set an HTTP header for the request.
*/
setHeader(name, value) {
this.headers = new Headers(this.headers);
this.headers.set(name, value);
return this;
}
then(onfulfilled, onrejected) {
// https://postgrest.org/en/stable/api.html#switching-schemas
if (this.schema === undefined) {
// skip
}
else if (['GET', 'HEAD'].includes(this.method)) {
this.headers.set('Accept-Profile', this.schema);
}
else {
this.headers.set('Content-Profile', this.schema);
}
if (this.method !== 'GET' && this.method !== 'HEAD') {
this.headers.set('Content-Type', 'application/json');
}
// NOTE: Invoke w/o `this` to avoid illegal invocation error.
// https://github.com/supabase/postgrest-js/pull/247
const _fetch = this.fetch;
let res = _fetch(this.url.toString(), {
method: this.method,
headers: this.headers,
body: JSON.stringify(this.body),
signal: this.signal,
}).then(async (res) => {
var _a, _b, _c, _d;
let error = null;
let data = null;
let count = null;
let status = res.status;
let statusText = res.statusText;
if (res.ok) {
if (this.method !== 'HEAD') {
const body = await res.text();
if (body === '') {
// Prefer: return=minimal
}
else if (this.headers.get('Accept') === 'text/csv') {
data = body;
}
else if (this.headers.get('Accept') &&
((_a = this.headers.get('Accept')) === null || _a === void 0 ? void 0 : _a.includes('application/vnd.pgrst.plan+text'))) {
data = body;
}
else {
data = JSON.parse(body);
}
}
const countHeader = (_b = this.headers.get('Prefer')) === null || _b === void 0 ? void 0 : _b.match(/count=(exact|planned|estimated)/);
const contentRange = (_c = res.headers.get('content-range')) === null || _c === void 0 ? void 0 : _c.split('/');
if (countHeader && contentRange && contentRange.length > 1) {
count = parseInt(contentRange[1]);
}
// Temporary partial fix for https://github.com/supabase/postgrest-js/issues/361
// Issue persists e.g. for `.insert([...]).select().maybeSingle()`
if (this.isMaybeSingle && this.method === 'GET' && Array.isArray(data)) {
if (data.length > 1) {
error = {
// https://github.com/PostgREST/postgrest/blob/a867d79c42419af16c18c3fb019eba8df992626f/src/PostgREST/Error.hs#L553
code: 'PGRST116',
details: `Results contain ${data.length} rows, application/vnd.pgrst.object+json requires 1 row`,
hint: null,
message: 'JSON object requested, multiple (or no) rows returned',
};
data = null;
count = null;
status = 406;
statusText = 'Not Acceptable';
}
else if (data.length === 1) {
data = data[0];
}
else {
data = null;
}
}
}
else {
const body = await res.text();
try {
error = JSON.parse(body);
// Workaround for https://github.com/supabase/postgrest-js/issues/295
if (Array.isArray(error) && res.status === 404) {
data = [];
error = null;
status = 200;
statusText = 'OK';
}
}
catch (_e) {
// Workaround for https://github.com/supabase/postgrest-js/issues/295
if (res.status === 404 && body === '') {
status = 204;
statusText = 'No Content';
}
else {
error = {
message: body,
};
}
}
if (error && this.isMaybeSingle && ((_d = error === null || error === void 0 ? void 0 : error.details) === null || _d === void 0 ? void 0 : _d.includes('0 rows'))) {
error = null;
status = 200;
statusText = 'OK';
}
if (error && this.shouldThrowOnError) {
throw new PostgrestError_1.default(error);
}
}
const postgrestResponse = {
error,
data,
count,
status,
statusText,
};
return postgrestResponse;
});
if (!this.shouldThrowOnError) {
res = res.catch((fetchError) => {
var _a, _b, _c;
return ({
error: {
message: `${(_a = fetchError === null || fetchError === void 0 ? void 0 : fetchError.name) !== null && _a !== void 0 ? _a : 'FetchError'}: ${fetchError === null || fetchError === void 0 ? void 0 : fetchError.message}`,
details: `${(_b = fetchError === null || fetchError === void 0 ? void 0 : fetchError.stack) !== null && _b !== void 0 ? _b : ''}`,
hint: '',
code: `${(_c = fetchError === null || fetchError === void 0 ? void 0 : fetchError.code) !== null && _c !== void 0 ? _c : ''}`,
},
data: null,
count: null,
status: 0,
statusText: '',
});
});
}
return res.then(onfulfilled, onrejected);
}
/**
* Override the type of the returned `data`.
*
* @typeParam NewResult - The new result type to override with
* @deprecated Use overrideTypes<yourType, { merge: false }>() method at the end of your call chain instead
*/
returns() {
/* istanbul ignore next */
return this;
}
/**
* Override the type of the returned `data` field in the response.
*
* @typeParam NewResult - The new type to cast the response data to
* @typeParam Options - Optional type configuration (defaults to { merge: true })
* @typeParam Options.merge - When true, merges the new type with existing return type. When false, replaces the existing types entirely (defaults to true)
* @example
* ```typescript
* // Merge with existing types (default behavior)
* const query = supabase
* .from('users')
* .select()
* .overrideTypes<{ custom_field: string }>()
*
* // Replace existing types completely
* const replaceQuery = supabase
* .from('users')
* .select()
* .overrideTypes<{ id: number; name: string }, { merge: false }>()
* ```
* @returns A PostgrestBuilder instance with the new type
*/
overrideTypes() {
return this;
}
}
exports.default = PostgrestBuilder;
//# sourceMappingURL=PostgrestBuilder.js.map