Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@furystack/inject

Package Overview
Dependencies
Maintainers
1
Versions
151
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@furystack/inject - npm Package Compare versions

Comparing version 6.0.3 to 7.0.0

dist/injectable.spec.js

1

dist/index.js

@@ -6,3 +6,4 @@ "use strict";

tslib_1.__exportStar(require("./injector"), exports);
tslib_1.__exportStar(require("./injected"), exports);
tslib_1.__exportStar(require("./models"), exports);
//# sourceMappingURL=index.js.map

15

dist/injectable.js

@@ -5,3 +5,2 @@ "use strict";

const injector_1 = require("./injector");
require("./reflect-metadata-polyfill");
/**

@@ -21,12 +20,6 @@ * The default options for the injectable classes

return (ctor) => {
const meta = Reflect.getMetadata('design:paramtypes', ctor);
const metaValue = {
dependencies: (meta &&
meta.map((param) => {
return param;
})) ||
[],
options: { ...exports.defaultInjectableOptions, ...options },
};
injector_1.Injector.meta.set(ctor, metaValue);
injector_1.Injector.options.set(ctor, {
...exports.defaultInjectableOptions,
...options,
});
};

@@ -33,0 +26,0 @@ };

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Injector = void 0;
const injectable_1 = require("./injectable");
class Injector {

@@ -43,3 +42,6 @@ constructor() {

}
const meta = Injector.meta.get(ctor);
if (this.cachedSingletons.has(ctor)) {
return this.cachedSingletons.get(ctor);
}
const meta = Injector.options.get(ctor);
if (!meta) {

@@ -53,7 +55,9 @@ throw Error(`No metadata found for '${ctor.name}'. Dependencies: ${dependencies

}
if (meta.options.lifetime === 'singleton') {
const invalidDeps = meta.dependencies
.map((dep) => ({ meta: Injector.meta.get(dep), dep }))
.filter((m) => m.meta && (m.meta.options.lifetime === 'scoped' || m.meta.options.lifetime === 'transient'))
.map((i) => i.meta && `${i.dep.name}:${i.meta.options.lifetime}`);
const { lifetime } = meta;
const injectedFields = Object.entries(Injector.injectableFields.get(ctor) || {});
if (lifetime === 'singleton') {
const invalidDeps = [...injectedFields]
.map(([, dep]) => ({ meta: Injector.options.get(dep), dep }))
.filter((m) => m.meta && (m.meta.lifetime === 'scoped' || m.meta.lifetime === 'transient'))
.map((i) => i.meta && `${i.dep.name}:${i.meta.lifetime}`);
if (invalidDeps.length) {

@@ -63,7 +67,7 @@ throw Error(`Injector error: Singleton type '${ctor.name}' depends on non-singleton injectables: ${invalidDeps.join(',')}`);

}
else if (meta.options.lifetime === 'scoped') {
const invalidDeps = meta.dependencies
.map((dep) => ({ meta: Injector.meta.get(dep), dep }))
.filter((m) => m.meta && m.meta.options.lifetime === 'transient')
.map((i) => i.meta && `${i.dep.name}:${i.meta.options.lifetime}`);
else if (lifetime === 'scoped') {
const invalidDeps = [...injectedFields.values()]
.map(([, dep]) => ({ meta: Injector.options.get(dep), dep }))
.filter((m) => m.meta && m.meta.lifetime === 'transient')
.map((i) => i.meta && `${i.dep.name}:${i.meta.lifetime}`);
if (invalidDeps.length) {

@@ -73,12 +77,12 @@ throw Error(`Injector error: Scoped type '${ctor.name}' depends on transient injectables: ${invalidDeps.join(',')}`);

}
if (this.cachedSingletons.has(ctor)) {
return this.cachedSingletons.get(ctor);
}
const fromParent = meta.options.lifetime === 'singleton' && this.options.parent && this.options.parent.getInstance(ctor);
const fromParent = lifetime === 'singleton' && this.options.parent && this.options.parent.getInstance(ctor);
if (fromParent) {
return fromParent;
}
const deps = meta.dependencies.map((dep) => this.getInstance(dep, [...dependencies, ctor]));
const newInstance = new ctor(...deps);
if (meta.options.lifetime !== 'transient') {
const deps = injectedFields.map(([key, dep]) => [key, this.getInstance(dep, [...dependencies, ctor])]);
const newInstance = new ctor();
deps.forEach(([key, value]) => {
newInstance[key] = value;
});
if (lifetime !== 'transient') {
this.setExplicitInstance(newInstance);

@@ -96,13 +100,2 @@ }

const ctor = key || instance.constructor;
if (!Injector.meta.has(ctor)) {
const meta = Reflect.getMetadata('design:paramtypes', ctor);
Injector.meta.set(ctor, {
dependencies: (meta &&
meta.map((param) => {
return param;
})) ||
[],
options: { ...injectable_1.defaultInjectableOptions, lifetime: 'explicit' },
});
}
if (instance.constructor === this.constructor) {

@@ -130,3 +123,4 @@ throw Error('Cannot set an injector instance as injectable');

*/
Injector.meta = new Map();
Injector.options = new Map();
Injector.injectableFields = new Map();
//# sourceMappingURL=injector.js.map

@@ -6,2 +6,3 @@ "use strict";

const injectable_1 = require("./injectable");
const injected_1 = require("./injected");
const injector_1 = require("./injector");

@@ -13,3 +14,3 @@ describe('Injector', () => {

});
it('Parent should be the default instance, if not specified', () => {
it('Parent should be undefined by default', () => {
const i = new injector_1.Injector();

@@ -19,14 +20,14 @@ expect(i.options.parent).toBeUndefined();

it('Should throw an error on circular dependencies', () => {
var InstanceClass_1;
const i = new injector_1.Injector();
let InstanceClass = class InstanceClass {
constructor(ohgodno) {
this.ohgodno = ohgodno;
/** */
}
let InstanceClass = InstanceClass_1 = class InstanceClass {
};
InstanceClass = tslib_1.__decorate([
(0, injectable_1.Injectable)(),
tslib_1.__metadata("design:paramtypes", [InstanceClass])
tslib_1.__decorate([
(0, injected_1.Injected)(InstanceClass_1),
tslib_1.__metadata("design:type", InstanceClass)
], InstanceClass.prototype, "ohgodno", void 0);
InstanceClass = InstanceClass_1 = tslib_1.__decorate([
(0, injectable_1.Injectable)()
], InstanceClass);
expect(() => i.getInstance(InstanceClass)).toThrow();
expect(() => i.getInstance(InstanceClass)).toThrowError('Circular dependencies found.');
});

@@ -86,15 +87,18 @@ it('Should set and return instance from cache', () => {

let InstanceClass = class InstanceClass {
constructor(injected1, injected2) {
this.injected1 = injected1;
this.injected2 = injected2;
/** */
}
};
tslib_1.__decorate([
(0, injected_1.Injected)(Injected1),
tslib_1.__metadata("design:type", Injected1)
], InstanceClass.prototype, "injected1", void 0);
tslib_1.__decorate([
(0, injected_1.Injected)(Injected2),
tslib_1.__metadata("design:type", Injected2)
], InstanceClass.prototype, "injected2", void 0);
InstanceClass = tslib_1.__decorate([
(0, injectable_1.Injectable)(),
tslib_1.__metadata("design:paramtypes", [Injected1, Injected2])
(0, injectable_1.Injectable)()
], InstanceClass);
expect(i.getInstance(InstanceClass)).toBeInstanceOf(InstanceClass);
expect(i.getInstance(InstanceClass).injected1).toBeInstanceOf(Injected1);
expect(i.getInstance(InstanceClass).injected2).toBeInstanceOf(Injected2);
const instance = i.getInstance(InstanceClass);
expect(instance).toBeInstanceOf(InstanceClass);
expect(instance.injected1).toBeInstanceOf(Injected1);
expect(instance.injected2).toBeInstanceOf(Injected2);
});

@@ -109,19 +113,18 @@ it('Should resolve parameters recursively', () => {

let Injected2 = class Injected2 {
constructor(injected1) {
this.injected1 = injected1;
}
};
tslib_1.__decorate([
(0, injected_1.Injected)(Injected1),
tslib_1.__metadata("design:type", Injected1)
], Injected2.prototype, "injected1", void 0);
Injected2 = tslib_1.__decorate([
(0, injectable_1.Injectable)(),
tslib_1.__metadata("design:paramtypes", [Injected1])
(0, injectable_1.Injectable)()
], Injected2);
let InstanceClass = class InstanceClass {
constructor(injected2) {
this.injected2 = injected2;
/** */
}
};
tslib_1.__decorate([
(0, injected_1.Injected)(Injected2),
tslib_1.__metadata("design:type", Injected2)
], InstanceClass.prototype, "injected2", void 0);
InstanceClass = tslib_1.__decorate([
(0, injectable_1.Injectable)(),
tslib_1.__metadata("design:paramtypes", [Injected2])
(0, injectable_1.Injectable)()
], InstanceClass);

@@ -194,9 +197,9 @@ expect(i.getInstance(InstanceClass)).toBeInstanceOf(InstanceClass);

let St1 = class St1 {
constructor(lt) {
this.lt = lt;
}
};
tslib_1.__decorate([
(0, injected_1.Injected)(Trs1),
tslib_1.__metadata("design:type", Trs1)
], St1.prototype, "lt", void 0);
St1 = tslib_1.__decorate([
(0, injectable_1.Injectable)({ lifetime: 'singleton' }),
tslib_1.__metadata("design:paramtypes", [Trs1])
(0, injectable_1.Injectable)({ lifetime: 'singleton' })
], St1);

@@ -214,9 +217,9 @@ (0, utils_1.using)(new injector_1.Injector(), (i) => {

let St2 = class St2 {
constructor(sc) {
this.sc = sc;
}
};
tslib_1.__decorate([
(0, injected_1.Injected)(Sc1),
tslib_1.__metadata("design:type", Sc1)
], St2.prototype, "sc", void 0);
St2 = tslib_1.__decorate([
(0, injectable_1.Injectable)({ lifetime: 'singleton' }),
tslib_1.__metadata("design:paramtypes", [Sc1])
(0, injectable_1.Injectable)({ lifetime: 'singleton' })
], St2);

@@ -234,9 +237,9 @@ (0, utils_1.using)(new injector_1.Injector(), (i) => {

let Sc2 = class Sc2 {
constructor(sc) {
this.sc = sc;
}
};
tslib_1.__decorate([
(0, injected_1.Injected)(Tr2),
tslib_1.__metadata("design:type", Tr2)
], Sc2.prototype, "sc", void 0);
Sc2 = tslib_1.__decorate([
(0, injectable_1.Injectable)({ lifetime: 'scoped' }),
tslib_1.__metadata("design:paramtypes", [Tr2])
(0, injectable_1.Injectable)({ lifetime: 'scoped' })
], Sc2);

@@ -243,0 +246,0 @@ (0, utils_1.using)(new injector_1.Injector(), (i) => {

{
"name": "@furystack/inject",
"version": "6.0.3",
"version": "7.0.0",
"description": "Core FuryStack package",

@@ -32,7 +32,7 @@ "main": "dist/index.js",

"dependencies": {
"@furystack/utils": "^3.0.3",
"@furystack/utils": "^3.0.4",
"tslib": "^2.4.0"
},
"devDependencies": {
"@types/jest": "^27.5.0"
"@types/jest": "^27.5.2"
},

@@ -39,0 +39,0 @@ "typings": "./types/index.d.ts",

export * from './injectable'
export * from './injector'
export * from './injected'
export * from './models'
import { Injector } from './injector'
import { Constructable } from './models/constructable'
import './reflect-metadata-polyfill'
/**

@@ -28,14 +26,7 @@ * Options for the injectable instance

return <T extends Constructable<any>>(ctor: T) => {
const meta = Reflect.getMetadata('design:paramtypes', ctor)
const metaValue = {
dependencies:
(meta &&
(meta as any[]).map((param) => {
return param
})) ||
[],
options: { ...defaultInjectableOptions, ...options },
}
Injector.meta.set(ctor, metaValue)
Injector.options.set(ctor, {
...defaultInjectableOptions,
...options,
})
}
}
import { Disposable, using, usingAsync } from '@furystack/utils'
import { Injectable } from './injectable'
import { Injected } from './injected'
import { Injector } from './injector'

@@ -11,3 +12,3 @@

it('Parent should be the default instance, if not specified', () => {
it('Parent should be undefined by default', () => {
const i = new Injector()

@@ -21,7 +22,6 @@ expect(i.options.parent).toBeUndefined()

class InstanceClass {
constructor(public ohgodno: InstanceClass) {
/** */
}
@Injected(InstanceClass)
public ohgodno!: InstanceClass
}
expect(() => i.getInstance(InstanceClass)).toThrow()
expect(() => i.getInstance(InstanceClass)).toThrowError('Circular dependencies found.')
})

@@ -74,9 +74,14 @@

class InstanceClass {
constructor(public injected1: Injected1, public injected2: Injected2) {
/** */
}
@Injected(Injected1)
public injected1!: Injected1
@Injected(Injected2)
public injected2!: Injected2
}
expect(i.getInstance(InstanceClass)).toBeInstanceOf(InstanceClass)
expect(i.getInstance(InstanceClass).injected1).toBeInstanceOf(Injected1)
expect(i.getInstance(InstanceClass).injected2).toBeInstanceOf(Injected2)
const instance = i.getInstance(InstanceClass)
expect(instance).toBeInstanceOf(InstanceClass)
expect(instance.injected1).toBeInstanceOf(Injected1)
expect(instance.injected2).toBeInstanceOf(Injected2)
})

@@ -91,3 +96,4 @@

class Injected2 {
constructor(public injected1: Injected1) {}
@Injected(Injected1)
public injected1!: Injected1
}

@@ -97,5 +103,4 @@

class InstanceClass {
constructor(public injected2: Injected2) {
/** */
}
@Injected(Injected2)
public injected2!: Injected2
}

@@ -177,3 +182,4 @@ expect(i.getInstance(InstanceClass)).toBeInstanceOf(InstanceClass)

class St1 {
constructor(public lt: Trs1) {}
@Injected(Trs1)
lt!: Trs1
}

@@ -194,3 +200,4 @@

class St2 {
constructor(public sc: Sc1) {}
@Injected(Sc1)
public sc!: Sc1
}

@@ -211,3 +218,4 @@

class Sc2 {
constructor(public sc: Tr2) {}
@Injected(Tr2)
public sc!: Tr2
}

@@ -214,0 +222,0 @@

import { Disposable } from '@furystack/utils'
import { defaultInjectableOptions } from './injectable'
import { InjectableOptions } from './injectable'
import { Constructable } from './models/constructable'

@@ -39,10 +39,6 @@

*/
public static meta: Map<
Constructable<any>,
{
dependencies: Array<Constructable<any>>
options: import('./injectable').InjectableOptions
}
> = new Map()
public static options: Map<Constructable<any>, InjectableOptions> = new Map()
public static injectableFields: Map<Constructable<any>, { [K: string]: Constructable<any> }> = new Map()
public readonly cachedSingletons: Map<Constructable<any>, any> = new Map()

@@ -62,3 +58,8 @@

}
const meta = Injector.meta.get(ctor)
if (this.cachedSingletons.has(ctor)) {
return this.cachedSingletons.get(ctor) as T
}
const meta = Injector.options.get(ctor)
if (!meta) {

@@ -75,7 +76,11 @@ throw Error(

if (meta.options.lifetime === 'singleton') {
const invalidDeps = meta.dependencies
.map((dep) => ({ meta: Injector.meta.get(dep), dep }))
.filter((m) => m.meta && (m.meta.options.lifetime === 'scoped' || m.meta.options.lifetime === 'transient'))
.map((i) => i.meta && `${i.dep.name}:${i.meta.options.lifetime}`)
const { lifetime } = meta
const injectedFields = Object.entries(Injector.injectableFields.get(ctor) || {})
if (lifetime === 'singleton') {
const invalidDeps = [...injectedFields]
.map(([, dep]) => ({ meta: Injector.options.get(dep), dep }))
.filter((m) => m.meta && (m.meta.lifetime === 'scoped' || m.meta.lifetime === 'transient'))
.map((i) => i.meta && `${i.dep.name}:${i.meta.lifetime}`)
if (invalidDeps.length) {

@@ -88,7 +93,7 @@ throw Error(

}
} else if (meta.options.lifetime === 'scoped') {
const invalidDeps = meta.dependencies
.map((dep) => ({ meta: Injector.meta.get(dep), dep }))
.filter((m) => m.meta && m.meta.options.lifetime === 'transient')
.map((i) => i.meta && `${i.dep.name}:${i.meta.options.lifetime}`)
} else if (lifetime === 'scoped') {
const invalidDeps = [...injectedFields.values()]
.map(([, dep]) => ({ meta: Injector.options.get(dep), dep }))
.filter((m) => m.meta && m.meta.lifetime === 'transient')
.map((i) => i.meta && `${i.dep.name}:${i.meta.lifetime}`)
if (invalidDeps.length) {

@@ -101,13 +106,12 @@ throw Error(

if (this.cachedSingletons.has(ctor)) {
return this.cachedSingletons.get(ctor) as T
}
const fromParent =
meta.options.lifetime === 'singleton' && this.options.parent && this.options.parent.getInstance(ctor)
const fromParent = lifetime === 'singleton' && this.options.parent && this.options.parent.getInstance(ctor)
if (fromParent) {
return fromParent
}
const deps = meta.dependencies.map((dep) => this.getInstance(dep, [...dependencies, ctor]))
const newInstance = new ctor(...deps)
if (meta.options.lifetime !== 'transient') {
const deps = injectedFields.map(([key, dep]) => [key, this.getInstance(dep, [...dependencies, ctor])])
const newInstance = new ctor()
deps.forEach(([key, value]) => {
newInstance[key as keyof T] = value
})
if (lifetime !== 'transient') {
this.setExplicitInstance(newInstance)

@@ -126,14 +130,3 @@ }

const ctor = key || (instance.constructor as Constructable<T>)
if (!Injector.meta.has(ctor)) {
const meta = Reflect.getMetadata('design:paramtypes', ctor)
Injector.meta.set(ctor, {
dependencies:
(meta &&
(meta as any[]).map((param) => {
return param
})) ||
[],
options: { ...defaultInjectableOptions, lifetime: 'explicit' as any },
})
}
if (instance.constructor === this.constructor) {

@@ -140,0 +133,0 @@ throw Error('Cannot set an injector instance as injectable')

export * from './injectable';
export * from './injector';
export * from './injected';
export * from './models';
//# sourceMappingURL=index.d.ts.map
import { Constructable } from './models/constructable';
import './reflect-metadata-polyfill';
/**

@@ -19,3 +18,3 @@ * Options for the injectable instance

*/
export declare const Injectable: (options?: Partial<InjectableOptions> | undefined) => <T extends Constructable<any>>(ctor: T) => void;
export declare const Injectable: (options?: Partial<InjectableOptions>) => <T extends Constructable<any>>(ctor: T) => void;
//# sourceMappingURL=injectable.d.ts.map
import { Disposable } from '@furystack/utils';
import { InjectableOptions } from './injectable';
import { Constructable } from './models/constructable';

@@ -18,5 +19,5 @@ export declare class Injector implements Disposable {

*/
static meta: Map<Constructable<any>, {
dependencies: Array<Constructable<any>>;
options: import('./injectable').InjectableOptions;
static options: Map<Constructable<any>, InjectableOptions>;
static injectableFields: Map<Constructable<any>, {
[K: string]: Constructable<any>;
}>;

@@ -23,0 +24,0 @@ readonly cachedSingletons: Map<Constructable<any>, any>;

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc