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

knifecycle

Package Overview
Dependencies
Maintainers
1
Versions
101
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

knifecycle - npm Package Compare versions

Comparing version 2.5.2 to 2.5.3

5

CHANGELOG.md

@@ -0,1 +1,6 @@

<a name="2.5.3"></a>
## [2.5.3](https://github.com/nfroidure/knifecycle/compare/v2.5.2...v2.5.3) (2018-09-16)
<a name="2.5.2"></a>

@@ -2,0 +7,0 @@ ## [2.5.2](https://github.com/nfroidure/knifecycle/compare/v2.5.1...v2.5.2) (2018-05-06)

34

dist/build.js

@@ -1,6 +0,6 @@

'use strict';
"use strict";
var _util = require('./util');
var _util = require("./util");
var _sequence = require('./sequence');
var _sequence = require("./sequence");

@@ -23,5 +23,3 @@ /* Architecture Note #2: Build

*/
module.exports = buildInitializer;
/**

@@ -44,2 +42,3 @@ * Create a JavaScript module that initialize

*/
function buildInitializer(constants, loader, dependencies) {

@@ -53,3 +52,2 @@ return Promise.all(dependencies.map(dependency => buildDependencyTree(constants, loader, dependency))).then(dependencyTrees => {

batches.pop();
return `${batches.map((batch, index) => `

@@ -73,4 +71,8 @@ // Definition batch #${index}${batch.map(name => {

}
return `
${name}: ${dependenciesHash[name].__initializerName}({${dependenciesHash[name].__inject ? `${dependenciesHash[name].__inject.map(_util.parseDependencyDeclaration).map(({ serviceName, mappedName }) => `
${name}: ${dependenciesHash[name].__initializerName}({${dependenciesHash[name].__inject ? `${dependenciesHash[name].__inject.map(_util.parseDependencyDeclaration).map(({
serviceName,
mappedName
}) => `
${serviceName}: services['${mappedName}'],`).join('')}` : ''}

@@ -90,3 +92,6 @@ })${'provider' === dependenciesHash[name].__type ? '.then(provider => provider.service)' : ''},`;

`).join('')}
return {${dependencies.map(_util.parseDependencyDeclaration).map(({ serviceName, mappedName }) => `
return {${dependencies.map(_util.parseDependencyDeclaration).map(({
serviceName,
mappedName
}) => `
${serviceName}: services['${mappedName}'],`).join('')}

@@ -100,3 +105,6 @@ };

function buildDependencyTree(constants, loader, dependencyDeclaration) {
const { mappedName, optional } = (0, _util.parseDependencyDeclaration)(dependencyDeclaration);
const {
mappedName,
optional
} = (0, _util.parseDependencyDeclaration)(dependencyDeclaration);

@@ -110,3 +118,6 @@ if (constants[mappedName]) {

return loader(mappedName).then(({ path, initializer }) => {
return loader(mappedName).then(({
path,
initializer
}) => {
const node = {

@@ -121,3 +132,2 @@ __name: mappedName,

};
return initializer[_util.SPECIAL_PROPS.INJECT] && initializer[_util.SPECIAL_PROPS.INJECT].length ? Promise.all(initializer[_util.SPECIAL_PROPS.INJECT].map(childDependencyDeclaration => buildDependencyTree(constants, loader, childDependencyDeclaration))).then(childNodes => {

@@ -131,2 +141,3 @@ node.__childNodes = childNodes.filter(identity);

}
throw err;

@@ -142,3 +153,2 @@ });

const nodeIsALeaf = !(node.__childNodes && node.__childNodes.length);
hash[node.__name] = node;

@@ -145,0 +155,0 @@

@@ -1,17 +0,11 @@

'use strict';
"use strict";
var _assert = require('assert');
var _assert = _interopRequireDefault(require("assert"));
var _assert2 = _interopRequireDefault(_assert);
var _yerror = _interopRequireDefault(require("yerror"));
var _yerror = require('yerror');
var _build = _interopRequireDefault(require("./build"));
var _yerror2 = _interopRequireDefault(_yerror);
var _util = require("./util");
var _build = require('./build');
var _build2 = _interopRequireDefault(_build);
var _util = require('./util');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -21,2 +15,3 @@

function aProvider() {}
const mockedConstants = {

@@ -45,2 +40,3 @@ NODE_ENV: 'development'

};
function mockedLoader(name) {

@@ -50,7 +46,7 @@ return mockedDepsHash[name] ? Promise.resolve({

initializer: mockedDepsHash[name]
}) : Promise.reject(new _yerror2.default('E_UNMATCHED_DEPENDENCY', name));
}) : Promise.reject(new _yerror.default('E_UNMATCHED_DEPENDENCY', name));
}
it('should build an initialization module', () => (0, _build2.default)(mockedConstants, mockedLoader, ['dep1', 'finalMappedDep>dep3']).then(content => {
_assert2.default.equal(content, `
it('should build an initialization module', () => (0, _build.default)(mockedConstants, mockedLoader, ['dep1', 'finalMappedDep>dep3']).then(content => {
_assert.default.equal(content, `
// Definition batch #0

@@ -57,0 +53,0 @@ import initDep1 from './services/dep1';

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

'use strict';
"use strict";

@@ -6,19 +6,44 @@ Object.defineProperty(exports, "__esModule", {

});
exports.options = exports.type = exports.inject = exports.name = exports.initializer = exports.Knifecycle = exports.getInstance = undefined;
Object.defineProperty(exports, "initializer", {
enumerable: true,
get: function () {
return _util.initializer;
}
});
Object.defineProperty(exports, "name", {
enumerable: true,
get: function () {
return _util.name;
}
});
Object.defineProperty(exports, "inject", {
enumerable: true,
get: function () {
return _util.inject;
}
});
Object.defineProperty(exports, "type", {
enumerable: true,
get: function () {
return _util.type;
}
});
Object.defineProperty(exports, "options", {
enumerable: true,
get: function () {
return _util.options;
}
});
exports.Knifecycle = exports.getInstance = exports.default = void 0;
var _util = require('./util');
var _util = require("./util");
var _yerror = require('yerror');
var _yerror = _interopRequireDefault(require("yerror"));
var _yerror2 = _interopRequireDefault(_yerror);
var _debug = _interopRequireDefault(require("debug"));
var _debug = require('debug');
var _debug2 = _interopRequireDefault(_debug);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const debug = (0, _debug2.default)('knifecycle'); /* eslint max-len: ["warn", { "ignoreComments": true }] */
/* eslint max-len: ["warn", { "ignoreComments": true }] */
const debug = (0, _debug.default)('knifecycle');
const DISPOSE = '$dispose';

@@ -29,5 +54,3 @@ const DESTROY = '$destroy';

const FATAL_ERROR = '$fatalError';
const ALLOWED_INITIALIZER_TYPES = ['provider', 'service'];
const E_BAD_ANALYZER_TYPE = 'E_BAD_ANALYZER_TYPE';

@@ -40,7 +63,5 @@ const E_UNMATCHED_DEPENDENCY = 'E_UNMATCHED_DEPENDENCY';

const E_BAD_INJECTION = 'E_BAD_INJECTION';
const E_CONSTANT_INJECTION = 'E_CONSTANT_INJECTION';
const E_CONSTANT_INJECTION = 'E_CONSTANT_INJECTION'; // Constants that should use Symbol whenever possible
// Constants that should use Symbol whenever possible
const INSTANCE = '__instance';
/* Architecture Note #1: Knifecycle

@@ -72,2 +93,3 @@

*/
class Knifecycle {

@@ -90,3 +112,5 @@ /**

this._singletonsServicesShutdownsPromises = new Map();
this.provider(INJECTOR, (0, _util.inject)([SILO_CONTEXT], ({ $siloContext }) => Promise.resolve({
this.provider(INJECTOR, (0, _util.inject)([SILO_CONTEXT], ({
$siloContext
}) => Promise.resolve({
service: dependenciesDeclarations => this._initializeDependencies($siloContext, $siloContext.name, dependenciesDeclarations, true)

@@ -98,8 +122,5 @@ })));

const $dispose = siloContext.servicesDescriptors.get(DISPOSE).service;
return $dispose();
}));
debug('Shutting down Knifecycle instance.');
return this.shutdownPromise;

@@ -111,3 +132,2 @@ }

}
/**

@@ -123,2 +143,4 @@ * Returns a Knifecycle instance (always the same)

*/
static getInstance() {

@@ -129,3 +151,2 @@ Knifecycle[INSTANCE] = Knifecycle[INSTANCE] || new Knifecycle();

}
/* Architecture Note #1.3: Declaring services

@@ -174,2 +195,4 @@ The first step to use `knifecycle` is to declare

*/
constant(constantName, constantValue) {

@@ -179,3 +202,3 @@ const contantLooksLikeAnInitializer = constantValue instanceof Function && constantValue[_util.SPECIAL_PROPS.INJECT];

if (contantLooksLikeAnInitializer) {
throw new _yerror2.default(E_CONSTANT_INJECTION, constantValue[_util.SPECIAL_PROPS.INJECT]);
throw new _yerror.default(E_CONSTANT_INJECTION, constantValue[_util.SPECIAL_PROPS.INJECT]);
}

@@ -185,3 +208,5 @@

name: constantName,
options: { singleton: true }
options: {
singleton: true
}
}, Promise.resolve.bind(Promise, {

@@ -191,8 +216,5 @@ service: constantValue,

})));
debug('Registered a new constant:', constantName);
return this;
}
/**

@@ -233,2 +255,4 @@ * Register a service initializer

*/
service(serviceName, initializer, options) {

@@ -243,3 +267,2 @@ this.register((0, _util.reuseSpecialProps)(initializer, initializer, {

}
/**

@@ -281,2 +304,4 @@ * Register a provider initializer

*/
provider(serviceName, initializer, options = {}) {

@@ -295,7 +320,9 @@ this.register((0, _util.reuseSpecialProps)(initializer, initializer, {

initializer[_util.SPECIAL_PROPS.TYPE] = initializer[_util.SPECIAL_PROPS.TYPE] || ALLOWED_INITIALIZER_TYPES[0];
if (!initializer[_util.SPECIAL_PROPS.NAME]) {
throw new _yerror2.default(E_ANONYMOUS_ANALYZER, initializer[_util.SPECIAL_PROPS.NAME]);
throw new _yerror.default(E_ANONYMOUS_ANALYZER, initializer[_util.SPECIAL_PROPS.NAME]);
}
if (!ALLOWED_INITIALIZER_TYPES.includes(initializer[_util.SPECIAL_PROPS.TYPE])) {
throw new _yerror2.default(E_BAD_ANALYZER_TYPE, initializer[_util.SPECIAL_PROPS.TYPE], ALLOWED_INITIALIZER_TYPES);
throw new _yerror.default(E_BAD_ANALYZER_TYPE, initializer[_util.SPECIAL_PROPS.TYPE], ALLOWED_INITIALIZER_TYPES);
}

@@ -311,3 +338,3 @@

if (initializerDependsOfItself) {
throw new _yerror2.default(E_CIRCULAR_DEPENDENCY, initializer[_util.SPECIAL_PROPS.NAME]);
throw new _yerror.default(E_CIRCULAR_DEPENDENCY, initializer[_util.SPECIAL_PROPS.NAME]);
}

@@ -320,2 +347,3 @@

this._servicesProviders.set(initializer[_util.SPECIAL_PROPS.NAME], initializer);
debug('Registered a new initializer:', initializer[_util.SPECIAL_PROPS.NAME]);

@@ -327,2 +355,3 @@ return this;

const serviceName = _pickServiceNameFromDeclaration(dependencyDeclaration);
const dependencyProvider = this._servicesProviders.get(serviceName);

@@ -333,3 +362,5 @@

}
declarationsStacks = declarationsStacks.concat(dependencyDeclaration);
dependencyProvider[_util.SPECIAL_PROPS.INJECT].forEach(childDependencyDeclaration => {

@@ -339,3 +370,3 @@ const childServiceName = _pickServiceNameFromDeclaration(childDependencyDeclaration);

if (rootServiceName === childServiceName) {
throw new _yerror2.default(...[E_CIRCULAR_DEPENDENCY, rootServiceName].concat(declarationsStacks).concat(childDependencyDeclaration));
throw new _yerror.default(...[E_CIRCULAR_DEPENDENCY, rootServiceName].concat(declarationsStacks).concat(childDependencyDeclaration));
}

@@ -346,3 +377,2 @@

}
/**

@@ -373,3 +403,9 @@ * Outputs a Mermaid compatible dependency graph of the declared services.

*/
toMermaidGraph({ shapes = [], styles = [], classes = {} } = {}) {
toMermaidGraph({
shapes = [],
styles = [],
classes = {}
} = {}) {
const servicesProviders = this._servicesProviders;

@@ -382,8 +418,13 @@ const links = Array.from(servicesProviders.keys()).filter(provider => !provider.startsWith('$')).reduce((links, serviceName) => {

}
return links.concat(serviceProvider[_util.SPECIAL_PROPS.INJECT].map(dependencyDeclaration => {
const dependedServiceName = _pickServiceNameFromDeclaration(dependencyDeclaration);
return { serviceName, dependedServiceName };
return {
serviceName,
dependedServiceName
};
}));
}, []);
const classesApplications = _applyClasses(classes, styles, links);

@@ -395,5 +436,7 @@

return ['graph TD'].concat(links.map(({ serviceName, dependedServiceName }) => ` ${_applyShapes(shapes, serviceName) || serviceName}-->${_applyShapes(shapes, dependedServiceName) || dependedServiceName}`)).concat(Object.keys(classes).map(className => ` classDef ${className} ${classes[className]}`)).concat(Object.keys(classesApplications).map(serviceName => ` class ${serviceName} ${classesApplications[serviceName]};`)).join('\n');
return ['graph TD'].concat(links.map(({
serviceName,
dependedServiceName
}) => ` ${_applyShapes(shapes, serviceName) || serviceName}-->${_applyShapes(shapes, dependedServiceName) || dependedServiceName}`)).concat(Object.keys(classes).map(className => ` classDef ${className} ${classes[className]}`)).concat(Object.keys(classesApplications).map(serviceName => ` class ${serviceName} ${classesApplications[serviceName]};`)).join('\n');
}
/* Architecture Note #1.4: Execution silos

@@ -426,4 +469,7 @@ Once all the services are declared, we need a way to bring

*/
run(dependenciesDeclarations) {
const _this = this;
const internalDependencies = [...new Set(dependenciesDeclarations.concat(DISPOSE))];

@@ -439,6 +485,6 @@ const siloContext = {

if (this.shutdownPromise) {
throw new _yerror2.default('E_INSTANCE_DESTROYED');
}
throw new _yerror.default('E_INSTANCE_DESTROYED');
} // Create a provider for the special fatal error service
// Create a provider for the special fatal error service
siloContext.servicesDescriptors.set(FATAL_ERROR, {

@@ -453,20 +499,16 @@ service: {

}
});
}); // Make the siloContext available for internal injections
// Make the siloContext available for internal injections
siloContext.servicesDescriptors.set(SILO_CONTEXT, {
service: siloContext
});
// Create a provider for the shutdown special dependency
}); // Create a provider for the shutdown special dependency
siloContext.servicesDescriptors.set(DISPOSE, {
service: () => {
siloContext.shutdownPromise = siloContext.shutdownPromise || _shutdownNextServices(siloContext.servicesSequence);
debug('Shutting down services');
return siloContext.shutdownPromise.then(() => {
this._silosContexts.delete(siloContext);
});
}); // Shutdown services in their instanciation order
// Shutdown services in their instanciation order
function _shutdownNextServices(reversedServiceSequence) {

@@ -476,4 +518,6 @@ if (0 === reversedServiceSequence.length) {

}
return Promise.all(reversedServiceSequence.pop().map(serviceName => {
const singletonServiceDescriptor = _this._singletonsServicesDescriptors.get(serviceName);
const serviceDescriptor = singletonServiceDescriptor || siloContext.servicesDescriptors.get(serviceName);

@@ -491,2 +535,3 @@ let serviceShutdownPromise = _this._singletonsServicesShutdownsPromises.get(serviceName) || siloContext.servicesShutdownsPromises.get(serviceName);

}
if (singletonServiceDescriptor) {

@@ -496,2 +541,3 @@ const handleSet = _this._singletonsServicesHandles.get(serviceName);

handleSet.delete(siloContext.name);
if (handleSet.size) {

@@ -501,9 +547,13 @@ debug('Singleton is used elsewhere:', serviceName, handleSet);

}
_this._singletonsServicesDescriptors.delete(serviceName);
}
debug('Shutting down a service:', serviceName);
serviceShutdownPromise = serviceDescriptor.dispose ? serviceDescriptor.dispose() : Promise.resolve();
if (singletonServiceDescriptor) {
_this._singletonsServicesShutdownsPromises.set(serviceName, serviceShutdownPromise);
}
siloContext.servicesShutdownsPromises.set(serviceName, serviceShutdownPromise);

@@ -523,4 +573,6 @@ return serviceShutdownPromise;

return dependenciesDeclarations.reduce((finalHash, dependencyDeclaration) => {
const { serviceName, mappedName } = (0, _util.parseDependencyDeclaration)(dependencyDeclaration);
const {
serviceName,
mappedName
} = (0, _util.parseDependencyDeclaration)(dependencyDeclaration);
finalHash[serviceName] = servicesHash[mappedName];

@@ -531,3 +583,2 @@ return finalHash;

}
/**

@@ -541,2 +592,4 @@ * Initialize or return a service descriptor

*/
_getServiceDescriptor(siloContext, injectOnly, serviceName) {

@@ -553,9 +606,9 @@ let serviceDescriptor = this._singletonsServicesDescriptors.get(serviceName);

return Promise.resolve(serviceDescriptor);
}
// The inject service is intended to be used as a workaround for unavoidable
} // The inject service is intended to be used as a workaround for unavoidable
// circular dependencies. It wouldn't make sense to instanciate new services
// at this level so throwing an error
if (injectOnly) {
return Promise.reject(new _yerror2.default(E_BAD_INJECTION, serviceName));
return Promise.reject(new _yerror.default(E_BAD_INJECTION, serviceName));
}

@@ -565,3 +618,2 @@

}
/**

@@ -574,6 +626,8 @@ * Initialize a service

*/
_initializeServiceDescriptor(siloContext, serviceName) {
const serviceProvider = this._servicesProviders.get(serviceName);
let serviceDescriptorPromise;
debug('Initializing a service descriptor:', serviceName);

@@ -583,24 +637,25 @@

debug('No service provider:', serviceName);
serviceDescriptorPromise = Promise.reject(new _yerror2.default(E_UNMATCHED_DEPENDENCY, serviceName));
serviceDescriptorPromise = Promise.reject(new _yerror.default(E_UNMATCHED_DEPENDENCY, serviceName));
siloContext.servicesDescriptors.set(serviceName, serviceDescriptorPromise);
return serviceDescriptorPromise;
}
// A singleton service may use a reserved resource
} // A singleton service may use a reserved resource
// like a TCP socket. This is why we have to be aware
// of singleton services full shutdown before creating
// a new one
serviceDescriptorPromise = (this._singletonsServicesShutdownsPromises.get(serviceName) || Promise.resolve()).
// Anyway delete any shutdown promise before instanciating
serviceDescriptorPromise = (this._singletonsServicesShutdownsPromises.get(serviceName) || Promise.resolve()). // Anyway delete any shutdown promise before instanciating
// a new service
then(() => {
this._singletonsServicesShutdownsPromises.delete(serviceName);
siloContext.servicesShutdownsPromises.delete(serviceName);
}).then(this._initializeDependencies.bind(this, siloContext, serviceName, serviceProvider[_util.SPECIAL_PROPS.INJECT]));
serviceDescriptorPromise = serviceDescriptorPromise.then(servicesHash => {
debug('Successfully gathered service dependencies:', serviceName);
return serviceProvider[_util.SPECIAL_PROPS.INJECT].reduce((finalHash, dependencyDeclaration) => {
const { serviceName, mappedName } = (0, _util.parseDependencyDeclaration)(dependencyDeclaration);
const {
serviceName,
mappedName
} = (0, _util.parseDependencyDeclaration)(dependencyDeclaration);
finalHash[serviceName] = servicesHash[mappedName];

@@ -612,5 +667,7 @@ return finalHash;

debug('Provider did not return a descriptor:', serviceName);
return Promise.reject(new _yerror2.default(E_BAD_SERVICE_PROVIDER, serviceName));
return Promise.reject(new _yerror.default(E_BAD_SERVICE_PROVIDER, serviceName));
}
debug('Successfully initialized a service descriptor:', serviceName);
if (serviceDescriptor.fatalErrorPromise) {

@@ -620,2 +677,3 @@ debug('Registering service descriptor error promise:', serviceName);

}
siloContext.servicesDescriptors.set(serviceName, serviceDescriptor);

@@ -625,12 +683,16 @@ return serviceDescriptor;

debug('Error initializing a service descriptor:', serviceName, err.stack);
if (E_UNMATCHED_DEPENDENCY === err.code) {
throw _yerror2.default.wrap(...[err, E_UNMATCHED_DEPENDENCY, serviceName].concat(err.params));
throw _yerror.default.wrap(...[err, E_UNMATCHED_DEPENDENCY, serviceName].concat(err.params));
}
throw err;
});
if (serviceProvider[_util.SPECIAL_PROPS.OPTIONS].singleton) {
const handlesSet = new Set();
handlesSet.add(siloContext.name);
handlesSet.add(siloContext.name);
this._singletonsServicesHandles.set(serviceName, handlesSet);
this._singletonsServicesDescriptors.set(serviceName, serviceDescriptorPromise);

@@ -640,5 +702,5 @@ } else {

}
return serviceDescriptorPromise;
}
/**

@@ -652,7 +714,11 @@ * Initialize a service dependencies

*/
_initializeDependencies(siloContext, serviceName, servicesDeclarations, injectOnly = false) {
debug('Initializing dependencies:', serviceName, servicesDeclarations);
return Promise.resolve().then(() => Promise.all(servicesDeclarations.map(serviceDeclaration => {
const { mappedName, optional } = (0, _util.parseDependencyDeclaration)(serviceDeclaration);
const {
mappedName,
optional
} = (0, _util.parseDependencyDeclaration)(serviceDeclaration);
return this._getServiceDescriptor(siloContext, injectOnly, mappedName).catch(err => {

@@ -662,2 +728,3 @@ if (optional) {

}
throw err;

@@ -672,2 +739,3 @@ });

}
return serviceDescriptor.service;

@@ -682,17 +750,15 @@ }));

}
}
exports.default = Knifecycle;
const getInstance = exports.getInstance = Knifecycle.getInstance;
exports.Knifecycle = Knifecycle;
exports.initializer = _util.initializer;
exports.name = _util.name;
exports.inject = _util.inject;
exports.type = _util.type;
exports.options = _util.options;
var _default = Knifecycle;
exports.default = _default;
const getInstance = Knifecycle.getInstance;
exports.getInstance = getInstance;
function _pickServiceNameFromDeclaration(dependencyDeclaration) {
const { serviceName } = (0, _util.parseDependencyDeclaration)(dependencyDeclaration);
const {
serviceName
} = (0, _util.parseDependencyDeclaration)(dependencyDeclaration);
return serviceName;

@@ -702,4 +768,6 @@ }

function _pickMappedNameFromDeclaration(dependencyDeclaration) {
const { serviceName, mappedName } = (0, _util.parseDependencyDeclaration)(dependencyDeclaration);
const {
serviceName,
mappedName
} = (0, _util.parseDependencyDeclaration)(dependencyDeclaration);
return mappedName || serviceName;

@@ -715,6 +783,9 @@ }

}
matches = shape.pattern.exec(serviceName);
if (!matches) {
return shapedService;
}
return shape.template.replace(/\$([0-9])+/g, ($, $1) => matches[parseInt($1, 10)]);

@@ -728,16 +799,23 @@ }, '');

function _applyStyles(classes, styles, { serviceName, dependedServiceName }) {
function _applyStyles(classes, styles, {
serviceName,
dependedServiceName
}) {
return styles.reduce((classesApplications, style) => {
if (style.pattern.test(serviceName) && !classesApplications[serviceName]) {
if (!classes[style.className]) {
throw new _yerror2.default('E_BAD_CLASS', style.className, serviceName);
throw new _yerror.default('E_BAD_CLASS', style.className, serviceName);
}
classesApplications[serviceName] = style.className;
}
if (style.pattern.test(dependedServiceName) && !classesApplications[dependedServiceName]) {
if (!classes[style.className]) {
throw new _yerror2.default('E_BAD_CLASS', style.className, dependedServiceName);
throw new _yerror.default('E_BAD_CLASS', style.className, dependedServiceName);
}
classesApplications[dependedServiceName] = style.className;
}
return classesApplications;

@@ -751,4 +829,5 @@ }, {});

if (!servicePromise || !servicePromise.then) {
throw new _yerror2.default(E_BAD_SERVICE_PROMISE, serviceName);
throw new _yerror.default(E_BAD_SERVICE_PROMISE, serviceName);
}
return servicePromise.then(_service_ => Promise.resolve({

@@ -755,0 +834,0 @@ service: _service_

@@ -1,15 +0,12 @@

'use strict';
"use strict";
var _assert = require('assert');
var _assert = _interopRequireDefault(require("assert"));
var _assert2 = _interopRequireDefault(_assert);
var _sinon = _interopRequireDefault(require("sinon"));
var _sinon = require('sinon');
var _index = require("./index");
var _sinon2 = _interopRequireDefault(_sinon);
var _index = require('./index');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* eslint max-nested-callbacks:0 */
describe('Knifecycle', () => {

@@ -35,13 +32,10 @@ let $;

});
describe('getInstance', () => {
it('should return an instance', () => {
(0, _assert2.default)(_index.Knifecycle.getInstance());
(0, _assert.default)(_index.Knifecycle.getInstance());
});
it('should always return the same instance', () => {
_assert2.default.equal(_index.Knifecycle.getInstance(), _index.Knifecycle.getInstance());
_assert.default.equal(_index.Knifecycle.getInstance(), _index.Knifecycle.getInstance());
});
});
describe('constant', () => {

@@ -51,9 +45,7 @@ it('should register an object', () => {

});
it('should register a function', () => {
$.constant('time', time);
});
it('should fail with dependencies since it makes no sense', () => {
_assert2.default.throws(() => {
_assert.default.throws(() => {
$.constant('time', (0, _index.inject)(['hash3'], time));

@@ -63,3 +55,2 @@ }, /E_CONSTANT_INJECTION/);

});
describe('service', () => {

@@ -70,3 +61,2 @@ it('should register service', () => {

});
describe('provider', () => {

@@ -76,25 +66,26 @@ it('should register provider', () => {

});
it('should fail with direct circular dependencies', () => {
_assert2.default.throws(() => {
_assert.default.throws(() => {
$.provider('hash', (0, _index.inject)(['hash'], hashProvider));
}, err => {
_assert2.default.deepEqual(err.code, 'E_CIRCULAR_DEPENDENCY');
_assert2.default.deepEqual(err.params, ['hash']);
_assert.default.deepEqual(err.code, 'E_CIRCULAR_DEPENDENCY');
_assert.default.deepEqual(err.params, ['hash']);
return true;
});
});
it('should fail with direct circular dependencies on mapped services', () => {
_assert2.default.throws(() => {
_assert.default.throws(() => {
$.provider('hash', (0, _index.inject)(['hash>lol'], hashProvider));
}, err => {
_assert2.default.deepEqual(err.code, 'E_CIRCULAR_DEPENDENCY');
_assert2.default.deepEqual(err.params, ['hash']);
_assert.default.deepEqual(err.code, 'E_CIRCULAR_DEPENDENCY');
_assert.default.deepEqual(err.params, ['hash']);
return true;
});
});
it('should fail with circular dependencies', () => {
_assert2.default.throws(() => {
_assert.default.throws(() => {
$.provider('hash', (0, _index.inject)(['hash3'], hashProvider));

@@ -105,10 +96,11 @@ $.provider('hash1', (0, _index.inject)(['hash'], hashProvider));

}, err => {
_assert2.default.deepEqual(err.code, 'E_CIRCULAR_DEPENDENCY');
_assert2.default.deepEqual(err.params, ['hash3', 'hash', 'hash3']);
_assert.default.deepEqual(err.code, 'E_CIRCULAR_DEPENDENCY');
_assert.default.deepEqual(err.params, ['hash3', 'hash', 'hash3']);
return true;
});
});
it('should fail with deeper circular dependencies', () => {
_assert2.default.throws(() => {
_assert.default.throws(() => {
$.provider('hash', (0, _index.inject)(['hash1'], hashProvider));

@@ -119,10 +111,11 @@ $.provider('hash1', (0, _index.inject)(['hash2'], hashProvider));

}, err => {
_assert2.default.deepEqual(err.code, 'E_CIRCULAR_DEPENDENCY');
_assert2.default.deepEqual(err.params, ['hash3', 'hash', 'hash1', 'hash2', 'hash3']);
_assert.default.deepEqual(err.code, 'E_CIRCULAR_DEPENDENCY');
_assert.default.deepEqual(err.params, ['hash3', 'hash', 'hash1', 'hash2', 'hash3']);
return true;
});
});
it('should fail with circular dependencies on mapped services', () => {
_assert2.default.throws(() => {
_assert.default.throws(() => {
$.provider('hash', (0, _index.inject)(['hash3>aHash3'], hashProvider));

@@ -133,4 +126,6 @@ $.provider('hash1', (0, _index.inject)(['hash>aHash'], hashProvider));

}, err => {
_assert2.default.deepEqual(err.code, 'E_CIRCULAR_DEPENDENCY');
_assert2.default.deepEqual(err.params, ['hash3', 'hash>aHash', 'hash3>aHash3']);
_assert.default.deepEqual(err.code, 'E_CIRCULAR_DEPENDENCY');
_assert.default.deepEqual(err.params, ['hash3', 'hash>aHash', 'hash3>aHash3']);
return true;

@@ -140,17 +135,15 @@ });

});
describe('run', () => {
it('should work with no dependencies', done => {
$.run([]).then(dependencies => {
_assert2.default.deepEqual(dependencies, {});
_assert.default.deepEqual(dependencies, {});
}).then(() => done()).catch(done);
});
it('should work with constant dependencies', done => {
$.constant('ENV', ENV);
$.constant('time', time);
$.run(['time', 'ENV']).then(dependencies => {
_assert.default.deepEqual(Object.keys(dependencies), ['time', 'ENV']);
$.run(['time', 'ENV']).then(dependencies => {
_assert2.default.deepEqual(Object.keys(dependencies), ['time', 'ENV']);
_assert2.default.deepEqual(dependencies, {
_assert.default.deepEqual(dependencies, {
ENV,

@@ -161,12 +154,13 @@ time

});
it('should work with service dependencies', done => {
$.service('sample', (0, _index.inject)(['time'], function sampleService({ time }) {
$.service('sample', (0, _index.inject)(['time'], function sampleService({
time
}) {
return Promise.resolve(typeof time);
}));
$.constant('time', time);
$.run(['sample']).then(dependencies => {
_assert.default.deepEqual(Object.keys(dependencies), ['sample']);
$.run(['sample']).then(dependencies => {
_assert2.default.deepEqual(Object.keys(dependencies), ['sample']);
_assert2.default.deepEqual(dependencies, {
_assert.default.deepEqual(dependencies, {
sample: 'function'

@@ -176,3 +170,2 @@ });

});
it('should work with simple dependencies', done => {

@@ -182,7 +175,9 @@ $.constant('ENV', ENV);

$.provider('hash', (0, _index.inject)(['ENV'], hashProvider));
$.run(['time', 'hash']).then(dependencies => {
_assert.default.deepEqual(Object.keys(dependencies), ['time', 'hash']);
$.run(['time', 'hash']).then(dependencies => {
_assert2.default.deepEqual(Object.keys(dependencies), ['time', 'hash']);
_assert2.default.deepEqual(dependencies, {
hash: { ENV },
_assert.default.deepEqual(dependencies, {
hash: {
ENV
},
time

@@ -192,3 +187,2 @@ });

});
it('should work with given optional dependencies', done => {

@@ -199,7 +193,10 @@ $.constant('ENV', ENV);

$.provider('hash', (0, _index.inject)(['ENV', '?DEBUG'], hashProvider));
$.run(['time', 'hash']).then(dependencies => {
_assert.default.deepEqual(Object.keys(dependencies), ['time', 'hash']);
$.run(['time', 'hash']).then(dependencies => {
_assert2.default.deepEqual(Object.keys(dependencies), ['time', 'hash']);
_assert2.default.deepEqual(dependencies, {
hash: { ENV, DEBUG: {} },
_assert.default.deepEqual(dependencies, {
hash: {
ENV,
DEBUG: {}
},
time

@@ -209,3 +206,2 @@ });

});
it('should work with lacking optional dependencies', done => {

@@ -215,7 +211,10 @@ $.constant('ENV', ENV);

$.provider('hash', (0, _index.inject)(['ENV', '?DEBUG'], hashProvider));
$.run(['time', 'hash']).then(dependencies => {
_assert.default.deepEqual(Object.keys(dependencies), ['time', 'hash']);
$.run(['time', 'hash']).then(dependencies => {
_assert2.default.deepEqual(Object.keys(dependencies), ['time', 'hash']);
_assert2.default.deepEqual(dependencies, {
hash: { ENV, DEBUG: {}.undef },
_assert.default.deepEqual(dependencies, {
hash: {
ENV,
DEBUG: {}.undef
},
time

@@ -225,3 +224,2 @@ });

});
it('should work with deeper dependencies', done => {

@@ -236,10 +234,8 @@ $.constant('ENV', ENV);

$.provider('hash5', (0, _index.inject)(['hash4'], hashProvider));
$.run(['hash5', 'time']).then(dependencies => {
_assert2.default.deepEqual(Object.keys(dependencies), ['hash5', 'time']);
_assert.default.deepEqual(Object.keys(dependencies), ['hash5', 'time']);
}).then(() => done()).catch(done);
});
it('should instanciate services once', done => {
const timeServiceStub = _sinon2.default.spy(timeService);
const timeServiceStub = _sinon.default.spy(timeService);

@@ -251,14 +247,14 @@ $.constant('ENV', ENV);

$.provider('hash3', (0, _index.inject)(['ENV', 'time'], hashProvider));
$.run(['hash', 'hash2', 'hash3', 'time']).then(dependencies => {
_assert.default.deepEqual(Object.keys(dependencies), ['hash', 'hash2', 'hash3', 'time']);
$.run(['hash', 'hash2', 'hash3', 'time']).then(dependencies => {
_assert2.default.deepEqual(Object.keys(dependencies), ['hash', 'hash2', 'hash3', 'time']);
_assert2.default.deepEqual(timeServiceStub.args, [[{}]]);
_assert.default.deepEqual(timeServiceStub.args, [[{}]]);
}).then(() => done()).catch(done);
});
it('should instanciate a single mapped service', done => {
const providerStub = _sinon2.default.stub().returns(Promise.resolve({
const providerStub = _sinon.default.stub().returns(Promise.resolve({
service: 'stub'
}));
const providerStub2 = _sinon2.default.stub().returns(Promise.resolve({
const providerStub2 = _sinon.default.stub().returns(Promise.resolve({
service: 'stub2'

@@ -270,6 +266,7 @@ }));

$.run(['stub>mappedStub']).then(dependencies => {
_assert2.default.deepEqual(dependencies, {
_assert.default.deepEqual(dependencies, {
stub: 'stub'
});
_assert2.default.deepEqual(providerStub.args, [[{
_assert.default.deepEqual(providerStub.args, [[{
stub2: 'stub2'

@@ -279,5 +276,4 @@ }]]);

});
it('should instanciate several services with mappings', done => {
const timeServiceStub = _sinon2.default.spy(timeService);
const timeServiceStub = _sinon.default.spy(timeService);

@@ -289,9 +285,8 @@ $.constant('ENV', ENV);

$.provider('aHash3', (0, _index.inject)(['ENV', 'hash>aHash'], hashProvider));
$.run(['hash2>aHash2', 'hash3>aHash3', 'time>aTime']).then(dependencies => {
_assert.default.deepEqual(Object.keys(dependencies), ['hash2', 'hash3', 'time']);
$.run(['hash2>aHash2', 'hash3>aHash3', 'time>aTime']).then(dependencies => {
_assert2.default.deepEqual(Object.keys(dependencies), ['hash2', 'hash3', 'time']);
_assert2.default.deepEqual(timeServiceStub.args, [[{}]]);
_assert.default.deepEqual(timeServiceStub.args, [[{}]]);
}).then(() => done()).catch(done);
});
it('should fail with bad service', done => {

@@ -302,7 +297,7 @@ $.service('lol', () => {});

}).catch(err => {
_assert2.default.deepEqual(err.code, 'E_BAD_SERVICE_PROMISE');
_assert2.default.deepEqual(err.params, ['lol']);
_assert.default.deepEqual(err.code, 'E_BAD_SERVICE_PROMISE');
_assert.default.deepEqual(err.params, ['lol']);
}).then(() => done()).catch(done);
});
it('should fail with bad provider', done => {

@@ -313,7 +308,7 @@ $.provider('lol', () => {});

}).catch(err => {
_assert2.default.deepEqual(err.code, 'E_BAD_SERVICE_PROVIDER');
_assert2.default.deepEqual(err.params, ['lol']);
_assert.default.deepEqual(err.code, 'E_BAD_SERVICE_PROVIDER');
_assert.default.deepEqual(err.params, ['lol']);
}).then(() => done()).catch(done);
});
it('should fail with bad service in a provider', done => {

@@ -324,7 +319,7 @@ $.provider('lol', () => Promise.resolve());

}).catch(err => {
_assert2.default.deepEqual(err.code, 'E_BAD_SERVICE_PROVIDER');
_assert2.default.deepEqual(err.params, ['lol']);
_assert.default.deepEqual(err.code, 'E_BAD_SERVICE_PROVIDER');
_assert.default.deepEqual(err.params, ['lol']);
}).then(() => done()).catch(done);
});
it('should fail with undeclared dependencies', done => {

@@ -334,7 +329,7 @@ $.run(['lol']).then(() => {

}).catch(err => {
_assert2.default.deepEqual(err.code, 'E_UNMATCHED_DEPENDENCY');
_assert2.default.deepEqual(err.params, ['lol']);
_assert.default.deepEqual(err.code, 'E_UNMATCHED_DEPENDENCY');
_assert.default.deepEqual(err.params, ['lol']);
}).then(() => done()).catch(done);
});
it('should fail with undeclared dependencies upstream', done => {

@@ -345,11 +340,10 @@ $.constant('ENV', ENV);

$.provider('hash2', (0, _index.inject)(['ENV', 'lol'], hashProvider));
$.run(['time', 'hash']).then(() => {
throw new Error('E_UNEXPECTED_SUCCESS');
}).catch(err => {
_assert2.default.deepEqual(err.code, 'E_UNMATCHED_DEPENDENCY');
_assert2.default.deepEqual(err.params, ['hash', 'hash2', 'lol']);
_assert.default.deepEqual(err.code, 'E_UNMATCHED_DEPENDENCY');
_assert.default.deepEqual(err.params, ['hash', 'hash2', 'lol']);
}).then(() => done()).catch(done);
});
it('should provide a fatal error handler', done => {

@@ -362,3 +356,5 @@ $.constant('ENV', ENV);

function processProvider({ $fatalError }) {
function processProvider({
$fatalError
}) {
return Promise.resolve({

@@ -371,3 +367,5 @@ service: {

function dbProvider({ ENV }) {
function dbProvider({
ENV
}) {
return Promise.resolve().then(() => {

@@ -382,3 +380,2 @@ let service;

});
return {

@@ -391,7 +388,10 @@ service,

$.run(['time', 'hash', 'db', 'process']).then(({ process, db }) => {
$.run(['time', 'hash', 'db', 'process']).then(({
process,
db
}) => {
process.fatalErrorPromise.then(() => {
done(new Error('E_UNEXPECTED_SUCCESS'));
}).catch(err => {
_assert2.default.deepEqual(err.message, 'E_DB_ERROR');
_assert.default.deepEqual(err.message, 'E_DB_ERROR');
}).then(() => done()).catch(done);

@@ -402,3 +402,2 @@ db.reject(new Error('E_DB_ERROR'));

});
describe('inject', () => {

@@ -409,12 +408,12 @@ it('should work with no dependencies', done => {

$.provider('hash', (0, _index.inject)(['ENV'], hashProvider));
$.run(['time', 'hash', '$injector']).then(dependencies => {
_assert.default.deepEqual(Object.keys(dependencies), ['time', 'hash', '$injector']);
$.run(['time', 'hash', '$injector']).then(dependencies => {
_assert2.default.deepEqual(Object.keys(dependencies), ['time', 'hash', '$injector']);
return dependencies.$injector([]).then(injectDependencies => {
_assert2.default.deepEqual(Object.keys(injectDependencies), []);
_assert2.default.deepEqual(injectDependencies, {});
_assert.default.deepEqual(Object.keys(injectDependencies), []);
_assert.default.deepEqual(injectDependencies, {});
});
}).then(() => done()).catch(done);
});
it('should work with same dependencies then the running silo', done => {

@@ -424,9 +423,12 @@ $.constant('ENV', ENV);

$.provider('hash', (0, _index.inject)(['ENV'], hashProvider));
$.run(['time', 'hash', '$injector']).then(dependencies => {
_assert.default.deepEqual(Object.keys(dependencies), ['time', 'hash', '$injector']);
$.run(['time', 'hash', '$injector']).then(dependencies => {
_assert2.default.deepEqual(Object.keys(dependencies), ['time', 'hash', '$injector']);
return dependencies.$injector(['time', 'hash']).then(injectDependencies => {
_assert2.default.deepEqual(Object.keys(injectDependencies), ['time', 'hash']);
_assert2.default.deepEqual(injectDependencies, {
hash: { ENV },
_assert.default.deepEqual(Object.keys(injectDependencies), ['time', 'hash']);
_assert.default.deepEqual(injectDependencies, {
hash: {
ENV
},
time

@@ -437,3 +439,2 @@ });

});
it('should fail with non instanciated dependencies', done => {

@@ -443,23 +444,27 @@ $.constant('ENV', ENV);

$.provider('hash', (0, _index.inject)(['ENV'], hashProvider));
$.run(['time', '$injector']).then(dependencies => {
_assert.default.deepEqual(Object.keys(dependencies), ['time', '$injector']);
$.run(['time', '$injector']).then(dependencies => {
_assert2.default.deepEqual(Object.keys(dependencies), ['time', '$injector']);
return dependencies.$injector(['time', 'hash']).catch(err => {
_assert2.default.equal(err.code, 'E_BAD_INJECTION');
_assert.default.equal(err.code, 'E_BAD_INJECTION');
});
}).then(() => done()).catch(done);
});
it('should create dependencies when not declared as singletons', done => {
$.constant('ENV', ENV);
$.provider('hash', (0, _index.inject)(['ENV'], hashProvider));
Promise.all([$.run(['hash']), $.run(['hash'])]).then(([{
hash
}, {
hash: sameHash
}]) => {
_assert.default.notEqual(hash, sameHash);
Promise.all([$.run(['hash']), $.run(['hash'])]).then(([{ hash }, { hash: sameHash }]) => {
_assert2.default.notEqual(hash, sameHash);
return $.run(['hash']).then(({ hash: yaSameHash }) => {
_assert2.default.notEqual(hash, yaSameHash);
return $.run(['hash']).then(({
hash: yaSameHash
}) => {
_assert.default.notEqual(hash, yaSameHash);
});
}).then(() => done()).catch(done);
});
it('should reuse dependencies when declared as singletons', done => {

@@ -473,8 +478,17 @@ $.constant('ENV', ENV);

}, hashProvider)));
Promise.all([$.run(['hash']), $.run(['hash']), $.run(['hash2']), $.run(['hash2'])]).then(([{
hash,
hash2
}, {
hash: sameHash,
hash2: sameHash2
}]) => {
_assert.default.equal(hash, sameHash);
Promise.all([$.run(['hash']), $.run(['hash']), $.run(['hash2']), $.run(['hash2'])]).then(([{ hash, hash2 }, { hash: sameHash, hash2: sameHash2 }]) => {
_assert2.default.equal(hash, sameHash);
_assert2.default.equal(hash2, sameHash2);
return $.run(['hash']).then(({ hash: yaSameHash }) => {
_assert2.default.equal(hash, yaSameHash);
_assert.default.equal(hash2, sameHash2);
return $.run(['hash']).then(({
hash: yaSameHash
}) => {
_assert.default.equal(hash, yaSameHash);
});

@@ -484,7 +498,6 @@ }).then(() => done()).catch(done);

});
describe('$destroy', () => {
it('should work even with one silo and no dependencies', done => {
$.run(['$destroy']).then(dependencies => {
_assert2.default.equal(typeof dependencies.$destroy, 'function');
_assert.default.equal(typeof dependencies.$destroy, 'function');

@@ -494,12 +507,12 @@ return dependencies.$destroy();

});
it('should work with several silos and dependencies', done => {
$.constant('ENV', ENV);
$.constant('time', time);
$.provider('hash', (0, _index.inject)(['ENV'], hashProvider), { singleton: true });
$.provider('hash', (0, _index.inject)(['ENV'], hashProvider), {
singleton: true
});
$.provider('hash1', (0, _index.inject)(['ENV'], hashProvider));
$.provider('hash2', (0, _index.inject)(['ENV'], hashProvider));
Promise.all([$.run(['$destroy']), $.run(['ENV', 'hash', 'hash1', 'time']), $.run(['ENV', 'hash', 'hash2'])]).then(([dependencies]) => {
_assert2.default.equal(typeof dependencies.$destroy, 'function');
_assert.default.equal(typeof dependencies.$destroy, 'function');

@@ -509,3 +522,2 @@ return dependencies.$destroy();

});
it('should work when trigered from several silos simultaneously', done => {

@@ -517,6 +529,4 @@ $.constant('ENV', ENV);

$.provider('hash2', (0, _index.inject)(['ENV'], hashProvider));
Promise.all([$.run(['$destroy']), $.run(['$destroy', 'ENV', 'hash', 'hash1', 'time']), $.run(['$destroy', 'ENV', 'hash', 'hash2'])]).then(dependenciesBuckets => Promise.all(dependenciesBuckets.map(dependencies => dependencies.$destroy()))).then(() => done()).catch(done);
});
it('should work when a silo shutdown is in progress', done => {

@@ -528,6 +538,4 @@ $.constant('ENV', ENV);

$.provider('hash2', (0, _index.inject)(['ENV'], hashProvider));
Promise.all([$.run(['$destroy']), $.run(['$dispose', 'ENV', 'hash', 'hash1', 'time']), $.run(['ENV', 'hash', 'hash2'])]).then(([dependencies1, dependencies2]) => Promise.all([dependencies2.$dispose(), dependencies1.$destroy()])).then(() => done()).catch(done);
});
it('should disallow new runs', done => {

@@ -538,10 +546,10 @@ $.constant('ENV', ENV);

$.provider('hash1', (0, _index.inject)(['ENV'], hashProvider));
$.run(['$destroy']).then(dependencies => {
_assert2.default.equal(typeof dependencies.$destroy, 'function');
_assert.default.equal(typeof dependencies.$destroy, 'function');
return dependencies.$destroy();
}).then(() => {
_assert2.default.throws(() => $.run(['ENV', 'hash', 'hash1']), err => {
_assert2.default.equal(err.code, 'E_INSTANCE_DESTROYED');
_assert.default.throws(() => $.run(['ENV', 'hash', 'hash1']), err => {
_assert.default.equal(err.code, 'E_INSTANCE_DESTROYED');
return true;

@@ -552,7 +560,6 @@ });

});
describe('$dispose', () => {
it('should work with no dependencies', done => {
$.run(['$dispose']).then(dependencies => {
_assert2.default.equal(typeof dependencies.$dispose, 'function');
_assert.default.equal(typeof dependencies.$dispose, 'function');

@@ -562,9 +569,7 @@ return dependencies.$dispose();

});
it('should work with constant dependencies', done => {
$.constant('ENV', ENV);
$.constant('time', time);
$.run(['time', 'ENV', '$dispose']).then(dependencies => {
_assert2.default.deepEqual(Object.keys(dependencies), ['time', 'ENV', '$dispose']);
_assert.default.deepEqual(Object.keys(dependencies), ['time', 'ENV', '$dispose']);

@@ -574,3 +579,2 @@ return dependencies.$dispose();

});
it('should work with simple dependencies', done => {

@@ -580,5 +584,4 @@ $.constant('ENV', ENV);

$.provider('hash', (0, _index.inject)(['ENV'], hashProvider));
$.run(['time', 'hash', '$dispose']).then(dependencies => {
_assert2.default.deepEqual(Object.keys(dependencies), ['time', 'hash', '$dispose']);
_assert.default.deepEqual(Object.keys(dependencies), ['time', 'hash', '$dispose']);

@@ -588,3 +591,2 @@ return dependencies.$dispose();

});
it('should work with deeper dependencies', done => {

@@ -596,3 +598,4 @@ let shutdownCallResolve;

});
const shutdownStub = _sinon2.default.spy(() => {
const shutdownStub = _sinon.default.spy(() => {
shutdownCallResolve();

@@ -619,15 +622,13 @@ return new Promise(resolve => {

})));
$.run(['hash5', 'time', '$dispose', 'shutdownChecker']).then(dependencies => {
_assert2.default.deepEqual(Object.keys(dependencies), ['hash5', 'time', '$dispose', 'shutdownChecker']);
_assert.default.deepEqual(Object.keys(dependencies), ['hash5', 'time', '$dispose', 'shutdownChecker']);
shutdownCallPromise.then(() => {
_assert2.default.deepEqual(shutdownStub.args, [[]]);
_assert.default.deepEqual(shutdownStub.args, [[]]);
shutdownResolve();
}).catch(done);
return dependencies.$dispose();
}).then(done).catch(done);
});
it('should work with deeper multi used dependencies', done => {

@@ -639,3 +640,4 @@ let shutdownCallResolve;

});
const shutdownStub = _sinon2.default.spy(() => {
const shutdownStub = _sinon.default.spy(() => {
shutdownCallResolve();

@@ -658,17 +660,15 @@ return new Promise(resolve => {

$.provider('hash2', (0, _index.inject)(['shutdownChecker'], hashProvider));
$.run(['hash1', 'hash2', '$dispose', 'shutdownChecker']).then(dependencies => {
_assert2.default.deepEqual(Object.keys(dependencies), ['hash1', 'hash2', '$dispose', 'shutdownChecker']);
_assert.default.deepEqual(Object.keys(dependencies), ['hash1', 'hash2', '$dispose', 'shutdownChecker']);
shutdownCallPromise.then(() => {
_assert2.default.deepEqual(shutdownStub.args, [[]]);
_assert.default.deepEqual(shutdownStub.args, [[]]);
shutdownResolve();
}).catch(done);
return dependencies.$dispose();
}).then(() => done()).catch(done);
});
it('should delay service shutdown to their deeper dependencies', done => {
const servicesShutdownCalls = _sinon2.default.spy(() => Promise.resolve());
const servicesShutdownCalls = _sinon.default.spy(() => Promise.resolve());

@@ -687,11 +687,10 @@ $.provider('hash', () => Promise.resolve({

})));
$.run(['hash2', '$dispose']).then(dependencies => {
_assert.default.deepEqual(Object.keys(dependencies), ['hash2', '$dispose']);
$.run(['hash2', '$dispose']).then(dependencies => {
_assert2.default.deepEqual(Object.keys(dependencies), ['hash2', '$dispose']);
return dependencies.$dispose();
}).then(() => {
_assert2.default.deepEqual(servicesShutdownCalls.args, [['hash2'], ['hash1'], ['hash']]);
_assert.default.deepEqual(servicesShutdownCalls.args, [['hash2'], ['hash1'], ['hash']]);
}).then(() => done()).catch(done);
});
it('should not shutdown singleton dependencies if used elsewhere', done => {

@@ -703,10 +702,11 @@ $.constant('ENV', ENV);

});
$.run(['time', 'hash']).then(dependencies => {
const { hash } = dependencies;
const {
hash
} = dependencies;
return $.run(['time', 'hash', '$dispose']).then(dependencies => {
_assert.default.equal(dependencies.hash, hash);
return $.run(['time', 'hash', '$dispose']).then(dependencies => {
_assert2.default.equal(dependencies.hash, hash);
return dependencies.$dispose().then(() => $.run(['time', 'hash']).then(dependencies => {
_assert2.default.equal(dependencies.hash, hash);
_assert.default.equal(dependencies.hash, hash);
}));

@@ -716,3 +716,2 @@ });

});
it('should shutdown singleton dependencies if not used elsewhere', done => {

@@ -724,8 +723,8 @@ $.constant('ENV', ENV);

});
$.run(['time', 'hash', '$dispose']).then(dependencies => {
const { hash } = dependencies;
const {
hash
} = dependencies;
return dependencies.$dispose().then(() => $.run(['time', 'hash']).then(dependencies => {
_assert2.default.notEqual(dependencies.hash, hash);
_assert.default.notEqual(dependencies.hash, hash);
}));

@@ -735,3 +734,2 @@ }).then(() => done()).catch(done);

});
describe('toMermaidGraph', () => {

@@ -741,5 +739,5 @@ it('should print nothing when no dependency', () => {

$.constant('time', time);
_assert2.default.equal($.toMermaidGraph(), '');
_assert.default.equal($.toMermaidGraph(), '');
});
it('should print a dependency graph', () => {

@@ -754,5 +752,5 @@ $.constant('ENV', ENV);

$.provider('hash5', (0, _index.inject)(['hash4'], hashProvider));
_assert2.default.equal($.toMermaidGraph(), 'graph TD\n' + ' hash-->ENV\n' + ' hash1-->hash\n' + ' hash2-->hash1\n' + ' hash3-->hash2\n' + ' hash4-->hash3\n' + ' hash5-->hash4');
_assert.default.equal($.toMermaidGraph(), 'graph TD\n' + ' hash-->ENV\n' + ' hash1-->hash\n' + ' hash2-->hash1\n' + ' hash3-->hash2\n' + ' hash4-->hash3\n' + ' hash5-->hash4');
});
it('should allow custom shapes', () => {

@@ -767,3 +765,4 @@ $.constant('ENV', ENV);

$.provider('hash5', (0, _index.inject)(['hash4'], hashProvider));
_assert2.default.equal($.toMermaidGraph({
_assert.default.equal($.toMermaidGraph({
shapes: [{

@@ -781,3 +780,2 @@ pattern: /^hash([0-9]+)$/,

});
it('should allow custom styles', () => {

@@ -792,3 +790,4 @@ $.constant('ENV', ENV);

$.provider('hash5', (0, _index.inject)(['hash4'], hashProvider));
_assert2.default.equal($.toMermaidGraph({
_assert.default.equal($.toMermaidGraph({
classes: {

@@ -817,2 +816,2 @@ exotic: 'fill:#f9f,stroke:#333,stroke-width:4px;'

});
}); /* eslint max-nested-callbacks:0 */
});

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

'use strict';
"use strict";

@@ -6,18 +6,21 @@ Object.defineProperty(exports, "__esModule", {

});
exports.$ = undefined;
exports.default = exports.$ = void 0;
var _index = require('./index');
var _index = require("./index");
const $ = exports.$ = (0, _index.getInstance)(); /* Architecture Note #1.2: One instance to rule them all
We almost never need to use several Knifecycle instances.
This is why we are providing the `knifecycle/instance`
module that give a direct access to a lazy instanciated
`Knifecycle` instance.
At the same time, I prefer choosing when instantiating a
singleton this is why I decided to not do it on the behalf
of the developers by instead providing an opt-in interface
to this singleton.
*/
exports.default = $;
/* Architecture Note #1.2: One instance to rule them all
We almost never need to use several Knifecycle instances.
This is why we are providing the `knifecycle/instance`
module that give a direct access to a lazy instanciated
`Knifecycle` instance.
At the same time, I prefer choosing when instantiating a
singleton this is why I decided to not do it on the behalf
of the developers by instead providing an opt-in interface
to this singleton.
*/
const $ = (0, _index.getInstance)();
exports.$ = $;
var _default = $;
exports.default = _default;

@@ -1,15 +0,9 @@

'use strict';
"use strict";
var _assert = require('assert');
var _assert = _interopRequireDefault(require("assert"));
var _assert2 = _interopRequireDefault(_assert);
var _index = _interopRequireDefault(require("./index"));
var _index = require('./index');
var _instance = _interopRequireDefault(require("./instance"));
var _index2 = _interopRequireDefault(_index);
var _instance = require('./instance');
var _instance2 = _interopRequireDefault(_instance);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -19,4 +13,4 @@

it('should provide the singleton instance', () => {
_assert2.default.equal(_instance2.default, _index2.default.getInstance());
_assert.default.equal(_instance.default, _index.default.getInstance());
});
});

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

'use strict';
"use strict";

@@ -8,6 +8,4 @@ Object.defineProperty(exports, "__esModule", {

var _yerror = require('yerror');
var _yerror = _interopRequireDefault(require("yerror"));
var _yerror2 = _interopRequireDefault(_yerror);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -27,2 +25,3 @@

}
batches.push(batch);

@@ -33,3 +32,3 @@ i++;

if (i === MAX_ITERATIONS) {
throw new _yerror2.default('E_PROBABLE_CIRCULAR_DEPENDENCY');
throw new _yerror.default('E_PROBABLE_CIRCULAR_DEPENDENCY');
}

@@ -36,0 +35,0 @@

@@ -1,9 +0,7 @@

'use strict';
"use strict";
var _assert = require('assert');
var _assert = _interopRequireDefault(require("assert"));
var _assert2 = _interopRequireDefault(_assert);
var _sequence = require("./sequence");
var _sequence = require('./sequence');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -17,5 +15,4 @@

_assert2.default.deepEqual((0, _sequence.buildInitializationSequence)(tree), [['lol']]);
_assert.default.deepEqual((0, _sequence.buildInitializationSequence)(tree), [['lol']]);
});
it('should work with multi-level trees', () => {

@@ -53,5 +50,4 @@ const tree = {

_assert2.default.deepEqual((0, _sequence.buildInitializationSequence)(tree), [['lol 1.1.1', 'lol 1.2', 'lol 2.1', 'lol 3.1.1'], ['lol 1.1', 'lol 2', 'lol 3.1'], ['lol 1', 'lol 3'], ['lol']]);
_assert.default.deepEqual((0, _sequence.buildInitializationSequence)(tree), [['lol 1.1.1', 'lol 1.2', 'lol 2.1', 'lol 3.1.1'], ['lol 1.1', 'lol 2', 'lol 3.1'], ['lol 1', 'lol 3'], ['lol']]);
});
it('should work with multi-level trees and cross dependencies', () => {

@@ -107,4 +103,4 @@ const tree = {

_assert2.default.deepEqual((0, _sequence.buildInitializationSequence)(tree), [['lol 1.1.1', 'lol 1.2', 'lol 2.1'], ['lol 1.1', 'lol 2'], ['lol 3.1'], ['lol 3'], ['lol 1.3'], ['lol 1'], ['lol']]);
_assert.default.deepEqual((0, _sequence.buildInitializationSequence)(tree), [['lol 1.1.1', 'lol 1.2', 'lol 2.1'], ['lol 1.1', 'lol 2'], ['lol 3.1'], ['lol 3'], ['lol 1.3'], ['lol 1'], ['lol']]);
});
});

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

'use strict';
"use strict";

@@ -6,3 +6,2 @@ Object.defineProperty(exports, "__esModule", {

});
exports.OPTIONAL_FLAG = exports.DECLARATION_SEPARATOR = exports.ALLOWED_SPECIAL_PROPS = exports.SPECIAL_PROPS = exports.SPECIAL_PROPS_PREFIX = undefined;
exports.reuseSpecialProps = reuseSpecialProps;

@@ -18,17 +17,18 @@ exports.wrapInitializer = wrapInitializer;

exports.parseDependencyDeclaration = parseDependencyDeclaration;
exports.OPTIONAL_FLAG = exports.DECLARATION_SEPARATOR = exports.ALLOWED_SPECIAL_PROPS = exports.SPECIAL_PROPS = exports.SPECIAL_PROPS_PREFIX = void 0;
var _yerror = require('yerror');
var _yerror = _interopRequireDefault(require("yerror"));
var _yerror2 = _interopRequireDefault(_yerror);
var _debug = _interopRequireDefault(require("debug"));
var _debug = require('debug');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var _debug2 = _interopRequireDefault(_debug);
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
const debug = (0, _debug2.default)('knifecycle');
const SPECIAL_PROPS_PREFIX = exports.SPECIAL_PROPS_PREFIX = '$';
const SPECIAL_PROPS = exports.SPECIAL_PROPS = {
const debug = (0, _debug.default)('knifecycle');
const SPECIAL_PROPS_PREFIX = '$';
exports.SPECIAL_PROPS_PREFIX = SPECIAL_PROPS_PREFIX;
const SPECIAL_PROPS = {
INJECT: `${SPECIAL_PROPS_PREFIX}inject`,

@@ -40,6 +40,8 @@ OPTIONS: `${SPECIAL_PROPS_PREFIX}options`,

};
const ALLOWED_SPECIAL_PROPS = exports.ALLOWED_SPECIAL_PROPS = Object.keys(SPECIAL_PROPS).map(key => SPECIAL_PROPS[key]);
const DECLARATION_SEPARATOR = exports.DECLARATION_SEPARATOR = '>';
const OPTIONAL_FLAG = exports.OPTIONAL_FLAG = '?';
exports.SPECIAL_PROPS = SPECIAL_PROPS;
const ALLOWED_SPECIAL_PROPS = Object.keys(SPECIAL_PROPS).map(key => SPECIAL_PROPS[key]);
exports.ALLOWED_SPECIAL_PROPS = ALLOWED_SPECIAL_PROPS;
const DECLARATION_SEPARATOR = '>';
exports.DECLARATION_SEPARATOR = DECLARATION_SEPARATOR;
const OPTIONAL_FLAG = '?';
/**

@@ -52,5 +54,9 @@ * Apply special props to the given function from another one

*/
exports.OPTIONAL_FLAG = OPTIONAL_FLAG;
function reuseSpecialProps(from, to, amend = {}) {
return [...new Set(Object.keys(from).concat(Object.keys(amend)))].filter(prop => prop.startsWith(SPECIAL_PROPS_PREFIX)).reduce((fn, prop) => {
const value = 'undefined' !== typeof amend[prop] ? amend[prop] : from[prop];
if (value instanceof Array) {

@@ -63,6 +69,6 @@ fn[prop] = value.concat();

}
return fn;
}, to.bind());
}
/**

@@ -78,6 +84,7 @@ * Allows to wrap an initializer to add extra

*/
function wrapInitializer(wrapper, baseInitializer) {
return reuseSpecialProps(baseInitializer, services => baseInitializer(services).then(wrapper.bind(null, services)));
}
/**

@@ -107,2 +114,4 @@ * Decorator creating a new initializer with some

*/
function inject(dependenciesDeclarations, initializer, merge = false) {

@@ -112,8 +121,5 @@ const uniqueInitializer = reuseSpecialProps(initializer, initializer, {

});
debug('Wrapped an initializer with dependencies:', dependenciesDeclarations);
return uniqueInitializer;
}
/**

@@ -144,2 +150,4 @@ * Decorator creating a new initializer with some

*/
function extra(extraInformations, initializer, merge = false) {

@@ -149,8 +157,5 @@ const uniqueInitializer = reuseSpecialProps(initializer, initializer, {

});
debug('Wrapped an initializer with extra informations:', extraInformations);
return uniqueInitializer;
}
/**

@@ -181,2 +186,4 @@ * Decorator to amend an initializer options.

*/
function options(options, initializer, merge = false) {

@@ -186,8 +193,5 @@ const uniqueInitializer = reuseSpecialProps(initializer, initializer, {

});
debug('Wrapped an initializer with options:', options);
return uniqueInitializer;
}
/**

@@ -209,2 +213,4 @@ * Decorator to set an initializer name.

*/
function name(name, initializer) {

@@ -214,8 +220,5 @@ const uniqueInitializer = reuseSpecialProps(initializer, initializer, {

});
debug('Wrapped an initializer with a name:', name);
return uniqueInitializer;
}
/**

@@ -243,2 +246,4 @@ * Decorator to set an initializer type.

*/
function type(type, initializer) {

@@ -248,8 +253,5 @@ const uniqueInitializer = reuseSpecialProps(initializer, initializer, {

});
debug('Wrapped an initializer with a type:', type);
return uniqueInitializer;
}
/**

@@ -276,2 +278,4 @@ * Decorator to set an initializer properties.

*/
function initializer(properties, initializer) {

@@ -282,13 +286,11 @@ const uniqueInitializer = reuseSpecialProps(initializer, initializer, Object.keys(properties).reduce((finalProperties, property) => {

if (!ALLOWED_SPECIAL_PROPS.includes(finalProperty)) {
throw new _yerror2.default('E_BAD_PROPERTY', property);
throw new _yerror.default('E_BAD_PROPERTY', property);
}
finalProperties[finalProperty] = properties[property];
return finalProperties;
}, {}));
debug('Wrapped an initializer with properties:', properties);
return uniqueInitializer;
}
/**

@@ -300,2 +302,4 @@ * Shortcut to create an initializer with a simple handler

* The dependencies to inject in it
* @param {Object} [extra]
* Optional extra data to associate with the handler
* @return {Function}

@@ -316,13 +320,26 @@ * Returns a new initializer

*/
function handler(handlerFunction, dependencies = []) {
function handler(handlerFunction, dependencies = [], extra) {
if (!handlerFunction.name) {
throw new _yerror2.default('E_NO_HANDLER_NAME');
throw new _yerror.default('E_NO_HANDLER_NAME');
}
return initializer({
name: handlerFunction.name,
type: 'service',
inject: dependencies
}, (...args) => Promise.resolve(handlerFunction.bind(null, ...args)));
inject: dependencies,
extra
},
/*#__PURE__*/
function () {
var _ref = _asyncToGenerator(function* (...args) {
return handlerFunction.bind(null, ...args);
});
return function () {
return _ref.apply(this, arguments);
};
}());
}
/* Architecture Note #1.3.1: Dependencies declaration syntax

@@ -354,6 +371,7 @@

*/
function parseDependencyDeclaration(dependencyDeclaration) {
const optional = dependencyDeclaration.startsWith(OPTIONAL_FLAG);
const [serviceName, mappedName] = (optional ? dependencyDeclaration.slice(1) : dependencyDeclaration).split(DECLARATION_SEPARATOR);
return {

@@ -360,0 +378,0 @@ serviceName,

@@ -1,13 +0,9 @@

'use strict';
"use strict";
var _assert = require('assert');
var _assert = _interopRequireDefault(require("assert"));
var _assert2 = _interopRequireDefault(_assert);
var _sinon = _interopRequireDefault(require("sinon"));
var _sinon = require('sinon');
var _util = require("./util");
var _sinon2 = _interopRequireDefault(_sinon);
var _util = require('./util');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -21,2 +17,3 @@

// function are here just as placeholders
/* istanbul ignore next */

@@ -27,2 +24,4 @@ function from() {

/* istanbul ignore next */
function to() {

@@ -35,17 +34,28 @@ return 'to';

from.$inject = ['ki', 'kooo', 'lol'];
from.$options = { singleton: false };
from.$extra = { httpHandler: true };
from.$options = {
singleton: false
};
from.$extra = {
httpHandler: true
};
const newFn = (0, _util.reuseSpecialProps)(from, to);
_assert2.default.notEqual(newFn, to);
_assert2.default.equal(newFn.$name, from.$name);
_assert2.default.equal(newFn.$type, from.$type);
_assert2.default.notEqual(newFn.$inject, from.$inject);
_assert2.default.deepEqual(newFn.$inject, from.$inject);
_assert2.default.notEqual(newFn.$options, from.$options);
_assert2.default.deepEqual(newFn.$options, from.$options);
_assert2.default.notEqual(newFn.$extra, from.$extra);
_assert2.default.deepEqual(newFn.$extra, from.$extra);
_assert.default.notEqual(newFn, to);
_assert.default.equal(newFn.$name, from.$name);
_assert.default.equal(newFn.$type, from.$type);
_assert.default.notEqual(newFn.$inject, from.$inject);
_assert.default.deepEqual(newFn.$inject, from.$inject);
_assert.default.notEqual(newFn.$options, from.$options);
_assert.default.deepEqual(newFn.$options, from.$options);
_assert.default.notEqual(newFn.$extra, from.$extra);
_assert.default.deepEqual(newFn.$extra, from.$extra);
const newFn2 = (0, _util.reuseSpecialProps)(from, to, {

@@ -55,14 +65,21 @@ $name: 'yolo'

_assert2.default.notEqual(newFn2, to);
_assert2.default.equal(newFn2.$name, 'yolo');
_assert2.default.equal(newFn2.$type, from.$type);
_assert2.default.notEqual(newFn2.$inject, from.$inject);
_assert2.default.deepEqual(newFn2.$inject, from.$inject);
_assert2.default.notEqual(newFn2.$options, from.$options);
_assert2.default.deepEqual(newFn2.$options, from.$options);
_assert2.default.notEqual(newFn.$extra, from.$extra);
_assert2.default.deepEqual(newFn.$extra, from.$extra);
_assert.default.notEqual(newFn2, to);
_assert.default.equal(newFn2.$name, 'yolo');
_assert.default.equal(newFn2.$type, from.$type);
_assert.default.notEqual(newFn2.$inject, from.$inject);
_assert.default.deepEqual(newFn2.$inject, from.$inject);
_assert.default.notEqual(newFn2.$options, from.$options);
_assert.default.deepEqual(newFn2.$options, from.$options);
_assert.default.notEqual(newFn.$extra, from.$extra);
_assert.default.deepEqual(newFn.$extra, from.$extra);
});
});
describe('wrapInitializer', done => {

@@ -77,18 +94,26 @@ it('should work', () => {

baseInitializer.$inject = ['log'];
baseInitializer.$options = { singleton: false };
baseInitializer.$extra = { httpHandler: false };
baseInitializer.$options = {
singleton: false
};
baseInitializer.$extra = {
httpHandler: false
};
const log = _sinon2.default.stub();
const newInitializer = (0, _util.wrapInitializer)(({ log }, service) => {
const log = _sinon.default.stub();
const newInitializer = (0, _util.wrapInitializer)(({
log
}, service) => {
log('Wrapping...');
return () => service() + '-wrapped';
}, baseInitializer);
newInitializer({
log
}).then(service => {
_assert.default.equal(service(), 'test-wrapped');
newInitializer({ log }).then(service => {
_assert2.default.equal(service(), 'test-wrapped');
_assert2.default.deepEqual(log.args, [['Wrapping...']]);
_assert.default.deepEqual(log.args, [['Wrapping...']]);
}).then(done).catch(done);
});
});
describe('inject', () => {

@@ -99,7 +124,8 @@ it('should allow to decorate an initializer with dependencies', () => {

_assert2.default.notEqual(newInitializer, aProvider);
_assert2.default.notEqual(newInitializer[_util.SPECIAL_PROPS.INJECT], dependencies);
_assert2.default.deepEqual(newInitializer[_util.SPECIAL_PROPS.INJECT], dependencies);
_assert.default.notEqual(newInitializer, aProvider);
_assert.default.notEqual(newInitializer[_util.SPECIAL_PROPS.INJECT], dependencies);
_assert.default.deepEqual(newInitializer[_util.SPECIAL_PROPS.INJECT], dependencies);
});
it('should allow to decorate an initializer with mapped dependencies', () => {

@@ -109,53 +135,70 @@ const dependencies = ['ANOTHER_ENV>ENV'];

_assert2.default.notEqual(newInitializer, aProvider);
_assert2.default.notEqual(newInitializer[_util.SPECIAL_PROPS.INJECT], dependencies);
_assert2.default.deepEqual(newInitializer[_util.SPECIAL_PROPS.INJECT], dependencies);
_assert.default.notEqual(newInitializer, aProvider);
_assert.default.notEqual(newInitializer[_util.SPECIAL_PROPS.INJECT], dependencies);
_assert.default.deepEqual(newInitializer[_util.SPECIAL_PROPS.INJECT], dependencies);
});
});
describe('options', () => {
it('should allow to decorate an initializer with options', () => {
const dependencies = ['ANOTHER_ENV>ENV'];
const baseOptions = { singleton: true };
const baseOptions = {
singleton: true
};
const newInitializer = (0, _util.inject)(dependencies, (0, _util.options)(baseOptions, aProvider));
_assert2.default.notEqual(newInitializer, aProvider);
_assert2.default.notEqual(newInitializer[_util.SPECIAL_PROPS.INJECT], dependencies);
_assert2.default.deepEqual(newInitializer[_util.SPECIAL_PROPS.INJECT], dependencies);
_assert2.default.notEqual(newInitializer[_util.SPECIAL_PROPS.OPTIONS], baseOptions);
_assert2.default.deepEqual(newInitializer[_util.SPECIAL_PROPS.OPTIONS], baseOptions);
_assert.default.notEqual(newInitializer, aProvider);
_assert.default.notEqual(newInitializer[_util.SPECIAL_PROPS.INJECT], dependencies);
_assert.default.deepEqual(newInitializer[_util.SPECIAL_PROPS.INJECT], dependencies);
_assert.default.notEqual(newInitializer[_util.SPECIAL_PROPS.OPTIONS], baseOptions);
_assert.default.deepEqual(newInitializer[_util.SPECIAL_PROPS.OPTIONS], baseOptions);
});
});
describe('name', () => {
it('should allow to decorate an initializer with a name', () => {
const dependencies = ['ANOTHER_ENV>ENV'];
const baseOptions = { singleton: true };
const baseOptions = {
singleton: true
};
const baseName = 'hash';
const newInitializer = (0, _util.inject)(dependencies, (0, _util.options)(baseOptions, (0, _util.name)(baseName, aProvider)));
_assert2.default.notEqual(newInitializer, aProvider);
_assert2.default.notEqual(newInitializer[_util.SPECIAL_PROPS.INJECT], dependencies);
_assert2.default.deepEqual(newInitializer[_util.SPECIAL_PROPS.INJECT], dependencies);
_assert2.default.notEqual(newInitializer[_util.SPECIAL_PROPS.OPTIONS], baseOptions);
_assert2.default.deepEqual(newInitializer[_util.SPECIAL_PROPS.OPTIONS], baseOptions);
_assert2.default.equal(newInitializer[_util.SPECIAL_PROPS.NAME], baseName);
_assert.default.notEqual(newInitializer, aProvider);
_assert.default.notEqual(newInitializer[_util.SPECIAL_PROPS.INJECT], dependencies);
_assert.default.deepEqual(newInitializer[_util.SPECIAL_PROPS.INJECT], dependencies);
_assert.default.notEqual(newInitializer[_util.SPECIAL_PROPS.OPTIONS], baseOptions);
_assert.default.deepEqual(newInitializer[_util.SPECIAL_PROPS.OPTIONS], baseOptions);
_assert.default.equal(newInitializer[_util.SPECIAL_PROPS.NAME], baseName);
});
});
describe('extra', () => {
it('should allow to decorate an initializer with extra infos', () => {
const extraInformations = { httpHandler: true };
const extraInformations = {
httpHandler: true
};
const newInitializer = (0, _util.extra)(extraInformations, aProvider);
_assert2.default.notEqual(newInitializer, aProvider);
_assert2.default.notEqual(newInitializer[_util.SPECIAL_PROPS.EXTRA], extraInformations);
_assert2.default.deepEqual(newInitializer[_util.SPECIAL_PROPS.EXTRA], extraInformations);
_assert.default.notEqual(newInitializer, aProvider);
_assert.default.notEqual(newInitializer[_util.SPECIAL_PROPS.EXTRA], extraInformations);
_assert.default.deepEqual(newInitializer[_util.SPECIAL_PROPS.EXTRA], extraInformations);
});
});
describe('type', () => {
it('should allow to decorate an initializer with a type', () => {
const dependencies = ['ANOTHER_ENV>ENV'];
const baseOptions = { singleton: true };
const baseOptions = {
singleton: true
};
const baseName = 'hash';

@@ -165,16 +208,23 @@ const baseType = 'service';

_assert2.default.notEqual(newInitializer, aProvider);
_assert2.default.notEqual(newInitializer[_util.SPECIAL_PROPS.INJECT], dependencies);
_assert2.default.deepEqual(newInitializer[_util.SPECIAL_PROPS.INJECT], dependencies);
_assert2.default.notEqual(newInitializer[_util.SPECIAL_PROPS.OPTIONS], baseOptions);
_assert2.default.deepEqual(newInitializer[_util.SPECIAL_PROPS.OPTIONS], baseOptions);
_assert2.default.equal(newInitializer[_util.SPECIAL_PROPS.NAME], baseName);
_assert2.default.equal(newInitializer[_util.SPECIAL_PROPS.TYPE], baseType);
_assert.default.notEqual(newInitializer, aProvider);
_assert.default.notEqual(newInitializer[_util.SPECIAL_PROPS.INJECT], dependencies);
_assert.default.deepEqual(newInitializer[_util.SPECIAL_PROPS.INJECT], dependencies);
_assert.default.notEqual(newInitializer[_util.SPECIAL_PROPS.OPTIONS], baseOptions);
_assert.default.deepEqual(newInitializer[_util.SPECIAL_PROPS.OPTIONS], baseOptions);
_assert.default.equal(newInitializer[_util.SPECIAL_PROPS.NAME], baseName);
_assert.default.equal(newInitializer[_util.SPECIAL_PROPS.TYPE], baseType);
});
});
describe('initializer', () => {
it('should allow to decorate an initializer with every properties', () => {
const dependencies = ['ANOTHER_ENV>ENV'];
const baseOptions = { singleton: true };
const baseOptions = {
singleton: true
};
const baseName = 'hash';

@@ -189,12 +239,17 @@ const baseType = 'service';

_assert2.default.notEqual(newInitializer, aProvider);
_assert2.default.notEqual(newInitializer[_util.SPECIAL_PROPS.INJECT], dependencies);
_assert2.default.deepEqual(newInitializer[_util.SPECIAL_PROPS.INJECT], dependencies);
_assert2.default.notEqual(newInitializer[_util.SPECIAL_PROPS.OPTIONS], baseOptions);
_assert2.default.deepEqual(newInitializer[_util.SPECIAL_PROPS.OPTIONS], baseOptions);
_assert2.default.equal(newInitializer[_util.SPECIAL_PROPS.NAME], baseName);
_assert2.default.equal(newInitializer[_util.SPECIAL_PROPS.TYPE], baseType);
_assert.default.notEqual(newInitializer, aProvider);
_assert.default.notEqual(newInitializer[_util.SPECIAL_PROPS.INJECT], dependencies);
_assert.default.deepEqual(newInitializer[_util.SPECIAL_PROPS.INJECT], dependencies);
_assert.default.notEqual(newInitializer[_util.SPECIAL_PROPS.OPTIONS], baseOptions);
_assert.default.deepEqual(newInitializer[_util.SPECIAL_PROPS.OPTIONS], baseOptions);
_assert.default.equal(newInitializer[_util.SPECIAL_PROPS.NAME], baseName);
_assert.default.equal(newInitializer[_util.SPECIAL_PROPS.TYPE], baseType);
});
});
describe('handler', () => {

@@ -209,6 +264,7 @@ it('should work', () => {

_assert2.default.deepEqual(theInitializer.$name, sampleHandler.name);
_assert2.default.deepEqual(theInitializer.$inject, ['kikooo', 'lol']);
_assert.default.deepEqual(theInitializer.$name, sampleHandler.name);
return theInitializer(services).then(theHandler => theHandler('test')).then(result => _assert2.default.deepEqual(result, {
_assert.default.deepEqual(theInitializer.$inject, ['kikooo', 'lol']);
return theInitializer(services).then(theHandler => theHandler('test')).then(result => _assert.default.deepEqual(result, {
deps: services,

@@ -219,8 +275,10 @@ args: ['test']

function sampleHandler(deps, ...args) {
return Promise.resolve({ deps, args });
return Promise.resolve({
deps,
args
});
}
});
it('should fail for anonymous functions', () => {
_assert2.default.throws(() => {
_assert.default.throws(() => {
(0, _util.handler)(() => {});

@@ -230,6 +288,5 @@ }, /E_NO_HANDLER_NAME/);

});
describe('parseDependencyDeclaration', () => {
it('should work', () => {
_assert2.default.deepEqual((0, _util.parseDependencyDeclaration)('pgsql>db'), {
_assert.default.deepEqual((0, _util.parseDependencyDeclaration)('pgsql>db'), {
serviceName: 'pgsql',

@@ -236,0 +293,0 @@ mappedName: 'db',

{
"name": "knifecycle",
"version": "2.5.2",
"version": "2.5.3",
"description": "Manage your NodeJS processes's lifecycle.",

@@ -38,4 +38,4 @@ "main": "dist/index.js",

"compile": "babel src --out-dir=dist",
"cover": "istanbul cover _mocha --report html -- --compilers js:babel-register src/*.mocha.js -R spec -t 5000",
"coveralls": "istanbul cover _mocha --report lcovonly -- --compilers js:babel-register src/*.mocha.js -R spec -t 5000 && cat ./coverage/lcov.info | coveralls && rm -rf ./coverage",
"cover": "nyc npm test && nyc report --reporter=text",
"coveralls": "nyc npm test && nyc report --reporter=text-lcov | coveralls && rm -rf ./coverage",
"cz": "env NODE_ENV=${NODE_ENV:-cli} git cz",

@@ -46,3 +46,3 @@ "doc": "echo \"# API\" > API.md; jsdoc2md src/*.js >> API.md",

"metapak": "metapak",
"mocha": "mocha --compilers js:babel-register src/*.mocha.js",
"mocha": "mocha --compilers js:@babel/register src/*.mocha.js",
"prepublish": "npm run compile",

@@ -63,34 +63,33 @@ "prettier": "prettier --write src/*.js",

"devDependencies": {
"babel-cli": "^6.26.0",
"babel-core": "^6.26.0",
"babel-eslint": "^8.2.2",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-preset-env": "^1.6.1",
"babel-register": "^6.26.0",
"browserify": "^14.4.0",
"commitizen": "^2.9.6",
"conventional-changelog-cli": "^1.3.8",
"coveralls": "^3.0.0",
"@babel/cli": "^7.0.0",
"@babel/core": "^7.0.1",
"@babel/plugin-proposal-object-rest-spread": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"@babel/register": "^7.0.0",
"babel-eslint": "^9.0.0",
"browserify": "^16.2.2",
"commitizen": "^2.10.1",
"conventional-changelog-cli": "^2.0.5",
"coveralls": "^3.0.2",
"cz-conventional-changelog": "^2.1.0",
"eslint": "^4.19.0",
"eslint-plugin-prettier": "^2.6.0",
"istanbul": "^1.0.0-alpha.2",
"eslint": "^5.6.0",
"eslint-plugin-prettier": "^2.6.2",
"jsarch": "^1.3.0",
"jsdoc-to-markdown": "^4.0.1",
"karma": "^2.0.0",
"karma-browserify": "^5.1.2",
"karma": "^3.0.0",
"karma-browserify": "^5.3.0",
"karma-chrome-launcher": "^2.2.0",
"karma-firefox-launcher": "^1.1.0",
"karma-mocha": "^1.3.0",
"karma-sauce-launcher": "^1.1.0",
"karma-sauce-launcher": "^1.2.0",
"metapak": "^1.0.3",
"metapak-nfroidure": "^6.1.0",
"mocha": "^5.0.0",
"mocha-lcov-reporter": "^1.3.0",
"prettier": "^1.11.1",
"sinon": "^4.4.6"
"metapak-nfroidure": "^6.3.0",
"mocha": "^5.2.0",
"nyc": "^13.0.1",
"prettier": "^1.14.2",
"sinon": "^6.3.3"
},
"dependencies": {
"debug": "^3.1.0",
"yerror": "^2.1.0"
"debug": "^4.0.1",
"yerror": "^2.1.3"
},

@@ -108,8 +107,11 @@ "config": {

"mocha",
"mocha-lcov-reporter",
"coveralls",
"istanbul",
"nyc",
"eslint",
"eslint-config-prettier",
"prettier",
"karma",
"karma-chrome-launcher",
"karma-firefox-launcher",
"karma-mocha",
"jsdoc-to-markdown",

@@ -122,3 +124,3 @@ "jsarch"

[
"env",
"@babel/env",
{

@@ -132,5 +134,5 @@ "targets": {

"plugins": [
"transform-object-rest-spread"
"@babel/plugin-proposal-object-rest-spread"
]
}
}

@@ -109,3 +109,3 @@ [//]: # ( )

// be set as a property of an object in first argument.
}, ({ ENV }) => {
}, async ({ ENV }) => {
return new Promise((resolve, reject) {

@@ -149,21 +149,19 @@ fs.readFile(ENV.CONFIG_PATH, function(err, data) {

// handle the service unrecoverable failure.
type: 'provider',,
type: 'provider',
options: { singleton: true },
}, ({ CONFIG, log }) {
return MongoClient.connect(CONFIG.DB_URI)
.then(function(db) {
let fatalErrorPromise = new Promise((resolve, reject) {
db.once('error', reject);
});
}, async ({ CONFIG, log }) {
const db = await MongoClient.connect(CONFIG.DB_URI);
let fatalErrorPromise = new Promise((resolve, reject) {
db.once('error', reject);
});
// Logging only if the `log` service is defined
log && log('info', 'db service initialized!');
// Logging only if the `log` service is defined
log && log('info', 'db service initialized!');
return {
service: db,
dispose: db.close.bind(db, true),
fatalErrorPromise,
};
});
}
return {
service: db,
dispose: db.close.bind(db, true),
fatalErrorPromise,
};
});
```

@@ -181,6 +179,6 @@

options: { singleton: true },
}, ({ ENV, CONFIG, log }) => {
}, async ({ ENV, CONFIG, log }) => {
const app = express();
return new Promise((resolve, reject) => {
const server = new Promise((resolve, reject) => {
const port = ENV.PORT || CONFIG.PORT;

@@ -191,26 +189,26 @@ const server = app.listen(port, () => {

});
}).then(function(server) {
let fatalErrorPromise = new Promise((resolve, reject) {
app.once('error', reject);
server.once('error', reject);
});
let fatalErrorPromise = new Promise((resolve, reject) {
app.once('error', reject);
server.once('error', reject);
});
function dispose() {
return new Promise((resolve, reject) => {
server.close((err) => {
if(err) {
reject(err);
return;
}
resolve();
})
});
}
function dispose() {
return new Promise((resolve, reject) => {
server.close((err) => {
if(err) {
reject(err);
return;
}
resolve();
})
});
}
return {
service: app,
dispose,
fatalErrorPromise,
};
});
return {
service: app,
dispose,
fatalErrorPromise,
};
});

@@ -246,8 +244,8 @@ ```

// on which the `db2` service now depends on
.register(name('DB2_CONFIG', inject(['CONFIG'], ({ CONFIG }) => {
.register(name('DB2_CONFIG', inject(['CONFIG'], async ({ CONFIG }) => {
// Let's just pick up the `db2` uri in the `CONFIG`
// service
return Promise.resolve({
return {
DB_URI: CONFIG.DB2_URI,
});
};
})))

@@ -271,11 +269,8 @@ // Add the process environment as a simple constant

['server', 'now', '?log'],
({ server: app, now, log }) {
return Promise.resolve()
.then(() => {
app.get('/time', (req, res, next) => {
const curTime = now();
async ({ server: app, now, log }) => {
app.get('/time', (req, res, next) => {
const curTime = now();
log && log('info', 'Sending the current time:', curTime);
res.status(200).send(curTime);
});
log && log('info', 'Sending the current time:', curTime);
res.status(200).send(curTime);
});

@@ -342,5 +337,12 @@ }

stubs/mocks in order to let you reuse it through
your projects easily.
your projects easily. Here are the current projects
that use this DI lib:
- [common-services](https://github.com/nfroidure/common-services):
contains the services I use the most in my apps.
- [swagger-http-router](https://github.com/nfroidure/swagger-http-router):
a complete HTTP router based on OpenAPI definitions with a few useful
services compatible with Knifecycle.
- [memory-kv-store](https://github.com/nfroidure/memory-kv-store):
a simple in memory key-value store.
[//]: # (::contents:end)

@@ -393,3 +395,3 @@

</dd>
<dt><a href="#handler">handler(handlerFunction, [dependencies])</a> ⇒ <code>function</code></dt>
<dt><a href="#handler">handler(handlerFunction, [dependencies], [extra])</a> ⇒ <code>function</code></dt>
<dd><p>Shortcut to create an initializer with a simple handler</p>

@@ -855,3 +857,3 @@ </dd>

## handler(handlerFunction, [dependencies]) ⇒ <code>function</code>
## handler(handlerFunction, [dependencies], [extra]) ⇒ <code>function</code>
Shortcut to create an initializer with a simple handler

@@ -866,2 +868,3 @@

| [dependencies] | <code>Array</code> | <code>[]</code> | The dependencies to inject in it |
| [extra] | <code>Object</code> | | Optional extra data to associate with the handler |

@@ -868,0 +871,0 @@ **Example**

@@ -277,2 +277,4 @@ import YError from 'yerror';

* The dependencies to inject in it
* @param {Object} [extra]
* Optional extra data to associate with the handler
* @return {Function}

@@ -293,3 +295,3 @@ * Returns a new initializer

*/
export function handler(handlerFunction, dependencies = []) {
export function handler(handlerFunction, dependencies = [], extra) {
if (!handlerFunction.name) {

@@ -303,4 +305,5 @@ throw new YError('E_NO_HANDLER_NAME');

inject: dependencies,
extra,
},
(...args) => Promise.resolve(handlerFunction.bind(null, ...args)),
async (...args) => handlerFunction.bind(null, ...args),
);

@@ -307,0 +310,0 @@ }

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