@supacloud/lite 0.29.1 → 0.29.3
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/CHANGELOG.md +14 -0
- package/dist/cli.js +85 -22
- package/dist/index.js +85 -22
- package/dist/runtime/db/database.d.ts +4 -0
- package/dist/runtime/db/database.d.ts.map +1 -1
- package/dist/runtime/rest/errors.d.ts +5 -5
- package/dist/runtime/rest/errors.d.ts.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.29.3](https://github.com/vibeunion/supacloud/compare/supacloud-lite-v0.29.2...supacloud-lite-v0.29.3) (2026-10-16)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* **lite:** preserve single-column table RPC responses ([#1971](https://github.com/vibeunion/supacloud/issues/1971)) ([63edb93](https://github.com/vibeunion/supacloud/commit/63edb937322130796260a1284c09cc895735214e))
|
|
9
|
+
|
|
10
|
+
## [0.29.2](https://github.com/vibeunion/supacloud/compare/supacloud-lite-v0.29.1...supacloud-lite-v0.29.2) (2026-10-15)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* **lite:** resolve RPC overloads using required arguments ([#1967](https://github.com/vibeunion/supacloud/issues/1967)) ([e00ffaf](https://github.com/vibeunion/supacloud/commit/e00ffafd41aa52c8f14c2e81f3bb8a8914b336c8))
|
|
16
|
+
|
|
3
17
|
## [0.29.1](https://github.com/vibeunion/supacloud/compare/supacloud-lite-v0.29.0...supacloud-lite-v0.29.1) (2026-10-15)
|
|
4
18
|
|
|
5
19
|
|
package/dist/cli.js
CHANGED
|
@@ -8,7 +8,7 @@ import { dirname as dirname8, join as join10, resolve as resolve6 } from "path";
|
|
|
8
8
|
// package.json
|
|
9
9
|
var package_default = {
|
|
10
10
|
name: "@supacloud/lite",
|
|
11
|
-
version: "0.29.
|
|
11
|
+
version: "0.29.3",
|
|
12
12
|
description: "Bun-native, single-project Supabase-compatible backend powered by PGlite or native PostgreSQL",
|
|
13
13
|
type: "module",
|
|
14
14
|
license: "Apache-2.0",
|
|
@@ -6820,9 +6820,20 @@ class Database {
|
|
|
6820
6820
|
if (cached)
|
|
6821
6821
|
return cached;
|
|
6822
6822
|
const res = await this.engine.query(`select p.proname as name, p.proretset as returns_set,
|
|
6823
|
+
coalesce('t' = any(p.proargmodes), false) as returns_table,
|
|
6823
6824
|
t.typname as return_type, t.typtype as return_typtype,
|
|
6824
6825
|
p.provolatile as volatility,
|
|
6825
|
-
|
|
6826
|
+
p.pronargs - p.pronargdefaults as required_arg_count,
|
|
6827
|
+
coalesce((
|
|
6828
|
+
select json_agg(json_build_object(
|
|
6829
|
+
'name', coalesce(a.name, ''),
|
|
6830
|
+
'type', format_type(a.type, null)
|
|
6831
|
+
) order by a.ordinal)
|
|
6832
|
+
from unnest(coalesce(p.proallargtypes, p.proargtypes::oid[]),
|
|
6833
|
+
p.proargnames, p.proargmodes)
|
|
6834
|
+
with ordinality as a(type, name, mode, ordinal)
|
|
6835
|
+
where a.mode is null or a.mode in ('i', 'b', 'v')
|
|
6836
|
+
), '[]'::json) as input_args
|
|
6826
6837
|
from pg_proc p
|
|
6827
6838
|
join pg_namespace n on n.oid = p.pronamespace
|
|
6828
6839
|
join pg_type t on t.oid = p.prorettype
|
|
@@ -6831,10 +6842,12 @@ class Database {
|
|
|
6831
6842
|
schema,
|
|
6832
6843
|
name: r.name,
|
|
6833
6844
|
returnsSet: r.returns_set,
|
|
6845
|
+
returnsTable: r.returns_table,
|
|
6834
6846
|
returnType: r.return_type,
|
|
6835
6847
|
returnTypType: r.return_typtype,
|
|
6836
6848
|
volatility: r.volatility,
|
|
6837
|
-
|
|
6849
|
+
requiredArgCount: r.required_arg_count,
|
|
6850
|
+
args: r.input_args
|
|
6838
6851
|
}));
|
|
6839
6852
|
this.fnCache.set(key, fns);
|
|
6840
6853
|
return fns;
|
|
@@ -8366,6 +8379,9 @@ function renderFilter(f, alias) {
|
|
|
8366
8379
|
|
|
8367
8380
|
// src/runtime/rest/errors.ts
|
|
8368
8381
|
function statusForSqlState(code, authenticated = true) {
|
|
8382
|
+
if (code.startsWith("PT")) {
|
|
8383
|
+
return /^PT[2-5][0-9]{2}$/.test(code) ? Number(code.slice(2)) : 500;
|
|
8384
|
+
}
|
|
8369
8385
|
switch (code) {
|
|
8370
8386
|
case "42501":
|
|
8371
8387
|
return authenticated ? 403 : 401;
|
|
@@ -8382,10 +8398,52 @@ function statusForSqlState(code, authenticated = true) {
|
|
|
8382
8398
|
return 409;
|
|
8383
8399
|
case "57014":
|
|
8384
8400
|
return 408;
|
|
8401
|
+
case "57P01":
|
|
8402
|
+
return 503;
|
|
8403
|
+
case "53400":
|
|
8404
|
+
return 500;
|
|
8385
8405
|
default:
|
|
8406
|
+
if (code.startsWith("08") || code.startsWith("53"))
|
|
8407
|
+
return 503;
|
|
8386
8408
|
return 400;
|
|
8387
8409
|
}
|
|
8388
8410
|
}
|
|
8411
|
+
function invalidPgrstResponse(part) {
|
|
8412
|
+
return jsonResponse(500, {
|
|
8413
|
+
code: "PGRST121",
|
|
8414
|
+
message: `Could not parse JSON in the "RAISE SQLSTATE 'PGRST'" error`,
|
|
8415
|
+
details: `Invalid JSON value or fields for ${part}`,
|
|
8416
|
+
hint: part === "MESSAGE" ? "MESSAGE must contain string 'code' and 'message'; optional 'details' and 'hint' must be strings or null." : "DETAIL must contain integer 'status' (200-599), string-valued 'headers', and optional string 'status_text'."
|
|
8417
|
+
});
|
|
8418
|
+
}
|
|
8419
|
+
function pgrstErrorToResponse(pg) {
|
|
8420
|
+
let part = "MESSAGE";
|
|
8421
|
+
try {
|
|
8422
|
+
const body = JSON.parse(pg.message);
|
|
8423
|
+
if (!isRecord(body) || typeof body.code !== "string" || typeof body.message !== "string" || body.details != null && typeof body.details !== "string" || body.hint != null && typeof body.hint !== "string") {
|
|
8424
|
+
return invalidPgrstResponse(part);
|
|
8425
|
+
}
|
|
8426
|
+
part = "DETAIL";
|
|
8427
|
+
const detail = JSON.parse(pg.detail ?? "");
|
|
8428
|
+
if (!isRecord(detail) || typeof detail.status !== "number" || !Number.isInteger(detail.status) || detail.status < 200 || detail.status > 599 || !isRecord(detail.headers) || detail.status_text != null && (typeof detail.status_text !== "string" || !/^[\t\x20-\x7e\x80-\xff]*$/.test(detail.status_text))) {
|
|
8429
|
+
return invalidPgrstResponse(part);
|
|
8430
|
+
}
|
|
8431
|
+
const headers = new Headers;
|
|
8432
|
+
for (const [name, value] of Object.entries(detail.headers)) {
|
|
8433
|
+
if (typeof value !== "string")
|
|
8434
|
+
return invalidPgrstResponse(part);
|
|
8435
|
+
headers.set(name, value);
|
|
8436
|
+
}
|
|
8437
|
+
return jsonResponse(detail.status, {
|
|
8438
|
+
code: body.code,
|
|
8439
|
+
message: body.message,
|
|
8440
|
+
details: body.details ?? null,
|
|
8441
|
+
hint: body.hint ?? null
|
|
8442
|
+
}, Object.fromEntries(headers), typeof detail.status_text === "string" ? detail.status_text : undefined);
|
|
8443
|
+
} catch {
|
|
8444
|
+
return invalidPgrstResponse(part);
|
|
8445
|
+
}
|
|
8446
|
+
}
|
|
8389
8447
|
function errorToResponse(e, authenticated = true) {
|
|
8390
8448
|
if (e instanceof ApiError) {
|
|
8391
8449
|
return jsonResponse(e.status, e.body);
|
|
@@ -8395,6 +8453,8 @@ function errorToResponse(e, authenticated = true) {
|
|
|
8395
8453
|
}
|
|
8396
8454
|
const pg = e;
|
|
8397
8455
|
if (pg && typeof pg.code === "string" && /^[0-9A-Z]{5}$/.test(pg.code)) {
|
|
8456
|
+
if (pg.code === "PGRST")
|
|
8457
|
+
return pgrstErrorToResponse(pg);
|
|
8398
8458
|
return jsonResponse(statusForSqlState(pg.code, authenticated), {
|
|
8399
8459
|
code: pg.code,
|
|
8400
8460
|
message: pg.message,
|
|
@@ -8405,9 +8465,11 @@ function errorToResponse(e, authenticated = true) {
|
|
|
8405
8465
|
const message = e instanceof Error ? e.message : String(e);
|
|
8406
8466
|
return jsonResponse(500, { code: "PGRST500", message, details: null, hint: null });
|
|
8407
8467
|
}
|
|
8408
|
-
function jsonResponse(status, body, headers = {}) {
|
|
8409
|
-
|
|
8468
|
+
function jsonResponse(status, body, headers = {}, statusText) {
|
|
8469
|
+
const bodyless = status === 204 || status === 205 || status === 304;
|
|
8470
|
+
return new Response(bodyless ? null : JSON.stringify(body), {
|
|
8410
8471
|
status,
|
|
8472
|
+
...statusText === undefined ? {} : { statusText },
|
|
8411
8473
|
headers: { "content-type": "application/json; charset=utf-8", ...headers }
|
|
8412
8474
|
});
|
|
8413
8475
|
}
|
|
@@ -8717,7 +8779,7 @@ class RestHandler {
|
|
|
8717
8779
|
}
|
|
8718
8780
|
}
|
|
8719
8781
|
}
|
|
8720
|
-
const fn = pickOverload(fns, Object.keys(args));
|
|
8782
|
+
const fn = pickOverload(schema, fnName, fns, Object.keys(args));
|
|
8721
8783
|
const call = renderCall(schema, fn, args);
|
|
8722
8784
|
const q = parseQuery(searchParams);
|
|
8723
8785
|
if (method === "GET" || method === "HEAD")
|
|
@@ -8742,7 +8804,7 @@ class RestHandler {
|
|
|
8742
8804
|
const value = res.rows[0].result;
|
|
8743
8805
|
return jsonResponse(200, value);
|
|
8744
8806
|
}
|
|
8745
|
-
if (fn.returnsSet && ["b", "d", "e"].includes(fn.returnTypType)) {
|
|
8807
|
+
if (fn.returnsSet && !fn.returnsTable && ["b", "d", "e"].includes(fn.returnTypType)) {
|
|
8746
8808
|
const res = await withRpcContext((query) => query(`select coalesce(json_agg(_v), '[]'::json) as body from ${call} as _t(_v)`, []));
|
|
8747
8809
|
return jsonResponse(200, res.rows[0].body);
|
|
8748
8810
|
}
|
|
@@ -8803,22 +8865,14 @@ function assertObjectCardinality(rows) {
|
|
|
8803
8865
|
});
|
|
8804
8866
|
}
|
|
8805
8867
|
}
|
|
8806
|
-
function pickOverload(fns, providedNames) {
|
|
8868
|
+
function pickOverload(schema, name, fns, providedNames) {
|
|
8807
8869
|
const provided = new Set(providedNames);
|
|
8808
|
-
const
|
|
8809
|
-
let best = null;
|
|
8810
|
-
for (const fn of fns) {
|
|
8870
|
+
const matches = fns.filter((fn) => {
|
|
8811
8871
|
const names = new Set(fn.args.map((a) => a.name));
|
|
8812
|
-
|
|
8813
|
-
|
|
8814
|
-
|
|
8815
|
-
|
|
8816
|
-
exact.push(fn);
|
|
8817
|
-
if (!best)
|
|
8818
|
-
best = fn;
|
|
8819
|
-
}
|
|
8820
|
-
if (exact.length > 1) {
|
|
8821
|
-
const candidates = exact.map((fn) => `${fn.schema}.${fn.name}(${fn.args.map((arg) => `${arg.name} => ${arg.type}`).join(", ")})`);
|
|
8872
|
+
return [...provided].every((p) => names.has(p)) && fn.args.slice(0, fn.requiredArgCount).every((arg) => provided.has(arg.name));
|
|
8873
|
+
});
|
|
8874
|
+
if (matches.length > 1) {
|
|
8875
|
+
const candidates = matches.map((fn) => `${fn.schema}.${fn.name}(${fn.args.map((arg) => `${arg.name} => ${arg.type}`).join(", ")})`);
|
|
8822
8876
|
throw new ApiError(300, {
|
|
8823
8877
|
code: "PGRST203",
|
|
8824
8878
|
message: `Could not choose the best candidate function between: ${candidates.join(", ")}`,
|
|
@@ -8826,7 +8880,16 @@ function pickOverload(fns, providedNames) {
|
|
|
8826
8880
|
hint: "Try renaming the parameters or the function itself in the database so function overloading can be resolved"
|
|
8827
8881
|
});
|
|
8828
8882
|
}
|
|
8829
|
-
|
|
8883
|
+
const match = matches[0];
|
|
8884
|
+
if (!match) {
|
|
8885
|
+
throw new ApiError(404, {
|
|
8886
|
+
code: "PGRST202",
|
|
8887
|
+
message: `Could not find the function ${schema}.${name}(${[...provided].sort().join(", ")}) in the schema cache`,
|
|
8888
|
+
details: null,
|
|
8889
|
+
hint: null
|
|
8890
|
+
});
|
|
8891
|
+
}
|
|
8892
|
+
return match;
|
|
8830
8893
|
}
|
|
8831
8894
|
function renderCall(schema, fn, args) {
|
|
8832
8895
|
const parts = [];
|
package/dist/index.js
CHANGED
|
@@ -88,7 +88,7 @@ function randomToken(bytes = 32) {
|
|
|
88
88
|
// package.json
|
|
89
89
|
var package_default = {
|
|
90
90
|
name: "@supacloud/lite",
|
|
91
|
-
version: "0.29.
|
|
91
|
+
version: "0.29.3",
|
|
92
92
|
description: "Bun-native, single-project Supabase-compatible backend powered by PGlite or native PostgreSQL",
|
|
93
93
|
type: "module",
|
|
94
94
|
license: "Apache-2.0",
|
|
@@ -6814,9 +6814,20 @@ class Database {
|
|
|
6814
6814
|
if (cached)
|
|
6815
6815
|
return cached;
|
|
6816
6816
|
const res = await this.engine.query(`select p.proname as name, p.proretset as returns_set,
|
|
6817
|
+
coalesce('t' = any(p.proargmodes), false) as returns_table,
|
|
6817
6818
|
t.typname as return_type, t.typtype as return_typtype,
|
|
6818
6819
|
p.provolatile as volatility,
|
|
6819
|
-
|
|
6820
|
+
p.pronargs - p.pronargdefaults as required_arg_count,
|
|
6821
|
+
coalesce((
|
|
6822
|
+
select json_agg(json_build_object(
|
|
6823
|
+
'name', coalesce(a.name, ''),
|
|
6824
|
+
'type', format_type(a.type, null)
|
|
6825
|
+
) order by a.ordinal)
|
|
6826
|
+
from unnest(coalesce(p.proallargtypes, p.proargtypes::oid[]),
|
|
6827
|
+
p.proargnames, p.proargmodes)
|
|
6828
|
+
with ordinality as a(type, name, mode, ordinal)
|
|
6829
|
+
where a.mode is null or a.mode in ('i', 'b', 'v')
|
|
6830
|
+
), '[]'::json) as input_args
|
|
6820
6831
|
from pg_proc p
|
|
6821
6832
|
join pg_namespace n on n.oid = p.pronamespace
|
|
6822
6833
|
join pg_type t on t.oid = p.prorettype
|
|
@@ -6825,10 +6836,12 @@ class Database {
|
|
|
6825
6836
|
schema,
|
|
6826
6837
|
name: r.name,
|
|
6827
6838
|
returnsSet: r.returns_set,
|
|
6839
|
+
returnsTable: r.returns_table,
|
|
6828
6840
|
returnType: r.return_type,
|
|
6829
6841
|
returnTypType: r.return_typtype,
|
|
6830
6842
|
volatility: r.volatility,
|
|
6831
|
-
|
|
6843
|
+
requiredArgCount: r.required_arg_count,
|
|
6844
|
+
args: r.input_args
|
|
6832
6845
|
}));
|
|
6833
6846
|
this.fnCache.set(key, fns);
|
|
6834
6847
|
return fns;
|
|
@@ -8360,6 +8373,9 @@ function renderFilter(f, alias) {
|
|
|
8360
8373
|
|
|
8361
8374
|
// src/runtime/rest/errors.ts
|
|
8362
8375
|
function statusForSqlState(code, authenticated = true) {
|
|
8376
|
+
if (code.startsWith("PT")) {
|
|
8377
|
+
return /^PT[2-5][0-9]{2}$/.test(code) ? Number(code.slice(2)) : 500;
|
|
8378
|
+
}
|
|
8363
8379
|
switch (code) {
|
|
8364
8380
|
case "42501":
|
|
8365
8381
|
return authenticated ? 403 : 401;
|
|
@@ -8376,10 +8392,52 @@ function statusForSqlState(code, authenticated = true) {
|
|
|
8376
8392
|
return 409;
|
|
8377
8393
|
case "57014":
|
|
8378
8394
|
return 408;
|
|
8395
|
+
case "57P01":
|
|
8396
|
+
return 503;
|
|
8397
|
+
case "53400":
|
|
8398
|
+
return 500;
|
|
8379
8399
|
default:
|
|
8400
|
+
if (code.startsWith("08") || code.startsWith("53"))
|
|
8401
|
+
return 503;
|
|
8380
8402
|
return 400;
|
|
8381
8403
|
}
|
|
8382
8404
|
}
|
|
8405
|
+
function invalidPgrstResponse(part) {
|
|
8406
|
+
return jsonResponse(500, {
|
|
8407
|
+
code: "PGRST121",
|
|
8408
|
+
message: `Could not parse JSON in the "RAISE SQLSTATE 'PGRST'" error`,
|
|
8409
|
+
details: `Invalid JSON value or fields for ${part}`,
|
|
8410
|
+
hint: part === "MESSAGE" ? "MESSAGE must contain string 'code' and 'message'; optional 'details' and 'hint' must be strings or null." : "DETAIL must contain integer 'status' (200-599), string-valued 'headers', and optional string 'status_text'."
|
|
8411
|
+
});
|
|
8412
|
+
}
|
|
8413
|
+
function pgrstErrorToResponse(pg) {
|
|
8414
|
+
let part = "MESSAGE";
|
|
8415
|
+
try {
|
|
8416
|
+
const body = JSON.parse(pg.message);
|
|
8417
|
+
if (!isRecord(body) || typeof body.code !== "string" || typeof body.message !== "string" || body.details != null && typeof body.details !== "string" || body.hint != null && typeof body.hint !== "string") {
|
|
8418
|
+
return invalidPgrstResponse(part);
|
|
8419
|
+
}
|
|
8420
|
+
part = "DETAIL";
|
|
8421
|
+
const detail = JSON.parse(pg.detail ?? "");
|
|
8422
|
+
if (!isRecord(detail) || typeof detail.status !== "number" || !Number.isInteger(detail.status) || detail.status < 200 || detail.status > 599 || !isRecord(detail.headers) || detail.status_text != null && (typeof detail.status_text !== "string" || !/^[\t\x20-\x7e\x80-\xff]*$/.test(detail.status_text))) {
|
|
8423
|
+
return invalidPgrstResponse(part);
|
|
8424
|
+
}
|
|
8425
|
+
const headers = new Headers;
|
|
8426
|
+
for (const [name, value] of Object.entries(detail.headers)) {
|
|
8427
|
+
if (typeof value !== "string")
|
|
8428
|
+
return invalidPgrstResponse(part);
|
|
8429
|
+
headers.set(name, value);
|
|
8430
|
+
}
|
|
8431
|
+
return jsonResponse(detail.status, {
|
|
8432
|
+
code: body.code,
|
|
8433
|
+
message: body.message,
|
|
8434
|
+
details: body.details ?? null,
|
|
8435
|
+
hint: body.hint ?? null
|
|
8436
|
+
}, Object.fromEntries(headers), typeof detail.status_text === "string" ? detail.status_text : undefined);
|
|
8437
|
+
} catch {
|
|
8438
|
+
return invalidPgrstResponse(part);
|
|
8439
|
+
}
|
|
8440
|
+
}
|
|
8383
8441
|
function errorToResponse(e, authenticated = true) {
|
|
8384
8442
|
if (e instanceof ApiError) {
|
|
8385
8443
|
return jsonResponse(e.status, e.body);
|
|
@@ -8389,6 +8447,8 @@ function errorToResponse(e, authenticated = true) {
|
|
|
8389
8447
|
}
|
|
8390
8448
|
const pg = e;
|
|
8391
8449
|
if (pg && typeof pg.code === "string" && /^[0-9A-Z]{5}$/.test(pg.code)) {
|
|
8450
|
+
if (pg.code === "PGRST")
|
|
8451
|
+
return pgrstErrorToResponse(pg);
|
|
8392
8452
|
return jsonResponse(statusForSqlState(pg.code, authenticated), {
|
|
8393
8453
|
code: pg.code,
|
|
8394
8454
|
message: pg.message,
|
|
@@ -8399,9 +8459,11 @@ function errorToResponse(e, authenticated = true) {
|
|
|
8399
8459
|
const message = e instanceof Error ? e.message : String(e);
|
|
8400
8460
|
return jsonResponse(500, { code: "PGRST500", message, details: null, hint: null });
|
|
8401
8461
|
}
|
|
8402
|
-
function jsonResponse(status, body, headers = {}) {
|
|
8403
|
-
|
|
8462
|
+
function jsonResponse(status, body, headers = {}, statusText) {
|
|
8463
|
+
const bodyless = status === 204 || status === 205 || status === 304;
|
|
8464
|
+
return new Response(bodyless ? null : JSON.stringify(body), {
|
|
8404
8465
|
status,
|
|
8466
|
+
...statusText === undefined ? {} : { statusText },
|
|
8405
8467
|
headers: { "content-type": "application/json; charset=utf-8", ...headers }
|
|
8406
8468
|
});
|
|
8407
8469
|
}
|
|
@@ -8711,7 +8773,7 @@ class RestHandler {
|
|
|
8711
8773
|
}
|
|
8712
8774
|
}
|
|
8713
8775
|
}
|
|
8714
|
-
const fn = pickOverload(fns, Object.keys(args));
|
|
8776
|
+
const fn = pickOverload(schema, fnName, fns, Object.keys(args));
|
|
8715
8777
|
const call = renderCall(schema, fn, args);
|
|
8716
8778
|
const q = parseQuery(searchParams);
|
|
8717
8779
|
if (method === "GET" || method === "HEAD")
|
|
@@ -8736,7 +8798,7 @@ class RestHandler {
|
|
|
8736
8798
|
const value = res.rows[0].result;
|
|
8737
8799
|
return jsonResponse(200, value);
|
|
8738
8800
|
}
|
|
8739
|
-
if (fn.returnsSet && ["b", "d", "e"].includes(fn.returnTypType)) {
|
|
8801
|
+
if (fn.returnsSet && !fn.returnsTable && ["b", "d", "e"].includes(fn.returnTypType)) {
|
|
8740
8802
|
const res = await withRpcContext((query) => query(`select coalesce(json_agg(_v), '[]'::json) as body from ${call} as _t(_v)`, []));
|
|
8741
8803
|
return jsonResponse(200, res.rows[0].body);
|
|
8742
8804
|
}
|
|
@@ -8797,22 +8859,14 @@ function assertObjectCardinality(rows) {
|
|
|
8797
8859
|
});
|
|
8798
8860
|
}
|
|
8799
8861
|
}
|
|
8800
|
-
function pickOverload(fns, providedNames) {
|
|
8862
|
+
function pickOverload(schema, name, fns, providedNames) {
|
|
8801
8863
|
const provided = new Set(providedNames);
|
|
8802
|
-
const
|
|
8803
|
-
let best = null;
|
|
8804
|
-
for (const fn of fns) {
|
|
8864
|
+
const matches = fns.filter((fn) => {
|
|
8805
8865
|
const names = new Set(fn.args.map((a) => a.name));
|
|
8806
|
-
|
|
8807
|
-
|
|
8808
|
-
|
|
8809
|
-
|
|
8810
|
-
exact.push(fn);
|
|
8811
|
-
if (!best)
|
|
8812
|
-
best = fn;
|
|
8813
|
-
}
|
|
8814
|
-
if (exact.length > 1) {
|
|
8815
|
-
const candidates = exact.map((fn) => `${fn.schema}.${fn.name}(${fn.args.map((arg) => `${arg.name} => ${arg.type}`).join(", ")})`);
|
|
8866
|
+
return [...provided].every((p) => names.has(p)) && fn.args.slice(0, fn.requiredArgCount).every((arg) => provided.has(arg.name));
|
|
8867
|
+
});
|
|
8868
|
+
if (matches.length > 1) {
|
|
8869
|
+
const candidates = matches.map((fn) => `${fn.schema}.${fn.name}(${fn.args.map((arg) => `${arg.name} => ${arg.type}`).join(", ")})`);
|
|
8816
8870
|
throw new ApiError(300, {
|
|
8817
8871
|
code: "PGRST203",
|
|
8818
8872
|
message: `Could not choose the best candidate function between: ${candidates.join(", ")}`,
|
|
@@ -8820,7 +8874,16 @@ function pickOverload(fns, providedNames) {
|
|
|
8820
8874
|
hint: "Try renaming the parameters or the function itself in the database so function overloading can be resolved"
|
|
8821
8875
|
});
|
|
8822
8876
|
}
|
|
8823
|
-
|
|
8877
|
+
const match = matches[0];
|
|
8878
|
+
if (!match) {
|
|
8879
|
+
throw new ApiError(404, {
|
|
8880
|
+
code: "PGRST202",
|
|
8881
|
+
message: `Could not find the function ${schema}.${name}(${[...provided].sort().join(", ")}) in the schema cache`,
|
|
8882
|
+
details: null,
|
|
8883
|
+
hint: null
|
|
8884
|
+
});
|
|
8885
|
+
}
|
|
8886
|
+
return match;
|
|
8824
8887
|
}
|
|
8825
8888
|
function renderCall(schema, fn, args) {
|
|
8826
8889
|
const parts = [];
|
|
@@ -43,11 +43,15 @@ export interface FunctionInfo {
|
|
|
43
43
|
schema: string;
|
|
44
44
|
name: string;
|
|
45
45
|
returnsSet: boolean;
|
|
46
|
+
/** Explicit RETURNS TABLE outputs, including a single base/domain/enum column. */
|
|
47
|
+
returnsTable: boolean;
|
|
46
48
|
returnType: string;
|
|
47
49
|
/** pg_type.typtype: b=base, c=composite, p=pseudo, d=domain, e=enum */
|
|
48
50
|
returnTypType: string;
|
|
49
51
|
/** pg_proc.provolatile: v=volatile, s=stable, i=immutable. Volatile calls may run DDL. */
|
|
50
52
|
volatility: string;
|
|
53
|
+
/** Leading input arguments without a PostgreSQL default. */
|
|
54
|
+
requiredArgCount: number;
|
|
51
55
|
args: FunctionArg[];
|
|
52
56
|
}
|
|
53
57
|
/** Introspected shape of one schema: tables keyed by name, plus its foreign keys. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../src/runtime/db/database.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../src/runtime/db/database.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/** HTTP status for a Postgres SQLSTATE, following PostgREST's mapping. */
|
|
2
2
|
export declare function statusForSqlState(code: string, authenticated?: boolean): number;
|
|
3
3
|
/**
|
|
4
|
-
* Normalize
|
|
5
|
-
*
|
|
6
|
-
* {@link statusForSqlState}
|
|
4
|
+
* Normalize thrown errors: ApiError/ParseError keep their status, PGRST
|
|
5
|
+
* exceptions supply structured response metadata, and other 5-char SQLSTATEs
|
|
6
|
+
* use {@link statusForSqlState}. Everything else becomes a 500.
|
|
7
7
|
*/
|
|
8
8
|
export declare function errorToResponse(e: unknown, authenticated?: boolean): Response;
|
|
9
|
-
/** JSON Response helper;
|
|
10
|
-
export declare function jsonResponse(status: number, body: unknown, headers?: Record<string, string
|
|
9
|
+
/** JSON Response helper; null-body HTTP statuses never serialize a payload. */
|
|
10
|
+
export declare function jsonResponse(status: number, body: unknown, headers?: Record<string, string>, statusText?: string): Response;
|
|
11
11
|
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/runtime/rest/errors.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/runtime/rest/errors.ts"],"names":[],"mappings":"AASA,0EAA0E;AAC1E,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,UAAO,GAAG,MAAM,CA8B5E;AAuDD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,OAAO,EAAE,aAAa,UAAO,GAAG,QAAQ,CAmB1E;AAED,+EAA+E;AAC/E,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,EACb,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,EACpC,UAAU,CAAC,EAAE,MAAM,GAClB,QAAQ,CAOV"}
|