@lastshotlabs/bunshot 0.0.21 → 0.0.25
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 +3035 -1249
- package/dist/adapters/localStorage.d.ts +6 -0
- package/dist/adapters/localStorage.js +44 -0
- package/dist/adapters/memoryAuth.d.ts +7 -0
- package/dist/adapters/memoryAuth.js +144 -0
- package/dist/adapters/memoryStorage.d.ts +3 -0
- package/dist/adapters/memoryStorage.js +44 -0
- package/dist/adapters/mongoAuth.js +120 -0
- package/dist/adapters/s3Storage.d.ts +14 -0
- package/dist/adapters/s3Storage.js +126 -0
- package/dist/adapters/sqliteAuth.d.ts +7 -0
- package/dist/adapters/sqliteAuth.js +199 -0
- package/dist/app.d.ts +100 -3
- package/dist/app.js +247 -46
- package/dist/cli.js +118 -38
- package/dist/index.d.ts +49 -7
- package/dist/index.js +35 -5
- package/dist/lib/HttpError.d.ts +5 -0
- package/dist/lib/HttpError.js +7 -0
- package/dist/lib/appConfig.d.ts +44 -0
- package/dist/lib/appConfig.js +16 -0
- package/dist/lib/auditLog.d.ts +52 -0
- package/dist/lib/auditLog.js +201 -0
- package/dist/lib/authAdapter.d.ts +69 -0
- package/dist/lib/constants.d.ts +4 -0
- package/dist/lib/constants.js +4 -0
- package/dist/lib/context.d.ts +19 -1
- package/dist/lib/context.js +17 -3
- package/dist/lib/createRoute.d.ts +28 -2
- package/dist/lib/createRoute.js +54 -3
- package/dist/lib/deletionCancelToken.d.ts +12 -0
- package/dist/lib/deletionCancelToken.js +88 -0
- package/dist/lib/groups.d.ts +113 -0
- package/dist/lib/groups.js +133 -0
- package/dist/lib/idempotency.d.ts +22 -0
- package/dist/lib/idempotency.js +182 -0
- package/dist/lib/metrics.d.ts +14 -0
- package/dist/lib/metrics.js +158 -0
- package/dist/lib/pagination.d.ts +119 -0
- package/dist/lib/pagination.js +166 -0
- package/dist/lib/session.d.ts +4 -0
- package/dist/lib/session.js +56 -2
- package/dist/lib/signing.d.ts +52 -0
- package/dist/lib/signing.js +180 -0
- package/dist/lib/storageAdapter.d.ts +30 -0
- package/dist/lib/storageAdapter.js +1 -0
- package/dist/lib/stripUnreferencedSchemas.d.ts +11 -0
- package/dist/lib/stripUnreferencedSchemas.js +79 -0
- package/dist/lib/tenant.js +2 -2
- package/dist/lib/upload.d.ts +35 -0
- package/dist/lib/upload.js +87 -0
- package/dist/lib/validate.js +2 -2
- package/dist/lib/ws.d.ts +1 -0
- package/dist/lib/ws.js +21 -0
- package/dist/lib/wsHeartbeat.d.ts +12 -0
- package/dist/lib/wsHeartbeat.js +57 -0
- package/dist/lib/wsMessages.d.ts +40 -0
- package/dist/lib/wsMessages.js +330 -0
- package/dist/lib/wsPresence.d.ts +25 -0
- package/dist/lib/wsPresence.js +99 -0
- package/dist/middleware/auditLog.d.ts +22 -0
- package/dist/middleware/auditLog.js +39 -0
- package/dist/middleware/cacheResponse.js +5 -1
- package/dist/middleware/csrf.js +10 -0
- package/dist/middleware/identify.js +57 -9
- package/dist/middleware/metrics.d.ts +9 -0
- package/dist/middleware/metrics.js +26 -0
- package/dist/middleware/requestId.d.ts +3 -0
- package/dist/middleware/requestId.js +7 -0
- package/dist/middleware/requestLogger.d.ts +38 -0
- package/dist/middleware/requestLogger.js +68 -0
- package/dist/middleware/requestSigning.d.ts +20 -0
- package/dist/middleware/requestSigning.js +99 -0
- package/dist/middleware/requireMfaSetup.d.ts +16 -0
- package/dist/middleware/requireMfaSetup.js +36 -0
- package/dist/middleware/requireRole.d.ts +9 -3
- package/dist/middleware/requireRole.js +23 -36
- package/dist/middleware/upload.d.ts +5 -0
- package/dist/middleware/upload.js +27 -0
- package/dist/middleware/webhookAuth.d.ts +30 -0
- package/dist/middleware/webhookAuth.js +57 -0
- package/dist/models/AuditLog.d.ts +30 -0
- package/dist/models/AuditLog.js +39 -0
- package/dist/models/Group.d.ts +21 -0
- package/dist/models/Group.js +28 -0
- package/dist/models/GroupMembership.d.ts +21 -0
- package/dist/models/GroupMembership.js +25 -0
- package/dist/routes/auth.js +84 -6
- package/dist/routes/groups.d.ts +21 -0
- package/dist/routes/groups.js +346 -0
- package/dist/routes/jobs.js +47 -45
- package/dist/routes/metrics.d.ts +7 -0
- package/dist/routes/metrics.js +52 -0
- package/dist/routes/mfa.js +4 -0
- package/dist/routes/uploads.d.ts +2 -0
- package/dist/routes/uploads.js +135 -0
- package/dist/server.d.ts +26 -0
- package/dist/server.js +46 -3
- package/dist/ws/index.js +3 -0
- package/docs/sections/auth-flow/full.md +779 -634
- package/docs/sections/auth-flow/overview.md +2 -2
- package/docs/sections/auth-security-examples/full.md +365 -0
- package/docs/sections/authentication/full.md +130 -0
- package/docs/sections/authentication/overview.md +5 -0
- package/docs/sections/cli/full.md +13 -1
- package/docs/sections/configuration/full.md +17 -0
- package/docs/sections/configuration/overview.md +1 -0
- package/docs/sections/exports/full.md +34 -3
- package/docs/sections/logging/full.md +83 -0
- package/docs/sections/metrics/full.md +127 -0
- package/docs/sections/oauth/full.md +189 -189
- package/docs/sections/oauth/overview.md +1 -1
- package/docs/sections/pagination/full.md +93 -0
- package/docs/sections/roles/full.md +224 -135
- package/docs/sections/roles/overview.md +3 -1
- package/docs/sections/signing/full.md +203 -0
- package/docs/sections/uploads/full.md +199 -0
- package/docs/sections/versioning/full.md +85 -0
- package/docs/sections/webhook-auth/full.md +100 -0
- package/docs/sections/websocket/full.md +83 -0
- package/docs/sections/websocket-rooms/full.md +6 -1
- package/package.json +16 -4
package/dist/server.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { Server, ServerWebSocket, WebSocketHandler } from "bun";
|
|
2
2
|
import { type CreateAppConfig } from "./app";
|
|
3
3
|
import { type SocketData } from "./ws/index";
|
|
4
|
+
import { type HeartbeatConfig } from "./lib/wsHeartbeat";
|
|
5
|
+
import { type WsMessageStore, type WsMessageDefaults } from "./lib/wsMessages";
|
|
4
6
|
export interface WsConfig<T extends object = object> {
|
|
5
7
|
/** Override or extend the default WebSocket handler */
|
|
6
8
|
handler?: WebSocketHandler<SocketData<T>>;
|
|
@@ -18,6 +20,25 @@ export interface WsConfig<T extends object = object> {
|
|
|
18
20
|
* Defaults to 65536 (64 KB).
|
|
19
21
|
*/
|
|
20
22
|
maxMessageSize?: number;
|
|
23
|
+
/**
|
|
24
|
+
* Heartbeat / ping-pong keepalive. Set `true` for defaults (30s interval, 10s timeout)
|
|
25
|
+
* or provide an object to customize intervals.
|
|
26
|
+
*/
|
|
27
|
+
heartbeat?: boolean | HeartbeatConfig;
|
|
28
|
+
/**
|
|
29
|
+
* Presence tracking. Set `true` for defaults or provide config.
|
|
30
|
+
* When enabled, `presence_join`/`presence_leave` events are broadcast to rooms.
|
|
31
|
+
*/
|
|
32
|
+
presence?: boolean | {
|
|
33
|
+
broadcastEvents?: boolean;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Message persistence. Opt rooms in via `configureRoom()`.
|
|
37
|
+
*/
|
|
38
|
+
persistence?: {
|
|
39
|
+
store?: WsMessageStore;
|
|
40
|
+
defaults?: WsMessageDefaults;
|
|
41
|
+
};
|
|
21
42
|
}
|
|
22
43
|
export interface CreateServerConfig<T extends object = object> extends CreateAppConfig {
|
|
23
44
|
port?: number;
|
|
@@ -27,5 +48,10 @@ export interface CreateServerConfig<T extends object = object> extends CreateApp
|
|
|
27
48
|
enableWorkers?: boolean;
|
|
28
49
|
/** WebSocket configuration */
|
|
29
50
|
ws?: WsConfig<T>;
|
|
51
|
+
/**
|
|
52
|
+
* Maximum request body size in bytes. Defaults to the upload config limit when present
|
|
53
|
+
* (maxFileSize * maxFiles), otherwise Bun's default (128 MB).
|
|
54
|
+
*/
|
|
55
|
+
maxRequestBodySize?: number;
|
|
30
56
|
}
|
|
31
57
|
export declare const createServer: <T extends object = object>(config: CreateServerConfig<T>) => Promise<Server<SocketData<T>>>;
|
package/dist/server.js
CHANGED
|
@@ -1,17 +1,44 @@
|
|
|
1
1
|
import { createApp } from "./app";
|
|
2
2
|
import { websocket as defaultWebsocket, createWsUpgradeHandler } from "./ws/index";
|
|
3
|
-
import { setWsServer, handleRoomActions, cleanupSocket } from "./lib/ws";
|
|
3
|
+
import { setWsServer, handleRoomActions, cleanupSocket, setPresenceEnabled } from "./lib/ws";
|
|
4
|
+
import { registerSocket, deregisterSocket, handlePong, startHeartbeat, stopHeartbeat } from "./lib/wsHeartbeat";
|
|
5
|
+
import { trackSocket, untrackSocket } from "./lib/wsPresence";
|
|
6
|
+
import { setWsMessageStore, setWsMessageDefaults } from "./lib/wsMessages";
|
|
4
7
|
import { log } from "./lib/logger";
|
|
5
8
|
export const createServer = async (config) => {
|
|
6
9
|
const app = await createApp(config);
|
|
7
10
|
const port = Number(process.env.PORT ?? config.port ?? 3000);
|
|
8
11
|
const { workersDir, enableWorkers = true, ws: wsConfig = {} } = config;
|
|
9
|
-
|
|
12
|
+
// Compute maxRequestBodySize: explicit config wins, else derive from upload config
|
|
13
|
+
let maxRequestBodySize = config.maxRequestBodySize;
|
|
14
|
+
if (maxRequestBodySize === undefined && config.upload) {
|
|
15
|
+
const maxFileSize = config.upload.maxFileSize ?? 10 * 1024 * 1024;
|
|
16
|
+
const maxFiles = config.upload.maxFiles ?? 10;
|
|
17
|
+
maxRequestBodySize = maxFileSize * maxFiles;
|
|
18
|
+
}
|
|
19
|
+
const { handler: userWs, upgradeHandler: wsUpgradeHandler, onRoomSubscribe, maxMessageSize = 65_536, heartbeat: heartbeatConfig, presence: presenceConfig, persistence: persistenceConfig, } = wsConfig;
|
|
20
|
+
// Configure presence
|
|
21
|
+
if (presenceConfig)
|
|
22
|
+
setPresenceEnabled(true);
|
|
23
|
+
// Configure message persistence
|
|
24
|
+
if (persistenceConfig) {
|
|
25
|
+
if (persistenceConfig.store)
|
|
26
|
+
setWsMessageStore(persistenceConfig.store);
|
|
27
|
+
if (persistenceConfig.defaults)
|
|
28
|
+
setWsMessageDefaults(persistenceConfig.defaults);
|
|
29
|
+
}
|
|
10
30
|
const defaultOpen = defaultWebsocket.open;
|
|
11
31
|
const defaultClose = defaultWebsocket.close;
|
|
12
32
|
const defaultDrain = defaultWebsocket.drain;
|
|
33
|
+
const heartbeatEnabled = !!heartbeatConfig;
|
|
13
34
|
const ws = {
|
|
14
|
-
open
|
|
35
|
+
open(socket) {
|
|
36
|
+
if (heartbeatEnabled)
|
|
37
|
+
registerSocket(socket, socket.data.id);
|
|
38
|
+
if (presenceConfig)
|
|
39
|
+
trackSocket(socket.data.id, socket.data.userId);
|
|
40
|
+
(userWs?.open ?? defaultOpen)(socket);
|
|
41
|
+
},
|
|
15
42
|
async message(socket, message) {
|
|
16
43
|
const size = typeof message === "string" ? message.length : message.byteLength;
|
|
17
44
|
if (size > maxMessageSize) {
|
|
@@ -26,10 +53,18 @@ export const createServer = async (config) => {
|
|
|
26
53
|
}
|
|
27
54
|
},
|
|
28
55
|
close(socket, code, reason) {
|
|
56
|
+
if (heartbeatEnabled)
|
|
57
|
+
deregisterSocket(socket.data.id);
|
|
58
|
+
if (presenceConfig)
|
|
59
|
+
untrackSocket(socket.data.id);
|
|
29
60
|
cleanupSocket(socket.data.id, socket.data.rooms);
|
|
30
61
|
socket.data.rooms.clear();
|
|
31
62
|
(userWs?.close ?? defaultClose)(socket, code, reason);
|
|
32
63
|
},
|
|
64
|
+
pong(socket) {
|
|
65
|
+
if (heartbeatEnabled)
|
|
66
|
+
handlePong(socket.data.id);
|
|
67
|
+
},
|
|
33
68
|
drain: userWs?.drain ?? defaultDrain,
|
|
34
69
|
};
|
|
35
70
|
let server;
|
|
@@ -42,12 +77,20 @@ export const createServer = async (config) => {
|
|
|
42
77
|
},
|
|
43
78
|
fetch: app.fetch,
|
|
44
79
|
websocket: ws,
|
|
80
|
+
...(maxRequestBodySize !== undefined ? { maxRequestBodySize } : {}),
|
|
45
81
|
error(err) {
|
|
46
82
|
console.error(err);
|
|
47
83
|
return Response.json({ error: "Internal Server Error" }, { status: 500 });
|
|
48
84
|
},
|
|
49
85
|
});
|
|
50
86
|
setWsServer(server);
|
|
87
|
+
// Start heartbeat after server is ready
|
|
88
|
+
if (heartbeatEnabled)
|
|
89
|
+
startHeartbeat(heartbeatConfig);
|
|
90
|
+
// Graceful shutdown — stop heartbeat alongside existing cleanup
|
|
91
|
+
const gracefulShutdown = () => { stopHeartbeat(); };
|
|
92
|
+
process.on("SIGTERM", gracefulShutdown);
|
|
93
|
+
process.on("SIGINT", gracefulShutdown);
|
|
51
94
|
if (enableWorkers && workersDir) {
|
|
52
95
|
const glob = new Bun.Glob("**/*.ts");
|
|
53
96
|
for await (const file of glob.scan({ cwd: workersDir })) {
|
package/dist/ws/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { verifyToken } from "../lib/jwt";
|
|
2
2
|
import { getSession } from "../lib/session";
|
|
3
3
|
import { COOKIE_TOKEN } from "../lib/constants";
|
|
4
|
+
import { trackSocket, untrackSocket } from "../lib/wsPresence";
|
|
4
5
|
export const createWsUpgradeHandler = (server) => async (req) => {
|
|
5
6
|
let userId = null;
|
|
6
7
|
try {
|
|
@@ -22,6 +23,7 @@ export const createWsUpgradeHandler = (server) => async (req) => {
|
|
|
22
23
|
};
|
|
23
24
|
export const websocket = {
|
|
24
25
|
open(ws) {
|
|
26
|
+
trackSocket(ws.data.id, ws.data.userId);
|
|
25
27
|
console.log(`[ws] connected: ${ws.data.id}`);
|
|
26
28
|
ws.send(JSON.stringify({ event: "connected", id: ws.data.id }));
|
|
27
29
|
},
|
|
@@ -30,6 +32,7 @@ export const websocket = {
|
|
|
30
32
|
// Override ws.handler.message in WsConfig for custom message handling.
|
|
31
33
|
},
|
|
32
34
|
close(ws) {
|
|
35
|
+
untrackSocket(ws.data.id);
|
|
33
36
|
console.log(`[ws] disconnected: ${ws.data.id}`);
|
|
34
37
|
},
|
|
35
38
|
};
|