@n8n/decorators 1.5.1 → 1.6.1

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.
@@ -6,4 +6,5 @@ export { Middleware } from './middleware';
6
6
  export { ControllerRegistryMetadata } from './controller-registry-metadata';
7
7
  export { Licensed } from './licensed';
8
8
  export { GlobalScope, ProjectScope } from './scoped';
9
- export type { AccessScope, Controller, CorsOptions, Method, RateLimit, StaticRouterMetadata, } from './types';
9
+ export type { AccessScope, Controller, CorsOptions, Method, StaticRouterMetadata, } from './types';
10
+ export { type RateLimiterLimits, type BodyKeyedRateLimiterConfig, type UserKeyedRateLimiterConfig, type KeyedRateLimiterConfig, createBodyKeyedRateLimiter, createUserKeyedRateLimiter, } from './rate-limit';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ProjectScope = exports.GlobalScope = exports.Licensed = exports.ControllerRegistryMetadata = exports.Middleware = exports.Options = exports.Head = exports.Delete = exports.Patch = exports.Put = exports.Post = exports.Get = exports.RootLevelController = exports.RestController = exports.Param = exports.Query = exports.Body = void 0;
3
+ exports.createUserKeyedRateLimiter = exports.createBodyKeyedRateLimiter = exports.ProjectScope = exports.GlobalScope = exports.Licensed = exports.ControllerRegistryMetadata = exports.Middleware = exports.Options = exports.Head = exports.Delete = exports.Patch = exports.Put = exports.Post = exports.Get = exports.RootLevelController = exports.RestController = exports.Param = exports.Query = exports.Body = void 0;
4
4
  var args_1 = require("./args");
5
5
  Object.defineProperty(exports, "Body", { enumerable: true, get: function () { return args_1.Body; } });
6
6
  Object.defineProperty(exports, "Query", { enumerable: true, get: function () { return args_1.Query; } });
@@ -26,4 +26,7 @@ Object.defineProperty(exports, "Licensed", { enumerable: true, get: function ()
26
26
  var scoped_1 = require("./scoped");
27
27
  Object.defineProperty(exports, "GlobalScope", { enumerable: true, get: function () { return scoped_1.GlobalScope; } });
28
28
  Object.defineProperty(exports, "ProjectScope", { enumerable: true, get: function () { return scoped_1.ProjectScope; } });
29
+ var rate_limit_1 = require("./rate-limit");
30
+ Object.defineProperty(exports, "createBodyKeyedRateLimiter", { enumerable: true, get: function () { return rate_limit_1.createBodyKeyedRateLimiter; } });
31
+ Object.defineProperty(exports, "createUserKeyedRateLimiter", { enumerable: true, get: function () { return rate_limit_1.createUserKeyedRateLimiter; } });
29
32
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/controller/index.ts"],"names":[],"mappings":";;;AAAA,+BAA4C;AAAnC,4FAAA,IAAI,OAAA;AAAE,6FAAA,KAAK,OAAA;AAAE,6FAAA,KAAK,OAAA;AAC3B,qDAAmD;AAA1C,iHAAA,cAAc,OAAA;AACvB,iEAA8D;AAArD,4HAAA,mBAAmB,OAAA;AAC5B,iCAAuE;AAA9D,4FAAA,GAAG,OAAA;AAAE,6FAAA,IAAI,OAAA;AAAE,4FAAA,GAAG,OAAA;AAAE,8FAAA,KAAK,OAAA;AAAE,+FAAA,MAAM,OAAA;AAAE,6FAAA,IAAI,OAAA;AAAE,gGAAA,OAAO,OAAA;AACrD,2CAA0C;AAAjC,wGAAA,UAAU,OAAA;AACnB,+EAA4E;AAAnE,0IAAA,0BAA0B,OAAA;AACnC,uCAAsC;AAA7B,oGAAA,QAAQ,OAAA;AACjB,mCAAqD;AAA5C,qGAAA,WAAW,OAAA;AAAE,sGAAA,YAAY,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/controller/index.ts"],"names":[],"mappings":";;;AAAA,+BAA4C;AAAnC,4FAAA,IAAI,OAAA;AAAE,6FAAA,KAAK,OAAA;AAAE,6FAAA,KAAK,OAAA;AAC3B,qDAAmD;AAA1C,iHAAA,cAAc,OAAA;AACvB,iEAA8D;AAArD,4HAAA,mBAAmB,OAAA;AAC5B,iCAAuE;AAA9D,4FAAA,GAAG,OAAA;AAAE,6FAAA,IAAI,OAAA;AAAE,4FAAA,GAAG,OAAA;AAAE,8FAAA,KAAK,OAAA;AAAE,+FAAA,MAAM,OAAA;AAAE,6FAAA,IAAI,OAAA;AAAE,gGAAA,OAAO,OAAA;AACrD,2CAA0C;AAAjC,wGAAA,UAAU,OAAA;AACnB,+EAA4E;AAAnE,0IAAA,0BAA0B,OAAA;AACnC,uCAAsC;AAA7B,oGAAA,QAAQ,OAAA;AACjB,mCAAqD;AAA5C,qGAAA,WAAW,OAAA;AAAE,sGAAA,YAAY,OAAA;AAQlC,2CAOsB;AAFrB,wHAAA,0BAA0B,OAAA;AAC1B,wHAAA,0BAA0B,OAAA"}
@@ -0,0 +1,16 @@
1
+ export interface RateLimiterLimits {
2
+ limit?: number;
3
+ windowMs?: number;
4
+ }
5
+ export interface BodyKeyedRateLimiterConfig extends RateLimiterLimits {
6
+ source: 'body';
7
+ field: string;
8
+ }
9
+ export interface UserKeyedRateLimiterConfig extends RateLimiterLimits {
10
+ source: 'user';
11
+ }
12
+ export type KeyedRateLimiterConfig = BodyKeyedRateLimiterConfig | UserKeyedRateLimiterConfig;
13
+ export declare const createBodyKeyedRateLimiter: <T extends object>({ limit, windowMs, field, }: RateLimiterLimits & {
14
+ field: keyof T & string;
15
+ }) => BodyKeyedRateLimiterConfig;
16
+ export declare const createUserKeyedRateLimiter: ({ limit, windowMs, }: RateLimiterLimits) => UserKeyedRateLimiterConfig;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createUserKeyedRateLimiter = exports.createBodyKeyedRateLimiter = void 0;
4
+ const createBodyKeyedRateLimiter = ({ limit, windowMs, field, }) => ({
5
+ source: 'body',
6
+ limit,
7
+ windowMs,
8
+ field,
9
+ });
10
+ exports.createBodyKeyedRateLimiter = createBodyKeyedRateLimiter;
11
+ const createUserKeyedRateLimiter = ({ limit, windowMs, }) => ({
12
+ source: 'user',
13
+ limit,
14
+ windowMs,
15
+ });
16
+ exports.createUserKeyedRateLimiter = createUserKeyedRateLimiter;
17
+ //# sourceMappingURL=rate-limit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit.js","sourceRoot":"","sources":["../../src/controller/rate-limit.ts"],"names":[],"mappings":";;;AA6CO,MAAM,0BAA0B,GAAG,CAAmB,EAC5D,KAAK,EACL,QAAQ,EACR,KAAK,GAGL,EAA8B,EAAE,CAAC,CAAC;IAClC,MAAM,EAAE,MAAM;IACd,KAAK;IACL,QAAQ;IACR,KAAK;CACL,CAAC,CAAC;AAXU,QAAA,0BAA0B,8BAWpC;AAYI,MAAM,0BAA0B,GAAG,CAAC,EAC1C,KAAK,EACL,QAAQ,GACW,EAA8B,EAAE,CAAC,CAAC;IACrD,MAAM,EAAE,MAAM;IACd,KAAK;IACL,QAAQ;CACR,CAAC,CAAC;AAPU,QAAA,0BAA0B,8BAOpC"}
@@ -1,12 +1,14 @@
1
1
  import type { RequestHandler } from 'express';
2
- import type { CorsOptions, RateLimit } from './types';
2
+ import type { KeyedRateLimiterConfig, RateLimiterLimits } from './rate-limit';
3
+ import type { CorsOptions } from './types';
3
4
  interface RouteOptions {
4
5
  middlewares?: RequestHandler[];
5
6
  usesTemplates?: boolean;
6
7
  skipAuth?: boolean;
7
8
  allowSkipPreviewAuth?: boolean;
8
9
  allowSkipMFA?: boolean;
9
- rateLimit?: boolean | RateLimit;
10
+ ipRateLimit?: boolean | RateLimiterLimits;
11
+ keyedRateLimit?: KeyedRateLimiterConfig;
10
12
  apiKeyAuth?: boolean;
11
13
  cors?: Partial<CorsOptions> | true;
12
14
  }
@@ -13,7 +13,8 @@ const RouteFactory = (method) => (path, options = {}) => (target, handlerName) =
13
13
  routeMetadata.allowSkipPreviewAuth = options.allowSkipPreviewAuth ?? false;
14
14
  routeMetadata.allowSkipMFA = options.allowSkipMFA ?? false;
15
15
  routeMetadata.apiKeyAuth = options.apiKeyAuth ?? false;
16
- routeMetadata.rateLimit = options.rateLimit;
16
+ routeMetadata.ipRateLimit = options.ipRateLimit;
17
+ routeMetadata.keyedRateLimit = options.keyedRateLimit;
17
18
  routeMetadata.cors = options.cors;
18
19
  };
19
20
  exports.Get = RouteFactory('get');
@@ -1 +1 @@
1
- {"version":3,"file":"route.js","sourceRoot":"","sources":["../../src/controller/route.ts"],"names":[],"mappings":";;;AAAA,gCAAoC;AAGpC,iFAA4E;AAmB5E,MAAM,YAAY,GACjB,CAAC,MAAc,EAAE,EAAE,CACnB,CAAC,IAAkB,EAAE,UAAwB,EAAE,EAAmB,EAAE,CACpE,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE;IACvB,MAAM,aAAa,GAAG,cAAS,CAAC,GAAG,CAAC,yDAA0B,CAAC,CAAC,gBAAgB,CAC/E,MAAM,CAAC,WAAyB,EAChC,MAAM,CAAC,WAAW,CAAC,CACnB,CAAC;IACF,aAAa,CAAC,MAAM,GAAG,MAAM,CAAC;IAC9B,aAAa,CAAC,IAAI,GAAG,IAAI,CAAC;IAC1B,aAAa,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC;IACtD,aAAa,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,KAAK,CAAC;IAC7D,aAAa,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,KAAK,CAAC;IACnD,aAAa,CAAC,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,IAAI,KAAK,CAAC;IAC3E,aAAa,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,KAAK,CAAC;IAC3D,aAAa,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,KAAK,CAAC;IACvD,aAAa,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IAC5C,aAAa,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;AACnC,CAAC,CAAC;AAEU,QAAA,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;AAC1B,QAAA,IAAI,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;AAC5B,QAAA,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;AAC1B,QAAA,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;AAC9B,QAAA,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;AAChC,QAAA,IAAI,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;AAC5B,QAAA,OAAO,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC"}
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../../src/controller/route.ts"],"names":[],"mappings":";;;AAAA,gCAAoC;AAGpC,iFAA4E;AAsB5E,MAAM,YAAY,GACjB,CAAC,MAAc,EAAE,EAAE,CACnB,CAAC,IAAkB,EAAE,UAAwB,EAAE,EAAmB,EAAE,CACpE,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE;IACvB,MAAM,aAAa,GAAG,cAAS,CAAC,GAAG,CAAC,yDAA0B,CAAC,CAAC,gBAAgB,CAC/E,MAAM,CAAC,WAAyB,EAChC,MAAM,CAAC,WAAW,CAAC,CACnB,CAAC;IACF,aAAa,CAAC,MAAM,GAAG,MAAM,CAAC;IAC9B,aAAa,CAAC,IAAI,GAAG,IAAI,CAAC;IAC1B,aAAa,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC;IACtD,aAAa,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,KAAK,CAAC;IAC7D,aAAa,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,KAAK,CAAC;IACnD,aAAa,CAAC,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,IAAI,KAAK,CAAC;IAC3E,aAAa,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,KAAK,CAAC;IAC3D,aAAa,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,KAAK,CAAC;IACvD,aAAa,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAChD,aAAa,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;IACtD,aAAa,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;AACnC,CAAC,CAAC;AAEU,QAAA,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;AAC1B,QAAA,IAAI,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;AAC5B,QAAA,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;AAC1B,QAAA,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;AAC9B,QAAA,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;AAChC,QAAA,IAAI,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;AAC5B,QAAA,OAAO,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC"}
@@ -2,6 +2,7 @@ import type { BooleanLicenseFeature } from '@n8n/constants';
2
2
  import type { Constructable } from '@n8n/di';
3
3
  import type { Scope } from '@n8n/permissions';
4
4
  import type { RequestHandler, Router } from 'express';
5
+ import type { KeyedRateLimiterConfig, RateLimiterLimits } from './rate-limit';
5
6
  export type Method = 'get' | 'post' | 'put' | 'patch' | 'delete' | 'head' | 'options';
6
7
  export type Arg = {
7
8
  type: 'body' | 'query';
@@ -16,10 +17,6 @@ export interface CorsOptions {
16
17
  allowCredentials?: boolean;
17
18
  maxAge?: number;
18
19
  }
19
- export interface RateLimit {
20
- limit?: number;
21
- windowMs?: number;
22
- }
23
20
  export type HandlerName = string;
24
21
  export interface AccessScope {
25
22
  scope: Scope;
@@ -35,7 +32,8 @@ export interface RouteMetadata {
35
32
  allowSkipMFA: boolean;
36
33
  apiKeyAuth: boolean;
37
34
  cors?: Partial<CorsOptions> | true;
38
- rateLimit?: boolean | RateLimit;
35
+ ipRateLimit?: boolean | RateLimiterLimits;
36
+ keyedRateLimit?: KeyedRateLimiterConfig;
39
37
  licenseFeature?: BooleanLicenseFeature;
40
38
  accessScope?: AccessScope;
41
39
  args: Arg[];
@@ -44,7 +42,7 @@ export interface RouteMetadata {
44
42
  export type StaticRouterMetadata = {
45
43
  path: string;
46
44
  router: Router;
47
- } & Partial<Pick<RouteMetadata, 'skipAuth' | 'allowSkipPreviewAuth' | 'allowSkipMFA' | 'middlewares' | 'rateLimit' | 'licenseFeature' | 'accessScope'>>;
45
+ } & Partial<Pick<RouteMetadata, 'skipAuth' | 'allowSkipPreviewAuth' | 'allowSkipMFA' | 'middlewares' | 'ipRateLimit' | 'keyedRateLimit' | 'licenseFeature' | 'accessScope'>>;
48
46
  export interface ControllerMetadata {
49
47
  basePath: `/${string}`;
50
48
  registerOnRootPath?: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@n8n/decorators",
3
- "version": "1.5.1",
3
+ "version": "1.6.1",
4
4
  "main": "dist/index.js",
5
5
  "module": "src/index.ts",
6
6
  "types": "dist/index.d.ts",
@@ -12,14 +12,17 @@
12
12
  "devDependencies": {
13
13
  "@types/express": "^5.0.1",
14
14
  "@types/lodash": "4.17.17",
15
- "@n8n/typescript-config": "1.3.0"
15
+ "vitest": "^3.1.3",
16
+ "zod": "3.25.67",
17
+ "@n8n/typescript-config": "1.3.0",
18
+ "@n8n/vitest-config": "1.6.0"
16
19
  },
17
20
  "dependencies": {
18
- "lodash": "4.17.21",
21
+ "lodash": "4.17.23",
22
+ "@n8n/di": "0.10.0",
19
23
  "@n8n/constants": "0.16.0",
20
- "@n8n/permissions": "0.47.0",
21
- "n8n-workflow": "2.5.1",
22
- "@n8n/di": "0.10.0"
24
+ "@n8n/permissions": "0.47.1",
25
+ "n8n-workflow": "2.6.1"
23
26
  },
24
27
  "license": "SEE LICENSE IN LICENSE.md",
25
28
  "homepage": "https://n8n.io",
@@ -41,8 +44,8 @@
41
44
  "lint": "eslint . --quiet",
42
45
  "lint:fix": "eslint . --fix",
43
46
  "watch": "tsc -p tsconfig.build.json --watch",
44
- "test": "jest",
45
- "test:unit": "jest",
46
- "test:dev": "jest --watch"
47
+ "test": "vitest run",
48
+ "test:unit": "vitest run",
49
+ "test:dev": "vitest"
47
50
  }
48
51
  }