UNPKG

15.8 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const tslib_1 = require("tslib");
4const fs = require("fs-extra");
5const lodash_1 = require("lodash");
6const rl$ = require("readline-sync");
7const typescript_lazy_get_decorator_1 = require("typescript-lazy-get-decorator");
8const IS_CI_1 = require("../const/IS_CI");
9const lastDirname_1 = require("../fns/lastDirname");
10const readJson_1 = require("../fns/readJson");
11const License_1 = require("../inc/License");
12const PackageManager_1 = require("../inc/PackageManager");
13const Colour_1 = require("./Colour");
14const Git_1 = require("./Git");
15const gh_repo_1 = require("./sync-request/gh-repo/gh-repo");
16let rl;
17if (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}
28else {
29 rl = rl$;
30}
31const memoisedFnNames = [];
32function Memo(_target, prop) {
33 memoisedFnNames.push(prop);
34}
35class 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 /** @internal */
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}
282tslib_1.__decorate([
283 typescript_lazy_get_decorator_1.LazyGetter(true),
284 tslib_1.__metadata("design:type", Object),
285 tslib_1.__metadata("design:paramtypes", [])
286], PromptableConfig.prototype, "ghRepoFromMetadata", null);
287tslib_1.__decorate([
288 typescript_lazy_get_decorator_1.LazyGetter(true),
289 tslib_1.__metadata("design:type", Object),
290 tslib_1.__metadata("design:paramtypes", [])
291], PromptableConfig.prototype, "ghUserFromMetadata", null);
292tslib_1.__decorate([
293 typescript_lazy_get_decorator_1.LazyGetter(true),
294 tslib_1.__metadata("design:type", Object),
295 tslib_1.__metadata("design:paramtypes", [])
296], PromptableConfig.prototype, "ghMetadata", null);
297tslib_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);
303tslib_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);
309tslib_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);
315tslib_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);
321tslib_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);
327tslib_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);
333tslib_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);
339tslib_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);
345tslib_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);
351tslib_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);
357tslib_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);
363tslib_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);
369tslib_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);
375tslib_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);
381tslib_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);
387tslib_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);
393tslib_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);
399tslib_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);
405tslib_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);
411tslib_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);
417tslib_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);
423exports.PromptableConfig = PromptableConfig;