Socket
Socket
Sign inDemoInstall

rsdi

Package Overview
Dependencies
Maintainers
1
Versions
41
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

rsdi - npm Package Compare versions

Comparing version 2.0.0 to 2.1.0

resolvers/FunctionResolver.d.ts

2

DefinitionName.d.ts

@@ -1,2 +0,2 @@

import { ResolverName } from "./DIContainer";
import { ResolverName } from "./types";
export declare function definitionNameToString(definitionName: ResolverName): string;

@@ -1,31 +0,9 @@

import { DependencyResolver } from "./DependencyResolver";
export interface ClassOf<C extends Object> {
new (...args: any[]): C;
}
/**
* Dependency injection container interface to expose
*/
export interface IDIContainer<ContainerResolvers extends INamedResolvers = {}> {
get: <Custom = void, Name extends ResolverName = ResolverName>(dependencyName: Name) => ResolvedType<Custom, Name, ContainerResolvers>;
}
import { DependencyResolver, IDIContainer, ResolvedType, ResolverName } from "./types";
interface INamedResolvers {
[k: string]: DependencyResolver | any;
}
declare type Resolve<N extends DependencyResolver> = N extends {
resolve(...args: any[]): infer R;
} ? R : never;
export declare type ResolverName = string | {
name: string;
};
/**
* Defines the type of resolved dependency
* - if Custom type is given - it will be returned
* - if name of Class is provided - instance type will be returned
* - if function is provided - function return type will be returned
*/
declare type ResolvedType<Custom, Name extends ResolverName, NamedResolvers extends INamedResolvers> = Custom extends void ? Name extends string ? NamedResolvers[Name] extends DependencyResolver ? Resolve<NamedResolvers[Name]> : NamedResolvers[Name] : Name extends ClassOf<any> ? InstanceType<Name> : Name extends (...args: any) => infer FT ? FT : never : Custom;
/**
* Dependency injection container
*/
export default class DIContainer<ContainerResolvers extends INamedResolvers = {}> implements IDIContainer<ContainerResolvers> {
export default class DIContainer implements IDIContainer {
private resolvers;

@@ -38,3 +16,3 @@ private resolved;

*/
get<Custom = void, Name extends ResolverName = ResolverName>(dependencyName: Name, parentDeps?: string[]): ResolvedType<Custom, Name, ContainerResolvers>;
get<Custom = void, Name extends ResolverName = string>(dependencyName: Name, parentDeps?: string[]): ResolvedType<Custom, Name>;
/**

@@ -44,3 +22,3 @@ * Adds multiple dependency resolvers to the container

*/
add<N extends INamedResolvers>(this: DIContainer<ContainerResolvers>, resolvers: N): asserts this is DIContainer<ContainerResolvers & N>;
add(resolvers: INamedResolvers): void;
/**

@@ -53,2 +31,6 @@ * Adds single dependency definition to the container

}
/**
* Resolves given function parameters
*/
export declare function resolveFunctionParameters(diContainer: IDIContainer, parameters?: Array<DependencyResolver<any> | any>, parentDeps?: string[]): any[];
export {};

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

Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveFunctionParameters = void 0;
var AbstractResolver_1 = __importDefault(require("./resolvers/AbstractResolver"));

@@ -73,2 +74,16 @@ var RawValueResolver_1 = __importDefault(require("./resolvers/RawValueResolver"));

exports.default = DIContainer;
/**
* Resolves given function parameters
*/
function resolveFunctionParameters(diContainer, parameters, parentDeps) {
if (parameters === void 0) { parameters = []; }
if (parentDeps === void 0) { parentDeps = []; }
return parameters.map(function (parameter) {
if (parameter instanceof AbstractResolver_1.default) {
return parameter.resolve(diContainer, parentDeps);
}
return parameter;
});
}
exports.resolveFunctionParameters = resolveFunctionParameters;
//# sourceMappingURL=DIContainer.js.map

@@ -1,4 +0,5 @@

import DIContainer, { IDIContainer } from "./DIContainer";
import { diObject as object, diValue as value, diUse as use, diFactory as factory } from "./resolversShorthands";
import DIContainer from "./DIContainer";
import { diObject as object, diValue as value, diUse as use, diFactory as factory, diFunc as func } from "./resolversShorthands";
import { IDIContainer } from "./types";
export default DIContainer;
export { object, value, use, factory, IDIContainer };
export { object, value, use, func, factory, IDIContainer };

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

Object.defineProperty(exports, "__esModule", { value: true });
exports.factory = exports.use = exports.value = exports.object = void 0;
exports.factory = exports.func = exports.use = exports.value = exports.object = void 0;
var DIContainer_1 = __importDefault(require("./DIContainer"));

@@ -14,3 +14,4 @@ var resolversShorthands_1 = require("./resolversShorthands");

Object.defineProperty(exports, "factory", { enumerable: true, get: function () { return resolversShorthands_1.diFactory; } });
Object.defineProperty(exports, "func", { enumerable: true, get: function () { return resolversShorthands_1.diFunc; } });
exports.default = DIContainer_1.default;
//# sourceMappingURL=index.js.map
{
"name": "rsdi",
"version": "2.0.0",
"description": "Simple dependency injection container for JavaScript/TypeScript",
"scripts": {
"test": "jest",
"format": "prettier 'src/**/*.ts' --write",
"build": "tsc",
"build-prod": "rm -Rf ./dist/* && NODE_ENV=production tsc --build tsconfig.json && cp README.md package.json dist/"
},
"keywords": [
"dependency injection",
"dependency",
"injection",
"ioc",
"container",
"javascript",
"typescript"
],
"homepage": "https://github.com/radzserg/rsdi",
"author": "Sergey Radzishevskii <radzserg@gmail.com>",
"license": "ISC",
"husky": {
"hooks": {
"pre-commit": "lint-staged"
"name": "rsdi",
"version": "2.1.0",
"description": "Simple dependency injection container for JavaScript/TypeScript",
"scripts": {
"test": "jest",
"format": "prettier 'src/**/*.ts' --write",
"build": "tsc",
"build-prod": "rm -Rf ./dist/* && NODE_ENV=production tsc --build tsconfig.json && cp README.md package.json dist/",
"pre-commit": "lint-staged"
},
"keywords": [
"dependency injection",
"dependency",
"injection",
"ioc",
"container",
"javascript",
"typescript"
],
"homepage": "https://github.com/radzserg/rsdi",
"author": "Sergey Radzishevskii <radzserg@gmail.com>",
"license": "ISC",
"lint-staged": {
"src/**/*.ts": "prettier --write --ignore-unknown"
},
"devDependencies": {
"@types/jest": "^26.0.23",
"husky": "^7.0.2",
"jest": "^27.0.6",
"lint-staged": "^11.2.0",
"prettier": "^2.4.1",
"ts-jest": "^27.0.3",
"typescript": "^4.3.5"
}
},
"lint-staged": {
"src/**/*.ts": "prettier --write --ignore-unknown"
},
"devDependencies": {
"@types/jest": "^26.0.23",
"husky": "^7.0.2",
"jest": "^27.0.6",
"lint-staged": "^11.1.2",
"prettier": "^2.4.1",
"ts-jest": "^27.0.3",
"typescript": "^4.3.5"
}
}

@@ -36,6 +36,6 @@ # RSDI - Dependency Injection Container

```typescript
import DIContainer, { object, use, factory, IDIContainer } from "rsdi";
import DIContainer, { object, use, factory, func, IDIContainer } from "rsdi";
export default function configureDI() {
const container: DIContainer = new DIContainer();
const container = new DIContainer();
container.add({

@@ -47,4 +47,4 @@ ENV: "test", // define raw value

),
knex: knex(),
Logger: factory(loggerFactory),
knex: knex(), // keeps raw value
Logger: func(loggerFactory), // lazy function, will be resolved when it will be needed
UsersRepo: factory((container: IDIContainer) => {

@@ -58,3 +58,3 @@ return UsersRepoFactory(container.get("knex"));

An entry point of your application will include
The entry point of your application will include

@@ -75,4 +75,7 @@ ```typescript

- [Object resolver](#object-resolver)
- [Function resolver](#function-resolver)
- [Factory resolver](#factory-resolver)
- [Advanced Usage](#advanced-usage)
- [Typescript type resolution](#typescript-type-resolution)
- [Dependency declaration](#dependency-declaration)
- [Async factory resolver](#async-factory-resolver)

@@ -112,3 +115,3 @@

const container: DIContainer = new DIContainer();
const container = new DIContainer();
container.add({

@@ -143,3 +146,3 @@ ENV: "PRODUCTION",

// container
const container: DIContainer = new DIContainer();
const container = new DIContainer();
container.add({

@@ -159,9 +162,32 @@ Storage: object(CookieStorage), // constructor without arguments

### Function resolver
Function resolver allows declaring lazy functions. Function will be called when it's actually needed.
```typescript
function UsersRepoFactory(knex: Knex): UsersRepo {
return {
async findById(id: number) {
await knex("users").where({ id });
},
};
}
const container = new DIContainer();
container.add({
DBConnection: knex(/* ... */),
UsersRepoFactory: func(UsersRepoFactory, use("DBConnection")),
});
const userRepo = container.get(UsersRepoFactory);
```
### Factory resolver
You can use factory resolver when you need more flexibility during initialisation. `container: IDIContainer` will be
pass as an argument to the factory method. So you can resolve other dependencies inside the factory function.
Factory resolver is similar to a Function resolver. You can use factory resolver when you need more flexibility
during initialization. `container: IDIContainer` will be passed in as an argument to the factory method. So you can
resolve other dependencies inside the factory function.
```typescript
const container: DIContainer = new DIContainer();
const container = new DIContainer();
container.add({

@@ -182,15 +208,13 @@ BrowserHistory: factory(configureHistory),

## Advanced Usage
### Typescript type resolution
`container.get` resolves type based on a configured container values
`container.get` and `use` helper resolve type based on following convention:
```typescript
container.add({ key1: "value1", key2: 123, Foo: new Foo() });
const s: string = container.get("key1"); // resolved as a given type
const i: number = container.get("key2");
const f: Foo = container.get("Foo");
```
- if given name is class - instance of a class
- if given name is function - return type of function
- if custom generic type is provided - custom type
- otherwise - any
`container.get` and `use` helper resolve type based on a given type name. Convention over configuration.
```typescript

@@ -203,6 +227,8 @@ const container: DIContainer = new DIContainer();

let bar: Bar = container.get(Bar); // types defined based on a given type Bar
let foo: Foo = container.get(Foo); // you can trick TS compiler rsdi relies on COC rule
let foo: Foo = container.get(Foo); // you can trick TS compiler (it's your responsibility)
let foo2: Foo = container.get<Foo>("Foo"); // custom generic type is provided
let foo3: Foo = container.get("Foo"); // any type
```
`use` example
Example: `use` defines type for a class constructor.

@@ -221,3 +247,3 @@ ```typescript

`container.get` and `use` helper resolve type based on a given factory return type.
Example: `container.get` resolve type based on a given factory return type.

@@ -236,11 +262,32 @@ ```typescript

`use` example
### Dependency declaration
RSDI resolves dependencies on a given type. It can be string or function. In the simplest case, you can use strings.
```typescript
function customFunction() {
return { b: 123 };
}
const definition: DependencyResolver<{ b: number }> = use(customFunction);
container.add({
Foo: new Foo(),
});
const foo = container.get<Foo>("Foo");
```
In order to avoid magic strings you can operate with types.
```typescript
const foo = container.get(Foo);
```
RSDI uses `Foo.name` behind the scene that equals to "Foo". Remember that this approach will not work for uglified code.
You can also rename the function Foo => Buzz, and forget to rename the declaration. From that perspective you can
declare dependencies this way.
```typescript
container.add({
[Foo.name]: new Foo(),
[MyFactory.name]: MyFactory(),
});
const foo = container.get(Foo);
const buzz = container.get(MyFactory);
```
### Async factory resolver

@@ -247,0 +294,0 @@

@@ -1,3 +0,2 @@

import { IDIContainer } from "../DIContainer";
import { DependencyResolver } from "../DependencyResolver";
import { DependencyResolver, IDIContainer } from "../types";
/**

@@ -4,0 +3,0 @@ * Keep AbstractResolver so we can use `if (dep instanceof AbstractResolver) ` checks

import AbstractResolver from "./AbstractResolver";
import { IDIContainer } from "../DIContainer";
import { IDIContainer } from "../types";
export declare type Factory = (container: IDIContainer) => any;

@@ -10,3 +10,3 @@ /**

constructor(factory: T);
resolve: (container: IDIContainer, _parentDeps?: string[] | undefined) => ReturnType<T>;
resolve: (container: IDIContainer) => ReturnType<T>;
}

@@ -30,3 +30,3 @@ "use strict";

var _this = _super.call(this) || this;
_this.resolve = function (container, _parentDeps) {
_this.resolve = function (container) {
return _this.factory(container);

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

import AbstractResolver from "./AbstractResolver";
import { ClassOf, IDIContainer } from "../DIContainer";
import { DependencyResolver } from "../DependencyResolver";
declare type WrapWithResolver<T extends any[]> = {
[K in keyof T]: T[K] | DependencyResolver<T[K]>;
};
declare type ParametersWithResolver<T extends (...args: any) => any> = T extends (...args: infer P) => any ? WrapWithResolver<P> : never;
declare type MethodArgs<T extends ClassOf<any>, K extends keyof InstanceType<T>> = ParametersWithResolver<InstanceType<T>[K]>;
import { ClassOf, DependencyResolver, IDIContainer, MethodArgs, WrapWithResolver } from "../types";
/**

@@ -35,2 +29,1 @@ * ObjectDefinition creates objects from the provided class.

}
export {};

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

var errors_1 = require("../errors");
var DIContainer_1 = require("../DIContainer");
/**

@@ -46,9 +47,4 @@ * ObjectDefinition creates objects from the provided class.

if (parentDeps === void 0) { parentDeps = []; }
var deps = _this.deps.map(function (dep) {
if (dep instanceof AbstractResolver_1.default) {
return dep.resolve(diContainer, parentDeps);
}
return dep;
});
var object = new ((_a = _this.constructorFunction).bind.apply(_a, __spreadArray([void 0], deps, false)))();
var constructorParameters = (0, DIContainer_1.resolveFunctionParameters)(diContainer, _this.deps, parentDeps);
var object = new ((_a = _this.constructorFunction).bind.apply(_a, __spreadArray([void 0], constructorParameters, false)))();
_this.methods.forEach(function (method) {

@@ -59,8 +55,3 @@ var methodName = method.methodName, args = method.args;

}
var resolvedArgs = args.map(function (arg) {
if (arg instanceof AbstractResolver_1.default) {
return arg.resolve(diContainer);
}
return arg;
});
var resolvedArgs = (0, DIContainer_1.resolveFunctionParameters)(diContainer, args, parentDeps);
object[methodName].apply(object, resolvedArgs);

@@ -67,0 +58,0 @@ });

import AbstractResolver from "./AbstractResolver";
import { IDIContainer } from "../DIContainer";
import { IDIContainer } from "../types";
/**

@@ -4,0 +4,0 @@ * Refers to existing definition. i.e. definition with provided name must exists in DIContainer

@@ -5,3 +5,4 @@ import ObjectResolver from "./resolvers/ObjectResolver";

import FactoryResolver, { Factory } from "./resolvers/FactoryResolver";
import { ClassOf, ResolverName } from "./DIContainer";
import { ClassOf, ResolverName, WrapWithResolver } from "./types";
import FunctionResolver from "./resolvers/FunctionResolver";
/**

@@ -34,2 +35,9 @@ * ObjectDefinition creates objects from the provided class.

export declare function diFactory<T extends Factory>(factory: T): FactoryResolver<T>;
/**
* FunctionResolver - allows to use custom function with specified parameters, where parameters are references to
* existing dependencies
* @param func
* @param parameters
*/
export declare function diFunc<T extends (...args: any) => any>(func: T, ...parameters: T extends (...args: infer ArgTypes) => any ? WrapWithResolver<ArgTypes> : never): FunctionResolver<T>;
export {};
"use strict";
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
var __importDefault = (this && this.__importDefault) || function (mod) {

@@ -6,3 +15,3 @@ return (mod && mod.__esModule) ? mod : { "default": mod };

Object.defineProperty(exports, "__esModule", { value: true });
exports.diFactory = exports.diUse = exports.diValue = exports.diObject = void 0;
exports.diFunc = exports.diFactory = exports.diUse = exports.diValue = exports.diObject = void 0;
var ObjectResolver_1 = __importDefault(require("./resolvers/ObjectResolver"));

@@ -13,2 +22,3 @@ var RawValueResolver_1 = __importDefault(require("./resolvers/RawValueResolver"));

var DefinitionName_1 = require("./DefinitionName");
var FunctionResolver_1 = __importDefault(require("./resolvers/FunctionResolver"));
// shorthands for Definition classes

@@ -47,2 +57,16 @@ /**

exports.diFactory = diFactory;
/**
* FunctionResolver - allows to use custom function with specified parameters, where parameters are references to
* existing dependencies
* @param func
* @param parameters
*/
function diFunc(func) {
var parameters = [];
for (var _i = 1; _i < arguments.length; _i++) {
parameters[_i - 1] = arguments[_i];
}
return new (FunctionResolver_1.default.bind.apply(FunctionResolver_1.default, __spreadArray([void 0, func], parameters, false)))();
}
exports.diFunc = diFunc;
//# sourceMappingURL=resolversShorthands.js.map

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