@supabase/postgrest-js 2.114.0-canary.0 → 2.115.0-canary.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +210 -71
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +44 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +44 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +210 -71
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/PostgrestBuilder.ts +27 -125
- package/src/PostgrestClient.ts +137 -0
- package/src/fetchWithRetry.ts +141 -0
- package/src/index.ts +1 -0
- package/src/types/types.ts +22 -0
- package/src/version.ts +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,34 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
2
2
|
|
|
3
|
-
//#region src/types/common/common.ts
|
|
4
|
-
/**
|
|
5
|
-
* Default number of retry attempts.
|
|
6
|
-
*/
|
|
7
|
-
const DEFAULT_MAX_RETRIES = 3;
|
|
8
|
-
/**
|
|
9
|
-
* Default exponential backoff delay function.
|
|
10
|
-
* Delays: 1s, 2s, 4s, 8s, ... (max 30s)
|
|
11
|
-
*
|
|
12
|
-
* @param attemptIndex - Zero-based index of the retry attempt
|
|
13
|
-
* @returns Delay in milliseconds before the next retry
|
|
14
|
-
*/
|
|
15
|
-
const getRetryDelay = (attemptIndex) => Math.min(1e3 * 2 ** attemptIndex, 3e4);
|
|
16
|
-
/**
|
|
17
|
-
* Status codes that are safe to retry.
|
|
18
|
-
* 520 = Cloudflare timeout/connection errors (transient)
|
|
19
|
-
* 503 = PostgREST schema cache not yet loaded (transient, signals retry via Retry-After header)
|
|
20
|
-
*/
|
|
21
|
-
const RETRYABLE_STATUS_CODES = [520, 503];
|
|
22
|
-
/**
|
|
23
|
-
* HTTP methods that are safe to retry (idempotent operations).
|
|
24
|
-
*/
|
|
25
|
-
const RETRYABLE_METHODS = [
|
|
26
|
-
"GET",
|
|
27
|
-
"HEAD",
|
|
28
|
-
"OPTIONS"
|
|
29
|
-
];
|
|
30
|
-
|
|
31
|
-
//#endregion
|
|
32
3
|
//#region src/PostgrestError.ts
|
|
33
4
|
/**
|
|
34
5
|
* Error format
|
|
@@ -86,6 +57,35 @@ var PostgrestError = class extends Error {
|
|
|
86
57
|
}
|
|
87
58
|
};
|
|
88
59
|
|
|
60
|
+
//#endregion
|
|
61
|
+
//#region src/types/common/common.ts
|
|
62
|
+
/**
|
|
63
|
+
* Default number of retry attempts.
|
|
64
|
+
*/
|
|
65
|
+
const DEFAULT_MAX_RETRIES = 3;
|
|
66
|
+
/**
|
|
67
|
+
* Default exponential backoff delay function.
|
|
68
|
+
* Delays: 1s, 2s, 4s, 8s, ... (max 30s)
|
|
69
|
+
*
|
|
70
|
+
* @param attemptIndex - Zero-based index of the retry attempt
|
|
71
|
+
* @returns Delay in milliseconds before the next retry
|
|
72
|
+
*/
|
|
73
|
+
const getRetryDelay = (attemptIndex) => Math.min(1e3 * 2 ** attemptIndex, 3e4);
|
|
74
|
+
/**
|
|
75
|
+
* Status codes that are safe to retry.
|
|
76
|
+
* 520 = Cloudflare timeout/connection errors (transient)
|
|
77
|
+
* 503 = PostgREST schema cache not yet loaded (transient, signals retry via Retry-After header)
|
|
78
|
+
*/
|
|
79
|
+
const RETRYABLE_STATUS_CODES = [520, 503];
|
|
80
|
+
/**
|
|
81
|
+
* HTTP methods that are safe to retry (idempotent operations).
|
|
82
|
+
*/
|
|
83
|
+
const RETRYABLE_METHODS = [
|
|
84
|
+
"GET",
|
|
85
|
+
"HEAD",
|
|
86
|
+
"OPTIONS"
|
|
87
|
+
];
|
|
88
|
+
|
|
89
89
|
//#endregion
|
|
90
90
|
//#region \0@oxc-project+runtime@0.103.0/helpers/typeof.js
|
|
91
91
|
function _typeof(o) {
|
|
@@ -153,7 +153,7 @@ function _objectSpread2(e) {
|
|
|
153
153
|
}
|
|
154
154
|
|
|
155
155
|
//#endregion
|
|
156
|
-
//#region src/
|
|
156
|
+
//#region src/fetchWithRetry.ts
|
|
157
157
|
/**
|
|
158
158
|
* Sleep for a given number of milliseconds.
|
|
159
159
|
* If an AbortSignal is provided, the sleep resolves early when the signal is aborted.
|
|
@@ -184,6 +184,56 @@ function shouldRetry(method, status, attemptCount, retryEnabled) {
|
|
|
184
184
|
if (!RETRYABLE_STATUS_CODES.includes(status)) return false;
|
|
185
185
|
return true;
|
|
186
186
|
}
|
|
187
|
+
/**
|
|
188
|
+
* Perform a request with the retry policy shared by every PostgREST call.
|
|
189
|
+
*
|
|
190
|
+
* Idempotent methods (GET, HEAD, OPTIONS) are retried up to
|
|
191
|
+
* `DEFAULT_MAX_RETRIES` times when the fetch rejects or the server answers
|
|
192
|
+
* with a retryable status (503, 520). The wait honours the `Retry-After`
|
|
193
|
+
* header when present and backs off exponentially otherwise. Retried
|
|
194
|
+
* attempts carry an `X-Retry-Count` header. Aborted requests and
|
|
195
|
+
* non-idempotent methods are never retried: their rejection propagates
|
|
196
|
+
* unchanged. A response body is drained before its request is retried.
|
|
197
|
+
*/
|
|
198
|
+
async function fetchWithRetry(fetchImpl, url, request, retryEnabled) {
|
|
199
|
+
let attemptCount = 0;
|
|
200
|
+
while (true) {
|
|
201
|
+
const headers = _objectSpread2({}, request.headers);
|
|
202
|
+
if (attemptCount > 0) headers["X-Retry-Count"] = String(attemptCount);
|
|
203
|
+
let res;
|
|
204
|
+
try {
|
|
205
|
+
res = await fetchImpl(url, {
|
|
206
|
+
method: request.method,
|
|
207
|
+
headers,
|
|
208
|
+
body: request.body,
|
|
209
|
+
signal: request.signal
|
|
210
|
+
});
|
|
211
|
+
} catch (fetchError) {
|
|
212
|
+
if ((fetchError === null || fetchError === void 0 ? void 0 : fetchError.name) === "AbortError" || (fetchError === null || fetchError === void 0 ? void 0 : fetchError.code) === "ABORT_ERR") throw fetchError;
|
|
213
|
+
if (!RETRYABLE_METHODS.includes(request.method)) throw fetchError;
|
|
214
|
+
if (retryEnabled && attemptCount < DEFAULT_MAX_RETRIES) {
|
|
215
|
+
const delay = getRetryDelay(attemptCount);
|
|
216
|
+
attemptCount++;
|
|
217
|
+
await sleep(delay, request.signal);
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
throw fetchError;
|
|
221
|
+
}
|
|
222
|
+
if (shouldRetry(request.method, res.status, attemptCount, retryEnabled)) {
|
|
223
|
+
var _res$headers$get, _res$headers;
|
|
224
|
+
const retryAfterHeader = (_res$headers$get = (_res$headers = res.headers) === null || _res$headers === void 0 ? void 0 : _res$headers.get("Retry-After")) !== null && _res$headers$get !== void 0 ? _res$headers$get : null;
|
|
225
|
+
const delay = retryAfterHeader !== null ? Math.max(0, parseInt(retryAfterHeader, 10) || 0) * 1e3 : getRetryDelay(attemptCount);
|
|
226
|
+
await res.text();
|
|
227
|
+
attemptCount++;
|
|
228
|
+
await sleep(delay, request.signal);
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
231
|
+
return res;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
//#endregion
|
|
236
|
+
//#region src/PostgrestBuilder.ts
|
|
187
237
|
var PostgrestBuilder = class {
|
|
188
238
|
/**
|
|
189
239
|
* Creates a builder configured for a specific PostgREST request.
|
|
@@ -352,43 +402,17 @@ var PostgrestBuilder = class {
|
|
|
352
402
|
}
|
|
353
403
|
const _fetch = this.fetch;
|
|
354
404
|
const executeWithRetry = async () => {
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
headers,
|
|
367
|
-
body: JSON.stringify(_this.body, (_, value) => typeof value === "bigint" ? value.toString() : value),
|
|
368
|
-
signal: _this.signal
|
|
369
|
-
});
|
|
370
|
-
} catch (fetchError) {
|
|
371
|
-
if ((fetchError === null || fetchError === void 0 ? void 0 : fetchError.name) === "AbortError" || (fetchError === null || fetchError === void 0 ? void 0 : fetchError.code) === "ABORT_ERR") throw fetchError;
|
|
372
|
-
if (!RETRYABLE_METHODS.includes(_this.method)) throw fetchError;
|
|
373
|
-
if (_this.retryEnabled && attemptCount < DEFAULT_MAX_RETRIES) {
|
|
374
|
-
const delay = getRetryDelay(attemptCount);
|
|
375
|
-
attemptCount++;
|
|
376
|
-
await sleep(delay, _this.signal);
|
|
377
|
-
continue;
|
|
378
|
-
}
|
|
379
|
-
throw fetchError;
|
|
380
|
-
}
|
|
381
|
-
if (shouldRetry(_this.method, res$1.status, attemptCount, _this.retryEnabled)) {
|
|
382
|
-
var _res$headers$get, _res$headers;
|
|
383
|
-
const retryAfterHeader = (_res$headers$get = (_res$headers = res$1.headers) === null || _res$headers === void 0 ? void 0 : _res$headers.get("Retry-After")) !== null && _res$headers$get !== void 0 ? _res$headers$get : null;
|
|
384
|
-
const delay = retryAfterHeader !== null ? Math.max(0, parseInt(retryAfterHeader, 10) || 0) * 1e3 : getRetryDelay(attemptCount);
|
|
385
|
-
await res$1.text();
|
|
386
|
-
attemptCount++;
|
|
387
|
-
await sleep(delay, _this.signal);
|
|
388
|
-
continue;
|
|
389
|
-
}
|
|
390
|
-
return await _this.processResponse(res$1);
|
|
391
|
-
}
|
|
405
|
+
const headers = {};
|
|
406
|
+
_this.headers.forEach((value, key) => {
|
|
407
|
+
headers[key] = value;
|
|
408
|
+
});
|
|
409
|
+
const res$1 = await fetchWithRetry(_fetch, _this.url.toString(), {
|
|
410
|
+
method: _this.method,
|
|
411
|
+
headers,
|
|
412
|
+
body: JSON.stringify(_this.body, (_, value) => typeof value === "bigint" ? value.toString() : value),
|
|
413
|
+
signal: _this.signal
|
|
414
|
+
}, _this.retryEnabled);
|
|
415
|
+
return await _this.processResponse(res$1);
|
|
392
416
|
};
|
|
393
417
|
let res = executeWithRetry();
|
|
394
418
|
if (!this.shouldThrowOnError) res = res.catch((fetchError) => {
|
|
@@ -446,7 +470,7 @@ var PostgrestBuilder = class {
|
|
|
446
470
|
let status = res.status;
|
|
447
471
|
let statusText = res.statusText;
|
|
448
472
|
if (res.ok) {
|
|
449
|
-
var _this$headers$get2, _res$headers$
|
|
473
|
+
var _this$headers$get2, _res$headers$get;
|
|
450
474
|
if (_this2.method !== "HEAD") {
|
|
451
475
|
var _this$headers$get;
|
|
452
476
|
const body = await res.text();
|
|
@@ -466,7 +490,7 @@ var PostgrestBuilder = class {
|
|
|
466
490
|
}
|
|
467
491
|
}
|
|
468
492
|
const countHeader = (_this$headers$get2 = _this2.headers.get("Prefer")) === null || _this$headers$get2 === void 0 ? void 0 : _this$headers$get2.match(/count=(exact|planned|estimated)/);
|
|
469
|
-
const contentRange = (_res$headers$
|
|
493
|
+
const contentRange = (_res$headers$get = res.headers.get("content-range")) === null || _res$headers$get === void 0 ? void 0 : _res$headers$get.split("/");
|
|
470
494
|
if (countHeader && contentRange && contentRange.length > 1) count = parseInt(contentRange[1]);
|
|
471
495
|
if (_this2.isMaybeSingle && Array.isArray(data)) if (data.length > 1) {
|
|
472
496
|
error = {
|
|
@@ -3563,6 +3587,54 @@ var PostgrestQueryBuilder = class {
|
|
|
3563
3587
|
//#endregion
|
|
3564
3588
|
//#region src/PostgrestClient.ts
|
|
3565
3589
|
/**
|
|
3590
|
+
* Build the error for a failed OpenAPI request. PostgREST answers with a JSON
|
|
3591
|
+
* error object when it produced the failure itself; proxies and disabled
|
|
3592
|
+
* OpenAPI output answer with plain text or an empty body, in which case the
|
|
3593
|
+
* body (or, failing that, the status text) becomes the message.
|
|
3594
|
+
*/
|
|
3595
|
+
function toOpenApiError(body, statusText) {
|
|
3596
|
+
try {
|
|
3597
|
+
const parsed = JSON.parse(body);
|
|
3598
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
3599
|
+
var _parsed$message, _parsed$details, _parsed$hint, _parsed$code;
|
|
3600
|
+
return new PostgrestError({
|
|
3601
|
+
message: String((_parsed$message = parsed.message) !== null && _parsed$message !== void 0 ? _parsed$message : body),
|
|
3602
|
+
details: (_parsed$details = parsed.details) !== null && _parsed$details !== void 0 ? _parsed$details : "",
|
|
3603
|
+
hint: (_parsed$hint = parsed.hint) !== null && _parsed$hint !== void 0 ? _parsed$hint : "",
|
|
3604
|
+
code: (_parsed$code = parsed.code) !== null && _parsed$code !== void 0 ? _parsed$code : ""
|
|
3605
|
+
});
|
|
3606
|
+
}
|
|
3607
|
+
} catch (_unused) {}
|
|
3608
|
+
return new PostgrestError({
|
|
3609
|
+
message: body || statusText,
|
|
3610
|
+
details: "",
|
|
3611
|
+
hint: "",
|
|
3612
|
+
code: ""
|
|
3613
|
+
});
|
|
3614
|
+
}
|
|
3615
|
+
/**
|
|
3616
|
+
* Build the response for a request that yielded no readable body: the fetch
|
|
3617
|
+
* itself rejected (no status is known, so it is 0), or the body stream failed
|
|
3618
|
+
* while being read (the response status is preserved).
|
|
3619
|
+
*/
|
|
3620
|
+
function toTransportFailure(cause, status, statusText) {
|
|
3621
|
+
var _err$name;
|
|
3622
|
+
const err = cause;
|
|
3623
|
+
return {
|
|
3624
|
+
success: false,
|
|
3625
|
+
error: new PostgrestError({
|
|
3626
|
+
message: `${(_err$name = err === null || err === void 0 ? void 0 : err.name) !== null && _err$name !== void 0 ? _err$name : "FetchError"}: ${err === null || err === void 0 ? void 0 : err.message}`,
|
|
3627
|
+
details: "",
|
|
3628
|
+
hint: "",
|
|
3629
|
+
code: ""
|
|
3630
|
+
}),
|
|
3631
|
+
data: null,
|
|
3632
|
+
count: null,
|
|
3633
|
+
status,
|
|
3634
|
+
statusText
|
|
3635
|
+
};
|
|
3636
|
+
}
|
|
3637
|
+
/**
|
|
3566
3638
|
* PostgREST client.
|
|
3567
3639
|
*
|
|
3568
3640
|
* @typeParam Database - Types for the schema from the [type
|
|
@@ -3671,6 +3743,73 @@ var PostgrestClient = class PostgrestClient {
|
|
|
3671
3743
|
});
|
|
3672
3744
|
}
|
|
3673
3745
|
/**
|
|
3746
|
+
* Fetch the OpenAPI description PostgREST publishes for this client's schema.
|
|
3747
|
+
*
|
|
3748
|
+
* The document lists only the tables, views and functions the caller's role
|
|
3749
|
+
* holds privileges on; PostgREST applies that filtering server-side. The
|
|
3750
|
+
* schema is the one this client was created with, so call `.schema()` first
|
|
3751
|
+
* to describe a different one. Transient failures are retried according to
|
|
3752
|
+
* the client's `retry` option, like any other idempotent request.
|
|
3753
|
+
*
|
|
3754
|
+
* @example
|
|
3755
|
+
* ```ts
|
|
3756
|
+
* const { data, error } = await supabase.getOpenApiSpec()
|
|
3757
|
+
* ```
|
|
3758
|
+
*
|
|
3759
|
+
* @example Describe a schema other than the client default
|
|
3760
|
+
* ```ts
|
|
3761
|
+
* const { data, error } = await supabase.schema('billing').getOpenApiSpec()
|
|
3762
|
+
* ```
|
|
3763
|
+
*
|
|
3764
|
+
* @category Database
|
|
3765
|
+
*/
|
|
3766
|
+
async getOpenApiSpec() {
|
|
3767
|
+
var _this = this;
|
|
3768
|
+
var _this$fetch;
|
|
3769
|
+
const headers = new Headers(_this.headers);
|
|
3770
|
+
headers.set("Accept", "application/openapi+json");
|
|
3771
|
+
if (_this.schemaName) headers.set("Accept-Profile", _this.schemaName);
|
|
3772
|
+
const requestHeaders = {};
|
|
3773
|
+
headers.forEach((value, key) => {
|
|
3774
|
+
requestHeaders[key] = value;
|
|
3775
|
+
});
|
|
3776
|
+
const fetchImpl = (_this$fetch = _this.fetch) !== null && _this$fetch !== void 0 ? _this$fetch : globalThis.fetch;
|
|
3777
|
+
let res;
|
|
3778
|
+
try {
|
|
3779
|
+
var _this$retry;
|
|
3780
|
+
res = await fetchWithRetry(fetchImpl, `${_this.url}/`, {
|
|
3781
|
+
method: "GET",
|
|
3782
|
+
headers: requestHeaders
|
|
3783
|
+
}, (_this$retry = _this.retry) !== null && _this$retry !== void 0 ? _this$retry : true);
|
|
3784
|
+
} catch (fetchError) {
|
|
3785
|
+
return toTransportFailure(fetchError, 0, "");
|
|
3786
|
+
}
|
|
3787
|
+
let body;
|
|
3788
|
+
try {
|
|
3789
|
+
body = await res.text();
|
|
3790
|
+
} catch (readError) {
|
|
3791
|
+
return toTransportFailure(readError, res.status, res.statusText);
|
|
3792
|
+
}
|
|
3793
|
+
if (res.ok) try {
|
|
3794
|
+
return {
|
|
3795
|
+
success: true,
|
|
3796
|
+
error: null,
|
|
3797
|
+
data: JSON.parse(body),
|
|
3798
|
+
count: null,
|
|
3799
|
+
status: res.status,
|
|
3800
|
+
statusText: res.statusText
|
|
3801
|
+
};
|
|
3802
|
+
} catch (_unused2) {}
|
|
3803
|
+
return {
|
|
3804
|
+
success: false,
|
|
3805
|
+
error: toOpenApiError(body, res.statusText),
|
|
3806
|
+
data: null,
|
|
3807
|
+
count: null,
|
|
3808
|
+
status: res.status,
|
|
3809
|
+
statusText: res.statusText
|
|
3810
|
+
};
|
|
3811
|
+
}
|
|
3812
|
+
/**
|
|
3674
3813
|
* Perform a function call.
|
|
3675
3814
|
*
|
|
3676
3815
|
* @param fn - The function name to call
|
|
@@ -3836,7 +3975,7 @@ var PostgrestClient = class PostgrestClient {
|
|
|
3836
3975
|
* ```
|
|
3837
3976
|
*/
|
|
3838
3977
|
rpc(fn, args = {}, { head = false, get = false, count } = {}) {
|
|
3839
|
-
var _this$
|
|
3978
|
+
var _this$fetch2;
|
|
3840
3979
|
let method;
|
|
3841
3980
|
const url = new URL(`${this.url}/rpc/${fn}`);
|
|
3842
3981
|
let body;
|
|
@@ -3863,7 +4002,7 @@ var PostgrestClient = class PostgrestClient {
|
|
|
3863
4002
|
headers,
|
|
3864
4003
|
schema: this.schemaName,
|
|
3865
4004
|
body,
|
|
3866
|
-
fetch: (_this$
|
|
4005
|
+
fetch: (_this$fetch2 = this.fetch) !== null && _this$fetch2 !== void 0 ? _this$fetch2 : fetch,
|
|
3867
4006
|
urlLengthLimit: this.urlLengthLimit,
|
|
3868
4007
|
retry: this.retry
|
|
3869
4008
|
});
|