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

hekdi

Package Overview
Dependencies
Maintainers
1
Versions
30
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

hekdi - npm Package Compare versions

Comparing version 1.0.0 to 1.1.0

docs/hapi.md

96

docs/express.md

@@ -1,95 +0,1 @@

## Express usage:
`hekdi` can be integrated with [express.js](https://github.com/expressjs/express).
```javascript
'use strict';
const express = require('express');
const { expressDI, createModule } = require('hekdi');
const app = express(); // create express app
class Ctrl { // create controller
static get $inject() {
return ['hello', 'world'];
}
constructor(hello, world) {
this.hello = hello;
this.world = world;
}
next(req, res, next) {
console.log('hi from next Ctrl method');
next();
}
greet(req, res) {
console.log('greet');
console.log('\n');
res.send(`${this.hello},${this.world}`);
}
hi(req, res, next, data) {
console.log('hi', data);
console.log('\n');
res.send(`${this.hello} there`);
}
}
const importedModule = createModule({ // create module to be injected
name: 'ServicesModule',
declarations: [
{ name: 'hello', strategy: 'value', value: 'Hello' },
{ name: 'world', strategy: 'value', value: 'World' },
],
exports: '*'
});
// create DI instance and register a router config to it.
const di = expressDI.create(app, {
'/api': { // router path
get: { // http method
controller: 'Controller', // Dependency
fn: 'hi', // dependency function to be called
data: ['args'] // data that will be passed to function as arguments after (req, res, next)
}
},
'/api/:test': {
get: {
controller: 'Controller',
fn: 'greet',
middlewares: [ // this array will register middlewares for this route.
(req, res, next) => { // if middleware is a function it will be registered
console.log('from middleware');
next();
}, { // but if it is a config then this dependency function will be found in module
controller: 'Controller',
fn: 'next'
}
]
},
}
});
di.bootstrap({ // bootstraps di
name: 'Module',
declarations: [
{ name: 'Controller', strategy: 'singleton', value: Ctrl }
],
imports: [ importedModule ]
});
app.listen(3000); // launch app
```
In the case of `get` request to `/api` we will get:
- console: 'hi' 'args'
- response: 'hello there'
In the case of `get` request to `/api/param` we will get:
- console:
- 'from middleware';
- 'hi from next Ctrl method';
- 'greet'
- response: 'Hello, World'
not done yet

@@ -8,3 +8,3 @@ 'use strict';

createModule: Module.createModule,
expressDI: require('./src/frameworks/express')
koaDI: require('./src/frameworks/koa')
};
{
"name": "hekdi",
"version": "1.0.0",
"version": "1.1.0",
"description": "Depedency injection framework for node.js",

@@ -18,7 +18,8 @@ "main": "index.js",

"koa-router": "^7.2.1",
"mocha": "^3.5.0"
"mocha": "^3.5.0",
"koa-body-parser": "^1.1.2"
},
"repository": {
"type": "git",
"url": "git@github.com:IvanProdaiko94/Injector.git"
"url": "git@github.com:IvanProdaiko94/hekdi.git"
},

@@ -41,4 +42,4 @@ "keywords": [

"engines": {
"node": ">=6.0.0"
"node": ">=7.6.0"
}
}

@@ -6,3 +6,6 @@ [![Build Status](https://travis-ci.org/IvanProdaiko94/hekdi.svg?branch=master)](https://travis-ci.org/IvanProdaiko94/hekdi)

[![license](https://img.shields.io/github/license/mashape/apistatus.svg)]()
[![npm](https://img.shields.io/npm/dm/hekdi.svg)](https://www.npmjs.com/package/hekdi)
[![npm](https://img.shields.io/npm/dt/hekdi.svg)](https://www.npmjs.com/package/hekdi)
# node.js Dependency Injection

@@ -18,4 +21,4 @@ This module provides dependency injection for node.js

- [Express](./docs/express.md)
- [Koa](./examples/koa.js)
- [Hapi](./examples/hapi.js)
- [Koa](./docs/koa.md)
- [Hapi](./docs/hapi.md)

@@ -22,0 +25,0 @@ ## Basic usage:

@@ -7,42 +7,2 @@ /**

const DI = require('../di');
/**
*
* @param app
* @param config Object
* @constructor
*/
function ExpressDI(app, config) {
DI.call(this);
for (const key in config) {
for (const method in config[key]) {
const routeConfig = config[key][method];
if (routeConfig.middlewares && routeConfig.middlewares.length) {
const fns = routeConfig.middlewares.map(middleware => {
return typeof middleware === 'function' ?
middleware :
(...args) => this.resolve(middleware.controller)[middleware.fn](...args);
});
app.use(key, ...fns);
}
if (!routeConfig.data) {
routeConfig.data = [];
}
app[method](
key,
(...args) => this.resolve(routeConfig.controller)[routeConfig.fn](...args, ...routeConfig.data)
);
}
}
}
ExpressDI.prototype = DI.prototype;
DI.prototype.constructor = DI;
ExpressDI.create = function(app, config) {
return new ExpressDI(app, config);
};
module.exports = ExpressDI;
const DI = require('../di');

@@ -6,1 +6,3 @@ /**

'use strict';
const DI = require('../di');

@@ -6,1 +6,90 @@ /**

'use strict';
const DI = require('../di');
/**
* @param ctx {Object}
* @param original {Function}
* @returns {Function}
*/
const diResolver = function(ctx, original) {
/** @param diConfig {Function|String|Object<{controller: string, action: string, [params]: Array}>} */
return function(diConfig) {
switch (typeof diConfig) {
case 'string':
original.call(ctx, ctx.context.di.resolve(diConfig));
break;
case 'object': // array
const { controller, action, params } = diConfig;
const dependency = ctx.context.di.resolve(controller);
original.call(ctx, async (ctx, next) => {
if (next) {
await dependency[action](ctx, next, params);
} else {
await dependency[action](ctx, params);
}
});
break;
default: // function
original.call(ctx, diConfig);
}
return ctx;
};
};
/**
* @param app {Object}
* @param ctx {Object}
* @param original {Function}
* @returns {Function}
*/
const diRouterResolver = function(app, ctx, original) {
/**
* path {string}
* @param diConfig {Function|String|Object<{controller: string, action: string, [params]: Array}>}
*/
return function(path, diConfig) {
switch (typeof diConfig) {
case 'string':
original.call(ctx, path, app.context.di.resolve(diConfig));
break;
case 'object': // array
const { controller, action, params } = diConfig;
const dependency = app.context.di.resolve(controller);
original.call(ctx, path, async (ctx, next) => {
if (next) {
await dependency[action](ctx, next, params);
} else {
await dependency[action](ctx, params);
}
});
break;
default: // function
original.call(ctx, path, diConfig);
}
return ctx;
};
};
/**
*
* @param app
* @param bootstrapModule {Module|Object}
* @param [router]
*/
module.exports = function koaDi(bootstrapModule, app, router) {
const di = new DI();
di.bootstrap(bootstrapModule);
di.main.injector.register({name: 'App', strategy: 'constant', value: app});
app.context.di = di;
app.use = diResolver(app, app.use);
if (router) {
router.use = diRouterResolver(app, router, router.use);
router.methods.forEach(method => {
const methodName = method.toLowerCase();
router[methodName] = diRouterResolver(app, router, router[methodName]);
})
}
};

@@ -5,70 +5,69 @@ 'use strict';

class Injector {
/**
* @param moduleName {string}
*/
constructor(moduleName) {
this.belongTo = moduleName;
this.dependencies = new Map();
}
/**
*
* @param moduleName {string}
* @constructor
*/
function Injector(moduleName) {
this.belongTo = moduleName;
this.dependencies = new Map();
}
/**
* @param dependencyName {String}
* @return {*}
*/
resolve(dependencyName) {
if (this.dependencies.has(dependencyName)) {
return this.dependencies.get(dependencyName).resolver();
} else {
throw new ReferenceError(errors.unmetDependency(this.belongTo, dependencyName));
}
/**
* @param dependencyName {String}
* @return {*}
*/
Injector.prototype.resolve = function(dependencyName) {
if (this.dependencies.has(dependencyName)) {
return this.dependencies.get(dependencyName).resolver();
}
throw new ReferenceError(errors.unmetDependency(this.belongTo, dependencyName));
};
/**
* @param dependencies {Map}
*/
addImports(dependencies) {
dependencies.forEach((dependencyConfig, key) => {
this.dependencies.set(key, dependencyConfig);
});
}
/**
* @param dependencies {Map}
*/
Injector.prototype.addImports = function(dependencies) {
dependencies.forEach((dependencyConfig, key) => {
this.dependencies.set(key, dependencyConfig);
});
};
/**
* @param dependencies {Object<{name: string, strategy: string: value: any}>}
* @return {Map}
*/
register(...dependencies) {
dependencies.map(config => {
const inject = config.value.$inject || [];
const dConf = this.getConfigOf(config.name);
if (dConf && dConf.strategy === 'constant') {
throw new Error(errors.dependencyIsRegistered(config.name));
} else if (!strategies.hasOwnProperty(config.strategy)) {
throw new Error(errors.incorrectResolutionStrategy(config.strategy, strategies));
} else if (inject.indexOf(config.name) !== -1) {
throw new Error(errors.selfDependency(config.name));
/**
* @param dependencies {Object<{name: string, strategy: string: value: any}>}
* @return {Map}
*/
Injector.prototype.register = function(...dependencies) {
dependencies.map(config => {
const inject = config.value.$inject || [];
const dConf = this.getConfigOf(config.name);
if (dConf && dConf.strategy === 'constant') {
throw new Error(errors.dependencyIsRegistered(config.name));
} else if (!strategies.hasOwnProperty(config.strategy)) {
throw new Error(errors.incorrectResolutionStrategy(config.strategy, strategies));
} else if (inject.indexOf(config.name) !== -1) {
throw new Error(errors.selfDependency(config.name));
}
inject.forEach(dep => {
if (this.dependencies.has(dep)) {
const depsToCheck = this.getConfigOf(dep).value.$inject || [];
if (depsToCheck.indexOf(config.name) !== -1) {
throw new Error(errors.circularDependency(config.name, dep));
}
}
inject.forEach(dep => {
if (this.dependencies.has(dep)) {
const depsToCheck = this.getConfigOf(dep).value.$inject || [];
if (depsToCheck.indexOf(config.name) !== -1) {
throw new Error(errors.circularDependency(config.name, dep));
}
}
});
config.resolver = strategies[config.strategy](config.name).bind(this);
config.belongTo = this.belongTo;
this.dependencies.set(config.name, config);
});
}
config.resolver = strategies[config.strategy](config.name).bind(this);
config.belongTo = this.belongTo;
this.dependencies.set(config.name, config);
});
};
/**
* @param dependencyName {String}
* @return {*}
*/
getConfigOf(dependencyName) {
return this.dependencies.get(dependencyName);
}
}
/**
* @param dependencyName {String}
* @return {*}
*/
Injector.prototype.getConfigOf = function(dependencyName) {
return this.dependencies.get(dependencyName);
};
module.exports = Injector;
'use strict';
const Injector = require('./injector');
class Module {
/**
* @param config <{
* name: string,
* [declarations]: Array<Object>,
* [imports]: Array<Module>,
* [exports]: Array<string>|string>
* }>
* @return Module <{name: string, injector: Injector, [exports]: Map}>
*/
constructor(config) {
this.name = config.name;
this.injector = new Injector(this.name);
/**
*
* @constructor
* @param config <{
* name: string,
* [declarations]: Array<Object>,
* [imports]: Array<Module>,
* [exports]: Array<string>|string>
* }>
* @return Module <{name: string, injector: Injector, [exports]: Map}>
*/
function Module(config) {
this.name = config.name;
this.injector = new Injector(this.name);
if (config.imports) {
config.imports.forEach(importedModule => {
if (importedModule.exports) {
this.injector.addImports(importedModule.exports);
if (config.imports) {
config.imports.forEach(importedModule => {
if (importedModule.exports) {
this.injector.addImports(importedModule.exports);
}
});
}
this.injector.register(...(config.declarations || []));
if (config.exports) {
const dependencies = this.injector.dependencies;
if (config.exports === '*') {
this.exports = new Map(dependencies);
} else {
this.exports = new Map();
config.exports.forEach(dependencyName => {
const dependencyConfig = this.injector.getConfigOf(dependencyName);
if (dependencyConfig.belongTo === this.name) {
this.exports.set(dependencyName, dependencyConfig);
}
});
}
this.injector.register(...(config.declarations || []));
if (config.exports) {
const dependencies = this.injector.dependencies;
if (config.exports === '*') {
this.exports = new Map(dependencies);
} else {
this.exports = new Map();
config.exports.forEach(dependencyName => {
const dependencyConfig = this.injector.getConfigOf(dependencyName);
if (dependencyConfig.belongTo === this.name) {
this.exports.set(dependencyName, dependencyConfig);
}
});
}
}
}
static createModule(config) {
return new Module(config);
}
}
Module.createModule = function(config) {
return new Module(config);
};
module.exports = Module;
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