var fs = require('fs'); var fse = require('fs-extra2'); var path = require('path'); var util = require('../util'); var config = require('../config'); var protocols = require('../rules/protocols'); var ORG_RE = /^@[\w-]+$/; var WHISLTE_PLUGIN_RE = /^whistle\.[a-z\d_\-]+$/; var HTTP_RE = /^https?:\/\//i; var PLUGIN_NAME_RE = /^(?:@[\w-]+\/)?(whistle\.[a-z\d_\-]+)$/; var DEV_PLUGINS_PATH = config.DEV_PLUGINS_PATH; var MAX_EXPIRE = 36000; var UTF8_OPTIONS = { encoding: 'utf8' }; var workerScript = util.readFileSync(path.join(__dirname, '../../assets/js/worker.js')); var workers = {}; function replaceScript(ctn) { return workerScript.replace('/*sourcecode*/', ctn); } exports.readWorkerSync = function(root, conf) { var file = util.getWebWorker(conf); file = file && util.readFileSync(path.join(root, file)); if (!file) { return; } var id = util.createHash(file); workers[id] = replaceScript(file); return id; }; exports.readWorker = function(root, conf, callback) { var file = util.getWebWorker(conf); if (!file) { return callback(); } readFile(path.join(root, file), function(err, ctn) { if (err || !ctn) { return callback(); } var id = util.createHash(ctn); workers[id] = replaceScript(ctn); callback(id); }); }; exports.getWorker = function(id) { return workers[id]; }; exports.resetWorkers = function(plugins) { var _workers = {}; Object.keys(plugins).forEach(function(key) { var plugin = plugins[key]; _workers[plugin.webWorker] = workers[plugin.webWorker]; }); workers = _workers; }; function isOrgModule(name) { return ORG_RE.test(name); } exports.isOrgModule = isOrgModule; exports.isPluginName = function(name) { return PLUGIN_NAME_RE.test(name); }; function isWhistleModule(name) { return WHISLTE_PLUGIN_RE.test(name); } exports.isWhistleModule = isWhistleModule; function getHomePageFromPackage(pkg) { if (HTTP_RE.test(pkg.homepage)) { return pkg.homepage; } return extractUrl(pkg.repository) || ''; } function extractUrl(repository) { if ( !repository || repository.type != 'git' || typeof repository.url != 'string' ) { return; } var url = repository.url.replace(/^git\+/i, ''); if (!HTTP_RE.test(url)) { url = url.replace(/^git@([^:]+):/, 'http://$1/'); } return url.replace(/\.git\s*$/i, ''); } exports.getHomePageFromPackage = getHomePageFromPackage; exports.parseValues = function (val) { if (val) { val = util.parseJSON(val); } if (!val) { return ''; } Object.keys(val).forEach(function (key) { val[key] = util.toString(val[key]); }); return val; }; exports.getPluginHomepage = function (pkg) { var url = pkg.pluginHomepage || pkg.pluginHomePage; return typeof url === 'string' ? url : undefined; }; exports.excludePlugin = function (name) { if ( protocols.contains(name) || (config.allowPluginList && config.allowPluginList.indexOf(name) === -1) ) { return true; } return config.blockPluginList && config.blockPluginList.indexOf(name) !== -1; }; function setPlugin(plugins, pkg, root, mtime, sync) { if (PLUGIN_NAME_RE.test(pkg.name)) { var name = sync ? RegExp.$1 : RegExp.$1.split('.', 2)[1]; plugins[name] = { root: root, mtime: mtime, notUn: true, isProj: true, isDev: true }; } } exports.readDevPluginsSync = function() { var plugins = {}; try { var files = fs.readdirSync(DEV_PLUGINS_PATH); files.forEach(function(file) { file = path.join(DEV_PLUGINS_PATH, file); try { var ctn = fs.readFileSync(file, UTF8_OPTIONS).split('\n'); if (Date.now() - ctn[0] < MAX_EXPIRE && ctn[1]) { var root = ctn[1]; var pkgPath = path.join(root, 'package.json'); var stats = fs.statSync(pkgPath); var pkg = fse.readJsonSync(pkgPath); setPlugin(plugins, pkg, root, stats.mtime.getTime(), true); } else { fs.unlinkSync(file); } } catch (e) {} }); } catch (e) {} return plugins; }; function readFile(filepath, callback) { fs.readFile(filepath, UTF8_OPTIONS, function (err, text) { if (!err) { return callback(err, text); } fs.readFile(filepath, UTF8_OPTIONS, callback); }); } function readDir(dir, callback) { fs.readdir(dir, function (err, list) { if (!err) { return callback(err, list); } fs.readdir(dir, callback); }); } function statFile(filepath, callback) { fs.stat(filepath, function (_, stat1) { if (stat1) { return callback(stat1.isFile() && stat1); } fs.stat(filepath, function (_, stat2) { callback(stat2 && stat2.isFile() && stat2); }); }); } exports.readFile = readFile; exports.readDir = readDir; exports.statFile = statFile; exports.readDevPlugins = function(callback) { var plugins = {}; readDir(DEV_PLUGINS_PATH, function(err, files) { var len = files && files.length; if (!len) { return callback(plugins); } files.forEach(function(file) { file = path.join(DEV_PLUGINS_PATH, file); readFile(file, function(_, ctn) { ctn = ctn && ctn.split('\n'); if (ctn && Date.now() - ctn[0] < MAX_EXPIRE && ctn[1]) { var root = ctn[1]; var pkgPath = path.join(root, 'package.json'); readFile(pkgPath, function(_, pkg) { if (pkg) { try { pkg = JSON.parse(pkg); return statFile(pkgPath, function(stats) { stats && setPlugin(plugins, pkg, root, stats.mtime.getTime()); --len === 0 && callback(plugins); }); } catch (e) {} } --len === 0 && callback(plugins); }); } else { fs.unlink(file, util.noop); --len === 0 && callback(plugins); } }); }); }); };