UNPKG

base-domain

Version:

simple module to help build Domain-Driven Design

244 lines (207 loc) 7.08 kB
'use strict'; var BaseDomainify, Facade, MasterDataResource, Path, coffee, fs, through, indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; through = require('through'); fs = require('fs'); Path = require('path'); coffee = require('coffee-script'); require('coffee-script/register'); if (Path.isAbsolute == null) { Path.isAbsolute = function(str) { return str.charAt(0) === '/'; }; } Facade = require('./lib/facade'); MasterDataResource = require('./master-data-resource'); BaseDomainify = (function() { function BaseDomainify(moduleName1) { this.moduleName = moduleName1 != null ? moduleName1 : 'base-domain'; this.initialCodeGenerated = false; } /** get CoffeeScript code of adding addClass methods to all domain files @method run @public @return {String} code CoffeeScript code */ BaseDomainify.prototype.run = function(file, options) { var data, dirname, end, i, initialCode, len, modName, modNamePath, modulePaths, modules, path, ref, ref1, ref2, write; this.file = file; if (options == null) { options = {}; } if (this.initialCodeGenerated) { return through(); } dirname = options.dirname, modules = options.modules; if (!dirname) { this.throwError(); } modulePaths = {}; ref1 = (ref = modules != null ? modules.split(',') : void 0) != null ? ref : []; for (i = 0, len = ref1.length; i < len; i++) { modNamePath = ref1[i]; ref2 = modNamePath.split(':'), modName = ref2[0], path = ref2[1]; modulePaths[modName] = path; } initialCode = this.getInitialCode(dirname, modulePaths); this.initialCodeGenerated = true; data = ''; write = function(buf) { return data += buf; }; end = function() { var j, len1, ref3, results, val; ref3 = [initialCode, data, null]; results = []; for (j = 0, len1 = ref3.length; j < len1; j++) { val = ref3[j]; results.push(this.queue(val)); } return results; }; return through(write, end); }; BaseDomainify.prototype.relativePath = function(path) { var dir, relPath; dir = Path.dirname(this.file); relPath = Path.relative(dir, path); if (relPath.charAt(0) !== '.') { relPath = './' + relPath; } return relPath; }; BaseDomainify.prototype.absolutePath = function(path) { if (Path.isAbsolute(path)) { return path; } return process.cwd() + '/' + path; }; BaseDomainify.prototype.baseName = function(path) { return Path.basename(path); }; /** get CoffeeScript code of adding addClass methods to all domain files @method getInitialCode @private @return {String} code CoffeeScript code */ BaseDomainify.prototype.getInitialCode = function(dirname, modulePaths) { var _, basename, coffeeCode, moduleName, path; basename = this.baseName(dirname); _ = ' '; coffeeCode = "Facade = require '" + this.moduleName + "'\n\nFacade::init = ->\n" + _ + "return unless @dirname.match '" + basename + "'\n"; coffeeCode += this.getScriptToLoadCoreModule(dirname); for (moduleName in modulePaths) { path = modulePaths[moduleName]; coffeeCode += this.getScriptToLoadModule(moduleName, path); } coffeeCode += _ + "return\n"; return coffee.compile(coffeeCode, { bare: true }); }; BaseDomainify.prototype.getScriptToLoadCoreModule = function(dirname) { var _, coffeeCode, filename, i, len, masterJSONPath, name, path, ref; _ = ' '; coffeeCode = ''; if (masterJSONPath = this.getMasterJSONPath(dirname)) { coffeeCode += _ + "@master?.loadFromJSON = -> require('" + masterJSONPath + "')\n"; } ref = this.getFiles(dirname); for (i = 0, len = ref.length; i < len; i++) { filename = ref[i]; name = filename.split('.')[0]; path = this.relativePath(dirname) + '/' + name; coffeeCode += _ + "@addClass '" + name + "', require('" + path + "')\n"; } return coffeeCode; }; BaseDomainify.prototype.getScriptToLoadModule = function(moduleName, moduleDirname) { var _, basename, coffeeCode, filename, i, len, name, path, ref; basename = this.baseName(moduleDirname); _ = ' '; coffeeCode = _ + "if @modules['" + moduleName + "'] and @modules['" + moduleName + "'].path.match '" + basename + "'\n"; ref = this.getFiles(moduleDirname); for (i = 0, len = ref.length; i < len; i++) { filename = ref[i]; name = filename.split('.')[0]; path = this.relativePath(moduleDirname) + '/' + name; coffeeCode += "" + _ + _ + "@addClass '" + moduleName + "/" + name + "', require('" + path + "')\n"; } return coffeeCode; }; /** @method getCodeOfMasterData @private @return {String} path */ BaseDomainify.prototype.getMasterJSONPath = function(dirname) { var e, error, facade, masterJSONPath, relPath; try { facade = Facade.createInstance({ dirname: this.absolutePath(dirname), master: true }); masterJSONPath = facade.master.masterJSONPath; if (!fs.existsSync(masterJSONPath)) { return ''; } relPath = MasterDataResource.getJSONPath(this.relativePath(dirname)); return relPath; } catch (error) { e = error; return ''; } }; /** get domain files to load @method getFiles @private @return {Array} filenames */ BaseDomainify.prototype.getFiles = function(dirname) { var ParentClass, ext, fileInfo, fileInfoDict, filename, files, i, klass, len, name, path, pntFileName, ref, ref1, ref2; fileInfoDict = {}; path = this.absolutePath(dirname); ref = fs.readdirSync(path); for (i = 0, len = ref.length; i < len; i++) { filename = ref[i]; ref1 = filename.split('.'), name = ref1[0], ext = ref1[1]; if (ext !== 'js' && ext !== 'coffee') { continue; } klass = require(path + '/' + filename); fileInfoDict[name] = { filename: filename, klass: klass }; } files = []; for (name in fileInfoDict) { fileInfo = fileInfoDict[name]; klass = fileInfo.klass, filename = fileInfo.filename; if (indexOf.call(files, filename) >= 0) { continue; } ParentClass = Object.getPrototypeOf(klass.prototype).constructor; if (ParentClass.className && (pntFileName = (ref2 = fileInfoDict[ParentClass.getName()]) != null ? ref2.filename : void 0)) { if (indexOf.call(files, pntFileName) < 0) { files.push(pntFileName); } } files.push(filename); } return files; }; /** throw error @method throwError @private */ BaseDomainify.prototype.throwError = function() { throw new Error("dirname must be passed.\n\nbrowserify -t [ base-domain/ify --dirname dirname --modules module1:/path/to/module1,module2:/path/to/module2 ]\n"); }; return BaseDomainify; })(); module.exports = BaseDomainify;