@spfn/core 0.1.0-alpha.88 → 0.2.0-beta.10
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 +298 -466
- package/dist/boss-DI1r4kTS.d.ts +244 -0
- package/dist/cache/index.d.ts +13 -33
- package/dist/cache/index.js +14 -703
- package/dist/cache/index.js.map +1 -1
- package/dist/codegen/index.d.ts +214 -17
- package/dist/codegen/index.js +231 -1420
- package/dist/codegen/index.js.map +1 -1
- package/dist/config/index.d.ts +1227 -0
- package/dist/config/index.js +273 -0
- package/dist/config/index.js.map +1 -0
- package/dist/db/index.d.ts +741 -59
- package/dist/db/index.js +1063 -1226
- package/dist/db/index.js.map +1 -1
- package/dist/env/index.d.ts +658 -308
- package/dist/env/index.js +503 -928
- package/dist/env/index.js.map +1 -1
- package/dist/env/loader.d.ts +87 -0
- package/dist/env/loader.js +70 -0
- package/dist/env/loader.js.map +1 -0
- package/dist/errors/index.d.ts +417 -29
- package/dist/errors/index.js +359 -98
- package/dist/errors/index.js.map +1 -1
- package/dist/event/index.d.ts +41 -0
- package/dist/event/index.js +131 -0
- package/dist/event/index.js.map +1 -0
- package/dist/event/sse/client.d.ts +82 -0
- package/dist/event/sse/client.js +115 -0
- package/dist/event/sse/client.js.map +1 -0
- package/dist/event/sse/index.d.ts +40 -0
- package/dist/event/sse/index.js +92 -0
- package/dist/event/sse/index.js.map +1 -0
- package/dist/job/index.d.ts +218 -0
- package/dist/job/index.js +410 -0
- package/dist/job/index.js.map +1 -0
- package/dist/logger/index.d.ts +20 -79
- package/dist/logger/index.js +82 -387
- package/dist/logger/index.js.map +1 -1
- package/dist/middleware/index.d.ts +102 -20
- package/dist/middleware/index.js +51 -705
- package/dist/middleware/index.js.map +1 -1
- package/dist/nextjs/index.d.ts +120 -0
- package/dist/nextjs/index.js +448 -0
- package/dist/nextjs/index.js.map +1 -0
- package/dist/{client/nextjs/index.d.ts → nextjs/server.d.ts} +335 -262
- package/dist/nextjs/server.js +637 -0
- package/dist/nextjs/server.js.map +1 -0
- package/dist/route/index.d.ts +879 -25
- package/dist/route/index.js +697 -1271
- package/dist/route/index.js.map +1 -1
- package/dist/route/types.d.ts +9 -0
- package/dist/route/types.js +3 -0
- package/dist/route/types.js.map +1 -0
- package/dist/router-Di7ENoah.d.ts +151 -0
- package/dist/server/index.d.ts +345 -64
- package/dist/server/index.js +1174 -3233
- package/dist/server/index.js.map +1 -1
- package/dist/types-B-e_f2dQ.d.ts +121 -0
- package/dist/types-BGl4QL1w.d.ts +77 -0
- package/dist/types-BOPTApC2.d.ts +245 -0
- package/docs/cache.md +133 -0
- package/docs/codegen.md +74 -0
- package/docs/database.md +346 -0
- package/docs/entity.md +539 -0
- package/docs/env.md +477 -0
- package/docs/errors.md +319 -0
- package/docs/event.md +116 -0
- package/docs/file-upload.md +717 -0
- package/docs/job.md +131 -0
- package/docs/logger.md +108 -0
- package/docs/middleware.md +337 -0
- package/docs/nextjs.md +241 -0
- package/docs/repository.md +496 -0
- package/docs/route.md +497 -0
- package/docs/server.md +307 -0
- package/package.json +68 -48
- package/dist/auto-loader-JFaZ9gON.d.ts +0 -80
- package/dist/client/index.d.ts +0 -358
- package/dist/client/index.js +0 -357
- package/dist/client/index.js.map +0 -1
- package/dist/client/nextjs/index.js +0 -371
- package/dist/client/nextjs/index.js.map +0 -1
- package/dist/codegen/generators/index.d.ts +0 -19
- package/dist/codegen/generators/index.js +0 -1404
- package/dist/codegen/generators/index.js.map +0 -1
- package/dist/database-errors-BNNmLTJE.d.ts +0 -86
- package/dist/events/index.d.ts +0 -183
- package/dist/events/index.js +0 -77
- package/dist/events/index.js.map +0 -1
- package/dist/index-DHiAqhKv.d.ts +0 -101
- package/dist/index.d.ts +0 -8
- package/dist/index.js +0 -3674
- package/dist/index.js.map +0 -1
- package/dist/types/index.d.ts +0 -121
- package/dist/types/index.js +0 -38
- package/dist/types/index.js.map +0 -1
- package/dist/types-BXibIEyj.d.ts +0 -60
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { TSchema } from '@sinclair/typebox';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Event System Types
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Pub/Sub capable cache interface for multi-instance events
|
|
9
|
+
*/
|
|
10
|
+
interface PubSubCache {
|
|
11
|
+
/**
|
|
12
|
+
* Publish a message to a channel
|
|
13
|
+
*/
|
|
14
|
+
publish(channel: string, message: unknown): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Subscribe to a channel
|
|
17
|
+
*/
|
|
18
|
+
subscribe(channel: string, handler: (message: unknown) => void | Promise<void>): Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Event handler function type
|
|
22
|
+
*/
|
|
23
|
+
type EventHandler<TPayload> = (payload: TPayload) => void | Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Job queue sender function type (used by job module)
|
|
26
|
+
*/
|
|
27
|
+
type JobQueueSender = (queueName: string, payload: unknown) => Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Event definition interface
|
|
30
|
+
*/
|
|
31
|
+
interface EventDef<TPayload = void> {
|
|
32
|
+
/**
|
|
33
|
+
* Unique event name
|
|
34
|
+
*/
|
|
35
|
+
readonly name: string;
|
|
36
|
+
/**
|
|
37
|
+
* TypeBox payload schema (optional)
|
|
38
|
+
*/
|
|
39
|
+
readonly schema?: TSchema;
|
|
40
|
+
/**
|
|
41
|
+
* Subscribe to this event (in-memory handler)
|
|
42
|
+
*/
|
|
43
|
+
subscribe: (handler: EventHandler<TPayload>) => () => void;
|
|
44
|
+
/**
|
|
45
|
+
* Unsubscribe all handlers
|
|
46
|
+
*/
|
|
47
|
+
unsubscribeAll: () => void;
|
|
48
|
+
/**
|
|
49
|
+
* Emit the event (triggers all subscribers and queued jobs)
|
|
50
|
+
*/
|
|
51
|
+
emit: TPayload extends void ? () => Promise<void> : (payload: TPayload) => Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Enable cache-based pub/sub for multi-instance support
|
|
54
|
+
* Must await before emitting events to ensure subscription is ready
|
|
55
|
+
*/
|
|
56
|
+
useCache: (cache: PubSubCache) => Promise<EventDef<TPayload>>;
|
|
57
|
+
/**
|
|
58
|
+
* Internal: Register a job queue to receive this event
|
|
59
|
+
* Called by job registration system
|
|
60
|
+
*/
|
|
61
|
+
_registerJobQueue: (queueName: string, sender: JobQueueSender) => void;
|
|
62
|
+
/**
|
|
63
|
+
* Type inference helper
|
|
64
|
+
*/
|
|
65
|
+
_payload: TPayload;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Infer payload type from EventDef
|
|
69
|
+
*/
|
|
70
|
+
type InferEventPayload$1<TEvent> = TEvent extends EventDef<infer TPayload> ? TPayload : never;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Event Router
|
|
74
|
+
*
|
|
75
|
+
* Type-safe event router for SSE subscription
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```typescript
|
|
79
|
+
* import { defineEvent, defineEventRouter } from '@spfn/core/event';
|
|
80
|
+
* import { Type } from '@sinclair/typebox';
|
|
81
|
+
*
|
|
82
|
+
* const userCreated = defineEvent('user.created', Type.Object({
|
|
83
|
+
* userId: Type.String(),
|
|
84
|
+
* }));
|
|
85
|
+
*
|
|
86
|
+
* const orderPlaced = defineEvent('order.placed', Type.Object({
|
|
87
|
+
* orderId: Type.String(),
|
|
88
|
+
* amount: Type.Number(),
|
|
89
|
+
* }));
|
|
90
|
+
*
|
|
91
|
+
* export const eventRouter = defineEventRouter({
|
|
92
|
+
* userCreated,
|
|
93
|
+
* orderPlaced,
|
|
94
|
+
* });
|
|
95
|
+
*
|
|
96
|
+
* export type EventRouter = typeof eventRouter;
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Event Router Definition
|
|
102
|
+
*/
|
|
103
|
+
interface EventRouterDef<TEvents extends Record<string, EventDef<any>>> {
|
|
104
|
+
/**
|
|
105
|
+
* Event definitions
|
|
106
|
+
*/
|
|
107
|
+
readonly events: TEvents;
|
|
108
|
+
/**
|
|
109
|
+
* Event names as array
|
|
110
|
+
*/
|
|
111
|
+
readonly eventNames: (keyof TEvents)[];
|
|
112
|
+
/**
|
|
113
|
+
* Type inference helper - payload types by event name
|
|
114
|
+
*/
|
|
115
|
+
readonly _types: {
|
|
116
|
+
[K in keyof TEvents]: TEvents[K]['_payload'];
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Infer event names from EventRouter
|
|
121
|
+
*/
|
|
122
|
+
type InferEventNames<T> = T extends EventRouterDef<infer E> ? keyof E & string : never;
|
|
123
|
+
/**
|
|
124
|
+
* Infer payload type for specific event
|
|
125
|
+
*/
|
|
126
|
+
type InferEventPayload<T extends EventRouterDef<any>, K extends InferEventNames<T>> = T['_types'][K];
|
|
127
|
+
/**
|
|
128
|
+
* Infer all event payloads map
|
|
129
|
+
*/
|
|
130
|
+
type InferEventPayloads<T extends EventRouterDef<any>> = T['_types'];
|
|
131
|
+
/**
|
|
132
|
+
* Define an event router for SSE subscription
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```typescript
|
|
136
|
+
* export const eventRouter = defineEventRouter({
|
|
137
|
+
* userCreated,
|
|
138
|
+
* orderPlaced,
|
|
139
|
+
* });
|
|
140
|
+
*
|
|
141
|
+
* // Type inference
|
|
142
|
+
* type Names = InferEventNames<typeof eventRouter>;
|
|
143
|
+
* // 'userCreated' | 'orderPlaced'
|
|
144
|
+
*
|
|
145
|
+
* type Payload = InferEventPayload<typeof eventRouter, 'userCreated'>;
|
|
146
|
+
* // { userId: string }
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
149
|
+
declare function defineEventRouter<TEvents extends Record<string, EventDef<any>>>(events: TEvents): EventRouterDef<TEvents>;
|
|
150
|
+
|
|
151
|
+
export { type EventRouterDef as E, type InferEventNames as I, type JobQueueSender as J, type PubSubCache as P, type EventDef as a, type InferEventPayload as b, type InferEventPayloads as c, defineEventRouter as d, type EventHandler as e, type InferEventPayload$1 as f };
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,62 +1,47 @@
|
|
|
1
1
|
import { MiddlewareHandler, Hono } from 'hono';
|
|
2
2
|
import { cors } from 'hono/cors';
|
|
3
3
|
import { serve } from '@hono/node-server';
|
|
4
|
+
import { NamedMiddleware, Router } from '@spfn/core/route';
|
|
5
|
+
import { J as JobRouter, B as BossOptions } from '../boss-DI1r4kTS.js';
|
|
6
|
+
import { E as EventRouterDef } from '../router-Di7ENoah.js';
|
|
7
|
+
import { S as SSEHandlerConfig } from '../types-B-e_f2dQ.js';
|
|
8
|
+
import '@sinclair/typebox';
|
|
9
|
+
import 'pg-boss';
|
|
4
10
|
|
|
5
11
|
/**
|
|
6
|
-
*
|
|
12
|
+
* Load environment files for SPFN server
|
|
13
|
+
*
|
|
14
|
+
* Priority (high → low, later files don't override):
|
|
15
|
+
* 1. .env.server.local - Server-only secrets (gitignored)
|
|
16
|
+
* 2. .env.server - Server-only defaults
|
|
17
|
+
* 3. .env.{NODE_ENV}.local
|
|
18
|
+
* 4. .env.local - Local overrides (gitignored)
|
|
19
|
+
* 5. .env.{NODE_ENV}
|
|
20
|
+
* 6. .env - Defaults
|
|
7
21
|
*/
|
|
8
|
-
|
|
22
|
+
declare function loadEnvFiles(): void;
|
|
23
|
+
|
|
9
24
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* Allows packages to automatically hook into server lifecycle
|
|
13
|
-
* Plugins are auto-discovered from @spfn/* packages in node_modules
|
|
25
|
+
* Workflow router interface for @spfn/core integration
|
|
14
26
|
*
|
|
15
|
-
* @
|
|
16
|
-
*
|
|
17
|
-
* // packages/auth/src/plugin.ts
|
|
18
|
-
* export const spfnPlugin: ServerPlugin = {
|
|
19
|
-
* name: '@spfn/auth',
|
|
20
|
-
* afterInfrastructure: async () => {
|
|
21
|
-
* await initializeAuth();
|
|
22
|
-
* },
|
|
23
|
-
* beforeRoutes: async (app) => {
|
|
24
|
-
* app.route('/_auth', authRoutes);
|
|
25
|
-
* }
|
|
26
|
-
* };
|
|
27
|
-
* ```
|
|
27
|
+
* This is a minimal interface that avoids circular dependency with @spfn/workflow.
|
|
28
|
+
* The actual WorkflowRouter from @spfn/workflow implements this interface.
|
|
28
29
|
*/
|
|
29
|
-
interface
|
|
30
|
-
/**
|
|
31
|
-
* Plugin name (should match package name)
|
|
32
|
-
*/
|
|
33
|
-
name: string;
|
|
30
|
+
interface WorkflowRouterLike {
|
|
34
31
|
/**
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Hook: Run before routes are loaded
|
|
41
|
-
* Use for: mounting plugin routes, adding middleware
|
|
42
|
-
*/
|
|
43
|
-
beforeRoutes?: (app: Hono) => Promise<void>;
|
|
44
|
-
/**
|
|
45
|
-
* Hook: Run after all routes are loaded
|
|
46
|
-
* Use for: final setup, fallback handlers
|
|
47
|
-
*/
|
|
48
|
-
afterRoutes?: (app: Hono) => Promise<void>;
|
|
49
|
-
/**
|
|
50
|
-
* Hook: Run after server starts successfully
|
|
51
|
-
* Use for: notifications, health checks
|
|
52
|
-
*/
|
|
53
|
-
afterStart?: (instance: ServerInstance) => Promise<void>;
|
|
54
|
-
/**
|
|
55
|
-
* Hook: Run before graceful shutdown
|
|
56
|
-
* Use for: cleanup plugin resources
|
|
32
|
+
* Initialize the workflow engine
|
|
33
|
+
* Called by server during infrastructure initialization
|
|
34
|
+
*
|
|
35
|
+
* @internal
|
|
57
36
|
*/
|
|
58
|
-
|
|
37
|
+
_init: (db: any, options?: {
|
|
38
|
+
largeOutputThreshold?: number;
|
|
39
|
+
}) => void;
|
|
59
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* CORS configuration options - inferred from hono/cors
|
|
43
|
+
*/
|
|
44
|
+
type CorsConfig = Parameters<typeof cors>[0];
|
|
60
45
|
/**
|
|
61
46
|
* Server Configuration Options
|
|
62
47
|
*
|
|
@@ -99,28 +84,102 @@ interface ServerConfig {
|
|
|
99
84
|
use?: MiddlewareHandler[];
|
|
100
85
|
/**
|
|
101
86
|
* Global middlewares with names for route-level skip control
|
|
102
|
-
*
|
|
87
|
+
* Use defineMiddleware() for type-safe middleware definitions
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```typescript
|
|
91
|
+
* import { defineMiddleware } from '@spfn/core/server';
|
|
92
|
+
*
|
|
93
|
+
* const authMiddleware = defineMiddleware('auth', async (c, next) => {
|
|
94
|
+
* // auth logic
|
|
95
|
+
* await next();
|
|
96
|
+
* });
|
|
97
|
+
*
|
|
98
|
+
* export default defineServerConfig()
|
|
99
|
+
* .middlewares([authMiddleware, rateLimitMiddleware])
|
|
100
|
+
* .build();
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
middlewares?: readonly NamedMiddleware[];
|
|
104
|
+
/**
|
|
105
|
+
* define-route based router
|
|
106
|
+
* Routes defined with route.get()...handler() style
|
|
107
|
+
* Will be automatically registered before file-based routes
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```typescript
|
|
111
|
+
* import { defineRouter, route } from '@spfn/core/route';
|
|
112
|
+
*
|
|
113
|
+
* const appRouter = defineRouter({
|
|
114
|
+
* getUser: route.get('/users/:id')...
|
|
115
|
+
* createUser: route.post('/users')...
|
|
116
|
+
* });
|
|
117
|
+
*
|
|
118
|
+
* export default defineServerConfig()
|
|
119
|
+
* .routes(appRouter)
|
|
120
|
+
* .build();
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
routes?: Router<any>;
|
|
124
|
+
/**
|
|
125
|
+
* Background jobs router
|
|
126
|
+
* Jobs defined with job()...handler() style
|
|
127
|
+
* Uses pg-boss for PostgreSQL-based job queue
|
|
103
128
|
*
|
|
104
129
|
* @example
|
|
105
130
|
* ```typescript
|
|
106
|
-
* import {
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
131
|
+
* import { job, defineJobRouter } from '@spfn/core/job';
|
|
132
|
+
*
|
|
133
|
+
* const sendEmail = job('send-email')
|
|
134
|
+
* .input(Type.Object({ to: Type.String() }))
|
|
135
|
+
* .handler(async (input) => { ... });
|
|
136
|
+
*
|
|
137
|
+
* const jobRouter = defineJobRouter({ sendEmail });
|
|
138
|
+
*
|
|
139
|
+
* export default defineServerConfig()
|
|
140
|
+
* .routes(appRouter)
|
|
141
|
+
* .jobs(jobRouter)
|
|
142
|
+
* .build();
|
|
114
143
|
* ```
|
|
115
144
|
*/
|
|
116
|
-
|
|
117
|
-
name: string;
|
|
118
|
-
handler: MiddlewareHandler;
|
|
119
|
-
}>;
|
|
145
|
+
jobs?: JobRouter<any>;
|
|
120
146
|
/**
|
|
121
|
-
*
|
|
147
|
+
* pg-boss configuration options
|
|
148
|
+
* Only used if jobs router is provided
|
|
122
149
|
*/
|
|
123
|
-
|
|
150
|
+
jobsConfig?: Omit<BossOptions, 'connectionString'>;
|
|
151
|
+
/**
|
|
152
|
+
* Event router for SSE (Server-Sent Events) subscription
|
|
153
|
+
* Enables real-time event streaming to frontend clients
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* ```typescript
|
|
157
|
+
* import { defineEvent, defineEventRouter } from '@spfn/core/event';
|
|
158
|
+
*
|
|
159
|
+
* const userCreated = defineEvent('user.created', Type.Object({
|
|
160
|
+
* userId: Type.String(),
|
|
161
|
+
* }));
|
|
162
|
+
*
|
|
163
|
+
* const eventRouter = defineEventRouter({ userCreated });
|
|
164
|
+
*
|
|
165
|
+
* export default defineServerConfig()
|
|
166
|
+
* .routes(appRouter)
|
|
167
|
+
* .events(eventRouter) // → GET /events/stream
|
|
168
|
+
* .build();
|
|
169
|
+
* ```
|
|
170
|
+
*/
|
|
171
|
+
events?: EventRouterDef<any>;
|
|
172
|
+
/**
|
|
173
|
+
* SSE configuration options
|
|
174
|
+
* Only used if events router is provided
|
|
175
|
+
*/
|
|
176
|
+
eventsConfig?: SSEHandlerConfig & {
|
|
177
|
+
/**
|
|
178
|
+
* SSE endpoint path
|
|
179
|
+
* @default '/events/stream'
|
|
180
|
+
*/
|
|
181
|
+
path?: string;
|
|
182
|
+
};
|
|
124
183
|
/**
|
|
125
184
|
* Enable debug mode (default: NODE_ENV === 'development')
|
|
126
185
|
*/
|
|
@@ -296,6 +355,39 @@ interface ServerConfig {
|
|
|
296
355
|
*/
|
|
297
356
|
redis?: boolean;
|
|
298
357
|
};
|
|
358
|
+
/**
|
|
359
|
+
* Workflow router for workflow orchestration
|
|
360
|
+
*
|
|
361
|
+
* Automatically initializes the workflow engine after database is ready.
|
|
362
|
+
* Workflows are defined using @spfn/workflow package.
|
|
363
|
+
*
|
|
364
|
+
* @example
|
|
365
|
+
* ```typescript
|
|
366
|
+
* import { defineWorkflowRouter } from '@spfn/workflow';
|
|
367
|
+
*
|
|
368
|
+
* const workflowRouter = defineWorkflowRouter([
|
|
369
|
+
* provisionTenant,
|
|
370
|
+
* deprovisionTenant,
|
|
371
|
+
* ]);
|
|
372
|
+
*
|
|
373
|
+
* export default defineServerConfig()
|
|
374
|
+
* .workflows(workflowRouter)
|
|
375
|
+
* .build();
|
|
376
|
+
* ```
|
|
377
|
+
*/
|
|
378
|
+
workflows?: WorkflowRouterLike;
|
|
379
|
+
/**
|
|
380
|
+
* Workflow engine configuration
|
|
381
|
+
* Only used if workflows router is provided
|
|
382
|
+
*/
|
|
383
|
+
workflowsConfig?: {
|
|
384
|
+
/**
|
|
385
|
+
* Large output threshold in bytes
|
|
386
|
+
* Outputs larger than this will be stored in external storage
|
|
387
|
+
* @default 1024 * 1024 (1MB)
|
|
388
|
+
*/
|
|
389
|
+
largeOutputThreshold?: number;
|
|
390
|
+
};
|
|
299
391
|
/**
|
|
300
392
|
* Server lifecycle hooks for custom infrastructure setup and management
|
|
301
393
|
* Allows initialization of custom services and resources at different stages
|
|
@@ -456,7 +548,7 @@ declare module 'hono' {
|
|
|
456
548
|
* 2. server.config.ts -> Partial customization
|
|
457
549
|
* 3. app.ts -> Full control (no auto config)
|
|
458
550
|
*/
|
|
459
|
-
declare function createServer(config?: ServerConfig
|
|
551
|
+
declare function createServer(config?: ServerConfig): Promise<Hono>;
|
|
460
552
|
|
|
461
553
|
/**
|
|
462
554
|
* Start SPFN Server
|
|
@@ -475,4 +567,193 @@ declare function createServer(config?: ServerConfig, plugins?: ServerPlugin[]):
|
|
|
475
567
|
*/
|
|
476
568
|
declare function startServer(config?: ServerConfig): Promise<ServerInstance>;
|
|
477
569
|
|
|
478
|
-
|
|
570
|
+
/**
|
|
571
|
+
* Server Config Builder
|
|
572
|
+
*
|
|
573
|
+
* Provides a fluent API for building server configuration
|
|
574
|
+
*/
|
|
575
|
+
|
|
576
|
+
declare class ServerConfigBuilder {
|
|
577
|
+
private config;
|
|
578
|
+
private lifecycles;
|
|
579
|
+
/**
|
|
580
|
+
* Set server port
|
|
581
|
+
*/
|
|
582
|
+
port(port: number): this;
|
|
583
|
+
/**
|
|
584
|
+
* Set server hostname
|
|
585
|
+
*/
|
|
586
|
+
host(host: string): this;
|
|
587
|
+
/**
|
|
588
|
+
* Set CORS configuration
|
|
589
|
+
*/
|
|
590
|
+
cors(cors: ServerConfig['cors']): this;
|
|
591
|
+
/**
|
|
592
|
+
* Configure built-in middleware
|
|
593
|
+
*/
|
|
594
|
+
middleware(middleware: ServerConfig['middleware']): this;
|
|
595
|
+
/**
|
|
596
|
+
* Add custom middleware
|
|
597
|
+
*/
|
|
598
|
+
use(handlers: MiddlewareHandler[]): this;
|
|
599
|
+
/**
|
|
600
|
+
* Add named middlewares for route-level skip control
|
|
601
|
+
*/
|
|
602
|
+
middlewares(middlewares: ServerConfig['middlewares']): this;
|
|
603
|
+
/**
|
|
604
|
+
* Register define-route based router
|
|
605
|
+
*
|
|
606
|
+
* Automatically applies:
|
|
607
|
+
* - Global middlewares from router._globalMiddlewares (via .use())
|
|
608
|
+
* - Package routers from router._packageRouters (via .packages())
|
|
609
|
+
*
|
|
610
|
+
* @example
|
|
611
|
+
* ```typescript
|
|
612
|
+
* const appRouter = defineRouter({
|
|
613
|
+
* getUser: route.get('/users/:id')...
|
|
614
|
+
* })
|
|
615
|
+
* .packages([authRouter, cmsAppRouter])
|
|
616
|
+
* .use([authMiddleware]);
|
|
617
|
+
*
|
|
618
|
+
* export default defineServerConfig()
|
|
619
|
+
* .routes(appRouter) // middlewares auto-applied
|
|
620
|
+
* .build();
|
|
621
|
+
* ```
|
|
622
|
+
*/
|
|
623
|
+
routes(router: Router<any>): this;
|
|
624
|
+
/**
|
|
625
|
+
* Register background jobs router
|
|
626
|
+
*
|
|
627
|
+
* @example
|
|
628
|
+
* ```typescript
|
|
629
|
+
* import { job, defineJobRouter } from '@spfn/core/job';
|
|
630
|
+
*
|
|
631
|
+
* const sendEmail = job('send-email')
|
|
632
|
+
* .input(Type.Object({ to: Type.String() }))
|
|
633
|
+
* .handler(async (input) => { ... });
|
|
634
|
+
*
|
|
635
|
+
* const jobRouter = defineJobRouter({ sendEmail });
|
|
636
|
+
*
|
|
637
|
+
* export default defineServerConfig()
|
|
638
|
+
* .routes(appRouter)
|
|
639
|
+
* .jobs(jobRouter)
|
|
640
|
+
* .build();
|
|
641
|
+
* ```
|
|
642
|
+
*/
|
|
643
|
+
jobs(router: JobRouter<any>, config?: Omit<BossOptions, 'connectionString'>): this;
|
|
644
|
+
/**
|
|
645
|
+
* Register event router for SSE (Server-Sent Events)
|
|
646
|
+
*
|
|
647
|
+
* Enables real-time event streaming to frontend clients.
|
|
648
|
+
* Events defined with defineEvent() can be subscribed by:
|
|
649
|
+
* - Backend: .subscribe() for internal handlers
|
|
650
|
+
* - Jobs: .on(event) for background processing
|
|
651
|
+
* - Frontend: SSE stream for real-time updates
|
|
652
|
+
*
|
|
653
|
+
* @example
|
|
654
|
+
* ```typescript
|
|
655
|
+
* import { defineEvent, defineEventRouter } from '@spfn/core/event';
|
|
656
|
+
*
|
|
657
|
+
* const userCreated = defineEvent('user.created', Type.Object({
|
|
658
|
+
* userId: Type.String(),
|
|
659
|
+
* }));
|
|
660
|
+
*
|
|
661
|
+
* const eventRouter = defineEventRouter({ userCreated });
|
|
662
|
+
*
|
|
663
|
+
* export default defineServerConfig()
|
|
664
|
+
* .routes(appRouter)
|
|
665
|
+
* .events(eventRouter) // → GET /events/stream
|
|
666
|
+
* .build();
|
|
667
|
+
*
|
|
668
|
+
* // Custom path
|
|
669
|
+
* .events(eventRouter, { path: '/sse' })
|
|
670
|
+
* ```
|
|
671
|
+
*/
|
|
672
|
+
events(router: EventRouterDef<any>, config?: SSEHandlerConfig & {
|
|
673
|
+
path?: string;
|
|
674
|
+
}): this;
|
|
675
|
+
/**
|
|
676
|
+
* Enable/disable debug mode
|
|
677
|
+
*/
|
|
678
|
+
debug(enabled: boolean): this;
|
|
679
|
+
/**
|
|
680
|
+
* Configure database settings
|
|
681
|
+
*/
|
|
682
|
+
database(database: ServerConfig['database']): this;
|
|
683
|
+
/**
|
|
684
|
+
* Configure server timeout settings
|
|
685
|
+
*/
|
|
686
|
+
timeout(timeout: ServerConfig['timeout']): this;
|
|
687
|
+
/**
|
|
688
|
+
* Configure graceful shutdown settings
|
|
689
|
+
*/
|
|
690
|
+
shutdown(shutdown: ServerConfig['shutdown']): this;
|
|
691
|
+
/**
|
|
692
|
+
* Configure health check endpoint
|
|
693
|
+
*/
|
|
694
|
+
healthCheck(healthCheck: ServerConfig['healthCheck']): this;
|
|
695
|
+
/**
|
|
696
|
+
* Configure infrastructure initialization
|
|
697
|
+
*/
|
|
698
|
+
infrastructure(infrastructure: ServerConfig['infrastructure']): this;
|
|
699
|
+
/**
|
|
700
|
+
* Register workflow router for workflow orchestration
|
|
701
|
+
*
|
|
702
|
+
* Automatically initializes the workflow engine after database is ready.
|
|
703
|
+
*
|
|
704
|
+
* @example
|
|
705
|
+
* ```typescript
|
|
706
|
+
* import { defineWorkflowRouter } from '@spfn/workflow';
|
|
707
|
+
*
|
|
708
|
+
* const workflowRouter = defineWorkflowRouter([
|
|
709
|
+
* provisionTenant,
|
|
710
|
+
* deprovisionTenant,
|
|
711
|
+
* ]);
|
|
712
|
+
*
|
|
713
|
+
* export default defineServerConfig()
|
|
714
|
+
* .routes(appRouter)
|
|
715
|
+
* .workflows(workflowRouter)
|
|
716
|
+
* .build();
|
|
717
|
+
* ```
|
|
718
|
+
*/
|
|
719
|
+
workflows(router: ServerConfig['workflows'], config?: ServerConfig['workflowsConfig']): this;
|
|
720
|
+
/**
|
|
721
|
+
* Configure lifecycle hooks
|
|
722
|
+
* Can be called multiple times - hooks will be executed in registration order
|
|
723
|
+
*/
|
|
724
|
+
lifecycle(lifecycle: ServerConfig['lifecycle']): this;
|
|
725
|
+
/**
|
|
726
|
+
* Build and return the final configuration
|
|
727
|
+
*/
|
|
728
|
+
build(): ServerConfig;
|
|
729
|
+
private mergeLifecycles;
|
|
730
|
+
}
|
|
731
|
+
/**
|
|
732
|
+
* Create a new server configuration builder
|
|
733
|
+
*
|
|
734
|
+
* @example
|
|
735
|
+
* ```typescript
|
|
736
|
+
* // server.config.ts
|
|
737
|
+
* import { defineServerConfig, route, defineRouter } from '@spfn/core/server';
|
|
738
|
+
* import { Type } from '@sinclair/typebox';
|
|
739
|
+
*
|
|
740
|
+
* const appRouter = defineRouter({
|
|
741
|
+
* getUser: route.get('/users/:id')
|
|
742
|
+
* .input({ params: Type.Object({ id: Type.String() }) })
|
|
743
|
+
* .handler(async (c) => {
|
|
744
|
+
* const { params } = await c.data();
|
|
745
|
+
* return { id: params.id, name: 'John' };
|
|
746
|
+
* }),
|
|
747
|
+
* });
|
|
748
|
+
*
|
|
749
|
+
* export default defineServerConfig()
|
|
750
|
+
* .port(3000)
|
|
751
|
+
* .routes(appRouter)
|
|
752
|
+
* .middleware({ logger: true, cors: true })
|
|
753
|
+
* .debug(true)
|
|
754
|
+
* .build();
|
|
755
|
+
* ```
|
|
756
|
+
*/
|
|
757
|
+
declare function defineServerConfig(): ServerConfigBuilder;
|
|
758
|
+
|
|
759
|
+
export { type AppFactory, type ServerConfig, type ServerInstance, createServer, defineServerConfig, loadEnvFiles, startServer };
|