tinbase 0.10.0 → 0.10.2
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/README.md +10 -9
- package/dist/admin/api.d.ts +62 -1
- package/dist/admin/api.js +221 -10
- package/dist/admin/api.js.map +1 -1
- package/dist/admin/ui.d.ts +1 -1
- package/dist/admin/ui.js +1548 -16
- package/dist/admin/ui.js.map +1 -1
- package/dist/auth/handler.d.ts +52 -5
- package/dist/auth/handler.js +147 -36
- package/dist/auth/handler.js.map +1 -1
- package/dist/auth/inbox.d.ts +4 -2
- package/dist/auth/inbox.js +1 -0
- package/dist/auth/inbox.js.map +1 -1
- package/dist/auth/oauth.d.ts +30 -4
- package/dist/auth/oauth.js +22 -6
- package/dist/auth/oauth.js.map +1 -1
- package/dist/auth/password.d.ts +5 -0
- package/dist/auth/password.js +7 -0
- package/dist/auth/password.js.map +1 -1
- package/dist/auth/qr.d.ts +1 -1
- package/dist/auth/qr.js +1 -1
- package/dist/auth/rate-limit.d.ts +33 -0
- package/dist/auth/rate-limit.js +63 -0
- package/dist/auth/rate-limit.js.map +1 -0
- package/dist/auth/redirect.d.ts +20 -0
- package/dist/auth/redirect.js +79 -0
- package/dist/auth/redirect.js.map +1 -0
- package/dist/auth/settings.d.ts +55 -0
- package/dist/auth/settings.js +116 -0
- package/dist/auth/settings.js.map +1 -0
- package/dist/auth/totp.js +1 -1
- package/dist/cli.js +43 -21
- package/dist/cli.js.map +1 -1
- package/dist/cron/service.d.ts +15 -2
- package/dist/cron/service.js +19 -2
- package/dist/cron/service.js.map +1 -1
- package/dist/db/bootstrap.d.ts +13 -6
- package/dist/db/bootstrap.js +26 -5
- package/dist/db/bootstrap.js.map +1 -1
- package/dist/db/database.d.ts +61 -3
- package/dist/db/database.js +72 -9
- package/dist/db/database.js.map +1 -1
- package/dist/db/emulated.d.ts +39 -2
- package/dist/db/emulated.js +39 -23
- package/dist/db/emulated.js.map +1 -1
- package/dist/db/engine.d.ts +19 -5
- package/dist/db/engine.js +4 -2
- package/dist/db/engine.js.map +1 -1
- package/dist/db/inspect.d.ts +6 -1
- package/dist/db/inspect.js +2 -1
- package/dist/db/inspect.js.map +1 -1
- package/dist/db/pglite-engine.d.ts +7 -1
- package/dist/db/pglite-engine.js +7 -1
- package/dist/db/pglite-engine.js.map +1 -1
- package/dist/db/pgmem-engine.d.ts +9 -3
- package/dist/db/pgmem-engine.js +13 -7
- package/dist/db/pgmem-engine.js.map +1 -1
- package/dist/db/schema-diff.d.ts +9 -1
- package/dist/db/schema-diff.js +19 -5
- package/dist/db/schema-diff.js.map +1 -1
- package/dist/db/sql-compat.d.ts +2 -2
- package/dist/db/sql-compat.js +2 -2
- package/dist/functions/deno-shim.d.ts +6 -17
- package/dist/functions/deno-shim.js +42 -10
- package/dist/functions/deno-shim.js.map +1 -1
- package/dist/functions/handler.d.ts +9 -4
- package/dist/functions/handler.js +9 -1
- package/dist/functions/handler.js.map +1 -1
- package/dist/gen-types.d.ts +6 -1
- package/dist/gen-types.js +53 -41
- package/dist/gen-types.js.map +1 -1
- package/dist/index.d.ts +33 -3
- package/dist/index.js +158 -28
- package/dist/index.js.map +1 -1
- package/dist/jwt.d.ts +4 -1
- package/dist/jwt.js +4 -2
- package/dist/jwt.js.map +1 -1
- package/dist/log-buffer.d.ts +7 -1
- package/dist/log-buffer.js +3 -0
- package/dist/log-buffer.js.map +1 -1
- package/dist/net/service.d.ts +35 -6
- package/dist/net/service.js +72 -17
- package/dist/net/service.js.map +1 -1
- package/dist/node/bun-server.d.ts +2 -1
- package/dist/node/bun-server.js +11 -1
- package/dist/node/bun-server.js.map +1 -1
- package/dist/node/bundle-function.d.ts +1 -1
- package/dist/node/bundle-function.js +1 -1
- package/dist/node/config-toml.d.ts +31 -0
- package/dist/node/config-toml.js +186 -0
- package/dist/node/config-toml.js.map +1 -0
- package/dist/node/db-diff.d.ts +13 -1
- package/dist/node/db-diff.js +3 -1
- package/dist/node/db-diff.js.map +1 -1
- package/dist/node/fs-driver.d.ts +16 -1
- package/dist/node/fs-driver.js +20 -1
- package/dist/node/fs-driver.js.map +1 -1
- package/dist/node/index.d.ts +2 -2
- package/dist/node/index.js +1 -1
- package/dist/node/index.js.map +1 -1
- package/dist/node/load-config.d.ts +80 -0
- package/dist/node/load-config.js +230 -0
- package/dist/node/load-config.js.map +1 -0
- package/dist/node/load-functions.d.ts +17 -2
- package/dist/node/load-functions.js +17 -4
- package/dist/node/load-functions.js.map +1 -1
- package/dist/node/native/engine.d.ts +7 -0
- package/dist/node/native/engine.js +58 -7
- package/dist/node/native/engine.js.map +1 -1
- package/dist/node/native/wire.d.ts +15 -1
- package/dist/node/native/wire.js +32 -10
- package/dist/node/native/wire.js.map +1 -1
- package/dist/node/project.d.ts +15 -1
- package/dist/node/project.js +19 -7
- package/dist/node/project.js.map +1 -1
- package/dist/node/server-shared.d.ts +4 -1
- package/dist/node/server.d.ts +11 -0
- package/dist/node/server.js +11 -0
- package/dist/node/server.js.map +1 -1
- package/dist/node/ws.d.ts +26 -1
- package/dist/node/ws.js +26 -3
- package/dist/node/ws.js.map +1 -1
- package/dist/realtime/engine.d.ts +6 -0
- package/dist/realtime/engine.js +45 -34
- package/dist/realtime/engine.js.map +1 -1
- package/dist/rest/build.d.ts +37 -1
- package/dist/rest/build.js +48 -8
- package/dist/rest/build.js.map +1 -1
- package/dist/rest/errors.d.ts +8 -0
- package/dist/rest/errors.js +12 -1
- package/dist/rest/errors.js.map +1 -1
- package/dist/rest/handler.d.ts +17 -1
- package/dist/rest/handler.js +48 -5
- package/dist/rest/handler.js.map +1 -1
- package/dist/rest/parse.d.ts +24 -1
- package/dist/rest/parse.js +7 -1
- package/dist/rest/parse.js.map +1 -1
- package/dist/retention/service.d.ts +3 -0
- package/dist/retention/service.js +3 -1
- package/dist/retention/service.js.map +1 -1
- package/dist/security.d.ts +22 -0
- package/dist/security.js +47 -0
- package/dist/security.js.map +1 -0
- package/dist/storage/driver.d.ts +8 -1
- package/dist/storage/driver.js +4 -1
- package/dist/storage/driver.js.map +1 -1
- package/dist/storage/handler.d.ts +10 -1
- package/dist/storage/handler.js +93 -12
- package/dist/storage/handler.js.map +1 -1
- package/dist/types.d.ts +77 -1
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -1
- package/dist/webhooks/service.d.ts +25 -2
- package/dist/webhooks/service.js +21 -3
- package/dist/webhooks/service.js.map +1 -1
- package/package.json +5 -3
package/dist/net/service.js
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
/** Cap on the response body we buffer into net._http_response (bytes). */
|
|
2
2
|
const MAX_RESPONSE_BYTES = 10 * 1024 * 1024;
|
|
3
|
+
/** Max redirect hops guardedFetch will follow, re-validating each target. */
|
|
4
|
+
const MAX_REDIRECTS = 5;
|
|
3
5
|
/**
|
|
4
|
-
* Reject requests to non-public destinations.
|
|
5
|
-
* (loopback / private / link-local / cloud-metadata)
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* Reject requests to non-public destinations. A synchronous literal-host guard
|
|
7
|
+
* (loopback / private / link-local / cloud-metadata) that also rejects
|
|
8
|
+
* alternate numeric IP encodings which would slip past the literal checks but
|
|
9
|
+
* still connect to a real address. No DNS lookup - a public hostname that
|
|
10
|
+
* *resolves* to private space (DNS rebinding) is a residual this doesn't cover;
|
|
11
|
+
* doing so would add a per-request lookup that can hang for 30s on an
|
|
12
|
+
* unresolvable host. Returns an error string, or null when the URL is allowed.
|
|
8
13
|
*/
|
|
9
14
|
export function blockedNetTarget(rawUrl) {
|
|
10
15
|
let u;
|
|
@@ -21,6 +26,13 @@ export function blockedNetTarget(rawUrl) {
|
|
|
21
26
|
return 'blocked host: localhost';
|
|
22
27
|
if (isPrivateIp(host))
|
|
23
28
|
return `blocked host: ${host}`;
|
|
29
|
+
// Reject alternate numeric encodings of an IP that pass the literal checks but
|
|
30
|
+
// still reach a real address - http://2130706433 and http://0x7f000001 both
|
|
31
|
+
// connect to 127.0.0.1. A genuine DNS name contains a letter and is not
|
|
32
|
+
// 0x-prefixed; dotted-IPv4 and IPv6 literals were already checked above.
|
|
33
|
+
if (!host.includes(':') && !/^\d{1,3}(\.\d{1,3}){3}$/.test(host) && (host.startsWith('0x') || !/[a-z]/i.test(host))) {
|
|
34
|
+
return `blocked host: ${host} (non-DNS address encoding)`;
|
|
35
|
+
}
|
|
24
36
|
return null;
|
|
25
37
|
}
|
|
26
38
|
function isPrivateIp(host) {
|
|
@@ -49,6 +61,32 @@ function isPrivateIp(host) {
|
|
|
49
61
|
return isPrivateIp(host.slice(7)); // IPv4-mapped
|
|
50
62
|
return false;
|
|
51
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* fetch with an SSRF guard that re-validates every redirect hop. Default fetch
|
|
66
|
+
* follows redirects without re-checking, so a public URL could 3xx into private
|
|
67
|
+
* space; this follows manually (capped at {@link MAX_REDIRECTS}) and runs
|
|
68
|
+
* {@link blockedNetTarget} on each target. Throws with the block reason on a
|
|
69
|
+
* rejected hop.
|
|
70
|
+
*/
|
|
71
|
+
export async function guardedFetch(fetchImpl, url, init = {}) {
|
|
72
|
+
let current = url;
|
|
73
|
+
for (let hop = 0; hop <= MAX_REDIRECTS; hop++) {
|
|
74
|
+
const blocked = blockedNetTarget(current);
|
|
75
|
+
if (blocked)
|
|
76
|
+
throw new Error(blocked);
|
|
77
|
+
const res = await fetchImpl(current, { ...init, redirect: 'manual' });
|
|
78
|
+
const location = res.status >= 300 && res.status < 400 ? res.headers.get('location') : null;
|
|
79
|
+
if (!location)
|
|
80
|
+
return res;
|
|
81
|
+
current = new URL(location, current).toString();
|
|
82
|
+
}
|
|
83
|
+
throw new Error(`too many redirects (>${MAX_REDIRECTS})`);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Drains net.http_request_queue on an interval, performs each request, and
|
|
87
|
+
* records the reply in net._http_response - the pg_net background worker,
|
|
88
|
+
* in-process.
|
|
89
|
+
*/
|
|
52
90
|
export class NetService {
|
|
53
91
|
db;
|
|
54
92
|
fetchImpl;
|
|
@@ -56,6 +94,8 @@ export class NetService {
|
|
|
56
94
|
onDeliver;
|
|
57
95
|
timer = null;
|
|
58
96
|
draining = false;
|
|
97
|
+
/** The in-flight tick, tracked so stop() can drain it before db.close(). */
|
|
98
|
+
inFlight = null;
|
|
59
99
|
constructor(db, fetchImpl = fetch,
|
|
60
100
|
/** how often to drain the queue (ms) */
|
|
61
101
|
tickMs = 500, onDeliver) {
|
|
@@ -64,22 +104,32 @@ export class NetService {
|
|
|
64
104
|
this.tickMs = tickMs;
|
|
65
105
|
this.onDeliver = onDeliver;
|
|
66
106
|
}
|
|
107
|
+
/** Begin draining the queue on the tick interval; no-op if already running. */
|
|
67
108
|
start() {
|
|
68
109
|
if (this.timer)
|
|
69
110
|
return;
|
|
70
|
-
this.timer = setInterval(() =>
|
|
111
|
+
this.timer = setInterval(() => {
|
|
112
|
+
this.inFlight = this.tick();
|
|
113
|
+
}, this.tickMs);
|
|
71
114
|
if (typeof this.timer === 'object' && 'unref' in this.timer)
|
|
72
115
|
this.timer.unref();
|
|
73
116
|
}
|
|
74
|
-
|
|
117
|
+
/**
|
|
118
|
+
* Stop the drain loop and wait for any in-flight tick to finish before the
|
|
119
|
+
* caller closes the database - the single connection busy-loops if closed
|
|
120
|
+
* while a query is still queued.
|
|
121
|
+
*/
|
|
122
|
+
async stop() {
|
|
75
123
|
if (this.timer)
|
|
76
124
|
clearInterval(this.timer);
|
|
77
125
|
this.timer = null;
|
|
126
|
+
await this.inFlight?.catch(() => { });
|
|
127
|
+
this.inFlight = null;
|
|
78
128
|
}
|
|
79
129
|
/** Drain any queued requests once (also callable directly in tests). */
|
|
80
130
|
async tick() {
|
|
81
131
|
if (this.draining)
|
|
82
|
-
return; // never overlap drains
|
|
132
|
+
return; // never overlap drains - one writer at a time
|
|
83
133
|
this.draining = true;
|
|
84
134
|
try {
|
|
85
135
|
let rows;
|
|
@@ -89,8 +139,18 @@ export class NetService {
|
|
|
89
139
|
catch {
|
|
90
140
|
return; // net.* not present (e.g. the pg-mem subset engine)
|
|
91
141
|
}
|
|
92
|
-
for (const row of rows)
|
|
93
|
-
|
|
142
|
+
for (const row of rows) {
|
|
143
|
+
try {
|
|
144
|
+
await this.deliver(row);
|
|
145
|
+
}
|
|
146
|
+
catch (e) {
|
|
147
|
+
// A malformed row must never poison the loop or reject out of the
|
|
148
|
+
// setInterval callback - dequeue it with the error recorded instead.
|
|
149
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
150
|
+
await this.record(row.id, null, null, null, null, false, msg);
|
|
151
|
+
this.onDeliver?.({ id: row.id, method: row.method, url: row.url, timedOut: false, error: msg });
|
|
152
|
+
}
|
|
153
|
+
}
|
|
94
154
|
}
|
|
95
155
|
finally {
|
|
96
156
|
this.draining = false;
|
|
@@ -106,16 +166,11 @@ export class NetService {
|
|
|
106
166
|
let respHeaders = null;
|
|
107
167
|
let timedOut = false;
|
|
108
168
|
let errorMsg = null;
|
|
109
|
-
const blocked = blockedNetTarget(row.url);
|
|
110
|
-
if (blocked) {
|
|
111
|
-
clearTimeout(timer);
|
|
112
|
-
await this.record(row.id, null, null, null, content, false, blocked);
|
|
113
|
-
this.onDeliver?.({ id: row.id, method: row.method, url: row.url, timedOut: false, error: blocked });
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
169
|
try {
|
|
117
170
|
const hasBody = row.method !== 'GET' && row.method !== 'HEAD';
|
|
118
|
-
|
|
171
|
+
// guardedFetch enforces the SSRF policy on the initial URL and every
|
|
172
|
+
// redirect hop (a plain fetch would follow a 3xx into private space).
|
|
173
|
+
const res = await guardedFetch(this.fetchImpl, row.url, {
|
|
119
174
|
method: row.method,
|
|
120
175
|
headers,
|
|
121
176
|
body: hasBody ? row.body ?? undefined : undefined,
|
package/dist/net/service.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/net/service.ts"],"names":[],"mappings":"AASA,0EAA0E;AAC1E,MAAM,kBAAkB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAA;AAE3C
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/net/service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Bun-native server: Bun.serve with first-class WebSockets. Used automatically
|
|
3
|
-
* when the CLI runs under Bun (including single-binary builds)
|
|
3
|
+
* when the CLI runs under Bun (including single-binary builds) - same backend,
|
|
4
4
|
* same RealtimeSocketLike contract as the node:http path.
|
|
5
5
|
*/
|
|
6
6
|
import type { SupaliteBackendShape } from './server-shared.js';
|
|
7
7
|
import type { RunningServer, ServeOptions } from './server.js';
|
|
8
|
+
/** Bun equivalent of {@link import('./server.js').serve}; same backend contract. */
|
|
8
9
|
export declare function serveBun(backend: SupaliteBackendShape, opts?: ServeOptions): Promise<RunningServer>;
|
package/dist/node/bun-server.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/** Bun equivalent of {@link import('./server.js').serve}; same backend contract. */
|
|
1
2
|
export async function serveBun(backend, opts = {}) {
|
|
2
3
|
const host = opts.host ?? '127.0.0.1';
|
|
3
4
|
const server = Bun.serve({
|
|
@@ -11,7 +12,16 @@ export async function serveBun(backend, opts = {}) {
|
|
|
11
12
|
return undefined;
|
|
12
13
|
return new Response('upgrade failed', { status: 400 });
|
|
13
14
|
}
|
|
14
|
-
|
|
15
|
+
// Expose the connecting client's address for rate limiting, stripping any
|
|
16
|
+
// client-supplied value first so the header can't be forged - the node:http
|
|
17
|
+
// server does the same from req.socket.remoteAddress. Without this, a
|
|
18
|
+
// spoofed x-tinbase-remote-addr rotated per request defeats the limiter.
|
|
19
|
+
const headers = new Headers(req.headers);
|
|
20
|
+
headers.delete('x-tinbase-remote-addr');
|
|
21
|
+
const ip = srv.requestIP(req)?.address;
|
|
22
|
+
if (ip)
|
|
23
|
+
headers.set('x-tinbase-remote-addr', ip);
|
|
24
|
+
return backend.fetch(new Request(req, { headers }));
|
|
15
25
|
},
|
|
16
26
|
websocket: {
|
|
17
27
|
open(ws) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bun-server.js","sourceRoot":"","sources":["../../src/node/bun-server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bun-server.js","sourceRoot":"","sources":["../../src/node/bun-server.ts"],"names":[],"mappings":"AAiBA,oFAAoF;AACpF,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,OAA6B,EAAE,OAAqB,EAAE;IACnF,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,WAAW,CAAA;IAErC,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC;QACvB,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,KAAK;QACxB,QAAQ,EAAE,IAAI;QACd,KAAK,CAAC,KAAK,CAAC,GAAY,EAAE,GAAQ;YAChC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YAC5B,IAAI,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,cAAc,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,CAAC;gBACzG,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,OAAO,EAAE,EAAE,CAAC,CAAA;gBACtF,IAAI,EAAE;oBAAE,OAAO,SAAS,CAAA;gBACxB,OAAO,IAAI,QAAQ,CAAC,gBAAgB,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;YACxD,CAAC;YACD,0EAA0E;YAC1E,4EAA4E;YAC5E,sEAAsE;YACtE,yEAAyE;YACzE,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;YACxC,OAAO,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAA;YACvC,MAAM,EAAE,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,OAAO,CAAA;YACtC,IAAI,EAAE;gBAAE,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,EAAE,CAAC,CAAA;YAChD,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,CAAA;QACrD,CAAC;QACD,SAAS,EAAE;YACT,IAAI,CAAC,EAA6F;gBAChG,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,CACtC;oBACE,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;oBAC7B,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC;iBAChD,EACD,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CACrB,CAAA;gBACD,EAAE,CAAC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;YAC3B,CAAC;YACD,OAAO,CAAC,EAAoB,EAAE,OAA4B;gBACxD,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC,CAAA;YAC7F,CAAC;YACD,KAAK,CAAC,EAAoB;gBACxB,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,CAAA;YAC5B,CAAC;SACF;KACF,CAAC,CAAA;IAEF,OAAO;QACL,MAAM,EAAE,MAAe;QACvB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,GAAG,EAAE,UAAU,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE;QACpC,KAAK,EAAE,KAAK,IAAI,EAAE;YAChB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACnB,CAAC;KACF,CAAA;AACH,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Map a Deno-style specifier to a fetchable URL. Pure
|
|
1
|
+
/** Map a Deno-style specifier to a fetchable URL. Pure - unit tested. */
|
|
2
2
|
export declare function rewriteRemoteSpecifier(spec: string): string;
|
|
3
3
|
/**
|
|
4
4
|
* Bundle `entryPath` to a single ESM file and return its path (written under
|
|
@@ -15,7 +15,7 @@ import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
|
15
15
|
import { existsSync } from 'node:fs';
|
|
16
16
|
import { tmpdir } from 'node:os';
|
|
17
17
|
import { join } from 'node:path';
|
|
18
|
-
/** Map a Deno-style specifier to a fetchable URL. Pure
|
|
18
|
+
/** Map a Deno-style specifier to a fetchable URL. Pure - unit tested. */
|
|
19
19
|
export function rewriteRemoteSpecifier(spec) {
|
|
20
20
|
if (spec.startsWith('npm:'))
|
|
21
21
|
return `https://esm.sh/${spec.slice(4)}`;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** A parsed table: its scalar/array values plus nested child tables. */
|
|
2
|
+
export interface ConfigTable {
|
|
3
|
+
/** scalar and single-line-array values declared directly under this table, by key */
|
|
4
|
+
values: Map<string, string | string[]>;
|
|
5
|
+
/** nested child tables, by their (single, undotted) segment name */
|
|
6
|
+
children: Map<string, ConfigTable>;
|
|
7
|
+
}
|
|
8
|
+
/** Parse config.toml at `projectDir/supabase/config.toml`; empty root if absent/unreadable. */
|
|
9
|
+
export declare function loadConfigToml(projectDir: string, env?: NodeJS.ProcessEnv): ConfigTable;
|
|
10
|
+
/** Parse TOML `text` into a table tree, resolving `env(VAR)` references. */
|
|
11
|
+
export declare function parseConfigToml(text: string, env?: NodeJS.ProcessEnv): ConfigTable;
|
|
12
|
+
/** Child table at a dotted path, or undefined if any segment is missing. */
|
|
13
|
+
export declare function tableAt(root: ConfigTable, path: string): ConfigTable | undefined;
|
|
14
|
+
/** String value at `key`, or undefined if absent, empty, or an array. */
|
|
15
|
+
export declare function getString(table: ConfigTable | undefined, key: string): string | undefined;
|
|
16
|
+
/** Boolean value at `key`, or undefined if absent or not exactly true/false. */
|
|
17
|
+
export declare function getBool(table: ConfigTable | undefined, key: string): boolean | undefined;
|
|
18
|
+
/** Integer value at `key` (base 10), or undefined if absent or unparseable. */
|
|
19
|
+
export declare function getInt(table: ConfigTable | undefined, key: string): number | undefined;
|
|
20
|
+
/** String-array value at `key`, or undefined if absent or a scalar. */
|
|
21
|
+
export declare function getStringArray(table: ConfigTable | undefined, key: string): string[] | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Parse a Supabase duration string ("1m", "24h", "10s", "50m") to seconds.
|
|
24
|
+
* Returns undefined if absent or malformed.
|
|
25
|
+
*/
|
|
26
|
+
export declare function getDurationSeconds(table: ConfigTable | undefined, key: string): number | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* Parse a Supabase byte-size string ("50MiB", "5MB", "500KB") to bytes.
|
|
29
|
+
* Returns undefined if absent or malformed.
|
|
30
|
+
*/
|
|
31
|
+
export declare function getByteSize(table: ConfigTable | undefined, key: string): number | undefined;
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A minimal TOML reader for supabase/config.toml - just enough of the format to
|
|
3
|
+
* read a real Supabase project's settings, without a TOML dependency. It handles
|
|
4
|
+
* the subset config.toml actually uses:
|
|
5
|
+
*
|
|
6
|
+
* - `[section]` and dotted `[section.sub.name]` table headers
|
|
7
|
+
* - `key = value` scalars (string, bool, integer)
|
|
8
|
+
* - single-line string arrays: `key = ["a", "b"]`
|
|
9
|
+
* - `#` line and inline comments
|
|
10
|
+
* - `env(VAR)` substitution against process.env (or a provided env)
|
|
11
|
+
*
|
|
12
|
+
* It does NOT handle inline tables (`{ a = 1 }`), multi-line arrays, or dotted
|
|
13
|
+
* keys inside a table body - none of which config.toml uses for the settings we
|
|
14
|
+
* read. Each loader (auth, api, storage, functions, oauth) reads from the one
|
|
15
|
+
* parsed tree instead of re-scanning the file.
|
|
16
|
+
*/
|
|
17
|
+
import { readFileSync } from 'node:fs';
|
|
18
|
+
import { join } from 'node:path';
|
|
19
|
+
function emptyTable() {
|
|
20
|
+
return { values: new Map(), children: new Map() };
|
|
21
|
+
}
|
|
22
|
+
/** Parse config.toml at `projectDir/supabase/config.toml`; empty root if absent/unreadable. */
|
|
23
|
+
export function loadConfigToml(projectDir, env = process.env) {
|
|
24
|
+
let text;
|
|
25
|
+
try {
|
|
26
|
+
text = readFileSync(join(projectDir, 'supabase', 'config.toml'), 'utf8');
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return emptyTable();
|
|
30
|
+
}
|
|
31
|
+
return parseConfigToml(text, env);
|
|
32
|
+
}
|
|
33
|
+
/** Parse TOML `text` into a table tree, resolving `env(VAR)` references. */
|
|
34
|
+
export function parseConfigToml(text, env = process.env) {
|
|
35
|
+
const root = emptyTable();
|
|
36
|
+
let current = root;
|
|
37
|
+
for (const rawLine of text.split('\n')) {
|
|
38
|
+
const line = stripComment(rawLine).trim();
|
|
39
|
+
if (!line)
|
|
40
|
+
continue;
|
|
41
|
+
const header = line.match(/^\[([^\]]+)\]$/);
|
|
42
|
+
if (header) {
|
|
43
|
+
current = descend(root, header[1].split('.').map((s) => s.trim()));
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
const kv = line.match(/^([A-Za-z0-9_]+)\s*=\s*(.+)$/);
|
|
47
|
+
if (!kv)
|
|
48
|
+
continue;
|
|
49
|
+
const value = parseValue(kv[2].trim(), env);
|
|
50
|
+
if (value !== undefined)
|
|
51
|
+
current.values.set(kv[1], value);
|
|
52
|
+
}
|
|
53
|
+
return root;
|
|
54
|
+
}
|
|
55
|
+
/** Walk/create the table at the given dotted path. */
|
|
56
|
+
function descend(root, path) {
|
|
57
|
+
let t = root;
|
|
58
|
+
for (const key of path) {
|
|
59
|
+
let next = t.children.get(key);
|
|
60
|
+
if (!next) {
|
|
61
|
+
next = emptyTable();
|
|
62
|
+
t.children.set(key, next);
|
|
63
|
+
}
|
|
64
|
+
t = next;
|
|
65
|
+
}
|
|
66
|
+
return t;
|
|
67
|
+
}
|
|
68
|
+
/** Remove a `#` comment that isn't inside a quoted string. */
|
|
69
|
+
function stripComment(line) {
|
|
70
|
+
let quote = null;
|
|
71
|
+
for (let i = 0; i < line.length; i++) {
|
|
72
|
+
const c = line[i];
|
|
73
|
+
if (quote) {
|
|
74
|
+
if (c === quote)
|
|
75
|
+
quote = null;
|
|
76
|
+
}
|
|
77
|
+
else if (c === '"' || c === "'") {
|
|
78
|
+
quote = c;
|
|
79
|
+
}
|
|
80
|
+
else if (c === '#') {
|
|
81
|
+
return line.slice(0, i);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return line;
|
|
85
|
+
}
|
|
86
|
+
/** Parse a scalar or single-line array value, resolving env() and stripping quotes. */
|
|
87
|
+
function parseValue(raw, env) {
|
|
88
|
+
if (raw.startsWith('[') && raw.endsWith(']')) {
|
|
89
|
+
const inner = raw.slice(1, -1).trim();
|
|
90
|
+
if (inner === '')
|
|
91
|
+
return [];
|
|
92
|
+
return inner
|
|
93
|
+
.split(',')
|
|
94
|
+
.map((s) => resolveScalar(s.trim(), env))
|
|
95
|
+
.filter((s) => s !== undefined && s !== '');
|
|
96
|
+
}
|
|
97
|
+
return resolveScalar(raw, env);
|
|
98
|
+
}
|
|
99
|
+
/** Strip quotes and expand an `env(VAR)` reference to its value. */
|
|
100
|
+
function resolveScalar(raw, env) {
|
|
101
|
+
const v = raw.trim().replace(/^["']|["']$/g, '');
|
|
102
|
+
const m = v.match(/^env\(\s*"?([A-Za-z0-9_]+)"?\s*\)$/);
|
|
103
|
+
if (m)
|
|
104
|
+
return env[m[1]];
|
|
105
|
+
return v;
|
|
106
|
+
}
|
|
107
|
+
// ── typed accessors ───────────────────────────────────────────────────────
|
|
108
|
+
/** Child table at a dotted path, or undefined if any segment is missing. */
|
|
109
|
+
export function tableAt(root, path) {
|
|
110
|
+
let t = root;
|
|
111
|
+
for (const key of path.split('.')) {
|
|
112
|
+
t = t?.children.get(key);
|
|
113
|
+
if (!t)
|
|
114
|
+
return undefined;
|
|
115
|
+
}
|
|
116
|
+
return t;
|
|
117
|
+
}
|
|
118
|
+
/** String value at `key`, or undefined if absent, empty, or an array. */
|
|
119
|
+
export function getString(table, key) {
|
|
120
|
+
const v = table?.values.get(key);
|
|
121
|
+
return typeof v === 'string' && v !== '' ? v : undefined;
|
|
122
|
+
}
|
|
123
|
+
/** Boolean value at `key`, or undefined if absent or not exactly true/false. */
|
|
124
|
+
export function getBool(table, key) {
|
|
125
|
+
const v = table?.values.get(key);
|
|
126
|
+
if (v === 'true')
|
|
127
|
+
return true;
|
|
128
|
+
if (v === 'false')
|
|
129
|
+
return false;
|
|
130
|
+
return undefined;
|
|
131
|
+
}
|
|
132
|
+
/** Integer value at `key` (base 10), or undefined if absent or unparseable. */
|
|
133
|
+
export function getInt(table, key) {
|
|
134
|
+
const v = table?.values.get(key);
|
|
135
|
+
if (typeof v !== 'string')
|
|
136
|
+
return undefined;
|
|
137
|
+
const n = parseInt(v, 10);
|
|
138
|
+
return Number.isFinite(n) ? n : undefined;
|
|
139
|
+
}
|
|
140
|
+
/** String-array value at `key`, or undefined if absent or a scalar. */
|
|
141
|
+
export function getStringArray(table, key) {
|
|
142
|
+
const v = table?.values.get(key);
|
|
143
|
+
return Array.isArray(v) ? v : undefined;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Parse a Supabase duration string ("1m", "24h", "10s", "50m") to seconds.
|
|
147
|
+
* Returns undefined if absent or malformed.
|
|
148
|
+
*/
|
|
149
|
+
export function getDurationSeconds(table, key) {
|
|
150
|
+
const v = table?.values.get(key);
|
|
151
|
+
if (typeof v !== 'string')
|
|
152
|
+
return undefined;
|
|
153
|
+
const m = v.trim().match(/^(\d+)\s*(s|m|h)$/i);
|
|
154
|
+
if (!m) {
|
|
155
|
+
const n = parseInt(v, 10);
|
|
156
|
+
return Number.isFinite(n) ? n : undefined;
|
|
157
|
+
}
|
|
158
|
+
const n = parseInt(m[1], 10);
|
|
159
|
+
const unit = m[2].toLowerCase();
|
|
160
|
+
return unit === 'h' ? n * 3600 : unit === 'm' ? n * 60 : n;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Parse a Supabase byte-size string ("50MiB", "5MB", "500KB") to bytes.
|
|
164
|
+
* Returns undefined if absent or malformed.
|
|
165
|
+
*/
|
|
166
|
+
export function getByteSize(table, key) {
|
|
167
|
+
const v = table?.values.get(key);
|
|
168
|
+
if (typeof v !== 'string')
|
|
169
|
+
return undefined;
|
|
170
|
+
const m = v.trim().match(/^(\d+(?:\.\d+)?)\s*(b|kb|kib|mb|mib|gb|gib)?$/i);
|
|
171
|
+
if (!m)
|
|
172
|
+
return undefined;
|
|
173
|
+
const n = parseFloat(m[1]);
|
|
174
|
+
const unit = (m[2] ?? 'b').toLowerCase();
|
|
175
|
+
const mult = {
|
|
176
|
+
b: 1,
|
|
177
|
+
kb: 1000,
|
|
178
|
+
kib: 1024,
|
|
179
|
+
mb: 1000 * 1000,
|
|
180
|
+
mib: 1024 * 1024,
|
|
181
|
+
gb: 1000 * 1000 * 1000,
|
|
182
|
+
gib: 1024 * 1024 * 1024,
|
|
183
|
+
};
|
|
184
|
+
return Math.round(n * (mult[unit] ?? 1));
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=config-toml.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-toml.js","sourceRoot":"","sources":["../../src/node/config-toml.ts"],"names":[],"mappings":"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"}
|
package/dist/node/db-diff.d.ts
CHANGED
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
import type { MigrationFile } from '../types.js';
|
|
2
|
+
/** Inputs for {@link computeDbDiff}: how to reach the live db plus the migrations that define the shadow. */
|
|
2
3
|
export interface DbDiffOptions {
|
|
3
4
|
/** the live project's data dir (wasm) or undefined when a native engine is passed */
|
|
4
5
|
liveDataDir?: string;
|
|
6
|
+
/** an already-open live engine; takes precedence over `liveDataDir` when set */
|
|
5
7
|
liveEngine?: import('../db/engine.js').DbEngine;
|
|
8
|
+
/** migrations applied to both the shadow and (as pending) the live db before diffing */
|
|
6
9
|
migrations: MigrationFile[];
|
|
10
|
+
/** ignored for diffing (seed is data, not schema); accepted so callers can pass one options bag */
|
|
7
11
|
seedSql?: string;
|
|
12
|
+
/** schema to diff; defaults to 'public' */
|
|
8
13
|
schema?: string;
|
|
9
14
|
/** factory for the shadow engine (native mode); omit for wasm/in-memory shadow */
|
|
10
15
|
makeShadowEngine?: () => Promise<import('../db/engine.js').DbEngine>;
|
|
11
16
|
}
|
|
17
|
+
/** Compute the DDL delta from the migrations-only shadow db to the current live schema. */
|
|
12
18
|
export declare function computeDbDiff(opts: DbDiffOptions): Promise<string[]>;
|
|
19
|
+
/** Fresh throwaway data dir for a native-engine shadow database, under the OS temp dir. */
|
|
13
20
|
export declare function shadowNativeDataDir(): string;
|
|
21
|
+
/** Inputs for {@link pullSchema}: everything {@link DbDiffOptions} needs plus where/how to write the migration. */
|
|
14
22
|
export interface DbPullOptions extends DbDiffOptions {
|
|
15
23
|
/** directory to write the migration into (usually supabase/migrations); omit to skip writing */
|
|
16
24
|
migrationsDir?: string;
|
|
@@ -19,14 +27,18 @@ export interface DbPullOptions extends DbDiffOptions {
|
|
|
19
27
|
/** timestamp version prefix; pass for determinism (default: now as YYYYMMDDHHMMSS) */
|
|
20
28
|
stamp?: string;
|
|
21
29
|
}
|
|
30
|
+
/** Outcome of a {@link pullSchema} run. */
|
|
22
31
|
export interface DbPullResult {
|
|
32
|
+
/** the diffed DDL statements; empty when live and migrations already match */
|
|
23
33
|
ddl: string[];
|
|
34
|
+
/** timestamp version recorded for the written migration, or null when nothing was written */
|
|
24
35
|
version: string | null;
|
|
36
|
+
/** path of the written migration file, or null when `migrationsDir` was omitted or ddl was empty */
|
|
25
37
|
path: string | null;
|
|
26
38
|
}
|
|
27
39
|
/**
|
|
28
40
|
* `tinbase db pull` core: like `db diff`, but writes the delta as a migration
|
|
29
|
-
* AND records it as already-applied on the live database
|
|
41
|
+
* AND records it as already-applied on the live database - the schema is
|
|
30
42
|
* already there, so a subsequent `tinbase start` must not re-run it. This is
|
|
31
43
|
* how you bring an out-of-migration (or externally-created) schema under
|
|
32
44
|
* version control.
|
package/dist/node/db-diff.js
CHANGED
|
@@ -10,6 +10,7 @@ import { tmpdir } from 'node:os';
|
|
|
10
10
|
import { join } from 'node:path';
|
|
11
11
|
import { createBackend } from '../index.js';
|
|
12
12
|
import { snapshotSchema, diffSchemas } from '../db/schema-diff.js';
|
|
13
|
+
/** Compute the DDL delta from the migrations-only shadow db to the current live schema. */
|
|
13
14
|
export async function computeDbDiff(opts) {
|
|
14
15
|
const schema = opts.schema ?? 'public';
|
|
15
16
|
// shadow = migrations only, fresh
|
|
@@ -35,12 +36,13 @@ export async function computeDbDiff(opts) {
|
|
|
35
36
|
await live.close();
|
|
36
37
|
}
|
|
37
38
|
}
|
|
39
|
+
/** Fresh throwaway data dir for a native-engine shadow database, under the OS temp dir. */
|
|
38
40
|
export function shadowNativeDataDir() {
|
|
39
41
|
return join(mkdtempSync(join(tmpdir(), 'tinbase-shadow-')), 'pg');
|
|
40
42
|
}
|
|
41
43
|
/**
|
|
42
44
|
* `tinbase db pull` core: like `db diff`, but writes the delta as a migration
|
|
43
|
-
* AND records it as already-applied on the live database
|
|
45
|
+
* AND records it as already-applied on the live database - the schema is
|
|
44
46
|
* already there, so a subsequent `tinbase start` must not re-run it. This is
|
|
45
47
|
* how you bring an out-of-migration (or externally-created) schema under
|
|
46
48
|
* version control.
|
package/dist/node/db-diff.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db-diff.js","sourceRoot":"","sources":["../../src/node/db-diff.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACrC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,aAAa,EAAuB,MAAM,aAAa,CAAA;AAChE,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"db-diff.js","sourceRoot":"","sources":["../../src/node/db-diff.ts"],"names":[],"mappings":"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"}
|
package/dist/node/fs-driver.d.ts
CHANGED
|
@@ -1,11 +1,26 @@
|
|
|
1
1
|
import type { StorageDriver } from '../types.js';
|
|
2
|
-
/**
|
|
2
|
+
/**
|
|
3
|
+
* Node-only {@link StorageDriver} that keeps object bytes as files under a
|
|
4
|
+
* single root directory. Keys map to relative paths beneath the root.
|
|
5
|
+
*/
|
|
3
6
|
export declare class FsStorageDriver implements StorageDriver {
|
|
4
7
|
private root;
|
|
5
8
|
constructor(root: string);
|
|
9
|
+
/**
|
|
10
|
+
* Resolve a storage key to an absolute path inside the root.
|
|
11
|
+
*
|
|
12
|
+
* SECURITY: rejects keys that escape the root (e.g. `../`); the normalized
|
|
13
|
+
* path must stay under `root` + separator or the key is refused.
|
|
14
|
+
*
|
|
15
|
+
* @throws if the key would resolve outside the root directory.
|
|
16
|
+
*/
|
|
6
17
|
private resolve;
|
|
18
|
+
/** Write object bytes, creating parent directories as needed. */
|
|
7
19
|
put(key: string, data: Uint8Array): Promise<void>;
|
|
20
|
+
/** Read object bytes, or null if the key does not exist. */
|
|
8
21
|
get(key: string): Promise<Uint8Array | null>;
|
|
22
|
+
/** Delete an object; a missing key is not an error. */
|
|
9
23
|
delete(key: string): Promise<void>;
|
|
24
|
+
/** Delete several objects in sequence. */
|
|
10
25
|
deleteMany(keys: string[]): Promise<void>;
|
|
11
26
|
}
|