@shadow-library/fastify 1.6.2 → 1.6.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/README.md +24 -1
- package/cjs/decorators/api-operation.decorator.js +1 -1
- package/cjs/module/fastify-module.interface.d.ts +10 -4
- package/cjs/module/fastify.module.d.ts +1 -0
- package/cjs/module/fastify.module.js +13 -3
- package/cjs/module/fastify.utils.js +2 -1
- package/cjs/server.error.js +4 -0
- package/esm/decorators/api-operation.decorator.js +1 -1
- package/esm/module/fastify-module.interface.d.ts +10 -4
- package/esm/module/fastify.module.d.ts +1 -0
- package/esm/module/fastify.module.js +13 -3
- package/esm/module/fastify.utils.js +2 -1
- package/esm/server.error.js +4 -0
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -663,6 +663,27 @@ childRouteHeaders: (contextService) => {
|
|
|
663
663
|
|
|
664
664
|
## Configuration
|
|
665
665
|
|
|
666
|
+
### Default Configuration
|
|
667
|
+
|
|
668
|
+
The `FastifyModule` automatically provides sensible defaults for core server options. The `host`, `port`, and `errorHandler` properties are all **optional** — if not specified, they are resolved from `@shadow-library/common`'s `Config` or fall back to built-in defaults:
|
|
669
|
+
|
|
670
|
+
| Property | Config Key | Default Value |
|
|
671
|
+
| -------------- | ---------- | --------------------- |
|
|
672
|
+
| `host` | `app.host` | `'localhost'` |
|
|
673
|
+
| `port` | `app.port` | `8080` |
|
|
674
|
+
| `errorHandler` | — | `DefaultErrorHandler` |
|
|
675
|
+
|
|
676
|
+
The `Config.load()` calls register `app.host` and `app.port` with the `Config` system, so they can be overridden via environment variables or any config source supported by `@shadow-library/common` without changing your module setup:
|
|
677
|
+
|
|
678
|
+
```typescript
|
|
679
|
+
// No explicit host/port needed — defaults are loaded from Config
|
|
680
|
+
FastifyModule.forRoot({
|
|
681
|
+
controllers: [UserController],
|
|
682
|
+
});
|
|
683
|
+
```
|
|
684
|
+
|
|
685
|
+
> **Note:** When using `forRootAsync`, the defaults are automatically merged with the config returned by your factory function, so you only need to specify the properties you want to override.
|
|
686
|
+
|
|
666
687
|
### Dynamic Module Configuration
|
|
667
688
|
|
|
668
689
|
`FastifyModule` is a **dynamic module** that configures itself based on the options you provide. Unlike static modules, dynamic modules return a module configuration object at runtime, allowing for flexible dependency injection and configuration.
|
|
@@ -740,7 +761,7 @@ export class AppModule {}
|
|
|
740
761
|
|
|
741
762
|
#### Asynchronous Configuration (forRootAsync)
|
|
742
763
|
|
|
743
|
-
Use `forRootAsync` when you need to inject dependencies or load configuration dynamically:
|
|
764
|
+
Use `forRootAsync` when you need to inject dependencies or load configuration dynamically. The config returned by your `useFactory` is automatically merged with the default configuration, so you only need to provide the properties you want to override:
|
|
744
765
|
|
|
745
766
|
```typescript
|
|
746
767
|
@Module({
|
|
@@ -758,6 +779,8 @@ Use `forRootAsync` when you need to inject dependencies or load configuration dy
|
|
|
758
779
|
export class AppModule {}
|
|
759
780
|
```
|
|
760
781
|
|
|
782
|
+
If your factory returns a `Promise`, the defaults are merged after the promise resolves. This works seamlessly with both sync and async factories.
|
|
783
|
+
|
|
761
784
|
#### Dynamic Module Benefits
|
|
762
785
|
|
|
763
786
|
- **Flexible Configuration**: Configure the module differently for different environments
|
|
@@ -14,22 +14,28 @@ import { ContextService } from '../services/index.js';
|
|
|
14
14
|
/**
|
|
15
15
|
* Defining types
|
|
16
16
|
*/
|
|
17
|
+
declare module '@shadow-library/common' {
|
|
18
|
+
interface ConfigRecords {
|
|
19
|
+
'app.port': number;
|
|
20
|
+
'app.host': string;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
17
23
|
export interface FastifyConfig extends FastifyServerOptions {
|
|
18
24
|
/**
|
|
19
25
|
* The host on which the Fastify instance is to be started
|
|
20
|
-
* @default
|
|
26
|
+
* @default localhost
|
|
21
27
|
*/
|
|
22
|
-
host
|
|
28
|
+
host?: string;
|
|
23
29
|
/**
|
|
24
30
|
* The port on which the Fastify instance is to be started
|
|
25
31
|
* @default 8080
|
|
26
32
|
*/
|
|
27
|
-
port
|
|
33
|
+
port?: number;
|
|
28
34
|
/**
|
|
29
35
|
* The error handler to be used to handle errors thrown by the Fastify instance
|
|
30
36
|
* @default DefaultErrorHandler
|
|
31
37
|
*/
|
|
32
|
-
errorHandler
|
|
38
|
+
errorHandler?: ErrorHandler;
|
|
33
39
|
/**
|
|
34
40
|
* The schema to be used to validate the response of the Fastify instance
|
|
35
41
|
* @default { '4xx': errorResponseSchema, '5xx': errorResponseSchema }
|
|
@@ -11,6 +11,7 @@ import { FastifyModuleAsyncOptions, FastifyModuleOptions } from './fastify-modul
|
|
|
11
11
|
*/
|
|
12
12
|
export declare class FastifyModule {
|
|
13
13
|
private static getDefaultConfig;
|
|
14
|
+
private static createConfigFactory;
|
|
14
15
|
static forRoot(options: FastifyModuleOptions): DynamicModule;
|
|
15
16
|
static forRootAsync(options: FastifyModuleAsyncOptions): DynamicModule;
|
|
16
17
|
}
|
|
@@ -32,10 +32,12 @@ const fastify_utils_1 = require("./fastify.utils.js");
|
|
|
32
32
|
*/
|
|
33
33
|
let FastifyModule = FastifyModule_1 = class FastifyModule {
|
|
34
34
|
static getDefaultConfig() {
|
|
35
|
+
common_1.Config.load('app.host', { defaultValue: 'localhost' });
|
|
36
|
+
common_1.Config.load('app.port', { defaultValue: '8080', validateType: 'number' });
|
|
35
37
|
const errorResponseSchema = class_schema_1.ClassSchema.generate(error_response_dto_1.ErrorResponseDto);
|
|
36
38
|
return {
|
|
37
|
-
host: '
|
|
38
|
-
port:
|
|
39
|
+
host: common_1.Config.get('app.host'),
|
|
40
|
+
port: common_1.Config.get('app.port'),
|
|
39
41
|
responseSchema: { '4xx': errorResponseSchema, '5xx': errorResponseSchema },
|
|
40
42
|
errorHandler: new classes_1.DefaultErrorHandler(),
|
|
41
43
|
maskSensitiveData: common_1.Config.isProd(),
|
|
@@ -47,6 +49,14 @@ let FastifyModule = FastifyModule_1 = class FastifyModule {
|
|
|
47
49
|
},
|
|
48
50
|
};
|
|
49
51
|
}
|
|
52
|
+
static createConfigFactory(factory) {
|
|
53
|
+
return (...args) => {
|
|
54
|
+
const config = factory(...args);
|
|
55
|
+
if (config instanceof Promise)
|
|
56
|
+
return config.then(resolvedConfig => Object.assign({}, this.getDefaultConfig(), resolvedConfig));
|
|
57
|
+
return Object.assign({}, this.getDefaultConfig(), config);
|
|
58
|
+
};
|
|
59
|
+
}
|
|
50
60
|
static forRoot(options) {
|
|
51
61
|
const config = Object.assign({}, this.getDefaultConfig(), common_1.utils.object.omitKeys(options, ['imports', 'controllers', 'providers', 'exports', 'fastifyFactory']));
|
|
52
62
|
return this.forRootAsync({
|
|
@@ -61,7 +71,7 @@ let FastifyModule = FastifyModule_1 = class FastifyModule {
|
|
|
61
71
|
static forRootAsync(options) {
|
|
62
72
|
const fastifyFactory = (config) => (0, fastify_utils_1.createFastifyInstance)(config, options.fastifyFactory);
|
|
63
73
|
const providers = [{ token: app_1.Router, useClass: fastify_router_1.FastifyRouter }, services_1.ContextService];
|
|
64
|
-
providers.push({ token: constants_1.FASTIFY_CONFIG, useFactory: options.useFactory, inject: options.inject });
|
|
74
|
+
providers.push({ token: constants_1.FASTIFY_CONFIG, useFactory: this.createConfigFactory(options.useFactory), inject: options.inject });
|
|
65
75
|
providers.push({ token: constants_1.FASTIFY_INSTANCE, useFactory: fastifyFactory, inject: [constants_1.FASTIFY_CONFIG] });
|
|
66
76
|
if (options.providers)
|
|
67
77
|
providers.push(...options.providers);
|
|
@@ -86,7 +86,8 @@ async function createFastifyInstance(config, fastifyFactory) {
|
|
|
86
86
|
const instance = (0, fastify_1.fastify)(options);
|
|
87
87
|
instance.setSchemaErrorFormatter(formatSchemaErrors);
|
|
88
88
|
instance.setNotFoundHandler(exports.notFoundHandler);
|
|
89
|
-
instance.setErrorHandler(errorHandler.handle.bind(errorHandler));
|
|
90
89
|
instance.setValidatorCompiler(routeSchema => compileValidator(routeSchema, { strictValidator, lenientValidator }));
|
|
90
|
+
if (errorHandler)
|
|
91
|
+
instance.setErrorHandler(errorHandler.handle.bind(errorHandler));
|
|
91
92
|
return fastifyFactory ? await fastifyFactory(instance) : instance;
|
|
92
93
|
}
|
package/cjs/server.error.js
CHANGED
|
@@ -23,6 +23,10 @@ const ERROR_STATUS_CODES = {
|
|
|
23
23
|
[common_1.ErrorType.UNAUTHORIZED]: 403,
|
|
24
24
|
[common_1.ErrorType.VALIDATION_ERROR]: 422,
|
|
25
25
|
[common_1.ErrorType.CONFLICT]: 409,
|
|
26
|
+
[common_1.ErrorType.INVALID_REQUEST]: 400,
|
|
27
|
+
[common_1.ErrorType.IO_ERROR]: 400,
|
|
28
|
+
[common_1.ErrorType.PERMISSION_DENIED]: 403,
|
|
29
|
+
[common_1.ErrorType.INTERNAL_ERROR]: 500,
|
|
26
30
|
};
|
|
27
31
|
class ServerError extends common_1.AppError {
|
|
28
32
|
getStatusCode() {
|
|
@@ -14,22 +14,28 @@ import { ContextService } from '../services/index.js';
|
|
|
14
14
|
/**
|
|
15
15
|
* Defining types
|
|
16
16
|
*/
|
|
17
|
+
declare module '@shadow-library/common' {
|
|
18
|
+
interface ConfigRecords {
|
|
19
|
+
'app.port': number;
|
|
20
|
+
'app.host': string;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
17
23
|
export interface FastifyConfig extends FastifyServerOptions {
|
|
18
24
|
/**
|
|
19
25
|
* The host on which the Fastify instance is to be started
|
|
20
|
-
* @default
|
|
26
|
+
* @default localhost
|
|
21
27
|
*/
|
|
22
|
-
host
|
|
28
|
+
host?: string;
|
|
23
29
|
/**
|
|
24
30
|
* The port on which the Fastify instance is to be started
|
|
25
31
|
* @default 8080
|
|
26
32
|
*/
|
|
27
|
-
port
|
|
33
|
+
port?: number;
|
|
28
34
|
/**
|
|
29
35
|
* The error handler to be used to handle errors thrown by the Fastify instance
|
|
30
36
|
* @default DefaultErrorHandler
|
|
31
37
|
*/
|
|
32
|
-
errorHandler
|
|
38
|
+
errorHandler?: ErrorHandler;
|
|
33
39
|
/**
|
|
34
40
|
* The schema to be used to validate the response of the Fastify instance
|
|
35
41
|
* @default { '4xx': errorResponseSchema, '5xx': errorResponseSchema }
|
|
@@ -11,6 +11,7 @@ import { FastifyModuleAsyncOptions, FastifyModuleOptions } from './fastify-modul
|
|
|
11
11
|
*/
|
|
12
12
|
export declare class FastifyModule {
|
|
13
13
|
private static getDefaultConfig;
|
|
14
|
+
private static createConfigFactory;
|
|
14
15
|
static forRoot(options: FastifyModuleOptions): DynamicModule;
|
|
15
16
|
static forRootAsync(options: FastifyModuleAsyncOptions): DynamicModule;
|
|
16
17
|
}
|
|
@@ -29,10 +29,12 @@ import { createFastifyInstance } from './fastify.utils.js';
|
|
|
29
29
|
*/
|
|
30
30
|
let FastifyModule = FastifyModule_1 = class FastifyModule {
|
|
31
31
|
static getDefaultConfig() {
|
|
32
|
+
Config.load('app.host', { defaultValue: 'localhost' });
|
|
33
|
+
Config.load('app.port', { defaultValue: '8080', validateType: 'number' });
|
|
32
34
|
const errorResponseSchema = ClassSchema.generate(ErrorResponseDto);
|
|
33
35
|
return {
|
|
34
|
-
host: '
|
|
35
|
-
port:
|
|
36
|
+
host: Config.get('app.host'),
|
|
37
|
+
port: Config.get('app.port'),
|
|
36
38
|
responseSchema: { '4xx': errorResponseSchema, '5xx': errorResponseSchema },
|
|
37
39
|
errorHandler: new DefaultErrorHandler(),
|
|
38
40
|
maskSensitiveData: Config.isProd(),
|
|
@@ -44,6 +46,14 @@ let FastifyModule = FastifyModule_1 = class FastifyModule {
|
|
|
44
46
|
},
|
|
45
47
|
};
|
|
46
48
|
}
|
|
49
|
+
static createConfigFactory(factory) {
|
|
50
|
+
return (...args) => {
|
|
51
|
+
const config = factory(...args);
|
|
52
|
+
if (config instanceof Promise)
|
|
53
|
+
return config.then(resolvedConfig => Object.assign({}, this.getDefaultConfig(), resolvedConfig));
|
|
54
|
+
return Object.assign({}, this.getDefaultConfig(), config);
|
|
55
|
+
};
|
|
56
|
+
}
|
|
47
57
|
static forRoot(options) {
|
|
48
58
|
const config = Object.assign({}, this.getDefaultConfig(), utils.object.omitKeys(options, ['imports', 'controllers', 'providers', 'exports', 'fastifyFactory']));
|
|
49
59
|
return this.forRootAsync({
|
|
@@ -58,7 +68,7 @@ let FastifyModule = FastifyModule_1 = class FastifyModule {
|
|
|
58
68
|
static forRootAsync(options) {
|
|
59
69
|
const fastifyFactory = (config) => createFastifyInstance(config, options.fastifyFactory);
|
|
60
70
|
const providers = [{ token: Router, useClass: FastifyRouter }, ContextService];
|
|
61
|
-
providers.push({ token: FASTIFY_CONFIG, useFactory: options.useFactory, inject: options.inject });
|
|
71
|
+
providers.push({ token: FASTIFY_CONFIG, useFactory: this.createConfigFactory(options.useFactory), inject: options.inject });
|
|
62
72
|
providers.push({ token: FASTIFY_INSTANCE, useFactory: fastifyFactory, inject: [FASTIFY_CONFIG] });
|
|
63
73
|
if (options.providers)
|
|
64
74
|
providers.push(...options.providers);
|
|
@@ -76,7 +76,8 @@ export async function createFastifyInstance(config, fastifyFactory) {
|
|
|
76
76
|
const instance = fastify(options);
|
|
77
77
|
instance.setSchemaErrorFormatter(formatSchemaErrors);
|
|
78
78
|
instance.setNotFoundHandler(notFoundHandler);
|
|
79
|
-
instance.setErrorHandler(errorHandler.handle.bind(errorHandler));
|
|
80
79
|
instance.setValidatorCompiler(routeSchema => compileValidator(routeSchema, { strictValidator, lenientValidator }));
|
|
80
|
+
if (errorHandler)
|
|
81
|
+
instance.setErrorHandler(errorHandler.handle.bind(errorHandler));
|
|
81
82
|
return fastifyFactory ? await fastifyFactory(instance) : instance;
|
|
82
83
|
}
|
package/esm/server.error.js
CHANGED
|
@@ -20,6 +20,10 @@ const ERROR_STATUS_CODES = {
|
|
|
20
20
|
[ErrorType.UNAUTHORIZED]: 403,
|
|
21
21
|
[ErrorType.VALIDATION_ERROR]: 422,
|
|
22
22
|
[ErrorType.CONFLICT]: 409,
|
|
23
|
+
[ErrorType.INVALID_REQUEST]: 400,
|
|
24
|
+
[ErrorType.IO_ERROR]: 400,
|
|
25
|
+
[ErrorType.PERMISSION_DENIED]: 403,
|
|
26
|
+
[ErrorType.INTERNAL_ERROR]: 500,
|
|
23
27
|
};
|
|
24
28
|
export class ServerError extends AppError {
|
|
25
29
|
getStatusCode() {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shadow-library/fastify",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.6.
|
|
4
|
+
"version": "1.6.4",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"description": "A Fastify wrapper featuring decorator-based routing, middleware and error handling",
|
|
7
7
|
"repository": {
|
|
@@ -27,9 +27,9 @@
|
|
|
27
27
|
},
|
|
28
28
|
"peerDependencies": {
|
|
29
29
|
"@fastify/view": "^10.0.0",
|
|
30
|
-
"@shadow-library/app": "^1.
|
|
31
|
-
"@shadow-library/class-schema": "^0.
|
|
32
|
-
"@shadow-library/common": "^1.
|
|
30
|
+
"@shadow-library/app": "^1.3.1",
|
|
31
|
+
"@shadow-library/class-schema": "^0.2.0",
|
|
32
|
+
"@shadow-library/common": "^1.5.2",
|
|
33
33
|
"reflect-metadata": "^0.2.2"
|
|
34
34
|
},
|
|
35
35
|
"peerDependenciesMeta": {
|