@zintrust/core 0.4.32 → 0.4.34

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zintrust/core",
3
- "version": "0.4.32",
3
+ "version": "0.4.34",
4
4
  "description": "Production-grade TypeScript backend framework for JavaScript",
5
5
  "homepage": "https://zintrust.com",
6
6
  "repository": {
@@ -1,6 +1,6 @@
1
1
  import type { MiddlewareConfigType } from './type';
2
- import type { Middleware } from '../middleware/MiddlewareStack';
3
2
  import type { MiddlewareFailureResponder } from '../middleware/MiddlewareFailureResponder';
3
+ import type { Middleware } from '../middleware/MiddlewareStack';
4
4
  type SharedMiddlewares = {
5
5
  log: Middleware;
6
6
  error: Middleware;
@@ -68,7 +68,10 @@ export declare const MiddlewareKeys: Readonly<{
68
68
  validateUserUpdate: true;
69
69
  validateUserFill: true;
70
70
  }>;
71
- export type MiddlewareKey = keyof typeof MiddlewareKeys;
71
+ export type ParameterizedRateLimitMiddlewareKey = `rateLimit:${number}:${number}`;
72
+ type StaticMiddlewareKey = keyof typeof MiddlewareKeys;
73
+ export type MiddlewareKey = StaticMiddlewareKey | ParameterizedRateLimitMiddlewareKey;
74
+ export declare const isKnownMiddlewareName: (value: string) => value is MiddlewareKey;
72
75
  export declare function createMiddlewareConfig(): MiddlewareConfigType;
73
76
  /**
74
77
  * Clear the middleware configuration cache
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../../src/config/middleware.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAUzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAK9D,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,wCAAwC,CAAC;AAgCzF,KAAK,iBAAiB,GAAG;IACvB,GAAG,EAAE,UAAU,CAAC;IAChB,KAAK,EAAE,UAAU,CAAC;IAClB,QAAQ,EAAE,UAAU,CAAC;IACrB,SAAS,EAAE,UAAU,CAAC;IACtB,YAAY,EAAE,UAAU,CAAC;IACzB,aAAa,EAAE,UAAU,CAAC;IAC1B,aAAa,EAAE,UAAU,CAAC;IAC1B,qBAAqB,EAAE,UAAU,CAAC;IAClC,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,UAAU,CAAC;IACjB,GAAG,EAAE,UAAU,CAAC;IAChB,WAAW,EAAE,UAAU,CAAC;IACxB,aAAa,EAAE,UAAU,CAAC;IAC1B,gBAAgB,EAAE,UAAU,CAAC;IAC7B,iBAAiB,EAAE,UAAU,CAAC;IAC9B,kBAAkB,EAAE,UAAU,CAAC;IAC/B,gBAAgB,EAAE,UAAU,CAAC;CAC9B,CAAC;AAEF,KAAK,sBAAsB,GAAG,MAAM,iBAAiB,CAAC;AACtD,KAAK,yBAAyB,GAAG,OAAO,CACtC,MAAM,CAAC,sBAAsB,EAAE,0BAA0B,CAAC,CAC3D,CAAC;AAEF,eAAO,MAAM,cAAc;;;;;CAKjB,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACjC,aAAa,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAClE,aAAa,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAClE,qBAAqB,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1E,UAAU,CAAC,EAAE,yBAAyB,CAAC;IACvC,MAAM,CAAC,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CACpC,CAAC;AAEF,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;EAkBuB,CAAC;AAEnD,MAAM,MAAM,aAAa,GAAG,MAAM,OAAO,cAAc,CAAC;AA2RxD,wBAAgB,sBAAsB,IAAI,oBAAoB,CA0C7D;AAID;;;GAGG;AACH,eAAO,MAAM,0BAA0B,QAAO,IAE7C,CAAC;AAwBF,eAAO,MAAM,gBAAgB,EAAE,oBAY7B,CAAC;AAEH,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../../src/config/middleware.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAUzD,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,wCAAwC,CAAC;AACzF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAoC9D,KAAK,iBAAiB,GAAG;IACvB,GAAG,EAAE,UAAU,CAAC;IAChB,KAAK,EAAE,UAAU,CAAC;IAClB,QAAQ,EAAE,UAAU,CAAC;IACrB,SAAS,EAAE,UAAU,CAAC;IACtB,YAAY,EAAE,UAAU,CAAC;IACzB,aAAa,EAAE,UAAU,CAAC;IAC1B,aAAa,EAAE,UAAU,CAAC;IAC1B,qBAAqB,EAAE,UAAU,CAAC;IAClC,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,UAAU,CAAC;IACjB,GAAG,EAAE,UAAU,CAAC;IAChB,WAAW,EAAE,UAAU,CAAC;IACxB,aAAa,EAAE,UAAU,CAAC;IAC1B,gBAAgB,EAAE,UAAU,CAAC;IAC7B,iBAAiB,EAAE,UAAU,CAAC;IAC9B,kBAAkB,EAAE,UAAU,CAAC;IAC/B,gBAAgB,EAAE,UAAU,CAAC;CAC9B,CAAC;AAEF,KAAK,sBAAsB,GAAG,MAAM,iBAAiB,CAAC;AACtD,KAAK,yBAAyB,GAAG,OAAO,CACtC,MAAM,CAAC,sBAAsB,EAAE,0BAA0B,CAAC,CAC3D,CAAC;AAEF,eAAO,MAAM,cAAc;;;;;CAKjB,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACjC,aAAa,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAClE,aAAa,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAClE,qBAAqB,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1E,UAAU,CAAC,EAAE,yBAAyB,CAAC;IACvC,MAAM,CAAC,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CACpC,CAAC;AAEF,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;EAkBuB,CAAC;AAEnD,MAAM,MAAM,mCAAmC,GAAG,aAAa,MAAM,IAAI,MAAM,EAAE,CAAC;AAElF,KAAK,mBAAmB,GAAG,MAAM,OAAO,cAAc,CAAC;AAEvD,MAAM,MAAM,aAAa,GAAG,mBAAmB,GAAG,mCAAmC,CAAC;AAyBtF,eAAO,MAAM,qBAAqB,GAAI,OAAO,MAAM,KAAG,KAAK,IAAI,aAI9D,CAAC;AAuUF,wBAAgB,sBAAsB,IAAI,oBAAoB,CA4C7D;AAID;;;GAGG;AACH,eAAO,MAAM,0BAA0B,QAAO,IAE7C,CAAC;AAwBF,eAAO,MAAM,gBAAgB,EAAE,oBAY7B,CAAC;AAEH,eAAe,gBAAgB,CAAC"}
@@ -40,6 +40,24 @@ export const MiddlewareKeys = Object.freeze({
40
40
  validateUserUpdate: true,
41
41
  validateUserFill: true,
42
42
  });
43
+ const parseParameterizedRateLimitKey = (value) => {
44
+ const match = /^rateLimit:(\d+):(\d+(?:\.\d+)?)$/.exec(value.trim());
45
+ if (!match)
46
+ return undefined;
47
+ const max = Number.parseInt(match[1] ?? '', 10);
48
+ const windowMinutes = Number.parseFloat(match[2] ?? '');
49
+ if (!Number.isInteger(max) || max < 1)
50
+ return undefined;
51
+ if (!Number.isFinite(windowMinutes) || windowMinutes <= 0)
52
+ return undefined;
53
+ const windowMs = Math.round(windowMinutes * 60_000);
54
+ if (!Number.isFinite(windowMs) || windowMs < 1)
55
+ return undefined;
56
+ return Object.freeze({ max, windowMs });
57
+ };
58
+ export const isKnownMiddlewareName = (value) => {
59
+ return (Object.hasOwn(MiddlewareKeys, value) || parseParameterizedRateLimitKey(value) !== undefined);
60
+ };
43
61
  // Ensure `ValidationMiddleware` is strongly typed here to avoid `error`-typed values
44
62
  // triggering `@typescript-eslint/no-unsafe-*` rules.
45
63
  const Validation = ValidationMiddleware;
@@ -207,6 +225,42 @@ const applySharedMiddlewareOverrides = (shared, projectRoute) => {
207
225
  }
208
226
  return Object.freeze(overridden);
209
227
  };
228
+ const createRouteMiddlewareRegistry = (resolvedShared, projectRoute, responders) => {
229
+ const target = Object.freeze({
230
+ ...resolvedShared,
231
+ ...projectRoute,
232
+ });
233
+ const dynamicRateLimits = new Map();
234
+ return new Proxy(target, {
235
+ get(currentTarget, prop, receiver) {
236
+ if (typeof prop !== 'string') {
237
+ return Reflect.get(currentTarget, prop, receiver);
238
+ }
239
+ const resolved = currentTarget[prop];
240
+ if (typeof resolved === 'function')
241
+ return resolved;
242
+ const cached = dynamicRateLimits.get(prop);
243
+ if (cached !== undefined)
244
+ return cached;
245
+ const parsed = parseParameterizedRateLimitKey(prop);
246
+ if (parsed === undefined)
247
+ return undefined;
248
+ const middleware = RateLimiter.create({
249
+ max: parsed.max,
250
+ windowMs: parsed.windowMs,
251
+ onFailure: responders.rateLimit,
252
+ });
253
+ dynamicRateLimits.set(prop, middleware);
254
+ return middleware;
255
+ },
256
+ ownKeys(currentTarget) {
257
+ return Reflect.ownKeys(currentTarget);
258
+ },
259
+ getOwnPropertyDescriptor(currentTarget, prop) {
260
+ return Reflect.getOwnPropertyDescriptor(currentTarget, prop);
261
+ },
262
+ });
263
+ };
210
264
  export function createMiddlewareConfig() {
211
265
  const loadMiddlewareConfig = StartupConfigFileRegistry.get(StartupConfigFile.Middleware) ?? {};
212
266
  const skipPathsFromEnv = Env.get('CSRF_SKIP_PATHS', '')
@@ -224,6 +278,7 @@ export function createMiddlewareConfig() {
224
278
  const projectGlobal = resolveProjectGlobalMiddlewares(effectiveMiddlewareConfig);
225
279
  const projectRoute = resolveProjectRouteMiddlewares(effectiveMiddlewareConfig);
226
280
  const resolvedShared = applySharedMiddlewareOverrides(shared, projectRoute);
281
+ const routeMiddlewareRegistry = createRouteMiddlewareRegistry(resolvedShared, projectRoute, responders);
227
282
  const middlewareConfigObj = {
228
283
  global: [
229
284
  resolvedShared.log,
@@ -236,10 +291,7 @@ export function createMiddlewareConfig() {
236
291
  resolvedShared.sanitizeBody,
237
292
  ...projectGlobal,
238
293
  ],
239
- route: {
240
- ...resolvedShared,
241
- ...projectRoute,
242
- },
294
+ route: routeMiddlewareRegistry,
243
295
  };
244
296
  return Object.freeze(middlewareConfigObj);
245
297
  }
@@ -1 +1 @@
1
- {"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../../src/config/queue.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,KAAK,EAAE,sBAAsB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAGhG,MAAM,MAAM,oBAAoB,GAAG,OAAO,CAAC;IACzC,OAAO,EAAE,eAAe,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACrC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,UAAU,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACnF,OAAO,EAAE;QACP,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;QAClC,WAAW,EAAE,OAAO,CAAC;QACrB,iBAAiB,EAAE,MAAM,CAAC;KAC3B,CAAC;CACH,CAAC,CAAC;AA+EH;;GAEG;AACH,eAAO,MAAM,iBAAiB,QAAO,kBA4DnC,CAAC;AA8CH,QAAA,MAAM,iBAAiB,QAAO;IAC5B,OAAO,EAAE,eAAe,CAAC;IACzB,OAAO,EAAE,kBAAkB,CAAC;IAC5B,SAAS,EAAE,CAAC,YAAY,EAAE,sBAAsB,KAAK,kBAAkB,CAAC,eAAe,CAAC,CAAC;IACzF,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,UAAU,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACnF,OAAO,EAAE;QACP,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;QAClC,WAAW,EAAE,OAAO,CAAC;QACrB,iBAAiB,EAAE,MAAM,CAAC;KAC3B,CAAC;CAuEH,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAqB/D,eAAO,MAAM,WAAW,EAAE,WAYxB,CAAC"}
1
+ {"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../../src/config/queue.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,KAAK,EAAE,sBAAsB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAGhG,MAAM,MAAM,oBAAoB,GAAG,OAAO,CAAC;IACzC,OAAO,EAAE,eAAe,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACrC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,UAAU,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACnF,OAAO,EAAE;QACP,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;QAClC,WAAW,EAAE,OAAO,CAAC;QACrB,iBAAiB,EAAE,MAAM,CAAC;KAC3B,CAAC;CACH,CAAC,CAAC;AA+EH;;GAEG;AACH,eAAO,MAAM,iBAAiB,QAAO,kBA4DnC,CAAC;AAgDH,QAAA,MAAM,iBAAiB,QAAO;IAC5B,OAAO,EAAE,eAAe,CAAC;IACzB,OAAO,EAAE,kBAAkB,CAAC;IAC5B,SAAS,EAAE,CAAC,YAAY,EAAE,sBAAsB,KAAK,kBAAkB,CAAC,eAAe,CAAC,CAAC;IACzF,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,UAAU,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACnF,OAAO,EAAE;QACP,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;QAClC,WAAW,EAAE,OAAO,CAAC;QACrB,iBAAiB,EAAE,MAAM,CAAC;KAC3B,CAAC;CAuEH,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAqB/D,eAAO,MAAM,WAAW,EAAE,WAYxB,CAAC"}
@@ -6,7 +6,7 @@
6
6
  import { Cloudflare } from './cloudflare.js';
7
7
  import { Env } from './env.js';
8
8
  import { Logger } from './logger.js';
9
- import { middlewareConfig } from './middleware.js';
9
+ import { isKnownMiddlewareName, middlewareConfig } from './middleware.js';
10
10
  import { ErrorFactory } from '../exceptions/ZintrustError.js';
11
11
  import { ZintrustLang } from '../lang/lang.js';
12
12
  import { StartupConfigFile, StartupConfigFileRegistry } from '../runtime/StartupConfigFileRegistry.js';
@@ -125,13 +125,15 @@ const createBaseMonitor = () => {
125
125
  .filter((m) => m.length > 0);
126
126
  if (enabled && middleware.length > 0) {
127
127
  const knownKeys = new Set(Object.keys(middlewareConfig.route ?? {}));
128
- const unknownKeys = middleware.filter((name) => !knownKeys.has(name));
128
+ const unknownKeys = middleware.filter((name) => {
129
+ return !knownKeys.has(name) && !isKnownMiddlewareName(name);
130
+ });
129
131
  if (unknownKeys.length > 0) {
130
132
  Logger.error('Unknown QUEUE_MONITOR_MIDDLEWARE keys configured', {
131
133
  unknownKeys,
132
134
  basePath,
133
135
  });
134
- throw ErrorFactory.createConfigError(`Unknown QUEUE_MONITOR_MIDDLEWARE key(s): ${unknownKeys.join(', ')}. These must match registered route middleware keys in your app.`);
136
+ throw ErrorFactory.createConfigError(`Unknown QUEUE_MONITOR_MIDDLEWARE key(s): ${unknownKeys.join(', ')}. These must match registered route middleware keys in your app or a supported dynamic middleware key such as rateLimit:<max>:<windowInMinutes>.`);
135
137
  }
136
138
  }
137
139
  return {
package/src/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  /**
2
- * @zintrust/core v0.4.32
2
+ * @zintrust/core v0.4.34
3
3
  *
4
4
  * ZinTrust Framework - Production-Grade TypeScript Backend
5
5
  * Built for performance, type safety, and exceptional developer experience
6
6
  *
7
7
  * Build Information:
8
- * Built: 2026-03-29T15:48:46.014Z
8
+ * Built: 2026-03-29T19:18:37.838Z
9
9
  * Node: >=20.0.0
10
10
  * License: MIT
11
11
  *
@@ -21,7 +21,7 @@
21
21
  * Available at runtime for debugging and health checks
22
22
  */
23
23
  export const ZINTRUST_VERSION = '0.1.41';
24
- export const ZINTRUST_BUILD_DATE = '2026-03-29T15:48:45.972Z'; // Replaced during build
24
+ export const ZINTRUST_BUILD_DATE = '2026-03-29T19:18:37.802Z'; // Replaced during build
25
25
  export { Application } from './boot/Application.js';
26
26
  export { AwsSigV4 } from './common/index.js';
27
27
  export { SignedRequest } from './security/SignedRequest.js';
@@ -1,3 +1,3 @@
1
1
  import '@zintrust/core/boot';
2
2
 
3
- export {};
3
+ export {};