init.js 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. "use strict";
  2. var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
  3. function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
  4. return new (P || (P = Promise))(function (resolve, reject) {
  5. function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
  6. function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
  7. function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
  8. step((generator = generator.apply(thisArg, _arguments || [])).next());
  9. });
  10. };
  11. var __importDefault = (this && this.__importDefault) || function (mod) {
  12. return (mod && mod.__esModule) ? mod : { "default": mod };
  13. };
  14. Object.defineProperty(exports, "__esModule", { value: true });
  15. exports.exec = void 0;
  16. const child_process_1 = require("child_process");
  17. const fs_1 = __importDefault(require("fs"));
  18. const path_1 = __importDefault(require("path"));
  19. const util_1 = __importDefault(require("util"));
  20. const MAX_BUFFER = 10 * Math.pow(2, 20);
  21. function exec(command, stdout, stderr) {
  22. return new Promise((resolve, reject) => {
  23. try {
  24. let stdoutbuf = '';
  25. let stderrbuf = '';
  26. // EXEC CHILD PROCESS
  27. const p = (0, child_process_1.exec)(command, { maxBuffer: MAX_BUFFER }, (err, out) => {
  28. if (err)
  29. return reject(err);
  30. if (stdoutbuf.length > 0 && typeof stdout === 'function')
  31. stdout(stdoutbuf);
  32. if (stderrbuf.length > 0 && typeof stderr === 'function')
  33. stderr(stderrbuf);
  34. resolve(out);
  35. });
  36. // PIPE STDOUT
  37. if (typeof stdout === 'function') {
  38. p.stdout.on('data', chunk => {
  39. stdoutbuf += chunk;
  40. let i = -1;
  41. while ((i = stdoutbuf.indexOf('\n')) >= 0) {
  42. const line = stdoutbuf.substring(0, i);
  43. stdoutbuf = stdoutbuf.substring(i + 1);
  44. if (typeof stdout === 'function') {
  45. stdout(line);
  46. }
  47. }
  48. });
  49. }
  50. else if (typeof stdout !== 'undefined') {
  51. p.stdout.pipe(stdout);
  52. }
  53. // PIPE STDERR
  54. if (typeof stderr === 'function') {
  55. p.stderr.on('data', chunk => {
  56. stderrbuf += chunk;
  57. let i = -1;
  58. while ((i = stderrbuf.indexOf('\n')) >= 0) {
  59. const line = stderrbuf.substring(0, i);
  60. stderrbuf = stderrbuf.substring(i + 1);
  61. if (typeof stderr === 'function') {
  62. stderr(line);
  63. }
  64. }
  65. });
  66. }
  67. else if (typeof stderr !== 'undefined') {
  68. p.stderr.pipe(stderr);
  69. }
  70. }
  71. catch (err) {
  72. reject(err);
  73. }
  74. });
  75. }
  76. exports.exec = exec;
  77. const cli = {
  78. blue: v => `\x1b[34m${v}\x1b[0m`,
  79. green: v => `\x1b[32m${v}\x1b[0m`,
  80. yellow: v => `\x1b[33m${v}\x1b[0m`,
  81. red: v => `\x1b[31m${v}\x1b[0m`
  82. };
  83. function readFile(path, encoding = 'utf8') {
  84. return __awaiter(this, void 0, void 0, function* () {
  85. return new Promise((resolve, reject) => {
  86. fs_1.default.readFile(path, { encoding }, (err, data) => {
  87. if (err)
  88. return reject(err);
  89. try {
  90. resolve(data.toString());
  91. }
  92. catch (e) {
  93. reject(e);
  94. }
  95. });
  96. });
  97. });
  98. }
  99. function readJsonFile(path, encoding = 'utf8') {
  100. return __awaiter(this, void 0, void 0, function* () {
  101. return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
  102. try {
  103. resolve(JSON.parse(yield readFile(path, encoding)));
  104. }
  105. catch (e) {
  106. reject(e);
  107. }
  108. }));
  109. });
  110. }
  111. (() => __awaiter(void 0, void 0, void 0, function* () {
  112. try {
  113. const projectRootDir = path_1.default.resolve(process.cwd());
  114. if (!fs_1.default.existsSync(path_1.default.resolve(projectRootDir, 'package.json'))) {
  115. console.log(cli.blue('[INFO]'), 'Not an NPM project yet - initializing...');
  116. yield exec('npm init -y', process.stdout, process.stderr);
  117. }
  118. const cloneDir = path_1.default.resolve(projectRootDir, '.clone');
  119. if (fs_1.default.existsSync(cloneDir)) {
  120. console.log(cli.blue('[WARNING]'), `There's an old .clone directory. Removing first...`);
  121. yield util_1.default.promisify(fs_1.default.rm)(cloneDir, { force: true, recursive: true });
  122. }
  123. console.log(cli.blue('[INFO]'), 'Cloning boilerplate repository (via HTTPS)...');
  124. yield exec(`git clone https://gogs.hostbbq.com/hostbbq/express-starter.git "${cloneDir}"`, process.stdout, process.stderr);
  125. let pkgJson = yield readJsonFile(path_1.default.resolve(cloneDir, 'package.json'));
  126. console.log(cli.blue('[INFO]'), 'Installing module dependencies...');
  127. let dependencies = Object.keys(pkgJson.dependencies).join('" "');
  128. yield exec(`npm install "${dependencies}"`, process.stdout, process.stderr);
  129. dependencies = Object.keys(pkgJson.devDependencies).join('" "');
  130. yield exec(`npm install --save-dev "${dependencies}"`, process.stdout, process.stderr);
  131. console.log(cli.blue('[INFO]'), 'Copying project files...');
  132. const copyFiles = ['.env', '.gitignore', '.prettierrc.js', 'tsconfig.json', '.vscode/settings.json', 'src', 'public', 'private'];
  133. for (const cpFile of copyFiles) {
  134. const sourceFile = path_1.default.resolve(cloneDir, cpFile);
  135. const targetFile = path_1.default.resolve(projectRootDir, cpFile);
  136. const targetDir = path_1.default.dirname(targetFile);
  137. if (!fs_1.default.existsSync(targetDir)) {
  138. yield util_1.default.promisify(fs_1.default.mkdir)(targetDir, { recursive: true, mode: 0o777 });
  139. }
  140. const stat = yield util_1.default.promisify(fs_1.default.stat)(sourceFile);
  141. if (stat.isFile()) {
  142. yield util_1.default.promisify(fs_1.default.copyFile)(sourceFile, targetFile);
  143. }
  144. else {
  145. yield exec(`cp -r "${sourceFile}" "${targetFile}"`);
  146. }
  147. }
  148. console.log(cli.blue('[INFO]'), 'Creating startup script');
  149. pkgJson = yield readJsonFile(path_1.default.resolve(projectRootDir, 'package.json'));
  150. pkgJson.scripts = Object.assign(Object.assign({}, pkgJson.scripts), { build: 'tsc -b', start: 'npm run build && node dist/index.js' });
  151. yield util_1.default.promisify(fs_1.default.writeFile)(path_1.default.resolve(projectRootDir, 'package.json'), JSON.stringify(pkgJson, null, 2));
  152. console.log(cli.blue('[INFO]'), 'Creating chat data directory');
  153. yield util_1.default.promisify(fs_1.default.mkdir)(path_1.default.resolve(projectRootDir, 'chatdata'));
  154. console.log(cli.blue('[INFO]'), 'Cleanup: Removing .clone directory...');
  155. yield util_1.default.promisify(fs_1.default.rm)(cloneDir, { force: true, recursive: true });
  156. console.log();
  157. console.log(cli.green('[SUCCESS] You can now start your express server with `npm start`'));
  158. process.exit(0);
  159. }
  160. catch (e) {
  161. console.error(e);
  162. process.exit(1);
  163. }
  164. }))();