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 | Object.defineProperty(exports, "__esModule", { value: true });
|
12 | exports.exit = exports.retrieveCols = exports.NewAction = void 0;
|
13 | const chalk = require("chalk");
|
14 | const child_process_1 = require("child_process");
|
15 | const fs = require("fs");
|
16 | const inquirer = require("inquirer");
|
17 | const path_1 = require("path");
|
18 | const defaults_1 = require("../lib/configuration/defaults");
|
19 | const package_managers_1 = require("../lib/package-managers");
|
20 | const questions_1 = require("../lib/questions/questions");
|
21 | const git_runner_1 = require("../lib/runners/git.runner");
|
22 | const schematics_1 = require("../lib/schematics");
|
23 | const ui_1 = require("../lib/ui");
|
24 | const formatting_1 = require("../lib/utils/formatting");
|
25 | const abstract_action_1 = require("./abstract.action");
|
26 | class NewAction extends abstract_action_1.AbstractAction {
|
27 | handle(inputs, options) {
|
28 | return __awaiter(this, void 0, void 0, function* () {
|
29 | const directoryOption = options.find((option) => option.name === 'directory');
|
30 | const dryRunOption = options.find((option) => option.name === 'dry-run');
|
31 | const isDryRunEnabled = dryRunOption && dryRunOption.value;
|
32 | yield askForMissingInformation(inputs, options);
|
33 | yield generateApplicationFiles(inputs, options).catch(exports.exit);
|
34 | const shouldSkipInstall = options.some((option) => option.name === 'skip-install' && option.value === true);
|
35 | const shouldSkipGit = options.some((option) => option.name === 'skip-git' && option.value === true);
|
36 | const projectDirectory = getProjectDirectory(getApplicationNameInput(inputs), directoryOption);
|
37 | if (!shouldSkipInstall) {
|
38 | yield installPackages(options, isDryRunEnabled, projectDirectory);
|
39 | }
|
40 | if (!isDryRunEnabled) {
|
41 | if (!shouldSkipGit) {
|
42 | yield initializeGitRepository(projectDirectory);
|
43 | yield createGitIgnoreFile(projectDirectory);
|
44 | }
|
45 | printCollective();
|
46 | }
|
47 | process.exit(0);
|
48 | });
|
49 | }
|
50 | }
|
51 | exports.NewAction = NewAction;
|
52 | const getApplicationNameInput = (inputs) => inputs.find((input) => input.name === 'name');
|
53 | const getPackageManagerInput = (inputs) => inputs.find((options) => options.name === 'packageManager');
|
54 | const getProjectDirectory = (applicationName, directoryOption) => {
|
55 | return ((directoryOption && directoryOption.value) ||
|
56 | (0, formatting_1.normalizeToKebabOrSnakeCase)(applicationName.value));
|
57 | };
|
58 | const askForMissingInformation = (inputs, options) => __awaiter(void 0, void 0, void 0, function* () {
|
59 | console.info(ui_1.MESSAGES.PROJECT_INFORMATION_START);
|
60 | console.info();
|
61 | const prompt = inquirer.createPromptModule();
|
62 | const nameInput = getApplicationNameInput(inputs);
|
63 | if (!nameInput.value) {
|
64 | const message = 'What name would you like to use for the new project?';
|
65 | const questions = [(0, questions_1.generateInput)('name', message)('nest-app')];
|
66 | const answers = yield prompt(questions);
|
67 | replaceInputMissingInformation(inputs, answers);
|
68 | }
|
69 | const packageManagerInput = getPackageManagerInput(options);
|
70 | if (!packageManagerInput.value) {
|
71 | const answers = yield askForPackageManager();
|
72 | replaceInputMissingInformation(options, answers);
|
73 | }
|
74 | });
|
75 | const replaceInputMissingInformation = (inputs, answers) => {
|
76 | return inputs.map((input) => (input.value =
|
77 | input.value !== undefined ? input.value : answers[input.name]));
|
78 | };
|
79 | const generateApplicationFiles = (args, options) => __awaiter(void 0, void 0, void 0, function* () {
|
80 | const collectionName = options.find((option) => option.name === 'collection' && option.value != null).value;
|
81 | const collection = schematics_1.CollectionFactory.create(collectionName || schematics_1.Collection.NESTJS);
|
82 | const schematicOptions = mapSchematicOptions(args.concat(options));
|
83 | yield collection.execute('application', schematicOptions);
|
84 | console.info();
|
85 | });
|
86 | const mapSchematicOptions = (options) => {
|
87 | return options.reduce((schematicOptions, option) => {
|
88 | if (option.name !== 'skip-install') {
|
89 | schematicOptions.push(new schematics_1.SchematicOption(option.name, option.value));
|
90 | }
|
91 | return schematicOptions;
|
92 | }, []);
|
93 | };
|
94 | const installPackages = (options, dryRunMode, installDirectory) => __awaiter(void 0, void 0, void 0, function* () {
|
95 | const inputPackageManager = getPackageManagerInput(options).value;
|
96 | let packageManager;
|
97 | if (dryRunMode) {
|
98 | console.info();
|
99 | console.info(chalk.green(ui_1.MESSAGES.DRY_RUN_MODE));
|
100 | console.info();
|
101 | return;
|
102 | }
|
103 | try {
|
104 | packageManager = package_managers_1.PackageManagerFactory.create(inputPackageManager);
|
105 | yield packageManager.install(installDirectory, inputPackageManager);
|
106 | }
|
107 | catch (error) {
|
108 | if (error && error.message) {
|
109 | console.error(chalk.red(error.message));
|
110 | }
|
111 | }
|
112 | });
|
113 | const askForPackageManager = () => __awaiter(void 0, void 0, void 0, function* () {
|
114 | const questions = [
|
115 | (0, questions_1.generateSelect)('packageManager')(ui_1.MESSAGES.PACKAGE_MANAGER_QUESTION)([
|
116 | package_managers_1.PackageManager.NPM,
|
117 | package_managers_1.PackageManager.YARN,
|
118 | package_managers_1.PackageManager.PNPM,
|
119 | ]),
|
120 | ];
|
121 | const prompt = inquirer.createPromptModule();
|
122 | return yield prompt(questions);
|
123 | });
|
124 | const initializeGitRepository = (dir) => __awaiter(void 0, void 0, void 0, function* () {
|
125 | const runner = new git_runner_1.GitRunner();
|
126 | yield runner.run('init', true, (0, path_1.join)(process.cwd(), dir)).catch(() => {
|
127 | console.error(chalk.red(ui_1.MESSAGES.GIT_INITIALIZATION_ERROR));
|
128 | });
|
129 | });
|
130 |
|
131 |
|
132 |
|
133 |
|
134 |
|
135 |
|
136 |
|
137 |
|
138 |
|
139 |
|
140 | const createGitIgnoreFile = (dir, content) => {
|
141 | const fileContent = content || defaults_1.defaultGitIgnore;
|
142 | const filePath = (0, path_1.join)(process.cwd(), dir, '.gitignore');
|
143 | if (fileExists(filePath)) {
|
144 | return;
|
145 | }
|
146 | return fs.promises.writeFile(filePath, fileContent);
|
147 | };
|
148 | const printCollective = () => {
|
149 | const dim = print('dim');
|
150 | const yellow = print('yellow');
|
151 | const emptyLine = print();
|
152 | emptyLine();
|
153 | yellow(`Thanks for installing Nest ${ui_1.EMOJIS.PRAY}`);
|
154 | dim('Please consider donating to our open collective');
|
155 | dim('to help us maintain this package.');
|
156 | emptyLine();
|
157 | emptyLine();
|
158 | print()(`${chalk.bold(`${ui_1.EMOJIS.WINE} Donate:`)} ${chalk.underline('https://opencollective.com/nest')}`);
|
159 | emptyLine();
|
160 | };
|
161 | const print = (color = null) => (str = '') => {
|
162 | const terminalCols = (0, exports.retrieveCols)();
|
163 | const strLength = str.replace(/\u001b\[[0-9]{2}m/g, '').length;
|
164 | const leftPaddingLength = Math.floor((terminalCols - strLength) / 2);
|
165 | const leftPadding = ' '.repeat(Math.max(leftPaddingLength, 0));
|
166 | if (color) {
|
167 | str = chalk[color](str);
|
168 | }
|
169 | console.log(leftPadding, str);
|
170 | };
|
171 | const retrieveCols = () => {
|
172 | const defaultCols = 80;
|
173 | try {
|
174 | const terminalCols = (0, child_process_1.execSync)('tput cols', {
|
175 | stdio: ['pipe', 'pipe', 'ignore'],
|
176 | });
|
177 | return parseInt(terminalCols.toString(), 10) || defaultCols;
|
178 | }
|
179 | catch (_a) {
|
180 | return defaultCols;
|
181 | }
|
182 | };
|
183 | exports.retrieveCols = retrieveCols;
|
184 | const fileExists = (path) => {
|
185 | try {
|
186 | fs.accessSync(path);
|
187 | return true;
|
188 | }
|
189 | catch (err) {
|
190 | if (err.code === 'ENOENT') {
|
191 | return false;
|
192 | }
|
193 | throw err;
|
194 | }
|
195 | };
|
196 | const exit = () => process.exit(1);
|
197 | exports.exit = exit;
|