@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,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output mode and the exit-code contract.
|
|
3
|
+
*
|
|
4
|
+
* ── Why this exists ─────────────────────────────────────────────────────────
|
|
5
|
+
*
|
|
6
|
+
* Every command printed emoji-decorated chalk and exited 1 for everything.
|
|
7
|
+
* A pipeline could not read back a release id, and — worse — could not tell
|
|
8
|
+
* "object storage flaked, retry this" from "the server rejected the promotion,
|
|
9
|
+
* stop and page someone". Both were `exit(1)`.
|
|
10
|
+
*
|
|
11
|
+
* ── The contract ────────────────────────────────────────────────────────────
|
|
12
|
+
*
|
|
13
|
+
* 0 success
|
|
14
|
+
* 1 usage or local error — bad flag, not signed in, no project. Do not retry.
|
|
15
|
+
* 2 server rejected it — a 4xx. The request was understood and refused.
|
|
16
|
+
* 3 a deliberate gate — a check the operator asked for said no
|
|
17
|
+
* (--fail-on, size budget, preflight gate).
|
|
18
|
+
* 4 transient — network, timeout, 5xx. Retrying is reasonable.
|
|
19
|
+
*
|
|
20
|
+
* 3 is the one that earns its place: it lets CI distinguish "your bundle is
|
|
21
|
+
* 2 MB over budget" from "the API is down", which are the same colour of red
|
|
22
|
+
* today and want opposite responses.
|
|
23
|
+
*/
|
|
24
|
+
export declare enum ExitCode {
|
|
25
|
+
Ok = 0,
|
|
26
|
+
Usage = 1,
|
|
27
|
+
Rejected = 2,
|
|
28
|
+
Gate = 3,
|
|
29
|
+
Network = 4
|
|
30
|
+
}
|
|
31
|
+
/** Enable machine output. Also set from SCALEBUN_JSON=1 for CI without flags. */
|
|
32
|
+
export declare function setJsonMode(on: boolean): void;
|
|
33
|
+
export declare function isJson(): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Print a result.
|
|
36
|
+
*
|
|
37
|
+
* `human` is a function rather than a string so the pretty path costs nothing
|
|
38
|
+
* when it will not run — several commands build tables and spinners that are
|
|
39
|
+
* pure waste under --json.
|
|
40
|
+
*/
|
|
41
|
+
export declare function emit(human: () => void, data: unknown): void;
|
|
42
|
+
/**
|
|
43
|
+
* A command the user is likely to want next.
|
|
44
|
+
*
|
|
45
|
+
* ── Why these are data and not just printed lines ───────────────────────────
|
|
46
|
+
*
|
|
47
|
+
* Commands already ended with a block like
|
|
48
|
+
*
|
|
49
|
+
* Watch it: scalebun ota status
|
|
50
|
+
* Widen it: scalebun ota rollout --percent 100
|
|
51
|
+
* Undo it: scalebun ota rollback
|
|
52
|
+
*
|
|
53
|
+
* which is genuinely the right advice at exactly the right moment — and then
|
|
54
|
+
* asks the reader to retype it. Inside the interactive session that is
|
|
55
|
+
* absurd: the session already knows how to run commands, it just could not
|
|
56
|
+
* see these because they were prose.
|
|
57
|
+
*
|
|
58
|
+
* Recording them alongside the printed text lets the session offer them as a
|
|
59
|
+
* choice, while the plain CLI keeps printing exactly what it printed before.
|
|
60
|
+
* One declaration, so the list a person reads and the list they can select
|
|
61
|
+
* from cannot disagree.
|
|
62
|
+
*/
|
|
63
|
+
export interface NextStep {
|
|
64
|
+
/** Why you would run it: "Watch it", "Undo it". */
|
|
65
|
+
label: string;
|
|
66
|
+
/** Argv, so the session can run it without parsing prose. */
|
|
67
|
+
argv: string[];
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Print the follow-up block AND record it for the session.
|
|
71
|
+
*
|
|
72
|
+
* Silent under --json: the steps belong in the JSON body if a pipeline wants
|
|
73
|
+
* them, not as prose interleaved with a document it is trying to parse.
|
|
74
|
+
*/
|
|
75
|
+
export declare function printNextSteps(steps: NextStep[], chalkish?: (s: string) => string): void;
|
|
76
|
+
/** Drain the recorded steps. The session calls this after each command. */
|
|
77
|
+
export declare function takeNextSteps(): NextStep[];
|
|
78
|
+
/**
|
|
79
|
+
* Fail with a typed exit code.
|
|
80
|
+
*
|
|
81
|
+
* Under --json the error is a JSON object on stdout as well, because a
|
|
82
|
+
* pipeline that has to parse stderr to find out what went wrong is not
|
|
83
|
+
* machine-readable in any useful sense.
|
|
84
|
+
*/
|
|
85
|
+
export declare function fail(message: string, details?: string[], code?: ExitCode): never;
|
|
86
|
+
/**
|
|
87
|
+
* Map a thrown API error onto an exit code.
|
|
88
|
+
*
|
|
89
|
+
* ApiClient formats errors as `API error (HTTP 422): …`, so the status is
|
|
90
|
+
* recoverable from the message without changing every call site. 4xx is the
|
|
91
|
+
* server understanding and refusing; 5xx and socket errors are worth a retry.
|
|
92
|
+
*/
|
|
93
|
+
export declare function codeForError(err: unknown): ExitCode;
|
|
94
|
+
/** Convenience: fail with the code implied by a thrown API error. */
|
|
95
|
+
export declare function failFromError(prefix: string, err: unknown, details?: string[]): never;
|
|
96
|
+
//# sourceMappingURL=output.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/utils/output.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,oBAAY,QAAQ;IAClB,EAAE,IAAI;IACN,KAAK,IAAI;IACT,QAAQ,IAAI;IACZ,IAAI,IAAI;IACR,OAAO,IAAI;CACZ;AAID,iFAAiF;AACjF,wBAAgB,WAAW,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,CAE7C;AAED,wBAAgB,MAAM,IAAI,OAAO,CAEhC;AAED;;;;;;GAMG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,IAAI,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAM3D;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,QAAQ;IACvB,mDAAmD;IACnD,KAAK,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAID;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAUxF;AAED,2EAA2E;AAC3E,wBAAgB,aAAa,IAAI,QAAQ,EAAE,CAI1C;AAED;;;;;;GAMG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,EAAO,EAAE,IAAI,GAAE,QAAyB,GAAG,KAAK,CAUpG;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,QAAQ,CAYnD;AAED,qEAAqE;AACrE,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,GAAE,MAAM,EAAO,GAAG,KAAK,CAGzF"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Output mode and the exit-code contract.
|
|
4
|
+
*
|
|
5
|
+
* ── Why this exists ─────────────────────────────────────────────────────────
|
|
6
|
+
*
|
|
7
|
+
* Every command printed emoji-decorated chalk and exited 1 for everything.
|
|
8
|
+
* A pipeline could not read back a release id, and — worse — could not tell
|
|
9
|
+
* "object storage flaked, retry this" from "the server rejected the promotion,
|
|
10
|
+
* stop and page someone". Both were `exit(1)`.
|
|
11
|
+
*
|
|
12
|
+
* ── The contract ────────────────────────────────────────────────────────────
|
|
13
|
+
*
|
|
14
|
+
* 0 success
|
|
15
|
+
* 1 usage or local error — bad flag, not signed in, no project. Do not retry.
|
|
16
|
+
* 2 server rejected it — a 4xx. The request was understood and refused.
|
|
17
|
+
* 3 a deliberate gate — a check the operator asked for said no
|
|
18
|
+
* (--fail-on, size budget, preflight gate).
|
|
19
|
+
* 4 transient — network, timeout, 5xx. Retrying is reasonable.
|
|
20
|
+
*
|
|
21
|
+
* 3 is the one that earns its place: it lets CI distinguish "your bundle is
|
|
22
|
+
* 2 MB over budget" from "the API is down", which are the same colour of red
|
|
23
|
+
* today and want opposite responses.
|
|
24
|
+
*/
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.ExitCode = void 0;
|
|
27
|
+
exports.setJsonMode = setJsonMode;
|
|
28
|
+
exports.isJson = isJson;
|
|
29
|
+
exports.emit = emit;
|
|
30
|
+
exports.printNextSteps = printNextSteps;
|
|
31
|
+
exports.takeNextSteps = takeNextSteps;
|
|
32
|
+
exports.fail = fail;
|
|
33
|
+
exports.codeForError = codeForError;
|
|
34
|
+
exports.failFromError = failFromError;
|
|
35
|
+
var ExitCode;
|
|
36
|
+
(function (ExitCode) {
|
|
37
|
+
ExitCode[ExitCode["Ok"] = 0] = "Ok";
|
|
38
|
+
ExitCode[ExitCode["Usage"] = 1] = "Usage";
|
|
39
|
+
ExitCode[ExitCode["Rejected"] = 2] = "Rejected";
|
|
40
|
+
ExitCode[ExitCode["Gate"] = 3] = "Gate";
|
|
41
|
+
ExitCode[ExitCode["Network"] = 4] = "Network";
|
|
42
|
+
})(ExitCode || (exports.ExitCode = ExitCode = {}));
|
|
43
|
+
let jsonMode = false;
|
|
44
|
+
/** Enable machine output. Also set from SCALEBUN_JSON=1 for CI without flags. */
|
|
45
|
+
function setJsonMode(on) {
|
|
46
|
+
jsonMode = on;
|
|
47
|
+
}
|
|
48
|
+
function isJson() {
|
|
49
|
+
return jsonMode || process.env.SCALEBUN_JSON === '1';
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Print a result.
|
|
53
|
+
*
|
|
54
|
+
* `human` is a function rather than a string so the pretty path costs nothing
|
|
55
|
+
* when it will not run — several commands build tables and spinners that are
|
|
56
|
+
* pure waste under --json.
|
|
57
|
+
*/
|
|
58
|
+
function emit(human, data) {
|
|
59
|
+
if (isJson()) {
|
|
60
|
+
process.stdout.write(JSON.stringify(data, null, 2) + '\n');
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
human();
|
|
64
|
+
}
|
|
65
|
+
let nextSteps = [];
|
|
66
|
+
/**
|
|
67
|
+
* Print the follow-up block AND record it for the session.
|
|
68
|
+
*
|
|
69
|
+
* Silent under --json: the steps belong in the JSON body if a pipeline wants
|
|
70
|
+
* them, not as prose interleaved with a document it is trying to parse.
|
|
71
|
+
*/
|
|
72
|
+
function printNextSteps(steps, chalkish) {
|
|
73
|
+
nextSteps = steps;
|
|
74
|
+
if (isJson() || !steps.length)
|
|
75
|
+
return;
|
|
76
|
+
const width = steps.reduce((w, s) => Math.max(w, s.label.length), 0);
|
|
77
|
+
console.log('');
|
|
78
|
+
for (const s of steps) {
|
|
79
|
+
const cmd = `scalebun ${s.argv.join(' ')}`;
|
|
80
|
+
console.log(` ${(s.label + ':').padEnd(width + 2)} ${chalkish ? chalkish(cmd) : cmd}`);
|
|
81
|
+
}
|
|
82
|
+
console.log('');
|
|
83
|
+
}
|
|
84
|
+
/** Drain the recorded steps. The session calls this after each command. */
|
|
85
|
+
function takeNextSteps() {
|
|
86
|
+
const out = nextSteps;
|
|
87
|
+
nextSteps = [];
|
|
88
|
+
return out;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Fail with a typed exit code.
|
|
92
|
+
*
|
|
93
|
+
* Under --json the error is a JSON object on stdout as well, because a
|
|
94
|
+
* pipeline that has to parse stderr to find out what went wrong is not
|
|
95
|
+
* machine-readable in any useful sense.
|
|
96
|
+
*/
|
|
97
|
+
function fail(message, details = [], code = ExitCode.Usage) {
|
|
98
|
+
if (isJson()) {
|
|
99
|
+
process.stdout.write(JSON.stringify({ ok: false, error: message, details, exitCode: code }, null, 2) + '\n');
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
console.error(`❌ ${message}`);
|
|
103
|
+
for (const d of details)
|
|
104
|
+
console.error(` ${d}`);
|
|
105
|
+
}
|
|
106
|
+
process.exit(code);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Map a thrown API error onto an exit code.
|
|
110
|
+
*
|
|
111
|
+
* ApiClient formats errors as `API error (HTTP 422): …`, so the status is
|
|
112
|
+
* recoverable from the message without changing every call site. 4xx is the
|
|
113
|
+
* server understanding and refusing; 5xx and socket errors are worth a retry.
|
|
114
|
+
*/
|
|
115
|
+
function codeForError(err) {
|
|
116
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
117
|
+
const m = /HTTP (\d{3})/.exec(msg);
|
|
118
|
+
if (m) {
|
|
119
|
+
const status = Number(m[1]);
|
|
120
|
+
if (status >= 500)
|
|
121
|
+
return ExitCode.Network;
|
|
122
|
+
if (status >= 400)
|
|
123
|
+
return ExitCode.Rejected;
|
|
124
|
+
}
|
|
125
|
+
if (/ETIMEDOUT|ECONNRESET|ENOTFOUND|EAI_AGAIN|socket hang up|network/i.test(msg)) {
|
|
126
|
+
return ExitCode.Network;
|
|
127
|
+
}
|
|
128
|
+
return ExitCode.Usage;
|
|
129
|
+
}
|
|
130
|
+
/** Convenience: fail with the code implied by a thrown API error. */
|
|
131
|
+
function failFromError(prefix, err, details = []) {
|
|
132
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
133
|
+
return fail(`${prefix}: ${msg}`, details, codeForError(err));
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/utils/output.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/** True when interactive hidden input is possible on this stdin. */
|
|
2
|
+
export declare function canPromptHidden(): boolean;
|
|
3
|
+
export declare function promptHidden(query: string): Promise<string>;
|
|
4
|
+
/** Close the shared prompt interface so the process can exit / move on. */
|
|
5
|
+
export declare function closePrompts(): void;
|
|
6
|
+
export interface TextOpts {
|
|
7
|
+
default?: string;
|
|
8
|
+
/** Reject the answer and re-ask; return the reason, or null to accept. */
|
|
9
|
+
validate?: (value: string) => string | null;
|
|
10
|
+
/**
|
|
11
|
+
* Accept an empty answer and return ''. Only for genuinely optional fields —
|
|
12
|
+
* the release note is the one that means it.
|
|
13
|
+
*/
|
|
14
|
+
allowEmpty?: boolean;
|
|
15
|
+
/** One line explaining what a good answer looks like, shown when re-asking. */
|
|
16
|
+
help?: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Free-text question with an optional default (shown in parentheses).
|
|
20
|
+
*
|
|
21
|
+
* ── Empty is a question, not an answer ──────────────────────────────────────
|
|
22
|
+
*
|
|
23
|
+
* This used to return '' the moment someone pressed Enter with nothing typed,
|
|
24
|
+
* and every caller then invented its own reaction. `text('App id')` in the
|
|
25
|
+
* publish wizard did `if (!id) process.exit(1)` — a silent exit 1, no message,
|
|
26
|
+
* from a prompt that had just told you it wanted an app id. Others carried the
|
|
27
|
+
* empty string onward until the API rejected a field the user never saw.
|
|
28
|
+
*
|
|
29
|
+
* Pressing Enter at a prompt with no default is almost never a decision; it is
|
|
30
|
+
* someone hurrying, or not knowing what is wanted. So empty now re-asks and
|
|
31
|
+
* explains, and callers with something sensible to fall back on pass a
|
|
32
|
+
* `default` — which is what "Enter means yes" should always have looked like.
|
|
33
|
+
* `allowEmpty` remains for fields that are honestly optional.
|
|
34
|
+
*/
|
|
35
|
+
export declare function text(query: string, opts?: TextOpts): Promise<string>;
|
|
36
|
+
/**
|
|
37
|
+
* Type-this-exact-phrase confirmation, for the destructive commands.
|
|
38
|
+
*
|
|
39
|
+
* Empty and wrong are DIFFERENT mistakes and deserve different answers:
|
|
40
|
+
*
|
|
41
|
+
* empty — cancel. Enter must stay an escape from a prompt that is about to
|
|
42
|
+
* delete a channel or roll back a fleet; re-asking would trap
|
|
43
|
+
* someone whose actual intent was to back out. But say so, rather
|
|
44
|
+
* than printing "Cancelled" and leaving them to guess whether the
|
|
45
|
+
* keystroke registered.
|
|
46
|
+
* wrong — re-ask. A typo in a channel name is not a decision to cancel, and
|
|
47
|
+
* making the operator re-run the whole command mid-incident to fix
|
|
48
|
+
* one character is the worst moment to be pedantic.
|
|
49
|
+
*/
|
|
50
|
+
export declare function confirmPhrase(query: string, expected: string, opts?: {
|
|
51
|
+
caseInsensitive?: boolean;
|
|
52
|
+
}): Promise<boolean>;
|
|
53
|
+
export interface ConfirmOpts {
|
|
54
|
+
/**
|
|
55
|
+
* What Enter means. OMIT IT to require an explicit y or n.
|
|
56
|
+
*
|
|
57
|
+
* Omit it for the decision that commits a flow. `(y/N)` promises that Enter
|
|
58
|
+
* is a safe no, and for "Configure advanced options?" that promise is worth
|
|
59
|
+
* keeping. But at the end of a wizard the user has just chosen a bundle and
|
|
60
|
+
* a rollout percentage, and one stray Enter throws all of it away with
|
|
61
|
+
* "Cancelled — nothing was promoted". Safe, and infuriating: the work is
|
|
62
|
+
* gone and nothing says which keystroke did it.
|
|
63
|
+
*/
|
|
64
|
+
default?: boolean;
|
|
65
|
+
/** Extra guidance shown when the answer is a number. */
|
|
66
|
+
numericHint?: string;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Yes/no question. Empty input takes the default; anything unrecognised
|
|
70
|
+
* RE-ASKS.
|
|
71
|
+
*
|
|
72
|
+
* ── Why it re-asks ──────────────────────────────────────────────────────────
|
|
73
|
+
*
|
|
74
|
+
* This used to be `return answer === 'y' || answer === 'yes'`, so every input
|
|
75
|
+
* that was not literally yes counted as no. Typing `50` at
|
|
76
|
+
* "Promote v14 to 100% of devices? (y/N)" — a completely reasonable thing to
|
|
77
|
+
* type when you wanted 50% — silently meant "no", and the CLI reported
|
|
78
|
+
* "Cancelled — nothing was promoted" as though the user had declined. The
|
|
79
|
+
* person did not decline. They answered a different question, and the tool
|
|
80
|
+
* discarded the answer and blamed them for it.
|
|
81
|
+
*
|
|
82
|
+
* The same swallow hid `yes please`, `Y ` with a stray space, and a mistyped
|
|
83
|
+
* `t`. Silently reading all of those as "no" is safe for the fleet and awful
|
|
84
|
+
* for the human: the destructive path is protected while the intent is lost
|
|
85
|
+
* without a word.
|
|
86
|
+
*/
|
|
87
|
+
export declare function confirm(query: string, opts?: ConfirmOpts): Promise<boolean>;
|
|
88
|
+
/** Integer question with optional default and min/max validation (loops until valid). */
|
|
89
|
+
export declare function number(query: string, opts?: {
|
|
90
|
+
default?: number;
|
|
91
|
+
min?: number;
|
|
92
|
+
max?: number;
|
|
93
|
+
}): Promise<number>;
|
|
94
|
+
export interface Choice<T> {
|
|
95
|
+
label: string;
|
|
96
|
+
value: T;
|
|
97
|
+
hint?: string;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Single choice from a list. Arrow keys (↑/↓, j/k) in a real TTY; a numbered
|
|
101
|
+
* prompt otherwise. Returns the chosen value.
|
|
102
|
+
*/
|
|
103
|
+
export declare function select<T>(query: string, choices: Choice<T>[], opts?: {
|
|
104
|
+
default?: number;
|
|
105
|
+
}): Promise<T>;
|
|
106
|
+
//# sourceMappingURL=prompt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/utils/prompt.ts"],"names":[],"mappings":"AA4BA,oEAAoE;AACpE,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAiD3D;AAiCD,2EAA2E;AAC3E,wBAAgB,YAAY,IAAI,IAAI,CAKnC;AAmBD,MAAM,WAAW,QAAQ;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAC5C;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,+EAA+E;IAC/E,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,QAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAsB9E;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE;IAAE,eAAe,CAAC,EAAE,OAAO,CAAA;CAAO,GACvC,OAAO,CAAC,OAAO,CAAC,CAclB;AA2BD,MAAM,WAAW,WAAW;IAC1B;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CAiCrF;AAED,yFAAyF;AACzF,wBAAsB,MAAM,CAC1B,KAAK,EAAE,MAAM,EACb,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAC1D,OAAO,CAAC,MAAM,CAAC,CA4CjB;AAED,MAAM,WAAW,MAAM,CAAC,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,CAAC,CAAC;IACT,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,wBAAsB,MAAM,CAAC,CAAC,EAC5B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EACpB,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9B,OAAO,CAAC,CAAC,CAAC,CAKZ"}
|