@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,250 @@
|
|
|
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.KEEP_BUNDLES = exports.BUNDLES_DIR = void 0;
|
|
37
|
+
exports.stamp = stamp;
|
|
38
|
+
exports.bundleFileName = bundleFileName;
|
|
39
|
+
exports.metaPathFor = metaPathFor;
|
|
40
|
+
exports.sigPathFor = sigPathFor;
|
|
41
|
+
exports.loadBundleAt = loadBundleAt;
|
|
42
|
+
exports.listLocalBundles = listLocalBundles;
|
|
43
|
+
exports.sigState = sigState;
|
|
44
|
+
exports.humanSize = humanSize;
|
|
45
|
+
exports.ago = ago;
|
|
46
|
+
exports.validForMinutes = validForMinutes;
|
|
47
|
+
exports.describeBundle = describeBundle;
|
|
48
|
+
exports.pruneExpiredSignatures = pruneExpiredSignatures;
|
|
49
|
+
exports.pruneBundles = pruneBundles;
|
|
50
|
+
const fs = __importStar(require("fs"));
|
|
51
|
+
const path = __importStar(require("path"));
|
|
52
|
+
/**
|
|
53
|
+
* The local bundles/ folder: naming, listing and sign status.
|
|
54
|
+
*
|
|
55
|
+
* `ota bundle` used to write a single fixed path — bundles/index.android.bundle —
|
|
56
|
+
* so every build silently destroyed the one before it. That is fine while a
|
|
57
|
+
* bundle is a throwaway, and wrong the moment you have three builds and need the
|
|
58
|
+
* SECOND one because the newest turned out to be broken. Bundles are a working
|
|
59
|
+
* set, so they get distinct names and keep their provenance.
|
|
60
|
+
*/
|
|
61
|
+
exports.BUNDLES_DIR = 'bundles';
|
|
62
|
+
/** Keep generously: 19MB each is cheap, deleting the build someone wanted is not. */
|
|
63
|
+
exports.KEEP_BUNDLES = 10;
|
|
64
|
+
/** `2026-09-10T15-42` — sortable, and legal on Windows (no colons). */
|
|
65
|
+
function stamp(d = new Date()) {
|
|
66
|
+
const p = (n) => String(n).padStart(2, '0');
|
|
67
|
+
return (`${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}` +
|
|
68
|
+
`T${p(d.getHours())}-${p(d.getMinutes())}`);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* `index.android.2026-09-10T15-42.a3f9c2.bundle`
|
|
72
|
+
*
|
|
73
|
+
* Time orders the list; the short git sha is what a human actually recognises
|
|
74
|
+
* ("the one before I made that change"). Without a sha the name still works,
|
|
75
|
+
* it is just less identifiable.
|
|
76
|
+
*/
|
|
77
|
+
function bundleFileName(platform, gitSha, at = new Date()) {
|
|
78
|
+
const short = gitSha ? `.${gitSha.slice(0, 6)}` : '';
|
|
79
|
+
return `index.${platform}.${stamp(at)}${short}.bundle`;
|
|
80
|
+
}
|
|
81
|
+
function metaPathFor(bundlePath) {
|
|
82
|
+
return `${bundlePath}.json`;
|
|
83
|
+
}
|
|
84
|
+
function sigPathFor(bundlePath) {
|
|
85
|
+
return `${bundlePath}.sbsig`;
|
|
86
|
+
}
|
|
87
|
+
function readJson(p) {
|
|
88
|
+
try {
|
|
89
|
+
return JSON.parse(fs.readFileSync(p, 'utf8'));
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Load one bundle by path, wherever it lives.
|
|
97
|
+
*
|
|
98
|
+
* `ota bundle build --output <dir>` puts the artifact outside bundles/, and a
|
|
99
|
+
* signature belongs beside its bundle rather than in some blessed folder. So
|
|
100
|
+
* signing reads the sidecars next to the file it was handed, and refuses to
|
|
101
|
+
* hunt for them elsewhere.
|
|
102
|
+
*/
|
|
103
|
+
function loadBundleAt(bundlePath) {
|
|
104
|
+
const abs = path.resolve(bundlePath);
|
|
105
|
+
if (!fs.existsSync(abs) || !fs.statSync(abs).isFile())
|
|
106
|
+
return null;
|
|
107
|
+
const st = fs.statSync(abs);
|
|
108
|
+
return {
|
|
109
|
+
bundlePath: abs,
|
|
110
|
+
metaPath: metaPathFor(abs),
|
|
111
|
+
sigPath: sigPathFor(abs),
|
|
112
|
+
name: path.basename(abs),
|
|
113
|
+
meta: readJson(metaPathFor(abs)),
|
|
114
|
+
sig: readJson(sigPathFor(abs)),
|
|
115
|
+
size: st.size,
|
|
116
|
+
mtimeMs: st.mtimeMs,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/** Every bundle in `dir`, newest first. */
|
|
120
|
+
function listLocalBundles(dir = exports.BUNDLES_DIR) {
|
|
121
|
+
const abs = path.resolve(dir);
|
|
122
|
+
if (!fs.existsSync(abs))
|
|
123
|
+
return [];
|
|
124
|
+
return fs
|
|
125
|
+
.readdirSync(abs)
|
|
126
|
+
.filter((f) => f.endsWith('.bundle'))
|
|
127
|
+
.map((name) => {
|
|
128
|
+
const bundlePath = path.join(abs, name);
|
|
129
|
+
const st = fs.statSync(bundlePath);
|
|
130
|
+
return {
|
|
131
|
+
bundlePath,
|
|
132
|
+
metaPath: metaPathFor(bundlePath),
|
|
133
|
+
sigPath: sigPathFor(bundlePath),
|
|
134
|
+
name,
|
|
135
|
+
meta: readJson(metaPathFor(bundlePath)),
|
|
136
|
+
sig: readJson(sigPathFor(bundlePath)),
|
|
137
|
+
size: st.size,
|
|
138
|
+
mtimeMs: st.mtimeMs,
|
|
139
|
+
};
|
|
140
|
+
})
|
|
141
|
+
.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* A signature is a short-lived ticket, not a permanent property of the file.
|
|
145
|
+
* Signing reserves an upload slot on the server, and that slot expires — so a
|
|
146
|
+
* bundle signed an hour ago is dead even though its .sbsig looks perfectly fine
|
|
147
|
+
* sitting on disk. Callers must be able to say so before someone uploads it.
|
|
148
|
+
*/
|
|
149
|
+
function sigState(b, now = new Date()) {
|
|
150
|
+
if (!b.sig)
|
|
151
|
+
return 'unsigned';
|
|
152
|
+
const expires = Date.parse(b.sig.uploadExpiresAt);
|
|
153
|
+
if (!Number.isFinite(expires))
|
|
154
|
+
return 'signed';
|
|
155
|
+
return expires > now.getTime() ? 'signed' : 'expired';
|
|
156
|
+
}
|
|
157
|
+
function humanSize(bytes) {
|
|
158
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
159
|
+
}
|
|
160
|
+
/** "3m", "17h", "2d" — coarse on purpose; exact times are noise in a picker. */
|
|
161
|
+
function ago(iso, now = new Date()) {
|
|
162
|
+
const t = typeof iso === 'number' ? iso : Date.parse(iso);
|
|
163
|
+
if (!Number.isFinite(t))
|
|
164
|
+
return '?';
|
|
165
|
+
const s = Math.max(0, Math.round((now.getTime() - t) / 1000));
|
|
166
|
+
if (s < 60)
|
|
167
|
+
return `${s}s`;
|
|
168
|
+
if (s < 3600)
|
|
169
|
+
return `${Math.round(s / 60)}m`;
|
|
170
|
+
if (s < 86400)
|
|
171
|
+
return `${Math.round(s / 3600)}h`;
|
|
172
|
+
return `${Math.round(s / 86400)}d`;
|
|
173
|
+
}
|
|
174
|
+
/** Minutes until the reserved upload slot closes; 0 once it has. */
|
|
175
|
+
function validForMinutes(b, now = new Date()) {
|
|
176
|
+
if (!b.sig)
|
|
177
|
+
return 0;
|
|
178
|
+
const expires = Date.parse(b.sig.uploadExpiresAt);
|
|
179
|
+
if (!Number.isFinite(expires))
|
|
180
|
+
return 0;
|
|
181
|
+
return Math.max(0, Math.round((expires - now.getTime()) / 60000));
|
|
182
|
+
}
|
|
183
|
+
/** One picker row: `15:42 a3f9c2 scalebun-ota (dirty) 19.0 MB signed 3m ago - valid 12m` */
|
|
184
|
+
function describeBundle(b, now = new Date()) {
|
|
185
|
+
const when = b.meta?.createdAt ? new Date(b.meta.createdAt) : new Date(b.mtimeMs);
|
|
186
|
+
const hhmm = `${String(when.getHours()).padStart(2, '0')}:${String(when.getMinutes()).padStart(2, '0')}`;
|
|
187
|
+
const sha = b.meta?.gitSha ? b.meta.gitSha.slice(0, 6) : '—'.repeat(6);
|
|
188
|
+
const branch = b.meta?.gitBranch ?? 'unknown';
|
|
189
|
+
const dirty = b.meta?.gitDirty ? ' (dirty)' : '';
|
|
190
|
+
const state = sigState(b, now);
|
|
191
|
+
const status = state === 'unsigned'
|
|
192
|
+
? 'unsigned'
|
|
193
|
+
: state === 'expired'
|
|
194
|
+
? `signed ${ago(b.sig.signedAt, now)} ago · EXPIRED`
|
|
195
|
+
: `signed ${ago(b.sig.signedAt, now)} ago · valid ${validForMinutes(b, now)}m`;
|
|
196
|
+
return `${hhmm} ${sha} ${branch}${dirty} ${humanSize(b.size)} ${status}`;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Delete signature tickets that can no longer be used.
|
|
200
|
+
*
|
|
201
|
+
* An expired ticket is not merely stale, it is impossible: the upload slot it
|
|
202
|
+
* reserved is gone, so no upload can ever succeed with it. Leaving it on disk
|
|
203
|
+
* costs nothing in space and a great deal in confusion — it still appears in a
|
|
204
|
+
* file picker, still looks like a signature, and pairing it with the wrong
|
|
205
|
+
* bundle produces a failure only the server can explain, after transferring the
|
|
206
|
+
* whole artifact. Removing it makes the folder tell the truth: every .sbsig
|
|
207
|
+
* present is one you can actually upload.
|
|
208
|
+
*
|
|
209
|
+
* Valid tickets for other bundles are left alone. Having two live signatures is
|
|
210
|
+
* legitimate; having a dead one is not.
|
|
211
|
+
*/
|
|
212
|
+
function pruneExpiredSignatures(dir = exports.BUNDLES_DIR, now = new Date()) {
|
|
213
|
+
const removed = [];
|
|
214
|
+
for (const b of listLocalBundles(dir)) {
|
|
215
|
+
if (sigState(b, now) !== 'expired')
|
|
216
|
+
continue;
|
|
217
|
+
try {
|
|
218
|
+
fs.unlinkSync(b.sigPath);
|
|
219
|
+
removed.push(path.basename(b.sigPath));
|
|
220
|
+
}
|
|
221
|
+
catch {
|
|
222
|
+
/* a locked file is not worth failing the signing run over */
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return removed;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Drop the oldest bundles past `keep`, with their sidecars.
|
|
229
|
+
*
|
|
230
|
+
* Deliberately generous. Reclaiming a few hundred MB is worth far less than the
|
|
231
|
+
* one time someone reaches for a build and finds the CLI threw it away.
|
|
232
|
+
*/
|
|
233
|
+
function pruneBundles(dir = exports.BUNDLES_DIR, keep = exports.KEEP_BUNDLES) {
|
|
234
|
+
const all = listLocalBundles(dir);
|
|
235
|
+
const removed = [];
|
|
236
|
+
for (const b of all.slice(keep)) {
|
|
237
|
+
for (const p of [b.bundlePath, b.metaPath, b.sigPath]) {
|
|
238
|
+
try {
|
|
239
|
+
if (fs.existsSync(p))
|
|
240
|
+
fs.unlinkSync(p);
|
|
241
|
+
}
|
|
242
|
+
catch {
|
|
243
|
+
/* a locked file is not worth failing a build over */
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
removed.push(b.name);
|
|
247
|
+
}
|
|
248
|
+
return removed;
|
|
249
|
+
}
|
|
250
|
+
//# sourceMappingURL=bundleStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundleStore.js","sourceRoot":"","sources":["../../src/utils/bundleStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project identity and onboarding stage — the one module the resolver, the
|
|
3
|
+
* splash and the shell all read.
|
|
4
|
+
*
|
|
5
|
+
* ── The problem this solves ─────────────────────────────────────────────────
|
|
6
|
+
*
|
|
7
|
+
* The CLI had no noun for "the project you are working on". Nine commands
|
|
8
|
+
* hard-required `--app-id <uuid>`, there was no config file, no
|
|
9
|
+
* `SCALEBUN_APP_ID`, and one credentials file with no notion of which app it
|
|
10
|
+
* belonged to. Every command therefore started by pasting a 25-character id
|
|
11
|
+
* copied out of a browser.
|
|
12
|
+
*
|
|
13
|
+
* ── Derive, never store ─────────────────────────────────────────────────────
|
|
14
|
+
*
|
|
15
|
+
* The onboarding stage below is DERIVED from facts on disk, not recorded as
|
|
16
|
+
* progress flags. A stored "user finished quickstart" bit lies the moment
|
|
17
|
+
* reality moves: a new machine loses it, a deleted key contradicts it, and an
|
|
18
|
+
* experienced developer opening a brand-new repo gets told they are an expert
|
|
19
|
+
* exactly when they need the wiring steps. Deriving costs a few `existsSync`
|
|
20
|
+
* calls, is always true, and is naturally per-project — which is the right
|
|
21
|
+
* granularity, because expertise does not transfer between checkouts.
|
|
22
|
+
*
|
|
23
|
+
* Everything here is SYNCHRONOUS and LOCAL. The splash renders on every bare
|
|
24
|
+
* invocation, so a network call in this path would tax every single run.
|
|
25
|
+
*/
|
|
26
|
+
/** Written by `scalebun link`. Lives at the project root, beside package.json. */
|
|
27
|
+
export declare const PROJECT_FILE = "scalebun.json";
|
|
28
|
+
export interface ProjectConfig {
|
|
29
|
+
/** The app every command in this directory defaults to. */
|
|
30
|
+
appId?: string;
|
|
31
|
+
/** Human label, cached so the prompt can say "WZB Pay" not a cuid. */
|
|
32
|
+
appName?: string;
|
|
33
|
+
/** Channel default for publish/promote. */
|
|
34
|
+
channel?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Last known release count for this app. A CACHE, not a progress flag: it is
|
|
37
|
+
* refreshed by any command that happens to fetch releases and self-corrects
|
|
38
|
+
* on the next one. Absent simply means "not seen yet".
|
|
39
|
+
*/
|
|
40
|
+
releaseCount?: number;
|
|
41
|
+
}
|
|
42
|
+
export type Stage = 0 | 1 | 2 | 3 | 4;
|
|
43
|
+
export interface Context {
|
|
44
|
+
/** 0 fresh · 1 signed in · 2 bound · 3 wired · 4 operating */
|
|
45
|
+
stage: Stage;
|
|
46
|
+
loggedIn: boolean;
|
|
47
|
+
email?: string;
|
|
48
|
+
/** Resolved app id, from flag > env > scalebun.json. Not from the network. */
|
|
49
|
+
appId?: string;
|
|
50
|
+
appName?: string;
|
|
51
|
+
channel?: string;
|
|
52
|
+
/** Directory holding scalebun.json, or null when this is not a linked project. */
|
|
53
|
+
projectRoot: string | null;
|
|
54
|
+
/** True when an android/ or ios/ directory exists here. */
|
|
55
|
+
isNativeProject: boolean;
|
|
56
|
+
platforms: Array<'android' | 'ios'>;
|
|
57
|
+
/** Per-platform OTA wiring, from the same greps `doctor` performs. */
|
|
58
|
+
wired: {
|
|
59
|
+
android: boolean | null;
|
|
60
|
+
ios: boolean | null;
|
|
61
|
+
};
|
|
62
|
+
/** True when a signing key exists locally. */
|
|
63
|
+
hasSigningKey: boolean;
|
|
64
|
+
releaseCount: number | null;
|
|
65
|
+
}
|
|
66
|
+
/** Walk up from `cwd` looking for scalebun.json. Stops at the filesystem root. */
|
|
67
|
+
export declare function findProjectRoot(cwd?: string): string | null;
|
|
68
|
+
/** Read scalebun.json from `root`, or null when absent/corrupt. */
|
|
69
|
+
export declare function readProjectConfig(root: string | null): ProjectConfig | null;
|
|
70
|
+
/** Write scalebun.json, merging over whatever is already there. */
|
|
71
|
+
export declare function writeProjectConfig(root: string, patch: ProjectConfig): ProjectConfig;
|
|
72
|
+
/**
|
|
73
|
+
* Record the release count seen by a command that already fetched releases.
|
|
74
|
+
* Best-effort: a read-only checkout must not fail a command over a cache write.
|
|
75
|
+
*/
|
|
76
|
+
export declare function cacheReleaseCount(count: number, cwd?: string): void;
|
|
77
|
+
/**
|
|
78
|
+
* Build the context for the current directory.
|
|
79
|
+
*
|
|
80
|
+
* @param opts.appId an explicit `--app-id` flag, which always wins.
|
|
81
|
+
*/
|
|
82
|
+
export declare function getContext(opts?: {
|
|
83
|
+
appId?: string;
|
|
84
|
+
cwd?: string;
|
|
85
|
+
}): Context;
|
|
86
|
+
/** One-line label for the shell prompt and the splash: "WZB Pay/production". */
|
|
87
|
+
export declare function contextLabel(ctx: Context): string | null;
|
|
88
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/utils/context.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,kFAAkF;AAClF,eAAO,MAAM,YAAY,kBAAkB,CAAC;AAE5C,MAAM,WAAW,aAAa;IAC5B,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAEtC,MAAM,WAAW,OAAO;IACtB,8DAA8D;IAC9D,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kFAAkF;IAClF,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,2DAA2D;IAC3D,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,CAAC;IACpC,sEAAsE;IACtE,KAAK,EAAE;QAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;QAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAAA;KAAE,CAAC;IACxD,8CAA8C;IAC9C,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,kFAAkF;AAClF,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,GAAG,IAAI,CAU1E;AAED,mEAAmE;AACnE,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,aAAa,GAAG,IAAI,CAY3E;AAED,mEAAmE;AACnE,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,aAAa,CAQpF;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,GAAE,MAAsB,GAAG,IAAI,CAQlF;AA6DD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CA2C/E;AAED,gFAAgF;AAChF,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAIxD"}
|
|
@@ -0,0 +1,247 @@
|
|
|
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.PROJECT_FILE = void 0;
|
|
37
|
+
exports.findProjectRoot = findProjectRoot;
|
|
38
|
+
exports.readProjectConfig = readProjectConfig;
|
|
39
|
+
exports.writeProjectConfig = writeProjectConfig;
|
|
40
|
+
exports.cacheReleaseCount = cacheReleaseCount;
|
|
41
|
+
exports.getContext = getContext;
|
|
42
|
+
exports.contextLabel = contextLabel;
|
|
43
|
+
const fs = __importStar(require("fs"));
|
|
44
|
+
const path = __importStar(require("path"));
|
|
45
|
+
const credentials_1 = require("./credentials");
|
|
46
|
+
/**
|
|
47
|
+
* Project identity and onboarding stage — the one module the resolver, the
|
|
48
|
+
* splash and the shell all read.
|
|
49
|
+
*
|
|
50
|
+
* ── The problem this solves ─────────────────────────────────────────────────
|
|
51
|
+
*
|
|
52
|
+
* The CLI had no noun for "the project you are working on". Nine commands
|
|
53
|
+
* hard-required `--app-id <uuid>`, there was no config file, no
|
|
54
|
+
* `SCALEBUN_APP_ID`, and one credentials file with no notion of which app it
|
|
55
|
+
* belonged to. Every command therefore started by pasting a 25-character id
|
|
56
|
+
* copied out of a browser.
|
|
57
|
+
*
|
|
58
|
+
* ── Derive, never store ─────────────────────────────────────────────────────
|
|
59
|
+
*
|
|
60
|
+
* The onboarding stage below is DERIVED from facts on disk, not recorded as
|
|
61
|
+
* progress flags. A stored "user finished quickstart" bit lies the moment
|
|
62
|
+
* reality moves: a new machine loses it, a deleted key contradicts it, and an
|
|
63
|
+
* experienced developer opening a brand-new repo gets told they are an expert
|
|
64
|
+
* exactly when they need the wiring steps. Deriving costs a few `existsSync`
|
|
65
|
+
* calls, is always true, and is naturally per-project — which is the right
|
|
66
|
+
* granularity, because expertise does not transfer between checkouts.
|
|
67
|
+
*
|
|
68
|
+
* Everything here is SYNCHRONOUS and LOCAL. The splash renders on every bare
|
|
69
|
+
* invocation, so a network call in this path would tax every single run.
|
|
70
|
+
*/
|
|
71
|
+
/** Written by `scalebun link`. Lives at the project root, beside package.json. */
|
|
72
|
+
exports.PROJECT_FILE = 'scalebun.json';
|
|
73
|
+
/** Walk up from `cwd` looking for scalebun.json. Stops at the filesystem root. */
|
|
74
|
+
function findProjectRoot(cwd = process.cwd()) {
|
|
75
|
+
let dir = path.resolve(cwd);
|
|
76
|
+
// Bounded by the root check below; a symlink loop cannot spin here because
|
|
77
|
+
// path.dirname always shortens or returns the same string at the root.
|
|
78
|
+
for (;;) {
|
|
79
|
+
if (fs.existsSync(path.join(dir, exports.PROJECT_FILE)))
|
|
80
|
+
return dir;
|
|
81
|
+
const parent = path.dirname(dir);
|
|
82
|
+
if (parent === dir)
|
|
83
|
+
return null;
|
|
84
|
+
dir = parent;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/** Read scalebun.json from `root`, or null when absent/corrupt. */
|
|
88
|
+
function readProjectConfig(root) {
|
|
89
|
+
if (!root)
|
|
90
|
+
return null;
|
|
91
|
+
try {
|
|
92
|
+
const raw = fs.readFileSync(path.join(root, exports.PROJECT_FILE), 'utf8');
|
|
93
|
+
const parsed = JSON.parse(raw);
|
|
94
|
+
// A hand-edited file that is valid JSON but not an object must not crash
|
|
95
|
+
// every command in the directory.
|
|
96
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))
|
|
97
|
+
return null;
|
|
98
|
+
return parsed;
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/** Write scalebun.json, merging over whatever is already there. */
|
|
105
|
+
function writeProjectConfig(root, patch) {
|
|
106
|
+
const existing = readProjectConfig(root) ?? {};
|
|
107
|
+
const merged = { ...existing, ...patch };
|
|
108
|
+
fs.writeFileSync(path.join(root, exports.PROJECT_FILE), JSON.stringify(merged, null, 2) + '\n');
|
|
109
|
+
return merged;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Record the release count seen by a command that already fetched releases.
|
|
113
|
+
* Best-effort: a read-only checkout must not fail a command over a cache write.
|
|
114
|
+
*/
|
|
115
|
+
function cacheReleaseCount(count, cwd = process.cwd()) {
|
|
116
|
+
const root = findProjectRoot(cwd);
|
|
117
|
+
if (!root)
|
|
118
|
+
return;
|
|
119
|
+
try {
|
|
120
|
+
writeProjectConfig(root, { releaseCount: count });
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
/* cache only */
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/** Does this native source file already resolve the OTA slot? */
|
|
127
|
+
function greppedWired(file, needle) {
|
|
128
|
+
try {
|
|
129
|
+
return fs.readFileSync(file, 'utf8').includes(needle);
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Android wiring: MainApplication must call ScaleBunOtaModule.getJSBundleFile.
|
|
137
|
+
* Returns null when there is no android/ directory to judge.
|
|
138
|
+
*/
|
|
139
|
+
function androidWired(cwd) {
|
|
140
|
+
const dir = path.join(cwd, 'android');
|
|
141
|
+
if (!fs.existsSync(dir))
|
|
142
|
+
return null;
|
|
143
|
+
const candidates = [
|
|
144
|
+
'app/src/main/java',
|
|
145
|
+
'app/src/main/kotlin',
|
|
146
|
+
].map((p) => path.join(dir, p));
|
|
147
|
+
for (const base of candidates) {
|
|
148
|
+
if (!fs.existsSync(base))
|
|
149
|
+
continue;
|
|
150
|
+
const found = findFile(base, /MainApplication\.(kt|java)$/);
|
|
151
|
+
if (found)
|
|
152
|
+
return greppedWired(found, 'ScaleBunOtaModule.getJSBundleFile');
|
|
153
|
+
}
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
/** iOS wiring: AppDelegate must resolve the slot via getBundleURL. */
|
|
157
|
+
function iosWired(cwd) {
|
|
158
|
+
const dir = path.join(cwd, 'ios');
|
|
159
|
+
if (!fs.existsSync(dir))
|
|
160
|
+
return null;
|
|
161
|
+
const found = findFile(dir, /AppDelegate\.(swift|mm|m)$/, 3);
|
|
162
|
+
return found ? greppedWired(found, 'ScaleBunOtaModule.getBundleURL') : false;
|
|
163
|
+
}
|
|
164
|
+
/** Shallow recursive find, depth-bounded so a huge ios/Pods tree cannot stall the splash. */
|
|
165
|
+
function findFile(dir, re, depth = 6) {
|
|
166
|
+
if (depth < 0)
|
|
167
|
+
return null;
|
|
168
|
+
let entries;
|
|
169
|
+
try {
|
|
170
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
for (const e of entries) {
|
|
176
|
+
const full = path.join(dir, e.name);
|
|
177
|
+
if (e.isFile() && re.test(e.name))
|
|
178
|
+
return full;
|
|
179
|
+
}
|
|
180
|
+
for (const e of entries) {
|
|
181
|
+
// Pods and build output contain thousands of files and never the app's own
|
|
182
|
+
// AppDelegate — skipping them is what keeps this under a few milliseconds.
|
|
183
|
+
if (!e.isDirectory() || e.name === 'Pods' || e.name === 'build' || e.name === 'node_modules')
|
|
184
|
+
continue;
|
|
185
|
+
const hit = findFile(path.join(dir, e.name), re, depth - 1);
|
|
186
|
+
if (hit)
|
|
187
|
+
return hit;
|
|
188
|
+
}
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Build the context for the current directory.
|
|
193
|
+
*
|
|
194
|
+
* @param opts.appId an explicit `--app-id` flag, which always wins.
|
|
195
|
+
*/
|
|
196
|
+
function getContext(opts = {}) {
|
|
197
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
198
|
+
const creds = (0, credentials_1.readCredentials)();
|
|
199
|
+
const projectRoot = findProjectRoot(cwd);
|
|
200
|
+
const project = readProjectConfig(projectRoot);
|
|
201
|
+
// Resolution order — explicit beats ambient beats stored.
|
|
202
|
+
const appId = opts.appId || process.env.SCALEBUN_APP_ID || project?.appId;
|
|
203
|
+
const platforms = [];
|
|
204
|
+
if (fs.existsSync(path.join(cwd, 'android')))
|
|
205
|
+
platforms.push('android');
|
|
206
|
+
if (fs.existsSync(path.join(cwd, 'ios')))
|
|
207
|
+
platforms.push('ios');
|
|
208
|
+
const wired = { android: androidWired(cwd), ios: iosWired(cwd) };
|
|
209
|
+
const hasSigningKey = fs.existsSync(path.join(cwd, '.scalebun', 'ota-signing-key.pem'));
|
|
210
|
+
const releaseCount = typeof project?.releaseCount === 'number' ? project.releaseCount : null;
|
|
211
|
+
// A project counts as wired when every platform it actually has is wired.
|
|
212
|
+
// An app with only android/ is fully wired once android is — demanding an
|
|
213
|
+
// ios/ directory it does not have would strand it at stage 2 forever.
|
|
214
|
+
const relevant = platforms.map((p) => wired[p]).filter((v) => v !== null);
|
|
215
|
+
const fullyWired = relevant.length > 0 && relevant.every(Boolean);
|
|
216
|
+
let stage = 0;
|
|
217
|
+
if (creds)
|
|
218
|
+
stage = 1;
|
|
219
|
+
if (creds && appId)
|
|
220
|
+
stage = 2;
|
|
221
|
+
if (creds && appId && fullyWired)
|
|
222
|
+
stage = 3;
|
|
223
|
+
if (creds && appId && fullyWired && (releaseCount ?? 0) > 0)
|
|
224
|
+
stage = 4;
|
|
225
|
+
return {
|
|
226
|
+
stage,
|
|
227
|
+
loggedIn: !!creds,
|
|
228
|
+
email: creds?.email,
|
|
229
|
+
appId,
|
|
230
|
+
appName: project?.appName,
|
|
231
|
+
channel: project?.channel,
|
|
232
|
+
projectRoot,
|
|
233
|
+
isNativeProject: platforms.length > 0,
|
|
234
|
+
platforms,
|
|
235
|
+
wired,
|
|
236
|
+
hasSigningKey,
|
|
237
|
+
releaseCount,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
/** One-line label for the shell prompt and the splash: "WZB Pay/production". */
|
|
241
|
+
function contextLabel(ctx) {
|
|
242
|
+
if (!ctx.appId)
|
|
243
|
+
return null;
|
|
244
|
+
const name = ctx.appName ?? ctx.appId;
|
|
245
|
+
return ctx.channel ? `${name}/${ctx.channel}` : name;
|
|
246
|
+
}
|
|
247
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/utils/context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The hosted ScaleBun backend. Used whenever no API URL is supplied — so login
|
|
3
|
+
* and CI need only a token. Override with --api-url or SCALEBUN_API_URL (e.g.
|
|
4
|
+
* self-hosted, staging, or http://localhost:3000/api/v1 for local dev). The
|
|
5
|
+
* /api/v1 suffix is required — without it every ingestion route 404s.
|
|
6
|
+
*/
|
|
7
|
+
export declare const DEFAULT_API_URL = "https://api.scalebun.com/api/v1";
|
|
8
|
+
export interface Credentials {
|
|
9
|
+
apiUrl: string;
|
|
10
|
+
token: string;
|
|
11
|
+
/** Account email, captured at login for the status box. Optional: pre-1.10.1
|
|
12
|
+
* logins and the CI env-var path don't have it. */
|
|
13
|
+
email?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Read credentials. Priority:
|
|
17
|
+
* 1. SCALEBUN_TOKEN / SCALEBUN_API_TOKEN (+ optional SCALEBUN_API_URL) env vars (for CI)
|
|
18
|
+
* 2. ~/.scalebun/credentials.json (from `scalebun login`)
|
|
19
|
+
*
|
|
20
|
+
* `SCALEBUN_API_TOKEN` is the name the dashboard's CI/CD setup page issues and
|
|
21
|
+
* documents; `SCALEBUN_TOKEN` is the original CLI name. Both are accepted —
|
|
22
|
+
* `SCALEBUN_TOKEN` wins when both are set, so nothing that worked before breaks.
|
|
23
|
+
*
|
|
24
|
+
* The API URL is optional in both paths and defaults to DEFAULT_API_URL, so a
|
|
25
|
+
* bare token is enough to authenticate against the hosted backend.
|
|
26
|
+
*/
|
|
27
|
+
export declare function readCredentials(): Credentials | null;
|
|
28
|
+
/**
|
|
29
|
+
* Store credentials to ~/.scalebun/credentials.json.
|
|
30
|
+
*
|
|
31
|
+
* The `mode: 0o600` below is real on macOS and Linux and a NO-OP ON WINDOWS —
|
|
32
|
+
* Node cannot express a Windows ACL through a Unix mode, so it silently drops
|
|
33
|
+
* it and the file lands with whatever the parent directory grants. That is how
|
|
34
|
+
* a token ends up readable by every other account on a shared machine while
|
|
35
|
+
* the code looks like it locked the file down. So on Windows the ACL is set
|
|
36
|
+
* explicitly afterwards, and a failure to do so is reported rather than
|
|
37
|
+
* swallowed: the user is entitled to know their token is sitting in a
|
|
38
|
+
* world-readable file.
|
|
39
|
+
*/
|
|
40
|
+
export declare function writeCredentials(creds: Credentials): void;
|
|
41
|
+
/**
|
|
42
|
+
* Windows-only ACL tightening: drop inherited ACEs and grant the current user
|
|
43
|
+
* alone full control. On POSIX the file mode already did this and this is a
|
|
44
|
+
* no-op.
|
|
45
|
+
*
|
|
46
|
+
* Exported because the credentials file is not the only secret this CLI writes:
|
|
47
|
+
* `ota generate-key-pair` puts an RSA PRIVATE SIGNING KEY on disk, and for
|
|
48
|
+
* a while that file got only the POSIX `mode: 0o600` — which Node silently
|
|
49
|
+
* drops on Windows — while the (less valuable) access token got this full
|
|
50
|
+
* treatment. Every secret the CLI writes must go through here.
|
|
51
|
+
*
|
|
52
|
+
* @param file absolute path of the just-written secret file
|
|
53
|
+
* @param whatItHolds short description used in the failure warning, e.g.
|
|
54
|
+
* "an access token" / "your OTA signing private key"
|
|
55
|
+
*/
|
|
56
|
+
export declare function restrictToCurrentUser(file: string, whatItHolds: string): void;
|
|
57
|
+
/** Delete stored credentials. */
|
|
58
|
+
export declare function clearCredentials(): void;
|
|
59
|
+
//# sourceMappingURL=credentials.d.ts.map
|