@run402/functions 1.48.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/ai.d.ts +20 -0
- package/dist/ai.d.ts.map +1 -0
- package/dist/ai.js +53 -0
- package/dist/ai.js.map +1 -0
- package/dist/auth.d.ts +11 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +24 -0
- package/dist/auth.js.map +1 -0
- package/dist/config.d.ts +8 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +11 -0
- package/dist/config.js.map +1 -0
- package/dist/db.d.ts +57 -0
- package/dist/db.d.ts.map +1 -0
- package/dist/db.js +181 -0
- package/dist/db.js.map +1 -0
- package/dist/email.d.ts +27 -0
- package/dist/email.d.ts.map +1 -0
- package/dist/email.js +58 -0
- package/dist/email.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/package.json +51 -0
package/dist/ai.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface TranslateOptions {
|
|
2
|
+
from?: string;
|
|
3
|
+
context?: string;
|
|
4
|
+
}
|
|
5
|
+
export interface TranslateResult {
|
|
6
|
+
text: string;
|
|
7
|
+
from: string;
|
|
8
|
+
to: string;
|
|
9
|
+
[key: string]: unknown;
|
|
10
|
+
}
|
|
11
|
+
export interface ModerateResult {
|
|
12
|
+
flagged: boolean;
|
|
13
|
+
categories: Record<string, boolean>;
|
|
14
|
+
[key: string]: unknown;
|
|
15
|
+
}
|
|
16
|
+
export declare const ai: {
|
|
17
|
+
translate(text: string, to: string, opts?: TranslateOptions): Promise<TranslateResult>;
|
|
18
|
+
moderate(text: string): Promise<ModerateResult>;
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=ai.d.ts.map
|
package/dist/ai.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../src/ai.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,eAAO,MAAM,EAAE;oBAEL,MAAM,MACR,MAAM,SACH,gBAAgB,GACtB,OAAO,CAAC,eAAe,CAAC;mBAyBN,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;CAqBtD,CAAC"}
|
package/dist/ai.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { config } from "./config.js";
|
|
2
|
+
export const ai = {
|
|
3
|
+
async translate(text, to, opts) {
|
|
4
|
+
const body = { text, to };
|
|
5
|
+
if (opts?.from)
|
|
6
|
+
body.from = opts.from;
|
|
7
|
+
if (opts?.context)
|
|
8
|
+
body.context = opts.context;
|
|
9
|
+
const res = await fetch(config.API_BASE + "/ai/v1/translate", {
|
|
10
|
+
method: "POST",
|
|
11
|
+
headers: {
|
|
12
|
+
Authorization: "Bearer " + config.SERVICE_KEY,
|
|
13
|
+
"Content-Type": "application/json",
|
|
14
|
+
},
|
|
15
|
+
body: JSON.stringify(body),
|
|
16
|
+
});
|
|
17
|
+
if (!res.ok) {
|
|
18
|
+
const errBody = await res.text();
|
|
19
|
+
let msg;
|
|
20
|
+
try {
|
|
21
|
+
msg = JSON.parse(errBody).error || errBody;
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
msg = errBody;
|
|
25
|
+
}
|
|
26
|
+
throw new Error("Translation failed (" + res.status + "): " + msg);
|
|
27
|
+
}
|
|
28
|
+
return res.json();
|
|
29
|
+
},
|
|
30
|
+
async moderate(text) {
|
|
31
|
+
const res = await fetch(config.API_BASE + "/ai/v1/moderate", {
|
|
32
|
+
method: "POST",
|
|
33
|
+
headers: {
|
|
34
|
+
Authorization: "Bearer " + config.SERVICE_KEY,
|
|
35
|
+
"Content-Type": "application/json",
|
|
36
|
+
},
|
|
37
|
+
body: JSON.stringify({ text }),
|
|
38
|
+
});
|
|
39
|
+
if (!res.ok) {
|
|
40
|
+
const errBody = await res.text();
|
|
41
|
+
let msg;
|
|
42
|
+
try {
|
|
43
|
+
msg = JSON.parse(errBody).error || errBody;
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
msg = errBody;
|
|
47
|
+
}
|
|
48
|
+
throw new Error("Moderation failed (" + res.status + "): " + msg);
|
|
49
|
+
}
|
|
50
|
+
return res.json();
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=ai.js.map
|
package/dist/ai.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai.js","sourceRoot":"","sources":["../src/ai.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAoBrC,MAAM,CAAC,MAAM,EAAE,GAAG;IAChB,KAAK,CAAC,SAAS,CACb,IAAY,EACZ,EAAU,EACV,IAAuB;QAEvB,MAAM,IAAI,GAA2B,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QAClD,IAAI,IAAI,EAAE,IAAI;YAAE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACtC,IAAI,IAAI,EAAE,OAAO;YAAE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAC/C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,QAAQ,GAAG,kBAAkB,EAAE;YAC5D,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,SAAS,GAAG,MAAM,CAAC,WAAW;gBAC7C,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC3B,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YACjC,IAAI,GAAW,CAAC;YAChB,IAAI,CAAC;gBACH,GAAG,GAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAwB,CAAC,KAAK,IAAI,OAAO,CAAC;YACrE,CAAC;YAAC,MAAM,CAAC;gBACP,GAAG,GAAG,OAAO,CAAC;YAChB,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,sBAAsB,GAAG,GAAG,CAAC,MAAM,GAAG,KAAK,GAAG,GAAG,CAAC,CAAC;QACrE,CAAC;QACD,OAAO,GAAG,CAAC,IAAI,EAA8B,CAAC;IAChD,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,IAAY;QACzB,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE;YAC3D,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,SAAS,GAAG,MAAM,CAAC,WAAW;gBAC7C,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC;SAC/B,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YACjC,IAAI,GAAW,CAAC;YAChB,IAAI,CAAC;gBACH,GAAG,GAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAwB,CAAC,KAAK,IAAI,OAAO,CAAC;YACrE,CAAC;YAAC,MAAM,CAAC;gBACP,GAAG,GAAG,OAAO,CAAC;YAChB,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,qBAAqB,GAAG,GAAG,CAAC,MAAM,GAAG,KAAK,GAAG,GAAG,CAAC,CAAC;QACpE,CAAC;QACD,OAAO,GAAG,CAAC,IAAI,EAA6B,CAAC;IAC/C,CAAC;CACF,CAAC"}
|
package/dist/auth.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface User {
|
|
2
|
+
id: string;
|
|
3
|
+
role: string;
|
|
4
|
+
email: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Verify the caller's JWT and return user identity.
|
|
8
|
+
* Returns { id, role, email } or null if unauthenticated/invalid.
|
|
9
|
+
*/
|
|
10
|
+
export declare function getUser(req: Request): User | null;
|
|
11
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,GAAG,IAAI,CAmBjD"}
|
package/dist/auth.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import jwt from "jsonwebtoken";
|
|
2
|
+
import { config } from "./config.js";
|
|
3
|
+
/**
|
|
4
|
+
* Verify the caller's JWT and return user identity.
|
|
5
|
+
* Returns { id, role, email } or null if unauthenticated/invalid.
|
|
6
|
+
*/
|
|
7
|
+
export function getUser(req) {
|
|
8
|
+
const authHeader = typeof req.headers.get === "function"
|
|
9
|
+
? req.headers.get("authorization")
|
|
10
|
+
: req.headers?.authorization;
|
|
11
|
+
if (!authHeader || !authHeader.startsWith("Bearer "))
|
|
12
|
+
return null;
|
|
13
|
+
const token = authHeader.slice(7);
|
|
14
|
+
try {
|
|
15
|
+
const payload = jwt.verify(token, config.JWT_SECRET);
|
|
16
|
+
if (payload.project_id !== config.PROJECT_ID)
|
|
17
|
+
return null;
|
|
18
|
+
return { id: payload.sub, role: payload.role, email: payload.email };
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=auth.js.map
|
package/dist/auth.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,cAAc,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAQrC;;;GAGG;AACH,MAAM,UAAU,OAAO,CAAC,GAAY;IAClC,MAAM,UAAU,GACd,OAAQ,GAAG,CAAC,OAA6C,CAAC,GAAG,KAAK,UAAU;QAC1E,CAAC,CAAE,GAAG,CAAC,OAAmB,CAAC,GAAG,CAAC,eAAe,CAAC;QAC/C,CAAC,CAAE,GAAG,CAAC,OAAyD,EAAE,aAAa,CAAC;IACpF,IAAI,CAAC,UAAU,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IAClE,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAClC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,UAAU,CAKlD,CAAC;QACF,IAAI,OAAO,CAAC,UAAU,KAAK,MAAM,CAAC,UAAU;YAAE,OAAO,IAAI,CAAC;QAC1D,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;IACvE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,MAAM;;;;;;CAMlB,CAAC"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Read env vars lazily (on access, not import time) so that:
|
|
2
|
+
// 1. Local dev can set process.env before each invocation
|
|
3
|
+
// 2. Module caching doesn't freeze config from the first import
|
|
4
|
+
export const config = {
|
|
5
|
+
get API_BASE() { return process.env.RUN402_API_BASE || "https://api.run402.com"; },
|
|
6
|
+
get PROJECT_ID() { return process.env.RUN402_PROJECT_ID || ""; },
|
|
7
|
+
get SERVICE_KEY() { return process.env.RUN402_SERVICE_KEY || ""; },
|
|
8
|
+
get ANON_KEY() { return process.env.RUN402_ANON_KEY || ""; },
|
|
9
|
+
get JWT_SECRET() { return process.env.RUN402_JWT_SECRET || ""; },
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,0DAA0D;AAC1D,gEAAgE;AAChE,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,IAAI,QAAQ,KAAK,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,wBAAwB,CAAC,CAAC,CAAC;IAClF,IAAI,UAAU,KAAK,OAAO,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC,CAAC;IAChE,IAAI,WAAW,KAAK,OAAO,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,EAAE,CAAC,CAAC,CAAC;IAClE,IAAI,QAAQ,KAAK,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC,CAAC;IAC5D,IAAI,UAAU,KAAK,OAAO,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC,CAAC;CACjE,CAAC"}
|
package/dist/db.d.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
interface QueryBuilderOpts {
|
|
2
|
+
apikey: string;
|
|
3
|
+
authorization: string | undefined;
|
|
4
|
+
basePath: string;
|
|
5
|
+
}
|
|
6
|
+
export declare class QueryBuilder {
|
|
7
|
+
#private;
|
|
8
|
+
constructor(table: string, opts: QueryBuilderOpts);
|
|
9
|
+
select(columns?: string): this;
|
|
10
|
+
eq(column: string, value: string | number): this;
|
|
11
|
+
neq(column: string, value: string | number): this;
|
|
12
|
+
gt(column: string, value: string | number): this;
|
|
13
|
+
lt(column: string, value: string | number): this;
|
|
14
|
+
gte(column: string, value: string | number): this;
|
|
15
|
+
lte(column: string, value: string | number): this;
|
|
16
|
+
like(column: string, pattern: string): this;
|
|
17
|
+
ilike(column: string, pattern: string): this;
|
|
18
|
+
in(column: string, values: (string | number)[]): this;
|
|
19
|
+
order(column: string, { ascending }?: {
|
|
20
|
+
ascending?: boolean | undefined;
|
|
21
|
+
}): this;
|
|
22
|
+
limit(count: number): this;
|
|
23
|
+
offset(count: number): this;
|
|
24
|
+
insert(data: Record<string, unknown> | Record<string, unknown>[]): this;
|
|
25
|
+
update(data: Record<string, unknown>): this;
|
|
26
|
+
delete(): this;
|
|
27
|
+
then(resolve: (value: Record<string, unknown>[]) => void, reject: (reason: Error) => void): void;
|
|
28
|
+
}
|
|
29
|
+
interface CallerDbClient {
|
|
30
|
+
from(table: string): QueryBuilder;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Caller-context DB client. Forwards the incoming Request's Authorization
|
|
34
|
+
* header to PostgREST so RLS policies evaluate against the caller's role.
|
|
35
|
+
* `apikey` is the project's anon key (routing only — does not grant bypass).
|
|
36
|
+
*
|
|
37
|
+
* If the incoming Request has no Authorization, the request is sent with
|
|
38
|
+
* just the anon apikey; PostgREST resolves role=anon and RLS decides whether
|
|
39
|
+
* the query succeeds or returns 401/403.
|
|
40
|
+
*/
|
|
41
|
+
export declare function db(req: Request): CallerDbClient;
|
|
42
|
+
interface AdminDbClient {
|
|
43
|
+
from(table: string): QueryBuilder;
|
|
44
|
+
sql(query: string, params?: unknown[]): Promise<Record<string, unknown>[]>;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Admin DB client. Uses the project's service_key (role=service_role,
|
|
48
|
+
* BYPASSRLS). Routes through /admin/v1/rest/* at the gateway, which rejects
|
|
49
|
+
* any other caller than service_role. Use for explicit server-side operations
|
|
50
|
+
* that must ignore RLS.
|
|
51
|
+
*
|
|
52
|
+
* `adminDb().sql()` targets the /projects/v1/admin/:id/sql endpoint, which
|
|
53
|
+
* runs arbitrary SQL as a superuser-scoped role on the project schema.
|
|
54
|
+
*/
|
|
55
|
+
export declare function adminDb(): AdminDbClient;
|
|
56
|
+
export {};
|
|
57
|
+
//# sourceMappingURL=db.d.ts.map
|
package/dist/db.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"AAEA,UAAU,gBAAgB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,YAAY;;gBASX,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB;IAOjD,MAAM,CAAC,OAAO,SAAM,GAAG,IAAI;IAK3B,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKhD,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKjD,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKhD,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKhD,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKjD,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKjD,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAK3C,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAK5C,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GAAG,IAAI;IAKrD,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,SAAgB,EAAE;;KAAK,GAAG,IAAI;IAKtD,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK1B,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK3B,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,IAAI;IAMvE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAM3C,MAAM,IAAI,IAAI;IAKd,IAAI,CACF,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,IAAI,EACnD,MAAM,EAAE,CAAC,MAAM,EAAE,KAAK,KAAK,IAAI,GAC9B,IAAI;CA6BR;AAOD,UAAU,cAAc;IACtB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAAC;CACnC;AAED;;;;;;;;GAQG;AACH,wBAAgB,EAAE,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,CAkB/C;AAED,UAAU,aAAa;IACrB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAAC;IAClC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;CAC5E;AAED;;;;;;;;GAQG;AACH,wBAAgB,OAAO,IAAI,aAAa,CA+BvC"}
|
package/dist/db.js
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { config } from "./config.js";
|
|
2
|
+
export class QueryBuilder {
|
|
3
|
+
#table;
|
|
4
|
+
#params = new URLSearchParams();
|
|
5
|
+
#method = "GET";
|
|
6
|
+
#body = undefined;
|
|
7
|
+
#apikey;
|
|
8
|
+
#authorization;
|
|
9
|
+
#basePath;
|
|
10
|
+
constructor(table, opts) {
|
|
11
|
+
this.#table = table;
|
|
12
|
+
this.#apikey = opts.apikey;
|
|
13
|
+
this.#authorization = opts.authorization;
|
|
14
|
+
this.#basePath = opts.basePath;
|
|
15
|
+
}
|
|
16
|
+
select(columns = "*") {
|
|
17
|
+
this.#params.set("select", columns);
|
|
18
|
+
return this;
|
|
19
|
+
}
|
|
20
|
+
eq(column, value) {
|
|
21
|
+
this.#params.append(column, `eq.${value}`);
|
|
22
|
+
return this;
|
|
23
|
+
}
|
|
24
|
+
neq(column, value) {
|
|
25
|
+
this.#params.append(column, `neq.${value}`);
|
|
26
|
+
return this;
|
|
27
|
+
}
|
|
28
|
+
gt(column, value) {
|
|
29
|
+
this.#params.append(column, `gt.${value}`);
|
|
30
|
+
return this;
|
|
31
|
+
}
|
|
32
|
+
lt(column, value) {
|
|
33
|
+
this.#params.append(column, `lt.${value}`);
|
|
34
|
+
return this;
|
|
35
|
+
}
|
|
36
|
+
gte(column, value) {
|
|
37
|
+
this.#params.append(column, `gte.${value}`);
|
|
38
|
+
return this;
|
|
39
|
+
}
|
|
40
|
+
lte(column, value) {
|
|
41
|
+
this.#params.append(column, `lte.${value}`);
|
|
42
|
+
return this;
|
|
43
|
+
}
|
|
44
|
+
like(column, pattern) {
|
|
45
|
+
this.#params.append(column, `like.${pattern}`);
|
|
46
|
+
return this;
|
|
47
|
+
}
|
|
48
|
+
ilike(column, pattern) {
|
|
49
|
+
this.#params.append(column, `ilike.${pattern}`);
|
|
50
|
+
return this;
|
|
51
|
+
}
|
|
52
|
+
in(column, values) {
|
|
53
|
+
this.#params.append(column, `in.(${values.join(",")})`);
|
|
54
|
+
return this;
|
|
55
|
+
}
|
|
56
|
+
order(column, { ascending = true } = {}) {
|
|
57
|
+
this.#params.append("order", `${column}.${ascending ? "asc" : "desc"}`);
|
|
58
|
+
return this;
|
|
59
|
+
}
|
|
60
|
+
limit(count) {
|
|
61
|
+
this.#params.set("limit", String(count));
|
|
62
|
+
return this;
|
|
63
|
+
}
|
|
64
|
+
offset(count) {
|
|
65
|
+
this.#params.set("offset", String(count));
|
|
66
|
+
return this;
|
|
67
|
+
}
|
|
68
|
+
insert(data) {
|
|
69
|
+
this.#method = "POST";
|
|
70
|
+
this.#body = Array.isArray(data) ? data : [data];
|
|
71
|
+
return this;
|
|
72
|
+
}
|
|
73
|
+
update(data) {
|
|
74
|
+
this.#method = "PATCH";
|
|
75
|
+
this.#body = data;
|
|
76
|
+
return this;
|
|
77
|
+
}
|
|
78
|
+
delete() {
|
|
79
|
+
this.#method = "DELETE";
|
|
80
|
+
return this;
|
|
81
|
+
}
|
|
82
|
+
then(resolve, reject) {
|
|
83
|
+
const qs = this.#params.toString();
|
|
84
|
+
const url = `${config.API_BASE}${this.#basePath}/${this.#table}${qs ? "?" + qs : ""}`;
|
|
85
|
+
const headers = {
|
|
86
|
+
apikey: this.#apikey,
|
|
87
|
+
"Content-Type": "application/json",
|
|
88
|
+
Prefer: "return=representation",
|
|
89
|
+
};
|
|
90
|
+
if (this.#authorization) {
|
|
91
|
+
headers.Authorization = this.#authorization;
|
|
92
|
+
}
|
|
93
|
+
fetch(url, {
|
|
94
|
+
method: this.#method,
|
|
95
|
+
headers,
|
|
96
|
+
body: this.#body ? JSON.stringify(this.#body) : undefined,
|
|
97
|
+
})
|
|
98
|
+
.then(async (res) => {
|
|
99
|
+
if (!res.ok) {
|
|
100
|
+
const errBody = await res.text();
|
|
101
|
+
reject(new Error(`PostgREST error (${res.status}): ${errBody}`));
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const data = await res.json();
|
|
105
|
+
resolve(data);
|
|
106
|
+
})
|
|
107
|
+
.catch(reject);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
function extractAuth(req) {
|
|
111
|
+
const auth = req.headers.get("authorization") ?? req.headers.get("Authorization");
|
|
112
|
+
return auth ?? undefined;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Caller-context DB client. Forwards the incoming Request's Authorization
|
|
116
|
+
* header to PostgREST so RLS policies evaluate against the caller's role.
|
|
117
|
+
* `apikey` is the project's anon key (routing only — does not grant bypass).
|
|
118
|
+
*
|
|
119
|
+
* If the incoming Request has no Authorization, the request is sent with
|
|
120
|
+
* just the anon apikey; PostgREST resolves role=anon and RLS decides whether
|
|
121
|
+
* the query succeeds or returns 401/403.
|
|
122
|
+
*/
|
|
123
|
+
export function db(req) {
|
|
124
|
+
if (!config.ANON_KEY) {
|
|
125
|
+
throw new Error("db(req) requires RUN402_ANON_KEY in the Lambda environment. " +
|
|
126
|
+
"Redeploy this function via the gateway to pick up the new env var.");
|
|
127
|
+
}
|
|
128
|
+
const authorization = extractAuth(req);
|
|
129
|
+
const anonKey = config.ANON_KEY;
|
|
130
|
+
return {
|
|
131
|
+
from(table) {
|
|
132
|
+
return new QueryBuilder(table, {
|
|
133
|
+
apikey: anonKey,
|
|
134
|
+
authorization,
|
|
135
|
+
basePath: "/rest/v1",
|
|
136
|
+
});
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Admin DB client. Uses the project's service_key (role=service_role,
|
|
142
|
+
* BYPASSRLS). Routes through /admin/v1/rest/* at the gateway, which rejects
|
|
143
|
+
* any other caller than service_role. Use for explicit server-side operations
|
|
144
|
+
* that must ignore RLS.
|
|
145
|
+
*
|
|
146
|
+
* `adminDb().sql()` targets the /projects/v1/admin/:id/sql endpoint, which
|
|
147
|
+
* runs arbitrary SQL as a superuser-scoped role on the project schema.
|
|
148
|
+
*/
|
|
149
|
+
export function adminDb() {
|
|
150
|
+
if (!config.SERVICE_KEY) {
|
|
151
|
+
throw new Error("adminDb() requires RUN402_SERVICE_KEY in the Lambda environment.");
|
|
152
|
+
}
|
|
153
|
+
const serviceKey = config.SERVICE_KEY;
|
|
154
|
+
return {
|
|
155
|
+
from(table) {
|
|
156
|
+
return new QueryBuilder(table, {
|
|
157
|
+
apikey: serviceKey,
|
|
158
|
+
authorization: `Bearer ${serviceKey}`,
|
|
159
|
+
basePath: "/admin/v1/rest",
|
|
160
|
+
});
|
|
161
|
+
},
|
|
162
|
+
async sql(query, params) {
|
|
163
|
+
const url = `${config.API_BASE}/projects/v1/admin/${config.PROJECT_ID}/sql`;
|
|
164
|
+
const hasParams = Array.isArray(params) && params.length > 0;
|
|
165
|
+
const res = await fetch(url, {
|
|
166
|
+
method: "POST",
|
|
167
|
+
headers: {
|
|
168
|
+
Authorization: `Bearer ${serviceKey}`,
|
|
169
|
+
"Content-Type": hasParams ? "application/json" : "text/plain",
|
|
170
|
+
},
|
|
171
|
+
body: hasParams ? JSON.stringify({ sql: query, params }) : query,
|
|
172
|
+
});
|
|
173
|
+
if (!res.ok) {
|
|
174
|
+
const errBody = await res.text();
|
|
175
|
+
throw new Error(`SQL error (${res.status}): ${errBody}`);
|
|
176
|
+
}
|
|
177
|
+
return res.json();
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=db.js.map
|
package/dist/db.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"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"}
|
package/dist/email.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface EmailRawOptions {
|
|
2
|
+
to: string;
|
|
3
|
+
subject: string;
|
|
4
|
+
html: string;
|
|
5
|
+
text?: string;
|
|
6
|
+
from_name?: string;
|
|
7
|
+
template?: never;
|
|
8
|
+
variables?: never;
|
|
9
|
+
}
|
|
10
|
+
export interface EmailTemplateOptions {
|
|
11
|
+
to: string;
|
|
12
|
+
template: string;
|
|
13
|
+
variables?: Record<string, string>;
|
|
14
|
+
from_name?: string;
|
|
15
|
+
subject?: never;
|
|
16
|
+
html?: never;
|
|
17
|
+
text?: never;
|
|
18
|
+
}
|
|
19
|
+
export type EmailSendOptions = EmailRawOptions | EmailTemplateOptions;
|
|
20
|
+
export interface EmailSendResult {
|
|
21
|
+
id: string;
|
|
22
|
+
[key: string]: unknown;
|
|
23
|
+
}
|
|
24
|
+
export declare const email: {
|
|
25
|
+
send(opts: EmailSendOptions): Promise<EmailSendResult>;
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=email.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email.d.ts","sourceRoot":"","sources":["../src/email.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,KAAK,CAAC;IACjB,SAAS,CAAC,EAAE,KAAK,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,KAAK,CAAC;IAChB,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,IAAI,CAAC,EAAE,KAAK,CAAC;CACd;AAED,MAAM,MAAM,gBAAgB,GAAG,eAAe,GAAG,oBAAoB,CAAC;AAEtE,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,eAAO,MAAM,KAAK;eAkBG,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;CAiC5D,CAAC"}
|
package/dist/email.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { config } from "./config.js";
|
|
2
|
+
export const email = (() => {
|
|
3
|
+
let _mailboxId = null;
|
|
4
|
+
async function _discoverMailbox() {
|
|
5
|
+
if (_mailboxId)
|
|
6
|
+
return _mailboxId;
|
|
7
|
+
const res = await fetch(config.API_BASE + "/mailboxes/v1", {
|
|
8
|
+
headers: { Authorization: "Bearer " + config.SERVICE_KEY },
|
|
9
|
+
});
|
|
10
|
+
if (!res.ok)
|
|
11
|
+
throw new Error("Failed to discover mailbox: " + (await res.text()));
|
|
12
|
+
const data = (await res.json());
|
|
13
|
+
if (!data.mailboxes || data.mailboxes.length === 0) {
|
|
14
|
+
throw new Error("No mailbox configured for this project");
|
|
15
|
+
}
|
|
16
|
+
_mailboxId = data.mailboxes[0].mailbox_id;
|
|
17
|
+
return _mailboxId;
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
async send(opts) {
|
|
21
|
+
const mbxId = await _discoverMailbox();
|
|
22
|
+
const body = { to: opts.to };
|
|
23
|
+
if ("template" in opts && opts.template) {
|
|
24
|
+
body.template = opts.template;
|
|
25
|
+
body.variables = opts.variables || {};
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
body.subject = opts.subject;
|
|
29
|
+
body.html = opts.html;
|
|
30
|
+
if (opts.text)
|
|
31
|
+
body.text = opts.text;
|
|
32
|
+
}
|
|
33
|
+
if (opts.from_name)
|
|
34
|
+
body.from_name = opts.from_name;
|
|
35
|
+
const res = await fetch(config.API_BASE + "/mailboxes/v1/" + mbxId + "/messages", {
|
|
36
|
+
method: "POST",
|
|
37
|
+
headers: {
|
|
38
|
+
Authorization: "Bearer " + config.SERVICE_KEY,
|
|
39
|
+
"Content-Type": "application/json",
|
|
40
|
+
},
|
|
41
|
+
body: JSON.stringify(body),
|
|
42
|
+
});
|
|
43
|
+
if (!res.ok) {
|
|
44
|
+
const errBody = await res.text();
|
|
45
|
+
let msg;
|
|
46
|
+
try {
|
|
47
|
+
msg = JSON.parse(errBody).error || errBody;
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
msg = errBody;
|
|
51
|
+
}
|
|
52
|
+
throw new Error("Email send failed (" + res.status + "): " + msg);
|
|
53
|
+
}
|
|
54
|
+
return res.json();
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
})();
|
|
58
|
+
//# sourceMappingURL=email.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email.js","sourceRoot":"","sources":["../src/email.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { db, adminDb, QueryBuilder } from "./db.js";
|
|
2
|
+
export { getUser } from "./auth.js";
|
|
3
|
+
export type { User } from "./auth.js";
|
|
4
|
+
export { email } from "./email.js";
|
|
5
|
+
export type { EmailSendOptions, EmailRawOptions, EmailTemplateOptions, EmailSendResult } from "./email.js";
|
|
6
|
+
export { ai } from "./ai.js";
|
|
7
|
+
export type { TranslateOptions, TranslateResult, ModerateResult } from "./ai.js";
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,YAAY,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC3G,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@run402/functions",
|
|
3
|
+
"version": "1.48.0",
|
|
4
|
+
"description": "In-function helper library for Run402 serverless functions — db, adminDb, getUser, email, ai. Auto-bundled into deployed functions; also installable for local TypeScript autocomplete.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"!dist/*.test.*",
|
|
17
|
+
"README.md"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc",
|
|
21
|
+
"test": "node --experimental-test-module-mocks --test --import tsx src/db.test.ts src/auth.test.ts"
|
|
22
|
+
},
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=18"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"jsonwebtoken": "^9.0.2"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/jsonwebtoken": "^9.0.9"
|
|
31
|
+
},
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "git+https://github.com/kychee-com/run402.git",
|
|
35
|
+
"directory": "functions"
|
|
36
|
+
},
|
|
37
|
+
"homepage": "https://run402.com",
|
|
38
|
+
"bugs": "https://github.com/kychee-com/run402/issues",
|
|
39
|
+
"author": "Kychee Technologies",
|
|
40
|
+
"license": "MIT",
|
|
41
|
+
"keywords": [
|
|
42
|
+
"run402",
|
|
43
|
+
"serverless",
|
|
44
|
+
"lambda",
|
|
45
|
+
"in-function-helpers",
|
|
46
|
+
"ai-agent"
|
|
47
|
+
],
|
|
48
|
+
"publishConfig": {
|
|
49
|
+
"access": "public"
|
|
50
|
+
}
|
|
51
|
+
}
|