@scalebun-release/cli 2.5.0
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/bin/scalebun.js +2 -0
- package/lib/api/client.d.ts +52 -0
- package/lib/api/client.d.ts.map +1 -0
- package/lib/api/client.js +335 -0
- package/lib/api/client.js.map +1 -0
- package/lib/commands/ci-init.d.ts +3 -0
- package/lib/commands/ci-init.d.ts.map +1 -0
- package/lib/commands/ci-init.js +348 -0
- package/lib/commands/ci-init.js.map +1 -0
- package/lib/commands/doctor.d.ts +31 -0
- package/lib/commands/doctor.d.ts.map +1 -0
- package/lib/commands/doctor.js +559 -0
- package/lib/commands/doctor.js.map +1 -0
- package/lib/commands/launch.d.ts +3 -0
- package/lib/commands/launch.d.ts.map +1 -0
- package/lib/commands/launch.js +23 -0
- package/lib/commands/launch.js.map +1 -0
- package/lib/commands/link.d.ts +16 -0
- package/lib/commands/link.d.ts.map +1 -0
- package/lib/commands/link.js +164 -0
- package/lib/commands/link.js.map +1 -0
- package/lib/commands/login.d.ts +12 -0
- package/lib/commands/login.d.ts.map +1 -0
- package/lib/commands/login.js +124 -0
- package/lib/commands/login.js.map +1 -0
- package/lib/commands/migrate-codepush.d.ts +13 -0
- package/lib/commands/migrate-codepush.d.ts.map +1 -0
- package/lib/commands/migrate-codepush.js +98 -0
- package/lib/commands/migrate-codepush.js.map +1 -0
- package/lib/commands/ota-bundle.d.ts +22 -0
- package/lib/commands/ota-bundle.d.ts.map +1 -0
- package/lib/commands/ota-bundle.js +253 -0
- package/lib/commands/ota-bundle.js.map +1 -0
- package/lib/commands/ota-channels.d.ts +3 -0
- package/lib/commands/ota-channels.d.ts.map +1 -0
- package/lib/commands/ota-channels.js +231 -0
- package/lib/commands/ota-channels.js.map +1 -0
- package/lib/commands/ota-delete-bundle.d.ts +16 -0
- package/lib/commands/ota-delete-bundle.d.ts.map +1 -0
- package/lib/commands/ota-delete-bundle.js +96 -0
- package/lib/commands/ota-delete-bundle.js.map +1 -0
- package/lib/commands/ota-inspect.d.ts +3 -0
- package/lib/commands/ota-inspect.d.ts.map +1 -0
- package/lib/commands/ota-inspect.js +258 -0
- package/lib/commands/ota-inspect.js.map +1 -0
- package/lib/commands/ota-keys.d.ts +91 -0
- package/lib/commands/ota-keys.d.ts.map +1 -0
- package/lib/commands/ota-keys.js +765 -0
- package/lib/commands/ota-keys.js.map +1 -0
- package/lib/commands/ota-promote.d.ts +3 -0
- package/lib/commands/ota-promote.d.ts.map +1 -0
- package/lib/commands/ota-promote.js +194 -0
- package/lib/commands/ota-promote.js.map +1 -0
- package/lib/commands/ota-publish.d.ts +26 -0
- package/lib/commands/ota-publish.d.ts.map +1 -0
- package/lib/commands/ota-publish.js +892 -0
- package/lib/commands/ota-publish.js.map +1 -0
- package/lib/commands/ota-rollout.d.ts +3 -0
- package/lib/commands/ota-rollout.d.ts.map +1 -0
- package/lib/commands/ota-rollout.js +265 -0
- package/lib/commands/ota-rollout.js.map +1 -0
- package/lib/commands/ota-sign.d.ts +19 -0
- package/lib/commands/ota-sign.d.ts.map +1 -0
- package/lib/commands/ota-sign.js +245 -0
- package/lib/commands/ota-sign.js.map +1 -0
- package/lib/commands/push-apns.d.ts +3 -0
- package/lib/commands/push-apns.d.ts.map +1 -0
- package/lib/commands/push-apns.js +166 -0
- package/lib/commands/push-apns.js.map +1 -0
- package/lib/commands/quickstart.d.ts +4 -0
- package/lib/commands/quickstart.d.ts.map +1 -0
- package/lib/commands/quickstart.js +672 -0
- package/lib/commands/quickstart.js.map +1 -0
- package/lib/commands/shell.d.ts +28 -0
- package/lib/commands/shell.d.ts.map +1 -0
- package/lib/commands/shell.js +512 -0
- package/lib/commands/shell.js.map +1 -0
- package/lib/commands/tls-pins.d.ts +27 -0
- package/lib/commands/tls-pins.d.ts.map +1 -0
- package/lib/commands/tls-pins.js +209 -0
- package/lib/commands/tls-pins.js.map +1 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +233 -0
- package/lib/index.js.map +1 -0
- package/lib/ui/banner.d.ts +23 -0
- package/lib/ui/banner.d.ts.map +1 -0
- package/lib/ui/banner.js +162 -0
- package/lib/ui/banner.js.map +1 -0
- package/lib/ui/graphics.d.ts +18 -0
- package/lib/ui/graphics.d.ts.map +1 -0
- package/lib/ui/graphics.js +134 -0
- package/lib/ui/graphics.js.map +1 -0
- package/lib/ui/mark.d.ts +4 -0
- package/lib/ui/mark.d.ts.map +1 -0
- package/lib/ui/mark.js +21 -0
- package/lib/ui/mark.js.map +1 -0
- package/lib/ui/menu.d.ts +109 -0
- package/lib/ui/menu.d.ts.map +1 -0
- package/lib/ui/menu.js +314 -0
- package/lib/ui/menu.js.map +1 -0
- package/lib/ui/sixel.d.ts +6 -0
- package/lib/ui/sixel.d.ts.map +1 -0
- package/lib/ui/sixel.js +9 -0
- package/lib/ui/sixel.js.map +1 -0
- package/lib/utils/apps.d.ts +29 -0
- package/lib/utils/apps.d.ts.map +1 -0
- package/lib/utils/apps.js +19 -0
- package/lib/utils/apps.js.map +1 -0
- package/lib/utils/browser.d.ts +9 -0
- package/lib/utils/browser.d.ts.map +1 -0
- package/lib/utils/browser.js +39 -0
- package/lib/utils/browser.js.map +1 -0
- package/lib/utils/bundle.d.ts +153 -0
- package/lib/utils/bundle.d.ts.map +1 -0
- package/lib/utils/bundle.js +459 -0
- package/lib/utils/bundle.js.map +1 -0
- package/lib/utils/bundleStore.d.ts +128 -0
- package/lib/utils/bundleStore.d.ts.map +1 -0
- package/lib/utils/bundleStore.js +250 -0
- package/lib/utils/bundleStore.js.map +1 -0
- package/lib/utils/context.d.ts +88 -0
- package/lib/utils/context.d.ts.map +1 -0
- package/lib/utils/context.js +247 -0
- package/lib/utils/context.js.map +1 -0
- package/lib/utils/credentials.d.ts +59 -0
- package/lib/utils/credentials.d.ts.map +1 -0
- package/lib/utils/credentials.js +147 -0
- package/lib/utils/credentials.js.map +1 -0
- package/lib/utils/guide.d.ts +63 -0
- package/lib/utils/guide.d.ts.map +1 -0
- package/lib/utils/guide.js +191 -0
- package/lib/utils/guide.js.map +1 -0
- package/lib/utils/hash.d.ts +3 -0
- package/lib/utils/hash.d.ts.map +1 -0
- package/lib/utils/hash.js +44 -0
- package/lib/utils/hash.js.map +1 -0
- package/lib/utils/native-id.d.ts +17 -0
- package/lib/utils/native-id.d.ts.map +1 -0
- package/lib/utils/native-id.js +105 -0
- package/lib/utils/native-id.js.map +1 -0
- package/lib/utils/output.d.ts +96 -0
- package/lib/utils/output.d.ts.map +1 -0
- package/lib/utils/output.js +135 -0
- package/lib/utils/output.js.map +1 -0
- package/lib/utils/prompt.d.ts +106 -0
- package/lib/utils/prompt.d.ts.map +1 -0
- package/lib/utils/prompt.js +457 -0
- package/lib/utils/prompt.js.map +1 -0
- package/lib/utils/provenance.d.ts +30 -0
- package/lib/utils/provenance.d.ts.map +1 -0
- package/lib/utils/provenance.js +157 -0
- package/lib/utils/provenance.js.map +1 -0
- package/lib/utils/resolve.d.ts +81 -0
- package/lib/utils/resolve.d.ts.map +1 -0
- package/lib/utils/resolve.js +139 -0
- package/lib/utils/resolve.js.map +1 -0
- package/lib/utils/sdkBin.d.ts +18 -0
- package/lib/utils/sdkBin.d.ts.map +1 -0
- package/lib/utils/sdkBin.js +76 -0
- package/lib/utils/sdkBin.js.map +1 -0
- package/lib/utils/signer.d.ts +94 -0
- package/lib/utils/signer.d.ts.map +1 -0
- package/lib/utils/signer.js +230 -0
- package/lib/utils/signer.js.map +1 -0
- package/lib/utils/signing.d.ts +102 -0
- package/lib/utils/signing.d.ts.map +1 -0
- package/lib/utils/signing.js +229 -0
- package/lib/utils/signing.js.map +1 -0
- package/lib/utils/transportSecurity.d.ts +36 -0
- package/lib/utils/transportSecurity.d.ts.map +1 -0
- package/lib/utils/transportSecurity.js +74 -0
- package/lib/utils/transportSecurity.js.map +1 -0
- package/lib/utils/trustAnchor.d.ts +109 -0
- package/lib/utils/trustAnchor.d.ts.map +1 -0
- package/lib/utils/trustAnchor.js +169 -0
- package/lib/utils/trustAnchor.js.map +1 -0
- package/lib/utils/ui.d.ts +12 -0
- package/lib/utils/ui.d.ts.map +1 -0
- package/lib/utils/ui.js +60 -0
- package/lib/utils/ui.js.map +1 -0
- package/lib/utils/validate.d.ts +62 -0
- package/lib/utils/validate.d.ts.map +1 -0
- package/lib/utils/validate.js +189 -0
- package/lib/utils/validate.js.map +1 -0
- package/lib/vendor/ota-protocol/base64.d.ts +11 -0
- package/lib/vendor/ota-protocol/base64.d.ts.map +1 -0
- package/lib/vendor/ota-protocol/base64.js +39 -0
- package/lib/vendor/ota-protocol/base64.js.map +1 -0
- package/lib/vendor/ota-protocol/codec.d.ts +26 -0
- package/lib/vendor/ota-protocol/codec.d.ts.map +1 -0
- package/lib/vendor/ota-protocol/codec.js +349 -0
- package/lib/vendor/ota-protocol/codec.js.map +1 -0
- package/lib/vendor/ota-protocol/hex.d.ts +8 -0
- package/lib/vendor/ota-protocol/hex.d.ts.map +1 -0
- package/lib/vendor/ota-protocol/hex.js +31 -0
- package/lib/vendor/ota-protocol/hex.js.map +1 -0
- package/lib/vendor/ota-protocol/index.d.ts +17 -0
- package/lib/vendor/ota-protocol/index.d.ts.map +1 -0
- package/lib/vendor/ota-protocol/index.js +41 -0
- package/lib/vendor/ota-protocol/index.js.map +1 -0
- package/lib/vendor/ota-protocol/limits.d.ts +39 -0
- package/lib/vendor/ota-protocol/limits.d.ts.map +1 -0
- package/lib/vendor/ota-protocol/limits.js +42 -0
- package/lib/vendor/ota-protocol/limits.js.map +1 -0
- package/lib/vendor/ota-protocol/types.d.ts +73 -0
- package/lib/vendor/ota-protocol/types.d.ts.map +1 -0
- package/lib/vendor/ota-protocol/types.js +24 -0
- package/lib/vendor/ota-protocol/types.js.map +1 -0
- package/package.json +37 -0
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.canPromptHidden = canPromptHidden;
|
|
40
|
+
exports.promptHidden = promptHidden;
|
|
41
|
+
exports.closePrompts = closePrompts;
|
|
42
|
+
exports.text = text;
|
|
43
|
+
exports.confirmPhrase = confirmPhrase;
|
|
44
|
+
exports.confirm = confirm;
|
|
45
|
+
exports.number = number;
|
|
46
|
+
exports.select = select;
|
|
47
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
48
|
+
const readline = __importStar(require("readline"));
|
|
49
|
+
/**
|
|
50
|
+
* Hidden terminal input for secrets (access tokens).
|
|
51
|
+
*
|
|
52
|
+
* `readline.question` echoes what the user types, so a pasted access token would
|
|
53
|
+
* sit in the terminal scrollback in cleartext. This reads the token in raw mode
|
|
54
|
+
* and echoes a `*` per character instead — the token never appears on screen.
|
|
55
|
+
*
|
|
56
|
+
* Paste-safe: a pasted token usually arrives as one multi-character `data`
|
|
57
|
+
* chunk (often with a trailing newline), so each chunk is processed
|
|
58
|
+
* character-by-character. Backspace and Ctrl-C are handled. When stdin is not a
|
|
59
|
+
* TTY (CI, pipes) raw mode is unavailable — callers must supply the token via
|
|
60
|
+
* --token or an env var instead of relying on this.
|
|
61
|
+
*
|
|
62
|
+
* Control keys are compared by char code to avoid embedding raw control bytes in
|
|
63
|
+
* this source file.
|
|
64
|
+
*/
|
|
65
|
+
const CODE_ETX = 3; // Ctrl-C
|
|
66
|
+
const CODE_EOT = 4; // Ctrl-D
|
|
67
|
+
const CODE_LF = 10; // \n
|
|
68
|
+
const CODE_CR = 13; // \r
|
|
69
|
+
const CODE_BS = 8; // Backspace
|
|
70
|
+
const CODE_DEL = 127; // Delete
|
|
71
|
+
const CODE_SPACE = 32; // first printable
|
|
72
|
+
/** True when interactive hidden input is possible on this stdin. */
|
|
73
|
+
function canPromptHidden() {
|
|
74
|
+
return Boolean(process.stdin.isTTY);
|
|
75
|
+
}
|
|
76
|
+
function promptHidden(query) {
|
|
77
|
+
return new Promise((resolve) => {
|
|
78
|
+
const stdin = process.stdin;
|
|
79
|
+
const stdout = process.stdout;
|
|
80
|
+
stdout.write(query);
|
|
81
|
+
stdin.resume();
|
|
82
|
+
stdin.setEncoding('utf8');
|
|
83
|
+
if (stdin.isTTY)
|
|
84
|
+
stdin.setRawMode(true);
|
|
85
|
+
let value = '';
|
|
86
|
+
const done = () => {
|
|
87
|
+
if (stdin.isTTY)
|
|
88
|
+
stdin.setRawMode(false);
|
|
89
|
+
stdin.pause();
|
|
90
|
+
stdin.removeListener('data', onData);
|
|
91
|
+
stdout.write('\n');
|
|
92
|
+
resolve(value);
|
|
93
|
+
};
|
|
94
|
+
const onData = (chunk) => {
|
|
95
|
+
for (const ch of chunk) {
|
|
96
|
+
const code = ch.charCodeAt(0);
|
|
97
|
+
if (code === CODE_CR || code === CODE_LF || code === CODE_EOT) {
|
|
98
|
+
// Enter / EOT → submit.
|
|
99
|
+
done();
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
else if (code === CODE_ETX) {
|
|
103
|
+
// Ctrl-C → abort.
|
|
104
|
+
if (stdin.isTTY)
|
|
105
|
+
stdin.setRawMode(false);
|
|
106
|
+
stdout.write('\n');
|
|
107
|
+
process.exit(1);
|
|
108
|
+
}
|
|
109
|
+
else if (code === CODE_BS || code === CODE_DEL) {
|
|
110
|
+
// Backspace / delete → drop last char and erase one `*`.
|
|
111
|
+
if (value.length > 0) {
|
|
112
|
+
value = value.slice(0, -1);
|
|
113
|
+
stdout.write('\b \b');
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
else if (code >= CODE_SPACE) {
|
|
117
|
+
// Printable → keep it, echo a mask.
|
|
118
|
+
value += ch;
|
|
119
|
+
stdout.write('*');
|
|
120
|
+
}
|
|
121
|
+
// Other control chars (arrows, etc.) are ignored.
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
stdin.on('data', onData);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
// ── Interactive prompts (dependency-free) ────────────────────────────────────
|
|
128
|
+
//
|
|
129
|
+
// A tiny prompt toolkit for the interactive `ota publish` wizard: text, confirm,
|
|
130
|
+
// number, and a select. `select` uses arrow keys in a real TTY and falls back to
|
|
131
|
+
// a numbered choice otherwise, so it works over pipes / limited terminals too.
|
|
132
|
+
// A single shared readline for all line-based prompts in a session. Creating a
|
|
133
|
+
// fresh interface per question is the classic anti-pattern: over a pipe the
|
|
134
|
+
// first one buffers the remaining lines and later ones hang on an already-ended
|
|
135
|
+
// stdin. One interface reads sequential lines correctly. It is created lazily —
|
|
136
|
+
// after the raw-mode `select`s run — so it never fights their stdin handling.
|
|
137
|
+
let sharedRl = null;
|
|
138
|
+
// The interactive session used to LEND its own readline to this module, because
|
|
139
|
+
// it held one open for the whole session and two interfaces on one stdin is a
|
|
140
|
+
// top-tier source of "the CLI just hangs" — both attach listeners, the last one
|
|
141
|
+
// consumes the keypress stream, and neither sees a complete line. The session
|
|
142
|
+
// no longer holds one: it owns stdin in raw mode for the menu and hands it back
|
|
143
|
+
// before running anything, so commands are free to make their own prompts here.
|
|
144
|
+
// One owner at a time, enforced by structure rather than by a lending protocol.
|
|
145
|
+
function getRl() {
|
|
146
|
+
if (!sharedRl) {
|
|
147
|
+
sharedRl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
148
|
+
sharedRl.on('close', () => {
|
|
149
|
+
sharedRl = null;
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
return sharedRl;
|
|
153
|
+
}
|
|
154
|
+
/** Close the shared prompt interface so the process can exit / move on. */
|
|
155
|
+
function closePrompts() {
|
|
156
|
+
if (sharedRl) {
|
|
157
|
+
sharedRl.close();
|
|
158
|
+
sharedRl = null;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/** One-line echoed question via the shared readline. Resolves '' on EOF. */
|
|
162
|
+
function ask(query) {
|
|
163
|
+
return new Promise((resolve) => {
|
|
164
|
+
const rl = getRl();
|
|
165
|
+
let answered = false;
|
|
166
|
+
const onClose = () => {
|
|
167
|
+
if (!answered)
|
|
168
|
+
resolve('');
|
|
169
|
+
};
|
|
170
|
+
rl.once('close', onClose);
|
|
171
|
+
rl.question(query, (answer) => {
|
|
172
|
+
answered = true;
|
|
173
|
+
rl.removeListener('close', onClose);
|
|
174
|
+
resolve(answer);
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Free-text question with an optional default (shown in parentheses).
|
|
180
|
+
*
|
|
181
|
+
* ── Empty is a question, not an answer ──────────────────────────────────────
|
|
182
|
+
*
|
|
183
|
+
* This used to return '' the moment someone pressed Enter with nothing typed,
|
|
184
|
+
* and every caller then invented its own reaction. `text('App id')` in the
|
|
185
|
+
* publish wizard did `if (!id) process.exit(1)` — a silent exit 1, no message,
|
|
186
|
+
* from a prompt that had just told you it wanted an app id. Others carried the
|
|
187
|
+
* empty string onward until the API rejected a field the user never saw.
|
|
188
|
+
*
|
|
189
|
+
* Pressing Enter at a prompt with no default is almost never a decision; it is
|
|
190
|
+
* someone hurrying, or not knowing what is wanted. So empty now re-asks and
|
|
191
|
+
* explains, and callers with something sensible to fall back on pass a
|
|
192
|
+
* `default` — which is what "Enter means yes" should always have looked like.
|
|
193
|
+
* `allowEmpty` remains for fields that are honestly optional.
|
|
194
|
+
*/
|
|
195
|
+
async function text(query, opts = {}) {
|
|
196
|
+
const suffix = opts.default ? chalk_1.default.dim(` (${opts.default})`) : '';
|
|
197
|
+
let empties = 0;
|
|
198
|
+
for (;;) {
|
|
199
|
+
const raw = (await ask(`${chalk_1.default.cyan('?')} ${query}${suffix}: `)).trim();
|
|
200
|
+
const answer = raw || opts.default || '';
|
|
201
|
+
if (!answer && !opts.allowEmpty) {
|
|
202
|
+
bailOnEmptyLoop(++empties, `${query} is required.`);
|
|
203
|
+
console.log(chalk_1.default.yellow(' Nothing entered — this one is needed to continue.'));
|
|
204
|
+
if (opts.help)
|
|
205
|
+
console.log(chalk_1.default.dim(` ${opts.help}`));
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
const problem = answer && opts.validate ? opts.validate(answer) : null;
|
|
209
|
+
if (problem) {
|
|
210
|
+
console.log(chalk_1.default.yellow(` ${problem}`));
|
|
211
|
+
if (opts.help)
|
|
212
|
+
console.log(chalk_1.default.dim(` ${opts.help}`));
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
return answer;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Type-this-exact-phrase confirmation, for the destructive commands.
|
|
220
|
+
*
|
|
221
|
+
* Empty and wrong are DIFFERENT mistakes and deserve different answers:
|
|
222
|
+
*
|
|
223
|
+
* empty — cancel. Enter must stay an escape from a prompt that is about to
|
|
224
|
+
* delete a channel or roll back a fleet; re-asking would trap
|
|
225
|
+
* someone whose actual intent was to back out. But say so, rather
|
|
226
|
+
* than printing "Cancelled" and leaving them to guess whether the
|
|
227
|
+
* keystroke registered.
|
|
228
|
+
* wrong — re-ask. A typo in a channel name is not a decision to cancel, and
|
|
229
|
+
* making the operator re-run the whole command mid-incident to fix
|
|
230
|
+
* one character is the worst moment to be pedantic.
|
|
231
|
+
*/
|
|
232
|
+
async function confirmPhrase(query, expected, opts = {}) {
|
|
233
|
+
const normalise = (v) => (opts.caseInsensitive ? v.toLowerCase() : v);
|
|
234
|
+
for (;;) {
|
|
235
|
+
const answer = (await ask(`${chalk_1.default.cyan('?')} ${query}`)).trim();
|
|
236
|
+
if (!answer) {
|
|
237
|
+
console.log(chalk_1.default.dim(' Nothing typed — cancelled.'));
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
if (normalise(answer) === normalise(expected))
|
|
241
|
+
return true;
|
|
242
|
+
console.log(chalk_1.default.yellow(` That is not "${expected}" — got "${answer}".`));
|
|
243
|
+
console.log(chalk_1.default.dim(' Type it exactly, or press Enter to cancel.'));
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Guard against a re-ask loop becoming a hang.
|
|
248
|
+
*
|
|
249
|
+
* `ask()` resolves '' both when a person presses Enter and when stdin closes,
|
|
250
|
+
* and the two are indistinguishable from here. So a prompt that re-asks on
|
|
251
|
+
* empty would spin forever against a closed or piped stdin, printing its
|
|
252
|
+
* help text into a void — a CI job that hangs until the runner kills it,
|
|
253
|
+
* looking like a network fault rather than a missing flag.
|
|
254
|
+
*
|
|
255
|
+
* Off a TTY there is nobody to help, so the first empty answer is fatal. On a
|
|
256
|
+
* TTY the cap is high enough that a real person never meets it.
|
|
257
|
+
*/
|
|
258
|
+
function bailOnEmptyLoop(attempts, what) {
|
|
259
|
+
const interactive = process.stdin.isTTY && process.stdout.isTTY;
|
|
260
|
+
if (interactive && attempts < 10)
|
|
261
|
+
return;
|
|
262
|
+
console.error(`❌ ${what}`);
|
|
263
|
+
if (!interactive) {
|
|
264
|
+
console.error(' Nothing is attached to answer this prompt — pass it as a flag instead.');
|
|
265
|
+
}
|
|
266
|
+
process.exit(1);
|
|
267
|
+
}
|
|
268
|
+
const YES = new Set(['y', 'yes', 'true', '1']);
|
|
269
|
+
const NO = new Set(['n', 'no', 'false', '0']);
|
|
270
|
+
/**
|
|
271
|
+
* Yes/no question. Empty input takes the default; anything unrecognised
|
|
272
|
+
* RE-ASKS.
|
|
273
|
+
*
|
|
274
|
+
* ── Why it re-asks ──────────────────────────────────────────────────────────
|
|
275
|
+
*
|
|
276
|
+
* This used to be `return answer === 'y' || answer === 'yes'`, so every input
|
|
277
|
+
* that was not literally yes counted as no. Typing `50` at
|
|
278
|
+
* "Promote v14 to 100% of devices? (y/N)" — a completely reasonable thing to
|
|
279
|
+
* type when you wanted 50% — silently meant "no", and the CLI reported
|
|
280
|
+
* "Cancelled — nothing was promoted" as though the user had declined. The
|
|
281
|
+
* person did not decline. They answered a different question, and the tool
|
|
282
|
+
* discarded the answer and blamed them for it.
|
|
283
|
+
*
|
|
284
|
+
* The same swallow hid `yes please`, `Y ` with a stray space, and a mistyped
|
|
285
|
+
* `t`. Silently reading all of those as "no" is safe for the fleet and awful
|
|
286
|
+
* for the human: the destructive path is protected while the intent is lost
|
|
287
|
+
* without a word.
|
|
288
|
+
*/
|
|
289
|
+
async function confirm(query, opts = {}) {
|
|
290
|
+
const required = opts.default === undefined;
|
|
291
|
+
// The suffix has to tell the truth about what Enter does. `(y/n)` with
|
|
292
|
+
// neither letter capitalised is the standing convention for "no default,
|
|
293
|
+
// answer the question" — writing `(y/N)` here and then re-asking would be a
|
|
294
|
+
// prompt that lies about its own contract.
|
|
295
|
+
const suffix = required ? '(y/n)' : opts.default ? '(Y/n)' : '(y/N)';
|
|
296
|
+
let empties = 0;
|
|
297
|
+
for (;;) {
|
|
298
|
+
const answer = (await ask(`${chalk_1.default.cyan('?')} ${query} ${chalk_1.default.dim(suffix)}: `))
|
|
299
|
+
.trim()
|
|
300
|
+
.toLowerCase();
|
|
301
|
+
if (!answer) {
|
|
302
|
+
if (!required)
|
|
303
|
+
return opts.default;
|
|
304
|
+
bailOnEmptyLoop(++empties, `${query} needs a yes or no.`);
|
|
305
|
+
console.log(chalk_1.default.yellow(' This one has no default — answer y or n.'));
|
|
306
|
+
console.log(chalk_1.default.dim(' Ctrl+C backs out without doing anything.'));
|
|
307
|
+
continue;
|
|
308
|
+
}
|
|
309
|
+
if (YES.has(answer))
|
|
310
|
+
return true;
|
|
311
|
+
if (NO.has(answer))
|
|
312
|
+
return false;
|
|
313
|
+
// A number here almost always means the user was answering the quantity in
|
|
314
|
+
// the question rather than the yes/no, so say so instead of "invalid".
|
|
315
|
+
if (/^\d+%?$/.test(answer)) {
|
|
316
|
+
console.log(chalk_1.default.yellow(` "${answer}" looks like a number — this is a yes or no question.`));
|
|
317
|
+
if (opts.numericHint)
|
|
318
|
+
console.log(chalk_1.default.dim(` ${opts.numericHint}`));
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
console.log(chalk_1.default.yellow(` Please answer y or n — got "${answer}".`));
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
/** Integer question with optional default and min/max validation (loops until valid). */
|
|
326
|
+
async function number(query, opts = {}) {
|
|
327
|
+
const { min, max } = opts;
|
|
328
|
+
const range = min !== undefined && max !== undefined ? ` between ${min} and ${max}` : '';
|
|
329
|
+
let empties = 0;
|
|
330
|
+
// eslint-disable-next-line no-constant-condition
|
|
331
|
+
while (true) {
|
|
332
|
+
const suffix = opts.default !== undefined ? chalk_1.default.dim(` (${opts.default})`) : '';
|
|
333
|
+
const raw = (await ask(`${chalk_1.default.cyan('?')} ${query}${suffix}: `)).trim();
|
|
334
|
+
if (!raw && opts.default !== undefined)
|
|
335
|
+
return opts.default;
|
|
336
|
+
// Empty with no default fell through to the format check below and was
|
|
337
|
+
// reported as `got ""`, which describes the input rather than the problem.
|
|
338
|
+
if (!raw) {
|
|
339
|
+
bailOnEmptyLoop(++empties, `${query} is required.`);
|
|
340
|
+
console.log(chalk_1.default.yellow(` Nothing entered — enter a whole number${range}.`));
|
|
341
|
+
continue;
|
|
342
|
+
}
|
|
343
|
+
// A trailing % is the obvious thing to type for something the question
|
|
344
|
+
// calls a percentage. Number('50%') is NaN, so without this the prompt
|
|
345
|
+
// rejects the right answer for a formatting reason.
|
|
346
|
+
const cleaned = raw.replace(/%$/, '').trim();
|
|
347
|
+
// Strict rather than Number(): that accepts '0x10', '1e3' and Infinity,
|
|
348
|
+
// and reading a hex literal as a rollout percentage helps nobody.
|
|
349
|
+
if (!/^[+-]?\d+$/.test(cleaned)) {
|
|
350
|
+
console.log(chalk_1.default.yellow(/^[+-]?\d*\.\d+$/.test(cleaned)
|
|
351
|
+
? ` Whole numbers only${range} — got "${raw}".`
|
|
352
|
+
: ` Please enter a whole number${range} — got "${raw}".`));
|
|
353
|
+
continue;
|
|
354
|
+
}
|
|
355
|
+
const n = Number(cleaned);
|
|
356
|
+
if ((min !== undefined && n < min) || (max !== undefined && n > max)) {
|
|
357
|
+
console.log(chalk_1.default.yellow(` ${n} is out of range — enter a whole number${range}.`));
|
|
358
|
+
continue;
|
|
359
|
+
}
|
|
360
|
+
return n;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Single choice from a list. Arrow keys (↑/↓, j/k) in a real TTY; a numbered
|
|
365
|
+
* prompt otherwise. Returns the chosen value.
|
|
366
|
+
*/
|
|
367
|
+
async function select(query, choices, opts = {}) {
|
|
368
|
+
if (!choices.length)
|
|
369
|
+
throw new Error('select() needs at least one choice');
|
|
370
|
+
const def = Math.min(Math.max(opts.default ?? 0, 0), choices.length - 1);
|
|
371
|
+
if (!process.stdin.isTTY)
|
|
372
|
+
return numberedSelect(query, choices, def);
|
|
373
|
+
return arrowSelect(query, choices, def);
|
|
374
|
+
}
|
|
375
|
+
async function numberedSelect(query, choices, def) {
|
|
376
|
+
console.log(`${chalk_1.default.cyan('?')} ${query}`);
|
|
377
|
+
choices.forEach((c, i) => {
|
|
378
|
+
console.log(` ${chalk_1.default.cyan(String(i + 1))}) ${c.label}${c.hint ? chalk_1.default.dim(` — ${c.hint}`) : ''}`);
|
|
379
|
+
});
|
|
380
|
+
// eslint-disable-next-line no-constant-condition
|
|
381
|
+
while (true) {
|
|
382
|
+
const raw = (await ask(` Choose 1-${choices.length} ${chalk_1.default.dim(`(${def + 1})`)}: `)).trim();
|
|
383
|
+
if (!raw)
|
|
384
|
+
return choices[def].value;
|
|
385
|
+
// parseInt('2abc') is 2, so a typo used to select a neighbour of what the
|
|
386
|
+
// user meant. Require the whole answer to be the number.
|
|
387
|
+
if (!/^\d+$/.test(raw)) {
|
|
388
|
+
console.log(chalk_1.default.yellow(` Enter a number between 1 and ${choices.length} — got "${raw}".`));
|
|
389
|
+
continue;
|
|
390
|
+
}
|
|
391
|
+
const n = Number(raw);
|
|
392
|
+
if (n >= 1 && n <= choices.length)
|
|
393
|
+
return choices[n - 1].value;
|
|
394
|
+
console.log(chalk_1.default.yellow(` ${n} is not on the list — choose between 1 and ${choices.length}.`));
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
function arrowSelect(query, choices, def) {
|
|
398
|
+
return new Promise((resolve) => {
|
|
399
|
+
const stdin = process.stdin;
|
|
400
|
+
const stdout = process.stdout;
|
|
401
|
+
let idx = def;
|
|
402
|
+
stdin.resume();
|
|
403
|
+
stdin.setEncoding('utf8');
|
|
404
|
+
if (stdin.isTTY)
|
|
405
|
+
stdin.setRawMode(true);
|
|
406
|
+
stdout.write('\x1b[?25l'); // hide cursor
|
|
407
|
+
const draw = (first) => {
|
|
408
|
+
if (!first)
|
|
409
|
+
stdout.write(`\x1b[${choices.length}A`); // back up to the first option
|
|
410
|
+
choices.forEach((c, i) => {
|
|
411
|
+
const active = i === idx;
|
|
412
|
+
const pointer = active ? chalk_1.default.cyan('❯') : ' ';
|
|
413
|
+
const label = active ? chalk_1.default.cyan(c.label) : c.label;
|
|
414
|
+
const hint = c.hint ? chalk_1.default.dim(` ${c.hint}`) : '';
|
|
415
|
+
stdout.write(`\r\x1b[K ${pointer} ${label}${hint}\n`);
|
|
416
|
+
});
|
|
417
|
+
};
|
|
418
|
+
stdout.write(`${chalk_1.default.cyan('?')} ${query}\n`);
|
|
419
|
+
draw(true);
|
|
420
|
+
const cleanup = () => {
|
|
421
|
+
if (stdin.isTTY)
|
|
422
|
+
stdin.setRawMode(false);
|
|
423
|
+
stdin.pause();
|
|
424
|
+
stdin.removeListener('data', onData);
|
|
425
|
+
stdout.write('\x1b[?25h'); // show cursor
|
|
426
|
+
};
|
|
427
|
+
const finish = () => {
|
|
428
|
+
cleanup();
|
|
429
|
+
// Collapse the query + options into one summary line.
|
|
430
|
+
stdout.write('\r');
|
|
431
|
+
stdout.write(`\x1b[${choices.length + 1}A`); // up to the query line
|
|
432
|
+
stdout.write('\x1b[J'); // clear query + options
|
|
433
|
+
stdout.write(`${chalk_1.default.cyan('?')} ${query} ${chalk_1.default.cyan('›')} ${chalk_1.default.cyan(choices[idx].label)}\n`);
|
|
434
|
+
resolve(choices[idx].value);
|
|
435
|
+
};
|
|
436
|
+
const onData = (chunk) => {
|
|
437
|
+
if (chunk === '\x1b[A' || chunk === '\x1bOA' || chunk === 'k') {
|
|
438
|
+
idx = (idx - 1 + choices.length) % choices.length;
|
|
439
|
+
draw(false);
|
|
440
|
+
}
|
|
441
|
+
else if (chunk === '\x1b[B' || chunk === '\x1bOB' || chunk === 'j') {
|
|
442
|
+
idx = (idx + 1) % choices.length;
|
|
443
|
+
draw(false);
|
|
444
|
+
}
|
|
445
|
+
else if (chunk === '\r' || chunk === '\n') {
|
|
446
|
+
finish();
|
|
447
|
+
}
|
|
448
|
+
else if (chunk === '\x03') {
|
|
449
|
+
cleanup();
|
|
450
|
+
stdout.write('\n');
|
|
451
|
+
process.exit(1);
|
|
452
|
+
}
|
|
453
|
+
};
|
|
454
|
+
stdin.on('data', onData);
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
//# sourceMappingURL=prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/utils/prompt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build provenance for an OTA bundle — where the code came from and which CI run
|
|
3
|
+
* produced it. Sent (optionally) with the presign request so the dashboard can
|
|
4
|
+
* show Git SHA / PR / CI build / pipeline. Every field is best-effort: on a
|
|
5
|
+
* developer's laptop only the git fields resolve; in CI the run metadata fills in.
|
|
6
|
+
*/
|
|
7
|
+
export interface Provenance {
|
|
8
|
+
gitSha?: string;
|
|
9
|
+
gitBranch?: string;
|
|
10
|
+
prNumber?: number;
|
|
11
|
+
ciProvider?: string;
|
|
12
|
+
ciPipeline?: string;
|
|
13
|
+
ciBuildNumber?: string;
|
|
14
|
+
ciRunUrl?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function collectProvenance(cwd?: string): Provenance;
|
|
17
|
+
export interface AssetEntry {
|
|
18
|
+
path: string;
|
|
19
|
+
assetType: 'js' | 'image' | 'font' | 'other';
|
|
20
|
+
sizeBytes: number;
|
|
21
|
+
sha256?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Enumerate the bundle + its Metro assets into a manifest the backend stores as
|
|
25
|
+
* per-asset rows (so the dashboard can diff added/changed/removed and size
|
|
26
|
+
* regressions). The JS bundle is always the first entry; `assetsDir` is the
|
|
27
|
+
* `--assets-dest` directory from `buildBundle` (absent for pre-built bundles).
|
|
28
|
+
*/
|
|
29
|
+
export declare function collectAssetManifest(bundlePath: string, bundleSha256: string, bundleSizeBytes: number, assetsDir?: string): AssetEntry[];
|
|
30
|
+
//# sourceMappingURL=provenance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provenance.d.ts","sourceRoot":"","sources":["../../src/utils/provenance.ts"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAsBD,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,MAAsB,GAAG,UAAU,CAmDzE;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,IAAI,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAUD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,EACvB,SAAS,CAAC,EAAE,MAAM,GACjB,UAAU,EAAE,CA6Bd"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.collectProvenance = collectProvenance;
|
|
37
|
+
exports.collectAssetManifest = collectAssetManifest;
|
|
38
|
+
const childProcess = __importStar(require("child_process"));
|
|
39
|
+
const fs = __importStar(require("fs"));
|
|
40
|
+
const path = __importStar(require("path"));
|
|
41
|
+
const hash_1 = require("./hash");
|
|
42
|
+
function git(args, cwd) {
|
|
43
|
+
try {
|
|
44
|
+
const out = childProcess
|
|
45
|
+
.execFileSync('git', args, { cwd, encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] })
|
|
46
|
+
.trim();
|
|
47
|
+
return out || undefined;
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/** Drop undefined keys so the JSON body stays clean. */
|
|
54
|
+
function compact(p) {
|
|
55
|
+
const out = {};
|
|
56
|
+
for (const [k, v] of Object.entries(p)) {
|
|
57
|
+
if (v !== undefined && v !== null && v !== '')
|
|
58
|
+
out[k] = v;
|
|
59
|
+
}
|
|
60
|
+
return out;
|
|
61
|
+
}
|
|
62
|
+
function collectProvenance(cwd = process.cwd()) {
|
|
63
|
+
const env = process.env;
|
|
64
|
+
// GitHub Actions
|
|
65
|
+
if (env.GITHUB_ACTIONS === 'true') {
|
|
66
|
+
const prMatch = /refs\/pull\/(\d+)\//.exec(env.GITHUB_REF ?? '');
|
|
67
|
+
return compact({
|
|
68
|
+
gitSha: env.GITHUB_SHA ?? git(['rev-parse', 'HEAD'], cwd),
|
|
69
|
+
gitBranch: env.GITHUB_REF_NAME ?? git(['rev-parse', '--abbrev-ref', 'HEAD'], cwd),
|
|
70
|
+
prNumber: prMatch ? Number(prMatch[1]) : undefined,
|
|
71
|
+
ciProvider: 'github-actions',
|
|
72
|
+
ciPipeline: env.GITHUB_WORKFLOW,
|
|
73
|
+
ciBuildNumber: env.GITHUB_RUN_NUMBER,
|
|
74
|
+
ciRunUrl: env.GITHUB_SERVER_URL && env.GITHUB_REPOSITORY && env.GITHUB_RUN_ID
|
|
75
|
+
? `${env.GITHUB_SERVER_URL}/${env.GITHUB_REPOSITORY}/actions/runs/${env.GITHUB_RUN_ID}`
|
|
76
|
+
: undefined,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
// GitLab CI
|
|
80
|
+
if (env.GITLAB_CI === 'true') {
|
|
81
|
+
return compact({
|
|
82
|
+
gitSha: env.CI_COMMIT_SHA ?? git(['rev-parse', 'HEAD'], cwd),
|
|
83
|
+
gitBranch: env.CI_COMMIT_REF_NAME ?? git(['rev-parse', '--abbrev-ref', 'HEAD'], cwd),
|
|
84
|
+
prNumber: env.CI_MERGE_REQUEST_IID ? Number(env.CI_MERGE_REQUEST_IID) : undefined,
|
|
85
|
+
ciProvider: 'gitlab-ci',
|
|
86
|
+
ciPipeline: env.CI_PIPELINE_NAME ?? env.CI_PROJECT_PATH,
|
|
87
|
+
ciBuildNumber: env.CI_PIPELINE_IID,
|
|
88
|
+
ciRunUrl: env.CI_PIPELINE_URL,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
// Bitrise
|
|
92
|
+
if (env.BITRISE_IO === 'true') {
|
|
93
|
+
return compact({
|
|
94
|
+
gitSha: env.BITRISE_GIT_COMMIT ?? git(['rev-parse', 'HEAD'], cwd),
|
|
95
|
+
gitBranch: env.BITRISE_GIT_BRANCH ?? git(['rev-parse', '--abbrev-ref', 'HEAD'], cwd),
|
|
96
|
+
prNumber: env.BITRISE_PULL_REQUEST ? Number(env.BITRISE_PULL_REQUEST) : undefined,
|
|
97
|
+
ciProvider: 'bitrise',
|
|
98
|
+
ciPipeline: env.BITRISE_TRIGGERED_WORKFLOW_ID,
|
|
99
|
+
ciBuildNumber: env.BITRISE_BUILD_NUMBER,
|
|
100
|
+
ciRunUrl: env.BITRISE_BUILD_URL,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
// Local / unknown CI — resolve what git can tell us.
|
|
104
|
+
return compact({
|
|
105
|
+
gitSha: git(['rev-parse', 'HEAD'], cwd),
|
|
106
|
+
gitBranch: git(['rev-parse', '--abbrev-ref', 'HEAD'], cwd),
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
function assetTypeForExt(p) {
|
|
110
|
+
const e = path.extname(p).toLowerCase();
|
|
111
|
+
if (['.js', '.jsbundle', '.hbc', '.bundle'].includes(e))
|
|
112
|
+
return 'js';
|
|
113
|
+
if (['.png', '.jpg', '.jpeg', '.gif', '.webp', '.svg', '.bmp', '.ico'].includes(e))
|
|
114
|
+
return 'image';
|
|
115
|
+
if (['.ttf', '.otf', '.woff', '.woff2'].includes(e))
|
|
116
|
+
return 'font';
|
|
117
|
+
return 'other';
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Enumerate the bundle + its Metro assets into a manifest the backend stores as
|
|
121
|
+
* per-asset rows (so the dashboard can diff added/changed/removed and size
|
|
122
|
+
* regressions). The JS bundle is always the first entry; `assetsDir` is the
|
|
123
|
+
* `--assets-dest` directory from `buildBundle` (absent for pre-built bundles).
|
|
124
|
+
*/
|
|
125
|
+
function collectAssetManifest(bundlePath, bundleSha256, bundleSizeBytes, assetsDir) {
|
|
126
|
+
const assets = [
|
|
127
|
+
{ path: path.basename(bundlePath), assetType: 'js', sizeBytes: bundleSizeBytes, sha256: bundleSha256 },
|
|
128
|
+
];
|
|
129
|
+
if (assetsDir && fs.existsSync(assetsDir)) {
|
|
130
|
+
const walk = (dir) => {
|
|
131
|
+
for (const name of fs.readdirSync(dir)) {
|
|
132
|
+
const full = path.join(dir, name);
|
|
133
|
+
const st = fs.statSync(full);
|
|
134
|
+
if (st.isDirectory()) {
|
|
135
|
+
walk(full);
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
const rel = path.relative(assetsDir, full).split(path.sep).join('/');
|
|
139
|
+
assets.push({
|
|
140
|
+
path: rel,
|
|
141
|
+
assetType: assetTypeForExt(name),
|
|
142
|
+
sizeBytes: st.size,
|
|
143
|
+
sha256: (0, hash_1.sha256File)(full),
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
try {
|
|
149
|
+
walk(assetsDir);
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
/* best-effort — a missing asset dir just means a JS-only manifest */
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return assets;
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=provenance.js.map
|