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

diod

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

diod - npm Package Compare versions

Comparing version 1.0.0-alpha.3 to 1.0.0-rc

lib/diod.es.js

39

lib/diod.d.ts

@@ -32,2 +32,9 @@ /**

get<T>(identifier: Identifier<T>): T;
/**
* Returns service ids for a given tag.
* @param tag The tag name.
* @typeParam T The type of the returned services.
* @returns An array of service identifiers tagged with the given tag.
*/
findTaggedServiceIdentifiers<T = unknown>(tag: string): Array<Identifier<T>>;
}

@@ -56,2 +63,19 @@ /**

*/
interface ConfigurableRegistration {
/**
* The service can be used as a dependency and it can be queried from the container.
* @returns
*/
public(): this;
/**
* The service can only be used as a dependency and it can't be queried from the container.
* @returns
*/
private(): this;
/**
* Tag the service (the tag will be added to previously added tags if there are).
* @returns
*/
addTag(tag: string): this;
}
interface WithScopeChange {

@@ -91,5 +115,5 @@ /**

* @param newable The implementation that the identifier will provide.
* @returns
* @returns Configuration fluent API for classes
*/
useClass(newable: Newable<T>): WithScopeChange & WithDependencies;
useClass(newable: Newable<T>): ConfigurableRegistration & WithScopeChange & WithDependencies;
/**

@@ -101,8 +125,9 @@ * Configure the class implementation that the identifier will provide.

*/
use(newable: Newable<T>): WithScopeChange & WithDependencies;
use(newable: Newable<T>): ConfigurableRegistration & WithScopeChange & WithDependencies;
/**
* Configure the instance that the identifier will provide.
* @param instance The instance that the identifier will provide.
* @returns Configuration fluent API for instances
*/
useInstance(instance: Instance<T>): void;
useInstance(instance: Instance<T>): ConfigurableRegistration;
/**

@@ -113,3 +138,3 @@ * Configure a factory that returns the instance that the identifier will provide.

*/
useFactory(factory: Factory<T>): WithScopeChange;
useFactory(factory: Factory<T>): ConfigurableRegistration & WithScopeChange;
}

@@ -150,3 +175,3 @@

*/
registerAndUse<T>(newable: Newable<T>): WithScopeChange & WithDependencies;
registerAndUse<T>(newable: Newable<T>): ConfigurableRegistration & WithScopeChange & WithDependencies;
/**

@@ -168,2 +193,2 @@ * Builds an inmutable [[Container]].

export { Abstract, BuildOptions, Container, ContainerBuilder, Factory, Identifier, Instance, Newable, Registration, Service, WithDependencies, WithScopeChange };
export { Abstract, BuildOptions, ConfigurableRegistration, Container, ContainerBuilder, Factory, Identifier, Instance, Newable, Registration, Service, WithDependencies, WithScopeChange };

@@ -25,6 +25,9 @@ 'use strict';

get(identifier) {
return this.getService(identifier, new Map());
return this.getService(identifier, new Map(), false);
}
getService(identifier, perRequestServices) {
const data = this.findServiceDataOrThrow(identifier);
findTaggedServiceIdentifiers(tag) {
return Array.from(this.services).filter(([, data]) => data.tags.indexOf(tag) >= 0).map(([id]) => id);
}
getService(identifier, perRequestServices, isDependency) {
const data = this.findServiceDataOrThrow(identifier, isDependency);
if (data.scope === ScopeType.Singleton && this.singletons.has(identifier)) {

@@ -44,4 +47,5 @@ return this.singletons.get(identifier);

get: (id) => {
return this.getService(id, perRequestServices);
}
return this.getService(id, perRequestServices, true);
},
findTaggedServiceIdentifiers: (tag) => this.findTaggedServiceIdentifiers(tag)
});

@@ -56,3 +60,3 @@ }

}
findServiceDataOrThrow(identifier) {
findServiceDataOrThrow(identifier, isDependency) {
const service = this.services.get(identifier);

@@ -62,2 +66,6 @@ if (!service) {

}
const data = service;
if (!isDependency && data.isPrivate) {
throw new Error(`The ${identifier.name} service has been registered as private and can not be directly get from the container`);
}
return service;

@@ -68,3 +76,3 @@ }

for (const dependencyIdentifier of dependencyIdentifiers) {
dependencies.push(this.getService(dependencyIdentifier, perRequestServices));
dependencies.push(this.getService(dependencyIdentifier, perRequestServices, true));
}

@@ -113,2 +121,18 @@ return dependencies;

class ServiceConfiguration {
constructor() {
this.isPrivate = false;
this.tags = [];
}
public() {
this.isPrivate = false;
return this;
}
private() {
this.isPrivate = true;
return this;
}
addTag(tag) {
this.tags = [...this.tags, tag];
return this;
}
asTransient() {

@@ -162,2 +186,4 @@ this.scope = ScopeType.Transient;

return {
tags: this.tags,
isPrivate: this.isPrivate,
scope: this.scope,

@@ -196,2 +222,4 @@ type: RegistrationType.Class,

return {
tags: this.tags,
isPrivate: this.isPrivate,
scope: this.scope,

@@ -220,2 +248,4 @@ type: RegistrationType.Factory,

return {
tags: this.tags,
isPrivate: this.isPrivate,
scope: this.scope,

@@ -251,2 +281,3 @@ type: RegistrationType.Instance,

this.buildable = buildable;
return buildable.instance;
}

@@ -253,0 +284,0 @@ useFactory(factory) {

9

package.json
{
"name": "diod",
"version": "1.0.0-alpha.3",
"version": "1.0.0-rc",
"description": "A very opinionated and different inversion of control container and dependency injector for Typescript, Node.js or browser apps",

@@ -16,3 +16,5 @@ "keywords": [

"main": "lib/diod.js",
"module": "lib/diod.mjs",
"module": "lib/diod.es.js",
"es2015": "lib/diod.es.js",
"browser": "lib/diod.umd.js",
"typings": "lib/diod.d.ts",

@@ -28,2 +30,3 @@ "files": [

"coverage:html": "tap --coverage-report=html",
"coverage:cobertura": "tap --coverage-report=cobertura",
"docs": "rimraf docs/api && typedoc",

@@ -83,5 +86,5 @@ "hook:commit-msg": "commitlint -e",

"limit": "2 kB",
"path": "lib/diod.mjs"
"path": "lib/diod.es.js"
}
]
}

@@ -1,8 +0,13 @@

# DIoD
# DIOD - Dependency Injection On Demand
![DIOD - Dependency Injection On Demand](https://raw.githubusercontent.com/artberri/diod/main/cover.jpg)
[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.0-4baaaa.svg)](./CODE_OF_CONDUCT.md)
[![MIT license](https://img.shields.io/npm/l/diod)](./LICENSE)
[![Build status](https://github.com/artberri/diod/actions/workflows/qa.yml/badge.svg)](https://github.com/artberri/diod/actions)
[![codecov](https://codecov.io/gh/artberri/diod/branch/main/graph/badge.svg?token=AGYQWMUQCA)](https://codecov.io/gh/artberri/diod)
## About
A very opinionated and lightweight (under 1.5kB minified and gzipped) inversion of control container and dependency injector for Node.js or browser apps. It is available for vanilla Javascript usage but its true power will be shown by building Typescript apps.
A very opinionated and lightweight (under 2kB minified and gzipped) inversion of control container and dependency injector for Node.js or browser apps. It is available for vanilla Javascript usage but its true power will be shown by building Typescript apps.

@@ -17,6 +22,6 @@ [Quick Start Guide](#quick-start-guide) |

These are the reasons that have led me to reinvent the wheel and create DIoD:
These are the reasons that have led me to reinvent the wheel and create DIOD:
- I don't like the string-based solutions that current Typescript dependency injection libraries use to bypass the Typescript compiler inabilty to emit Javascript constructs. DIoD autowiring will always be based on constructor typings and property injection will be avoided, even when it implies to work with abstract classes instead of interfaces.
- I don't like to couple my domain or application layers (see [hexagonal arquitecture](<https://en.wikipedia.org/wiki/Hexagonal_architecture_(software)>)) with a dependency injection library. Despite DIoD provides a decorator for ease of usage, you are encouraged to [create and use your own](.docs/custom-decorator.md) keeping your inner layers free of DIoD.
- I don't like the string-based solutions that current Typescript dependency injection libraries use to bypass the Typescript compiler inabilty to emit Javascript constructs. DIOD autowiring will always be based on constructor typings and property injection will be avoided, even when it implies to work with abstract classes instead of interfaces.
- I don't like to couple my domain or application layers (see [hexagonal arquitecture](<https://en.wikipedia.org/wiki/Hexagonal_architecture_(software)>)) with a dependency injection library. Despite DIOD provides a decorator for ease of usage, you are encouraged to [create and use your own](.docs/custom-decorator.md) keeping your inner layers free of DIOD.

@@ -30,7 +35,7 @@ Both reasons are related with some TypeScript constraints: whenever you want to work with type information in runtime (in compiled JS), you inevitably need to use decorators. Even so, you won't be able to have information about interfaces at runtime.

- **Autowire**
When you ask for a service, DIoD reads the type-hints on your constructor and automatically passes the correct service dependencies to it. The same process will be used to create the required dependencies.
When you ask for a service, DIOD reads the type-hints on your constructor and automatically passes the correct service dependencies to it. The same process will be used to create the required dependencies.
- **Custom decorators**
DIoD requires decorators for dependency guessing while autowiring, but it accepts any class decorator if you don't want to use the one it provides.
DIOD requires decorators for dependency guessing while autowiring, but it accepts any class decorator if you don't want to use the one it provides.
- **Compiler**
After all needed services are registered the container needs to be built. During this build, DIoD will check for errors like missing dependencies, wrong configurations or circular dependencies. An inmutable container will be finally created if there aren't any errors in the building.
After all needed services are registered the container needs to be built. During this build, DIOD will check for errors like missing dependencies, wrong configurations or circular dependencies. An inmutable container will be finally created if there aren't any errors in the building.
- **Support for vanilla JS**

@@ -46,11 +51,8 @@ Usage with vanilla Javascript is possible by manually defining service dependencies.

By default every service is transient, but they can be registered as singletons or as 'per request' (the same instance of a service will be used within a single request).
#### Coming soon
- **Visibility**
Creating private services will be allowed. This means creating services not allowed to be directly getted but used only as dependencies.
Services can be marked as private. Private services will be available only as dependencies and they will not be able to be queried from the IoC container.
- **Tagging**
Ability to tag services in the container and to query services based on tags.
- **Auto registration**
A global option that will enable to use service without registering them in the container.
- **Lightweight**
DIOD will be always dependency free and under 2kB.

@@ -86,3 +88,3 @@ ## Quick Start Guide

The Reflect polyfill import should be added only once in your code base and before DIoD is used:
The Reflect polyfill import should be added only once in your code base and before DIOD is used:

@@ -104,3 +106,3 @@ ```sh

All the registered services must be decorated because [this is the only way to make type metadata available at runtime](https://www.typescriptlang.org/tsconfig#emitDecoratorMetadata) in Typescript. DIoD provides the `@Service()` decorator for ease of usage, but you can [create your own decorator](./docs/custom-decorator.md) to avoid coupling your inner arquitecture layers with DIoD.
All the registered services must be decorated because [this is the only way to make type metadata available at runtime](https://www.typescriptlang.org/tsconfig#emitDecoratorMetadata) in Typescript. DIOD provides the `@Service()` decorator for ease of usage, but you can [create your own decorator](./docs/custom-decorator.md) to avoid coupling your inner arquitecture layers with DIOD.

@@ -127,3 +129,3 @@ Imagine that you want to have a class like this:

The **D** of the [SOLID](https://en.wikipedia.org/wiki/SOLID) principles refers to [dependency inversion](https://en.wikipedia.org/wiki/Dependency_inversion_principle). This principle encourages developers to use abstractions to define dependencies in certain situations. Abstractions are usually defined with interfaces in other languages, but Typescript interfaces are not available at runtime and that's why DIoD requires abstract classes for abstractions if you want them to be autowired. More information available in the [Motivation](#motivation) section.
The **D** of the [SOLID](https://en.wikipedia.org/wiki/SOLID) principles refers to [dependency inversion](https://en.wikipedia.org/wiki/Dependency_inversion_principle). This principle encourages developers to use abstractions to define dependencies in certain situations. Abstractions are usually defined with interfaces in other languages, but Typescript interfaces are not available at runtime and that's why DIOD requires abstract classes for abstractions if you want them to be autowired. More information available in the [Motivation](#motivation) section.

@@ -203,11 +205,11 @@ ```ts

A special thanks to every open source contributor that helped or inspired me to create DIoD, including but not limited to all the contributors of the following libraries: [InversifyJS](https://github.com/inversify/InversifyJS), [Node Dependency Injection](https://github.com/zazoomauro/node-dependency-injection), [TSyringe](https://github.com/microsoft/tsyringe), [Autofac](https://github.com/autofac/Autofac), [Ninject](https://github.com/ninject/Ninject) and the [Symfony DependencyInjection Component](https://github.com/symfony/dependency-injection)
A special thanks to every open source contributor that helped or inspired me to create DIOD, including but not limited to all the contributors of the following libraries: [InversifyJS](https://github.com/inversify/InversifyJS), [Node Dependency Injection](https://github.com/zazoomauro/node-dependency-injection), [TSyringe](https://github.com/microsoft/tsyringe), [Autofac](https://github.com/autofac/Autofac), [Ninject](https://github.com/ninject/Ninject) and the [Symfony DependencyInjection Component](https://github.com/symfony/dependency-injection)
## Pronunciation and name origin
DIoD will be pronounced like the English word 'diode' _/ˈdaɪəʊd/_. DIoD is the abbreviation of **Dependency Injection or Die**, which is the first and only thing I was able to elaborate after I realised that the short `diod` package name was free on the NPM registry.
DIOD will be pronounced like the English word 'diode' _/ˈdaɪəʊd/_. DIOD is the abbreviation of **Dependency Injection On Demand**, which is the first I was able to elaborate after I realised that the short `diod` package name was free on the NPM registry.
## License
DIoD is released under the MIT license:
DIOD is released under the MIT license:

@@ -214,0 +216,0 @@ MIT License

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