@absolutejs/absolute 0.20.0-beta.85 → 0.20.0-beta.87
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/dist/angular/components/core/streamingSlotRegistrar.js +1 -1
- package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
- package/dist/build.js +656 -18
- package/dist/build.js.map +5 -5
- package/dist/cli/{compile-d7g2fvqe.js → compile-5hchbcbd.js} +3 -3
- package/dist/cli/{config-naw5fer4.js → config-vy04mqce.js} +1 -1
- package/dist/cli/{dev-skb8dz33.js → dev-6shm8qsn.js} +2 -2
- package/dist/cli/{expoProject-3mmwtemn.js → expoProject-dac8fqhq.js} +1 -1
- package/dist/cli/{index-q78x1k9q.js → index-39j0dhq7.js} +2 -2
- package/dist/cli/{index-8gksmws3.js → index-jqdt7841.js} +2 -2
- package/dist/cli/{index-czw3jd8f.js → index-rd2hbttb.js} +67 -1
- package/dist/cli/{index-p8ezgd5e.js → index-tame6e2c.js} +65 -3
- package/dist/cli/index.js +5 -5
- package/dist/cli/{mobile-pdck6a35.js → mobile-c94a5y9k.js} +205 -10
- package/dist/cli/{start-jbgfw27x.js → start-7jg0csqy.js} +4 -4
- package/dist/index.js +656 -18
- package/dist/index.js.map +5 -5
- package/dist/mobile/index.js +840 -25
- package/dist/mobile/index.js.map +8 -8
- package/dist/mobile/remoteMacAgentEntry.js +270 -208
- package/dist/mobile/shellUpdate.js +138 -23
- package/dist/src/mobile/config.d.ts +14 -0
- package/dist/src/mobile/updateClient.d.ts +13 -0
- package/dist/src/mobile/updatePublisher.d.ts +78 -1
- package/dist/src/mobile/updateServer.d.ts +28 -0
- package/dist/types/build.d.ts +25 -0
- package/package.json +2 -2
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
createIslandRegistryDefinitionPlugin,
|
|
13
13
|
finalizeAbsoluteMobileCompatibilityBuild,
|
|
14
14
|
resolveServerBundleExternals
|
|
15
|
-
} from "./index-
|
|
15
|
+
} from "./index-jqdt7841.js";
|
|
16
16
|
import {
|
|
17
17
|
loadIslandRegistryBuildInfo
|
|
18
18
|
} from "./index-bzs19w3r.js";
|
|
@@ -35,8 +35,8 @@ import {
|
|
|
35
35
|
import"./index-w5vswatm.js";
|
|
36
36
|
import {
|
|
37
37
|
normalizeAbsoluteMobileConfig
|
|
38
|
-
} from "./index-
|
|
39
|
-
import"./index-
|
|
38
|
+
} from "./index-rd2hbttb.js";
|
|
39
|
+
import"./index-tame6e2c.js";
|
|
40
40
|
import {
|
|
41
41
|
ABSOLUTE_NATIVE_AUTH_CLIENTS_ENV,
|
|
42
42
|
installAbsoluteMobileAuthEnvironment
|
|
@@ -1281,8 +1281,8 @@ var loadAbsoluteMobileDevModules = async () => {
|
|
|
1281
1281
|
remoteMacProtocol,
|
|
1282
1282
|
iosNativeWatcher
|
|
1283
1283
|
] = await Promise.all([
|
|
1284
|
-
import("./config-
|
|
1285
|
-
import("./expoProject-
|
|
1284
|
+
import("./config-vy04mqce.js"),
|
|
1285
|
+
import("./expoProject-dac8fqhq.js"),
|
|
1286
1286
|
import("./expoDevController-n19kb5fr.js"),
|
|
1287
1287
|
import("./nativeAuth-zx4tsb1f.js"),
|
|
1288
1288
|
import("./androidEmulatorController-nybhzc6c.js"),
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
createIslandRegistryDefinitionPlugin,
|
|
7
7
|
finalizeAbsoluteMobileCompatibilityBuild,
|
|
8
8
|
resolveServerBundleExternals
|
|
9
|
-
} from "./index-
|
|
9
|
+
} from "./index-jqdt7841.js";
|
|
10
10
|
import {
|
|
11
11
|
loadIslandRegistryBuildInfo
|
|
12
12
|
} from "./index-bzs19w3r.js";
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
} from "./index-9kwmb3c0.js";
|
|
27
27
|
import {
|
|
28
28
|
normalizeAbsoluteMobileConfig
|
|
29
|
-
} from "./index-
|
|
29
|
+
} from "./index-rd2hbttb.js";
|
|
30
30
|
import {
|
|
31
31
|
installAbsoluteMobileAuthEnvironment
|
|
32
32
|
} from "./index-ar4gz15x.js";
|
|
@@ -4,13 +4,13 @@ import {
|
|
|
4
4
|
} from "./index-s2tazax7.js";
|
|
5
5
|
import {
|
|
6
6
|
normalizeAbsoluteMobileConfig
|
|
7
|
-
} from "./index-
|
|
7
|
+
} from "./index-rd2hbttb.js";
|
|
8
8
|
import {
|
|
9
9
|
assertAbsoluteDeviceCapabilityPackages,
|
|
10
10
|
resolveAbsoluteMobileUpdateRuntime,
|
|
11
11
|
syncAbsoluteExpoWebAssets,
|
|
12
12
|
writeAbsoluteExpoProject
|
|
13
|
-
} from "./index-
|
|
13
|
+
} from "./index-tame6e2c.js";
|
|
14
14
|
|
|
15
15
|
// src/build/islandRegistryTransform.ts
|
|
16
16
|
import { basename } from "path";
|
|
@@ -11,6 +11,16 @@ var UPDATE_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/u;
|
|
|
11
11
|
var UPDATE_PUBLIC_KEY_PATTERN = /^[A-Za-z0-9+/]+={0,2}$/u;
|
|
12
12
|
var ENVIRONMENT_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/u;
|
|
13
13
|
var DEFAULT_UPDATE_BOOT_TIMEOUT_MS = 20000;
|
|
14
|
+
var DEFAULT_UPDATE_HEALTH_FAILURE_RATE = 0.2;
|
|
15
|
+
var DEFAULT_UPDATE_HEALTH_MINIMUM_REPORTS = 20;
|
|
16
|
+
var DEFAULT_UPDATE_ROLLOUT_FAILURE_RATE = 0.05;
|
|
17
|
+
var DEFAULT_UPDATE_ROLLOUT_OBSERVATION_MINUTES = 60;
|
|
18
|
+
var MINUTE_MS = 60 * 1000;
|
|
19
|
+
var DEFAULT_UPDATE_ROLLOUT_STAGES = [
|
|
20
|
+
{ minimumReports: 20, observationMinutes: 60, rollout: 0.05 },
|
|
21
|
+
{ minimumReports: 100, observationMinutes: 360, rollout: 0.25 },
|
|
22
|
+
{ minimumReports: 100, observationMinutes: 0, rollout: 1 }
|
|
23
|
+
];
|
|
14
24
|
var MINIMUM_UPDATE_BOOT_TIMEOUT_MS = 5000;
|
|
15
25
|
var MAXIMUM_UPDATE_BOOT_TIMEOUT_MS = 120000;
|
|
16
26
|
var HOSTNAME_PATTERN = /^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)(?:\.(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?))*$/;
|
|
@@ -230,6 +240,56 @@ var normalizeUpdateServer = (config, productionOrigin, projectRoot, updates) =>
|
|
|
230
240
|
if (!ENVIRONMENT_NAME_PATTERN.test(expoPrivateKeyEnv))
|
|
231
241
|
throw new TypeError("mobile.updates.server.expoPrivateKeyEnv must be a valid environment variable name.");
|
|
232
242
|
const autoMount = config.updates.server?.autoMount ?? true;
|
|
243
|
+
const configuredHealth = config.updates.server?.health;
|
|
244
|
+
let health;
|
|
245
|
+
if (configuredHealth !== false) {
|
|
246
|
+
const failureRate = configuredHealth?.failureRate ?? DEFAULT_UPDATE_HEALTH_FAILURE_RATE;
|
|
247
|
+
const minimumReports = configuredHealth?.minimumReports ?? DEFAULT_UPDATE_HEALTH_MINIMUM_REPORTS;
|
|
248
|
+
const secretEnv = requireText(configuredHealth?.secretEnv ?? "ABSOLUTE_MOBILE_UPDATE_HEALTH_SECRET", "mobile.updates.server.health.secretEnv");
|
|
249
|
+
if (!Number.isFinite(failureRate) || failureRate <= 0 || failureRate > 1)
|
|
250
|
+
throw new TypeError("mobile.updates.server.health.failureRate must be greater than 0 and at most 1.");
|
|
251
|
+
if (!Number.isSafeInteger(minimumReports) || minimumReports < 1)
|
|
252
|
+
throw new TypeError("mobile.updates.server.health.minimumReports must be a positive integer.");
|
|
253
|
+
if (!ENVIRONMENT_NAME_PATTERN.test(secretEnv))
|
|
254
|
+
throw new TypeError("mobile.updates.server.health.secretEnv must be a valid environment variable name.");
|
|
255
|
+
health = { failureRate, minimumReports, secretEnv };
|
|
256
|
+
}
|
|
257
|
+
const configuredRollout = config.updates.server?.rollout;
|
|
258
|
+
let rollout;
|
|
259
|
+
if (configuredRollout !== undefined && configuredRollout !== false) {
|
|
260
|
+
if (!health)
|
|
261
|
+
throw new TypeError("mobile.updates.server.rollout requires fleet health to be enabled.");
|
|
262
|
+
if (configuredRollout.automatic !== undefined && typeof configuredRollout.automatic !== "boolean")
|
|
263
|
+
throw new TypeError("mobile.updates.server.rollout.automatic must be boolean.");
|
|
264
|
+
const configuredStages = configuredRollout.stages ?? DEFAULT_UPDATE_ROLLOUT_STAGES;
|
|
265
|
+
const stages = configuredStages.map((stage, index) => {
|
|
266
|
+
const previousStage = configuredStages[index - 1];
|
|
267
|
+
const maximumFailureRate = stage.maximumFailureRate ?? DEFAULT_UPDATE_ROLLOUT_FAILURE_RATE;
|
|
268
|
+
const minimumReports = stage.minimumReports ?? DEFAULT_UPDATE_HEALTH_MINIMUM_REPORTS;
|
|
269
|
+
const observationMinutes = stage.observationMinutes ?? DEFAULT_UPDATE_ROLLOUT_OBSERVATION_MINUTES;
|
|
270
|
+
const observationMs = observationMinutes * MINUTE_MS;
|
|
271
|
+
if (!Number.isFinite(stage.rollout) || stage.rollout <= 0 || stage.rollout > 1 || previousStage !== undefined && stage.rollout <= previousStage.rollout)
|
|
272
|
+
throw new TypeError("mobile.updates.server.rollout stages must be strictly increasing fractions greater than 0 and at most 1.");
|
|
273
|
+
if (!Number.isFinite(maximumFailureRate) || maximumFailureRate < 0 || maximumFailureRate >= health.failureRate)
|
|
274
|
+
throw new TypeError("mobile.updates.server.rollout maximumFailureRate must be non-negative and lower than the fleet-health pause rate.");
|
|
275
|
+
if (!Number.isSafeInteger(minimumReports) || minimumReports < health.minimumReports)
|
|
276
|
+
throw new TypeError("mobile.updates.server.rollout minimumReports must be an integer at least as large as the fleet-health minimumReports.");
|
|
277
|
+
if (!Number.isFinite(observationMinutes) || observationMinutes < 0 || !Number.isSafeInteger(observationMs))
|
|
278
|
+
throw new TypeError("mobile.updates.server.rollout observationMinutes must produce a non-negative whole number of milliseconds.");
|
|
279
|
+
return {
|
|
280
|
+
maximumFailureRate,
|
|
281
|
+
minimumReports,
|
|
282
|
+
observationMs,
|
|
283
|
+
rollout: stage.rollout
|
|
284
|
+
};
|
|
285
|
+
});
|
|
286
|
+
if (stages.length === 0 || stages.at(-1)?.rollout !== 1)
|
|
287
|
+
throw new TypeError("mobile.updates.server.rollout stages must end at rollout 1.");
|
|
288
|
+
rollout = {
|
|
289
|
+
automatic: configuredRollout.automatic ?? false,
|
|
290
|
+
stages
|
|
291
|
+
};
|
|
292
|
+
}
|
|
233
293
|
if (autoMount) {
|
|
234
294
|
const manifest = new URL(updates.manifestUrl);
|
|
235
295
|
if (manifest.origin !== productionOrigin)
|
|
@@ -262,7 +322,13 @@ var normalizeUpdateServer = (config, productionOrigin, projectRoot, updates) =>
|
|
|
262
322
|
throw new TypeError(`mobile.updates.server.expoCodeSigningKeys.${keyId} certificate is not currently valid.`);
|
|
263
323
|
expoCodeSigningKeys[keyId] = { certificatePem, privateKeyEnv };
|
|
264
324
|
}
|
|
265
|
-
return {
|
|
325
|
+
return {
|
|
326
|
+
autoMount,
|
|
327
|
+
expoCodeSigningKeys,
|
|
328
|
+
...health ? { health } : {},
|
|
329
|
+
...rollout ? { rollout } : {},
|
|
330
|
+
registryModule
|
|
331
|
+
};
|
|
266
332
|
};
|
|
267
333
|
var validateExpoNativeRouteSegment = (path, segment, index, count, parameters) => {
|
|
268
334
|
if (segment === "*" && (index !== count - 1 || count === 1)) {
|
|
@@ -1728,11 +1728,48 @@ export default function AbsoluteLayout() {
|
|
|
1728
1728
|
return <Stack screenOptions={{ headerShown: false }} />;
|
|
1729
1729
|
}
|
|
1730
1730
|
`;
|
|
1731
|
-
var updatesRuntimeSource = () => `${EXPO_GENERATED_HEADER}import { randomUUID } from 'expo-crypto';
|
|
1731
|
+
var updatesRuntimeSource = (config) => `${EXPO_GENERATED_HEADER}import { randomUUID } from 'expo-crypto';
|
|
1732
1732
|
import * as SecureStore from 'expo-secure-store';
|
|
1733
1733
|
import * as Updates from 'expo-updates';
|
|
1734
1734
|
|
|
1735
1735
|
const INSTALLATION_KEY = 'absolutejs.mobile.update.installation.v1';
|
|
1736
|
+
const PENDING_HEALTH_KEY = 'absolutejs.mobile.update.pending-health.v1';
|
|
1737
|
+
const APP_ID = ${JSON.stringify(config.appId)};
|
|
1738
|
+
const CHANNEL = ${JSON.stringify(config.updates?.channel)};
|
|
1739
|
+
const MANIFEST_URL = ${JSON.stringify(config.updates?.manifestUrl)};
|
|
1740
|
+
|
|
1741
|
+
const updateIdentity = (value: unknown) => {
|
|
1742
|
+
if (!value || typeof value !== 'object') return undefined;
|
|
1743
|
+
const extra = Reflect.get(value, 'extra');
|
|
1744
|
+
if (!extra || typeof extra !== 'object') return undefined;
|
|
1745
|
+
const absolute = Reflect.get(extra, 'absolutejs');
|
|
1746
|
+
if (!absolute || typeof absolute !== 'object') return undefined;
|
|
1747
|
+
const healthToken = Reflect.get(absolute, 'healthToken');
|
|
1748
|
+
const releaseId = Reflect.get(absolute, 'releaseId');
|
|
1749
|
+
return typeof healthToken === 'string' && typeof releaseId === 'string'
|
|
1750
|
+
? { healthToken, releaseId }
|
|
1751
|
+
: undefined;
|
|
1752
|
+
};
|
|
1753
|
+
|
|
1754
|
+
const report = async (installationId: string, evidence: { healthToken: string; kind: string; releaseId: string }) => {
|
|
1755
|
+
const endpoint = new URL('./health', MANIFEST_URL);
|
|
1756
|
+
await fetch(endpoint.href, {
|
|
1757
|
+
body: JSON.stringify({ kind: evidence.kind, releaseId: evidence.releaseId }),
|
|
1758
|
+
cache: 'no-store',
|
|
1759
|
+
credentials: 'omit',
|
|
1760
|
+
headers: {
|
|
1761
|
+
'content-type': 'application/json',
|
|
1762
|
+
'x-absolute-mobile-app': APP_ID,
|
|
1763
|
+
'x-absolute-mobile-channel': CHANNEL,
|
|
1764
|
+
'x-absolute-mobile-health-token': evidence.healthToken,
|
|
1765
|
+
'x-absolute-mobile-installation': installationId,
|
|
1766
|
+
'x-absolute-mobile-release': updateIdentity(Updates.manifest)?.releaseId ?? 'embedded',
|
|
1767
|
+
'x-absolute-mobile-runtime': Updates.runtimeVersion ?? ''
|
|
1768
|
+
},
|
|
1769
|
+
method: 'POST',
|
|
1770
|
+
redirect: 'error'
|
|
1771
|
+
});
|
|
1772
|
+
};
|
|
1736
1773
|
|
|
1737
1774
|
let startPromise: Promise<void> | undefined;
|
|
1738
1775
|
export const startAbsoluteExpoUpdates = () => {
|
|
@@ -1744,9 +1781,34 @@ export const startAbsoluteExpoUpdates = () => {
|
|
|
1744
1781
|
await SecureStore.setItemAsync(INSTALLATION_KEY, installationId);
|
|
1745
1782
|
}
|
|
1746
1783
|
await Updates.setExtraParamAsync('absolute-installation', installationId);
|
|
1784
|
+
const pendingSource = await SecureStore.getItemAsync(PENDING_HEALTH_KEY);
|
|
1785
|
+
if (pendingSource) {
|
|
1786
|
+
try {
|
|
1787
|
+
const pending = JSON.parse(pendingSource);
|
|
1788
|
+
const active = updateIdentity(Updates.manifest);
|
|
1789
|
+
if (typeof pending?.healthToken === 'string' && typeof pending?.releaseId === 'string')
|
|
1790
|
+
await report(installationId, {
|
|
1791
|
+
healthToken: pending.healthToken,
|
|
1792
|
+
kind: active?.releaseId === pending.releaseId ? 'activated' : 'rolled-back',
|
|
1793
|
+
releaseId: pending.releaseId
|
|
1794
|
+
});
|
|
1795
|
+
} catch {}
|
|
1796
|
+
await SecureStore.deleteItemAsync(PENDING_HEALTH_KEY);
|
|
1797
|
+
}
|
|
1747
1798
|
const result = await Updates.checkForUpdateAsync();
|
|
1748
1799
|
if (result.isAvailable || result.isRollBackToEmbedded) {
|
|
1749
|
-
|
|
1800
|
+
const available = updateIdentity(Reflect.get(result, 'manifest'));
|
|
1801
|
+
try {
|
|
1802
|
+
const fetched = await Updates.fetchUpdateAsync();
|
|
1803
|
+
const identity = updateIdentity(Reflect.get(fetched, 'manifest')) ?? available;
|
|
1804
|
+
if (identity) {
|
|
1805
|
+
await SecureStore.setItemAsync(PENDING_HEALTH_KEY, JSON.stringify(identity));
|
|
1806
|
+
await report(installationId, { ...identity, kind: 'downloaded' });
|
|
1807
|
+
}
|
|
1808
|
+
} catch (error) {
|
|
1809
|
+
if (available) await report(installationId, { ...available, kind: 'download-failed' }).catch(() => undefined);
|
|
1810
|
+
throw error;
|
|
1811
|
+
}
|
|
1750
1812
|
if (result.isRollBackToEmbedded) {
|
|
1751
1813
|
await Updates.reloadAsync();
|
|
1752
1814
|
}
|
|
@@ -2691,7 +2753,7 @@ node_modules/
|
|
|
2691
2753
|
files.set(path, source);
|
|
2692
2754
|
}
|
|
2693
2755
|
if (config.updates) {
|
|
2694
|
-
files.set(join4(project, "src", "generated", "AbsoluteUpdates.ts"), updatesRuntimeSource());
|
|
2756
|
+
files.set(join4(project, "src", "generated", "AbsoluteUpdates.ts"), updatesRuntimeSource(config));
|
|
2695
2757
|
}
|
|
2696
2758
|
const expoCodeSigning = config.updates?.expoCodeSigning;
|
|
2697
2759
|
if (expoCodeSigning)
|
package/dist/cli/index.js
CHANGED
|
@@ -58,7 +58,7 @@ if (command === "dev") {
|
|
|
58
58
|
}
|
|
59
59
|
const positionalArgs = stripNamedArgs("--config", "--android-device", "--ios-device").filter((arg) => arg !== "--no-mobile" && arg !== "--eager");
|
|
60
60
|
const serverEntry = positionalArgs[0] ?? DEFAULT_SERVER_ENTRY;
|
|
61
|
-
const { dev } = await import("./dev-
|
|
61
|
+
const { dev } = await import("./dev-6shm8qsn.js");
|
|
62
62
|
await dev(serverEntry, configPath, {
|
|
63
63
|
androidDevice,
|
|
64
64
|
eager: args.includes("--eager"),
|
|
@@ -71,7 +71,7 @@ if (command === "dev") {
|
|
|
71
71
|
const configPath = parseNamedArg("--config");
|
|
72
72
|
const positionalArgs = stripNamedArgs("--outdir", "--config").filter((arg) => arg !== "--prebuilt");
|
|
73
73
|
const serverEntry = positionalArgs[0] ?? DEFAULT_SERVER_ENTRY;
|
|
74
|
-
const { start } = await import("./start-
|
|
74
|
+
const { start } = await import("./start-7jg0csqy.js");
|
|
75
75
|
await start(serverEntry, outdir, configPath, {
|
|
76
76
|
prebuilt: args.includes("--prebuilt")
|
|
77
77
|
});
|
|
@@ -81,7 +81,7 @@ if (command === "dev") {
|
|
|
81
81
|
const configPath = parseNamedArg("--config");
|
|
82
82
|
const positionalArgs = stripNamedArgs("--outdir", "--config");
|
|
83
83
|
const serverEntry = positionalArgs[0] ?? DEFAULT_SERVER_ENTRY;
|
|
84
|
-
const { start } = await import("./start-
|
|
84
|
+
const { start } = await import("./start-7jg0csqy.js");
|
|
85
85
|
await start(serverEntry, outdir, configPath, { prepareOnly: true });
|
|
86
86
|
} else if (command === "build") {
|
|
87
87
|
sendTelemetryEvent("cli:command", { command });
|
|
@@ -197,13 +197,13 @@ if (command === "dev") {
|
|
|
197
197
|
const configPath = parseNamedArg("--config");
|
|
198
198
|
const positionalArgs = stripNamedArgs("--outdir", "--outfile", "--config");
|
|
199
199
|
const serverEntry = positionalArgs[0] ?? DEFAULT_SERVER_ENTRY;
|
|
200
|
-
const { compile } = await import("./compile-
|
|
200
|
+
const { compile } = await import("./compile-5hchbcbd.js");
|
|
201
201
|
await compile(serverEntry, outdir, outfile, configPath);
|
|
202
202
|
} else if (command === "mobile") {
|
|
203
203
|
sendTelemetryEvent("cli:command", {
|
|
204
204
|
command: `mobile:${workspaceCommand ?? "unknown"}`
|
|
205
205
|
});
|
|
206
|
-
const { runMobile } = await import("./mobile-
|
|
206
|
+
const { runMobile } = await import("./mobile-c94a5y9k.js");
|
|
207
207
|
try {
|
|
208
208
|
await runMobile(args);
|
|
209
209
|
} catch (error) {
|
|
@@ -7,12 +7,12 @@ import {
|
|
|
7
7
|
} from "./index-9r7n9dqp.js";
|
|
8
8
|
import {
|
|
9
9
|
start
|
|
10
|
-
} from "./index-
|
|
10
|
+
} from "./index-39j0dhq7.js";
|
|
11
11
|
import {
|
|
12
12
|
ABSOLUTE_MOBILE_CLIENT_MANIFEST_FORMAT,
|
|
13
13
|
ABSOLUTE_MOBILE_PAGE_PROTOCOL_VERSION,
|
|
14
14
|
resolveAbsoluteMobileRoute
|
|
15
|
-
} from "./index-
|
|
15
|
+
} from "./index-jqdt7841.js";
|
|
16
16
|
import"./index-bzs19w3r.js";
|
|
17
17
|
import"./index-s2tazax7.js";
|
|
18
18
|
import {
|
|
@@ -52,7 +52,7 @@ import {
|
|
|
52
52
|
import"./index-w5vswatm.js";
|
|
53
53
|
import {
|
|
54
54
|
normalizeAbsoluteMobileConfig
|
|
55
|
-
} from "./index-
|
|
55
|
+
} from "./index-rd2hbttb.js";
|
|
56
56
|
import {
|
|
57
57
|
ABSOLUTE_MOBILE_UPDATE_FORMAT,
|
|
58
58
|
absoluteDeviceNativeRequirements,
|
|
@@ -66,7 +66,7 @@ import {
|
|
|
66
66
|
syncAbsoluteExpoWebAssets,
|
|
67
67
|
unsignedAbsoluteMobileUpdate,
|
|
68
68
|
writeAbsoluteExpoProject
|
|
69
|
-
} from "./index-
|
|
69
|
+
} from "./index-tame6e2c.js";
|
|
70
70
|
import {
|
|
71
71
|
normalizeAbsoluteIosDeviceIdentifier
|
|
72
72
|
} from "./index-j66p8hn5.js";
|
|
@@ -19318,6 +19318,18 @@ var verifyDurableModule = async (module) => {
|
|
|
19318
19318
|
throw new TypeError(`Durable mobile update storage verification failed for ${module.metadata.provider}. Check the bucket, endpoint, credentials, and read/write/delete permissions.`, { cause: error });
|
|
19319
19319
|
}
|
|
19320
19320
|
};
|
|
19321
|
+
var verifyHealthModule = (config, module) => {
|
|
19322
|
+
if (!config.updateServer?.health)
|
|
19323
|
+
return;
|
|
19324
|
+
if (typeof module.registry.inspectUpdateHealth !== "function" || typeof module.registry.issueUpdateHealthToken !== "function" || typeof module.registry.recordUpdateHealth !== "function")
|
|
19325
|
+
throw new TypeError("Mobile update fleet health is enabled but the registry is not provisioned for it. Run `absolute mobile update provision --force`.");
|
|
19326
|
+
};
|
|
19327
|
+
var verifyRolloutModule = (config, module) => {
|
|
19328
|
+
if (!config.updateServer?.rollout)
|
|
19329
|
+
return;
|
|
19330
|
+
if (typeof module.registry.advanceUpdateRollout !== "function" || typeof module.registry.cancelUpdateRollout !== "function" || typeof module.registry.inspectUpdateRollout !== "function" || typeof module.registry.pauseUpdateRollout !== "function" || typeof module.registry.reconcileUpdateRollout !== "function" || typeof module.registry.resumeUpdateRollout !== "function")
|
|
19331
|
+
throw new TypeError("Mobile update rollout orchestration is enabled but the registry is not provisioned for it. Run `absolute mobile update provision --force`.");
|
|
19332
|
+
};
|
|
19321
19333
|
var expoSigningOptions = (config) => {
|
|
19322
19334
|
if (!config.updates?.expoCodeSigning)
|
|
19323
19335
|
return;
|
|
@@ -19350,12 +19362,14 @@ var inspectAbsoluteMobileUpdateServer = async (config, projectRoot) => {
|
|
|
19350
19362
|
return;
|
|
19351
19363
|
const module = await loadAbsoluteMobileUpdateServerModule(projectRoot, config.updateServer?.registryModule);
|
|
19352
19364
|
await verifyDurableModule(module);
|
|
19365
|
+
verifyHealthModule(config, module);
|
|
19366
|
+
verifyRolloutModule(config, module);
|
|
19353
19367
|
if (config.engine === "expo")
|
|
19354
19368
|
expoSigningOptions(config);
|
|
19355
19369
|
return module.metadata;
|
|
19356
19370
|
};
|
|
19357
19371
|
var publicKeysSource = (publicKeys) => JSON.stringify(publicKeys, null, "\t");
|
|
19358
|
-
var
|
|
19372
|
+
var renderAbsoluteMobileUpdateRegistryBase = (options) => {
|
|
19359
19373
|
const metadata = `export const absoluteMobileUpdateServer = {
|
|
19360
19374
|
format: 1,
|
|
19361
19375
|
provider: '${options.storage}',
|
|
@@ -19422,6 +19436,28 @@ export default createMobileUpdateRegistry({
|
|
|
19422
19436
|
});
|
|
19423
19437
|
`;
|
|
19424
19438
|
};
|
|
19439
|
+
var renderAbsoluteMobileUpdateRegistry = (options) => {
|
|
19440
|
+
const source = renderAbsoluteMobileUpdateRegistryBase(options);
|
|
19441
|
+
let generated = "";
|
|
19442
|
+
if (options.health) {
|
|
19443
|
+
const secret = options.storage === "local" ? `process.env.${options.health.secretEnv} ?? 'absolutejs-local-health-secret-not-for-production'` : `required('${options.health.secretEnv}')`;
|
|
19444
|
+
generated += ` health: {
|
|
19445
|
+
autoPause: { failureRate: ${options.health.failureRate}, minimumReports: ${options.health.minimumReports} },
|
|
19446
|
+
secret: ${secret}
|
|
19447
|
+
},
|
|
19448
|
+
`;
|
|
19449
|
+
}
|
|
19450
|
+
if (options.rollout)
|
|
19451
|
+
generated += ` rollout: ${JSON.stringify(options.rollout, null, "\t").replaceAll(`
|
|
19452
|
+
`, `
|
|
19453
|
+
`)},
|
|
19454
|
+
`;
|
|
19455
|
+
if (!generated)
|
|
19456
|
+
return source;
|
|
19457
|
+
return source.replace(`export default createMobileUpdateRegistry({
|
|
19458
|
+
`, `export default createMobileUpdateRegistry({
|
|
19459
|
+
${generated}`);
|
|
19460
|
+
};
|
|
19425
19461
|
var writeAbsoluteMobileUpdateRegistry = async (options) => {
|
|
19426
19462
|
const path = projectPath(options.projectRoot, options.modulePath ?? DEFAULT_MOBILE_UPDATE_REGISTRY_MODULE);
|
|
19427
19463
|
if (!options.force) {
|
|
@@ -19433,6 +19469,8 @@ var writeAbsoluteMobileUpdateRegistry = async (options) => {
|
|
|
19433
19469
|
}
|
|
19434
19470
|
await mkdir5(dirname4(path), { recursive: true });
|
|
19435
19471
|
await Bun.write(path, renderAbsoluteMobileUpdateRegistry({
|
|
19472
|
+
...options.health ? { health: options.health } : {},
|
|
19473
|
+
...options.rollout ? { rollout: options.rollout } : {},
|
|
19436
19474
|
publicKeys: options.publicKeys,
|
|
19437
19475
|
storage: options.storage
|
|
19438
19476
|
}));
|
|
@@ -21994,6 +22032,66 @@ var lifecycleMethod = (publisher, name) => {
|
|
|
21994
22032
|
throw new TypeError(`Mobile update registry does not support ${name}. Re-run \`absolute mobile update provision --force\` after upgrading @absolutejs/deploy.`);
|
|
21995
22033
|
return method;
|
|
21996
22034
|
};
|
|
22035
|
+
var validateHealthReport = (report, options) => {
|
|
22036
|
+
if (!object3(report) || report.appId !== options.appId || report.channel !== options.channel || options.releaseId !== undefined && report.releaseId !== options.releaseId || typeof report.paused !== "boolean" || ![
|
|
22037
|
+
report.activated,
|
|
22038
|
+
report.downloaded,
|
|
22039
|
+
report.downloadFailed,
|
|
22040
|
+
report.failures,
|
|
22041
|
+
report.quarantined,
|
|
22042
|
+
report.reportedInstallations,
|
|
22043
|
+
report.rolledBack,
|
|
22044
|
+
report.terminalReports
|
|
22045
|
+
].every((value) => Number.isSafeInteger(value) && value >= 0) || !Number.isFinite(report.failureRate) || report.failureRate < 0 || report.failureRate > 1 || !Number.isFinite(report.rollout) || report.rollout < 0 || report.rollout > 1 || !object3(report.transfer) || ![
|
|
22046
|
+
report.transfer.avoidedBytes,
|
|
22047
|
+
report.transfer.downloadedBytes,
|
|
22048
|
+
report.transfer.durationMs,
|
|
22049
|
+
report.transfer.resumedBytes,
|
|
22050
|
+
report.transfer.reusedBytes,
|
|
22051
|
+
report.transfer.throughputBytesPerSecond
|
|
22052
|
+
].every((value) => Number.isFinite(value) && value >= 0))
|
|
22053
|
+
throw new TypeError("Mobile update registry returned an invalid health report.");
|
|
22054
|
+
return report;
|
|
22055
|
+
};
|
|
22056
|
+
var inspectAbsoluteMobileUpdateHealth = async (options) => {
|
|
22057
|
+
const report = await lifecycleMethod(options.publisher, "inspectUpdateHealth")({
|
|
22058
|
+
appId: options.appId,
|
|
22059
|
+
channel: options.channel,
|
|
22060
|
+
...options.releaseId ? { releaseId: options.releaseId } : {}
|
|
22061
|
+
});
|
|
22062
|
+
if (report === null)
|
|
22063
|
+
return null;
|
|
22064
|
+
return validateHealthReport(report, options);
|
|
22065
|
+
};
|
|
22066
|
+
var validateRolloutReport = (report, options) => {
|
|
22067
|
+
validateHealthReport(report, options);
|
|
22068
|
+
const validStage = (stage) => stage === undefined || object3(stage) && Number.isFinite(stage.rollout) && stage.rollout > 0 && stage.rollout <= 1 && Number.isSafeInteger(stage.minimumReports) && stage.minimumReports > 0 && Number.isSafeInteger(stage.observationMs) && stage.observationMs >= 0 && Number.isFinite(stage.maximumFailureRate) && stage.maximumFailureRate >= 0 && stage.maximumFailureRate < 1;
|
|
22069
|
+
if (typeof report.automatic !== "boolean" || !Number.isSafeInteger(report.currentStage) || report.currentStage < 0 || !Number.isFinite(Date.parse(report.enteredAt)) || !["active", "cancelled", "complete", "paused"].includes(report.status) || report.pausedBy !== undefined && report.pausedBy !== "fleet-health" && report.pausedBy !== "operator" || !validStage(report.nextStage) || report.paused !== (report.status === "paused" || report.status === "cancelled"))
|
|
22070
|
+
throw new TypeError("Mobile update registry returned an invalid rollout report.");
|
|
22071
|
+
return report;
|
|
22072
|
+
};
|
|
22073
|
+
var inspectAbsoluteMobileUpdateRollout = async (options) => {
|
|
22074
|
+
const report = await lifecycleMethod(options.publisher, "inspectUpdateRollout")({ appId: options.appId, channel: options.channel });
|
|
22075
|
+
return report === null ? null : validateRolloutReport(report, options);
|
|
22076
|
+
};
|
|
22077
|
+
var mutateAbsoluteMobileUpdateRollout = async (method, options) => validateRolloutReport(await lifecycleMethod(options.publisher, method)({
|
|
22078
|
+
appId: options.appId,
|
|
22079
|
+
channel: options.channel,
|
|
22080
|
+
...method === "advanceUpdateRollout" && options.rollout !== undefined ? { rollout: options.rollout } : {},
|
|
22081
|
+
...options.signal ? { signal: options.signal } : {}
|
|
22082
|
+
}), options);
|
|
22083
|
+
var advanceAbsoluteMobileUpdateRollout = (options) => mutateAbsoluteMobileUpdateRollout("advanceUpdateRollout", options);
|
|
22084
|
+
var cancelAbsoluteMobileUpdateRollout = (options) => mutateAbsoluteMobileUpdateRollout("cancelUpdateRollout", options);
|
|
22085
|
+
var pauseAbsoluteMobileUpdateRollout = (options) => mutateAbsoluteMobileUpdateRollout("pauseUpdateRollout", options);
|
|
22086
|
+
var reconcileAbsoluteMobileUpdateRollout = async (options) => {
|
|
22087
|
+
const report = await lifecycleMethod(options.publisher, "reconcileUpdateRollout")({
|
|
22088
|
+
appId: options.appId,
|
|
22089
|
+
channel: options.channel,
|
|
22090
|
+
...options.signal ? { signal: options.signal } : {}
|
|
22091
|
+
});
|
|
22092
|
+
return report === null ? null : validateRolloutReport(report, options);
|
|
22093
|
+
};
|
|
22094
|
+
var resumeAbsoluteMobileUpdateRollout = (options) => mutateAbsoluteMobileUpdateRollout("resumeUpdateRollout", options);
|
|
21997
22095
|
var validOptionalCounters = (values) => values.every((value) => value === undefined) || values.every((value) => Number.isSafeInteger(value) && (value ?? -1) >= 0);
|
|
21998
22096
|
var validateStorageIdentity = (result, appId) => {
|
|
21999
22097
|
if (!object3(result) || result.appId !== appId || !Array.isArray(result.releases) || ![
|
|
@@ -22780,6 +22878,7 @@ var mobileUpdatePublisher = async (args) => {
|
|
|
22780
22878
|
throw new TypeError("Mobile updates are not configured.");
|
|
22781
22879
|
const modulePath = valueAfter(args, "--registry") ?? mobile.updateServer.registryModule;
|
|
22782
22880
|
return {
|
|
22881
|
+
mobile,
|
|
22783
22882
|
projectRoot,
|
|
22784
22883
|
publisher: await loadAbsoluteMobileUpdatePublisher(projectRoot, modulePath)
|
|
22785
22884
|
};
|
|
@@ -22793,7 +22892,7 @@ var provisionMobileUpdate = async (args) => {
|
|
|
22793
22892
|
throw new TypeError("--storage must be local or s3.");
|
|
22794
22893
|
const modulePath = valueAfter(args, "--registry") ?? mobile.updateServer.registryModule;
|
|
22795
22894
|
const packages = [
|
|
22796
|
-
"@absolutejs/deploy@0.25.
|
|
22895
|
+
"@absolutejs/deploy@0.25.13",
|
|
22797
22896
|
"@absolutejs/blob@0.5.2",
|
|
22798
22897
|
...requestedStorage === "s3" ? [
|
|
22799
22898
|
"@aws-sdk/client-s3@3.1095.0",
|
|
@@ -22806,6 +22905,8 @@ var provisionMobileUpdate = async (args) => {
|
|
|
22806
22905
|
await installApprovedPackages(projectRoot, args, `Mobile update serving needs ${missing.map(packageNameFromSpec).join(", ")}. Install them now?`, missing);
|
|
22807
22906
|
const path = await writeAbsoluteMobileUpdateRegistry({
|
|
22808
22907
|
force: args.includes("--force"),
|
|
22908
|
+
...mobile.updateServer.health ? { health: mobile.updateServer.health } : {},
|
|
22909
|
+
...mobile.updateServer.rollout ? { rollout: mobile.updateServer.rollout } : {},
|
|
22809
22910
|
modulePath,
|
|
22810
22911
|
projectRoot,
|
|
22811
22912
|
publicKeys: mobile.updates.publicKeys,
|
|
@@ -22815,7 +22916,7 @@ var provisionMobileUpdate = async (args) => {
|
|
|
22815
22916
|
if (requestedStorage === "local")
|
|
22816
22917
|
console.log("Production release checks will require durable storage. Re-run with --storage s3 --force before deploying.");
|
|
22817
22918
|
else
|
|
22818
|
-
console.log(
|
|
22919
|
+
console.log(`Set ABSOLUTE_MOBILE_UPDATE_S3_BUCKET${mobile.updateServer.health ? `, ${mobile.updateServer.health.secretEnv},` : ""} and standard AWS credentials on the trusted server; endpoint and region overrides are optional.`);
|
|
22819
22920
|
const expoSigning = mobile.updates.expoCodeSigning;
|
|
22820
22921
|
if (expoSigning) {
|
|
22821
22922
|
const signingKey = mobile.updateServer.expoCodeSigningKeys[expoSigning.keyId];
|
|
@@ -22834,12 +22935,12 @@ var publishMobileUpdate = async (args) => {
|
|
|
22834
22935
|
});
|
|
22835
22936
|
if (!releaseDirectory)
|
|
22836
22937
|
throw new TypeError("mobile update publish requires a release directory.");
|
|
22837
|
-
const { projectRoot, publisher } = await mobileUpdatePublisher(args);
|
|
22938
|
+
const { mobile, projectRoot, publisher } = await mobileUpdatePublisher(args);
|
|
22838
22939
|
const result = await publishAbsoluteMobileUpdate({
|
|
22839
22940
|
projectRoot,
|
|
22840
22941
|
publisher,
|
|
22841
22942
|
releaseDirectory,
|
|
22842
|
-
rollout: updateRollout(args, 0.05)
|
|
22943
|
+
rollout: updateRollout(args, mobile.updateServer?.rollout?.stages[0]?.rollout ?? 0.05)
|
|
22843
22944
|
});
|
|
22844
22945
|
console.log(`${result.reused ? "Reused" : "Published"} mobile update ${result.releaseId} to ${result.channel} at ${Math.round(result.rollout * 100)}%.`);
|
|
22845
22946
|
if (result.storedBytes !== undefined && result.reusedBytes !== undefined && result.storedFiles !== undefined && result.reusedFiles !== undefined)
|
|
@@ -22938,6 +23039,92 @@ var inspectMobileUpdateStorage = async (args) => {
|
|
|
22938
23039
|
});
|
|
22939
23040
|
return report;
|
|
22940
23041
|
};
|
|
23042
|
+
var inspectMobileUpdateHealth = async (args) => {
|
|
23043
|
+
const { mobile } = await loadMobile(valueAfter(args, "--config"));
|
|
23044
|
+
if (!mobile.updates)
|
|
23045
|
+
throw new TypeError("mobile update status requires mobile.updates config.");
|
|
23046
|
+
const { publisher } = await mobileUpdatePublisher(args);
|
|
23047
|
+
const releaseId = valueAfter(args, "--release");
|
|
23048
|
+
const rolloutReport = mobile.updateServer?.rollout ? await inspectAbsoluteMobileUpdateRollout({
|
|
23049
|
+
appId: mobile.appId,
|
|
23050
|
+
channel: mobile.updates.channel,
|
|
23051
|
+
publisher
|
|
23052
|
+
}) : undefined;
|
|
23053
|
+
const report = mobile.updateServer?.rollout ? rolloutReport : await inspectAbsoluteMobileUpdateHealth({
|
|
23054
|
+
appId: mobile.appId,
|
|
23055
|
+
channel: mobile.updates.channel,
|
|
23056
|
+
publisher,
|
|
23057
|
+
...releaseId ? { releaseId } : {}
|
|
23058
|
+
});
|
|
23059
|
+
if (args.includes("--json"))
|
|
23060
|
+
console.log(JSON.stringify(report, null, 2));
|
|
23061
|
+
else if (!report)
|
|
23062
|
+
console.log(`No active mobile update exists on ${mobile.updates.channel}.`);
|
|
23063
|
+
else {
|
|
23064
|
+
console.log(`${report.releaseId} is ${rolloutReport?.status.toUpperCase() ?? (report.paused ? "PAUSED" : "ACTIVE")} at ${Math.round(report.rollout * 100)}%: ${report.terminalReports} terminal reports, ${report.failures} failures (${(report.failureRate * 100).toFixed(1)}%).`);
|
|
23065
|
+
if (rolloutReport)
|
|
23066
|
+
console.log(` Stage ${rolloutReport.currentStage + 1} entered ${rolloutReport.enteredAt}; advancement is ${rolloutReport.automatic ? "automatic" : "manual"}${rolloutReport.nextStage ? `, next ${Math.round(rolloutReport.nextStage.rollout * 100)}%` : ""}${rolloutReport.pausedBy ? `, paused by ${rolloutReport.pausedBy}` : ""}.`);
|
|
23067
|
+
console.log(` ${report.activated} activated, ${report.rolledBack} rolled back, ${report.quarantined} quarantined, ${report.downloaded} downloaded, ${report.downloadFailed} download failures.`);
|
|
23068
|
+
console.log(` Transfer: ${formatBytes(report.transfer.downloadedBytes)} downloaded, ${formatBytes(report.transfer.avoidedBytes)} avoided (${formatBytes(report.transfer.resumedBytes)} resumed, ${formatBytes(report.transfer.reusedBytes)} reused).`);
|
|
23069
|
+
}
|
|
23070
|
+
return report;
|
|
23071
|
+
};
|
|
23072
|
+
var MOBILE_UPDATE_ROLLOUT_ACTION_LABEL = {
|
|
23073
|
+
advance: "Advanced",
|
|
23074
|
+
cancel: "Cancelled",
|
|
23075
|
+
pause: "Paused",
|
|
23076
|
+
reconcile: "Reconciled",
|
|
23077
|
+
resume: "Resumed"
|
|
23078
|
+
};
|
|
23079
|
+
var isMobileUpdateRolloutAction = (value) => value !== undefined && Object.hasOwn(MOBILE_UPDATE_ROLLOUT_ACTION_LABEL, value);
|
|
23080
|
+
var controlMobileUpdateRollout = async (action, args) => {
|
|
23081
|
+
const startedAt = performance.now();
|
|
23082
|
+
const { mobile } = await loadMobile(valueAfter(args, "--config"));
|
|
23083
|
+
if (!mobile.updates || !mobile.updateServer?.rollout)
|
|
23084
|
+
throw new TypeError(`mobile update ${action} requires mobile.updates.server.rollout config.`);
|
|
23085
|
+
const { publisher } = await mobileUpdatePublisher(args);
|
|
23086
|
+
const options = {
|
|
23087
|
+
appId: mobile.appId,
|
|
23088
|
+
channel: mobile.updates.channel,
|
|
23089
|
+
publisher
|
|
23090
|
+
};
|
|
23091
|
+
const requestedRollout = valueAfter(args, "--rollout");
|
|
23092
|
+
let report;
|
|
23093
|
+
switch (action) {
|
|
23094
|
+
case "advance":
|
|
23095
|
+
report = await advanceAbsoluteMobileUpdateRollout({
|
|
23096
|
+
...options,
|
|
23097
|
+
...requestedRollout ? { rollout: updateRollout(args) } : {}
|
|
23098
|
+
});
|
|
23099
|
+
break;
|
|
23100
|
+
case "cancel":
|
|
23101
|
+
report = await cancelAbsoluteMobileUpdateRollout(options);
|
|
23102
|
+
break;
|
|
23103
|
+
case "pause":
|
|
23104
|
+
report = await pauseAbsoluteMobileUpdateRollout(options);
|
|
23105
|
+
break;
|
|
23106
|
+
case "reconcile":
|
|
23107
|
+
report = await reconcileAbsoluteMobileUpdateRollout(options);
|
|
23108
|
+
break;
|
|
23109
|
+
case "resume":
|
|
23110
|
+
report = await resumeAbsoluteMobileUpdateRollout(options);
|
|
23111
|
+
}
|
|
23112
|
+
if (args.includes("--json"))
|
|
23113
|
+
console.log(JSON.stringify(report, null, 2));
|
|
23114
|
+
else if (!report)
|
|
23115
|
+
console.log(`No active mobile update exists on ${mobile.updates.channel}.`);
|
|
23116
|
+
else
|
|
23117
|
+
console.log(`${MOBILE_UPDATE_ROLLOUT_ACTION_LABEL[action]} ${report.releaseId}: ${report.status.toUpperCase()} at ${Math.round(report.rollout * 100)}% (stage ${report.currentStage + 1}).`);
|
|
23118
|
+
sendTelemetryEvent("mobile:update-rollout", {
|
|
23119
|
+
action,
|
|
23120
|
+
durationMs: Math.round(performance.now() - startedAt),
|
|
23121
|
+
...report ? {
|
|
23122
|
+
automatic: report.automatic,
|
|
23123
|
+
status: report.status
|
|
23124
|
+
} : { status: "empty" }
|
|
23125
|
+
});
|
|
23126
|
+
return report;
|
|
23127
|
+
};
|
|
22941
23128
|
var collectMobileUpdates = async (args) => {
|
|
22942
23129
|
const startedAt = performance.now();
|
|
22943
23130
|
const { mobile } = await loadMobile(valueAfter(args, "--config"));
|
|
@@ -24316,6 +24503,14 @@ var runMobile = async (args) => {
|
|
|
24316
24503
|
await inspectMobileUpdateStorage(args.slice(2));
|
|
24317
24504
|
return;
|
|
24318
24505
|
}
|
|
24506
|
+
if (command === "update" && args[1] === "status") {
|
|
24507
|
+
await inspectMobileUpdateHealth(args.slice(2));
|
|
24508
|
+
return;
|
|
24509
|
+
}
|
|
24510
|
+
if (command === "update" && isMobileUpdateRolloutAction(args[1])) {
|
|
24511
|
+
await controlMobileUpdateRollout(args[1], args.slice(2));
|
|
24512
|
+
return;
|
|
24513
|
+
}
|
|
24319
24514
|
if (command === "update" && args[1] === "gc") {
|
|
24320
24515
|
await collectMobileUpdates(args.slice(2));
|
|
24321
24516
|
return;
|
|
@@ -24328,7 +24523,7 @@ var runMobile = async (args) => {
|
|
|
24328
24523
|
await publishIos(args.slice(2));
|
|
24329
24524
|
return;
|
|
24330
24525
|
}
|
|
24331
|
-
throw new TypeError("Usage: absolute mobile <pair mac <name> <user@host> [--port n] [--workspace path] | remotes [inspect [name] [--json] | clean [name] --yes | --json] | unpair mac <name> | init [--no-native] [--force] | sync [ios|android] | inspect [--json] [--require-bundle] | associations [--outdir dir] [--verify] | ci github [server-entry] [--publish] [--registry module] [--secret-env NAME] [--output path] [--force] [--json] | doctor [ios|android|release [ios|android]] [--remote name] [--json|--fix [--yes]] | build <android|ios> [server-entry] [--remote name] [--outdir dir] [--web-outdir dir] [--unsigned] | update provision [--storage local|s3] [--registry module] [--force] [--yes] | update signing generate --private-key path [--certificate path] [--public-key path] [--key-id id] [--common-name name] [--validity-years n] | update build [server-entry] --classification bug-fix|content|security --key-id id --signing-key path --within-submitted-purpose [--outdir dir] [--web-outdir dir] | update publish <release-directory> [--rollout fraction] [--registry module] | update promote --release id --rollout fraction [--registry module] | update rollback [--release id] [--registry module] | update storage [--retain count] [--min-age-days days] [--registry module] [--json] | update gc [--retain count] [--min-age-days days] [--grace-days days] [--apply] [--registry module] [--json] | publish android [server-entry] [--registry module] [--channel name] [--play-track track] [--play-status completed|draft|halted|in-progress] [--play-rollout fraction] [--play-name name] [--play-notes language=text] [--play-update-priority 0..5] [--play-hold-review] [--play-cancel-existing-review] [--outdir dir] [--web-outdir dir] [--unsigned] | publish ios [server-entry] [--remote name] [--registry module] [--channel name] [--testflight-group name-or-id] [--testflight-notes locale=text] [--testflight-submit-review] [--outdir dir] [--web-outdir dir] [--unsigned] | test android [--route path] [--wait-for-hmr] [--report [dir]] [--timeout ms] [--port n] [--serial id] [--artifacts dir] [--json]
|
|
24526
|
+
throw new TypeError("Usage: absolute mobile <pair mac <name> <user@host> [--port n] [--workspace path] | remotes [inspect [name] [--json] | clean [name] --yes | --json] | unpair mac <name> | init [--no-native] [--force] | sync [ios|android] | inspect [--json] [--require-bundle] | associations [--outdir dir] [--verify] | ci github [server-entry] [--publish] [--registry module] [--secret-env NAME] [--output path] [--force] [--json] | doctor [ios|android|release [ios|android]] [--remote name] [--json|--fix [--yes]] | build <android|ios> [server-entry] [--remote name] [--outdir dir] [--web-outdir dir] [--unsigned] | update provision [--storage local|s3] [--registry module] [--force] [--yes] | update signing generate --private-key path [--certificate path] [--public-key path] [--key-id id] [--common-name name] [--validity-years n] | update build [server-entry] --classification bug-fix|content|security --key-id id --signing-key path --within-submitted-purpose [--outdir dir] [--web-outdir dir] | update publish <release-directory> [--rollout fraction] [--registry module] | update promote --release id --rollout fraction [--registry module] | update rollback [--release id] [--registry module] | update status [--registry module] [--json] | update advance [--rollout fraction] [--registry module] [--json] | update pause|resume|cancel|reconcile [--registry module] [--json] | update storage [--retain count] [--min-age-days days] [--registry module] [--json] | update gc [--retain count] [--min-age-days days] [--grace-days days] [--apply] [--registry module] [--json] | publish android [server-entry] [--registry module] [--channel name] [--play-track track] [--play-status completed|draft|halted|in-progress] [--play-rollout fraction] [--play-name name] [--play-notes language=text] [--play-update-priority 0..5] [--play-hold-review] [--play-cancel-existing-review] [--outdir dir] [--web-outdir dir] [--unsigned] | publish ios [server-entry] [--remote name] [--registry module] [--channel name] [--testflight-group name-or-id] [--testflight-notes locale=text] [--testflight-submit-review] [--outdir dir] [--web-outdir dir] [--unsigned] | test android [--route path] [--wait-for-hmr] [--report [dir]] [--timeout ms] [--port n] [--serial id] [--artifacts dir] [--json]> [--config path]");
|
|
24332
24527
|
};
|
|
24333
24528
|
export {
|
|
24334
24529
|
runMobile
|