<commit_before>const fs = require('../core/fs.js');
const async = require('async');
const ProcessLauncher = require('../core/processes/processLauncher');
const utils = require('../utils/utils.js');
const constants = require('../constants');

class Pipeline {

  constructor(options) {
    this.env = options.env;
    this.buildDir = options.buildDir;
    this.contractsFiles = options.contractsFiles;
    this.assetFiles = options.assetFiles;
    this.events = options.events;
    this.logger = options.logger;
    this.plugins = options.plugins;
    this.webpackConfigName = options.webpackConfigName;
    this.pipelinePlugins = this.plugins.getPluginsFor('pipeline');
  }

  build(abi, contractsJSON, path, callback) {
    let self = this;
    const importsList = {};
    let placeholderPage;

    if (!this.assetFiles || !Object.keys(this.assetFiles).length) {
      return callback();
    }

    async.waterfall([
      function createPlaceholderPage(next){
        self.events.request('embark-building-placeholder', (html) => {
          fs.mkdirpSync(self.buildDir); // create dist/ folder if not already exists
          fs.writeFile(utils.joinPath(self.buildDir, 'index.html'), html, next);
        });
      },
      function buildTheContracts(next) {
        self.buildContracts(next);
      },
      function buildWeb3(next) {
        self.buildWeb3JS(next);
      },
      function createImportList(next) {
        importsList["Embark/EmbarkJS"] = fs.dappPath(".embark", 'embark.js');
        importsList["Embark/web3"] = fs.dappPath(".embark", 'web3_instance.js');
        importsList["Embark/contracts"] = fs.dappPath(".embark/contracts", '');

        self.plugins.getPluginsProperty('imports', 'imports').forEach(function (importObject) {
          let [importName, importLocation] = importObject;
          importsList[importName] = importLocation;
        });

        next();
      },
      function writeContracts(next) {
        self.events.request('contracts:list', (_err, contracts) => {
          // ensure the .embark/contracts directory exists (create if not exists)
          fs.mkdirp(fs.dappPath(".embark/contracts", ''), (err) => {
            if(err) return next(err);

            // Create a file .embark/contracts/index.js that requires all contract files
            // Used to enable alternate import syntax:
            // e.g. import {Token} from 'Embark/contracts'
            // e.g. import * as Contracts from 'Embark/contracts'
            let importsHelperFile = fs.createWriteStream(fs.dappPath(".embark/contracts", 'index.js'));
            importsHelperFile.write('module.exports = {\n');

            async.eachOf(contracts, (contract, idx, eachCb) => {
              self.events.request('code-generator:contract', contract.className, (contractCode) => {
                let filePath = fs.dappPath(".embark/contracts", contract.className + '.js');
                importsList["Embark/contracts/" + contract.className] = filePath;
                fs.writeFile(filePath, contractCode, eachCb);

                // add the contract to the exports list to support alternate import syntax
                importsHelperFile.write(`"${contract.className}": require('./${contract.className}').default`);
                if(idx < contracts.length - 1) importsHelperFile.write(',\n'); // add a comma if we have more contracts to add
              });
            }, function(){
              importsHelperFile.write('\n}'); // close the module.exports = {}
              importsHelperFile.close(next); // close the write stream
            });
          });
        });
      },
      function runWebpack(next) {
        self.logger.info(__(`running webpack with '${self.webpackConfigName}' config...`));
        Object.keys(self.assetFiles)
          .filter(key => key.match(/\.js?$/))
          .forEach(key => {
            self.logger.info(__("writing file") + " " + (utils.joinPath(self.buildDir, key)).bold.dim);
          });
        let built = false;
        const webpackProcess = new ProcessLauncher({
          modulePath: utils.joinPath(__dirname, 'webpackProcess.js'),
          logger: self.logger,
          events: self.events,
          exitCallback: function (code) {
            if (!built) {
              return next(`Webpack build exited with code ${code} before the process finished`);
            }
            if (code) {
              self.logger(__('Webpack build process exited with code ', code));
            }
          }
        });
        webpackProcess.send({action: constants.pipeline.init, options: {webpackConfigName: self.webpackConfigName}});
        webpackProcess.send({action: constants.pipeline.build, assets: self.assetFiles, importsList});

        webpackProcess.once('result', constants.pipeline.built, (msg) => {
          built = true;
          webpackProcess.kill();
          return next(msg.error);
        });
      },
      function assetFileWrite(next) {
        async.eachOf(
          // assetFileWrite should not process .js files
          Object.keys(self.assetFiles)
            .filter(key => !key.match(/\.js?$/))
            .reduce((obj, key) => {
              obj[key] = self.assetFiles[key];
              return obj;
            }, {}),
          function (files, targetFile, cb) {
            const isDir = targetFile.slice(-1) === '/' || targetFile.indexOf('.') === -1;
            // if it's not a directory
            if (!isDir) {
              self.logger.info(__("writing file") + " " + (utils.joinPath(self.buildDir, targetFile)).bold.dim);
            }
            async.map(
              files,
              function (file, fileCb) {
                self.logger.trace("reading " + file.filename);
                return file.content(function (fileContent) {
                  self.runPlugins(file, fileContent, fileCb);
                });
              },
              function (err, contentFiles) {
                if (err) {
                  self.logger.error(__('errors found while generating') + ' ' + targetFile);
                }
                let dir = targetFile.split('/').slice(0, -1).join('/');
                self.logger.trace("creating dir " + utils.joinPath(self.buildDir, dir));
                fs.mkdirpSync(utils.joinPath(self.buildDir, dir));

                // if it's a directory
                if (isDir) {
                  let targetDir = targetFile;

                  if (targetDir.slice(-1) !== '/') {
                    targetDir = targetDir + '/';
                  }

                  async.each(contentFiles, function (file, mapCb) {
                    let filename = file.filename.replace(file.basedir + '/', '');
                    self.logger.info("writing file " + (utils.joinPath(self.buildDir, targetDir, filename)).bold.dim);

                    fs.copy(file.path, utils.joinPath(self.buildDir, targetDir, filename), {overwrite: true}, mapCb);
                  }, cb);
                  return;
                }

                let content = contentFiles.map(function (file) {
                  if (file === undefined) {
                    return "";
                  }
                  return file.content;
                }).join("\n");

                if(new RegExp(/^index.html?/i).test(targetFile)){
                  targetFile = targetFile.replace('index', 'index-temp');
                  placeholderPage = targetFile;
                }
                fs.writeFile(utils.joinPath(self.buildDir, targetFile), content, cb);
              }
            );
          },
          next
        );
      },
      function removePlaceholderPage(next){
        let placeholderFile = utils.joinPath(self.buildDir, placeholderPage);
        fs.access(utils.joinPath(self.buildDir, placeholderPage), (err) => {
          if (err) return next(); // index-temp doesn't exist, do nothing

          // rename index-temp.htm/l to index.htm/l, effectively replacing our placeholder page
          // with the contents of the built index.html page
          fs.move(placeholderFile, placeholderFile.replace('index-temp', 'index'), {overwrite: true}, next);
        });
      }
    ], callback);
  }

  runPlugins(file, fileContent, fileCb) {
    const self = this;
    if (self.pipelinePlugins.length <= 0) {
      return fileCb(null, {content: fileContent, filename: file.filename, path: file.path, basedir: file.basedir, modified: true});
    }
    async.eachSeries(
      self.pipelinePlugins,
      function(plugin, pluginCB) {
        if (file.options && file.options.skipPipeline) {
          return pluginCB();
        }

        fileContent = plugin.runPipeline({targetFile: file.filename, source: fileContent});
        file.modified = true;
        pluginCB();
      },
      function (err) {
        if (err) {
          self.logger.error(err.message);
        }
        return fileCb(null, {content: fileContent, filename: file.filename, path: file.path, basedir: file.basedir, modified: true});
      }
    );
  }

  buildContracts(cb) {
    const self = this;

    async.waterfall([
      function makeDirectory(next) {
        fs.mkdirp(fs.dappPath(self.buildDir, 'contracts'), (err, _result) => {
          next(err);
        });
      },
      function getContracts(next) {
        self.events.request('contracts:list', (err, contracts) => {
          next(err, contracts);
        });
      },
      function writeContractsJSON(contracts, next) {
        async.each(contracts, (contract, eachCb) => {
          fs.writeJson(fs.dappPath(self.buildDir, 'contracts', contract.className + ".json"), contract, {spaces: 2}, eachCb);
        }, () => { next(); });
      }
    ], cb);
  }

  buildWeb3JS(cb) {
    const self = this;
    async.waterfall([
      function makeDirectory(next) {
        fs.mkdirp(fs.dappPath(".embark"), (err, _result) => {
          next(err);
        });
      },
      function getWeb3Code(next) {
        self.events.request('code-generator:web3js', next);
      },
      function writeFile(code, next) {
        fs.writeFile(fs.dappPath(".embark", 'web3_instance.js'), code, next);
      }
    ], cb);
  }
}

module.exports = Pipeline;
<commit_msg>self.logger -> self.logger.error<commit_after>const fs = require('../core/fs.js');
const async = require('async');
const ProcessLauncher = require('../core/processes/processLauncher');
const utils = require('../utils/utils.js');
const constants = require('../constants');

class Pipeline {

  constructor(options) {
    this.env = options.env;
    this.buildDir = options.buildDir;
    this.contractsFiles = options.contractsFiles;
    this.assetFiles = options.assetFiles;
    this.events = options.events;
    this.logger = options.logger;
    this.plugins = options.plugins;
    this.webpackConfigName = options.webpackConfigName;
    this.pipelinePlugins = this.plugins.getPluginsFor('pipeline');
  }

  build(abi, contractsJSON, path, callback) {
    let self = this;
    const importsList = {};
    let placeholderPage;

    if (!this.assetFiles || !Object.keys(this.assetFiles).length) {
      return callback();
    }

    async.waterfall([
      function createPlaceholderPage(next){
        self.events.request('embark-building-placeholder', (html) => {
          fs.mkdirpSync(self.buildDir); // create dist/ folder if not already exists
          fs.writeFile(utils.joinPath(self.buildDir, 'index.html'), html, next);
        });
      },
      function buildTheContracts(next) {
        self.buildContracts(next);
      },
      function buildWeb3(next) {
        self.buildWeb3JS(next);
      },
      function createImportList(next) {
        importsList["Embark/EmbarkJS"] = fs.dappPath(".embark", 'embark.js');
        importsList["Embark/web3"] = fs.dappPath(".embark", 'web3_instance.js');
        importsList["Embark/contracts"] = fs.dappPath(".embark/contracts", '');

        self.plugins.getPluginsProperty('imports', 'imports').forEach(function (importObject) {
          let [importName, importLocation] = importObject;
          importsList[importName] = importLocation;
        });

        next();
      },
      function writeContracts(next) {
        self.events.request('contracts:list', (_err, contracts) => {
          // ensure the .embark/contracts directory exists (create if not exists)
          fs.mkdirp(fs.dappPath(".embark/contracts", ''), (err) => {
            if(err) return next(err);

            // Create a file .embark/contracts/index.js that requires all contract files
            // Used to enable alternate import syntax:
            // e.g. import {Token} from 'Embark/contracts'
            // e.g. import * as Contracts from 'Embark/contracts'
            let importsHelperFile = fs.createWriteStream(fs.dappPath(".embark/contracts", 'index.js'));
            importsHelperFile.write('module.exports = {\n');

            async.eachOf(contracts, (contract, idx, eachCb) => {
              self.events.request('code-generator:contract', contract.className, (contractCode) => {
                let filePath = fs.dappPath(".embark/contracts", contract.className + '.js');
                importsList["Embark/contracts/" + contract.className] = filePath;
                fs.writeFile(filePath, contractCode, eachCb);

                // add the contract to the exports list to support alternate import syntax
                importsHelperFile.write(`"${contract.className}": require('./${contract.className}').default`);
                if(idx < contracts.length - 1) importsHelperFile.write(',\n'); // add a comma if we have more contracts to add
              });
            }, function(){
              importsHelperFile.write('\n}'); // close the module.exports = {}
              importsHelperFile.close(next); // close the write stream
            });
          });
        });
      },
      function runWebpack(next) {
        self.logger.info(__(`running webpack with '${self.webpackConfigName}' config...`));
        Object.keys(self.assetFiles)
          .filter(key => key.match(/\.js?$/))
          .forEach(key => {
            self.logger.info(__("writing file") + " " + (utils.joinPath(self.buildDir, key)).bold.dim);
          });
        let built = false;
        const webpackProcess = new ProcessLauncher({
          modulePath: utils.joinPath(__dirname, 'webpackProcess.js'),
          logger: self.logger,
          events: self.events,
          exitCallback: function (code) {
            if (!built) {
              return next(`Webpack build exited with code ${code} before the process finished`);
            }
            if (code) {
              self.logger.error(__('Webpack build process exited with code ', code));
            }
          }
        });
        webpackProcess.send({action: constants.pipeline.init, options: {webpackConfigName: self.webpackConfigName}});
        webpackProcess.send({action: constants.pipeline.build, assets: self.assetFiles, importsList});

        webpackProcess.once('result', constants.pipeline.built, (msg) => {
          built = true;
          webpackProcess.kill();
          return next(msg.error);
        });
      },
      function assetFileWrite(next) {
        async.eachOf(
          // assetFileWrite should not process .js files
          Object.keys(self.assetFiles)
            .filter(key => !key.match(/\.js?$/))
            .reduce((obj, key) => {
              obj[key] = self.assetFiles[key];
              return obj;
            }, {}),
          function (files, targetFile, cb) {
            const isDir = targetFile.slice(-1) === '/' || targetFile.indexOf('.') === -1;
            // if it's not a directory
            if (!isDir) {
              self.logger.info(__("writing file") + " " + (utils.joinPath(self.buildDir, targetFile)).bold.dim);
            }
            async.map(
              files,
              function (file, fileCb) {
                self.logger.trace("reading " + file.filename);
                return file.content(function (fileContent) {
                  self.runPlugins(file, fileContent, fileCb);
                });
              },
              function (err, contentFiles) {
                if (err) {
                  self.logger.error(__('errors found while generating') + ' ' + targetFile);
                }
                let dir = targetFile.split('/').slice(0, -1).join('/');
                self.logger.trace("creating dir " + utils.joinPath(self.buildDir, dir));
                fs.mkdirpSync(utils.joinPath(self.buildDir, dir));

                // if it's a directory
                if (isDir) {
                  let targetDir = targetFile;

                  if (targetDir.slice(-1) !== '/') {
                    targetDir = targetDir + '/';
                  }

                  async.each(contentFiles, function (file, mapCb) {
                    let filename = file.filename.replace(file.basedir + '/', '');
                    self.logger.info("writing file " + (utils.joinPath(self.buildDir, targetDir, filename)).bold.dim);

                    fs.copy(file.path, utils.joinPath(self.buildDir, targetDir, filename), {overwrite: true}, mapCb);
                  }, cb);
                  return;
                }

                let content = contentFiles.map(function (file) {
                  if (file === undefined) {
                    return "";
                  }
                  return file.content;
                }).join("\n");

                if(new RegExp(/^index.html?/i).test(targetFile)){
                  targetFile = targetFile.replace('index', 'index-temp');
                  placeholderPage = targetFile;
                }
                fs.writeFile(utils.joinPath(self.buildDir, targetFile), content, cb);
              }
            );
          },
          next
        );
      },
      function removePlaceholderPage(next){
        let placeholderFile = utils.joinPath(self.buildDir, placeholderPage);
        fs.access(utils.joinPath(self.buildDir, placeholderPage), (err) => {
          if (err) return next(); // index-temp doesn't exist, do nothing

          // rename index-temp.htm/l to index.htm/l, effectively replacing our placeholder page
          // with the contents of the built index.html page
          fs.move(placeholderFile, placeholderFile.replace('index-temp', 'index'), {overwrite: true}, next);
        });
      }
    ], callback);
  }

  runPlugins(file, fileContent, fileCb) {
    const self = this;
    if (self.pipelinePlugins.length <= 0) {
      return fileCb(null, {content: fileContent, filename: file.filename, path: file.path, basedir: file.basedir, modified: true});
    }
    async.eachSeries(
      self.pipelinePlugins,
      function(plugin, pluginCB) {
        if (file.options && file.options.skipPipeline) {
          return pluginCB();
        }

        fileContent = plugin.runPipeline({targetFile: file.filename, source: fileContent});
        file.modified = true;
        pluginCB();
      },
      function (err) {
        if (err) {
          self.logger.error(err.message);
        }
        return fileCb(null, {content: fileContent, filename: file.filename, path: file.path, basedir: file.basedir, modified: true});
      }
    );
  }

  buildContracts(cb) {
    const self = this;

    async.waterfall([
      function makeDirectory(next) {
        fs.mkdirp(fs.dappPath(self.buildDir, 'contracts'), (err, _result) => {
          next(err);
        });
      },
      function getContracts(next) {
        self.events.request('contracts:list', (err, contracts) => {
          next(err, contracts);
        });
      },
      function writeContractsJSON(contracts, next) {
        async.each(contracts, (contract, eachCb) => {
          fs.writeJson(fs.dappPath(self.buildDir, 'contracts', contract.className + ".json"), contract, {spaces: 2}, eachCb);
        }, () => { next(); });
      }
    ], cb);
  }

  buildWeb3JS(cb) {
    const self = this;
    async.waterfall([
      function makeDirectory(next) {
        fs.mkdirp(fs.dappPath(".embark"), (err, _result) => {
          next(err);
        });
      },
      function getWeb3Code(next) {
        self.events.request('code-generator:web3js', next);
      },
      function writeFile(code, next) {
        fs.writeFile(fs.dappPath(".embark", 'web3_instance.js'), code, next);
      }
    ], cb);
  }
}

module.exports = Pipeline;
<|endoftext|>


<commit_before>var Util, DOM;

(function (Util, DOMTree) {
    'use strict';

    var Loader      = Util.extendProto(LoaderProto),
        DOMProto    = Object.getPrototypeOf(DOMTree);

    Util.extend(DOMProto, Loader);

    function LoaderProto() {
        var Images  = DOM.Images,
            Events  = DOM.Events,
            Loader  = this;

        /**
         * Function gets id by src
         * @param pSrc
         *
         * Example: http://domain.com/1.js -> 1_js
         */
        this.getIdBySrc             = function(src) {
            var num, sub, id,
                isStr       = Util.isString(src);

            if (isStr) {
                num    = src.lastIndexOf('/') + 1,
                sub    = src.substr(src, num),
                id     = Util.rmStrOnce(src, sub);

                /* убираем точки */
                while (id.indexOf('.') > 0)
                    id = id.replace('.', '_');
            }

            return id;
        };

        /**
         * load file countent via ajax
         *
         * @param pParams
         */
        this.ajax                    = function(params) {
            var p           = params, countProgress,
                type        = p.type || p.method || 'GET',
                xhr         = new XMLHttpRequest();

            xhr.open(type, p.url, true);

            if (p.responseType)
                xhr.responseType = p.responseType;

            Events.add('progress', function(event) {
                var percent, count;

                if (event.lengthComputable) {
                    percent = (event.loaded / event.total) * 100;
                    count   = Math.round(percent);

                    if (countProgress)
                        Images.setProgress(count);

                    countProgress = true;
                }

            }, xhr.upload);

            Events.add('readystatechange', function(event) {
                var TYPE_JSON, type, data, isContain,
                    xhr         = event.target;

                if (xhr.readyState === 4 /* Complete */) {
                    Images.clearProgress();
                    TYPE_JSON   = 'application/json';
                    type        = xhr.getResponseHeader('content-type');

                    if (xhr.status === 200 /* OK */) {
                        data        = xhr.response;
                        isContain   = Util.isContainStr(type, TYPE_JSON);

                        if (p.dataType !== 'text')
                            /* If it's json - parse it as json */
                            if (type && isContain)
                                data = Util.parseJSON(xhr.response) || xhr.response;

                            Util.exec(p.success, data, xhr.statusText, xhr);
                    }
                    /* file not found or connection lost */
                    else {
                        /* if html given or something like thet
                         * getBack just status of result
                         */
                        if (type && type.indexOf('text/plain') !== 0)
                            xhr.responseText = xhr.statusText;

                        Util.exec(p.error, xhr);
                    }
                }
            }, xhr);

            xhr.send(p.data);
        };

        /**
         * create elements and load them to DOM-tree
         * one-by-one
         *
         * @param params
         * @param callback
         */
        this.anyLoadOnLoad          = function(params, callback) {
            var param, func,
                isArray     = Util.isArray(params);

            if (isArray) {
                param   = params.shift();
                isArray = Util.isArray(param);
                func    = function() {
                    Loader.anyLoadOnLoad(params, callback);
                };

                if (!param) {
                    Util.exec(callback);
                } else if (isArray) {
                    Loader.anyLoadInParallel(param, callback);
                } else {
                    if (Util.isString(param))
                        param = {
                            src : param
                        };

                    if (!param.func)
                        param.func = func;

                    Loader.anyload(param);
                }
            };

            return Loader;
        }

        /**
         * improve callback of funcs so
         * we pop number of function and
         * if it's last we call pCallBack
         *
         * @param params
         * @param callback - onload function
         */
        this.anyLoadInParallel        = function(params, callback) {
            var i, n, param, func,
                done        = [],

                doneFunc    = function (func) {
                    Util.exec(func);

                    if (!done.pop())
                        Util.exec(callback);
                };

            if (!Util.isArray(params))
                params = [params];

            n = params.length;
            for (i = 0; i < n; i++) {
                param = params.pop();

                if (param) {
                    done.push(i);

                    if (Util.isString(param))
                        param   = { src : param };
                    else
                        func        = param.func;

                    param.func  = Util.retExec(doneFunc, func);

                    Loader.anyload(param);
                }
            }

            return Loader;
        };

        /**
         * Функция создаёт элемент и загружает файл с src.
         *
         * @param pParams_o = {
         * name, - название тэга
         * src', - путь к файлу
         * func, - обьект, содержаий одну из функций
         *          или сразу две onload и onerror
         *          {onload: function() {}, onerror: function();}
         * style,
         * id,
         * element,
         * async, - true by default
         * inner: 'id{color:red, },
         * class,
         * not_append - false by default
         * }
         */
        this.anyload                 = function(pParams_o) {
            var i, n, lElements_a;

            if (!pParams_o ) return;

            /* if a couple of params was
             * processing every of params
             * and quit
             */
            if (Util.isArray(pParams_o)) {
                lElements_a = [];
                for(i = 0, n = pParams_o.length; i < n ; i++)
                    lElements_a[i] = this.anyload(pParams_o[i]);

                return lElements_a;
            }

            var lName       = pParams_o.name,
                lAttr       = pParams_o.attribute,
                lID         = pParams_o.id,
                lClass      = pParams_o.className,
                lSrc        = pParams_o.src,
                lFunc       = pParams_o.func,
                lOnError,
                lAsync      = pParams_o.async,
                lParent     = pParams_o.parent || document.body,
                lInner      = pParams_o.inner,
                lStyle      = pParams_o.style,
                lNotAppend  = pParams_o.not_append;

            if (Util.isObject(lFunc)) {
                lOnError = lFunc.onerror;
                lFunc  = lFunc.onload;
            }
            /* убираем путь к файлу, оставляя только название файла */
            if (!lID && lSrc)
                lID = DOM.getIdBySrc(lSrc);

            var lElement = DOMTree.getById(lID);

            /* если скрипт еще не загружен */
            if (!lElement) {
                if (!lName && lSrc) {

                    var lDot = lSrc.lastIndexOf('.'),
                        lExt =  lSrc.substr(lDot);
                    switch(lExt) {
                        case '.js':
                            lName = 'script';
                            break;
                        case '.css':
                            lName = 'link';
                            lParent = document.head;
                            break;
                        default:
                            return {code: -1, text: 'name can not be empty'};
                    }
                }
                lElement                = document.createElement(lName);

                if (lID)
                    lElement.id         = lID;

                if (lClass)
                    lElement.className  = lClass;

                if (lSrc) {
                    /* if work with css use href */
                    if (lName === 'link') {
                        lElement.href = lSrc;
                        lElement.rel = 'stylesheet';
                    } else
                        lElement.src  = lSrc;

                    /*
                     * if passed arguments function
                     * then it's onload by default
                     *
                     * if object - then onload and onerror
                     */
                    var lLoad     = function(pEvent) {
                            Events.remove('load', lLoad, lElement);
                            Events.remove('error', lError, lElement);

                            Util.exec(lFunc, pEvent);
                        },

                        lError    = function() {
                            lParent.removeChild(lElement);

                            Images.showError({
                                responseText: 'file ' +
                                lSrc                  +
                                ' could not be loaded',
                                status : 404
                            });

                            Util.exec(lOnError);
                        };

                    Events.add('load', lLoad, lElement);
                    Events.addError(lError, lElement);
                }

                if (lAttr)
                    for(i in lAttr)
                        lElement.setAttribute(i, lAttr[i]);

                if (lStyle)
                    lElement.style.cssText = lStyle;

                if (lAsync || lAsync === undefined)
                    lElement.async = true;

                if (!lNotAppend)
                    lParent.appendChild(lElement);

                if (lInner)
                    lElement.innerHTML = lInner;
            }
            /* если js-файл уже загружен
             * запускаем функцию onload
             */
            else
                Util.exec(lFunc);

            return lElement;
        },

        /**
         * Функция загружает js-файл
         *
         * @param pSrc
         * @param pFunc
         */
        this.jsload                  = function(pSrc, pFunc) {
            var lRet = Loader.anyload({
                name : 'script',
                src  : pSrc,
                func : pFunc
            });

            return lRet;
        },

        /**
         * returns jsload functions
         */
        this.retJSLoad               = function(pSrc, pFunc) {
            var lRet = function() {
                return Loader.jsload(pSrc, pFunc);
            };

            return lRet;
        },

        /**
         * Функция создаёт елемент style и записывает туда стили
         * @param pParams_o - структура параметров, заполняеться таким
         * образом: {src: ' ',func: '', id: '', element: '', inner: ''}
         * все параметры опциональны
         */
        this.cssSet                  = function(pParams_o) {
            pParams_o.name      = 'style';
            pParams_o.parent    = pParams_o.parent || document.head;

            return Loader.anyload(pParams_o);
        },

        /**
         * Function loads external css files
         * @pParams_o - структура параметров, заполняеться таким
         * образом: {src: ' ',func: '', id: '', element: '', inner: ''}
         * все параметры опциональны
         */
        this.cssLoad                 = function(pParams_o) {
             if (Util.isArray(pParams_o)) {
                for(var i = 0, n = pParams_o.length; i < n; i++) {
                    pParams_o[i].name = 'link';
                    pParams_o[i].parent   = pParams_o.parent || document.head;
                }

                return Loader.anyload(pParams_o);
            }

            else if (Util.isString(pParams_o))
                pParams_o = { src: pParams_o };

            pParams_o.name      = 'link';
            pParams_o.parent    = pParams_o.parent || document.head;

            return Loader.anyload(pParams_o);
        };

        /**
         * load jquery from google cdn or local copy
         * @param pParams
         */
        this.jquery                     = function(paramObj) {
            var params  = paramObj || {},
                onload  = params.onload,
                onerror = params.onerror;

            /* загружаем jquery: */
            Loader.jsload('//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js', {
                onload  : onload,
                onerror : onerror
            });
        };
    }
})(Util, DOM);
<commit_msg>chore(loader) add ";"<commit_after>var Util, DOM;

(function (Util, DOMTree) {
    'use strict';

    var Loader      = Util.extendProto(LoaderProto),
        DOMProto    = Object.getPrototypeOf(DOMTree);

    Util.extend(DOMProto, Loader);

    function LoaderProto() {
        var Images  = DOM.Images,
            Events  = DOM.Events,
            Loader  = this;

        /**
         * Function gets id by src
         * @param pSrc
         *
         * Example: http://domain.com/1.js -> 1_js
         */
        this.getIdBySrc             = function(src) {
            var num, sub, id,
                isStr       = Util.isString(src);

            if (isStr) {
                num    = src.lastIndexOf('/') + 1,
                sub    = src.substr(src, num),
                id     = Util.rmStrOnce(src, sub);

                /* убираем точки */
                while (id.indexOf('.') > 0)
                    id = id.replace('.', '_');
            }

            return id;
        };

        /**
         * load file countent via ajax
         *
         * @param pParams
         */
        this.ajax                    = function(params) {
            var p           = params, countProgress,
                type        = p.type || p.method || 'GET',
                xhr         = new XMLHttpRequest();

            xhr.open(type, p.url, true);

            if (p.responseType)
                xhr.responseType = p.responseType;

            Events.add('progress', function(event) {
                var percent, count;

                if (event.lengthComputable) {
                    percent = (event.loaded / event.total) * 100;
                    count   = Math.round(percent);

                    if (countProgress)
                        Images.setProgress(count);

                    countProgress = true;
                }

            }, xhr.upload);

            Events.add('readystatechange', function(event) {
                var TYPE_JSON, type, data, isContain,
                    xhr         = event.target;

                if (xhr.readyState === 4 /* Complete */) {
                    Images.clearProgress();
                    TYPE_JSON   = 'application/json';
                    type        = xhr.getResponseHeader('content-type');

                    if (xhr.status === 200 /* OK */) {
                        data        = xhr.response;
                        isContain   = Util.isContainStr(type, TYPE_JSON);

                        if (p.dataType !== 'text')
                            /* If it's json - parse it as json */
                            if (type && isContain)
                                data = Util.parseJSON(xhr.response) || xhr.response;

                            Util.exec(p.success, data, xhr.statusText, xhr);
                    }
                    /* file not found or connection lost */
                    else {
                        /* if html given or something like thet
                         * getBack just status of result
                         */
                        if (type && type.indexOf('text/plain') !== 0)
                            xhr.responseText = xhr.statusText;

                        Util.exec(p.error, xhr);
                    }
                }
            }, xhr);

            xhr.send(p.data);
        };

        /**
         * create elements and load them to DOM-tree
         * one-by-one
         *
         * @param params
         * @param callback
         */
        this.anyLoadOnLoad          = function(params, callback) {
            var param, func,
                isArray     = Util.isArray(params);

            if (isArray) {
                param   = params.shift();
                isArray = Util.isArray(param);
                func    = function() {
                    Loader.anyLoadOnLoad(params, callback);
                };

                if (!param) {
                    Util.exec(callback);
                } else if (isArray) {
                    Loader.anyLoadInParallel(param, callback);
                } else {
                    if (Util.isString(param))
                        param = {
                            src : param
                        };

                    if (!param.func)
                        param.func = func;

                    Loader.anyload(param);
                }
            }

            return Loader;
        };

        /**
         * improve callback of funcs so
         * we pop number of function and
         * if it's last we call pCallBack
         *
         * @param params
         * @param callback - onload function
         */
        this.anyLoadInParallel        = function(params, callback) {
            var i, n, param, func,
                done        = [],

                doneFunc    = function (func) {
                    Util.exec(func);

                    if (!done.pop())
                        Util.exec(callback);
                };

            if (!Util.isArray(params))
                params = [params];

            n = params.length;
            for (i = 0; i < n; i++) {
                param = params.pop();

                if (param) {
                    done.push(i);

                    if (Util.isString(param))
                        param   = { src : param };
                    else
                        func        = param.func;

                    param.func  = Util.retExec(doneFunc, func);

                    Loader.anyload(param);
                }
            }

            return Loader;
        };

        /**
         * Функция создаёт элемент и загружает файл с src.
         *
         * @param pParams_o = {
         * name, - название тэга
         * src', - путь к файлу
         * func, - обьект, содержаий одну из функций
         *          или сразу две onload и onerror
         *          {onload: function() {}, onerror: function();}
         * style,
         * id,
         * element,
         * async, - true by default
         * inner: 'id{color:red, },
         * class,
         * not_append - false by default
         * }
         */
        this.anyload                 = function(pParams_o) {
            var i, n, lElements_a;

            if (!pParams_o ) return;

            /* if a couple of params was
             * processing every of params
             * and quit
             */
            if (Util.isArray(pParams_o)) {
                lElements_a = [];
                for(i = 0, n = pParams_o.length; i < n ; i++)
                    lElements_a[i] = this.anyload(pParams_o[i]);

                return lElements_a;
            }

            var lName       = pParams_o.name,
                lAttr       = pParams_o.attribute,
                lID         = pParams_o.id,
                lClass      = pParams_o.className,
                lSrc        = pParams_o.src,
                lFunc       = pParams_o.func,
                lOnError,
                lAsync      = pParams_o.async,
                lParent     = pParams_o.parent || document.body,
                lInner      = pParams_o.inner,
                lStyle      = pParams_o.style,
                lNotAppend  = pParams_o.not_append;

            if (Util.isObject(lFunc)) {
                lOnError = lFunc.onerror;
                lFunc  = lFunc.onload;
            }
            /* убираем путь к файлу, оставляя только название файла */
            if (!lID && lSrc)
                lID = DOM.getIdBySrc(lSrc);

            var lElement = DOMTree.getById(lID);

            /* если скрипт еще не загружен */
            if (!lElement) {
                if (!lName && lSrc) {

                    var lDot = lSrc.lastIndexOf('.'),
                        lExt =  lSrc.substr(lDot);
                    switch(lExt) {
                        case '.js':
                            lName = 'script';
                            break;
                        case '.css':
                            lName = 'link';
                            lParent = document.head;
                            break;
                        default:
                            return {code: -1, text: 'name can not be empty'};
                    }
                }
                lElement                = document.createElement(lName);

                if (lID)
                    lElement.id         = lID;

                if (lClass)
                    lElement.className  = lClass;

                if (lSrc) {
                    /* if work with css use href */
                    if (lName === 'link') {
                        lElement.href = lSrc;
                        lElement.rel = 'stylesheet';
                    } else
                        lElement.src  = lSrc;

                    /*
                     * if passed arguments function
                     * then it's onload by default
                     *
                     * if object - then onload and onerror
                     */
                    var lLoad     = function(pEvent) {
                            Events.remove('load', lLoad, lElement);
                            Events.remove('error', lError, lElement);

                            Util.exec(lFunc, pEvent);
                        },

                        lError    = function() {
                            lParent.removeChild(lElement);

                            Images.showError({
                                responseText: 'file ' +
                                lSrc                  +
                                ' could not be loaded',
                                status : 404
                            });

                            Util.exec(lOnError);
                        };

                    Events.add('load', lLoad, lElement);
                    Events.addError(lError, lElement);
                }

                if (lAttr)
                    for(i in lAttr)
                        lElement.setAttribute(i, lAttr[i]);

                if (lStyle)
                    lElement.style.cssText = lStyle;

                if (lAsync || lAsync === undefined)
                    lElement.async = true;

                if (!lNotAppend)
                    lParent.appendChild(lElement);

                if (lInner)
                    lElement.innerHTML = lInner;
            }
            /* если js-файл уже загружен
             * запускаем функцию onload
             */
            else
                Util.exec(lFunc);

            return lElement;
        },

        /**
         * Функция загружает js-файл
         *
         * @param pSrc
         * @param pFunc
         */
        this.jsload                  = function(pSrc, pFunc) {
            var lRet = Loader.anyload({
                name : 'script',
                src  : pSrc,
                func : pFunc
            });

            return lRet;
        },

        /**
         * returns jsload functions
         */
        this.retJSLoad               = function(pSrc, pFunc) {
            var lRet = function() {
                return Loader.jsload(pSrc, pFunc);
            };

            return lRet;
        },

        /**
         * Функция создаёт елемент style и записывает туда стили
         * @param pParams_o - структура параметров, заполняеться таким
         * образом: {src: ' ',func: '', id: '', element: '', inner: ''}
         * все параметры опциональны
         */
        this.cssSet                  = function(pParams_o) {
            pParams_o.name      = 'style';
            pParams_o.parent    = pParams_o.parent || document.head;

            return Loader.anyload(pParams_o);
        },

        /**
         * Function loads external css files
         * @pParams_o - структура параметров, заполняеться таким
         * образом: {src: ' ',func: '', id: '', element: '', inner: ''}
         * все параметры опциональны
         */
        this.cssLoad                 = function(pParams_o) {
             if (Util.isArray(pParams_o)) {
                for(var i = 0, n = pParams_o.length; i < n; i++) {
                    pParams_o[i].name = 'link';
                    pParams_o[i].parent   = pParams_o.parent || document.head;
                }

                return Loader.anyload(pParams_o);
            }

            else if (Util.isString(pParams_o))
                pParams_o = { src: pParams_o };

            pParams_o.name      = 'link';
            pParams_o.parent    = pParams_o.parent || document.head;

            return Loader.anyload(pParams_o);
        };

        /**
         * load jquery from google cdn or local copy
         * @param pParams
         */
        this.jquery                     = function(paramObj) {
            var params  = paramObj || {},
                onload  = params.onload,
                onerror = params.onerror;

            /* загружаем jquery: */
            Loader.jsload('//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js', {
                onload  : onload,
                onerror : onerror
            });
        };
    }
})(Util, DOM);
<|endoftext|>


<commit_before>module.exports = {
    id: "playbook",
    initialize:function() {},
    objects: {
        navigator: {
            children: {
                device: {
                    path: "cordova/plugin/playbook/device"
                }
            }
        },
        device: {
            path: "cordova/plugin/playbook/device"
        }
    }
};
<commit_msg>Move navigator.device to merges object for PlayBook.<commit_after>module.exports = {
    id: "playbook",
    initialize:function() {},
    objects: {
        device: {
            path: "cordova/plugin/playbook/device"
        }
    },
    merges: {
        navigator: {
            children: {
                device: {
                    path: "cordova/plugin/playbook/device"
                }
            }
        }
    }
};
<|endoftext|>


<commit_before> 'use strict';

var build       = module.exports = {};
var fs          = require('fs-sync');
var node_path   = require('path');
var hum         = require('hum');
var semver      = require('semver');
var async       = require('async');
var putin       = require('put-in');
var pkg_helper  = require('../util/package');
var lang        = require('../util/lang');
var exec        = require('child_process').exec;

var USER_HOME   = process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'];

// @param {Object} options
//      see ./lib/option/build.js for details
build.run = function(options, callback){
    // if the destination is not specified by user
    if ( !options.dest ) {
        options.dest = this.context.profile.get('built_root');
    }

    var self = this;
    var pkg = pkg_helper.get_package_json(options.cwd);

    if ( pkg.err ) {
        return callback(pkg.err);
    }

    options.pkg = pkg.cortex;
    this.MESSAGE = this.context.locale.require('command-build');

    async.series([
        function (done) {
            // run custom build script
            self.run_build_script(options, done);
        },

        function (done) {
            // determine build tasks
            self.determine_tasks(options, done);
        },

        function (done) {
            // real building
            self.build(options, done);
        }

    ], function (err) {
        callback(err);
    });
};

// Run custom build scripts, such as 'grunt'
build.run_build_script = function (options, callback) {
    var pkg = options.pkg;
    var build_script = lang.makeArray( pkg.scripts && pkg.scripts.build );

    if ( !build_script.length ) {
        return callback(null);
    }

    var self = this;

    this.logger.info('{{cyan run}} build script ...');

    exec( build_script.join(' && '), {
        cwd: options.cwd

    }, function(err, stdout, stderr){
        if ( err ) {
            return callback(err);
        }

        self.logger.info(stdout);
        stderr && self.logger.error(stderr);

        callback(null);
    });
};

build.determine_tasks = function (options, callback) {
    var cache_root  = this.context.profile.get('cache_root');
    var tasks       = options.tasks = {};
    var name        = options.pkg.name;
    var version     = options.pkg.version;
    var built_root  = options.dest;

    var self = this;

    if ( options.ranges ) {
        pkg_helper.get_module_document({
            name: name,
            cache_root: cache_root

        }, function (err, json) {
            if ( err ) {
                return callback(err);
            }

            var versions    = json && json.versions && Object.keys(json.versions) || [];
            versions.sort(semver.rcompare);

            // '1.2.3' -> '~1.2.0'
            var range       = self.get_base_range(version);
            var max_patch   = semver.maxSatisfying(versions, range);
            var max         = versions[0];

            if (
                // if the current minor(feature) doesn't exist
                !max_patch ||

                // greater or equal to
                semver.gte(version, max_patch)
            ) {
                tasks[version] = node_path.join(built_root, name, range);

                // if the package is not the latest patch,
                // it's impossible to be the latest of all versions
                if (
                    // if there's no versions on the regsitry
                    !max ||

                    // if current version is the greatest
                    semver.gte(version, max)
                ) {
                    tasks.latest = node_path.join(built_root, name, 'latest');
                }
            }

            // {
            //     '1.2.3': '/xxx/~1.2.0',
            //     'latest': '/xxx/latest'
            // }
            callback(null, tasks);
        });

    } else {
        tasks[version] = node_path.join(built_root, name, version);
        callback(null, tasks);
    }
};

// '1.2.3' -> '~1.2.0'
build.get_base_range = function (version) {
    var parsed_semver = semver.parse(version);

    return ['~' + parsed_semver.major, parsed_semver.minor, 0].join('.');
};

build.build = function (options, callback) {
    var pkg = options.pkg;

    var self = this;

    // distribution directory
    var dist = lang.object_member_by_namespaces(options.pkg, 'directories.dist');

    if ( dist ) {
        dist = node_path.join(options.cwd, dist);

        // if `dist` dir exists, skip building and just copy it
        if ( fs.exists(dist) ) {
            self.logger.info('dist dir "' + dist + '" found, {{cyan skip}} building ...');

            self.copy_dist(dist, options, callback);

        } else {
            // if `cortex.directories.dist` is declared, the dir must be existed.
            callback({
                code: 'EDISTNOTEXISTS',
                message: 'dist dir "' + dist + '" does not exist.',
                data: {
                    dist: dist
                }
            });
        }

    } else {
        self.get_node_path(function (search_path) {
            // make sure the commonjs builder already installed
            self.check_builder(search_path, options, function (err) {
                if ( err ) {
                    return callback(err);
                }

                self.get_entries(options.cwd, options.pkg, function (err, entries) {
                    if ( err ) {
                        return callback(err);
                    }

                    options.entries = entries;

                    var tasks = options.tasks;
                    async.parallel(
                        Object.keys(tasks).map(function (target_version) {
                            return function (done) {
                                var to = tasks[target_version];
                                self.run_build_task(target_version, to, options, done);
                            }
                        }),

                        callback
                    );
                });
            });
        });
    }
};

// copy dist dir to the destination dirs
build.copy_dist = function (dist, options, callback) {
    var self = this;

    lang.each(options.tasks, function (to) {
        self.logger.info('{{cyan copy}} "' + dist + '" to "' + to + '".');
        self.cp(dist, to);
    });

    callback(null);
};

build.get_node_path = function (callback) {
    var NODE_PATH = process.env.NODE_PATH;
    var search_path;

    if ( NODE_PATH ) {
        search_path = NODE_PATH.split(':').filter(Boolean)[0];
    }

    callback( search_path || '/usr/local/lib/node_modules' );
};

// Check if the builder exists.
build.check_builder = function (search_path, options, callback) {
    var builder = options.builder = this.context.profile.get('builder');
    options.builder_task = this.context.profile.get('builder_task');

    if(!builder){
        return callback(this.MESSAGE.BUILDER_MUST_BE_DEFINED);
    }

    if(!fs.exists(node_path.join(search_path, builder))){
        this.logger.info('\n{{cyan install}} commonjs builder...');

        // install tasks if not exists
        putin(search_path).install(builder, function(code){
            if(code === 0){
                callback(null);

            }else{
                callback(self.logger.template(self.MESSAGE.PACKAGE_NOT_FOUNT_ON_NPM,{
                    name: builder
                }));
            }
        });

    } else {
        callback(null);
    }
};

build.get_entries = function (cwd, pkg, callback) {
    var main_entry = pkg.main || 'index.js';
    var entries = pkg.entries ?
            fs.expand(pkg.entries, {
                cwd: cwd
            }) :
            [];

    var fail = entries.some(function (entry) {
        // entries should not be located at the parent folder of the main entry.
        if ( node_path.relative( node_path.dirname(main_entry), entry).indexOf('..') === 0 ) {
            callback({
                code: 'EINVALIDENTRIES',
                message: 'entry "' + entry + '" should not be located at the parent folder of "' + main_entry + '"',
                data: {
                    main: main_entry,
                    entry: entry
                }
            });

            return true;
        }
    });

    if ( !fail ) {
        entries.push(main_entry);

        callback(null, entries);
    }
};

build.run_build_task = function (target_version, to, options, callback) {
    var task_name = options.builder_task;
    var init_config = {};
    var entries = {};

    options.entries.forEach(function (entry) {
        entries[ node_path.join(options.cwd, entry) ] = node_path.join(to, entry);
    });

    init_config[task_name] = {
        'all': {
            options: {
                entries: entries,
                targetVersion: target_version
            }
        }
    };

    var self = this;

    async.parallel([
        // run commonjs builder
        function (done) {
            hum({
                cwd: options.cwd
            })
            .npmTasks(options.builder)
            .task(options.builder_task)
            .init(init_config)
            .options({
                force: true
            })
            .done(done);
        },

        // copy css
        function (done) {
            self.copy_css(to, options, done);
        }

    ], callback);
};

build.copy_css = function (to, options, callback) {
    var pkg = options.pkg;
    var css = lang.object_member_by_namespaces(pkg, 'directories.css');

    if ( css ) {
        css = node_path.join(options.cwd, css);

        try {
            this.cp(css, to);
        } catch(e) {
            return callback(e);
        }

        return callback(null);

    } else {
        callback(null);
    }
};

// publish files from `from` to `to`
build.cp = function (from, to) {
    if ( from === to ) {
        return;
    }

    fs.exists(to) && fs.remove(to, {
        force: true
    });

    fs.copy(from, to, {
        force: true
    });
};

<commit_msg>#176: command/build: pass the cooked package object to tasks<commit_after> 'use strict';

var build       = module.exports = {};
var fs          = require('fs-sync');
var node_path   = require('path');
var hum         = require('hum');
var semver      = require('semver');
var async       = require('async');
var putin       = require('put-in');
var pkg_helper  = require('../util/package');
var lang        = require('../util/lang');
var exec        = require('child_process').exec;

var USER_HOME   = process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'];

// @param {Object} options
//      see ./lib/option/build.js for details
build.run = function(options, callback){
    // if the destination is not specified by user
    if ( !options.dest ) {
        options.dest = this.context.profile.get('built_root');
    }

    var self = this;
    var pkg = pkg_helper.get_package_json(options.cwd);

    if ( pkg.err ) {
        return callback(pkg.err);
    }

    options.pkg = pkg.cortex;
    this.MESSAGE = this.context.locale.require('command-build');

    async.series([
        function (done) {
            // run custom build script
            self.run_build_script(options, done);
        },

        function (done) {
            // determine build tasks
            self.determine_tasks(options, done);
        },

        function (done) {
            // real building
            self.build(options, done);
        }

    ], function (err) {
        callback(err);
    });
};

// Run custom build scripts, such as 'grunt'
build.run_build_script = function (options, callback) {
    var pkg = options.pkg;
    var build_script = lang.makeArray( pkg.scripts && pkg.scripts.build );

    if ( !build_script.length ) {
        return callback(null);
    }

    var self = this;

    this.logger.info('{{cyan run}} build script ...');

    exec( build_script.join(' && '), {
        cwd: options.cwd

    }, function(err, stdout, stderr){
        if ( err ) {
            return callback(err);
        }

        self.logger.info(stdout);
        stderr && self.logger.error(stderr);

        callback(null);
    });
};

build.determine_tasks = function (options, callback) {
    var cache_root  = this.context.profile.get('cache_root');
    var tasks       = options.tasks = {};
    var name        = options.pkg.name;
    var version     = options.pkg.version;
    var built_root  = options.dest;

    var self = this;

    if ( options.ranges ) {
        pkg_helper.get_module_document({
            name: name,
            cache_root: cache_root

        }, function (err, json) {
            if ( err ) {
                return callback(err);
            }

            var versions    = json && json.versions && Object.keys(json.versions) || [];
            versions.sort(semver.rcompare);

            // '1.2.3' -> '~1.2.0'
            var range       = self.get_base_range(version);
            var max_patch   = semver.maxSatisfying(versions, range);
            var max         = versions[0];

            if (
                // if the current minor(feature) doesn't exist
                !max_patch ||

                // greater or equal to
                semver.gte(version, max_patch)
            ) {
                tasks[version] = node_path.join(built_root, name, range);

                // if the package is not the latest patch,
                // it's impossible to be the latest of all versions
                if (
                    // if there's no versions on the regsitry
                    !max ||

                    // if current version is the greatest
                    semver.gte(version, max)
                ) {
                    tasks.latest = node_path.join(built_root, name, 'latest');
                }
            }

            // {
            //     '1.2.3': '/xxx/~1.2.0',
            //     'latest': '/xxx/latest'
            // }
            callback(null, tasks);
        });

    } else {
        tasks[version] = node_path.join(built_root, name, version);
        callback(null, tasks);
    }
};

// '1.2.3' -> '~1.2.0'
build.get_base_range = function (version) {
    var parsed_semver = semver.parse(version);

    return ['~' + parsed_semver.major, parsed_semver.minor, 0].join('.');
};

build.build = function (options, callback) {
    var pkg = options.pkg;

    var self = this;

    // distribution directory
    var dist = lang.object_member_by_namespaces(options.pkg, 'directories.dist');

    if ( dist ) {
        dist = node_path.join(options.cwd, dist);

        // if `dist` dir exists, skip building and just copy it
        if ( fs.exists(dist) ) {
            self.logger.info('dist dir "' + dist + '" found, {{cyan skip}} building ...');

            self.copy_dist(dist, options, callback);

        } else {
            // if `cortex.directories.dist` is declared, the dir must be existed.
            callback({
                code: 'EDISTNOTEXISTS',
                message: 'dist dir "' + dist + '" does not exist.',
                data: {
                    dist: dist
                }
            });
        }

    } else {
        self.get_node_path(function (search_path) {
            // make sure the commonjs builder already installed
            self.check_builder(search_path, options, function (err) {
                if ( err ) {
                    return callback(err);
                }

                self.get_entries(options.cwd, options.pkg, function (err, entries) {
                    if ( err ) {
                        return callback(err);
                    }

                    options.entries = entries;

                    var tasks = options.tasks;
                    async.parallel(
                        Object.keys(tasks).map(function (target_version) {
                            return function (done) {
                                var to = tasks[target_version];
                                self.run_build_task(target_version, to, options, done);
                            }
                        }),

                        callback
                    );
                });
            });
        });
    }
};

// copy dist dir to the destination dirs
build.copy_dist = function (dist, options, callback) {
    var self = this;

    lang.each(options.tasks, function (to) {
        self.logger.info('{{cyan copy}} "' + dist + '" to "' + to + '".');
        self.cp(dist, to);
    });

    callback(null);
};

build.get_node_path = function (callback) {
    var NODE_PATH = process.env.NODE_PATH;
    var search_path;

    if ( NODE_PATH ) {
        search_path = NODE_PATH.split(':').filter(Boolean)[0];
    }

    callback( search_path || '/usr/local/lib/node_modules' );
};

// Check if the builder exists.
build.check_builder = function (search_path, options, callback) {
    var builder = options.builder = this.context.profile.get('builder');
    options.builder_task = this.context.profile.get('builder_task');

    if(!builder){
        return callback(this.MESSAGE.BUILDER_MUST_BE_DEFINED);
    }

    if(!fs.exists(node_path.join(search_path, builder))){
        this.logger.info('\n{{cyan install}} commonjs builder...');

        // install tasks if not exists
        putin(search_path).install(builder, function(code){
            if(code === 0){
                callback(null);

            }else{
                callback(self.logger.template(self.MESSAGE.PACKAGE_NOT_FOUNT_ON_NPM,{
                    name: builder
                }));
            }
        });

    } else {
        callback(null);
    }
};

build.get_entries = function (cwd, pkg, callback) {
    var main_entry = pkg.main || 'index.js';
    var entries = pkg.entries ?
            fs.expand(pkg.entries, {
                cwd: cwd
            }) :
            [];

    var fail = entries.some(function (entry) {
        // entries should not be located at the parent folder of the main entry.
        if ( node_path.relative( node_path.dirname(main_entry), entry).indexOf('..') === 0 ) {
            callback({
                code: 'EINVALIDENTRIES',
                message: 'entry "' + entry + '" should not be located at the parent folder of "' + main_entry + '"',
                data: {
                    main: main_entry,
                    entry: entry
                }
            });

            return true;
        }
    });

    if ( !fail ) {
        entries.push(main_entry);

        callback(null, entries);
    }
};

build.run_build_task = function (target_version, to, options, callback) {
    var task_name = options.builder_task;
    var init_config = {};
    var entries = {};

    options.entries.forEach(function (entry) {
        entries[ node_path.join(options.cwd, entry) ] = node_path.join(to, entry);
    });

    init_config[task_name] = {
        'all': {
            options: {
                entries: entries,
                pkg: options.pkg,
                targetVersion: target_version
            }
        }
    };

    var self = this;

    async.parallel([
        // run commonjs builder
        function (done) {
            hum({
                cwd: options.cwd
            })
            .npmTasks(options.builder)
            .task(options.builder_task)
            .init(init_config)
            .options({
                force: true
            })
            .done(done);
        },

        // copy css
        function (done) {
            self.copy_css(to, options, done);
        }

    ], callback);
};

build.copy_css = function (to, options, callback) {
    var pkg = options.pkg;
    var css = lang.object_member_by_namespaces(pkg, 'directories.css');

    if ( css ) {
        css = node_path.join(options.cwd, css);

        try {
            this.cp(css, to);
        } catch(e) {
            return callback(e);
        }

        return callback(null);

    } else {
        callback(null);
    }
};

// publish files from `from` to `to`
build.cp = function (from, to) {
    if ( from === to ) {
        return;
    }

    fs.exists(to) && fs.remove(to, {
        force: true
    });

    fs.copy(from, to, {
        force: true
    });
};

<|endoftext|>


<commit_before>'use strict';

const uuid = require('uuid');
const Joi  = require('joi');

const addJob            = require('../db/redis.js').addJob;
const mailgun           = require('./utils/mailgun.js');
const getAgenciesEmails = require('../db/redis.js').getAgenciesEmails;
const notifyAgencies    = require('./utils/mailgun.js').notifyAgenciesOfNewJob;

const backendInput = new RegExp(/^[a-zA-Z0-9 .,?\-@!:;]*$/);
const frontendInput ='[a-zA-Z0-9 .,£$€?\-@!:;]*';

const joiOpts = {
  jobTitle: Joi.string().min(1).max(30).required().regex(backendInput),
  jobDescription: Joi.string().min(1).max(3000).required().regex(backendInput),
  teamCulture: Joi.string().min(1).max(100).require().regex(backendInput),
  typesOfProjects: Joi.string().min(1).max(100).required().regex(backendInput),
  skillOne: Joi.any().optional(),
  skillTwo: Joi.any().optional(),
  skillThree: Joi.any().optional(),
  personality: Joi.any().optional(),
  salary: Joi.any().optional(),
  searchDeadline: Joi.date()
};

let opts = {
  frontendInput: frontendInput
};

exports.register = (server, options, next) => {

  server.route([{
    method: 'GET',
    path: '/submitjob',
    config: {
      auth: {
        strategy: 'hrns-cookie',
        scope:'client'
      },
      handler: (request, reply) => {
        reply.view('submitjob', opts, { layout: 'client' });
      }
    }
  }, {
    method: 'POST',
    path: '/submitjob',
    config: {
      auth: {
        strategy: 'hrns-cookie'
      },
      valiate: {
        payload: joiOpts
      },
      handler: (request, reply) => {
        let id = request.auth.credentials.profile.id;
        let payload = request.payload;
        let vid = uuid.v1();

        for (var i in payload) {
          if (payload[i] === '') {
            delete payload[i];
          }
        }

        addJob(payload, id, vid, (res) => {
          if (res) {
            getAgenciesEmails((res) => {
              if (res) {
                notifyAgencies.to = res;
                mailgun.messages().send(notifyAgencies, (error, body) => console.log('body', body));
                opts.message = 'Thanks for submitting a new job! We\'ll be supplying you with great candidates in no time!';
                reply.view('submitjob', opts, { layout: 'client' });
              } else {
                opts.message = 'Sorry, something went wrong, please try again';
                reply.view('submitjob', opts, { layout: 'client' });
              }
            });
          } else {
            opts.message = 'Sorry, something went wrong, please try again';
            reply.view('submitjob', opts, { layout: 'client' });
          }
        });
      }
    }
  }]);
  return next();
};

exports.register.attributes = {
  name: 'SubmitJob'
};
<commit_msg>correct joi vlaidation<commit_after>'use strict';

const uuid = require('uuid');
const Joi  = require('joi');

const addJob            = require('../db/redis.js').addJob;
const mailgun           = require('./utils/mailgun.js');
const getAgenciesEmails = require('../db/redis.js').getAgenciesEmails;
const notifyAgencies    = require('./utils/mailgun.js').notifyAgenciesOfNewJob;

const backendInput = new RegExp(/^[a-zA-Z0-9 .,?\-@!:;]*$/);
const frontendInput ='[a-zA-Z0-9 .,£$€?\-@!:;]*';

const joiOpts = {
  jobTitle: Joi.string().min(1).max(30).required().regex(backendInput),
  jobDescription: Joi.string().min(1).max(3000).required().regex(backendInput),
  teamCulture: Joi.string().min(1).max(100).required().regex(backendInput),
  typesOfProjects: Joi.string().min(1).max(100).required().regex(backendInput),
  skillOne: Joi.any().optional(),
  skillTwo: Joi.any().optional(),
  skillThree: Joi.any().optional(),
  personality: Joi.any().optional(),
  salary: Joi.any().optional(),
  searchDeadline: Joi.date()
};

let opts = {
  frontendInput: frontendInput
};

exports.register = (server, options, next) => {

  server.route([{
    method: 'GET',
    path: '/submitjob',
    config: {
      auth: {
        strategy: 'hrns-cookie',
        scope:'client'
      },
      handler: (request, reply) => {
        reply.view('submitjob', opts, { layout: 'client' });
      }
    }
  }, {
    method: 'POST',
    path: '/submitjob',
    config: {
      auth: {
        strategy: 'hrns-cookie'
      },
      valiate: {
        payload: joiOpts
      },
      handler: (request, reply) => {
        let id = request.auth.credentials.profile.id;
        let payload = request.payload;
        let vid = uuid.v1();

        for (var i in payload) {
          if (payload[i] === '') {
            delete payload[i];
          }
        }

        addJob(payload, id, vid, (res) => {
          if (res) {
            getAgenciesEmails((res) => {
              if (res) {
                notifyAgencies.to = res;
                mailgun.messages().send(notifyAgencies, (error, body) => console.log('body', body));
                opts.message = 'Thanks for submitting a new job! We\'ll be supplying you with great candidates in no time!';
                reply.view('submitjob', opts, { layout: 'client' });
              } else {
                opts.message = 'Sorry, something went wrong, please try again';
                reply.view('submitjob', opts, { layout: 'client' });
              }
            });
          } else {
            opts.message = 'Sorry, something went wrong, please try again';
            reply.view('submitjob', opts, { layout: 'client' });
          }
        });
      }
    }
  }]);
  return next();
};

exports.register.attributes = {
  name: 'SubmitJob'
};
<|endoftext|>


<commit_before>'use strict'

const {Command} = require('heroku-command')
const plugins = require('../plugins')

function stderrwidth () {
  if (!process.stdout.isTTY) return 80
  return process.stdout.getWindowSize()[0]
}

class Help extends Command {
  async run () {
    plugins.load()
    let subject = this.argv.slice(1).find(arg => !['help', '-h', '--help'].includes(arg))
    if (!subject) return this.all()
    let topic = plugins.topics.find(t => t.name === subject.split(':')[0])
    if (topic.help) return topic.help(subject)
    this.topic(topic, subject)
  }

  all () {
    const max = require('lodash.maxby')
    const S = require('string')

    this.log(`Usage: ${this.argv[0]} COMMAND [--app APP] [command-specific-options]

  Help topics, type ${this.color.cmd(this.argv[0] + ' help TOPIC')} for more details:
  `)
    let topics = plugins.topics
    topics = topics.filter(t => !t.hidden)
    let maxlength = max(topics, 'name.length').name.length
    for (let topic of topics) {
      this.log(`  ${this.argv[0]} ${S(topic.name).padRight(maxlength)}${topic.description ? ' # ' + topic.description : ''}`)
    }

    this.log()
  }

  topic (topic, subject) {
    const max = require('lodash.maxby')
    const S = require('string')
    const linewrap = require('../linewrap')

    function renderArg (arg) {
      if (arg.required !== false && arg.optional !== true) return ` <${arg.name}>`
      else return ` [${arg.name}]`
    }

    function renderFlags (flags) {
      const max = require('lodash.maxby')
      let lines = []
      for (let flag of flags) {
        let label = []
        if (flag.char) label.push(`-${flag.char}`)
        if (flag.name) label.push(` --${flag.name}`)
        let usage = flag.hasValue ? ` ${flag.name.toUpperCase()}` : ''
        let description = flag.description || ''
        if (flag.required || flag.optional === false) description = `(required) ${description}`
        lines.push([label.join(',').trim() + usage, description])
      }
      let maxLength = max(lines, '0')[0].length
      return lines.map(line => {
        let desc = line[1] || ''
        if (desc) {
          desc = linewrap(maxLength + 4, stderrwidth(), {
            skipScheme: 'ansi-color'
          })(desc).trim()
          desc = ' # ' + desc.split('\n').map(l => {
            if (l[0] !== ' ') return l
            return l.substr(0, maxLength + 1) + ' # ' + l.substr(maxLength + 4)
          }).join('\n')
        }
        return ` ${S(line[0]).padRight(maxLength)}${desc}`
      }).join('\n')
    }

    let command = subject.split(':').slice(1).join(':')
    command = plugins.commands.find(c => c.topic === topic.name && (c.command === command || (!c.command && !command)))

    if (command) {
      let cmd = command.command ? `${command.topic}:${command.command}` : command.topic
      // TODO: get usage if defined
      let usage = `${this.argv[0]} ${cmd}` + (command.args || []).map(renderArg).join('')
      this.log(`Usage: ${this.color.cmd(usage)}\n`)
      if (command.description) this.log(`${command.description.trim()}\n`)
      if (command.flags && command.flags.length) this.log(`${renderFlags(command.flags)}\n`)
      if (command.help) this.log(`${command.help.trim()}\n`)
    }

    if (subject.includes(':')) return

    let commands = plugins.commands.filter(c => c.topic === subject && c.command)
    if (commands.length === 0) return
    this.log(`${this.argv[0]} ${subject} commands: (${this.color.cmd(this.argv[0] + ' help ' + subject + ':COMMAND')} for details)
  `)
    let maxLength = max(commands, 'command.length').command.length + subject.length + 1
    for (let command of commands) {
      let cmd = command.command ? `${command.topic}:${command.command}` : command.topic
      this.log(`  ${S(cmd).padRight(maxLength)}${command.description ? ' # ' + command.description : ''}`)
    }
    this.log()
  }
}

Help.topic = 'help'
Help.description = 'display help'
Help.variableArgs = true

module.exports = Help
<commit_msg>show help with no matchin topic<commit_after>'use strict'

const {Command} = require('heroku-command')
const plugins = require('../plugins')

function stderrwidth () {
  if (!process.stdout.isTTY) return 80
  return process.stdout.getWindowSize()[0]
}

class Help extends Command {
  async run () {
    plugins.load()
    let subject = this.argv.slice(1).find(arg => !['help', '-h', '--help'].includes(arg))
    if (!subject) return this.all()
    let topic = plugins.topics.find(t => t.name === subject.split(':')[0])
    if (!topic) return this.all()
    if (topic.help) return topic.help(subject)
    this.topic(topic, subject)
  }

  all () {
    const max = require('lodash.maxby')
    const S = require('string')

    this.log(`Usage: ${this.argv[0]} COMMAND [--app APP] [command-specific-options]

  Help topics, type ${this.color.cmd(this.argv[0] + ' help TOPIC')} for more details:
  `)
    let topics = plugins.topics
    topics = topics.filter(t => !t.hidden)
    let maxlength = max(topics, 'name.length').name.length
    for (let topic of topics) {
      this.log(`  ${this.argv[0]} ${S(topic.name).padRight(maxlength)}${topic.description ? ' # ' + topic.description : ''}`)
    }

    this.log()
  }

  topic (topic, subject) {
    const max = require('lodash.maxby')
    const S = require('string')
    const linewrap = require('../linewrap')

    function renderArg (arg) {
      if (arg.required !== false && arg.optional !== true) return ` <${arg.name}>`
      else return ` [${arg.name}]`
    }

    function renderFlags (flags) {
      const max = require('lodash.maxby')
      let lines = []
      for (let flag of flags) {
        let label = []
        if (flag.char) label.push(`-${flag.char}`)
        if (flag.name) label.push(` --${flag.name}`)
        let usage = flag.hasValue ? ` ${flag.name.toUpperCase()}` : ''
        let description = flag.description || ''
        if (flag.required || flag.optional === false) description = `(required) ${description}`
        lines.push([label.join(',').trim() + usage, description])
      }
      let maxLength = max(lines, '0')[0].length
      return lines.map(line => {
        let desc = line[1] || ''
        if (desc) {
          desc = linewrap(maxLength + 4, stderrwidth(), {
            skipScheme: 'ansi-color'
          })(desc).trim()
          desc = ' # ' + desc.split('\n').map(l => {
            if (l[0] !== ' ') return l
            return l.substr(0, maxLength + 1) + ' # ' + l.substr(maxLength + 4)
          }).join('\n')
        }
        return ` ${S(line[0]).padRight(maxLength)}${desc}`
      }).join('\n')
    }

    let command = subject.split(':').slice(1).join(':')
    command = plugins.commands.find(c => c.topic === topic.name && (c.command === command || (!c.command && !command)))

    if (command) {
      let cmd = command.command ? `${command.topic}:${command.command}` : command.topic
      // TODO: get usage if defined
      let usage = `${this.argv[0]} ${cmd}` + (command.args || []).map(renderArg).join('')
      this.log(`Usage: ${this.color.cmd(usage)}\n`)
      if (command.description) this.log(`${command.description.trim()}\n`)
      if (command.flags && command.flags.length) this.log(`${renderFlags(command.flags)}\n`)
      if (command.help) this.log(`${command.help.trim()}\n`)
    }

    if (subject.includes(':')) return

    let commands = plugins.commands.filter(c => c.topic === subject && c.command)
    if (commands.length === 0) return
    this.log(`${this.argv[0]} ${subject} commands: (${this.color.cmd(this.argv[0] + ' help ' + subject + ':COMMAND')} for details)
  `)
    let maxLength = max(commands, 'command.length').command.length + subject.length + 1
    for (let command of commands) {
      let cmd = command.command ? `${command.topic}:${command.command}` : command.topic
      this.log(`  ${S(cmd).padRight(maxLength)}${command.description ? ' # ' + command.description : ''}`)
    }
    this.log()
  }
}

Help.topic = 'help'
Help.description = 'display help'
Help.variableArgs = true

module.exports = Help
<|endoftext|>