{"_id":"@divstake-nestjs/di","_rev":"3-d14ed16687999a9deecbf4716d817a5a","name":"@divstake-nestjs/di","dist-tags":{"latest":"0.0.2"},"versions":{"0.0.0-semantic-release":{"name":"@divstake-nestjs/di","version":"0.0.0-semantic-release","keywords":["divstake","divstake-nestjs","divstake-nestjs-modules","skaibaLab","di"],"license":"MIT","_id":"@divstake-nestjs/di@0.0.0-semantic-release","maintainers":[{"name":"skaibalab","email":"skaibalab@gmail.com"}],"homepage":"https://github.com/skaibaLab/divstake-nestjs-modules","bugs":{"url":"https://github.com/skaibaLab/divstake-nestjs-modules/issues"},"dist":{"shasum":"ccf275d7e57e95e3aa543d7a33ad0f5c57eb28a1","tarball":"https://registry.npmjs.org/@divstake-nestjs/di/-/di-0.0.0-semantic-release.tgz","fileCount":20,"integrity":"sha512-qbvnPEQmhPVHVd25D+J9YQqYFe413ve6HjweTSSW9RVT+Tf872o6mDD1qf2Dk4UBYSd1Jss8wwAri4j3uclzTA==","signatures":[{"sig":"MEYCIQCx9nuVGphVXpSYMqi08lglfWeYt5/y8ipvTuzIO47m+wIhAO8gENzuRRjGra8Bmisuz6bqqrdnmhwBlrlzD/bYofzE","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":14930},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"8dd313c39120dfa32d4e8b5adf40619bf2da0ead","_npmUser":{"name":"skaibalab","email":"skaibalab@gmail.com"},"repository":{"url":"git+https://github.com/skaibaLab/divstake-nestjs-modules.git","type":"git","directory":"packages/di"},"_npmVersion":"10.9.3","description":"NestJS Dependency Injection runtime helpers for Lido Finance projects. Part of [DivStake NestJS Modules](https://github.com/skaibaLab/divstake-nestjs-modules/#readme)","directories":{},"sideEffects":false,"_nodeVersion":"22.19.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"^7.5.2","@nestjs/core":"^8.2.5","@nestjs/common":"^8.2.5","@nestjs/testing":"^8.2.5","reflect-metadata":"^0.1.13"},"peerDependencies":{"rxjs":"^7.5.2","tslib":"^2.3.1","@nestjs/core":"^8.2.5","@nestjs/common":"^8.2.5","reflect-metadata":"^0.1.13"},"_npmOperationalInternal":{"tmp":"tmp/di_0.0.0-semantic-release_1759981446969_0.34067560619883364","host":"s3://npm-registry-packages-npm-production"}},"0.0.1":{"name":"@divstake-nestjs/di","version":"0.0.1","keywords":["divstake","divstake-nestjs","divstake-nestjs-modules","skaibaLab","di"],"license":"MIT","_id":"@divstake-nestjs/di@0.0.1","maintainers":[{"name":"skaibalab","email":"skaibalab@gmail.com"}],"homepage":"https://github.com/skaibaLab/divstake-nestjs-modules","bugs":{"url":"https://github.com/skaibaLab/divstake-nestjs-modules/issues"},"dist":{"shasum":"11e4d4ce0af51d8cb7892d70da004c32c836728b","tarball":"https://registry.npmjs.org/@divstake-nestjs/di/-/di-0.0.1.tgz","fileCount":20,"integrity":"sha512-19VnpDIFtMqiWPEbrbYpTl66Qe77ISfvOAkCSsuYbGM+nadPPE70unC/yACMXhKR8XWXZxtzujcKquM8h+jPQw==","signatures":[{"sig":"MEYCIQCO7zYUhAbnJbaMZxdbINPDMHjMMjJ3twlsjnIt/4twXgIhALkmwkcwror0WWnbABUpaevHGW4KwKDboY8pGvfjzDlK","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":14913},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"5ee9938ecb765bc4f78ba15194123946b7237641","_npmUser":{"name":"skaibalab","email":"skaibalab@gmail.com"},"repository":{"url":"git+https://github.com/skaibaLab/divstake-nestjs-modules.git","type":"git","directory":"packages/di"},"_npmVersion":"10.9.3","description":"NestJS Dependency Injection runtime helpers for Lido Finance projects. Part of [DivStake NestJS Modules](https://github.com/skaibaLab/divstake-nestjs-modules/#readme)","directories":{},"sideEffects":false,"_nodeVersion":"22.19.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"^7.5.2","@nestjs/core":"^8.2.5","@nestjs/common":"^8.2.5","@nestjs/testing":"^8.2.5","reflect-metadata":"^0.1.13"},"peerDependencies":{"rxjs":"^7.5.2","tslib":"^2.3.1","@nestjs/core":"^8.2.5","@nestjs/common":"^8.2.5","reflect-metadata":"^0.1.13"},"_npmOperationalInternal":{"tmp":"tmp/di_0.0.1_1762582268329_0.3917637680510946","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@divstake-nestjs/di","version":"0.0.2","main":"dist/index.js","types":"dist/index.d.ts","license":"MIT","homepage":"https://github.com/skaibaLab/divstake-nestjs-modules","repository":{"type":"git","url":"git+https://github.com/skaibaLab/divstake-nestjs-modules.git","directory":"packages/di"},"bugs":{"url":"https://github.com/skaibaLab/divstake-nestjs-modules/issues"},"sideEffects":false,"keywords":["divstake","divstake-nestjs","divstake-nestjs-modules","skaibaLab","di"],"publishConfig":{"registry":"https://registry.npmjs.org/","access":"public"},"peerDependencies":{"@nestjs/common":"^8.2.5","@nestjs/core":"^8.2.5","reflect-metadata":"^0.1.13","rxjs":"^7.5.2","tslib":"^2.3.1"},"devDependencies":{"@nestjs/common":"^8.2.5","@nestjs/core":"^8.2.5","@nestjs/testing":"^8.2.5","reflect-metadata":"^0.1.13","rxjs":"^7.5.2"},"_id":"@divstake-nestjs/di@0.0.2","gitHead":"bb1942a047092f57ccc3ac0da1f0a1be94150426","description":"NestJS Dependency Injection runtime helpers for Lido Finance projects. Part of [DivStake NestJS Modules](https://github.com/skaibaLab/divstake-nestjs-modules/#readme)","_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-m11FQS4JjQg9XNZVLtLS/QI9vVNXIA7iUFoWHP4SN6IkUHDK7x1F+t2rRMU3m84zWIgU0RB5R68HQ7tv9383eQ==","shasum":"67bfe9f13332d82edf9d4efbb79c4893b76a21a7","tarball":"https://registry.npmjs.org/@divstake-nestjs/di/-/di-0.0.2.tgz","fileCount":20,"unpackedSize":14913,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIFwSTCdb20Dpw/SohDDOCzAFc+8xvsyjBa53teLCh9MuAiBDX3hxsjiokeOv+veRHntZrQR8mH50ONrDzjNrdDcnHA=="}]},"_npmUser":{"name":"skaibalab","email":"skaibalab@gmail.com"},"directories":{},"maintainers":[{"name":"skaibalab","email":"skaibalab@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/di_0.0.2_1777867155226_0.029100050110077103"},"_hasShrinkwrap":false}},"time":{"created":"2025-10-09T03:44:06.898Z","modified":"2026-05-04T03:59:15.500Z","0.0.0-semantic-release":"2025-10-09T03:44:07.141Z","0.0.1":"2025-11-08T06:11:08.529Z","0.0.2":"2026-05-04T03:59:15.372Z"},"bugs":{"url":"https://github.com/skaibaLab/divstake-nestjs-modules/issues"},"license":"MIT","homepage":"https://github.com/skaibaLab/divstake-nestjs-modules","keywords":["divstake","divstake-nestjs","divstake-nestjs-modules","skaibaLab","di"],"repository":{"type":"git","url":"git+https://github.com/skaibaLab/divstake-nestjs-modules.git","directory":"packages/di"},"description":"NestJS Dependency Injection runtime helpers for Lido Finance projects. Part of [DivStake NestJS Modules](https://github.com/skaibaLab/divstake-nestjs-modules/#readme)","maintainers":[{"name":"skaibalab","email":"skaibalab@gmail.com"}],"readme":"# Nest JS Dependency Injection runtime helpers\n\nNestJS Dependency Injection runtime helpers for Lido Finance projects.\nPart of [DivStake NestJS Modules](https://github.com/skaibaLab/divstake-nestjs-modules/#readme)\n\n## Install\n\n```bash\nyarn add @divstake-nestjs/di\n```\n\n## Motivation\n\nThis module exists to solve following things:\n\n1. the lack of runtime interfaces in Typescript\n2. necessity of `@Inject` decorators for constructor arguments when working with NestJS\n3. use of `Symbol` to point to specific implementation when working with NestJS\n\n## The problem\n\nWhen working with NestJS in case you need two different implementations of one interface,\nyou have to introduce multiple tokens (symbols), which point to different implementations.\n\n```ts\n// bar-service.interface.ts\nexport interface BarServiceInterface {\n  someMethod(): string;\n}\n```\n\n```ts\n// bar-service-a.ts\nexport const BarServiceAToken = Symbol();\n\nexport class BarServiceA implements BarServiceInterface {\n  someMethod(): string {\n    return 'BarServiceA';\n  }\n}\n```\n\n```ts\n// bar-service-b.ts\nexport const BarServiceBToken = Symbol();\n\nexport class BarServiceB implements BarServiceInterface {\n  someMethod(): string {\n    return 'BarServiceB';\n  }\n}\n```\n\n```ts\n// foo-service.ts\nimport { Inject, Injectable } from '@nestjs/common';\nimport { BarServiceInterface } from './bar-service.interface';\nimport { BarServiceAToken } from './bar-service-a';\nimport { BarServiceBToken } from './bar-service-b';\n\n@Injectable()\nexport class FooService {\n  // it's necessary to inject `BarServiceAToken` symbol here to point to specific implementation\n  public constructor(\n    @Inject(BarServiceAToken) private barService: BarServiceInterface,\n  ) {}\n\n  public checkInstanceOf() {\n    // this is impossible because Typescript types do not exist in runtime\n    this.barService instanceof BarServiceInterface;\n  }\n}\n```\n\n## Solution\n\nModule exposes two primitives:\n\n1. `createInterface<I>(nameOfInterface: string): InterfaceTag<I>` function.\n\nCreates special interface-like anonymous class `InterfaceTag` that acts like an interface\nutilizing `Symbol.hasInstance` method that allows to override behavior of `instanceof` operator.\n\n2. `@ImplementsAtRuntime<T>(interfaceTag: InterfaceTag<T>): ClassDecorator` class decorator\n\nClass decorator indicating that class implements interface at runtime with the help of `Reflect`.\nNeeded for proper work of `instanceof` operator for class instances.\n\n## Usage\n\n### Basic usage\n\n```ts\nimport { createInterface, ImplementsAtRuntime } from '@divstake-nestjs/di';\n\ninterface FooInterface {\n  foo(): string;\n}\n\ninterface BarInterface {\n  bar(): number;\n}\n\nconst FooInterface = createInterface<FooInterface>('FooInterface');\nconst BarInterface = createInterface<BarInterface>('BarInterface');\n\n@ImplementsAtRuntime(FooInterface)\nexport class FooBar implements FooInterface, BarInterface {\n  bar(): number {\n    return 2;\n  }\n\n  foo(): string {\n    return 'bar';\n  }\n}\n\nconst foobar = new FooBar();\n\nconsole.log(foobar instanceof FooInterface === true); // true\nconsole.log(foobar instanceof BarInterface === true); // true\n```\n\n### Nest.js usage\n\n```ts\n// service.interface.ts\nimport { createInterface } from '@divstake-nestjs/di';\n\nexport interface ServiceInterface {\n  doSmth(): string;\n}\n// the interface name and the name of the constant should be the same\nexport const ServiceInterface =\n  createInterface<ServiceInterface>('ServiceInterface');\n```\n\n```ts\n// service.ts\nimport { ImplementsAtRuntime } from '@divstake-nestjs/di';\nimport { Injectable } from '@nestjs/common';\n\n// here, we are importing the type and the constant in one variable 'ServiceInterface'\nimport { ServiceInterface } from './service.interface';\n\n@Injectable()\n@ImplementsAtRuntime(ServiceInterface)\nexport class ServiceA implements ServiceInterface {\n  doSmth(): string {\n    return 'serviceA';\n  }\n}\n\n@Injectable()\n@ImplementsAtRuntime(ServiceInterface)\nexport class ServiceB implements ServiceInterface {\n  doSmth(): string {\n    return 'serviceB';\n  }\n}\n```\n\n```ts\n// service.module.ts\nimport { Injectable } from '@nestjs/common';\nimport { ServiceA, ServiceB } from './service';\nimport { ServiceInterface } from './service.interface';\n\nexport interface ServiceModuleOptions {\n  service: 'A' | 'B';\n}\n\n@Module({})\nexport class ServiceModule {\n  static forRoot(options?: ServiceModuleOptions): DynamicModule {\n    return {\n      global: true,\n      ...this.forFeature(options),\n    };\n  }\n\n  static forFeature(options?: ServiceModuleOptions): DynamicModule {\n    return {\n      module: ServiceModule,\n      // depending on the options module can provide\n      // different immplementation for `ServiceInterface`\n      providers: [\n        options?.service === 'A'\n          ? {\n              provide: ServiceInterface,\n              useClass: ServiceA,\n            }\n          : {\n              provide: ServiceInterface,\n              useClass: ServiceB,\n            },\n      ],\n      exports: [ServiceInterface],\n    };\n  }\n}\n```\n\n```ts\n// some-other-service.ts\nexport class SomeOtherService {\n  // no `@Inject` decorator here\n  public constructor(private service: ServiceInterface) {}\n\n  public someMethod() {\n    // implementation of doSmth depends on `ServiceModuleOptions` value\n    this.service.doSmth();\n  }\n}\n```\n","readmeFilename":"README.md"}