@rabstack/rab-api 1.8.1-next.0 → 1.8.1-next.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.
package/index.cjs.js CHANGED
@@ -518,7 +518,92 @@ var utils = /*#__PURE__*/Object.freeze({
518
518
  validateJoiSchema: validateJoiSchema
519
519
  });
520
520
 
521
+ const DEFAULT_TTL = 900; // 15 minutes
522
+ const DEFAULT_STRATEGY = 'url-params';
523
+ /**
524
+ * Normalize cache config - handles `cache: true` shorthand
525
+ */ function normalizeCacheConfig(cache, defaultTtl) {
526
+ if (!cache) return null;
527
+ if (cache === true) {
528
+ return {
529
+ ttl: defaultTtl != null ? defaultTtl : DEFAULT_TTL,
530
+ strategy: DEFAULT_STRATEGY
531
+ };
532
+ }
533
+ var _cache_ttl, _ref, _cache_strategy;
534
+ return {
535
+ ttl: (_ref = (_cache_ttl = cache.ttl) != null ? _cache_ttl : defaultTtl) != null ? _ref : DEFAULT_TTL,
536
+ strategy: (_cache_strategy = cache.strategy) != null ? _cache_strategy : DEFAULT_STRATEGY,
537
+ invalidates: cache.invalidates
538
+ };
539
+ }
540
+ /**
541
+ * Build cache key from request based on strategy
542
+ * - url-params: resolved path only (e.g., /stores/123/categories)
543
+ * - url-query: resolved path + sorted query (e.g., /stores/123/categories?lang=en&page=1)
544
+ */ function buildCacheKey(req, strategy) {
545
+ var _req_originalUrl;
546
+ // Get the resolved path (with params filled in)
547
+ const path = ((_req_originalUrl = req.originalUrl) == null ? void 0 : _req_originalUrl.split('?')[0]) || req.path;
548
+ // url-params: just the path
549
+ if (strategy === 'url-params') {
550
+ return path;
551
+ }
552
+ // url-query: path + sorted query string
553
+ const query = req.query;
554
+ if (query && Object.keys(query).length > 0) {
555
+ const sortedQuery = Object.keys(query).sort().map((key)=>`${key}=${query[key]}`).join('&');
556
+ return `${path}?${sortedQuery}`;
557
+ }
558
+ return path;
559
+ }
560
+ /**
561
+ * Resolve :param placeholders in a pattern using request params
562
+ */ function resolvePattern(pattern, params) {
563
+ return pattern.replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g, (_, paramName)=>{
564
+ const value = params[paramName];
565
+ if (value === undefined) {
566
+ // Keep original if param not found (might be a wildcard pattern)
567
+ return `:${paramName}`;
568
+ }
569
+ return value;
570
+ });
571
+ }
572
+ /**
573
+ * Resolve all invalidation patterns for a request
574
+ */ function resolveInvalidationPatterns(patterns, req) {
575
+ const resolved = [];
576
+ for (const pattern of patterns){
577
+ if (typeof pattern === 'function') {
578
+ const result = pattern(req);
579
+ if (Array.isArray(result)) {
580
+ resolved.push(...result);
581
+ } else {
582
+ resolved.push(result);
583
+ }
584
+ } else {
585
+ resolved.push(resolvePattern(pattern, req.params || {}));
586
+ }
587
+ }
588
+ return resolved;
589
+ }
590
+ /**
591
+ * Check if cache should be applied (has ttl, not just invalidation)
592
+ */ function shouldCache(config) {
593
+ return config.ttl !== undefined && config.ttl > 0;
594
+ }
595
+ /**
596
+ * Check if there are invalidation patterns
597
+ */ function hasInvalidations(config) {
598
+ return Array.isArray(config.invalidates) && config.invalidates.length > 0;
599
+ }
600
+
521
601
  const controllerHandler = (controller, config)=>{
602
+ // Normalize cache config once at setup time
603
+ const cacheConfig = normalizeCacheConfig(config.cache, config.cacheDefaultTtl);
604
+ const cacheAdapter = config.cacheAdapter;
605
+ const isCacheEnabled = cacheConfig && cacheAdapter && shouldCache(cacheConfig);
606
+ const hasInvalidationPatterns = cacheConfig && hasInvalidations(cacheConfig);
522
607
  return async (req, res, next)=>{
523
608
  try {
524
609
  let query = req.query;
@@ -529,19 +614,45 @@ const controllerHandler = (controller, config)=>{
529
614
  query = await config.validateQuery(req.query);
530
615
  }
531
616
  }
617
+ // Check cache before executing handler
618
+ if (isCacheEnabled) {
619
+ const cacheKey = buildCacheKey(req, cacheConfig.strategy);
620
+ const cached = await cacheAdapter.get(cacheKey);
621
+ if (cached) {
622
+ return res.status(200).json(cached);
623
+ }
624
+ }
532
625
  const response = await controller.handler(_extends({}, req, {
533
626
  query,
534
627
  body: req.body
535
628
  }));
536
- var _response_statusCode, _response_statusCode1;
537
- return res.status((_response_statusCode = response.statusCode) != null ? _response_statusCode : 200).json(response.excludeMetaData ? response.data : _extends({
629
+ var _response_statusCode;
630
+ const jsonResponse = response.excludeMetaData ? response.data : _extends({
538
631
  message: 'successful',
539
- statusCode: (_response_statusCode1 = response.statusCode) != null ? _response_statusCode1 : 200
632
+ statusCode: (_response_statusCode = response.statusCode) != null ? _response_statusCode : 200
540
633
  }, response.data ? {
541
634
  data: response.data
542
635
  } : {
543
636
  data: response
544
- }));
637
+ });
638
+ // Cache the response after successful execution
639
+ if (isCacheEnabled) {
640
+ const cacheKey = buildCacheKey(req, cacheConfig.strategy);
641
+ // Don't await - cache in background
642
+ cacheAdapter.set(cacheKey, jsonResponse, cacheConfig.ttl).catch(()=>{
643
+ // Silently ignore cache errors
644
+ });
645
+ }
646
+ // Handle invalidations after successful mutation
647
+ if (hasInvalidationPatterns && cacheAdapter) {
648
+ const patterns = resolveInvalidationPatterns(cacheConfig.invalidates, req);
649
+ // Invalidate in background
650
+ Promise.all(patterns.map((pattern)=>pattern.includes('*') ? cacheAdapter.delPattern(pattern) : cacheAdapter.del(pattern))).catch(()=>{
651
+ // Silently ignore invalidation errors
652
+ });
653
+ }
654
+ var _response_statusCode1;
655
+ return res.status((_response_statusCode1 = response.statusCode) != null ? _response_statusCode1 : 200).json(jsonResponse);
545
656
  } catch (error) {
546
657
  if (error instanceof RabApiError) {
547
658
  return next(new RabApiError(error.message, error.statusCode, error.errorCode, error.errors));
@@ -984,11 +1095,13 @@ class AtomExpressApp {
984
1095
  var _options_auth;
985
1096
  this.collectedRoutes = [];
986
1097
  this.setupRouteController = (expressRouter, route, parentOptions)=>{
987
- var _config_docs;
1098
+ var _this_options_cache, _this_options_cache1, _config_docs;
988
1099
  const metaData = retrieveRouteMetaData(route);
989
1100
  const { method, path, options } = metaData;
990
1101
  const config = _extends({}, parentOptions, options, {
991
- enforceBodyValidation: this.options.enforceBodyValidation
1102
+ enforceBodyValidation: this.options.enforceBodyValidation,
1103
+ cacheAdapter: (_this_options_cache = this.options.cache) == null ? void 0 : _this_options_cache.adapter,
1104
+ cacheDefaultTtl: (_this_options_cache1 = this.options.cache) == null ? void 0 : _this_options_cache1.defaultTtl
992
1105
  });
993
1106
  if (method == 'get' && config.querySchema && !config.validateQuery) {
994
1107
  const querySchema = config.querySchema;
@@ -1101,8 +1214,14 @@ exports.UnauthorizedException = UnauthorizedException;
1101
1214
  exports.UnprocessableEntityException = UnprocessableEntityException;
1102
1215
  exports.authHandler = authHandler;
1103
1216
  exports.bodyValidatorWithContext = bodyValidatorWithContext;
1217
+ exports.buildCacheKey = buildCacheKey;
1104
1218
  exports.controllerHandler = controllerHandler;
1105
1219
  exports.errorHandler = errorHandler;
1106
1220
  exports.extractTokenFromHeader = extractTokenFromHeader;
1221
+ exports.hasInvalidations = hasInvalidations;
1107
1222
  exports.isCallBackPipe = isCallBackPipe;
1108
1223
  exports.isRouteAController = isRouteAController;
1224
+ exports.normalizeCacheConfig = normalizeCacheConfig;
1225
+ exports.resolveInvalidationPatterns = resolveInvalidationPatterns;
1226
+ exports.resolvePattern = resolvePattern;
1227
+ exports.shouldCache = shouldCache;
package/index.esm.d.ts CHANGED
@@ -97,6 +97,8 @@ export declare type AtomExpressOptions = {
97
97
  }>;
98
98
  }>;
99
99
  };
100
+ /** Global cache configuration */
101
+ cache?: RabApiCacheOptions;
100
102
  };
101
103
 
102
104
  export declare namespace AtomHelpers {
@@ -152,10 +154,36 @@ export declare class BadRequestException extends RabApiError {
152
154
 
153
155
  export declare const bodyValidatorWithContext: (config: RouteHandleOptions) => (req: any, res: Response_2, next: NextFunction) => Promise<void>;
154
156
 
157
+ /**
158
+ * Build cache key from request based on strategy
159
+ * - url-params: resolved path only (e.g., /stores/123/categories)
160
+ * - url-query: resolved path + sorted query (e.g., /stores/123/categories?lang=en&page=1)
161
+ */
162
+ export declare function buildCacheKey(req: any, strategy: CacheStrategy): string;
163
+
155
164
  export declare type BuildRouterProps = CreateRouterProps & {
156
165
  fullPath?: string;
157
166
  };
158
167
 
168
+ /**
169
+ * Cache configuration for route decorators
170
+ */
171
+ export declare interface CacheConfig {
172
+ /** Time-to-live in seconds (default: 900 = 15 minutes) */
173
+ ttl?: number;
174
+ /** Key derivation strategy (default: 'url-params') */
175
+ strategy?: CacheStrategy;
176
+ /** URL patterns to invalidate after successful response */
177
+ invalidates?: InvalidationPattern[];
178
+ }
179
+
180
+ /**
181
+ * Cache key strategy
182
+ * - 'url-params': Uses resolved URL path (e.g., /stores/123/categories)
183
+ * - 'url-query': Uses resolved URL path + sorted query string
184
+ */
185
+ export declare type CacheStrategy = 'url-params' | 'url-query';
186
+
159
187
  export declare interface CollectedRoute {
160
188
  method: string;
161
189
  path: string;
@@ -425,11 +453,26 @@ export declare function Get(path: string, options?: ControllerRouteDefinitionOpt
425
453
  */
426
454
  export declare type GetController<TResponse, TQuery = any, TParams = any, TUser = any> = IControllerClass<TQuery, any, TResponse, TParams, TUser>;
427
455
 
456
+ /**
457
+ * Check if there are invalidation patterns
458
+ */
459
+ export declare function hasInvalidations(config: CacheConfig): boolean;
460
+
428
461
  /**
429
462
  * Supported HTTP methods for route decorators.
430
463
  */
431
464
  export declare type HttpMethod = 'get' | 'post' | 'put' | 'patch' | 'delete';
432
465
 
466
+ /**
467
+ * Cache adapter interface - implement this to provide your own cache backend (Redis, Memory, etc.)
468
+ */
469
+ export declare interface ICacheAdapter {
470
+ get<T>(key: string): Promise<T | null>;
471
+ set<T>(key: string, data: T, ttlSeconds: number): Promise<void>;
472
+ del(key: string): Promise<void>;
473
+ delPattern(pattern: string): Promise<void>;
474
+ }
475
+
433
476
  /**
434
477
  * Controller class type definition.
435
478
  * Used to define the type shape for controller implementations.
@@ -495,6 +538,8 @@ export declare type InjectorsMetadata<TQuery = any, TBody = any, TResponse = any
495
538
  querySchema?: Joi.ObjectSchema<TParams>;
496
539
  excludeFromDocs?: boolean;
497
540
  docs?: OpenApiDocsMetadata;
541
+ /** Cache configuration - use `true` for defaults or provide config object */
542
+ cache?: true | CacheConfig;
498
543
  };
499
544
 
500
545
  /**
@@ -514,6 +559,12 @@ export declare class InternalServerErrorException extends RabApiError {
514
559
  constructor(message?: string, errorCode?: string);
515
560
  }
516
561
 
562
+ /**
563
+ * Invalidation pattern - either a URL pattern string or a function that returns pattern(s)
564
+ * URL patterns with :param placeholders are auto-resolved from request params
565
+ */
566
+ export declare type InvalidationPattern = string | ((req: any) => string | string[]);
567
+
517
568
  export declare const isCallBackPipe: (pipe: PipeFn | PipeFnCallBack) => pipe is PipeFnCallBack;
518
569
 
519
570
  export declare function isRouteAController(value: AppRoute): value is ControllerClassType;
@@ -553,6 +604,11 @@ export declare class MethodNotAllowedException extends RabApiError {
553
604
  constructor(message?: string, errorCode?: string);
554
605
  }
555
606
 
607
+ /**
608
+ * Normalize cache config - handles `cache: true` shorthand
609
+ */
610
+ export declare function normalizeCacheConfig(cache: true | CacheConfig | undefined, defaultTtl?: number): CacheConfig | null;
611
+
556
612
  /**
557
613
  * Represents a 404 Not Found error.
558
614
  * Use this when a requested resource does not exist.
@@ -775,6 +831,16 @@ export declare class RabApi {
775
831
  static createApp(props: AtomExpressOptions): AtomExpressApp;
776
832
  }
777
833
 
834
+ /**
835
+ * Global cache configuration for RabApi
836
+ */
837
+ export declare interface RabApiCacheOptions {
838
+ /** Cache adapter implementation (Redis, Memory, etc.) */
839
+ adapter: ICacheAdapter;
840
+ /** Default TTL in seconds (default: 900 = 15 minutes) */
841
+ defaultTtl?: number;
842
+ }
843
+
778
844
  /**
779
845
  * Base controller interface that all HTTP method controllers implement.
780
846
  * Defines the contract for request handlers.
@@ -877,9 +943,24 @@ export declare class RequestTimeoutException extends RabApiError {
877
943
  constructor(message?: string, errorCode?: string);
878
944
  }
879
945
 
946
+ /**
947
+ * Resolve all invalidation patterns for a request
948
+ */
949
+ export declare function resolveInvalidationPatterns(patterns: InvalidationPattern[], req: any): string[];
950
+
951
+ /**
952
+ * Resolve :param placeholders in a pattern using request params
953
+ */
954
+ export declare function resolvePattern(pattern: string, params: Record<string, string>): string;
955
+
880
956
  declare function retrieveRouteMetaData(route: ControllerClassType): ControllerRouteDefinition;
881
957
 
882
- export declare type RouteHandleOptions = InjectorsMetadata & Pick<AtomExpressOptions, 'enforceBodyValidation'>;
958
+ export declare type RouteHandleOptions = InjectorsMetadata & Pick<AtomExpressOptions, 'enforceBodyValidation'> & {
959
+ /** Resolved cache adapter from global options */
960
+ cacheAdapter?: ICacheAdapter;
961
+ /** Default TTL from global options */
962
+ cacheDefaultTtl?: number;
963
+ };
883
964
 
884
965
  /**
885
966
  * Represents a 503 Service Unavailable error.
@@ -898,6 +979,11 @@ export declare class ServiceUnavailableException extends RabApiError {
898
979
  constructor(message?: string, errorCode?: string);
899
980
  }
900
981
 
982
+ /**
983
+ * Check if cache should be applied (has ttl, not just invalidation)
984
+ */
985
+ export declare function shouldCache(config: CacheConfig): boolean;
986
+
901
987
  /**
902
988
  * Represents a 429 Too Many Requests error.
903
989
  * Use this when rate limiting is exceeded.
package/index.esm.js CHANGED
@@ -516,7 +516,92 @@ var utils = /*#__PURE__*/Object.freeze({
516
516
  validateJoiSchema: validateJoiSchema
517
517
  });
518
518
 
519
+ const DEFAULT_TTL = 900; // 15 minutes
520
+ const DEFAULT_STRATEGY = 'url-params';
521
+ /**
522
+ * Normalize cache config - handles `cache: true` shorthand
523
+ */ function normalizeCacheConfig(cache, defaultTtl) {
524
+ if (!cache) return null;
525
+ if (cache === true) {
526
+ return {
527
+ ttl: defaultTtl != null ? defaultTtl : DEFAULT_TTL,
528
+ strategy: DEFAULT_STRATEGY
529
+ };
530
+ }
531
+ var _cache_ttl, _ref, _cache_strategy;
532
+ return {
533
+ ttl: (_ref = (_cache_ttl = cache.ttl) != null ? _cache_ttl : defaultTtl) != null ? _ref : DEFAULT_TTL,
534
+ strategy: (_cache_strategy = cache.strategy) != null ? _cache_strategy : DEFAULT_STRATEGY,
535
+ invalidates: cache.invalidates
536
+ };
537
+ }
538
+ /**
539
+ * Build cache key from request based on strategy
540
+ * - url-params: resolved path only (e.g., /stores/123/categories)
541
+ * - url-query: resolved path + sorted query (e.g., /stores/123/categories?lang=en&page=1)
542
+ */ function buildCacheKey(req, strategy) {
543
+ var _req_originalUrl;
544
+ // Get the resolved path (with params filled in)
545
+ const path = ((_req_originalUrl = req.originalUrl) == null ? void 0 : _req_originalUrl.split('?')[0]) || req.path;
546
+ // url-params: just the path
547
+ if (strategy === 'url-params') {
548
+ return path;
549
+ }
550
+ // url-query: path + sorted query string
551
+ const query = req.query;
552
+ if (query && Object.keys(query).length > 0) {
553
+ const sortedQuery = Object.keys(query).sort().map((key)=>`${key}=${query[key]}`).join('&');
554
+ return `${path}?${sortedQuery}`;
555
+ }
556
+ return path;
557
+ }
558
+ /**
559
+ * Resolve :param placeholders in a pattern using request params
560
+ */ function resolvePattern(pattern, params) {
561
+ return pattern.replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g, (_, paramName)=>{
562
+ const value = params[paramName];
563
+ if (value === undefined) {
564
+ // Keep original if param not found (might be a wildcard pattern)
565
+ return `:${paramName}`;
566
+ }
567
+ return value;
568
+ });
569
+ }
570
+ /**
571
+ * Resolve all invalidation patterns for a request
572
+ */ function resolveInvalidationPatterns(patterns, req) {
573
+ const resolved = [];
574
+ for (const pattern of patterns){
575
+ if (typeof pattern === 'function') {
576
+ const result = pattern(req);
577
+ if (Array.isArray(result)) {
578
+ resolved.push(...result);
579
+ } else {
580
+ resolved.push(result);
581
+ }
582
+ } else {
583
+ resolved.push(resolvePattern(pattern, req.params || {}));
584
+ }
585
+ }
586
+ return resolved;
587
+ }
588
+ /**
589
+ * Check if cache should be applied (has ttl, not just invalidation)
590
+ */ function shouldCache(config) {
591
+ return config.ttl !== undefined && config.ttl > 0;
592
+ }
593
+ /**
594
+ * Check if there are invalidation patterns
595
+ */ function hasInvalidations(config) {
596
+ return Array.isArray(config.invalidates) && config.invalidates.length > 0;
597
+ }
598
+
519
599
  const controllerHandler = (controller, config)=>{
600
+ // Normalize cache config once at setup time
601
+ const cacheConfig = normalizeCacheConfig(config.cache, config.cacheDefaultTtl);
602
+ const cacheAdapter = config.cacheAdapter;
603
+ const isCacheEnabled = cacheConfig && cacheAdapter && shouldCache(cacheConfig);
604
+ const hasInvalidationPatterns = cacheConfig && hasInvalidations(cacheConfig);
520
605
  return async (req, res, next)=>{
521
606
  try {
522
607
  let query = req.query;
@@ -527,19 +612,45 @@ const controllerHandler = (controller, config)=>{
527
612
  query = await config.validateQuery(req.query);
528
613
  }
529
614
  }
615
+ // Check cache before executing handler
616
+ if (isCacheEnabled) {
617
+ const cacheKey = buildCacheKey(req, cacheConfig.strategy);
618
+ const cached = await cacheAdapter.get(cacheKey);
619
+ if (cached) {
620
+ return res.status(200).json(cached);
621
+ }
622
+ }
530
623
  const response = await controller.handler(_extends({}, req, {
531
624
  query,
532
625
  body: req.body
533
626
  }));
534
- var _response_statusCode, _response_statusCode1;
535
- return res.status((_response_statusCode = response.statusCode) != null ? _response_statusCode : 200).json(response.excludeMetaData ? response.data : _extends({
627
+ var _response_statusCode;
628
+ const jsonResponse = response.excludeMetaData ? response.data : _extends({
536
629
  message: 'successful',
537
- statusCode: (_response_statusCode1 = response.statusCode) != null ? _response_statusCode1 : 200
630
+ statusCode: (_response_statusCode = response.statusCode) != null ? _response_statusCode : 200
538
631
  }, response.data ? {
539
632
  data: response.data
540
633
  } : {
541
634
  data: response
542
- }));
635
+ });
636
+ // Cache the response after successful execution
637
+ if (isCacheEnabled) {
638
+ const cacheKey = buildCacheKey(req, cacheConfig.strategy);
639
+ // Don't await - cache in background
640
+ cacheAdapter.set(cacheKey, jsonResponse, cacheConfig.ttl).catch(()=>{
641
+ // Silently ignore cache errors
642
+ });
643
+ }
644
+ // Handle invalidations after successful mutation
645
+ if (hasInvalidationPatterns && cacheAdapter) {
646
+ const patterns = resolveInvalidationPatterns(cacheConfig.invalidates, req);
647
+ // Invalidate in background
648
+ Promise.all(patterns.map((pattern)=>pattern.includes('*') ? cacheAdapter.delPattern(pattern) : cacheAdapter.del(pattern))).catch(()=>{
649
+ // Silently ignore invalidation errors
650
+ });
651
+ }
652
+ var _response_statusCode1;
653
+ return res.status((_response_statusCode1 = response.statusCode) != null ? _response_statusCode1 : 200).json(jsonResponse);
543
654
  } catch (error) {
544
655
  if (error instanceof RabApiError) {
545
656
  return next(new RabApiError(error.message, error.statusCode, error.errorCode, error.errors));
@@ -982,11 +1093,13 @@ class AtomExpressApp {
982
1093
  var _options_auth;
983
1094
  this.collectedRoutes = [];
984
1095
  this.setupRouteController = (expressRouter, route, parentOptions)=>{
985
- var _config_docs;
1096
+ var _this_options_cache, _this_options_cache1, _config_docs;
986
1097
  const metaData = retrieveRouteMetaData(route);
987
1098
  const { method, path, options } = metaData;
988
1099
  const config = _extends({}, parentOptions, options, {
989
- enforceBodyValidation: this.options.enforceBodyValidation
1100
+ enforceBodyValidation: this.options.enforceBodyValidation,
1101
+ cacheAdapter: (_this_options_cache = this.options.cache) == null ? void 0 : _this_options_cache.adapter,
1102
+ cacheDefaultTtl: (_this_options_cache1 = this.options.cache) == null ? void 0 : _this_options_cache1.defaultTtl
990
1103
  });
991
1104
  if (method == 'get' && config.querySchema && !config.validateQuery) {
992
1105
  const querySchema = config.querySchema;
@@ -1070,4 +1183,4 @@ class AtomExpressApp {
1070
1183
  }
1071
1184
  }
1072
1185
 
1073
- export { AtomExpressApp, utils as AtomHelpers, AtomRoute, BadRequestException, CONTROLLER_ROUTE_KEY, ConflictException, Controller, Delete, DiContainer, ForbiddenException, Get, Injectable, InternalServerErrorException, MethodNotAllowedException, NotFoundException, OpenApiGenerator, Patch, PayloadTooLargeException, Post, Put, RabApi, RabApiError, RequestTimeoutException, ServiceUnavailableException, TooManyRequestsException, UnauthorizedException, UnprocessableEntityException, authHandler, bodyValidatorWithContext, controllerHandler, errorHandler, extractTokenFromHeader, isCallBackPipe, isRouteAController };
1186
+ export { AtomExpressApp, utils as AtomHelpers, AtomRoute, BadRequestException, CONTROLLER_ROUTE_KEY, ConflictException, Controller, Delete, DiContainer, ForbiddenException, Get, Injectable, InternalServerErrorException, MethodNotAllowedException, NotFoundException, OpenApiGenerator, Patch, PayloadTooLargeException, Post, Put, RabApi, RabApiError, RequestTimeoutException, ServiceUnavailableException, TooManyRequestsException, UnauthorizedException, UnprocessableEntityException, authHandler, bodyValidatorWithContext, buildCacheKey, controllerHandler, errorHandler, extractTokenFromHeader, hasInvalidations, isCallBackPipe, isRouteAController, normalizeCacheConfig, resolveInvalidationPatterns, resolvePattern, shouldCache };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rabstack/rab-api",
3
- "version": "1.8.1-next.0",
3
+ "version": "1.8.1-next.1",
4
4
  "description": "A TypeScript REST API framework built on Express.js with decorator-based routing, dependency injection, and built-in validation",
5
5
  "author": "Softin",
6
6
  "license": "MIT",