Socket
Socket
Sign inDemoInstall

sdic

Package Overview
Dependencies
8
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.1.0 to 1.2.0

.travis.yml

131

container.js

@@ -6,3 +6,3 @@ const fs = require('fs');

const _isFunction = require('lodash.isfunction');
const _isObject = require('lodash.isobject');
const _isPlainObject = require('lodash.isplainobject');
const _isString = require('lodash.isstring');

@@ -44,2 +44,41 @@ const getParamNames = require('get-parameter-names');

let createModuleName = (initialName, relPath, opts = {}) => {
let moduleName = initialName;
if ('alias' in opts && !(_isString(opts.alias) && /^[a-zA-Z_$]{1}[a-zA-Z0-9_$]+$/.test(opts.alias))) {
return throwError(`Invalid alias: ${opts.alias}`);
}
if (opts.alias) {
moduleName = opts.alias;
delete opts.alias;
} else {
moduleName = moduleName.replace(/[^a-zA-Z0-9]+(\w)/g, (match, letter) => letter.toUpperCase());
let dirname = _path.dirname(relPath).replace(/^([\/]+)(.*)/gi, ((_str, _g1, g2) => g2));
if (dirname.length > 1) { // ignores '.', '/', ...
if (opts.reverseName === true) {
moduleName = dirname.split('/').join('/').replace(/[^a-zA-Z0-9]+(\w)/g, (match, letter) => letter.toUpperCase()) + ucfirst(moduleName);
} else {
moduleName = moduleName + ucfirst(dirname.split('/').reverse().join('/').replace(/[^a-zA-Z0-9]+(\w)/g, (match, letter) => letter.toUpperCase()));
}
}
if (opts.prefix) {
moduleName = opts.prefix + ucfirst(moduleName);
//delete opts.prefix;
}
if (opts.postfix) {
moduleName = moduleName + ucfirst(opts.postfix);
//delete opts.postfix;
}
}
if (opts.deduplicate === true) {
moduleName = moduleName.replace(/([A-Z])/g, (match, letter) => "_" + match).split('_').map(part => ucfirst(part))
.filter((part, index, arr) => arr.indexOf(part) === index).join('');
}
return moduleName.charAt(0).toLowerCase() + moduleName.substr(1);
};
let loadFile = (file, relPath = '', opts = {}) => {

@@ -54,45 +93,31 @@ if (allowedExtensions && !(allowedExtensions.includes(file.match(/\w+$/)[0]))) return;

let moduleFile = file.replace(/\.\w+$/, '');
let moduleName;
let moduleName = createModuleName(_path.basename(moduleFile), relPath, opts);
if ('alias' in opts && !(_isString(opts.alias) && /^[a-zA-Z_$]{1}[a-zA-Z0-9_$]+$/.test(opts.alias))) {
return throwError(`Invalid alias: ${opts.alias}`);
}
if (opts.alias) {
moduleName = opts.alias;
delete opts.alias;
} else {
// Remove dashes from basename and camelcase result
moduleName = _path.basename(moduleFile);
moduleName = moduleName.replace(/[^a-zA-Z0-9]+(\w)/g, (match, letter) => letter.toUpperCase());
let dirname = _path.dirname(relPath).replace(/^([\/]+)(.*)/gi, ((_str, _g1, g2) => g2));
if (dirname.length > 1) { // ignores '.', '/', ...
if (opts.reverseName === true) {
moduleName = dirname.split('/').join('/').replace(/[^a-zA-Z0-9]+(\w)/g, (match, letter) => letter.toUpperCase()) + ucfirst(moduleName);
} else {
moduleName = moduleName + ucfirst(dirname.split('/').reverse().join('/').replace(/[^a-zA-Z0-9]+(\w)/g, (match, letter) => letter.toUpperCase()));
}
// Register module
let module = require(moduleFile);
if (_isPlainObject(module)) {
let content = fs.readFileSync(file);
if (!content) {
return throwError(`Cannot load file contents: ${moduleFile}`);
}
if (opts.prefix) {
moduleName = opts.prefix + ucfirst(moduleName);
//delete opts.prefix;
}
content = content.toString();
let es6mode = /export (let|const|function|class|default)/m.test(content);
if (es6mode) {
// named ES6 exports
Object.keys(module).forEach(key => {
container.register(
key === 'default' ? moduleName : createModuleName(key, relPath, opts),
module[key],
_extend(opts, {dependencies: resolveArguments(module[key])})
);
});
} else {
container.register(moduleName, module, opts);
}
if (opts.postfix) {
moduleName = moduleName + ucfirst(opts.postfix);
//delete opts.postfix;
}
content = null;
} else {
container.register(moduleName, module, opts);
}
if (opts.deduplicate === true) {
let deduplicated = moduleName.replace(/([A-Z])/g, (match, letter) => "_" + match).split('_').map(part => ucfirst(part))
.filter((part, index, arr) => arr.indexOf(part) === index).join('');
moduleName = deduplicated.charAt(0).toLowerCase() + deduplicated.substr(1);
}
// Register module
container.register(moduleName, require(moduleFile), opts);
};

@@ -136,2 +161,10 @@

let makeClassInstance = (constructor, args) => {
function F() {
return constructor.apply(this, args);
}
F.prototype = constructor.prototype;
return new F();
};
let getModuleInstance = (name, overrides = {}, visited = []) => {

@@ -174,6 +207,16 @@

// create instance
// create instance
let instance;
try {
instance = factory.fn.apply(factory, args);
try {
// try to create instance of functional module
instance = factory.fn.apply(factory, args);
} catch (err) {
if (!/Cannot call a class as a function/.test(err.message)) {
throw err;
}
// try to create instance of class module
instance = makeClassInstance(factory.fn, args);
}
} catch (err) {

@@ -210,6 +253,2 @@ err.message = `Cannot create an instance of: ${name}. Error: ${err.message}`;

register: (name, fn, opts = {}) => {
if (_isObject(fn) && 'default' in fn) {
fn = fn.default;
}
if (fn === undefined) {

@@ -232,3 +271,3 @@ return throwError('Unable to register empty (undefined) module');

fn: fn,
dependencies: resolveArguments(fn),
dependencies: opts.dependencies ? opts.dependencies : resolveArguments(fn),
opts: opts

@@ -235,0 +274,0 @@ };

{
"name": "sdic",
"version": "1.1.0",
"version": "1.2.0",
"description": "Simple dependency injection container",

@@ -29,2 +29,3 @@ "main": "index.js",

"lodash.isobject": "^3.0.2",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1"

@@ -31,0 +32,0 @@ },

@@ -5,2 +5,4 @@ # SDIC: Simple Dependency Injection Container

[![Build Status](https://travis-ci.org/josefzamrzla/sdic.svg?branch=master)](https://travis-ci.org/josefzamrzla/sdic)
## Install

@@ -102,3 +104,3 @@ ```bash

or using ES6 **export default** syntax (currently only default exports are supported):
or using ES6 **export default** syntax:

@@ -128,3 +130,3 @@ ```javascript

or using ES6 **export default** syntax (currently only default exports are supported):
or using ES6 **export default** syntax:

@@ -143,2 +145,30 @@ ```javascript

### Multiple modules definition using ES6 named exports
```javascript
// module without dependencies
export const firstFunctionalService = () => {
return {
method: () => ({passed: true})
}
};
// module dependds on fooService
export function secondFunctionalService (fooService) {
return {
method: () => fooService.method()
}
};
// module dependds on fooService
export class ClassService {
constructor(fooService) {
this.fooService = fooService;
}
method() {
return this.fooService.method();
}
}
```
### Manual module registration

@@ -289,2 +319,6 @@

**ES6 note:** when loading named exports into the container, then:
* exported name will be taken instead of a filename (with lowercased first letter)
* filename will be taken for default (not-named) export
## TODO

@@ -297,5 +331,4 @@ * load both file and folder with the same name, eg:

```
* add support for ES6 named exports
* docs, docs, docs
Based on the idea of: https://www.npmjs.com/package/adctd

@@ -1,5 +0,7 @@

const service = (fooService) => ({
method: () => fooService.method()
});
const service = (fooService) => {
return {
method: () => fooService.method()
}
};
export default service;

@@ -149,4 +149,4 @@ const expect = require('chai').expect;

describe('should be able to register module with "export default" syntax', () => {
it('without dependencies', () => {
describe('should be able to register es6 modules', () => {
it('export default without dependencies', () => {
container.load('./export-default/dummy-service');

@@ -158,3 +158,3 @@ expect(container.getAll()).to.contain.all.keys(['dummyService']);

it('with dependencies', () => {
it('export default with dependencies', () => {
container.register('fooService', () => ({method: () => ({passed: true})}));

@@ -166,3 +166,31 @@ container.load('./export-default/service-with-params');

});
it('named exports', () => {
container.register('fooService', () => ({method: () => ({passed: true})}));
container.load('./named-exports', {alias: null});
expect(container.getAll()).to.contain.all.keys(['firstFunctionalService', 'secondFunctionalService', 'classService', 'services']);
expect(Object.keys(container.getAll()).length).to.eql(6); // 5 + container itself
expect(container.get('firstFunctionalService').method()).to.deep.equal({passed: true});
expect(container.get('secondFunctionalService').method()).to.deep.equal({passed: true});
expect(container.get('classService').method()).to.deep.equal({passed: true});
expect(container.get('services').method()).to.deep.equal({passed: true}); // default export
});
it('named exports respects opts rules (prefix, postfix, alias)', () => {
container.register('fooService', () => ({method: () => ({passed: true})}));
container.load('./named-exports', {prefix: 'pre', postfix: 'post'}); // alias == basedir
expect(container.getAll()).to.contain.all.keys([
'preFirstFunctionalServiceNamedExportsPost',
'preSecondFunctionalServiceNamedExportsPost',
'preClassServiceNamedExportsPost',
'preServicesNamedExportsPost']);
expect(Object.keys(container.getAll()).length).to.eql(6); // 5 + container itself
expect(container.get('preFirstFunctionalServiceNamedExportsPost').method()).to.deep.equal({passed: true});
expect(container.get('preSecondFunctionalServiceNamedExportsPost').method()).to.deep.equal({passed: true});
expect(container.get('preClassServiceNamedExportsPost').method()).to.deep.equal({passed: true});
expect(container.get('preServicesNamedExportsPost').method()).to.deep.equal({passed: true}); // default export
});
});
});
SocketSocket SOC 2 Logo

Product

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc