bin.js 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. #!/usr/bin/env node
  2. "use strict";
  3. Object.defineProperty(exports, "__esModule", { value: true });
  4. exports.BsErrorTypes = exports.BsErrorLevels = void 0;
  5. const startOpts = require("../cli-options/opts.start.json");
  6. const reloadOpts = require("../cli-options/opts.reload.json");
  7. const recipeOpts = require("../cli-options/opts.recipe.json");
  8. const pkg = require("../package.json");
  9. const utils = require("./utils");
  10. const path_1 = require("path");
  11. const fs_1 = require("fs");
  12. const logger_1 = require("./logger");
  13. const eazy_logger_1 = require("eazy-logger");
  14. const cli_options_1 = require("./cli/cli-options");
  15. var BsErrorLevels;
  16. (function (BsErrorLevels) {
  17. BsErrorLevels["Fatal"] = "Fatal";
  18. })(BsErrorLevels = exports.BsErrorLevels || (exports.BsErrorLevels = {}));
  19. var BsErrorTypes;
  20. (function (BsErrorTypes) {
  21. BsErrorTypes["PathNotFound"] = "PathNotFound";
  22. BsErrorTypes["HostAndListenIncompatible"] = "HostAndListenIncompatible";
  23. })(BsErrorTypes = exports.BsErrorTypes || (exports.BsErrorTypes = {}));
  24. /**
  25. * Handle cli input
  26. */
  27. if (!module.parent) {
  28. runFromCli();
  29. }
  30. function freshYargs() {
  31. return require("yargs")(process.argv.slice(2));
  32. }
  33. function runFromCli() {
  34. const yargs = freshYargs()
  35. .command("start", "Start the server")
  36. .command("init", "Create a configuration file")
  37. .command("reload", "Send a reload event over HTTP protocol")
  38. .command("recipe", "Generate the files for a recipe")
  39. .version(pkg.version)
  40. .help(false)
  41. .epilogue([
  42. "For help running a certain command, type <command> --help",
  43. " $0 start --help",
  44. "",
  45. "You can run a static server by providing a path(s) directly",
  46. " $0 app/src app/tmp",
  47. "",
  48. "If the directory contains a 'index.html' file, you can omit any input",
  49. " $0",
  50. "",
  51. "You can run the proxy in this manner too",
  52. " $0 https://example.com",
  53. "",
  54. "To run a proxy, whilst also serving static files",
  55. (0, eazy_logger_1.compile)(" $0 https://example.com htdocs/themes/example")
  56. ].join("\n"));
  57. const argv = yargs.argv;
  58. const input = argv._;
  59. const command = input[0];
  60. const valid = ["start", "init", "reload", "recipe"];
  61. if (valid.indexOf(command) > -1) {
  62. return handleIncoming(command, freshYargs());
  63. }
  64. if (input.length) {
  65. return handleNoCommand(argv, input, freshYargs());
  66. }
  67. if ((0, fs_1.existsSync)("index.html")) {
  68. return handleNoCommand(argv, ["."], freshYargs());
  69. }
  70. yargs.showHelp();
  71. }
  72. /**
  73. * Feature: If no command was specified, try to do the 'right thing'
  74. *
  75. * If paths were given, start the server
  76. * eg: browser-sync app/code app/design
  77. * is equal to: browser-sync start --server app/code app/design
  78. *
  79. * eg: browser-sync http://example.com
  80. * is equal to: browser-sync start --proxy http://example.com
  81. *
  82. * eg: browser-sync http://example.com themes/example
  83. * is equal to: browser-sync start --proxy http://example.com --ss themes/example
  84. *
  85. * @param argv
  86. * @param input
  87. * @returns {any}
  88. */
  89. function handleNoCommand(argv, input, yargs) {
  90. const processed = processStart(yargs);
  91. const paths = input.map(path => {
  92. const resolved = (0, path_1.resolve)(path);
  93. const isUrl = /^https?:\/\//.test(path);
  94. return {
  95. isUrl,
  96. userInput: path,
  97. resolved,
  98. errors: isUrl ? [] : pathErrors(path, resolved)
  99. };
  100. });
  101. const withErrors = paths.filter(item => item.errors.length);
  102. const withoutErrors = paths.filter(item => item.errors.length === 0);
  103. if (withErrors.length) {
  104. withErrors.forEach(item => {
  105. logger_1.logger.unprefixed("error", (0, cli_options_1.printErrors)(item.errors));
  106. });
  107. return process.exit(1);
  108. }
  109. const serveStaticPaths = withoutErrors
  110. .filter(item => item.isUrl === false)
  111. .map(item => item.resolved);
  112. const urls = withoutErrors
  113. .filter(item => item.isUrl === true)
  114. .map(item => item.userInput);
  115. /**
  116. * If a URL was given, switch to proxy mode and use
  117. * any other paths as serveStatic options
  118. */
  119. if (urls.length) {
  120. const proxy = urls[0];
  121. const config = Object.assign(Object.assign({}, processed), { proxy, serveStatic: serveStaticPaths });
  122. return handleCli({ cli: { flags: config, input: ["start"] } });
  123. }
  124. /**
  125. * if NO urls were given switch directly to server mode
  126. * @type {{server: {baseDir: any}}}
  127. */
  128. const config = Object.assign(Object.assign({}, processed), { server: { baseDir: serveStaticPaths } });
  129. return handleCli({ cli: { flags: config, input: ["start"] } });
  130. }
  131. /**
  132. * @param {{cli: object, [whitelist]: array, [cb]: function}} opts
  133. * @returns {*}
  134. */
  135. function handleCli(opts) {
  136. opts.cb = opts.cb || utils.defaultCallback;
  137. const m = require(`./cli/command.${opts.cli.input[0]}`);
  138. if (m.default) {
  139. return m.default(opts);
  140. }
  141. return m(opts);
  142. }
  143. exports.default = handleCli;
  144. function processStart(yargs) {
  145. return yargs
  146. .usage("Usage: $0 start [options]")
  147. .options(startOpts)
  148. .example("$0 start -s app", "- Use the App directory to serve files")
  149. .example("$0 start -p www.bbc.co.uk", "- Proxy an existing website")
  150. .default("cwd", () => process.cwd())
  151. .argv;
  152. }
  153. /**
  154. * @param {string} command
  155. * @param {object} yargs
  156. * @param cwd
  157. */
  158. function handleIncoming(command, yargs) {
  159. let out;
  160. if (command === "start") {
  161. out = processStart(yargs);
  162. }
  163. if (command === "init") {
  164. out = yargs
  165. .usage("Usage: $0 init")
  166. .example("$0 init")
  167. .default("cwd", () => process.cwd())
  168. .help().argv;
  169. }
  170. if (command === "reload") {
  171. out = yargs
  172. .usage("Usage: $0 reload")
  173. .options(reloadOpts)
  174. .example("$0 reload")
  175. .example("$0 reload --port 4000")
  176. .default("cwd", () => process.cwd())
  177. .argv;
  178. }
  179. if (command === "recipe") {
  180. out = yargs
  181. .usage("Usage: $0 recipe <recipe-name>")
  182. .option(recipeOpts)
  183. .example("$0 recipe ls", "list the recipes")
  184. .example("$0 recipe gulp.sass", "use the gulp.sass recipe")
  185. .default("cwd", () => process.cwd())
  186. .argv;
  187. }
  188. if (out.help) {
  189. return yargs.showHelp();
  190. }
  191. handleCli({ cli: { flags: out, input: out._ } });
  192. }
  193. function pathErrors(input, resolved) {
  194. if (!(0, fs_1.existsSync)(resolved)) {
  195. return [
  196. {
  197. type: BsErrorTypes.PathNotFound,
  198. level: BsErrorLevels.Fatal,
  199. errors: [
  200. {
  201. error: new Error(`Path not found: ${input}`),
  202. meta() {
  203. return [
  204. `Your Input: {yellow:${input}}`,
  205. `CWD: {yellow:${process.cwd()}}`,
  206. `Resolved to: {yellow:${resolved}}`
  207. ];
  208. }
  209. }
  210. ]
  211. }
  212. ];
  213. }
  214. return [];
  215. }
  216. //# sourceMappingURL=bin.js.map