<commit_before>var fs = require('fs');
var path = require('path');

var async = require('async');
var closure = require('closure-util');
var fse = require('fs-extra');
var nomnom = require('nomnom');
var temp = require('temp').track();

var log = closure.log;

/**
 * Assert that a provided config object is valid.
 * @param {Object} config Build configuration object.
 * @param {function(Error)} callback Called with an error if config is invalid.
 */
function assertValidConfig(config, callback) {
  process.nextTick(function() {
    if (config.namespace && typeof config.namespace !== 'string') {
      callback(new Error('Config "namespace" must be a string'));
      return;
    }
    if (config.compile && typeof config.compile !== 'object') {
      callback(new Error('Config "compile" must be an object'));
      return;
    }
    if (config.jvm && !Array.isArray(config.jvm)) {
      callback(new Error('Config "jvm" must be an array'));
      return;
    }
    if (config.src && !Array.isArray(config.src)) {
      callback(new Error('Config "src" must be an array'));
      return;
    }
    callback(null);
  });
}

/**
 * Read the build configuration file.
 * @param {string} configPath Path to config file.
 * @param {function(Error, Object)} callback Callback.
 */
function readConfig(configPath, callback) {
  fs.readFile(configPath, function(err, data) {
    if (err) {
      if (err.code === 'ENOENT') {
        err = new Error('Unable to find config file: ' + configPath);
      }
      callback(err);
      return;
    }
    var config;
    try {
      config = JSON.parse(String(data));
    } catch (err2) {
      callback(new Error('Trouble parsing config as JSON: ' + err2.message));
      return;
    }
    callback(null, config);
  });
}

/**
 * Get the list of sources sorted in dependency order.
 * @param {Array.<string>} src List of paths or patterns to source files.  By
 *     default, all .js files in the src directory are included.
 * @param {string} ignoreRequires Ignore requires pattern.  Will be used in
 *     a RegExp object.
 * @param {function(Error, Array.<string>)} callback Called with a list of paths
 *     or any error.
 */
function getDependencies(src, ignoreRequires, callback) {
  log.info('ol', 'Parsing dependencies');
  var options = {lib: src, ignoreRequires: ignoreRequires};
  closure.getDependencies(options, function(err, paths) {
    if (err) {
      callback(err);
      return;
    }
    callback(null, paths);
  });
}

/**
 * Concatenate all sources.
 * @param {Array.<string>} paths List of paths to source files.
 * @param {function(Error, string)} callback Called with the concatenated
 *     output or any error.
 */
function concatenate(paths, callback) {
  async.map(paths, fs.readFile, function(err, results) {
    if (err) {
      var msg = 'Trouble concatenating sources.  ' + err.message;
      callback(new Error(msg));
    } else {
      var preamble = 'var CLOSURE_NO_DEPS = true;\n';
      callback(null, preamble + results.join('\n'));
    }
  });
}

/**
 * Run the compiler.
 * @param {Object} config Build configuration object.
 * @param {Array.<string>} paths List of paths to source files.
 * @param {function(Error, string)} callback Called with the compiled output or
 *     any error.
 */
function build(config, paths, callback) {
  var options = config.compile;
  if (!options) {
    log.info('ol', 'No compile options found.  Concatenating ' +
        paths.length + ' sources');
    concatenate(paths, callback);
  } else {
    log.info('ol', 'Compiling ' + paths.length + ' sources');
    options.js = paths.concat(options.js || []);
    if (config.jvm) {
      closure.compile(options, config.jvm, callback);
    } else {
      closure.compile(options, callback);
    }
  }
}

/**
 * Generate a build of the library.
 * @param {Object} config Build configuration object.  Must have an "exports"
 *     array and a "compile" object with options for the compiler.
 * @param {function(Error, string)} callback Called with the compiled source
 *     or any error.
 */
function main(config, callback) {
  async.waterfall([
    assertValidConfig.bind(null, config),
    getDependencies.bind(null, config.src, config.ignoreRequires),
    build.bind(null, config)
  ], callback);
}

/**
 * If running this module directly, read the config file and call the main
 * function.
 */
if (require.main === module) {
  var options = nomnom.options({
    config: {
      position: 0,
      required: true,
      help: 'Path to JSON config file'
    },
    output: {
      position: 1,
      required: true,
      help: 'Output file path'
    },
    loglevel: {
      abbr: 'l',
      choices: ['silly', 'verbose', 'info', 'warn', 'error'],
      default: 'info',
      help: 'Log level',
      metavar: 'LEVEL'
    }
  }).parse();

  /**
   * Set the log level.
   * @type {string}
   */
  log.level = options.loglevel;

  // read the config, run the main function, and write the output file
  async.waterfall([
    readConfig.bind(null, options.config),
    main,
    fse.outputFile.bind(fse, options.output)
  ], function(err) {
    if (err) {
      log.error(err.message);
      process.exit(1);
    } else {
      process.exit(0);
    }
  });
}

/**
 * Export main function.
 */
module.exports = main;
<commit_msg>Update build.js<commit_after>/**
 * This task builds OpenLayers with the Closure Compiler.
 */
var fs = require('fs');
var path = require('path');

var async = require('async');
var closure = require('closure-util');
var fse = require('fs-extra');
var nomnom = require('nomnom');
var temp = require('temp').track();

var generateExports = require('./generate-exports');

var log = closure.log;
var root = path.join(__dirname, '..');

/**
 * Assert that a provided config object is valid.
 * @param {Object} config Build configuration object.
 * @param {function(Error)} callback Called with an error if config is invalid.
 */
function assertValidConfig(config, callback) {
  process.nextTick(function() {
    if (!Array.isArray(config.exports)) {
      callback(new Error('Config missing "exports" array'));
      return;
    }
    if (config.namespace && typeof config.namespace !== 'string') {
      callback(new Error('Config "namespace" must be a string'));
      return;
    }
    if (config.compile && typeof config.compile !== 'object') {
      callback(new Error('Config "compile" must be an object'));
      return;
    }
    if (config.jvm && !Array.isArray(config.jvm)) {
      callback(new Error('Config "jvm" must be an array'));
      return;
    }
    if (config.src && !Array.isArray(config.src)) {
      callback(new Error('Config "src" must be an array'));
      return;
    }
    callback(null);
  });
}

/**
 * Read the build configuration file.
 * @param {string} configPath Path to config file.
 * @param {function(Error, Object)} callback Callback.
 */
function readConfig(configPath, callback) {
  fs.readFile(configPath, function(err, data) {
    if (err) {
      if (err.code === 'ENOENT') {
        err = new Error('Unable to find config file: ' + configPath);
      }
      callback(err);
      return;
    }
    var config;
    try {
      config = JSON.parse(String(data));
    } catch (err2) {
      callback(new Error('Trouble parsing config as JSON: ' + err2.message));
      return;
    }
    callback(null, config);
  });
}

/**
 * Write the exports code to a temporary file.
 * @param {string} exports Exports code.
 * @param {function(Error, string)} callback Called with the path to the temp
 *     file (or any error).
 */
function writeExports(exports, callback) {
  temp.open({prefix: 'exports', suffix: '.js'}, function(err, info) {
    if (err) {
      callback(err);
      return;
    }
    log.verbose('build', 'Writing exports: ' + info.path);
    fs.writeFile(info.path, exports, function(err) {
      if (err) {
        callback(err);
        return;
      }
      fs.close(info.fd, function(err) {
        if (err) {
          callback(err);
          return;
        }
        callback(null, info.path);
      });
    });
  });
}

/**
 * Get the list of sources sorted in dependency order.
 * @param {Array.<string>} src List of paths or patterns to source files.  By
 *     default, all .js files in the src directory are included.
 * @param {string} exports Exports code (with goog.exportSymbol calls).
 * @param {function(Error, Array.<string>)} callback Called with a list of paths
 *     or any error.
 */
function getDependencies(src, exports, callback) {
  writeExports(exports, function(err, exportsPath) {
    if (err) {
      callback(err);
      return;
    }
    log.info('ol', 'Parsing dependencies');
    src = src || ['src/**/*.js'];
    closure.getDependencies({lib: src}, function(err, paths) {
      if (err) {
        callback(err);
        return;
      }
      paths.push(exportsPath);
      callback(null, paths);
    });
  });
}

/**
 * Concatenate all sources.
 * @param {Array.<string>} paths List of paths to source files.
 * @param {function(Error, string)} callback Called with the concatenated
 *     output or any error.
 */
function concatenate(paths, callback) {
  async.map(paths, fs.readFile, function(err, results) {
    if (err) {
      var msg = 'Trouble concatenating sources.  ' + err.message;
      callback(new Error(msg));
    } else {
      var preamble = 'var CLOSURE_NO_DEPS = true;\n';
      callback(null, preamble + results.join('\n'));
    }
  });
}

/**
 * Run the compiler.
 * @param {Object} config Build configuration object.
 * @param {Array.<string>} paths List of paths to source files.
 * @param {function(Error, string)} callback Called with the compiled output or
 *     any error.
 */
function build(config, paths, callback) {
  var options = config.compile;
  if (!options) {
    log.info('ol', 'No compile options found.  Concatenating ' +
        paths.length + ' sources');
    concatenate(paths, callback);
  } else {
    log.info('ol', 'Compiling ' + paths.length + ' sources');
    options.js = paths.concat(options.js || []);
    if (config.jvm) {
      closure.compile(options, config.jvm, callback);
    } else {
      closure.compile(options, callback);
    }
  }
}

/**
 * Generate a build of the library.
 * @param {Object} config Build configuration object.  Must have an "exports"
 *     array and a "compile" object with options for the compiler.
 * @param {function(Error, string)} callback Called with the compiled source
 *     or any error.
 */
function main(config, callback) {
  async.waterfall([
    assertValidConfig.bind(null, config),
    generateExports.bind(null, config),
    getDependencies.bind(null, config.src),
    build.bind(null, config)
  ], callback);
}

/**
 * If running this module directly, read the config file and call the main
 * function.
 */
if (require.main === module) {
  var options = nomnom.options({
    config: {
      position: 0,
      required: true,
      help: 'Path to JSON config file'
    },
    output: {
      position: 1,
      required: true,
      help: 'Output file path'
    },
    loglevel: {
      abbr: 'l',
      choices: ['silly', 'verbose', 'info', 'warn', 'error'],
      default: 'info',
      help: 'Log level',
      metavar: 'LEVEL'
    }
  }).parse();

  /**
   * Set the log level.
   * @type {string}
   */
  log.level = options.loglevel;

  // read the config, run the main function, and write the output file
  async.waterfall([
    readConfig.bind(null, options.config),
    main,
    fse.outputFile.bind(fse, options.output)
  ], function(err) {
    if (err) {
      log.error(err.message);
      process.exit(1);
    } else {
      process.exit(0);
    }
  });
}

/**
 * Export main function.
 */
module.exports = main;
<|endoftext|>


<commit_before>(function() {
    /* Tools to be called from gulp when building a standard app */

    "use strict";
    var gulp = require('gulp');
    var fs = require("fs");
    var path = require("path");

    var browserify = require("browserify");
    var es6ify = require("es6ify");
    var stringify = require('stringify');

    var remapify = require("remapify");
    var filterTransform = require("filter-transform");
    var uglify = require('gulp-uglify');
    var buffer = require('vinyl-buffer');
    var source = require('vinyl-source-stream');
    var extend = require("extend");

    var stripify = require("stripify");

    var chokidar = require('chokidar');

    var async = require("async");

    var tools = module.exports;
    var cwd = process.cwd();

    var sassPath = process.platform === "win32" ? "sass.bat" : "sass";

    var options = {
        globals: {
            angular: "angular",
            jquery: "$"
        },
        serverapp: {

        },
        sourceFolder: "./src",
        libFolder: "./lib",
        cssEntryPoint: "./css/index.scss",
        moduleMappings: {},
        customBrowserifyTransforms: [],
        additionalWatchPaths: [],
        buildfolder: "./build",
        cssVariations: {
            "ie": '$browserType: "ie";'
        },
        imageFolders: ["./src/images"]
    };

    tools.init = function(opt) {
        extend(options, opt);
        options.moduleMappings.chondric = path.resolve(__dirname, "../es6");

    };

    tools.test = function() {
        console.log("Test function");
    };

    tools.buildVariation = function(variation, env, watch, destFolder, onBuildComplete) {
        console.log(options);
        var debugMode = env != "prod"; //true;
        if (options.debug !== undefined) debugMode = options.debug;
        if (options[env] && options[env].debug !== undefined) debugMode = options[env].debug;
        console.log("Debug: " + debugMode);
        console.log("building " + variation + " for " + env);
        var buildfolder = path.resolve(cwd, options.buildfolder);
        if (!fs.existsSync(buildfolder)) fs.mkdirSync(buildfolder);
        var tempFolder = path.resolve(buildfolder, "temp");
        if (!fs.existsSync(tempFolder)) fs.mkdirSync(tempFolder);
        var envFolder = path.resolve(buildfolder, env);
        if (!fs.existsSync(envFolder)) fs.mkdirSync(envFolder);
        var varFolder = path.resolve(buildfolder, env, variation);
        if (!fs.existsSync(varFolder)) fs.mkdirSync(varFolder);

        if (destFolder) varFolder = path.resolve(cwd, destFolder);

        var hostSettings = {};
        extend(hostSettings, options.hostSettings);
        extend(hostSettings, options[env]);
        fs.writeFileSync(path.resolve(tempFolder, "hostsettings.js"), "module.exports=" + JSON.stringify(hostSettings), "utf-8");

        var moduleMappings = [{
            src: 'hostsettings.js',
            expose: 'build',
            cwd: tempFolder
        }];
        for (var k in options.moduleMappings) {
            moduleMappings.push({
                src: './**/*.html',
                expose: k,
                cwd: options.moduleMappings[k],
            });
            moduleMappings.push({
                src: './**/*.js',
                expose: k,
                cwd: options.moduleMappings[k],
            });
        }

        console.log(moduleMappings);

        var sourceFolder = path.resolve(cwd, options.sourceFolder);
        var libFolder = path.resolve(cwd, options.libFolder);

        var filteredEs6ify = filterTransform(
            function(file) {
                // browserify needs transforms to be global, and compiling es5 modules
                // breaks stuff, so only compile the bits we know are es6
                if (file.indexOf("node_modules") >= 0) {
                    // files under node_modules are only compiled as es6 if they are included in
                    // moduleMappings - i.e. if chondric was loaded with npm install rather than npm link
                    for (var i = 0; i < moduleMappings.length; i++) {
                        var pn = moduleMappings[i].cwd;
                        if (file.indexOf(pn) === 0 && file.lastIndexOf("node_modules") < pn.length) {
                            return path.extname(file) === '.js';
                        }
                    }
                    return false;
                }
                return path.extname(file) === '.js';

            },
            es6ify
        );

        function buildClientJs(onComplete) {
            var jsBuildError = null;
            var globalShim = require('browserify-global-shim').configure(options.globals);
            var b = browserify({
                    debug: debugMode,
                    extensions: [".txt", ".html"],
                    //paths: [path.resolve(__dirname,"../es6")]
                })
                .add(es6ify.runtime, {
                    entry: true
                })
                .plugin(remapify, moduleMappings)
                .transform(stringify({
                    extensions: ['.txt', '.html'],
                    minify: true
                }), {
                    global: true
                });

            for (var i = 0; i < options.customBrowserifyTransforms.length; i++) {
                b = b.transform(options.customBrowserifyTransforms[i]());
            }

            b = b.transform(filteredEs6ify, {
                global: true
            });

            b = b.transform(globalShim, {
                global: true
            });

            if (!debugMode) {
                // remove console.log calls
                b = b.transform({
                    global: true
                }, stripify);
            }
            if (debugMode && options.browserTests) {
                // inject tests
                b.require(require.resolve(path.resolve(cwd, options.browserTests)), {
                    expose: "test",
                    entry: true
                });
            }
            b.require(require.resolve(path.resolve(sourceFolder, variation + ".js")), {
                entry: true
            });

            function reportError(title, msg, source, detail) {
                var errorReporter = fs.readFileSync(path.resolve(__dirname, "./reporterror.js"), "utf-8");

                errorReporter = errorReporter.replace("\"[TITLE]\"", JSON.stringify(title || "Error"));
                errorReporter = errorReporter.replace("\"[MESSAGE]\"", JSON.stringify(msg || "Something went wrong"));
                errorReporter = errorReporter.replace("\"[SOURCE]\"", JSON.stringify(source || ""));
                errorReporter = errorReporter.replace("\"[DETAIL]\"", JSON.stringify(detail || ""));
                return errorReporter;
            }

            b = b.bundle()
                .once('error', function(err) {
                    console.log("Browserify error");
                    console.log(err.message);
                    var msg = err.message;
                    var source = "";
                    var detail = "";

                    var m = /(.*):(\d+):(\d+): (.*)/.exec(msg);
                    if (m && m.length >= 5) {
                        msg = m[4];
                        var fn = m[1];
                        var errorLine = parseInt(m[2]);
                        source = m[1] + ":" + m[2] + ":" + m[3];
                        detail = "";

                        var sc = fs.readFileSync(fn, "utf-8").split("\n");
                        for (var i = errorLine - 4; i < errorLine + 3; i++) {
                            var l = sc[i];
                            if (l === undefined) continue;
                            detail += l + "\n";
                        }

                    }

                    jsBuildError = {
                        message: msg,
                        source: source,
                        detail: detail
                    };
                    var errorReporter = reportError("BuildError", msg, source, detail);
                    fs.writeFileSync(path.resolve(varFolder, "app.js"), errorReporter);
                    if (onComplete) onComplete(jsBuildError);
                    this.emit("end");
                });
            b.on('error', function(err) {
                // Ignore any errors after the first so onComplete is only called once
            });
            b.on("end", function() {
                if (!jsBuildError) {
                    console.log("Done browserify");
                    if (onComplete) onComplete();
                }
            });

            var appFile = path.resolve(varFolder, "app.js");
            var appFileTemp = path.resolve(varFolder, "app (building).js");
            var appFileEs3 = path.resolve(varFolder, "app-es3.js");

            // For use with <script>$.getScript(window.atob ? "app.js" : "app-es3.js");</script>
            fs.writeFileSync(appFileEs3, reportError("App error", "This app is designed for use in modern browsers."));

            if (debugMode) {
                fs.writeFileSync(appFile, reportError("Build Incomplete", "Browserify build in progress - try again in a few seconds."));

                b.on("end", function() {
                    if (!jsBuildError && fs.existsSync(appFileTemp)) {
                        if (fs.existsSync(appFile)) fs.unlinkSync(appFile);
                        fs.renameSync(appFileTemp, appFile);
                    }
                });

                b = b.pipe(fs.createWriteStream(appFileTemp));
            } else {
                b = b
                    .pipe(source('app.js')) // gives streaming vinyl file object
                    .pipe(buffer()) // <----- convert from streaming to buffered vinyl file object
                    .pipe(uglify({
                        mangle: true,
                        compress: false
                    }))
                    .pipe(gulp.dest(varFolder));
            }

        }

        function copyHtml() {
            gulp.src(sourceFolder + '/*.html')
                .pipe(gulp.dest(varFolder));
        }

        function copyLib() {
            gulp.src(libFolder + '/*.js')
                .pipe(gulp.dest(varFolder + "/lib"));
        }

        function copyImages() {
            var flatten = require('gulp-flatten');
            console.log("Copying images");
            var globs = [];
            for (var i = 0; i < options.imageFolders.length; i++) {
                var imgf = options.imageFolders[i];
                globs.push(imgf + "/**");
            }

            console.log(globs);
            gulp.src(globs)
                .pipe(flatten())
                .pipe(gulp.dest(varFolder + "/images"));

        }

        //        function copyImages() {
        //            gulp.src(__dirname + '/apphtml/images/**/*')
        //                .pipe(gulp.dest(options.buildfolder + "/" + env + "/" + variation + "/images"))
        //                .on("end", function() {
        //                    gulp.src(process.cwd() + "/images/**/*")
        //                        .pipe(gulp.dest(options.buildfolder + "/" + env + "/" + variation + "/images"));
        //                });
        //        }

        function buildCssFile(inputFile, outputFile, fileBuilt) {
            var params = (debugMode ? ["--style", "nested"] : ["--style", "compressed"])
                .concat(["-I", ".", inputFile, varFolder + "/" + outputFile]);
            // using spawn because libsass sourcemaps are buggy

            var spawn = require("child_process").spawn;
            var p = spawn(sassPath, params, {
                cwd: cwd
            });
            p.stdout.on('data', function(data) {
                console.log("" + data);
            });

            p.stderr.on('data', function(data) {
                console.log("" + data);
            });
            p.on("close", function(code) {
                console.log("Done sass build of " + inputFile + " with code " + code);
                if (fileBuilt) fileBuilt(code === 0 ? null : ("SASS Error " + code));
            });

        }

        function buildCss(onCssBuilt) {
            var cssEntryPoint = path.resolve(cwd, options.cssEntryPoint);

            buildCssFile(cssEntryPoint, "app.css", function(err) {
                if (err) return onCssBuilt && onCssBuilt();

                var variations = [];
                for (var k in options.cssVariations) {
                    variations.push({
                        key: k,
                        settings: options.cssVariations[k]
                    });
                }

                async.eachSeries(variations, function(v, next) {
                    var iesrc = v.settings + '\n@import "' + (path.relative(tempFolder, cssEntryPoint).replace(/\\/ig, "/")) + '";';
                    var ieCssFile = path.resolve(tempFolder, "index-" + v.key + ".scss");
                    fs.writeFileSync(ieCssFile, iesrc);
                    buildCssFile(ieCssFile, "app-" + v.key + ".css", next);
                }, onCssBuilt);

            });

        }

        buildClientJs(function(err) {
            if (err) return onBuildComplete && onBuildComplete(err);
            buildCss(function(err) {
                if (err) return onBuildComplete && onBuildComplete(err);
                copyHtml();
                copyImages();
                copyLib();
                if (options.afterBrowserify) options.afterBrowserify(varFolder, env, variation);
                console.log("Build completed successfully");
                return onBuildComplete && onBuildComplete(err);
            });
        });

        if (watch) {

            var paths = [
                    path.resolve(__dirname, "../es6"),
                    sourceFolder
                ]
                .concat(options.additionalWatchPaths);

            // watch the css folder if it isn't already watched as part of the source folder
            var cssFolder = path.dirname(path.resolve(cwd, options.cssEntryPoint));
            if (cssFolder.indexOf(sourceFolder) !== 0) paths.push(cssFolder);

            // watch image folders
            for (var i = 0; i < options.imageFolders.length; i++) {
                var imgf = options.imageFolders[i];
                if (imgf.indexOf(sourceFolder) !== 0) paths.push(imgf);
            }

            // watch tests
            if (options.browserTests) {
                paths.push(path.dirname(path.resolve(options.browserTests)));
            }

            var watcher = chokidar.watch(paths, {
                ignored: /[\/\\]\./,
                persistent: true,
                ignoreInitial: true
            });

            watcher.on("all", function(type, file) {
                console.log(type + " event for " + file);
                var ext = path.extname(file);
                if (ext == ".scss") {
                    console.log("CSS needs rebuild");
                    buildCss();
                } else if (ext == ".js" || ext == ".html") {
                    console.log("Browserify package needs rebuild");
                    buildClientJs(function(err) {
                        if (!err && options.afterBrowserify) options.afterBrowserify(varFolder, env, variation);
                    });
                } else if (ext == ".jpg" || ext == ".jpeg" || ext == ".png" || ext == ".gif") {
                    console.log("Updating images");
                    copyImages();

                }
                // if the changed file is .js or .html, need to run browserify
                // copy html only copies a single file, so maybe just include that in the browserify process

                // src/images just needs to be copied if anything changes, and it can't contain anything used by browserify

            });

        }
    };

    tools.buildTask = function() {
        var args = process.argv.slice(3);
        if (args.length != 2 || args[0].indexOf("--") !== 0 || args[1].indexOf("--") !== 0) {
            console.log("Invalid arguments for build task");
            console.log("Usage: gulp build --web --dev");
            return;
        }
        var variation = args[0].substr(2);
        var env = args[1].substr(2);

        tools.buildVariation(variation, env);
    };

})();
<commit_msg>filter for global shim<commit_after>(function() {
    /* Tools to be called from gulp when building a standard app */

    "use strict";
    var gulp = require('gulp');
    var fs = require("fs");
    var path = require("path");

    var browserify = require("browserify");
    var es6ify = require("es6ify");
    var stringify = require('stringify');

    var remapify = require("remapify");
    var filterTransform = require("filter-transform");
    var uglify = require('gulp-uglify');
    var buffer = require('vinyl-buffer');
    var source = require('vinyl-source-stream');
    var extend = require("extend");

    var stripify = require("stripify");

    var chokidar = require('chokidar');

    var async = require("async");

    var tools = module.exports;
    var cwd = process.cwd();

    var sassPath = process.platform === "win32" ? "sass.bat" : "sass";

    var options = {
        globals: {
            angular: "angular",
            jquery: "$"
        },
        serverapp: {

        },
        sourceFolder: "./src",
        libFolder: "./lib",
        cssEntryPoint: "./css/index.scss",
        moduleMappings: {},
        customBrowserifyTransforms: [],
        additionalWatchPaths: [],
        buildfolder: "./build",
        cssVariations: {
            "ie": '$browserType: "ie";'
        },
        imageFolders: ["./src/images"]
    };

    tools.init = function(opt) {
        extend(options, opt);
        options.moduleMappings.chondric = path.resolve(__dirname, "../es6");

    };

    tools.test = function() {
        console.log("Test function");
    };

    tools.buildVariation = function(variation, env, watch, destFolder, onBuildComplete) {
        console.log(options);
        var debugMode = env != "prod"; //true;
        if (options.debug !== undefined) debugMode = options.debug;
        if (options[env] && options[env].debug !== undefined) debugMode = options[env].debug;
        console.log("Debug: " + debugMode);
        console.log("building " + variation + " for " + env);
        var buildfolder = path.resolve(cwd, options.buildfolder);
        if (!fs.existsSync(buildfolder)) fs.mkdirSync(buildfolder);
        var tempFolder = path.resolve(buildfolder, "temp");
        if (!fs.existsSync(tempFolder)) fs.mkdirSync(tempFolder);
        var envFolder = path.resolve(buildfolder, env);
        if (!fs.existsSync(envFolder)) fs.mkdirSync(envFolder);
        var varFolder = path.resolve(buildfolder, env, variation);
        if (!fs.existsSync(varFolder)) fs.mkdirSync(varFolder);

        if (destFolder) varFolder = path.resolve(cwd, destFolder);

        var hostSettings = {};
        extend(hostSettings, options.hostSettings);
        extend(hostSettings, options[env]);
        fs.writeFileSync(path.resolve(tempFolder, "hostsettings.js"), "module.exports=" + JSON.stringify(hostSettings), "utf-8");

        var moduleMappings = [{
            src: 'hostsettings.js',
            expose: 'build',
            cwd: tempFolder
        }];
        for (var k in options.moduleMappings) {
            moduleMappings.push({
                src: './**/*.html',
                expose: k,
                cwd: options.moduleMappings[k],
            });
            moduleMappings.push({
                src: './**/*.js',
                expose: k,
                cwd: options.moduleMappings[k],
            });
        }

        console.log(moduleMappings);

        var sourceFolder = path.resolve(cwd, options.sourceFolder);
        var libFolder = path.resolve(cwd, options.libFolder);

        var filteredEs6ify = filterTransform(
            function(file) {
                // browserify needs transforms to be global, and compiling es5 modules
                // breaks stuff, so only compile the bits we know are es6
                if (file.indexOf("node_modules") >= 0) {
                    // files under node_modules are only compiled as es6 if they are included in
                    // moduleMappings - i.e. if chondric was loaded with npm install rather than npm link
                    for (var i = 0; i < moduleMappings.length; i++) {
                        var pn = moduleMappings[i].cwd;
                        if (file.indexOf(pn) === 0 && file.lastIndexOf("node_modules") < pn.length) {
                            return path.extname(file) === '.js';
                        }
                    }
                    return false;
                }
                return path.extname(file) === '.js';

            },
            es6ify
        );

        var globalShim = filterTransform(
            function(file) {
                return path.extname(file) === ".js";
            },
            require('browserify-global-shim').configure(options.globals)
        );

        function buildClientJs(onComplete) {
            var jsBuildError = null;

            var b = browserify({
                    debug: debugMode,
                    extensions: [".txt", ".html"],
                    //paths: [path.resolve(__dirname,"../es6")]
                })
                .add(es6ify.runtime, {
                    entry: true
                })
                .plugin(remapify, moduleMappings)
                .transform(stringify({
                    extensions: ['.txt', '.html'],
                    minify: true
                }), {
                    global: true
                });

            for (var i = 0; i < options.customBrowserifyTransforms.length; i++) {
                b = b.transform(options.customBrowserifyTransforms[i]());
            }

            b = b.transform(filteredEs6ify, {
                global: true
            });

            b = b.transform(globalShim, {
                global: true
            });

            if (!debugMode) {
                // remove console.log calls
                b = b.transform({
                    global: true
                }, stripify);
            }
            if (debugMode && options.browserTests) {
                // inject tests
                b.require(require.resolve(path.resolve(cwd, options.browserTests)), {
                    expose: "test",
                    entry: true
                });
            }
            b.require(require.resolve(path.resolve(sourceFolder, variation + ".js")), {
                entry: true
            });

            function reportError(title, msg, source, detail) {
                var errorReporter = fs.readFileSync(path.resolve(__dirname, "./reporterror.js"), "utf-8");

                errorReporter = errorReporter.replace("\"[TITLE]\"", JSON.stringify(title || "Error"));
                errorReporter = errorReporter.replace("\"[MESSAGE]\"", JSON.stringify(msg || "Something went wrong"));
                errorReporter = errorReporter.replace("\"[SOURCE]\"", JSON.stringify(source || ""));
                errorReporter = errorReporter.replace("\"[DETAIL]\"", JSON.stringify(detail || ""));
                return errorReporter;
            }

            b = b.bundle()
                .once('error', function(err) {
                    console.log("Browserify error");
                    console.log(err.message);
                    var msg = err.message;
                    var source = "";
                    var detail = "";

                    var m = /(.*):(\d+):(\d+): (.*)/.exec(msg);
                    if (m && m.length >= 5) {
                        msg = m[4];
                        var fn = m[1];
                        var errorLine = parseInt(m[2]);
                        source = m[1] + ":" + m[2] + ":" + m[3];
                        detail = "";

                        var sc = fs.readFileSync(fn, "utf-8").split("\n");
                        for (var i = errorLine - 4; i < errorLine + 3; i++) {
                            var l = sc[i];
                            if (l === undefined) continue;
                            detail += l + "\n";
                        }

                    }

                    jsBuildError = {
                        message: msg,
                        source: source,
                        detail: detail
                    };
                    var errorReporter = reportError("BuildError", msg, source, detail);
                    fs.writeFileSync(path.resolve(varFolder, "app.js"), errorReporter);
                    if (onComplete) onComplete(jsBuildError);
                    this.emit("end");
                });
            b.on('error', function(err) {
                // Ignore any errors after the first so onComplete is only called once
            });
            b.on("end", function() {
                if (!jsBuildError) {
                    console.log("Done browserify");
                    if (onComplete) onComplete();
                }
            });

            var appFile = path.resolve(varFolder, "app.js");
            var appFileTemp = path.resolve(varFolder, "app (building).js");
            var appFileEs3 = path.resolve(varFolder, "app-es3.js");

            // For use with <script>$.getScript(window.atob ? "app.js" : "app-es3.js");</script>
            fs.writeFileSync(appFileEs3, reportError("App error", "This app is designed for use in modern browsers."));

            if (debugMode) {
                fs.writeFileSync(appFile, reportError("Build Incomplete", "Browserify build in progress - try again in a few seconds."));

                b.on("end", function() {
                    if (!jsBuildError && fs.existsSync(appFileTemp)) {
                        if (fs.existsSync(appFile)) fs.unlinkSync(appFile);
                        fs.renameSync(appFileTemp, appFile);
                    }
                });

                b = b.pipe(fs.createWriteStream(appFileTemp));
            } else {
                b = b
                    .pipe(source('app.js')) // gives streaming vinyl file object
                    .pipe(buffer()) // <----- convert from streaming to buffered vinyl file object
                    .pipe(uglify({
                        mangle: true,
                        compress: false
                    }))
                    .pipe(gulp.dest(varFolder));
            }

        }

        function copyHtml() {
            gulp.src(sourceFolder + '/*.html')
                .pipe(gulp.dest(varFolder));
        }

        function copyLib() {
            gulp.src(libFolder + '/*.js')
                .pipe(gulp.dest(varFolder + "/lib"));
        }

        function copyImages() {
            var flatten = require('gulp-flatten');
            console.log("Copying images");
            var globs = [];
            for (var i = 0; i < options.imageFolders.length; i++) {
                var imgf = options.imageFolders[i];
                globs.push(imgf + "/**");
            }

            console.log(globs);
            gulp.src(globs)
                .pipe(flatten())
                .pipe(gulp.dest(varFolder + "/images"));

        }

        //        function copyImages() {
        //            gulp.src(__dirname + '/apphtml/images/**/*')
        //                .pipe(gulp.dest(options.buildfolder + "/" + env + "/" + variation + "/images"))
        //                .on("end", function() {
        //                    gulp.src(process.cwd() + "/images/**/*")
        //                        .pipe(gulp.dest(options.buildfolder + "/" + env + "/" + variation + "/images"));
        //                });
        //        }

        function buildCssFile(inputFile, outputFile, fileBuilt) {
            var params = (debugMode ? ["--style", "nested"] : ["--style", "compressed"])
                .concat(["-I", ".", inputFile, varFolder + "/" + outputFile]);
            // using spawn because libsass sourcemaps are buggy

            var spawn = require("child_process").spawn;
            var p = spawn(sassPath, params, {
                cwd: cwd
            });
            p.stdout.on('data', function(data) {
                console.log("" + data);
            });

            p.stderr.on('data', function(data) {
                console.log("" + data);
            });
            p.on("close", function(code) {
                console.log("Done sass build of " + inputFile + " with code " + code);
                if (fileBuilt) fileBuilt(code === 0 ? null : ("SASS Error " + code));
            });

        }

        function buildCss(onCssBuilt) {
            var cssEntryPoint = path.resolve(cwd, options.cssEntryPoint);

            buildCssFile(cssEntryPoint, "app.css", function(err) {
                if (err) return onCssBuilt && onCssBuilt();

                var variations = [];
                for (var k in options.cssVariations) {
                    variations.push({
                        key: k,
                        settings: options.cssVariations[k]
                    });
                }

                async.eachSeries(variations, function(v, next) {
                    var iesrc = v.settings + '\n@import "' + (path.relative(tempFolder, cssEntryPoint).replace(/\\/ig, "/")) + '";';
                    var ieCssFile = path.resolve(tempFolder, "index-" + v.key + ".scss");
                    fs.writeFileSync(ieCssFile, iesrc);
                    buildCssFile(ieCssFile, "app-" + v.key + ".css", next);
                }, onCssBuilt);

            });

        }

        buildClientJs(function(err) {
            if (err) return onBuildComplete && onBuildComplete(err);
            buildCss(function(err) {
                if (err) return onBuildComplete && onBuildComplete(err);
                copyHtml();
                copyImages();
                copyLib();
                if (options.afterBrowserify) options.afterBrowserify(varFolder, env, variation);
                console.log("Build completed successfully");
                return onBuildComplete && onBuildComplete(err);
            });
        });

        if (watch) {

            var paths = [
                    path.resolve(__dirname, "../es6"),
                    sourceFolder
                ]
                .concat(options.additionalWatchPaths);

            // watch the css folder if it isn't already watched as part of the source folder
            var cssFolder = path.dirname(path.resolve(cwd, options.cssEntryPoint));
            if (cssFolder.indexOf(sourceFolder) !== 0) paths.push(cssFolder);

            // watch image folders
            for (var i = 0; i < options.imageFolders.length; i++) {
                var imgf = options.imageFolders[i];
                if (imgf.indexOf(sourceFolder) !== 0) paths.push(imgf);
            }

            // watch tests
            if (options.browserTests) {
                paths.push(path.dirname(path.resolve(options.browserTests)));
            }

            var watcher = chokidar.watch(paths, {
                ignored: /[\/\\]\./,
                persistent: true,
                ignoreInitial: true
            });

            watcher.on("all", function(type, file) {
                console.log(type + " event for " + file);
                var ext = path.extname(file);
                if (ext == ".scss") {
                    console.log("CSS needs rebuild");
                    buildCss();
                } else if (ext == ".js" || ext == ".html") {
                    console.log("Browserify package needs rebuild");
                    buildClientJs(function(err) {
                        if (!err && options.afterBrowserify) options.afterBrowserify(varFolder, env, variation);
                    });
                } else if (ext == ".jpg" || ext == ".jpeg" || ext == ".png" || ext == ".gif") {
                    console.log("Updating images");
                    copyImages();

                }
                // if the changed file is .js or .html, need to run browserify
                // copy html only copies a single file, so maybe just include that in the browserify process

                // src/images just needs to be copied if anything changes, and it can't contain anything used by browserify

            });

        }
    };

    tools.buildTask = function() {
        var args = process.argv.slice(3);
        if (args.length != 2 || args[0].indexOf("--") !== 0 || args[1].indexOf("--") !== 0) {
            console.log("Invalid arguments for build task");
            console.log("Usage: gulp build --web --dev");
            return;
        }
        var variation = args[0].substr(2);
        var env = args[1].substr(2);

        tools.buildVariation(variation, env);
    };

})();
<|endoftext|>


<commit_before>/*
	参考文档：http://rongcloud.cn/docs/server.html#group_user_gag
*/
const config = require('./api.json');
const verify = require('../verify.json');

const request = require('../../request').request;
const utils = require('../../utils');

const _ = utils.underscore;
const logger = utils.logger;
const getError = utils.getError;

const check = utils.check;

let add = (group) => {
  let conf = config.add;

  let whVerify = _.extend(_.pick(verify.group, 'id', 'members'));
  let error = check({
    api: conf,
    model: 'group',
    data: group,
    verify: whVerify
  });
  if (error) {
    return Promise.reject(error);
  }

  let members = group.members;
  group.members = _.map(members, (member) => {
    return member.id;
  });

  group = utils.rename(group, {
    id: 'groupId',
    members: 'userId'
  });

  return request({
    url: conf.url,
    data: group
  }).then(result => {
    return result.text;
  }).catch(error => {
    error = getError({
      code: error,
      errors: conf.response.fail
    });
    logger.log({
      content: error,
      level: 'error',
      pos: 'Group.MuteWhiteList.add'
    });
    return error;
  });
};

let remove = (group) => {
  let conf = config.remove;

  let error = check({
    api: conf,
    model: 'group',
    data: group,
    verify: _.pick(verify.group, 'id', 'members')
  });
  if (error) {
    return Promise.reject(error);
  }

  let members = group.members;
  group.members = _.map(members, (member) => {
    return member.id;
  });

  group = utils.rename(group, {
    id: 'groupId',
    members: 'userId'
  });

  return request({
    url: conf.url,
    data: group
  }).then(result => {
    return result.text;
  }).catch(error => {
    error = getError({
      code: error,
      errors: conf.response.fail
    });
    logger.log({
      content: error,
      level: 'error',
      pos: 'Group.MuteWhiteList.remove'
    });
    return error;
  });
};

let getList = (group) => {
  let conf = config.getList;

  let error = check({
    api: conf,
    model: 'group',
    data: group,
    verify: _.pick(verify.group, 'id')
  });
  if (error) {
    return Promise.reject(error);
  }

  group = utils.rename(group, {
    id: 'groupId'
  });

  return request({
    url: conf.url,
    data: group
  }).then(result => {
    result = utils.rename(result.text, {
      users: 'userIds'
    });
    let members = result.members || [];
    result = _.omit(result, 'userIds')
    return _.extend(result, {
      id: group.groupId,
      members: _.map(members, (memberId) => {
        return {
          id: memberId
        }
      })
    });
  }).catch(error => {
    error = getError({
      code: error,
      errors: conf.response.fail
    });
    logger.log({
      content: error,
      level: 'error',
      pos: 'Group.MuteWhiteList.getList'
    });
    return error;
  });
};

module.exports = {
  add: add,
  remove: remove,
  getList: getList
};<commit_msg>fix: getList 返回参数<commit_after>/*
	参考文档：http://rongcloud.cn/docs/server.html#group_user_gag
*/
const config = require('./api.json');
const verify = require('../verify.json');

const request = require('../../request').request;
const utils = require('../../utils');

const _ = utils.underscore;
const logger = utils.logger;
const getError = utils.getError;

const check = utils.check;

let add = (group) => {
  let conf = config.add;

  let whVerify = _.extend(_.pick(verify.group, 'id', 'members'));
  let error = check({
    api: conf,
    model: 'group',
    data: group,
    verify: whVerify
  });
  if (error) {
    return Promise.reject(error);
  }

  let members = group.members;
  group.members = _.map(members, (member) => {
    return member.id;
  });

  group = utils.rename(group, {
    id: 'groupId',
    members: 'userId'
  });

  return request({
    url: conf.url,
    data: group
  }).then(result => {
    return result.text;
  }).catch(error => {
    error = getError({
      code: error,
      errors: conf.response.fail
    });
    logger.log({
      content: error,
      level: 'error',
      pos: 'Group.MuteWhiteList.add'
    });
    return error;
  });
};

let remove = (group) => {
  let conf = config.remove;

  let error = check({
    api: conf,
    model: 'group',
    data: group,
    verify: _.pick(verify.group, 'id', 'members')
  });
  if (error) {
    return Promise.reject(error);
  }

  let members = group.members;
  group.members = _.map(members, (member) => {
    return member.id;
  });

  group = utils.rename(group, {
    id: 'groupId',
    members: 'userId'
  });

  return request({
    url: conf.url,
    data: group
  }).then(result => {
    return result.text;
  }).catch(error => {
    error = getError({
      code: error,
      errors: conf.response.fail
    });
    logger.log({
      content: error,
      level: 'error',
      pos: 'Group.MuteWhiteList.remove'
    });
    return error;
  });
};

let getList = (group) => {
  let conf = config.getList;

  let error = check({
    api: conf,
    model: 'group',
    data: group,
    verify: _.pick(verify.group, 'id')
  });
  if (error) {
    return Promise.reject(error);
  }

  group = utils.rename(group, {
    id: 'groupId'
  });

  return request({
    url: conf.url,
    data: group
  }).then(result => {
    result = utils.rename(result.text, {
      userIds: 'members'
    });
    return {
      id: group.groupId,
      members: _.map(result.members, (memberId) => {
        return {
          id: memberId
        }
      })
    };
  }).catch(error => {
    error = getError({
      code: error,
      errors: conf.response.fail
    });
    logger.log({
      content: error,
      level: 'error',
      pos: 'Group.MuteWhiteList.getList'
    });
    return error;
  });
};

module.exports = {
  add: add,
  remove: remove,
  getList: getList
};<|endoftext|>


<commit_before>// Load stores, their schemas & init N.settings
//

"use strict";

// stdlib
var path = require('path');

// 3rd-party
var _       = require('lodash');
var fstools = require('fs-tools');

// internal
var apify       = require('../../../system/init/utils/apify');
var Settings    = require('../../../settings/settings');

var SETTING_SCHEMA_DEFAUTLS = {
  extends:      false
, type:         null
, 'default':    null
, category_key: null
, group_key:    null
, priority:     10
, values:       null
, before_show:  null
, before_save:  null
, validators:   null
};

var SETTING_GROUP_DEFAUTLS = {
  parent:   null
, priority: 10
};

////////////////////////////////////////////////////////////////////////////////

module.exports = function (N) {
  // Generate sub-event
  N.wire.after("init:models", { priority: 50 }, function emit_init_settings(N, callback) {
    N.wire.emit("init:__settings", N, callback);
  });

  N.wire.on("init:__settings", function init_settings(N) {
    var settings = {}; // cache: setting name => array of schemas (from stores)

    //
    // Normalize setting schemas.
    //

    if (!N.config.setting_schemas) {
      N.config.setting_schemas = {};
    }

    // Collect all available setting schemas form different stores.
    _.forEach(N.config.setting_schemas, function (store) {
      _.forEach(store, function (config, name) {
        if (!settings.hasOwnProperty(name)) {
          settings[name] = [];
        }

        settings[name].push(config);
      });
    });

    // Resolve `extends` flags and fill-in default schema values.
    _.forEach(settings, function (configList) {
      var configBase = _.find(configList, function (config) {
        return !config.extends;
      });

      _.forEach(configList, function (config) {
        if (config.extends) {
          _.defaults(config, configBase);
        }

        _.defaults(config, SETTING_SCHEMA_DEFAUTLS);
      });
    });

    //
    // Normalize setting groups.
    // (!) Groups are for global settings only, to organize interface.
    //

    if (!N.config.setting_groups) {
      N.config.setting_groups = {};
    }

    _.forEach(N.config.setting_groups, function (config, name, groups) {
      groups[name] = _.defaults(config || {}, SETTING_GROUP_DEFAUTLS);
    });

    // Check for nested groups - it's forbidden.
    _.forEach(N.config.setting_groups, function (config, name, groups) {
      if (config.parent) {
        if (!groups.hasOwnProperty(config.parent)) {
          throw 'Setting group "' + name + '" is nested into a non-existent ' +
                'group "' + config.parent + '"';
        }

        if (groups[config.parent].parent) {
          throw 'Setting group "' + name + '" is nested into a non-root group ' +
                '"' + config.parent + '"';
        }
      }
    });

    //
    // Initialize Settings.
    //

    N.settings = new Settings();

    _.forEach(N.runtime.apps, function (app) {
      var storesRoot = path.join(app.root, 'stores');

      fstools.walkSync(storesRoot, /\.js$/, function (file) {
        var apiPath, store;

        // skip "hidden" files (name/dir starts with underscore)
        if (file.match(/(^|\/|\\)_/)) {
          return;
        }

        apiPath = apify(file, storesRoot, /\.js$/);

        // Try to init store
        store = require(file)(N);

        if (!store) {
          throw apiPath + " store constructor returns nothing (in: " + file + ")";
        }

        // register known keys and theirs default values
        _.forEach(N.config.setting_schemas[apiPath], function (config, key) {
          store.addKnownKey(key, config['type'], config['default']);
        });

        // register store in settings
        N.settings.addStore(apiPath, store);
      });
    });

    N.logger.info('Stores init done ');
  });
};
<commit_msg>Name corrections.<commit_after>// Load stores, their schemas & init N.settings
//

"use strict";

// stdlib
var path = require('path');

// 3rd-party
var _       = require('lodash');
var fstools = require('fs-tools');

// internal
var apify       = require('../../../system/init/utils/apify');
var Settings    = require('../../../settings/settings');

var SETTING_SCHEMA_DEFAUTLS = {
  extends:      false
, type:         null
, 'default':    null
, category_key: null
, group_key:    null
, priority:     10
, values:       null
, before_show:  null
, before_save:  null
, validators:   null
};

var SETTING_GROUP_DEFAUTLS = {
  parent:   null
, priority: 10
};

////////////////////////////////////////////////////////////////////////////////

module.exports = function (N) {
  // Generate sub-event
  N.wire.after("init:models", { priority: 50 }, function emit_init_settings(N, callback) {
    N.wire.emit("init:__settings", N, callback);
  });

  N.wire.on("init:__settings", function init_settings(N) {
    var schemasCache = {}; // cache: setting name => array of schemas (from stores)

    //
    // Normalize setting schemas.
    //

    if (!N.config.setting_schemas) {
      N.config.setting_schemas = {};
    }

    // Collect all available setting schemas form different stores.
    _.forEach(N.config.setting_schemas, function (store) {
      _.forEach(store, function (schema, name) {
        if (!schemasCache.hasOwnProperty(name)) {
          schemasCache[name] = [];
        }

        schemasCache[name].push(schema);
      });
    });

    // Resolve `extends` flags and fill-in default schema values.
    _.forEach(schemasCache, function (schemaList) {
      var baseSchema = _.find(schemaList, function (schema) {
        return !schema.extends;
      });

      _.forEach(schemaList, function (schema) {
        if (schema.extends) {
          _.defaults(schema, baseSchema);
        }

        _.defaults(schema, SETTING_SCHEMA_DEFAUTLS);
      });
    });

    //
    // Normalize setting groups.
    // (!) Groups are for global settings only, to organize interface.
    //

    if (!N.config.setting_groups) {
      N.config.setting_groups = {};
    }

    _.forEach(N.config.setting_groups, function (group, name, collection) {
      collection[name] = _.defaults(group || {}, SETTING_GROUP_DEFAUTLS);
    });

    // Check for nested groups - it's forbidden.
    _.forEach(N.config.setting_groups, function (group, name, collection) {
      if (group.parent) {
        if (!collection.hasOwnProperty(group.parent)) {
          throw 'Setting group "' + name + '" is nested into a non-existent ' +
                'group "' + group.parent + '"';
        }

        if (collection[group.parent].parent) {
          throw 'Setting group "' + name + '" is nested into a non-root group ' +
                '"' + group.parent + '"';
        }
      }
    });

    //
    // Initialize Settings.
    //

    N.settings = new Settings();

    _.forEach(N.runtime.apps, function (app) {
      var storesRoot = path.join(app.root, 'stores');

      fstools.walkSync(storesRoot, /\.js$/, function (file) {
        var apiPath, store;

        // skip "hidden" files (name/dir starts with underscore)
        if (file.match(/(^|\/|\\)_/)) {
          return;
        }

        apiPath = apify(file, storesRoot, /\.js$/);

        // Try to init store
        store = require(file)(N);

        if (!store) {
          throw apiPath + " store constructor returns nothing (in: " + file + ")";
        }

        // register known keys and theirs default values
        _.forEach(N.config.setting_schemas[apiPath], function (config, key) {
          store.addKnownKey(key, config['type'], config['default']);
        });

        // register store in settings
        N.settings.addStore(apiPath, store);
      });
    });

    N.logger.info('Stores init done ');
  });
};
<|endoftext|>


<commit_before>// Load stores, their schemas & init N.settings
//

'use strict';

var _        = require('lodash');
var async    = require('async');
var path     = require('path');
var fstools  = require('fs-tools');
var apify    = require('../../../system/init/utils/apify');
var Settings = require('../../../settings/settings');

var SETTING_SCHEMA_DEFAUTLS = {
  extends:      false
, type:         null
, 'default':    null
, category_key: null
, group_key:    null
, priority:     10
, values:       null
, before_show:  null
, before_save:  null
, validators:   null
};

var SETTING_GROUP_DEFAUTLS = {
  parent:   null
, priority: 10
};

var SETTING_TYPE_DEFAULTS = {
  boolean:  false
, number:   0
, string:   ''
, text:     ''
, wysiwyg:  ''
, combobox: []
};

module.exports = function (N) {
  // Generate a sub-event in order to initialize settings manager.
  // The reason for that is to allow hooks in other apps like `nodeca.users` or
  // `nodeca.forum` to expose their extensions.
  // Currently only one extension is possible - special `values` fetcher.
  // It used for dropdown/combobox settings which need some dynamic data from
  // the database or whatever (e.g. 'usergroups' values fetcher).
  //
  N.wire.after('init:models', { priority: 50 }, function emit_init_settings(N, callback) {
    var extensions = { values: {} };

    N.wire.emit('init:settings', extensions, callback);
  });

  // Normalize setting schemas.
  //
  N.wire.before('init:settings', { priority: -1 }, function (extensions, callback) {
    var schemasCache = {}; // cache: setting name => array of schemas (from stores)

    if (!N.config.setting_schemas) {
      N.config.setting_schemas = {};
    }

    // Collect all available setting schemas form different stores.
    _.forEach(N.config.setting_schemas, function (store) {
      _.forEach(store, function (schema, name) {
        if (!schemasCache.hasOwnProperty(name)) {
          schemasCache[name] = [];
        }

        schemasCache[name].push(schema);
      });
    });

    // Resolve `extends` flags and fill-in default schema values.
    async.forEach(_.keys(schemasCache), function (name, nextSetting) {
      var baseSchema = _.find(schemasCache[name], function (schema) {
        return !schema.extends;
      });

      async.forEach(schemasCache[name], function (schema, nextSchema) {
        if (schema.extends) {
          _.defaults(schema, baseSchema);
        }

        // No default value specified - try to detect or throw an error.
        if (!_.has(schema, 'default')) {
          if (!_.has(SETTING_TYPE_DEFAULTS, schema.type)) {
            nextSchema('There is no default value for setting of type ' +
                       '"' + schema.type + '".');
            return;
          }

          schema['default'] = SETTING_TYPE_DEFAULTS[schema.type];
        }

        // Use defaults for non-existent fields.
        _.defaults(schema, SETTING_SCHEMA_DEFAUTLS);

        // If `values` is a string - it's a special values fetcher function.
        if (_.isString(schema.values)) {
          if (!_.has(extensions.values, schema.values)) {
            nextSchema('There is no setting value options fetcher named ' +
                       '"' + schema.values + '". Check setting definitions.');
            return;
          }

          var fetcher = extensions.values[schema.values];

          // Expose the fetcher - setting editors will use it.
          schema.values = fetcher;

          // Resolve default values from the config using the fetcher.
          // It's needed since config values may be actually alias names of
          // values returned by the fetcher.
          // For example real value may be a generated ObjectId.
          fetcher(null, function (err, values) {
            if (err) {
              nextSchema(err);
              return;
            }

            schema['default'] = _.map(schema['default'], function (configValue) {
              var realValue = _.find(values, { name: configValue });

              return realValue ? realValue.value : configValue;
            });

            nextSchema();
          });
        } else {
          nextSchema();
        }
      }, nextSetting);
    }, callback);
  });

  // Normalize setting groups.
  // (!) Groups are for global settings only, to organize interface.
  //
  N.wire.before('init:settings', { priority: -1 }, function () {
    if (!N.config.setting_groups) {
      N.config.setting_groups = {};
    }

    _.forEach(N.config.setting_groups, function (group, name, collection) {
      collection[name] = _.defaults(group || {}, SETTING_GROUP_DEFAUTLS);
    });

    // Check for nested groups - it's forbidden.
    _.forEach(N.config.setting_groups, function (group, name, collection) {
      if (group.parent) {
        if (!collection.hasOwnProperty(group.parent)) {
          throw 'Setting group "' + name + '" is nested into a non-existent ' +
                'group "' + group.parent + '"';
        }

        if (collection[group.parent].parent) {
          throw 'Setting group "' + name + '" is nested into a non-root group ' +
                '"' + group.parent + '"';
        }
      }
    });
  });

  // Initialize N.settings object.
  //
  N.wire.on('init:settings', function () {
    N.settings = new Settings();

    _.forEach(N.runtime.apps, function (app) {
      var storesRoot = path.join(app.root, 'stores');

      fstools.walkSync(storesRoot, /\.js$/, function (file) {
        var apiPath, store;

        // skip "hidden" files (name/dir starts with underscore)
        if (file.match(/(^|\/|\\)_/)) {
          return;
        }

        apiPath = apify(file, storesRoot, /\.js$/);

        // Try to init store
        store = require(file)(N);

        if (!store) {
          throw apiPath + " store constructor returns nothing (in: " + file + ")";
        }

        // register known keys and theirs default values
        _.forEach(N.config.setting_schemas[apiPath], function (config, key) {
          store.addKnownKey(key, config['type'], config['default']);
        });

        // register store in settings
        N.settings.addStore(apiPath, store);
      });
    });

    N.logger.info('Settings init done');
  });
};
<commit_msg>Add names for init:settings Wire handlers.<commit_after>// Load stores, their schemas & init N.settings
//

'use strict';

var _        = require('lodash');
var async    = require('async');
var path     = require('path');
var fstools  = require('fs-tools');
var apify    = require('../../../system/init/utils/apify');
var Settings = require('../../../settings/settings');

var SETTING_SCHEMA_DEFAUTLS = {
  extends:      false
, type:         null
, 'default':    null
, category_key: null
, group_key:    null
, priority:     10
, values:       null
, before_show:  null
, before_save:  null
, validators:   null
};

var SETTING_GROUP_DEFAUTLS = {
  parent:   null
, priority: 10
};

var SETTING_TYPE_DEFAULTS = {
  boolean:  false
, number:   0
, string:   ''
, text:     ''
, wysiwyg:  ''
, combobox: []
};

module.exports = function (N) {
  // Generate a sub-event in order to initialize settings manager.
  // The reason for that is to allow hooks in other apps like `nodeca.users` or
  // `nodeca.forum` to expose their extensions.
  // Currently only one extension is possible - special `values` fetcher.
  // It used for dropdown/combobox settings which need some dynamic data from
  // the database or whatever (e.g. 'usergroups' values fetcher).
  //
  N.wire.after('init:models', { priority: 50 }, function emit_init_settings(N, callback) {
    var extensions = { values: {} };

    N.wire.emit('init:settings', extensions, callback);
  });

  // Normalize setting schemas.
  //
  N.wire.before('init:settings', { priority: -1 }, function normalize_setting_schemas(extensions, callback) {
    var schemasCache = {}; // cache: setting name => array of schemas (from stores)

    if (!N.config.setting_schemas) {
      N.config.setting_schemas = {};
    }

    // Collect all available setting schemas form different stores.
    _.forEach(N.config.setting_schemas, function (store) {
      _.forEach(store, function (schema, name) {
        if (!schemasCache.hasOwnProperty(name)) {
          schemasCache[name] = [];
        }

        schemasCache[name].push(schema);
      });
    });

    // Resolve `extends` flags and fill-in default schema values.
    async.forEach(_.keys(schemasCache), function (name, nextSetting) {
      var baseSchema = _.find(schemasCache[name], function (schema) {
        return !schema.extends;
      });

      async.forEach(schemasCache[name], function (schema, nextSchema) {
        if (schema.extends) {
          _.defaults(schema, baseSchema);
        }

        // No default value specified - try to detect or throw an error.
        if (!_.has(schema, 'default')) {
          if (!_.has(SETTING_TYPE_DEFAULTS, schema.type)) {
            nextSchema('There is no default value for setting of type ' +
                       '"' + schema.type + '".');
            return;
          }

          schema['default'] = SETTING_TYPE_DEFAULTS[schema.type];
        }

        // Use defaults for non-existent fields.
        _.defaults(schema, SETTING_SCHEMA_DEFAUTLS);

        // If `values` is a string - it's a special values fetcher function.
        if (_.isString(schema.values)) {
          if (!_.has(extensions.values, schema.values)) {
            nextSchema('There is no setting value options fetcher named ' +
                       '"' + schema.values + '". Check setting definitions.');
            return;
          }

          var fetcher = extensions.values[schema.values];

          // Expose the fetcher - setting editors will use it.
          schema.values = fetcher;

          // Resolve default values from the config using the fetcher.
          // It's needed since config values may be actually alias names of
          // values returned by the fetcher.
          // For example real value may be a generated ObjectId.
          fetcher(null, function (err, values) {
            if (err) {
              nextSchema(err);
              return;
            }

            schema['default'] = _.map(schema['default'], function (configValue) {
              var realValue = _.find(values, { name: configValue });

              return realValue ? realValue.value : configValue;
            });

            nextSchema();
          });
        } else {
          nextSchema();
        }
      }, nextSetting);
    }, callback);
  });

  // Normalize setting groups.
  // (!) Groups are for global settings only, to organize interface.
  //
  N.wire.before('init:settings', { priority: -1 }, function normalize_setting_groups() {
    if (!N.config.setting_groups) {
      N.config.setting_groups = {};
    }

    _.forEach(N.config.setting_groups, function (group, name, collection) {
      collection[name] = _.defaults(group || {}, SETTING_GROUP_DEFAUTLS);
    });

    // Check for nested groups - it's forbidden.
    _.forEach(N.config.setting_groups, function (group, name, collection) {
      if (group.parent) {
        if (!collection.hasOwnProperty(group.parent)) {
          throw 'Setting group "' + name + '" is nested into a non-existent ' +
                'group "' + group.parent + '"';
        }

        if (collection[group.parent].parent) {
          throw 'Setting group "' + name + '" is nested into a non-root group ' +
                '"' + group.parent + '"';
        }
      }
    });
  });

  // Initialize N.settings object.
  //
  N.wire.on('init:settings', function init_settings() {
    N.settings = new Settings();

    _.forEach(N.runtime.apps, function (app) {
      var storesRoot = path.join(app.root, 'stores');

      fstools.walkSync(storesRoot, /\.js$/, function (file) {
        var apiPath, store;

        // skip "hidden" files (name/dir starts with underscore)
        if (file.match(/(^|\/|\\)_/)) {
          return;
        }

        apiPath = apify(file, storesRoot, /\.js$/);

        // Try to init store
        store = require(file)(N);

        if (!store) {
          throw apiPath + " store constructor returns nothing (in: " + file + ")";
        }

        // register known keys and theirs default values
        _.forEach(N.config.setting_schemas[apiPath], function (config, key) {
          store.addKnownKey(key, config['type'], config['default']);
        });

        // register store in settings
        N.settings.addStore(apiPath, store);
      });
    });

    N.logger.info('Settings init done');
  });
};
<|endoftext|>


<commit_before>'use strict';

/*global nodeca, _*/

// stdlib
var fs    = require('fs');
var path  = require('path');

// 3rd-party
var apiTree       = require('nlib').ApiTree;
var async         = require('nlib').Vendor.Async;
var fstools       = require('nlib').Vendor.FsTools;
var safePropName  = require('nlib').Support.safePropName;
var findRequires  = require('find-requires');

// internal
var findPaths = require('./find_paths');

////////////////////////////////////////////////////////////////////////////////

function Requisite() {
  this.requires = {};
  this.idx      = 1;
}

Requisite.prototype.process = function (source, pathname) {
  var
  self  = this,
  files = findRequires(source, { raw: true }),
  o, p, i;

  while (files.length) {
    o = files.shift();

    if (!o.value) {
      return new Error("Cannot handle non-string required path: " + o.raw);
    }

    try {
      p = require.resolve(path.resolve(path.dirname(pathname.absolutePath), o.value));
    } catch (err) {
      return new Error(err.message +
                       ' (require: ' + o.value + ') (in: ' + pathname + ')');
    }

    i = this.requires[p];

    if (undefined === i) {
      i = this.idx++;
      this.requires[p] = i;
    }

    source = source.replace(o.value, i);
  }

  return source;
};

Requisite.prototype.bundle = function () {
  var parts = [];

  parts.push(
    '(function () {',
      'var modules = {};',
      'function define(name, init) {',
        'modules[name] = { init: init };',
      '}',
      'function require(name) {',
        'if (!modules[name]) { throw new Error("Unknown module " + name); }',
        'if (!modules[name].module) {',
          'modules[name].module = { exports: {} };',
          'modules[name].init.call(modules[name].module.exports, ',
            'modules[name].module.exports, modules[name].module, ',
            'require);',
        '}',
        'return modules[name].module.exports;',
      '}'
  );

  _.each(this.requires, function (i, pathname) {
    parts.push(
      'define("' + i + '", function (exports, module, require, define, modules) {',
      fs.readFileSync(pathname, 'utf8'),
      '});'
    );
  });

  parts.push(
      'return require;',
    '})'
  );

  return parts.join('\n');
};

// produces bundled server/client (js) trees for the browswers
function browserifyClient(callback) {
  var
  bundleConfig  = require('../../../bundle.yml'),
  packageConfig = bundleConfig.packages.fontello,
  clientConfig  = packageConfig.client,
  clientRoot    = path.resolve(nodeca.runtime.apps[0].root, clientConfig.root),
  findOptions   = _.pick(clientConfig, 'include', 'exclude');

  findOptions.root = clientRoot;

  findPaths(findOptions, function (err, pathnames) {
    var heads = [], bodies = [], requisite = new Requisite();

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

    async.forEachSeries(pathnames, function (pathname, nextPath) {
      pathname.read('utf8', function (err, source) {
        var // [ '["foo"]', '["bar"]', '["baz"]' ]
        apiPathParts = pathname.apiPath.split('.').map(safePropName);

        if (err) {
          nextPath(err);
          return;
        }

        // feed all parents of apiPath into heads array
        apiPathParts.reduce(function (prev, curr) {
          if (-1 === heads.indexOf(prev)) {
            heads.push(prev);
          }

          return prev + curr;
        });

        source = requisite.process(source, pathname);

        if (source instanceof Error) {
          nextPath(source);
          return;
        }

        bodies.push(
          ('this' + apiPathParts.join('') + ' = (function (require) {'),
            ('(function (exports, module) {'),
            source,
            ('}.call(this.exports, this.exports, this));'),
            ('return this.exports;'),
          ('}.call({ exports: {} }, require));')
        );

        nextPath();
      });
    }, function (err) {
      var head = _.uniq(heads.sort(), true).map(function (api) {
        return 'this' + api + ' = {};';
      }).join('\n');

      callback(err, [
        '(function () {',
        'var require = ' + requisite.bundle() + ';\n\n',
        head + '\n\n' + bodies.join('\n'),
        '}.call(nodeca.client));'
      ].join('\n'));
    });
  });
}

////////////////////////////////////////////////////////////////////////////////

// buildApiTree(root, callback(err)) -> Void
// - root (String): Pathname where to save browserified api.js.
// - callback (Function): Executed once everything is done.
//
// Browserifies server/shared/client trees into api.js file.
//
module.exports = function buildApiTree(root, callback) {
  browserifyClient(function (err, client) {
    var server;

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

    server = apiTree.browserifyServerTree(nodeca.server, 'this.nodeca.server', {
      method: 'nodeca.io.apiTree'
    });

    fs.writeFile(path.join(root, 'api.js'), server + '\n\n' + client, callback);
  });
};
<commit_msg>Allow deep-nested requisite requires<commit_after>'use strict';

/*global nodeca, _*/

// stdlib
var fs    = require('fs');
var path  = require('path');

// 3rd-party
var apiTree       = require('nlib').ApiTree;
var async         = require('nlib').Vendor.Async;
var fstools       = require('nlib').Vendor.FsTools;
var safePropName  = require('nlib').Support.safePropName;
var findRequires  = require('find-requires');

// internal
var findPaths = require('./find_paths');

////////////////////////////////////////////////////////////////////////////////

function Requisite() {
  this.requires = {};
  this.idx      = 1;
}

Requisite.prototype.process = function (source, pathname) {
  var
  self  = this,
  files = findRequires(source, { raw: true }),
  dependency, o, p;

  while (files.length) {
    o = files.shift();

    if (!o.value) {
      return new Error("Cannot handle non-string required path: " + o.raw);
    }

    try {
      p = require.resolve(path.resolve(path.dirname(pathname.toString()), o.value));
    } catch (err) {
      return new Error(err.message +
                       ' (require: ' + o.value + ') (in: ' + pathname + ')');
    }

    dependency = this.requires[p];

    if (undefined === dependency) {
      this.requires[p] = { idx: this.idx++, source: null };
      // prevent from "cyclic" loops
      this.requires[p].source = this.process(fs.readFileSync(p, 'utf8'), p);
    }

    source = source.replace(o.value, dependency.idx);
  }

  return source;
};

Requisite.prototype.bundle = function () {
  var parts = [];

  parts.push(
    '(function () {',
      'var modules = {};',
      'function define(name, init) {',
        'modules[name] = { init: init };',
      '}',
      'function require(name) {',
        'if (!modules[name]) { throw new Error("Unknown module " + name); }',
        'if (!modules[name].module) {',
          'modules[name].module = { exports: {} };',
          'modules[name].init.call(modules[name].module.exports, ',
            'modules[name].module.exports, modules[name].module, ',
            'require);',
        '}',
        'return modules[name].module.exports;',
      '}'
  );

  _.each(this.requires, function (dep, pathname) {
    parts.push(
      'define("' + dep.idx + '", function (exports, module, require, define, modules) {',
      dep.source,
      '});'
    );
  });

  parts.push(
      'return require;',
    '})'
  );

  return parts.join('\n');
};

// produces bundled server/client (js) trees for the browswers
function browserifyClient(callback) {
  var
  bundleConfig  = require('../../../bundle.yml'),
  packageConfig = bundleConfig.packages.fontello,
  clientConfig  = packageConfig.client,
  clientRoot    = path.resolve(nodeca.runtime.apps[0].root, clientConfig.root),
  findOptions   = _.pick(clientConfig, 'include', 'exclude');

  findOptions.root = clientRoot;

  findPaths(findOptions, function (err, pathnames) {
    var heads = [], bodies = [], requisite = new Requisite();

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

    async.forEachSeries(pathnames, function (pathname, nextPath) {
      pathname.read('utf8', function (err, source) {
        var // [ '["foo"]', '["bar"]', '["baz"]' ]
        apiPathParts = pathname.apiPath.split('.').map(safePropName);

        if (err) {
          nextPath(err);
          return;
        }

        // feed all parents of apiPath into heads array
        apiPathParts.reduce(function (prev, curr) {
          if (-1 === heads.indexOf(prev)) {
            heads.push(prev);
          }

          return prev + curr;
        });

        source = requisite.process(source, pathname);

        if (source instanceof Error) {
          nextPath(source);
          return;
        }

        bodies.push(
          ('this' + apiPathParts.join('') + ' = (function (require) {'),
            ('(function (exports, module) {'),
            source,
            ('}.call(this.exports, this.exports, this));'),
            ('return this.exports;'),
          ('}.call({ exports: {} }, require));')
        );

        nextPath();
      });
    }, function (err) {
      var head = _.uniq(heads.sort(), true).map(function (api) {
        return 'this' + api + ' = {};';
      }).join('\n');

      callback(err, [
        '(function () {',
        'var require = ' + requisite.bundle() + ';\n\n',
        head + '\n\n' + bodies.join('\n'),
        '}.call(nodeca.client));'
      ].join('\n'));
    });
  });
}

////////////////////////////////////////////////////////////////////////////////

// buildApiTree(root, callback(err)) -> Void
// - root (String): Pathname where to save browserified api.js.
// - callback (Function): Executed once everything is done.
//
// Browserifies server/shared/client trees into api.js file.
//
module.exports = function buildApiTree(root, callback) {
  browserifyClient(function (err, client) {
    var server;

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

    server = apiTree.browserifyServerTree(nodeca.server, 'this.nodeca.server', {
      method: 'nodeca.io.apiTree'
    });

    fs.writeFile(path.join(root, 'api.js'), server + '\n\n' + client, callback);
  });
};
<|endoftext|>


<commit_before>/**
 * Created by Samuel Castro <samuelcastrosilva@gmail.com> on 1/5/16.
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 */

var exec = require('cordova/exec'),
    cordova = require('cordova');

function InstagramShare() {}

InstagramShare.prototype.test = function(successCallback, errorCallback) {
    exec(successCallback, errorCallback, "InstagramShare", "test", []);
};

InstagramShare.prototype.isInstalled = function(successCallback, errorCallback) {
    exec(successCallback, errorCallback, "InstagramShare", "isInstalled", []);
};

InstagramShare.prototype.shareMedia = function(filePath, successCallback, errorCallback) {
    exec(successCallback, errorCallback, "InstagramShare", "shareMedia", [filePath]);
};

module.exports = new InstagramShare();

<commit_msg>Creating shareMedia method<commit_after>/**
 * Created by Samuel Castro <samuelcastrosilva@gmail.com> on 1/5/16.
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 */

var exec = require('cordova/exec'),
    cordova = require('cordova');

function InstagramShare() {}

InstagramShare.prototype.test = function(successCallback, errorCallback) {
    exec(successCallback, errorCallback, "InstagramShare", "test", []);
};

InstagramShare.prototype.isInstalled = function(successCallback, errorCallback) {
    exec(successCallback, errorCallback, "InstagramShare", "isInstalled", []);
};

InstagramShare.prototype.shareMedia = function(filePath, caption, successCallback, errorCallback) {
    exec(successCallback, errorCallback, "InstagramShare", "shareMedia", [filePath, caption]);
};

module.exports = new InstagramShare();

<|endoftext|>


<commit_before>var utily = require("utily");
var pkg = require("../package.json");
var colors = require("../colors.json");

//Generate the header
module.exports.getHeader = function() {
    let banner = [];
    banner.push("/**");
    banner.push(" * @name         {{ name }} v{{ version }}");
    banner.push(" * @description  {{ description }}");
    banner.push(" * @docs         {{ homepage }}");
    banner.push(" * @license      {{ license }}");
    banner.push("**/");
    banner.push(" ");
    banner.push(" ");
    return utily.string.format(banner.join("\n"), pkg);
};

//Get the package version
module.exports.getVersion = function() {
    return pkg.version;
};

//Get the colors list
module.exports.getColors = function() {
    return colors;
};
<commit_msg>Fixed depdnencies<commit_after>let kofi = require("kofi");
let pkg = require("../package.json");
let colors = require("../colors.json");

//Generate the header
module.exports.getHeader = function() {
    let banner = [];
    banner.push("/**");
    banner.push(" * @name         {{ name }} v{{ version }}");
    banner.push(" * @description  {{ description }}");
    banner.push(" * @docs         {{ homepage }}");
    banner.push(" * @license      {{ license }}");
    banner.push("**/");
    banner.push(" ");
    banner.push(" ");
    return kofi.format(banner.join("\n"), pkg);
};

//Get the package version
module.exports.getVersion = function() {
    return pkg.version;
};

//Get the colors list
module.exports.getColors = function() {
    return colors;
};
<|endoftext|>