@dismissible/nestjs-api 2.0.1 → 2.0.2-alpha.f50def9.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/config/.env.development.yaml +10 -0
- package/config/.env.yaml +17 -0
- package/package.json +22 -21
- package/src/app.module.d.ts +4 -0
- package/src/app.module.js +10 -2
- package/src/app.module.js.map +1 -1
- package/src/config/default-app.config.d.ts +2 -0
- package/src/config/default-app.config.js +7 -0
- package/src/config/default-app.config.js.map +1 -1
- package/src/dismissible-nest-factory.d.ts +4 -0
- package/src/dismissible-nest-factory.js.map +1 -1
|
@@ -31,6 +31,16 @@ storage:
|
|
|
31
31
|
jwtAuth:
|
|
32
32
|
enabled: false
|
|
33
33
|
|
|
34
|
+
rateLimiter:
|
|
35
|
+
enabled: true
|
|
36
|
+
points: ${DISMISSIBLE_RATE_LIMITER_POINTS:-10000}
|
|
37
|
+
duration: ${DISMISSIBLE_RATE_LIMITER_DURATION:-1}
|
|
38
|
+
blockDuration: ${DISMISSIBLE_RATE_LIMITER_BLOCK_DURATION:-1}
|
|
39
|
+
keyType: ${DISMISSIBLE_RATE_LIMITER_KEY_TYPE:-ip,origin,referrer}
|
|
40
|
+
keyMode: ${DISMISSIBLE_RATE_LIMITER_KEY_MODE:-any}
|
|
41
|
+
ignoredKeys: ${DISMISSIBLE_RATE_LIMITER_IGNORED_KEYS:-}
|
|
42
|
+
priority: ${DISMISSIBLE_RATE_LIMITER_PRIORITY:--101}
|
|
43
|
+
|
|
34
44
|
validation:
|
|
35
45
|
disableErrorMessages: false
|
|
36
46
|
whitelist: false
|
package/config/.env.yaml
CHANGED
|
@@ -48,6 +48,23 @@ jwtAuth:
|
|
|
48
48
|
userIdMatchRegex: ${DISMISSIBLE_JWT_AUTH_USER_ID_MATCH_REGEX:-}
|
|
49
49
|
userIdClaim: ${DISMISSIBLE_JWT_AUTH_USER_ID_CLAIM:-sub}
|
|
50
50
|
|
|
51
|
+
rateLimiter:
|
|
52
|
+
enabled: ${DISMISSIBLE_RATE_LIMITER_ENABLED:-false}
|
|
53
|
+
# Number of requests allowed per duration window
|
|
54
|
+
points: ${DISMISSIBLE_RATE_LIMITER_POINTS:-10000}
|
|
55
|
+
# Time window in seconds for rate limiting
|
|
56
|
+
duration: ${DISMISSIBLE_RATE_LIMITER_DURATION:-1}
|
|
57
|
+
# Optional: Duration in seconds to block requests after limit is exceeded (if not set, requests are allowed again after the duration window resets)
|
|
58
|
+
blockDuration: ${DISMISSIBLE_RATE_LIMITER_BLOCK_DURATION:-}
|
|
59
|
+
# Key type(s) for rate limiting: 'ip' (by IP address), 'origin' (by Origin header), 'referrer' (by Referer header). Can be comma-separated to combine types (e.g., 'ip,origin')
|
|
60
|
+
keyType: ${DISMISSIBLE_RATE_LIMITER_KEY_TYPE:-ip,origin,referrer}
|
|
61
|
+
# Mode for combining key types: 'and' (combine all), 'or' (use first available), 'any' (check all independently)
|
|
62
|
+
keyMode: ${DISMISSIBLE_RATE_LIMITER_KEY_MODE:-any}
|
|
63
|
+
# Optional: Comma-separated keys to bypass rate limiting. Matching is exact after trim+lowercase. For Origin/Referer, the URL hostname is matched (e.g. "https://google.com/search" matches "google.com").
|
|
64
|
+
ignoredKeys: ${DISMISSIBLE_RATE_LIMITER_IGNORED_KEYS:-}
|
|
65
|
+
# Hook priority (lower numbers run first)
|
|
66
|
+
priority: ${DISMISSIBLE_RATE_LIMITER_PRIORITY:--101}
|
|
67
|
+
|
|
51
68
|
validation:
|
|
52
69
|
disableErrorMessages: ${DISMISSIBLE_VALIDATION_DISABLE_ERROR_MESSAGES:-true}
|
|
53
70
|
whitelist: ${DISMISSIBLE_VALIDATION_WHITELIST:-true}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dismissible/nestjs-api",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2-alpha.f50def9.0",
|
|
4
4
|
"description": "Dismissible API application",
|
|
5
5
|
"main": "./src/index.js",
|
|
6
6
|
"types": "./src/index.d.ts",
|
|
@@ -30,25 +30,26 @@
|
|
|
30
30
|
"storage:setup:dynamodb": "npx dismissible-dynamodb-setup"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@dismissible/nestjs-core": "
|
|
34
|
-
"@dismissible/nestjs-item": "
|
|
35
|
-
"@dismissible/nestjs-jwt-auth-hook": "
|
|
36
|
-
"@dismissible/nestjs-storage": "
|
|
37
|
-
"@dismissible/nestjs-postgres-storage": "
|
|
38
|
-
"@dismissible/nestjs-dynamodb-storage": "
|
|
39
|
-
"@dismissible/nestjs-logger": "
|
|
40
|
-
"@nestjs
|
|
41
|
-
"@nestjs/
|
|
42
|
-
"@nestjs/
|
|
43
|
-
"fastify": "
|
|
44
|
-
"
|
|
45
|
-
"@fastify/
|
|
46
|
-
"@
|
|
47
|
-
"
|
|
48
|
-
"class-
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
33
|
+
"@dismissible/nestjs-core": "2.0.2-alpha.f50def9.0",
|
|
34
|
+
"@dismissible/nestjs-item": "2.0.2-alpha.f50def9.0",
|
|
35
|
+
"@dismissible/nestjs-jwt-auth-hook": "2.0.2-alpha.f50def9.0",
|
|
36
|
+
"@dismissible/nestjs-storage": "2.0.2-alpha.f50def9.0",
|
|
37
|
+
"@dismissible/nestjs-postgres-storage": "2.0.2-alpha.f50def9.0",
|
|
38
|
+
"@dismissible/nestjs-dynamodb-storage": "2.0.2-alpha.f50def9.0",
|
|
39
|
+
"@dismissible/nestjs-logger": "2.0.2-alpha.f50def9.0",
|
|
40
|
+
"@dismissible/nestjs-rate-limiter-hook": "2.0.2-alpha.f50def9.0",
|
|
41
|
+
"@nestjs/common": "11.1.11",
|
|
42
|
+
"@nestjs/core": "11.1.11",
|
|
43
|
+
"@nestjs/platform-fastify": "11.1.11",
|
|
44
|
+
"fastify": "5.6.2",
|
|
45
|
+
"@fastify/helmet": "13.0.2",
|
|
46
|
+
"@fastify/static": "8.3.0",
|
|
47
|
+
"@nestjs/swagger": "11.2.3",
|
|
48
|
+
"class-transformer": "0.5.1",
|
|
49
|
+
"class-validator": "0.14.3",
|
|
50
|
+
"nest-typed-config": "2.10.1",
|
|
51
|
+
"reflect-metadata": "0.2.2",
|
|
52
|
+
"rxjs": "7.8.2"
|
|
52
53
|
},
|
|
53
54
|
"keywords": [
|
|
54
55
|
"nestjs",
|
|
@@ -64,4 +65,4 @@
|
|
|
64
65
|
"access": "public"
|
|
65
66
|
},
|
|
66
67
|
"type": "commonjs"
|
|
67
|
-
}
|
|
68
|
+
}
|
package/src/app.module.d.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { DynamicModule, ModuleMetadata, Type } from '@nestjs/common';
|
|
2
|
+
import { IDismissibleLifecycleHook } from '@dismissible/nestjs-core';
|
|
2
3
|
import { IDismissibleLogger } from '@dismissible/nestjs-logger';
|
|
3
4
|
import { DefaultAppConfig } from './config/default-app.config';
|
|
5
|
+
import { StorageType } from './storage/storage.config';
|
|
4
6
|
export type AppModuleOptions = {
|
|
5
7
|
configPath?: string;
|
|
6
8
|
schema?: new () => DefaultAppConfig;
|
|
7
9
|
logger?: Type<IDismissibleLogger>;
|
|
8
10
|
imports?: DynamicModule[];
|
|
11
|
+
hooks?: Type<IDismissibleLifecycleHook>[];
|
|
12
|
+
storage?: StorageType;
|
|
9
13
|
};
|
|
10
14
|
export declare class AppModule {
|
|
11
15
|
static forRoot(options?: AppModuleOptions): {
|
package/src/app.module.js
CHANGED
|
@@ -11,6 +11,8 @@ const path_1 = require("path");
|
|
|
11
11
|
const nestjs_core_1 = require("@dismissible/nestjs-core");
|
|
12
12
|
const dynamic_storage_module_1 = require("./storage/dynamic-storage.module");
|
|
13
13
|
const nestjs_jwt_auth_hook_1 = require("@dismissible/nestjs-jwt-auth-hook");
|
|
14
|
+
const nestjs_rate_limiter_hook_1 = require("@dismissible/nestjs-rate-limiter-hook");
|
|
15
|
+
const class_transformer_1 = require("class-transformer");
|
|
14
16
|
let AppModule = AppModule_1 = class AppModule {
|
|
15
17
|
static forRoot(options) {
|
|
16
18
|
return {
|
|
@@ -27,19 +29,25 @@ let AppModule = AppModule_1 = class AppModule {
|
|
|
27
29
|
}),
|
|
28
30
|
health_1.HealthModule,
|
|
29
31
|
...(options?.imports ?? []),
|
|
32
|
+
nestjs_rate_limiter_hook_1.RateLimiterHookModule.forRootAsync({
|
|
33
|
+
useFactory: (config) => {
|
|
34
|
+
return config.rateLimiter ?? (0, class_transformer_1.plainToClass)(nestjs_rate_limiter_hook_1.RateLimiterHookConfig, { enabled: false });
|
|
35
|
+
},
|
|
36
|
+
inject: [options?.schema ?? app_config_1.AppConfig],
|
|
37
|
+
}),
|
|
30
38
|
nestjs_jwt_auth_hook_1.JwtAuthHookModule.forRootAsync({
|
|
31
39
|
useFactory: (config) => config,
|
|
32
40
|
inject: [nestjs_jwt_auth_hook_1.JwtAuthHookConfig],
|
|
33
41
|
}),
|
|
34
42
|
nestjs_core_1.DismissibleModule.forRoot({
|
|
35
43
|
logger: options?.logger,
|
|
36
|
-
hooks: [nestjs_jwt_auth_hook_1.JwtAuthHook],
|
|
44
|
+
hooks: [nestjs_jwt_auth_hook_1.JwtAuthHook, nestjs_rate_limiter_hook_1.RateLimiterHook, ...(options?.hooks ?? [])],
|
|
37
45
|
storage: dynamic_storage_module_1.DynamicStorageModule.forRootAsync({
|
|
38
46
|
// TODO: nestjs doesn't support optional dynamic modules.
|
|
39
47
|
// So instead, we are just using the env vars to switch between modules.
|
|
40
48
|
// This isn't ideal, but there's not a great option. I will look to see
|
|
41
49
|
// if we can raise an issue similar to this: https://github.com/nestjs/nest/issues/9868
|
|
42
|
-
storage: process.env.DISMISSIBLE_STORAGE_TYPE,
|
|
50
|
+
storage: options?.storage ?? process.env.DISMISSIBLE_STORAGE_TYPE,
|
|
43
51
|
}),
|
|
44
52
|
}),
|
|
45
53
|
],
|
package/src/app.module.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.module.js","sourceRoot":"","sources":["../../../api/src/app.module.ts"],"names":[],"mappings":";;;;;AAAA,2CAA6E;AAC7E,qCAAwC;AACxC,qCAAwC;AACxC,oDAAgD;AAChD,+BAA4B;AAC5B,
|
|
1
|
+
{"version":3,"file":"app.module.js","sourceRoot":"","sources":["../../../api/src/app.module.ts"],"names":[],"mappings":";;;;;AAAA,2CAA6E;AAC7E,qCAAwC;AACxC,qCAAwC;AACxC,oDAAgD;AAChD,+BAA4B;AAC5B,0DAAwF;AAGxF,6EAAwE;AACxE,4EAI2C;AAE3C,oFAI+C;AAC/C,yDAAiD;AAY1C,IAAM,SAAS,iBAAf,MAAM,SAAS;IACpB,MAAM,CAAC,OAAO,CAAC,OAA0B;QACvC,OAAO;YACL,MAAM,EAAE,WAAS;YACjB,GAAG,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC;SACnC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,iBAAiB,CAAC,OAA0B;QACjD,OAAO;YACL,OAAO,EAAE;gBACP,qBAAY,CAAC,OAAO,CAAC;oBACnB,IAAI,EAAE,OAAO,EAAE,UAAU,IAAI,IAAA,WAAI,EAAC,SAAS,EAAE,WAAW,CAAC;oBACzD,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,sBAAS;iBACrC,CAAC;gBACF,qBAAY;gBACZ,GAAG,CAAC,OAAO,EAAE,OAAO,IAAI,EAAE,CAAC;gBAC3B,gDAAqB,CAAC,YAAY,CAAC;oBACjC,UAAU,EAAE,CAAC,MAAwB,EAAE,EAAE;wBACvC,OAAO,MAAM,CAAC,WAAW,IAAI,IAAA,gCAAY,EAAC,gDAAqB,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;oBACvF,CAAC;oBACD,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,IAAI,sBAAS,CAAC;iBACvC,CAAC;gBACF,wCAAiB,CAAC,YAAY,CAAC;oBAC7B,UAAU,EAAE,CAAC,MAAyB,EAAE,EAAE,CAAC,MAAM;oBACjD,MAAM,EAAE,CAAC,wCAAiB,CAAC;iBAC5B,CAAC;gBACF,+BAAiB,CAAC,OAAO,CAAC;oBACxB,MAAM,EAAE,OAAO,EAAE,MAAM;oBACvB,KAAK,EAAE,CAAC,kCAAW,EAAE,0CAAe,EAAE,GAAG,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;oBAChE,OAAO,EAAE,6CAAoB,CAAC,YAAY,CAAC;wBACzC,yDAAyD;wBACzD,0EAA0E;wBAC1E,yEAAyE;wBACzE,yFAAyF;wBACzF,OAAO,EAAE,OAAO,EAAE,OAAO,IAAK,OAAO,CAAC,GAAG,CAAC,wBAAwC;qBACnF,CAAC;iBACH,CAAC;aACH;SACF,CAAC;IACJ,CAAC;CACF,CAAA;AAzCY,8BAAS;oBAAT,SAAS;IADrB,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,SAAS,CAyCrB"}
|
|
@@ -2,8 +2,10 @@ import { ServerConfig } from '../server/server.config';
|
|
|
2
2
|
import { CorsConfig } from '../cors';
|
|
3
3
|
import { HelmetConfig } from '../helmet';
|
|
4
4
|
import { ValidationConfig } from '../validation';
|
|
5
|
+
import { RateLimiterHookConfig } from '@dismissible/nestjs-rate-limiter-hook';
|
|
5
6
|
export declare class DefaultAppConfig {
|
|
6
7
|
readonly server: ServerConfig;
|
|
8
|
+
readonly rateLimiter?: RateLimiterHookConfig;
|
|
7
9
|
readonly cors: CorsConfig;
|
|
8
10
|
readonly helmet: HelmetConfig;
|
|
9
11
|
readonly validation: ValidationConfig;
|
|
@@ -8,6 +8,7 @@ const server_config_1 = require("../server/server.config");
|
|
|
8
8
|
const cors_1 = require("../cors");
|
|
9
9
|
const helmet_1 = require("../helmet");
|
|
10
10
|
const validation_1 = require("../validation");
|
|
11
|
+
const nestjs_rate_limiter_hook_1 = require("@dismissible/nestjs-rate-limiter-hook");
|
|
11
12
|
class DefaultAppConfig {
|
|
12
13
|
}
|
|
13
14
|
exports.DefaultAppConfig = DefaultAppConfig;
|
|
@@ -16,6 +17,12 @@ tslib_1.__decorate([
|
|
|
16
17
|
(0, class_transformer_1.Type)(() => server_config_1.ServerConfig),
|
|
17
18
|
tslib_1.__metadata("design:type", server_config_1.ServerConfig)
|
|
18
19
|
], DefaultAppConfig.prototype, "server", void 0);
|
|
20
|
+
tslib_1.__decorate([
|
|
21
|
+
(0, class_validator_1.IsOptional)(),
|
|
22
|
+
(0, class_validator_1.ValidateNested)(),
|
|
23
|
+
(0, class_transformer_1.Type)(() => nestjs_rate_limiter_hook_1.RateLimiterHookConfig),
|
|
24
|
+
tslib_1.__metadata("design:type", nestjs_rate_limiter_hook_1.RateLimiterHookConfig)
|
|
25
|
+
], DefaultAppConfig.prototype, "rateLimiter", void 0);
|
|
19
26
|
tslib_1.__decorate([
|
|
20
27
|
(0, class_validator_1.ValidateNested)(),
|
|
21
28
|
(0, class_transformer_1.Type)(() => cors_1.CorsConfig),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default-app.config.js","sourceRoot":"","sources":["../../../../api/src/config/default-app.config.ts"],"names":[],"mappings":";;;;AAAA,
|
|
1
|
+
{"version":3,"file":"default-app.config.js","sourceRoot":"","sources":["../../../../api/src/config/default-app.config.ts"],"names":[],"mappings":";;;;AAAA,qDAA6D;AAC7D,yDAAyC;AACzC,2DAAuD;AACvD,kCAAqC;AACrC,sCAAyC;AACzC,8CAAiD;AACjD,oFAA8E;AAE9E,MAAa,gBAAgB;CAqB5B;AArBD,4CAqBC;AAlBiB;IAFf,IAAA,gCAAc,GAAE;IAChB,IAAA,wBAAI,EAAC,GAAG,EAAE,CAAC,4BAAY,CAAC;sCACA,4BAAY;gDAAC;AAKtB;IAHf,IAAA,4BAAU,GAAE;IACZ,IAAA,gCAAc,GAAE;IAChB,IAAA,wBAAI,EAAC,GAAG,EAAE,CAAC,gDAAqB,CAAC;sCACJ,gDAAqB;qDAAC;AAIpC;IAFf,IAAA,gCAAc,GAAE;IAChB,IAAA,wBAAI,EAAC,GAAG,EAAE,CAAC,iBAAU,CAAC;sCACA,iBAAU;8CAAC;AAIlB;IAFf,IAAA,gCAAc,GAAE;IAChB,IAAA,wBAAI,EAAC,GAAG,EAAE,CAAC,qBAAY,CAAC;sCACA,qBAAY;gDAAC;AAItB;IAFf,IAAA,gCAAc,GAAE;IAChB,IAAA,wBAAI,EAAC,GAAG,EAAE,CAAC,6BAAgB,CAAC;sCACA,6BAAgB;oDAAC"}
|
|
@@ -2,6 +2,8 @@ import { INestApplication } from '@nestjs/common';
|
|
|
2
2
|
import { DefaultAppConfig } from './config/default-app.config';
|
|
3
3
|
import { IDismissibleLogger } from '@dismissible/nestjs-logger';
|
|
4
4
|
import { Type, DynamicModule } from '@nestjs/common';
|
|
5
|
+
import { IDismissibleLifecycleHook } from '@dismissible/nestjs-hooks';
|
|
6
|
+
import { StorageType } from './storage/storage.config';
|
|
5
7
|
export interface IDismissibleNestApplication {
|
|
6
8
|
getNestApplication(): INestApplication;
|
|
7
9
|
start(): Promise<void>;
|
|
@@ -11,6 +13,8 @@ export interface IDismissibleNestFactoryOptions {
|
|
|
11
13
|
schema?: new () => DefaultAppConfig;
|
|
12
14
|
logger?: Type<IDismissibleLogger>;
|
|
13
15
|
imports?: DynamicModule[];
|
|
16
|
+
hooks?: Type<IDismissibleLifecycleHook>[];
|
|
17
|
+
storage?: StorageType;
|
|
14
18
|
}
|
|
15
19
|
export declare class DismissibleNestFactory {
|
|
16
20
|
static create(options?: IDismissibleNestFactoryOptions): Promise<IDismissibleNestApplication>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dismissible-nest-factory.js","sourceRoot":"","sources":["../../../api/src/dismissible-nest-factory.ts"],"names":[],"mappings":";;;AACA,uCAA2C;AAC3C,+DAAkF;AAClF,6CAAyC;AACzC,0DAAsD;AACtD,2CAA2C;
|
|
1
|
+
{"version":3,"file":"dismissible-nest-factory.js","sourceRoot":"","sources":["../../../api/src/dismissible-nest-factory.ts"],"names":[],"mappings":";;;AACA,uCAA2C;AAC3C,+DAAkF;AAClF,6CAAyC;AACzC,0DAAsD;AACtD,2CAA2C;AAqB3C,MAAM,0BAA0B;IAC9B,YAA6B,GAA2B;QAA3B,QAAG,GAAH,GAAG,CAAwB;IAAG,CAAC;IAE5D,KAAK,CAAC,KAAK;QACT,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,4BAAY,CAAC,CAAC;QAChD,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,IAAI,IAAI,CAAC;QACvC,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACvC,OAAO,CAAC,GAAG,CAAC,kDAAkD,IAAI,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,kBAAkB;QAChB,OAAO,IAAI,CAAC,GAAG,CAAC;IAClB,CAAC;CACF;AAED,MAAa,sBAAsB;IACjC,MAAM,CAAC,KAAK,CAAC,MAAM,CACjB,OAAwC;QAExC,MAAM,GAAG,GAAG,MAAM,kBAAW,CAAC,MAAM,CAClC,sBAAS,CAAC,OAAO,CAAC,OAAO,CAAC,EAC1B,IAAI,iCAAc,CAAC;YACjB,SAAS,EAAE,EAAE,GAAG,IAAI,EAAE,OAAO;SAC9B,CAAC,CACH,CAAC;QACF,MAAM,IAAA,wBAAY,EAAC,GAAG,CAAC,CAAC;QAExB,OAAO,IAAI,0BAA0B,CAAC,GAAG,CAAC,CAAC;IAC7C,CAAC;CACF;AAdD,wDAcC"}
|