@veloxts/core 0.1.0 → 0.2.0
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 +7 -5
- package/package.json +1 -1
- package/dist/app.d.ts +0 -235
- package/dist/app.d.ts.map +0 -1
- package/dist/app.js +0 -380
- package/dist/app.js.map +0 -1
- package/dist/context.d.ts +0 -88
- package/dist/context.d.ts.map +0 -1
- package/dist/context.js +0 -57
- package/dist/context.js.map +0 -1
- package/dist/errors.d.ts +0 -298
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js +0 -294
- package/dist/errors.js.map +0 -1
- package/dist/index.d.ts +0 -28
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -26
- package/dist/index.js.map +0 -1
- package/dist/plugin.d.ts +0 -182
- package/dist/plugin.d.ts.map +0 -1
- package/dist/plugin.js +0 -121
- package/dist/plugin.js.map +0 -1
- package/dist/types.d.ts +0 -118
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -6
- package/dist/types.js.map +0 -1
- package/dist/utils/config.d.ts +0 -181
- package/dist/utils/config.d.ts.map +0 -1
- package/dist/utils/config.js +0 -99
- package/dist/utils/config.js.map +0 -1
- package/dist/utils/lifecycle.d.ts +0 -78
- package/dist/utils/lifecycle.d.ts.map +0 -1
- package/dist/utils/lifecycle.js +0 -128
- package/dist/utils/lifecycle.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# @veloxts/core
|
|
2
2
|
|
|
3
|
+
> **Alpha Release** - This framework is in early development. APIs may change between versions. Not recommended for production use yet.
|
|
4
|
+
|
|
3
5
|
Foundation package for the VeloxTS framework - provides the core Fastify wrapper, plugin system, and base context.
|
|
4
6
|
|
|
5
7
|
## Installation
|
|
@@ -17,7 +19,7 @@ import { createVeloxApp } from '@veloxts/core';
|
|
|
17
19
|
|
|
18
20
|
// Create application
|
|
19
21
|
const app = await createVeloxApp({
|
|
20
|
-
port:
|
|
22
|
+
port: 3210,
|
|
21
23
|
host: '0.0.0.0',
|
|
22
24
|
logger: true,
|
|
23
25
|
});
|
|
@@ -381,7 +383,7 @@ app.server.get('/users/:id', async (request, reply) => {
|
|
|
381
383
|
|
|
382
384
|
```typescript
|
|
383
385
|
{
|
|
384
|
-
port:
|
|
386
|
+
port: 3210,
|
|
385
387
|
host: '0.0.0.0',
|
|
386
388
|
logger: process.env.NODE_ENV !== 'production',
|
|
387
389
|
}
|
|
@@ -391,7 +393,7 @@ app.server.get('/users/:id', async (request, reply) => {
|
|
|
391
393
|
|
|
392
394
|
```typescript
|
|
393
395
|
const app = await createVeloxApp({
|
|
394
|
-
port: Number(process.env.PORT) ||
|
|
396
|
+
port: Number(process.env.PORT) || 3210,
|
|
395
397
|
host: process.env.HOST || '0.0.0.0',
|
|
396
398
|
logger: process.env.NODE_ENV !== 'production',
|
|
397
399
|
fastify: {
|
|
@@ -404,7 +406,7 @@ const app = await createVeloxApp({
|
|
|
404
406
|
|
|
405
407
|
```typescript
|
|
406
408
|
const app = await createVeloxApp({
|
|
407
|
-
port:
|
|
409
|
+
port: 3210,
|
|
408
410
|
host: '0.0.0.0',
|
|
409
411
|
logger: {
|
|
410
412
|
level: 'warn',
|
|
@@ -527,7 +529,7 @@ import { userProcedures } from './procedures/users';
|
|
|
527
529
|
// Initialize
|
|
528
530
|
const prisma = new PrismaClient();
|
|
529
531
|
const app = await createVeloxApp({
|
|
530
|
-
port: Number(process.env.PORT) ||
|
|
532
|
+
port: Number(process.env.PORT) || 3210,
|
|
531
533
|
logger: true,
|
|
532
534
|
});
|
|
533
535
|
|
package/package.json
CHANGED
package/dist/app.d.ts
DELETED
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Main VeloxTS application class
|
|
3
|
-
* Provides Fastify wrapper with plugin system and lifecycle management
|
|
4
|
-
* @module app
|
|
5
|
-
*/
|
|
6
|
-
import { type FastifyInstance } from 'fastify';
|
|
7
|
-
import type { PluginOptions, VeloxPlugin } from './plugin.js';
|
|
8
|
-
import type { ShutdownHandler } from './types.js';
|
|
9
|
-
import type { FrozenVeloxAppConfig, VeloxAppConfig } from './utils/config.js';
|
|
10
|
-
/**
|
|
11
|
-
* Main VeloxTS application instance
|
|
12
|
-
*
|
|
13
|
-
* Wraps Fastify with additional features:
|
|
14
|
-
* - Type-safe plugin system
|
|
15
|
-
* - Request-scoped context
|
|
16
|
-
* - Graceful shutdown handling
|
|
17
|
-
* - Lifecycle management
|
|
18
|
-
*
|
|
19
|
-
* @example
|
|
20
|
-
* ```typescript
|
|
21
|
-
* const app = await createVeloxApp({
|
|
22
|
-
* port: 3000,
|
|
23
|
-
* logger: true
|
|
24
|
-
* });
|
|
25
|
-
*
|
|
26
|
-
* await app.register(myPlugin);
|
|
27
|
-
* await app.start();
|
|
28
|
-
* ```
|
|
29
|
-
*/
|
|
30
|
-
export declare class VeloxApp {
|
|
31
|
-
private readonly _server;
|
|
32
|
-
private readonly _config;
|
|
33
|
-
private readonly _lifecycle;
|
|
34
|
-
private _isRunning;
|
|
35
|
-
private _address;
|
|
36
|
-
/**
|
|
37
|
-
* Creates a new VeloxApp instance
|
|
38
|
-
*
|
|
39
|
-
* @param config - Application configuration
|
|
40
|
-
* @internal
|
|
41
|
-
*/
|
|
42
|
-
constructor(config: VeloxAppConfig);
|
|
43
|
-
/**
|
|
44
|
-
* Underlying Fastify server instance
|
|
45
|
-
*
|
|
46
|
-
* Provides direct access to Fastify for advanced usage.
|
|
47
|
-
* Most users won't need this - use VeloxApp methods instead.
|
|
48
|
-
*
|
|
49
|
-
* @example
|
|
50
|
-
* ```typescript
|
|
51
|
-
* // Access Fastify decorators
|
|
52
|
-
* app.server.hasDecorator('db');
|
|
53
|
-
*
|
|
54
|
-
* // Use Fastify hooks directly
|
|
55
|
-
* app.server.addHook('onRequest', async (request, reply) => {
|
|
56
|
-
* console.log('Request received:', request.url);
|
|
57
|
-
* });
|
|
58
|
-
* ```
|
|
59
|
-
*/
|
|
60
|
-
get server(): FastifyInstance;
|
|
61
|
-
/**
|
|
62
|
-
* Application configuration (readonly, frozen)
|
|
63
|
-
*/
|
|
64
|
-
get config(): FrozenVeloxAppConfig;
|
|
65
|
-
/**
|
|
66
|
-
* Check if server is currently running
|
|
67
|
-
*/
|
|
68
|
-
get isRunning(): boolean;
|
|
69
|
-
/**
|
|
70
|
-
* Server address (host:port) if running, null otherwise
|
|
71
|
-
*/
|
|
72
|
-
get address(): string | null;
|
|
73
|
-
/**
|
|
74
|
-
* Async initialization (called by factory function)
|
|
75
|
-
*
|
|
76
|
-
* @internal - This method is public for factory access but should not be called directly.
|
|
77
|
-
* Use createVeloxApp() instead.
|
|
78
|
-
*/
|
|
79
|
-
initialize(): Promise<void>;
|
|
80
|
-
/**
|
|
81
|
-
* Sets up request context decorator
|
|
82
|
-
*
|
|
83
|
-
* Adds `request.context` property to all requests via onRequest hook
|
|
84
|
-
*
|
|
85
|
-
* @internal
|
|
86
|
-
*/
|
|
87
|
-
private _setupContext;
|
|
88
|
-
/**
|
|
89
|
-
* Sets up global error handling
|
|
90
|
-
*
|
|
91
|
-
* Ensures VeloxErrors are serialized with proper status codes
|
|
92
|
-
*
|
|
93
|
-
* @internal
|
|
94
|
-
*/
|
|
95
|
-
private _setupErrorHandling;
|
|
96
|
-
/**
|
|
97
|
-
* Sets up graceful shutdown handlers for process signals
|
|
98
|
-
*
|
|
99
|
-
* @internal
|
|
100
|
-
*/
|
|
101
|
-
private _setupGracefulShutdown;
|
|
102
|
-
/**
|
|
103
|
-
* Registers a plugin with the application
|
|
104
|
-
*
|
|
105
|
-
* Plugins must be registered before calling `start()`
|
|
106
|
-
*
|
|
107
|
-
* @template Options - Type of options the plugin accepts
|
|
108
|
-
* @param plugin - Plugin to register
|
|
109
|
-
* @param options - Options to pass to the plugin
|
|
110
|
-
* @throws {VeloxError} If plugin metadata is invalid
|
|
111
|
-
*
|
|
112
|
-
* @example
|
|
113
|
-
* ```typescript
|
|
114
|
-
* await app.use(databasePlugin, {
|
|
115
|
-
* connectionString: 'postgresql://...'
|
|
116
|
-
* });
|
|
117
|
-
* ```
|
|
118
|
-
*/
|
|
119
|
-
use<Options extends PluginOptions>(plugin: VeloxPlugin<Options>, options?: Options): Promise<void>;
|
|
120
|
-
/**
|
|
121
|
-
* Registers routes with the application
|
|
122
|
-
*
|
|
123
|
-
* This is a convenience method that passes the Fastify server
|
|
124
|
-
* to a route registration function. Designed to work seamlessly
|
|
125
|
-
* with @veloxts/router's registerRestRoutes.
|
|
126
|
-
*
|
|
127
|
-
* Routes must be registered before calling `start()`.
|
|
128
|
-
*
|
|
129
|
-
* @param registrar - Function that registers routes on the server
|
|
130
|
-
*
|
|
131
|
-
* @example
|
|
132
|
-
* ```typescript
|
|
133
|
-
* import { registerRestRoutes } from '@veloxts/router';
|
|
134
|
-
*
|
|
135
|
-
* // Fluent registration
|
|
136
|
-
* app.routes((server) => {
|
|
137
|
-
* registerRestRoutes(server, [userProcedures, postProcedures], { prefix: '/api' });
|
|
138
|
-
* });
|
|
139
|
-
* ```
|
|
140
|
-
*
|
|
141
|
-
* @example
|
|
142
|
-
* ```typescript
|
|
143
|
-
* // Or with the helper from @veloxts/router
|
|
144
|
-
* import { createRoutesRegistrar } from '@veloxts/router';
|
|
145
|
-
*
|
|
146
|
-
* app.routes(createRoutesRegistrar([users, posts], { prefix: '/api' }));
|
|
147
|
-
* ```
|
|
148
|
-
*/
|
|
149
|
-
routes(registrar: (server: FastifyInstance) => void): this;
|
|
150
|
-
/**
|
|
151
|
-
* Starts the server and begins listening for requests
|
|
152
|
-
*
|
|
153
|
-
* @throws {VeloxError} If server is already running or fails to start
|
|
154
|
-
*
|
|
155
|
-
* @example
|
|
156
|
-
* ```typescript
|
|
157
|
-
* await app.start();
|
|
158
|
-
* console.log(`Server listening on ${app.address}`);
|
|
159
|
-
* ```
|
|
160
|
-
*/
|
|
161
|
-
start(): Promise<void>;
|
|
162
|
-
/**
|
|
163
|
-
* Stops the server gracefully
|
|
164
|
-
*
|
|
165
|
-
* - Stops accepting new requests
|
|
166
|
-
* - Waits for in-flight requests to complete
|
|
167
|
-
* - Executes shutdown handlers
|
|
168
|
-
* - Closes the server
|
|
169
|
-
*
|
|
170
|
-
* @throws {VeloxError} If server is not running or fails to stop
|
|
171
|
-
*
|
|
172
|
-
* @example
|
|
173
|
-
* ```typescript
|
|
174
|
-
* await app.stop();
|
|
175
|
-
* console.log('Server stopped');
|
|
176
|
-
* ```
|
|
177
|
-
*/
|
|
178
|
-
stop(): Promise<void>;
|
|
179
|
-
/**
|
|
180
|
-
* Adds a shutdown handler
|
|
181
|
-
*
|
|
182
|
-
* Shutdown handlers are called when the server stops, either via `stop()`
|
|
183
|
-
* or when receiving SIGINT/SIGTERM signals
|
|
184
|
-
*
|
|
185
|
-
* @param handler - Async function to call during shutdown
|
|
186
|
-
*
|
|
187
|
-
* @example
|
|
188
|
-
* ```typescript
|
|
189
|
-
* app.onShutdown(async () => {
|
|
190
|
-
* await database.disconnect();
|
|
191
|
-
* console.log('Database connection closed');
|
|
192
|
-
* });
|
|
193
|
-
* ```
|
|
194
|
-
*/
|
|
195
|
-
onShutdown(handler: ShutdownHandler): void;
|
|
196
|
-
}
|
|
197
|
-
/**
|
|
198
|
-
* Creates a new VeloxTS application instance
|
|
199
|
-
*
|
|
200
|
-
* This is the main entry point for creating a VeloxTS app.
|
|
201
|
-
* The function is async to allow for async initialization.
|
|
202
|
-
*
|
|
203
|
-
* @param config - Application configuration
|
|
204
|
-
* @returns Promise resolving to VeloxApp instance
|
|
205
|
-
*
|
|
206
|
-
* @example
|
|
207
|
-
* ```typescript
|
|
208
|
-
* const app = await createVeloxApp({
|
|
209
|
-
* port: 3000,
|
|
210
|
-
* host: '0.0.0.0',
|
|
211
|
-
* logger: true
|
|
212
|
-
* });
|
|
213
|
-
* ```
|
|
214
|
-
*
|
|
215
|
-
* @example
|
|
216
|
-
* ```typescript
|
|
217
|
-
* // With default configuration
|
|
218
|
-
* const app = await createVeloxApp();
|
|
219
|
-
* await app.start(); // Listens on port 3000
|
|
220
|
-
* ```
|
|
221
|
-
*
|
|
222
|
-
* @example
|
|
223
|
-
* ```typescript
|
|
224
|
-
* // With custom Fastify options
|
|
225
|
-
* const app = await createVeloxApp({
|
|
226
|
-
* port: 4000,
|
|
227
|
-
* fastify: {
|
|
228
|
-
* requestTimeout: 30000,
|
|
229
|
-
* bodyLimit: 1048576 * 10, // 10MB
|
|
230
|
-
* }
|
|
231
|
-
* });
|
|
232
|
-
* ```
|
|
233
|
-
*/
|
|
234
|
-
export declare function createVeloxApp(config?: VeloxAppConfig): Promise<VeloxApp>;
|
|
235
|
-
//# sourceMappingURL=app.d.ts.map
|
package/dist/app.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAgB,EAAE,KAAK,eAAe,EAA6B,MAAM,SAAS,CAAC;AAKnF,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAI9E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkB;IAC1C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuB;IAC/C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAmB;IAC9C,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAuB;IAEvC;;;;;OAKG;gBACS,MAAM,EAAE,cAAc;IA4BlC;;;;;;;;;;;;;;;;OAgBG;IACH,IAAI,MAAM,IAAI,eAAe,CAE5B;IAED;;OAEG;IACH,IAAI,MAAM,IAAI,oBAAoB,CAEjC;IAED;;OAEG;IACH,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,MAAM,GAAG,IAAI,CAE3B;IAED;;;;;OAKG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAKjC;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;IAWrB;;;;;;OAMG;IACH,OAAO,CAAC,mBAAmB;IA0C3B;;;;OAIG;IACH,OAAO,CAAC,sBAAsB;IAM9B;;;;;;;;;;;;;;;;OAgBG;IACG,GAAG,CAAC,OAAO,SAAS,aAAa,EACrC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,EAC5B,OAAO,CAAC,EAAE,OAAO,GAChB,OAAO,CAAC,IAAI,CAAC;IAuBhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,MAAM,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,GAAG,IAAI;IAK1D;;;;;;;;;;OAUG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA4B5B;;;;;;;;;;;;;;;OAeG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA4B3B;;;;;;;;;;;;;;;OAeG;IACH,UAAU,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI;CAG3C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAsB,cAAc,CAAC,MAAM,GAAE,cAAmB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAInF"}
|
package/dist/app.js
DELETED
|
@@ -1,380 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Main VeloxTS application class
|
|
3
|
-
* Provides Fastify wrapper with plugin system and lifecycle management
|
|
4
|
-
* @module app
|
|
5
|
-
*/
|
|
6
|
-
import fastify from 'fastify';
|
|
7
|
-
import fp from 'fastify-plugin';
|
|
8
|
-
import { createContext } from './context.js';
|
|
9
|
-
import { isVeloxError, VeloxError } from './errors.js';
|
|
10
|
-
import { validatePluginMetadata } from './plugin.js';
|
|
11
|
-
import { mergeConfig, validateConfig } from './utils/config.js';
|
|
12
|
-
import { LifecycleManager } from './utils/lifecycle.js';
|
|
13
|
-
/**
|
|
14
|
-
* Main VeloxTS application instance
|
|
15
|
-
*
|
|
16
|
-
* Wraps Fastify with additional features:
|
|
17
|
-
* - Type-safe plugin system
|
|
18
|
-
* - Request-scoped context
|
|
19
|
-
* - Graceful shutdown handling
|
|
20
|
-
* - Lifecycle management
|
|
21
|
-
*
|
|
22
|
-
* @example
|
|
23
|
-
* ```typescript
|
|
24
|
-
* const app = await createVeloxApp({
|
|
25
|
-
* port: 3000,
|
|
26
|
-
* logger: true
|
|
27
|
-
* });
|
|
28
|
-
*
|
|
29
|
-
* await app.register(myPlugin);
|
|
30
|
-
* await app.start();
|
|
31
|
-
* ```
|
|
32
|
-
*/
|
|
33
|
-
export class VeloxApp {
|
|
34
|
-
_server;
|
|
35
|
-
_config;
|
|
36
|
-
_lifecycle;
|
|
37
|
-
_isRunning = false;
|
|
38
|
-
_address = null;
|
|
39
|
-
/**
|
|
40
|
-
* Creates a new VeloxApp instance
|
|
41
|
-
*
|
|
42
|
-
* @param config - Application configuration
|
|
43
|
-
* @internal
|
|
44
|
-
*/
|
|
45
|
-
constructor(config) {
|
|
46
|
-
// Merge user config with defaults and validate
|
|
47
|
-
const merged = mergeConfig(config);
|
|
48
|
-
// Validate and freeze configuration
|
|
49
|
-
this._config = validateConfig(merged);
|
|
50
|
-
// Create Fastify instance
|
|
51
|
-
const fastifyOptions = {
|
|
52
|
-
logger: this._config.logger,
|
|
53
|
-
...this._config.fastify,
|
|
54
|
-
};
|
|
55
|
-
this._server = fastify(fastifyOptions);
|
|
56
|
-
// Initialize lifecycle manager
|
|
57
|
-
this._lifecycle = new LifecycleManager();
|
|
58
|
-
// Set up context decorator
|
|
59
|
-
this._setupContext();
|
|
60
|
-
// Set up error handling
|
|
61
|
-
this._setupErrorHandling();
|
|
62
|
-
// Set up graceful shutdown
|
|
63
|
-
this._setupGracefulShutdown();
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Underlying Fastify server instance
|
|
67
|
-
*
|
|
68
|
-
* Provides direct access to Fastify for advanced usage.
|
|
69
|
-
* Most users won't need this - use VeloxApp methods instead.
|
|
70
|
-
*
|
|
71
|
-
* @example
|
|
72
|
-
* ```typescript
|
|
73
|
-
* // Access Fastify decorators
|
|
74
|
-
* app.server.hasDecorator('db');
|
|
75
|
-
*
|
|
76
|
-
* // Use Fastify hooks directly
|
|
77
|
-
* app.server.addHook('onRequest', async (request, reply) => {
|
|
78
|
-
* console.log('Request received:', request.url);
|
|
79
|
-
* });
|
|
80
|
-
* ```
|
|
81
|
-
*/
|
|
82
|
-
get server() {
|
|
83
|
-
return this._server;
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Application configuration (readonly, frozen)
|
|
87
|
-
*/
|
|
88
|
-
get config() {
|
|
89
|
-
return this._config;
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Check if server is currently running
|
|
93
|
-
*/
|
|
94
|
-
get isRunning() {
|
|
95
|
-
return this._isRunning;
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Server address (host:port) if running, null otherwise
|
|
99
|
-
*/
|
|
100
|
-
get address() {
|
|
101
|
-
return this._address;
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Async initialization (called by factory function)
|
|
105
|
-
*
|
|
106
|
-
* @internal - This method is public for factory access but should not be called directly.
|
|
107
|
-
* Use createVeloxApp() instead.
|
|
108
|
-
*/
|
|
109
|
-
async initialize() {
|
|
110
|
-
// Keep empty - ready() must be called in start() after plugins are registered
|
|
111
|
-
// This is a Fastify constraint: plugins must be registered before ready()
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Sets up request context decorator
|
|
115
|
-
*
|
|
116
|
-
* Adds `request.context` property to all requests via onRequest hook
|
|
117
|
-
*
|
|
118
|
-
* @internal
|
|
119
|
-
*/
|
|
120
|
-
_setupContext() {
|
|
121
|
-
// Create context for each request via direct assignment
|
|
122
|
-
// TypeScript's declaration merging provides type safety
|
|
123
|
-
this._server.addHook('onRequest', async (request, reply) => {
|
|
124
|
-
// Direct assignment is ~100-400ns faster than Object.defineProperty
|
|
125
|
-
// We use a mutable type assertion here because this is the framework's
|
|
126
|
-
// initialization code - the readonly constraint is for user code safety
|
|
127
|
-
request.context = createContext(request, reply);
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* Sets up global error handling
|
|
132
|
-
*
|
|
133
|
-
* Ensures VeloxErrors are serialized with proper status codes
|
|
134
|
-
*
|
|
135
|
-
* @internal
|
|
136
|
-
*/
|
|
137
|
-
_setupErrorHandling() {
|
|
138
|
-
this._server.setErrorHandler(async (error, request, reply) => {
|
|
139
|
-
try {
|
|
140
|
-
// Only log server errors (5xx), not client errors (4xx)
|
|
141
|
-
const statusCode = isVeloxError(error)
|
|
142
|
-
? error.statusCode
|
|
143
|
-
: typeof error === 'object' && error !== null && 'statusCode' in error
|
|
144
|
-
? error.statusCode
|
|
145
|
-
: 500;
|
|
146
|
-
if (statusCode >= 500) {
|
|
147
|
-
request.log.error(error);
|
|
148
|
-
}
|
|
149
|
-
// Handle VeloxError instances (fast path - most common case)
|
|
150
|
-
if (isVeloxError(error)) {
|
|
151
|
-
return reply.status(error.statusCode).send(error.toJSON());
|
|
152
|
-
}
|
|
153
|
-
// Handle other errors
|
|
154
|
-
const message = error instanceof Error ? error.message : 'Internal Server Error';
|
|
155
|
-
const name = error instanceof Error ? error.name : 'Error';
|
|
156
|
-
return reply.status(statusCode).send({
|
|
157
|
-
error: name,
|
|
158
|
-
message,
|
|
159
|
-
statusCode,
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
catch (handlerError) {
|
|
163
|
-
// Last resort error handling - prevents unhandled rejections
|
|
164
|
-
console.error('Critical error in error handler:', handlerError);
|
|
165
|
-
if (!reply.sent) {
|
|
166
|
-
return reply.status(500).send({
|
|
167
|
-
error: 'InternalServerError',
|
|
168
|
-
message: 'Internal Server Error',
|
|
169
|
-
statusCode: 500,
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* Sets up graceful shutdown handlers for process signals
|
|
177
|
-
*
|
|
178
|
-
* @internal
|
|
179
|
-
*/
|
|
180
|
-
_setupGracefulShutdown() {
|
|
181
|
-
this._lifecycle.setupSignalHandlers(async () => {
|
|
182
|
-
await this.stop();
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
/**
|
|
186
|
-
* Registers a plugin with the application
|
|
187
|
-
*
|
|
188
|
-
* Plugins must be registered before calling `start()`
|
|
189
|
-
*
|
|
190
|
-
* @template Options - Type of options the plugin accepts
|
|
191
|
-
* @param plugin - Plugin to register
|
|
192
|
-
* @param options - Options to pass to the plugin
|
|
193
|
-
* @throws {VeloxError} If plugin metadata is invalid
|
|
194
|
-
*
|
|
195
|
-
* @example
|
|
196
|
-
* ```typescript
|
|
197
|
-
* await app.use(databasePlugin, {
|
|
198
|
-
* connectionString: 'postgresql://...'
|
|
199
|
-
* });
|
|
200
|
-
* ```
|
|
201
|
-
*/
|
|
202
|
-
async use(plugin, options) {
|
|
203
|
-
// Validate plugin metadata
|
|
204
|
-
validatePluginMetadata(plugin);
|
|
205
|
-
// Wrap plugin with fastify-plugin for proper encapsulation
|
|
206
|
-
const wrappedPlugin = fp(plugin.register, {
|
|
207
|
-
name: plugin.name,
|
|
208
|
-
dependencies: plugin.dependencies,
|
|
209
|
-
fastify: '5.x',
|
|
210
|
-
});
|
|
211
|
-
// Register with Fastify
|
|
212
|
-
try {
|
|
213
|
-
await this._server.register(wrappedPlugin, options ?? {});
|
|
214
|
-
}
|
|
215
|
-
catch (error) {
|
|
216
|
-
throw new VeloxError(`Failed to register plugin "${plugin.name}": ${error instanceof Error ? error.message : String(error)}`, 500, 'PLUGIN_REGISTRATION_ERROR');
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
/**
|
|
220
|
-
* Registers routes with the application
|
|
221
|
-
*
|
|
222
|
-
* This is a convenience method that passes the Fastify server
|
|
223
|
-
* to a route registration function. Designed to work seamlessly
|
|
224
|
-
* with @veloxts/router's registerRestRoutes.
|
|
225
|
-
*
|
|
226
|
-
* Routes must be registered before calling `start()`.
|
|
227
|
-
*
|
|
228
|
-
* @param registrar - Function that registers routes on the server
|
|
229
|
-
*
|
|
230
|
-
* @example
|
|
231
|
-
* ```typescript
|
|
232
|
-
* import { registerRestRoutes } from '@veloxts/router';
|
|
233
|
-
*
|
|
234
|
-
* // Fluent registration
|
|
235
|
-
* app.routes((server) => {
|
|
236
|
-
* registerRestRoutes(server, [userProcedures, postProcedures], { prefix: '/api' });
|
|
237
|
-
* });
|
|
238
|
-
* ```
|
|
239
|
-
*
|
|
240
|
-
* @example
|
|
241
|
-
* ```typescript
|
|
242
|
-
* // Or with the helper from @veloxts/router
|
|
243
|
-
* import { createRoutesRegistrar } from '@veloxts/router';
|
|
244
|
-
*
|
|
245
|
-
* app.routes(createRoutesRegistrar([users, posts], { prefix: '/api' }));
|
|
246
|
-
* ```
|
|
247
|
-
*/
|
|
248
|
-
routes(registrar) {
|
|
249
|
-
registrar(this._server);
|
|
250
|
-
return this;
|
|
251
|
-
}
|
|
252
|
-
/**
|
|
253
|
-
* Starts the server and begins listening for requests
|
|
254
|
-
*
|
|
255
|
-
* @throws {VeloxError} If server is already running or fails to start
|
|
256
|
-
*
|
|
257
|
-
* @example
|
|
258
|
-
* ```typescript
|
|
259
|
-
* await app.start();
|
|
260
|
-
* console.log(`Server listening on ${app.address}`);
|
|
261
|
-
* ```
|
|
262
|
-
*/
|
|
263
|
-
async start() {
|
|
264
|
-
if (this._isRunning) {
|
|
265
|
-
throw new VeloxError('Server is already running', 500, 'SERVER_ALREADY_RUNNING');
|
|
266
|
-
}
|
|
267
|
-
try {
|
|
268
|
-
// Ensure Fastify is ready before listening (must be after plugin registration)
|
|
269
|
-
await this._server.ready();
|
|
270
|
-
// Start listening
|
|
271
|
-
const address = await this._server.listen({
|
|
272
|
-
port: this._config.port,
|
|
273
|
-
host: this._config.host,
|
|
274
|
-
});
|
|
275
|
-
this._isRunning = true;
|
|
276
|
-
this._address = address;
|
|
277
|
-
this._server.log.info(`Server listening on ${address}`);
|
|
278
|
-
}
|
|
279
|
-
catch (error) {
|
|
280
|
-
throw new VeloxError(`Failed to start server: ${error instanceof Error ? error.message : String(error)}`, 500, 'SERVER_START_ERROR');
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
/**
|
|
284
|
-
* Stops the server gracefully
|
|
285
|
-
*
|
|
286
|
-
* - Stops accepting new requests
|
|
287
|
-
* - Waits for in-flight requests to complete
|
|
288
|
-
* - Executes shutdown handlers
|
|
289
|
-
* - Closes the server
|
|
290
|
-
*
|
|
291
|
-
* @throws {VeloxError} If server is not running or fails to stop
|
|
292
|
-
*
|
|
293
|
-
* @example
|
|
294
|
-
* ```typescript
|
|
295
|
-
* await app.stop();
|
|
296
|
-
* console.log('Server stopped');
|
|
297
|
-
* ```
|
|
298
|
-
*/
|
|
299
|
-
async stop() {
|
|
300
|
-
if (!this._isRunning) {
|
|
301
|
-
throw new VeloxError('Server is not running', 500, 'SERVER_NOT_RUNNING');
|
|
302
|
-
}
|
|
303
|
-
try {
|
|
304
|
-
// Execute shutdown handlers
|
|
305
|
-
await this._lifecycle.executeShutdownHandlers();
|
|
306
|
-
// Clean up signal handlers to prevent memory leaks in tests
|
|
307
|
-
this._lifecycle.cleanupSignalHandlers();
|
|
308
|
-
// Close server
|
|
309
|
-
await this._server.close();
|
|
310
|
-
this._isRunning = false;
|
|
311
|
-
this._address = null;
|
|
312
|
-
this._server.log.info('Server stopped');
|
|
313
|
-
}
|
|
314
|
-
catch (error) {
|
|
315
|
-
throw new VeloxError(`Failed to stop server: ${error instanceof Error ? error.message : String(error)}`, 500, 'SERVER_STOP_ERROR');
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
/**
|
|
319
|
-
* Adds a shutdown handler
|
|
320
|
-
*
|
|
321
|
-
* Shutdown handlers are called when the server stops, either via `stop()`
|
|
322
|
-
* or when receiving SIGINT/SIGTERM signals
|
|
323
|
-
*
|
|
324
|
-
* @param handler - Async function to call during shutdown
|
|
325
|
-
*
|
|
326
|
-
* @example
|
|
327
|
-
* ```typescript
|
|
328
|
-
* app.onShutdown(async () => {
|
|
329
|
-
* await database.disconnect();
|
|
330
|
-
* console.log('Database connection closed');
|
|
331
|
-
* });
|
|
332
|
-
* ```
|
|
333
|
-
*/
|
|
334
|
-
onShutdown(handler) {
|
|
335
|
-
this._lifecycle.addShutdownHandler(handler);
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
/**
|
|
339
|
-
* Creates a new VeloxTS application instance
|
|
340
|
-
*
|
|
341
|
-
* This is the main entry point for creating a VeloxTS app.
|
|
342
|
-
* The function is async to allow for async initialization.
|
|
343
|
-
*
|
|
344
|
-
* @param config - Application configuration
|
|
345
|
-
* @returns Promise resolving to VeloxApp instance
|
|
346
|
-
*
|
|
347
|
-
* @example
|
|
348
|
-
* ```typescript
|
|
349
|
-
* const app = await createVeloxApp({
|
|
350
|
-
* port: 3000,
|
|
351
|
-
* host: '0.0.0.0',
|
|
352
|
-
* logger: true
|
|
353
|
-
* });
|
|
354
|
-
* ```
|
|
355
|
-
*
|
|
356
|
-
* @example
|
|
357
|
-
* ```typescript
|
|
358
|
-
* // With default configuration
|
|
359
|
-
* const app = await createVeloxApp();
|
|
360
|
-
* await app.start(); // Listens on port 3000
|
|
361
|
-
* ```
|
|
362
|
-
*
|
|
363
|
-
* @example
|
|
364
|
-
* ```typescript
|
|
365
|
-
* // With custom Fastify options
|
|
366
|
-
* const app = await createVeloxApp({
|
|
367
|
-
* port: 4000,
|
|
368
|
-
* fastify: {
|
|
369
|
-
* requestTimeout: 30000,
|
|
370
|
-
* bodyLimit: 1048576 * 10, // 10MB
|
|
371
|
-
* }
|
|
372
|
-
* });
|
|
373
|
-
* ```
|
|
374
|
-
*/
|
|
375
|
-
export async function createVeloxApp(config = {}) {
|
|
376
|
-
const app = new VeloxApp(config);
|
|
377
|
-
await app.initialize();
|
|
378
|
-
return app;
|
|
379
|
-
}
|
|
380
|
-
//# sourceMappingURL=app.js.map
|
package/dist/app.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
|