[
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\nindent_style = space\nindent_size = 2\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true\n\n[*.md]\ntrim_trailing_whitespace = false\n"
  },
  {
    "path": ".gitignore",
    "content": "node_modules\n~*\n*~\n.DS_Store\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2016 nowa\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# nowa\n\n[![NPM version](https://img.shields.io/npm/v/nowa.svg?style=flat)](https://npmjs.org/package/nowa)\n\nnowa webpack solution\n\n----\n\n## Feature\n\n- Generate a [webpack](https://github.com/webpack/webpack) based boilerplate.\n- Run a local server for web developer, support proxy and HMR.\n- Easy to use and customize third-party UI components.\n- Support customized webpack.config.js.\n- Support `buildvars` to automatically output bundles with different varible combinations.\n\nCheckout [https://nowa-webpack.github.io/](https://nowa-webpack.github.io/) for more information.\n\n## Install\n\n- Install nowa\n\n```bash\n$ npm i nowa -g\n```\n\n- Install all frequently-used nowa plugins ([build](https://github.com/nowa-webpack/nowa-build), [init](https://github.com/nowa-webpack/nowa-init), [lib](https://github.com/nowa-webpack/nowa-lib), [server](https://github.com/nowa-webpack/nowa-server))\n\n```bash\n$ nowa install\n```\n\n> You can install any plugin by `nowa install <name>`.\n\n> Find more plugins, visit [here](https://www.npmjs.com/search?q=nowa-).\n\n## Usage\n\n- Generate a boilerplate.\n\n```bash\n$ mkdir test && cd test\n$ nowa init uxcore\n```\n\n- Start a local dev server.\n\n```bash\n$ nowa server\n```\n\n- Build project.\n\n```bash\n$ nowa build\n```\n\n- Build libraries.\n\n```bash\n$ nowa lib\n```\n"
  },
  {
    "path": "bin/nowa",
    "content": "#!/usr/bin/env node\n\nmodule.exports = require('../');\n"
  },
  {
    "path": "bin/nowa.cmd",
    "content": "@IF EXIST \"%~dp0\\node.exe\" (\r\n  \"%~dp0\\node.exe\"  \"%~dp0\\..\\nowa\\bin\\nowa\" %*\r\n) ELSE (\r\n  @SETLOCAL\r\n  @SET PATHEXT=%PATHEXT:;.JS;=;%\r\n  node  \"%~dp0\\..\\nowa\\bin\\nowa\" %*\r\n)"
  },
  {
    "path": "index.js",
    "content": "#!/usr/bin/env node\n\nmodule.exports = require('./src');\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"nowa\",\n  \"version\": \"1.2.2\",\n  \"description\": \"nowa webpack solution\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\",\n    \"preuninstall\": \"node ./uninstall.js\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/nowa-webpack/nowa.git\"\n  },\n  \"keywords\": [\n    \"nowa\",\n    \"webpack\",\n    \"server\",\n    \"builder\"\n  ],\n  \"author\": \"gbk <ck0123456@gmail.com>\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/nowa-webpack/nowa/issues\"\n  },\n  \"homepage\": \"https://github.com/nowa-webpack/nowa#readme\",\n  \"dependencies\": {\n    \"chalk\": \"~1.1.3\",\n    \"commander\": \"~2.9.0\",\n    \"nowa-install\": \"^1.0.0\",\n    \"nowa-plugin\": \"^1.0.0\",\n    \"package-json\": \"~2.3.2\",\n    \"resolve\": \"~1.1.7\",\n    \"semver\": \"~5.1.0\"\n  },\n  \"bin\": {\n    \"nowa\": \"./bin/nowa\"\n  },\n  \"engines\": {\n    \"node\": \">=4.0.0\",\n    \"npm\": \"^3.0.0\"\n  }\n}\n"
  },
  {
    "path": "src/check.js",
    "content": "/*\n* @Author: gbk\n* @Date:   2016-06-25 17:44:38\n* @Last Modified by:   gbk\n* @Last Modified time: 2016-06-25 22:26:03\n*/\n\n'use strict';\n\nvar os = require('os');\nvar fs = require('fs');\nvar path = require('path');\n\nvar packageJson = require('package-json');\n\nvar configRoot = path.join(os.homedir(), '.nowa');\nvar versionsPath = path.join(configRoot, 'latest-versions.json');\n\n// tasks definiation\nvar majorVersion = process.argv[2].split('.')[0];\nvar tasks = process.argv.slice(3).map(function(command) {\n  return packageJson(command, majorVersion);\n});\ntasks.push(packageJson('nowa', 'latest'))\ntasks.push(new Promise(function(resolve) {\n  fs.mkdir(configRoot, resolve);\n}));\n\n// run tasks\nnew Promise(function(resolve, reject) {\n  fs.readFile(versionsPath, 'utf-8', function(err, data) {\n    if (data) {\n      data = JSON.parse(data);\n\n      // check interval by 1 day\n      if (Date.now() - data.update > 3600000 * 24) {\n        resolve(Promise.all(tasks));\n      } else {\n        reject();\n      }\n    } else {\n      resolve(Promise.all(tasks));\n    }\n  });\n}).then(function(pkgs) {\n\n  // write to versions store\n  var versions = {};\n  pkgs.forEach(function(pkg) {\n    versions[pkg.name] = pkg.version;\n  });\n  fs.writeFile(versionsPath, JSON.stringify({\n    versions: versions,\n    update: Date.now()\n  }));\n});\n"
  },
  {
    "path": "src/index.js",
    "content": "/*\n* @Author: gbk\n* @Date:   2016-04-11 16:43:10\n* @Last Modified by:   gbk\n* @Last Modified time: 2017-03-23 21:33:26\n*/\n\n'use strict';\n\nvar fs = require('fs');\nvar path = require('path');\n\nvar resolve = require('resolve');\nvar program = require('commander');\nvar chalk = require('chalk');\nvar semver = require('semver');\n\nvar updateNotifier = require('./update-notifier');\nvar pkg = require('../package.json');\nvar argvs = process.argv;\nvar command = argvs[2];\n\n// check nodejs version\nif (!semver.satisfies(process.version, pkg.engines.node)) {\n  console.log(chalk.red.bold('Require nodejs version ' + pkg.engines.node + ', current ' + process.version));\n  console.log('Download the latest nodejs here ' + chalk.green('https://nodejs.org/en/download/'));\n  process.exit();\n}\n\n// program definiation\nprogram\n  .version(pkg.version)\n  .usage('<command> [options]');\n\n// dirs to find plugins\nvar moduleDirs = [\n  path.join(__dirname, '..', 'node_modules'),\n  path.join(__dirname, '..', '..')\n];\nprogram._moduleDirs = moduleDirs;\n\n// locate the plugin\nvar pluginPath = findPluginPath(command);\n\nif (pluginPath) { // plugin found\n\n  // check update of current command\n  updateNotifier(pkg.version, 'nowa-' + command);\n\n  // regist current plugin\n  var pluginDef = require(pluginPath);\n  var plugin = program.command(pluginDef.command || command);\n\n  if (pluginDef.description) {\n    plugin.description(pluginDef.description);\n  }\n\n  // set options\n  if (pluginDef.options) {\n\n    // default options in abc.json\n    var defaultOpts = loadDefaultOpts(process.cwd(), 'abc.json');\n    var optNameReg = /\\-\\-(\\w+)/;\n    pluginDef.options.forEach(function(optArgs) {\n      if (optArgs) {\n        plugin.option.apply(plugin, optArgs);\n\n        // replace default value with options in abc.json\n        var matches = optNameReg.exec(optArgs[0]);\n        if (matches && matches[1] in defaultOpts) {\n          plugin[matches[1]] = defaultOpts[matches[1]]\n        }\n      }\n    });\n  }\n\n  // set action\n  if (pluginDef.action) {\n    plugin.action(function(cmd, opts) {\n      if (cmd instanceof program.Command) {\n        opts = cmd;\n        cmd = '';\n      }\n      opts = opts || {};\n\n      // run plugin action\n      if (cmd) {\n        pluginDef.action.call(this, cmd, opts);\n      } else {\n        pluginDef.action.call(this, opts);\n      }\n    });\n  }\n\n} else if (!command) { // plugin not found\n\n  var plugins;\n  var pluginPool = {};\n  moduleDirs.forEach(function(modulesDir, index) {\n\n    // search plugins\n    plugins = fs.readdirSync(modulesDir).filter(function(name) {\n\n      // filter by name\n      return /^nowa\\-\\w+$/.test(name);\n    });\n\n    // regist all the plugins\n    plugins.forEach(function(name) {\n\n      // ensure local plugins not be overridden\n      if (!pluginPool[name]) {\n        pluginPool[name] = true;\n\n        // regist a plugin for help\n        var pluginPkg = require(path.join(modulesDir, name, 'package.json'));\n        program\n          .command(name.substring(5))\n          .description(pluginPkg.description + chalk.green(' (v' + pluginPkg.version + ')'));\n      }\n    });\n  });\n\n  // check update of all plugins\n  updateNotifier.apply(null, [ pkg.version ].concat(plugins));\n}\n\n// parse command line arguments\nprogram.parse(argvs);\n\n// output help if no argv specified\nif (!argvs.slice(2).length) {\n  program.outputHelp();\n}\n\n// locate the plugin by command\nfunction findPluginPath(command) {\n  if (command && /^\\w+$/.test(command)) {\n    try {\n      return resolve.sync('nowa-' + command, {\n        paths: moduleDirs\n      });\n    } catch (e) {\n      console.log('');\n      console.log('  ' + chalk.green.bold(command) + ' command is not installed.');\n      console.log('  You can try to install it by ' + chalk.blue.bold('nowa install ' + command) + '.');\n      console.log('');\n    }\n  }\n}\n\n// load default options\nfunction loadDefaultOpts(startDir, configFile) {\n  try {\n    return require(path.join(startDir, configFile)).options || {};\n  } catch (e) {\n    var dir = path.dirname(startDir);\n    if (dir === startDir) {\n      return {};\n    }\n    return loadDefaultOpts(dir, configFile);\n  }\n}\n"
  },
  {
    "path": "src/update-notifier.js",
    "content": "/*\n* @Author: gbk\n* @Date:   2016-06-25 12:42:56\n* @Last Modified by:   gbk\n* @Last Modified time: 2017-06-21 20:53:33\n*/\n\n'use strict';\n\nvar os = require('os');\nvar fs = require('fs');\nvar path = require('path');\nvar spawn = require('child_process').spawn;\n\nvar chalk = require('chalk');\nvar semver = require('semver');\n\nmodule.exports = function() {\n  // do not show update tip inside nowa-gui\n  if (process.env.NOWA_GUI) {\n    return;\n  }\n\n  // check for nowa-gui installation\n  try {\n    fs.statSync(path.join(os.homedir(), '.nowa-gui', 'user_config.json'))\n  } catch (e) {\n    console.log(\n      chalk.yellow(\n        '\\n  Nowa GUI for all platform is available now!' +\n        '\\n  You can download it here:' +\n        '\\n  https://nowa-webpack.github.io/')\n      );\n  }\n\n  // read latest versions\n  var versionsFile = path.join(os.homedir(), '.nowa', 'latest-versions.json');\n  var store = {};\n  try {\n    store = JSON.parse(fs.readFileSync(versionsFile, 'utf-8'));\n  } catch(e) {}\n  var versions = store.versions || {};\n\n  // compare versions and show tip\n  var isTipShow = false;\n  var argvs = Array.prototype.slice.call(arguments, 0);\n  argvs.slice(1).concat([ 'nowa' ]).forEach(function(plugin) {\n    try {\n      var pkg = require(path.join(__dirname, '..', '..', plugin, 'package.json'));\n      if (versions[plugin] && semver.lt(pkg.version, versions[plugin])) {\n        if (plugin === 'nowa') {\n\n          // do not show nowa update tip if any plugins need update\n          if (!isTipShow) {\n            console.log(\n              chalk.yellow(\n                '\\n  Update available: ' +\n                plugin + '@' + versions[plugin] + ' (Current: ' + pkg.version + ')' +\n                '\\n  Run  `npm i nowa -g`  to update.')\n              );\n          }\n        } else {\n          console.log(\n            chalk.yellow(\n              '\\n  Update available: ' +\n              plugin + '@' + versions[plugin] + ' (Current: ' + pkg.version + ')' +\n              '\\n  Run  `nowa install ' + plugin.substring(5) + '`  to update.')\n            );\n        }\n        isTipShow = true;\n      }\n    } catch(e) {\n    }\n  });\n\n  // fetch latest versions\n  spawn(process.execPath, [\n    path.join(__dirname, 'check')\n  ].concat(argvs), {\n    detached: true,\n    stdio: 'ignore'\n  }).unref();\n};\n"
  },
  {
    "path": "uninstall.js",
    "content": "/*\n* @Author: gbk\n* @Date:   2016-06-26 10:38:07\n* @Last Modified by:   gbk\n* @Last Modified time: 2017-03-20 10:51:44\n*/\n\n'use strict';\n\nvar os = require('os');\nvar path = require('path');\nvar exec = require('child_process').execSync;\n\nvar configRoot = path.join(os.homedir(), '.nowa');\nvar rimrafPath = path.join(configRoot, 'install', '.bin', 'rimraf');\nvar installMods = path.join(configRoot, 'install', '*');\nexec('node ' + rimrafPath + ' ../nowa-* ' + installMods);\n"
  }
]