@hazeljs/core 0.2.0-beta.71 → 0.2.0-beta.73
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/dist/__tests__/decorators.test.d.ts.map +1 -1
- package/dist/__tests__/decorators.test.js +276 -0
- package/dist/decorators.d.ts +68 -1
- package/dist/decorators.d.ts.map +1 -1
- package/dist/decorators.js +196 -1
- package/dist/errors/http.error.d.ts +3 -0
- package/dist/errors/http.error.d.ts.map +1 -1
- package/dist/errors/http.error.js +8 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -2
- package/dist/interceptors/interceptor.d.ts +8 -0
- package/dist/interceptors/interceptor.d.ts.map +1 -1
- package/dist/interceptors/interceptor.js +26 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +3 -0
- package/dist/request-context.d.ts +5 -0
- package/dist/request-context.d.ts.map +1 -1
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +37 -2
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decorators.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/decorators.test.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"decorators.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/decorators.test.ts"],"names":[],"mappings":"AAuCA,OAAO,kBAAkB,CAAC"}
|
|
@@ -958,4 +958,280 @@ describe('Decorators', () => {
|
|
|
958
958
|
expect(guardMeta).toContain(RoleGuard);
|
|
959
959
|
});
|
|
960
960
|
});
|
|
961
|
+
describe('Ip', () => {
|
|
962
|
+
it('should register ip injection type', () => {
|
|
963
|
+
class TestController {
|
|
964
|
+
get(ip) {
|
|
965
|
+
return { ip };
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
__decorate([
|
|
969
|
+
(0, decorators_1.Get)('/'),
|
|
970
|
+
__param(0, (0, decorators_1.Ip)()),
|
|
971
|
+
__metadata("design:type", Function),
|
|
972
|
+
__metadata("design:paramtypes", [String]),
|
|
973
|
+
__metadata("design:returntype", void 0)
|
|
974
|
+
], TestController.prototype, "get", null);
|
|
975
|
+
const injections = Reflect.getMetadata('hazel:inject', TestController, 'get');
|
|
976
|
+
expect(injections[0]).toEqual({ type: 'ip' });
|
|
977
|
+
});
|
|
978
|
+
it('should throw when used outside a method parameter', () => {
|
|
979
|
+
class Ctrl {
|
|
980
|
+
get() { }
|
|
981
|
+
}
|
|
982
|
+
expect(() => (0, decorators_1.Ip)()(Ctrl.prototype, undefined, 0)).toThrow('Ip decorator must be used on a method parameter');
|
|
983
|
+
});
|
|
984
|
+
});
|
|
985
|
+
describe('Host', () => {
|
|
986
|
+
it('should register host injection type', () => {
|
|
987
|
+
class TestController {
|
|
988
|
+
get(host) {
|
|
989
|
+
return { host };
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
__decorate([
|
|
993
|
+
(0, decorators_1.Get)('/'),
|
|
994
|
+
__param(0, (0, decorators_1.Host)()),
|
|
995
|
+
__metadata("design:type", Function),
|
|
996
|
+
__metadata("design:paramtypes", [String]),
|
|
997
|
+
__metadata("design:returntype", void 0)
|
|
998
|
+
], TestController.prototype, "get", null);
|
|
999
|
+
const injections = Reflect.getMetadata('hazel:inject', TestController, 'get');
|
|
1000
|
+
expect(injections[0]).toEqual({ type: 'host' });
|
|
1001
|
+
});
|
|
1002
|
+
it('should throw when used outside a method parameter', () => {
|
|
1003
|
+
class Ctrl {
|
|
1004
|
+
get() { }
|
|
1005
|
+
}
|
|
1006
|
+
expect(() => (0, decorators_1.Host)()(Ctrl.prototype, undefined, 0)).toThrow('Host decorator must be used on a method parameter');
|
|
1007
|
+
});
|
|
1008
|
+
});
|
|
1009
|
+
describe('Public', () => {
|
|
1010
|
+
it('should set public metadata on class', () => {
|
|
1011
|
+
let TestController = class TestController {
|
|
1012
|
+
};
|
|
1013
|
+
TestController = __decorate([
|
|
1014
|
+
(0, decorators_1.Public)()
|
|
1015
|
+
], TestController);
|
|
1016
|
+
expect(Reflect.getMetadata('hazel:public', TestController)).toBe(true);
|
|
1017
|
+
});
|
|
1018
|
+
it('should set public metadata on method', () => {
|
|
1019
|
+
class TestController {
|
|
1020
|
+
login() {
|
|
1021
|
+
return {};
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
__decorate([
|
|
1025
|
+
(0, decorators_1.Public)(),
|
|
1026
|
+
(0, decorators_1.Get)('/login'),
|
|
1027
|
+
__metadata("design:type", Function),
|
|
1028
|
+
__metadata("design:paramtypes", []),
|
|
1029
|
+
__metadata("design:returntype", void 0)
|
|
1030
|
+
], TestController.prototype, "login", null);
|
|
1031
|
+
expect(Reflect.getMetadata('hazel:public', TestController.prototype, 'login')).toBe(true);
|
|
1032
|
+
});
|
|
1033
|
+
});
|
|
1034
|
+
describe('SkipAuth', () => {
|
|
1035
|
+
it('should be an alias for Public', () => {
|
|
1036
|
+
expect(decorators_1.SkipAuth).toBe(decorators_1.Public);
|
|
1037
|
+
});
|
|
1038
|
+
});
|
|
1039
|
+
describe('Timeout', () => {
|
|
1040
|
+
it('should store timeout in metadata', () => {
|
|
1041
|
+
class TestController {
|
|
1042
|
+
get() {
|
|
1043
|
+
return {};
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
__decorate([
|
|
1047
|
+
(0, decorators_1.Timeout)(5000),
|
|
1048
|
+
(0, decorators_1.Get)('/'),
|
|
1049
|
+
__metadata("design:type", Function),
|
|
1050
|
+
__metadata("design:paramtypes", []),
|
|
1051
|
+
__metadata("design:returntype", void 0)
|
|
1052
|
+
], TestController.prototype, "get", null);
|
|
1053
|
+
expect(Reflect.getMetadata('hazel:timeout', TestController.prototype, 'get')).toBe(5000);
|
|
1054
|
+
});
|
|
1055
|
+
});
|
|
1056
|
+
describe('Optional', () => {
|
|
1057
|
+
it('should add parameter index to optional indices', () => {
|
|
1058
|
+
class TestController {
|
|
1059
|
+
get(q) {
|
|
1060
|
+
return { q };
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
__decorate([
|
|
1064
|
+
(0, decorators_1.Get)('/'),
|
|
1065
|
+
__param(0, (0, decorators_1.Optional)()),
|
|
1066
|
+
__param(0, (0, decorators_1.Query)('q')),
|
|
1067
|
+
__metadata("design:type", Function),
|
|
1068
|
+
__metadata("design:paramtypes", [String]),
|
|
1069
|
+
__metadata("design:returntype", void 0)
|
|
1070
|
+
], TestController.prototype, "get", null);
|
|
1071
|
+
const indices = Reflect.getMetadata('hazel:optional-indices', TestController, 'get');
|
|
1072
|
+
expect(indices).toContain(0);
|
|
1073
|
+
});
|
|
1074
|
+
it('should throw when used outside a method parameter', () => {
|
|
1075
|
+
class Ctrl {
|
|
1076
|
+
get() { }
|
|
1077
|
+
}
|
|
1078
|
+
expect(() => (0, decorators_1.Optional)()(Ctrl.prototype, undefined, 0)).toThrow('Optional decorator must be used on a method parameter');
|
|
1079
|
+
});
|
|
1080
|
+
});
|
|
1081
|
+
describe('Session', () => {
|
|
1082
|
+
it('should register session injection type', () => {
|
|
1083
|
+
class TestController {
|
|
1084
|
+
get(session) {
|
|
1085
|
+
return { session };
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
__decorate([
|
|
1089
|
+
(0, decorators_1.Get)('/'),
|
|
1090
|
+
__param(0, (0, decorators_1.Session)()),
|
|
1091
|
+
__metadata("design:type", Function),
|
|
1092
|
+
__metadata("design:paramtypes", [Object]),
|
|
1093
|
+
__metadata("design:returntype", void 0)
|
|
1094
|
+
], TestController.prototype, "get", null);
|
|
1095
|
+
const injections = Reflect.getMetadata('hazel:inject', TestController, 'get');
|
|
1096
|
+
expect(injections[0]).toEqual({ type: 'session' });
|
|
1097
|
+
});
|
|
1098
|
+
it('should throw when used outside a method parameter', () => {
|
|
1099
|
+
class Ctrl {
|
|
1100
|
+
get() { }
|
|
1101
|
+
}
|
|
1102
|
+
expect(() => (0, decorators_1.Session)()(Ctrl.prototype, undefined, 0)).toThrow('Session decorator must be used on a method parameter');
|
|
1103
|
+
});
|
|
1104
|
+
});
|
|
1105
|
+
describe('Retry', () => {
|
|
1106
|
+
it('should store retry options and add RetryInterceptor to route', () => {
|
|
1107
|
+
class TestController {
|
|
1108
|
+
get() {
|
|
1109
|
+
return {};
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
__decorate([
|
|
1113
|
+
(0, decorators_1.Retry)({ count: 3, delay: 100 }),
|
|
1114
|
+
(0, decorators_1.Get)('/'),
|
|
1115
|
+
__metadata("design:type", Function),
|
|
1116
|
+
__metadata("design:paramtypes", []),
|
|
1117
|
+
__metadata("design:returntype", void 0)
|
|
1118
|
+
], TestController.prototype, "get", null);
|
|
1119
|
+
expect(Reflect.getMetadata('hazel:retry', TestController.prototype, 'get')).toEqual({
|
|
1120
|
+
count: 3,
|
|
1121
|
+
delay: 100,
|
|
1122
|
+
});
|
|
1123
|
+
const routes = Reflect.getMetadata('hazel:routes', TestController);
|
|
1124
|
+
const route = routes.find((r) => r.propertyKey === 'get');
|
|
1125
|
+
expect(route?.interceptors?.[0]?.type?.name).toBe('RetryInterceptor');
|
|
1126
|
+
});
|
|
1127
|
+
});
|
|
1128
|
+
describe('ApiTags', () => {
|
|
1129
|
+
it('should set api tags on class', () => {
|
|
1130
|
+
let TestController = class TestController {
|
|
1131
|
+
};
|
|
1132
|
+
TestController = __decorate([
|
|
1133
|
+
(0, decorators_1.ApiTags)('users', 'admin')
|
|
1134
|
+
], TestController);
|
|
1135
|
+
expect(Reflect.getMetadata('hazel:api:tags', TestController)).toEqual(['users', 'admin']);
|
|
1136
|
+
});
|
|
1137
|
+
it('should set api tags on method', () => {
|
|
1138
|
+
class TestController {
|
|
1139
|
+
login() {
|
|
1140
|
+
return {};
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
__decorate([
|
|
1144
|
+
(0, decorators_1.ApiTags)('auth'),
|
|
1145
|
+
(0, decorators_1.Get)('/login'),
|
|
1146
|
+
__metadata("design:type", Function),
|
|
1147
|
+
__metadata("design:paramtypes", []),
|
|
1148
|
+
__metadata("design:returntype", void 0)
|
|
1149
|
+
], TestController.prototype, "login", null);
|
|
1150
|
+
expect(Reflect.getMetadata('hazel:api:tags', TestController.prototype, 'login')).toEqual(['auth']);
|
|
1151
|
+
});
|
|
1152
|
+
});
|
|
1153
|
+
describe('ApiOperation', () => {
|
|
1154
|
+
it('should store operation options when given object', () => {
|
|
1155
|
+
class TestController {
|
|
1156
|
+
get() {
|
|
1157
|
+
return {};
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
__decorate([
|
|
1161
|
+
(0, decorators_1.ApiOperation)({ summary: 'Get user', description: 'Returns a user', operationId: 'getUser' }),
|
|
1162
|
+
(0, decorators_1.Get)('/'),
|
|
1163
|
+
__metadata("design:type", Function),
|
|
1164
|
+
__metadata("design:paramtypes", []),
|
|
1165
|
+
__metadata("design:returntype", void 0)
|
|
1166
|
+
], TestController.prototype, "get", null);
|
|
1167
|
+
expect(Reflect.getMetadata('hazel:api:operation', TestController.prototype, 'get')).toEqual({
|
|
1168
|
+
summary: 'Get user',
|
|
1169
|
+
description: 'Returns a user',
|
|
1170
|
+
operationId: 'getUser',
|
|
1171
|
+
});
|
|
1172
|
+
});
|
|
1173
|
+
it('should accept string as summary', () => {
|
|
1174
|
+
class TestController {
|
|
1175
|
+
get() {
|
|
1176
|
+
return {};
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
__decorate([
|
|
1180
|
+
(0, decorators_1.ApiOperation)('List users'),
|
|
1181
|
+
(0, decorators_1.Get)('/'),
|
|
1182
|
+
__metadata("design:type", Function),
|
|
1183
|
+
__metadata("design:paramtypes", []),
|
|
1184
|
+
__metadata("design:returntype", void 0)
|
|
1185
|
+
], TestController.prototype, "get", null);
|
|
1186
|
+
expect(Reflect.getMetadata('hazel:api:operation', TestController.prototype, 'get')).toEqual({
|
|
1187
|
+
summary: 'List users',
|
|
1188
|
+
});
|
|
1189
|
+
});
|
|
1190
|
+
});
|
|
1191
|
+
describe('SetMetadata and getMetadata', () => {
|
|
1192
|
+
it('should set and get class-level metadata', () => {
|
|
1193
|
+
let AdminController = class AdminController {
|
|
1194
|
+
};
|
|
1195
|
+
AdminController = __decorate([
|
|
1196
|
+
(0, decorators_1.SetMetadata)('roles', ['admin'])
|
|
1197
|
+
], AdminController);
|
|
1198
|
+
expect((0, decorators_1.getMetadata)('roles', AdminController)).toEqual(['admin']);
|
|
1199
|
+
expect(Reflect.getMetadata(`${decorators_1.CUSTOM_METADATA_PREFIX}roles`, AdminController)).toEqual(['admin']);
|
|
1200
|
+
});
|
|
1201
|
+
it('should set and get method-level metadata', () => {
|
|
1202
|
+
class TestController {
|
|
1203
|
+
get() {
|
|
1204
|
+
return {};
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
__decorate([
|
|
1208
|
+
(0, decorators_1.SetMetadata)('roles', ['user']),
|
|
1209
|
+
(0, decorators_1.Get)('/'),
|
|
1210
|
+
__metadata("design:type", Function),
|
|
1211
|
+
__metadata("design:paramtypes", []),
|
|
1212
|
+
__metadata("design:returntype", void 0)
|
|
1213
|
+
], TestController.prototype, "get", null);
|
|
1214
|
+
expect((0, decorators_1.getMetadata)('roles', TestController.prototype, 'get')).toEqual(['user']);
|
|
1215
|
+
});
|
|
1216
|
+
});
|
|
1217
|
+
describe('createParamDecorator', () => {
|
|
1218
|
+
it('should register custom inject metadata', () => {
|
|
1219
|
+
const MyParam = (0, decorators_1.createParamDecorator)((_req, ctx) => ctx.query?.foo);
|
|
1220
|
+
class TestController {
|
|
1221
|
+
get(foo) {
|
|
1222
|
+
return { foo };
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
__decorate([
|
|
1226
|
+
(0, decorators_1.Get)('/'),
|
|
1227
|
+
__param(0, MyParam),
|
|
1228
|
+
__metadata("design:type", Function),
|
|
1229
|
+
__metadata("design:paramtypes", [String]),
|
|
1230
|
+
__metadata("design:returntype", void 0)
|
|
1231
|
+
], TestController.prototype, "get", null);
|
|
1232
|
+
const injections = Reflect.getMetadata('hazel:inject', TestController, 'get');
|
|
1233
|
+
expect(injections).toBeDefined();
|
|
1234
|
+
expect(injections[0]).toEqual({ type: 'custom', resolve: expect.any(Function) });
|
|
1235
|
+
});
|
|
1236
|
+
});
|
|
961
1237
|
});
|
package/dist/decorators.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import 'reflect-metadata';
|
|
2
|
-
import { Type, RequestContext } from './types';
|
|
2
|
+
import { Type, RequestContext, Request } from './types';
|
|
3
3
|
import { PipeTransform, PipeMetadata } from './pipes/pipe';
|
|
4
4
|
import { Interceptor, InterceptorMetadata } from './interceptors/interceptor';
|
|
5
5
|
import { HazelApp } from './hazel-app';
|
|
6
|
+
import type { Container } from './container';
|
|
7
|
+
export declare const CUSTOM_METADATA_PREFIX = "hazel:meta:";
|
|
6
8
|
export interface ControllerMetadata {
|
|
7
9
|
path: string;
|
|
8
10
|
interceptors?: InterceptorMetadata[];
|
|
@@ -95,5 +97,70 @@ export declare function HttpCode(statusCode: number): MethodDecorator;
|
|
|
95
97
|
export declare function Header(name: string, value: string): MethodDecorator;
|
|
96
98
|
export declare function Redirect(url: string, statusCode?: number): MethodDecorator;
|
|
97
99
|
export declare function Res(): ParameterDecorator;
|
|
100
|
+
export declare function Ip(): ParameterDecorator;
|
|
101
|
+
export declare function Host(): ParameterDecorator;
|
|
102
|
+
/**
|
|
103
|
+
* Marks a controller or route as public (no auth required).
|
|
104
|
+
* Guards should check Reflect.getMetadata(PUBLIC_METADATA_KEY, target, propertyKey)
|
|
105
|
+
* or Reflect.getMetadata(PUBLIC_METADATA_KEY, target) and allow the request when true.
|
|
106
|
+
*/
|
|
107
|
+
export declare function Public(): ClassDecorator & MethodDecorator;
|
|
108
|
+
/** Alias for @Public(). Use when you want to skip auth for specific routes. */
|
|
109
|
+
export declare const SkipAuth: typeof Public;
|
|
110
|
+
export declare function Timeout(ms: number): MethodDecorator;
|
|
111
|
+
export declare function Optional(): ParameterDecorator;
|
|
112
|
+
export declare function Session(): ParameterDecorator;
|
|
113
|
+
export interface RetryDecoratorOptions {
|
|
114
|
+
count: number;
|
|
115
|
+
delay?: number;
|
|
116
|
+
retryIf?: (err: Error) => boolean;
|
|
117
|
+
}
|
|
118
|
+
export declare function Retry(options: RetryDecoratorOptions): MethodDecorator;
|
|
119
|
+
export declare function ApiTags(...tags: string[]): ClassDecorator & MethodDecorator;
|
|
120
|
+
export interface ApiOperationOptions {
|
|
121
|
+
summary?: string;
|
|
122
|
+
description?: string;
|
|
123
|
+
operationId?: string;
|
|
124
|
+
}
|
|
125
|
+
export declare function ApiOperation(options: ApiOperationOptions | string): MethodDecorator;
|
|
126
|
+
/**
|
|
127
|
+
* Sets arbitrary metadata on a class or method.
|
|
128
|
+
* Guards, interceptors, and other components can read it via getMetadata(key, target, propertyKey?).
|
|
129
|
+
*
|
|
130
|
+
* @param key - Metadata key (stored under hazel:meta:<key> to avoid collisions)
|
|
131
|
+
* @param value - Value to store (any serializable or object)
|
|
132
|
+
* @example
|
|
133
|
+
* SetMetadata('roles', ['admin'])(MyController)
|
|
134
|
+
* SetMetadata('roles', ['user'])(MyController.prototype, 'getProfile')
|
|
135
|
+
*/
|
|
136
|
+
export declare function SetMetadata(key: string, value: unknown): ClassDecorator & MethodDecorator;
|
|
137
|
+
/**
|
|
138
|
+
* Reads custom metadata set with SetMetadata.
|
|
139
|
+
*
|
|
140
|
+
* @param key - Key passed to SetMetadata(key, value)
|
|
141
|
+
* @param target - Class or prototype
|
|
142
|
+
* @param propertyKey - Optional method name (for method-level metadata)
|
|
143
|
+
*/
|
|
144
|
+
export declare function getMetadata<T = unknown>(key: string, target: object, propertyKey?: string | symbol): T | undefined;
|
|
145
|
+
/**
|
|
146
|
+
* Context passed to custom parameter decorator resolvers.
|
|
147
|
+
* The router calls the resolver with (req, context, container) when invoking the handler.
|
|
148
|
+
*/
|
|
149
|
+
export interface ParamDecoratorContext {
|
|
150
|
+
req: Request;
|
|
151
|
+
context: RequestContext;
|
|
152
|
+
container: Container;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Creates a custom parameter decorator that injects a value computed from the request.
|
|
156
|
+
* The resolver receives the raw request, parsed request context, and the DI container.
|
|
157
|
+
* Return value can be a Promise for async resolution (e.g. loading the current user from DB).
|
|
158
|
+
*
|
|
159
|
+
* @param resolve - Function (req, context, container) => value | Promise<value>
|
|
160
|
+
* @example
|
|
161
|
+
* const CurrentUser = createParamDecorator(async (req, ctx, container) => ctx.user ?? req.user);
|
|
162
|
+
* // In controller: getProfile(@CurrentUser() user: User) { ... }
|
|
163
|
+
*/
|
|
164
|
+
export declare function createParamDecorator<T = unknown>(resolve: (req: Request, context: RequestContext, container: Container) => T | Promise<T>): ParameterDecorator;
|
|
98
165
|
export { HazelApp };
|
|
99
166
|
//# sourceMappingURL=decorators.d.ts.map
|
package/dist/decorators.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../src/decorators.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAE1B,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../src/decorators.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAE1B,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAoB,MAAM,4BAA4B,CAAC;AAChG,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAmB7C,eAAO,MAAM,sBAAsB,gBAAgB,CAAC;AAEpD,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,mBAAmB,EAAE,CAAC;CACtC;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;IAC9B,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;IAC9B,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC;IACvB,YAAY,CAAC,EAAE,mBAAmB,EAAE,CAAC;CACtC;AAID,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,WAAW,GAAG,WAAW,GAAG,SAAS,CAAC;CAC/C;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,WAAW,GAAG,WAAW,GAAG,SAAS,CAAC;CAC/C;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,WAAW,GAAG,WAAW,GAAG,SAAS,CAAC;CAC/C;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe;IAC9B,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,gBAAgB;IAC/B,YAAY,IAAI;QACd,UAAU,IAAI,OAAO,CAAC;QACtB,WAAW,IAAI,OAAO,CAAC;QACvB;;;;WAIG;QACH,UAAU,IAAI,cAAc,CAAC;KAC9B,CAAC;CACH;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;CACpE;AAGD,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAErD,wBAAgB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,GAAG,cAAc,CAQ9E;AAED,wBAAgB,UAAU,CAAC,OAAO,GAAE,iBAAsB,GAAG,cAAc,CAS1E;AAED,wBAAgB,GAAG,CAAC,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,GAAG,eAAe,CAGzE;AAED,wBAAgB,IAAI,CAAC,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,GAAG,eAAe,CAG1E;AAED,wBAAgB,GAAG,CAAC,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,GAAG,eAAe,CAGzE;AAED,wBAAgB,MAAM,CAAC,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,GAAG,eAAe,CAG5E;AAED,wBAAgB,KAAK,CAAC,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,GAAG,eAAe,CAG3E;AAED,wBAAgB,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,kBAAkB,CAalF;AAED,wBAAgB,OAAO,CAAC,OAAO,GAAE,cAAmB,GAAG,cAAc,CAyBpE;AAED,wBAAgB,IAAI,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,kBAAkB,CA6BhE;AAED,wBAAgB,OAAO,IAAI,kBAAkB,CAgB5C;AAED,wBAAgB,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,kBAAkB,CAuBvF;AAED,wBAAgB,KAAK,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,kBAAkB,CAuBxF;AAED,wBAAgB,QAAQ,CACtB,GAAG,KAAK,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,YAAY,CAAC,EAAE,GAC/C,cAAc,GAAG,eAAe,CAgClC;AAED,wBAAgB,eAAe,CAC7B,GAAG,YAAY,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,mBAAmB,CAAC,EAAE,GAC3D,cAAc,GAAG,eAAe,CA4BlC;AAED,wBAAgB,SAAS,CAAC,GAAG,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,EAAE,GAAG,cAAc,GAAG,eAAe,CAmB1F;AAED,wBAAgB,MAAM,CAAC,OAAO,EAAE;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,eAAe,CASlB;AAED,wBAAgB,GAAG,IAAI,kBAAkB,CAgBxC;AAED,wBAAgB,OAAO,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,kBAAkB,CAgB/D;AAED,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,CAS5D;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,eAAe,CAYnE;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,GAAE,MAAY,GAAG,eAAe,CAS/E;AAED,wBAAgB,GAAG,IAAI,kBAAkB,CAyBxC;AAED,wBAAgB,EAAE,IAAI,kBAAkB,CAevC;AAED,wBAAgB,IAAI,IAAI,kBAAkB,CAezC;AAED;;;;GAIG;AACH,wBAAgB,MAAM,IAAI,cAAc,GAAG,eAAe,CAoBzD;AAED,+EAA+E;AAC/E,eAAO,MAAM,QAAQ,eAAS,CAAC;AAE/B,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,CASnD;AAED,wBAAgB,QAAQ,IAAI,kBAAkB,CAiB7C;AAED,wBAAgB,OAAO,IAAI,kBAAkB,CAe5C;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,OAAO,CAAC;CACnC;AAED,wBAAgB,KAAK,CAAC,OAAO,EAAE,qBAAqB,GAAG,eAAe,CAgBrE;AAED,wBAAgB,OAAO,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,cAAc,GAAG,eAAe,CAoB3E;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,GAAG,eAAe,CAUnF;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,cAAc,GAAG,eAAe,CAczF;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,CAAC,GAAG,OAAO,EACrC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,GAC5B,CAAC,GAAG,SAAS,CAMf;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,OAAO,CAAC;IACb,OAAO,EAAE,cAAc,CAAC;IACxB,SAAS,EAAE,SAAS,CAAC;CACtB;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,GAAG,OAAO,EAC9C,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,SAAS,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GACvF,kBAAkB,CAcpB;AA8CD,OAAO,EAAE,QAAQ,EAAE,CAAC"}
|
package/dist/decorators.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.HazelApp = exports.Module = exports.HazelModule = void 0;
|
|
6
|
+
exports.HazelApp = exports.SkipAuth = exports.Module = exports.HazelModule = exports.CUSTOM_METADATA_PREFIX = void 0;
|
|
7
7
|
exports.Controller = Controller;
|
|
8
8
|
exports.Injectable = Injectable;
|
|
9
9
|
exports.Get = Get;
|
|
@@ -27,8 +27,21 @@ exports.HttpCode = HttpCode;
|
|
|
27
27
|
exports.Header = Header;
|
|
28
28
|
exports.Redirect = Redirect;
|
|
29
29
|
exports.Res = Res;
|
|
30
|
+
exports.Ip = Ip;
|
|
31
|
+
exports.Host = Host;
|
|
32
|
+
exports.Public = Public;
|
|
33
|
+
exports.Timeout = Timeout;
|
|
34
|
+
exports.Optional = Optional;
|
|
35
|
+
exports.Session = Session;
|
|
36
|
+
exports.Retry = Retry;
|
|
37
|
+
exports.ApiTags = ApiTags;
|
|
38
|
+
exports.ApiOperation = ApiOperation;
|
|
39
|
+
exports.SetMetadata = SetMetadata;
|
|
40
|
+
exports.getMetadata = getMetadata;
|
|
41
|
+
exports.createParamDecorator = createParamDecorator;
|
|
30
42
|
require("reflect-metadata");
|
|
31
43
|
const logger_1 = __importDefault(require("./logger"));
|
|
44
|
+
const interceptor_1 = require("./interceptors/interceptor");
|
|
32
45
|
const hazel_app_1 = require("./hazel-app");
|
|
33
46
|
Object.defineProperty(exports, "HazelApp", { enumerable: true, get: function () { return hazel_app_1.HazelApp; } });
|
|
34
47
|
const CONTROLLER_METADATA_KEY = 'hazel:controller';
|
|
@@ -42,6 +55,13 @@ const CLASS_INTERCEPTOR_METADATA_KEY = 'hazel:class-interceptors';
|
|
|
42
55
|
const HTTP_CODE_METADATA_KEY = 'hazel:http-code';
|
|
43
56
|
const HEADER_METADATA_KEY = 'hazel:headers';
|
|
44
57
|
const REDIRECT_METADATA_KEY = 'hazel:redirect';
|
|
58
|
+
const PUBLIC_METADATA_KEY = 'hazel:public';
|
|
59
|
+
const TIMEOUT_METADATA_KEY = 'hazel:timeout';
|
|
60
|
+
const OPTIONAL_INDICES_METADATA_KEY = 'hazel:optional-indices';
|
|
61
|
+
const RETRY_METADATA_KEY = 'hazel:retry';
|
|
62
|
+
const API_TAGS_METADATA_KEY = 'hazel:api:tags';
|
|
63
|
+
const API_OPERATION_METADATA_KEY = 'hazel:api:operation';
|
|
64
|
+
exports.CUSTOM_METADATA_PREFIX = 'hazel:meta:';
|
|
45
65
|
// Re-export from hazel-module for backward compatibility
|
|
46
66
|
var hazel_module_1 = require("./hazel-module");
|
|
47
67
|
Object.defineProperty(exports, "HazelModule", { enumerable: true, get: function () { return hazel_module_1.HazelModule; } });
|
|
@@ -313,6 +333,181 @@ function Res() {
|
|
|
313
333
|
logger_1.default.debug('Updated injections:', JSON.stringify(injections, null, 2));
|
|
314
334
|
};
|
|
315
335
|
}
|
|
336
|
+
function Ip() {
|
|
337
|
+
return (target, propertyKey, parameterIndex) => {
|
|
338
|
+
if (!propertyKey) {
|
|
339
|
+
throw new Error('Ip decorator must be used on a method parameter');
|
|
340
|
+
}
|
|
341
|
+
const constructor = target
|
|
342
|
+
.constructor;
|
|
343
|
+
const injections = Reflect.getMetadata(INJECT_METADATA_KEY, constructor, propertyKey) || [];
|
|
344
|
+
injections[parameterIndex] = { type: 'ip' };
|
|
345
|
+
Reflect.defineMetadata(INJECT_METADATA_KEY, injections, constructor, propertyKey);
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
function Host() {
|
|
349
|
+
return (target, propertyKey, parameterIndex) => {
|
|
350
|
+
if (!propertyKey) {
|
|
351
|
+
throw new Error('Host decorator must be used on a method parameter');
|
|
352
|
+
}
|
|
353
|
+
const constructor = target
|
|
354
|
+
.constructor;
|
|
355
|
+
const injections = Reflect.getMetadata(INJECT_METADATA_KEY, constructor, propertyKey) || [];
|
|
356
|
+
injections[parameterIndex] = { type: 'host' };
|
|
357
|
+
Reflect.defineMetadata(INJECT_METADATA_KEY, injections, constructor, propertyKey);
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Marks a controller or route as public (no auth required).
|
|
362
|
+
* Guards should check Reflect.getMetadata(PUBLIC_METADATA_KEY, target, propertyKey)
|
|
363
|
+
* or Reflect.getMetadata(PUBLIC_METADATA_KEY, target) and allow the request when true.
|
|
364
|
+
*/
|
|
365
|
+
function Public() {
|
|
366
|
+
const setPublic = (target, propertyKey) => {
|
|
367
|
+
if (propertyKey === undefined) {
|
|
368
|
+
Reflect.defineMetadata(PUBLIC_METADATA_KEY, true, target);
|
|
369
|
+
}
|
|
370
|
+
else {
|
|
371
|
+
Reflect.defineMetadata(PUBLIC_METADATA_KEY, true, target, propertyKey);
|
|
372
|
+
}
|
|
373
|
+
};
|
|
374
|
+
const decorator = (target, propertyKey, descriptor) => {
|
|
375
|
+
if (propertyKey !== undefined && descriptor !== undefined) {
|
|
376
|
+
setPublic(target, propertyKey);
|
|
377
|
+
return descriptor;
|
|
378
|
+
}
|
|
379
|
+
setPublic(target);
|
|
380
|
+
};
|
|
381
|
+
return decorator;
|
|
382
|
+
}
|
|
383
|
+
/** Alias for @Public(). Use when you want to skip auth for specific routes. */
|
|
384
|
+
exports.SkipAuth = Public;
|
|
385
|
+
function Timeout(ms) {
|
|
386
|
+
return (target, propertyKey, descriptor) => {
|
|
387
|
+
Reflect.defineMetadata(TIMEOUT_METADATA_KEY, ms, target, propertyKey);
|
|
388
|
+
return descriptor;
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
function Optional() {
|
|
392
|
+
return (target, propertyKey, parameterIndex) => {
|
|
393
|
+
if (!propertyKey) {
|
|
394
|
+
throw new Error('Optional decorator must be used on a method parameter');
|
|
395
|
+
}
|
|
396
|
+
const constructor = target
|
|
397
|
+
.constructor;
|
|
398
|
+
const indices = Reflect.getMetadata(OPTIONAL_INDICES_METADATA_KEY, constructor, propertyKey) || [];
|
|
399
|
+
if (!indices.includes(parameterIndex)) {
|
|
400
|
+
indices.push(parameterIndex);
|
|
401
|
+
}
|
|
402
|
+
Reflect.defineMetadata(OPTIONAL_INDICES_METADATA_KEY, indices, constructor, propertyKey);
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
function Session() {
|
|
406
|
+
return (target, propertyKey, parameterIndex) => {
|
|
407
|
+
if (!propertyKey) {
|
|
408
|
+
throw new Error('Session decorator must be used on a method parameter');
|
|
409
|
+
}
|
|
410
|
+
const constructor = target
|
|
411
|
+
.constructor;
|
|
412
|
+
const injections = Reflect.getMetadata(INJECT_METADATA_KEY, constructor, propertyKey) || [];
|
|
413
|
+
injections[parameterIndex] = { type: 'session' };
|
|
414
|
+
Reflect.defineMetadata(INJECT_METADATA_KEY, injections, constructor, propertyKey);
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
function Retry(options) {
|
|
418
|
+
return (target, propertyKey, descriptor) => {
|
|
419
|
+
Reflect.defineMetadata(RETRY_METADATA_KEY, options, target, propertyKey);
|
|
420
|
+
const routes = Reflect.getMetadata(ROUTE_METADATA_KEY, target.constructor) || [];
|
|
421
|
+
const route = routes.find((r) => r.propertyKey === propertyKey);
|
|
422
|
+
if (route) {
|
|
423
|
+
route.interceptors = route.interceptors || [];
|
|
424
|
+
route.interceptors.unshift({ type: interceptor_1.RetryInterceptor, options });
|
|
425
|
+
Reflect.defineMetadata(ROUTE_METADATA_KEY, routes, target.constructor);
|
|
426
|
+
}
|
|
427
|
+
return descriptor;
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
function ApiTags(...tags) {
|
|
431
|
+
const setTags = (target, propertyKey) => {
|
|
432
|
+
if (propertyKey === undefined) {
|
|
433
|
+
Reflect.defineMetadata(API_TAGS_METADATA_KEY, tags, target);
|
|
434
|
+
}
|
|
435
|
+
else {
|
|
436
|
+
Reflect.defineMetadata(API_TAGS_METADATA_KEY, tags, target, propertyKey);
|
|
437
|
+
}
|
|
438
|
+
};
|
|
439
|
+
const decorator = (target, propertyKey, descriptor) => {
|
|
440
|
+
if (propertyKey !== undefined && descriptor !== undefined) {
|
|
441
|
+
setTags(target, propertyKey);
|
|
442
|
+
return descriptor;
|
|
443
|
+
}
|
|
444
|
+
setTags(target);
|
|
445
|
+
};
|
|
446
|
+
return decorator;
|
|
447
|
+
}
|
|
448
|
+
function ApiOperation(options) {
|
|
449
|
+
const opts = typeof options === 'string' ? { summary: options } : options;
|
|
450
|
+
return (target, propertyKey, descriptor) => {
|
|
451
|
+
Reflect.defineMetadata(API_OPERATION_METADATA_KEY, opts, target, propertyKey);
|
|
452
|
+
return descriptor;
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* Sets arbitrary metadata on a class or method.
|
|
457
|
+
* Guards, interceptors, and other components can read it via getMetadata(key, target, propertyKey?).
|
|
458
|
+
*
|
|
459
|
+
* @param key - Metadata key (stored under hazel:meta:<key> to avoid collisions)
|
|
460
|
+
* @param value - Value to store (any serializable or object)
|
|
461
|
+
* @example
|
|
462
|
+
* SetMetadata('roles', ['admin'])(MyController)
|
|
463
|
+
* SetMetadata('roles', ['user'])(MyController.prototype, 'getProfile')
|
|
464
|
+
*/
|
|
465
|
+
function SetMetadata(key, value) {
|
|
466
|
+
const metaKey = `${exports.CUSTOM_METADATA_PREFIX}${key}`;
|
|
467
|
+
const decorator = (target, propertyKey, descriptor) => {
|
|
468
|
+
if (propertyKey !== undefined && descriptor !== undefined) {
|
|
469
|
+
Reflect.defineMetadata(metaKey, value, target, propertyKey);
|
|
470
|
+
return descriptor;
|
|
471
|
+
}
|
|
472
|
+
Reflect.defineMetadata(metaKey, value, target);
|
|
473
|
+
};
|
|
474
|
+
return decorator;
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Reads custom metadata set with SetMetadata.
|
|
478
|
+
*
|
|
479
|
+
* @param key - Key passed to SetMetadata(key, value)
|
|
480
|
+
* @param target - Class or prototype
|
|
481
|
+
* @param propertyKey - Optional method name (for method-level metadata)
|
|
482
|
+
*/
|
|
483
|
+
function getMetadata(key, target, propertyKey) {
|
|
484
|
+
const metaKey = `${exports.CUSTOM_METADATA_PREFIX}${key}`;
|
|
485
|
+
if (propertyKey !== undefined) {
|
|
486
|
+
return Reflect.getMetadata(metaKey, target, propertyKey);
|
|
487
|
+
}
|
|
488
|
+
return Reflect.getMetadata(metaKey, target);
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Creates a custom parameter decorator that injects a value computed from the request.
|
|
492
|
+
* The resolver receives the raw request, parsed request context, and the DI container.
|
|
493
|
+
* Return value can be a Promise for async resolution (e.g. loading the current user from DB).
|
|
494
|
+
*
|
|
495
|
+
* @param resolve - Function (req, context, container) => value | Promise<value>
|
|
496
|
+
* @example
|
|
497
|
+
* const CurrentUser = createParamDecorator(async (req, ctx, container) => ctx.user ?? req.user);
|
|
498
|
+
* // In controller: getProfile(@CurrentUser() user: User) { ... }
|
|
499
|
+
*/
|
|
500
|
+
function createParamDecorator(resolve) {
|
|
501
|
+
return (target, propertyKey, parameterIndex) => {
|
|
502
|
+
if (!propertyKey) {
|
|
503
|
+
throw new Error('createParamDecorator must be used on a method parameter');
|
|
504
|
+
}
|
|
505
|
+
const constructor = target.constructor;
|
|
506
|
+
const injections = Reflect.getMetadata(INJECT_METADATA_KEY, constructor, propertyKey) || [];
|
|
507
|
+
injections[parameterIndex] = { type: 'custom', resolve };
|
|
508
|
+
Reflect.defineMetadata(INJECT_METADATA_KEY, injections, constructor, propertyKey);
|
|
509
|
+
};
|
|
510
|
+
}
|
|
316
511
|
function createRouteDecorator(method, options) {
|
|
317
512
|
return (target, propertyKey, descriptor) => {
|
|
318
513
|
logger_1.default.debug(`Registering ${method} route: ${String(propertyKey)}`);
|
|
@@ -18,6 +18,9 @@ export declare class NotFoundError extends HttpError {
|
|
|
18
18
|
export declare class ConflictError extends HttpError {
|
|
19
19
|
constructor(message: string);
|
|
20
20
|
}
|
|
21
|
+
export declare class RequestTimeoutError extends HttpError {
|
|
22
|
+
constructor(message?: string);
|
|
23
|
+
}
|
|
21
24
|
export declare class InternalServerError extends HttpError {
|
|
22
25
|
constructor(message?: string);
|
|
23
26
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.error.d.ts","sourceRoot":"","sources":["../../src/errors/http.error.ts"],"names":[],"mappings":"AAAA,qBAAa,SAAU,SAAQ,KAAK;aAEhB,UAAU,EAAE,MAAM;aAElB,MAAM,CAAC,EAAE,MAAM,EAAE;gBAFjB,UAAU,EAAE,MAAM,EAClC,OAAO,EAAE,MAAM,EACC,MAAM,CAAC,EAAE,MAAM,EAAE,YAAA;CAKpC;AAED,qBAAa,eAAgB,SAAQ,SAAS;gBAChC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE;CAI/C;AAED,qBAAa,iBAAkB,SAAQ,SAAS;gBAClC,OAAO,GAAE,MAAuB;CAI7C;AAED,qBAAa,cAAe,SAAQ,SAAS;gBAC/B,OAAO,GAAE,MAAoB;CAI1C;AAED,qBAAa,aAAc,SAAQ,SAAS;gBAC9B,OAAO,GAAE,MAAoB;CAI1C;AAED,qBAAa,aAAc,SAAQ,SAAS;gBAC9B,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,mBAAoB,SAAQ,SAAS;gBACpC,OAAO,GAAE,MAAgC;CAItD;AAGD,eAAO,MAAM,aAAa,kBAAY,CAAC;AACvC,eAAO,MAAM,mBAAmB,wBAAkB,CAAC;AACnD,eAAO,MAAM,qBAAqB,0BAAoB,CAAC;AACvD,eAAO,MAAM,kBAAkB,uBAAiB,CAAC;AACjD,eAAO,MAAM,iBAAiB,sBAAgB,CAAC;AAC/C,eAAO,MAAM,iBAAiB,sBAAgB,CAAC;AAC/C,eAAO,MAAM,4BAA4B,4BAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"http.error.d.ts","sourceRoot":"","sources":["../../src/errors/http.error.ts"],"names":[],"mappings":"AAAA,qBAAa,SAAU,SAAQ,KAAK;aAEhB,UAAU,EAAE,MAAM;aAElB,MAAM,CAAC,EAAE,MAAM,EAAE;gBAFjB,UAAU,EAAE,MAAM,EAClC,OAAO,EAAE,MAAM,EACC,MAAM,CAAC,EAAE,MAAM,EAAE,YAAA;CAKpC;AAED,qBAAa,eAAgB,SAAQ,SAAS;gBAChC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE;CAI/C;AAED,qBAAa,iBAAkB,SAAQ,SAAS;gBAClC,OAAO,GAAE,MAAuB;CAI7C;AAED,qBAAa,cAAe,SAAQ,SAAS;gBAC/B,OAAO,GAAE,MAAoB;CAI1C;AAED,qBAAa,aAAc,SAAQ,SAAS;gBAC9B,OAAO,GAAE,MAAoB;CAI1C;AAED,qBAAa,aAAc,SAAQ,SAAS;gBAC9B,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,mBAAoB,SAAQ,SAAS;gBACpC,OAAO,GAAE,MAA0B;CAIhD;AAED,qBAAa,mBAAoB,SAAQ,SAAS;gBACpC,OAAO,GAAE,MAAgC;CAItD;AAGD,eAAO,MAAM,aAAa,kBAAY,CAAC;AACvC,eAAO,MAAM,mBAAmB,wBAAkB,CAAC;AACnD,eAAO,MAAM,qBAAqB,0BAAoB,CAAC;AACvD,eAAO,MAAM,kBAAkB,uBAAiB,CAAC;AACjD,eAAO,MAAM,iBAAiB,sBAAgB,CAAC;AAC/C,eAAO,MAAM,iBAAiB,sBAAgB,CAAC;AAC/C,eAAO,MAAM,4BAA4B,4BAAsB,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.InternalServerErrorException = exports.ConflictException = exports.NotFoundException = exports.ForbiddenException = exports.UnauthorizedException = exports.BadRequestException = exports.HttpException = exports.InternalServerError = exports.ConflictError = exports.NotFoundError = exports.ForbiddenError = exports.UnauthorizedError = exports.BadRequestError = exports.HttpError = void 0;
|
|
3
|
+
exports.InternalServerErrorException = exports.ConflictException = exports.NotFoundException = exports.ForbiddenException = exports.UnauthorizedException = exports.BadRequestException = exports.HttpException = exports.InternalServerError = exports.RequestTimeoutError = exports.ConflictError = exports.NotFoundError = exports.ForbiddenError = exports.UnauthorizedError = exports.BadRequestError = exports.HttpError = void 0;
|
|
4
4
|
class HttpError extends Error {
|
|
5
5
|
constructor(statusCode, message, errors) {
|
|
6
6
|
super(message);
|
|
@@ -45,6 +45,13 @@ class ConflictError extends HttpError {
|
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
exports.ConflictError = ConflictError;
|
|
48
|
+
class RequestTimeoutError extends HttpError {
|
|
49
|
+
constructor(message = 'Request Timeout') {
|
|
50
|
+
super(408, message);
|
|
51
|
+
this.name = 'RequestTimeoutError';
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
exports.RequestTimeoutError = RequestTimeoutError;
|
|
48
55
|
class InternalServerError extends HttpError {
|
|
49
56
|
constructor(message = 'Internal Server Error') {
|
|
50
57
|
super(500, message);
|
package/dist/index.d.ts
CHANGED
|
@@ -12,13 +12,13 @@ export { HealthCheckManager, BuiltInHealthChecks } from './health';
|
|
|
12
12
|
export type { HealthCheck, HealthCheckResult, HealthStatus } from './health';
|
|
13
13
|
export { TimeoutMiddleware } from './middleware/timeout.middleware';
|
|
14
14
|
export type { TimeoutOptions } from './middleware/timeout.middleware';
|
|
15
|
-
export { Controller, Injectable, Service, Get, Post, Put, Delete, Patch, Body, Param, Query, Req, Res, Headers, HttpCode, Header, Redirect, Inject, UsePipes, UseInterceptors, UseGuards, type ControllerMetadata, type RouteMetadata, type ControllerOptions, type RouteOptions, type ServiceOptions, type InjectableOptions, type RepositoryOptions, type OnModuleInit, type OnModuleDestroy, type ExecutionContext, type CanActivate, } from './decorators';
|
|
15
|
+
export { Controller, Injectable, Service, Get, Post, Put, Delete, Patch, Body, Param, Query, Req, Res, Ip, Host, Headers, HttpCode, Header, Redirect, Inject, UsePipes, UseInterceptors, UseGuards, Public, SkipAuth, AITask, Timeout, Optional, Session, Retry, ApiTags, ApiOperation, SetMetadata, getMetadata, createParamDecorator, CUSTOM_METADATA_PREFIX, type ControllerMetadata, type RouteMetadata, type ControllerOptions, type RouteOptions, type ServiceOptions, type InjectableOptions, type RepositoryOptions, type OnModuleInit, type OnModuleDestroy, type ExecutionContext, type CanActivate, type RetryDecoratorOptions, type ApiOperationOptions, type ParamDecoratorContext, } from './decorators';
|
|
16
16
|
export { Container, Scope, type InjectionToken, type Provider } from './container';
|
|
17
17
|
export type { Type, Request, Response, RequestContext, ValidationSchema } from './types';
|
|
18
|
-
export { HttpError, BadRequestError, UnauthorizedError, ForbiddenError, NotFoundError, ConflictError, InternalServerError, HttpException, BadRequestException, UnauthorizedException, ForbiddenException, NotFoundException, ConflictException, InternalServerErrorException, } from './errors/http.error';
|
|
18
|
+
export { HttpError, BadRequestError, UnauthorizedError, ForbiddenError, NotFoundError, ConflictError, InternalServerError, HttpException, BadRequestException, UnauthorizedException, ForbiddenException, NotFoundException, ConflictException, InternalServerErrorException, RequestTimeoutError, } from './errors/http.error';
|
|
19
19
|
export { PipeTransform, ValidationError, ParseIntPipe, type PipeMetadata } from './pipes/pipe';
|
|
20
20
|
export { ValidationPipe } from './pipes/validation.pipe';
|
|
21
|
-
export { Interceptor, type InterceptorMetadata } from './interceptors/interceptor';
|
|
21
|
+
export { Interceptor, RetryInterceptor, type InterceptorMetadata, type RetryOptions, } from './interceptors/interceptor';
|
|
22
22
|
export { type ExceptionFilter, type ArgumentsHost, ArgumentsHostImpl, Catch, getFilterExceptions, } from './filters/exception-filter';
|
|
23
23
|
export { HttpExceptionFilter } from './filters/http-exception.filter';
|
|
24
24
|
export { Test, TestingModule, TestingModuleBuilder, type TestingModuleMetadata, } from './testing/testing.module';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,kBAAkB,CAAC;AAG1B,OAAO,EAAE,QAAQ,EAAE,KAAK,gBAAgB,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC7F,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAGnE,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,YAAY,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACnE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAG7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,YAAY,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAGtE,OAAO,EACL,UAAU,EACV,UAAU,EACV,OAAO,EACP,GAAG,EACH,IAAI,EACJ,GAAG,EACH,MAAM,EACN,KAAK,EACL,IAAI,EACJ,KAAK,EACL,KAAK,EACL,GAAG,EACH,GAAG,EACH,OAAO,EACP,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,eAAe,EACf,SAAS,EACT,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,WAAW,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -7,8 +7,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
7
7
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
8
|
};
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.
|
|
11
|
-
exports.escapeHtml = exports.sanitizeObject = exports.sanitizeSql = exports.sanitizeEmail = exports.sanitizeUrl = exports.sanitizeString = exports.sanitizeHtml = exports.RequestParser = exports.Router = exports.Validator = exports.default = exports.logger = exports.UploadedFiles = exports.UploadedFile = exports.FileUploadInterceptor = exports.CsrfMiddleware = exports.RateLimitMiddleware = exports.SecurityHeadersMiddleware = exports.LoggerMiddleware = exports.CorsMiddleware = exports.GlobalMiddlewareManager = exports.extractVersion = exports.matchVersion = exports.getVersionMetadata = exports.VersioningType = exports.Version = exports.RouteMatcher = exports.TestingModuleBuilder = exports.TestingModule = exports.Test = exports.HttpExceptionFilter = exports.getFilterExceptions = exports.Catch = void 0;
|
|
10
|
+
exports.UnauthorizedError = exports.BadRequestError = exports.HttpError = exports.Scope = exports.Container = exports.CUSTOM_METADATA_PREFIX = exports.createParamDecorator = exports.getMetadata = exports.SetMetadata = exports.ApiOperation = exports.ApiTags = exports.Retry = exports.Session = exports.Optional = exports.Timeout = exports.AITask = exports.SkipAuth = exports.Public = exports.UseGuards = exports.UseInterceptors = exports.UsePipes = exports.Inject = exports.Redirect = exports.Header = exports.HttpCode = exports.Headers = exports.Host = exports.Ip = exports.Res = exports.Req = exports.Query = exports.Param = exports.Body = exports.Patch = exports.Delete = exports.Put = exports.Post = exports.Get = exports.Service = exports.Injectable = exports.Controller = exports.TimeoutMiddleware = exports.BuiltInHealthChecks = exports.HealthCheckManager = exports.ShutdownManager = exports.getModuleMetadata = exports.HazelModuleInstance = exports.Module = exports.HazelModule = exports.HazelApp = void 0;
|
|
11
|
+
exports.escapeHtml = exports.sanitizeObject = exports.sanitizeSql = exports.sanitizeEmail = exports.sanitizeUrl = exports.sanitizeString = exports.sanitizeHtml = exports.RequestParser = exports.Router = exports.Validator = exports.default = exports.logger = exports.UploadedFiles = exports.UploadedFile = exports.FileUploadInterceptor = exports.CsrfMiddleware = exports.RateLimitMiddleware = exports.SecurityHeadersMiddleware = exports.LoggerMiddleware = exports.CorsMiddleware = exports.GlobalMiddlewareManager = exports.extractVersion = exports.matchVersion = exports.getVersionMetadata = exports.VersioningType = exports.Version = exports.RouteMatcher = exports.TestingModuleBuilder = exports.TestingModule = exports.Test = exports.HttpExceptionFilter = exports.getFilterExceptions = exports.Catch = exports.ArgumentsHostImpl = exports.RetryInterceptor = exports.ValidationPipe = exports.ParseIntPipe = exports.ValidationError = exports.RequestTimeoutError = exports.InternalServerErrorException = exports.ConflictException = exports.NotFoundException = exports.ForbiddenException = exports.UnauthorizedException = exports.BadRequestException = exports.HttpException = exports.InternalServerError = exports.ConflictError = exports.NotFoundError = exports.ForbiddenError = void 0;
|
|
12
12
|
// Import reflect-metadata to enable decorator metadata
|
|
13
13
|
// Users don't need to import this manually
|
|
14
14
|
require("reflect-metadata");
|
|
@@ -44,6 +44,8 @@ Object.defineProperty(exports, "Param", { enumerable: true, get: function () { r
|
|
|
44
44
|
Object.defineProperty(exports, "Query", { enumerable: true, get: function () { return decorators_1.Query; } });
|
|
45
45
|
Object.defineProperty(exports, "Req", { enumerable: true, get: function () { return decorators_1.Req; } });
|
|
46
46
|
Object.defineProperty(exports, "Res", { enumerable: true, get: function () { return decorators_1.Res; } });
|
|
47
|
+
Object.defineProperty(exports, "Ip", { enumerable: true, get: function () { return decorators_1.Ip; } });
|
|
48
|
+
Object.defineProperty(exports, "Host", { enumerable: true, get: function () { return decorators_1.Host; } });
|
|
47
49
|
Object.defineProperty(exports, "Headers", { enumerable: true, get: function () { return decorators_1.Headers; } });
|
|
48
50
|
Object.defineProperty(exports, "HttpCode", { enumerable: true, get: function () { return decorators_1.HttpCode; } });
|
|
49
51
|
Object.defineProperty(exports, "Header", { enumerable: true, get: function () { return decorators_1.Header; } });
|
|
@@ -52,6 +54,19 @@ Object.defineProperty(exports, "Inject", { enumerable: true, get: function () {
|
|
|
52
54
|
Object.defineProperty(exports, "UsePipes", { enumerable: true, get: function () { return decorators_1.UsePipes; } });
|
|
53
55
|
Object.defineProperty(exports, "UseInterceptors", { enumerable: true, get: function () { return decorators_1.UseInterceptors; } });
|
|
54
56
|
Object.defineProperty(exports, "UseGuards", { enumerable: true, get: function () { return decorators_1.UseGuards; } });
|
|
57
|
+
Object.defineProperty(exports, "Public", { enumerable: true, get: function () { return decorators_1.Public; } });
|
|
58
|
+
Object.defineProperty(exports, "SkipAuth", { enumerable: true, get: function () { return decorators_1.SkipAuth; } });
|
|
59
|
+
Object.defineProperty(exports, "AITask", { enumerable: true, get: function () { return decorators_1.AITask; } });
|
|
60
|
+
Object.defineProperty(exports, "Timeout", { enumerable: true, get: function () { return decorators_1.Timeout; } });
|
|
61
|
+
Object.defineProperty(exports, "Optional", { enumerable: true, get: function () { return decorators_1.Optional; } });
|
|
62
|
+
Object.defineProperty(exports, "Session", { enumerable: true, get: function () { return decorators_1.Session; } });
|
|
63
|
+
Object.defineProperty(exports, "Retry", { enumerable: true, get: function () { return decorators_1.Retry; } });
|
|
64
|
+
Object.defineProperty(exports, "ApiTags", { enumerable: true, get: function () { return decorators_1.ApiTags; } });
|
|
65
|
+
Object.defineProperty(exports, "ApiOperation", { enumerable: true, get: function () { return decorators_1.ApiOperation; } });
|
|
66
|
+
Object.defineProperty(exports, "SetMetadata", { enumerable: true, get: function () { return decorators_1.SetMetadata; } });
|
|
67
|
+
Object.defineProperty(exports, "getMetadata", { enumerable: true, get: function () { return decorators_1.getMetadata; } });
|
|
68
|
+
Object.defineProperty(exports, "createParamDecorator", { enumerable: true, get: function () { return decorators_1.createParamDecorator; } });
|
|
69
|
+
Object.defineProperty(exports, "CUSTOM_METADATA_PREFIX", { enumerable: true, get: function () { return decorators_1.CUSTOM_METADATA_PREFIX; } });
|
|
55
70
|
// Container & DI
|
|
56
71
|
var container_1 = require("./container");
|
|
57
72
|
Object.defineProperty(exports, "Container", { enumerable: true, get: function () { return container_1.Container; } });
|
|
@@ -72,12 +87,16 @@ Object.defineProperty(exports, "ForbiddenException", { enumerable: true, get: fu
|
|
|
72
87
|
Object.defineProperty(exports, "NotFoundException", { enumerable: true, get: function () { return http_error_1.NotFoundException; } });
|
|
73
88
|
Object.defineProperty(exports, "ConflictException", { enumerable: true, get: function () { return http_error_1.ConflictException; } });
|
|
74
89
|
Object.defineProperty(exports, "InternalServerErrorException", { enumerable: true, get: function () { return http_error_1.InternalServerErrorException; } });
|
|
90
|
+
Object.defineProperty(exports, "RequestTimeoutError", { enumerable: true, get: function () { return http_error_1.RequestTimeoutError; } });
|
|
75
91
|
// Pipes
|
|
76
92
|
var pipe_1 = require("./pipes/pipe");
|
|
77
93
|
Object.defineProperty(exports, "ValidationError", { enumerable: true, get: function () { return pipe_1.ValidationError; } });
|
|
78
94
|
Object.defineProperty(exports, "ParseIntPipe", { enumerable: true, get: function () { return pipe_1.ParseIntPipe; } });
|
|
79
95
|
var validation_pipe_1 = require("./pipes/validation.pipe");
|
|
80
96
|
Object.defineProperty(exports, "ValidationPipe", { enumerable: true, get: function () { return validation_pipe_1.ValidationPipe; } });
|
|
97
|
+
// Interceptors
|
|
98
|
+
var interceptor_1 = require("./interceptors/interceptor");
|
|
99
|
+
Object.defineProperty(exports, "RetryInterceptor", { enumerable: true, get: function () { return interceptor_1.RetryInterceptor; } });
|
|
81
100
|
// Filters
|
|
82
101
|
var exception_filter_1 = require("./filters/exception-filter");
|
|
83
102
|
Object.defineProperty(exports, "ArgumentsHostImpl", { enumerable: true, get: function () { return exception_filter_1.ArgumentsHostImpl; } });
|
|
@@ -18,5 +18,13 @@ export declare class CacheInterceptor implements Interceptor {
|
|
|
18
18
|
constructor(options?: CacheOptions);
|
|
19
19
|
intercept(context: RequestContext, next: () => Promise<unknown>): Promise<unknown>;
|
|
20
20
|
}
|
|
21
|
+
export interface RetryOptions {
|
|
22
|
+
count: number;
|
|
23
|
+
delay?: number;
|
|
24
|
+
retryIf?: (err: Error) => boolean;
|
|
25
|
+
}
|
|
26
|
+
export declare class RetryInterceptor implements Interceptor {
|
|
27
|
+
intercept(context: RequestContext, next: () => Promise<unknown>): Promise<unknown>;
|
|
28
|
+
}
|
|
21
29
|
export type Type<T = unknown> = new (...args: unknown[]) => T;
|
|
22
30
|
//# sourceMappingURL=interceptor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interceptor.d.ts","sourceRoot":"","sources":["../../src/interceptors/interceptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGpD,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACpF;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,qBAAa,kBAAmB,YAAW,WAAW;IAC9C,SAAS,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;CAgBzF;AAED,qBAAa,gBAAiB,YAAW,WAAW;IAClD,OAAO,CAAC,MAAM,CAAC,KAAK,CAA2D;IAC/E,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;gBAEjB,OAAO,CAAC,EAAE,YAAY;IAI5B,SAAS,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;CAgBzF;AAED,MAAM,MAAM,IAAI,CAAC,CAAC,GAAG,OAAO,IAAI,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"interceptor.d.ts","sourceRoot":"","sources":["../../src/interceptors/interceptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGpD,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACpF;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,qBAAa,kBAAmB,YAAW,WAAW;IAC9C,SAAS,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;CAgBzF;AAED,qBAAa,gBAAiB,YAAW,WAAW;IAClD,OAAO,CAAC,MAAM,CAAC,KAAK,CAA2D;IAC/E,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;gBAEjB,OAAO,CAAC,EAAE,YAAY;IAI5B,SAAS,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;CAgBzF;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,OAAO,CAAC;CACnC;AAED,qBAAa,gBAAiB,YAAW,WAAW;IAC5C,SAAS,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;CAqBzF;AAED,MAAM,MAAM,IAAI,CAAC,CAAC,GAAG,OAAO,IAAI,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC"}
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.CacheInterceptor = exports.LoggingInterceptor = void 0;
|
|
6
|
+
exports.RetryInterceptor = exports.CacheInterceptor = exports.LoggingInterceptor = void 0;
|
|
7
7
|
const logger_1 = __importDefault(require("../logger"));
|
|
8
8
|
class LoggingInterceptor {
|
|
9
9
|
async intercept(context, next) {
|
|
@@ -44,3 +44,28 @@ class CacheInterceptor {
|
|
|
44
44
|
}
|
|
45
45
|
exports.CacheInterceptor = CacheInterceptor;
|
|
46
46
|
CacheInterceptor.cache = new Map();
|
|
47
|
+
class RetryInterceptor {
|
|
48
|
+
async intercept(context, next) {
|
|
49
|
+
const opts = context.retryOptions;
|
|
50
|
+
if (!opts || opts.count < 1) {
|
|
51
|
+
return next();
|
|
52
|
+
}
|
|
53
|
+
const delayMs = opts.delay ?? 100;
|
|
54
|
+
const shouldRetry = opts.retryIf ?? (() => true);
|
|
55
|
+
let lastError;
|
|
56
|
+
for (let attempt = 0; attempt <= opts.count; attempt++) {
|
|
57
|
+
try {
|
|
58
|
+
return await next();
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
lastError = err instanceof Error ? err : new Error(String(err));
|
|
62
|
+
if (attempt === opts.count || !shouldRetry(lastError)) {
|
|
63
|
+
throw lastError;
|
|
64
|
+
}
|
|
65
|
+
await new Promise((r) => setTimeout(r, delayMs));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
throw lastError;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
exports.RetryInterceptor = RetryInterceptor;
|
package/dist/logger.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAK9B,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAwQvD,eAAO,MAAM,aAAa,GACxB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,MAAM,MAAM,IAAI,KACf,
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAK9B,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAwQvD,eAAO,MAAM,aAAa,GACxB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,MAAM,MAAM,IAAI,KACf,IAyBF,CAAC;AAQF,QAAA,MAAM,cAAc;0BALO,OAAO;CAOhC,CAAC;AAGH,eAAe,cAAc,CAAC"}
|
package/dist/logger.js
CHANGED
|
@@ -226,6 +226,9 @@ logger.info(chalk_1.default.cyan.bold('Application started'), appInfo);
|
|
|
226
226
|
const requestLogger = (req, res, next) => {
|
|
227
227
|
const start = Date.now();
|
|
228
228
|
res.on('finish', () => {
|
|
229
|
+
const pathname = (req.url ?? '').split('?')[0];
|
|
230
|
+
if (pathname === '/favicon.ico')
|
|
231
|
+
return;
|
|
229
232
|
const duration = Date.now() - start;
|
|
230
233
|
const statusColor = res.statusCode >= 500
|
|
231
234
|
? chalk_1.default.red
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request-context.d.ts","sourceRoot":"","sources":["../src/request-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE/B,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACxB,IAAI,CAAC,EAAE;QACL,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;
|
|
1
|
+
{"version":3,"file":"request-context.d.ts","sourceRoot":"","sources":["../src/request-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE/B,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACxB,IAAI,CAAC,EAAE;QACL,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,YAAY,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,OAAO,CAAA;KAAE,CAAC;CACrF"}
|
package/dist/router.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAMxC,OAAO,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAMxC,OAAO,kBAAkB,CAAC;AAc1B,UAAU,UAAU;IAClB,OAAO,EAAE,YAAY,CAAC;IACtB,OAAO,EAAE,cAAc,CAAC;CACzB;AAED,KAAK,YAAY,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,cAAc,KAAK,IAAI,CAAC;AAEpF,qBAAa,MAAM;IAKL,OAAO,CAAC,SAAS;IAJ7B,OAAO,CAAC,MAAM,CAA0C;IACxD,OAAO,CAAC,cAAc,CAAuD;IAC7E,OAAO,CAAC,iBAAiB,CAAoB;gBAEzB,SAAS,EAAE,SAAS;IAUxC,kBAAkB,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI;YA4DrC,UAAU;YAsBV,iBAAiB;IAe/B,OAAO,CAAC,kBAAkB;IAgT1B,OAAO,CAAC,aAAa;IAiBrB,OAAO,CAAC,SAAS;IAiBjB,OAAO,CAAC,kBAAkB;IAW1B,OAAO,CAAC,aAAa;IAOf,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IA0C7F,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,IAAI;IAIjD,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,IAAI;IAIlD,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,IAAI;IAIjD,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,IAAI;IAIpD,OAAO,CAAC,QAAQ;IAKV,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAkChE"}
|
package/dist/router.js
CHANGED
|
@@ -17,6 +17,8 @@ const CONTROLLER_METADATA_KEY = 'hazel:controller';
|
|
|
17
17
|
const HTTP_CODE_METADATA_KEY = 'hazel:http-code';
|
|
18
18
|
const HEADER_METADATA_KEY = 'hazel:headers';
|
|
19
19
|
const REDIRECT_METADATA_KEY = 'hazel:redirect';
|
|
20
|
+
const TIMEOUT_METADATA_KEY = 'hazel:timeout';
|
|
21
|
+
const OPTIONAL_INDICES_METADATA_KEY = 'hazel:optional-indices';
|
|
20
22
|
class Router {
|
|
21
23
|
constructor(container) {
|
|
22
24
|
this.container = container;
|
|
@@ -133,6 +135,7 @@ class Router {
|
|
|
133
135
|
method: req.method || 'GET',
|
|
134
136
|
url: req.url || '/',
|
|
135
137
|
};
|
|
138
|
+
context.retryOptions = Reflect.getMetadata('hazel:retry', controllerClass.prototype, methodName);
|
|
136
139
|
// Execute guards (class-level + method-level)
|
|
137
140
|
const classGuards = Reflect.getMetadata('hazel:guards', controllerClass) || [];
|
|
138
141
|
const methodGuards = Reflect.getMetadata('hazel:guards', controllerClass.prototype, methodName) || [];
|
|
@@ -241,6 +244,23 @@ class Router {
|
|
|
241
244
|
const user = context.user ?? req.user;
|
|
242
245
|
args[i] = injection.field ? user?.[injection.field] : user;
|
|
243
246
|
}
|
|
247
|
+
else if (injection.type === 'ip') {
|
|
248
|
+
const r = req;
|
|
249
|
+
const forwarded = r.headers?.['x-forwarded-for'];
|
|
250
|
+
const ip = typeof forwarded === 'string'
|
|
251
|
+
? forwarded.split(',')[0].trim()
|
|
252
|
+
: Array.isArray(forwarded)
|
|
253
|
+
? forwarded[0]?.trim()
|
|
254
|
+
: r.socket?.remoteAddress;
|
|
255
|
+
args[i] = ip ?? undefined;
|
|
256
|
+
}
|
|
257
|
+
else if (injection.type === 'host') {
|
|
258
|
+
const host = req.headers?.['host'];
|
|
259
|
+
args[i] = typeof host === 'string' ? host : Array.isArray(host) ? host[0] : undefined;
|
|
260
|
+
}
|
|
261
|
+
else if (injection.type === 'session') {
|
|
262
|
+
args[i] = req.session;
|
|
263
|
+
}
|
|
244
264
|
else if (injection.type === 'custom' && typeof injection.resolve === 'function') {
|
|
245
265
|
// Handle custom parameter decorators (e.g. @Ability() from @hazeljs/casl).
|
|
246
266
|
// The decorator stores a resolver function; call it with request, context, container.
|
|
@@ -248,6 +268,12 @@ class Router {
|
|
|
248
268
|
}
|
|
249
269
|
}
|
|
250
270
|
}
|
|
271
|
+
const optionalIndices = Reflect.getMetadata(OPTIONAL_INDICES_METADATA_KEY, controllerClass, methodName) || [];
|
|
272
|
+
for (const i of optionalIndices) {
|
|
273
|
+
if (i < args.length && (args[i] === undefined || args[i] === null)) {
|
|
274
|
+
args[i] = undefined;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
251
277
|
// Auto-inject RequestContext for undecorated parameters
|
|
252
278
|
const paramTypes = Reflect.getMetadata('design:paramtypes', controllerClass.prototype, methodName) || [];
|
|
253
279
|
for (let i = 0; i < paramTypes.length; i++) {
|
|
@@ -268,10 +294,19 @@ class Router {
|
|
|
268
294
|
}
|
|
269
295
|
// Get the controller method
|
|
270
296
|
const method = controller[methodName];
|
|
271
|
-
|
|
272
|
-
|
|
297
|
+
const timeoutMs = Reflect.getMetadata(TIMEOUT_METADATA_KEY, controllerClass.prototype, methodName);
|
|
298
|
+
let handlerPromise = this.applyInterceptors(Reflect.getMetadata('hazel:interceptors', controllerClass, methodName) || [], context, async () => {
|
|
273
299
|
return method.apply(controller, args);
|
|
274
300
|
});
|
|
301
|
+
if (timeoutMs != null && timeoutMs > 0) {
|
|
302
|
+
handlerPromise = Promise.race([
|
|
303
|
+
handlerPromise,
|
|
304
|
+
new Promise((_, reject) => {
|
|
305
|
+
setTimeout(() => reject(new http_error_1.RequestTimeoutError(`Request timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
306
|
+
}),
|
|
307
|
+
]);
|
|
308
|
+
}
|
|
309
|
+
const result = await handlerPromise;
|
|
275
310
|
// Apply @Redirect metadata
|
|
276
311
|
const redirectMeta = Reflect.getMetadata(REDIRECT_METADATA_KEY, controllerClass.prototype, methodName);
|
|
277
312
|
if (redirectMeta) {
|
package/dist/types.d.ts
CHANGED
|
@@ -56,6 +56,12 @@ export interface RequestContext {
|
|
|
56
56
|
[key: string]: unknown;
|
|
57
57
|
};
|
|
58
58
|
req?: Request;
|
|
59
|
+
/** Set by router from @Retry() metadata; consumed by RetryInterceptor */
|
|
60
|
+
retryOptions?: {
|
|
61
|
+
count: number;
|
|
62
|
+
delay?: number;
|
|
63
|
+
retryIf?: (err: Error) => boolean;
|
|
64
|
+
};
|
|
59
65
|
}
|
|
60
66
|
export interface ValidationRule {
|
|
61
67
|
type: 'string' | 'number' | 'boolean' | 'object' | 'array';
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hazeljs/core",
|
|
3
|
-
"version": "0.2.0-beta.
|
|
3
|
+
"version": "0.2.0-beta.73",
|
|
4
4
|
"description": "Core HazelJS framework - Dependency injection, routing, decorators, and base functionality",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -63,5 +63,5 @@
|
|
|
63
63
|
"url": "https://github.com/hazeljs/hazel-js/issues"
|
|
64
64
|
},
|
|
65
65
|
"homepage": "https://hazeljs.com",
|
|
66
|
-
"gitHead": "
|
|
66
|
+
"gitHead": "24092246c221bc5b4437be1a8661cd07c3445cdf"
|
|
67
67
|
}
|