@absolutejs/absolute 0.20.0-beta.111 → 0.20.0-beta.113
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/CHANGELOG.md +14 -0
- package/changelog.json +46 -0
- package/dist/angular/components/core/streamingSlotRegistrar.js +1 -1
- package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
- package/dist/cli/index.js +1 -1
- package/dist/cli/{mobile-k7gpwfs8.js → mobile-v11nwcj9.js} +688 -137
- package/dist/mobile/index.js +516 -203
- package/dist/mobile/index.js.map +7 -6
- package/dist/src/mobile/ciPromotionAudit.d.ts +26 -2
- package/dist/src/mobile/ciPromotionLedger.d.ts +49 -0
- package/dist/src/mobile/ciWorkflow.d.ts +1 -1
- package/dist/src/mobile/index.d.ts +1 -0
- package/package.json +1 -1
package/dist/mobile/index.js
CHANGED
|
@@ -19401,7 +19401,7 @@ var init_compatibilityDispatcher = __esm(() => {
|
|
|
19401
19401
|
// src/cli/scripts/telemetry.ts
|
|
19402
19402
|
import { existsSync as existsSync5, mkdirSync, readFileSync as readFileSync6, writeFileSync } from "fs";
|
|
19403
19403
|
import { homedir as homedir4 } from "os";
|
|
19404
|
-
import { join as
|
|
19404
|
+
import { join as join26 } from "path";
|
|
19405
19405
|
var configDir, configPath, getTelemetryConfig = () => {
|
|
19406
19406
|
try {
|
|
19407
19407
|
if (!existsSync5(configPath))
|
|
@@ -19414,14 +19414,14 @@ var configDir, configPath, getTelemetryConfig = () => {
|
|
|
19414
19414
|
}
|
|
19415
19415
|
};
|
|
19416
19416
|
var init_telemetry = __esm(() => {
|
|
19417
|
-
configDir =
|
|
19418
|
-
configPath =
|
|
19417
|
+
configDir = join26(homedir4(), ".absolutejs");
|
|
19418
|
+
configPath = join26(configDir, "telemetry.json");
|
|
19419
19419
|
});
|
|
19420
19420
|
|
|
19421
19421
|
// src/cli/telemetryEvent.ts
|
|
19422
19422
|
import { existsSync as existsSync6, readFileSync as readFileSync7 } from "fs";
|
|
19423
19423
|
import { arch, platform as platform3 } from "os";
|
|
19424
|
-
import { dirname as
|
|
19424
|
+
import { dirname as dirname19, join as join27, parse } from "path";
|
|
19425
19425
|
var checkCandidate = (candidate) => {
|
|
19426
19426
|
if (!existsSync6(candidate)) {
|
|
19427
19427
|
return null;
|
|
@@ -19441,12 +19441,12 @@ var checkCandidate = (candidate) => {
|
|
|
19441
19441
|
}, findPackageVersion = () => {
|
|
19442
19442
|
let { dir } = import.meta;
|
|
19443
19443
|
while (dir !== parse(dir).root) {
|
|
19444
|
-
const candidate =
|
|
19444
|
+
const candidate = join27(dir, "package.json");
|
|
19445
19445
|
const version = checkCandidate(candidate);
|
|
19446
19446
|
if (version) {
|
|
19447
19447
|
return version;
|
|
19448
19448
|
}
|
|
19449
|
-
dir =
|
|
19449
|
+
dir = dirname19(dir);
|
|
19450
19450
|
}
|
|
19451
19451
|
return "unknown";
|
|
19452
19452
|
}, sendTelemetryEvent = (event, payload) => {
|
|
@@ -19487,7 +19487,7 @@ __export(exports_mobilePreview, {
|
|
|
19487
19487
|
createAbsoluteMobilePreviewPlugin: () => createAbsoluteMobilePreviewPlugin
|
|
19488
19488
|
});
|
|
19489
19489
|
import { Elysia as Elysia3 } from "elysia";
|
|
19490
|
-
var ABSOLUTE_MOBILE_PREVIEW_PATH = "/__absolute/mobile-preview", escapeHtml2 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """),
|
|
19490
|
+
var ABSOLUTE_MOBILE_PREVIEW_PATH = "/__absolute/mobile-preview", escapeHtml2 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """), isRecord15 = (value) => typeof value === "object" && value !== null, normalizeEntry2 = (entry) => {
|
|
19491
19491
|
const parsed = new URL(entry ?? "/", "https://absolute.invalid");
|
|
19492
19492
|
return `${parsed.pathname}${parsed.search}${parsed.hash}`;
|
|
19493
19493
|
}, absoluteMobilePreviewDocument = (mobile) => {
|
|
@@ -19535,7 +19535,7 @@ var ABSOLUTE_MOBILE_PREVIEW_PATH = "/__absolute/mobile-preview", escapeHtml2 = (
|
|
|
19535
19535
|
"X-Robots-Tag": "noindex, nofollow"
|
|
19536
19536
|
}
|
|
19537
19537
|
})).post("/__absolute/mobile-preview-telemetry", ({ body, status }) => {
|
|
19538
|
-
const value =
|
|
19538
|
+
const value = isRecord15(body) ? body : undefined;
|
|
19539
19539
|
const durationMs = value?.durationMs;
|
|
19540
19540
|
const platform4 = value?.platform;
|
|
19541
19541
|
if (typeof durationMs !== "number" || !Number.isFinite(durationMs) || durationMs < 0 || durationMs > 300000 || platform4 !== "android" && platform4 !== "ios") {
|
|
@@ -20086,13 +20086,13 @@ import {
|
|
|
20086
20086
|
createHmac,
|
|
20087
20087
|
createPrivateKey,
|
|
20088
20088
|
createPublicKey as createPublicKey2,
|
|
20089
|
-
randomUUID as
|
|
20089
|
+
randomUUID as randomUUID6,
|
|
20090
20090
|
sign as sign2,
|
|
20091
20091
|
timingSafeEqual,
|
|
20092
20092
|
verify as verify2,
|
|
20093
20093
|
X509Certificate as X509Certificate3
|
|
20094
20094
|
} from "crypto";
|
|
20095
|
-
import { readFile as
|
|
20095
|
+
import { readFile as readFile31, stat as stat9 } from "fs/promises";
|
|
20096
20096
|
import path from "path";
|
|
20097
20097
|
var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updates", MAX_FILE_BYTES, MAX_TOTAL_BYTES, DAY_MS, DEFAULT_MIN_AGE_MS, DEFAULT_GRACE_PERIOD_MS, DEFAULT_RETAIN_RECENT = 5, HASH, RELEASE, APP_ID, NAME, EXPO_DESCRIPTOR = "_absolute/expo-update.json", EXPO_CODE_SIGNING_ALGORITHM = "rsa-v1_5-sha256", HEALTH_TOKEN_VERSION = 1, HEALTH_KINDS, FAILURE_HEALTH_KINDS, MobileUpdateRegistryError, object6 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), text2 = (value, field2) => {
|
|
20098
20098
|
if (typeof value !== "string" || value.length === 0)
|
|
@@ -20446,7 +20446,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
20446
20446
|
...input,
|
|
20447
20447
|
format: MOBILE_UPDATE_REGISTRY_FORMAT,
|
|
20448
20448
|
promotedAt,
|
|
20449
|
-
promotionId: digest(new TextEncoder().encode(`${input.appId}\x00${input.channel}\x00${input.releaseId ?? "embedded"}\x00${promotedAt}\x00${
|
|
20449
|
+
promotionId: digest(new TextEncoder().encode(`${input.appId}\x00${input.channel}\x00${input.releaseId ?? "embedded"}\x00${promotedAt}\x00${randomUUID6()}`))
|
|
20450
20450
|
};
|
|
20451
20451
|
await beforeWrite?.(value);
|
|
20452
20452
|
const bytes = json(value);
|
|
@@ -20548,7 +20548,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
20548
20548
|
if (!releaseId)
|
|
20549
20549
|
throw new MobileUpdateRegistryError("Mobile update channel does not have an active release");
|
|
20550
20550
|
const createdAt = clock().toISOString();
|
|
20551
|
-
const id =
|
|
20551
|
+
const id = randomUUID6();
|
|
20552
20552
|
const event = {
|
|
20553
20553
|
action,
|
|
20554
20554
|
createdAt,
|
|
@@ -21125,7 +21125,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
21125
21125
|
verifyManifestSignature(manifest, options.publicKeys);
|
|
21126
21126
|
await assertNotMarked(manifest.appId, manifest.releaseId);
|
|
21127
21127
|
const localRoot = path.resolve(input.releaseDirectory);
|
|
21128
|
-
const localManifest = parseMobileUpdateManifest(JSON.parse(await
|
|
21128
|
+
const localManifest = parseMobileUpdateManifest(JSON.parse(await readFile31(path.join(localRoot, "update.json"), "utf8")));
|
|
21129
21129
|
if (JSON.stringify(localManifest) !== JSON.stringify(manifest))
|
|
21130
21130
|
throw new MobileUpdateRegistryError("Local mobile update manifest changed");
|
|
21131
21131
|
const existing = await readManifest(manifest.appId, manifest.releaseId);
|
|
@@ -21411,8 +21411,8 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
21411
21411
|
});
|
|
21412
21412
|
}
|
|
21413
21413
|
const pathname = new URL(request.url).pathname.replace(/^\/+/, "");
|
|
21414
|
-
const
|
|
21415
|
-
if (request.method === "POST" &&
|
|
21414
|
+
const relative24 = pathname.startsWith(`${route}/`) ? pathname.slice(route.length + 1) : "";
|
|
21415
|
+
if (request.method === "POST" && relative24 === "health") {
|
|
21416
21416
|
if (!options.registry.recordUpdateHealth)
|
|
21417
21417
|
return new Response(null, { status: 404 });
|
|
21418
21418
|
const appId = request.headers.get("x-absolute-mobile-app");
|
|
@@ -21455,7 +21455,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
21455
21455
|
}
|
|
21456
21456
|
if (request.method !== "GET")
|
|
21457
21457
|
return new Response(null, { status: 405 });
|
|
21458
|
-
if (
|
|
21458
|
+
if (relative24 === "update.json") {
|
|
21459
21459
|
const expoProtocolVersion = request.headers.get("expo-protocol-version");
|
|
21460
21460
|
const expoProtocol = expoProtocolVersion !== null;
|
|
21461
21461
|
if (expoProtocol && expoProtocolVersion !== "1")
|
|
@@ -21573,7 +21573,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
21573
21573
|
}
|
|
21574
21574
|
});
|
|
21575
21575
|
}
|
|
21576
|
-
const match = /^(amu_[a-f0-9]{64})\/files\/(.+)$/.exec(
|
|
21576
|
+
const match = /^(amu_[a-f0-9]{64})\/files\/(.+)$/.exec(relative24);
|
|
21577
21577
|
if (!match?.[1] || !match[2])
|
|
21578
21578
|
return new Response(null, { status: 404 });
|
|
21579
21579
|
const file = await options.registry.readUpdateFile({
|
|
@@ -21666,15 +21666,15 @@ import {
|
|
|
21666
21666
|
createPublicKey as createPublicKey3,
|
|
21667
21667
|
X509Certificate as X509Certificate4
|
|
21668
21668
|
} from "crypto";
|
|
21669
|
-
import { access as
|
|
21670
|
-
import { dirname as
|
|
21669
|
+
import { access as access23, mkdir as mkdir25 } from "fs/promises";
|
|
21670
|
+
import { dirname as dirname25, isAbsolute as isAbsolute15, relative as relative24, resolve as resolve26, sep as sep17 } from "path";
|
|
21671
21671
|
import { pathToFileURL as pathToFileURL5 } from "url";
|
|
21672
21672
|
import { Elysia as Elysia4 } from "elysia";
|
|
21673
21673
|
var ABSOLUTE_MOBILE_UPDATE_SERVER_FORMAT = 1, DEFAULT_MOBILE_UPDATE_REGISTRY_MODULE = "mobile.update.ts", object7 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), projectPath4 = (projectRoot, requested) => {
|
|
21674
|
-
const root =
|
|
21675
|
-
const path2 =
|
|
21676
|
-
const projectRelative =
|
|
21677
|
-
if (projectRelative === ".." || projectRelative.startsWith(`..${
|
|
21674
|
+
const root = resolve26(projectRoot);
|
|
21675
|
+
const path2 = resolve26(root, requested);
|
|
21676
|
+
const projectRelative = relative24(root, path2);
|
|
21677
|
+
if (projectRelative === ".." || projectRelative.startsWith(`..${sep17}`) || isAbsolute15(projectRelative))
|
|
21678
21678
|
throw new TypeError("mobile.updates.server.registry must remain inside the project.");
|
|
21679
21679
|
return path2;
|
|
21680
21680
|
}, isRegistry4 = (value) => object7(value) && [
|
|
@@ -21697,7 +21697,7 @@ var ABSOLUTE_MOBILE_UPDATE_SERVER_FORMAT = 1, DEFAULT_MOBILE_UPDATE_REGISTRY_MOD
|
|
|
21697
21697
|
return metadata;
|
|
21698
21698
|
}, loadAbsoluteMobileUpdateServerModule = async (projectRoot, requestedModulePath = DEFAULT_MOBILE_UPDATE_REGISTRY_MODULE) => {
|
|
21699
21699
|
const modulePath = projectPath4(projectRoot, requestedModulePath);
|
|
21700
|
-
await
|
|
21700
|
+
await access23(modulePath).catch(() => {
|
|
21701
21701
|
throw new TypeError(`Mobile update server registry does not exist: ${modulePath}. Run \`absolute mobile update provision\`.`);
|
|
21702
21702
|
});
|
|
21703
21703
|
const loaded = await import(pathToFileURL5(modulePath).href);
|
|
@@ -21886,13 +21886,13 @@ ${generated}`);
|
|
|
21886
21886
|
}, writeAbsoluteMobileUpdateRegistry = async (options) => {
|
|
21887
21887
|
const path2 = projectPath4(options.projectRoot, options.modulePath ?? DEFAULT_MOBILE_UPDATE_REGISTRY_MODULE);
|
|
21888
21888
|
if (!options.force) {
|
|
21889
|
-
await
|
|
21889
|
+
await access23(path2).then(() => {
|
|
21890
21890
|
throw new TypeError(`Mobile update registry already exists: ${path2}. Pass --force to replace it.`);
|
|
21891
21891
|
}, () => {
|
|
21892
21892
|
return;
|
|
21893
21893
|
});
|
|
21894
21894
|
}
|
|
21895
|
-
await
|
|
21895
|
+
await mkdir25(dirname25(path2), { recursive: true });
|
|
21896
21896
|
await Bun.write(path2, renderAbsoluteMobileUpdateRegistry({
|
|
21897
21897
|
...options.health ? { health: options.health } : {},
|
|
21898
21898
|
...options.rollout ? { rollout: options.rollout } : {},
|
|
@@ -33560,12 +33560,15 @@ var writeAbsoluteMobileReleaseCertification = async (projectRoot, certification,
|
|
|
33560
33560
|
|
|
33561
33561
|
// src/mobile/ciPromotionAudit.ts
|
|
33562
33562
|
var ABSOLUTE_MOBILE_CI_PROMOTION_AUDIT_FORMAT = 1;
|
|
33563
|
-
var ABSOLUTE_MOBILE_CI_PROMOTION_CONTEXT_FORMAT =
|
|
33563
|
+
var ABSOLUTE_MOBILE_CI_PROMOTION_CONTEXT_FORMAT = 2;
|
|
33564
33564
|
var MAX_GITHUB_OUTPUT_BYTES = 1048576;
|
|
33565
33565
|
var MAX_AUDIT_JSON_BYTES = 1048576;
|
|
33566
33566
|
var MAX_SEARCH_FILES = 20000;
|
|
33567
33567
|
var RUN_ID_PATTERN = /^[1-9][0-9]*$/u;
|
|
33568
33568
|
var REPOSITORY_PATTERN2 = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/u;
|
|
33569
|
+
var DISPATCH_ID_PATTERN = /^amp_[a-f0-9]{32}$/u;
|
|
33570
|
+
var PROMOTION_DISCOVERY_ATTEMPTS = 60;
|
|
33571
|
+
var PROMOTION_DISCOVERY_INTERVAL_MS = 1000;
|
|
33569
33572
|
var isRecord13 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
33570
33573
|
var requiredString = (value, name) => {
|
|
33571
33574
|
if (typeof value !== "string" || value.trim() === "")
|
|
@@ -33582,6 +33585,26 @@ var runId = (value, name) => {
|
|
|
33582
33585
|
throw new TypeError(`${name} is invalid.`);
|
|
33583
33586
|
return value;
|
|
33584
33587
|
};
|
|
33588
|
+
var dispatchId = (value) => {
|
|
33589
|
+
if (!DISPATCH_ID_PATTERN.test(value))
|
|
33590
|
+
throw new TypeError("Mobile promotion dispatch ID is invalid.");
|
|
33591
|
+
return value;
|
|
33592
|
+
};
|
|
33593
|
+
var promotionRunTitle = (value) => `AbsoluteJS mobile promotion [${dispatchId(value)}]`;
|
|
33594
|
+
var promotionDiscoveryCommand = (workflow, repository) => [
|
|
33595
|
+
"gh",
|
|
33596
|
+
"run",
|
|
33597
|
+
"list",
|
|
33598
|
+
"--workflow",
|
|
33599
|
+
workflow,
|
|
33600
|
+
"--event",
|
|
33601
|
+
"workflow_dispatch",
|
|
33602
|
+
"--limit",
|
|
33603
|
+
"50",
|
|
33604
|
+
...repositoryArgs(repository),
|
|
33605
|
+
"--json",
|
|
33606
|
+
"databaseId,displayTitle,event,url"
|
|
33607
|
+
];
|
|
33585
33608
|
var repositoryArgs = (repository) => {
|
|
33586
33609
|
if (repository === undefined)
|
|
33587
33610
|
return [];
|
|
@@ -33629,6 +33652,27 @@ var parseJob = (value) => {
|
|
|
33629
33652
|
status: requiredString(value.status, "GitHub job status")
|
|
33630
33653
|
};
|
|
33631
33654
|
};
|
|
33655
|
+
var discoverAbsoluteMobilePromotionRun = async (options) => {
|
|
33656
|
+
const requestedDispatchId = dispatchId(options.dispatchId);
|
|
33657
|
+
const attempts = options.attempts ?? PROMOTION_DISCOVERY_ATTEMPTS;
|
|
33658
|
+
if (!Number.isSafeInteger(attempts) || attempts < 1 || attempts > 300)
|
|
33659
|
+
throw new TypeError("Mobile promotion discovery attempts are invalid.");
|
|
33660
|
+
const pollIntervalMs = options.pollIntervalMs ?? PROMOTION_DISCOVERY_INTERVAL_MS;
|
|
33661
|
+
if (!Number.isSafeInteger(pollIntervalMs) || pollIntervalMs < 0 || pollIntervalMs > 1e4)
|
|
33662
|
+
throw new TypeError("Mobile promotion discovery interval is invalid.");
|
|
33663
|
+
const sleep = options.sleep ?? Bun.sleep;
|
|
33664
|
+
const discover = async (attempt) => {
|
|
33665
|
+
const result = await requireCommand(options.run ?? defaultRunner, promotionDiscoveryCommand(options.workflow, options.repository), { cwd: options.projectRoot }, "GitHub promotion run discovery");
|
|
33666
|
+
const discovered = parseAbsoluteMobilePromotionRunList(JSON.parse(result.stdout), requestedDispatchId);
|
|
33667
|
+
if (discovered)
|
|
33668
|
+
return discovered;
|
|
33669
|
+
if (attempt >= attempts)
|
|
33670
|
+
throw new TypeError(`GitHub did not expose promotion dispatch ${requestedDispatchId} within ${attempts} attempts.`);
|
|
33671
|
+
await sleep(pollIntervalMs);
|
|
33672
|
+
return discover(attempt + 1);
|
|
33673
|
+
};
|
|
33674
|
+
return discover(1);
|
|
33675
|
+
};
|
|
33632
33676
|
var inspectAbsoluteMobileCiRun = async (options) => {
|
|
33633
33677
|
const requestedRunId = runId(options.runId, "GitHub run ID");
|
|
33634
33678
|
const result = await requireCommand(options.run ?? defaultRunner, [
|
|
@@ -33638,7 +33682,7 @@ var inspectAbsoluteMobileCiRun = async (options) => {
|
|
|
33638
33682
|
requestedRunId,
|
|
33639
33683
|
...repositoryArgs(options.repository),
|
|
33640
33684
|
"--json",
|
|
33641
|
-
"conclusion,createdAt,databaseId,headBranch,headSha,jobs,startedAt,status,updatedAt,url,workflowName"
|
|
33685
|
+
"conclusion,createdAt,databaseId,displayTitle,headBranch,headSha,jobs,startedAt,status,updatedAt,url,workflowName"
|
|
33642
33686
|
], { cwd: options.projectRoot }, "GitHub workflow inspection");
|
|
33643
33687
|
return parseAbsoluteMobileCiRunStatus(JSON.parse(result.stdout), requestedRunId);
|
|
33644
33688
|
};
|
|
@@ -33651,6 +33695,7 @@ var parseAbsoluteMobileCiRunStatus = (value, requestedRunId) => {
|
|
|
33651
33695
|
return {
|
|
33652
33696
|
conclusion: optionalString(value.conclusion, "GitHub run conclusion"),
|
|
33653
33697
|
createdAt: requiredString(value.createdAt, "GitHub run createdAt"),
|
|
33698
|
+
displayTitle: requiredString(value.displayTitle, "GitHub run displayTitle"),
|
|
33654
33699
|
headBranch: requiredString(value.headBranch, "GitHub run headBranch"),
|
|
33655
33700
|
headSha: requiredString(value.headSha, "GitHub run headSha"),
|
|
33656
33701
|
jobs: value.jobs.map(parseJob),
|
|
@@ -33663,20 +33708,44 @@ var parseAbsoluteMobileCiRunStatus = (value, requestedRunId) => {
|
|
|
33663
33708
|
};
|
|
33664
33709
|
};
|
|
33665
33710
|
var parseAbsoluteMobilePromotionContext = (value) => {
|
|
33666
|
-
if (!isRecord13(value) || value.format !== ABSOLUTE_MOBILE_CI_PROMOTION_CONTEXT_FORMAT || value.platform !== "android" && value.platform !== "ios")
|
|
33711
|
+
if (!isRecord13(value) || value.format !== 1 && value.format !== ABSOLUTE_MOBILE_CI_PROMOTION_CONTEXT_FORMAT || value.platform !== "android" && value.platform !== "ios")
|
|
33667
33712
|
throw new TypeError("Mobile promotion context is invalid.");
|
|
33668
33713
|
const { platform: platform3 } = value;
|
|
33669
33714
|
const sourceArtifact = requiredString(value.sourceArtifact, "promotion source artifact");
|
|
33670
33715
|
if (sourceArtifact !== `absolute-mobile-${platform3}`)
|
|
33671
33716
|
throw new TypeError("Mobile promotion source artifact is invalid.");
|
|
33672
33717
|
return {
|
|
33673
|
-
format:
|
|
33718
|
+
dispatchId: value.format === 1 ? null : dispatchId(requiredString(value.dispatchId, "promotion dispatch ID")),
|
|
33719
|
+
format: value.format,
|
|
33674
33720
|
platform: platform3,
|
|
33675
33721
|
promotionRunId: runId(requiredString(value.promotionRunId, "promotion run ID"), "promotion run ID"),
|
|
33676
33722
|
sourceArtifact,
|
|
33677
33723
|
sourceRunId: runId(requiredString(value.sourceRunId, "source run ID"), "source run ID")
|
|
33678
33724
|
};
|
|
33679
33725
|
};
|
|
33726
|
+
var parseAbsoluteMobilePromotionRunList = (value, requestedDispatchId) => {
|
|
33727
|
+
if (!Array.isArray(value))
|
|
33728
|
+
throw new TypeError("GitHub workflow run list response is invalid.");
|
|
33729
|
+
const expectedTitle = promotionRunTitle(requestedDispatchId);
|
|
33730
|
+
const matches2 = value.filter((candidate) => isRecord13(candidate) && candidate.displayTitle === expectedTitle);
|
|
33731
|
+
if (matches2.length === 0)
|
|
33732
|
+
return null;
|
|
33733
|
+
if (matches2.length !== 1)
|
|
33734
|
+
throw new TypeError("GitHub returned multiple runs for one promotion dispatch identity.");
|
|
33735
|
+
const [match] = matches2;
|
|
33736
|
+
if (!isRecord13(match) || match.event !== "workflow_dispatch")
|
|
33737
|
+
throw new TypeError("GitHub promotion run identity is invalid.");
|
|
33738
|
+
const databaseId = typeof match.databaseId === "number" || typeof match.databaseId === "string" ? String(match.databaseId) : "";
|
|
33739
|
+
const requestedRunId = runId(databaseId, "GitHub promotion run ID");
|
|
33740
|
+
const url = requiredString(match.url, "GitHub promotion run URL");
|
|
33741
|
+
if (!url.endsWith(`/actions/runs/${requestedRunId}`))
|
|
33742
|
+
throw new TypeError("GitHub promotion run URL does not match its ID.");
|
|
33743
|
+
return {
|
|
33744
|
+
dispatchId: requestedDispatchId,
|
|
33745
|
+
runId: requestedRunId,
|
|
33746
|
+
url
|
|
33747
|
+
};
|
|
33748
|
+
};
|
|
33680
33749
|
var watchAbsoluteMobileCiRun = async (options) => {
|
|
33681
33750
|
const requestedRunId = runId(options.runId, "GitHub run ID");
|
|
33682
33751
|
await requireCommand(options.run ?? defaultRunner, [
|
|
@@ -33795,6 +33864,7 @@ var renderAuditMarkdown = (audit) => `# AbsoluteJS mobile promotion audit
|
|
|
33795
33864
|
- Artifact SHA-256: \`${audit.release.sha256}\`
|
|
33796
33865
|
- Source workflow run: ${audit.github.sourceRunId}
|
|
33797
33866
|
- Promotion workflow run: ${audit.github.promotionRunId}
|
|
33867
|
+
- Dispatch correlation: ${audit.github.dispatchId ?? "legacy workflow (not recorded)"}
|
|
33798
33868
|
- Workflow: ${audit.github.workflowName}
|
|
33799
33869
|
- GitHub identity: \`${audit.provenance.repository}/${audit.provenance.workflowPath}@${audit.provenance.ref}\`
|
|
33800
33870
|
- Certification: \`${audit.certification.certificationId}\` (${audit.certification.strength})
|
|
@@ -33844,6 +33914,8 @@ var auditAbsoluteMobileCiPromotion = async (options) => {
|
|
|
33844
33914
|
throw new TypeError("Promotion context run identity does not match.");
|
|
33845
33915
|
if (context && context.platform !== platform3)
|
|
33846
33916
|
throw new TypeError("Promotion context platform does not match.");
|
|
33917
|
+
if (context?.dispatchId && status.displayTitle !== promotionRunTitle(context.dispatchId))
|
|
33918
|
+
throw new TypeError("Promotion dispatch identity does not match the GitHub run.");
|
|
33847
33919
|
const sourceRunId = options.sourceRunId ? runId(options.sourceRunId, "GitHub source run ID") : context?.sourceRunId;
|
|
33848
33920
|
if (!sourceRunId)
|
|
33849
33921
|
throw new TypeError("Promotion artifact predates source-run context; pass --source-run-id.");
|
|
@@ -33912,6 +33984,7 @@ var auditAbsoluteMobileCiPromotion = async (options) => {
|
|
|
33912
33984
|
format: ABSOLUTE_MOBILE_CI_PROMOTION_AUDIT_FORMAT,
|
|
33913
33985
|
github: {
|
|
33914
33986
|
conclusion: status.conclusion,
|
|
33987
|
+
dispatchId: context?.dispatchId ?? null,
|
|
33915
33988
|
promotionRunId,
|
|
33916
33989
|
repository: verification.identity.repository,
|
|
33917
33990
|
sourceRunId,
|
|
@@ -33946,11 +34019,229 @@ var auditAbsoluteMobileCiPromotion = async (options) => {
|
|
|
33946
34019
|
throw error;
|
|
33947
34020
|
}
|
|
33948
34021
|
};
|
|
34022
|
+
// src/mobile/ciPromotionLedger.ts
|
|
34023
|
+
import {
|
|
34024
|
+
access as access19,
|
|
34025
|
+
link,
|
|
34026
|
+
lstat as lstat2,
|
|
34027
|
+
mkdir as mkdir19,
|
|
34028
|
+
open,
|
|
34029
|
+
readFile as readFile23,
|
|
34030
|
+
readdir as readdir8,
|
|
34031
|
+
rename as rename15,
|
|
34032
|
+
rm as rm15
|
|
34033
|
+
} from "fs/promises";
|
|
34034
|
+
import { dirname as dirname17, isAbsolute as isAbsolute12, join as join25, relative as relative18, resolve as resolve20, sep as sep13 } from "path";
|
|
34035
|
+
import { randomUUID as randomUUID5 } from "crypto";
|
|
34036
|
+
var ABSOLUTE_MOBILE_CI_PROMOTION_OPERATION_FORMAT = 1;
|
|
34037
|
+
var MAX_OPERATION_BYTES = 65536;
|
|
34038
|
+
var MAX_OPERATIONS = 1000;
|
|
34039
|
+
var DISPATCH_ID_PATTERN2 = /^amp_[a-f0-9]{32}$/u;
|
|
34040
|
+
var RUN_ID_PATTERN2 = /^[1-9][0-9]*$/u;
|
|
34041
|
+
var SHA256_PATTERN = /^[a-f0-9]{64}$/u;
|
|
34042
|
+
var CERTIFICATION_ID_PATTERN = /^amobile_cert_[a-f0-9]{64}$/u;
|
|
34043
|
+
var RELEASE_ID_PATTERN2 = /^amobile_(?:android|ios)_[a-f0-9]{64}$/u;
|
|
34044
|
+
var REPOSITORY_PATTERN3 = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/u;
|
|
34045
|
+
var LAST_ASCII_CONTROL = 31;
|
|
34046
|
+
var DELETE_CHARACTER = 127;
|
|
34047
|
+
var PHASES = [
|
|
34048
|
+
"dispatching",
|
|
34049
|
+
"dispatched",
|
|
34050
|
+
"discovered",
|
|
34051
|
+
"completed",
|
|
34052
|
+
"audited"
|
|
34053
|
+
];
|
|
34054
|
+
var isRecord14 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
34055
|
+
var requiredString2 = (value, label, max = 512) => {
|
|
34056
|
+
const hasControlCharacter = typeof value === "string" && Array.from(value).some((character) => {
|
|
34057
|
+
const code = character.codePointAt(0);
|
|
34058
|
+
return code !== undefined && (code <= LAST_ASCII_CONTROL || code === DELETE_CHARACTER);
|
|
34059
|
+
});
|
|
34060
|
+
if (typeof value !== "string" || value.trim() === "" || value !== value.trim() || value.length > max || hasControlCharacter)
|
|
34061
|
+
throw new TypeError(`${label} is invalid.`);
|
|
34062
|
+
return value;
|
|
34063
|
+
};
|
|
34064
|
+
var optionalString2 = (value, label, max = 512) => {
|
|
34065
|
+
if (value === null)
|
|
34066
|
+
return null;
|
|
34067
|
+
return requiredString2(value, label, max);
|
|
34068
|
+
};
|
|
34069
|
+
var boolean = (value, label) => {
|
|
34070
|
+
if (typeof value !== "boolean")
|
|
34071
|
+
throw new TypeError(`${label} is invalid.`);
|
|
34072
|
+
return value;
|
|
34073
|
+
};
|
|
34074
|
+
var timestamp = (value, label) => {
|
|
34075
|
+
const parsed = requiredString2(value, label, 64);
|
|
34076
|
+
if (!Number.isFinite(Date.parse(parsed)))
|
|
34077
|
+
throw new TypeError(`${label} is invalid.`);
|
|
34078
|
+
return parsed;
|
|
34079
|
+
};
|
|
34080
|
+
var projectRelativePath = (value, label) => {
|
|
34081
|
+
const parsed = requiredString2(value, label, 512);
|
|
34082
|
+
if (isAbsolute12(parsed) || parsed === ".." || parsed.startsWith(`..${sep13}`) || parsed.split(/[\\/]/u).includes(".."))
|
|
34083
|
+
throw new TypeError(`${label} must be project-relative.`);
|
|
34084
|
+
return parsed.replaceAll("\\", "/");
|
|
34085
|
+
};
|
|
34086
|
+
var nullableProjectRelativePath = (value, label) => value === null ? null : projectRelativePath(value, label);
|
|
34087
|
+
var dispatchId2 = (value) => {
|
|
34088
|
+
const parsed = requiredString2(value, "Promotion dispatch ID", 36);
|
|
34089
|
+
if (!DISPATCH_ID_PATTERN2.test(parsed))
|
|
34090
|
+
throw new TypeError("Promotion dispatch ID is invalid.");
|
|
34091
|
+
return parsed;
|
|
34092
|
+
};
|
|
34093
|
+
var runId2 = (value, label) => {
|
|
34094
|
+
const parsed = requiredString2(value, label, 32);
|
|
34095
|
+
if (!RUN_ID_PATTERN2.test(parsed))
|
|
34096
|
+
throw new TypeError(`${label} is invalid.`);
|
|
34097
|
+
return parsed;
|
|
34098
|
+
};
|
|
34099
|
+
var nullableRunId = (value, label) => value === null ? null : runId2(value, label);
|
|
34100
|
+
var operationRoot = (projectRoot) => join25(resolve20(projectRoot), ".absolutejs", "mobile-ci", "promotions");
|
|
34101
|
+
var absoluteMobilePromotionOperationPath = (projectRoot, requestedDispatchId) => join25(operationRoot(projectRoot), dispatchId2(requestedDispatchId), "operation.json");
|
|
34102
|
+
var operationPhase = (value) => {
|
|
34103
|
+
const phase = PHASES.find((candidate) => candidate === value);
|
|
34104
|
+
if (!phase)
|
|
34105
|
+
throw new TypeError("Mobile promotion operation phase is invalid.");
|
|
34106
|
+
return phase;
|
|
34107
|
+
};
|
|
34108
|
+
var parseAbsoluteMobilePromotionOperation = (value) => {
|
|
34109
|
+
if (!isRecord14(value) || value.format !== ABSOLUTE_MOBILE_CI_PROMOTION_OPERATION_FORMAT || value.platform !== "android" && value.platform !== "ios")
|
|
34110
|
+
throw new TypeError("Mobile promotion operation is invalid.");
|
|
34111
|
+
const parsed = {
|
|
34112
|
+
auditDirectory: nullableProjectRelativePath(value.auditDirectory, "Promotion audit directory"),
|
|
34113
|
+
auditOutputDirectory: nullableProjectRelativePath(value.auditOutputDirectory, "Promotion requested audit directory"),
|
|
34114
|
+
auditRequested: boolean(value.auditRequested, "Promotion audit request"),
|
|
34115
|
+
certificationId: requiredString2(value.certificationId, "Promotion certification ID", 256),
|
|
34116
|
+
certificationSha256: requiredString2(value.certificationSha256, "Promotion certification digest", 64),
|
|
34117
|
+
channel: optionalString2(value.channel, "Promotion channel", 128),
|
|
34118
|
+
conclusion: optionalString2(value.conclusion, "Promotion conclusion", 64),
|
|
34119
|
+
createdAt: timestamp(value.createdAt, "Promotion creation time"),
|
|
34120
|
+
dispatchId: dispatchId2(value.dispatchId),
|
|
34121
|
+
format: ABSOLUTE_MOBILE_CI_PROMOTION_OPERATION_FORMAT,
|
|
34122
|
+
githubStatus: optionalString2(value.githubStatus, "Promotion GitHub status", 64),
|
|
34123
|
+
phase: operationPhase(value.phase),
|
|
34124
|
+
platform: value.platform,
|
|
34125
|
+
playTrack: optionalString2(value.playTrack, "Promotion Play track", 128),
|
|
34126
|
+
ref: optionalString2(value.ref, "Promotion ref", 256),
|
|
34127
|
+
releaseId: requiredString2(value.releaseId, "Promotion release ID", 256),
|
|
34128
|
+
repository: optionalString2(value.repository, "Promotion repository", 256),
|
|
34129
|
+
runId: nullableRunId(value.runId, "Promotion run ID"),
|
|
34130
|
+
sourceRunId: runId2(value.sourceRunId, "Promotion source run ID"),
|
|
34131
|
+
testflightGroup: optionalString2(value.testflightGroup, "Promotion TestFlight group", 128),
|
|
34132
|
+
testflightSubmitReview: boolean(value.testflightSubmitReview, "Promotion TestFlight review setting"),
|
|
34133
|
+
updatedAt: timestamp(value.updatedAt, "Promotion update time"),
|
|
34134
|
+
url: optionalString2(value.url, "Promotion run URL", 1024),
|
|
34135
|
+
watchRequested: boolean(value.watchRequested, "Promotion watch request"),
|
|
34136
|
+
workflow: projectRelativePath(value.workflow, "Promotion workflow")
|
|
34137
|
+
};
|
|
34138
|
+
if (!SHA256_PATTERN.test(parsed.certificationSha256))
|
|
34139
|
+
throw new TypeError("Promotion certification digest is invalid.");
|
|
34140
|
+
if (!CERTIFICATION_ID_PATTERN.test(parsed.certificationId))
|
|
34141
|
+
throw new TypeError("Promotion certification ID is invalid.");
|
|
34142
|
+
if (!RELEASE_ID_PATTERN2.test(parsed.releaseId))
|
|
34143
|
+
throw new TypeError("Promotion release ID is invalid.");
|
|
34144
|
+
if (parsed.repository !== null && !REPOSITORY_PATTERN3.test(parsed.repository))
|
|
34145
|
+
throw new TypeError("Promotion repository is invalid.");
|
|
34146
|
+
const discovered = PHASES.indexOf(parsed.phase) >= PHASES.indexOf("discovered");
|
|
34147
|
+
const completed = PHASES.indexOf(parsed.phase) >= PHASES.indexOf("completed");
|
|
34148
|
+
if (discovered && (!parsed.runId || !parsed.url) || !discovered && (parsed.runId || parsed.url) || completed && (parsed.githubStatus !== "completed" || !parsed.conclusion) || !completed && (parsed.githubStatus || parsed.conclusion) || parsed.phase === "audited" && !parsed.auditDirectory || parsed.phase !== "audited" && parsed.auditDirectory)
|
|
34149
|
+
throw new TypeError("Mobile promotion operation phase is incomplete.");
|
|
34150
|
+
if (parsed.url && parsed.runId) {
|
|
34151
|
+
const url = new URL(parsed.url);
|
|
34152
|
+
if (url.protocol !== "https:" || url.username !== "" || url.password !== "" || url.search !== "" || url.hash !== "" || !url.pathname.endsWith(`/actions/runs/${parsed.runId}`))
|
|
34153
|
+
throw new TypeError("Promotion run URL is invalid.");
|
|
34154
|
+
}
|
|
34155
|
+
if (Date.parse(parsed.updatedAt) < Date.parse(parsed.createdAt))
|
|
34156
|
+
throw new TypeError("Promotion operation time moved backwards.");
|
|
34157
|
+
return parsed;
|
|
34158
|
+
};
|
|
34159
|
+
var serialize = (operation2) => `${JSON.stringify(parseAbsoluteMobilePromotionOperation(operation2), null, 2)}
|
|
34160
|
+
`;
|
|
34161
|
+
var writeSynced = async (path, source) => {
|
|
34162
|
+
const handle = await open(path, "wx", 384);
|
|
34163
|
+
try {
|
|
34164
|
+
await handle.writeFile(source);
|
|
34165
|
+
await handle.sync();
|
|
34166
|
+
} finally {
|
|
34167
|
+
await handle.close();
|
|
34168
|
+
}
|
|
34169
|
+
};
|
|
34170
|
+
var atomicWrite = async (path, source, exclusive) => {
|
|
34171
|
+
await mkdir19(dirname17(path), { recursive: true });
|
|
34172
|
+
const temporary = join25(dirname17(path), `.operation-${randomUUID5()}.tmp`);
|
|
34173
|
+
try {
|
|
34174
|
+
await writeSynced(temporary, source);
|
|
34175
|
+
if (exclusive)
|
|
34176
|
+
await link(temporary, path);
|
|
34177
|
+
else
|
|
34178
|
+
await rename15(temporary, path);
|
|
34179
|
+
} finally {
|
|
34180
|
+
await rm15(temporary, { force: true });
|
|
34181
|
+
}
|
|
34182
|
+
};
|
|
34183
|
+
var advanceAbsoluteMobilePromotionOperation = async (projectRoot, requestedDispatchId, options, now = () => new Date) => {
|
|
34184
|
+
const current = await readAbsoluteMobilePromotionOperation(projectRoot, requestedDispatchId);
|
|
34185
|
+
if (PHASES.indexOf(options.phase) < PHASES.indexOf(current.phase))
|
|
34186
|
+
throw new TypeError("Mobile promotion operation cannot move backwards.");
|
|
34187
|
+
if (current.runId && options.runId && current.runId !== options.runId || current.url && options.url && current.url !== options.url || current.auditDirectory && options.auditDirectory && current.auditDirectory !== options.auditDirectory)
|
|
34188
|
+
throw new TypeError("Mobile promotion operation identity is immutable.");
|
|
34189
|
+
const next = parseAbsoluteMobilePromotionOperation({
|
|
34190
|
+
...current,
|
|
34191
|
+
auditDirectory: options.auditDirectory === undefined ? current.auditDirectory : options.auditDirectory,
|
|
34192
|
+
conclusion: options.conclusion === undefined ? current.conclusion : options.conclusion,
|
|
34193
|
+
githubStatus: options.githubStatus === undefined ? current.githubStatus : options.githubStatus,
|
|
34194
|
+
phase: options.phase,
|
|
34195
|
+
runId: options.runId === undefined ? current.runId : options.runId,
|
|
34196
|
+
updatedAt: now().toISOString(),
|
|
34197
|
+
url: options.url === undefined ? current.url : options.url
|
|
34198
|
+
});
|
|
34199
|
+
await atomicWrite(absoluteMobilePromotionOperationPath(projectRoot, requestedDispatchId), serialize(next), false);
|
|
34200
|
+
return next;
|
|
34201
|
+
};
|
|
34202
|
+
var createAbsoluteMobilePromotionOperation = async (projectRoot, options) => {
|
|
34203
|
+
const now = (options.now ?? (() => new Date))().toISOString();
|
|
34204
|
+
const operation2 = parseAbsoluteMobilePromotionOperation({
|
|
34205
|
+
...options,
|
|
34206
|
+
auditDirectory: null,
|
|
34207
|
+
conclusion: null,
|
|
34208
|
+
createdAt: now,
|
|
34209
|
+
format: ABSOLUTE_MOBILE_CI_PROMOTION_OPERATION_FORMAT,
|
|
34210
|
+
githubStatus: null,
|
|
34211
|
+
phase: "dispatching",
|
|
34212
|
+
runId: null,
|
|
34213
|
+
updatedAt: now,
|
|
34214
|
+
url: null
|
|
34215
|
+
});
|
|
34216
|
+
await atomicWrite(absoluteMobilePromotionOperationPath(projectRoot, operation2.dispatchId), serialize(operation2), true);
|
|
34217
|
+
return operation2;
|
|
34218
|
+
};
|
|
34219
|
+
var listAbsoluteMobilePromotionOperations = async (projectRoot) => {
|
|
34220
|
+
const root = operationRoot(projectRoot);
|
|
34221
|
+
if (!await access19(root).then(() => true).catch(() => false))
|
|
34222
|
+
return [];
|
|
34223
|
+
const entries = await readdir8(root, { withFileTypes: true });
|
|
34224
|
+
if (entries.length > MAX_OPERATIONS)
|
|
34225
|
+
throw new TypeError("Mobile promotion operation count exceeds the limit.");
|
|
34226
|
+
const operations = await Promise.all(entries.filter((entry) => entry.isDirectory() && DISPATCH_ID_PATTERN2.test(entry.name)).map((entry) => readAbsoluteMobilePromotionOperation(projectRoot, entry.name)));
|
|
34227
|
+
return operations.sort((left, right) => right.updatedAt.localeCompare(left.updatedAt));
|
|
34228
|
+
};
|
|
34229
|
+
var readAbsoluteMobilePromotionOperation = async (projectRoot, requestedDispatchId) => {
|
|
34230
|
+
const path = absoluteMobilePromotionOperationPath(projectRoot, requestedDispatchId);
|
|
34231
|
+
const metadata = await lstat2(path).catch(() => null);
|
|
34232
|
+
if (!metadata?.isFile() || metadata.size > MAX_OPERATION_BYTES)
|
|
34233
|
+
throw new TypeError(`Mobile promotion operation ${requestedDispatchId} was not found or is invalid.`);
|
|
34234
|
+
const operation2 = parseAbsoluteMobilePromotionOperation(JSON.parse(await readFile23(path, "utf8")));
|
|
34235
|
+
if (operation2.dispatchId !== requestedDispatchId)
|
|
34236
|
+
throw new TypeError("Mobile promotion operation identity does not match.");
|
|
34237
|
+
return operation2;
|
|
34238
|
+
};
|
|
34239
|
+
var relativeAbsoluteMobilePromotionOperationPath = (projectRoot, dispatchIdValue) => relative18(resolve20(projectRoot), absoluteMobilePromotionOperationPath(projectRoot, dispatchIdValue)).replaceAll("\\", "/");
|
|
33949
34240
|
// src/mobile/ciWorkflow.ts
|
|
33950
34241
|
import { existsSync as existsSync4 } from "fs";
|
|
33951
|
-
import { access as
|
|
33952
|
-
import { dirname as
|
|
33953
|
-
var ABSOLUTE_MOBILE_CI_WORKFLOW_FORMAT =
|
|
34242
|
+
import { access as access20, mkdir as mkdir20, readFile as readFile24, writeFile as writeFile19 } from "fs/promises";
|
|
34243
|
+
import { dirname as dirname18, extname as extname5, relative as relative19, resolve as resolve21, sep as sep14 } from "path";
|
|
34244
|
+
var ABSOLUTE_MOBILE_CI_WORKFLOW_FORMAT = 4;
|
|
33954
34245
|
var SECRET_NAME_PATTERN = /^[A-Z][A-Z0-9_]*$/u;
|
|
33955
34246
|
var CI_ENV_INDENTATION = 6;
|
|
33956
34247
|
var RESERVED_SECRET_NAMES = new Set([
|
|
@@ -33970,7 +34261,7 @@ var RESERVED_SECRET_NAMES = new Set([
|
|
|
33970
34261
|
]);
|
|
33971
34262
|
var exists9 = async (path) => {
|
|
33972
34263
|
try {
|
|
33973
|
-
await
|
|
34264
|
+
await access20(path);
|
|
33974
34265
|
return true;
|
|
33975
34266
|
} catch {
|
|
33976
34267
|
return false;
|
|
@@ -33978,10 +34269,10 @@ var exists9 = async (path) => {
|
|
|
33978
34269
|
};
|
|
33979
34270
|
var yamlString = (value) => `'${value.replaceAll("'", "''")}'`;
|
|
33980
34271
|
var projectPath2 = (projectRoot, value, field2, options = {}) => {
|
|
33981
|
-
const root =
|
|
33982
|
-
const path =
|
|
33983
|
-
const portable =
|
|
33984
|
-
if (portable === ".." || portable.startsWith(`..${
|
|
34272
|
+
const root = resolve21(projectRoot);
|
|
34273
|
+
const path = resolve21(root, value);
|
|
34274
|
+
const portable = relative19(root, path).replaceAll("\\", "/");
|
|
34275
|
+
if (portable === ".." || portable.startsWith(`..${sep14}`) || portable.startsWith("../") || portable === "") {
|
|
33985
34276
|
throw new TypeError(`${field2} must remain inside the project root.`);
|
|
33986
34277
|
}
|
|
33987
34278
|
if (/\r|\n/u.test(portable) || portable.startsWith("-"))
|
|
@@ -33991,11 +34282,11 @@ var projectPath2 = (projectRoot, value, field2, options = {}) => {
|
|
|
33991
34282
|
return portable;
|
|
33992
34283
|
};
|
|
33993
34284
|
var workflowOutputPath = (projectRoot, value) => {
|
|
33994
|
-
const root =
|
|
33995
|
-
const workflows =
|
|
33996
|
-
const path =
|
|
33997
|
-
const portable =
|
|
33998
|
-
if (portable === ".." || portable.startsWith(`..${
|
|
34285
|
+
const root = resolve21(projectRoot);
|
|
34286
|
+
const workflows = resolve21(root, ".github/workflows");
|
|
34287
|
+
const path = resolve21(root, value ?? ".github/workflows/absolute-mobile.yml");
|
|
34288
|
+
const portable = relative19(workflows, path);
|
|
34289
|
+
if (portable === ".." || portable.startsWith(`..${sep14}`) || extname5(path) !== ".yml" && extname5(path) !== ".yaml") {
|
|
33999
34290
|
throw new TypeError("mobile ci github --output must be a .yml or .yaml file inside .github/workflows.");
|
|
34000
34291
|
}
|
|
34001
34292
|
return path;
|
|
@@ -34109,6 +34400,10 @@ var publishingInputs = (platforms, includePublishing) => {
|
|
|
34109
34400
|
description: Source workflow run ID for promotion without rebuilding
|
|
34110
34401
|
required: false
|
|
34111
34402
|
type: string`,
|
|
34403
|
+
` dispatch_id:
|
|
34404
|
+
description: Unique promotion correlation ID supplied by the AbsoluteJS CLI
|
|
34405
|
+
required: false
|
|
34406
|
+
type: string`,
|
|
34112
34407
|
` certification_base64:
|
|
34113
34408
|
description: AbsoluteJS certification supplied by the promotion CLI
|
|
34114
34409
|
required: false
|
|
@@ -34481,6 +34776,10 @@ var promotionValidationSteps = ` - name: Validate promotion handoff
|
|
|
34481
34776
|
echo "Promotion requires a numeric source workflow run ID." >&2
|
|
34482
34777
|
exit 1
|
|
34483
34778
|
fi
|
|
34779
|
+
if [[ ! "$ABSOLUTE_PROMOTION_DISPATCH_ID" =~ ^amp_[a-f0-9]{32}$ ]]; then
|
|
34780
|
+
echo "Promotion requires a valid AbsoluteJS dispatch correlation ID." >&2
|
|
34781
|
+
exit 1
|
|
34782
|
+
fi
|
|
34484
34783
|
if [[ -z "$ABSOLUTE_CERTIFICATION_BASE64" ]]; then
|
|
34485
34784
|
echo "Promotion requires certification supplied by absolute mobile ci promote." >&2
|
|
34486
34785
|
exit 1
|
|
@@ -34495,7 +34794,7 @@ var promotionSharedSteps = (platform3) => ` - name: Restore exact ${platfor
|
|
|
34495
34794
|
- name: Record bounded promotion context
|
|
34496
34795
|
shell: bash
|
|
34497
34796
|
run: |
|
|
34498
|
-
bun -e 'const sourceRunId = process.env.ABSOLUTE_SOURCE_RUN_ID; const promotionRunId = process.env.GITHUB_RUN_ID; if (!sourceRunId?.match(/^[1-9][0-9]*$/) || !promotionRunId?.match(/^[1-9][0-9]*$/)) throw new Error("Invalid promotion run identity"); await Bun.write(".absolutejs/mobile-ci/promotion-context.json", JSON.stringify({ format:
|
|
34797
|
+
bun -e 'const dispatchId = process.env.ABSOLUTE_PROMOTION_DISPATCH_ID; const sourceRunId = process.env.ABSOLUTE_SOURCE_RUN_ID; const promotionRunId = process.env.GITHUB_RUN_ID; if (!dispatchId?.match(/^amp_[a-f0-9]{32}$/) || !sourceRunId?.match(/^[1-9][0-9]*$/) || !promotionRunId?.match(/^[1-9][0-9]*$/)) throw new Error("Invalid promotion run identity"); await Bun.write(".absolutejs/mobile-ci/promotion-context.json", JSON.stringify({ dispatchId, format: 2, platform: ${JSON.stringify(platform3)}, promotionRunId, sourceArtifact: ${JSON.stringify(`absolute-mobile-${platform3}`)}, sourceRunId }, null, 2) + "\\n");'
|
|
34499
34798
|
- name: Import and verify exact certification
|
|
34500
34799
|
shell: bash
|
|
34501
34800
|
run: |
|
|
@@ -34533,6 +34832,7 @@ var androidPromotionJob = (options) => {
|
|
|
34533
34832
|
id-token: write
|
|
34534
34833
|
env:
|
|
34535
34834
|
ABSOLUTE_CERTIFICATION_BASE64: \${{ inputs.certification_base64 }}
|
|
34835
|
+
ABSOLUTE_PROMOTION_DISPATCH_ID: \${{ inputs.dispatch_id }}
|
|
34536
34836
|
ABSOLUTE_RELEASE_CHANNEL: \${{ inputs.channel }}
|
|
34537
34837
|
ABSOLUTE_SOURCE_RUN_ID: \${{ inputs.source_run_id }}
|
|
34538
34838
|
ABSOLUTE_PLAY_TRACK: \${{ inputs.play_track }}
|
|
@@ -34598,6 +34898,7 @@ var iosPromotionJob = (options) => {
|
|
|
34598
34898
|
id-token: write
|
|
34599
34899
|
env:
|
|
34600
34900
|
ABSOLUTE_CERTIFICATION_BASE64: \${{ inputs.certification_base64 }}
|
|
34901
|
+
ABSOLUTE_PROMOTION_DISPATCH_ID: \${{ inputs.dispatch_id }}
|
|
34601
34902
|
ABSOLUTE_RELEASE_CHANNEL: \${{ inputs.channel }}
|
|
34602
34903
|
ABSOLUTE_SOURCE_RUN_ID: \${{ inputs.source_run_id }}
|
|
34603
34904
|
ABSOLUTE_TESTFLIGHT_GROUP: \${{ inputs.testflight_group }}
|
|
@@ -34688,6 +34989,7 @@ var createAbsoluteMobileGithubWorkflow = (options) => {
|
|
|
34688
34989
|
});
|
|
34689
34990
|
let workflow = `# Generated by AbsoluteJS. Regenerate with: absolute mobile ci github${includePublishing ? " --publish" : ""}
|
|
34690
34991
|
name: AbsoluteJS Mobile
|
|
34992
|
+
run-name: \${{ inputs.operation == 'promote' && format('AbsoluteJS mobile promotion [{0}]', inputs.dispatch_id) || format('AbsoluteJS mobile {0}', github.event_name) }}
|
|
34691
34993
|
|
|
34692
34994
|
on:
|
|
34693
34995
|
pull_request:
|
|
@@ -34713,6 +35015,7 @@ jobs:
|
|
|
34713
35015
|
env:
|
|
34714
35016
|
${environment}${includePublishing ? `
|
|
34715
35017
|
ABSOLUTE_PROMOTION_PLATFORM: \${{ inputs.platform }}
|
|
35018
|
+
ABSOLUTE_PROMOTION_DISPATCH_ID: \${{ inputs.dispatch_id }}
|
|
34716
35019
|
ABSOLUTE_SOURCE_RUN_ID: \${{ inputs.source_run_id }}
|
|
34717
35020
|
ABSOLUTE_CERTIFICATION_BASE64: \${{ inputs.certification_base64 }}` : ""}
|
|
34718
35021
|
steps:
|
|
@@ -34744,11 +35047,11 @@ ${bundleAuditSteps}${platforms.includes("android") ? androidJob({ customSecrets,
|
|
|
34744
35047
|
var writeAbsoluteMobileGithubWorkflow = async (options) => {
|
|
34745
35048
|
const path = workflowOutputPath(options.projectRoot, options.outputPath);
|
|
34746
35049
|
const generated = createAbsoluteMobileGithubWorkflow(options);
|
|
34747
|
-
const previous = await exists9(path) ? await
|
|
35050
|
+
const previous = await exists9(path) ? await readFile24(path, "utf8") : undefined;
|
|
34748
35051
|
if (previous !== undefined && previous !== generated.workflow && !options.force)
|
|
34749
|
-
throw new TypeError(`${
|
|
35052
|
+
throw new TypeError(`${relative19(options.projectRoot, path)} already exists and differs. Rerun with --force to replace the generated workflow.`);
|
|
34750
35053
|
if (previous !== generated.workflow) {
|
|
34751
|
-
await
|
|
35054
|
+
await mkdir20(dirname18(path), { recursive: true });
|
|
34752
35055
|
await writeFile19(path, generated.workflow);
|
|
34753
35056
|
}
|
|
34754
35057
|
return {
|
|
@@ -34767,20 +35070,20 @@ init_materializedBundle();
|
|
|
34767
35070
|
init_mobilePreview();
|
|
34768
35071
|
|
|
34769
35072
|
// src/mobile/nativeDeepLinks.ts
|
|
34770
|
-
import { readFile as
|
|
34771
|
-
import { join as
|
|
35073
|
+
import { readFile as readFile25, rename as rename16, writeFile as writeFile20 } from "fs/promises";
|
|
35074
|
+
import { join as join28 } from "path";
|
|
34772
35075
|
var START_MARKER = "<!-- absolutejs:deep-links:start -->";
|
|
34773
35076
|
var END_MARKER = "<!-- absolutejs:deep-links:end -->";
|
|
34774
35077
|
var IOS_ENTITLEMENTS = "App/AbsoluteJS.entitlements";
|
|
34775
35078
|
var NOT_FOUND = -1;
|
|
34776
35079
|
var escapeXml = (value) => value.replaceAll("&", "&").replaceAll('"', """).replaceAll("'", "'").replaceAll("<", "<").replaceAll(">", ">");
|
|
34777
35080
|
var writeChangedFile = async (path, source) => {
|
|
34778
|
-
const current = await
|
|
35081
|
+
const current = await readFile25(path, "utf8");
|
|
34779
35082
|
if (current === source)
|
|
34780
35083
|
return false;
|
|
34781
35084
|
const temporary = `${path}.${crypto.randomUUID()}.tmp`;
|
|
34782
35085
|
await writeFile20(temporary, source, { flag: "wx" });
|
|
34783
|
-
await
|
|
35086
|
+
await rename16(temporary, path);
|
|
34784
35087
|
return true;
|
|
34785
35088
|
};
|
|
34786
35089
|
var replaceManagedRegion = (source, region, insertAt) => {
|
|
@@ -34825,8 +35128,8 @@ ${hosts}
|
|
|
34825
35128
|
`;
|
|
34826
35129
|
};
|
|
34827
35130
|
var configureAndroid = async (config) => {
|
|
34828
|
-
const path =
|
|
34829
|
-
const source = await
|
|
35131
|
+
const path = join28(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
|
|
35132
|
+
const source = await readFile25(path, "utf8");
|
|
34830
35133
|
const mainActivity = source.indexOf('android:name=".MainActivity"');
|
|
34831
35134
|
if (mainActivity === NOT_FOUND) {
|
|
34832
35135
|
throw new TypeError("Android MainActivity was not found.");
|
|
@@ -34851,8 +35154,8 @@ var iosSchemeRegion = (scheme) => ` ${START_MARKER}
|
|
|
34851
35154
|
${END_MARKER}
|
|
34852
35155
|
`;
|
|
34853
35156
|
var configureIosInfo = async (config) => {
|
|
34854
|
-
const path =
|
|
34855
|
-
const source = await
|
|
35157
|
+
const path = join28(config.nativeProjectDirectory, "ios/App/App/Info.plist");
|
|
35158
|
+
const source = await readFile25(path, "utf8");
|
|
34856
35159
|
const region = config.deepLinkScheme ? iosSchemeRegion(config.deepLinkScheme) : ` ${START_MARKER}
|
|
34857
35160
|
${END_MARKER}
|
|
34858
35161
|
`;
|
|
@@ -34875,10 +35178,10 @@ ${domains}
|
|
|
34875
35178
|
`;
|
|
34876
35179
|
};
|
|
34877
35180
|
var configureIosEntitlements = async (config) => {
|
|
34878
|
-
const path =
|
|
35181
|
+
const path = join28(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
|
|
34879
35182
|
let current = "";
|
|
34880
35183
|
try {
|
|
34881
|
-
current = await
|
|
35184
|
+
current = await readFile25(path, "utf8");
|
|
34882
35185
|
} catch (error) {
|
|
34883
35186
|
if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
|
|
34884
35187
|
throw error;
|
|
@@ -34889,12 +35192,12 @@ var configureIosEntitlements = async (config) => {
|
|
|
34889
35192
|
return false;
|
|
34890
35193
|
const temporary = `${path}.${crypto.randomUUID()}.tmp`;
|
|
34891
35194
|
await writeFile20(temporary, source, { flag: "wx" });
|
|
34892
|
-
await
|
|
35195
|
+
await rename16(temporary, path);
|
|
34893
35196
|
return true;
|
|
34894
35197
|
};
|
|
34895
35198
|
var configureIosProject = async (config) => {
|
|
34896
|
-
const path =
|
|
34897
|
-
const source = await
|
|
35199
|
+
const path = join28(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
|
|
35200
|
+
const source = await readFile25(path, "utf8");
|
|
34898
35201
|
const declarations = [
|
|
34899
35202
|
...source.matchAll(/CODE_SIGN_ENTITLEMENTS = ([^;]+);/g)
|
|
34900
35203
|
].map((match) => match[1]);
|
|
@@ -34933,8 +35236,8 @@ var applyAbsoluteNativeDeepLinks = async (config, platforms = config.platforms)
|
|
|
34933
35236
|
};
|
|
34934
35237
|
// src/mobile/nativeDeviceCapabilities.ts
|
|
34935
35238
|
init_deviceCapabilities();
|
|
34936
|
-
import { readFile as
|
|
34937
|
-
import { join as
|
|
35239
|
+
import { readFile as readFile26, rename as rename17, writeFile as writeFile21 } from "fs/promises";
|
|
35240
|
+
import { join as join29 } from "path";
|
|
34938
35241
|
var START_MARKER2 = "<!-- absolutejs:device-capabilities:start -->";
|
|
34939
35242
|
var END_MARKER2 = "<!-- absolutejs:device-capabilities:end -->";
|
|
34940
35243
|
var NOT_FOUND2 = -1;
|
|
@@ -34944,12 +35247,12 @@ var PUSH_START_MARKER = "absolutejs:push-notifications:start";
|
|
|
34944
35247
|
var PUSH_END_MARKER = "absolutejs:push-notifications:end";
|
|
34945
35248
|
var escapeXml2 = (value) => value.replaceAll("&", "&").replaceAll('"', """).replaceAll("'", "'").replaceAll("<", "<").replaceAll(">", ">");
|
|
34946
35249
|
var writeChangedFile2 = async (path, source) => {
|
|
34947
|
-
const current = await
|
|
35250
|
+
const current = await readFile26(path, "utf8");
|
|
34948
35251
|
if (current === source)
|
|
34949
35252
|
return false;
|
|
34950
35253
|
const temporary = `${path}.${crypto.randomUUID()}.tmp`;
|
|
34951
35254
|
await writeFile21(temporary, source, { flag: "wx" });
|
|
34952
|
-
await
|
|
35255
|
+
await rename17(temporary, path);
|
|
34953
35256
|
return true;
|
|
34954
35257
|
};
|
|
34955
35258
|
var writeOptionalChangedFile = async (path, source) => {
|
|
@@ -34964,7 +35267,7 @@ var writeOptionalChangedFile = async (path, source) => {
|
|
|
34964
35267
|
};
|
|
34965
35268
|
var optionalSource = async (path) => {
|
|
34966
35269
|
try {
|
|
34967
|
-
return await
|
|
35270
|
+
return await readFile26(path, "utf8");
|
|
34968
35271
|
} catch (error) {
|
|
34969
35272
|
if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
|
|
34970
35273
|
return null;
|
|
@@ -35084,8 +35387,8 @@ var writeIosPrivacyManifest = async (path, current, source) => {
|
|
|
35084
35387
|
var configureIosPrivacyProject = async (config, requirements) => {
|
|
35085
35388
|
if (requirements.iosPrivacyAccessedApis.length === 0)
|
|
35086
35389
|
return false;
|
|
35087
|
-
const projectPath3 =
|
|
35088
|
-
const project = await
|
|
35390
|
+
const projectPath3 = join29(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
|
|
35391
|
+
const project = await readFile26(projectPath3, "utf8");
|
|
35089
35392
|
return writeChangedFile2(projectPath3, addIosPrivacyProjectReference(project));
|
|
35090
35393
|
};
|
|
35091
35394
|
var addIosPrivacyProjectReference = (source) => {
|
|
@@ -35137,8 +35440,8 @@ ${next.slice(index)}`;
|
|
|
35137
35440
|
return next;
|
|
35138
35441
|
};
|
|
35139
35442
|
var configureIos2 = async (config, plan) => {
|
|
35140
|
-
const path =
|
|
35141
|
-
const source = await
|
|
35443
|
+
const path = join29(config.nativeProjectDirectory, "ios/App/App/Info.plist");
|
|
35444
|
+
const source = await readFile26(path, "utf8");
|
|
35142
35445
|
const requirements = absoluteDeviceNativeRequirements(plan);
|
|
35143
35446
|
const existingSystemBars = source.match(/<key>UIViewControllerBasedStatusBarAppearance<\/key>\s*<(true|false)\s*\/>/u);
|
|
35144
35447
|
const ownedStart = source.indexOf(START_MARKER2);
|
|
@@ -35158,7 +35461,7 @@ ${content}
|
|
|
35158
35461
|
${END_MARKER2}
|
|
35159
35462
|
` : "";
|
|
35160
35463
|
const infoChanged = await writeChangedFile2(path, managed(source, region, source.lastIndexOf("</dict>")));
|
|
35161
|
-
const privacyPath =
|
|
35464
|
+
const privacyPath = join29(config.nativeProjectDirectory, "ios/App/App/PrivacyInfo.xcprivacy");
|
|
35162
35465
|
const privacyCurrent = await optionalSource(privacyPath);
|
|
35163
35466
|
const privacySource = privacyManifestSource(privacyCurrent, requirements);
|
|
35164
35467
|
const [privacyChanged, projectChanged, pushChanged] = await Promise.all([
|
|
@@ -35169,7 +35472,7 @@ ${content}
|
|
|
35169
35472
|
return infoChanged || privacyChanged || projectChanged || pushChanged;
|
|
35170
35473
|
};
|
|
35171
35474
|
var configureIosPushNotifications = async (config, enabled) => {
|
|
35172
|
-
const entitlementsPath =
|
|
35475
|
+
const entitlementsPath = join29(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
|
|
35173
35476
|
const entitlements = await optionalSource(entitlementsPath);
|
|
35174
35477
|
if (entitlements === null && !enabled)
|
|
35175
35478
|
return false;
|
|
@@ -35181,7 +35484,7 @@ var configureIosPushNotifications = async (config, enabled) => {
|
|
|
35181
35484
|
<!-- ${PUSH_END_MARKER} -->
|
|
35182
35485
|
` : "";
|
|
35183
35486
|
const nextEntitlements = replacePushRegion(entitlements, entitlementRegion, entitlements.lastIndexOf("</dict>"));
|
|
35184
|
-
const delegatePath =
|
|
35487
|
+
const delegatePath = join29(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
|
|
35185
35488
|
const delegate = await optionalSource(delegatePath);
|
|
35186
35489
|
if (delegate === null && !enabled)
|
|
35187
35490
|
return false;
|
|
@@ -35230,8 +35533,8 @@ var replacePushRegion = (source, region, insertion) => {
|
|
|
35230
35533
|
return `${source.slice(0, insertion)}${region}${source.slice(insertion)}`;
|
|
35231
35534
|
};
|
|
35232
35535
|
var configureAndroid2 = async (config, plan) => {
|
|
35233
|
-
const path =
|
|
35234
|
-
const source = await
|
|
35536
|
+
const path = join29(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
|
|
35537
|
+
const source = await readFile26(path, "utf8");
|
|
35235
35538
|
const permissions = absoluteDeviceNativeRequirements(plan).androidPermissions;
|
|
35236
35539
|
const content = permissions.map((permission) => ` <uses-permission android:name="${escapeXml2(permission)}" />`).join(`
|
|
35237
35540
|
`);
|
|
@@ -35266,7 +35569,7 @@ ${content}
|
|
|
35266
35569
|
throw new TypeError(`Android google-services.json does not contain package ${config.appId}.`);
|
|
35267
35570
|
const [manifestChanged, firebaseChanged] = await Promise.all([
|
|
35268
35571
|
writeChangedFile2(path, nextManifest),
|
|
35269
|
-
writeOptionalChangedFile(
|
|
35572
|
+
writeOptionalChangedFile(join29(config.nativeProjectDirectory, "android/app/google-services.json"), firebaseSource)
|
|
35270
35573
|
]);
|
|
35271
35574
|
return manifestChanged || firebaseChanged;
|
|
35272
35575
|
};
|
|
@@ -35285,14 +35588,14 @@ init_nativeAuth();
|
|
|
35285
35588
|
|
|
35286
35589
|
// src/mobile/nativeUpdates.ts
|
|
35287
35590
|
import {
|
|
35288
|
-
mkdir as
|
|
35289
|
-
readFile as
|
|
35290
|
-
readdir as
|
|
35291
|
-
rename as
|
|
35292
|
-
rm as
|
|
35591
|
+
mkdir as mkdir21,
|
|
35592
|
+
readFile as readFile27,
|
|
35593
|
+
readdir as readdir9,
|
|
35594
|
+
rename as rename18,
|
|
35595
|
+
rm as rm16,
|
|
35293
35596
|
writeFile as writeFile22
|
|
35294
35597
|
} from "fs/promises";
|
|
35295
|
-
import { dirname as
|
|
35598
|
+
import { dirname as dirname20, join as join30 } from "path";
|
|
35296
35599
|
var START = "// absolutejs:mobile-updates:start";
|
|
35297
35600
|
var END = "// absolutejs:mobile-updates:end";
|
|
35298
35601
|
var PLUGIN_START = "// absolutejs:mobile-update-plugin:start";
|
|
@@ -35300,32 +35603,32 @@ var PLUGIN_END = "// absolutejs:mobile-update-plugin:end";
|
|
|
35300
35603
|
var ANDROID_PLUGIN = "AbsoluteMobileUpdateWatchdogPlugin.java";
|
|
35301
35604
|
var optionalSource2 = async (path) => {
|
|
35302
35605
|
try {
|
|
35303
|
-
return await
|
|
35606
|
+
return await readFile27(path, "utf8");
|
|
35304
35607
|
} catch (error) {
|
|
35305
35608
|
if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
|
|
35306
35609
|
return null;
|
|
35307
35610
|
throw error;
|
|
35308
35611
|
}
|
|
35309
35612
|
};
|
|
35310
|
-
var
|
|
35613
|
+
var isRecord16 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
35311
35614
|
var writeChanged = async (path, source) => {
|
|
35312
35615
|
const current = await optionalSource2(path);
|
|
35313
35616
|
if (current === source)
|
|
35314
35617
|
return false;
|
|
35315
|
-
await
|
|
35618
|
+
await mkdir21(dirname20(path), { recursive: true });
|
|
35316
35619
|
if (current === null) {
|
|
35317
35620
|
await writeFile22(path, source, { flag: "wx" });
|
|
35318
35621
|
return true;
|
|
35319
35622
|
}
|
|
35320
35623
|
const temporary = `${path}.${crypto.randomUUID()}.tmp`;
|
|
35321
35624
|
await writeFile22(temporary, source, { flag: "wx" });
|
|
35322
|
-
await
|
|
35625
|
+
await rename18(temporary, path);
|
|
35323
35626
|
return true;
|
|
35324
35627
|
};
|
|
35325
35628
|
var removeOwnedFile = async (path) => {
|
|
35326
35629
|
if (await optionalSource2(path) === null)
|
|
35327
35630
|
return false;
|
|
35328
|
-
await
|
|
35631
|
+
await rm16(path);
|
|
35329
35632
|
return true;
|
|
35330
35633
|
};
|
|
35331
35634
|
var replaceMarkedRegion = (source, start, end, region, insertion, error) => {
|
|
@@ -35462,9 +35765,9 @@ public final class AbsoluteMobileUpdateWatchdogPlugin: CAPPlugin, CAPBridgedPlug
|
|
|
35462
35765
|
${PLUGIN_END}
|
|
35463
35766
|
`;
|
|
35464
35767
|
var configureIos3 = async (config, enabled) => {
|
|
35465
|
-
const path =
|
|
35466
|
-
const capacitorConfigPath =
|
|
35467
|
-
let source = await
|
|
35768
|
+
const path = join30(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
|
|
35769
|
+
const capacitorConfigPath = join30(config.nativeProjectDirectory, "ios/App/App/capacitor.config.json");
|
|
35770
|
+
let source = await readFile27(path, "utf8");
|
|
35468
35771
|
const launch2 = source.indexOf("didFinishLaunchingWithOptions");
|
|
35469
35772
|
const brace = launch2 < 0 ? -1 : source.indexOf("{", launch2);
|
|
35470
35773
|
const launchRegion = enabled ? ` ${START}
|
|
@@ -35475,11 +35778,11 @@ var configureIos3 = async (config, enabled) => {
|
|
|
35475
35778
|
`, brace) + 1, "Could not find a safe iOS location for mobile update recovery.");
|
|
35476
35779
|
const plugin = enabled ? iosPluginRegion(config.updates?.bootTimeoutMs ?? 20000) : "";
|
|
35477
35780
|
source = replaceMarkedRegion(source, PLUGIN_START, PLUGIN_END, plugin, source.length, "Could not find a safe iOS location for the mobile update watchdog.");
|
|
35478
|
-
const capacitorConfigSource2 = await
|
|
35781
|
+
const capacitorConfigSource2 = await readFile27(capacitorConfigPath, "utf8");
|
|
35479
35782
|
let capacitorConfig;
|
|
35480
35783
|
try {
|
|
35481
35784
|
const value = JSON.parse(capacitorConfigSource2);
|
|
35482
|
-
if (!
|
|
35785
|
+
if (!isRecord16(value))
|
|
35483
35786
|
throw new TypeError;
|
|
35484
35787
|
capacitorConfig = value;
|
|
35485
35788
|
} catch {
|
|
@@ -35648,19 +35951,19 @@ public final class AbsoluteMobileUpdateWatchdogPlugin extends Plugin {
|
|
|
35648
35951
|
var androidActivityInRoot = async (root) => {
|
|
35649
35952
|
let entries;
|
|
35650
35953
|
try {
|
|
35651
|
-
entries = await
|
|
35954
|
+
entries = await readdir9(root, { recursive: true });
|
|
35652
35955
|
} catch (error) {
|
|
35653
35956
|
if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
|
|
35654
35957
|
return;
|
|
35655
35958
|
throw error;
|
|
35656
35959
|
}
|
|
35657
35960
|
const candidate = entries.find((entry) => entry.endsWith("/MainActivity.java") || entry.endsWith("/MainActivity.kt") || entry === "MainActivity.java" || entry === "MainActivity.kt");
|
|
35658
|
-
return candidate ?
|
|
35961
|
+
return candidate ? join30(root, candidate) : undefined;
|
|
35659
35962
|
};
|
|
35660
35963
|
var androidActivity = async (config) => {
|
|
35661
35964
|
const roots = [
|
|
35662
|
-
|
|
35663
|
-
|
|
35965
|
+
join30(config.nativeProjectDirectory, "android/app/src/main/java"),
|
|
35966
|
+
join30(config.nativeProjectDirectory, "android/app/src/main/kotlin")
|
|
35664
35967
|
];
|
|
35665
35968
|
const candidates = await Promise.all(roots.map(androidActivityInRoot));
|
|
35666
35969
|
const candidate = candidates.find((value) => value !== undefined);
|
|
@@ -35759,12 +36062,12 @@ var injectAndroidActivity = (source, enabled) => {
|
|
|
35759
36062
|
};
|
|
35760
36063
|
var configureAndroid3 = async (config, enabled) => {
|
|
35761
36064
|
const activityPath = await androidActivity(config);
|
|
35762
|
-
const activity = await
|
|
36065
|
+
const activity = await readFile27(activityPath, "utf8");
|
|
35763
36066
|
const packageName = activity.match(/^\s*package\s+([A-Za-z0-9_.]+)\s*[;\n]/mu)?.[1];
|
|
35764
36067
|
if (!packageName)
|
|
35765
36068
|
throw new TypeError("Android MainActivity package declaration was not found.");
|
|
35766
36069
|
const packagePath = packageName.replaceAll(".", "/");
|
|
35767
|
-
const pluginPath =
|
|
36070
|
+
const pluginPath = join30(config.nativeProjectDirectory, "android/app/src/main/java", packagePath, ANDROID_PLUGIN);
|
|
35768
36071
|
const changed = await Promise.all([
|
|
35769
36072
|
writeChanged(activityPath, injectAndroidActivity(activity, enabled)),
|
|
35770
36073
|
enabled ? writeChanged(pluginPath, androidPluginSource(packageName, config.updates?.bootTimeoutMs ?? 20000)) : removeOwnedFile(pluginPath)
|
|
@@ -35784,14 +36087,14 @@ var applyAbsoluteNativeUpdates = async (config, platforms = config.platforms) =>
|
|
|
35784
36087
|
};
|
|
35785
36088
|
// src/mobile/nativeObservability.ts
|
|
35786
36089
|
import {
|
|
35787
|
-
mkdir as
|
|
35788
|
-
readFile as
|
|
35789
|
-
readdir as
|
|
35790
|
-
rename as
|
|
35791
|
-
rm as
|
|
36090
|
+
mkdir as mkdir22,
|
|
36091
|
+
readFile as readFile28,
|
|
36092
|
+
readdir as readdir10,
|
|
36093
|
+
rename as rename19,
|
|
36094
|
+
rm as rm17,
|
|
35792
36095
|
writeFile as writeFile23
|
|
35793
36096
|
} from "fs/promises";
|
|
35794
|
-
import { dirname as
|
|
36097
|
+
import { dirname as dirname21, join as join31 } from "path";
|
|
35795
36098
|
var START2 = "// absolutejs:native-observability:start";
|
|
35796
36099
|
var END2 = "// absolutejs:native-observability:end";
|
|
35797
36100
|
var PLUGIN_START2 = "// absolutejs:native-observability-plugin:start";
|
|
@@ -35799,7 +36102,7 @@ var PLUGIN_END2 = "// absolutejs:native-observability-plugin:end";
|
|
|
35799
36102
|
var ANDROID_PLUGIN2 = "AbsoluteMobileObservabilityPlugin.java";
|
|
35800
36103
|
var optionalSource3 = async (path) => {
|
|
35801
36104
|
try {
|
|
35802
|
-
return await
|
|
36105
|
+
return await readFile28(path, "utf8");
|
|
35803
36106
|
} catch (error) {
|
|
35804
36107
|
if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
|
|
35805
36108
|
return null;
|
|
@@ -35810,23 +36113,23 @@ var writeChanged2 = async (path, source) => {
|
|
|
35810
36113
|
const current = await optionalSource3(path);
|
|
35811
36114
|
if (current === source)
|
|
35812
36115
|
return false;
|
|
35813
|
-
await
|
|
36116
|
+
await mkdir22(dirname21(path), { recursive: true });
|
|
35814
36117
|
if (current === null) {
|
|
35815
36118
|
await writeFile23(path, source, { flag: "wx" });
|
|
35816
36119
|
return true;
|
|
35817
36120
|
}
|
|
35818
36121
|
const temporary = `${path}.${crypto.randomUUID()}.tmp`;
|
|
35819
36122
|
await writeFile23(temporary, source, { flag: "wx" });
|
|
35820
|
-
await
|
|
36123
|
+
await rename19(temporary, path);
|
|
35821
36124
|
return true;
|
|
35822
36125
|
};
|
|
35823
36126
|
var removeOwnedFile2 = async (path) => {
|
|
35824
36127
|
if (await optionalSource3(path) === null)
|
|
35825
36128
|
return false;
|
|
35826
|
-
await
|
|
36129
|
+
await rm17(path);
|
|
35827
36130
|
return true;
|
|
35828
36131
|
};
|
|
35829
|
-
var
|
|
36132
|
+
var isRecord17 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
35830
36133
|
var replaceMarkedRegion2 = (source, start, end, region, insertion, error) => {
|
|
35831
36134
|
const existingStart = source.indexOf(start);
|
|
35832
36135
|
const existingEnd = source.indexOf(end);
|
|
@@ -35959,9 +36262,9 @@ public final class AbsoluteMobileObservabilityPlugin: CAPPlugin, CAPBridgedPlugi
|
|
|
35959
36262
|
${PLUGIN_END2}
|
|
35960
36263
|
`;
|
|
35961
36264
|
var configureIos4 = async (config, enabled) => {
|
|
35962
|
-
const path =
|
|
35963
|
-
const capacitorConfigPath =
|
|
35964
|
-
let source = await
|
|
36265
|
+
const path = join31(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
|
|
36266
|
+
const capacitorConfigPath = join31(config.nativeProjectDirectory, "ios/App/App/capacitor.config.json");
|
|
36267
|
+
let source = await readFile28(path, "utf8");
|
|
35965
36268
|
if (enabled && !source.includes("import MetricKit")) {
|
|
35966
36269
|
const capacitorImport = source.lastIndexOf("import Capacitor");
|
|
35967
36270
|
if (capacitorImport < 0)
|
|
@@ -35975,11 +36278,11 @@ ${source.slice(newline + 1)}`;
|
|
|
35975
36278
|
source = source.replace(`import MetricKit
|
|
35976
36279
|
`, "");
|
|
35977
36280
|
source = replaceMarkedRegion2(source, PLUGIN_START2, PLUGIN_END2, enabled ? iosPluginRegion2 : "", source.length, "Could not find a safe iOS location for native observability.");
|
|
35978
|
-
const capacitorConfigSource2 = await
|
|
36281
|
+
const capacitorConfigSource2 = await readFile28(capacitorConfigPath, "utf8");
|
|
35979
36282
|
let capacitorConfig;
|
|
35980
36283
|
try {
|
|
35981
36284
|
const value = JSON.parse(capacitorConfigSource2);
|
|
35982
|
-
if (!
|
|
36285
|
+
if (!isRecord17(value))
|
|
35983
36286
|
throw new TypeError;
|
|
35984
36287
|
capacitorConfig = value;
|
|
35985
36288
|
} catch {
|
|
@@ -36213,19 +36516,19 @@ public final class AbsoluteMobileObservabilityPlugin extends Plugin {
|
|
|
36213
36516
|
var androidActivityInRoot2 = async (root) => {
|
|
36214
36517
|
let entries;
|
|
36215
36518
|
try {
|
|
36216
|
-
entries = await
|
|
36519
|
+
entries = await readdir10(root, { recursive: true });
|
|
36217
36520
|
} catch (error) {
|
|
36218
36521
|
if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
|
|
36219
36522
|
return;
|
|
36220
36523
|
throw error;
|
|
36221
36524
|
}
|
|
36222
36525
|
const candidate = entries.find((entry) => entry.endsWith("/MainActivity.java") || entry.endsWith("/MainActivity.kt") || entry === "MainActivity.java" || entry === "MainActivity.kt");
|
|
36223
|
-
return candidate ?
|
|
36526
|
+
return candidate ? join31(root, candidate) : undefined;
|
|
36224
36527
|
};
|
|
36225
36528
|
var androidActivity2 = async (config) => {
|
|
36226
36529
|
const roots = [
|
|
36227
|
-
|
|
36228
|
-
|
|
36530
|
+
join31(config.nativeProjectDirectory, "android/app/src/main/java"),
|
|
36531
|
+
join31(config.nativeProjectDirectory, "android/app/src/main/kotlin")
|
|
36229
36532
|
];
|
|
36230
36533
|
const candidates = await Promise.all(roots.map(androidActivityInRoot2));
|
|
36231
36534
|
const candidate = candidates.find((value) => value !== undefined);
|
|
@@ -36293,11 +36596,11 @@ var injectAndroidActivity2 = (source, enabled) => {
|
|
|
36293
36596
|
};
|
|
36294
36597
|
var configureAndroid4 = async (config, enabled) => {
|
|
36295
36598
|
const activityPath = await androidActivity2(config);
|
|
36296
|
-
const activity = await
|
|
36599
|
+
const activity = await readFile28(activityPath, "utf8");
|
|
36297
36600
|
const packageName = activity.match(/^\s*package\s+([A-Za-z0-9_.]+)\s*[;\n]/mu)?.[1];
|
|
36298
36601
|
if (!packageName)
|
|
36299
36602
|
throw new TypeError("Android MainActivity package declaration was not found.");
|
|
36300
|
-
const pluginPath =
|
|
36603
|
+
const pluginPath = join31(config.nativeProjectDirectory, "android/app/src/main/java", packageName.replaceAll(".", "/"), ANDROID_PLUGIN2);
|
|
36301
36604
|
const changed = await Promise.all([
|
|
36302
36605
|
writeChanged2(activityPath, injectAndroidActivity2(activity, enabled)),
|
|
36303
36606
|
enabled ? writeChanged2(pluginPath, androidPluginSource2(packageName)) : removeOwnedFile2(pluginPath)
|
|
@@ -36316,8 +36619,8 @@ var applyAbsoluteNativeObservability = async (config, platforms = config.platfor
|
|
|
36316
36619
|
return { changed: changed.some(Boolean) };
|
|
36317
36620
|
};
|
|
36318
36621
|
// src/mobile/nativeReleaseReadiness.ts
|
|
36319
|
-
import { mkdir as
|
|
36320
|
-
import { dirname as
|
|
36622
|
+
import { mkdir as mkdir23, readFile as readFile29, readdir as readdir11, rename as rename20, writeFile as writeFile24 } from "fs/promises";
|
|
36623
|
+
import { dirname as dirname22, join as join32 } from "path";
|
|
36321
36624
|
var START3 = "// absolutejs:release-readiness:start";
|
|
36322
36625
|
var END3 = "// absolutejs:release-readiness:end";
|
|
36323
36626
|
var IOS_PLUGIN_START = "// absolutejs:release-readiness-plugin:start";
|
|
@@ -36325,7 +36628,7 @@ var IOS_PLUGIN_END = "// absolutejs:release-readiness-plugin:end";
|
|
|
36325
36628
|
var ANDROID_PLUGIN3 = "AbsoluteReleaseReadinessPlugin.java";
|
|
36326
36629
|
var optionalSource4 = async (path) => {
|
|
36327
36630
|
try {
|
|
36328
|
-
return await
|
|
36631
|
+
return await readFile29(path, "utf8");
|
|
36329
36632
|
} catch (error) {
|
|
36330
36633
|
if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
|
|
36331
36634
|
return null;
|
|
@@ -36336,32 +36639,32 @@ var writeChanged3 = async (path, source) => {
|
|
|
36336
36639
|
const current = await optionalSource4(path);
|
|
36337
36640
|
if (current === source)
|
|
36338
36641
|
return false;
|
|
36339
|
-
await
|
|
36642
|
+
await mkdir23(dirname22(path), { recursive: true });
|
|
36340
36643
|
if (current === null) {
|
|
36341
36644
|
await writeFile24(path, source, { flag: "wx" });
|
|
36342
36645
|
return true;
|
|
36343
36646
|
}
|
|
36344
36647
|
const temporary = `${path}.${crypto.randomUUID()}.tmp`;
|
|
36345
36648
|
await writeFile24(temporary, source, { flag: "wx" });
|
|
36346
|
-
await
|
|
36649
|
+
await rename20(temporary, path);
|
|
36347
36650
|
return true;
|
|
36348
36651
|
};
|
|
36349
36652
|
var activityInRoot = async (root) => {
|
|
36350
36653
|
let entries;
|
|
36351
36654
|
try {
|
|
36352
|
-
entries = await
|
|
36655
|
+
entries = await readdir11(root, { recursive: true });
|
|
36353
36656
|
} catch (error) {
|
|
36354
36657
|
if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "ENOENT")
|
|
36355
36658
|
return;
|
|
36356
36659
|
throw error;
|
|
36357
36660
|
}
|
|
36358
36661
|
const candidate = entries.find((entry) => entry.endsWith("/MainActivity.java") || entry.endsWith("/MainActivity.kt") || entry === "MainActivity.java" || entry === "MainActivity.kt");
|
|
36359
|
-
return candidate ?
|
|
36662
|
+
return candidate ? join32(root, candidate) : undefined;
|
|
36360
36663
|
};
|
|
36361
36664
|
var activityPath = async (config) => {
|
|
36362
36665
|
const roots = [
|
|
36363
|
-
|
|
36364
|
-
|
|
36666
|
+
join32(config.nativeProjectDirectory, "android/app/src/main/java"),
|
|
36667
|
+
join32(config.nativeProjectDirectory, "android/app/src/main/kotlin")
|
|
36365
36668
|
];
|
|
36366
36669
|
const candidates = await Promise.all(roots.map(activityInRoot));
|
|
36367
36670
|
const candidate = candidates.find((value) => value !== undefined);
|
|
@@ -36471,9 +36774,9 @@ var replaceIosPluginRegion = (appDelegate, existingStart, existingEnd) => {
|
|
|
36471
36774
|
return `${appDelegate.slice(0, from)}${iosPluginRegion3}${appDelegate.slice(through)}`;
|
|
36472
36775
|
};
|
|
36473
36776
|
var configureIos5 = async (config) => {
|
|
36474
|
-
const appDelegatePath =
|
|
36475
|
-
const capacitorConfigPath =
|
|
36476
|
-
const appDelegate = await
|
|
36777
|
+
const appDelegatePath = join32(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
|
|
36778
|
+
const capacitorConfigPath = join32(config.nativeProjectDirectory, "ios/App/App/capacitor.config.json");
|
|
36779
|
+
const appDelegate = await readFile29(appDelegatePath, "utf8");
|
|
36477
36780
|
const existingStart = appDelegate.indexOf(IOS_PLUGIN_START);
|
|
36478
36781
|
const existingEnd = appDelegate.indexOf(IOS_PLUGIN_END);
|
|
36479
36782
|
if (existingStart < 0 !== existingEnd < 0 || existingStart >= 0 && existingEnd < existingStart)
|
|
@@ -36483,7 +36786,7 @@ var configureIos5 = async (config) => {
|
|
|
36483
36786
|
${iosPluginRegion3}` : replaceIosPluginRegion(appDelegate, existingStart, existingEnd);
|
|
36484
36787
|
let capacitorConfig;
|
|
36485
36788
|
try {
|
|
36486
|
-
capacitorConfig = JSON.parse(await
|
|
36789
|
+
capacitorConfig = JSON.parse(await readFile29(capacitorConfigPath, "utf8"));
|
|
36487
36790
|
} catch {
|
|
36488
36791
|
throw new TypeError("iOS capacitor.config.json is invalid; run Capacitor sync before projecting release readiness.");
|
|
36489
36792
|
}
|
|
@@ -36508,11 +36811,11 @@ ${iosPluginRegion3}` : replaceIosPluginRegion(appDelegate, existingStart, existi
|
|
|
36508
36811
|
};
|
|
36509
36812
|
var configureAndroid5 = async (config) => {
|
|
36510
36813
|
const mainActivityPath = await activityPath(config);
|
|
36511
|
-
const activity = await
|
|
36814
|
+
const activity = await readFile29(mainActivityPath, "utf8");
|
|
36512
36815
|
const packageName = activity.match(/^\s*package\s+([A-Za-z0-9_.]+)\s*[;\n]/mu)?.[1];
|
|
36513
36816
|
if (!packageName)
|
|
36514
36817
|
throw new TypeError("Android MainActivity package declaration was not found.");
|
|
36515
|
-
const pluginPath =
|
|
36818
|
+
const pluginPath = join32(config.nativeProjectDirectory, "android/app/src/main/java", packageName.replaceAll(".", "/"), ANDROID_PLUGIN3);
|
|
36516
36819
|
const changed = await Promise.all([
|
|
36517
36820
|
writeChanged3(mainActivityPath, injectRegistration(activity)),
|
|
36518
36821
|
writeChanged3(pluginPath, pluginSource(packageName))
|
|
@@ -36535,8 +36838,8 @@ init_producerContext();
|
|
|
36535
36838
|
init_releaseArtifact();
|
|
36536
36839
|
|
|
36537
36840
|
// src/mobile/releasePublisher.ts
|
|
36538
|
-
import { access as
|
|
36539
|
-
import { isAbsolute as
|
|
36841
|
+
import { access as access21 } from "fs/promises";
|
|
36842
|
+
import { isAbsolute as isAbsolute13, relative as relative20, resolve as resolve22, sep as sep15 } from "path";
|
|
36540
36843
|
import { pathToFileURL as pathToFileURL3 } from "url";
|
|
36541
36844
|
var prepareAbsoluteIosRelease = async (publisher, options) => {
|
|
36542
36845
|
if (typeof publisher.prepareIosRelease !== "function") {
|
|
@@ -36570,24 +36873,24 @@ var requireCertificationReceipt = (publication, certification, requirement, rele
|
|
|
36570
36873
|
if (verification && (!receipt.provenance || receipt.provenance.subject !== releaseId))
|
|
36571
36874
|
throw new TypeError("Native release registry did not retain trusted certification provenance.");
|
|
36572
36875
|
};
|
|
36573
|
-
var
|
|
36574
|
-
var isPublisher = (value) =>
|
|
36876
|
+
var isRecord18 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
36877
|
+
var isPublisher = (value) => isRecord18(value) && typeof value.publish === "function";
|
|
36575
36878
|
var publisherModulePath = (projectRoot, requested) => {
|
|
36576
|
-
const root =
|
|
36577
|
-
const path =
|
|
36578
|
-
const projectRelative =
|
|
36579
|
-
if (projectRelative === ".." || projectRelative.startsWith(`..${
|
|
36879
|
+
const root = resolve22(projectRoot);
|
|
36880
|
+
const path = resolve22(root, requested);
|
|
36881
|
+
const projectRelative = relative20(root, path);
|
|
36882
|
+
if (projectRelative === ".." || projectRelative.startsWith(`..${sep15}`) || isAbsolute13(projectRelative)) {
|
|
36580
36883
|
throw new TypeError("mobile publish --registry must remain inside the project.");
|
|
36581
36884
|
}
|
|
36582
36885
|
return path;
|
|
36583
36886
|
};
|
|
36584
36887
|
var loadAbsoluteNativeReleasePublisher = async (projectRoot, requestedModulePath) => {
|
|
36585
36888
|
const modulePath = publisherModulePath(projectRoot, requestedModulePath);
|
|
36586
|
-
await
|
|
36889
|
+
await access21(modulePath).catch(() => {
|
|
36587
36890
|
throw new TypeError(`Native release registry module does not exist: ${modulePath}`);
|
|
36588
36891
|
});
|
|
36589
36892
|
const loaded = await import(pathToFileURL3(modulePath).href);
|
|
36590
|
-
const publisher =
|
|
36893
|
+
const publisher = isRecord18(loaded) ? loaded.default ?? loaded.registry : undefined;
|
|
36591
36894
|
if (!isPublisher(publisher)) {
|
|
36592
36895
|
throw new TypeError("Native release registry module must default-export a registry with publish(options).");
|
|
36593
36896
|
}
|
|
@@ -36669,7 +36972,7 @@ var publishAbsoluteIosRelease = async (options) => {
|
|
|
36669
36972
|
init_pageProtocol();
|
|
36670
36973
|
init_releaseArtifact();
|
|
36671
36974
|
import { existsSync as existsSync7, readFileSync as readFileSync8 } from "fs";
|
|
36672
|
-
import { dirname as
|
|
36975
|
+
import { dirname as dirname23, extname as extname6, relative as relative21, resolve as resolve23 } from "path";
|
|
36673
36976
|
import ts2 from "typescript";
|
|
36674
36977
|
var ROUTE_METHODS = new Set(["get", "head"]);
|
|
36675
36978
|
var SOURCE_FILTER = /\.[cm]?[jt]sx?$/;
|
|
@@ -36720,7 +37023,7 @@ var PAGE_HANDLERS = new Map([
|
|
|
36720
37023
|
]
|
|
36721
37024
|
]);
|
|
36722
37025
|
var posixPath = (value) => value.replace(/\\/g, "/");
|
|
36723
|
-
var findTsconfig = (entry, projectRoot) => ts2.findConfigFile(
|
|
37026
|
+
var findTsconfig = (entry, projectRoot) => ts2.findConfigFile(dirname23(entry), existsSync7, "tsconfig.json") ?? ts2.findConfigFile(projectRoot, existsSync7, "tsconfig.json");
|
|
36724
37027
|
var createProgram = (entry, projectRoot) => {
|
|
36725
37028
|
const configPath2 = findTsconfig(entry, projectRoot);
|
|
36726
37029
|
if (!configPath2) {
|
|
@@ -36732,7 +37035,7 @@ var createProgram = (entry, projectRoot) => {
|
|
|
36732
37035
|
target: ts2.ScriptTarget.ESNext
|
|
36733
37036
|
});
|
|
36734
37037
|
}
|
|
36735
|
-
const parsed = ts2.parseJsonConfigFileContent(ts2.readConfigFile(configPath2, (path) => readFileSync8(path, "utf8")).config, ts2.sys,
|
|
37038
|
+
const parsed = ts2.parseJsonConfigFileContent(ts2.readConfigFile(configPath2, (path) => readFileSync8(path, "utf8")).config, ts2.sys, dirname23(configPath2));
|
|
36736
37039
|
if (!parsed.fileNames.includes(entry))
|
|
36737
37040
|
parsed.fileNames.push(entry);
|
|
36738
37041
|
return ts2.createProgram(parsed.fileNames, parsed.options);
|
|
@@ -36838,7 +37141,7 @@ var resolvePageIdentity = (expression, sourceFile, checker, projectRoot) => {
|
|
|
36838
37141
|
const declaration = symbol?.declarations?.[0];
|
|
36839
37142
|
const file = declaration?.getSourceFile().fileName ?? sourceFile.fileName;
|
|
36840
37143
|
const exportedName = symbol?.name ?? expression.getText(sourceFile);
|
|
36841
|
-
const source = posixPath(
|
|
37144
|
+
const source = posixPath(relative21(projectRoot, file));
|
|
36842
37145
|
return `${source}#${exportedName}`;
|
|
36843
37146
|
};
|
|
36844
37147
|
var resolveAlias = (symbol, checker) => {
|
|
@@ -37077,7 +37380,7 @@ var analyzeProgram = (program, projectRoot) => {
|
|
|
37077
37380
|
const checker = program.getTypeChecker();
|
|
37078
37381
|
const analyzed = new Map;
|
|
37079
37382
|
for (const sourceFile of program.getSourceFiles()) {
|
|
37080
|
-
const resolvedFile =
|
|
37383
|
+
const resolvedFile = resolve23(sourceFile.fileName);
|
|
37081
37384
|
if (!isProjectSource(sourceFile, resolvedFile, projectRoot))
|
|
37082
37385
|
continue;
|
|
37083
37386
|
const analysis = analyzeSourceFile(sourceFile, checker, projectRoot);
|
|
@@ -37170,14 +37473,14 @@ var transformFile = (source, fileName, analysis) => {
|
|
|
37170
37473
|
};
|
|
37171
37474
|
var ABSOLUTE_MOBILE_TRANSFORM_PROTOCOL = ABSOLUTE_MOBILE_PAGE_PROTOCOL_VERSION;
|
|
37172
37475
|
var createAbsoluteMobileRouteMetadataPlugin = (options) => {
|
|
37173
|
-
const projectRoot =
|
|
37174
|
-
const entry =
|
|
37476
|
+
const projectRoot = resolve23(options.projectRoot ?? process.cwd());
|
|
37477
|
+
const entry = resolve23(options.entry);
|
|
37175
37478
|
const analyzed = analyzeProgram(createProgram(entry, projectRoot), projectRoot);
|
|
37176
37479
|
return {
|
|
37177
37480
|
name: "absolute-mobile-route-metadata",
|
|
37178
37481
|
setup(build) {
|
|
37179
37482
|
build.onLoad({ filter: SOURCE_FILTER }, async ({ path }) => {
|
|
37180
|
-
const analysis = analyzed.get(
|
|
37483
|
+
const analysis = analyzed.get(resolve23(path));
|
|
37181
37484
|
if (!analysis)
|
|
37182
37485
|
return;
|
|
37183
37486
|
const source = await Bun.file(path).text();
|
|
@@ -37190,11 +37493,11 @@ var createAbsoluteMobileRouteMetadataPlugin = (options) => {
|
|
|
37190
37493
|
};
|
|
37191
37494
|
};
|
|
37192
37495
|
var inspectAbsoluteMobileRouteMetadata = (options) => {
|
|
37193
|
-
const projectRoot =
|
|
37194
|
-
const entry =
|
|
37496
|
+
const projectRoot = resolve23(options.projectRoot ?? process.cwd());
|
|
37497
|
+
const entry = resolve23(options.entry);
|
|
37195
37498
|
const analyzed = analyzeProgram(createProgram(entry, projectRoot), projectRoot);
|
|
37196
37499
|
return [...analyzed.entries()].flatMap(([file, analysis]) => [...analysis.byRouteCall.values()].map(({ metadata }) => ({
|
|
37197
|
-
file: posixPath(
|
|
37500
|
+
file: posixPath(relative21(projectRoot, file)),
|
|
37198
37501
|
metadata
|
|
37199
37502
|
})));
|
|
37200
37503
|
};
|
|
@@ -37528,7 +37831,7 @@ var createCapacitor = (win) => {
|
|
|
37528
37831
|
callbackId
|
|
37529
37832
|
}, callback);
|
|
37530
37833
|
};
|
|
37531
|
-
const p = new Promise((
|
|
37834
|
+
const p = new Promise((resolve24) => call.then(() => resolve24({ remove })));
|
|
37532
37835
|
p.remove = async () => {
|
|
37533
37836
|
console.warn(`Using addListener() without 'await' is deprecated.`);
|
|
37534
37837
|
await remove();
|
|
@@ -37733,11 +38036,11 @@ class CapacitorCookiesPluginWeb extends WebPlugin {
|
|
|
37733
38036
|
var CapacitorCookies = registerPlugin("CapacitorCookies", {
|
|
37734
38037
|
web: () => new CapacitorCookiesPluginWeb
|
|
37735
38038
|
});
|
|
37736
|
-
var readBlobAsBase64 = async (blob) => new Promise((
|
|
38039
|
+
var readBlobAsBase64 = async (blob) => new Promise((resolve24, reject) => {
|
|
37737
38040
|
const reader = new FileReader;
|
|
37738
38041
|
reader.onload = () => {
|
|
37739
38042
|
const base64String = reader.result;
|
|
37740
|
-
|
|
38043
|
+
resolve24(base64String.indexOf(",") >= 0 ? base64String.split(",")[1] : base64String);
|
|
37741
38044
|
};
|
|
37742
38045
|
reader.onerror = (error) => reject(error);
|
|
37743
38046
|
reader.readAsDataURL(blob);
|
|
@@ -37913,7 +38216,7 @@ var REPORT_KINDS = new Set([
|
|
|
37913
38216
|
"signal"
|
|
37914
38217
|
]);
|
|
37915
38218
|
var nativeObservability = registerPlugin("AbsoluteMobileObservability");
|
|
37916
|
-
var
|
|
38219
|
+
var isRecord19 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
37917
38220
|
var redactText = (value) => value.slice(0, MAX_STRING_LENGTH).replace(/\b(Bearer)\s+[A-Za-z0-9._~+/-]+=*/giu, "$1 [REDACTED]").replace(/([?&](?:access_token|api_?key|authorization|code|id_token|password|refresh_token|secret|token)=)[^&#\s]*/giu, "$1[REDACTED]").replace(/\b((?:access_?token|api_?key|authorization|client_?secret|cookie|id_?token|password|passwd|refresh_?token|secret|token)\s*[:=]\s*)[^,\s;]+/giu, "$1[REDACTED]").replace(/\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/gu, "[REDACTED]");
|
|
37918
38221
|
var redactValue = (value, depth = 0) => {
|
|
37919
38222
|
if (depth >= MAX_REDACTION_DEPTH)
|
|
@@ -37924,7 +38227,7 @@ var redactValue = (value, depth = 0) => {
|
|
|
37924
38227
|
return value;
|
|
37925
38228
|
if (Array.isArray(value))
|
|
37926
38229
|
return value.slice(0, 64).map((entry) => redactValue(entry, depth + 1));
|
|
37927
|
-
if (!
|
|
38230
|
+
if (!isRecord19(value))
|
|
37928
38231
|
return String(value).slice(0, MAX_STRING_LENGTH);
|
|
37929
38232
|
return Object.fromEntries(Object.entries(value).slice(0, 128).map(([key, entry]) => [
|
|
37930
38233
|
key,
|
|
@@ -37932,7 +38235,7 @@ var redactValue = (value, depth = 0) => {
|
|
|
37932
38235
|
]));
|
|
37933
38236
|
};
|
|
37934
38237
|
var parseReport = (value) => {
|
|
37935
|
-
if (!
|
|
38238
|
+
if (!isRecord19(value) || !isRecord19(value.details))
|
|
37936
38239
|
return;
|
|
37937
38240
|
if (typeof value.id !== "string" || !REPORT_ID.test(value.id))
|
|
37938
38241
|
return;
|
|
@@ -37943,7 +38246,7 @@ var parseReport = (value) => {
|
|
|
37943
38246
|
if (value.platform !== "android" && value.platform !== "ios")
|
|
37944
38247
|
return;
|
|
37945
38248
|
const details = redactValue(value.details);
|
|
37946
|
-
if (!
|
|
38249
|
+
if (!isRecord19(details))
|
|
37947
38250
|
return;
|
|
37948
38251
|
if (new TextEncoder().encode(JSON.stringify(details)).byteLength > MAX_DETAIL_BYTES)
|
|
37949
38252
|
return;
|
|
@@ -40755,13 +41058,13 @@ var createBeacon = (options) => {
|
|
|
40755
41058
|
}
|
|
40756
41059
|
};
|
|
40757
41060
|
const documentStylesAreReady = () => {
|
|
40758
|
-
const stylesheets = Array.from(document.querySelectorAll('link[rel~="stylesheet"]')).filter((
|
|
40759
|
-
if (
|
|
41061
|
+
const stylesheets = Array.from(document.querySelectorAll('link[rel~="stylesheet"]')).filter((link2) => {
|
|
41062
|
+
if (link2.disabled)
|
|
40760
41063
|
return false;
|
|
40761
|
-
const media =
|
|
41064
|
+
const media = link2.media.trim();
|
|
40762
41065
|
return media === "" || typeof window.matchMedia !== "function" || window.matchMedia(media).matches;
|
|
40763
41066
|
});
|
|
40764
|
-
if (!stylesheets.every((
|
|
41067
|
+
if (!stylesheets.every((link2) => link2.sheet !== null))
|
|
40765
41068
|
return false;
|
|
40766
41069
|
if (stylesheets.length === 0)
|
|
40767
41070
|
return true;
|
|
@@ -42397,8 +42700,8 @@ var createBeacon = (options) => {
|
|
|
42397
42700
|
if (await fontAvailable(element))
|
|
42398
42701
|
return;
|
|
42399
42702
|
if (confirmationMs > 0) {
|
|
42400
|
-
await new Promise((
|
|
42401
|
-
const timer2 = window.setTimeout(
|
|
42703
|
+
await new Promise((resolve24) => {
|
|
42704
|
+
const timer2 = window.setTimeout(resolve24, confirmationMs);
|
|
42402
42705
|
cleanups.push(() => window.clearTimeout(timer2));
|
|
42403
42706
|
});
|
|
42404
42707
|
if (document.visibilityState === "hidden")
|
|
@@ -42891,8 +43194,8 @@ var sheetById = (id) => {
|
|
|
42891
43194
|
const target = document.getElementById(id);
|
|
42892
43195
|
return target instanceof HTMLDialogElement && target.dataset.absoluteSheet !== undefined ? target : undefined;
|
|
42893
43196
|
};
|
|
42894
|
-
var dispatchSheet = (sheet,
|
|
42895
|
-
detail: { id: sheet.id, open }
|
|
43197
|
+
var dispatchSheet = (sheet, open2) => dispatchEvent(new CustomEvent(SHEET_EVENT, {
|
|
43198
|
+
detail: { id: sheet.id, open: open2 }
|
|
42896
43199
|
}));
|
|
42897
43200
|
var focusSheet = (sheet) => {
|
|
42898
43201
|
const target = sheet.querySelector('[autofocus], button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
|
|
@@ -43386,51 +43689,51 @@ var createAbsoluteMobileUpdateClient = (options) => {
|
|
|
43386
43689
|
};
|
|
43387
43690
|
};
|
|
43388
43691
|
// src/mobile/updatePublisher.ts
|
|
43389
|
-
import { access as
|
|
43390
|
-
import { isAbsolute as
|
|
43692
|
+
import { access as access22 } from "fs/promises";
|
|
43693
|
+
import { isAbsolute as isAbsolute14, relative as relative23, resolve as resolve25, sep as sep16 } from "path";
|
|
43391
43694
|
import { pathToFileURL as pathToFileURL4 } from "url";
|
|
43392
43695
|
|
|
43393
43696
|
// src/mobile/updateSigning.ts
|
|
43394
43697
|
import { createHash as createHash17, sign, verify } from "crypto";
|
|
43395
43698
|
import {
|
|
43396
43699
|
cp as cp2,
|
|
43397
|
-
mkdir as
|
|
43700
|
+
mkdir as mkdir24,
|
|
43398
43701
|
mkdtemp as mkdtemp12,
|
|
43399
|
-
readdir as
|
|
43400
|
-
readFile as
|
|
43401
|
-
rename as
|
|
43402
|
-
rm as
|
|
43702
|
+
readdir as readdir12,
|
|
43703
|
+
readFile as readFile30,
|
|
43704
|
+
rename as rename21,
|
|
43705
|
+
rm as rm18,
|
|
43403
43706
|
stat as stat8,
|
|
43404
43707
|
writeFile as writeFile25
|
|
43405
43708
|
} from "fs/promises";
|
|
43406
|
-
import { dirname as
|
|
43709
|
+
import { dirname as dirname24, join as join33, relative as relative22, resolve as resolve24 } from "path";
|
|
43407
43710
|
var UPDATE_MANIFEST_FILE = "update.json";
|
|
43408
43711
|
var UPDATE_FILES_DIRECTORY = "files";
|
|
43409
43712
|
var sha2565 = (value) => createHash17("sha256").update(value).digest("hex");
|
|
43410
43713
|
var listFiles = async (root, directory = root) => {
|
|
43411
|
-
const entries = await
|
|
43714
|
+
const entries = await readdir12(directory, { withFileTypes: true });
|
|
43412
43715
|
const paths = await Promise.all(entries.map(async (entry) => {
|
|
43413
|
-
const path =
|
|
43716
|
+
const path = join33(directory, entry.name);
|
|
43414
43717
|
if (entry.isDirectory())
|
|
43415
43718
|
return listFiles(root, path);
|
|
43416
43719
|
if (!entry.isFile())
|
|
43417
43720
|
throw new TypeError("Mobile updates cannot contain links or special files.");
|
|
43418
|
-
return [
|
|
43721
|
+
return [relative22(root, path).replaceAll("\\", "/")];
|
|
43419
43722
|
}));
|
|
43420
43723
|
return paths.flat().sort((left, right) => left.localeCompare(right));
|
|
43421
43724
|
};
|
|
43422
43725
|
var inspectFiles = async (root, paths) => Promise.all(paths.map(async (path) => {
|
|
43423
|
-
const source =
|
|
43726
|
+
const source = join33(root, path);
|
|
43424
43727
|
const [metadata, contents] = await Promise.all([
|
|
43425
43728
|
stat8(source),
|
|
43426
|
-
|
|
43729
|
+
readFile30(source)
|
|
43427
43730
|
]);
|
|
43428
43731
|
return { bytes: metadata.size, path, sha256: sha2565(contents) };
|
|
43429
43732
|
}));
|
|
43430
43733
|
var releaseIdFor = (value) => `amu_${sha2565(canonicalizeAbsoluteMobileUpdate(value))}`;
|
|
43431
43734
|
var buildAbsoluteMobileUpdate = async (options) => {
|
|
43432
|
-
const bundleDirectory =
|
|
43433
|
-
const outputRoot =
|
|
43735
|
+
const bundleDirectory = resolve24(options.bundleDirectory);
|
|
43736
|
+
const outputRoot = resolve24(options.outputDirectory);
|
|
43434
43737
|
if (outputRoot === bundleDirectory || outputRoot.startsWith(`${bundleDirectory}/`))
|
|
43435
43738
|
throw new TypeError("Mobile update output must be outside the embedded bundle.");
|
|
43436
43739
|
const paths = await listFiles(bundleDirectory);
|
|
@@ -43458,38 +43761,38 @@ var buildAbsoluteMobileUpdate = async (options) => {
|
|
|
43458
43761
|
value: signature.toString("base64")
|
|
43459
43762
|
}
|
|
43460
43763
|
});
|
|
43461
|
-
await
|
|
43462
|
-
const outputDirectory =
|
|
43463
|
-
const staging = await mkdtemp12(
|
|
43764
|
+
await mkdir24(outputRoot, { recursive: true });
|
|
43765
|
+
const outputDirectory = join33(outputRoot, manifest.releaseId);
|
|
43766
|
+
const staging = await mkdtemp12(join33(outputRoot, ".stage-"));
|
|
43464
43767
|
try {
|
|
43465
|
-
await cp2(bundleDirectory,
|
|
43768
|
+
await cp2(bundleDirectory, join33(staging, UPDATE_FILES_DIRECTORY), {
|
|
43466
43769
|
force: true,
|
|
43467
43770
|
recursive: true
|
|
43468
43771
|
});
|
|
43469
|
-
await writeFile25(
|
|
43772
|
+
await writeFile25(join33(staging, UPDATE_MANIFEST_FILE), `${JSON.stringify(manifest, null, "\t")}
|
|
43470
43773
|
`);
|
|
43471
|
-
await
|
|
43774
|
+
await rename21(staging, outputDirectory);
|
|
43472
43775
|
} catch (error) {
|
|
43473
|
-
await
|
|
43776
|
+
await rm18(staging, { force: true, recursive: true });
|
|
43474
43777
|
if (typeof error === "object" && error !== null && Reflect.get(error, "code") === "EEXIST")
|
|
43475
43778
|
throw new TypeError(`Mobile update ${manifest.releaseId} already exists.`, { cause: error });
|
|
43476
43779
|
throw error;
|
|
43477
43780
|
}
|
|
43478
43781
|
return {
|
|
43479
43782
|
manifest,
|
|
43480
|
-
manifestPath:
|
|
43783
|
+
manifestPath: join33(outputDirectory, UPDATE_MANIFEST_FILE),
|
|
43481
43784
|
outputDirectory
|
|
43482
43785
|
};
|
|
43483
43786
|
};
|
|
43484
43787
|
var copyAbsoluteMobileUpdateFile = async (updateDirectory, path, destination) => {
|
|
43485
|
-
const source =
|
|
43486
|
-
const root =
|
|
43788
|
+
const source = resolve24(updateDirectory, UPDATE_FILES_DIRECTORY, path);
|
|
43789
|
+
const root = resolve24(updateDirectory, UPDATE_FILES_DIRECTORY);
|
|
43487
43790
|
if (!source.startsWith(`${root}/`))
|
|
43488
43791
|
throw new TypeError("Update file escaped its release.");
|
|
43489
|
-
await
|
|
43792
|
+
await mkdir24(dirname24(destination), { recursive: true });
|
|
43490
43793
|
await cp2(source, destination, { force: true });
|
|
43491
43794
|
};
|
|
43492
|
-
var readAbsoluteMobileUpdate = async (directory) => parseAbsoluteMobileUpdateManifest(JSON.parse(await
|
|
43795
|
+
var readAbsoluteMobileUpdate = async (directory) => parseAbsoluteMobileUpdateManifest(JSON.parse(await readFile30(join33(resolve24(directory), UPDATE_MANIFEST_FILE), "utf8")));
|
|
43493
43796
|
var verifyAbsoluteMobileUpdateSignature = (manifestValue, publicKey) => {
|
|
43494
43797
|
const manifest = parseAbsoluteMobileUpdateManifest(manifestValue);
|
|
43495
43798
|
const valid = verify("sha256", absoluteMobileUpdateSigningPayload(unsignedAbsoluteMobileUpdate(manifest)), { dsaEncoding: "ieee-p1363", key: publicKey }, Buffer.from(manifest.signature.value, "base64"));
|
|
@@ -43606,16 +43909,16 @@ var pruneAbsoluteMobileUpdates = async (options) => {
|
|
|
43606
43909
|
var object5 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
43607
43910
|
var isPublisher2 = (value) => object5(value) && typeof value.publishUpdate === "function" && typeof value.promoteUpdate === "function" && typeof value.rollbackUpdate === "function";
|
|
43608
43911
|
var projectPath3 = (projectRoot, requested, label) => {
|
|
43609
|
-
const root =
|
|
43610
|
-
const path =
|
|
43611
|
-
const projectRelative =
|
|
43612
|
-
if (projectRelative === ".." || projectRelative.startsWith(`..${
|
|
43912
|
+
const root = resolve25(projectRoot);
|
|
43913
|
+
const path = resolve25(root, requested);
|
|
43914
|
+
const projectRelative = relative23(root, path);
|
|
43915
|
+
if (projectRelative === ".." || projectRelative.startsWith(`..${sep16}`) || isAbsolute14(projectRelative))
|
|
43613
43916
|
throw new TypeError(`${label} must remain inside the project.`);
|
|
43614
43917
|
return path;
|
|
43615
43918
|
};
|
|
43616
43919
|
var loadAbsoluteMobileUpdatePublisher = async (projectRoot, requestedModulePath) => {
|
|
43617
43920
|
const modulePath = projectPath3(projectRoot, requestedModulePath, "mobile update registry");
|
|
43618
|
-
await
|
|
43921
|
+
await access22(modulePath).catch(() => {
|
|
43619
43922
|
throw new TypeError(`Mobile update registry does not exist: ${modulePath}`);
|
|
43620
43923
|
});
|
|
43621
43924
|
const loaded = await import(pathToFileURL4(modulePath).href);
|
|
@@ -43724,6 +44027,7 @@ export {
|
|
|
43724
44027
|
ABSOLUTE_MOBILE_CERTIFICATION_VERIFICATION_FORMAT,
|
|
43725
44028
|
ABSOLUTE_MOBILE_CI_PROMOTION_AUDIT_FORMAT,
|
|
43726
44029
|
ABSOLUTE_MOBILE_CI_PROMOTION_CONTEXT_FORMAT,
|
|
44030
|
+
ABSOLUTE_MOBILE_CI_PROMOTION_OPERATION_FORMAT,
|
|
43727
44031
|
ABSOLUTE_MOBILE_CI_WORKFLOW_FORMAT,
|
|
43728
44032
|
ABSOLUTE_MOBILE_CLIENT_MANIFEST_FORMAT,
|
|
43729
44033
|
ABSOLUTE_MOBILE_COMPATIBILITY_FORMAT,
|
|
@@ -43767,6 +44071,7 @@ export {
|
|
|
43767
44071
|
absoluteExpoNativeObservabilityPaths,
|
|
43768
44072
|
absoluteIosDeviceAcceptanceCommands,
|
|
43769
44073
|
absoluteMobilePreviewDocument,
|
|
44074
|
+
absoluteMobilePromotionOperationPath,
|
|
43770
44075
|
absoluteMobileUpdateSigningPayload,
|
|
43771
44076
|
absolutePercentile,
|
|
43772
44077
|
absolutePssMiB,
|
|
@@ -43778,6 +44083,7 @@ export {
|
|
|
43778
44083
|
acceptsAbsoluteRouteData,
|
|
43779
44084
|
acquireAbsoluteRemoteMacReleaseLease,
|
|
43780
44085
|
activateAbsoluteMobilePage,
|
|
44086
|
+
advanceAbsoluteMobilePromotionOperation,
|
|
43781
44087
|
advanceAbsoluteMobileUpdateRollout,
|
|
43782
44088
|
applyAbsoluteNativeDeepLinks,
|
|
43783
44089
|
applyAbsoluteNativeDeviceCapabilities,
|
|
@@ -43819,6 +44125,7 @@ export {
|
|
|
43819
44125
|
createAbsoluteMobilePageErrorResponse,
|
|
43820
44126
|
createAbsoluteMobilePageRequest,
|
|
43821
44127
|
createAbsoluteMobilePreviewPlugin,
|
|
44128
|
+
createAbsoluteMobilePromotionOperation,
|
|
43822
44129
|
createAbsoluteMobileReleaseCertification,
|
|
43823
44130
|
createAbsoluteMobileRouteMetadataPlugin,
|
|
43824
44131
|
createAbsoluteMobileUpdateClient,
|
|
@@ -43829,6 +44136,7 @@ export {
|
|
|
43829
44136
|
createAbsoluteRemoteIosDevProject,
|
|
43830
44137
|
directAbsoluteProjectPackages,
|
|
43831
44138
|
discoverAbsoluteDeviceCapabilities,
|
|
44139
|
+
discoverAbsoluteMobilePromotionRun,
|
|
43832
44140
|
discoverAbsoluteSyncSchema,
|
|
43833
44141
|
disposeAbsoluteMobilePage,
|
|
43834
44142
|
drainAbsoluteMobileNativeObservability,
|
|
@@ -43873,6 +44181,7 @@ export {
|
|
|
43873
44181
|
isAbsoluteExpoNativeRootInput,
|
|
43874
44182
|
isAbsoluteIosNativeRootInput,
|
|
43875
44183
|
isAbsoluteMobileUpdateRolloutMember,
|
|
44184
|
+
listAbsoluteMobilePromotionOperations,
|
|
43876
44185
|
listAbsoluteRemoteMacProfiles,
|
|
43877
44186
|
loadAbsoluteDeviceCapabilityProviders,
|
|
43878
44187
|
loadAbsoluteMobileMaterializedBundle,
|
|
@@ -43909,6 +44218,8 @@ export {
|
|
|
43909
44218
|
parseAbsoluteMobilePageEnvelope,
|
|
43910
44219
|
parseAbsoluteMobilePageRequest,
|
|
43911
44220
|
parseAbsoluteMobilePromotionContext,
|
|
44221
|
+
parseAbsoluteMobilePromotionOperation,
|
|
44222
|
+
parseAbsoluteMobilePromotionRunList,
|
|
43912
44223
|
parseAbsoluteMobileUnsignedUpdateManifest,
|
|
43913
44224
|
parseAbsoluteMobileUpdateManifest,
|
|
43914
44225
|
parseAbsoluteMobileUpdateRequest,
|
|
@@ -43934,11 +44245,13 @@ export {
|
|
|
43934
44245
|
readAbsoluteMobileCertificationVerification,
|
|
43935
44246
|
readAbsoluteMobileLinkIntent,
|
|
43936
44247
|
readAbsoluteMobileMaterializedReleases,
|
|
44248
|
+
readAbsoluteMobilePromotionOperation,
|
|
43937
44249
|
readAbsoluteMobileReleaseCertification,
|
|
43938
44250
|
readAbsoluteMobileUpdate,
|
|
43939
44251
|
readAbsoluteSigstoreBundle,
|
|
43940
44252
|
reconcileAbsoluteMobileUpdateRollout,
|
|
43941
44253
|
redactAbsoluteIosLog,
|
|
44254
|
+
relativeAbsoluteMobilePromotionOperationPath,
|
|
43942
44255
|
removeAbsoluteRemoteMacProfile,
|
|
43943
44256
|
renderAbsoluteMobileReleaseCertification,
|
|
43944
44257
|
renderAbsoluteMobileUpdateRegistry,
|
|
@@ -43994,5 +44307,5 @@ export {
|
|
|
43994
44307
|
writeAbsoluteMobileUpdateRegistry
|
|
43995
44308
|
};
|
|
43996
44309
|
|
|
43997
|
-
//# debugId=
|
|
44310
|
+
//# debugId=8439B99573B3AFB964756E2164756E21
|
|
43998
44311
|
//# sourceMappingURL=index.js.map
|