bunderstack 0.17.0-beta.2 → 0.17.0-beta.4
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 +233 -0
- package/README.md +11 -1
- package/dist/access.d.ts +116 -0
- package/dist/access.d.ts.map +1 -0
- package/dist/access.js +325 -0
- package/dist/access.js.map +1 -0
- package/dist/api/builder.d.ts +145 -0
- package/dist/api/builder.d.ts.map +1 -0
- package/dist/api/builder.js +28 -0
- package/dist/api/builder.js.map +1 -0
- package/dist/api/context.d.ts +34 -0
- package/dist/api/context.d.ts.map +1 -0
- package/dist/api/context.js +32 -0
- package/dist/api/context.js.map +1 -0
- package/dist/api/crud-router.d.ts +290 -0
- package/dist/api/crud-router.d.ts.map +1 -0
- package/dist/api/crud-router.js +249 -0
- package/dist/api/crud-router.js.map +1 -0
- package/dist/api/openapi.d.ts +6 -0
- package/dist/api/openapi.d.ts.map +1 -0
- package/dist/api/openapi.js +146 -0
- package/dist/api/openapi.js.map +1 -0
- package/dist/api/realtime-router.d.ts +76 -0
- package/dist/api/realtime-router.d.ts.map +1 -0
- package/dist/api/realtime-router.js +41 -0
- package/dist/api/realtime-router.js.map +1 -0
- package/dist/api/registry.d.ts +30 -0
- package/dist/api/registry.d.ts.map +1 -0
- package/dist/api/registry.js +239 -0
- package/dist/api/registry.js.map +1 -0
- package/dist/api/router.d.ts +9 -0
- package/dist/api/router.d.ts.map +1 -0
- package/dist/api/router.js +19 -0
- package/dist/api/router.js.map +1 -0
- package/dist/api/storage-router.d.ts +279 -0
- package/dist/api/storage-router.d.ts.map +1 -0
- package/dist/api/storage-router.js +155 -0
- package/dist/api/storage-router.js.map +1 -0
- package/dist/api/types.d.ts +55 -0
- package/dist/api/types.d.ts.map +1 -0
- package/dist/api/types.js +2 -0
- package/dist/api/types.js.map +1 -0
- package/dist/auth.d.ts +31 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +102 -0
- package/dist/auth.js.map +1 -0
- package/dist/blueprint-generator.d.ts +18 -0
- package/dist/blueprint-generator.d.ts.map +1 -0
- package/dist/blueprint-generator.js +125 -0
- package/dist/blueprint-generator.js.map +1 -0
- package/dist/blueprint.d.ts +46 -0
- package/dist/blueprint.d.ts.map +1 -0
- package/dist/blueprint.js +162 -0
- package/dist/blueprint.js.map +1 -0
- package/dist/cli.d.ts +8 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +68 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +108 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +90 -0
- package/dist/config.js.map +1 -0
- package/dist/cron.d.ts +4 -0
- package/dist/cron.d.ts.map +1 -0
- package/dist/cron.js +3 -0
- package/dist/cron.js.map +1 -0
- package/dist/crud-operations.d.ts +43 -0
- package/dist/crud-operations.d.ts.map +1 -0
- package/dist/crud-operations.js +238 -0
- package/dist/crud-operations.js.map +1 -0
- package/dist/database/adapter.d.ts +20 -0
- package/dist/database/adapter.d.ts.map +1 -0
- package/dist/database/adapter.js +2 -0
- package/dist/database/adapter.js.map +1 -0
- package/dist/database/bun-sql.d.ts +3 -0
- package/dist/database/bun-sql.d.ts.map +1 -0
- package/dist/database/bun-sql.js +21 -0
- package/dist/database/bun-sql.js.map +1 -0
- package/dist/database/libsql.d.ts +3 -0
- package/dist/database/libsql.d.ts.map +1 -0
- package/dist/database/libsql.js +22 -0
- package/dist/database/libsql.js.map +1 -0
- package/dist/database/pglite.d.ts +3 -0
- package/dist/database/pglite.d.ts.map +1 -0
- package/dist/database/pglite.js +27 -0
- package/dist/database/pglite.js.map +1 -0
- package/dist/database/postgres-js.d.ts +3 -0
- package/dist/database/postgres-js.d.ts.map +1 -0
- package/dist/database/postgres-js.js +21 -0
- package/dist/database/postgres-js.js.map +1 -0
- package/dist/db.d.ts +18 -0
- package/dist/db.d.ts.map +1 -0
- package/dist/db.js +26 -0
- package/dist/db.js.map +1 -0
- package/dist/dialect.d.ts +17 -0
- package/dist/dialect.d.ts.map +1 -0
- package/dist/dialect.js +22 -0
- package/dist/dialect.js.map +1 -0
- package/dist/email/smtp.d.ts +14 -0
- package/dist/email/smtp.d.ts.map +1 -0
- package/dist/email/smtp.js +27 -0
- package/dist/email/smtp.js.map +1 -0
- package/dist/email.d.ts +39 -0
- package/dist/email.d.ts.map +1 -0
- package/dist/email.js +97 -0
- package/dist/email.js.map +1 -0
- package/dist/env.d.ts +47 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +99 -0
- package/dist/env.js.map +1 -0
- package/dist/errors.d.ts +125 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +92 -0
- package/dist/errors.js.map +1 -0
- package/dist/handler.d.ts +9 -0
- package/dist/handler.d.ts.map +1 -0
- package/dist/handler.js +22 -0
- package/dist/handler.js.map +1 -0
- package/dist/idempotency.d.ts +17 -0
- package/dist/idempotency.d.ts.map +1 -0
- package/dist/idempotency.js +65 -0
- package/dist/idempotency.js.map +1 -0
- package/dist/index.d.ts +134 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +480 -0
- package/dist/index.js.map +1 -0
- package/dist/internal-tables-pg.d.ts +481 -0
- package/dist/internal-tables-pg.d.ts.map +1 -0
- package/{src/internal-tables-pg.ts → dist/internal-tables-pg.js} +10 -34
- package/dist/internal-tables-pg.js.map +1 -0
- package/dist/internal-tables.d.ts +2509 -0
- package/dist/internal-tables.d.ts.map +1 -0
- package/dist/internal-tables.js +108 -0
- package/dist/internal-tables.js.map +1 -0
- package/dist/jobs/cron.d.ts +15 -0
- package/dist/jobs/cron.d.ts.map +1 -0
- package/dist/jobs/cron.js +74 -0
- package/dist/jobs/cron.js.map +1 -0
- package/dist/jobs/define.d.ts +133 -0
- package/dist/jobs/define.d.ts.map +1 -0
- package/dist/jobs/define.js +74 -0
- package/dist/jobs/define.js.map +1 -0
- package/dist/jobs/index.d.ts +11 -0
- package/dist/jobs/index.d.ts.map +1 -0
- package/dist/jobs/index.js +8 -0
- package/dist/jobs/index.js.map +1 -0
- package/dist/jobs/queue.d.ts +6 -0
- package/dist/jobs/queue.d.ts.map +1 -0
- package/dist/jobs/queue.js +55 -0
- package/dist/jobs/queue.js.map +1 -0
- package/dist/jobs/runtime.d.ts +13 -0
- package/dist/jobs/runtime.d.ts.map +1 -0
- package/dist/jobs/runtime.js +46 -0
- package/dist/jobs/runtime.js.map +1 -0
- package/dist/jobs/slots.d.ts +25 -0
- package/dist/jobs/slots.d.ts.map +1 -0
- package/dist/jobs/slots.js +41 -0
- package/dist/jobs/slots.js.map +1 -0
- package/dist/jobs/worker.d.ts +12 -0
- package/dist/jobs/worker.d.ts.map +1 -0
- package/dist/jobs/worker.js +311 -0
- package/dist/jobs/worker.js.map +1 -0
- package/dist/lifecycle.d.ts +10 -0
- package/dist/lifecycle.d.ts.map +1 -0
- package/dist/lifecycle.js +37 -0
- package/dist/lifecycle.js.map +1 -0
- package/dist/list-query.d.ts +62 -0
- package/dist/list-query.d.ts.map +1 -0
- package/dist/list-query.js +194 -0
- package/dist/list-query.js.map +1 -0
- package/dist/manifest.d.ts +59 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +167 -0
- package/dist/manifest.js.map +1 -0
- package/dist/provision-internals.d.ts +24 -0
- package/dist/provision-internals.d.ts.map +1 -0
- package/dist/provision-internals.js +7 -0
- package/dist/provision-internals.js.map +1 -0
- package/dist/provision.d.ts +23 -0
- package/dist/provision.d.ts.map +1 -0
- package/dist/provision.js +96 -0
- package/dist/provision.js.map +1 -0
- package/dist/rate-limit.d.ts +7 -0
- package/dist/rate-limit.d.ts.map +1 -0
- package/dist/rate-limit.js +49 -0
- package/dist/rate-limit.js.map +1 -0
- package/dist/realtime/facade.d.ts +18 -0
- package/dist/realtime/facade.d.ts.map +1 -0
- package/dist/realtime/facade.js +36 -0
- package/dist/realtime/facade.js.map +1 -0
- package/dist/realtime/filter.d.ts +13 -0
- package/dist/realtime/filter.d.ts.map +1 -0
- package/dist/realtime/filter.js +48 -0
- package/dist/realtime/filter.js.map +1 -0
- package/dist/realtime/heartbeat.d.ts +14 -0
- package/dist/realtime/heartbeat.d.ts.map +1 -0
- package/dist/realtime/heartbeat.js +64 -0
- package/dist/realtime/heartbeat.js.map +1 -0
- package/dist/realtime/publisher.d.ts +21 -0
- package/dist/realtime/publisher.d.ts.map +1 -0
- package/dist/realtime/publisher.js +17 -0
- package/dist/realtime/publisher.js.map +1 -0
- package/dist/schema-export-pg.d.ts +2 -0
- package/dist/schema-export-pg.d.ts.map +1 -0
- package/dist/schema-export-pg.js +4 -0
- package/dist/schema-export-pg.js.map +1 -0
- package/dist/schema-export.d.ts +2 -0
- package/dist/schema-export.d.ts.map +1 -0
- package/dist/schema-export.js +2 -0
- package/dist/schema-export.js.map +1 -0
- package/dist/scope.d.ts +4 -0
- package/dist/scope.d.ts.map +1 -0
- package/dist/scope.js +13 -0
- package/dist/scope.js.map +1 -0
- package/dist/standard-schema.d.ts +13 -0
- package/dist/standard-schema.d.ts.map +1 -0
- package/dist/standard-schema.js +34 -0
- package/dist/standard-schema.js.map +1 -0
- package/dist/storage/buckets.d.ts +80 -0
- package/dist/storage/buckets.d.ts.map +1 -0
- package/dist/storage/buckets.js +178 -0
- package/dist/storage/buckets.js.map +1 -0
- package/dist/storage/delete.d.ts +11 -0
- package/dist/storage/delete.d.ts.map +1 -0
- package/dist/storage/delete.js +18 -0
- package/dist/storage/delete.js.map +1 -0
- package/dist/storage/file-meta.d.ts +37 -0
- package/dist/storage/file-meta.d.ts.map +1 -0
- package/dist/storage/file-meta.js +166 -0
- package/dist/storage/file-meta.js.map +1 -0
- package/dist/storage/index.d.ts +28 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +5 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/local.d.ts +15 -0
- package/dist/storage/local.d.ts.map +1 -0
- package/dist/storage/local.js +56 -0
- package/dist/storage/local.js.map +1 -0
- package/dist/storage/operations.d.ts +54 -0
- package/dist/storage/operations.d.ts.map +1 -0
- package/dist/storage/operations.js +250 -0
- package/dist/storage/operations.js.map +1 -0
- package/dist/storage/registry.d.ts +10 -0
- package/dist/storage/registry.d.ts.map +1 -0
- package/dist/storage/registry.js +23 -0
- package/dist/storage/registry.js.map +1 -0
- package/dist/storage/s3.d.ts +28 -0
- package/dist/storage/s3.d.ts.map +1 -0
- package/dist/storage/s3.js +71 -0
- package/dist/storage/s3.js.map +1 -0
- package/dist/storage/sweep.d.ts +9 -0
- package/dist/storage/sweep.d.ts.map +1 -0
- package/dist/storage/sweep.js +17 -0
- package/dist/storage/sweep.js.map +1 -0
- package/dist/storage/thumbnails.d.ts +11 -0
- package/dist/storage/thumbnails.d.ts.map +1 -0
- package/dist/storage/thumbnails.js +60 -0
- package/dist/storage/thumbnails.js.map +1 -0
- package/dist/testing.d.ts +27 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +11 -0
- package/dist/testing.js.map +1 -0
- package/dist/typeid-pg.d.ts +19 -0
- package/dist/typeid-pg.d.ts.map +1 -0
- package/{src/typeid-pg.ts → dist/typeid-pg.js} +10 -13
- package/dist/typeid-pg.js.map +1 -0
- package/dist/typeid.d.ts +45 -0
- package/dist/typeid.d.ts.map +1 -0
- package/dist/typeid.js +100 -0
- package/dist/typeid.js.map +1 -0
- package/package.json +77 -28
- package/src/access.ts +0 -532
- package/src/api/builder.ts +0 -52
- package/src/api/context.ts +0 -83
- package/src/api/crud-router.ts +0 -386
- package/src/api/openapi.ts +0 -184
- package/src/api/realtime-router.ts +0 -75
- package/src/api/registry.ts +0 -338
- package/src/api/router.ts +0 -34
- package/src/api/storage-router.ts +0 -224
- package/src/api/types.ts +0 -105
- package/src/auth.ts +0 -117
- package/src/blueprint-generator.ts +0 -203
- package/src/blueprint.ts +0 -264
- package/src/cli.ts +0 -90
- package/src/config.ts +0 -215
- package/src/cron.ts +0 -3
- package/src/crud-operations.ts +0 -478
- package/src/database/adapter.ts +0 -26
- package/src/database/bun-sql.ts +0 -23
- package/src/database/libsql.ts +0 -28
- package/src/database/pglite.ts +0 -33
- package/src/database/postgres-js.ts +0 -33
- package/src/db.ts +0 -61
- package/src/dialect.ts +0 -38
- package/src/email/smtp.ts +0 -45
- package/src/email.ts +0 -154
- package/src/env.ts +0 -180
- package/src/errors.ts +0 -123
- package/src/handler.ts +0 -30
- package/src/idempotency.ts +0 -97
- package/src/index.ts +0 -834
- package/src/internal-tables.ts +0 -149
- package/src/jobs/cron.ts +0 -87
- package/src/jobs/define.ts +0 -283
- package/src/jobs/index.ts +0 -37
- package/src/jobs/queue.ts +0 -67
- package/src/jobs/runtime.ts +0 -58
- package/src/jobs/slots.ts +0 -52
- package/src/jobs/worker.ts +0 -369
- package/src/lifecycle.ts +0 -49
- package/src/list-query.ts +0 -333
- package/src/manifest.ts +0 -297
- package/src/provision-internals.ts +0 -29
- package/src/provision.ts +0 -128
- package/src/rate-limit.ts +0 -71
- package/src/realtime/facade.ts +0 -74
- package/src/realtime/filter.ts +0 -81
- package/src/realtime/heartbeat.ts +0 -80
- package/src/realtime/publisher.ts +0 -46
- package/src/schema-export-pg.ts +0 -7
- package/src/schema-export.ts +0 -5
- package/src/scope.ts +0 -17
- package/src/standard-schema.ts +0 -59
- package/src/storage/buckets.ts +0 -308
- package/src/storage/delete.ts +0 -26
- package/src/storage/file-meta.ts +0 -222
- package/src/storage/index.ts +0 -39
- package/src/storage/local.ts +0 -69
- package/src/storage/operations.ts +0 -398
- package/src/storage/registry.ts +0 -40
- package/src/storage/s3.ts +0 -99
- package/src/storage/sweep.ts +0 -25
- package/src/storage/thumbnails.ts +0 -65
- package/src/testing.ts +0 -31
- package/src/typeid.ts +0 -116
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
const buckets = new Map();
|
|
2
|
+
function resolveConfig(config) {
|
|
3
|
+
if (!config)
|
|
4
|
+
return null;
|
|
5
|
+
if (config === true)
|
|
6
|
+
return {};
|
|
7
|
+
return config;
|
|
8
|
+
}
|
|
9
|
+
function clientKey(req) {
|
|
10
|
+
const forwarded = req.headers.get('x-forwarded-for');
|
|
11
|
+
if (forwarded)
|
|
12
|
+
return forwarded.split(',')[0].trim();
|
|
13
|
+
return req.headers.get('x-real-ip') ?? 'local';
|
|
14
|
+
}
|
|
15
|
+
export function createRateLimiter(config) {
|
|
16
|
+
const resolved = resolveConfig(config);
|
|
17
|
+
if (!resolved) {
|
|
18
|
+
return async (_req) => null;
|
|
19
|
+
}
|
|
20
|
+
const windowMs = resolved.windowMs ?? 60_000;
|
|
21
|
+
const max = resolved.max ?? 100;
|
|
22
|
+
return async (req) => {
|
|
23
|
+
if (resolved.skip?.(req))
|
|
24
|
+
return null;
|
|
25
|
+
const key = `${clientKey(req)}:${new URL(req.url).pathname}`;
|
|
26
|
+
const now = Date.now();
|
|
27
|
+
let bucket = buckets.get(key);
|
|
28
|
+
if (!bucket || bucket.resetAt <= now) {
|
|
29
|
+
bucket = { count: 0, resetAt: now + windowMs };
|
|
30
|
+
buckets.set(key, bucket);
|
|
31
|
+
}
|
|
32
|
+
bucket.count += 1;
|
|
33
|
+
if (bucket.count > max) {
|
|
34
|
+
const retryAfter = Math.ceil((bucket.resetAt - now) / 1000);
|
|
35
|
+
return new Response(JSON.stringify({
|
|
36
|
+
error: 'Too many requests',
|
|
37
|
+
code: 'TOO_MANY_REQUESTS',
|
|
38
|
+
}), {
|
|
39
|
+
status: 429,
|
|
40
|
+
headers: {
|
|
41
|
+
'Content-Type': 'application/json',
|
|
42
|
+
'Retry-After': String(retryAfter),
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=rate-limit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limit.js","sourceRoot":"","sources":["../src/rate-limit.ts"],"names":[],"mappings":"AAWA,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAA;AAEzC,SAAS,aAAa,CACpB,MAA6C;IAE7C,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IACxB,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,EAAE,CAAA;IAC9B,OAAO,MAAM,CAAA;AACf,CAAC;AAED,SAAS,SAAS,CAAC,GAAY;IAC7B,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAA;IACpD,IAAI,SAAS;QAAE,OAAO,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,CAAA;IACrD,OAAO,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,OAAO,CAAA;AAChD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,MAA6C;IAE7C,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,CAAA;IACtC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,KAAK,EAAE,IAAa,EAAE,EAAE,CAAC,IAAI,CAAA;IACtC,CAAC;IAED,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,IAAI,MAAM,CAAA;IAC5C,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,IAAI,GAAG,CAAA;IAE/B,OAAO,KAAK,EAAE,GAAY,EAA4B,EAAE;QACtD,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAA;QAErC,MAAM,GAAG,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAA;QAC5D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACtB,IAAI,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QAE7B,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,OAAO,IAAI,GAAG,EAAE,CAAC;YACrC,MAAM,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,GAAG,QAAQ,EAAE,CAAA;YAC9C,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;QAC1B,CAAC;QAED,MAAM,CAAC,KAAK,IAAI,CAAC,CAAA;QACjB,IAAI,MAAM,CAAC,KAAK,GAAG,GAAG,EAAE,CAAC;YACvB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,CAAA;YAC3D,OAAO,IAAI,QAAQ,CACjB,IAAI,CAAC,SAAS,CAAC;gBACb,KAAK,EAAE,mBAAmB;gBAC1B,IAAI,EAAE,mBAAmB;aAC1B,CAAC,EACF;gBACE,MAAM,EAAE,GAAG;gBACX,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,aAAa,EAAE,MAAM,CAAC,UAAU,CAAC;iBAClC;aACF,CACF,CAAA;QACH,CAAC;QAED,OAAO,IAAI,CAAA;IACb,CAAC,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type InferSelectModel, type Table } from 'drizzle-orm';
|
|
2
|
+
import type { RealtimeAction, RealtimePublisher } from './publisher.js';
|
|
3
|
+
export type RealtimeTransport = 'disabled' | 'memory' | 'redis';
|
|
4
|
+
export type SchemaTable<TSchema extends Record<string, unknown>> = Extract<TSchema[keyof TSchema], Table>;
|
|
5
|
+
export interface RealtimeFacade<TSchema extends Record<string, unknown> = Record<string, unknown>> {
|
|
6
|
+
readonly enabled: boolean;
|
|
7
|
+
readonly transport: RealtimeTransport;
|
|
8
|
+
publish<TTable extends SchemaTable<TSchema>>(table: TTable, action: RealtimeAction, record: InferSelectModel<TTable>): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* One name for a table everywhere: events, subscriptions, and the CRUD router
|
|
12
|
+
* all use the schema key. Pass the schema so a key like `creditBalances` is not
|
|
13
|
+
* published as its SQL name `credit_balances` — clients subscribe with the key
|
|
14
|
+
* they call procedures with. Without a schema, the SQL name is the only name
|
|
15
|
+
* available and is used as-is.
|
|
16
|
+
*/
|
|
17
|
+
export declare function createRealtimeFacade<TSchema extends Record<string, unknown>>(publisher?: RealtimePublisher, transport?: RealtimeTransport, schema?: TSchema): RealtimeFacade<TSchema>;
|
|
18
|
+
//# sourceMappingURL=facade.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"facade.d.ts","sourceRoot":"","sources":["../../src/realtime/facade.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,KAAK,EACX,MAAM,aAAa,CAAA;AAEpB,OAAO,KAAK,EACV,cAAc,EACd,iBAAiB,EAClB,MAAM,aAAa,CAAA;AAEpB,MAAM,MAAM,iBAAiB,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,CAAA;AAE/D,MAAM,MAAM,WAAW,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,OAAO,CACxE,OAAO,CAAC,MAAM,OAAO,CAAC,EACtB,KAAK,CACN,CAAA;AAED,MAAM,WAAW,cAAc,CAC7B,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAEjE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAA;IAErC,OAAO,CAAC,MAAM,SAAS,WAAW,CAAC,OAAO,CAAC,EACzC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,gBAAgB,CAAC,MAAM,CAAC,GAC/B,OAAO,CAAC,IAAI,CAAC,CAAA;CACjB;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1E,SAAS,CAAC,EAAE,iBAAiB,EAC7B,SAAS,GAAE,iBAAqD,EAChE,MAAM,CAAC,EAAE,OAAO,GACf,cAAc,CAAC,OAAO,CAAC,CA8BzB"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { getTableName, isTable, } from 'drizzle-orm';
|
|
2
|
+
/**
|
|
3
|
+
* One name for a table everywhere: events, subscriptions, and the CRUD router
|
|
4
|
+
* all use the schema key. Pass the schema so a key like `creditBalances` is not
|
|
5
|
+
* published as its SQL name `credit_balances` — clients subscribe with the key
|
|
6
|
+
* they call procedures with. Without a schema, the SQL name is the only name
|
|
7
|
+
* available and is used as-is.
|
|
8
|
+
*/
|
|
9
|
+
export function createRealtimeFacade(publisher, transport = publisher ? 'memory' : 'disabled', schema) {
|
|
10
|
+
if (!publisher && transport !== 'disabled') {
|
|
11
|
+
throw new Error('[bunderstack] an enabled realtime transport requires a publisher');
|
|
12
|
+
}
|
|
13
|
+
if (publisher && transport === 'disabled') {
|
|
14
|
+
throw new Error('[bunderstack] a realtime publisher cannot use the disabled transport');
|
|
15
|
+
}
|
|
16
|
+
const keyByTableName = new Map();
|
|
17
|
+
for (const [key, value] of Object.entries(schema ?? {})) {
|
|
18
|
+
if (isTable(value))
|
|
19
|
+
keyByTableName.set(getTableName(value), key);
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
enabled: publisher !== undefined,
|
|
23
|
+
transport,
|
|
24
|
+
async publish(table, action, record) {
|
|
25
|
+
if (!publisher)
|
|
26
|
+
return;
|
|
27
|
+
const tableName = getTableName(table);
|
|
28
|
+
await publisher.publish('change', {
|
|
29
|
+
table: keyByTableName.get(tableName) ?? tableName,
|
|
30
|
+
action,
|
|
31
|
+
record: record,
|
|
32
|
+
});
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=facade.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"facade.js","sourceRoot":"","sources":["../../src/realtime/facade.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,OAAO,GAGR,MAAM,aAAa,CAAA;AA2BpB;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAClC,SAA6B,EAC7B,YAA+B,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,EAChE,MAAgB;IAEhB,IAAI,CAAC,SAAS,IAAI,SAAS,KAAK,UAAU,EAAE,CAAC;QAC3C,MAAM,IAAI,KAAK,CACb,kEAAkE,CACnE,CAAA;IACH,CAAC;IACD,IAAI,SAAS,IAAI,SAAS,KAAK,UAAU,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CACb,sEAAsE,CACvE,CAAA;IACH,CAAC;IAED,MAAM,cAAc,GAAG,IAAI,GAAG,EAAkB,CAAA;IAChD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,CAAC;QACxD,IAAI,OAAO,CAAC,KAAK,CAAC;YAAE,cAAc,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAA;IAClE,CAAC;IAED,OAAO;QACL,OAAO,EAAE,SAAS,KAAK,SAAS;QAChC,SAAS;QACT,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM;YACjC,IAAI,CAAC,SAAS;gBAAE,OAAM;YACtB,MAAM,SAAS,GAAG,YAAY,CAAC,KAAK,CAAC,CAAA;YACrC,MAAM,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE;gBAChC,KAAK,EAAE,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,SAAS;gBACjD,MAAM;gBACN,MAAM,EAAE,MAA4C;aACrD,CAAC,CAAA;QACJ,CAAC;KACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { AccessUser, ResolvedAccess } from '../access.js';
|
|
2
|
+
import type { RealtimeChange } from './publisher.js';
|
|
3
|
+
export interface FilterRealtimeChangesOptions {
|
|
4
|
+
subscriptions: readonly string[];
|
|
5
|
+
access: ResolvedAccess;
|
|
6
|
+
request: Request;
|
|
7
|
+
getSession: () => Promise<{
|
|
8
|
+
user: AccessUser | null;
|
|
9
|
+
activeOrganizationId: string | null;
|
|
10
|
+
}>;
|
|
11
|
+
}
|
|
12
|
+
export declare function filterRealtimeChanges(source: AsyncIterable<RealtimeChange>, options: FilterRealtimeChangesOptions): AsyncGenerator<RealtimeChange, void, void>;
|
|
13
|
+
//# sourceMappingURL=filter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../../src/realtime/filter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,UAAU,EACV,cAAc,EACf,MAAM,WAAW,CAAA;AAClB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAQjD,MAAM,WAAW,4BAA4B;IAC3C,aAAa,EAAE,SAAS,MAAM,EAAE,CAAA;IAChC,MAAM,EAAE,cAAc,CAAA;IACtB,OAAO,EAAE,OAAO,CAAA;IAChB,UAAU,EAAE,MAAM,OAAO,CAAC;QACxB,IAAI,EAAE,UAAU,GAAG,IAAI,CAAA;QACvB,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAA;KACpC,CAAC,CAAA;CACH;AAED,wBAAuB,qBAAqB,CAC1C,MAAM,EAAE,aAAa,CAAC,cAAc,CAAC,EACrC,OAAO,EAAE,4BAA4B,GACpC,cAAc,CAAC,cAAc,EAAE,IAAI,EAAE,IAAI,CAAC,CAqD5C"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { getEventMeta, withEventMeta } from '@orpc/server';
|
|
2
|
+
import { checkAccess, rowMatchesScope, tableEntryForName, } from '../access.js';
|
|
3
|
+
export async function* filterRealtimeChanges(source, options) {
|
|
4
|
+
const subscriptions = new Set(options.subscriptions);
|
|
5
|
+
let sessionPromise;
|
|
6
|
+
const getSession = () => (sessionPromise ??= options.getSession());
|
|
7
|
+
for await (const change of source) {
|
|
8
|
+
// Events name tables by schema key; the SQL-name lookup stays as a fallback
|
|
9
|
+
// for publishers outside the CRUD path that only know the physical name.
|
|
10
|
+
const entry = options.access.get(change.table) ??
|
|
11
|
+
tableEntryForName(options.access, change.table);
|
|
12
|
+
if (!entry?.enabled)
|
|
13
|
+
continue;
|
|
14
|
+
const recordId = change.record.id;
|
|
15
|
+
if (!subscriptions.has(change.table) &&
|
|
16
|
+
(recordId == null ||
|
|
17
|
+
!subscriptions.has(`${change.table}/${String(recordId)}`))) {
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
if (entry.get === 'deny')
|
|
21
|
+
continue;
|
|
22
|
+
const needsSession = entry.get !== 'public' || entry.readScope !== undefined;
|
|
23
|
+
const session = needsSession
|
|
24
|
+
? await getSession()
|
|
25
|
+
: { user: null, activeOrganizationId: null };
|
|
26
|
+
const context = {
|
|
27
|
+
request: options.request,
|
|
28
|
+
user: session.user,
|
|
29
|
+
row: change.record,
|
|
30
|
+
session: { activeOrganizationId: session.activeOrganizationId },
|
|
31
|
+
};
|
|
32
|
+
if (!(await checkAccess(entry.get, context, entry.ownerColumn)).allowed) {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (entry.readScope &&
|
|
36
|
+
!rowMatchesScope(change.record, entry.readScope(context))) {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
const projected = {
|
|
40
|
+
table: change.table,
|
|
41
|
+
action: change.action,
|
|
42
|
+
record: change.record,
|
|
43
|
+
};
|
|
44
|
+
const meta = getEventMeta(change);
|
|
45
|
+
yield meta ? withEventMeta(projected, meta) : projected;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=filter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filter.js","sourceRoot":"","sources":["../../src/realtime/filter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAQ1D,OAAO,EACL,WAAW,EACX,eAAe,EACf,iBAAiB,GAClB,MAAM,WAAW,CAAA;AAYlB,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,qBAAqB,CAC1C,MAAqC,EACrC,OAAqC;IAErC,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAA;IACpD,IAAI,cAES,CAAA;IACb,MAAM,UAAU,GAAG,GAAG,EAAE,CAAC,CAAC,cAAc,KAAK,OAAO,CAAC,UAAU,EAAE,CAAC,CAAA;IAElE,IAAI,KAAK,EAAE,MAAM,MAAM,IAAI,MAAM,EAAE,CAAC;QAClC,4EAA4E;QAC5E,yEAAyE;QACzE,MAAM,KAAK,GACT,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC;YAChC,iBAAiB,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAA;QACjD,IAAI,CAAC,KAAK,EAAE,OAAO;YAAE,SAAQ;QAE7B,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,CAAA;QACjC,IACE,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC;YAChC,CAAC,QAAQ,IAAI,IAAI;gBACf,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,EAC5D,CAAC;YACD,SAAQ;QACV,CAAC;QACD,IAAI,KAAK,CAAC,GAAG,KAAK,MAAM;YAAE,SAAQ;QAElC,MAAM,YAAY,GAAG,KAAK,CAAC,GAAG,KAAK,QAAQ,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,CAAA;QAC5E,MAAM,OAAO,GAAG,YAAY;YAC1B,CAAC,CAAC,MAAM,UAAU,EAAE;YACpB,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,oBAAoB,EAAE,IAAI,EAAE,CAAA;QAC9C,MAAM,OAAO,GAAG;YACd,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,GAAG,EAAE,MAAM,CAAC,MAAM;YAClB,OAAO,EAAE,EAAE,oBAAoB,EAAE,OAAO,CAAC,oBAAoB,EAAE;SAChE,CAAA;QACD,IAAI,CAAC,CAAC,MAAM,WAAW,CAAC,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;YACxE,SAAQ;QACV,CAAC;QACD,IACE,KAAK,CAAC,SAAS;YACf,CAAC,eAAe,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,EACzD,CAAC;YACD,SAAQ;QACV,CAAC;QAED,MAAM,SAAS,GAAmB;YAChC,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,MAAM,EAAE,MAAM,CAAC,MAAM;SACtB,CAAA;QACD,MAAM,IAAI,GAAG,YAAY,CAAC,MAAM,CAAC,CAAA;QACjC,MAAM,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IACzD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const REALTIME_HEARTBEAT_INTERVAL_MS = 5000;
|
|
2
|
+
export type RealtimeHeartbeat = {
|
|
3
|
+
type: 'heartbeat';
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Emits a transport-only event whenever the source has been idle for an
|
|
7
|
+
* interval. Heartbeats are deliberately not published, persisted, or assigned
|
|
8
|
+
* event IDs, so they do not affect replay and resume semantics.
|
|
9
|
+
*/
|
|
10
|
+
export declare function withRealtimeHeartbeat<T>(source: AsyncIterable<T>, options: {
|
|
11
|
+
intervalMs?: number;
|
|
12
|
+
signal?: AbortSignal;
|
|
13
|
+
}): AsyncGenerator<T | RealtimeHeartbeat, void, void>;
|
|
14
|
+
//# sourceMappingURL=heartbeat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heartbeat.d.ts","sourceRoot":"","sources":["../../src/realtime/heartbeat.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,8BAA8B,OAAQ,CAAA;AAEnD,MAAM,MAAM,iBAAiB,GAAG;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,CAAA;AAOrD;;;;GAIG;AACH,wBAAuB,qBAAqB,CAAC,CAAC,EAC5C,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,EACxB,OAAO,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAE,GACrD,cAAc,CAAC,CAAC,GAAG,iBAAiB,EAAE,IAAI,EAAE,IAAI,CAAC,CA8DnD"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export const REALTIME_HEARTBEAT_INTERVAL_MS = 5_000;
|
|
2
|
+
/**
|
|
3
|
+
* Emits a transport-only event whenever the source has been idle for an
|
|
4
|
+
* interval. Heartbeats are deliberately not published, persisted, or assigned
|
|
5
|
+
* event IDs, so they do not affect replay and resume semantics.
|
|
6
|
+
*/
|
|
7
|
+
export async function* withRealtimeHeartbeat(source, options) {
|
|
8
|
+
const intervalMs = Math.max(1, options.intervalMs ?? REALTIME_HEARTBEAT_INTERVAL_MS);
|
|
9
|
+
const iterator = source[Symbol.asyncIterator]();
|
|
10
|
+
let state = { status: 'pending' };
|
|
11
|
+
let wake;
|
|
12
|
+
const getState = () => state;
|
|
13
|
+
const requestNext = () => {
|
|
14
|
+
state = { status: 'pending' };
|
|
15
|
+
void iterator.next().then((result) => {
|
|
16
|
+
state = { status: 'ready', result };
|
|
17
|
+
wake?.();
|
|
18
|
+
}, (error) => {
|
|
19
|
+
state = { status: 'error', error };
|
|
20
|
+
wake?.();
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
requestNext();
|
|
24
|
+
try {
|
|
25
|
+
while (!options.signal?.aborted) {
|
|
26
|
+
let current = getState();
|
|
27
|
+
if (current.status === 'pending') {
|
|
28
|
+
await new Promise((resolve) => {
|
|
29
|
+
let settled = false;
|
|
30
|
+
const finish = () => {
|
|
31
|
+
if (settled)
|
|
32
|
+
return;
|
|
33
|
+
settled = true;
|
|
34
|
+
clearTimeout(timer);
|
|
35
|
+
options.signal?.removeEventListener('abort', finish);
|
|
36
|
+
resolve();
|
|
37
|
+
};
|
|
38
|
+
const timer = setTimeout(finish, intervalMs);
|
|
39
|
+
options.signal?.addEventListener('abort', finish, { once: true });
|
|
40
|
+
wake = finish;
|
|
41
|
+
});
|
|
42
|
+
wake = undefined;
|
|
43
|
+
if (options.signal?.aborted)
|
|
44
|
+
break;
|
|
45
|
+
current = getState();
|
|
46
|
+
if (current.status === 'pending') {
|
|
47
|
+
yield { type: 'heartbeat' };
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (current.status === 'error')
|
|
52
|
+
throw current.error;
|
|
53
|
+
if (current.result.done)
|
|
54
|
+
break;
|
|
55
|
+
yield current.result.value;
|
|
56
|
+
requestNext();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
finally {
|
|
60
|
+
wake = undefined;
|
|
61
|
+
await iterator.return?.();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=heartbeat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heartbeat.js","sourceRoot":"","sources":["../../src/realtime/heartbeat.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,8BAA8B,GAAG,KAAK,CAAA;AASnD;;;;GAIG;AACH,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,qBAAqB,CAC1C,MAAwB,EACxB,OAAsD;IAEtD,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CACzB,CAAC,EACD,OAAO,CAAC,UAAU,IAAI,8BAA8B,CACrD,CAAA;IACD,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAA;IAC/C,IAAI,KAAK,GAAmB,EAAE,MAAM,EAAE,SAAS,EAAE,CAAA;IACjD,IAAI,IAA8B,CAAA;IAClC,MAAM,QAAQ,GAAG,GAAmB,EAAE,CAAC,KAAK,CAAA;IAE5C,MAAM,WAAW,GAAG,GAAG,EAAE;QACvB,KAAK,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,CAAA;QAC7B,KAAK,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,CACvB,CAAC,MAAM,EAAE,EAAE;YACT,KAAK,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAA;YACnC,IAAI,EAAE,EAAE,CAAA;QACV,CAAC,EACD,CAAC,KAAc,EAAE,EAAE;YACjB,KAAK,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,CAAA;YAClC,IAAI,EAAE,EAAE,CAAA;QACV,CAAC,CACF,CAAA;IACH,CAAC,CAAA;IAED,WAAW,EAAE,CAAA;IACb,IAAI,CAAC;QACH,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;YAChC,IAAI,OAAO,GAAG,QAAQ,EAAE,CAAA;YACxB,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBACjC,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;oBAClC,IAAI,OAAO,GAAG,KAAK,CAAA;oBACnB,MAAM,MAAM,GAAG,GAAG,EAAE;wBAClB,IAAI,OAAO;4BAAE,OAAM;wBACnB,OAAO,GAAG,IAAI,CAAA;wBACd,YAAY,CAAC,KAAK,CAAC,CAAA;wBACnB,OAAO,CAAC,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;wBACpD,OAAO,EAAE,CAAA;oBACX,CAAC,CAAA;oBACD,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;oBAC5C,OAAO,CAAC,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;oBACjE,IAAI,GAAG,MAAM,CAAA;gBACf,CAAC,CAAC,CAAA;gBACF,IAAI,GAAG,SAAS,CAAA;gBAEhB,IAAI,OAAO,CAAC,MAAM,EAAE,OAAO;oBAAE,MAAK;gBAClC,OAAO,GAAG,QAAQ,EAAE,CAAA;gBACpB,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;oBACjC,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,CAAA;oBAC3B,SAAQ;gBACV,CAAC;YACH,CAAC;YAED,IAAI,OAAO,CAAC,MAAM,KAAK,OAAO;gBAAE,MAAM,OAAO,CAAC,KAAK,CAAA;YACnD,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI;gBAAE,MAAK;YAE9B,MAAM,OAAO,CAAC,MAAM,CAAC,KAAK,CAAA;YAC1B,WAAW,EAAE,CAAA;QACf,CAAC;IACH,CAAC;YAAS,CAAC;QACT,IAAI,GAAG,SAAS,CAAA;QAChB,MAAM,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAA;IAC3B,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Publisher } from '@orpc/publisher';
|
|
2
|
+
import type { RedisClient } from 'bun';
|
|
3
|
+
export type RealtimeAction = 'create' | 'update' | 'delete';
|
|
4
|
+
export interface RealtimeChange {
|
|
5
|
+
table: string;
|
|
6
|
+
action: RealtimeAction;
|
|
7
|
+
record: Record<string, unknown>;
|
|
8
|
+
}
|
|
9
|
+
export interface RealtimeEvents extends Record<string, object> {
|
|
10
|
+
change: RealtimeChange;
|
|
11
|
+
}
|
|
12
|
+
export type RealtimePublisher = Publisher<RealtimeEvents>;
|
|
13
|
+
export interface RealtimePublisherOptions {
|
|
14
|
+
maxBufferedEvents?: number;
|
|
15
|
+
resumeSeconds?: number;
|
|
16
|
+
}
|
|
17
|
+
export declare function createMemoryRealtimePublisher(options?: RealtimePublisherOptions): RealtimePublisher;
|
|
18
|
+
export declare function createRedisRealtimePublisher(redis: RedisClient, subscriber: RedisClient | Promise<RedisClient>, options?: RealtimePublisherOptions & {
|
|
19
|
+
prefix?: string;
|
|
20
|
+
}): RealtimePublisher;
|
|
21
|
+
//# sourceMappingURL=publisher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publisher.d.ts","sourceRoot":"","sources":["../../src/realtime/publisher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,KAAK,CAAA;AAKtC,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAE3D,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,cAAc,CAAA;IACtB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAChC;AAED,MAAM,WAAW,cAAe,SAAQ,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAC5D,MAAM,EAAE,cAAc,CAAA;CACvB;AAED,MAAM,MAAM,iBAAiB,GAAG,SAAS,CAAC,cAAc,CAAC,CAAA;AAEzD,MAAM,WAAW,wBAAwB;IACvC,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,wBAAgB,6BAA6B,CAC3C,OAAO,GAAE,wBAA6B,GACrC,iBAAiB,CAKnB;AAED,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,WAAW,EAClB,UAAU,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,EAC9C,OAAO,GAAE,wBAAwB,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAC3D,iBAAiB,CAOnB"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { BunRedisPublisher } from '@orpc/bun';
|
|
2
|
+
import { MemoryPublisher } from '@orpc/publisher/memory';
|
|
3
|
+
export function createMemoryRealtimePublisher(options = {}) {
|
|
4
|
+
return new MemoryPublisher({
|
|
5
|
+
maxBufferedEvents: options.maxBufferedEvents,
|
|
6
|
+
resume: { enabled: true, seconds: options.resumeSeconds ?? 300 },
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
export function createRedisRealtimePublisher(redis, subscriber, options = {}) {
|
|
10
|
+
return new BunRedisPublisher(redis, {
|
|
11
|
+
subscriber,
|
|
12
|
+
prefix: options.prefix ?? 'bunderstack:',
|
|
13
|
+
maxBufferedEvents: options.maxBufferedEvents,
|
|
14
|
+
resume: { enabled: true, seconds: options.resumeSeconds ?? 300 },
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=publisher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publisher.js","sourceRoot":"","sources":["../../src/realtime/publisher.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAqBxD,MAAM,UAAU,6BAA6B,CAC3C,UAAoC,EAAE;IAEtC,OAAO,IAAI,eAAe,CAAiB;QACzC,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;QAC5C,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,aAAa,IAAI,GAAG,EAAE;KACjE,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,UAAU,4BAA4B,CAC1C,KAAkB,EAClB,UAA8C,EAC9C,UAA0D,EAAE;IAE5D,OAAO,IAAI,iBAAiB,CAAiB,KAAK,EAAE;QAClD,UAAU;QACV,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,cAAc;QACxC,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;QAC5C,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,aAAa,IAAI,GAAG,EAAE;KACjE,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-export-pg.d.ts","sourceRoot":"","sources":["../src/schema-export-pg.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,kBAAkB,IAAI,gBAAgB,EACtC,wBAAwB,IAAI,sBAAsB,EAClD,iBAAiB,IAAI,eAAe,GACrC,MAAM,sBAAsB,CAAA"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// src/schema-export-pg.ts — pg twins under the same names bunderstack/schema
|
|
2
|
+
// uses, so `export * from 'bunderstack/schema/pg'` mirrors the sqlite setup.
|
|
3
|
+
export { bunderstackFilesPg as bunderstackFiles, bunderstackIdempotencyPg as bunderstackIdempotency, bunderstackJobsPg as bunderstackJobs, } from './internal-tables-pg.js';
|
|
4
|
+
//# sourceMappingURL=schema-export-pg.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-export-pg.js","sourceRoot":"","sources":["../src/schema-export-pg.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,6EAA6E;AAC7E,OAAO,EACL,kBAAkB,IAAI,gBAAgB,EACtC,wBAAwB,IAAI,sBAAsB,EAClD,iBAAiB,IAAI,eAAe,GACrC,MAAM,sBAAsB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-export.d.ts","sourceRoot":"","sources":["../src/schema-export.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,eAAe,GAChB,MAAM,mBAAmB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-export.js","sourceRoot":"","sources":["../src/schema-export.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,eAAe,GAChB,MAAM,mBAAmB,CAAA"}
|
package/dist/scope.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,eAAe,EAAW,KAAK,GAAG,EAAE,MAAM,aAAa,CAAA;AAEzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAExC,wBAAgB,eAAe,CAC7B,KAAK,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC,CAAC,CAAC,EAC5C,KAAK,EAAE,QAAQ,GACd,GAAG,GAAG,SAAS,CASjB"}
|
package/dist/scope.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { and, eq, getTableColumns, inArray } from 'drizzle-orm';
|
|
2
|
+
export function buildScopeWhere(table, scope) {
|
|
3
|
+
const columns = getTableColumns(table);
|
|
4
|
+
const conditions = [];
|
|
5
|
+
for (const [name, value] of Object.entries(scope)) {
|
|
6
|
+
const col = columns[name];
|
|
7
|
+
if (!col)
|
|
8
|
+
continue;
|
|
9
|
+
conditions.push(Array.isArray(value) ? inArray(col, value) : eq(col, value));
|
|
10
|
+
}
|
|
11
|
+
return conditions.length ? and(...conditions) : undefined;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=scope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.js","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,eAAe,EAAE,OAAO,EAAY,MAAM,aAAa,CAAA;AAIzE,MAAM,UAAU,eAAe,CAC7B,KAA4C,EAC5C,KAAe;IAEf,MAAM,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,CAAA;IACtC,MAAM,UAAU,GAAU,EAAE,CAAA;IAC5B,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAClD,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;QACzB,IAAI,CAAC,GAAG;YAAE,SAAQ;QAClB,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAA;IAC9E,CAAC;IACD,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;AAC3D,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { StandardSchemaV1 } from '@standard-schema/spec';
|
|
2
|
+
export type StandardSchema = StandardSchemaV1;
|
|
3
|
+
export type InferStandardOutput<TSchema extends StandardSchemaV1> = StandardSchemaV1.InferOutput<TSchema>;
|
|
4
|
+
export type StandardSchemaIssue = {
|
|
5
|
+
path: PropertyKey[];
|
|
6
|
+
message: string;
|
|
7
|
+
};
|
|
8
|
+
export declare class StandardSchemaValidationError extends Error {
|
|
9
|
+
readonly issues: StandardSchemaIssue[];
|
|
10
|
+
constructor(label: string, issues: readonly StandardSchemaV1.Issue[]);
|
|
11
|
+
}
|
|
12
|
+
export declare function validateStandardSchema<TSchema extends StandardSchemaV1>(schema: TSchema, value: unknown, label: string): StandardSchemaV1.InferOutput<TSchema>;
|
|
13
|
+
//# sourceMappingURL=standard-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"standard-schema.d.ts","sourceRoot":"","sources":["../src/standard-schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAE7D,MAAM,MAAM,cAAc,GAAG,gBAAgB,CAAA;AAC7C,MAAM,MAAM,mBAAmB,CAAC,OAAO,SAAS,gBAAgB,IAC9D,gBAAgB,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;AAEvC,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,WAAW,EAAE,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,qBAAa,6BAA8B,SAAQ,KAAK;IACtD,QAAQ,CAAC,MAAM,EAAE,mBAAmB,EAAE,CAAA;gBAE1B,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,gBAAgB,CAAC,KAAK,EAAE;CAkBrE;AAWD,wBAAgB,sBAAsB,CAAC,OAAO,SAAS,gBAAgB,EACrE,MAAM,EAAE,OAAO,EACf,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,MAAM,GACZ,gBAAgB,CAAC,WAAW,CAAC,OAAO,CAAC,CAWvC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export class StandardSchemaValidationError extends Error {
|
|
2
|
+
issues;
|
|
3
|
+
constructor(label, issues) {
|
|
4
|
+
const normalized = issues.map((issue) => ({
|
|
5
|
+
path: [...(issue.path ?? [])].map((segment) => typeof segment === 'object' ? segment.key : segment),
|
|
6
|
+
message: issue.message,
|
|
7
|
+
}));
|
|
8
|
+
super(normalized
|
|
9
|
+
.map((issue) => {
|
|
10
|
+
const path = issue.path.map(String).join('.');
|
|
11
|
+
return `${label}${path ? `.${path}` : ''}: ${issue.message}`;
|
|
12
|
+
})
|
|
13
|
+
.join('\n'));
|
|
14
|
+
this.name = 'StandardSchemaValidationError';
|
|
15
|
+
this.issues = normalized;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function isPromiseLike(value) {
|
|
19
|
+
return (typeof value === 'object' &&
|
|
20
|
+
value !== null &&
|
|
21
|
+
'then' in value &&
|
|
22
|
+
typeof value.then === 'function');
|
|
23
|
+
}
|
|
24
|
+
export function validateStandardSchema(schema, value, label) {
|
|
25
|
+
const result = schema['~standard'].validate(value);
|
|
26
|
+
if (isPromiseLike(result)) {
|
|
27
|
+
throw new Error(`[bunderstack] ${label} schema validation must be synchronous`);
|
|
28
|
+
}
|
|
29
|
+
if (result.issues) {
|
|
30
|
+
throw new StandardSchemaValidationError(label, result.issues);
|
|
31
|
+
}
|
|
32
|
+
return result.value;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=standard-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"standard-schema.js","sourceRoot":"","sources":["../src/standard-schema.ts"],"names":[],"mappings":"AAWA,MAAM,OAAO,6BAA8B,SAAQ,KAAK;IAC7C,MAAM,CAAuB;IAEtC,YAAY,KAAa,EAAE,MAAyC;QAClE,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACxC,IAAI,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAC5C,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CACpD;YACD,OAAO,EAAE,KAAK,CAAC,OAAO;SACvB,CAAC,CAAC,CAAA;QACH,KAAK,CACH,UAAU;aACP,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YACb,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YAC7C,OAAO,GAAG,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,OAAO,EAAE,CAAA;QAC9D,CAAC,CAAC;aACD,IAAI,CAAC,IAAI,CAAC,CACd,CAAA;QACD,IAAI,CAAC,IAAI,GAAG,+BAA+B,CAAA;QAC3C,IAAI,CAAC,MAAM,GAAG,UAAU,CAAA;IAC1B,CAAC;CACF;AAED,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,MAAM,IAAI,KAAK;QACf,OAAO,KAAK,CAAC,IAAI,KAAK,UAAU,CACjC,CAAA;AACH,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,MAAe,EACf,KAAc,EACd,KAAa;IAEb,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IAClD,IAAI,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CACb,iBAAiB,KAAK,wCAAwC,CAC/D,CAAA;IACH,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,MAAM,IAAI,6BAA6B,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;IAC/D,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAA;AACrB,CAAC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { OperationRule, ScopeResolver } from '../access.js';
|
|
2
|
+
export type BucketBackendInput = {
|
|
3
|
+
s3: {
|
|
4
|
+
bucket: string;
|
|
5
|
+
region?: string;
|
|
6
|
+
endpoint?: string;
|
|
7
|
+
publicUrl?: string;
|
|
8
|
+
};
|
|
9
|
+
} | {
|
|
10
|
+
local: string;
|
|
11
|
+
};
|
|
12
|
+
export type BucketConfigInput = {
|
|
13
|
+
visibility?: 'public' | 'private';
|
|
14
|
+
access?: {
|
|
15
|
+
create?: OperationRule;
|
|
16
|
+
get?: OperationRule;
|
|
17
|
+
delete?: OperationRule;
|
|
18
|
+
};
|
|
19
|
+
upload?: {
|
|
20
|
+
maxSize?: string | number;
|
|
21
|
+
accept?: string[];
|
|
22
|
+
};
|
|
23
|
+
transforms?: boolean;
|
|
24
|
+
scope?: {
|
|
25
|
+
read?: ScopeResolver;
|
|
26
|
+
write?: ScopeResolver;
|
|
27
|
+
};
|
|
28
|
+
quota?: {
|
|
29
|
+
perUser?: string | number;
|
|
30
|
+
perScope?: string | number;
|
|
31
|
+
};
|
|
32
|
+
} & Partial<BucketBackendInput>;
|
|
33
|
+
export type StorageConfigInput = {
|
|
34
|
+
s3?: true | {
|
|
35
|
+
endpoint?: string;
|
|
36
|
+
};
|
|
37
|
+
local?: true | string;
|
|
38
|
+
defaultBucket?: string;
|
|
39
|
+
buckets?: Record<string, BucketConfigInput>;
|
|
40
|
+
};
|
|
41
|
+
export type ResolvedBackend = {
|
|
42
|
+
type: 'local';
|
|
43
|
+
path: string;
|
|
44
|
+
} | {
|
|
45
|
+
type: 's3';
|
|
46
|
+
bucket: string;
|
|
47
|
+
region: string;
|
|
48
|
+
endpoint?: string;
|
|
49
|
+
accessKeyId: string;
|
|
50
|
+
secretAccessKey: string;
|
|
51
|
+
publicUrl?: string;
|
|
52
|
+
};
|
|
53
|
+
export type ResolvedBucket = {
|
|
54
|
+
name: string;
|
|
55
|
+
backend: ResolvedBackend;
|
|
56
|
+
visibility: 'public' | 'private';
|
|
57
|
+
access: {
|
|
58
|
+
create: OperationRule;
|
|
59
|
+
get: OperationRule;
|
|
60
|
+
delete: OperationRule;
|
|
61
|
+
};
|
|
62
|
+
upload?: {
|
|
63
|
+
maxSizeBytes?: number;
|
|
64
|
+
accept?: string[];
|
|
65
|
+
};
|
|
66
|
+
transforms: boolean;
|
|
67
|
+
readScope?: ScopeResolver;
|
|
68
|
+
writeScope?: ScopeResolver;
|
|
69
|
+
quota?: {
|
|
70
|
+
perUserBytes?: number;
|
|
71
|
+
perScopeBytes?: number;
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
export type ResolvedStorageBuckets = {
|
|
75
|
+
defaultBucket: string;
|
|
76
|
+
buckets: Map<string, ResolvedBucket>;
|
|
77
|
+
};
|
|
78
|
+
export declare function parseSize(value: string | number): number;
|
|
79
|
+
export declare function resolveBuckets(input: StorageConfigInput | undefined, env?: Record<string, string | undefined>): ResolvedStorageBuckets;
|
|
80
|
+
//# sourceMappingURL=buckets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buckets.d.ts","sourceRoot":"","sources":["../../src/storage/buckets.ts"],"names":[],"mappings":"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"}
|