@absolutejs/absolute 0.20.0-beta.86 → 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 +350 -33
- package/dist/build.js.map +5 -5
- package/dist/cli/{compile-e9cn3xpx.js → compile-5hchbcbd.js} +2 -2
- package/dist/cli/{config-z2kf085h.js → config-vy04mqce.js} +1 -1
- package/dist/cli/{dev-3hweza3s.js → dev-6shm8qsn.js} +1 -1
- package/dist/cli/{index-9rk7v35t.js → index-39j0dhq7.js} +2 -2
- package/dist/cli/{index-x48brywr.js → index-jqdt7841.js} +1 -1
- package/dist/cli/{index-3tsmbyze.js → index-rd2hbttb.js} +45 -0
- package/dist/cli/index.js +5 -5
- package/dist/cli/{mobile-2p3z33t1.js → mobile-c94a5y9k.js} +141 -23
- package/dist/cli/{start-7t186mhg.js → start-7jg0csqy.js} +3 -3
- package/dist/index.js +350 -33
- package/dist/index.js.map +5 -5
- package/dist/mobile/index.js +396 -41
- package/dist/mobile/index.js.map +6 -6
- package/dist/mobile/remoteMacAgentEntry.js +167 -167
- package/dist/src/mobile/config.d.ts +9 -0
- package/dist/src/mobile/updatePublisher.d.ts +67 -1
- package/dist/src/mobile/updateServer.d.ts +18 -0
- package/dist/types/build.d.ts +16 -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,7 +35,7 @@ import {
|
|
|
35
35
|
import"./index-w5vswatm.js";
|
|
36
36
|
import {
|
|
37
37
|
normalizeAbsoluteMobileConfig
|
|
38
|
-
} from "./index-
|
|
38
|
+
} from "./index-rd2hbttb.js";
|
|
39
39
|
import"./index-tame6e2c.js";
|
|
40
40
|
import {
|
|
41
41
|
ABSOLUTE_NATIVE_AUTH_CLIENTS_ENV,
|
|
@@ -1281,7 +1281,7 @@ var loadAbsoluteMobileDevModules = async () => {
|
|
|
1281
1281
|
remoteMacProtocol,
|
|
1282
1282
|
iosNativeWatcher
|
|
1283
1283
|
] = await Promise.all([
|
|
1284
|
-
import("./config-
|
|
1284
|
+
import("./config-vy04mqce.js"),
|
|
1285
1285
|
import("./expoProject-dac8fqhq.js"),
|
|
1286
1286
|
import("./expoDevController-n19kb5fr.js"),
|
|
1287
1287
|
import("./nativeAuth-zx4tsb1f.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";
|
|
@@ -13,6 +13,14 @@ var ENVIRONMENT_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/u;
|
|
|
13
13
|
var DEFAULT_UPDATE_BOOT_TIMEOUT_MS = 20000;
|
|
14
14
|
var DEFAULT_UPDATE_HEALTH_FAILURE_RATE = 0.2;
|
|
15
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
|
+
];
|
|
16
24
|
var MINIMUM_UPDATE_BOOT_TIMEOUT_MS = 5000;
|
|
17
25
|
var MAXIMUM_UPDATE_BOOT_TIMEOUT_MS = 120000;
|
|
18
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])?))*$/;
|
|
@@ -246,6 +254,42 @@ var normalizeUpdateServer = (config, productionOrigin, projectRoot, updates) =>
|
|
|
246
254
|
throw new TypeError("mobile.updates.server.health.secretEnv must be a valid environment variable name.");
|
|
247
255
|
health = { failureRate, minimumReports, secretEnv };
|
|
248
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
|
+
}
|
|
249
293
|
if (autoMount) {
|
|
250
294
|
const manifest = new URL(updates.manifestUrl);
|
|
251
295
|
if (manifest.origin !== productionOrigin)
|
|
@@ -282,6 +326,7 @@ var normalizeUpdateServer = (config, productionOrigin, projectRoot, updates) =>
|
|
|
282
326
|
autoMount,
|
|
283
327
|
expoCodeSigningKeys,
|
|
284
328
|
...health ? { health } : {},
|
|
329
|
+
...rollout ? { rollout } : {},
|
|
285
330
|
registryModule
|
|
286
331
|
};
|
|
287
332
|
};
|
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,
|
|
@@ -19324,6 +19324,12 @@ var verifyHealthModule = (config, module) => {
|
|
|
19324
19324
|
if (typeof module.registry.inspectUpdateHealth !== "function" || typeof module.registry.issueUpdateHealthToken !== "function" || typeof module.registry.recordUpdateHealth !== "function")
|
|
19325
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
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
|
+
};
|
|
19327
19333
|
var expoSigningOptions = (config) => {
|
|
19328
19334
|
if (!config.updates?.expoCodeSigning)
|
|
19329
19335
|
return;
|
|
@@ -19357,6 +19363,7 @@ var inspectAbsoluteMobileUpdateServer = async (config, projectRoot) => {
|
|
|
19357
19363
|
const module = await loadAbsoluteMobileUpdateServerModule(projectRoot, config.updateServer?.registryModule);
|
|
19358
19364
|
await verifyDurableModule(module);
|
|
19359
19365
|
verifyHealthModule(config, module);
|
|
19366
|
+
verifyRolloutModule(config, module);
|
|
19360
19367
|
if (config.engine === "expo")
|
|
19361
19368
|
expoSigningOptions(config);
|
|
19362
19369
|
return module.metadata;
|
|
@@ -19431,17 +19438,25 @@ export default createMobileUpdateRegistry({
|
|
|
19431
19438
|
};
|
|
19432
19439
|
var renderAbsoluteMobileUpdateRegistry = (options) => {
|
|
19433
19440
|
const source = renderAbsoluteMobileUpdateRegistryBase(options);
|
|
19434
|
-
|
|
19435
|
-
|
|
19436
|
-
|
|
19437
|
-
|
|
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: {
|
|
19438
19445
|
autoPause: { failureRate: ${options.health.failureRate}, minimumReports: ${options.health.minimumReports} },
|
|
19439
19446
|
secret: ${secret}
|
|
19440
19447
|
},
|
|
19441
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;
|
|
19442
19457
|
return source.replace(`export default createMobileUpdateRegistry({
|
|
19443
19458
|
`, `export default createMobileUpdateRegistry({
|
|
19444
|
-
${
|
|
19459
|
+
${generated}`);
|
|
19445
19460
|
};
|
|
19446
19461
|
var writeAbsoluteMobileUpdateRegistry = async (options) => {
|
|
19447
19462
|
const path = projectPath(options.projectRoot, options.modulePath ?? DEFAULT_MOBILE_UPDATE_REGISTRY_MODULE);
|
|
@@ -19455,6 +19470,7 @@ var writeAbsoluteMobileUpdateRegistry = async (options) => {
|
|
|
19455
19470
|
await mkdir5(dirname4(path), { recursive: true });
|
|
19456
19471
|
await Bun.write(path, renderAbsoluteMobileUpdateRegistry({
|
|
19457
19472
|
...options.health ? { health: options.health } : {},
|
|
19473
|
+
...options.rollout ? { rollout: options.rollout } : {},
|
|
19458
19474
|
publicKeys: options.publicKeys,
|
|
19459
19475
|
storage: options.storage
|
|
19460
19476
|
}));
|
|
@@ -22016,14 +22032,7 @@ var lifecycleMethod = (publisher, name) => {
|
|
|
22016
22032
|
throw new TypeError(`Mobile update registry does not support ${name}. Re-run \`absolute mobile update provision --force\` after upgrading @absolutejs/deploy.`);
|
|
22017
22033
|
return method;
|
|
22018
22034
|
};
|
|
22019
|
-
var
|
|
22020
|
-
const report = await lifecycleMethod(options.publisher, "inspectUpdateHealth")({
|
|
22021
|
-
appId: options.appId,
|
|
22022
|
-
channel: options.channel,
|
|
22023
|
-
...options.releaseId ? { releaseId: options.releaseId } : {}
|
|
22024
|
-
});
|
|
22025
|
-
if (report === null)
|
|
22026
|
-
return null;
|
|
22035
|
+
var validateHealthReport = (report, options) => {
|
|
22027
22036
|
if (!object3(report) || report.appId !== options.appId || report.channel !== options.channel || options.releaseId !== undefined && report.releaseId !== options.releaseId || typeof report.paused !== "boolean" || ![
|
|
22028
22037
|
report.activated,
|
|
22029
22038
|
report.downloaded,
|
|
@@ -22044,6 +22053,45 @@ var inspectAbsoluteMobileUpdateHealth = async (options) => {
|
|
|
22044
22053
|
throw new TypeError("Mobile update registry returned an invalid health report.");
|
|
22045
22054
|
return report;
|
|
22046
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);
|
|
22047
22095
|
var validOptionalCounters = (values) => values.every((value) => value === undefined) || values.every((value) => Number.isSafeInteger(value) && (value ?? -1) >= 0);
|
|
22048
22096
|
var validateStorageIdentity = (result, appId) => {
|
|
22049
22097
|
if (!object3(result) || result.appId !== appId || !Array.isArray(result.releases) || ![
|
|
@@ -22830,6 +22878,7 @@ var mobileUpdatePublisher = async (args) => {
|
|
|
22830
22878
|
throw new TypeError("Mobile updates are not configured.");
|
|
22831
22879
|
const modulePath = valueAfter(args, "--registry") ?? mobile.updateServer.registryModule;
|
|
22832
22880
|
return {
|
|
22881
|
+
mobile,
|
|
22833
22882
|
projectRoot,
|
|
22834
22883
|
publisher: await loadAbsoluteMobileUpdatePublisher(projectRoot, modulePath)
|
|
22835
22884
|
};
|
|
@@ -22843,7 +22892,7 @@ var provisionMobileUpdate = async (args) => {
|
|
|
22843
22892
|
throw new TypeError("--storage must be local or s3.");
|
|
22844
22893
|
const modulePath = valueAfter(args, "--registry") ?? mobile.updateServer.registryModule;
|
|
22845
22894
|
const packages = [
|
|
22846
|
-
"@absolutejs/deploy@0.25.
|
|
22895
|
+
"@absolutejs/deploy@0.25.13",
|
|
22847
22896
|
"@absolutejs/blob@0.5.2",
|
|
22848
22897
|
...requestedStorage === "s3" ? [
|
|
22849
22898
|
"@aws-sdk/client-s3@3.1095.0",
|
|
@@ -22857,6 +22906,7 @@ var provisionMobileUpdate = async (args) => {
|
|
|
22857
22906
|
const path = await writeAbsoluteMobileUpdateRegistry({
|
|
22858
22907
|
force: args.includes("--force"),
|
|
22859
22908
|
...mobile.updateServer.health ? { health: mobile.updateServer.health } : {},
|
|
22909
|
+
...mobile.updateServer.rollout ? { rollout: mobile.updateServer.rollout } : {},
|
|
22860
22910
|
modulePath,
|
|
22861
22911
|
projectRoot,
|
|
22862
22912
|
publicKeys: mobile.updates.publicKeys,
|
|
@@ -22885,12 +22935,12 @@ var publishMobileUpdate = async (args) => {
|
|
|
22885
22935
|
});
|
|
22886
22936
|
if (!releaseDirectory)
|
|
22887
22937
|
throw new TypeError("mobile update publish requires a release directory.");
|
|
22888
|
-
const { projectRoot, publisher } = await mobileUpdatePublisher(args);
|
|
22938
|
+
const { mobile, projectRoot, publisher } = await mobileUpdatePublisher(args);
|
|
22889
22939
|
const result = await publishAbsoluteMobileUpdate({
|
|
22890
22940
|
projectRoot,
|
|
22891
22941
|
publisher,
|
|
22892
22942
|
releaseDirectory,
|
|
22893
|
-
rollout: updateRollout(args, 0.05)
|
|
22943
|
+
rollout: updateRollout(args, mobile.updateServer?.rollout?.stages[0]?.rollout ?? 0.05)
|
|
22894
22944
|
});
|
|
22895
22945
|
console.log(`${result.reused ? "Reused" : "Published"} mobile update ${result.releaseId} to ${result.channel} at ${Math.round(result.rollout * 100)}%.`);
|
|
22896
22946
|
if (result.storedBytes !== undefined && result.reusedBytes !== undefined && result.storedFiles !== undefined && result.reusedFiles !== undefined)
|
|
@@ -22994,23 +23044,87 @@ var inspectMobileUpdateHealth = async (args) => {
|
|
|
22994
23044
|
if (!mobile.updates)
|
|
22995
23045
|
throw new TypeError("mobile update status requires mobile.updates config.");
|
|
22996
23046
|
const { publisher } = await mobileUpdatePublisher(args);
|
|
22997
|
-
const
|
|
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({
|
|
22998
23054
|
appId: mobile.appId,
|
|
22999
23055
|
channel: mobile.updates.channel,
|
|
23000
23056
|
publisher,
|
|
23001
|
-
...
|
|
23057
|
+
...releaseId ? { releaseId } : {}
|
|
23002
23058
|
});
|
|
23003
23059
|
if (args.includes("--json"))
|
|
23004
23060
|
console.log(JSON.stringify(report, null, 2));
|
|
23005
23061
|
else if (!report)
|
|
23006
23062
|
console.log(`No active mobile update exists on ${mobile.updates.channel}.`);
|
|
23007
23063
|
else {
|
|
23008
|
-
console.log(`${report.releaseId} is ${report.paused ? "PAUSED" : "
|
|
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}` : ""}.`);
|
|
23009
23067
|
console.log(` ${report.activated} activated, ${report.rolledBack} rolled back, ${report.quarantined} quarantined, ${report.downloaded} downloaded, ${report.downloadFailed} download failures.`);
|
|
23010
23068
|
console.log(` Transfer: ${formatBytes(report.transfer.downloadedBytes)} downloaded, ${formatBytes(report.transfer.avoidedBytes)} avoided (${formatBytes(report.transfer.resumedBytes)} resumed, ${formatBytes(report.transfer.reusedBytes)} reused).`);
|
|
23011
23069
|
}
|
|
23012
23070
|
return report;
|
|
23013
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
|
+
};
|
|
23014
23128
|
var collectMobileUpdates = async (args) => {
|
|
23015
23129
|
const startedAt = performance.now();
|
|
23016
23130
|
const { mobile } = await loadMobile(valueAfter(args, "--config"));
|
|
@@ -24393,6 +24507,10 @@ var runMobile = async (args) => {
|
|
|
24393
24507
|
await inspectMobileUpdateHealth(args.slice(2));
|
|
24394
24508
|
return;
|
|
24395
24509
|
}
|
|
24510
|
+
if (command === "update" && isMobileUpdateRolloutAction(args[1])) {
|
|
24511
|
+
await controlMobileUpdateRollout(args[1], args.slice(2));
|
|
24512
|
+
return;
|
|
24513
|
+
}
|
|
24396
24514
|
if (command === "update" && args[1] === "gc") {
|
|
24397
24515
|
await collectMobileUpdates(args.slice(2));
|
|
24398
24516
|
return;
|
|
@@ -24405,7 +24523,7 @@ var runMobile = async (args) => {
|
|
|
24405
24523
|
await publishIos(args.slice(2));
|
|
24406
24524
|
return;
|
|
24407
24525
|
}
|
|
24408
|
-
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 [--
|
|
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]");
|
|
24409
24527
|
};
|
|
24410
24528
|
export {
|
|
24411
24529
|
runMobile
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
start
|
|
4
|
-
} from "./index-
|
|
5
|
-
import"./index-
|
|
4
|
+
} from "./index-39j0dhq7.js";
|
|
5
|
+
import"./index-jqdt7841.js";
|
|
6
6
|
import"./index-bzs19w3r.js";
|
|
7
7
|
import"./index-s2tazax7.js";
|
|
8
8
|
import"./index-fc9vxw56.js";
|
|
@@ -10,7 +10,7 @@ import"./index-r8x3839e.js";
|
|
|
10
10
|
import"./index-06cmrcdq.js";
|
|
11
11
|
import"./index-9kwmb3c0.js";
|
|
12
12
|
import"./index-w5vswatm.js";
|
|
13
|
-
import"./index-
|
|
13
|
+
import"./index-rd2hbttb.js";
|
|
14
14
|
import"./index-tame6e2c.js";
|
|
15
15
|
import"./index-ar4gz15x.js";
|
|
16
16
|
import"./index-t84wxk1p.js";
|