@scalebun/cli 1.10.1 → 1.11.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/lib/commands/ci-init.d.ts.map +1 -1
- package/lib/commands/ci-init.js +80 -2
- package/lib/commands/ci-init.js.map +1 -1
- package/lib/commands/doctor.d.ts.map +1 -1
- package/lib/commands/doctor.js +148 -3
- package/lib/commands/doctor.js.map +1 -1
- 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.map +1 -1
- package/lib/commands/login.js +29 -7
- package/lib/commands/login.js.map +1 -1
- package/lib/commands/ota-bundle.d.ts +15 -2
- package/lib/commands/ota-bundle.d.ts.map +1 -1
- package/lib/commands/ota-bundle.js +142 -12
- package/lib/commands/ota-bundle.js.map +1 -1
- package/lib/commands/ota-channels.d.ts.map +1 -1
- package/lib/commands/ota-channels.js +213 -21
- package/lib/commands/ota-channels.js.map +1 -1
- 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 +18 -0
- package/lib/commands/ota-keys.d.ts.map +1 -1
- package/lib/commands/ota-keys.js +149 -4
- package/lib/commands/ota-keys.js.map +1 -1
- 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.map +1 -1
- package/lib/commands/ota-publish.js +114 -38
- package/lib/commands/ota-publish.js.map +1 -1
- package/lib/commands/ota-rollout.d.ts.map +1 -1
- package/lib/commands/ota-rollout.js +201 -171
- package/lib/commands/ota-rollout.js.map +1 -1
- package/lib/commands/quickstart.d.ts.map +1 -1
- package/lib/commands/quickstart.js +110 -8
- package/lib/commands/quickstart.js.map +1 -1
- 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/index.js +140 -4
- package/lib/index.js.map +1 -1
- 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/utils/bundle.d.ts.map +1 -1
- package/lib/utils/bundle.js +24 -3
- package/lib/utils/bundle.js.map +1 -1
- 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 +16 -0
- package/lib/utils/credentials.d.ts.map +1 -1
- package/lib/utils/credentials.js +14 -3
- package/lib/utils/credentials.js.map +1 -1
- package/lib/utils/guide.d.ts +63 -0
- package/lib/utils/guide.d.ts.map +1 -0
- package/lib/utils/guide.js +189 -0
- package/lib/utils/guide.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 +80 -6
- package/lib/utils/prompt.d.ts.map +1 -1
- package/lib/utils/prompt.js +184 -20
- package/lib/utils/prompt.js.map +1 -1
- 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/ui.d.ts +10 -1
- package/lib/utils/ui.d.ts.map +1 -1
- package/lib/utils/ui.js +18 -57
- package/lib/utils/ui.js.map +1 -1
- 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/package.json +3 -2
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.isNonInteractive = isNonInteractive;
|
|
7
|
+
exports.resolveAppId = resolveAppId;
|
|
8
|
+
exports.describeRelease = describeRelease;
|
|
9
|
+
exports.resolveRelease = resolveRelease;
|
|
10
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
11
|
+
const client_1 = require("../api/client");
|
|
12
|
+
const credentials_1 = require("./credentials");
|
|
13
|
+
const apps_1 = require("./apps");
|
|
14
|
+
const context_1 = require("./context");
|
|
15
|
+
const prompt_1 = require("./prompt");
|
|
16
|
+
const output_1 = require("./output");
|
|
17
|
+
const validate_1 = require("./validate");
|
|
18
|
+
/**
|
|
19
|
+
* True when this process must not prompt: no TTY, or the caller forbade it.
|
|
20
|
+
*
|
|
21
|
+
* `isJson()` is the authority on machine mode rather than a per-command
|
|
22
|
+
* `opts.json`. Commander does not hand root options down to subcommand
|
|
23
|
+
* handlers — and because the root declares `--json` too, it consumes the flag
|
|
24
|
+
* before a subcommand ever sees it. So the flag is read once from raw argv at
|
|
25
|
+
* startup (`applyGlobalFlags`) and every consumer asks `output.ts`. The
|
|
26
|
+
* per-command `--json` declarations remain, purely so `--help` documents them.
|
|
27
|
+
*/
|
|
28
|
+
function isNonInteractive(opts = {}) {
|
|
29
|
+
return (!!opts.nonInteractive ||
|
|
30
|
+
(0, output_1.isJson)() ||
|
|
31
|
+
!process.stdin.isTTY ||
|
|
32
|
+
!process.stdout.isTTY ||
|
|
33
|
+
process.argv.includes('--non-interactive') ||
|
|
34
|
+
process.env.CI === 'true');
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Resolve the app id for a command.
|
|
38
|
+
*
|
|
39
|
+
* Never returns an empty string — it either returns an id or exits with a
|
|
40
|
+
* message naming the exact flag to pass.
|
|
41
|
+
*/
|
|
42
|
+
async function resolveAppId(opts = {}) {
|
|
43
|
+
const flag = opts.flag ?? '--app-id';
|
|
44
|
+
// An explicit flag is checked before it is used. The two ways an id arrives
|
|
45
|
+
// broken both end in a confusing 404 rather than a usage error: an unset
|
|
46
|
+
// shell variable (`--app-id $APP`) leaves the flag to swallow whatever comes
|
|
47
|
+
// next, and a mis-quoted paste brings whitespace with it. Only the explicit
|
|
48
|
+
// value is checked — a stored scalebun.json or SCALEBUN_APP_ID is the user's
|
|
49
|
+
// own earlier input and failing here would strand a linked project.
|
|
50
|
+
if (opts.appId !== undefined)
|
|
51
|
+
(0, validate_1.checkedId)(flag, opts.appId);
|
|
52
|
+
// Layers 1 + 2 — explicit, then ambient. getContext does both, in order.
|
|
53
|
+
const ctx = (0, context_1.getContext)({ appId: opts.appId });
|
|
54
|
+
if (ctx.appId)
|
|
55
|
+
return ctx.appId;
|
|
56
|
+
const creds = (0, credentials_1.readCredentials)();
|
|
57
|
+
if (!creds) {
|
|
58
|
+
(0, output_1.fail)('Not signed in.', ['Run `scalebun login`, or set SCALEBUN_TOKEN in CI.'], output_1.ExitCode.Usage);
|
|
59
|
+
}
|
|
60
|
+
// Layers 3 + 4 need the network, so they are also the layers CI must not reach.
|
|
61
|
+
if (isNonInteractive(opts)) {
|
|
62
|
+
(0, output_1.fail)(`${flag} is required.`, [
|
|
63
|
+
`Pass ${flag}, set SCALEBUN_APP_ID, or run \`scalebun link\` in this project.`,
|
|
64
|
+
'This shell is not interactive, so the app cannot be chosen here.',
|
|
65
|
+
], output_1.ExitCode.Usage);
|
|
66
|
+
}
|
|
67
|
+
let entries;
|
|
68
|
+
try {
|
|
69
|
+
entries = await (0, apps_1.fetchAllApps)(new client_1.ApiClient(creds));
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
(0, output_1.fail)(`Could not list apps: ${err?.message ?? err}`, [], output_1.ExitCode.Network);
|
|
73
|
+
}
|
|
74
|
+
if (!entries.length) {
|
|
75
|
+
(0, output_1.fail)('This account has no apps yet.', ['Create one in the dashboard (Organization → Project → App), then re-run.'], output_1.ExitCode.Usage);
|
|
76
|
+
}
|
|
77
|
+
// Layer 3 — one app is not a choice, so do not present it as one.
|
|
78
|
+
if (entries.length === 1) {
|
|
79
|
+
const only = entries[0];
|
|
80
|
+
console.log(chalk_1.default.dim(`Using your only app: ${only.app.name} (${only.app.id})`));
|
|
81
|
+
rememberIfLinked(only);
|
|
82
|
+
return only.app.id;
|
|
83
|
+
}
|
|
84
|
+
// Layer 4 — a real choice, so ask.
|
|
85
|
+
const chosen = await (0, prompt_1.select)('Which app?', entries.map((e) => ({
|
|
86
|
+
label: `${e.app.name} ${chalk_1.default.dim(`${e.orgName} / ${e.projectName}`)}`,
|
|
87
|
+
value: e,
|
|
88
|
+
})));
|
|
89
|
+
(0, prompt_1.closePrompts)();
|
|
90
|
+
rememberIfLinked(chosen);
|
|
91
|
+
return chosen.app.id;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Cache the choice into an EXISTING scalebun.json.
|
|
95
|
+
*
|
|
96
|
+
* Deliberately does not create one: `scalebun link` is the command that decides
|
|
97
|
+
* a directory is a ScaleBun project, and a picker answering one command should
|
|
98
|
+
* not silently write a config file into a directory the user never linked.
|
|
99
|
+
*/
|
|
100
|
+
function rememberIfLinked(entry) {
|
|
101
|
+
const root = (0, context_1.findProjectRoot)();
|
|
102
|
+
if (!root)
|
|
103
|
+
return;
|
|
104
|
+
try {
|
|
105
|
+
(0, context_1.writeProjectConfig)(root, { appId: entry.app.id, appName: entry.app.name });
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
/* cache only */
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
function describeRelease(r) {
|
|
112
|
+
const v = r.bundle?.version != null ? `v${r.bundle.version}` : r.id;
|
|
113
|
+
const p = r.bundle?.platform ? ` (${r.bundle.platform})` : '';
|
|
114
|
+
return `${v}${p} — ${r.status} @ ${r.rolloutPercent ?? 0}%`;
|
|
115
|
+
}
|
|
116
|
+
async function resolveRelease(releases, opts) {
|
|
117
|
+
if (opts.releaseId) {
|
|
118
|
+
const hit = releases.find((r) => r.id === opts.releaseId);
|
|
119
|
+
if (!hit)
|
|
120
|
+
(0, output_1.fail)(`No release ${opts.releaseId} on this app.`, [], output_1.ExitCode.Usage);
|
|
121
|
+
return hit;
|
|
122
|
+
}
|
|
123
|
+
const candidates = releases.filter((r) => opts.statuses.includes(r.status));
|
|
124
|
+
if (candidates.length === 0) {
|
|
125
|
+
(0, output_1.fail)(`Nothing to ${opts.verb} — no release is ${opts.statuses.join(' or ')}.`, ['Run `scalebun ota releases` to see the current state.'], output_1.ExitCode.Usage);
|
|
126
|
+
}
|
|
127
|
+
if (candidates.length === 1)
|
|
128
|
+
return candidates[0];
|
|
129
|
+
// More than one qualifies. Refusing to guess is right — but the old code
|
|
130
|
+
// then exited and made the operator copy an id out of a list during an
|
|
131
|
+
// incident. On a TTY, offer the list as a choice instead.
|
|
132
|
+
if (isNonInteractive(opts)) {
|
|
133
|
+
(0, output_1.fail)(`${candidates.length} releases are ${opts.statuses.join(' or ')} — pass --release-id.`, candidates.map((r) => ` ${r.id} ${describeRelease(r)}`), output_1.ExitCode.Usage);
|
|
134
|
+
}
|
|
135
|
+
const chosen = await (0, prompt_1.select)(`Which release do you want to ${opts.verb}?`, candidates.map((r) => ({ label: describeRelease(r), value: r })));
|
|
136
|
+
(0, prompt_1.closePrompts)();
|
|
137
|
+
return chosen;
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=resolve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/utils/resolve.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Locating and running @scalebun/react-native's bin from this CLI.
|
|
3
|
+
*
|
|
4
|
+
* `init android` / `init ios` live in the SDK package (they need its native
|
|
5
|
+
* codemods), but both this CLI and the SDK declare the same `scalebun` bin
|
|
6
|
+
* name — so whichever binary the user ends up with must be able to reach the
|
|
7
|
+
* other's commands. The SDK bin already forwards `ota …` here; these helpers
|
|
8
|
+
* are the return path, shared by the unknown-command forwarder (index.ts) and
|
|
9
|
+
* quickstart's native-wiring step.
|
|
10
|
+
*/
|
|
11
|
+
/** Resolve @scalebun/react-native's bin script, or null when absent. */
|
|
12
|
+
export declare function resolveSdkBin(): string | null;
|
|
13
|
+
/**
|
|
14
|
+
* Run the SDK bin with the given argv, inheriting stdio.
|
|
15
|
+
* Returns the child's exit code (1 when the child died on a signal).
|
|
16
|
+
*/
|
|
17
|
+
export declare function runSdkBin(sdkBin: string, args: string[]): number;
|
|
18
|
+
//# sourceMappingURL=sdkBin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdkBin.d.ts","sourceRoot":"","sources":["../../src/utils/sdkBin.ts"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;AAEH,wEAAwE;AACxE,wBAAgB,aAAa,IAAI,MAAM,GAAG,IAAI,CAc7C;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAGhE"}
|
|
@@ -0,0 +1,76 @@
|
|
|
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.resolveSdkBin = resolveSdkBin;
|
|
37
|
+
exports.runSdkBin = runSdkBin;
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const child_process_1 = require("child_process");
|
|
41
|
+
/**
|
|
42
|
+
* Locating and running @scalebun/react-native's bin from this CLI.
|
|
43
|
+
*
|
|
44
|
+
* `init android` / `init ios` live in the SDK package (they need its native
|
|
45
|
+
* codemods), but both this CLI and the SDK declare the same `scalebun` bin
|
|
46
|
+
* name — so whichever binary the user ends up with must be able to reach the
|
|
47
|
+
* other's commands. The SDK bin already forwards `ota …` here; these helpers
|
|
48
|
+
* are the return path, shared by the unknown-command forwarder (index.ts) and
|
|
49
|
+
* quickstart's native-wiring step.
|
|
50
|
+
*/
|
|
51
|
+
/** Resolve @scalebun/react-native's bin script, or null when absent. */
|
|
52
|
+
function resolveSdkBin() {
|
|
53
|
+
try {
|
|
54
|
+
// The SDK's `exports` map has no "./bin/*" entry, so resolving the bin
|
|
55
|
+
// subpath directly throws ERR_PACKAGE_PATH_NOT_EXPORTED. "./package.json"
|
|
56
|
+
// IS exported — resolve that and join. cwd first: the SDK is installed in
|
|
57
|
+
// the app being worked on, not necessarily next to this CLI.
|
|
58
|
+
const pkg = require.resolve('@scalebun/react-native/package.json', {
|
|
59
|
+
paths: [process.cwd(), __dirname],
|
|
60
|
+
});
|
|
61
|
+
const bin = path.join(path.dirname(pkg), 'bin', 'scalebun.js');
|
|
62
|
+
return fs.existsSync(bin) ? bin : null;
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Run the SDK bin with the given argv, inheriting stdio.
|
|
70
|
+
* Returns the child's exit code (1 when the child died on a signal).
|
|
71
|
+
*/
|
|
72
|
+
function runSdkBin(sdkBin, args) {
|
|
73
|
+
const res = (0, child_process_1.spawnSync)(process.execPath, [sdkBin, ...args], { stdio: 'inherit' });
|
|
74
|
+
return res.status ?? 1;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=sdkBin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdkBin.js","sourceRoot":"","sources":["../../src/utils/sdkBin.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgBA,sCAcC;AAMD,8BAGC;AAvCD,uCAAyB;AACzB,2CAA6B;AAC7B,iDAA0C;AAE1C;;;;;;;;;GASG;AAEH,wEAAwE;AACxE,SAAgB,aAAa;IAC3B,IAAI,CAAC;QACH,uEAAuE;QACvE,0EAA0E;QAC1E,0EAA0E;QAC1E,6DAA6D;QAC7D,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,qCAAqC,EAAE;YACjE,KAAK,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC;SAClC,CAAC,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC;QAC/D,OAAO,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAgB,SAAS,CAAC,MAAc,EAAE,IAAc;IACtD,MAAM,GAAG,GAAG,IAAA,yBAAS,EAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IACjF,OAAO,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC;AACzB,CAAC"}
|
package/lib/utils/ui.d.ts
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The status box as a string.
|
|
3
|
+
*
|
|
4
|
+
* The interactive session redraws the whole screen on every keypress, and it
|
|
5
|
+
* does that with ONE write — a sequence of console.log calls would tear
|
|
6
|
+
* visibly as the terminal painted each line. Returning text lets the session
|
|
7
|
+
* compose a frame; `renderStatus` below keeps the print-and-exit path
|
|
8
|
+
* unchanged, so the two can never drift.
|
|
9
|
+
*/
|
|
10
|
+
export declare function statusText(): string;
|
|
1
11
|
export declare function renderStatus(): void;
|
|
2
|
-
export declare function renderCommands(): void;
|
|
3
12
|
//# sourceMappingURL=ui.d.ts.map
|
package/lib/utils/ui.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../src/utils/ui.ts"],"names":[],"mappings":"AAYA,wBAAgB,
|
|
1
|
+
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../src/utils/ui.ts"],"names":[],"mappings":"AAYA;;;;;;;;GAQG;AACH,wBAAgB,UAAU,IAAI,MAAM,CA8BnC;AAED,wBAAgB,YAAY,IAAI,IAAI,CAEnC"}
|
package/lib/utils/ui.js
CHANGED
|
@@ -3,8 +3,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.statusText = statusText;
|
|
6
7
|
exports.renderStatus = renderStatus;
|
|
7
|
-
exports.renderCommands = renderCommands;
|
|
8
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
9
9
|
const credentials_1 = require("./credentials");
|
|
10
10
|
// NOTE: the splash art (mark + wordmark) now lives in ../ui/banner.ts. This file
|
|
@@ -14,14 +14,24 @@ const credentials_1 = require("./credentials");
|
|
|
14
14
|
// or the right border lands on a different column on every row.
|
|
15
15
|
const STRIP_ANSI = /\x1b\[[0-9;]*m/g;
|
|
16
16
|
const visibleLen = (s) => s.replace(STRIP_ANSI, '').length;
|
|
17
|
-
|
|
17
|
+
/**
|
|
18
|
+
* The status box as a string.
|
|
19
|
+
*
|
|
20
|
+
* The interactive session redraws the whole screen on every keypress, and it
|
|
21
|
+
* does that with ONE write — a sequence of console.log calls would tear
|
|
22
|
+
* visibly as the terminal painted each line. Returning text lets the session
|
|
23
|
+
* compose a frame; `renderStatus` below keeps the print-and-exit path
|
|
24
|
+
* unchanged, so the two can never drift.
|
|
25
|
+
*/
|
|
26
|
+
function statusText() {
|
|
27
|
+
const out = [];
|
|
18
28
|
const creds = (0, credentials_1.readCredentials)();
|
|
19
29
|
const verbose = process.argv.slice(2).includes('--verbose');
|
|
20
30
|
const inner = 58;
|
|
21
|
-
const border = (l, r) =>
|
|
31
|
+
const border = (l, r) => out.push(chalk_1.default.gray(l + '─'.repeat(inner + 2) + r));
|
|
22
32
|
const row = (content) => {
|
|
23
33
|
const pad = ' '.repeat(Math.max(0, inner - visibleLen(content)));
|
|
24
|
-
|
|
34
|
+
out.push(`${chalk_1.default.gray('│')} ${content}${pad} ${chalk_1.default.gray('│')}`);
|
|
25
35
|
};
|
|
26
36
|
border('┌', '┐');
|
|
27
37
|
if (creds) {
|
|
@@ -41,59 +51,10 @@ function renderStatus() {
|
|
|
41
51
|
row(`${chalk_1.default.bold.yellow('○ NOT LOGGED IN')} ${chalk_1.default.dim('· run')} ${chalk_1.default.cyan('scalebun login')}`);
|
|
42
52
|
}
|
|
43
53
|
border('└', '┘');
|
|
44
|
-
|
|
54
|
+
out.push('');
|
|
55
|
+
return out.join('\n') + '\n';
|
|
45
56
|
}
|
|
46
|
-
function
|
|
47
|
-
|
|
48
|
-
// commands above (' 1. ' is 7 chars wide, so `scalebun login` sits at col 7).
|
|
49
|
-
const cmd = (name, desc) => console.log(` ${chalk_1.default.cyan(name.padEnd(34))} ${chalk_1.default.dim(desc)}`);
|
|
50
|
-
// ── Get started: publish your first OTA update ──────────────────────────────
|
|
51
|
-
console.log(chalk_1.default.bold.white(' PUBLISH YOUR FIRST OTA UPDATE'));
|
|
52
|
-
console.log(` ${chalk_1.default.green('scalebun quickstart')} ${chalk_1.default.dim('one guided flow: login → app → keys → health check → first release')}`);
|
|
53
|
-
console.log(chalk_1.default.dim(' …or do it step by step:'));
|
|
54
|
-
console.log(` ${chalk_1.default.dim('1.')} ${chalk_1.default.cyan('scalebun login')} ${chalk_1.default.dim('authenticate (paste an access token)')}`);
|
|
55
|
-
console.log(` ${chalk_1.default.dim('2.')} ${chalk_1.default.cyan('scalebun apps')} ${chalk_1.default.dim('find your --app-id')}`);
|
|
56
|
-
console.log(` ${chalk_1.default.dim('3.')} ${chalk_1.default.cyan('scalebun init android')} ${chalk_1.default.dim('/')} ${chalk_1.default.cyan('init ios')} ${chalk_1.default.dim('wire the native app for OTA, then rebuild')}`);
|
|
57
|
-
console.log(` ${chalk_1.default.dim('4.')} ${chalk_1.default.cyan('scalebun ota generate-key-pair --app-id <id>')} ${chalk_1.default.dim('(optional) code-signing key')}`);
|
|
58
|
-
console.log(` ${chalk_1.default.dim('5.')} ${chalk_1.default.cyan('scalebun ota publish --app-id <id> --hermes')} ${chalk_1.default.dim('bundle, upload & ship it')}`);
|
|
59
|
-
console.log('');
|
|
60
|
-
// ── Project setup (from @scalebun/react-native) ─────────────────────────────
|
|
61
|
-
console.log(chalk_1.default.bold.white(' PROJECT SETUP'));
|
|
62
|
-
cmd('scalebun doctor', 'check the project is correctly set up for OTA updates');
|
|
63
|
-
cmd('scalebun init ios', 'wire the iOS AppDelegate for OTA + Direct APNs (--check / --dry-run)');
|
|
64
|
-
cmd('scalebun init android', 'wire the Android MainApplication for OTA (--check / --dry-run)');
|
|
65
|
-
console.log('');
|
|
66
|
-
// ── OTA (every subcommand, so it is discoverable) ───────────────────────────
|
|
67
|
-
console.log(chalk_1.default.bold.white(' OTA UPDATES'));
|
|
68
|
-
cmd('scalebun ota publish', 'bundle, upload & publish a release (--app-id, --platform, --hermes)');
|
|
69
|
-
cmd('scalebun ota bundle', 'build a standalone bundle file for manual dashboard upload');
|
|
70
|
-
cmd('scalebun ota channels', 'list OTA channels (default, staging, production)');
|
|
71
|
-
cmd('scalebun ota releases', 'list releases and their current rollout state');
|
|
72
|
-
cmd('scalebun ota rollout', 'set rollout % (also: ota pause / resume / rollback)');
|
|
73
|
-
cmd('scalebun ota generate-key-pair', 'create an ed25519 signing key and register the public half');
|
|
74
|
-
cmd('scalebun ota register-key', 'register an existing public key with an app');
|
|
75
|
-
cmd('scalebun ota keys', 'list signing keys registered for an app');
|
|
76
|
-
cmd('scalebun ota delete-bundle', 'delete an OTA bundle permanently');
|
|
77
|
-
console.log('');
|
|
78
|
-
// ── Account & tooling ───────────────────────────────────────────────────────
|
|
79
|
-
console.log(chalk_1.default.bold.white(' ACCOUNT & TOOLING'));
|
|
80
|
-
cmd('scalebun login / logout', 'authenticate (paste a token) / clear stored credentials');
|
|
81
|
-
cmd('scalebun apps', 'list your apps + IDs (--keys for client keys)');
|
|
82
|
-
cmd('scalebun quickstart', 'guided first-release walkthrough');
|
|
83
|
-
cmd('scalebun migrate codepush', 'migrate a project from Microsoft CodePush to Scalebun OTA');
|
|
84
|
-
cmd('scalebun ci init', 'generate a CI/CD pipeline for OTA publishing');
|
|
85
|
-
cmd('scalebun launch', 'open the CLI in a standalone terminal window');
|
|
86
|
-
console.log('');
|
|
87
|
-
console.log(chalk_1.default.dim(` Run 'scalebun <command> --help' for every flag (e.g. scalebun ota publish --help).`));
|
|
88
|
-
console.log('');
|
|
89
|
-
// ── Examples ────────────────────────────────────────────────────────────────
|
|
90
|
-
console.log(chalk_1.default.bold.white(' EXAMPLES'));
|
|
91
|
-
console.log(chalk_1.default.gray(' # Silent update — applies on next launch (the default):'));
|
|
92
|
-
console.log(` ${chalk_1.default.dim('$')} ${chalk_1.default.green('scalebun ota publish')} --app-id <id> --platform android --hermes --release-note "UI refresh"\n`);
|
|
93
|
-
console.log(chalk_1.default.gray(' # Immediate hotfix — reloads the app right away:'));
|
|
94
|
-
console.log(` ${chalk_1.default.dim('$')} ${chalk_1.default.green('scalebun ota publish')} --app-id <id> --platform android --hermes --install-mode IMMEDIATE --release-note "Critical fix"\n`);
|
|
95
|
-
console.log(chalk_1.default.gray(' # Cautious staged rollout — start at 10%, then ramp:'));
|
|
96
|
-
console.log(` ${chalk_1.default.dim('$')} ${chalk_1.default.green('scalebun ota publish')} --app-id <id> --platform android --hermes --rollout 10`);
|
|
97
|
-
console.log(` ${chalk_1.default.dim('$')} ${chalk_1.default.green('scalebun ota rollout')} --app-id <id> --percent 100\n`);
|
|
57
|
+
function renderStatus() {
|
|
58
|
+
process.stdout.write(statusText());
|
|
98
59
|
}
|
|
99
60
|
//# sourceMappingURL=ui.js.map
|
package/lib/utils/ui.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../../src/utils/ui.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../../src/utils/ui.ts"],"names":[],"mappings":";;;;;AAqBA,gCA8BC;AAED,oCAEC;AAvDD,kDAA0B;AAC1B,+CAAiE;AAEjE,iFAAiF;AACjF,gFAAgF;AAEhF,6EAA6E;AAC7E,kFAAkF;AAClF,gEAAgE;AAChE,MAAM,UAAU,GAAG,iBAAiB,CAAC;AACrC,MAAM,UAAU,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC;AAE3E;;;;;;;;GAQG;AACH,SAAgB,UAAU;IACxB,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,MAAM,KAAK,GAAG,IAAA,6BAAe,GAAE,CAAC;IAChC,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC5D,MAAM,KAAK,GAAG,EAAE,CAAC;IAEjB,MAAM,MAAM,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,eAAK,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC7F,MAAM,GAAG,GAAG,CAAC,OAAe,EAAE,EAAE;QAC9B,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACjE,GAAG,CAAC,IAAI,CAAC,GAAG,eAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,OAAO,GAAG,GAAG,IAAI,eAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACrE,CAAC,CAAC;IAEF,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACjB,IAAI,KAAK,EAAE,CAAC;QACV,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACzC,4EAA4E;QAC5E,mCAAmC;QACnC,IAAI,KAAK,CAAC,KAAK;YAAE,GAAG,CAAC,eAAK,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;QAC7C,yEAAyE;QACzE,2EAA2E;QAC3E,yEAAyE;QACzE,IAAI,OAAO,IAAI,KAAK,CAAC,MAAM,KAAK,6BAAe,EAAE,CAAC;YAChD,GAAG,CAAC,GAAG,eAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,eAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,GAAG,eAAK,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,IAAI,eAAK,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,eAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;IACvG,CAAC;IACD,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACjB,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACb,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAC/B,CAAC;AAED,SAAgB,YAAY;IAC1B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;AACrC,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/** The allowed value closest to `raw`, when one is close enough to mean it. */
|
|
2
|
+
export declare function nearest(raw: string, allowed: readonly string[]): string | null;
|
|
3
|
+
export interface EnumOpts {
|
|
4
|
+
/** Accept any letter case, normalising to the allowed spelling. */
|
|
5
|
+
caseInsensitive?: boolean;
|
|
6
|
+
/** Extra guidance printed under the error. */
|
|
7
|
+
details?: string[];
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* One of `allowed`, or exit.
|
|
11
|
+
*
|
|
12
|
+
* Replaces `if (opts.x === 'known')` chains, where an unrecognised value is
|
|
13
|
+
* indistinguishable from the flag not being passed at all.
|
|
14
|
+
*/
|
|
15
|
+
export declare function checkedEnum<T extends string>(flag: string, raw: string, allowed: readonly T[], opts?: EnumOpts): T;
|
|
16
|
+
export interface IntOpts {
|
|
17
|
+
min?: number;
|
|
18
|
+
max?: number;
|
|
19
|
+
/** Used when the flag was omitted entirely. Never used to paper over junk. */
|
|
20
|
+
fallback?: number;
|
|
21
|
+
details?: string[];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* A whole number in range, or exit.
|
|
25
|
+
*
|
|
26
|
+
* `Number('12abc')` is NaN and `Number('')` is 0 — both of which a `|| default`
|
|
27
|
+
* turns into a plausible-looking value the user never asked for. Everything
|
|
28
|
+
* that is not cleanly an integer is refused here instead.
|
|
29
|
+
*/
|
|
30
|
+
export declare function checkedInt(flag: string, raw: unknown, opts?: IntOpts): number;
|
|
31
|
+
/**
|
|
32
|
+
* A rollout percentage, 0-100.
|
|
33
|
+
*
|
|
34
|
+
* A trailing `%` is accepted because it is the obvious thing to type for a
|
|
35
|
+
* value the help text calls a percentage, and refusing it teaches nothing.
|
|
36
|
+
*/
|
|
37
|
+
export declare function checkedPercent(flag: string, raw: unknown, fallback?: number): number;
|
|
38
|
+
/**
|
|
39
|
+
* An identifier, or exit.
|
|
40
|
+
*
|
|
41
|
+
* Catches the two ways ids arrive broken: an empty value from an unquoted
|
|
42
|
+
* shell variable that did not expand (`--app-id $APP` with APP unset becomes
|
|
43
|
+
* `--app-id` swallowing the NEXT flag), and a value with whitespace or a
|
|
44
|
+
* leading dash from a mis-quoted paste. Both otherwise reach the API and come
|
|
45
|
+
* back as a confusing 404.
|
|
46
|
+
*/
|
|
47
|
+
export declare function checkedId(flag: string, raw: unknown): string;
|
|
48
|
+
/**
|
|
49
|
+
* A semver range the server will accept, or exit.
|
|
50
|
+
*
|
|
51
|
+
* Deliberately loose. Ranges legitimately look like `1.0.0`, `^1.0.0`,
|
|
52
|
+
* `>=1.0.0`, `1.x`, `>=1.0.0 <2.0.0` and `*`, and a strict grammar here would
|
|
53
|
+
* reject valid input the API would have taken. The check is only for the
|
|
54
|
+
* shapes that are certainly wrong — empty, or containing no version at all —
|
|
55
|
+
* because those come back as a 400 describing a field the user never typed.
|
|
56
|
+
*/
|
|
57
|
+
export declare function checkedVersionRange(flag: string, raw: unknown): string;
|
|
58
|
+
/** Non-empty free text, or exit. Trims, so a whitespace-only value is empty. */
|
|
59
|
+
export declare function checkedText(flag: string, raw: unknown, opts?: {
|
|
60
|
+
max?: number;
|
|
61
|
+
}): string;
|
|
62
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/utils/validate.ts"],"names":[],"mappings":"AAoDA,+EAA+E;AAC/E,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAc9E;AAED,MAAM,WAAW,QAAQ;IACvB,mEAAmE;IACnE,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,8CAA8C;IAC9C,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAC1C,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,SAAS,CAAC,EAAE,EACrB,IAAI,GAAE,QAAa,GAClB,CAAC,CAcH;AAED,MAAM,WAAW,OAAO;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,GAAE,OAAY,GAAG,MAAM,CAgCjF;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAQpF;AAED;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,MAAM,CAgB5D;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,MAAM,CAiBtE;AAED,gFAAgF;AAChF,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,MAAM,CAO3F"}
|