@scalebun/cli 2.0.5 → 2.0.7
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/doctor.d.ts.map +1 -1
- package/lib/commands/doctor.js +18 -0
- package/lib/commands/doctor.js.map +1 -1
- package/lib/commands/ota-bundle.d.ts.map +1 -1
- package/lib/commands/ota-bundle.js +43 -3
- package/lib/commands/ota-bundle.js.map +1 -1
- package/lib/commands/ota-delete-bundle.d.ts +7 -2
- package/lib/commands/ota-delete-bundle.d.ts.map +1 -1
- package/lib/commands/ota-delete-bundle.js +60 -55
- package/lib/commands/ota-delete-bundle.js.map +1 -1
- package/lib/commands/ota-keys.d.ts.map +1 -1
- package/lib/commands/ota-keys.js +56 -6
- package/lib/commands/ota-keys.js.map +1 -1
- 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 +231 -0
- package/lib/commands/ota-sign.js.map +1 -0
- package/lib/commands/quickstart.d.ts.map +1 -1
- package/lib/commands/quickstart.js +135 -11
- package/lib/commands/quickstart.js.map +1 -1
- package/lib/index.js +2 -0
- package/lib/index.js.map +1 -1
- 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/guide.d.ts.map +1 -1
- package/lib/utils/guide.js +1 -0
- package/lib/utils/guide.js.map +1 -1
- package/lib/utils/trustAnchor.d.ts +69 -11
- package/lib/utils/trustAnchor.d.ts.map +1 -1
- package/lib/utils/trustAnchor.js +90 -4
- package/lib/utils/trustAnchor.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The local bundles/ folder: naming, listing and sign status.
|
|
3
|
+
*
|
|
4
|
+
* `ota bundle` used to write a single fixed path — bundles/index.android.bundle —
|
|
5
|
+
* so every build silently destroyed the one before it. That is fine while a
|
|
6
|
+
* bundle is a throwaway, and wrong the moment you have three builds and need the
|
|
7
|
+
* SECOND one because the newest turned out to be broken. Bundles are a working
|
|
8
|
+
* set, so they get distinct names and keep their provenance.
|
|
9
|
+
*/
|
|
10
|
+
export declare const BUNDLES_DIR = "bundles";
|
|
11
|
+
/** Keep generously: 19MB each is cheap, deleting the build someone wanted is not. */
|
|
12
|
+
export declare const KEEP_BUNDLES = 10;
|
|
13
|
+
export interface BundleMeta {
|
|
14
|
+
platform: string;
|
|
15
|
+
createdAt: string;
|
|
16
|
+
sha256: string;
|
|
17
|
+
size: number;
|
|
18
|
+
gitSha?: string;
|
|
19
|
+
gitBranch?: string;
|
|
20
|
+
gitDirty?: boolean;
|
|
21
|
+
hermes?: boolean;
|
|
22
|
+
}
|
|
23
|
+
/** A signature ticket written beside a bundle by `ota sign`. */
|
|
24
|
+
export interface BundleSig {
|
|
25
|
+
protocol: string;
|
|
26
|
+
keyId: string;
|
|
27
|
+
signedPayload: string;
|
|
28
|
+
signature: string;
|
|
29
|
+
/** Server-reserved identity this signature is bound to. */
|
|
30
|
+
bundleId: string;
|
|
31
|
+
releaseId: string;
|
|
32
|
+
releaseSequence: number;
|
|
33
|
+
appId: string;
|
|
34
|
+
/**
|
|
35
|
+
* SHA-256 of the exact bytes this signature covers.
|
|
36
|
+
*
|
|
37
|
+
* Lets an uploader prove the pairing BEFORE transferring anything. Without it
|
|
38
|
+
* the only check is server-side at finalize, which means a full upload, a
|
|
39
|
+
* rejection, and an error that does not obviously mean "you picked the wrong
|
|
40
|
+
* file" — the failure mode when two builds sit side by side.
|
|
41
|
+
*/
|
|
42
|
+
artifactSha256: string;
|
|
43
|
+
signedAt: string;
|
|
44
|
+
/** When the reserved upload slot stops accepting the bytes. */
|
|
45
|
+
uploadExpiresAt: string;
|
|
46
|
+
/**
|
|
47
|
+
* The presigned PUT URL for the reserved slot, so whoever uploads does not
|
|
48
|
+
* need to reserve one of their own — a second reservation would carry a
|
|
49
|
+
* different bundleId, which this signature does not cover.
|
|
50
|
+
*
|
|
51
|
+
* Safe to hand over: it permits one PUT to one storage key for 15 minutes,
|
|
52
|
+
* and finalize re-hashes the bytes server-side and rejects any mismatch
|
|
53
|
+
* against the sha256 this signature binds. Swapping the payload therefore
|
|
54
|
+
* fails at finalize, and would fail again on the device.
|
|
55
|
+
*/
|
|
56
|
+
uploadUrl: string;
|
|
57
|
+
}
|
|
58
|
+
export interface LocalBundle {
|
|
59
|
+
bundlePath: string;
|
|
60
|
+
metaPath: string;
|
|
61
|
+
sigPath: string;
|
|
62
|
+
name: string;
|
|
63
|
+
meta: BundleMeta | null;
|
|
64
|
+
sig: BundleSig | null;
|
|
65
|
+
size: number;
|
|
66
|
+
mtimeMs: number;
|
|
67
|
+
}
|
|
68
|
+
/** `2026-09-10T15-42` — sortable, and legal on Windows (no colons). */
|
|
69
|
+
export declare function stamp(d?: Date): string;
|
|
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
|
+
export declare function bundleFileName(platform: string, gitSha?: string, at?: Date): string;
|
|
78
|
+
export declare function metaPathFor(bundlePath: string): string;
|
|
79
|
+
export declare function sigPathFor(bundlePath: string): string;
|
|
80
|
+
/**
|
|
81
|
+
* Load one bundle by path, wherever it lives.
|
|
82
|
+
*
|
|
83
|
+
* `ota bundle build --output <dir>` puts the artifact outside bundles/, and a
|
|
84
|
+
* signature belongs beside its bundle rather than in some blessed folder. So
|
|
85
|
+
* signing reads the sidecars next to the file it was handed, and refuses to
|
|
86
|
+
* hunt for them elsewhere.
|
|
87
|
+
*/
|
|
88
|
+
export declare function loadBundleAt(bundlePath: string): LocalBundle | null;
|
|
89
|
+
/** Every bundle in `dir`, newest first. */
|
|
90
|
+
export declare function listLocalBundles(dir?: string): LocalBundle[];
|
|
91
|
+
export type SigState = 'unsigned' | 'signed' | 'expired';
|
|
92
|
+
/**
|
|
93
|
+
* A signature is a short-lived ticket, not a permanent property of the file.
|
|
94
|
+
* Signing reserves an upload slot on the server, and that slot expires — so a
|
|
95
|
+
* bundle signed an hour ago is dead even though its .sbsig looks perfectly fine
|
|
96
|
+
* sitting on disk. Callers must be able to say so before someone uploads it.
|
|
97
|
+
*/
|
|
98
|
+
export declare function sigState(b: LocalBundle, now?: Date): SigState;
|
|
99
|
+
export declare function humanSize(bytes: number): string;
|
|
100
|
+
/** "3m", "17h", "2d" — coarse on purpose; exact times are noise in a picker. */
|
|
101
|
+
export declare function ago(iso: string | number, now?: Date): string;
|
|
102
|
+
/** Minutes until the reserved upload slot closes; 0 once it has. */
|
|
103
|
+
export declare function validForMinutes(b: LocalBundle, now?: Date): number;
|
|
104
|
+
/** One picker row: `15:42 a3f9c2 scalebun-ota (dirty) 19.0 MB signed 3m ago - valid 12m` */
|
|
105
|
+
export declare function describeBundle(b: LocalBundle, now?: Date): string;
|
|
106
|
+
/**
|
|
107
|
+
* Delete signature tickets that can no longer be used.
|
|
108
|
+
*
|
|
109
|
+
* An expired ticket is not merely stale, it is impossible: the upload slot it
|
|
110
|
+
* reserved is gone, so no upload can ever succeed with it. Leaving it on disk
|
|
111
|
+
* costs nothing in space and a great deal in confusion — it still appears in a
|
|
112
|
+
* file picker, still looks like a signature, and pairing it with the wrong
|
|
113
|
+
* bundle produces a failure only the server can explain, after transferring the
|
|
114
|
+
* whole artifact. Removing it makes the folder tell the truth: every .sbsig
|
|
115
|
+
* present is one you can actually upload.
|
|
116
|
+
*
|
|
117
|
+
* Valid tickets for other bundles are left alone. Having two live signatures is
|
|
118
|
+
* legitimate; having a dead one is not.
|
|
119
|
+
*/
|
|
120
|
+
export declare function pruneExpiredSignatures(dir?: string, now?: Date): string[];
|
|
121
|
+
/**
|
|
122
|
+
* Drop the oldest bundles past `keep`, with their sidecars.
|
|
123
|
+
*
|
|
124
|
+
* Deliberately generous. Reclaiming a few hundred MB is worth far less than the
|
|
125
|
+
* one time someone reaches for a build and finds the CLI threw it away.
|
|
126
|
+
*/
|
|
127
|
+
export declare function pruneBundles(dir?: string, keep?: number): string[];
|
|
128
|
+
//# sourceMappingURL=bundleStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundleStore.d.ts","sourceRoot":"","sources":["../../src/utils/bundleStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -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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"}
|
package/lib/utils/guide.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guide.d.ts","sourceRoot":"","sources":["../../src/utils/guide.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAgB,MAAM,WAAW,CAAC;AAElD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,MAAM,WAAW,YAAY;IAC3B,iEAAiE;IACjE,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B;AAED,eAAO,MAAM,MAAM,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"guide.d.ts","sourceRoot":"","sources":["../../src/utils/guide.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAgB,MAAM,WAAW,CAAC;AAElD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,MAAM,WAAW,YAAY;IAC3B,iEAAiE;IACjE,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B;AAED,eAAO,MAAM,MAAM,EAAE,YAAY,EAyDhC,CAAC;AAEF,2DAA2D;AAC3D,wBAAgB,YAAY,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAExD;AAKD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAkBxD;AAED,iDAAiD;AACjD,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CA4CjD;AAED,+EAA+E;AAC/E,wBAAgB,iBAAiB,IAAI,IAAI,CASxC;AAED,gDAAgD;AAChD,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAiB9C;AAED,0DAA0D;AAC1D,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAO3D;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAGpD"}
|
package/lib/utils/guide.js
CHANGED
|
@@ -22,6 +22,7 @@ exports.GROUPS = [
|
|
|
22
22
|
{ argv: ['ota', 'promote'], desc: 'promote an uploaded bundle to a channel' },
|
|
23
23
|
{ argv: ['ota', 'bundles'], desc: 'list uploaded bundles, newest first' },
|
|
24
24
|
{ argv: ['ota', 'bundle', 'build'], desc: 'build a bundle file for manual upload' },
|
|
25
|
+
{ argv: ['ota', 'sign'], desc: 'sign a built bundle so it can be uploaded from the dashboard' },
|
|
25
26
|
],
|
|
26
27
|
},
|
|
27
28
|
{
|
package/lib/utils/guide.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guide.js","sourceRoot":"","sources":["../../src/utils/guide.ts"],"names":[],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"guide.js","sourceRoot":"","sources":["../../src/utils/guide.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,10 +2,27 @@
|
|
|
2
2
|
* The native trust anchor: the public half of your signing key, compiled into
|
|
3
3
|
* the app so the device can refuse anything it did not authorise.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* Each platform reads a different file from a different place, and both fail
|
|
6
|
+
* the same way when it is missing — an empty registry, which means every
|
|
7
|
+
* release is refused with UNKNOWN_KEY_ID.
|
|
8
|
+
*
|
|
9
|
+
* Android android/app/src/main/assets/scalebun_ota_keys.json
|
|
10
|
+
* In `assets/`, NOT `res/raw/`. The registry reads it with
|
|
11
|
+
* `context.assets.open()`; a file in res/raw is invisible to that
|
|
12
|
+
* call, so enforcement is silently off — the app still runs, still
|
|
13
|
+
* updates, and simply verifies nothing.
|
|
14
|
+
*
|
|
15
|
+
* iOS ios/<App>/ScaleBunOtaKeys.json
|
|
16
|
+
* Read with `Bundle.main.url(forResource:withExtension:)`, so it
|
|
17
|
+
* must be a member of the app target's Copy Bundle Resources phase.
|
|
18
|
+
* Writing the file is not enough: Xcode ships only what the target
|
|
19
|
+
* references, and a file sitting beside the sources that nobody
|
|
20
|
+
* added is not in the .app at all. isInXcodeResources() below exists
|
|
21
|
+
* to catch exactly that.
|
|
22
|
+
*
|
|
23
|
+
* The filenames differ by platform, and the iOS one is `.json`. Earlier CLI
|
|
24
|
+
* output told people to add `ScaleBunOtaKeys.plist`, which no code has ever
|
|
25
|
+
* read — following it produced UNKNOWN_KEY_ID with nothing to point at.
|
|
9
26
|
*/
|
|
10
27
|
export interface TrustAnchor {
|
|
11
28
|
/**
|
|
@@ -21,6 +38,8 @@ export interface TrustAnchor {
|
|
|
21
38
|
}>;
|
|
22
39
|
}
|
|
23
40
|
export declare const ANDROID_ANCHOR_RELATIVE: string;
|
|
41
|
+
/** `ScaleBunOtaKeyRegistry.defaultResource` + ".json", on the iOS side. */
|
|
42
|
+
export declare const IOS_ANCHOR_FILENAME = "ScaleBunOtaKeys.json";
|
|
24
43
|
export interface WriteAnchorResult {
|
|
25
44
|
path: string;
|
|
26
45
|
/** Key ids trusted after the write, in file order. */
|
|
@@ -28,24 +47,63 @@ export interface WriteAnchorResult {
|
|
|
28
47
|
/** True when an existing anchor was read and its other keys preserved. */
|
|
29
48
|
merged: boolean;
|
|
30
49
|
}
|
|
50
|
+
export interface WriteIosAnchorResult extends WriteAnchorResult {
|
|
51
|
+
/**
|
|
52
|
+
* False when project.pbxproj does not mention the file yet.
|
|
53
|
+
*
|
|
54
|
+
* This is the iOS-specific trap, and the reason the flag exists: the anchor
|
|
55
|
+
* can be written perfectly and still not ship, because Xcode copies only what
|
|
56
|
+
* the target references. The device then finds no resource, builds an empty
|
|
57
|
+
* registry, and refuses every release with UNKNOWN_KEY_ID — while a
|
|
58
|
+
* correct-looking file sits right there in the source tree.
|
|
59
|
+
*/
|
|
60
|
+
inXcodeResources: boolean;
|
|
61
|
+
}
|
|
62
|
+
export declare function writeAndroidTrustAnchor(opts: {
|
|
63
|
+
cwd: string;
|
|
64
|
+
projectId: string;
|
|
65
|
+
keyId: string;
|
|
66
|
+
publicKeyPem: string;
|
|
67
|
+
}): WriteAnchorResult;
|
|
68
|
+
/** `ios/<App>.xcodeproj`, or null when there is no iOS project here. */
|
|
69
|
+
export declare function findXcodeProject(cwd: string): string | null;
|
|
31
70
|
/**
|
|
32
|
-
*
|
|
71
|
+
* The folder the app's own sources live in — `ios/<App>/`.
|
|
33
72
|
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
73
|
+
* Xcode groups mirror the filesystem here by React Native convention, so that
|
|
74
|
+
* is where a new resource belongs if it is going to be easy to add to the
|
|
75
|
+
* target. Falls back to whichever folder holds the AppDelegate, for projects
|
|
76
|
+
* renamed away from their directory.
|
|
38
77
|
*/
|
|
39
|
-
export declare function
|
|
78
|
+
export declare function iosAppSourceDir(cwd: string): string | null;
|
|
79
|
+
/**
|
|
80
|
+
* Is the anchor already referenced by the Xcode project?
|
|
81
|
+
*
|
|
82
|
+
* A substring check over project.pbxproj rather than a real parse: the question
|
|
83
|
+
* is only "has anyone added this filename", and erring toward "no" costs one
|
|
84
|
+
* extra printing of the instructions.
|
|
85
|
+
*/
|
|
86
|
+
export declare function isInXcodeResources(cwd: string): boolean;
|
|
87
|
+
/**
|
|
88
|
+
* Add a key to the iOS trust anchor, creating the file if needed.
|
|
89
|
+
*
|
|
90
|
+
* Writes into `ios/<App>/` and reports whether the project references it yet.
|
|
91
|
+
* Adding it to the target is left to the caller: that means editing
|
|
92
|
+
* project.pbxproj, and a corrupted pbxproj costs far more than the single drag
|
|
93
|
+
* it would save.
|
|
94
|
+
*/
|
|
95
|
+
export declare function writeIosTrustAnchor(opts: {
|
|
40
96
|
cwd: string;
|
|
41
97
|
projectId: string;
|
|
42
98
|
keyId: string;
|
|
43
99
|
publicKeyPem: string;
|
|
44
|
-
}):
|
|
100
|
+
}): WriteIosAnchorResult;
|
|
45
101
|
/**
|
|
46
102
|
* Does this look like a native Android project we can write into? Used to skip
|
|
47
103
|
* the anchor with a clear message instead of scattering directories into
|
|
48
104
|
* whatever folder the user happened to run from.
|
|
49
105
|
*/
|
|
50
106
|
export declare function hasAndroidProject(cwd: string): boolean;
|
|
107
|
+
/** The iOS counterpart: an `ios/` folder with an actual Xcode project in it. */
|
|
108
|
+
export declare function hasIosProject(cwd: string): boolean;
|
|
51
109
|
//# sourceMappingURL=trustAnchor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trustAnchor.d.ts","sourceRoot":"","sources":["../../src/utils/trustAnchor.ts"],"names":[],"mappings":"AAGA
|
|
1
|
+
{"version":3,"file":"trustAnchor.d.ts","sourceRoot":"","sources":["../../src/utils/trustAnchor.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,WAAW,WAAW;IAC1B;;;;;OAKG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACnD;AAED,eAAO,MAAM,uBAAuB,QAOnC,CAAC;AAEF,2EAA2E;AAC3E,eAAO,MAAM,mBAAmB,yBAAyB,CAAC;AAE1D,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,0EAA0E;IAC1E,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,oBAAqB,SAAQ,iBAAiB;IAC7D;;;;;;;;OAQG;IACH,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AA2CD,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,iBAAiB,CAEpB;AAED,wEAAwE;AACxE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAK3D;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgB1D;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAUvD;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACxC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,oBAAoB,CASvB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED,gFAAgF;AAChF,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAElD"}
|