@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 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 tsyringe.container.resolve(instance);
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 tsyringe.container.resolve(instance);
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 tsyringe.container.resolve(classConstruct);
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
- tsyringe.injectable()(targetConstructor);
1299
- common.commonContainer.setMetadata(targetConstructor.name, targetConstructor, "services");
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
- tsyringe.injectable()(targetConstructor);
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>(): Function;
304
- declare function injectable<T = unknown>(options: any): Function;
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
- 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, setEnvInfo, tooManyRequests, unAuthorized, unprocessableEntity, useFilter, validationProblem };
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 container.resolve(instance);
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 container.resolve(instance);
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 container.resolve(classConstruct);
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
- injectable$1()(targetConstructor);
1297
- commonContainer.setMetadata(targetConstructor.name, targetConstructor, "services");
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$1()(targetConstructor);
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
- 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, setEnvInfo, tooManyRequests, unAuthorized, unprocessableEntity, useFilter, validationProblem };
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.60",
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.60"
20
+ "@nattyjs/common": "0.0.1-beta.61"
22
21
  },
23
22
  "devDependencies": {
24
23
  "unbuild": "1.2.1"