@impeccable/reviews 0.1.21 → 0.1.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cloudflare-access.js +4 -0
- package/dist/cloudflare.js +15 -18
- package/dist/fence.js +47 -26
- package/dist/host-questions.js +42 -19
- package/dist/main.js +38 -17
- package/dist/netlify-password.js +114 -37
- package/dist/playbook/cases/monorepo.md +5 -5
- package/dist/playbook/cases/netlify-setup.md +2 -2
- package/dist/playbook/cases/preview-protection.md +5 -4
- package/dist/playbook/cases/pull-requests.md +1 -1
- package/dist/playbook/cases/vercel-setup.md +2 -2
- package/dist/playbook.js +2 -2
- package/dist/pr-summary.js +45 -0
- package/dist/preflight.js +1 -1
- package/dist/sandbox.js +4 -4
- package/dist/tools.js +312 -116
- package/dist/ui/bridge.js +5 -3
- package/dist/ui/look.js +3 -2
- package/dist/ui/screens.js +6 -6
- package/package.json +1 -1
package/dist/ui/bridge.js
CHANGED
|
@@ -121,7 +121,9 @@ async function askOnStdin(q) {
|
|
|
121
121
|
const out = process.stdout;
|
|
122
122
|
if (q.kind === 'confirm') {
|
|
123
123
|
out.write(`\n${q.title ? `${q.title}\n` : ''}${q.hint ? `${q.hint}\n` : ''}${q.prompt}\n`);
|
|
124
|
-
|
|
124
|
+
// Lowercased after "to", but for the I of "I'll install it myself".
|
|
125
|
+
const lower = (label) => label.toLowerCase().replace(/^i(?=['\s])/, 'I');
|
|
126
|
+
const how = `Type y to ${lower(q.confirmLabel ?? 'continue')}, or Enter to ${lower(q.skipLabel ?? 'skip')}:`;
|
|
125
127
|
out.write(`${how} `);
|
|
126
128
|
for (let line = await nextLine(); line !== null; line = await nextLine()) {
|
|
127
129
|
if (/^y(es)?$/i.test(line.trim()))
|
|
@@ -130,7 +132,7 @@ async function askOnStdin(q) {
|
|
|
130
132
|
return { skipped: true };
|
|
131
133
|
out.write(`That is not an answer to this one. ${how} `);
|
|
132
134
|
}
|
|
133
|
-
return { skipped: true };
|
|
135
|
+
return { skipped: true, closed: true };
|
|
134
136
|
}
|
|
135
137
|
if (q.kind === 'account') {
|
|
136
138
|
// An empty username keeps the one the field would hold; an empty password skips the account.
|
|
@@ -158,5 +160,5 @@ async function askOnStdin(q) {
|
|
|
158
160
|
out.write(`That is not an answer to this one. ${how} `);
|
|
159
161
|
}
|
|
160
162
|
// Nobody is there to answer.
|
|
161
|
-
return { skipped: true };
|
|
163
|
+
return { skipped: true, closed: true };
|
|
162
164
|
}
|
package/dist/ui/look.js
CHANGED
|
@@ -80,7 +80,8 @@ function dotRows(word, max) {
|
|
|
80
80
|
/** A paragraph of plain text wrapped to at most `max` columns: a sentence a line when each fits, else lines as even as the words allow. */
|
|
81
81
|
function balanced(given, max) {
|
|
82
82
|
const text = given.split(' ').map((word) => dotRows(word, max).join('\n')).join(' ');
|
|
83
|
-
|
|
83
|
+
// A sentence ends on a mark after its last word: the "!" a warning opens with is no sentence of its own.
|
|
84
|
+
const sentences = text.split(/(?<=\S[.!?])\s+/);
|
|
84
85
|
if (sentences.length > 1 && sentences.every((line) => visibleWidth(line) <= max))
|
|
85
86
|
return sentences;
|
|
86
87
|
const lines = wrapTextWithAnsi(text, Math.max(10, max));
|
|
@@ -349,7 +350,7 @@ function pageOf(f, inner) {
|
|
|
349
350
|
return runPage(scene, f, inner, st);
|
|
350
351
|
case 'pull':
|
|
351
352
|
return {
|
|
352
|
-
heading: 'Your first review is on its way',
|
|
353
|
+
heading: scene.app ? `${scene.app}'s first review is on its way` : 'Your first review is on its way',
|
|
353
354
|
text: said(SEE_THE_REVIEW, inner, st),
|
|
354
355
|
rule: divider(inner, st),
|
|
355
356
|
action: pullAction(scene.url, scene.copied, inner, st),
|
package/dist/ui/screens.js
CHANGED
|
@@ -117,7 +117,7 @@ class Wizard {
|
|
|
117
117
|
process.off('SIGHUP', this.onSignal);
|
|
118
118
|
mountUi(null);
|
|
119
119
|
for (const question of this.questions.splice(0))
|
|
120
|
-
question.resolve({ skipped: true });
|
|
120
|
+
question.resolve({ skipped: true, closed: true });
|
|
121
121
|
// Leaves the alternate screen without copying the last frame out of it: the scrollback gets the outro's summary only.
|
|
122
122
|
this.tui.stop({ preserveScreen: true });
|
|
123
123
|
this.restoreConsole();
|
|
@@ -240,7 +240,7 @@ class Wizard {
|
|
|
240
240
|
}
|
|
241
241
|
this.stopAsked = 0;
|
|
242
242
|
for (const question of this.questions.splice(0))
|
|
243
|
-
question.resolve({ skipped: true });
|
|
243
|
+
question.resolve({ skipped: true, closed: true });
|
|
244
244
|
this.state.status('Stopping the setup');
|
|
245
245
|
this.redraw();
|
|
246
246
|
run.cancel();
|
|
@@ -342,7 +342,7 @@ class Wizard {
|
|
|
342
342
|
if (view.kind === 'signin')
|
|
343
343
|
return { kind: 'signin', link: view.link, copied: view.copied, again: view.again, note: view.pasting ? undefined : view.note, checkout: view.opts.checkout };
|
|
344
344
|
if (view.kind === 'pull')
|
|
345
|
-
return { kind: 'pull', url: view.url, copied: view.copied };
|
|
345
|
+
return { kind: 'pull', url: view.url, ...(view.app ? { app: view.app } : {}), copied: view.copied };
|
|
346
346
|
if (view.kind === 'outro')
|
|
347
347
|
return { kind: 'outro', outro: view.outro, leaving: view.leaving, copied: view.copied };
|
|
348
348
|
return { kind: 'run', tasks: this.state.tasks, band: this.state.band(!this.questions.length, live), wait: this.state.timer(live) };
|
|
@@ -486,8 +486,8 @@ async function handOver(url, hand) {
|
|
|
486
486
|
const copied = hand.copy(url).catch(() => false);
|
|
487
487
|
return (await Promise.race([copied, new Promise((r) => setTimeout(() => r(false), 1000).unref())])) === true;
|
|
488
488
|
}
|
|
489
|
-
/** The test drive on a screen of its own once the run has ended, before the last screen shows the setup pull request, handed over as it appears, until a key other than ↑↓ PgUp PgDn is pressed, or for 20 minutes. Without a terminal there is no such screen: the summary has it. */
|
|
490
|
-
export async function showPullRequest(url, hand) {
|
|
489
|
+
/** The test drive on a screen of its own once the run has ended, before the last screen shows the setup pull request, handed over as it appears, until a key other than ↑↓ PgUp PgDn is pressed, or for 20 minutes; on a repository with several apps, each app's in turn, named (impeccable-reviews#397). Without a terminal there is no such screen: the summary has it. */
|
|
490
|
+
export async function showPullRequest(url, hand, app) {
|
|
491
491
|
const screen = host();
|
|
492
492
|
if (!screen)
|
|
493
493
|
return;
|
|
@@ -499,7 +499,7 @@ export async function showPullRequest(url, hand) {
|
|
|
499
499
|
resolve();
|
|
500
500
|
};
|
|
501
501
|
const timer = setTimeout(done, CLOSE_AFTER_MS).unref();
|
|
502
|
-
const view = { kind: 'pull', url, copied, copy: () => hand.copy(url), done };
|
|
502
|
+
const view = { kind: 'pull', url, ...(app ? { app } : {}), copied, copy: () => hand.copy(url), done };
|
|
503
503
|
screen.views = [];
|
|
504
504
|
screen.push(view);
|
|
505
505
|
});
|