@nattyjs/core 0.0.1-beta.60 → 0.0.1-beta.61
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 +203 -39
- package/dist/index.d.ts +79 -3
- package/dist/index.mjs +201 -40
- package/package.json +2 -3
package/dist/index.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const common = require('@nattyjs/common');
|
|
4
|
-
const tsyringe = require('tsyringe');
|
|
5
4
|
const pathToRegexp = require('path-to-regexp');
|
|
5
|
+
require('reflect-metadata');
|
|
6
6
|
|
|
7
7
|
function defineNattyConfig(config) {
|
|
8
8
|
return config;
|
|
@@ -277,6 +277,38 @@ class HttpException extends Error {
|
|
|
277
277
|
}
|
|
278
278
|
}
|
|
279
279
|
|
|
280
|
+
class HttpRequest {
|
|
281
|
+
constructor(http) {
|
|
282
|
+
this.httpRequest = http;
|
|
283
|
+
}
|
|
284
|
+
get cookies() {
|
|
285
|
+
return this.httpRequest.cookies;
|
|
286
|
+
}
|
|
287
|
+
get url() {
|
|
288
|
+
return this.httpRequest.url;
|
|
289
|
+
}
|
|
290
|
+
get method() {
|
|
291
|
+
return this.httpRequest.method;
|
|
292
|
+
}
|
|
293
|
+
get headers() {
|
|
294
|
+
return this.httpRequest.headers;
|
|
295
|
+
}
|
|
296
|
+
get user() {
|
|
297
|
+
return null;
|
|
298
|
+
}
|
|
299
|
+
get body() {
|
|
300
|
+
return this.httpRequest.body;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
class HttpContext {
|
|
305
|
+
constructor(request, context) {
|
|
306
|
+
this.request = new HttpRequest(request);
|
|
307
|
+
this.response = new HttpResponse();
|
|
308
|
+
this.context = context;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
280
312
|
var RequestPipeline = /* @__PURE__ */ ((RequestPipeline2) => {
|
|
281
313
|
RequestPipeline2[RequestPipeline2["onAuthentication"] = 0] = "onAuthentication";
|
|
282
314
|
RequestPipeline2[RequestPipeline2["onAuthorization"] = 1] = "onAuthorization";
|
|
@@ -914,7 +946,7 @@ class AbstractExecutionContext {
|
|
|
914
946
|
this.routeInfo = routeInfo;
|
|
915
947
|
}
|
|
916
948
|
resolveService(instance) {
|
|
917
|
-
return
|
|
949
|
+
return this.context.services.get(instance);
|
|
918
950
|
}
|
|
919
951
|
get request() {
|
|
920
952
|
return this.context.request;
|
|
@@ -1042,7 +1074,7 @@ class RequestProcessor extends RouteParser {
|
|
|
1042
1074
|
}
|
|
1043
1075
|
}
|
|
1044
1076
|
resolveFilter(instance) {
|
|
1045
|
-
return
|
|
1077
|
+
return this.httpContext.services.get(instance);
|
|
1046
1078
|
}
|
|
1047
1079
|
getAuthenticationClass() {
|
|
1048
1080
|
let authentication = void 0;
|
|
@@ -1116,9 +1148,153 @@ class RequestProcessor extends RouteParser {
|
|
|
1116
1148
|
}
|
|
1117
1149
|
}
|
|
1118
1150
|
|
|
1151
|
+
const PARAM_TOKENS_KEY = Symbol.for("natty:di:paramtokens");
|
|
1152
|
+
function getParamTokens(Cls) {
|
|
1153
|
+
return Reflect.getMetadata(PARAM_TOKENS_KEY, Cls);
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
function isClassToken(x) {
|
|
1157
|
+
return typeof x === "function";
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
var Lifetime = /* @__PURE__ */ ((Lifetime2) => {
|
|
1161
|
+
Lifetime2["Singleton"] = "singleton";
|
|
1162
|
+
Lifetime2["Scoped"] = "scoped";
|
|
1163
|
+
Lifetime2["Transient"] = "transient";
|
|
1164
|
+
return Lifetime2;
|
|
1165
|
+
})(Lifetime || {});
|
|
1166
|
+
|
|
1167
|
+
function isDisposable(x) {
|
|
1168
|
+
return x && typeof x.dispose === "function";
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
class NattyScope {
|
|
1172
|
+
constructor(root) {
|
|
1173
|
+
this.root = root;
|
|
1174
|
+
this.scoped = /* @__PURE__ */ new Map();
|
|
1175
|
+
this.disposables = [];
|
|
1176
|
+
}
|
|
1177
|
+
createScope() {
|
|
1178
|
+
return new NattyScope(this.root);
|
|
1179
|
+
}
|
|
1180
|
+
set(token, value) {
|
|
1181
|
+
this.scoped.set(token, value);
|
|
1182
|
+
if (isDisposable(value))
|
|
1183
|
+
this.disposables.push(value);
|
|
1184
|
+
}
|
|
1185
|
+
tryGet(token) {
|
|
1186
|
+
try {
|
|
1187
|
+
return this.get(token);
|
|
1188
|
+
} catch {
|
|
1189
|
+
return void 0;
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
get(token) {
|
|
1193
|
+
if (this.scoped.has(token))
|
|
1194
|
+
return this.scoped.get(token);
|
|
1195
|
+
const desc = this.root._getDescriptor(token);
|
|
1196
|
+
if (!desc) {
|
|
1197
|
+
if (typeof token === "function")
|
|
1198
|
+
return this.root.construct(token, this);
|
|
1199
|
+
throw new Error(`DI: No registration for token: ${String(token)}`);
|
|
1200
|
+
}
|
|
1201
|
+
if (desc.lifetime === Lifetime.Singleton) {
|
|
1202
|
+
return this.root.get(token);
|
|
1203
|
+
}
|
|
1204
|
+
if (desc.lifetime === Lifetime.Scoped) {
|
|
1205
|
+
const created = desc.useFactory ? desc.useFactory(this) : this.root.construct(desc.useClass, this);
|
|
1206
|
+
this.scoped.set(token, created);
|
|
1207
|
+
if (isDisposable(created))
|
|
1208
|
+
this.disposables.push(created);
|
|
1209
|
+
return created;
|
|
1210
|
+
}
|
|
1211
|
+
return desc.useFactory ? desc.useFactory(this) : this.root.construct(desc.useClass, this);
|
|
1212
|
+
}
|
|
1213
|
+
async dispose() {
|
|
1214
|
+
for (let i = this.disposables.length - 1; i >= 0; i--) {
|
|
1215
|
+
const d = this.disposables[i];
|
|
1216
|
+
await d.dispose();
|
|
1217
|
+
}
|
|
1218
|
+
this.disposables.length = 0;
|
|
1219
|
+
this.scoped.clear();
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
class NattyContainer {
|
|
1224
|
+
constructor() {
|
|
1225
|
+
this.regs = /* @__PURE__ */ new Map();
|
|
1226
|
+
this.singletons = /* @__PURE__ */ new Map();
|
|
1227
|
+
}
|
|
1228
|
+
register(token, desc) {
|
|
1229
|
+
this.regs.set(token, desc);
|
|
1230
|
+
}
|
|
1231
|
+
addTransient(token, useClass, useFactory) {
|
|
1232
|
+
this.register(token, { lifetime: Lifetime.Transient, useClass: useClass ?? token, useFactory });
|
|
1233
|
+
}
|
|
1234
|
+
addScoped(token, useClass, useFactory) {
|
|
1235
|
+
this.register(token, { lifetime: Lifetime.Scoped, useClass: useClass ?? token, useFactory });
|
|
1236
|
+
}
|
|
1237
|
+
addSingleton(token, useClass, useFactory) {
|
|
1238
|
+
this.register(token, { lifetime: Lifetime.Singleton, useClass: useClass ?? token, useFactory });
|
|
1239
|
+
}
|
|
1240
|
+
addInstance(token, value) {
|
|
1241
|
+
this.register(token, { lifetime: Lifetime.Singleton, useValue: value });
|
|
1242
|
+
this.singletons.set(token, value);
|
|
1243
|
+
}
|
|
1244
|
+
createScope() {
|
|
1245
|
+
return new NattyScope(this);
|
|
1246
|
+
}
|
|
1247
|
+
set(_token, _value) {
|
|
1248
|
+
throw new Error("Use scope.set(token, value) for per-request instances.");
|
|
1249
|
+
}
|
|
1250
|
+
tryGet(token) {
|
|
1251
|
+
try {
|
|
1252
|
+
return this.get(token);
|
|
1253
|
+
} catch {
|
|
1254
|
+
return void 0;
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
get(token) {
|
|
1258
|
+
const desc = this.regs.get(token);
|
|
1259
|
+
if (!desc) {
|
|
1260
|
+
if (isClassToken(token))
|
|
1261
|
+
return this.construct(token, this);
|
|
1262
|
+
throw new Error(`DI: No registration for token: ${String(token)}`);
|
|
1263
|
+
}
|
|
1264
|
+
if (desc.lifetime === Lifetime.Singleton) {
|
|
1265
|
+
if (desc.useValue !== void 0)
|
|
1266
|
+
return desc.useValue;
|
|
1267
|
+
if (this.singletons.has(token))
|
|
1268
|
+
return this.singletons.get(token);
|
|
1269
|
+
const created = desc.useFactory ? desc.useFactory(this) : this.construct(desc.useClass, this);
|
|
1270
|
+
this.singletons.set(token, created);
|
|
1271
|
+
return created;
|
|
1272
|
+
}
|
|
1273
|
+
throw new Error(
|
|
1274
|
+
`DI: Tried to resolve ${desc.lifetime} service from root container. Use httpContext.services.get(...)`
|
|
1275
|
+
);
|
|
1276
|
+
}
|
|
1277
|
+
construct(Cls, sp) {
|
|
1278
|
+
const paramTypes = Reflect.getMetadata("design:paramtypes", Cls) || [];
|
|
1279
|
+
const overrideTokens = getParamTokens(Cls) || [];
|
|
1280
|
+
const args = paramTypes.map((t, i) => sp.get(overrideTokens[i] ?? t));
|
|
1281
|
+
return new Cls(...args);
|
|
1282
|
+
}
|
|
1283
|
+
_getDescriptor(token) {
|
|
1284
|
+
return this.regs.get(token);
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1288
|
+
const nattyServiceResolver = new NattyContainer();
|
|
1289
|
+
|
|
1119
1290
|
class Resolver extends RequestProcessor {
|
|
1120
1291
|
constructor(httpContext) {
|
|
1121
1292
|
super(httpContext);
|
|
1293
|
+
this.registerDependency();
|
|
1294
|
+
}
|
|
1295
|
+
registerDependency() {
|
|
1296
|
+
this.httpContext.services = nattyServiceResolver.createScope();
|
|
1297
|
+
this.httpContext.services.set(HttpContext, this.httpContext);
|
|
1122
1298
|
}
|
|
1123
1299
|
getControllerInstance() {
|
|
1124
1300
|
const controller = this.routeInfo.controller;
|
|
@@ -1127,7 +1303,7 @@ class Resolver extends RequestProcessor {
|
|
|
1127
1303
|
return instance;
|
|
1128
1304
|
}
|
|
1129
1305
|
resolveClass(classConstruct) {
|
|
1130
|
-
return
|
|
1306
|
+
return nattyServiceResolver.get(classConstruct);
|
|
1131
1307
|
}
|
|
1132
1308
|
resolveConstructorParameters() {
|
|
1133
1309
|
let parameters = [];
|
|
@@ -1261,42 +1437,15 @@ class HttpHandler {
|
|
|
1261
1437
|
}
|
|
1262
1438
|
}
|
|
1263
1439
|
|
|
1264
|
-
class HttpRequest {
|
|
1265
|
-
constructor(http) {
|
|
1266
|
-
this.httpRequest = http;
|
|
1267
|
-
}
|
|
1268
|
-
get cookies() {
|
|
1269
|
-
return this.httpRequest.cookies;
|
|
1270
|
-
}
|
|
1271
|
-
get url() {
|
|
1272
|
-
return this.httpRequest.url;
|
|
1273
|
-
}
|
|
1274
|
-
get method() {
|
|
1275
|
-
return this.httpRequest.method;
|
|
1276
|
-
}
|
|
1277
|
-
get headers() {
|
|
1278
|
-
return this.httpRequest.headers;
|
|
1279
|
-
}
|
|
1280
|
-
get user() {
|
|
1281
|
-
return null;
|
|
1282
|
-
}
|
|
1283
|
-
get body() {
|
|
1284
|
-
return this.httpRequest.body;
|
|
1285
|
-
}
|
|
1286
|
-
}
|
|
1287
|
-
|
|
1288
|
-
class HttpContext {
|
|
1289
|
-
constructor(request, context) {
|
|
1290
|
-
this.request = new HttpRequest(request);
|
|
1291
|
-
this.response = new HttpResponse();
|
|
1292
|
-
this.context = context;
|
|
1293
|
-
}
|
|
1294
|
-
}
|
|
1295
|
-
|
|
1296
1440
|
function injectable(options = {}) {
|
|
1297
1441
|
return (targetConstructor) => {
|
|
1298
|
-
|
|
1299
|
-
|
|
1442
|
+
const lt = options.lifetime ?? Lifetime.Transient;
|
|
1443
|
+
if (lt === Lifetime.Singleton)
|
|
1444
|
+
nattyServiceResolver.addSingleton(targetConstructor);
|
|
1445
|
+
else if (lt === Lifetime.Scoped)
|
|
1446
|
+
nattyServiceResolver.addScoped(targetConstructor);
|
|
1447
|
+
else
|
|
1448
|
+
nattyServiceResolver.addTransient(targetConstructor);
|
|
1300
1449
|
};
|
|
1301
1450
|
}
|
|
1302
1451
|
|
|
@@ -1308,7 +1457,7 @@ function $request(request) {
|
|
|
1308
1457
|
|
|
1309
1458
|
function filter(config) {
|
|
1310
1459
|
return (targetConstructor) => {
|
|
1311
|
-
|
|
1460
|
+
injectable({ lifetime: Lifetime.Transient })(targetConstructor);
|
|
1312
1461
|
};
|
|
1313
1462
|
}
|
|
1314
1463
|
|
|
@@ -1627,6 +1776,18 @@ function authorize(permission) {
|
|
|
1627
1776
|
};
|
|
1628
1777
|
}
|
|
1629
1778
|
|
|
1779
|
+
function scoped(token) {
|
|
1780
|
+
return injectable({ lifetime: Lifetime.Scoped, token });
|
|
1781
|
+
}
|
|
1782
|
+
|
|
1783
|
+
function transient(token) {
|
|
1784
|
+
return injectable({ lifetime: Lifetime.Transient, token });
|
|
1785
|
+
}
|
|
1786
|
+
|
|
1787
|
+
function singleton(token) {
|
|
1788
|
+
return injectable({ lifetime: Lifetime.Singleton, token });
|
|
1789
|
+
}
|
|
1790
|
+
|
|
1630
1791
|
exports.$request = $request;
|
|
1631
1792
|
exports.AbstractModelState = AbstractModelState;
|
|
1632
1793
|
exports.AcceptedException = AcceptedException;
|
|
@@ -1696,8 +1857,11 @@ exports.redirect = redirect;
|
|
|
1696
1857
|
exports.redirectPermanent = redirectPermanent;
|
|
1697
1858
|
exports.registerDecorator = registerDecorator;
|
|
1698
1859
|
exports.route = route;
|
|
1860
|
+
exports.scoped = scoped;
|
|
1699
1861
|
exports.setEnvInfo = setEnvInfo;
|
|
1862
|
+
exports.singleton = singleton;
|
|
1700
1863
|
exports.tooManyRequests = tooManyRequests;
|
|
1864
|
+
exports.transient = transient;
|
|
1701
1865
|
exports.unAuthorized = unAuthorized;
|
|
1702
1866
|
exports.unprocessableEntity = unprocessableEntity;
|
|
1703
1867
|
exports.useFilter = useFilter;
|
package/dist/index.d.ts
CHANGED
|
@@ -279,6 +279,72 @@ declare class HttpResponse {
|
|
|
279
279
|
write(responseInit: HttpResponseInit): void;
|
|
280
280
|
}
|
|
281
281
|
|
|
282
|
+
type DIClassType<T = any> = new (...args: any[]) => T;
|
|
283
|
+
|
|
284
|
+
type Token<T = any> = DIClassType<T> | symbol | string;
|
|
285
|
+
|
|
286
|
+
interface ServiceProvider {
|
|
287
|
+
get<T>(token: Token<T>): T;
|
|
288
|
+
tryGet<T>(token: Token<T>): T | undefined;
|
|
289
|
+
set<T>(token: Token<T>, value: T): void;
|
|
290
|
+
createScope(): Scope;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
interface Scope extends ServiceProvider {
|
|
294
|
+
dispose(): Promise<void> | void;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
type Factory<T = any> = (sp: ServiceProvider) => T;
|
|
298
|
+
|
|
299
|
+
declare enum Lifetime {
|
|
300
|
+
Singleton = "singleton",
|
|
301
|
+
Scoped = "scoped",
|
|
302
|
+
Transient = "transient"
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
type Descriptor<T = any> = {
|
|
306
|
+
lifetime: Lifetime.Singleton;
|
|
307
|
+
useValue?: T;
|
|
308
|
+
useClass?: DIClassType<T>;
|
|
309
|
+
useFactory?: Factory<T>;
|
|
310
|
+
} | {
|
|
311
|
+
lifetime: Lifetime.Scoped;
|
|
312
|
+
useClass?: DIClassType<T>;
|
|
313
|
+
useFactory?: Factory<T>;
|
|
314
|
+
} | {
|
|
315
|
+
lifetime: Lifetime.Transient;
|
|
316
|
+
useClass?: DIClassType<T>;
|
|
317
|
+
useFactory?: Factory<T>;
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
declare class NattyContainer implements ServiceProvider {
|
|
321
|
+
private readonly regs;
|
|
322
|
+
private readonly singletons;
|
|
323
|
+
register<T>(token: Token<T>, desc: Descriptor<T>): void;
|
|
324
|
+
addTransient<T>(token: Token<T>, useClass?: DIClassType<T>, useFactory?: Factory<T>): void;
|
|
325
|
+
addScoped<T>(token: Token<T>, useClass?: DIClassType<T>, useFactory?: Factory<T>): void;
|
|
326
|
+
addSingleton<T>(token: Token<T>, useClass?: DIClassType<T>, useFactory?: Factory<T>): void;
|
|
327
|
+
addInstance<T>(token: Token<T>, value: T): void;
|
|
328
|
+
createScope(): NattyScope;
|
|
329
|
+
set<T>(_token: Token<T>, _value: T): void;
|
|
330
|
+
tryGet<T>(token: Token<T>): T | undefined;
|
|
331
|
+
get<T>(token: Token<T>): T;
|
|
332
|
+
construct<T>(Cls: DIClassType<T>, sp: ServiceProvider): T;
|
|
333
|
+
_getDescriptor<T>(token: Token<T>): Descriptor<T> | undefined;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
declare class NattyScope implements Scope {
|
|
337
|
+
private readonly root;
|
|
338
|
+
private readonly scoped;
|
|
339
|
+
private readonly disposables;
|
|
340
|
+
constructor(root: NattyContainer);
|
|
341
|
+
createScope(): NattyScope;
|
|
342
|
+
set<T>(token: Token<T>, value: T): void;
|
|
343
|
+
tryGet<T>(token: Token<T>): T | undefined;
|
|
344
|
+
get<T>(token: Token<T>): T;
|
|
345
|
+
dispose(): Promise<void>;
|
|
346
|
+
}
|
|
347
|
+
|
|
282
348
|
declare class HttpContext {
|
|
283
349
|
constructor(request: HttpRequestInit, context: any);
|
|
284
350
|
request: HttpRequest;
|
|
@@ -289,6 +355,7 @@ declare class HttpContext {
|
|
|
289
355
|
[key: string]: RouteConfig;
|
|
290
356
|
};
|
|
291
357
|
user: UserIdentity<any>;
|
|
358
|
+
services: NattyScope;
|
|
292
359
|
}
|
|
293
360
|
|
|
294
361
|
declare class HttpHandler {
|
|
@@ -300,8 +367,11 @@ interface HttpModule {
|
|
|
300
367
|
init: (config: NattyConfig) => void;
|
|
301
368
|
}
|
|
302
369
|
|
|
303
|
-
declare function injectable<T = unknown>():
|
|
304
|
-
declare function injectable<T = unknown>(options:
|
|
370
|
+
declare function injectable<T = unknown>(): ClassDecorator;
|
|
371
|
+
declare function injectable<T = unknown>(options: {
|
|
372
|
+
lifetime?: Lifetime;
|
|
373
|
+
token?: Token<T>;
|
|
374
|
+
}): ClassDecorator;
|
|
305
375
|
|
|
306
376
|
declare function $request(request: HttpRequestInit): Promise<HttpResponse>;
|
|
307
377
|
|
|
@@ -614,4 +684,10 @@ declare function authorize(permission: {
|
|
|
614
684
|
|
|
615
685
|
declare function CreateProblemDetail(modelName: string, detail: any): ProblemDetail;
|
|
616
686
|
|
|
617
|
-
|
|
687
|
+
declare function scoped<T = unknown>(): ClassDecorator;
|
|
688
|
+
|
|
689
|
+
declare function transient<T = unknown>(): ClassDecorator;
|
|
690
|
+
|
|
691
|
+
declare function singleton<T = unknown>(): ClassDecorator;
|
|
692
|
+
|
|
693
|
+
export { $request, AbstractModelState, AcceptedException, AcceptedResult, BadRequestResult, BaseController, BaseResult, BuildOptions, ClassTypeInfo, ConflictResult, CreateProblemDetail, CreatedResult, Delete, FileResult, ForbiddenAccessException, ForbiddenAccessInfoResult, HttpBadRequestException, HttpConflictException, HttpContext, HttpException, HttpHandler, HttpModule, HttpNotFoundException, HttpResponse, HttpStatusCode, HttpUnprocessableEntityException, MethodInfo$1 as MethodInfo, ModelBindingContext, NoContentResult, NotFoundResult, OkResult, ParameterInfo, ProblemDetailsException, ProblemResult, RedirectException, RedirectPermanentException, RedirectResult, ResponseExtras, Results, RetryAfter, RunOn, TooManyRequestsException, TooManyRequestsResult, TypeInfo$1 as TypeInfo, UnAuthorizedResult, UnauthorizedAccessException, UnprocessableEntityResult, ValidationProblemDetailsException, accepted, anonymous, authenticationOnly, authorize, badRequest, conflict, created, createdAt, createdWith, defineNattyConfig, entityContainer, file, filter, forbiddenAccess, forbiddenAccessInfo, get, init, injectable, noContent, notFound, notFoundWith, ok, post, problem, put, redirect, redirectPermanent, registerDecorator, route, scoped, setEnvInfo, singleton, tooManyRequests, transient, unAuthorized, unprocessableEntity, useFilter, validationProblem };
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { commonContainer, isObject, List, BLANK as BLANK$1, RIGHT_SLASH } from '@nattyjs/common';
|
|
2
|
-
import { container, injectable as injectable$1 } from 'tsyringe';
|
|
3
2
|
import { match } from 'path-to-regexp';
|
|
3
|
+
import 'reflect-metadata';
|
|
4
4
|
|
|
5
5
|
function defineNattyConfig(config) {
|
|
6
6
|
return config;
|
|
@@ -275,6 +275,38 @@ class HttpException extends Error {
|
|
|
275
275
|
}
|
|
276
276
|
}
|
|
277
277
|
|
|
278
|
+
class HttpRequest {
|
|
279
|
+
constructor(http) {
|
|
280
|
+
this.httpRequest = http;
|
|
281
|
+
}
|
|
282
|
+
get cookies() {
|
|
283
|
+
return this.httpRequest.cookies;
|
|
284
|
+
}
|
|
285
|
+
get url() {
|
|
286
|
+
return this.httpRequest.url;
|
|
287
|
+
}
|
|
288
|
+
get method() {
|
|
289
|
+
return this.httpRequest.method;
|
|
290
|
+
}
|
|
291
|
+
get headers() {
|
|
292
|
+
return this.httpRequest.headers;
|
|
293
|
+
}
|
|
294
|
+
get user() {
|
|
295
|
+
return null;
|
|
296
|
+
}
|
|
297
|
+
get body() {
|
|
298
|
+
return this.httpRequest.body;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
class HttpContext {
|
|
303
|
+
constructor(request, context) {
|
|
304
|
+
this.request = new HttpRequest(request);
|
|
305
|
+
this.response = new HttpResponse();
|
|
306
|
+
this.context = context;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
278
310
|
var RequestPipeline = /* @__PURE__ */ ((RequestPipeline2) => {
|
|
279
311
|
RequestPipeline2[RequestPipeline2["onAuthentication"] = 0] = "onAuthentication";
|
|
280
312
|
RequestPipeline2[RequestPipeline2["onAuthorization"] = 1] = "onAuthorization";
|
|
@@ -912,7 +944,7 @@ class AbstractExecutionContext {
|
|
|
912
944
|
this.routeInfo = routeInfo;
|
|
913
945
|
}
|
|
914
946
|
resolveService(instance) {
|
|
915
|
-
return
|
|
947
|
+
return this.context.services.get(instance);
|
|
916
948
|
}
|
|
917
949
|
get request() {
|
|
918
950
|
return this.context.request;
|
|
@@ -1040,7 +1072,7 @@ class RequestProcessor extends RouteParser {
|
|
|
1040
1072
|
}
|
|
1041
1073
|
}
|
|
1042
1074
|
resolveFilter(instance) {
|
|
1043
|
-
return
|
|
1075
|
+
return this.httpContext.services.get(instance);
|
|
1044
1076
|
}
|
|
1045
1077
|
getAuthenticationClass() {
|
|
1046
1078
|
let authentication = void 0;
|
|
@@ -1114,9 +1146,153 @@ class RequestProcessor extends RouteParser {
|
|
|
1114
1146
|
}
|
|
1115
1147
|
}
|
|
1116
1148
|
|
|
1149
|
+
const PARAM_TOKENS_KEY = Symbol.for("natty:di:paramtokens");
|
|
1150
|
+
function getParamTokens(Cls) {
|
|
1151
|
+
return Reflect.getMetadata(PARAM_TOKENS_KEY, Cls);
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
function isClassToken(x) {
|
|
1155
|
+
return typeof x === "function";
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
var Lifetime = /* @__PURE__ */ ((Lifetime2) => {
|
|
1159
|
+
Lifetime2["Singleton"] = "singleton";
|
|
1160
|
+
Lifetime2["Scoped"] = "scoped";
|
|
1161
|
+
Lifetime2["Transient"] = "transient";
|
|
1162
|
+
return Lifetime2;
|
|
1163
|
+
})(Lifetime || {});
|
|
1164
|
+
|
|
1165
|
+
function isDisposable(x) {
|
|
1166
|
+
return x && typeof x.dispose === "function";
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
class NattyScope {
|
|
1170
|
+
constructor(root) {
|
|
1171
|
+
this.root = root;
|
|
1172
|
+
this.scoped = /* @__PURE__ */ new Map();
|
|
1173
|
+
this.disposables = [];
|
|
1174
|
+
}
|
|
1175
|
+
createScope() {
|
|
1176
|
+
return new NattyScope(this.root);
|
|
1177
|
+
}
|
|
1178
|
+
set(token, value) {
|
|
1179
|
+
this.scoped.set(token, value);
|
|
1180
|
+
if (isDisposable(value))
|
|
1181
|
+
this.disposables.push(value);
|
|
1182
|
+
}
|
|
1183
|
+
tryGet(token) {
|
|
1184
|
+
try {
|
|
1185
|
+
return this.get(token);
|
|
1186
|
+
} catch {
|
|
1187
|
+
return void 0;
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
get(token) {
|
|
1191
|
+
if (this.scoped.has(token))
|
|
1192
|
+
return this.scoped.get(token);
|
|
1193
|
+
const desc = this.root._getDescriptor(token);
|
|
1194
|
+
if (!desc) {
|
|
1195
|
+
if (typeof token === "function")
|
|
1196
|
+
return this.root.construct(token, this);
|
|
1197
|
+
throw new Error(`DI: No registration for token: ${String(token)}`);
|
|
1198
|
+
}
|
|
1199
|
+
if (desc.lifetime === Lifetime.Singleton) {
|
|
1200
|
+
return this.root.get(token);
|
|
1201
|
+
}
|
|
1202
|
+
if (desc.lifetime === Lifetime.Scoped) {
|
|
1203
|
+
const created = desc.useFactory ? desc.useFactory(this) : this.root.construct(desc.useClass, this);
|
|
1204
|
+
this.scoped.set(token, created);
|
|
1205
|
+
if (isDisposable(created))
|
|
1206
|
+
this.disposables.push(created);
|
|
1207
|
+
return created;
|
|
1208
|
+
}
|
|
1209
|
+
return desc.useFactory ? desc.useFactory(this) : this.root.construct(desc.useClass, this);
|
|
1210
|
+
}
|
|
1211
|
+
async dispose() {
|
|
1212
|
+
for (let i = this.disposables.length - 1; i >= 0; i--) {
|
|
1213
|
+
const d = this.disposables[i];
|
|
1214
|
+
await d.dispose();
|
|
1215
|
+
}
|
|
1216
|
+
this.disposables.length = 0;
|
|
1217
|
+
this.scoped.clear();
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
class NattyContainer {
|
|
1222
|
+
constructor() {
|
|
1223
|
+
this.regs = /* @__PURE__ */ new Map();
|
|
1224
|
+
this.singletons = /* @__PURE__ */ new Map();
|
|
1225
|
+
}
|
|
1226
|
+
register(token, desc) {
|
|
1227
|
+
this.regs.set(token, desc);
|
|
1228
|
+
}
|
|
1229
|
+
addTransient(token, useClass, useFactory) {
|
|
1230
|
+
this.register(token, { lifetime: Lifetime.Transient, useClass: useClass ?? token, useFactory });
|
|
1231
|
+
}
|
|
1232
|
+
addScoped(token, useClass, useFactory) {
|
|
1233
|
+
this.register(token, { lifetime: Lifetime.Scoped, useClass: useClass ?? token, useFactory });
|
|
1234
|
+
}
|
|
1235
|
+
addSingleton(token, useClass, useFactory) {
|
|
1236
|
+
this.register(token, { lifetime: Lifetime.Singleton, useClass: useClass ?? token, useFactory });
|
|
1237
|
+
}
|
|
1238
|
+
addInstance(token, value) {
|
|
1239
|
+
this.register(token, { lifetime: Lifetime.Singleton, useValue: value });
|
|
1240
|
+
this.singletons.set(token, value);
|
|
1241
|
+
}
|
|
1242
|
+
createScope() {
|
|
1243
|
+
return new NattyScope(this);
|
|
1244
|
+
}
|
|
1245
|
+
set(_token, _value) {
|
|
1246
|
+
throw new Error("Use scope.set(token, value) for per-request instances.");
|
|
1247
|
+
}
|
|
1248
|
+
tryGet(token) {
|
|
1249
|
+
try {
|
|
1250
|
+
return this.get(token);
|
|
1251
|
+
} catch {
|
|
1252
|
+
return void 0;
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
get(token) {
|
|
1256
|
+
const desc = this.regs.get(token);
|
|
1257
|
+
if (!desc) {
|
|
1258
|
+
if (isClassToken(token))
|
|
1259
|
+
return this.construct(token, this);
|
|
1260
|
+
throw new Error(`DI: No registration for token: ${String(token)}`);
|
|
1261
|
+
}
|
|
1262
|
+
if (desc.lifetime === Lifetime.Singleton) {
|
|
1263
|
+
if (desc.useValue !== void 0)
|
|
1264
|
+
return desc.useValue;
|
|
1265
|
+
if (this.singletons.has(token))
|
|
1266
|
+
return this.singletons.get(token);
|
|
1267
|
+
const created = desc.useFactory ? desc.useFactory(this) : this.construct(desc.useClass, this);
|
|
1268
|
+
this.singletons.set(token, created);
|
|
1269
|
+
return created;
|
|
1270
|
+
}
|
|
1271
|
+
throw new Error(
|
|
1272
|
+
`DI: Tried to resolve ${desc.lifetime} service from root container. Use httpContext.services.get(...)`
|
|
1273
|
+
);
|
|
1274
|
+
}
|
|
1275
|
+
construct(Cls, sp) {
|
|
1276
|
+
const paramTypes = Reflect.getMetadata("design:paramtypes", Cls) || [];
|
|
1277
|
+
const overrideTokens = getParamTokens(Cls) || [];
|
|
1278
|
+
const args = paramTypes.map((t, i) => sp.get(overrideTokens[i] ?? t));
|
|
1279
|
+
return new Cls(...args);
|
|
1280
|
+
}
|
|
1281
|
+
_getDescriptor(token) {
|
|
1282
|
+
return this.regs.get(token);
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
const nattyServiceResolver = new NattyContainer();
|
|
1287
|
+
|
|
1117
1288
|
class Resolver extends RequestProcessor {
|
|
1118
1289
|
constructor(httpContext) {
|
|
1119
1290
|
super(httpContext);
|
|
1291
|
+
this.registerDependency();
|
|
1292
|
+
}
|
|
1293
|
+
registerDependency() {
|
|
1294
|
+
this.httpContext.services = nattyServiceResolver.createScope();
|
|
1295
|
+
this.httpContext.services.set(HttpContext, this.httpContext);
|
|
1120
1296
|
}
|
|
1121
1297
|
getControllerInstance() {
|
|
1122
1298
|
const controller = this.routeInfo.controller;
|
|
@@ -1125,7 +1301,7 @@ class Resolver extends RequestProcessor {
|
|
|
1125
1301
|
return instance;
|
|
1126
1302
|
}
|
|
1127
1303
|
resolveClass(classConstruct) {
|
|
1128
|
-
return
|
|
1304
|
+
return nattyServiceResolver.get(classConstruct);
|
|
1129
1305
|
}
|
|
1130
1306
|
resolveConstructorParameters() {
|
|
1131
1307
|
let parameters = [];
|
|
@@ -1259,42 +1435,15 @@ class HttpHandler {
|
|
|
1259
1435
|
}
|
|
1260
1436
|
}
|
|
1261
1437
|
|
|
1262
|
-
class HttpRequest {
|
|
1263
|
-
constructor(http) {
|
|
1264
|
-
this.httpRequest = http;
|
|
1265
|
-
}
|
|
1266
|
-
get cookies() {
|
|
1267
|
-
return this.httpRequest.cookies;
|
|
1268
|
-
}
|
|
1269
|
-
get url() {
|
|
1270
|
-
return this.httpRequest.url;
|
|
1271
|
-
}
|
|
1272
|
-
get method() {
|
|
1273
|
-
return this.httpRequest.method;
|
|
1274
|
-
}
|
|
1275
|
-
get headers() {
|
|
1276
|
-
return this.httpRequest.headers;
|
|
1277
|
-
}
|
|
1278
|
-
get user() {
|
|
1279
|
-
return null;
|
|
1280
|
-
}
|
|
1281
|
-
get body() {
|
|
1282
|
-
return this.httpRequest.body;
|
|
1283
|
-
}
|
|
1284
|
-
}
|
|
1285
|
-
|
|
1286
|
-
class HttpContext {
|
|
1287
|
-
constructor(request, context) {
|
|
1288
|
-
this.request = new HttpRequest(request);
|
|
1289
|
-
this.response = new HttpResponse();
|
|
1290
|
-
this.context = context;
|
|
1291
|
-
}
|
|
1292
|
-
}
|
|
1293
|
-
|
|
1294
1438
|
function injectable(options = {}) {
|
|
1295
1439
|
return (targetConstructor) => {
|
|
1296
|
-
|
|
1297
|
-
|
|
1440
|
+
const lt = options.lifetime ?? Lifetime.Transient;
|
|
1441
|
+
if (lt === Lifetime.Singleton)
|
|
1442
|
+
nattyServiceResolver.addSingleton(targetConstructor);
|
|
1443
|
+
else if (lt === Lifetime.Scoped)
|
|
1444
|
+
nattyServiceResolver.addScoped(targetConstructor);
|
|
1445
|
+
else
|
|
1446
|
+
nattyServiceResolver.addTransient(targetConstructor);
|
|
1298
1447
|
};
|
|
1299
1448
|
}
|
|
1300
1449
|
|
|
@@ -1306,7 +1455,7 @@ function $request(request) {
|
|
|
1306
1455
|
|
|
1307
1456
|
function filter(config) {
|
|
1308
1457
|
return (targetConstructor) => {
|
|
1309
|
-
injectable
|
|
1458
|
+
injectable({ lifetime: Lifetime.Transient })(targetConstructor);
|
|
1310
1459
|
};
|
|
1311
1460
|
}
|
|
1312
1461
|
|
|
@@ -1625,4 +1774,16 @@ function authorize(permission) {
|
|
|
1625
1774
|
};
|
|
1626
1775
|
}
|
|
1627
1776
|
|
|
1628
|
-
|
|
1777
|
+
function scoped(token) {
|
|
1778
|
+
return injectable({ lifetime: Lifetime.Scoped, token });
|
|
1779
|
+
}
|
|
1780
|
+
|
|
1781
|
+
function transient(token) {
|
|
1782
|
+
return injectable({ lifetime: Lifetime.Transient, token });
|
|
1783
|
+
}
|
|
1784
|
+
|
|
1785
|
+
function singleton(token) {
|
|
1786
|
+
return injectable({ lifetime: Lifetime.Singleton, token });
|
|
1787
|
+
}
|
|
1788
|
+
|
|
1789
|
+
export { $request, AbstractModelState, AcceptedException, AcceptedResult, BadRequestResult, BaseController, BaseResult, ConflictResult, CreateProblemDetail, CreatedResult, Delete, FileResult, ForbiddenAccessException, ForbiddenAccessInfoResult, HttpBadRequestException, HttpConflictException, HttpContext, HttpException, HttpHandler, HttpNotFoundException, HttpResponse, HttpStatusCode, HttpUnprocessableEntityException, ModelBindingContext, NoContentResult, NotFoundResult, OkResult, ProblemDetailsException, ProblemResult, RedirectException, RedirectPermanentException, RedirectResult, Results, RunOn, TooManyRequestsException, TooManyRequestsResult, UnAuthorizedResult, UnauthorizedAccessException, UnprocessableEntityResult, ValidationProblemDetailsException, accepted, anonymous, authenticationOnly, authorize, badRequest, conflict, created, createdAt, createdWith, defineNattyConfig, entityContainer, file, filter, forbiddenAccess, forbiddenAccessInfo, get, init, injectable, noContent, notFound, notFoundWith, ok, post, problem, put, redirect, redirectPermanent, registerDecorator, 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.61",
|
|
4
4
|
"description": "",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"author": "ajayojha",
|
|
@@ -16,9 +16,8 @@
|
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"reflect-metadata": "0.2.2",
|
|
19
|
-
"tsyringe": "^4.7.0",
|
|
20
19
|
"path-to-regexp": "6.2.1",
|
|
21
|
-
"@nattyjs/common": "0.0.1-beta.
|
|
20
|
+
"@nattyjs/common": "0.0.1-beta.61"
|
|
22
21
|
},
|
|
23
22
|
"devDependencies": {
|
|
24
23
|
"unbuild": "1.2.1"
|