From bc4d143821a01a0ef6bc9f3d3252d19bd8991c99 Mon Sep 17 00:00:00 2001 From: Matus Zeman Date: Thu, 15 Jun 2017 11:12:27 +0200 Subject: [PATCH] dic loader replaced dic class loader --- README.md | 119 ++++++++++++--------- es5/dic-class-loader.js | 100 ----------------- es5/dic.js | 2 +- es5/index.js | 2 +- es5/parser.js | 3 +- package.json | 2 +- src/dic-class-loader.js | 53 --------- src/dic-loader.js | 98 +++++++++++++++++ src/dic-loader.spec.js | 38 +++++++ src/index.js | 2 +- src/parser.js | 3 +- test/dic-loader/service-a.js | 4 + test/dic-loader/service-b.factory.js | 5 + test/dic-loader/service-c.async-factory.js | 5 + test/dic-loader/service-d.instance.js | 3 + 15 files changed, 229 insertions(+), 210 deletions(-) delete mode 100644 es5/dic-class-loader.js delete mode 100644 src/dic-class-loader.js create mode 100644 src/dic-loader.js create mode 100644 src/dic-loader.spec.js create mode 100644 test/dic-loader/service-a.js create mode 100644 test/dic-loader/service-b.factory.js create mode 100644 test/dic-loader/service-c.async-factory.js create mode 100644 test/dic-loader/service-d.instance.js diff --git a/README.md b/README.md index f0d5dd7..cc8e99d 100644 --- a/README.md +++ b/README.md @@ -96,12 +96,12 @@ dic.getAsync('myApp').then(app => { ## Classes
-
DicClassLoader
-

Class loader

-
DicConfigLoader

Config loader - sets up Dic from the config (plain object)

+
DicLoader
+

Dic loader

+
Dic

Dependency injection container

For more usage examples see: instance, class, factory, @@ -116,54 +116,6 @@ dic.getAsync('myApp').then(app => {

- - -## DicClassLoader -Class loader - -**Kind**: global class - -* [DicClassLoader](#DicClassLoader) - * [new DicClassLoader(dic, opts)](#new_DicClassLoader_new) - * [.loadPath(path)](#DicClassLoader+loadPath) - - - -### new DicClassLoader(dic, opts) - -| Param | Type | Description | -| --- | --- | --- | -| dic | [Dic](#Dic) | | -| opts | Object | | -| opts.rootDir | string | Absolute path to root folder of source files. Default: `process.cwd()` | - - - -### dicClassLoader.loadPath(path) -Load all files and register exported classes to [Dic](#Dic). - -All files are expected to export a class. - -File name dictates what name the service will be registered as. -E.g. `my-service.js` service would become registered as `myService` => file name is camelCased. - -**Kind**: instance method of [DicClassLoader](#DicClassLoader) - -| Param | Type | Description | -| --- | --- | --- | -| path | string | glob expression [https://www.npmjs.com/package/globby](https://www.npmjs.com/package/globby) | - -**Example** -```js -// Registers all classes under `CWD/src` folder. - -const {Dic, DicClassLoader} = require('bb-dic'); -const dic = new Dic(); -const loader = new DicClassLoader(dic); -loader.loadPath('src/*.js'); - -module.exports = dic; -``` ## DicConfigLoader @@ -218,6 +170,71 @@ Set up Dic according the config } } ``` + + +## DicLoader +Dic loader + +**Kind**: global class + +* [DicLoader](#DicLoader) + * [new DicLoader(opts)](#new_DicLoader_new) + * [.loadPath(dic, path)](#DicLoader+loadPath) + + + +### new DicLoader(opts) + +| Param | Type | Description | +| --- | --- | --- | +| opts | Object | | +| opts.rootDir | string | Absolute path to root folder of source files. Default: `process.cwd()` | + +**Example** +```js +const {Dic, DicLoader} = require('bb-dic'); +const dic = new Dic() + +const loader = new DicLoader({ + rootDir: __dirname //if not specified process.cwd() is used +}); + +//loads all .js files under src folder +loader.loadPath('src/*.js'); +``` + + +### dicLoader.loadPath(dic, path) +Load all instances/factories/classes to [Dic](#Dic). + +File types and what they should export +- name.js -> class +- name.factory.js -> factory +- name.async-factory.js -> async factory +- name.instance.js -> instance + + +File name dictates what name the service will be registered as. +E.g. `my-service.js` service would become registered as `myService` => file name is camelCased. + +**Kind**: instance method of [DicLoader](#DicLoader) + +| Param | Type | Description | +| --- | --- | --- | +| dic | [Dic](#Dic) | | +| path | string | glob expression [https://www.npmjs.com/package/globby](https://www.npmjs.com/package/globby) | + +**Example** +```js +// Registers all services under `CWD/src` folder. + +const {Dic, DicLoader} = require('bb-dic'); +const dic = new Dic(); +const loader = new DicLoader(); +loader.loadPath(dic, 'src/*.js'); + +module.exports = dic; +``` ## Dic diff --git a/es5/dic-class-loader.js b/es5/dic-class-loader.js deleted file mode 100644 index 906bc1c..0000000 --- a/es5/dic-class-loader.js +++ /dev/null @@ -1,100 +0,0 @@ -'use strict'; - -var _getIterator2 = require('babel-runtime/core-js/get-iterator'); - -var _getIterator3 = _interopRequireDefault(_getIterator2); - -var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); - -var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); - -var _createClass2 = require('babel-runtime/helpers/createClass'); - -var _createClass3 = _interopRequireDefault(_createClass2); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var _ = require('lodash'); -var nodePath = require('path'); -var globby = require('globby'); -var Dic = require('./dic'); - -/** - * Class loader - */ - -var DicClassLoader = function () { - /** - * @param {Dic} dic - * @param {Object} opts - * @param {string} opts.rootDir Absolute path to root folder of source files. Default: `process.cwd()` - */ - function DicClassLoader(dic) { - var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - (0, _classCallCheck3.default)(this, DicClassLoader); - - this.options = _.defaults(opts, { - rootDir: process.cwd() - }); - this.dic = dic; - } - - /** - * Load all files and register exported classes to {@link Dic}. - * - * All files are expected to export a class. - * - * File name dictates what name the service will be registered as. - * E.g. `my-service.js` service would become registered as `myService` => file name is camelCased. - * - * @example // Registers all classes under `CWD/src` folder. - * - * const {Dic, DicClassLoader} = require('bb-dic'); - * const dic = new Dic(); - * const loader = new DicClassLoader(dic); - * loader.loadPath('src/*.js'); - * - * module.exports = dic; - * - * @param {string} path glob expression {@link https://www.npmjs.com/package/globby} - */ - - - (0, _createClass3.default)(DicClassLoader, [{ - key: 'loadPath', - value: function loadPath(path) { - var ret = globby.sync(path, { - cwd: this.options.rootDir - }); - var _iteratorNormalCompletion = true; - var _didIteratorError = false; - var _iteratorError = undefined; - - try { - for (var _iterator = (0, _getIterator3.default)(ret), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { - var p = _step.value; - - var mod = require(this.options.rootDir + '/' + p); - var name = _.camelCase(nodePath.basename(p, '.js')); - this.dic.registerClass(name, mod); - } - } catch (err) { - _didIteratorError = true; - _iteratorError = err; - } finally { - try { - if (!_iteratorNormalCompletion && _iterator.return) { - _iterator.return(); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } - } - } - }]); - return DicClassLoader; -}(); - -module.exports = DicClassLoader; \ No newline at end of file diff --git a/es5/dic.js b/es5/dic.js index 794c481..c2b8835 100644 --- a/es5/dic.js +++ b/es5/dic.js @@ -866,7 +866,7 @@ var Dic = function () { paramsAlias: Joi.object().default({}), asyncFactory: Joi.func(), inject: Joi.object().default({}), - container: Joi.object().type(Dic).optional().default(this) + container: Joi.object().default(this) //type(Dic) - this does not work when having Dic from different packages obviously })); if (!def.type) { diff --git a/es5/index.js b/es5/index.js index e3846f9..0d89180 100644 --- a/es5/index.js +++ b/es5/index.js @@ -2,7 +2,7 @@ module.exports = { Dic: require('./dic'), - DicClassLoader: require('./dic-class-loader'), + DicLoader: require('./dic-loader'), DicConfigLoader: require('./dic-config-loader'), DicFactory: require('./dic-factory'), Parser: require('./parser') diff --git a/es5/parser.js b/es5/parser.js index 7a70c4c..1c24b5c 100644 --- a/es5/parser.js +++ b/es5/parser.js @@ -48,7 +48,8 @@ var Parser = function () { }); return this.parseNode(node); } catch (e) { - console.log('XXX'); //XXX + console.log('Failed to parse the class'); //XXX + console.log(target); //XXX console.log(e); //XXX throw e; } diff --git a/package.json b/package.json index 30e287e..f905b19 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bb-dic", - "version": "0.9.1", + "version": "1.0.0", "description": "A dependency injection container", "main": "src/index.js", "scripts": { diff --git a/src/dic-class-loader.js b/src/dic-class-loader.js deleted file mode 100644 index 064335c..0000000 --- a/src/dic-class-loader.js +++ /dev/null @@ -1,53 +0,0 @@ -const _ = require('lodash'); -const nodePath = require('path'); -const globby = require('globby'); -const Dic = require('./dic'); - -/** - * Class loader - */ -class DicClassLoader { - /** - * @param {Dic} dic - * @param {Object} opts - * @param {string} opts.rootDir Absolute path to root folder of source files. Default: `process.cwd()` - */ - constructor(dic, opts = {}) { - this.options = _.defaults(opts, { - rootDir: process.cwd() - }); - this.dic = dic; - } - - /** - * Load all files and register exported classes to {@link Dic}. - * - * All files are expected to export a class. - * - * File name dictates what name the service will be registered as. - * E.g. `my-service.js` service would become registered as `myService` => file name is camelCased. - * - * @example // Registers all classes under `CWD/src` folder. - * - * const {Dic, DicClassLoader} = require('bb-dic'); - * const dic = new Dic(); - * const loader = new DicClassLoader(dic); - * loader.loadPath('src/*.js'); - * - * module.exports = dic; - * - * @param {string} path glob expression {@link https://www.npmjs.com/package/globby} - */ - loadPath(path) { - const ret = globby.sync(path, { - cwd: this.options.rootDir - }); - for (const p of ret) { - const mod = require(this.options.rootDir + '/' + p); - const name = _.camelCase(nodePath.basename(p, '.js')); - this.dic.registerClass(name, mod); - } - } -} - -module.exports = DicClassLoader; diff --git a/src/dic-loader.js b/src/dic-loader.js new file mode 100644 index 0000000..781cafe --- /dev/null +++ b/src/dic-loader.js @@ -0,0 +1,98 @@ +const _ = require('lodash'); +const nodePath = require('path'); +const globby = require('globby'); + +/** + * Dic loader + * + * @example + * const {Dic, DicLoader} = require('bb-dic'); + * const dic = new Dic() + * + * const loader = new DicLoader({ + * rootDir: __dirname //if not specified process.cwd() is used + * }); + * + * //loads all .js files under src folder + * loader.loadPath('src/*.js'); + */ +class DicLoader { + /** + * @param {Object} opts + * @param {string} opts.rootDir Absolute path to root folder of source files. Default: `process.cwd()` + */ + constructor(opts = {}) { + this.options = _.defaults(opts, { + rootDir: process.cwd(), + debug: false + }); + } + + /** + * Load all instances/factories/classes to {@link Dic}. + * + * File types and what they should export + * - name.js -> class + * - name.factory.js -> factory + * - name.async-factory.js -> async factory + * - name.instance.js -> instance + * + * + * File name dictates what name the service will be registered as. + * E.g. `my-service.js` service would become registered as `myService` => file name is camelCased. + * + * @example // Registers all services under `CWD/src` folder. + * + * const {Dic, DicLoader} = require('bb-dic'); + * const dic = new Dic(); + * const loader = new DicLoader(); + * loader.loadPath(dic, 'src/*.js'); + * + * module.exports = dic; + * + * @param {Dic} dic + * @param {string} path glob expression {@link https://www.npmjs.com/package/globby} + */ + loadPath(dic, path) { + const ret = globby.sync(path, { + cwd: this.options.rootDir + }); + for (const p of ret) { + const path = this.options.rootDir + '/' + p; + const mod = require(path); + const basename = nodePath.basename(p, '.js'); + + let type = 'class'; + let name = _.camelCase(basename); + + const match = basename.match(/(.*)\.(factory|async-factory|instance)$/); + if (match) { + name = _.camelCase(match[1]); + type = match[2]; + } + + if (this.options.debug) { + console.log(`DicLoader: ${name} [${type}] -> ${path}`); + } + + switch(type) { + case 'class': + dic.registerClass(name, mod); + break; + case 'async-factory': + dic.asyncFactory(name, mod); + break; + case 'factory': + dic.factory(name, mod); + break; + case 'instance': + dic.instance(name, mod); + break; + default: + throw new Error(`Type ${type} not supported`); + } + } + } +} + +module.exports = DicLoader; diff --git a/src/dic-loader.spec.js b/src/dic-loader.spec.js new file mode 100644 index 0000000..ea10eb9 --- /dev/null +++ b/src/dic-loader.spec.js @@ -0,0 +1,38 @@ +const expect = require('chai').expect; +const {Dic, DicLoader} = require('./index'); + +const ServiceA = require('../test/dic-loader/service-a'); + +describe('DicLoader', () => { + before(function() { + this.expect = { + instanceof: async (dic, ins, classDef) => { + expect(dic.get(ins)).instanceof(classDef); + expect(await dic.getAsync(ins)).instanceof(classDef); + } + } + }); + + beforeEach(function() { + this.dic = new Dic(); + this.dicLoader = new DicLoader({ + rootDir: __dirname + '/../test/dic-loader' + //debug: true + }); + }); + + describe('.loadPath()', () => { + it('works', async function() { + const {dic, dicLoader} = this; + + dicLoader.loadPath(dic, '*.js'); + await dic.asyncInit(); + + await this.expect.instanceof(dic, 'serviceA', ServiceA); + await this.expect.instanceof(dic, 'serviceB', ServiceA); + await this.expect.instanceof(dic, 'serviceC', ServiceA); + await this.expect.instanceof(dic, 'serviceD', ServiceA); + }); + }); + +}); diff --git a/src/index.js b/src/index.js index 6acc4ec..911536d 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,6 @@ module.exports = { Dic: require('./dic'), - DicClassLoader: require('./dic-class-loader'), + DicLoader: require('./dic-loader'), DicConfigLoader: require('./dic-config-loader'), DicFactory: require('./dic-factory'), Parser: require('./parser') diff --git a/src/parser.js b/src/parser.js index a86669a..163dc9e 100644 --- a/src/parser.js +++ b/src/parser.js @@ -30,7 +30,8 @@ class Parser { }); return this.parseNode(node); } catch(e) { - console.log('XXX');//XXX + console.log('Failed to parse the class');//XXX + console.log(target);//XXX console.log(e);//XXX throw e; } diff --git a/test/dic-loader/service-a.js b/test/dic-loader/service-a.js new file mode 100644 index 0000000..a75e409 --- /dev/null +++ b/test/dic-loader/service-a.js @@ -0,0 +1,4 @@ +class ServiceA { +} + +module.exports = ServiceA; diff --git a/test/dic-loader/service-b.factory.js b/test/dic-loader/service-b.factory.js new file mode 100644 index 0000000..22329fc --- /dev/null +++ b/test/dic-loader/service-b.factory.js @@ -0,0 +1,5 @@ +const ServiceA = require('./service-a'); + +module.exports = function() { + return new ServiceA(); +}; diff --git a/test/dic-loader/service-c.async-factory.js b/test/dic-loader/service-c.async-factory.js new file mode 100644 index 0000000..c7af53a --- /dev/null +++ b/test/dic-loader/service-c.async-factory.js @@ -0,0 +1,5 @@ +const ServiceA = require('./service-a'); + +module.exports = async function() { + return new ServiceA(); +}; diff --git a/test/dic-loader/service-d.instance.js b/test/dic-loader/service-d.instance.js new file mode 100644 index 0000000..aac846c --- /dev/null +++ b/test/dic-loader/service-d.instance.js @@ -0,0 +1,3 @@ +const ServiceA = require('./service-a'); + +module.exports = new ServiceA();