@spfn/core 0.2.0-beta.9 → 0.3.0-beta.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/LICENSE +1 -1
- package/README.md +467 -305
- package/dist/authz/index.d.ts +34 -0
- package/dist/authz/index.js +810 -0
- package/dist/authz/index.js.map +1 -0
- package/dist/{boss-DI1r4kTS.d.ts → boss-D16fO2oG.d.ts} +41 -1
- package/dist/cache/index.js +42 -30
- package/dist/cache/index.js.map +1 -1
- package/dist/codegen/index.d.ts +121 -13
- package/dist/codegen/index.js +212 -15
- package/dist/codegen/index.js.map +1 -1
- package/dist/config/index.d.ts +615 -6
- package/dist/config/index.js +124 -5
- package/dist/config/index.js.map +1 -1
- package/dist/contract/index.d.ts +220 -0
- package/dist/contract/index.js +558 -0
- package/dist/contract/index.js.map +1 -0
- package/dist/db/index.d.ts +528 -85
- package/dist/db/index.js +831 -122
- package/dist/db/index.js.map +1 -1
- package/dist/define-middleware-DfDP39Nq.d.ts +167 -0
- package/dist/env/index.d.ts +26 -2
- package/dist/env/index.js +15 -5
- package/dist/env/index.js.map +1 -1
- package/dist/env/loader.d.ts +26 -19
- package/dist/env/loader.js +32 -25
- package/dist/env/loader.js.map +1 -1
- package/dist/errors/index.d.ts +10 -0
- package/dist/errors/index.js +418 -5
- package/dist/errors/index.js.map +1 -1
- package/dist/event/index.d.ts +33 -3
- package/dist/event/index.js +24 -3
- package/dist/event/index.js.map +1 -1
- package/dist/event/sse/client.d.ts +42 -3
- package/dist/event/sse/client.js +128 -45
- package/dist/event/sse/client.js.map +1 -1
- package/dist/event/sse/index.d.ts +12 -5
- package/dist/event/sse/index.js +280 -32
- package/dist/event/sse/index.js.map +1 -1
- package/dist/event/ws/client.d.ts +59 -0
- package/dist/event/ws/client.js +273 -0
- package/dist/event/ws/client.js.map +1 -0
- package/dist/event/ws/index.d.ts +94 -0
- package/dist/event/ws/index.js +272 -0
- package/dist/event/ws/index.js.map +1 -0
- package/dist/job/index.d.ts +2 -2
- package/dist/job/index.js +155 -42
- package/dist/job/index.js.map +1 -1
- package/dist/logger/index.d.ts +5 -0
- package/dist/logger/index.js +14 -0
- package/dist/logger/index.js.map +1 -1
- package/dist/middleware/index.d.ts +347 -9
- package/dist/middleware/index.js +1462 -15
- package/dist/middleware/index.js.map +1 -1
- package/dist/nextjs/index.d.ts +2 -2
- package/dist/nextjs/index.js +42 -28
- package/dist/nextjs/index.js.map +1 -1
- package/dist/nextjs/server.d.ts +35 -51
- package/dist/nextjs/server.js +126 -60
- package/dist/nextjs/server.js.map +1 -1
- package/dist/ops/index.d.ts +152 -0
- package/dist/ops/index.js +500 -0
- package/dist/ops/index.js.map +1 -0
- package/dist/route/index.d.ts +8 -694
- package/dist/route/index.js +111 -22
- package/dist/route/index.js.map +1 -1
- package/dist/router-Qbssr11H.d.ts +676 -0
- package/dist/security/index.d.ts +83 -0
- package/dist/security/index.js +173 -0
- package/dist/security/index.js.map +1 -0
- package/dist/server/index.d.ts +491 -22
- package/dist/server/index.js +1887 -308
- package/dist/server/index.js.map +1 -1
- package/dist/token-manager-BT5EnUAR.d.ts +278 -0
- package/dist/types-2AbaW4Ie.d.ts +205 -0
- package/dist/{types-BOPTApC2.d.ts → types-9oszaJqp.d.ts} +7 -2
- package/dist/types-D1c57Ko-.d.ts +115 -0
- package/dist/types-ZQODsBft.d.ts +282 -0
- package/package.json +244 -208
- package/dist/router-Di7ENoah.d.ts +0 -151
- package/dist/types-B-e_f2dQ.d.ts +0 -121
- package/docs/cache.md +0 -133
- package/docs/codegen.md +0 -74
- package/docs/database.md +0 -346
- package/docs/entity.md +0 -539
- package/docs/env.md +0 -477
- package/docs/errors.md +0 -319
- package/docs/event.md +0 -116
- package/docs/job.md +0 -131
- package/docs/logger.md +0 -108
- package/docs/middleware.md +0 -337
- package/docs/nextjs.md +0 -241
- package/docs/repository.md +0 -496
- package/docs/route.md +0 -497
- package/docs/server.md +0 -307
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import { Context } from 'hono';
|
|
2
|
+
import { b as EventRouterDef, I as InferEventNames, e as InferEventPayload, i as SSETokenStore, S as SSETokenManager } from './token-manager-BT5EnUAR.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* SSE Types
|
|
6
|
+
*
|
|
7
|
+
* Type definitions for Server-Sent Events
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* SSE message sent from server
|
|
12
|
+
*/
|
|
13
|
+
interface SSEMessage<TEvent extends string = string, TPayload = unknown> {
|
|
14
|
+
/** Event name */
|
|
15
|
+
event: TEvent;
|
|
16
|
+
/** Event payload */
|
|
17
|
+
data: TPayload;
|
|
18
|
+
/** Optional message ID for reconnection */
|
|
19
|
+
id?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* SSE auth configuration (internal, non-generic)
|
|
23
|
+
*
|
|
24
|
+
* Stored in SSEHandlerConfig. Generic user-facing version is SSEAuthConfig.
|
|
25
|
+
*/
|
|
26
|
+
interface SSEHandlerAuthConfig {
|
|
27
|
+
/**
|
|
28
|
+
* Enable SSE token authentication
|
|
29
|
+
* @default false
|
|
30
|
+
*/
|
|
31
|
+
enabled?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Token TTL in milliseconds
|
|
34
|
+
* @default 30000
|
|
35
|
+
*/
|
|
36
|
+
tokenTtl?: number;
|
|
37
|
+
/**
|
|
38
|
+
* Custom token store (e.g., Redis for multi-instance)
|
|
39
|
+
*/
|
|
40
|
+
store?: SSETokenStore;
|
|
41
|
+
/**
|
|
42
|
+
* External token manager instance or lazy resolver.
|
|
43
|
+
*
|
|
44
|
+
* When provided, the SSE system uses this manager instead of creating its own.
|
|
45
|
+
* Useful for sharing a single token manager with auth package's one-time token system.
|
|
46
|
+
*
|
|
47
|
+
* Use a function when the manager is not available at module load time
|
|
48
|
+
* (e.g. initialized in a lifecycle hook that runs after config evaluation).
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* import { getOneTimeTokenManager } from '@spfn/auth/server';
|
|
53
|
+
*
|
|
54
|
+
* // Lazy resolver (recommended — avoids timing issues)
|
|
55
|
+
* .events(eventRouter, {
|
|
56
|
+
* auth: {
|
|
57
|
+
* enabled: true,
|
|
58
|
+
* tokenManager: () => getOneTimeTokenManager(),
|
|
59
|
+
* },
|
|
60
|
+
* })
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
tokenManager?: SSETokenManager | (() => SSETokenManager);
|
|
64
|
+
/**
|
|
65
|
+
* Extract subject (user ID) from Hono context
|
|
66
|
+
* @default (c) => c.get('auth')?.userId ?? null
|
|
67
|
+
*/
|
|
68
|
+
getSubject?: (c: Context) => string | null;
|
|
69
|
+
/**
|
|
70
|
+
* Subscription authorization hook (called once on connect)
|
|
71
|
+
*
|
|
72
|
+
* Return allowed events subset. Empty array = 403 rejection.
|
|
73
|
+
*/
|
|
74
|
+
authorize?: (subject: string, events: string[]) => Promise<string[]> | string[];
|
|
75
|
+
/**
|
|
76
|
+
* Per-event payload filter map (called on every event emission)
|
|
77
|
+
*
|
|
78
|
+
* Return false to skip sending the event to this user.
|
|
79
|
+
*/
|
|
80
|
+
filter?: Record<string, (subject: string, payload: unknown) => boolean>;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* SSE auth configuration (user-facing, generic)
|
|
84
|
+
*
|
|
85
|
+
* Provides type-safe event names and payload inference from EventRouter.
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```typescript
|
|
89
|
+
* .events(eventRouter, {
|
|
90
|
+
* auth: {
|
|
91
|
+
* enabled: true,
|
|
92
|
+
* authorize: async (subject, events) => {
|
|
93
|
+
* // events: ('userCreated' | 'orderUpdated')[]
|
|
94
|
+
* return events.filter(e => hasPermission(subject, e));
|
|
95
|
+
* },
|
|
96
|
+
* filter: {
|
|
97
|
+
* orderUpdated: (subject, payload) => {
|
|
98
|
+
* // payload: { orderId: string; userId: string }
|
|
99
|
+
* return payload.userId === subject;
|
|
100
|
+
* },
|
|
101
|
+
* },
|
|
102
|
+
* },
|
|
103
|
+
* })
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
interface SSEAuthConfig<TRouter extends EventRouterDef<any>> {
|
|
107
|
+
enabled?: boolean;
|
|
108
|
+
tokenTtl?: number;
|
|
109
|
+
store?: SSETokenStore;
|
|
110
|
+
tokenManager?: SSETokenManager | (() => SSETokenManager);
|
|
111
|
+
getSubject?: (c: Context) => string | null;
|
|
112
|
+
authorize?: (subject: string, events: InferEventNames<TRouter>[]) => Promise<InferEventNames<TRouter>[]> | InferEventNames<TRouter>[];
|
|
113
|
+
filter?: {
|
|
114
|
+
[K in InferEventNames<TRouter>]?: (subject: string, payload: InferEventPayload<TRouter, K>) => boolean;
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* SSE Handler configuration
|
|
119
|
+
*/
|
|
120
|
+
interface SSEHandlerConfig {
|
|
121
|
+
/**
|
|
122
|
+
* Keep-alive ping interval in milliseconds
|
|
123
|
+
* @default 10000
|
|
124
|
+
*/
|
|
125
|
+
pingInterval?: number;
|
|
126
|
+
/**
|
|
127
|
+
* Custom headers for SSE response
|
|
128
|
+
*/
|
|
129
|
+
headers?: Record<string, string>;
|
|
130
|
+
/**
|
|
131
|
+
* Max outbound frames buffered per connection before a slow consumer is
|
|
132
|
+
* dropped (connection closed). Bounds memory under a fast producer + slow
|
|
133
|
+
* client; the client reconnects rather than receiving corrupted/partial data.
|
|
134
|
+
* @default 1000
|
|
135
|
+
*/
|
|
136
|
+
maxQueue?: number;
|
|
137
|
+
/**
|
|
138
|
+
* Cross-pod event broadcast via the cache (Redis/Valkey) pub/sub.
|
|
139
|
+
*
|
|
140
|
+
* When `true` (default) and a cache is configured (`CACHE_URL`), each event
|
|
141
|
+
* is auto-wired so an `emit` on one pod reaches subscribers on every pod.
|
|
142
|
+
* Without a cache this is a no-op (events stay in-process). Set `false` to
|
|
143
|
+
* force in-process even when a cache is present.
|
|
144
|
+
*
|
|
145
|
+
* @default true
|
|
146
|
+
*/
|
|
147
|
+
multiInstance?: boolean;
|
|
148
|
+
/**
|
|
149
|
+
* Pub/sub channel prefix for cross-pod broadcast.
|
|
150
|
+
*
|
|
151
|
+
* Defaults to env `SPFN_SSE_CHANNEL_PREFIX`, else `spfn:sse:`. Use distinct
|
|
152
|
+
* prefixes to isolate apps/tenants that share one Redis instance.
|
|
153
|
+
*/
|
|
154
|
+
channelPrefix?: string;
|
|
155
|
+
/**
|
|
156
|
+
* Authentication and authorization configuration
|
|
157
|
+
*/
|
|
158
|
+
auth?: SSEHandlerAuthConfig;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* SSE Client configuration
|
|
162
|
+
*/
|
|
163
|
+
interface SSEClientConfig {
|
|
164
|
+
/**
|
|
165
|
+
* Backend API host URL
|
|
166
|
+
* @default NEXT_PUBLIC_SPFN_API_URL || 'http://localhost:8790'
|
|
167
|
+
* @example 'http://localhost:8790'
|
|
168
|
+
* @example 'https://api.example.com'
|
|
169
|
+
*/
|
|
170
|
+
host?: string;
|
|
171
|
+
/**
|
|
172
|
+
* SSE endpoint pathname
|
|
173
|
+
* @default '/events/stream'
|
|
174
|
+
*/
|
|
175
|
+
pathname?: string;
|
|
176
|
+
/**
|
|
177
|
+
* Full URL (overrides host + pathname)
|
|
178
|
+
* @deprecated Use host and pathname instead
|
|
179
|
+
* @example 'http://localhost:8790/events/stream'
|
|
180
|
+
*/
|
|
181
|
+
url?: string;
|
|
182
|
+
/**
|
|
183
|
+
* Auto reconnect on disconnect
|
|
184
|
+
* @default true
|
|
185
|
+
*/
|
|
186
|
+
reconnect?: boolean;
|
|
187
|
+
/**
|
|
188
|
+
* Reconnect delay in milliseconds
|
|
189
|
+
* @default 3000
|
|
190
|
+
*/
|
|
191
|
+
reconnectDelay?: number;
|
|
192
|
+
/**
|
|
193
|
+
* Maximum reconnect attempts (0 = infinite)
|
|
194
|
+
* @default 0
|
|
195
|
+
*/
|
|
196
|
+
maxReconnectAttempts?: number;
|
|
197
|
+
/**
|
|
198
|
+
* Include credentials (cookies) in request
|
|
199
|
+
* @default false
|
|
200
|
+
*/
|
|
201
|
+
withCredentials?: boolean;
|
|
202
|
+
/**
|
|
203
|
+
* Acquire a one-time SSE token before connecting.
|
|
204
|
+
*
|
|
205
|
+
* Called on every (re)connect. The returned token is appended
|
|
206
|
+
* to the SSE URL as `?token=...`.
|
|
207
|
+
*
|
|
208
|
+
* For automatic token acquisition via RPC proxy, use `createAuthSSEClient` instead.
|
|
209
|
+
*
|
|
210
|
+
* @example
|
|
211
|
+
* ```typescript
|
|
212
|
+
* // Recommended: use createAuthSSEClient for automatic token handling
|
|
213
|
+
* import { createAuthSSEClient } from '@spfn/core/event/sse/client';
|
|
214
|
+
* const client = createAuthSSEClient<EventRouter>();
|
|
215
|
+
*
|
|
216
|
+
* // Manual: provide acquireToken directly
|
|
217
|
+
* acquireToken: async () => {
|
|
218
|
+
* const res = await fetch('/api/rpc/eventsToken', {
|
|
219
|
+
* method: 'POST',
|
|
220
|
+
* credentials: 'include',
|
|
221
|
+
* });
|
|
222
|
+
* const data = await res.json();
|
|
223
|
+
* return data.token;
|
|
224
|
+
* }
|
|
225
|
+
* ```
|
|
226
|
+
*/
|
|
227
|
+
acquireToken?: () => Promise<string>;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Event handler function
|
|
231
|
+
*/
|
|
232
|
+
type SSEEventHandler<TPayload> = (payload: TPayload) => void;
|
|
233
|
+
/**
|
|
234
|
+
* Event handlers map for EventRouter
|
|
235
|
+
*/
|
|
236
|
+
type SSEEventHandlers<TRouter extends EventRouterDef<any>> = {
|
|
237
|
+
[K in InferEventNames<TRouter>]?: SSEEventHandler<InferEventPayload<TRouter, K>>;
|
|
238
|
+
};
|
|
239
|
+
/**
|
|
240
|
+
* Subscription options
|
|
241
|
+
*/
|
|
242
|
+
interface SSESubscribeOptions<TRouter extends EventRouterDef<any>> {
|
|
243
|
+
/**
|
|
244
|
+
* Events to subscribe
|
|
245
|
+
*/
|
|
246
|
+
events: InferEventNames<TRouter>[];
|
|
247
|
+
/**
|
|
248
|
+
* Event handlers
|
|
249
|
+
*/
|
|
250
|
+
handlers: SSEEventHandlers<TRouter>;
|
|
251
|
+
/**
|
|
252
|
+
* Called when connection opens
|
|
253
|
+
*/
|
|
254
|
+
onOpen?: () => void;
|
|
255
|
+
/**
|
|
256
|
+
* Called on connection error
|
|
257
|
+
*/
|
|
258
|
+
onError?: (error: Event) => void;
|
|
259
|
+
/**
|
|
260
|
+
* Called when connection is permanently closed
|
|
261
|
+
*
|
|
262
|
+
* Triggered when:
|
|
263
|
+
* - unsubscribe() is called
|
|
264
|
+
* - client.close() is called
|
|
265
|
+
* - Max reconnect attempts exceeded
|
|
266
|
+
*/
|
|
267
|
+
onClose?: () => void;
|
|
268
|
+
/**
|
|
269
|
+
* Called when reconnecting
|
|
270
|
+
*/
|
|
271
|
+
onReconnect?: (attempt: number) => void;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* SSE connection state
|
|
275
|
+
*/
|
|
276
|
+
type SSEConnectionState = 'connecting' | 'open' | 'closed' | 'error';
|
|
277
|
+
/**
|
|
278
|
+
* Unsubscribe function
|
|
279
|
+
*/
|
|
280
|
+
type SSEUnsubscribe = () => void;
|
|
281
|
+
|
|
282
|
+
export type { SSEClientConfig as S, SSESubscribeOptions as a, SSEUnsubscribe as b, SSEConnectionState as c, SSEHandlerConfig as d, SSEAuthConfig as e, SSEEventHandler as f, SSEEventHandlers as g, SSEHandlerAuthConfig as h, SSEMessage as i };
|