@nattyjs/core 0.0.1-beta.64 → 0.0.1-beta.66
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/index.cjs +343 -73
- package/dist/index.d.ts +49 -22
- package/dist/index.mjs +337 -75
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -2,8 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
const common = require('@nattyjs/common');
|
|
4
4
|
const pathToRegexp = require('path-to-regexp');
|
|
5
|
+
const path = require('node:path');
|
|
5
6
|
require('reflect-metadata');
|
|
6
7
|
|
|
8
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
9
|
+
|
|
10
|
+
const path__default = /*#__PURE__*/_interopDefaultCompat(path);
|
|
11
|
+
|
|
7
12
|
function defineNattyConfig(config) {
|
|
8
13
|
return config;
|
|
9
14
|
}
|
|
@@ -54,6 +59,7 @@ function Delete() {
|
|
|
54
59
|
};
|
|
55
60
|
}
|
|
56
61
|
|
|
62
|
+
const HTTP_METHODS = ["get", "post", "put", "delete"];
|
|
57
63
|
const _StaticContainer = class {
|
|
58
64
|
setup(types) {
|
|
59
65
|
_StaticContainer.types = types;
|
|
@@ -65,14 +71,56 @@ const nattyContainer = new class {
|
|
|
65
71
|
constructor() {
|
|
66
72
|
this.container = /* @__PURE__ */ new Map();
|
|
67
73
|
this.containerState = /* @__PURE__ */ new Map();
|
|
74
|
+
this.compiledRoutes = {};
|
|
68
75
|
}
|
|
69
76
|
get types() {
|
|
70
77
|
return common.commonContainer.types;
|
|
71
78
|
}
|
|
72
79
|
setup(config, routes, resolver) {
|
|
73
80
|
this.config = config;
|
|
74
|
-
this.routes = routes;
|
|
75
81
|
this.resolver = resolver;
|
|
82
|
+
this.applyRouteSnapshot(routes);
|
|
83
|
+
}
|
|
84
|
+
replaceRoutes(manifest) {
|
|
85
|
+
if (manifest.resolver)
|
|
86
|
+
this.resolver = manifest.resolver;
|
|
87
|
+
this.applyRouteSnapshot(manifest.routes);
|
|
88
|
+
}
|
|
89
|
+
applyRouteSnapshot(routes) {
|
|
90
|
+
this.routes = routes;
|
|
91
|
+
this.compiledRoutes = this.createCompiledRoutes(routes);
|
|
92
|
+
}
|
|
93
|
+
createCompiledRoutes(routes) {
|
|
94
|
+
const compiledRoutes = {};
|
|
95
|
+
for (const method of HTTP_METHODS)
|
|
96
|
+
compiledRoutes[method] = [];
|
|
97
|
+
for (const [rootPath, routeConfig] of Object.entries(routes)) {
|
|
98
|
+
for (const method of HTTP_METHODS) {
|
|
99
|
+
const childRoutes = routeConfig[method];
|
|
100
|
+
if (!childRoutes)
|
|
101
|
+
continue;
|
|
102
|
+
for (const [childRoutePath, routeInfo] of Object.entries(childRoutes)) {
|
|
103
|
+
const childPath = this.normalizeChildPath(childRoutePath);
|
|
104
|
+
const configuredRoutePath = `${rootPath}${childPath}`;
|
|
105
|
+
compiledRoutes[method].push({
|
|
106
|
+
requestMethod: method,
|
|
107
|
+
configuredRoutePath,
|
|
108
|
+
matcher: pathToRegexp.match(configuredRoutePath, { decode: decodeURIComponent }),
|
|
109
|
+
routeConfig,
|
|
110
|
+
methodInfo: routeInfo
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return compiledRoutes;
|
|
116
|
+
}
|
|
117
|
+
normalizeChildPath(childRoutePath) {
|
|
118
|
+
if (childRoutePath.indexOf("/") === 0)
|
|
119
|
+
return childRoutePath === "/" ? BLANK : childRoutePath;
|
|
120
|
+
return `/${childRoutePath}`;
|
|
121
|
+
}
|
|
122
|
+
getCompiledRoutes(method) {
|
|
123
|
+
return this.compiledRoutes[method] || [];
|
|
76
124
|
}
|
|
77
125
|
getTypes() {
|
|
78
126
|
return StaticContainer.types;
|
|
@@ -163,8 +211,10 @@ function setupLegacyTypes(types) {
|
|
|
163
211
|
function defaultResolver(path) {
|
|
164
212
|
if (typeof path === "function")
|
|
165
213
|
return path();
|
|
166
|
-
if (typeof path === "string")
|
|
167
|
-
|
|
214
|
+
if (typeof path === "string") {
|
|
215
|
+
const normalizedPath = path.startsWith("/") ? `.${path}` : path;
|
|
216
|
+
return require(normalizedPath);
|
|
217
|
+
}
|
|
168
218
|
return {};
|
|
169
219
|
}
|
|
170
220
|
function initializeModule(config) {
|
|
@@ -514,6 +564,15 @@ class BaseResponse {
|
|
|
514
564
|
notFound() {
|
|
515
565
|
throw new HttpNotFoundException({});
|
|
516
566
|
}
|
|
567
|
+
normalizeHttpResponse(result) {
|
|
568
|
+
if (result instanceof HttpResponse)
|
|
569
|
+
return result;
|
|
570
|
+
if (result instanceof HttpException)
|
|
571
|
+
return result.getResponse();
|
|
572
|
+
if (result && typeof result === "object" && ("status" in result || "body" in result || "headers" in result || "cookies" in result || "isBuffer" in result))
|
|
573
|
+
return new HttpResponse(result);
|
|
574
|
+
return result;
|
|
575
|
+
}
|
|
517
576
|
}
|
|
518
577
|
|
|
519
578
|
function getTypedErrorMessage(type, value) {
|
|
@@ -848,8 +907,8 @@ class RouteParser extends ParameterTypeConverter {
|
|
|
848
907
|
get httpMethod() {
|
|
849
908
|
return this.httpContext.request.method.toLowerCase();
|
|
850
909
|
}
|
|
851
|
-
get
|
|
852
|
-
return nattyContainer.
|
|
910
|
+
get compiledRoutes() {
|
|
911
|
+
return nattyContainer.getCompiledRoutes(this.httpMethod);
|
|
853
912
|
}
|
|
854
913
|
init() {
|
|
855
914
|
const isMatched = this.matchRoute();
|
|
@@ -862,47 +921,46 @@ class RouteParser extends ParameterTypeConverter {
|
|
|
862
921
|
return controllerInfo[name];
|
|
863
922
|
}
|
|
864
923
|
matchRoute() {
|
|
865
|
-
|
|
866
|
-
const requestPathname = this.getRequestPathname();
|
|
867
|
-
for (const
|
|
868
|
-
const
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
this.routeInfo = {
|
|
881
|
-
path: `${common.commonContainer.nattyConfig.api.rootPath}/${requestPathname}`,
|
|
882
|
-
configuredRoutePath: `${common.commonContainer.nattyConfig.api.rootPath}/${configuredRoutePath}`,
|
|
883
|
-
controller: this.getController(routeConfig),
|
|
884
|
-
parameters: routeConfig.parameters,
|
|
885
|
-
methodInfo,
|
|
886
|
-
params: this.convert(methodInfo, matched.params),
|
|
887
|
-
queryParams: this.getQueryParams()
|
|
888
|
-
};
|
|
889
|
-
break;
|
|
890
|
-
}
|
|
891
|
-
}
|
|
924
|
+
const requestUrl = this.getRequestUrl();
|
|
925
|
+
const requestPathname = this.getRequestPathname(requestUrl);
|
|
926
|
+
for (const route of this.compiledRoutes) {
|
|
927
|
+
const matched = route.matcher(requestPathname);
|
|
928
|
+
if (matched) {
|
|
929
|
+
this.routeInfo = {
|
|
930
|
+
path: `${common.commonContainer.nattyConfig.api.rootPath}/${requestPathname}`,
|
|
931
|
+
configuredRoutePath: `${common.commonContainer.nattyConfig.api.rootPath}/${route.configuredRoutePath}`,
|
|
932
|
+
controller: this.getController(route.routeConfig),
|
|
933
|
+
parameters: route.routeConfig.parameters,
|
|
934
|
+
methodInfo: route.methodInfo,
|
|
935
|
+
params: this.convert(route.methodInfo, matched.params),
|
|
936
|
+
queryParams: this.getQueryParams(requestUrl)
|
|
937
|
+
};
|
|
938
|
+
return true;
|
|
892
939
|
}
|
|
893
940
|
}
|
|
894
|
-
return
|
|
895
|
-
}
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
941
|
+
return false;
|
|
942
|
+
}
|
|
943
|
+
getRequestUrl() {
|
|
944
|
+
if (!this.parsedRequestUrl)
|
|
945
|
+
this.parsedRequestUrl = new URL(this.httpContext.request.url);
|
|
946
|
+
return this.parsedRequestUrl;
|
|
947
|
+
}
|
|
948
|
+
getRequestPathname(url) {
|
|
949
|
+
const apiRootPath = String(common.commonContainer.nattyConfig.api.rootPath || "").replace(/^\/+|\/+$/g, "");
|
|
950
|
+
const normalizedPathname = url.pathname.replace(/^\/+/, "");
|
|
951
|
+
if (!apiRootPath) {
|
|
952
|
+
return normalizedPathname;
|
|
953
|
+
}
|
|
954
|
+
if (normalizedPathname === apiRootPath) {
|
|
955
|
+
return "";
|
|
956
|
+
}
|
|
957
|
+
const apiPrefix = `${apiRootPath}/`;
|
|
958
|
+
if (normalizedPathname.startsWith(apiPrefix)) {
|
|
959
|
+
return normalizedPathname.slice(apiPrefix.length);
|
|
960
|
+
}
|
|
961
|
+
return normalizedPathname;
|
|
962
|
+
}
|
|
963
|
+
getQueryParams(url) {
|
|
906
964
|
const queryParams = {};
|
|
907
965
|
for (const param of url.searchParams.keys())
|
|
908
966
|
queryParams[param] = url.searchParams.get(param);
|
|
@@ -913,8 +971,10 @@ class RouteParser extends ParameterTypeConverter {
|
|
|
913
971
|
const decoratorStateContainer = new class {
|
|
914
972
|
constructor() {
|
|
915
973
|
this.controllerConfig = {};
|
|
974
|
+
this.controllerSources = /* @__PURE__ */ new Map();
|
|
975
|
+
this.sourceControllers = /* @__PURE__ */ new Map();
|
|
916
976
|
}
|
|
917
|
-
register(params, type, additionalConfig) {
|
|
977
|
+
register(params, type, additionalConfig, sourceFile) {
|
|
918
978
|
const name = params.target.name || params.target.constructor.name;
|
|
919
979
|
let controllerInfo = this.controllerConfig[name] || null;
|
|
920
980
|
let controllerMethodInfo = null;
|
|
@@ -927,6 +987,9 @@ const decoratorStateContainer = new class {
|
|
|
927
987
|
controllerMethodInfo[type] = additionalConfig;
|
|
928
988
|
} else
|
|
929
989
|
controllerInfo.config[type] = additionalConfig;
|
|
990
|
+
if (sourceFile) {
|
|
991
|
+
this.trackControllerSource(name, sourceFile);
|
|
992
|
+
}
|
|
930
993
|
}
|
|
931
994
|
getInfo(controllerName, methodName, type) {
|
|
932
995
|
const controllerInfo = this.controllerConfig[controllerName];
|
|
@@ -939,6 +1002,55 @@ const decoratorStateContainer = new class {
|
|
|
939
1002
|
methodConfig = methodInfo[type];
|
|
940
1003
|
return { controllerConfig, methodConfig };
|
|
941
1004
|
}
|
|
1005
|
+
clearFromSource(sourceFile) {
|
|
1006
|
+
const normalizedSourceFile = this.normalizeFilePath(sourceFile);
|
|
1007
|
+
const controllerNames = Array.from(
|
|
1008
|
+
this.sourceControllers.get(normalizedSourceFile) || []
|
|
1009
|
+
);
|
|
1010
|
+
this.clearControllers(controllerNames);
|
|
1011
|
+
this.sourceControllers.delete(normalizedSourceFile);
|
|
1012
|
+
return controllerNames;
|
|
1013
|
+
}
|
|
1014
|
+
clearControllers(controllerNames) {
|
|
1015
|
+
const removedControllers = [];
|
|
1016
|
+
for (const controllerName of controllerNames) {
|
|
1017
|
+
const previousSource = this.controllerSources.get(controllerName);
|
|
1018
|
+
delete this.controllerConfig[controllerName];
|
|
1019
|
+
this.controllerSources.delete(controllerName);
|
|
1020
|
+
removedControllers.push(controllerName);
|
|
1021
|
+
if (previousSource) {
|
|
1022
|
+
const controllers = this.sourceControllers.get(previousSource);
|
|
1023
|
+
controllers?.delete(controllerName);
|
|
1024
|
+
if (controllers && controllers.size === 0) {
|
|
1025
|
+
this.sourceControllers.delete(previousSource);
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
return removedControllers;
|
|
1030
|
+
}
|
|
1031
|
+
reset() {
|
|
1032
|
+
this.controllerConfig = {};
|
|
1033
|
+
this.controllerSources.clear();
|
|
1034
|
+
this.sourceControllers.clear();
|
|
1035
|
+
}
|
|
1036
|
+
trackControllerSource(controllerName, sourceFile) {
|
|
1037
|
+
const normalizedSourceFile = this.normalizeFilePath(sourceFile);
|
|
1038
|
+
const previousSource = this.controllerSources.get(controllerName);
|
|
1039
|
+
if (previousSource && previousSource !== normalizedSourceFile) {
|
|
1040
|
+
this.sourceControllers.get(previousSource)?.delete(controllerName);
|
|
1041
|
+
if (this.sourceControllers.get(previousSource)?.size === 0) {
|
|
1042
|
+
this.sourceControllers.delete(previousSource);
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
this.controllerSources.set(controllerName, normalizedSourceFile);
|
|
1046
|
+
if (!this.sourceControllers.has(normalizedSourceFile)) {
|
|
1047
|
+
this.sourceControllers.set(normalizedSourceFile, /* @__PURE__ */ new Set());
|
|
1048
|
+
}
|
|
1049
|
+
this.sourceControllers.get(normalizedSourceFile)?.add(controllerName);
|
|
1050
|
+
}
|
|
1051
|
+
normalizeFilePath(filePath) {
|
|
1052
|
+
return path__default.resolve(filePath).replace(/\\/g, "/");
|
|
1053
|
+
}
|
|
942
1054
|
}();
|
|
943
1055
|
|
|
944
1056
|
var DecoratorType = /* @__PURE__ */ ((DecoratorType2) => {
|
|
@@ -1239,25 +1351,47 @@ class NattyScope {
|
|
|
1239
1351
|
}
|
|
1240
1352
|
}
|
|
1241
1353
|
|
|
1354
|
+
function normalizeFilePath$1(filePath) {
|
|
1355
|
+
return path__default.resolve(filePath).replace(/\\/g, "/");
|
|
1356
|
+
}
|
|
1242
1357
|
class NattyContainer {
|
|
1243
1358
|
constructor() {
|
|
1244
1359
|
this.regs = /* @__PURE__ */ new Map();
|
|
1245
1360
|
this.singletons = /* @__PURE__ */ new Map();
|
|
1361
|
+
this.tokenSources = /* @__PURE__ */ new Map();
|
|
1362
|
+
this.sourceTokens = /* @__PURE__ */ new Map();
|
|
1363
|
+
this.metadataKeySources = /* @__PURE__ */ new Map();
|
|
1364
|
+
this.sourceMetadataKeys = /* @__PURE__ */ new Map();
|
|
1246
1365
|
}
|
|
1247
|
-
register(token, desc) {
|
|
1366
|
+
register(token, desc, sourceFile) {
|
|
1248
1367
|
this.regs.set(token, desc);
|
|
1368
|
+
if (sourceFile) {
|
|
1369
|
+
this.trackTokenSource(token, sourceFile);
|
|
1370
|
+
}
|
|
1249
1371
|
}
|
|
1250
|
-
addTransient(token, useClass, useFactory) {
|
|
1251
|
-
this.register(
|
|
1372
|
+
addTransient(token, useClass, useFactory, sourceFile) {
|
|
1373
|
+
this.register(
|
|
1374
|
+
token,
|
|
1375
|
+
{ lifetime: Lifetime.Transient, useClass: useClass ?? token, useFactory },
|
|
1376
|
+
sourceFile
|
|
1377
|
+
);
|
|
1252
1378
|
}
|
|
1253
|
-
addScoped(token, useClass, useFactory) {
|
|
1254
|
-
this.register(
|
|
1379
|
+
addScoped(token, useClass, useFactory, sourceFile) {
|
|
1380
|
+
this.register(
|
|
1381
|
+
token,
|
|
1382
|
+
{ lifetime: Lifetime.Scoped, useClass: useClass ?? token, useFactory },
|
|
1383
|
+
sourceFile
|
|
1384
|
+
);
|
|
1255
1385
|
}
|
|
1256
|
-
addSingleton(token, useClass, useFactory) {
|
|
1257
|
-
this.register(
|
|
1386
|
+
addSingleton(token, useClass, useFactory, sourceFile) {
|
|
1387
|
+
this.register(
|
|
1388
|
+
token,
|
|
1389
|
+
{ lifetime: Lifetime.Singleton, useClass: useClass ?? token, useFactory },
|
|
1390
|
+
sourceFile
|
|
1391
|
+
);
|
|
1258
1392
|
}
|
|
1259
|
-
addInstance(token, value) {
|
|
1260
|
-
this.register(token, { lifetime: Lifetime.Singleton, useValue: value });
|
|
1393
|
+
addInstance(token, value, sourceFile) {
|
|
1394
|
+
this.register(token, { lifetime: Lifetime.Singleton, useValue: value }, sourceFile);
|
|
1261
1395
|
this.singletons.set(token, value);
|
|
1262
1396
|
}
|
|
1263
1397
|
createScope() {
|
|
@@ -1302,6 +1436,57 @@ class NattyContainer {
|
|
|
1302
1436
|
_getDescriptor(token) {
|
|
1303
1437
|
return this.regs.get(token);
|
|
1304
1438
|
}
|
|
1439
|
+
trackMetadataKey(sourceFile, key) {
|
|
1440
|
+
const normalizedSourceFile = normalizeFilePath$1(sourceFile);
|
|
1441
|
+
const previousSource = this.metadataKeySources.get(key);
|
|
1442
|
+
if (previousSource && previousSource !== normalizedSourceFile) {
|
|
1443
|
+
this.sourceMetadataKeys.get(previousSource)?.delete(key);
|
|
1444
|
+
if (this.sourceMetadataKeys.get(previousSource)?.size === 0) {
|
|
1445
|
+
this.sourceMetadataKeys.delete(previousSource);
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1448
|
+
this.metadataKeySources.set(key, normalizedSourceFile);
|
|
1449
|
+
if (!this.sourceMetadataKeys.has(normalizedSourceFile)) {
|
|
1450
|
+
this.sourceMetadataKeys.set(normalizedSourceFile, /* @__PURE__ */ new Set());
|
|
1451
|
+
}
|
|
1452
|
+
this.sourceMetadataKeys.get(normalizedSourceFile)?.add(key);
|
|
1453
|
+
}
|
|
1454
|
+
clearRegistrationsFromSource(sourceFile) {
|
|
1455
|
+
const normalizedSourceFile = normalizeFilePath$1(sourceFile);
|
|
1456
|
+
const tokens = Array.from(this.sourceTokens.get(normalizedSourceFile) || []);
|
|
1457
|
+
const metadataKeys = Array.from(
|
|
1458
|
+
this.sourceMetadataKeys.get(normalizedSourceFile) || []
|
|
1459
|
+
);
|
|
1460
|
+
for (const token of tokens) {
|
|
1461
|
+
this.regs.delete(token);
|
|
1462
|
+
this.singletons.delete(token);
|
|
1463
|
+
this.tokenSources.delete(token);
|
|
1464
|
+
}
|
|
1465
|
+
for (const metadataKey of metadataKeys) {
|
|
1466
|
+
this.metadataKeySources.delete(metadataKey);
|
|
1467
|
+
}
|
|
1468
|
+
this.sourceTokens.delete(normalizedSourceFile);
|
|
1469
|
+
this.sourceMetadataKeys.delete(normalizedSourceFile);
|
|
1470
|
+
return {
|
|
1471
|
+
metadataKeys,
|
|
1472
|
+
tokens
|
|
1473
|
+
};
|
|
1474
|
+
}
|
|
1475
|
+
trackTokenSource(token, sourceFile) {
|
|
1476
|
+
const normalizedSourceFile = normalizeFilePath$1(sourceFile);
|
|
1477
|
+
const previousSource = this.tokenSources.get(token);
|
|
1478
|
+
if (previousSource && previousSource !== normalizedSourceFile) {
|
|
1479
|
+
this.sourceTokens.get(previousSource)?.delete(token);
|
|
1480
|
+
if (this.sourceTokens.get(previousSource)?.size === 0) {
|
|
1481
|
+
this.sourceTokens.delete(previousSource);
|
|
1482
|
+
}
|
|
1483
|
+
}
|
|
1484
|
+
this.tokenSources.set(token, normalizedSourceFile);
|
|
1485
|
+
if (!this.sourceTokens.has(normalizedSourceFile)) {
|
|
1486
|
+
this.sourceTokens.set(normalizedSourceFile, /* @__PURE__ */ new Set());
|
|
1487
|
+
}
|
|
1488
|
+
this.sourceTokens.get(normalizedSourceFile)?.add(token);
|
|
1489
|
+
}
|
|
1305
1490
|
}
|
|
1306
1491
|
|
|
1307
1492
|
const nattyServiceResolver = new NattyContainer();
|
|
@@ -1407,14 +1592,14 @@ class Resolver extends RequestProcessor {
|
|
|
1407
1592
|
if (onException) {
|
|
1408
1593
|
const instance = this.resolveClass(onException);
|
|
1409
1594
|
if (instance.onException)
|
|
1410
|
-
result = instance.onException({
|
|
1595
|
+
result = this.normalizeHttpResponse(instance.onException({
|
|
1411
1596
|
error: ex,
|
|
1412
1597
|
request: this.httpContext.request,
|
|
1413
1598
|
routeInfo: this.routeInfo
|
|
1414
|
-
});
|
|
1599
|
+
}));
|
|
1415
1600
|
} else
|
|
1416
1601
|
result = new HttpException({
|
|
1417
|
-
body:
|
|
1602
|
+
body: { message: ex.message, stack: ex.stack },
|
|
1418
1603
|
status: HttpStatusCode.serverError
|
|
1419
1604
|
}).getResponse();
|
|
1420
1605
|
}
|
|
@@ -1442,14 +1627,17 @@ class RequestHandler extends Resolver {
|
|
|
1442
1627
|
if (onException) {
|
|
1443
1628
|
const instance = this.resolveClass(onException);
|
|
1444
1629
|
if (instance.onException)
|
|
1445
|
-
return instance.onException({
|
|
1630
|
+
return this.normalizeHttpResponse(instance.onException({
|
|
1446
1631
|
error: ex,
|
|
1447
1632
|
request: this.httpContext.request,
|
|
1448
1633
|
routeInfo: this.routeInfo
|
|
1449
|
-
});
|
|
1634
|
+
}));
|
|
1450
1635
|
} else
|
|
1451
1636
|
return new HttpException({
|
|
1452
|
-
body:
|
|
1637
|
+
body: {
|
|
1638
|
+
message: ex?.message,
|
|
1639
|
+
stack: ex?.stack
|
|
1640
|
+
},
|
|
1453
1641
|
status: HttpStatusCode.serverError
|
|
1454
1642
|
});
|
|
1455
1643
|
}
|
|
@@ -1462,20 +1650,59 @@ class HttpHandler {
|
|
|
1462
1650
|
async processRequest(httpContext) {
|
|
1463
1651
|
const requestProcessor = new RequestHandler(httpContext);
|
|
1464
1652
|
const result = await requestProcessor.onRequest();
|
|
1465
|
-
|
|
1653
|
+
if (result instanceof HttpResponse) {
|
|
1654
|
+
return result;
|
|
1655
|
+
}
|
|
1656
|
+
if (result instanceof HttpException) {
|
|
1657
|
+
return result.getResponse();
|
|
1658
|
+
}
|
|
1659
|
+
return new HttpResponse({ body: result });
|
|
1660
|
+
}
|
|
1661
|
+
}
|
|
1662
|
+
|
|
1663
|
+
const STACK_PATH_REGEX = /\bat (?:(?:.+?) \()?(.+):(\d+):(\d+)\)?$/;
|
|
1664
|
+
function normalizeFilePath(filePath) {
|
|
1665
|
+
return path__default.resolve(filePath).replace(/\\/g, "/");
|
|
1666
|
+
}
|
|
1667
|
+
function isInternalRegistrationFrame(filePath) {
|
|
1668
|
+
const normalizedPath = normalizeFilePath(filePath);
|
|
1669
|
+
return normalizedPath.includes("/packages/core/decorators/") || normalizedPath.includes("/packages/core/functions/") || normalizedPath.includes("/packages/core/domain/di/") || normalizedPath.includes("/packages/core/const/") || normalizedPath.includes("/packages/core/dist/") || normalizedPath.includes("/node_modules/@nattyjs/core/dist/");
|
|
1670
|
+
}
|
|
1671
|
+
function getRegistrationSourceFile() {
|
|
1672
|
+
const stack = new Error().stack;
|
|
1673
|
+
return getRegistrationSourceFileFromStack(stack);
|
|
1674
|
+
}
|
|
1675
|
+
function getRegistrationSourceFileFromStack(stack) {
|
|
1676
|
+
if (!stack) {
|
|
1677
|
+
return void 0;
|
|
1466
1678
|
}
|
|
1679
|
+
const lines = stack.split("\n").slice(1);
|
|
1680
|
+
for (const line of lines) {
|
|
1681
|
+
const match = line.trim().match(STACK_PATH_REGEX);
|
|
1682
|
+
if (!match) {
|
|
1683
|
+
continue;
|
|
1684
|
+
}
|
|
1685
|
+
const filePath = normalizeFilePath(match[1]);
|
|
1686
|
+
if (!isInternalRegistrationFrame(filePath)) {
|
|
1687
|
+
return filePath;
|
|
1688
|
+
}
|
|
1689
|
+
}
|
|
1690
|
+
return void 0;
|
|
1467
1691
|
}
|
|
1468
1692
|
|
|
1469
1693
|
function injectable(options = {}) {
|
|
1470
1694
|
return (targetConstructor) => {
|
|
1471
1695
|
const lt = options.lifetime ?? Lifetime.Transient;
|
|
1696
|
+
const sourceFile = getRegistrationSourceFile();
|
|
1472
1697
|
if (lt === Lifetime.Singleton)
|
|
1473
|
-
nattyServiceResolver.addSingleton(targetConstructor);
|
|
1698
|
+
nattyServiceResolver.addSingleton(targetConstructor, void 0, void 0, sourceFile);
|
|
1474
1699
|
else if (lt === Lifetime.Scoped)
|
|
1475
|
-
nattyServiceResolver.addScoped(targetConstructor);
|
|
1700
|
+
nattyServiceResolver.addScoped(targetConstructor, void 0, void 0, sourceFile);
|
|
1476
1701
|
else
|
|
1477
|
-
nattyServiceResolver.addTransient(targetConstructor);
|
|
1702
|
+
nattyServiceResolver.addTransient(targetConstructor, void 0, void 0, sourceFile);
|
|
1478
1703
|
common.commonContainer.setMetadata(targetConstructor.name, targetConstructor, "services");
|
|
1704
|
+
if (sourceFile)
|
|
1705
|
+
nattyServiceResolver.trackMetadataKey(sourceFile, targetConstructor.name);
|
|
1479
1706
|
};
|
|
1480
1707
|
}
|
|
1481
1708
|
|
|
@@ -1761,7 +1988,12 @@ const Results = {
|
|
|
1761
1988
|
};
|
|
1762
1989
|
|
|
1763
1990
|
function base(params, type, additionaConfig) {
|
|
1764
|
-
decoratorStateContainer.register(
|
|
1991
|
+
decoratorStateContainer.register(
|
|
1992
|
+
params,
|
|
1993
|
+
type,
|
|
1994
|
+
additionaConfig,
|
|
1995
|
+
getRegistrationSourceFile()
|
|
1996
|
+
);
|
|
1765
1997
|
}
|
|
1766
1998
|
|
|
1767
1999
|
function useFilter(config) {
|
|
@@ -1786,6 +2018,12 @@ function authenticationOnly() {
|
|
|
1786
2018
|
};
|
|
1787
2019
|
}
|
|
1788
2020
|
|
|
2021
|
+
function onException(exceptionFilter) {
|
|
2022
|
+
return function(target, propertyKey, descriptor) {
|
|
2023
|
+
base({ target, propertyKey, descriptor }, DecoratorType.onException, exceptionFilter);
|
|
2024
|
+
};
|
|
2025
|
+
}
|
|
2026
|
+
|
|
1789
2027
|
function setEnvInfo(envTsDefinition, envValueInfo) {
|
|
1790
2028
|
if (envTsDefinition && envValueInfo) {
|
|
1791
2029
|
common.commonContainer.setEnvTsDefinition(envTsDefinition);
|
|
@@ -1833,30 +2071,40 @@ function getTokenTypeName(token) {
|
|
|
1833
2071
|
return key.slice(separatorIndex + 1);
|
|
1834
2072
|
}
|
|
1835
2073
|
|
|
1836
|
-
function registerLifetime(targetConstructor, lifetime) {
|
|
2074
|
+
function registerLifetime(targetConstructor, sourceFile, lifetime) {
|
|
1837
2075
|
if (lifetime === Lifetime.Singleton) {
|
|
1838
|
-
nattyServiceResolver.addSingleton(targetConstructor);
|
|
2076
|
+
nattyServiceResolver.addSingleton(targetConstructor, void 0, void 0, sourceFile);
|
|
1839
2077
|
return;
|
|
1840
2078
|
}
|
|
1841
2079
|
if (lifetime === Lifetime.Scoped) {
|
|
1842
|
-
nattyServiceResolver.addScoped(targetConstructor);
|
|
2080
|
+
nattyServiceResolver.addScoped(targetConstructor, void 0, void 0, sourceFile);
|
|
1843
2081
|
return;
|
|
1844
2082
|
}
|
|
1845
2083
|
if (lifetime === Lifetime.Transient) {
|
|
1846
|
-
nattyServiceResolver.addTransient(targetConstructor);
|
|
2084
|
+
nattyServiceResolver.addTransient(targetConstructor, void 0, void 0, sourceFile);
|
|
1847
2085
|
}
|
|
1848
2086
|
}
|
|
1849
|
-
function registerAliasTypeName(token) {
|
|
2087
|
+
function registerAliasTypeName(token, sourceFile) {
|
|
1850
2088
|
const typeName = getTokenTypeName(token);
|
|
1851
2089
|
if (typeName) {
|
|
1852
2090
|
common.commonContainer.setMetadata(typeName, token, "services");
|
|
2091
|
+
if (sourceFile)
|
|
2092
|
+
nattyServiceResolver.trackMetadataKey(sourceFile, typeName);
|
|
1853
2093
|
}
|
|
1854
2094
|
}
|
|
1855
2095
|
function registerDiToken(targetConstructor, token, options = {}) {
|
|
2096
|
+
const sourceFile = getRegistrationSourceFile();
|
|
1856
2097
|
common.commonContainer.setMetadata(targetConstructor.name, targetConstructor, "services");
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
2098
|
+
if (sourceFile)
|
|
2099
|
+
nattyServiceResolver.trackMetadataKey(sourceFile, targetConstructor.name);
|
|
2100
|
+
registerAliasTypeName(token, sourceFile);
|
|
2101
|
+
registerLifetime(targetConstructor, sourceFile, options.lifetime);
|
|
2102
|
+
nattyServiceResolver.addTransient(
|
|
2103
|
+
token,
|
|
2104
|
+
void 0,
|
|
2105
|
+
(serviceProvider) => serviceProvider.get(targetConstructor),
|
|
2106
|
+
sourceFile
|
|
2107
|
+
);
|
|
1860
2108
|
}
|
|
1861
2109
|
|
|
1862
2110
|
function di(token, options = {}) {
|
|
@@ -1869,6 +2117,24 @@ function createServiceScope() {
|
|
|
1869
2117
|
return nattyServiceResolver.createScope();
|
|
1870
2118
|
}
|
|
1871
2119
|
|
|
2120
|
+
function clearHotReloadRegistrations(files) {
|
|
2121
|
+
for (const filePath of files || []) {
|
|
2122
|
+
const result = nattyServiceResolver.clearRegistrationsFromSource(filePath);
|
|
2123
|
+
decoratorStateContainer.clearFromSource(filePath);
|
|
2124
|
+
for (const metadataKey of result.metadataKeys) {
|
|
2125
|
+
common.commonContainer.deleteMetadataValue(metadataKey, "services");
|
|
2126
|
+
}
|
|
2127
|
+
}
|
|
2128
|
+
}
|
|
2129
|
+
|
|
2130
|
+
function clearHotReloadControllerMetadata(controllerNames) {
|
|
2131
|
+
decoratorStateContainer.clearControllers(controllerNames || []);
|
|
2132
|
+
}
|
|
2133
|
+
|
|
2134
|
+
function replaceRoutes(manifest) {
|
|
2135
|
+
nattyContainer.replaceRoutes(manifest);
|
|
2136
|
+
}
|
|
2137
|
+
|
|
1872
2138
|
exports.$request = $request;
|
|
1873
2139
|
exports.AbstractModelState = AbstractModelState;
|
|
1874
2140
|
exports.AcceptedException = AcceptedException;
|
|
@@ -1915,6 +2181,8 @@ exports.anonymous = anonymous;
|
|
|
1915
2181
|
exports.authenticationOnly = authenticationOnly;
|
|
1916
2182
|
exports.authorize = authorize;
|
|
1917
2183
|
exports.badRequest = badRequest;
|
|
2184
|
+
exports.clearHotReloadControllerMetadata = clearHotReloadControllerMetadata;
|
|
2185
|
+
exports.clearHotReloadRegistrations = clearHotReloadRegistrations;
|
|
1918
2186
|
exports.conflict = conflict;
|
|
1919
2187
|
exports.createServiceScope = createServiceScope;
|
|
1920
2188
|
exports.created = created;
|
|
@@ -1934,12 +2202,14 @@ exports.noContent = noContent;
|
|
|
1934
2202
|
exports.notFound = notFound;
|
|
1935
2203
|
exports.notFoundWith = notFoundWith;
|
|
1936
2204
|
exports.ok = ok;
|
|
2205
|
+
exports.onException = onException;
|
|
1937
2206
|
exports.post = post;
|
|
1938
2207
|
exports.problem = problem;
|
|
1939
2208
|
exports.put = put;
|
|
1940
2209
|
exports.redirect = redirect;
|
|
1941
2210
|
exports.redirectPermanent = redirectPermanent;
|
|
1942
2211
|
exports.registerDecorator = registerDecorator;
|
|
2212
|
+
exports.replaceRoutes = replaceRoutes;
|
|
1943
2213
|
exports.route = route;
|
|
1944
2214
|
exports.scoped = scoped;
|
|
1945
2215
|
exports.setEnvInfo = setEnvInfo;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NattyConfig, UserIdentity } from '@nattyjs/common';
|
|
1
|
+
import { NattyConfig, UserIdentity, ClassType, ExceptionFilter } from '@nattyjs/common';
|
|
2
2
|
import { GlobalConfig } from '@nattyjs/common/interfaces/global-config';
|
|
3
3
|
|
|
4
4
|
interface DecoratorInfo$1 {
|
|
@@ -305,20 +305,31 @@ type Descriptor<T = any> = {
|
|
|
305
305
|
useFactory?: Factory<T>;
|
|
306
306
|
};
|
|
307
307
|
|
|
308
|
+
type ClearRegistrationsResult = {
|
|
309
|
+
metadataKeys: string[];
|
|
310
|
+
tokens: Token[];
|
|
311
|
+
};
|
|
308
312
|
declare class NattyContainer implements ServiceProvider {
|
|
309
313
|
private readonly regs;
|
|
310
314
|
private readonly singletons;
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
315
|
+
private readonly tokenSources;
|
|
316
|
+
private readonly sourceTokens;
|
|
317
|
+
private readonly metadataKeySources;
|
|
318
|
+
private readonly sourceMetadataKeys;
|
|
319
|
+
register<T>(token: Token<T>, desc: Descriptor<T>, sourceFile?: string): void;
|
|
320
|
+
addTransient<T>(token: Token<T>, useClass?: DIClassType<T>, useFactory?: Factory<T>, sourceFile?: string): void;
|
|
321
|
+
addScoped<T>(token: Token<T>, useClass?: DIClassType<T>, useFactory?: Factory<T>, sourceFile?: string): void;
|
|
322
|
+
addSingleton<T>(token: Token<T>, useClass?: DIClassType<T>, useFactory?: Factory<T>, sourceFile?: string): void;
|
|
323
|
+
addInstance<T>(token: Token<T>, value: T, sourceFile?: string): void;
|
|
316
324
|
createScope(): NattyScope;
|
|
317
325
|
set<T>(_token: Token<T>, _value: T): void;
|
|
318
326
|
tryGet<T>(token: Token<T>): T | undefined;
|
|
319
327
|
get<T>(token: Token<T>): T;
|
|
320
328
|
construct<T>(Cls: DIClassType<T>, sp: ServiceProvider): T;
|
|
321
329
|
_getDescriptor<T>(token: Token<T>): Descriptor<T> | undefined;
|
|
330
|
+
trackMetadataKey(sourceFile: string, key: string): void;
|
|
331
|
+
clearRegistrationsFromSource(sourceFile: string): ClearRegistrationsResult;
|
|
332
|
+
private trackTokenSource;
|
|
322
333
|
}
|
|
323
334
|
|
|
324
335
|
declare class NattyScope implements Scope {
|
|
@@ -391,6 +402,7 @@ declare abstract class BaseResponse {
|
|
|
391
402
|
badRequest(): void;
|
|
392
403
|
success(body: any): HttpResponse;
|
|
393
404
|
notFound(): void;
|
|
405
|
+
protected normalizeHttpResponse(result: any): any;
|
|
394
406
|
}
|
|
395
407
|
|
|
396
408
|
declare abstract class ParameterTypeConverter extends BaseResponse {
|
|
@@ -402,9 +414,9 @@ declare abstract class ParameterTypeConverter extends BaseResponse {
|
|
|
402
414
|
};
|
|
403
415
|
get types(): TypesInfo;
|
|
404
416
|
getObjectTypeInfo(typeName: string): {
|
|
405
|
-
path?:
|
|
406
|
-
props?:
|
|
407
|
-
values?:
|
|
417
|
+
path?: any;
|
|
418
|
+
props?: TypeInfo[];
|
|
419
|
+
values?: any[];
|
|
408
420
|
};
|
|
409
421
|
isArrayType(typeName: string): boolean;
|
|
410
422
|
getTypeName(typeName: string): string;
|
|
@@ -563,21 +575,21 @@ declare class StatusCodeResult<T = unknown> extends BaseResult implements IHttpR
|
|
|
563
575
|
|
|
564
576
|
declare const Results: {
|
|
565
577
|
readonly ok: <T = unknown>(value?: T, extras?: ResponseExtras) => OkResult<T>;
|
|
566
|
-
readonly created: <
|
|
567
|
-
readonly createdWith: <
|
|
568
|
-
readonly createdAt: <
|
|
569
|
-
readonly accepted: <
|
|
578
|
+
readonly created: <T_1 = unknown>(value?: T_1, extras?: ResponseExtras) => CreatedResult<T_1>;
|
|
579
|
+
readonly createdWith: <T_2 = unknown>(location: string, value?: T_2, extras?: ResponseExtras) => CreatedResult<T_2>;
|
|
580
|
+
readonly createdAt: <T_3 = unknown>(location: string, value?: T_3, extras?: ResponseExtras) => CreatedResult<T_3>;
|
|
581
|
+
readonly accepted: <T_4 = unknown>(value?: T_4, extras?: ResponseExtras) => AcceptedResult<T_4>;
|
|
570
582
|
readonly noContent: (extras?: ResponseExtras) => NoContentResult;
|
|
571
583
|
readonly file: (buffer?: Buffer, extras?: ResponseExtras) => FileResult;
|
|
572
|
-
readonly statusCode: <
|
|
573
|
-
readonly badRequest: <
|
|
584
|
+
readonly statusCode: <T_5 = unknown>(status: number, value?: T_5, extras?: ResponseExtras) => StatusCodeResult<T_5>;
|
|
585
|
+
readonly badRequest: <T_6 = ExceptionTypeInfo>(value?: T_6, extras?: ResponseExtras) => BadRequestResult<T_6>;
|
|
574
586
|
readonly notFound: (extras?: ResponseExtras) => NotFoundResult<any>;
|
|
575
|
-
readonly notFoundWith: <
|
|
576
|
-
readonly unAuthorized: <
|
|
577
|
-
readonly forbid: <
|
|
578
|
-
readonly conflict: <
|
|
579
|
-
readonly unprocessableEntity: <
|
|
580
|
-
readonly tooManyRequests: <
|
|
587
|
+
readonly notFoundWith: <T_7 = unknown>(value?: T_7, extras?: ResponseExtras) => NotFoundResult<T_7>;
|
|
588
|
+
readonly unAuthorized: <T_8 = ExceptionTypeInfo>(value?: T_8, extras?: ResponseExtras) => UnAuthorizedResult<T_8>;
|
|
589
|
+
readonly forbid: <T_9 = ExceptionTypeInfo>(value?: T_9, extras?: ResponseExtras) => ForbiddenAccessInfoResult<unknown>;
|
|
590
|
+
readonly conflict: <T_10 = unknown>(value?: T_10, extras?: ResponseExtras) => ConflictResult<T_10>;
|
|
591
|
+
readonly unprocessableEntity: <T_11 = unknown>(value?: T_11, extras?: ResponseExtras) => UnprocessableEntityResult<T_11>;
|
|
592
|
+
readonly tooManyRequests: <T_12 = unknown>(value?: T_12, retryAfterSeconds?: number, extras?: ResponseExtras) => TooManyRequestsResult<T_12>;
|
|
581
593
|
readonly redirect: (location: string, extras?: ResponseExtras) => RedirectResult;
|
|
582
594
|
readonly redirectPermanent: (location: string, extras?: ResponseExtras) => RedirectResult;
|
|
583
595
|
readonly problem: (p: ProblemDetails, extras?: ResponseExtras) => ProblemResult;
|
|
@@ -644,6 +656,8 @@ declare function anonymous(): (target: any, propertyKey?: string, descriptor?: a
|
|
|
644
656
|
|
|
645
657
|
declare function authenticationOnly(): (target: any, propertyKey?: string, descriptor?: any) => void;
|
|
646
658
|
|
|
659
|
+
declare function onException(exceptionFilter: ClassType<ExceptionFilter>): (target: any, propertyKey?: string, descriptor?: any) => void;
|
|
660
|
+
|
|
647
661
|
declare function setEnvInfo(envTsDefinition: {
|
|
648
662
|
[key: string]: string;
|
|
649
663
|
}, envValueInfo: {
|
|
@@ -690,4 +704,17 @@ declare function registerType<T>(): unknown;
|
|
|
690
704
|
|
|
691
705
|
declare function createServiceScope(): NattyScope;
|
|
692
706
|
|
|
693
|
-
|
|
707
|
+
declare function clearHotReloadRegistrations(files: string[]): void;
|
|
708
|
+
|
|
709
|
+
declare function clearHotReloadControllerMetadata(controllerNames: string[]): void;
|
|
710
|
+
|
|
711
|
+
interface RuntimeManifest {
|
|
712
|
+
routes: {
|
|
713
|
+
[key: string]: RouteConfig;
|
|
714
|
+
};
|
|
715
|
+
resolver?: (path: string) => any;
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
declare function replaceRoutes(manifest: RuntimeManifest): void;
|
|
719
|
+
|
|
720
|
+
export { $request, AbstractModelState, AcceptedException, AcceptedResult, BadRequestResult, BaseController, BaseResult, BuildOptions, ClassTypeInfo, ConflictResult, CreateProblemDetail, CreatedResult, Delete, DiOptions, FileResult, ForbiddenAccessException, ForbiddenAccessInfoResult, HttpBadRequestException, HttpConflictException, HttpContext, HttpException, HttpHandler, HttpModule, HttpNotFoundException, HttpResponse, HttpStatusCode, HttpUnprocessableEntityException, Lifetime, MethodInfo$1 as MethodInfo, ModelBindingContext, NoContentResult, NotFoundResult, OkResult, ParameterInfo, ProblemDetailsException, ProblemResult, RedirectException, RedirectPermanentException, RedirectResult, ResponseExtras, Results, RetryAfter, RunOn, RuntimeManifest, TooManyRequestsException, TooManyRequestsResult, TypeInfo$1 as TypeInfo, UnAuthorizedResult, UnauthorizedAccessException, UnprocessableEntityResult, ValidationProblemDetailsException, accepted, anonymous, authenticationOnly, authorize, badRequest, clearHotReloadControllerMetadata, clearHotReloadRegistrations, conflict, createServiceScope, created, createdAt, createdWith, defineNattyConfig, di, entityContainer, file, filter, forbiddenAccess, forbiddenAccessInfo, get, init, injectable, noContent, notFound, notFoundWith, ok, onException, post, problem, put, redirect, redirectPermanent, registerDecorator, registerType, replaceRoutes, route, scoped, setEnvInfo, singleton, tooManyRequests, transient, unAuthorized, unprocessableEntity, useFilter, validationProblem };
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { commonContainer, isObject, List, BLANK as BLANK$1
|
|
1
|
+
import { commonContainer, isObject, List, BLANK as BLANK$1 } from '@nattyjs/common';
|
|
2
2
|
import { match } from 'path-to-regexp';
|
|
3
|
+
import path from 'node:path';
|
|
3
4
|
import 'reflect-metadata';
|
|
4
5
|
|
|
5
6
|
function defineNattyConfig(config) {
|
|
@@ -52,6 +53,7 @@ function Delete() {
|
|
|
52
53
|
};
|
|
53
54
|
}
|
|
54
55
|
|
|
56
|
+
const HTTP_METHODS = ["get", "post", "put", "delete"];
|
|
55
57
|
const _StaticContainer = class {
|
|
56
58
|
setup(types) {
|
|
57
59
|
_StaticContainer.types = types;
|
|
@@ -63,14 +65,56 @@ const nattyContainer = new class {
|
|
|
63
65
|
constructor() {
|
|
64
66
|
this.container = /* @__PURE__ */ new Map();
|
|
65
67
|
this.containerState = /* @__PURE__ */ new Map();
|
|
68
|
+
this.compiledRoutes = {};
|
|
66
69
|
}
|
|
67
70
|
get types() {
|
|
68
71
|
return commonContainer.types;
|
|
69
72
|
}
|
|
70
73
|
setup(config, routes, resolver) {
|
|
71
74
|
this.config = config;
|
|
72
|
-
this.routes = routes;
|
|
73
75
|
this.resolver = resolver;
|
|
76
|
+
this.applyRouteSnapshot(routes);
|
|
77
|
+
}
|
|
78
|
+
replaceRoutes(manifest) {
|
|
79
|
+
if (manifest.resolver)
|
|
80
|
+
this.resolver = manifest.resolver;
|
|
81
|
+
this.applyRouteSnapshot(manifest.routes);
|
|
82
|
+
}
|
|
83
|
+
applyRouteSnapshot(routes) {
|
|
84
|
+
this.routes = routes;
|
|
85
|
+
this.compiledRoutes = this.createCompiledRoutes(routes);
|
|
86
|
+
}
|
|
87
|
+
createCompiledRoutes(routes) {
|
|
88
|
+
const compiledRoutes = {};
|
|
89
|
+
for (const method of HTTP_METHODS)
|
|
90
|
+
compiledRoutes[method] = [];
|
|
91
|
+
for (const [rootPath, routeConfig] of Object.entries(routes)) {
|
|
92
|
+
for (const method of HTTP_METHODS) {
|
|
93
|
+
const childRoutes = routeConfig[method];
|
|
94
|
+
if (!childRoutes)
|
|
95
|
+
continue;
|
|
96
|
+
for (const [childRoutePath, routeInfo] of Object.entries(childRoutes)) {
|
|
97
|
+
const childPath = this.normalizeChildPath(childRoutePath);
|
|
98
|
+
const configuredRoutePath = `${rootPath}${childPath}`;
|
|
99
|
+
compiledRoutes[method].push({
|
|
100
|
+
requestMethod: method,
|
|
101
|
+
configuredRoutePath,
|
|
102
|
+
matcher: match(configuredRoutePath, { decode: decodeURIComponent }),
|
|
103
|
+
routeConfig,
|
|
104
|
+
methodInfo: routeInfo
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return compiledRoutes;
|
|
110
|
+
}
|
|
111
|
+
normalizeChildPath(childRoutePath) {
|
|
112
|
+
if (childRoutePath.indexOf("/") === 0)
|
|
113
|
+
return childRoutePath === "/" ? BLANK : childRoutePath;
|
|
114
|
+
return `/${childRoutePath}`;
|
|
115
|
+
}
|
|
116
|
+
getCompiledRoutes(method) {
|
|
117
|
+
return this.compiledRoutes[method] || [];
|
|
74
118
|
}
|
|
75
119
|
getTypes() {
|
|
76
120
|
return StaticContainer.types;
|
|
@@ -161,8 +205,10 @@ function setupLegacyTypes(types) {
|
|
|
161
205
|
function defaultResolver(path) {
|
|
162
206
|
if (typeof path === "function")
|
|
163
207
|
return path();
|
|
164
|
-
if (typeof path === "string")
|
|
165
|
-
|
|
208
|
+
if (typeof path === "string") {
|
|
209
|
+
const normalizedPath = path.startsWith("/") ? `.${path}` : path;
|
|
210
|
+
return require(normalizedPath);
|
|
211
|
+
}
|
|
166
212
|
return {};
|
|
167
213
|
}
|
|
168
214
|
function initializeModule(config) {
|
|
@@ -512,6 +558,15 @@ class BaseResponse {
|
|
|
512
558
|
notFound() {
|
|
513
559
|
throw new HttpNotFoundException({});
|
|
514
560
|
}
|
|
561
|
+
normalizeHttpResponse(result) {
|
|
562
|
+
if (result instanceof HttpResponse)
|
|
563
|
+
return result;
|
|
564
|
+
if (result instanceof HttpException)
|
|
565
|
+
return result.getResponse();
|
|
566
|
+
if (result && typeof result === "object" && ("status" in result || "body" in result || "headers" in result || "cookies" in result || "isBuffer" in result))
|
|
567
|
+
return new HttpResponse(result);
|
|
568
|
+
return result;
|
|
569
|
+
}
|
|
515
570
|
}
|
|
516
571
|
|
|
517
572
|
function getTypedErrorMessage(type, value) {
|
|
@@ -846,8 +901,8 @@ class RouteParser extends ParameterTypeConverter {
|
|
|
846
901
|
get httpMethod() {
|
|
847
902
|
return this.httpContext.request.method.toLowerCase();
|
|
848
903
|
}
|
|
849
|
-
get
|
|
850
|
-
return nattyContainer.
|
|
904
|
+
get compiledRoutes() {
|
|
905
|
+
return nattyContainer.getCompiledRoutes(this.httpMethod);
|
|
851
906
|
}
|
|
852
907
|
init() {
|
|
853
908
|
const isMatched = this.matchRoute();
|
|
@@ -860,47 +915,46 @@ class RouteParser extends ParameterTypeConverter {
|
|
|
860
915
|
return controllerInfo[name];
|
|
861
916
|
}
|
|
862
917
|
matchRoute() {
|
|
863
|
-
|
|
864
|
-
const requestPathname = this.getRequestPathname();
|
|
865
|
-
for (const
|
|
866
|
-
const
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
this.routeInfo = {
|
|
879
|
-
path: `${commonContainer.nattyConfig.api.rootPath}/${requestPathname}`,
|
|
880
|
-
configuredRoutePath: `${commonContainer.nattyConfig.api.rootPath}/${configuredRoutePath}`,
|
|
881
|
-
controller: this.getController(routeConfig),
|
|
882
|
-
parameters: routeConfig.parameters,
|
|
883
|
-
methodInfo,
|
|
884
|
-
params: this.convert(methodInfo, matched.params),
|
|
885
|
-
queryParams: this.getQueryParams()
|
|
886
|
-
};
|
|
887
|
-
break;
|
|
888
|
-
}
|
|
889
|
-
}
|
|
918
|
+
const requestUrl = this.getRequestUrl();
|
|
919
|
+
const requestPathname = this.getRequestPathname(requestUrl);
|
|
920
|
+
for (const route of this.compiledRoutes) {
|
|
921
|
+
const matched = route.matcher(requestPathname);
|
|
922
|
+
if (matched) {
|
|
923
|
+
this.routeInfo = {
|
|
924
|
+
path: `${commonContainer.nattyConfig.api.rootPath}/${requestPathname}`,
|
|
925
|
+
configuredRoutePath: `${commonContainer.nattyConfig.api.rootPath}/${route.configuredRoutePath}`,
|
|
926
|
+
controller: this.getController(route.routeConfig),
|
|
927
|
+
parameters: route.routeConfig.parameters,
|
|
928
|
+
methodInfo: route.methodInfo,
|
|
929
|
+
params: this.convert(route.methodInfo, matched.params),
|
|
930
|
+
queryParams: this.getQueryParams(requestUrl)
|
|
931
|
+
};
|
|
932
|
+
return true;
|
|
890
933
|
}
|
|
891
934
|
}
|
|
892
|
-
return
|
|
893
|
-
}
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
935
|
+
return false;
|
|
936
|
+
}
|
|
937
|
+
getRequestUrl() {
|
|
938
|
+
if (!this.parsedRequestUrl)
|
|
939
|
+
this.parsedRequestUrl = new URL(this.httpContext.request.url);
|
|
940
|
+
return this.parsedRequestUrl;
|
|
941
|
+
}
|
|
942
|
+
getRequestPathname(url) {
|
|
943
|
+
const apiRootPath = String(commonContainer.nattyConfig.api.rootPath || "").replace(/^\/+|\/+$/g, "");
|
|
944
|
+
const normalizedPathname = url.pathname.replace(/^\/+/, "");
|
|
945
|
+
if (!apiRootPath) {
|
|
946
|
+
return normalizedPathname;
|
|
947
|
+
}
|
|
948
|
+
if (normalizedPathname === apiRootPath) {
|
|
949
|
+
return "";
|
|
950
|
+
}
|
|
951
|
+
const apiPrefix = `${apiRootPath}/`;
|
|
952
|
+
if (normalizedPathname.startsWith(apiPrefix)) {
|
|
953
|
+
return normalizedPathname.slice(apiPrefix.length);
|
|
954
|
+
}
|
|
955
|
+
return normalizedPathname;
|
|
956
|
+
}
|
|
957
|
+
getQueryParams(url) {
|
|
904
958
|
const queryParams = {};
|
|
905
959
|
for (const param of url.searchParams.keys())
|
|
906
960
|
queryParams[param] = url.searchParams.get(param);
|
|
@@ -911,8 +965,10 @@ class RouteParser extends ParameterTypeConverter {
|
|
|
911
965
|
const decoratorStateContainer = new class {
|
|
912
966
|
constructor() {
|
|
913
967
|
this.controllerConfig = {};
|
|
968
|
+
this.controllerSources = /* @__PURE__ */ new Map();
|
|
969
|
+
this.sourceControllers = /* @__PURE__ */ new Map();
|
|
914
970
|
}
|
|
915
|
-
register(params, type, additionalConfig) {
|
|
971
|
+
register(params, type, additionalConfig, sourceFile) {
|
|
916
972
|
const name = params.target.name || params.target.constructor.name;
|
|
917
973
|
let controllerInfo = this.controllerConfig[name] || null;
|
|
918
974
|
let controllerMethodInfo = null;
|
|
@@ -925,6 +981,9 @@ const decoratorStateContainer = new class {
|
|
|
925
981
|
controllerMethodInfo[type] = additionalConfig;
|
|
926
982
|
} else
|
|
927
983
|
controllerInfo.config[type] = additionalConfig;
|
|
984
|
+
if (sourceFile) {
|
|
985
|
+
this.trackControllerSource(name, sourceFile);
|
|
986
|
+
}
|
|
928
987
|
}
|
|
929
988
|
getInfo(controllerName, methodName, type) {
|
|
930
989
|
const controllerInfo = this.controllerConfig[controllerName];
|
|
@@ -937,6 +996,55 @@ const decoratorStateContainer = new class {
|
|
|
937
996
|
methodConfig = methodInfo[type];
|
|
938
997
|
return { controllerConfig, methodConfig };
|
|
939
998
|
}
|
|
999
|
+
clearFromSource(sourceFile) {
|
|
1000
|
+
const normalizedSourceFile = this.normalizeFilePath(sourceFile);
|
|
1001
|
+
const controllerNames = Array.from(
|
|
1002
|
+
this.sourceControllers.get(normalizedSourceFile) || []
|
|
1003
|
+
);
|
|
1004
|
+
this.clearControllers(controllerNames);
|
|
1005
|
+
this.sourceControllers.delete(normalizedSourceFile);
|
|
1006
|
+
return controllerNames;
|
|
1007
|
+
}
|
|
1008
|
+
clearControllers(controllerNames) {
|
|
1009
|
+
const removedControllers = [];
|
|
1010
|
+
for (const controllerName of controllerNames) {
|
|
1011
|
+
const previousSource = this.controllerSources.get(controllerName);
|
|
1012
|
+
delete this.controllerConfig[controllerName];
|
|
1013
|
+
this.controllerSources.delete(controllerName);
|
|
1014
|
+
removedControllers.push(controllerName);
|
|
1015
|
+
if (previousSource) {
|
|
1016
|
+
const controllers = this.sourceControllers.get(previousSource);
|
|
1017
|
+
controllers?.delete(controllerName);
|
|
1018
|
+
if (controllers && controllers.size === 0) {
|
|
1019
|
+
this.sourceControllers.delete(previousSource);
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
return removedControllers;
|
|
1024
|
+
}
|
|
1025
|
+
reset() {
|
|
1026
|
+
this.controllerConfig = {};
|
|
1027
|
+
this.controllerSources.clear();
|
|
1028
|
+
this.sourceControllers.clear();
|
|
1029
|
+
}
|
|
1030
|
+
trackControllerSource(controllerName, sourceFile) {
|
|
1031
|
+
const normalizedSourceFile = this.normalizeFilePath(sourceFile);
|
|
1032
|
+
const previousSource = this.controllerSources.get(controllerName);
|
|
1033
|
+
if (previousSource && previousSource !== normalizedSourceFile) {
|
|
1034
|
+
this.sourceControllers.get(previousSource)?.delete(controllerName);
|
|
1035
|
+
if (this.sourceControllers.get(previousSource)?.size === 0) {
|
|
1036
|
+
this.sourceControllers.delete(previousSource);
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
this.controllerSources.set(controllerName, normalizedSourceFile);
|
|
1040
|
+
if (!this.sourceControllers.has(normalizedSourceFile)) {
|
|
1041
|
+
this.sourceControllers.set(normalizedSourceFile, /* @__PURE__ */ new Set());
|
|
1042
|
+
}
|
|
1043
|
+
this.sourceControllers.get(normalizedSourceFile)?.add(controllerName);
|
|
1044
|
+
}
|
|
1045
|
+
normalizeFilePath(filePath) {
|
|
1046
|
+
return path.resolve(filePath).replace(/\\/g, "/");
|
|
1047
|
+
}
|
|
940
1048
|
}();
|
|
941
1049
|
|
|
942
1050
|
var DecoratorType = /* @__PURE__ */ ((DecoratorType2) => {
|
|
@@ -1237,25 +1345,47 @@ class NattyScope {
|
|
|
1237
1345
|
}
|
|
1238
1346
|
}
|
|
1239
1347
|
|
|
1348
|
+
function normalizeFilePath$1(filePath) {
|
|
1349
|
+
return path.resolve(filePath).replace(/\\/g, "/");
|
|
1350
|
+
}
|
|
1240
1351
|
class NattyContainer {
|
|
1241
1352
|
constructor() {
|
|
1242
1353
|
this.regs = /* @__PURE__ */ new Map();
|
|
1243
1354
|
this.singletons = /* @__PURE__ */ new Map();
|
|
1355
|
+
this.tokenSources = /* @__PURE__ */ new Map();
|
|
1356
|
+
this.sourceTokens = /* @__PURE__ */ new Map();
|
|
1357
|
+
this.metadataKeySources = /* @__PURE__ */ new Map();
|
|
1358
|
+
this.sourceMetadataKeys = /* @__PURE__ */ new Map();
|
|
1244
1359
|
}
|
|
1245
|
-
register(token, desc) {
|
|
1360
|
+
register(token, desc, sourceFile) {
|
|
1246
1361
|
this.regs.set(token, desc);
|
|
1362
|
+
if (sourceFile) {
|
|
1363
|
+
this.trackTokenSource(token, sourceFile);
|
|
1364
|
+
}
|
|
1247
1365
|
}
|
|
1248
|
-
addTransient(token, useClass, useFactory) {
|
|
1249
|
-
this.register(
|
|
1366
|
+
addTransient(token, useClass, useFactory, sourceFile) {
|
|
1367
|
+
this.register(
|
|
1368
|
+
token,
|
|
1369
|
+
{ lifetime: Lifetime.Transient, useClass: useClass ?? token, useFactory },
|
|
1370
|
+
sourceFile
|
|
1371
|
+
);
|
|
1250
1372
|
}
|
|
1251
|
-
addScoped(token, useClass, useFactory) {
|
|
1252
|
-
this.register(
|
|
1373
|
+
addScoped(token, useClass, useFactory, sourceFile) {
|
|
1374
|
+
this.register(
|
|
1375
|
+
token,
|
|
1376
|
+
{ lifetime: Lifetime.Scoped, useClass: useClass ?? token, useFactory },
|
|
1377
|
+
sourceFile
|
|
1378
|
+
);
|
|
1253
1379
|
}
|
|
1254
|
-
addSingleton(token, useClass, useFactory) {
|
|
1255
|
-
this.register(
|
|
1380
|
+
addSingleton(token, useClass, useFactory, sourceFile) {
|
|
1381
|
+
this.register(
|
|
1382
|
+
token,
|
|
1383
|
+
{ lifetime: Lifetime.Singleton, useClass: useClass ?? token, useFactory },
|
|
1384
|
+
sourceFile
|
|
1385
|
+
);
|
|
1256
1386
|
}
|
|
1257
|
-
addInstance(token, value) {
|
|
1258
|
-
this.register(token, { lifetime: Lifetime.Singleton, useValue: value });
|
|
1387
|
+
addInstance(token, value, sourceFile) {
|
|
1388
|
+
this.register(token, { lifetime: Lifetime.Singleton, useValue: value }, sourceFile);
|
|
1259
1389
|
this.singletons.set(token, value);
|
|
1260
1390
|
}
|
|
1261
1391
|
createScope() {
|
|
@@ -1300,6 +1430,57 @@ class NattyContainer {
|
|
|
1300
1430
|
_getDescriptor(token) {
|
|
1301
1431
|
return this.regs.get(token);
|
|
1302
1432
|
}
|
|
1433
|
+
trackMetadataKey(sourceFile, key) {
|
|
1434
|
+
const normalizedSourceFile = normalizeFilePath$1(sourceFile);
|
|
1435
|
+
const previousSource = this.metadataKeySources.get(key);
|
|
1436
|
+
if (previousSource && previousSource !== normalizedSourceFile) {
|
|
1437
|
+
this.sourceMetadataKeys.get(previousSource)?.delete(key);
|
|
1438
|
+
if (this.sourceMetadataKeys.get(previousSource)?.size === 0) {
|
|
1439
|
+
this.sourceMetadataKeys.delete(previousSource);
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1442
|
+
this.metadataKeySources.set(key, normalizedSourceFile);
|
|
1443
|
+
if (!this.sourceMetadataKeys.has(normalizedSourceFile)) {
|
|
1444
|
+
this.sourceMetadataKeys.set(normalizedSourceFile, /* @__PURE__ */ new Set());
|
|
1445
|
+
}
|
|
1446
|
+
this.sourceMetadataKeys.get(normalizedSourceFile)?.add(key);
|
|
1447
|
+
}
|
|
1448
|
+
clearRegistrationsFromSource(sourceFile) {
|
|
1449
|
+
const normalizedSourceFile = normalizeFilePath$1(sourceFile);
|
|
1450
|
+
const tokens = Array.from(this.sourceTokens.get(normalizedSourceFile) || []);
|
|
1451
|
+
const metadataKeys = Array.from(
|
|
1452
|
+
this.sourceMetadataKeys.get(normalizedSourceFile) || []
|
|
1453
|
+
);
|
|
1454
|
+
for (const token of tokens) {
|
|
1455
|
+
this.regs.delete(token);
|
|
1456
|
+
this.singletons.delete(token);
|
|
1457
|
+
this.tokenSources.delete(token);
|
|
1458
|
+
}
|
|
1459
|
+
for (const metadataKey of metadataKeys) {
|
|
1460
|
+
this.metadataKeySources.delete(metadataKey);
|
|
1461
|
+
}
|
|
1462
|
+
this.sourceTokens.delete(normalizedSourceFile);
|
|
1463
|
+
this.sourceMetadataKeys.delete(normalizedSourceFile);
|
|
1464
|
+
return {
|
|
1465
|
+
metadataKeys,
|
|
1466
|
+
tokens
|
|
1467
|
+
};
|
|
1468
|
+
}
|
|
1469
|
+
trackTokenSource(token, sourceFile) {
|
|
1470
|
+
const normalizedSourceFile = normalizeFilePath$1(sourceFile);
|
|
1471
|
+
const previousSource = this.tokenSources.get(token);
|
|
1472
|
+
if (previousSource && previousSource !== normalizedSourceFile) {
|
|
1473
|
+
this.sourceTokens.get(previousSource)?.delete(token);
|
|
1474
|
+
if (this.sourceTokens.get(previousSource)?.size === 0) {
|
|
1475
|
+
this.sourceTokens.delete(previousSource);
|
|
1476
|
+
}
|
|
1477
|
+
}
|
|
1478
|
+
this.tokenSources.set(token, normalizedSourceFile);
|
|
1479
|
+
if (!this.sourceTokens.has(normalizedSourceFile)) {
|
|
1480
|
+
this.sourceTokens.set(normalizedSourceFile, /* @__PURE__ */ new Set());
|
|
1481
|
+
}
|
|
1482
|
+
this.sourceTokens.get(normalizedSourceFile)?.add(token);
|
|
1483
|
+
}
|
|
1303
1484
|
}
|
|
1304
1485
|
|
|
1305
1486
|
const nattyServiceResolver = new NattyContainer();
|
|
@@ -1405,14 +1586,14 @@ class Resolver extends RequestProcessor {
|
|
|
1405
1586
|
if (onException) {
|
|
1406
1587
|
const instance = this.resolveClass(onException);
|
|
1407
1588
|
if (instance.onException)
|
|
1408
|
-
result = instance.onException({
|
|
1589
|
+
result = this.normalizeHttpResponse(instance.onException({
|
|
1409
1590
|
error: ex,
|
|
1410
1591
|
request: this.httpContext.request,
|
|
1411
1592
|
routeInfo: this.routeInfo
|
|
1412
|
-
});
|
|
1593
|
+
}));
|
|
1413
1594
|
} else
|
|
1414
1595
|
result = new HttpException({
|
|
1415
|
-
body:
|
|
1596
|
+
body: { message: ex.message, stack: ex.stack },
|
|
1416
1597
|
status: HttpStatusCode.serverError
|
|
1417
1598
|
}).getResponse();
|
|
1418
1599
|
}
|
|
@@ -1440,14 +1621,17 @@ class RequestHandler extends Resolver {
|
|
|
1440
1621
|
if (onException) {
|
|
1441
1622
|
const instance = this.resolveClass(onException);
|
|
1442
1623
|
if (instance.onException)
|
|
1443
|
-
return instance.onException({
|
|
1624
|
+
return this.normalizeHttpResponse(instance.onException({
|
|
1444
1625
|
error: ex,
|
|
1445
1626
|
request: this.httpContext.request,
|
|
1446
1627
|
routeInfo: this.routeInfo
|
|
1447
|
-
});
|
|
1628
|
+
}));
|
|
1448
1629
|
} else
|
|
1449
1630
|
return new HttpException({
|
|
1450
|
-
body:
|
|
1631
|
+
body: {
|
|
1632
|
+
message: ex?.message,
|
|
1633
|
+
stack: ex?.stack
|
|
1634
|
+
},
|
|
1451
1635
|
status: HttpStatusCode.serverError
|
|
1452
1636
|
});
|
|
1453
1637
|
}
|
|
@@ -1460,20 +1644,59 @@ class HttpHandler {
|
|
|
1460
1644
|
async processRequest(httpContext) {
|
|
1461
1645
|
const requestProcessor = new RequestHandler(httpContext);
|
|
1462
1646
|
const result = await requestProcessor.onRequest();
|
|
1463
|
-
|
|
1647
|
+
if (result instanceof HttpResponse) {
|
|
1648
|
+
return result;
|
|
1649
|
+
}
|
|
1650
|
+
if (result instanceof HttpException) {
|
|
1651
|
+
return result.getResponse();
|
|
1652
|
+
}
|
|
1653
|
+
return new HttpResponse({ body: result });
|
|
1464
1654
|
}
|
|
1465
1655
|
}
|
|
1466
1656
|
|
|
1657
|
+
const STACK_PATH_REGEX = /\bat (?:(?:.+?) \()?(.+):(\d+):(\d+)\)?$/;
|
|
1658
|
+
function normalizeFilePath(filePath) {
|
|
1659
|
+
return path.resolve(filePath).replace(/\\/g, "/");
|
|
1660
|
+
}
|
|
1661
|
+
function isInternalRegistrationFrame(filePath) {
|
|
1662
|
+
const normalizedPath = normalizeFilePath(filePath);
|
|
1663
|
+
return normalizedPath.includes("/packages/core/decorators/") || normalizedPath.includes("/packages/core/functions/") || normalizedPath.includes("/packages/core/domain/di/") || normalizedPath.includes("/packages/core/const/") || normalizedPath.includes("/packages/core/dist/") || normalizedPath.includes("/node_modules/@nattyjs/core/dist/");
|
|
1664
|
+
}
|
|
1665
|
+
function getRegistrationSourceFile() {
|
|
1666
|
+
const stack = new Error().stack;
|
|
1667
|
+
return getRegistrationSourceFileFromStack(stack);
|
|
1668
|
+
}
|
|
1669
|
+
function getRegistrationSourceFileFromStack(stack) {
|
|
1670
|
+
if (!stack) {
|
|
1671
|
+
return void 0;
|
|
1672
|
+
}
|
|
1673
|
+
const lines = stack.split("\n").slice(1);
|
|
1674
|
+
for (const line of lines) {
|
|
1675
|
+
const match = line.trim().match(STACK_PATH_REGEX);
|
|
1676
|
+
if (!match) {
|
|
1677
|
+
continue;
|
|
1678
|
+
}
|
|
1679
|
+
const filePath = normalizeFilePath(match[1]);
|
|
1680
|
+
if (!isInternalRegistrationFrame(filePath)) {
|
|
1681
|
+
return filePath;
|
|
1682
|
+
}
|
|
1683
|
+
}
|
|
1684
|
+
return void 0;
|
|
1685
|
+
}
|
|
1686
|
+
|
|
1467
1687
|
function injectable(options = {}) {
|
|
1468
1688
|
return (targetConstructor) => {
|
|
1469
1689
|
const lt = options.lifetime ?? Lifetime.Transient;
|
|
1690
|
+
const sourceFile = getRegistrationSourceFile();
|
|
1470
1691
|
if (lt === Lifetime.Singleton)
|
|
1471
|
-
nattyServiceResolver.addSingleton(targetConstructor);
|
|
1692
|
+
nattyServiceResolver.addSingleton(targetConstructor, void 0, void 0, sourceFile);
|
|
1472
1693
|
else if (lt === Lifetime.Scoped)
|
|
1473
|
-
nattyServiceResolver.addScoped(targetConstructor);
|
|
1694
|
+
nattyServiceResolver.addScoped(targetConstructor, void 0, void 0, sourceFile);
|
|
1474
1695
|
else
|
|
1475
|
-
nattyServiceResolver.addTransient(targetConstructor);
|
|
1696
|
+
nattyServiceResolver.addTransient(targetConstructor, void 0, void 0, sourceFile);
|
|
1476
1697
|
commonContainer.setMetadata(targetConstructor.name, targetConstructor, "services");
|
|
1698
|
+
if (sourceFile)
|
|
1699
|
+
nattyServiceResolver.trackMetadataKey(sourceFile, targetConstructor.name);
|
|
1477
1700
|
};
|
|
1478
1701
|
}
|
|
1479
1702
|
|
|
@@ -1759,7 +1982,12 @@ const Results = {
|
|
|
1759
1982
|
};
|
|
1760
1983
|
|
|
1761
1984
|
function base(params, type, additionaConfig) {
|
|
1762
|
-
decoratorStateContainer.register(
|
|
1985
|
+
decoratorStateContainer.register(
|
|
1986
|
+
params,
|
|
1987
|
+
type,
|
|
1988
|
+
additionaConfig,
|
|
1989
|
+
getRegistrationSourceFile()
|
|
1990
|
+
);
|
|
1763
1991
|
}
|
|
1764
1992
|
|
|
1765
1993
|
function useFilter(config) {
|
|
@@ -1784,6 +2012,12 @@ function authenticationOnly() {
|
|
|
1784
2012
|
};
|
|
1785
2013
|
}
|
|
1786
2014
|
|
|
2015
|
+
function onException(exceptionFilter) {
|
|
2016
|
+
return function(target, propertyKey, descriptor) {
|
|
2017
|
+
base({ target, propertyKey, descriptor }, DecoratorType.onException, exceptionFilter);
|
|
2018
|
+
};
|
|
2019
|
+
}
|
|
2020
|
+
|
|
1787
2021
|
function setEnvInfo(envTsDefinition, envValueInfo) {
|
|
1788
2022
|
if (envTsDefinition && envValueInfo) {
|
|
1789
2023
|
commonContainer.setEnvTsDefinition(envTsDefinition);
|
|
@@ -1831,30 +2065,40 @@ function getTokenTypeName(token) {
|
|
|
1831
2065
|
return key.slice(separatorIndex + 1);
|
|
1832
2066
|
}
|
|
1833
2067
|
|
|
1834
|
-
function registerLifetime(targetConstructor, lifetime) {
|
|
2068
|
+
function registerLifetime(targetConstructor, sourceFile, lifetime) {
|
|
1835
2069
|
if (lifetime === Lifetime.Singleton) {
|
|
1836
|
-
nattyServiceResolver.addSingleton(targetConstructor);
|
|
2070
|
+
nattyServiceResolver.addSingleton(targetConstructor, void 0, void 0, sourceFile);
|
|
1837
2071
|
return;
|
|
1838
2072
|
}
|
|
1839
2073
|
if (lifetime === Lifetime.Scoped) {
|
|
1840
|
-
nattyServiceResolver.addScoped(targetConstructor);
|
|
2074
|
+
nattyServiceResolver.addScoped(targetConstructor, void 0, void 0, sourceFile);
|
|
1841
2075
|
return;
|
|
1842
2076
|
}
|
|
1843
2077
|
if (lifetime === Lifetime.Transient) {
|
|
1844
|
-
nattyServiceResolver.addTransient(targetConstructor);
|
|
2078
|
+
nattyServiceResolver.addTransient(targetConstructor, void 0, void 0, sourceFile);
|
|
1845
2079
|
}
|
|
1846
2080
|
}
|
|
1847
|
-
function registerAliasTypeName(token) {
|
|
2081
|
+
function registerAliasTypeName(token, sourceFile) {
|
|
1848
2082
|
const typeName = getTokenTypeName(token);
|
|
1849
2083
|
if (typeName) {
|
|
1850
2084
|
commonContainer.setMetadata(typeName, token, "services");
|
|
2085
|
+
if (sourceFile)
|
|
2086
|
+
nattyServiceResolver.trackMetadataKey(sourceFile, typeName);
|
|
1851
2087
|
}
|
|
1852
2088
|
}
|
|
1853
2089
|
function registerDiToken(targetConstructor, token, options = {}) {
|
|
2090
|
+
const sourceFile = getRegistrationSourceFile();
|
|
1854
2091
|
commonContainer.setMetadata(targetConstructor.name, targetConstructor, "services");
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
2092
|
+
if (sourceFile)
|
|
2093
|
+
nattyServiceResolver.trackMetadataKey(sourceFile, targetConstructor.name);
|
|
2094
|
+
registerAliasTypeName(token, sourceFile);
|
|
2095
|
+
registerLifetime(targetConstructor, sourceFile, options.lifetime);
|
|
2096
|
+
nattyServiceResolver.addTransient(
|
|
2097
|
+
token,
|
|
2098
|
+
void 0,
|
|
2099
|
+
(serviceProvider) => serviceProvider.get(targetConstructor),
|
|
2100
|
+
sourceFile
|
|
2101
|
+
);
|
|
1858
2102
|
}
|
|
1859
2103
|
|
|
1860
2104
|
function di(token, options = {}) {
|
|
@@ -1867,4 +2111,22 @@ function createServiceScope() {
|
|
|
1867
2111
|
return nattyServiceResolver.createScope();
|
|
1868
2112
|
}
|
|
1869
2113
|
|
|
1870
|
-
|
|
2114
|
+
function clearHotReloadRegistrations(files) {
|
|
2115
|
+
for (const filePath of files || []) {
|
|
2116
|
+
const result = nattyServiceResolver.clearRegistrationsFromSource(filePath);
|
|
2117
|
+
decoratorStateContainer.clearFromSource(filePath);
|
|
2118
|
+
for (const metadataKey of result.metadataKeys) {
|
|
2119
|
+
commonContainer.deleteMetadataValue(metadataKey, "services");
|
|
2120
|
+
}
|
|
2121
|
+
}
|
|
2122
|
+
}
|
|
2123
|
+
|
|
2124
|
+
function clearHotReloadControllerMetadata(controllerNames) {
|
|
2125
|
+
decoratorStateContainer.clearControllers(controllerNames || []);
|
|
2126
|
+
}
|
|
2127
|
+
|
|
2128
|
+
function replaceRoutes(manifest) {
|
|
2129
|
+
nattyContainer.replaceRoutes(manifest);
|
|
2130
|
+
}
|
|
2131
|
+
|
|
2132
|
+
export { $request, AbstractModelState, AcceptedException, AcceptedResult, BadRequestResult, BaseController, BaseResult, ConflictResult, CreateProblemDetail, CreatedResult, Delete, FileResult, ForbiddenAccessException, ForbiddenAccessInfoResult, HttpBadRequestException, HttpConflictException, HttpContext, HttpException, HttpHandler, HttpNotFoundException, HttpResponse, HttpStatusCode, HttpUnprocessableEntityException, Lifetime, ModelBindingContext, NoContentResult, NotFoundResult, OkResult, ProblemDetailsException, ProblemResult, RedirectException, RedirectPermanentException, RedirectResult, Results, RunOn, TooManyRequestsException, TooManyRequestsResult, UnAuthorizedResult, UnauthorizedAccessException, UnprocessableEntityResult, ValidationProblemDetailsException, accepted, anonymous, authenticationOnly, authorize, badRequest, clearHotReloadControllerMetadata, clearHotReloadRegistrations, conflict, createServiceScope, created, createdAt, createdWith, defineNattyConfig, di, entityContainer, file, filter, forbiddenAccess, forbiddenAccessInfo, get, init, injectable, noContent, notFound, notFoundWith, ok, onException, post, problem, put, redirect, redirectPermanent, registerDecorator, replaceRoutes, route, scoped, setEnvInfo, singleton, tooManyRequests, transient, unAuthorized, unprocessableEntity, useFilter, validationProblem };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nattyjs/core",
|
|
3
|
-
"version": "0.0.1-beta.
|
|
3
|
+
"version": "0.0.1-beta.66",
|
|
4
4
|
"description": "",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"author": "ajayojha",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"reflect-metadata": "0.2.2",
|
|
19
19
|
"path-to-regexp": "6.2.1",
|
|
20
|
-
"@nattyjs/common": "0.0.1-beta.
|
|
20
|
+
"@nattyjs/common": "0.0.1-beta.66"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"unbuild": "1.2.1"
|