@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,459 @@
|
|
|
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.readHermesBytecodeVersion = readHermesBytecodeVersion;
|
|
37
|
+
exports.hermescCandidates = hermescCandidates;
|
|
38
|
+
exports.resolveHermesc = resolveHermesc;
|
|
39
|
+
exports.detectProjectRnVersion = detectProjectRnVersion;
|
|
40
|
+
exports.isExpoProject = isExpoProject;
|
|
41
|
+
exports.resolveBundler = resolveBundler;
|
|
42
|
+
exports.buildBundle = buildBundle;
|
|
43
|
+
exports.listAssets = listAssets;
|
|
44
|
+
const childProcess = __importStar(require("child_process"));
|
|
45
|
+
const fs = __importStar(require("fs"));
|
|
46
|
+
const path = __importStar(require("path"));
|
|
47
|
+
const os = __importStar(require("os"));
|
|
48
|
+
/**
|
|
49
|
+
* Hermes bytecode file magic, little-endian on disk.
|
|
50
|
+
* Source: `const uint64_t MAGIC = 0x1F1903C103BC1FC6` in Hermes.
|
|
51
|
+
*/
|
|
52
|
+
const HBC_MAGIC = Buffer.from([0xc6, 0x1f, 0xbc, 0x03, 0xc1, 0x03, 0x19, 0x1f]);
|
|
53
|
+
/**
|
|
54
|
+
* Read the HBC format version straight out of the compiled file header.
|
|
55
|
+
*
|
|
56
|
+
* Parsed from the artifact rather than from `hermesc --version` output, because
|
|
57
|
+
* the header is what the device's VM actually compares against — and its format
|
|
58
|
+
* is stable, whereas the CLI's version banner is not.
|
|
59
|
+
*
|
|
60
|
+
* Returns null when the file is not Hermes bytecode.
|
|
61
|
+
*/
|
|
62
|
+
function readHermesBytecodeVersion(filePath) {
|
|
63
|
+
let fd;
|
|
64
|
+
try {
|
|
65
|
+
fd = fs.openSync(filePath, 'r');
|
|
66
|
+
const header = Buffer.alloc(12);
|
|
67
|
+
const read = fs.readSync(fd, header, 0, 12, 0);
|
|
68
|
+
if (read < 12)
|
|
69
|
+
return null;
|
|
70
|
+
if (!header.subarray(0, 8).equals(HBC_MAGIC))
|
|
71
|
+
return null;
|
|
72
|
+
return header.readUInt32LE(8);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
finally {
|
|
78
|
+
if (fd !== undefined) {
|
|
79
|
+
try {
|
|
80
|
+
fs.closeSync(fd);
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
/* ignore */
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Locate the `hermesc` binary that ships inside React Native.
|
|
90
|
+
*
|
|
91
|
+
* `hermesc` is NOT an npm package — `npx hermesc` fails with
|
|
92
|
+
* "No versions available for hermesc" on every project, which meant `--hermes`
|
|
93
|
+
* silently degraded to a plain JS bundle every single time it was used. React
|
|
94
|
+
* Native ships a prebuilt binary per host platform under `sdks/hermesc/`.
|
|
95
|
+
*
|
|
96
|
+
* Using the copy inside the project's own `react-native` is also the correct
|
|
97
|
+
* choice for a second reason: it is the compiler matched to the Hermes runtime
|
|
98
|
+
* in that app's binary. Compiling with any other hermesc is what produces
|
|
99
|
+
* "Wrong bytecode version. Expected 96 but got 98" on device.
|
|
100
|
+
*
|
|
101
|
+
* Where it lives moved. Up to ~0.86 it was the prebuilt under `sdks/hermesc/`;
|
|
102
|
+
* from 0.87 that is no longer populated and the binary comes from the
|
|
103
|
+
* hermes-engine pod instead. This looked in exactly one place, so on 0.87 a
|
|
104
|
+
* default `--hermes` publish failed with nothing to point at. The candidate
|
|
105
|
+
* list below mirrors React Native's own resolution order, override included.
|
|
106
|
+
*/
|
|
107
|
+
function hermescCandidates(cwd = process.cwd()) {
|
|
108
|
+
const dir = process.platform === 'win32'
|
|
109
|
+
? 'win64-bin'
|
|
110
|
+
: process.platform === 'darwin'
|
|
111
|
+
? 'osx-bin'
|
|
112
|
+
: 'linux64-bin';
|
|
113
|
+
const bin = process.platform === 'win32' ? 'hermesc.exe' : 'hermesc';
|
|
114
|
+
const out = [];
|
|
115
|
+
// 1. HERMES_CLI_PATH — React Native's own override, read by
|
|
116
|
+
// scripts/react-native-xcode.sh. Honouring the same variable means a
|
|
117
|
+
// project that already had to point RN at a custom hermesc does not have
|
|
118
|
+
// to tell us separately.
|
|
119
|
+
const override = process.env.HERMES_CLI_PATH?.trim();
|
|
120
|
+
if (override)
|
|
121
|
+
out.push(override);
|
|
122
|
+
// 2. The prebuilt binary inside the project's react-native. Present through
|
|
123
|
+
// ~0.86 and still the common case.
|
|
124
|
+
out.push(path.join(cwd, 'node_modules', 'react-native', 'sdks', 'hermesc', dir, bin));
|
|
125
|
+
// 3. The hermes-engine CocoaPod. From RN 0.87 the prebuilt above is no longer
|
|
126
|
+
// populated and this is where the binary actually lands, which is exactly
|
|
127
|
+
// what react-native-xcode.sh resolves to:
|
|
128
|
+
// HERMES_ENGINE_PATH="$PODS_ROOT/hermes-engine"
|
|
129
|
+
// HERMES_CLI_PATH="$HERMES_ENGINE_PATH/destroot/bin/hermesc"
|
|
130
|
+
// Without this, a default `--hermes` publish on 0.87 fails outright and the
|
|
131
|
+
// only escape is --allow-plain-js, which costs 20-30% cold start AND breaks
|
|
132
|
+
// delta patching (plain JS cannot diff against a bytecode base).
|
|
133
|
+
out.push(path.join(cwd, 'ios', 'Pods', 'hermes-engine', 'destroot', 'bin', 'hermesc'));
|
|
134
|
+
// 4. Built from source (RN_SRC / building hermes locally).
|
|
135
|
+
out.push(path.join(cwd, 'node_modules', 'react-native', 'sdks', 'hermes', 'build', 'bin', 'hermesc'));
|
|
136
|
+
out.push(path.join(cwd, 'ios', 'Pods', 'hermes-engine', 'build_host_hermesc', 'bin', 'hermesc'));
|
|
137
|
+
return out;
|
|
138
|
+
}
|
|
139
|
+
function resolveHermesc(cwd = process.cwd()) {
|
|
140
|
+
for (const candidate of hermescCandidates(cwd)) {
|
|
141
|
+
try {
|
|
142
|
+
if (fs.existsSync(candidate) && fs.statSync(candidate).isFile())
|
|
143
|
+
return candidate;
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
// An unreadable candidate is not a reason to abandon the search.
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
/** React Native version of the project being published, from its node_modules. */
|
|
152
|
+
function detectProjectRnVersion(cwd = process.cwd()) {
|
|
153
|
+
try {
|
|
154
|
+
const pkgPath = path.join(cwd, 'node_modules', 'react-native', 'package.json');
|
|
155
|
+
if (!fs.existsSync(pkgPath))
|
|
156
|
+
return null;
|
|
157
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
158
|
+
return typeof pkg.version === 'string' ? pkg.version : null;
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Shell out to `npx react-native bundle` to produce a JS bundle.
|
|
166
|
+
*
|
|
167
|
+
* When opts.hermes is true, also runs hermesc to compile to bytecode.
|
|
168
|
+
* The native runtime detects the format from magic bytes (\x1f\x\xbc —
|
|
169
|
+
* Hermes bytecode header), so the same .jsbundle extension works for both.
|
|
170
|
+
*/
|
|
171
|
+
/**
|
|
172
|
+
* True when this project is an Expo app.
|
|
173
|
+
*
|
|
174
|
+
* Expo projects do not ship `@react-native-community/cli`, so `npx react-native
|
|
175
|
+
* bundle` fails outright with a "react-native depends on
|
|
176
|
+
* @react-native-community/cli" error. Expo's equivalent is `expo export:embed`,
|
|
177
|
+
* which takes the same flags and produces the same artifact. Detecting this is
|
|
178
|
+
* not a nicety — without it `ota publish` cannot build a bundle in an Expo app
|
|
179
|
+
* at all, which is a large share of the React Native ecosystem.
|
|
180
|
+
*/
|
|
181
|
+
function isExpoProject(cwd = process.cwd()) {
|
|
182
|
+
try {
|
|
183
|
+
if (fs.existsSync(path.join(cwd, 'node_modules', 'expo', 'package.json'))) {
|
|
184
|
+
return true;
|
|
185
|
+
}
|
|
186
|
+
const pkgPath = path.join(cwd, 'package.json');
|
|
187
|
+
if (!fs.existsSync(pkgPath))
|
|
188
|
+
return false;
|
|
189
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
190
|
+
return Boolean(pkg.dependencies?.expo ?? pkg.devDependencies?.expo);
|
|
191
|
+
}
|
|
192
|
+
catch {
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* How long to let `react-native bundle` / `expo export:embed` run before giving
|
|
198
|
+
* up, in milliseconds.
|
|
199
|
+
*
|
|
200
|
+
* The old cap was a hardcoded 5 minutes, which aborted real builds: a large app's
|
|
201
|
+
* FIRST cold Metro bundle with `--dev false` (full minification, no cache) can
|
|
202
|
+
* run well past that, and the abort surfaced only as a bare `ETIMEDOUT`. The
|
|
203
|
+
* default is now 20 minutes; `SCALEBUN_BUNDLE_TIMEOUT_MS` overrides it for
|
|
204
|
+
* extreme projects or slow CI. A non-positive or unparseable value falls back to
|
|
205
|
+
* the default rather than disabling the guard (0 would mean "no timeout").
|
|
206
|
+
*/
|
|
207
|
+
function resolveBundleTimeoutMs() {
|
|
208
|
+
const raw = Number(process.env.SCALEBUN_BUNDLE_TIMEOUT_MS);
|
|
209
|
+
return Number.isFinite(raw) && raw > 0 ? Math.floor(raw) : 20 * 60000;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* How to invoke this project's bundler.
|
|
213
|
+
*
|
|
214
|
+
* `npx react-native bundle` was the only path, and it fails on a project that is
|
|
215
|
+
* entirely healthy: React Native 0.77+ no longer links a `react-native` bin into
|
|
216
|
+
* node_modules/.bin (the executable moved to @react-native-community/cli, which
|
|
217
|
+
* links `rnc-cli` instead). npx then finds nothing on PATH and the publish dies
|
|
218
|
+
* with "'react-native' is not recognized as an internal or external command" —
|
|
219
|
+
* a message that reads like a broken install rather than a moved binary, and one
|
|
220
|
+
* a user cannot act on.
|
|
221
|
+
*
|
|
222
|
+
* So prefer the entrypoint the project already has on disk. react-native's own
|
|
223
|
+
* package.json still declares `bin: { "react-native": "cli.js" }`, so cli.js is
|
|
224
|
+
* present even when nothing linked it; running it through `node` needs no bin
|
|
225
|
+
* link, no PATH lookup and no shell — which also sidesteps the .cmd/EINVAL
|
|
226
|
+
* spawn problem that forces shell:true everywhere else on Windows.
|
|
227
|
+
*/
|
|
228
|
+
function resolveBundler(cwd, expo) {
|
|
229
|
+
if (expo) {
|
|
230
|
+
// Expo ships its own bin and does not have @react-native-community/cli.
|
|
231
|
+
return { cmd: 'npx', pre: ['expo', 'export:embed'], shell: true, label: 'expo export:embed' };
|
|
232
|
+
}
|
|
233
|
+
const cliJs = path.join(cwd, 'node_modules', 'react-native', 'cli.js');
|
|
234
|
+
if (fs.existsSync(cliJs)) {
|
|
235
|
+
// process.execPath is the node running us — always a real executable.
|
|
236
|
+
return {
|
|
237
|
+
cmd: process.execPath,
|
|
238
|
+
pre: [cliJs, 'bundle'],
|
|
239
|
+
shell: false,
|
|
240
|
+
label: 'react-native bundle (node_modules/react-native/cli.js)',
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
const rnc = path.join(cwd, 'node_modules', '.bin', process.platform === 'win32' ? 'rnc-cli.cmd' : 'rnc-cli');
|
|
244
|
+
if (fs.existsSync(rnc)) {
|
|
245
|
+
// Quoted because shell:true concatenates, and a project path may contain spaces.
|
|
246
|
+
return { cmd: `"${rnc}"`, pre: ['bundle'], shell: true, label: 'rnc-cli bundle' };
|
|
247
|
+
}
|
|
248
|
+
// Last resort: whatever npx can find. Kept so a non-standard layout still has
|
|
249
|
+
// a chance rather than being refused outright.
|
|
250
|
+
return { cmd: 'npx', pre: ['react-native', 'bundle'], shell: true, label: 'react-native bundle' };
|
|
251
|
+
}
|
|
252
|
+
function buildBundle(opts) {
|
|
253
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'scalebun-bundle-'));
|
|
254
|
+
const bundlePath = path.join(tmpDir, 'bundle.jsbundle');
|
|
255
|
+
const assetsPath = path.join(tmpDir, 'assets');
|
|
256
|
+
const BUNDLE_TIMEOUT_MS = resolveBundleTimeoutMs();
|
|
257
|
+
fs.mkdirSync(assetsPath, { recursive: true });
|
|
258
|
+
// `expo export:embed` is the Expo-side equivalent of `react-native bundle`
|
|
259
|
+
// and accepts the same flags. Both emit a plain JS bundle; Hermes compilation
|
|
260
|
+
// is a separate step below in either case.
|
|
261
|
+
const expo = isExpoProject();
|
|
262
|
+
const bundler = resolveBundler(process.cwd(), expo);
|
|
263
|
+
const args = [...bundler.pre];
|
|
264
|
+
args.push('--platform', opts.platform, '--dev', String(opts.dev), '--entry-file', opts.entryFile, '--bundle-output', bundlePath, '--assets-dest', assetsPath);
|
|
265
|
+
// Sprint 8: Generate sourcemap if requested
|
|
266
|
+
if (opts.sourcemap) {
|
|
267
|
+
args.push('--sourcemap-output', bundlePath + '.map');
|
|
268
|
+
}
|
|
269
|
+
console.log(` Detected ${expo ? 'Expo' : 'bare React Native'} project`);
|
|
270
|
+
console.log(` Running: ${bundler.label}`);
|
|
271
|
+
const result = childProcess.spawnSync(bundler.cmd, args, {
|
|
272
|
+
// stdin IGNORED, stdout/stderr inherited. Metro never reads stdin, and
|
|
273
|
+
// inheriting a console stdin that a parent prompt (readline/raw mode) still
|
|
274
|
+
// holds corrupts the child's handle on Windows — the process is then killed
|
|
275
|
+
// with a null exit code. Ignoring stdin makes the build robust to whatever
|
|
276
|
+
// state the interactive wizard left the terminal in.
|
|
277
|
+
stdio: ['ignore', 'inherit', 'inherit'],
|
|
278
|
+
// shell:true is REQUIRED here, not incidental. On Windows `npx` is `npx.cmd`,
|
|
279
|
+
// and since the CVE-2024-27980 mitigation Node throws EINVAL when spawning a
|
|
280
|
+
// .cmd/.bat WITHOUT a shell — so `spawnSync('npx.cmd', …, {shell:false})`
|
|
281
|
+
// would fail outright. The trade-off is that on a timeout Windows kills only
|
|
282
|
+
// this cmd.exe and orphans the Metro grandchild (its "Done writing bundle
|
|
283
|
+
// output" then prints after we've already errored); the generous, override-
|
|
284
|
+
// able timeout below is what keeps that path from firing on a healthy build.
|
|
285
|
+
shell: bundler.shell,
|
|
286
|
+
timeout: BUNDLE_TIMEOUT_MS,
|
|
287
|
+
});
|
|
288
|
+
const tool = expo ? 'expo export:embed' : 'react-native bundle';
|
|
289
|
+
if (result.error) {
|
|
290
|
+
// spawn itself failed (command not found, timeout → ETIMEDOUT, etc.).
|
|
291
|
+
// A timeout is the common one on a large app whose first cold Metro build
|
|
292
|
+
// legitimately runs long — say the limit and how to lift it, rather than
|
|
293
|
+
// leaving a bare "ETIMEDOUT" that reads like a crash.
|
|
294
|
+
const timedOut = result.error.code === 'ETIMEDOUT';
|
|
295
|
+
const hint = timedOut
|
|
296
|
+
? ` — the build exceeded ${Math.round(BUNDLE_TIMEOUT_MS / 60000)} min. A large app's first ` +
|
|
297
|
+
'cold bundle can take longer; raise the limit with SCALEBUN_BUNDLE_TIMEOUT_MS ' +
|
|
298
|
+
'(milliseconds), or pre-build and pass --skip-bundle --bundle-path.'
|
|
299
|
+
: '';
|
|
300
|
+
throw new Error(`${tool} could not be run: ${result.error.message}${hint}`);
|
|
301
|
+
}
|
|
302
|
+
if (result.status !== 0) {
|
|
303
|
+
// status is null when the child was terminated by a signal rather than
|
|
304
|
+
// exiting — report that instead of a bare "null".
|
|
305
|
+
const why = result.signal
|
|
306
|
+
? `terminated by signal ${result.signal}`
|
|
307
|
+
: `exit code ${result.status}`;
|
|
308
|
+
throw new Error(`${tool} failed (${why}). Try running the printed command directly to see the error.`);
|
|
309
|
+
}
|
|
310
|
+
if (!fs.existsSync(bundlePath)) {
|
|
311
|
+
throw new Error(`Bundle file not found at ${bundlePath}`);
|
|
312
|
+
}
|
|
313
|
+
// Identity marker — injected into the JS source, before any Hermes step
|
|
314
|
+
// (after hermesc the artifact is binary and text would corrupt the header).
|
|
315
|
+
//
|
|
316
|
+
// APPENDED, not prepended. Metro has already written the sourcemap by this
|
|
317
|
+
// point, and a prepended line shifts every generated line down by one —
|
|
318
|
+
// silently corrupting the line numbers of every symbolicated stack trace
|
|
319
|
+
// from this bundle. An appended statement adds no mappings and moves none;
|
|
320
|
+
// it still executes during bundle evaluation, and the SDK reads the global
|
|
321
|
+
// at init(), long after evaluation completes.
|
|
322
|
+
if (opts.identityToken) {
|
|
323
|
+
const marker = `\nglobalThis.__SCALEBUN_OTA_ID__=${JSON.stringify(opts.identityToken)};\n`;
|
|
324
|
+
fs.appendFileSync(bundlePath, marker, 'utf-8');
|
|
325
|
+
}
|
|
326
|
+
// Hermes bytecode compilation (opt-in)
|
|
327
|
+
if (opts.hermes) {
|
|
328
|
+
console.log(' Compiling to Hermes bytecode…');
|
|
329
|
+
// Compile to a sibling path, then rename. hermesc reading and writing the
|
|
330
|
+
// same path in one invocation is not guaranteed to be safe, and a truncated
|
|
331
|
+
// in-place write would produce a bundle that hashes fine and never loads.
|
|
332
|
+
const hbcPath = bundlePath + '.hbc';
|
|
333
|
+
const hermesc = resolveHermesc();
|
|
334
|
+
// A missing hermesc is handled with the compile failures below, so that
|
|
335
|
+
// "cannot compile" has exactly one outcome regardless of the reason.
|
|
336
|
+
// Output is CAPTURED, not inherited. hermesc emits one warning per
|
|
337
|
+
// undeclared global per module ("the variable Buffer was not declared…"),
|
|
338
|
+
// and each warning quotes the offending source line — which in a minified
|
|
339
|
+
// bundle is a single line of 100KB+. Two consequences shaped this code:
|
|
340
|
+
// 1. Inherited stdio drowned the publish summary in megabytes of noise.
|
|
341
|
+
// 2. spawnSync's DEFAULT maxBuffer is 1MB; the quoted warnings blow past
|
|
342
|
+
// it, Node kills hermesc (ENOBUFS), and `--hermes` silently degrades
|
|
343
|
+
// to plain JS — the same bug as `npx hermesc`, via a different door.
|
|
344
|
+
// Hit live on the very first publish after the capture change.
|
|
345
|
+
const hermescResult = hermesc
|
|
346
|
+
? childProcess.spawnSync(hermesc, ['-emit-binary', '-out', hbcPath, bundlePath], {
|
|
347
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
348
|
+
shell: false,
|
|
349
|
+
timeout: 120000,
|
|
350
|
+
encoding: 'utf-8',
|
|
351
|
+
maxBuffer: 256 * 1024 * 1024,
|
|
352
|
+
})
|
|
353
|
+
: { status: 1 };
|
|
354
|
+
if (hermesc && hermescResult.status === 0) {
|
|
355
|
+
const warnings = `${hermescResult.stdout ?? ''}${hermescResult.stderr ?? ''}`
|
|
356
|
+
.split('\n')
|
|
357
|
+
.filter((l) => l.includes('warning:')).length;
|
|
358
|
+
if (warnings > 0) {
|
|
359
|
+
console.log(` (${warnings} hermesc warnings suppressed — expected for RN bundles)`);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
if (hermescResult.status !== 0 || !fs.existsSync(hbcPath)) {
|
|
363
|
+
// Collect the reason before deciding what to do with it — the same
|
|
364
|
+
// detail is worth printing whether this ends as an error or a warning.
|
|
365
|
+
const reason = hermesc
|
|
366
|
+
? `hermesc failed (exit ${hermescResult.status}` +
|
|
367
|
+
`${hermescResult.error ? `, ${hermescResult.error.message}` : ''})`
|
|
368
|
+
: 'hermesc not found under node_modules/react-native/sdks/hermesc';
|
|
369
|
+
// Only lines that carry the error itself, each clipped: a quoted
|
|
370
|
+
// minified source line is 100KB of noise per line.
|
|
371
|
+
const errLines = `${hermescResult.stderr ?? ''}`
|
|
372
|
+
.split('\n')
|
|
373
|
+
.filter((l) => l.includes('error:'))
|
|
374
|
+
.slice(0, 5)
|
|
375
|
+
.map((l) => (l.length > 200 ? l.slice(0, 200) + '…' : l));
|
|
376
|
+
try {
|
|
377
|
+
if (fs.existsSync(hbcPath))
|
|
378
|
+
fs.unlinkSync(hbcPath);
|
|
379
|
+
}
|
|
380
|
+
catch {
|
|
381
|
+
/* ignore */
|
|
382
|
+
}
|
|
383
|
+
if (!opts.allowPlainJs) {
|
|
384
|
+
// STOP. --hermes was explicitly requested; shipping the uncompiled
|
|
385
|
+
// bundle instead would publish a different artifact than the one
|
|
386
|
+
// asked for, and nothing downstream could tell.
|
|
387
|
+
for (const l of errLines)
|
|
388
|
+
console.error(` ${l}`);
|
|
389
|
+
throw new Error(`${reason}.\n` +
|
|
390
|
+
' --hermes was requested, so this is a hard failure rather than a silent\n' +
|
|
391
|
+
' downgrade: shipping plain JS would slow every user\'s cold start by\n' +
|
|
392
|
+
' 20-30% and break delta patching against previous bytecode releases.\n' +
|
|
393
|
+
' Fix the toolchain, or pass --allow-plain-js to publish uncompiled.');
|
|
394
|
+
}
|
|
395
|
+
console.warn(` ⚠️ ${reason} — shipping plain JS bundle (--allow-plain-js)`);
|
|
396
|
+
for (const l of errLines)
|
|
397
|
+
console.warn(` ${l}`);
|
|
398
|
+
}
|
|
399
|
+
else {
|
|
400
|
+
fs.renameSync(hbcPath, bundlePath);
|
|
401
|
+
console.log(' ✅ Hermes bytecode compiled');
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
else {
|
|
405
|
+
// Reached only when the caller explicitly opted out — every command
|
|
406
|
+
// defaults to bytecode. The old text ("Use --hermes for bytecode
|
|
407
|
+
// compilation") described a default that no longer exists and read as
|
|
408
|
+
// though plain JS were normal.
|
|
409
|
+
console.log(' ℹ️ Shipping plain JS — Hermes was disabled for this build.');
|
|
410
|
+
console.log(' Cold start is ~20-30% slower, and delta patches against a');
|
|
411
|
+
console.log(' previous bytecode release collapse to a full download.');
|
|
412
|
+
}
|
|
413
|
+
// Read the format back off the artifact rather than trusting the flag. When
|
|
414
|
+
// hermesc fails we fall back to plain JS, and recording `hermes: true` anyway
|
|
415
|
+
// would tell the backend to gate devices on a bytecode version this bundle
|
|
416
|
+
// does not have.
|
|
417
|
+
const hermesBytecodeVersion = readHermesBytecodeVersion(bundlePath);
|
|
418
|
+
if (opts.hermes && hermesBytecodeVersion === null) {
|
|
419
|
+
console.warn(' ⚠️ Artifact is not Hermes bytecode — recording it as plain JS.');
|
|
420
|
+
}
|
|
421
|
+
return {
|
|
422
|
+
bundlePath,
|
|
423
|
+
assetsPath,
|
|
424
|
+
assets: listAssets(assetsPath),
|
|
425
|
+
hermesCompiled: hermesBytecodeVersion !== null,
|
|
426
|
+
hermesBytecodeVersion,
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Every asset file Metro emitted for this bundle, relative to the assets root.
|
|
431
|
+
*
|
|
432
|
+
* OTA ships ONE artifact: the JS/bytecode bundle. Assets are resolved from what
|
|
433
|
+
* the installed binary already contains, so an image or font added since the
|
|
434
|
+
* last store build is referenced by the new JS and is simply not there — the
|
|
435
|
+
* update installs cleanly and renders a missing image. `ota publish` uses this
|
|
436
|
+
* list to say so out loud rather than discarding the directory in silence.
|
|
437
|
+
*/
|
|
438
|
+
function listAssets(root) {
|
|
439
|
+
const out = [];
|
|
440
|
+
const walk = (dir, prefix) => {
|
|
441
|
+
let entries;
|
|
442
|
+
try {
|
|
443
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
444
|
+
}
|
|
445
|
+
catch {
|
|
446
|
+
return; // no assets dir at all is the common, healthy case
|
|
447
|
+
}
|
|
448
|
+
for (const entry of entries) {
|
|
449
|
+
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
450
|
+
if (entry.isDirectory())
|
|
451
|
+
walk(path.join(dir, entry.name), rel);
|
|
452
|
+
else
|
|
453
|
+
out.push(rel);
|
|
454
|
+
}
|
|
455
|
+
};
|
|
456
|
+
walk(root, '');
|
|
457
|
+
return out;
|
|
458
|
+
}
|
|
459
|
+
//# sourceMappingURL=bundle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundle.js","sourceRoot":"","sources":["../../src/utils/bundle.ts"],"names":[],"mappings":"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"}
|
|
@@ -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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"}
|