@absolutejs/absolute 0.20.0-beta.107 → 0.20.0-beta.109

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.
@@ -613,7 +613,7 @@ __export(exports_config, {
613
613
  import { readFileSync as readFileSync2 } from "fs";
614
614
  import { resolve as resolve8 } from "path";
615
615
  import { createHash as createHash10, createPublicKey, X509Certificate as X509Certificate2 } from "crypto";
616
- var APP_ID_PATTERN, SCHEME_PATTERN, APPLE_APP_ID_PREFIX_PATTERN, CERTIFICATE_FINGERPRINT_PATTERN, UPDATE_NAME_PATTERN, UPDATE_PUBLIC_KEY_PATTERN, ENVIRONMENT_NAME_PATTERN, DEFAULT_UPDATE_BOOT_TIMEOUT_MS = 20000, DEFAULT_UPDATE_HEALTH_FAILURE_RATE = 0.2, DEFAULT_UPDATE_HEALTH_MINIMUM_REPORTS = 20, DEFAULT_UPDATE_ROLLOUT_FAILURE_RATE = 0.05, DEFAULT_UPDATE_ROLLOUT_OBSERVATION_MINUTES = 60, MINUTE_MS, DEFAULT_UPDATE_ROLLOUT_STAGES, MINIMUM_UPDATE_BOOT_TIMEOUT_MS = 5000, MAXIMUM_UPDATE_BOOT_TIMEOUT_MS = 120000, HOSTNAME_PATTERN, EXPO_RESERVED_ROUTE_PREFIXES, resolveProjectPath = (projectRoot, value, field2) => {
616
+ var APP_ID_PATTERN, SCHEME_PATTERN, APPLE_APP_ID_PREFIX_PATTERN, CERTIFICATE_FINGERPRINT_PATTERN, UPDATE_NAME_PATTERN, RELEASE_TARGET_PATTERN, UPDATE_PUBLIC_KEY_PATTERN, ENVIRONMENT_NAME_PATTERN, DEFAULT_UPDATE_BOOT_TIMEOUT_MS = 20000, DEFAULT_UPDATE_HEALTH_FAILURE_RATE = 0.2, DEFAULT_UPDATE_HEALTH_MINIMUM_REPORTS = 20, DEFAULT_UPDATE_ROLLOUT_FAILURE_RATE = 0.05, DEFAULT_UPDATE_ROLLOUT_OBSERVATION_MINUTES = 60, MINUTE_MS, DEFAULT_UPDATE_ROLLOUT_STAGES, MINIMUM_UPDATE_BOOT_TIMEOUT_MS = 5000, MAXIMUM_UPDATE_BOOT_TIMEOUT_MS = 120000, HOSTNAME_PATTERN, EXPO_RESERVED_ROUTE_PREFIXES, resolveProjectPath = (projectRoot, value, field2) => {
617
617
  const root = resolve8(projectRoot);
618
618
  const path = resolve8(root, value);
619
619
  if (path !== root && !path.startsWith(`${root}/`)) {
@@ -649,6 +649,54 @@ var APP_ID_PATTERN, SCHEME_PATTERN, APPLE_APP_ID_PREFIX_PATTERN, CERTIFICATE_FIN
649
649
  throw new TypeError("mobile.platforms must contain at least one platform.");
650
650
  }
651
651
  return normalized;
652
+ }, normalizeAndroidCertificationPolicy = (value) => {
653
+ if (value === false || value === undefined)
654
+ return;
655
+ if (value !== "installed")
656
+ throw new TypeError("mobile.release.certification channel Android policy must be installed or false.");
657
+ return value;
658
+ }, normalizeIosCertificationPolicy = (value) => {
659
+ if (value === false || value === undefined)
660
+ return;
661
+ if (!["simulator", "device", "store"].includes(value))
662
+ throw new TypeError("mobile.release.certification channel iOS policy must be simulator, device, store, or false.");
663
+ return value;
664
+ }, normalizeReleaseCertification = (config) => {
665
+ const configured = config.release?.certification;
666
+ if (configured === false)
667
+ return { channels: {}, googlePlayTracks: {} };
668
+ const channels = {
669
+ production: { android: "installed", ios: "store" }
670
+ };
671
+ const googlePlayTracks = {
672
+ production: "installed"
673
+ };
674
+ for (const [name, policy] of Object.entries(configured?.channels ?? {})) {
675
+ if (!RELEASE_TARGET_PATTERN.test(name))
676
+ throw new TypeError("mobile.release.certification.channels contains an invalid channel.");
677
+ const normalized = {};
678
+ const android = normalizeAndroidCertificationPolicy(policy.android);
679
+ const ios = normalizeIosCertificationPolicy(policy.ios);
680
+ if (android)
681
+ normalized.android = android;
682
+ if (ios)
683
+ normalized.ios = ios;
684
+ channels[name] = normalized;
685
+ }
686
+ for (const [name, requirement] of Object.entries(configured?.googlePlayTracks ?? {})) {
687
+ if (!RELEASE_TARGET_PATTERN.test(name))
688
+ throw new TypeError("mobile.release.certification.googlePlayTracks contains an invalid track.");
689
+ if (requirement === false)
690
+ delete googlePlayTracks[name];
691
+ else if (requirement === "installed")
692
+ googlePlayTracks[name] = requirement;
693
+ else
694
+ throw new TypeError("mobile.release.certification Google Play policy must be installed or false.");
695
+ }
696
+ return {
697
+ channels: Object.fromEntries(Object.entries(channels).sort(([left], [right]) => left.localeCompare(right))),
698
+ googlePlayTracks: Object.fromEntries(Object.entries(googlePlayTracks).sort(([left], [right]) => left.localeCompare(right)))
699
+ };
652
700
  }, normalizeHosts = (hosts, productionOrigin) => {
653
701
  const normalizeHostname = (host) => {
654
702
  const value = requireText(host, "mobile.deepLinks.hosts").toLowerCase();
@@ -975,6 +1023,7 @@ var APP_ID_PATTERN, SCHEME_PATTERN, APPLE_APP_ID_PREFIX_PATTERN, CERTIFICATE_FIN
975
1023
  platforms: normalizePlatforms(config.platforms),
976
1024
  productionOrigin,
977
1025
  pushAndroidGoogleServicesFile: resolveProjectPath(projectRoot, config.pushNotifications?.android?.googleServicesFile ?? "google-services.json", "mobile.pushNotifications.android.googleServicesFile"),
1026
+ releaseCertification: normalizeReleaseCertification(config),
978
1027
  ...updates ? { updates } : {},
979
1028
  ...updateServer ? { updateServer } : {}
980
1029
  };
@@ -985,6 +1034,7 @@ var init_config = __esm(() => {
985
1034
  APPLE_APP_ID_PREFIX_PATTERN = /^[A-Z0-9]{10}$/;
986
1035
  CERTIFICATE_FINGERPRINT_PATTERN = /^[0-9A-F]{64}$/;
987
1036
  UPDATE_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/u;
1037
+ RELEASE_TARGET_PATTERN = /^[a-z0-9][a-z0-9._-]{0,63}$/u;
988
1038
  UPDATE_PUBLIC_KEY_PATTERN = /^[A-Za-z0-9+/]+={0,2}$/u;
989
1039
  ENVIRONMENT_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/u;
990
1040
  MINUTE_MS = 60 * 1000;
@@ -33168,12 +33218,9 @@ var androidJob = (options) => {
33168
33218
  ABSOLUTE_GOOGLE_CREDENTIALS_BASE64: \${{ secrets.ABSOLUTE_GOOGLE_CREDENTIALS_BASE64 }}
33169
33219
  GOOGLE_APPLICATION_CREDENTIALS: \${{ runner.temp }}/absolute-google-credentials.json` : "";
33170
33220
  const publishCommand = options.includePublishing ? `if [[ "$ABSOLUTE_PUBLISH" == "true" ]]; then
33171
- args=(bunx absolute mobile publish android "$ABSOLUTE_SERVER_ENTRY" --registry "$ABSOLUTE_REGISTRY_MODULE")
33172
- if [[ -n "$ABSOLUTE_RELEASE_CHANNEL" ]]; then
33173
- args+=(--channel "$ABSOLUTE_RELEASE_CHANNEL")
33174
- fi
33221
+ args=(bunx absolute mobile build android "$ABSOLUTE_SERVER_ENTRY")
33175
33222
  if [[ "$ABSOLUTE_PLAY_TRACK" != "registry-only" ]]; then
33176
- args+=(--play-track "$ABSOLUTE_PLAY_TRACK")
33223
+ args+=(--registry "$ABSOLUTE_REGISTRY_MODULE" --play-track "$ABSOLUTE_PLAY_TRACK")
33177
33224
  fi
33178
33225
  else
33179
33226
  args=(bunx absolute mobile build android "$ABSOLUTE_SERVER_ENTRY")
@@ -33187,6 +33234,58 @@ var androidJob = (options) => {
33187
33234
  printf '%s' "$ABSOLUTE_GOOGLE_CREDENTIALS_BASE64" | base64 --decode > "$GOOGLE_APPLICATION_CREDENTIALS"
33188
33235
  chmod 600 "$GOOGLE_APPLICATION_CREDENTIALS"
33189
33236
  fi` : "";
33237
+ const certificationSteps = options.includePublishing ? `
33238
+ - name: Install-test and certify exact Android release
33239
+ if: inputs.publish
33240
+ shell: bash
33241
+ run: |
33242
+ args=(bunx absolute mobile doctor android --fix --yes)
33243
+ ${appendConfigArgument}
33244
+ "\${args[@]}"
33245
+ shopt -s nullglob
33246
+ releases=(.absolutejs/mobile/releases/android/*)
33247
+ if [[ "\${#releases[@]}" -ne 1 || ! -d "\${releases[0]}" ]]; then
33248
+ echo "Expected exactly one immutable Android release directory." >&2
33249
+ exit 1
33250
+ fi
33251
+ RELEASE_DIRECTORY="\${releases[0]}"
33252
+ args=(bunx absolute mobile test android --release "$RELEASE_DIRECTORY" --report .absolutejs/mobile-ci/acceptance/android --yes)
33253
+ ${appendConfigArgument}
33254
+ "\${args[@]}"
33255
+ args=(bunx absolute mobile certify "$RELEASE_DIRECTORY" --evidence .absolutejs/mobile-ci/acceptance/android --require installed --outdir .absolutejs/mobile-ci/certifications/android --json)
33256
+ "\${args[@]}" > .absolutejs/mobile-ci/android-certification.json
33257
+ - name: Publish certified Android release
33258
+ if: inputs.publish
33259
+ shell: bash
33260
+ run: |
33261
+ shopt -s nullglob
33262
+ releases=(.absolutejs/mobile/releases/android/*)
33263
+ certifications=(.absolutejs/mobile-ci/certifications/android/*)
33264
+ if [[ "\${#releases[@]}" -ne 1 || "\${#certifications[@]}" -ne 1 || ! -d "\${releases[0]}" || ! -d "\${certifications[0]}" ]]; then
33265
+ echo "Expected exactly one Android release and certification." >&2
33266
+ exit 1
33267
+ fi
33268
+ args=(bunx absolute mobile publish android --release "\${releases[0]}" --certification "\${certifications[0]}" --registry "$ABSOLUTE_REGISTRY_MODULE")
33269
+ if [[ -n "$ABSOLUTE_RELEASE_CHANNEL" ]]; then
33270
+ args+=(--channel "$ABSOLUTE_RELEASE_CHANNEL")
33271
+ fi
33272
+ if [[ "$ABSOLUTE_PLAY_TRACK" != "registry-only" ]]; then
33273
+ args+=(--play-track "$ABSOLUTE_PLAY_TRACK")
33274
+ fi
33275
+ ${appendConfigArgument}
33276
+ "\${args[@]}"
33277
+ - name: Upload Android acceptance and certification
33278
+ if: always() && inputs.publish
33279
+ uses: actions/upload-artifact@v7
33280
+ with:
33281
+ name: absolute-mobile-android-certification
33282
+ path: |
33283
+ .absolutejs/mobile-ci/acceptance/android/
33284
+ .absolutejs/mobile-ci/certifications/android/
33285
+ .absolutejs/mobile-ci/android-certification.json
33286
+ if-no-files-found: error
33287
+ retention-days: 30
33288
+ include-hidden-files: true` : "";
33190
33289
  return `
33191
33290
  android:
33192
33291
  name: Signed Android release
@@ -33225,13 +33324,14 @@ ${installSteps}
33225
33324
  done
33226
33325
  printf '%s' "$ABSOLUTE_ANDROID_KEYSTORE_BASE64" | base64 --decode > "\${{ runner.temp }}/absolute-release.jks"
33227
33326
  chmod 600 "\${{ runner.temp }}/absolute-release.jks"${googleSetup}
33228
- - name: Build or publish Android
33327
+ - name: Build Android
33229
33328
  shell: bash
33230
33329
  run: |
33231
33330
  ${publishCommand}
33232
33331
  ${appendConfigArgument}
33233
33332
  "\${args[@]}"
33234
33333
  ${releaseAuditSteps("android")}
33334
+ ${certificationSteps}
33235
33335
  - name: Attest Android App Bundle
33236
33336
  if: inputs.attest
33237
33337
  uses: actions/attest@v4
@@ -33264,15 +33364,9 @@ var iosJob = (options) => {
33264
33364
  APP_STORE_CONNECT_PRIVATE_KEY_BASE64: \${{ secrets.APP_STORE_CONNECT_PRIVATE_KEY_BASE64 }}
33265
33365
  APP_STORE_CONNECT_PRIVATE_KEY_PATH: \${{ runner.temp }}/AuthKey_AbsoluteJS.p8` : "";
33266
33366
  const publishCommand = options.includePublishing ? `if [[ "$ABSOLUTE_PUBLISH" == "true" ]]; then
33267
- args=(bunx absolute mobile publish ios "$ABSOLUTE_SERVER_ENTRY" --registry "$ABSOLUTE_REGISTRY_MODULE")
33268
- if [[ -n "$ABSOLUTE_RELEASE_CHANNEL" ]]; then
33269
- args+=(--channel "$ABSOLUTE_RELEASE_CHANNEL")
33270
- fi
33367
+ args=(bunx absolute mobile build ios "$ABSOLUTE_SERVER_ENTRY")
33271
33368
  if [[ -n "$ABSOLUTE_TESTFLIGHT_GROUP" ]]; then
33272
- args+=(--testflight-group "$ABSOLUTE_TESTFLIGHT_GROUP")
33273
- fi
33274
- if [[ "$ABSOLUTE_TESTFLIGHT_SUBMIT_REVIEW" == "true" ]]; then
33275
- args+=(--testflight-submit-review)
33369
+ args+=(--registry "$ABSOLUTE_REGISTRY_MODULE" --testflight-group "$ABSOLUTE_TESTFLIGHT_GROUP")
33276
33370
  fi
33277
33371
  else
33278
33372
  args=(bunx absolute mobile build ios "$ABSOLUTE_SERVER_ENTRY")
@@ -33286,6 +33380,58 @@ var iosJob = (options) => {
33286
33380
  printf '%s' "$APP_STORE_CONNECT_PRIVATE_KEY_BASE64" | base64 --decode > "$APP_STORE_CONNECT_PRIVATE_KEY_PATH"
33287
33381
  chmod 600 "$APP_STORE_CONNECT_PRIVATE_KEY_PATH"
33288
33382
  fi` : "";
33383
+ const certificationSteps = options.includePublishing ? `
33384
+ - name: Simulator-test and certify exact iOS release
33385
+ if: inputs.publish
33386
+ shell: bash
33387
+ run: |
33388
+ shopt -s nullglob
33389
+ releases=(.absolutejs/mobile/releases/ios/*)
33390
+ if [[ "\${#releases[@]}" -ne 1 || ! -d "\${releases[0]}" ]]; then
33391
+ echo "Expected exactly one immutable iOS release directory." >&2
33392
+ exit 1
33393
+ fi
33394
+ RELEASE_DIRECTORY="\${releases[0]}"
33395
+ args=(bunx absolute mobile test ios --release "$RELEASE_DIRECTORY" --report .absolutejs/mobile-ci/acceptance/ios --yes)
33396
+ ${appendConfigArgument}
33397
+ "\${args[@]}"
33398
+ args=(bunx absolute mobile certify "$RELEASE_DIRECTORY" --evidence .absolutejs/mobile-ci/acceptance/ios --require simulator --outdir .absolutejs/mobile-ci/certifications/ios --json)
33399
+ "\${args[@]}" > .absolutejs/mobile-ci/ios-certification.json
33400
+ - name: Publish certified iOS release
33401
+ if: inputs.publish
33402
+ shell: bash
33403
+ run: |
33404
+ shopt -s nullglob
33405
+ releases=(.absolutejs/mobile/releases/ios/*)
33406
+ certifications=(.absolutejs/mobile-ci/certifications/ios/*)
33407
+ if [[ "\${#releases[@]}" -ne 1 || "\${#certifications[@]}" -ne 1 || ! -d "\${releases[0]}" || ! -d "\${certifications[0]}" ]]; then
33408
+ echo "Expected exactly one iOS release and certification." >&2
33409
+ exit 1
33410
+ fi
33411
+ args=(bunx absolute mobile publish ios --release "\${releases[0]}" --certification "\${certifications[0]}" --registry "$ABSOLUTE_REGISTRY_MODULE")
33412
+ if [[ -n "$ABSOLUTE_RELEASE_CHANNEL" ]]; then
33413
+ args+=(--channel "$ABSOLUTE_RELEASE_CHANNEL")
33414
+ fi
33415
+ if [[ -n "$ABSOLUTE_TESTFLIGHT_GROUP" ]]; then
33416
+ args+=(--testflight-group "$ABSOLUTE_TESTFLIGHT_GROUP")
33417
+ fi
33418
+ if [[ "$ABSOLUTE_TESTFLIGHT_SUBMIT_REVIEW" == "true" ]]; then
33419
+ args+=(--testflight-submit-review)
33420
+ fi
33421
+ ${appendConfigArgument}
33422
+ "\${args[@]}"
33423
+ - name: Upload iOS acceptance and certification
33424
+ if: always() && inputs.publish
33425
+ uses: actions/upload-artifact@v7
33426
+ with:
33427
+ name: absolute-mobile-ios-certification
33428
+ path: |
33429
+ .absolutejs/mobile-ci/acceptance/ios/
33430
+ .absolutejs/mobile-ci/certifications/ios/
33431
+ .absolutejs/mobile-ci/ios-certification.json
33432
+ if-no-files-found: error
33433
+ retention-days: 30
33434
+ include-hidden-files: true` : "";
33289
33435
  return `
33290
33436
  ios:
33291
33437
  name: Signed iOS release
@@ -33337,13 +33483,14 @@ ${installSteps}
33337
33483
  security list-keychain -d user -s "$KEYCHAIN_PATH"
33338
33484
  mkdir -p "$(dirname "$PROFILE_DESTINATION")"
33339
33485
  cp "$PROFILE_PATH" "$PROFILE_DESTINATION"${appStoreDecode}
33340
- - name: Build or publish iOS
33486
+ - name: Build iOS
33341
33487
  shell: bash
33342
33488
  run: |
33343
33489
  ${publishCommand}
33344
33490
  ${appendConfigArgument}
33345
33491
  "\${args[@]}"
33346
33492
  ${releaseAuditSteps("ios")}
33493
+ ${certificationSteps}
33347
33494
  - name: Attest iOS IPA
33348
33495
  if: inputs.attest
33349
33496
  uses: actions/attest@v4
@@ -35430,6 +35577,14 @@ var satisfiesRequirement = (strength, requirement) => {
35430
35577
  return false;
35431
35578
  return STRENGTH_RANK[strength] >= STRENGTH_RANK[requirement];
35432
35579
  };
35580
+ var resolveAbsoluteMobileCertificationRequirement = (config, target) => {
35581
+ const channelRequirement = target.channel ? config.releaseCertification.channels[target.channel]?.[target.platform] : undefined;
35582
+ const playRequirement = target.googlePlayTrack ? config.releaseCertification.googlePlayTracks[target.googlePlayTrack] : undefined;
35583
+ const requirements = [channelRequirement, playRequirement].filter((value) => value !== undefined);
35584
+ if (requirements.length === 0)
35585
+ return;
35586
+ return requirements.reduce((strongest, candidate) => STRENGTH_RANK[candidate] > STRENGTH_RANK[strongest] ? candidate : strongest);
35587
+ };
35433
35588
  var validateCertifiedEvidence = (platform4, evidence) => {
35434
35589
  if (platform4 === "android") {
35435
35590
  if (evidence.strength !== "installed" || evidence.networkUnavailable !== "proven" || evidence.artifactExactness !== undefined || evidence.distribution !== undefined || evidence.remote)
@@ -35675,6 +35830,15 @@ var prepareAbsoluteAndroidRelease = async (publisher, options) => {
35675
35830
  }
35676
35831
  return versionCode;
35677
35832
  };
35833
+ var requireCertificationReceipt = (publication, certification, requirement, releaseId) => {
35834
+ if (!certification && !requirement)
35835
+ return;
35836
+ if (!certification || !requirement)
35837
+ throw new TypeError("Native release publication certification contract is incomplete.");
35838
+ const receipt = publication.certification;
35839
+ if (!receipt || receipt.certificationId !== certification.certificationId || receipt.releaseId !== releaseId || receipt.requirement !== requirement || receipt.strength !== certification.strength)
35840
+ throw new TypeError("Native release registry did not retain the required release certification.");
35841
+ };
35678
35842
  var isRecord15 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
35679
35843
  var isPublisher = (value) => isRecord15(value) && typeof value.publish === "function";
35680
35844
  var publisherModulePath = (projectRoot, requested) => {
@@ -35699,9 +35863,16 @@ var loadAbsoluteNativeReleasePublisher = async (projectRoot, requestedModulePath
35699
35863
  return publisher;
35700
35864
  };
35701
35865
  var publishAbsoluteAndroidRelease = async (options) => {
35866
+ const certificationRequirement = options.certificationRequirement ?? options.certification?.requirement;
35867
+ if (options.certification)
35868
+ verifyAbsoluteMobileReleaseCertification(options.certification, options.release, certificationRequirement);
35869
+ else if (certificationRequirement)
35870
+ throw new TypeError(`Android release publication requires ${certificationRequirement} certification.`);
35702
35871
  const publisher = await loadAbsoluteNativeReleasePublisher(options.projectRoot, options.modulePath);
35703
35872
  const publication = await publisher.publish({
35704
35873
  allowUnsigned: options.allowUnsigned,
35874
+ certification: options.certification,
35875
+ certificationRequirement,
35705
35876
  channel: options.channel,
35706
35877
  googlePlay: options.googlePlay,
35707
35878
  releaseRoot: options.release.releaseRoot,
@@ -35712,6 +35883,7 @@ var publishAbsoluteAndroidRelease = async (options) => {
35712
35883
  if (!actual || actual.appId !== expected.appId || actual.platform !== "android" || actual.releaseId !== expected.releaseId || actual.sha256 !== expected.sha256 || actual.signed !== expected.signed || actual.versionCode !== expected.versionCode || typeof publication.reused !== "boolean") {
35713
35884
  throw new TypeError("Native release registry returned a different Android release identity.");
35714
35885
  }
35886
+ requireCertificationReceipt(publication, options.certification, certificationRequirement, expected.releaseId);
35715
35887
  if (options.channel !== undefined && (publication.channel?.channel !== options.channel || publication.channel.releaseId !== expected.releaseId)) {
35716
35888
  throw new TypeError("Native release registry did not promote the requested channel.");
35717
35889
  }
@@ -35724,10 +35896,17 @@ var publishAbsoluteAndroidRelease = async (options) => {
35724
35896
  return publication;
35725
35897
  };
35726
35898
  var publishAbsoluteIosRelease = async (options) => {
35899
+ const certificationRequirement = options.certificationRequirement ?? options.certification?.requirement;
35900
+ if (options.certification)
35901
+ verifyAbsoluteMobileReleaseCertification(options.certification, options.release, certificationRequirement);
35902
+ else if (certificationRequirement)
35903
+ throw new TypeError(`iOS release publication requires ${certificationRequirement} certification.`);
35727
35904
  const publisher = await loadAbsoluteNativeReleasePublisher(options.projectRoot, options.modulePath);
35728
35905
  const publication = await publisher.publish({
35729
35906
  allowUnsigned: options.allowUnsigned,
35730
35907
  appStoreConnect: options.appStoreConnect,
35908
+ certification: options.certification,
35909
+ certificationRequirement,
35731
35910
  channel: options.channel,
35732
35911
  releaseRoot: options.release.releaseRoot,
35733
35912
  signal: options.signal
@@ -35737,6 +35916,7 @@ var publishAbsoluteIosRelease = async (options) => {
35737
35916
  if (!actual || actual.appId !== expected.appId || actual.platform !== "ios" || actual.releaseId !== expected.releaseId || actual.sha256 !== expected.sha256 || actual.signed !== expected.signed || actual.buildNumber !== expected.buildNumber || actual.marketingVersion !== expected.marketingVersion || typeof publication.reused !== "boolean") {
35738
35917
  throw new TypeError("Native release registry returned a different iOS release identity.");
35739
35918
  }
35919
+ requireCertificationReceipt(publication, options.certification, certificationRequirement, expected.releaseId);
35740
35920
  if (options.channel !== undefined && (publication.channel?.channel !== options.channel || publication.channel.releaseId !== expected.releaseId)) {
35741
35921
  throw new TypeError("Native release registry did not promote the requested channel.");
35742
35922
  }
@@ -43021,6 +43201,7 @@ export {
43021
43201
  resolveAbsoluteDeviceCapabilityPlan,
43022
43202
  resolveAbsoluteIosXcodeProject,
43023
43203
  resolveAbsoluteMobileAuthManifest,
43204
+ resolveAbsoluteMobileCertificationRequirement,
43024
43205
  resolveAbsoluteMobileCompatibilityRelease,
43025
43206
  resolveAbsoluteMobileDeepLink,
43026
43207
  resolveAbsoluteMobileNavigation,
@@ -43062,5 +43243,5 @@ export {
43062
43243
  writeAbsoluteMobileUpdateRegistry
43063
43244
  };
43064
43245
 
43065
- //# debugId=DB53CC7C8DF0442B64756E2164756E21
43246
+ //# debugId=F8C3D6BAA9852D3F64756E2164756E21
43066
43247
  //# sourceMappingURL=index.js.map