@protobase/server 0.32.0 → 0.33.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.
|
@@ -47,6 +47,11 @@ export type CorsOptions = {
|
|
|
47
47
|
type SharedOptions = {
|
|
48
48
|
/** Answers CORS preflights before authentication and adds the CORS headers to every response, problems included. */
|
|
49
49
|
cors?: CorsOptions;
|
|
50
|
+
/**
|
|
51
|
+
* Also answers at `/api/sb/functions/v1/<name>`, as Supabase's `verify_jwt` does, where the app's publishable key alone
|
|
52
|
+
* admits a caller. For functions moved from Supabase; not together with `roles` or `capability`.
|
|
53
|
+
*/
|
|
54
|
+
supabase?: boolean;
|
|
50
55
|
};
|
|
51
56
|
/** A function anyone may call, such as a webhook; it can still ask for a caller with `context.caller()`. */
|
|
52
57
|
export type PublicFunctionOptions = SharedOptions & {
|
|
@@ -78,7 +83,7 @@ export type FunctionSource = ApiFunction | FunctionHandler | FunctionApp;
|
|
|
78
83
|
/**
|
|
79
84
|
* A function of your own, served at `/api/functions/<name>`. Without options it needs a signed-in caller, through the
|
|
80
85
|
* app's `authenticate`, and with the app's `roles` one whose roles hold `*`; `{ roles }` or `{ capability }` opens it
|
|
81
|
-
* to more, `{ public: true }` to anyone, as for a webhook.
|
|
86
|
+
* to more, `{ public: true }` to anyone, as for a webhook. `{ supabase: true }` serves it at `/api/sb/functions/v1/<name>` too.
|
|
82
87
|
*/
|
|
83
88
|
export declare function defineFunction(handler: FunctionHandler | FunctionApp): ApiFunction;
|
|
84
89
|
export declare function defineFunction(options: PublicFunctionOptions, handler: PublicFunctionHandler | FunctionApp<PublicFunctionContext>): ApiFunction;
|
|
@@ -7,11 +7,12 @@ import { Hono } from "hono";
|
|
|
7
7
|
import { cors } from "hono/cors";
|
|
8
8
|
//#region src/functions/supabase-routes.ts
|
|
9
9
|
/**
|
|
10
|
-
* The
|
|
11
|
-
* a request its app's keys admit, as Supabase's `verify_jwt` does,
|
|
12
|
-
* caller, not the app's session, so
|
|
13
|
-
*
|
|
14
|
-
* reaches it unchecked.
|
|
10
|
+
* The functions with `supabase: true` again at `/api/sb/functions/v1/<name>`, as Supabase serves Edge Functions. A
|
|
11
|
+
* protected one lets in a request its app's keys admit, as Supabase's `verify_jwt` does, the publishable key alone
|
|
12
|
+
* included, and a public one anyone. Either gets the key-made caller, not the app's session, so neither may have
|
|
13
|
+
* `roles` or `capability`: that stops startup. As on Supabase, the function sees the path from its name on,
|
|
14
|
+
* `/<name>/more/parts`, and a CORS preflight, which carries no key, reaches it unchecked. Every other function is a 404
|
|
15
|
+
* here, and none of its code runs.
|
|
15
16
|
*/
|
|
16
17
|
const supabaseFunctionRoutes = ({ functions, db, keys, caller, onError }) => {
|
|
17
18
|
const app = new Hono().basePath(supabaseFunctionsPath);
|
|
@@ -19,9 +20,17 @@ const supabaseFunctionRoutes = ({ functions, db, keys, caller, onError }) => {
|
|
|
19
20
|
const hasKeys = keys.publishable !== void 0 || keys.secret !== void 0;
|
|
20
21
|
for (const [name, fn] of Object.entries(functions)) {
|
|
21
22
|
const { options } = fn;
|
|
23
|
+
if (options.supabase !== true) {
|
|
24
|
+
app.all(`/${name}/*`, () => {
|
|
25
|
+
throw notFound(`The function "${name}" answers at /api/functions/${name} only: give it supabase: true to answer here too`);
|
|
26
|
+
});
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
const { roles, capability } = options;
|
|
30
|
+
const gated = roles !== void 0 ? "roles" : capability !== void 0 ? "a capability" : void 0;
|
|
31
|
+
if (gated) throw new Error(`The function "${name}" has supabase: true and ${gated}, which /api/sb/functions/v1 cannot check: drop one`);
|
|
22
32
|
if (options.cors) app.use(`/${name}/*`, cors(options.cors));
|
|
23
33
|
app.all(`/${name}/*`, (c) => runInBackground(async () => {
|
|
24
|
-
if (!options.public && options.roles) throw notFound(`The function "${name}" checks roles, so it is served at /api/functions/${name} only`);
|
|
25
34
|
const request = relativeRequest(c.req.raw, supabaseFunctionsPath);
|
|
26
35
|
if (options.public || c.req.method === "OPTIONS") {
|
|
27
36
|
let resolved;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@protobase/server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.33.0",
|
|
4
4
|
"description": "The Protobase REST API as a Hono app, with Better Auth sign-in.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -32,9 +32,9 @@
|
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@better-auth/passkey": "^1.7.7",
|
|
34
34
|
"@better-auth/sso": "^1.7.7",
|
|
35
|
-
"@protobase/layout": "0.
|
|
36
|
-
"@protobase/query": "0.
|
|
37
|
-
"@protobase/schema": "0.
|
|
35
|
+
"@protobase/layout": "0.33.0",
|
|
36
|
+
"@protobase/query": "0.33.0",
|
|
37
|
+
"@protobase/schema": "0.33.0",
|
|
38
38
|
"@react-email/render": "^2.1.0",
|
|
39
39
|
"@scalar/hono-api-reference": "^0.12.10",
|
|
40
40
|
"@sentry/core": "^11.7.0",
|