1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const tslib_1 = require("tslib");
|
4 | const fs = require("fs-extra");
|
5 | const lazy_get_decorator_1 = require("lazy-get-decorator");
|
6 | const lodash_1 = require("lodash");
|
7 | const rl$ = require("readline-sync");
|
8 | const IS_CI_1 = require("../const/IS_CI");
|
9 | const lastDirname_1 = require("../fns/lastDirname");
|
10 | const readJson_1 = require("../fns/readJson");
|
11 | const License_1 = require("../inc/License");
|
12 | const PackageManager_1 = require("../inc/PackageManager");
|
13 | const Colour_1 = require("./Colour");
|
14 | const Git_1 = require("./Git");
|
15 | const gh_repo_1 = require("./sync-request/gh-repo/gh-repo");
|
16 | let rl;
|
17 | if (IS_CI_1.IS_CI) {
|
18 | rl = lodash_1.cloneDeep(rl$);
|
19 | function throwError() {
|
20 | throw new Error('Unable to prompt in test environment; Please set full configuration.');
|
21 | }
|
22 | for (const k of Object.keys(rl)) {
|
23 | if (typeof rl[k] === 'function') {
|
24 | rl[k] = throwError;
|
25 | }
|
26 | }
|
27 | }
|
28 | else {
|
29 | rl = rl$;
|
30 | }
|
31 | const memoisedFnNames = [];
|
32 | function Memo(_target, prop) {
|
33 | memoisedFnNames.push(prop);
|
34 | }
|
35 | class PromptableConfig {
|
36 | constructor(data) {
|
37 | this.data = data;
|
38 | for (const fn of memoisedFnNames) {
|
39 | this[fn] = lodash_1.memoize(this[fn]);
|
40 | }
|
41 | }
|
42 |
|
43 | static get readline() {
|
44 | return rl;
|
45 | }
|
46 | get ghRepoFromMetadata() {
|
47 | if (this.ghMetadata) {
|
48 | return this.ghMetadata.repo;
|
49 | }
|
50 | return null;
|
51 | }
|
52 | get ghUserFromMetadata() {
|
53 | if (this.ghMetadata) {
|
54 | return this.ghMetadata.user;
|
55 | }
|
56 | return null;
|
57 | }
|
58 | get ghMetadata() {
|
59 | try {
|
60 | if (Git_1.Git.originUrl) {
|
61 | const match = /([a-z0-9-_.]+)\/([a-z0-9-_.]+)\.git/i.exec(Git_1.Git.originUrl);
|
62 | if (match) {
|
63 | return {
|
64 | repo: match[2],
|
65 | user: match[1]
|
66 | };
|
67 | }
|
68 | }
|
69 | return null;
|
70 | }
|
71 | catch (_a) {
|
72 | return null;
|
73 | }
|
74 | }
|
75 | get(k) {
|
76 | return this.data[k];
|
77 | }
|
78 | has(k, strict = true) {
|
79 | return strict ? this.data[k] !== undefined : !!this.data[k];
|
80 | }
|
81 | promptedEmail(prop = 'email') {
|
82 | return this.getPromptEmail(prop, 'What\'s your email? ');
|
83 | }
|
84 | promptedEncryptionPassword(prop = 'password') {
|
85 | return this.getPromptHidden(prop, 'Encryption password: ');
|
86 | }
|
87 | promptedGhEmail(prop = 'ghEmail') {
|
88 | return this.getPromptEmail(prop, 'What\'s GitHub your email? ');
|
89 | }
|
90 | promptedGhRepo(prop = 'ghRepo') {
|
91 | let msg = 'What is your GitHub repo';
|
92 | if (this.has(prop)) {
|
93 | return this.get(prop);
|
94 | }
|
95 | else if (!IS_CI_1.IS_CI && this.ghRepoFromMetadata) {
|
96 | if (rl.keyInYNStrict(`Is your GitHub repo ${Colour_1.Colour.cyan(this.ghRepoFromMetadata)}? `)) {
|
97 | this.data[prop] = this.ghRepoFromMetadata;
|
98 | return this.ghRepoFromMetadata;
|
99 | }
|
100 | else {
|
101 | return this.getPrompt(prop, `${msg} then? `);
|
102 | }
|
103 | }
|
104 | return this.getPrompt(prop, `${msg}? `);
|
105 | }
|
106 | promptedGhToken(prop = 'ghToken') {
|
107 | return this.getPromptHidden(prop, [
|
108 | 'What\'s your global GitHub token used only by this CLI tool?',
|
109 | `You can create one here: ${"https://github.com/settings/tokens/new" /* GH_TOK_URL */} `
|
110 | ].join(' '));
|
111 | }
|
112 | promptedGhUser(prop = 'ghUser') {
|
113 | let msg = 'What is your GitHub username';
|
114 | if (this.has(prop)) {
|
115 | return this.get(prop);
|
116 | }
|
117 | else if (!IS_CI_1.IS_CI && this.ghUserFromMetadata) {
|
118 | if (rl.keyInYNStrict(`Is your GitHub username ${Colour_1.Colour.cyan(this.ghUserFromMetadata)}? `)) {
|
119 | this.data[prop] = this.ghUserFromMetadata;
|
120 | return this.ghUserFromMetadata;
|
121 | }
|
122 | else {
|
123 | return this.getPrompt(prop, `${msg} then? `);
|
124 | }
|
125 | }
|
126 | return this.getPrompt(prop, `${msg}? `);
|
127 | }
|
128 | promptedGpgKeyId(prop = 'gpgKeyId') {
|
129 | return this.getPromptHidden(prop, 'What\'s GPG key ID? ');
|
130 | }
|
131 | promptedGpgKeyPwd(prop = 'gpgKeyPwd') {
|
132 | return this.getPromptHidden(prop, 'What\'s GPG key password? ');
|
133 | }
|
134 | promptedGpgPrivkey(prop = 'gpgPrivkey') {
|
135 | return this.getPromptHidden(prop, 'Paste your GPG private key contents: ');
|
136 | }
|
137 | promptedGpgPubkey(prop = 'gpgPubkey') {
|
138 | return this.getPrompt(prop, 'Paste your GPG public key contents: ');
|
139 | }
|
140 | promptedLicense(prop = 'license') {
|
141 | let pjson;
|
142 | if (this.has(prop)) {
|
143 | return this.get(prop);
|
144 | }
|
145 | else if ((pjson = readJson_1.readJson()) && License_1.isLicense(pjson.license)) {
|
146 | this.data[prop] = pjson.license;
|
147 | return pjson.license;
|
148 | }
|
149 | return this.getPromptSelect(prop, 'What license do you with to use? ', License_1.LICENSE_VALUES);
|
150 | }
|
151 | promptedName(prop = 'name') {
|
152 | return this.getPrompt(prop, 'What\'s your name? ');
|
153 | }
|
154 | promptedPkgMgr(prop = 'pkgMgr') {
|
155 | if (this.has(prop)) {
|
156 | return this.get(prop);
|
157 | }
|
158 | const files = fs.readdirSync(process.cwd(), 'utf8');
|
159 | if (files.includes('yarn.lock')) {
|
160 | return PackageManager_1.PackageManager.YARN;
|
161 | }
|
162 | else if (files.includes('package-lock.json')) {
|
163 | return PackageManager_1.PackageManager.NPM;
|
164 | }
|
165 | else {
|
166 | return this.getPromptSelect(prop, 'What package manager do you want to use? ', PackageManager_1.PACKAGE_MANAGERS);
|
167 | }
|
168 | }
|
169 | promptedProjectDescription(prop = 'projectDesc') {
|
170 | if (this.has(prop)) {
|
171 | return this.get(prop);
|
172 | }
|
173 | const tok = this.promptedGhToken();
|
174 | const repo = this.promptedGhRepo();
|
175 | const user = this.promptedGhUser();
|
176 | const ghProjRemote = gh_repo_1.getGhRepoData(tok, user, repo);
|
177 | if (ghProjRemote && ghProjRemote.description) {
|
178 | this.data[prop] = ghProjRemote.description;
|
179 | return this.data[prop];
|
180 | }
|
181 | return this.getPrompt(prop, 'What\'s your project description? ');
|
182 | }
|
183 | promptedProjectKeywords(prop = 'projectKeywords') {
|
184 | return this.getPromptArray(prop, 'What are your project keywords?');
|
185 | }
|
186 | promptedProjectName(prop = 'projectName') {
|
187 | const ask = (opt) => rl.keyInYNStrict(`Is your project name ${Colour_1.Colour.cyan(opt)}? `);
|
188 | let dir;
|
189 | if (this.has(prop)) {
|
190 | return this.get(prop);
|
191 | }
|
192 | else if (this.ghRepoFromMetadata && ask(this.ghRepoFromMetadata)) {
|
193 | this.data[prop] = this.ghRepoFromMetadata;
|
194 | return this.ghRepoFromMetadata;
|
195 | }
|
196 | else if (ask((dir = lastDirname_1.lastDirname()))) {
|
197 | this.data[prop] = dir;
|
198 | return dir;
|
199 | }
|
200 | else {
|
201 | return this.getPrompt(prop, 'What is your project name then? ');
|
202 | }
|
203 | }
|
204 | promptedReleaseGhToken(prop = 'releaseGhToken') {
|
205 | return this.getPromptHidden(prop, [
|
206 | 'What\'s your release GitHub token?',
|
207 | `You can create one here: ${"https://github.com/settings/tokens/new" /* GH_TOK_URL */} `
|
208 | ].join(' '));
|
209 | }
|
210 | promptedReleaseNpmToken(prop = 'releaseNpmToken') {
|
211 | return this.getPromptHidden(prop, 'What\'s your release NPM token? ');
|
212 | }
|
213 | promptedTravisTokenOrg(prop = 'travisTokenOrg') {
|
214 | return this.getPromptHidden(prop, 'What\'s your travis-ci token? ');
|
215 | }
|
216 | promptedTravisTokenPro(prop = 'travisTokenPro') {
|
217 | return this.getPromptHidden(prop, 'What\'s your travis-ci token? ');
|
218 | }
|
219 | promptedUserWebsite(prop = 'userWebsite') {
|
220 | return this.getPromptEmail(prop, 'What\'s your name? ');
|
221 | }
|
222 | getPrompt(k, question, forbidEmpty = true, strict = true) {
|
223 | return this.promptCommon(k, () => rl.question(question), forbidEmpty, strict);
|
224 | }
|
225 | getPromptArray(k, question, forbidEmpty = true) {
|
226 | if (!lodash_1.isEmpty(this.get(k))) {
|
227 | return this.get(k);
|
228 | }
|
229 | const out = [];
|
230 | const run = () => {
|
231 | console.log(question);
|
232 | console.log('Enter an empty line when done');
|
233 | let response;
|
234 | do {
|
235 | response = rl.question('').trim();
|
236 | if (response) {
|
237 | out.push(response);
|
238 | }
|
239 | } while (response);
|
240 | if (forbidEmpty && !out.length) {
|
241 | run();
|
242 | }
|
243 | };
|
244 | run();
|
245 | this.data[k] = out;
|
246 | return out;
|
247 | }
|
248 | getPromptEmail(k, question, forbidEmpty = true, strict = true) {
|
249 | return this.promptCommon(k, () => rl.questionEMail(question), forbidEmpty, strict);
|
250 | }
|
251 | getPromptHidden(k, question, forbidEmpty = true, strict = true) {
|
252 | return this.promptCommon(k, () => rl.question(question, { hideEchoBack: true, cancel: true }), forbidEmpty, strict);
|
253 | }
|
254 | getPromptSelect(k, question, opts, strict = true) {
|
255 | if (this.has(k, strict)) {
|
256 | return this.data[k];
|
257 | }
|
258 | else {
|
259 | const idx = rl.keyInSelect(opts, question, { cancel: false });
|
260 | this.data[k] = opts[idx];
|
261 | return this.data[k];
|
262 | }
|
263 | }
|
264 | promptCommon(k, askFn, forbidEmpty, strict) {
|
265 | if (this.has(k, strict)) {
|
266 | return this.data[k];
|
267 | }
|
268 | else if (forbidEmpty) {
|
269 | let v;
|
270 | do {
|
271 | v = askFn();
|
272 | } while (!v);
|
273 | this.data[k] = v;
|
274 | return this.data[k];
|
275 | }
|
276 | else {
|
277 | this.data[k] = askFn();
|
278 | return this.data[k];
|
279 | }
|
280 | }
|
281 | }
|
282 | tslib_1.__decorate([
|
283 | lazy_get_decorator_1.LazyGetter(true),
|
284 | tslib_1.__metadata("design:type", Object),
|
285 | tslib_1.__metadata("design:paramtypes", [])
|
286 | ], PromptableConfig.prototype, "ghRepoFromMetadata", null);
|
287 | tslib_1.__decorate([
|
288 | lazy_get_decorator_1.LazyGetter(true),
|
289 | tslib_1.__metadata("design:type", Object),
|
290 | tslib_1.__metadata("design:paramtypes", [])
|
291 | ], PromptableConfig.prototype, "ghUserFromMetadata", null);
|
292 | tslib_1.__decorate([
|
293 | lazy_get_decorator_1.LazyGetter(true),
|
294 | tslib_1.__metadata("design:type", Object),
|
295 | tslib_1.__metadata("design:paramtypes", [])
|
296 | ], PromptableConfig.prototype, "ghMetadata", null);
|
297 | tslib_1.__decorate([
|
298 | Memo,
|
299 | tslib_1.__metadata("design:type", Function),
|
300 | tslib_1.__metadata("design:paramtypes", [Object]),
|
301 | tslib_1.__metadata("design:returntype", String)
|
302 | ], PromptableConfig.prototype, "promptedEmail", null);
|
303 | tslib_1.__decorate([
|
304 | Memo,
|
305 | tslib_1.__metadata("design:type", Function),
|
306 | tslib_1.__metadata("design:paramtypes", [Object]),
|
307 | tslib_1.__metadata("design:returntype", String)
|
308 | ], PromptableConfig.prototype, "promptedEncryptionPassword", null);
|
309 | tslib_1.__decorate([
|
310 | Memo,
|
311 | tslib_1.__metadata("design:type", Function),
|
312 | tslib_1.__metadata("design:paramtypes", [Object]),
|
313 | tslib_1.__metadata("design:returntype", String)
|
314 | ], PromptableConfig.prototype, "promptedGhEmail", null);
|
315 | tslib_1.__decorate([
|
316 | Memo,
|
317 | tslib_1.__metadata("design:type", Function),
|
318 | tslib_1.__metadata("design:paramtypes", [Object]),
|
319 | tslib_1.__metadata("design:returntype", String)
|
320 | ], PromptableConfig.prototype, "promptedGhRepo", null);
|
321 | tslib_1.__decorate([
|
322 | Memo,
|
323 | tslib_1.__metadata("design:type", Function),
|
324 | tslib_1.__metadata("design:paramtypes", [Object]),
|
325 | tslib_1.__metadata("design:returntype", String)
|
326 | ], PromptableConfig.prototype, "promptedGhToken", null);
|
327 | tslib_1.__decorate([
|
328 | Memo,
|
329 | tslib_1.__metadata("design:type", Function),
|
330 | tslib_1.__metadata("design:paramtypes", [Object]),
|
331 | tslib_1.__metadata("design:returntype", String)
|
332 | ], PromptableConfig.prototype, "promptedGhUser", null);
|
333 | tslib_1.__decorate([
|
334 | Memo,
|
335 | tslib_1.__metadata("design:type", Function),
|
336 | tslib_1.__metadata("design:paramtypes", [Object]),
|
337 | tslib_1.__metadata("design:returntype", String)
|
338 | ], PromptableConfig.prototype, "promptedGpgKeyId", null);
|
339 | tslib_1.__decorate([
|
340 | Memo,
|
341 | tslib_1.__metadata("design:type", Function),
|
342 | tslib_1.__metadata("design:paramtypes", [Object]),
|
343 | tslib_1.__metadata("design:returntype", String)
|
344 | ], PromptableConfig.prototype, "promptedGpgKeyPwd", null);
|
345 | tslib_1.__decorate([
|
346 | Memo,
|
347 | tslib_1.__metadata("design:type", Function),
|
348 | tslib_1.__metadata("design:paramtypes", [Object]),
|
349 | tslib_1.__metadata("design:returntype", String)
|
350 | ], PromptableConfig.prototype, "promptedGpgPrivkey", null);
|
351 | tslib_1.__decorate([
|
352 | Memo,
|
353 | tslib_1.__metadata("design:type", Function),
|
354 | tslib_1.__metadata("design:paramtypes", [Object]),
|
355 | tslib_1.__metadata("design:returntype", String)
|
356 | ], PromptableConfig.prototype, "promptedGpgPubkey", null);
|
357 | tslib_1.__decorate([
|
358 | Memo,
|
359 | tslib_1.__metadata("design:type", Function),
|
360 | tslib_1.__metadata("design:paramtypes", [Object]),
|
361 | tslib_1.__metadata("design:returntype", String)
|
362 | ], PromptableConfig.prototype, "promptedLicense", null);
|
363 | tslib_1.__decorate([
|
364 | Memo,
|
365 | tslib_1.__metadata("design:type", Function),
|
366 | tslib_1.__metadata("design:paramtypes", [Object]),
|
367 | tslib_1.__metadata("design:returntype", String)
|
368 | ], PromptableConfig.prototype, "promptedName", null);
|
369 | tslib_1.__decorate([
|
370 | Memo,
|
371 | tslib_1.__metadata("design:type", Function),
|
372 | tslib_1.__metadata("design:paramtypes", [Object]),
|
373 | tslib_1.__metadata("design:returntype", String)
|
374 | ], PromptableConfig.prototype, "promptedPkgMgr", null);
|
375 | tslib_1.__decorate([
|
376 | Memo,
|
377 | tslib_1.__metadata("design:type", Function),
|
378 | tslib_1.__metadata("design:paramtypes", [Object]),
|
379 | tslib_1.__metadata("design:returntype", String)
|
380 | ], PromptableConfig.prototype, "promptedProjectDescription", null);
|
381 | tslib_1.__decorate([
|
382 | Memo,
|
383 | tslib_1.__metadata("design:type", Function),
|
384 | tslib_1.__metadata("design:paramtypes", [Object]),
|
385 | tslib_1.__metadata("design:returntype", String)
|
386 | ], PromptableConfig.prototype, "promptedProjectKeywords", null);
|
387 | tslib_1.__decorate([
|
388 | Memo,
|
389 | tslib_1.__metadata("design:type", Function),
|
390 | tslib_1.__metadata("design:paramtypes", [Object]),
|
391 | tslib_1.__metadata("design:returntype", String)
|
392 | ], PromptableConfig.prototype, "promptedProjectName", null);
|
393 | tslib_1.__decorate([
|
394 | Memo,
|
395 | tslib_1.__metadata("design:type", Function),
|
396 | tslib_1.__metadata("design:paramtypes", [Object]),
|
397 | tslib_1.__metadata("design:returntype", String)
|
398 | ], PromptableConfig.prototype, "promptedReleaseGhToken", null);
|
399 | tslib_1.__decorate([
|
400 | Memo,
|
401 | tslib_1.__metadata("design:type", Function),
|
402 | tslib_1.__metadata("design:paramtypes", [Object]),
|
403 | tslib_1.__metadata("design:returntype", String)
|
404 | ], PromptableConfig.prototype, "promptedReleaseNpmToken", null);
|
405 | tslib_1.__decorate([
|
406 | Memo,
|
407 | tslib_1.__metadata("design:type", Function),
|
408 | tslib_1.__metadata("design:paramtypes", [Object]),
|
409 | tslib_1.__metadata("design:returntype", String)
|
410 | ], PromptableConfig.prototype, "promptedTravisTokenOrg", null);
|
411 | tslib_1.__decorate([
|
412 | Memo,
|
413 | tslib_1.__metadata("design:type", Function),
|
414 | tslib_1.__metadata("design:paramtypes", [Object]),
|
415 | tslib_1.__metadata("design:returntype", String)
|
416 | ], PromptableConfig.prototype, "promptedTravisTokenPro", null);
|
417 | tslib_1.__decorate([
|
418 | Memo,
|
419 | tslib_1.__metadata("design:type", Function),
|
420 | tslib_1.__metadata("design:paramtypes", [Object]),
|
421 | tslib_1.__metadata("design:returntype", String)
|
422 | ], PromptableConfig.prototype, "promptedUserWebsite", null);
|
423 | exports.PromptableConfig = PromptableConfig;
|