@absolutejs/absolute 0.20.0-beta.169 → 0.20.0-beta.170
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 +80 -0
- package/README.md +232 -0
- package/changelog.json +228 -0
- package/dist/angular/browser.js +7 -8
- package/dist/angular/browser.js.map +6 -5
- package/dist/angular/components/core/streamingSlotRegistrar.js +6 -2
- package/dist/angular/components/core/streamingSlotRegistry.js +7 -3
- package/dist/angular/index.js +555 -156
- package/dist/angular/index.js.map +29 -23
- package/dist/angular/server.js +555 -156
- package/dist/angular/server.js.map +29 -23
- package/dist/build/buildWorker.js +14 -8
- package/dist/build.js +4949 -1941
- package/dist/build.js.map +72 -42
- package/dist/cli/{add-7azr0c83.js → add-6a7pjkn9.js} +11 -7
- package/dist/cli/{analyze-3cyek6v3.js → analyze-606fshwa.js} +1 -1
- package/dist/cli/{build-25rz8v25.js → build-g81xqbb9.js} +1 -1
- package/dist/cli/{compile-4jnfxts9.js → compile-9y1w9zpj.js} +3 -3
- package/dist/cli/config/server.js +10699 -1538
- package/dist/cli/{dev-9tk5hn2e.js → dev-hyeb89hp.js} +5 -1
- package/dist/cli/{doctor-4nv2c2j3.js → doctor-h55y9hj1.js} +1 -1
- package/dist/cli/{generate-v75p2fct.js → generate-20x1pkf7.js} +4 -4
- package/dist/cli/{htmx-427swtdz.js → htmx-6mz2h7k1.js} +2 -2
- package/dist/cli/{index-bhbs6d5z.js → index-32ge2w1f.js} +12 -4
- package/dist/cli/{index-a4ws2jwd.js → index-3wz3mktm.js} +1 -1
- package/dist/cli/{index-b7hjgknf.js → index-9sksd8c8.js} +13 -4
- package/dist/cli/{index-eyzwc7gz.js → index-qbrzvmh9.js} +4 -2
- package/dist/cli/index-qw98g1p6.js +269 -0
- package/dist/cli/{index-434b7j4a.js → index-vtp20gwf.js} +69 -1
- package/dist/cli/{index-h7qhz02e.js → index-wk0pyxrg.js} +3 -0
- package/dist/cli/{index-k3y8cb6c.js → index-z6f43b20.js} +1 -1
- package/dist/cli/index.js +16 -16
- package/dist/cli/{islands-8sgky9gh.js → islands-dc54e5y1.js} +1 -1
- package/dist/cli/{ls-4m4yqwww.js → ls-b6zz24nt.js} +1 -1
- package/dist/cli/{mobile-hcxjr2gf.js → mobile-ajnnvqtv.js} +3 -3
- package/dist/cli/prerender-fqpp0m1j.js +10 -0
- package/dist/cli/{remove-1ycjx85k.js → remove-t8x1mrxg.js} +4 -4
- package/dist/cli/{start-mbaejxhm.js → start-d6p831ny.js} +3 -3
- package/dist/cli/{typecheck-dr068pmh.js → typecheck-stbt0qt5.js} +6 -1
- package/dist/cli/{workspace-1sycp9g1.js → workspace-61hh6jq1.js} +1 -1
- package/dist/client/chunks/index-6b66nzyf.js +381 -0
- package/dist/client/chunks/index-6b66nzyf.js.map +11 -0
- package/dist/client/chunks/{islands-rc28k5sx.js → islands-s2ta5ajb.js} +5 -2
- package/dist/client/chunks/{islands-rc28k5sx.js.map → islands-s2ta5ajb.js.map} +7 -6
- package/dist/client/index.js +160 -3
- package/dist/client/index.js.map +6 -4
- package/dist/client/navigation.js +764 -0
- package/dist/client/navigation.js.map +10 -0
- package/dist/client/prefetch.js +33 -375
- package/dist/client/prefetch.js.map +3 -4
- package/dist/core/streamingSlotRegistrar.js +5 -2
- package/dist/core/streamingSlotRegistrar.js.map +5 -4
- package/dist/core/streamingSlotRegistry.js +5 -2
- package/dist/core/streamingSlotRegistry.js.map +5 -4
- package/dist/dev/client/cspNonce.ts +28 -0
- package/dist/dev/client/handlers/html.ts +4 -3
- package/dist/dev/client/handlers/htmx.ts +3 -2
- package/dist/dev/client/handlers/svelte.ts +15 -90
- package/dist/dev/client/syncDevtools.ts +2 -1
- package/dist/dev/serverBootstrap.js +11 -4
- package/dist/i18n/index.js +543 -0
- package/dist/i18n/index.js.map +15 -0
- package/dist/index.js +6339 -2233
- package/dist/index.js.map +89 -54
- package/dist/islands/index.js +282 -40
- package/dist/islands/index.js.map +14 -10
- package/dist/mobile/browser.js +7 -2
- package/dist/mobile/browser.js.map +5 -4
- package/dist/mobile/index.js +7 -2
- package/dist/mobile/index.js.map +5 -4
- package/dist/mobile/remoteMacAgentEntry.js +1 -1
- package/dist/react/components/browser/index.js +94 -4
- package/dist/react/components/index.js +150 -10
- package/dist/react/components/index.js.map +15 -10
- package/dist/react/hooks/index.js +479 -13
- package/dist/react/hooks/index.js.map +12 -4
- package/dist/react/index.js +769 -166
- package/dist/react/index.js.map +32 -21
- package/dist/react/router/browser.js +21 -4
- package/dist/react/router/browser.js.map +5 -4
- package/dist/react/router/index.js +21 -4
- package/dist/react/router/index.js.map +5 -4
- package/dist/react/server.js +597 -203
- package/dist/react/server.js.map +25 -15
- package/dist/src/angular/zoneRuntime.d.ts +5 -0
- package/dist/src/build/buildReactServerComponents.d.ts +22 -0
- package/dist/src/build/downlevelAsyncForZone.d.ts +1 -0
- package/dist/src/build/fileRoutes.d.ts +65 -0
- package/dist/src/build/fonts/buildFonts.d.ts +25 -0
- package/dist/src/build/fonts/fallbackMetrics.d.ts +13 -0
- package/dist/src/build/fonts/googleFonts.d.ts +18 -0
- package/dist/src/build/fonts/injectFontTags.d.ts +7 -0
- package/dist/src/build/fonts/parseFontMetrics.d.ts +4 -0
- package/dist/src/build/generateReactIndexes.d.ts +7 -1
- package/dist/src/build/htmlIncludes.d.ts +16 -0
- package/dist/src/build/inlineSourceMapComment.d.ts +1 -0
- package/dist/src/build/scanConventions.d.ts +3 -0
- package/dist/src/build/vitals.d.ts +21 -0
- package/dist/src/client/formActions.d.ts +29 -0
- package/dist/src/client/index.d.ts +2 -0
- package/dist/src/client/navigation.d.ts +16 -0
- package/dist/src/client/prefetch.d.ts +2 -30
- package/dist/src/core/build.d.ts +2 -2
- package/dist/src/core/cspNonce.d.ts +12 -0
- package/dist/src/core/fileRouteAdapter.d.ts +15 -0
- package/dist/src/core/fileRoutes.d.ts +5 -0
- package/dist/src/core/formActionFlash.d.ts +25 -0
- package/dist/src/core/formActions.d.ts +249 -0
- package/dist/src/core/index.d.ts +5 -0
- package/dist/src/core/partialPrerender.d.ts +28 -0
- package/dist/src/core/partialPrerenderServe.d.ts +24 -0
- package/dist/src/core/precompressed.d.ts +11 -1
- package/dist/src/core/prerenderNonce.d.ts +9 -0
- package/dist/src/core/productionRuntime.d.ts +4 -2
- package/dist/src/core/serverOnlyStaticFiles.d.ts +8 -0
- package/dist/src/core/staticHtmlNonce.d.ts +2 -0
- package/dist/src/core/vitals.d.ts +108 -0
- package/dist/src/dev/angular/fastHmrCompiler.d.ts +1 -1
- package/dist/src/dev/client/cspNonce.d.ts +2 -0
- package/dist/src/dev/fileRouteRefresher.d.ts +5 -0
- package/dist/src/dev/importCost/instrument.d.ts +1 -1
- package/dist/src/dev/reactServerComponentsRebuild.d.ts +3 -0
- package/dist/src/i18n/defineMessages.d.ts +5 -0
- package/dist/src/i18n/formatMessage.d.ts +26 -0
- package/dist/src/i18n/index.d.ts +6 -0
- package/dist/src/i18n/intlCache.d.ts +5 -0
- package/dist/src/i18n/routing.d.ts +28 -0
- package/dist/src/i18n/translator.d.ts +11 -0
- package/dist/src/mobile/androidRelease.d.ts +2 -2
- package/dist/src/mobile/iosRelease.d.ts +4 -4
- package/dist/src/mobile/materializedBundle.d.ts +1 -1
- package/dist/src/mobile/mobileInspect.d.ts +1 -1
- package/dist/src/mobile/releaseArtifact.d.ts +2 -2
- package/dist/src/mobile/remoteMacProtocol.d.ts +2 -2
- package/dist/src/plugins/i18n.d.ts +30 -0
- package/dist/src/plugins/index.d.ts +2 -1
- package/dist/src/plugins/secureHeaders.d.ts +48 -0
- package/dist/src/react/components/Head.d.ts +1 -1
- package/dist/src/react/components/StreamSlot.browser.d.ts +1 -0
- package/dist/src/react/components/StreamSlot.d.ts +5 -1
- package/dist/src/react/components/SuspenseSlot.browser.d.ts +2 -0
- package/dist/src/react/components/SuspenseSlot.d.ts +12 -0
- package/dist/src/react/fileRoute.d.ts +18 -0
- package/dist/src/react/hooks/index.d.ts +4 -0
- package/dist/src/react/hooks/useFormAction.d.ts +42 -0
- package/dist/src/react/hooks/useI18n.d.ts +15 -0
- package/dist/src/react/index.d.ts +2 -0
- package/dist/src/react/server.d.ts +2 -0
- package/dist/src/react/serverComponents/constants.d.ts +11 -0
- package/dist/src/react/serverComponents/flightPayload.d.ts +2 -0
- package/dist/src/react/serverComponents/pageHandler.d.ts +14 -0
- package/dist/src/svelte/browser.d.ts +1 -0
- package/dist/src/svelte/fileRoute.d.ts +15 -0
- package/dist/src/svelte/i18n.d.ts +8 -0
- package/dist/src/svelte/index.d.ts +2 -0
- package/dist/src/svelte/lowerAwaitSlotSyntax.d.ts +5 -1
- package/dist/src/svelte/renderToReadableStream.d.ts +10 -2
- package/dist/src/svelte/router/browser.d.ts +3 -1
- package/dist/src/svelte/router/goto.d.ts +13 -10
- package/dist/src/svelte/router/guards.d.ts +43 -0
- package/dist/src/svelte/router/index.d.ts +3 -1
- package/dist/src/svelte/router/lazy.d.ts +17 -0
- package/dist/src/svelte/router/lazyModule.d.ts +29 -0
- package/dist/src/svelte/router/navigation.d.ts +55 -0
- package/dist/src/svelte/router/pushState.d.ts +4 -2
- package/dist/src/svelte/router/scroll.d.ts +34 -0
- package/dist/src/svelte/routerSsr.d.ts +9 -0
- package/dist/src/svelte/server.d.ts +1 -0
- package/dist/src/utils/cspNonceRef.d.ts +8 -0
- package/dist/src/utils/fontAssets.d.ts +17 -0
- package/dist/src/utils/formActionProtocol.d.ts +10 -0
- package/dist/src/utils/generateHeadElement.d.ts +1 -1
- package/dist/src/utils/index.d.ts +1 -0
- package/dist/src/utils/inlinePageCss.d.ts +18 -0
- package/dist/src/utils/loadConfig.d.ts +5 -0
- package/dist/src/utils/localeRef.d.ts +10 -0
- package/dist/src/utils/resolveConvention.d.ts +6 -1
- package/dist/src/utils/streamingSlots.d.ts +5 -0
- package/dist/src/vue/browser.d.ts +2 -0
- package/dist/src/vue/components/Image.d.ts +2 -2
- package/dist/src/vue/index.d.ts +2 -0
- package/dist/src/vue/serverDataPayload.d.ts +32 -0
- package/dist/src/vue/serverDataState.d.ts +9 -0
- package/dist/src/vue/useServerData.browser.d.ts +6 -0
- package/dist/src/vue/useServerData.d.ts +24 -0
- package/dist/svelte/browser.js +330 -3
- package/dist/svelte/browser.js.map +8 -4
- package/dist/svelte/components/AwaitSlot.svelte +5 -0
- package/dist/svelte/components/Head.svelte +50 -0
- package/dist/svelte/components/JsonLd.svelte +9 -1
- package/dist/svelte/components/StreamSlot.svelte +5 -0
- package/dist/svelte/index.js +1017 -117
- package/dist/svelte/index.js.map +38 -24
- package/dist/svelte/router/Link.svelte +40 -8
- package/dist/svelte/router/Route.svelte +157 -12
- package/dist/svelte/router/Route.svelte.d.ts +39 -5
- package/dist/svelte/router/Router.svelte +140 -25
- package/dist/svelte/router/Router.svelte.d.ts +5 -1
- package/dist/svelte/router/browser.ts +10 -0
- package/dist/svelte/router/goto.ts +15 -86
- package/dist/svelte/router/guards.ts +112 -0
- package/dist/svelte/router/index.ts +10 -0
- package/dist/svelte/router/lazy.ts +82 -0
- package/dist/svelte/router/lazyModule.ts +74 -0
- package/dist/svelte/router/navigation.ts +412 -0
- package/dist/svelte/router/pushState.ts +7 -4
- package/dist/svelte/router/scroll.ts +286 -0
- package/dist/svelte/server.js +747 -252
- package/dist/svelte/server.js.map +30 -20
- package/dist/types/angular.d.ts +2 -0
- package/dist/types/build.d.ts +37 -0
- package/dist/types/conventions.d.ts +3 -0
- package/dist/types/fileRoutes.d.ts +72 -0
- package/dist/types/fonts.d.ts +86 -0
- package/dist/types/formAction.d.ts +54 -0
- package/dist/types/globals.d.ts +10 -0
- package/dist/types/i18n.d.ts +185 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/metadata.d.ts +11 -0
- package/dist/types/navigation.d.ts +37 -0
- package/dist/types/prefetch.d.ts +10 -0
- package/dist/types/sitemap.d.ts +4 -0
- package/dist/types/svelteRouter.d.ts +89 -2
- package/dist/types/svelteRouter.ts +112 -2
- package/dist/types/vue.d.ts +46 -1
- package/dist/utils/iconVersion.ts +34 -0
- package/dist/vue/browser.js +107 -11
- package/dist/vue/browser.js.map +7 -4
- package/dist/vue/components/index.js +5 -2
- package/dist/vue/components/index.js.map +5 -4
- package/dist/vue/index.js +712 -158
- package/dist/vue/index.js.map +32 -23
- package/dist/vue/server.js +310 -79
- package/dist/vue/server.js.map +20 -15
- package/package.json +9 -1
- package/dist/cli/prerender-mfnwsvyt.js +0 -7
- package/dist/src/plugins/pageRouter.d.ts +0 -1
- /package/dist/cli/{index-j7m8pq48.js → index-rervww4p.js} +0 -0
|
@@ -2707,7 +2707,7 @@ ${Pr}
|
|
|
2707
2707
|
${ve}
|
|
2708
2708
|
${gE}
|
|
2709
2709
|
`:"",at=z.indexOf("<application"),ht=at===Uy?Uy:z.lastIndexOf(`
|
|
2710
|
-
`,at)+1,cr=DB(z,qe,ht);if(!P.capabilities.includes("pushNotifications"))return aP(M,cr);let mr=await IB(v.pushAndroidGoogleServicesFile);if(mr===null)throw TypeError(`Push notifications require Firebase config at ${v.pushAndroidGoogleServicesFile}. Set mobile.pushNotifications.android.googleServicesFile to override it.`);let Pr;try{Pr=JSON.parse(mr)}catch(os){throw TypeError("Android google-services.json is invalid JSON.",{cause:os})}let xe=typeof Pr==="object"&&Pr!==null?Reflect.get(Pr,"client"):void 0;if(!(Array.isArray(xe)&&xe.some((os)=>{let Pi=typeof os==="object"&&os!==null?Reflect.get(os,"client_info"):void 0,Us=typeof Pi==="object"&&Pi!==null?Reflect.get(Pi,"android_client_info"):void 0;return typeof Us==="object"&&Us!==null&&Reflect.get(Us,"package_name")===v.appId})))throw TypeError(`Android google-services.json does not contain package ${v.appId}.`);let[Nt,Ot]=await Promise.all([aP(M,cr),Vxt(a6(v.nativeProjectDirectory,"android/app/google-services.json"),mr)]);return Nt||Ot},z9e=async(v,P,M=P.platforms,z=rP(v))=>({changed:(await Promise.all(M.map(async(ve)=>({didChange:ve==="ios"?await Yxt(P,z):await e2t(P,z),platform:ve})))).filter(({didChange:ve})=>ve).map(({platform:ve})=>ve)});import{access as I2t,readFile as El,readdir as N2t}from"fs/promises";import{createHash as K9e}from"crypto";import{dirname as Q9e,extname as Y9e,join as Ba,relative as hE}from"path";import{createHash as i2t}from"crypto";import{access as s2t,readFile as V9e,stat as a2t}from"fs/promises";import{join as o2t,relative as c2t,resolve as RY}from"path";var FY=1;var o6={appBuild:"x-absolute-mobile-app-build",pageBundle:"x-absolute-mobile-page-bundle",pageContracts:"x-absolute-mobile-page-contracts",pageId:"x-absolute-mobile-page-id",protocol:"x-absolute-mobile-protocol",runtime:"x-absolute-mobile-runtime"};var RAt=["Accept",o6.protocol,o6.runtime,o6.appBuild,o6.pageBundle,o6.pageContracts,o6.pageId];var t2t=/[.*+?^${}()|[\]\\]/g,r2t=(v)=>{if(v==="*")return".*";if(v.startsWith(":")&&v.endsWith("?"))return"[^/]*";if(v.startsWith(":"))return"[^/]+";return v.replace(t2t,"\\$&")},n2t=(v,P)=>{let M=v.split("/").map(r2t).join("/");return new RegExp(`^${M}/?$`).test(P)},Z0e=(v,P,M="GET")=>v.find((z)=>z.method===M&&n2t(z.pattern,P));var W9e=1;var l2t=new Set(["angular","ember","html","htmx","react","svelte","vue"]),q9e=/^[a-f0-9]{64}$/u,R7=(v)=>typeof v==="object"&&v!==null&&!Array.isArray(v),u2t=(v,P)=>c2t(RY(v),RY(P)).replaceAll("\\","/")||".",_2t=async(v)=>{try{return await s2t(v),!0}catch{return!1}},f2t=async(v)=>{let P=JSON.parse(await V9e(v,"utf8"));if(!R7(P))throw TypeError("JSON root must be an object.");return P},V0=(v,P)=>{if(typeof v!=="string"||v.length===0)throw TypeError(`${P} must be a non-empty string.`);return v},p2t=(v,P)=>{if(!Array.isArray(v)||!v.every((M)=>typeof M==="string"))throw TypeError(`${P} must be a string array.`);return v},eve=async(v,P,M,z)=>{let ce=V0(P,M),ve=RY(v,ce),qe=RY(v);if(ve===qe||!ve.startsWith(`${qe}/`))throw TypeError(`${M} must remain inside the mobile bundle.`);if(!(await a2t(ve).catch(()=>{return}))?.isFile())throw TypeError(`${M} does not exist in the mobile bundle.`);if(z!==void 0){if(!q9e.test(z))throw TypeError(`${M} has an invalid SHA-256 digest.`);if(i2t("sha256").update(await V9e(ve)).digest("hex")!==z)throw TypeError(`${M} failed its SHA-256 integrity check.`)}return ce},$9e=async(v,P)=>{let M=o2t(v.bundleDirectory,"absolute-mobile-manifest.json"),z=u2t(P,M);if(!await _2t(M))return{manifest:z,status:"missing"};try{let ce=await f2t(M);if(ce.format!==W9e)throw TypeError("format is not supported by this runtime.");if(V0(ce.appId,"appId")!==v.appId)throw TypeError("appId does not match the effective mobile config.");if(V0(ce.productionOrigin,"productionOrigin")!==v.productionOrigin)throw TypeError("productionOrigin does not match the effective mobile config.");let ve=V0(ce.appBuild,"appBuild"),qe=V0(ce.runtime,"runtime"),at=V0(ce.nativeRuntime,"nativeRuntime");if(!q9e.test(at))throw TypeError("nativeRuntime must be a SHA-256 fingerprint.");if(qe!==String(FY))throw TypeError("runtime is not supported by this AbsoluteJS build.");let ht=p2t(ce.deviceCapabilities,"deviceCapabilities").sort();if(JSON.stringify(ce.updates??null)!==JSON.stringify(v.updates??null))throw TypeError("Embedded update trust configuration does not match mobile config.");if(!Array.isArray(ce.pages)||!Array.isArray(ce.routes))throw TypeError("pages and routes must be arrays.");let cr=new Set,mr=new Set;await Promise.all(ce.pages.map(async(Nt)=>{if(!R7(Nt))throw TypeError("pages contains an invalid entry.");let Ot=V0(Nt.pageId,"page.pageId");if(cr.has(Ot))throw TypeError("page.pageId values must be unique.");cr.add(Ot);let os=V0(Nt.framework,"page.framework");if(!l2t.has(os))throw TypeError("page.framework is unsupported.");mr.add(os);let Pi=V0(Nt.bundleHash,"page.bundleHash");if(V0(Nt.contract,"page.contract"),V0(Nt.propsSchemaHash,"page.propsSchemaHash"),await eve(v.bundleDirectory,Nt.localBundlePath,"page.localBundlePath",Pi),Nt.localStylePath!==void 0){let Us=V0(Nt.styleBundleHash,"page.styleBundleHash");await eve(v.bundleDirectory,Nt.localStylePath,"page.localStylePath",Us)}else if(Nt.styleBundleHash!==void 0)throw TypeError("page.styleBundleHash requires page.localStylePath.")}));let Pr=ce.routes.map((Nt)=>{if(!R7(Nt))throw TypeError("routes contains an invalid entry.");let{method:Ot}=Nt;if(Ot!=="GET"&&Ot!=="HEAD")throw TypeError("route.method must be GET or HEAD.");let os=V0(Nt.pageId,"route.pageId");if(!cr.has(os))throw TypeError("route.pageId references a missing page.");return{method:Ot,pageId:os,pattern:V0(Nt.pattern,"route.pattern")}});await Promise.all(["index.html","absolute-mobile-bootstrap.js"].map((Nt)=>eve(v.bundleDirectory,Nt,Nt)));let xe=new URL(v.entry,"https://absolute.invalid").pathname,qn=Z0e(Pr,xe)!==void 0;if(!qn)throw TypeError("entry is not owned by an embedded route.");return{appBuild:ve,auth:R7(ce.auth),capabilities:ht,entryResolved:qn,frameworks:[...mr].sort(),manifest:z,nativeRuntime:at,pageCount:ce.pages.length,routeCount:ce.routes.length,runtime:qe,status:"valid",sync:R7(ce.sync),updates:R7(ce.updates)}}catch(ce){return{issue:ce instanceof Error?ce.message:"The embedded mobile manifest is invalid.",manifest:z,status:"invalid"}}};import{createPrivateKey as d2t,createPublicKey as m2t,X509Certificate as g2t}from"crypto";import{access as h2t,mkdir as tPt}from"fs/promises";import{dirname as nPt,isAbsolute as y2t,relative as v2t,resolve as H9e,sep as b2t}from"path";import{pathToFileURL as S2t}from"url";var G9e=1,T2t="mobile.update.ts",tve=(v)=>typeof v==="object"&&v!==null&&!Array.isArray(v),x2t=(v,P)=>{let M=H9e(v),z=H9e(M,P),ce=v2t(M,z);if(ce===".."||ce.startsWith(`..${b2t}`)||y2t(ce))throw TypeError("mobile.updates.server.registry must remain inside the project.");return z},k2t=(v)=>tve(v)&&["publishUpdate","promoteUpdate","rollbackUpdate","resolveUpdate","readUpdateFile"].every((P)=>typeof v[P]==="function"),C2t=(v)=>{if(!tve(v))throw TypeError("Mobile update registry must export valid absoluteMobileUpdateServer metadata. Run `absolute mobile update provision`.");let{format:P,provider:M,storage:z}=v;if(P!==G9e||z!=="local"&&z!=="durable"||typeof M!=="string"||!M)throw TypeError("Mobile update registry must export valid absoluteMobileUpdateServer metadata. Run `absolute mobile update provision`.");return{format:G9e,provider:M,storage:z}},E2t=async(v,P=T2t)=>{let M=x2t(v,P);await h2t(M).catch(()=>{throw TypeError(`Mobile update server registry does not exist: ${M}. Run \`absolute mobile update provision\`.`)});let z=await import(S2t(M).href);if(!tve(z))throw TypeError("Mobile update registry module has no exports.");let ce=z.default??z.registry;if(!k2t(ce))throw TypeError("Mobile update registry must implement publication, promotion, rollback, resolution, and file reads.");let ve=C2t(z.absoluteMobileUpdateServer),qe=z.verifyAbsoluteMobileUpdateServer;if(ve.storage==="durable"&&typeof qe!=="function")throw TypeError("Mobile update registries marked durable must export verifyAbsoluteMobileUpdateServer(). Re-run `absolute mobile update provision --storage s3 --force` or provide an active durability check.");return{metadata:ve,registry:ce,...typeof qe==="function"?{verifyDurability:async()=>{await qe()}}:{}}},w2t=async(v)=>{if(v.metadata.storage!=="durable")throw TypeError("Mobile production updates require durable object storage. Re-run `absolute mobile update provision --storage s3 --force` or configure a durable adapter.");try{await v.verifyDurability?.()}catch(P){throw TypeError(`Durable mobile update storage verification failed for ${v.metadata.provider}. Check the bucket, endpoint, credentials, and read/write/delete permissions.`,{cause:P})}},A2t=(v,P)=>{if(!v.updateServer?.health)return;if(typeof P.registry.inspectUpdateHealth!=="function"||typeof P.registry.issueUpdateHealthToken!=="function"||typeof P.registry.recordUpdateHealth!=="function")throw TypeError("Mobile update fleet health is enabled but the registry is not provisioned for it. Run `absolute mobile update provision --force`.")},P2t=(v,P)=>{if(!v.updateServer?.rollout)return;if(typeof P.registry.advanceUpdateRollout!=="function"||typeof P.registry.cancelUpdateRollout!=="function"||typeof P.registry.inspectUpdateRollout!=="function"||typeof P.registry.pauseUpdateRollout!=="function"||typeof P.registry.reconcileUpdateRollout!=="function"||typeof P.registry.resumeUpdateRollout!=="function")throw TypeError("Mobile update rollout orchestration is enabled but the registry is not provisioned for it. Run `absolute mobile update provision --force`.")},D2t=(v)=>{if(!v.updates?.expoCodeSigning)return;let P=Object.entries(v.updateServer?.expoCodeSigningKeys??{});return{keys:Object.fromEntries(P.map(([z,ce])=>{let ve=process.env[ce.privateKeyEnv];if(!ve)throw TypeError(`Expo update serving requires ${ce.privateKeyEnv} on the trusted server.`);try{let at=new g2t(ce.certificatePem).publicKey.export({format:"der",type:"spki"}),ht=m2t(d2t(ve)).export({format:"der",type:"spki"});if(!at.equals(ht))throw Error("key mismatch")}catch(qe){throw TypeError(`${ce.privateKeyEnv} must contain the RSA private key matching Expo update key ${z}.`,{cause:qe})}return[z,{certificate:ce.certificatePem,privateKey:ve}]}))}};var X9e=async(v,P)=>{if(!v.updates)return;let M=await E2t(P,v.updateServer?.registryModule);if(await w2t(M),A2t(v,M),P2t(v,M),v.engine==="expo")D2t(v);return M.metadata};var O2t=/(?:hmr-timing|__absolute_target|absolutejs-error-overlay)/u,F2t=new Set([".html",".js",".mjs"]),Z9e=/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u,eje=-1,R2t=["bun.lock","bun.lockb","package-lock.json","pnpm-lock.yaml","yarn.lock"];var j2=async(v)=>{try{return await I2t(v),!0}catch{return!1}},M2t=async(v,P,M)=>{if(P)return rve(v);if(!M||!F2t.has(Y9e(v)))return;let z=await El(v,"utf8");return O2t.test(z)?v:void 0},rve=async(v)=>{if(!await j2(v))return;let P=await N2t(v,{withFileTypes:!0});return(await Promise.all(P.map((z)=>M2t(Ba(v,z.name),z.isDirectory(),z.isFile())))).find((z)=>z!==void 0)},cu=(v,P,M)=>({detail:P,id:v,path:M,status:"pass"}),mc=(v,P,M,z)=>({detail:P,id:v,path:M,remediation:z,status:"fail"}),tje=(v,P,M,z)=>({detail:P,id:v,path:M,remediation:z,status:"warn"}),L2t=async(v,P)=>{if(!v.updates)return;try{let M=await X9e(v,P);return cu("updates.trusted-server",`The trusted update server proved durable ${M?.provider??"object"} storage read/write/delete access, supports publish/promote/rollback, and has valid server-only signing material.`,v.updateServer?.registryModule)}catch(M){return mc("updates.trusted-server",M instanceof Error?M.message:"The trusted mobile update server is not release-ready.",v.updateServer?.registryModule??"mobile.update.ts","Run `absolute mobile update provision --storage s3 --force`, provision its environment variables on the trusted server, and rerun the release doctor.")}},j2t=async(v,P)=>{let M=await k9e(v,P);if(M.status==="absent")return tje("mobile.branding",M.detail,void 0,"Configure mobile.branding and run `absolute mobile assets` before store submission.");if(!M.ready)return mc("mobile.branding",M.detail,M.manifestPath,"Run `absolute mobile assets`, review the generated preview, and commit the native resource changes.");return cu("mobile.branding",M.detail,M.manifestPath)},M7=(v)=>typeof v==="object"&&v!==null&&!Array.isArray(v),yE=async(v)=>{let P=JSON.parse(await El(v,"utf8"));if(typeof P!=="object"||P===null||Array.isArray(P))throw TypeError("JSON root must be an object.");return Object.fromEntries(Object.entries(P))},nve=(v)=>{let P=new Map;for(let M of["dependencies","devDependencies"]){let z=v[M];if(typeof z!=="object"||z===null||Array.isArray(z))continue;for(let[ce,ve]of Object.entries(z))if(typeof ve==="string")P.set(ce,ve)}return P},B2t=(v)=>v.split("-")[0]?.split(".").slice(0,2).join("."),J2t=async(v,P)=>{let M=Ba(P,"package.json");try{let z=await yE(M),ce=nve(z),ve=["@capacitor/core","@capacitor/cli",...v.platforms.map((ht)=>`@capacitor/${ht}`)],qe=await Promise.all(ve.map(async(ht)=>{let cr=ce.get(ht);if(!cr||!Z9e.test(cr))throw TypeError(`${ht} must be a direct exact dependency.`);if((await yE(await $2t(P,ht))).version!==cr)throw TypeError(`${ht} does not match its installed version.`);return cr}));if(new Set(qe.map(B2t)).size!==1)throw TypeError("Capacitor core, CLI, and platform packages must use one major/minor line.");return cu("mobile.capacitor-versions",`Capacitor core, CLI, and configured platforms are pinned and aligned on ${qe[0]}.`,M)}catch(z){return mc("mobile.capacitor-versions",z instanceof Error?z.message:"Capacitor package versions could not be validated.",M,"Pin @capacitor/core, @capacitor/cli, and each configured platform to exact versions on the same major/minor line, then reinstall.")}},U2t=(v,P)=>{if(Z9e.test(v))return v===P;if(!v.startsWith("~"))return!1;let M=v.slice(1).split(".").map(Number),z=P.split(".").map(Number);return z[0]===M[0]&&z[1]===M[1]&&(z[2]??eje)>=(M[2]??0)},z2t=async(v)=>{let P=Ba(v.nativeProjectDirectory,"package.json");try{let M=await yE(P),z=nve(M),ve=["expo","expo-router","react","react-native"].find((ht)=>!z.has(ht));if(ve)throw TypeError(`Generated Expo project is missing ${ve}.`);let at=(await Promise.all([...z].map(async([ht,cr])=>({declared:cr,installed:await yE(Ba(v.nativeProjectDirectory,"node_modules",ht,"package.json")),name:ht})))).find(({declared:ht,installed:cr})=>typeof cr.version!=="string"||!U2t(ht,cr.version));if(at)throw TypeError(`Generated Expo dependency ${at.name}@${at.declared} does not match its installed version.`);if(!await j2(Ba(v.nativeProjectDirectory,"bun.lock")))throw TypeError("Generated Expo dependency lockfile is missing.");return cu("mobile.expo-versions",`Generated Expo SDK dependencies are pinned, installed, and locked (${z.get("expo")}).`,P)}catch(M){return mc("mobile.expo-versions",M instanceof Error?M.message:"Generated Expo dependency versions could not be validated.",P,"Run `absolute mobile init --yes`, then rebuild the production Expo project.")}},W2t=async(v)=>(await Promise.all(R2t.map(async(P)=>({exists:await j2(Ba(v,P)),name:P,path:Ba(v,P)})))).find(({exists:P})=>P),V2t=(v)=>{if(Array.isArray(v))return v;if(M7(v)&&Array.isArray(v.packages))return v.packages;return[]},rje=async(v,P)=>{let M=await yE(Ba(v,"package.json")).catch(()=>{return}),z=hE(v,P).replace(/\\/gu,"/");return V2t(M?.workspaces).some((ce)=>typeof ce==="string"&&new Bun.Glob(ce).match(z))},nje=(v)=>{let P=[],M=v;while(!0){P.push(M);let z=Q9e(M);if(z===M)return P;M=z}},q2t=async(v)=>(await Promise.all(nje(v).map(async(M,z)=>{let ce=await W2t(M);if(!ce||z>0&&!await rje(M,v))return;return ce}))).find((M)=>M!==void 0),$2t=async(v,P)=>{let z=(await Promise.all(nje(v).map(async(ce,ve)=>{if(ve>0&&!await rje(ce,v))return;let qe=Ba(ce,"node_modules",P,"package.json");return await j2(qe)?qe:void 0}))).find((ce)=>ce!==void 0);if(z)return z;throw TypeError(`${P} is not installed for this application.`)},H2t=async(v)=>{let P=await q2t(v);return P?cu("mobile.dependency-lock",`Dependency graph is locked by ${P.name}.`,P.path):mc("mobile.dependency-lock","No supported dependency lockfile is present.",v,"Install dependencies with the project package manager and commit its lockfile before release.")},G2t=(v,P)=>new URL(v.productionOrigin).protocol==="https:"?cu("mobile.production-origin","Production transport uses an HTTPS origin."):mc("mobile.production-origin","A loopback development origin cannot be used for a signed release.",P,"Configure mobile.server.productionOrigin with the deployed HTTPS origin."),X2t=(v,P)=>{let M=[...v.platforms.includes("ios")&&!v.appleAppIdPrefix?["mobile.deepLinks.apple.appIdPrefix"]:[],...v.platforms.includes("android")&&v.androidCertificateFingerprints.length===0?["mobile.deepLinks.android.sha256CertificateFingerprints"]:[]];return M.length===0?cu("mobile.association-identities","Deep-link association identities are configured for every release platform."):mc("mobile.association-identities",`Release association identity is missing: ${M.join(", ")}.`,P,"Configure the Apple application prefix and every Android signing-certificate SHA-256 fingerprint used for release.")},MY=async(v,P)=>await j2(v)?mc(`${P}.dev-journal`,"A live-reload recovery journal is still active.",v,"Close the development session or run mobile doctor again after stale-session repair."):cu(`${P}.dev-journal`,"No live-reload recovery journal is active.",v),K2t=(v)=>{try{return JSON.parse(v)}catch{return}},Q2t=(v)=>{if(typeof v!=="object"||v===null)return;let P=Reflect.get(v,"server");return typeof P==="object"&&P!==null?P:void 0},ije=(v)=>{let P=K2t(v),M=Q2t(P);if(P===void 0)return!0;if(!M)return!1;let z=Reflect.get(M,"allowNavigation");return typeof Reflect.get(M,"url")==="string"||Reflect.get(M,"cleartext")===!0||Array.isArray(z)&&z.length>0},Y2t=async(v)=>{if(!await j2(v))return mc("android.capacitor-config","The generated Android Capacitor config is missing.",v,"Run `absolute mobile sync android` before release validation.");return ije(await El(v,"utf8"))?mc("android.capacitor-config","Android Capacitor config contains a development server URL, cleartext transport, navigation allowlist, or invalid JSON.",v,"Run `absolute mobile sync android`; do not ship development transport overrides."):cu("android.capacitor-config","Android Capacitor config contains no development transport overrides.",v)},sje=async(v,P,M)=>{try{let z=await yE(M);if(z.appId!==v.appId||z.appName!==v.appName)throw TypeError(`${P} packaged application identity does not match mobile config.`);return cu(`${P}.app-identity`,`Packaged ${P} application identity matches mobile config.`,M)}catch(z){return mc(`${P}.app-identity`,z instanceof Error?z.message:`${P} application identity could not be validated.`,M,`Run \`absolute mobile sync ${P}\` and review the generated Capacitor config.`)}},aje=async(v)=>{if(!await j2(v))return mc("android.cleartext","The Android manifest is missing.",v,"Run `absolute mobile sync android` before release validation.");let P=await El(v,"utf8"),M=/android:usesCleartextTraffic=["']true["']/u.test(P),z=P.match(/android:networkSecurityConfig=["']@xml\/([a-z0-9_]+)["']/u)?.[1],ce=z?Ba(Q9e(v),"res","xml",`${z}.xml`):void 0,ve=/android:networkSecurityConfig=["']@xml\/absolutejs_dev_network_security["']/u.test(P),qe=ce?await El(ce,"utf8").then((ht)=>ht.includes("@raw/absolutejs_dev_ca")).catch(()=>!1):!1,at=ve||qe;return M||at?mc("android.cleartext",at?"Android still references the AbsoluteJS development certificate authority.":"Android explicitly permits cleartext traffic.",v,"Run `absolute mobile sync android`; do not ship development transport or trust overrides."):cu("android.cleartext","Android does not explicitly permit cleartext traffic.",v)},ive=async(v)=>{let P=await rve(v);return P?mc("android.hmr-assets","A packaged Android asset contains the development HMR client.",P,"Rebuild the production mobile bundle and run Capacitor sync again."):cu("android.hmr-assets","Packaged Android assets contain no development HMR markers.",v)},LY=async(v,P,M,z)=>{let ce=await $9e({...v,bundleDirectory:z},P);if(ce.status==="valid")return cu(`${M}.bundle-integrity`,`Packaged mobile manifest, runtime, routes, and ${ce.pageCount??0} page asset(s) passed structural and SHA-256 validation.`,Ba(z,"absolute-mobile-manifest.json"));return mc(`${M}.bundle-integrity`,ce.status==="missing"?"The packaged mobile manifest is missing.":`The packaged mobile bundle is invalid: ${ce.issue??"unknown validation error"}`,Ba(z,"absolute-mobile-manifest.json"),"Rebuild the production mobile bundle and run Capacitor sync for this platform.")},jY=async(v,P,M)=>{let z=Ba(M,"index.html");try{let ce=await El(z,"utf8");if(["Content-Security-Policy","default-src 'self'","base-uri 'none'","object-src 'none'","script-src 'self'","form-action 'none'",v.productionOrigin].filter((at)=>!ce.includes(at)).length>0)throw TypeError("Packaged shell CSP is missing a required AbsoluteJS directive or backend origin.");return cu(`${P}.content-security-policy`,"Packaged shell CSP restricts scripts, objects, base URLs, forms, and backend connections.",z)}catch(ce){return mc(`${P}.content-security-policy`,ce instanceof Error?ce.message:"Packaged shell CSP could not be validated.",z,"Rebuild the production mobile bundle with the AbsoluteJS-generated shell.")}},Z2t=async(v,P)=>{let M=v.updates?.expoCodeSigning,z=M7(P.updates)?P.updates:void 0;if(v.updates&&!M)throw TypeError("Expo production updates require an embedded code-signing certificate.");if(!M&&z&&(("codeSigningCertificate"in z)||("codeSigningMetadata"in z)))throw TypeError("Generated Expo config contains unconfigured code-signing material.");if(!M)return;if(!z||z.codeSigningCertificate!=="./certs/absolute-mobile-update.pem"||!M7(z.codeSigningMetadata)||z.codeSigningMetadata.keyid!==M.keyId||z.codeSigningMetadata.alg!==M.algorithm)throw TypeError("Generated Expo code-signing metadata does not match mobile config.");if(await El(Ba(v.nativeProjectDirectory,"certs","absolute-mobile-update.pem"),"utf8")!==M.certificatePem)throw TypeError("Generated Expo code-signing certificate does not match mobile config.")},oje=async(v,P)=>{let M=Ba(v.nativeProjectDirectory,"app.json");try{let z=await yE(M);if(!M7(z.expo))throw TypeError("Generated Expo application config is invalid.");let{expo:ce}=z;if(ce.name!==v.appName||v.platforms.includes("android")&&(!M7(ce.android)||ce.android.package!==v.appId)||v.platforms.includes("ios")&&(!M7(ce.ios)||ce.ios.bundleIdentifier!==v.appId))throw TypeError("Generated Expo application identity does not match mobile config.");let ve=bY(v,P).fingerprint;if(ce.runtimeVersion!==ve)throw TypeError("Generated Expo runtimeVersion does not match the AbsoluteJS native contract.");if(await Z2t(v,ce),Array.isArray(ce.plugins)&&ce.plugins.some((qe)=>typeof qe==="string"&&qe.includes("withAbsoluteDevelopmentCa")))throw TypeError("Generated Expo production config includes the development CA plugin.");return cu("expo.app-config","Expo application identity and generated native runtime match the production mobile config.",M)}catch(z){return mc("expo.app-config",z instanceof Error?z.message:"Generated Expo application config could not be validated.",M,"Run `absolute mobile build <platform>`; do not edit the generated Expo project.")}},cje=async(v)=>{let P=Ba(v.nativeProjectDirectory,"src","generated","webAssets.ts"),M=Ba(v.nativeProjectDirectory,"assets","absolute");try{let[z,ce]=await Promise.all([El(P,"utf8"),yE(Ba(v.bundleDirectory,"absolute-mobile-manifest.json"))]);if(z.includes("embedded AbsoluteJS bundle is unavailable")||typeof ce.appBuild!=="string"||!z.includes(JSON.stringify(ce.appBuild))||!z.includes(JSON.stringify(v.productionOrigin)))throw TypeError("Generated Expo assets do not contain the prepared production release identity.");let ve=(await Array.fromAsync(new Bun.Glob("**/*").scan({cwd:v.bundleDirectory,onlyFiles:!0}))).sort(),qe=(await Array.fromAsync(new Bun.Glob("*.absasset").scan({cwd:M,onlyFiles:!0}))).sort();if(ve.length===0||qe.length!==1)throw TypeError("Generated Expo asset count does not match the prepared mobile bundle.");let at=await Promise.all(ve.map((Pr)=>El(Ba(v.bundleDirectory,Pr)))),ht=0,cr=ve.map((Pr,xe)=>{let qn={length:at[xe]?.byteLength??0,md5:K9e("md5").update(at[xe]??Buffer.alloc(0)).digest("hex"),offset:ht,path:Pr.replaceAll("\\","/")};return ht+=qn.length,qn}),mr=await El(Ba(M,qe[0]??""));if(!mr.equals(Buffer.concat(at))||!z.includes(`const ARCHIVE_MD5 = ${JSON.stringify(K9e("md5").update(mr).digest("hex"))};`)||!z.includes(`const ARCHIVE_LENGTH = ${mr.byteLength};`)||cr.some((Pr)=>!z.includes(JSON.stringify(Pr))))throw TypeError("Generated Expo asset bytes differ from the prepared mobile bundle.");return cu("expo.bundle-projection",`Expo embeds the complete signed mobile bundle as one opaque archive containing ${ve.length} file(s).`,P)}catch(z){return mc("expo.bundle-projection",z instanceof Error?z.message:"Generated Expo assets could not be validated.",P,"Run `absolute mobile build <platform>` to regenerate and verify the production asset projection.")}},BY=async(v,P)=>{if(!await j2(v))return[];return(await Array.fromAsync(new Bun.Glob("**/*").scan({cwd:v,onlyFiles:!0}))).filter((z)=>P.has(Y9e(z))).map((z)=>Ba(v,z))},l6=async(v,P)=>{let z=(await Promise.all(v.map((ce)=>El(ce,"utf8")))).findIndex((ce)=>P.test(ce));return z===eje?void 0:v[z]},lje=async(v)=>{let P=Ba(v,"app/src/main/AndroidManifest.xml");try{let M=await El(P,"utf8");if(/android:debuggable=["']true["']/u.test(M))throw TypeError("Android release manifest explicitly enables application debugging.");let z=await BY(Ba(v,"app/src/main"),new Set([".java",".kt"])),ce=await l6(z,/setWebContentsDebuggingEnabled\s*\(\s*true\s*\)/u);if(ce)return mc("android.native-debugging","Android application source unconditionally enables WebView debugging.",ce,"Remove the unconditional WebView debugging call; use the platform debug-build behavior during development.");return cu("android.native-debugging","Android does not explicitly enable app or WebView debugging in release source.",P)}catch(M){return mc("android.native-debugging",M instanceof Error?M.message:"Android native debugging configuration could not be validated.",P,"Remove explicit release debugging settings and rerun mobile sync.")}},uje=async(v)=>{let M=[...(await El(v,"utf8").catch(()=>"")).matchAll(/<(?:activity|activity-alias|provider|receiver|service)\b[^>]*>/giu)].map(([z])=>z).filter((z)=>/android:exported=["']true["']/iu.test(z)).map((z)=>z.match(/android:name=["']([^"']+)["']/iu)?.[1]).filter((z)=>Boolean(z)&&z!==".MainActivity");return M.length===0?cu("android.exported-components","No non-launcher Android component is explicitly exported.",v):tje("android.exported-components",`${M.length} non-launcher Android component(s) are exported and require manual authorization review.`,v,"Confirm each exported component is intentional, permission-protected where appropriate, and documented in the mobile threat model review.")},_je=async(v,P)=>{try{let M=await El(P,"utf8"),z=(ce)=>[...M.matchAll(/<data\b[^>]*>/giu)].some(([ve])=>ve.includes('android:scheme="https"')&&ve.includes(`android:host="${ce}"`));if(!M.includes('android:autoVerify="true"')||!M.includes("android.intent.category.BROWSABLE")||v.deepLinkHosts.some((ce)=>!z(ce))||v.deepLinkScheme&&!M.includes(`android:scheme="${v.deepLinkScheme}"`))throw TypeError("Android App Link or custom-scheme projection does not match mobile config.");return cu("android.deep-links","Android verified links and custom scheme match the effective mobile config.",P)}catch(M){return mc("android.deep-links",M instanceof Error?M.message:"Android deep-link projection could not be validated.",P,"Run `absolute mobile sync android` and review the AbsoluteJS-owned deep-link region.")}},fje=async(v,P)=>{if(!v.updates)return;let M=String(v.updates.bootTimeoutMs);if(P==="ios"){let at=Ba(v.nativeProjectDirectory,"ios/App/App/AppDelegate.swift"),ht=Ba(v.nativeProjectDirectory,"ios/App/App/capacitor.config.json"),[cr,mr]=await Promise.all([El(at,"utf8").catch(()=>""),El(ht,"utf8").catch(()=>"")]);return cr.includes("AbsoluteMobileUpdateWatchdogPlugin")&&cr.includes("recoverInterruptedBoot()")&&cr.includes(`.milliseconds(${M})`)&&cr.includes("quarantinedReleases")&&mr.includes("AbsoluteMobileUpdateWatchdogPlugin")?cu("ios.update-watchdog",`The native update boot watchdog is projected with a ${M}ms deadline.`,at):mc("ios.update-watchdog","The iOS update boot watchdog does not match mobile config.",at,"Run `absolute mobile sync ios` before building the release.")}let z=Ba(v.nativeProjectDirectory,"android/app/src/main"),ce=await BY(z,new Set([".java",".kt"])),[ve,qe]=await Promise.all([l6(ce,/recoverInterruptedBoot\s*\(\s*this\s*\)/u),l6(ce,new RegExp(`handler\\.postDelayed\\(deadline,\\s*${M}L\\)`,"u"))]);return ve&&qe?cu("android.update-watchdog",`The native update boot watchdog is projected with a ${M}ms deadline.`,qe):mc("android.update-watchdog","The Android update boot watchdog does not match mobile config.",qe??z,"Run `absolute mobile sync android` before building the release.")},JY=async(v,P)=>{if(!v.observability)return;let M=v.nativeProjectDirectory;if(v.engine==="expo"){let at=Ba(M,"modules","absolute-mobile-observability"),ht=Ba(at,"expo-module.config.json"),cr=P==="android"?Ba(at,"android/src/main/java/expo/modules/absolutemobileobservability/AbsoluteMobileObservabilityModule.kt"):Ba(at,"ios/AbsoluteMobileObservabilityModule.swift"),[mr,Pr]=await Promise.all([El(ht,"utf8").catch(()=>""),El(cr,"utf8").catch(()=>"")]);return mr.includes("AbsoluteMobileObservabilityModule")&&Pr.includes("AbsoluteMobileObservability")&&(P==="android"?Pr.includes("getHistoricalProcessExitReasons"):Pr.includes("MXMetricManagerSubscriber"))?cu(`${P}.native-observability`,`The Expo ${P} native process collector is projected and autolinkable.`,cr):mc(`${P}.native-observability`,`The Expo ${P} native process collector is missing or incomplete.`,cr,`Run \`absolute mobile build ${P}\` before building the release.`)}if(P==="ios"){let at=Ba(M,"ios/App/App/AppDelegate.swift"),ht=Ba(M,"ios/App/App/capacitor.config.json"),[cr,mr]=await Promise.all([El(at,"utf8").catch(()=>""),El(ht,"utf8").catch(()=>"")]);return cr.includes("AbsoluteMobileObservabilityPlugin")&&cr.includes("MXMetricManagerSubscriber")&&mr.includes("AbsoluteMobileObservabilityPlugin")?cu("ios.native-observability","The iOS MetricKit native process collector is projected and registered.",at):mc("ios.native-observability","The iOS MetricKit native process collector is missing or unregistered.",at,"Run `absolute mobile sync ios` before building the release.")}let z=Ba(M,"android/app/src/main"),ce=await BY(z,new Set([".java",".kt"])),[ve,qe]=await Promise.all([l6(ce,/registerPlugin\s*\(\s*AbsoluteMobileObservabilityPlugin(?:::class\.java|\.class)\s*\)/u),l6(ce,/getHistoricalProcessExitReasons\s*\(/u)]);return ve&&qe?cu("android.native-observability","The Android process-exit collector is projected and registered.",qe):mc("android.native-observability","The Android process-exit collector is missing or unregistered.",qe??z,"Run `absolute mobile sync android` before building the release.")},pje=async(v)=>{let P=async(qe)=>(await BY(v,qe)).filter((at)=>!hE(v,at).split(/[\\/]/u).some((ht)=>["Pods","DerivedData","build"].includes(ht))),M=await P(new Set([".entitlements"])),z=await l6(M,/<key>(?:com\.apple\.security\.)?get-task-allow<\/key>\s*<true\s*\/>/u);if(z)return mc("ios.native-debugging","iOS source entitlements explicitly permit debugger attachment.",z,"Remove get-task-allow from source entitlements; Xcode supplies development entitlements only to debug builds.");let ce=await P(new Set([".m",".mm",".swift"])),ve=await l6(ce,/\.isInspectable\s*=\s*true|setInspectable\s*\(\s*true\s*\)/u);if(ve)return mc("ios.native-debugging","iOS application source unconditionally enables WebView inspection.",ve,"Remove unconditional WebView inspection from release source.");return cu("ios.native-debugging","iOS source does not enable release debugger attachment or WebView inspection.",M[0]??v)},ekt=async(v,P)=>{let M=Ba(P,"App/App/Info.plist"),z=Ba(P,"App/App/AbsoluteJS.entitlements"),ce=Ba(P,"App/App.xcodeproj/project.pbxproj");try{let[ve,qe,at]=await Promise.all([El(M,"utf8"),El(z,"utf8"),El(ce,"utf8")]);if(v.deepLinkScheme&&(!ve.includes("<key>CFBundleURLTypes</key>")||!ve.includes(`<string>${v.deepLinkScheme}</string>`)))throw TypeError("iOS custom URL scheme does not match mobile config.");if(v.deepLinkHosts.some((ht)=>!qe.includes(`<string>applinks:${ht}</string>`)))throw TypeError("iOS associated domains do not match mobile config.");if(!at.includes("CODE_SIGN_ENTITLEMENTS = App/AbsoluteJS.entitlements;"))throw TypeError("iOS target does not sign the AbsoluteJS entitlements file.");return cu("ios.deep-links","iOS universal links, custom scheme, and signed entitlements match mobile config.",z)}catch(ve){return mc("ios.deep-links",ve instanceof Error?ve.message:"iOS deep-link projection could not be validated.",z,"Run `absolute mobile sync ios` and review the AbsoluteJS-owned deep-link and entitlement projection.")}},tkt=(v)=>{if(!ZA(v))return;let P=Ba(v,"package.json");try{let M=w7(v),z=M.components.map((Pr)=>`${Pr.id}@${Pr.version}`).join(", "),ce=M.components.flatMap((Pr)=>Pr.localData?.collections??[]),ve=M.components.flatMap((Pr)=>Pr.localData?.mutations??[]),qe=[...ce,...ve].filter((Pr)=>Pr.protection==="required").length,at=[...ce,...ve].filter((Pr)=>Pr.persistence==="memory-only"||Pr.onProtectionUnavailable==="memory-only").length,ht={clientWins:ve.filter((Pr)=>Pr.conflict?.strategy==="client-wins").length,manual:ve.filter((Pr)=>Pr.conflict?.strategy==="manual").length,serverWins:ve.filter((Pr)=>Pr.conflict?.strategy==="server-wins").length},cr=M.components.map((Pr)=>Pr.localData?.maxBytesPerNamespace).filter((Pr)=>Pr!==void 0),mr=`${ce.length} collection rule(s), ${ve.length} mutation rule(s), ${qe} encryption-required, ${at} memory-only fallback(s), conflicts ${ht.clientWins} client-wins/${ht.serverWins} server-wins/${ht.manual} manual${cr.length>0?`, ${Math.min(...cr)}-byte effective quota`:", no logical quota"}`;return cu("sync.storage-schema",`Generated offline schema is compatible: ${z}; ${mr}.`,P)}catch(M){return mc("sync.storage-schema",M instanceof Error?M.message:"Generated offline schema metadata is invalid.",P,"Fix absolutejs.sync.localSchema metadata in the named app or package before releasing.")}},rkt={camera:"NSCameraUsageDescription","location-always":"NSLocationAlwaysAndWhenInUseUsageDescription","location-when-in-use":"NSLocationWhenInUseUsageDescription","photo-library":"NSPhotoLibraryUsageDescription","photo-library-add":"NSPhotoLibraryAddUsageDescription"},nkt=async(v,P)=>{if(!v.platforms.includes("android")||P.length===0)return;let M=Ba(v.nativeProjectDirectory,"android/app/src/main/AndroidManifest.xml"),z=await El(M,"utf8"),ce=P.filter((ve)=>!z.includes(`android:name="${ve}"`)&&!z.includes(`android:name='${ve}'`));if(ce.length===0)return;return mc("mobile.device-capabilities",`Android is missing native declarations for: ${ce.join(", ")}.`,M,"Run `absolute mobile sync android` to regenerate detected device permissions.")},ikt=async(v,P)=>{if(!v.platforms.includes("ios")||P.length===0)return;let M=Ba(v.nativeProjectDirectory,"ios"),z=v.engine==="expo"?await c6(M,"**/Info.plist","Info.plist"):Ba(M,"App/App/Info.plist"),ce=await El(z,"utf8"),ve=P.filter((qe)=>!ce.includes(`<key>${rkt[qe]}</key>`));if(ve.length===0)return;return mc("mobile.device-capabilities",`iOS is missing usage descriptions for: ${ve.join(", ")}.`,z,"Run `absolute mobile sync ios` to regenerate detected device usage descriptions.")},skt=async(v,P,M)=>{if(M.iosPrivacyAccessedApis.length===0)return;let z=await c6(v,"**/PrivacyInfo.xcprivacy","privacy manifest"),ce=await El(z,"utf8");if(!M.iosPrivacyAccessedApis.some(({api:qe,reasons:at})=>!ce.includes(`<string>${qe}</string>`)||at.some((ht)=>!ce.includes(`<string>${ht}</string>`)))&&P.includes(z.split(/[\\/]/u).at(-1)??""))return;return mc("mobile.device-capabilities","Expo iOS privacy manifest or target membership does not match detected capabilities.",z,"Run `absolute mobile build ios` to regenerate detected Expo privacy declarations.")},akt=async(v,P)=>{if(!P.iosPushNotifications)return;let M=await c6(v,"**/*.entitlements","entitlements");if((await El(M,"utf8")).includes("<key>aps-environment</key>"))return;return mc("mobile.device-capabilities","Expo iOS push entitlement does not match detected capabilities.",M,"Run `absolute mobile build ios` to regenerate native push integration.")},okt=async(v,P)=>{let M=Ba(v.nativeProjectDirectory,"ios"),z=await c6(M,"**/*.xcodeproj/project.pbxproj","Xcode project"),ce=await El(z,"utf8"),ve=await skt(M,ce,P);if(ve)return ve;return akt(M,P)},ckt=async(v,P)=>{if(!v.platforms.includes("ios"))return;if(v.engine==="expo")return okt(v,P);let M=Ba(v.nativeProjectDirectory,"ios/App/App"),z=Ba(M,"Info.plist"),ce=await El(z,"utf8").catch(()=>"");if(P.iosSystemBars&&!/<key>UIViewControllerBasedStatusBarAppearance<\/key>\s*<true\s*\/>/u.test(ce))return mc("mobile.device-capabilities","iOS system-bar capability is missing its required view-controller setting.",z,"Run `absolute mobile sync ios` to regenerate native capability settings.");if(P.iosPrivacyAccessedApis.length>0){let ve=Ba(M,"PrivacyInfo.xcprivacy"),qe=Ba(v.nativeProjectDirectory,"ios/App/App.xcodeproj/project.pbxproj"),[at,ht]=await Promise.all([El(ve,"utf8").catch(()=>""),El(qe,"utf8").catch(()=>"")]);if(P.iosPrivacyAccessedApis.some(({api:mr,reasons:Pr})=>!at.includes(`<string>${mr}</string>`)||Pr.some((xe)=>!at.includes(`<string>${xe}</string>`)))||!ht.includes("PrivacyInfo.xcprivacy in Resources"))return mc("mobile.device-capabilities","iOS privacy manifest or target membership does not match detected native capabilities.",ve,"Run `absolute mobile sync ios` to regenerate and target PrivacyInfo.xcprivacy.")}if(P.iosPushNotifications){let ve=Ba(v.nativeProjectDirectory,"ios/App/App/AbsoluteJS.entitlements"),qe=Ba(M,"AppDelegate.swift"),[at,ht]=await Promise.all([El(ve,"utf8").catch(()=>""),El(qe,"utf8").catch(()=>"")]);if(!at.includes("<key>aps-environment</key>")||!ht.includes("capacitorDidRegisterForRemoteNotifications")||!ht.includes("capacitorDidFailToRegisterForRemoteNotifications"))return mc("mobile.device-capabilities","iOS push entitlement or AppDelegate forwarding does not match detected capabilities.",ve,"Run `absolute mobile sync ios` to regenerate native push integration.")}return},lkt=async(v,P)=>{let M=Ba(P,"package.json");try{let z=rP(P,v.engine);await(async()=>{if(v.engine==="capacitor")return _9e(P,z);let cr=await yE(Ba(v.nativeProjectDirectory,"package.json")),mr=nve(cr),Pr=z.requiredPackages.filter((xe)=>{let qn=xe.lastIndexOf("@");return mr.get(xe.slice(0,qn))!==xe.slice(qn+1)});if(Pr.length>0)throw TypeError(`Generated Expo project is missing detected capability packages: ${Pr.join(", ")}.`);return})();let ve=e6(z),qe=await nkt(v,ve.androidPermissions);if(qe)return qe;let at=await ikt(v,ve.iosUsageDescriptions);if(at)return at;let ht=await ckt(v,ve);if(ht)return ht;return cu("mobile.device-capabilities",z.capabilities.length>0?`Native provider packages and permission declarations match detected capabilities: ${z.capabilities.join(", ")}.`:"No optional native device capabilities are used.",M)}catch(z){return mc("mobile.device-capabilities",z instanceof Error?z.message:"Native device capability provisioning is invalid.",M,"Run `absolute mobile sync` and approve the exact capability plugins before releasing.")}},ukt=async(v,P)=>{let M=Ba(v.nativeProjectDirectory,"android"),z=Ba(M,"app","src","main","assets","capacitor.config.json"),ce=Ba(M,"app","src","main","AndroidManifest.xml"),ve=Ba(M,"app","src","main","assets","public"),qe=Ba(P,".absolutejs","mobile","dev-session","journal.json");return(await Promise.all([MY(qe,"android"),Y2t(z),sje(v,"android",z),aje(ce),ive(ve),LY(v,P,"android",ve),jY(v,"android",ve),lje(M),uje(ce),_je(v,ce),fje(v,"android"),JY(v,"android")])).filter((ht)=>ht!==void 0).map((ht)=>({...ht,path:ht.path?hE(P,ht.path).replaceAll("\\","/")||".":void 0}))},_kt=async(v,P)=>{let M=Ba(v.nativeProjectDirectory,"android"),z=Ba(M,"app","src","main","AndroidManifest.xml"),ce=Ba(P,".absolutejs","mobile","expo-dev-session","journal.json");return(await Promise.all([MY(ce,"android"),oje(v,P),cje(v),aje(z),ive(v.bundleDirectory),LY(v,P,"android",v.bundleDirectory),jY(v,"android",v.bundleDirectory),lje(M),uje(z),_je(v,z),JY(v,"android")])).filter((qe)=>qe!==void 0).map((qe)=>({...qe,path:qe.path?hE(P,qe.path).replaceAll("\\","/")||".":void 0}))},c6=async(v,P,M)=>{let z=(await Array.fromAsync(new Bun.Glob(P).scan({cwd:v,onlyFiles:!0}))).filter((ve)=>!ve.split(/[\\/]/u).some((qe)=>["Pods","DerivedData","build"].includes(qe)));if(z.length!==1)throw TypeError(z.length===0?`Generated Expo iOS project is missing its ${M}.`:`Generated Expo iOS project contains ambiguous ${M} files.`);let[ce]=z;if(!ce)throw TypeError(`Generated Expo iOS project is missing its ${M}.`);return Ba(v,ce)},fkt=async(v,P)=>{try{let[M,z,ce]=await Promise.all([c6(P,"**/Info.plist","Info.plist"),c6(P,"**/*.entitlements","entitlements"),c6(P,"**/*.xcodeproj/project.pbxproj","Xcode project")]),[ve,qe,at]=await Promise.all([El(M,"utf8"),El(z,"utf8"),El(ce,"utf8")]);if(/<key>NSAllowsArbitraryLoads<\/key>\s*<true\s*\/>/u.test(ve))throw TypeError("Expo iOS App Transport Security permits arbitrary network loads.");if(v.deepLinkScheme&&(!ve.includes("<key>CFBundleURLTypes</key>")||!ve.includes(`<string>${v.deepLinkScheme}</string>`)))throw TypeError("Expo iOS custom URL scheme does not match mobile config.");if(v.deepLinkHosts.some((ht)=>!qe.includes(`<string>applinks:${ht}</string>`)))throw TypeError("Expo iOS associated domains do not match mobile config.");if(!at.includes(z.split(/[\\/]/u).at(-1)??""))throw TypeError("Expo iOS target does not sign its generated entitlements file.");return cu("ios.expo-native-projection","Expo iOS transport security, URL schemes, universal links, and signed entitlements match mobile config.",z)}catch(M){return mc("ios.expo-native-projection",M instanceof Error?M.message:"Expo iOS native projection could not be validated.",P,"Run `absolute mobile build ios` to regenerate the production Expo CNG project.")}},pkt=async(v,P)=>{let M=Ba(v.nativeProjectDirectory,"ios"),z=Ba(P,".absolutejs","mobile","expo-dev-session","journal.json"),ce=[await MY(z,"ios")];ce.push(v.iosVersion?cu("ios.marketing-version",`The iOS marketing version is ${v.iosVersion}.`):mc("ios.marketing-version","iOS has no explicit App Store marketing version.",P,"Add mobile.ios.version to absolutejs.config.ts, for example 1.0.0.")),ce.push(...await Promise.all([oje(v,P),cje(v),ive(v.bundleDirectory),LY(v,P,"ios",v.bundleDirectory),jY(v,"ios",v.bundleDirectory),fkt(v,M),pje(M)]));let ve=await JY(v,"ios");if(ve)ce.push(ve);return ce.map((qe)=>({...qe,path:qe.path?hE(P,qe.path).replaceAll("\\","/")||".":void 0}))},dkt=async(v,P)=>{let M=Ba(v.nativeProjectDirectory,"ios","App","App"),z=Ba(M,"capacitor.config.json"),ce=Ba(M,"Info.plist"),ve=Ba(M,"public"),qe=Ba(P,".absolutejs","mobile","ios-dev-session","journal.json"),at=[await MY(qe,"ios")],ht=v.updates?await fje(v,"ios"):void 0;if(!v.iosVersion)at.push(mc("ios.marketing-version","iOS has no explicit App Store marketing version.",P,"Add mobile.ios.version to absolutejs.config.ts, for example 1.0.0."));else at.push(cu("ios.marketing-version",`The iOS marketing version is ${v.iosVersion}.`));if(!await j2(z))at.push(mc("ios.capacitor-config","The generated iOS Capacitor config is missing.",z,"Run `absolute mobile sync ios` before release validation."));else if(ije(await El(z,"utf8")))at.push(mc("ios.capacitor-config","iOS Capacitor config contains a development server URL, cleartext transport, navigation allowlist, or invalid JSON.",z,"Run `absolute mobile sync ios`; do not ship development transport overrides."));else at.push(cu("ios.capacitor-config","iOS Capacitor config contains no development transport overrides.",z));if(at.push(await sje(v,"ios",z)),!await j2(ce))at.push(mc("ios.transport-security","The iOS Info.plist is missing.",ce,"Run `absolute mobile sync ios` before release validation."));else{let Pr=await El(ce,"utf8");at.push(/<key>NSAllowsArbitraryLoads<\/key>\s*<true\s*\/>/u.test(Pr)?mc("ios.transport-security","iOS App Transport Security permits arbitrary network loads.",ce,"Remove NSAllowsArbitraryLoads from the release Info.plist."):cu("ios.transport-security","iOS App Transport Security does not permit arbitrary loads.",ce))}let cr=await rve(ve);at.push(cr?mc("ios.hmr-assets","A packaged iOS asset contains the development HMR client.",cr,"Rebuild the production mobile bundle and run Capacitor sync again."):cu("ios.hmr-assets","Packaged iOS assets contain no development HMR markers.",ve)),at.push(await LY(v,P,"ios",ve),await jY(v,"ios",ve),await pje(Ba(v.nativeProjectDirectory,"ios")),await ekt(v,Ba(v.nativeProjectDirectory,"ios")));let mr=await JY(v,"ios");if(mr)at.push(mr);if(ht)at.push(ht);return at.map((Pr)=>({...Pr,path:Pr.path?hE(P,Pr.path).replaceAll("\\","/")||".":void 0}))};var dje=async(v,P)=>{let z=(await Promise.all([Promise.resolve(G2t(v,P)),Promise.resolve(X2t(v,P)),H2t(P),v.engine==="expo"?z2t(v):J2t(v,P),j2t(v,P),L2t(v,P)])).filter((qe)=>qe!==void 0).map((qe)=>({...qe,path:qe.path?hE(P,qe.path).replaceAll("\\","/")||".":void 0}));if(v.platforms.includes("android"))z.push(...v.engine==="expo"?await _kt(v,P):await ukt(v,P));if(v.platforms.includes("ios"))z.push(...v.engine==="expo"?await pkt(v,P):await dkt(v,P));let ce=tkt(P);if(ce)z.push({...ce,path:ce.path?hE(P,ce.path).replaceAll("\\","/")||".":void 0});let ve=await lkt(v,P);return z.push({...ve,path:ve.path?hE(P,ve.path).replaceAll("\\","/")||".":void 0}),{checks:z,ready:z.length>0&&z.every((qe)=>qe.status!=="fail")}};import{createHash as ove}from"crypto";import{access as mkt,copyFile as hje,mkdir as zY,mkdtemp as yje,readdir as cve,readFile as VY,rename as gkt,rm as vje,stat as qY,writeFile as lve}from"fs/promises";import{basename as mje,dirname as sve,isAbsolute as bje,join as Sf,relative as L7,resolve as WY,sep as ave}from"path";var hkt=1,ykt=(v)=>{if(v===void 0)return;let P=v.trim().toUpperCase();if(!/^[A-Z0-9]{10}$/u.test(P))throw TypeError("iOS development team must contain ten letters or digits.");return`DEVELOPMENT_TEAM=${P}`},j7=(v)=>typeof v==="object"&&v!==null&&!Array.isArray(v),vkt=(v)=>{if(!j7(v)||typeof v.appBuild!=="string"||typeof v.appId!=="string"||typeof v.runtime!=="string")throw TypeError("Invalid embedded AbsoluteJS mobile manifest.");return{appBuild:v.appBuild,appId:v.appId,deviceCapabilities:Array.isArray(v.deviceCapabilities)?v.deviceCapabilities.filter((P)=>typeof P==="string"):[],runtime:v.runtime}},bkt=/<key>aps-environment<\/key>\s*<string>([^<]*)<\/string>/,Skt=async(v)=>{let P=Sf(v.staging,"push-entitlement-check");if(v.capture(["ditto","-x","-k",v.artifactPath,P]).exitCode!==0)throw TypeError("Could not unpack the exported IPA to check its push entitlement.");let M=await OB(Sf(P,"Payload"),".app");if(!M)throw TypeError("The exported IPA does not contain an app bundle.");let z=v.capture(["codesign","--display","--entitlements",":-",M]);if(z.exitCode!==0)throw TypeError("Could not read the exported app's signed entitlements.");let ce=bkt.exec(z.stdout)?.[1];if(ce!=="production")throw TypeError(`The app uses push notifications, but its signed aps-environment entitlement is ${ce?`"${ce}"`:"missing"}, not "production". APNs production would reject its device tokens, so no installed user would receive push. Sign the release with an App Store distribution profile whose App ID has Push Notifications enabled.`)},u6=async(v)=>{try{return await mkt(v),!0}catch{return!1}},uve=async(v)=>{let P=Sf(v,"App","App.xcworkspace");if(await u6(P))return["-workspace",P];let M=Sf(v,"App","App.xcodeproj");if(await u6(M))return["-project",M];throw TypeError(`Neither App.xcworkspace nor App.xcodeproj exists under ${Sf(v,"App")}. Generate the native project with "absolute mobile sync ios".`)},Tkt=async(v,P={})=>Bun.spawn(v,{cwd:P.cwd,env:P.env,stderr:"inherit",stdin:"inherit",stdout:"inherit"}).exited,Sje=(v,P={})=>{try{let M=Bun.spawnSync(v,{cwd:P.cwd,env:P.env,stderr:"pipe",stdin:"ignore",stdout:"pipe"});return{exitCode:M.exitCode,stderr:M.stderr.toString(),stdout:M.stdout.toString()}}catch(M){return{exitCode:1,stderr:M instanceof Error?M.message:String(M),stdout:""}}},xkt=new Set(["Pods","DerivedData","build","xcuserdata",".swiftpm","swiftpm"]),Tje=async(v,P=v,M={})=>{let z=await cve(P,{withFileTypes:!0});return(await Promise.all(z.sort((ve,qe)=>ve.name.localeCompare(qe.name)).map(async(ve)=>{let qe=Sf(P,ve.name),at=L7(v,qe).replaceAll("\\","/");if(ve.isDirectory()&&(xkt.has(ve.name)||at==="App/App/public"&&M.includePublicBundle!==!0))return[];if(ve.isDirectory())return Tje(v,qe,M);return ve.isFile()?[qe]:[]}))).flat()},_ve=async(v,P={})=>{let M=ove("sha256"),z=await Tje(v,v,P),ce=await Promise.all(z.map((ve)=>VY(ve)));return z.forEach((ve,qe)=>{M.update(L7(v,ve).replaceAll("\\","/")),M.update("\x00"),M.update(ce[qe]??new Uint8Array),M.update("\x00")}),M.digest("hex")},kkt=(v,P)=>{let M=WY(v),z=WY(M,P??".absolutejs/mobile/releases/ios"),ce=L7(M,z);if(ce===".."||ce.startsWith(`..${ave}`)||bje(ce))throw TypeError("mobile build --outdir must remain inside the project.");return z},$Y=async(v)=>ove("sha256").update(await VY(v)).digest("hex"),Ckt=async(v,P)=>{if(!P.registeredDevice)return;let M=Sf(v,P.registeredDevice.artifact),[z,ce]=await Promise.all([qY(M).then(({size:ve})=>ve),$Y(M)]);if(z!==P.registeredDevice.bytes||ce!==P.registeredDevice.sha256)throw TypeError(`Immutable iOS release ${P.releaseId} registered-device artifact is missing or modified.`);return M},Ekt=async(v,P,M)=>{if(!P.registeredDevice)return;if(!M)throw TypeError("iOS release metadata requires a registered-device artifact.");await hje(M,Sf(v,P.registeredDevice.artifact))},OB=async(v,P)=>{if(!await u6(v))return;let M=await cve(v,{withFileTypes:!0});return(await Promise.all(M.map(async(ce)=>{let ve=Sf(v,ce.name);if(ce.isDirectory()&&ce.name.endsWith(P))return ve;if(ce.isFile()&&ce.name.endsWith(P))return ve;return ce.isDirectory()?OB(ve,P):void 0}))).find((ce)=>ce!==void 0)},UY=async(v,P,M={})=>{if(!await u6(v))return[];let z=await cve(v,{withFileTypes:!0});return(await Promise.all(z.map(async(ve)=>{let qe=Sf(v,ve.name);if(ve.name.endsWith(P))return[qe];if(!ve.isDirectory()||M.excludedDirectories?.has(ve.name))return[];return UY(qe,P,M)}))).flat().sort()},wkt=(v)=>{let P=mje(v);return(P==="project.xcworkspace"?mje(sve(v)):P).replace(/\.(xcodeproj|xcworkspace)$/,"")},Akt=(v,P,M)=>{let z=M(["xcodebuild","-list","-json",...v],{cwd:P});if(z.exitCode!==0)return[];try{let ce=JSON.parse(z.stdout),ve=j7(ce)?ce.workspace??ce.project:void 0,qe=j7(ve)?ve.schemes:void 0;return Array.isArray(qe)?qe.filter((at)=>typeof at==="string"):[]}catch{return[]}},fve=async(v,P={})=>{let M=P.workspacePath?WY(v,P.workspacePath):void 0;if(M){let xe=L7(v,M);if(xe===".."||xe.startsWith(`..${ave}`)||bje(xe))throw TypeError("iOS release workspacePath must remain inside the native iOS project.")}let z=M?[M]:await UY(v,".xcworkspace",{excludedDirectories:new Set(["Pods","DerivedData","build"])});if(z.length>1)throw TypeError(`iOS release found multiple Xcode workspaces: ${z.map((xe)=>L7(v,xe)).join(", ")}. Pass an explicit workspacePath.`);let[ce]=z,ve;if(ce&&await u6(ce))ve=["-workspace",ce];else if(M)throw TypeError("iOS release could not find the requested Xcode workspace.");else{let xe=await UY(v,".xcodeproj",{excludedDirectories:new Set(["Pods","DerivedData","build"])});if(xe.length>1)throw TypeError(`iOS release found multiple Xcode projects: ${xe.map((Nt)=>L7(v,Nt)).join(", ")}.`);let[qn]=xe;if(!qn||!await u6(qn))throw TypeError("iOS release could not find an Xcode workspace or project.");ve=["-project",qn]}if(P.scheme)return{scheme:P.scheme,target:ve};let qe=await UY(v,".xcscheme",{excludedDirectories:new Set(["Pods","DerivedData","build"])}),at=[...new Set(qe.map((xe)=>xe.slice(xe.lastIndexOf(ave)+1,-9)))];if(at.length>1)throw TypeError(`iOS release found multiple shared Xcode schemes: ${at.join(", ")}. Pass an explicit scheme.`);if(at[0])return{scheme:at[0],target:ve};let ht=ve[1]??"",cr=wkt(ht),mr=Akt(ve,v,P.capture??Sje),Pr=mr.length===1?mr[0]:mr.find((xe)=>xe===cr);if(Pr)return{scheme:Pr,target:ve};throw TypeError(mr.length>0?`iOS release found Xcode schemes ${mr.join(", ")}, none shared or named ${cr}. Pass an explicit scheme.`:"iOS release could not find a shared Xcode scheme.")},xje=(v)=>`<?xml version="1.0" encoding="UTF-8"?>
|
|
2710
|
+
`,at)+1,cr=DB(z,qe,ht);if(!P.capabilities.includes("pushNotifications"))return aP(M,cr);let mr=await IB(v.pushAndroidGoogleServicesFile);if(mr===null)throw TypeError(`Push notifications require Firebase config at ${v.pushAndroidGoogleServicesFile}. Set mobile.pushNotifications.android.googleServicesFile to override it.`);let Pr;try{Pr=JSON.parse(mr)}catch(os){throw TypeError("Android google-services.json is invalid JSON.",{cause:os})}let xe=typeof Pr==="object"&&Pr!==null?Reflect.get(Pr,"client"):void 0;if(!(Array.isArray(xe)&&xe.some((os)=>{let Pi=typeof os==="object"&&os!==null?Reflect.get(os,"client_info"):void 0,Us=typeof Pi==="object"&&Pi!==null?Reflect.get(Pi,"android_client_info"):void 0;return typeof Us==="object"&&Us!==null&&Reflect.get(Us,"package_name")===v.appId})))throw TypeError(`Android google-services.json does not contain package ${v.appId}.`);let[Nt,Ot]=await Promise.all([aP(M,cr),Vxt(a6(v.nativeProjectDirectory,"android/app/google-services.json"),mr)]);return Nt||Ot},z9e=async(v,P,M=P.platforms,z=rP(v))=>({changed:(await Promise.all(M.map(async(ve)=>({didChange:ve==="ios"?await Yxt(P,z):await e2t(P,z),platform:ve})))).filter(({didChange:ve})=>ve).map(({platform:ve})=>ve)});import{access as I2t,readFile as El,readdir as N2t}from"fs/promises";import{createHash as K9e}from"crypto";import{dirname as Q9e,extname as Y9e,join as Ba,relative as hE}from"path";import{createHash as i2t}from"crypto";import{access as s2t,readFile as V9e,stat as a2t}from"fs/promises";import{join as o2t,relative as c2t,resolve as RY}from"path";var FY=1;var o6={appBuild:"x-absolute-mobile-app-build",pageBundle:"x-absolute-mobile-page-bundle",pageContracts:"x-absolute-mobile-page-contracts",pageId:"x-absolute-mobile-page-id",protocol:"x-absolute-mobile-protocol",runtime:"x-absolute-mobile-runtime"};var jAt=["Accept",o6.protocol,o6.runtime,o6.appBuild,o6.pageBundle,o6.pageContracts,o6.pageId];var t2t=/[.*+?^${}()|[\]\\]/g,r2t=(v)=>{if(v==="*")return".*";if(v.startsWith(":")&&v.endsWith("?"))return"[^/]*";if(v.startsWith(":"))return"[^/]+";return v.replace(t2t,"\\$&")},n2t=(v,P)=>{let M=v.split("/").map(r2t).join("/");return new RegExp(`^${M}/?$`).test(P)},Z0e=(v,P,M="GET")=>v.find((z)=>z.method===M&&n2t(z.pattern,P));var W9e=1;var l2t=new Set(["angular","ember","html","htmx","react","svelte","vue"]),q9e=/^[a-f0-9]{64}$/u,R7=(v)=>typeof v==="object"&&v!==null&&!Array.isArray(v),u2t=(v,P)=>c2t(RY(v),RY(P)).replaceAll("\\","/")||".",_2t=async(v)=>{try{return await s2t(v),!0}catch{return!1}},f2t=async(v)=>{let P=JSON.parse(await V9e(v,"utf8"));if(!R7(P))throw TypeError("JSON root must be an object.");return P},V0=(v,P)=>{if(typeof v!=="string"||v.length===0)throw TypeError(`${P} must be a non-empty string.`);return v},p2t=(v,P)=>{if(!Array.isArray(v)||!v.every((M)=>typeof M==="string"))throw TypeError(`${P} must be a string array.`);return v},eve=async(v,P,M,z)=>{let ce=V0(P,M),ve=RY(v,ce),qe=RY(v);if(ve===qe||!ve.startsWith(`${qe}/`))throw TypeError(`${M} must remain inside the mobile bundle.`);if(!(await a2t(ve).catch(()=>{return}))?.isFile())throw TypeError(`${M} does not exist in the mobile bundle.`);if(z!==void 0){if(!q9e.test(z))throw TypeError(`${M} has an invalid SHA-256 digest.`);if(i2t("sha256").update(await V9e(ve)).digest("hex")!==z)throw TypeError(`${M} failed its SHA-256 integrity check.`)}return ce},$9e=async(v,P)=>{let M=o2t(v.bundleDirectory,"absolute-mobile-manifest.json"),z=u2t(P,M);if(!await _2t(M))return{manifest:z,status:"missing"};try{let ce=await f2t(M);if(ce.format!==W9e)throw TypeError("format is not supported by this runtime.");if(V0(ce.appId,"appId")!==v.appId)throw TypeError("appId does not match the effective mobile config.");if(V0(ce.productionOrigin,"productionOrigin")!==v.productionOrigin)throw TypeError("productionOrigin does not match the effective mobile config.");let ve=V0(ce.appBuild,"appBuild"),qe=V0(ce.runtime,"runtime"),at=V0(ce.nativeRuntime,"nativeRuntime");if(!q9e.test(at))throw TypeError("nativeRuntime must be a SHA-256 fingerprint.");if(qe!==String(FY))throw TypeError("runtime is not supported by this AbsoluteJS build.");let ht=p2t(ce.deviceCapabilities,"deviceCapabilities").sort();if(JSON.stringify(ce.updates??null)!==JSON.stringify(v.updates??null))throw TypeError("Embedded update trust configuration does not match mobile config.");if(!Array.isArray(ce.pages)||!Array.isArray(ce.routes))throw TypeError("pages and routes must be arrays.");let cr=new Set,mr=new Set;await Promise.all(ce.pages.map(async(Nt)=>{if(!R7(Nt))throw TypeError("pages contains an invalid entry.");let Ot=V0(Nt.pageId,"page.pageId");if(cr.has(Ot))throw TypeError("page.pageId values must be unique.");cr.add(Ot);let os=V0(Nt.framework,"page.framework");if(!l2t.has(os))throw TypeError("page.framework is unsupported.");mr.add(os);let Pi=V0(Nt.bundleHash,"page.bundleHash");if(V0(Nt.contract,"page.contract"),V0(Nt.propsSchemaHash,"page.propsSchemaHash"),await eve(v.bundleDirectory,Nt.localBundlePath,"page.localBundlePath",Pi),Nt.localStylePath!==void 0){let Us=V0(Nt.styleBundleHash,"page.styleBundleHash");await eve(v.bundleDirectory,Nt.localStylePath,"page.localStylePath",Us)}else if(Nt.styleBundleHash!==void 0)throw TypeError("page.styleBundleHash requires page.localStylePath.")}));let Pr=ce.routes.map((Nt)=>{if(!R7(Nt))throw TypeError("routes contains an invalid entry.");let{method:Ot}=Nt;if(Ot!=="GET"&&Ot!=="HEAD")throw TypeError("route.method must be GET or HEAD.");let os=V0(Nt.pageId,"route.pageId");if(!cr.has(os))throw TypeError("route.pageId references a missing page.");return{method:Ot,pageId:os,pattern:V0(Nt.pattern,"route.pattern")}});await Promise.all(["index.html","absolute-mobile-bootstrap.js"].map((Nt)=>eve(v.bundleDirectory,Nt,Nt)));let xe=new URL(v.entry,"https://absolute.invalid").pathname,qn=Z0e(Pr,xe)!==void 0;if(!qn)throw TypeError("entry is not owned by an embedded route.");return{appBuild:ve,auth:R7(ce.auth),capabilities:ht,entryResolved:qn,frameworks:[...mr].sort(),manifest:z,nativeRuntime:at,pageCount:ce.pages.length,routeCount:ce.routes.length,runtime:qe,status:"valid",sync:R7(ce.sync),updates:R7(ce.updates)}}catch(ce){return{issue:ce instanceof Error?ce.message:"The embedded mobile manifest is invalid.",manifest:z,status:"invalid"}}};import{createPrivateKey as d2t,createPublicKey as m2t,X509Certificate as g2t}from"crypto";import{access as h2t,mkdir as iPt}from"fs/promises";import{dirname as aPt,isAbsolute as y2t,relative as v2t,resolve as H9e,sep as b2t}from"path";import{pathToFileURL as S2t}from"url";var G9e=1,T2t="mobile.update.ts",tve=(v)=>typeof v==="object"&&v!==null&&!Array.isArray(v),x2t=(v,P)=>{let M=H9e(v),z=H9e(M,P),ce=v2t(M,z);if(ce===".."||ce.startsWith(`..${b2t}`)||y2t(ce))throw TypeError("mobile.updates.server.registry must remain inside the project.");return z},k2t=(v)=>tve(v)&&["publishUpdate","promoteUpdate","rollbackUpdate","resolveUpdate","readUpdateFile"].every((P)=>typeof v[P]==="function"),C2t=(v)=>{if(!tve(v))throw TypeError("Mobile update registry must export valid absoluteMobileUpdateServer metadata. Run `absolute mobile update provision`.");let{format:P,provider:M,storage:z}=v;if(P!==G9e||z!=="local"&&z!=="durable"||typeof M!=="string"||!M)throw TypeError("Mobile update registry must export valid absoluteMobileUpdateServer metadata. Run `absolute mobile update provision`.");return{format:G9e,provider:M,storage:z}},E2t=async(v,P=T2t)=>{let M=x2t(v,P);await h2t(M).catch(()=>{throw TypeError(`Mobile update server registry does not exist: ${M}. Run \`absolute mobile update provision\`.`)});let z=await import(S2t(M).href);if(!tve(z))throw TypeError("Mobile update registry module has no exports.");let ce=z.default??z.registry;if(!k2t(ce))throw TypeError("Mobile update registry must implement publication, promotion, rollback, resolution, and file reads.");let ve=C2t(z.absoluteMobileUpdateServer),qe=z.verifyAbsoluteMobileUpdateServer;if(ve.storage==="durable"&&typeof qe!=="function")throw TypeError("Mobile update registries marked durable must export verifyAbsoluteMobileUpdateServer(). Re-run `absolute mobile update provision --storage s3 --force` or provide an active durability check.");return{metadata:ve,registry:ce,...typeof qe==="function"?{verifyDurability:async()=>{await qe()}}:{}}},w2t=async(v)=>{if(v.metadata.storage!=="durable")throw TypeError("Mobile production updates require durable object storage. Re-run `absolute mobile update provision --storage s3 --force` or configure a durable adapter.");try{await v.verifyDurability?.()}catch(P){throw TypeError(`Durable mobile update storage verification failed for ${v.metadata.provider}. Check the bucket, endpoint, credentials, and read/write/delete permissions.`,{cause:P})}},A2t=(v,P)=>{if(!v.updateServer?.health)return;if(typeof P.registry.inspectUpdateHealth!=="function"||typeof P.registry.issueUpdateHealthToken!=="function"||typeof P.registry.recordUpdateHealth!=="function")throw TypeError("Mobile update fleet health is enabled but the registry is not provisioned for it. Run `absolute mobile update provision --force`.")},P2t=(v,P)=>{if(!v.updateServer?.rollout)return;if(typeof P.registry.advanceUpdateRollout!=="function"||typeof P.registry.cancelUpdateRollout!=="function"||typeof P.registry.inspectUpdateRollout!=="function"||typeof P.registry.pauseUpdateRollout!=="function"||typeof P.registry.reconcileUpdateRollout!=="function"||typeof P.registry.resumeUpdateRollout!=="function")throw TypeError("Mobile update rollout orchestration is enabled but the registry is not provisioned for it. Run `absolute mobile update provision --force`.")},D2t=(v)=>{if(!v.updates?.expoCodeSigning)return;let P=Object.entries(v.updateServer?.expoCodeSigningKeys??{});return{keys:Object.fromEntries(P.map(([z,ce])=>{let ve=process.env[ce.privateKeyEnv];if(!ve)throw TypeError(`Expo update serving requires ${ce.privateKeyEnv} on the trusted server.`);try{let at=new g2t(ce.certificatePem).publicKey.export({format:"der",type:"spki"}),ht=m2t(d2t(ve)).export({format:"der",type:"spki"});if(!at.equals(ht))throw Error("key mismatch")}catch(qe){throw TypeError(`${ce.privateKeyEnv} must contain the RSA private key matching Expo update key ${z}.`,{cause:qe})}return[z,{certificate:ce.certificatePem,privateKey:ve}]}))}};var X9e=async(v,P)=>{if(!v.updates)return;let M=await E2t(P,v.updateServer?.registryModule);if(await w2t(M),A2t(v,M),P2t(v,M),v.engine==="expo")D2t(v);return M.metadata};var O2t=/(?:hmr-timing|__absolute_target|absolutejs-error-overlay)/u,F2t=new Set([".html",".js",".mjs"]),Z9e=/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u,eje=-1,R2t=["bun.lock","bun.lockb","package-lock.json","pnpm-lock.yaml","yarn.lock"];var j2=async(v)=>{try{return await I2t(v),!0}catch{return!1}},M2t=async(v,P,M)=>{if(P)return rve(v);if(!M||!F2t.has(Y9e(v)))return;let z=await El(v,"utf8");return O2t.test(z)?v:void 0},rve=async(v)=>{if(!await j2(v))return;let P=await N2t(v,{withFileTypes:!0});return(await Promise.all(P.map((z)=>M2t(Ba(v,z.name),z.isDirectory(),z.isFile())))).find((z)=>z!==void 0)},cu=(v,P,M)=>({detail:P,id:v,path:M,status:"pass"}),mc=(v,P,M,z)=>({detail:P,id:v,path:M,remediation:z,status:"fail"}),tje=(v,P,M,z)=>({detail:P,id:v,path:M,remediation:z,status:"warn"}),L2t=async(v,P)=>{if(!v.updates)return;try{let M=await X9e(v,P);return cu("updates.trusted-server",`The trusted update server proved durable ${M?.provider??"object"} storage read/write/delete access, supports publish/promote/rollback, and has valid server-only signing material.`,v.updateServer?.registryModule)}catch(M){return mc("updates.trusted-server",M instanceof Error?M.message:"The trusted mobile update server is not release-ready.",v.updateServer?.registryModule??"mobile.update.ts","Run `absolute mobile update provision --storage s3 --force`, provision its environment variables on the trusted server, and rerun the release doctor.")}},j2t=async(v,P)=>{let M=await k9e(v,P);if(M.status==="absent")return tje("mobile.branding",M.detail,void 0,"Configure mobile.branding and run `absolute mobile assets` before store submission.");if(!M.ready)return mc("mobile.branding",M.detail,M.manifestPath,"Run `absolute mobile assets`, review the generated preview, and commit the native resource changes.");return cu("mobile.branding",M.detail,M.manifestPath)},M7=(v)=>typeof v==="object"&&v!==null&&!Array.isArray(v),yE=async(v)=>{let P=JSON.parse(await El(v,"utf8"));if(typeof P!=="object"||P===null||Array.isArray(P))throw TypeError("JSON root must be an object.");return Object.fromEntries(Object.entries(P))},nve=(v)=>{let P=new Map;for(let M of["dependencies","devDependencies"]){let z=v[M];if(typeof z!=="object"||z===null||Array.isArray(z))continue;for(let[ce,ve]of Object.entries(z))if(typeof ve==="string")P.set(ce,ve)}return P},B2t=(v)=>v.split("-")[0]?.split(".").slice(0,2).join("."),J2t=async(v,P)=>{let M=Ba(P,"package.json");try{let z=await yE(M),ce=nve(z),ve=["@capacitor/core","@capacitor/cli",...v.platforms.map((ht)=>`@capacitor/${ht}`)],qe=await Promise.all(ve.map(async(ht)=>{let cr=ce.get(ht);if(!cr||!Z9e.test(cr))throw TypeError(`${ht} must be a direct exact dependency.`);if((await yE(await $2t(P,ht))).version!==cr)throw TypeError(`${ht} does not match its installed version.`);return cr}));if(new Set(qe.map(B2t)).size!==1)throw TypeError("Capacitor core, CLI, and platform packages must use one major/minor line.");return cu("mobile.capacitor-versions",`Capacitor core, CLI, and configured platforms are pinned and aligned on ${qe[0]}.`,M)}catch(z){return mc("mobile.capacitor-versions",z instanceof Error?z.message:"Capacitor package versions could not be validated.",M,"Pin @capacitor/core, @capacitor/cli, and each configured platform to exact versions on the same major/minor line, then reinstall.")}},U2t=(v,P)=>{if(Z9e.test(v))return v===P;if(!v.startsWith("~"))return!1;let M=v.slice(1).split(".").map(Number),z=P.split(".").map(Number);return z[0]===M[0]&&z[1]===M[1]&&(z[2]??eje)>=(M[2]??0)},z2t=async(v)=>{let P=Ba(v.nativeProjectDirectory,"package.json");try{let M=await yE(P),z=nve(M),ve=["expo","expo-router","react","react-native"].find((ht)=>!z.has(ht));if(ve)throw TypeError(`Generated Expo project is missing ${ve}.`);let at=(await Promise.all([...z].map(async([ht,cr])=>({declared:cr,installed:await yE(Ba(v.nativeProjectDirectory,"node_modules",ht,"package.json")),name:ht})))).find(({declared:ht,installed:cr})=>typeof cr.version!=="string"||!U2t(ht,cr.version));if(at)throw TypeError(`Generated Expo dependency ${at.name}@${at.declared} does not match its installed version.`);if(!await j2(Ba(v.nativeProjectDirectory,"bun.lock")))throw TypeError("Generated Expo dependency lockfile is missing.");return cu("mobile.expo-versions",`Generated Expo SDK dependencies are pinned, installed, and locked (${z.get("expo")}).`,P)}catch(M){return mc("mobile.expo-versions",M instanceof Error?M.message:"Generated Expo dependency versions could not be validated.",P,"Run `absolute mobile init --yes`, then rebuild the production Expo project.")}},W2t=async(v)=>(await Promise.all(R2t.map(async(P)=>({exists:await j2(Ba(v,P)),name:P,path:Ba(v,P)})))).find(({exists:P})=>P),V2t=(v)=>{if(Array.isArray(v))return v;if(M7(v)&&Array.isArray(v.packages))return v.packages;return[]},rje=async(v,P)=>{let M=await yE(Ba(v,"package.json")).catch(()=>{return}),z=hE(v,P).replace(/\\/gu,"/");return V2t(M?.workspaces).some((ce)=>typeof ce==="string"&&new Bun.Glob(ce).match(z))},nje=(v)=>{let P=[],M=v;while(!0){P.push(M);let z=Q9e(M);if(z===M)return P;M=z}},q2t=async(v)=>(await Promise.all(nje(v).map(async(M,z)=>{let ce=await W2t(M);if(!ce||z>0&&!await rje(M,v))return;return ce}))).find((M)=>M!==void 0),$2t=async(v,P)=>{let z=(await Promise.all(nje(v).map(async(ce,ve)=>{if(ve>0&&!await rje(ce,v))return;let qe=Ba(ce,"node_modules",P,"package.json");return await j2(qe)?qe:void 0}))).find((ce)=>ce!==void 0);if(z)return z;throw TypeError(`${P} is not installed for this application.`)},H2t=async(v)=>{let P=await q2t(v);return P?cu("mobile.dependency-lock",`Dependency graph is locked by ${P.name}.`,P.path):mc("mobile.dependency-lock","No supported dependency lockfile is present.",v,"Install dependencies with the project package manager and commit its lockfile before release.")},G2t=(v,P)=>new URL(v.productionOrigin).protocol==="https:"?cu("mobile.production-origin","Production transport uses an HTTPS origin."):mc("mobile.production-origin","A loopback development origin cannot be used for a signed release.",P,"Configure mobile.server.productionOrigin with the deployed HTTPS origin."),X2t=(v,P)=>{let M=[...v.platforms.includes("ios")&&!v.appleAppIdPrefix?["mobile.deepLinks.apple.appIdPrefix"]:[],...v.platforms.includes("android")&&v.androidCertificateFingerprints.length===0?["mobile.deepLinks.android.sha256CertificateFingerprints"]:[]];return M.length===0?cu("mobile.association-identities","Deep-link association identities are configured for every release platform."):mc("mobile.association-identities",`Release association identity is missing: ${M.join(", ")}.`,P,"Configure the Apple application prefix and every Android signing-certificate SHA-256 fingerprint used for release.")},MY=async(v,P)=>await j2(v)?mc(`${P}.dev-journal`,"A live-reload recovery journal is still active.",v,"Close the development session or run mobile doctor again after stale-session repair."):cu(`${P}.dev-journal`,"No live-reload recovery journal is active.",v),K2t=(v)=>{try{return JSON.parse(v)}catch{return}},Q2t=(v)=>{if(typeof v!=="object"||v===null)return;let P=Reflect.get(v,"server");return typeof P==="object"&&P!==null?P:void 0},ije=(v)=>{let P=K2t(v),M=Q2t(P);if(P===void 0)return!0;if(!M)return!1;let z=Reflect.get(M,"allowNavigation");return typeof Reflect.get(M,"url")==="string"||Reflect.get(M,"cleartext")===!0||Array.isArray(z)&&z.length>0},Y2t=async(v)=>{if(!await j2(v))return mc("android.capacitor-config","The generated Android Capacitor config is missing.",v,"Run `absolute mobile sync android` before release validation.");return ije(await El(v,"utf8"))?mc("android.capacitor-config","Android Capacitor config contains a development server URL, cleartext transport, navigation allowlist, or invalid JSON.",v,"Run `absolute mobile sync android`; do not ship development transport overrides."):cu("android.capacitor-config","Android Capacitor config contains no development transport overrides.",v)},sje=async(v,P,M)=>{try{let z=await yE(M);if(z.appId!==v.appId||z.appName!==v.appName)throw TypeError(`${P} packaged application identity does not match mobile config.`);return cu(`${P}.app-identity`,`Packaged ${P} application identity matches mobile config.`,M)}catch(z){return mc(`${P}.app-identity`,z instanceof Error?z.message:`${P} application identity could not be validated.`,M,`Run \`absolute mobile sync ${P}\` and review the generated Capacitor config.`)}},aje=async(v)=>{if(!await j2(v))return mc("android.cleartext","The Android manifest is missing.",v,"Run `absolute mobile sync android` before release validation.");let P=await El(v,"utf8"),M=/android:usesCleartextTraffic=["']true["']/u.test(P),z=P.match(/android:networkSecurityConfig=["']@xml\/([a-z0-9_]+)["']/u)?.[1],ce=z?Ba(Q9e(v),"res","xml",`${z}.xml`):void 0,ve=/android:networkSecurityConfig=["']@xml\/absolutejs_dev_network_security["']/u.test(P),qe=ce?await El(ce,"utf8").then((ht)=>ht.includes("@raw/absolutejs_dev_ca")).catch(()=>!1):!1,at=ve||qe;return M||at?mc("android.cleartext",at?"Android still references the AbsoluteJS development certificate authority.":"Android explicitly permits cleartext traffic.",v,"Run `absolute mobile sync android`; do not ship development transport or trust overrides."):cu("android.cleartext","Android does not explicitly permit cleartext traffic.",v)},ive=async(v)=>{let P=await rve(v);return P?mc("android.hmr-assets","A packaged Android asset contains the development HMR client.",P,"Rebuild the production mobile bundle and run Capacitor sync again."):cu("android.hmr-assets","Packaged Android assets contain no development HMR markers.",v)},LY=async(v,P,M,z)=>{let ce=await $9e({...v,bundleDirectory:z},P);if(ce.status==="valid")return cu(`${M}.bundle-integrity`,`Packaged mobile manifest, runtime, routes, and ${ce.pageCount??0} page asset(s) passed structural and SHA-256 validation.`,Ba(z,"absolute-mobile-manifest.json"));return mc(`${M}.bundle-integrity`,ce.status==="missing"?"The packaged mobile manifest is missing.":`The packaged mobile bundle is invalid: ${ce.issue??"unknown validation error"}`,Ba(z,"absolute-mobile-manifest.json"),"Rebuild the production mobile bundle and run Capacitor sync for this platform.")},jY=async(v,P,M)=>{let z=Ba(M,"index.html");try{let ce=await El(z,"utf8");if(["Content-Security-Policy","default-src 'self'","base-uri 'none'","object-src 'none'","script-src 'self'","form-action 'none'",v.productionOrigin].filter((at)=>!ce.includes(at)).length>0)throw TypeError("Packaged shell CSP is missing a required AbsoluteJS directive or backend origin.");return cu(`${P}.content-security-policy`,"Packaged shell CSP restricts scripts, objects, base URLs, forms, and backend connections.",z)}catch(ce){return mc(`${P}.content-security-policy`,ce instanceof Error?ce.message:"Packaged shell CSP could not be validated.",z,"Rebuild the production mobile bundle with the AbsoluteJS-generated shell.")}},Z2t=async(v,P)=>{let M=v.updates?.expoCodeSigning,z=M7(P.updates)?P.updates:void 0;if(v.updates&&!M)throw TypeError("Expo production updates require an embedded code-signing certificate.");if(!M&&z&&(("codeSigningCertificate"in z)||("codeSigningMetadata"in z)))throw TypeError("Generated Expo config contains unconfigured code-signing material.");if(!M)return;if(!z||z.codeSigningCertificate!=="./certs/absolute-mobile-update.pem"||!M7(z.codeSigningMetadata)||z.codeSigningMetadata.keyid!==M.keyId||z.codeSigningMetadata.alg!==M.algorithm)throw TypeError("Generated Expo code-signing metadata does not match mobile config.");if(await El(Ba(v.nativeProjectDirectory,"certs","absolute-mobile-update.pem"),"utf8")!==M.certificatePem)throw TypeError("Generated Expo code-signing certificate does not match mobile config.")},oje=async(v,P)=>{let M=Ba(v.nativeProjectDirectory,"app.json");try{let z=await yE(M);if(!M7(z.expo))throw TypeError("Generated Expo application config is invalid.");let{expo:ce}=z;if(ce.name!==v.appName||v.platforms.includes("android")&&(!M7(ce.android)||ce.android.package!==v.appId)||v.platforms.includes("ios")&&(!M7(ce.ios)||ce.ios.bundleIdentifier!==v.appId))throw TypeError("Generated Expo application identity does not match mobile config.");let ve=bY(v,P).fingerprint;if(ce.runtimeVersion!==ve)throw TypeError("Generated Expo runtimeVersion does not match the AbsoluteJS native contract.");if(await Z2t(v,ce),Array.isArray(ce.plugins)&&ce.plugins.some((qe)=>typeof qe==="string"&&qe.includes("withAbsoluteDevelopmentCa")))throw TypeError("Generated Expo production config includes the development CA plugin.");return cu("expo.app-config","Expo application identity and generated native runtime match the production mobile config.",M)}catch(z){return mc("expo.app-config",z instanceof Error?z.message:"Generated Expo application config could not be validated.",M,"Run `absolute mobile build <platform>`; do not edit the generated Expo project.")}},cje=async(v)=>{let P=Ba(v.nativeProjectDirectory,"src","generated","webAssets.ts"),M=Ba(v.nativeProjectDirectory,"assets","absolute");try{let[z,ce]=await Promise.all([El(P,"utf8"),yE(Ba(v.bundleDirectory,"absolute-mobile-manifest.json"))]);if(z.includes("embedded AbsoluteJS bundle is unavailable")||typeof ce.appBuild!=="string"||!z.includes(JSON.stringify(ce.appBuild))||!z.includes(JSON.stringify(v.productionOrigin)))throw TypeError("Generated Expo assets do not contain the prepared production release identity.");let ve=(await Array.fromAsync(new Bun.Glob("**/*").scan({cwd:v.bundleDirectory,onlyFiles:!0}))).sort(),qe=(await Array.fromAsync(new Bun.Glob("*.absasset").scan({cwd:M,onlyFiles:!0}))).sort();if(ve.length===0||qe.length!==1)throw TypeError("Generated Expo asset count does not match the prepared mobile bundle.");let at=await Promise.all(ve.map((Pr)=>El(Ba(v.bundleDirectory,Pr)))),ht=0,cr=ve.map((Pr,xe)=>{let qn={length:at[xe]?.byteLength??0,md5:K9e("md5").update(at[xe]??Buffer.alloc(0)).digest("hex"),offset:ht,path:Pr.replaceAll("\\","/")};return ht+=qn.length,qn}),mr=await El(Ba(M,qe[0]??""));if(!mr.equals(Buffer.concat(at))||!z.includes(`const ARCHIVE_MD5 = ${JSON.stringify(K9e("md5").update(mr).digest("hex"))};`)||!z.includes(`const ARCHIVE_LENGTH = ${mr.byteLength};`)||cr.some((Pr)=>!z.includes(JSON.stringify(Pr))))throw TypeError("Generated Expo asset bytes differ from the prepared mobile bundle.");return cu("expo.bundle-projection",`Expo embeds the complete signed mobile bundle as one opaque archive containing ${ve.length} file(s).`,P)}catch(z){return mc("expo.bundle-projection",z instanceof Error?z.message:"Generated Expo assets could not be validated.",P,"Run `absolute mobile build <platform>` to regenerate and verify the production asset projection.")}},BY=async(v,P)=>{if(!await j2(v))return[];return(await Array.fromAsync(new Bun.Glob("**/*").scan({cwd:v,onlyFiles:!0}))).filter((z)=>P.has(Y9e(z))).map((z)=>Ba(v,z))},l6=async(v,P)=>{let z=(await Promise.all(v.map((ce)=>El(ce,"utf8")))).findIndex((ce)=>P.test(ce));return z===eje?void 0:v[z]},lje=async(v)=>{let P=Ba(v,"app/src/main/AndroidManifest.xml");try{let M=await El(P,"utf8");if(/android:debuggable=["']true["']/u.test(M))throw TypeError("Android release manifest explicitly enables application debugging.");let z=await BY(Ba(v,"app/src/main"),new Set([".java",".kt"])),ce=await l6(z,/setWebContentsDebuggingEnabled\s*\(\s*true\s*\)/u);if(ce)return mc("android.native-debugging","Android application source unconditionally enables WebView debugging.",ce,"Remove the unconditional WebView debugging call; use the platform debug-build behavior during development.");return cu("android.native-debugging","Android does not explicitly enable app or WebView debugging in release source.",P)}catch(M){return mc("android.native-debugging",M instanceof Error?M.message:"Android native debugging configuration could not be validated.",P,"Remove explicit release debugging settings and rerun mobile sync.")}},uje=async(v)=>{let M=[...(await El(v,"utf8").catch(()=>"")).matchAll(/<(?:activity|activity-alias|provider|receiver|service)\b[^>]*>/giu)].map(([z])=>z).filter((z)=>/android:exported=["']true["']/iu.test(z)).map((z)=>z.match(/android:name=["']([^"']+)["']/iu)?.[1]).filter((z)=>Boolean(z)&&z!==".MainActivity");return M.length===0?cu("android.exported-components","No non-launcher Android component is explicitly exported.",v):tje("android.exported-components",`${M.length} non-launcher Android component(s) are exported and require manual authorization review.`,v,"Confirm each exported component is intentional, permission-protected where appropriate, and documented in the mobile threat model review.")},_je=async(v,P)=>{try{let M=await El(P,"utf8"),z=(ce)=>[...M.matchAll(/<data\b[^>]*>/giu)].some(([ve])=>ve.includes('android:scheme="https"')&&ve.includes(`android:host="${ce}"`));if(!M.includes('android:autoVerify="true"')||!M.includes("android.intent.category.BROWSABLE")||v.deepLinkHosts.some((ce)=>!z(ce))||v.deepLinkScheme&&!M.includes(`android:scheme="${v.deepLinkScheme}"`))throw TypeError("Android App Link or custom-scheme projection does not match mobile config.");return cu("android.deep-links","Android verified links and custom scheme match the effective mobile config.",P)}catch(M){return mc("android.deep-links",M instanceof Error?M.message:"Android deep-link projection could not be validated.",P,"Run `absolute mobile sync android` and review the AbsoluteJS-owned deep-link region.")}},fje=async(v,P)=>{if(!v.updates)return;let M=String(v.updates.bootTimeoutMs);if(P==="ios"){let at=Ba(v.nativeProjectDirectory,"ios/App/App/AppDelegate.swift"),ht=Ba(v.nativeProjectDirectory,"ios/App/App/capacitor.config.json"),[cr,mr]=await Promise.all([El(at,"utf8").catch(()=>""),El(ht,"utf8").catch(()=>"")]);return cr.includes("AbsoluteMobileUpdateWatchdogPlugin")&&cr.includes("recoverInterruptedBoot()")&&cr.includes(`.milliseconds(${M})`)&&cr.includes("quarantinedReleases")&&mr.includes("AbsoluteMobileUpdateWatchdogPlugin")?cu("ios.update-watchdog",`The native update boot watchdog is projected with a ${M}ms deadline.`,at):mc("ios.update-watchdog","The iOS update boot watchdog does not match mobile config.",at,"Run `absolute mobile sync ios` before building the release.")}let z=Ba(v.nativeProjectDirectory,"android/app/src/main"),ce=await BY(z,new Set([".java",".kt"])),[ve,qe]=await Promise.all([l6(ce,/recoverInterruptedBoot\s*\(\s*this\s*\)/u),l6(ce,new RegExp(`handler\\.postDelayed\\(deadline,\\s*${M}L\\)`,"u"))]);return ve&&qe?cu("android.update-watchdog",`The native update boot watchdog is projected with a ${M}ms deadline.`,qe):mc("android.update-watchdog","The Android update boot watchdog does not match mobile config.",qe??z,"Run `absolute mobile sync android` before building the release.")},JY=async(v,P)=>{if(!v.observability)return;let M=v.nativeProjectDirectory;if(v.engine==="expo"){let at=Ba(M,"modules","absolute-mobile-observability"),ht=Ba(at,"expo-module.config.json"),cr=P==="android"?Ba(at,"android/src/main/java/expo/modules/absolutemobileobservability/AbsoluteMobileObservabilityModule.kt"):Ba(at,"ios/AbsoluteMobileObservabilityModule.swift"),[mr,Pr]=await Promise.all([El(ht,"utf8").catch(()=>""),El(cr,"utf8").catch(()=>"")]);return mr.includes("AbsoluteMobileObservabilityModule")&&Pr.includes("AbsoluteMobileObservability")&&(P==="android"?Pr.includes("getHistoricalProcessExitReasons"):Pr.includes("MXMetricManagerSubscriber"))?cu(`${P}.native-observability`,`The Expo ${P} native process collector is projected and autolinkable.`,cr):mc(`${P}.native-observability`,`The Expo ${P} native process collector is missing or incomplete.`,cr,`Run \`absolute mobile build ${P}\` before building the release.`)}if(P==="ios"){let at=Ba(M,"ios/App/App/AppDelegate.swift"),ht=Ba(M,"ios/App/App/capacitor.config.json"),[cr,mr]=await Promise.all([El(at,"utf8").catch(()=>""),El(ht,"utf8").catch(()=>"")]);return cr.includes("AbsoluteMobileObservabilityPlugin")&&cr.includes("MXMetricManagerSubscriber")&&mr.includes("AbsoluteMobileObservabilityPlugin")?cu("ios.native-observability","The iOS MetricKit native process collector is projected and registered.",at):mc("ios.native-observability","The iOS MetricKit native process collector is missing or unregistered.",at,"Run `absolute mobile sync ios` before building the release.")}let z=Ba(M,"android/app/src/main"),ce=await BY(z,new Set([".java",".kt"])),[ve,qe]=await Promise.all([l6(ce,/registerPlugin\s*\(\s*AbsoluteMobileObservabilityPlugin(?:::class\.java|\.class)\s*\)/u),l6(ce,/getHistoricalProcessExitReasons\s*\(/u)]);return ve&&qe?cu("android.native-observability","The Android process-exit collector is projected and registered.",qe):mc("android.native-observability","The Android process-exit collector is missing or unregistered.",qe??z,"Run `absolute mobile sync android` before building the release.")},pje=async(v)=>{let P=async(qe)=>(await BY(v,qe)).filter((at)=>!hE(v,at).split(/[\\/]/u).some((ht)=>["Pods","DerivedData","build"].includes(ht))),M=await P(new Set([".entitlements"])),z=await l6(M,/<key>(?:com\.apple\.security\.)?get-task-allow<\/key>\s*<true\s*\/>/u);if(z)return mc("ios.native-debugging","iOS source entitlements explicitly permit debugger attachment.",z,"Remove get-task-allow from source entitlements; Xcode supplies development entitlements only to debug builds.");let ce=await P(new Set([".m",".mm",".swift"])),ve=await l6(ce,/\.isInspectable\s*=\s*true|setInspectable\s*\(\s*true\s*\)/u);if(ve)return mc("ios.native-debugging","iOS application source unconditionally enables WebView inspection.",ve,"Remove unconditional WebView inspection from release source.");return cu("ios.native-debugging","iOS source does not enable release debugger attachment or WebView inspection.",M[0]??v)},ekt=async(v,P)=>{let M=Ba(P,"App/App/Info.plist"),z=Ba(P,"App/App/AbsoluteJS.entitlements"),ce=Ba(P,"App/App.xcodeproj/project.pbxproj");try{let[ve,qe,at]=await Promise.all([El(M,"utf8"),El(z,"utf8"),El(ce,"utf8")]);if(v.deepLinkScheme&&(!ve.includes("<key>CFBundleURLTypes</key>")||!ve.includes(`<string>${v.deepLinkScheme}</string>`)))throw TypeError("iOS custom URL scheme does not match mobile config.");if(v.deepLinkHosts.some((ht)=>!qe.includes(`<string>applinks:${ht}</string>`)))throw TypeError("iOS associated domains do not match mobile config.");if(!at.includes("CODE_SIGN_ENTITLEMENTS = App/AbsoluteJS.entitlements;"))throw TypeError("iOS target does not sign the AbsoluteJS entitlements file.");return cu("ios.deep-links","iOS universal links, custom scheme, and signed entitlements match mobile config.",z)}catch(ve){return mc("ios.deep-links",ve instanceof Error?ve.message:"iOS deep-link projection could not be validated.",z,"Run `absolute mobile sync ios` and review the AbsoluteJS-owned deep-link and entitlement projection.")}},tkt=(v)=>{if(!ZA(v))return;let P=Ba(v,"package.json");try{let M=w7(v),z=M.components.map((Pr)=>`${Pr.id}@${Pr.version}`).join(", "),ce=M.components.flatMap((Pr)=>Pr.localData?.collections??[]),ve=M.components.flatMap((Pr)=>Pr.localData?.mutations??[]),qe=[...ce,...ve].filter((Pr)=>Pr.protection==="required").length,at=[...ce,...ve].filter((Pr)=>Pr.persistence==="memory-only"||Pr.onProtectionUnavailable==="memory-only").length,ht={clientWins:ve.filter((Pr)=>Pr.conflict?.strategy==="client-wins").length,manual:ve.filter((Pr)=>Pr.conflict?.strategy==="manual").length,serverWins:ve.filter((Pr)=>Pr.conflict?.strategy==="server-wins").length},cr=M.components.map((Pr)=>Pr.localData?.maxBytesPerNamespace).filter((Pr)=>Pr!==void 0),mr=`${ce.length} collection rule(s), ${ve.length} mutation rule(s), ${qe} encryption-required, ${at} memory-only fallback(s), conflicts ${ht.clientWins} client-wins/${ht.serverWins} server-wins/${ht.manual} manual${cr.length>0?`, ${Math.min(...cr)}-byte effective quota`:", no logical quota"}`;return cu("sync.storage-schema",`Generated offline schema is compatible: ${z}; ${mr}.`,P)}catch(M){return mc("sync.storage-schema",M instanceof Error?M.message:"Generated offline schema metadata is invalid.",P,"Fix absolutejs.sync.localSchema metadata in the named app or package before releasing.")}},rkt={camera:"NSCameraUsageDescription","location-always":"NSLocationAlwaysAndWhenInUseUsageDescription","location-when-in-use":"NSLocationWhenInUseUsageDescription","photo-library":"NSPhotoLibraryUsageDescription","photo-library-add":"NSPhotoLibraryAddUsageDescription"},nkt=async(v,P)=>{if(!v.platforms.includes("android")||P.length===0)return;let M=Ba(v.nativeProjectDirectory,"android/app/src/main/AndroidManifest.xml"),z=await El(M,"utf8"),ce=P.filter((ve)=>!z.includes(`android:name="${ve}"`)&&!z.includes(`android:name='${ve}'`));if(ce.length===0)return;return mc("mobile.device-capabilities",`Android is missing native declarations for: ${ce.join(", ")}.`,M,"Run `absolute mobile sync android` to regenerate detected device permissions.")},ikt=async(v,P)=>{if(!v.platforms.includes("ios")||P.length===0)return;let M=Ba(v.nativeProjectDirectory,"ios"),z=v.engine==="expo"?await c6(M,"**/Info.plist","Info.plist"):Ba(M,"App/App/Info.plist"),ce=await El(z,"utf8"),ve=P.filter((qe)=>!ce.includes(`<key>${rkt[qe]}</key>`));if(ve.length===0)return;return mc("mobile.device-capabilities",`iOS is missing usage descriptions for: ${ve.join(", ")}.`,z,"Run `absolute mobile sync ios` to regenerate detected device usage descriptions.")},skt=async(v,P,M)=>{if(M.iosPrivacyAccessedApis.length===0)return;let z=await c6(v,"**/PrivacyInfo.xcprivacy","privacy manifest"),ce=await El(z,"utf8");if(!M.iosPrivacyAccessedApis.some(({api:qe,reasons:at})=>!ce.includes(`<string>${qe}</string>`)||at.some((ht)=>!ce.includes(`<string>${ht}</string>`)))&&P.includes(z.split(/[\\/]/u).at(-1)??""))return;return mc("mobile.device-capabilities","Expo iOS privacy manifest or target membership does not match detected capabilities.",z,"Run `absolute mobile build ios` to regenerate detected Expo privacy declarations.")},akt=async(v,P)=>{if(!P.iosPushNotifications)return;let M=await c6(v,"**/*.entitlements","entitlements");if((await El(M,"utf8")).includes("<key>aps-environment</key>"))return;return mc("mobile.device-capabilities","Expo iOS push entitlement does not match detected capabilities.",M,"Run `absolute mobile build ios` to regenerate native push integration.")},okt=async(v,P)=>{let M=Ba(v.nativeProjectDirectory,"ios"),z=await c6(M,"**/*.xcodeproj/project.pbxproj","Xcode project"),ce=await El(z,"utf8"),ve=await skt(M,ce,P);if(ve)return ve;return akt(M,P)},ckt=async(v,P)=>{if(!v.platforms.includes("ios"))return;if(v.engine==="expo")return okt(v,P);let M=Ba(v.nativeProjectDirectory,"ios/App/App"),z=Ba(M,"Info.plist"),ce=await El(z,"utf8").catch(()=>"");if(P.iosSystemBars&&!/<key>UIViewControllerBasedStatusBarAppearance<\/key>\s*<true\s*\/>/u.test(ce))return mc("mobile.device-capabilities","iOS system-bar capability is missing its required view-controller setting.",z,"Run `absolute mobile sync ios` to regenerate native capability settings.");if(P.iosPrivacyAccessedApis.length>0){let ve=Ba(M,"PrivacyInfo.xcprivacy"),qe=Ba(v.nativeProjectDirectory,"ios/App/App.xcodeproj/project.pbxproj"),[at,ht]=await Promise.all([El(ve,"utf8").catch(()=>""),El(qe,"utf8").catch(()=>"")]);if(P.iosPrivacyAccessedApis.some(({api:mr,reasons:Pr})=>!at.includes(`<string>${mr}</string>`)||Pr.some((xe)=>!at.includes(`<string>${xe}</string>`)))||!ht.includes("PrivacyInfo.xcprivacy in Resources"))return mc("mobile.device-capabilities","iOS privacy manifest or target membership does not match detected native capabilities.",ve,"Run `absolute mobile sync ios` to regenerate and target PrivacyInfo.xcprivacy.")}if(P.iosPushNotifications){let ve=Ba(v.nativeProjectDirectory,"ios/App/App/AbsoluteJS.entitlements"),qe=Ba(M,"AppDelegate.swift"),[at,ht]=await Promise.all([El(ve,"utf8").catch(()=>""),El(qe,"utf8").catch(()=>"")]);if(!at.includes("<key>aps-environment</key>")||!ht.includes("capacitorDidRegisterForRemoteNotifications")||!ht.includes("capacitorDidFailToRegisterForRemoteNotifications"))return mc("mobile.device-capabilities","iOS push entitlement or AppDelegate forwarding does not match detected capabilities.",ve,"Run `absolute mobile sync ios` to regenerate native push integration.")}return},lkt=async(v,P)=>{let M=Ba(P,"package.json");try{let z=rP(P,v.engine);await(async()=>{if(v.engine==="capacitor")return _9e(P,z);let cr=await yE(Ba(v.nativeProjectDirectory,"package.json")),mr=nve(cr),Pr=z.requiredPackages.filter((xe)=>{let qn=xe.lastIndexOf("@");return mr.get(xe.slice(0,qn))!==xe.slice(qn+1)});if(Pr.length>0)throw TypeError(`Generated Expo project is missing detected capability packages: ${Pr.join(", ")}.`);return})();let ve=e6(z),qe=await nkt(v,ve.androidPermissions);if(qe)return qe;let at=await ikt(v,ve.iosUsageDescriptions);if(at)return at;let ht=await ckt(v,ve);if(ht)return ht;return cu("mobile.device-capabilities",z.capabilities.length>0?`Native provider packages and permission declarations match detected capabilities: ${z.capabilities.join(", ")}.`:"No optional native device capabilities are used.",M)}catch(z){return mc("mobile.device-capabilities",z instanceof Error?z.message:"Native device capability provisioning is invalid.",M,"Run `absolute mobile sync` and approve the exact capability plugins before releasing.")}},ukt=async(v,P)=>{let M=Ba(v.nativeProjectDirectory,"android"),z=Ba(M,"app","src","main","assets","capacitor.config.json"),ce=Ba(M,"app","src","main","AndroidManifest.xml"),ve=Ba(M,"app","src","main","assets","public"),qe=Ba(P,".absolutejs","mobile","dev-session","journal.json");return(await Promise.all([MY(qe,"android"),Y2t(z),sje(v,"android",z),aje(ce),ive(ve),LY(v,P,"android",ve),jY(v,"android",ve),lje(M),uje(ce),_je(v,ce),fje(v,"android"),JY(v,"android")])).filter((ht)=>ht!==void 0).map((ht)=>({...ht,path:ht.path?hE(P,ht.path).replaceAll("\\","/")||".":void 0}))},_kt=async(v,P)=>{let M=Ba(v.nativeProjectDirectory,"android"),z=Ba(M,"app","src","main","AndroidManifest.xml"),ce=Ba(P,".absolutejs","mobile","expo-dev-session","journal.json");return(await Promise.all([MY(ce,"android"),oje(v,P),cje(v),aje(z),ive(v.bundleDirectory),LY(v,P,"android",v.bundleDirectory),jY(v,"android",v.bundleDirectory),lje(M),uje(z),_je(v,z),JY(v,"android")])).filter((qe)=>qe!==void 0).map((qe)=>({...qe,path:qe.path?hE(P,qe.path).replaceAll("\\","/")||".":void 0}))},c6=async(v,P,M)=>{let z=(await Array.fromAsync(new Bun.Glob(P).scan({cwd:v,onlyFiles:!0}))).filter((ve)=>!ve.split(/[\\/]/u).some((qe)=>["Pods","DerivedData","build"].includes(qe)));if(z.length!==1)throw TypeError(z.length===0?`Generated Expo iOS project is missing its ${M}.`:`Generated Expo iOS project contains ambiguous ${M} files.`);let[ce]=z;if(!ce)throw TypeError(`Generated Expo iOS project is missing its ${M}.`);return Ba(v,ce)},fkt=async(v,P)=>{try{let[M,z,ce]=await Promise.all([c6(P,"**/Info.plist","Info.plist"),c6(P,"**/*.entitlements","entitlements"),c6(P,"**/*.xcodeproj/project.pbxproj","Xcode project")]),[ve,qe,at]=await Promise.all([El(M,"utf8"),El(z,"utf8"),El(ce,"utf8")]);if(/<key>NSAllowsArbitraryLoads<\/key>\s*<true\s*\/>/u.test(ve))throw TypeError("Expo iOS App Transport Security permits arbitrary network loads.");if(v.deepLinkScheme&&(!ve.includes("<key>CFBundleURLTypes</key>")||!ve.includes(`<string>${v.deepLinkScheme}</string>`)))throw TypeError("Expo iOS custom URL scheme does not match mobile config.");if(v.deepLinkHosts.some((ht)=>!qe.includes(`<string>applinks:${ht}</string>`)))throw TypeError("Expo iOS associated domains do not match mobile config.");if(!at.includes(z.split(/[\\/]/u).at(-1)??""))throw TypeError("Expo iOS target does not sign its generated entitlements file.");return cu("ios.expo-native-projection","Expo iOS transport security, URL schemes, universal links, and signed entitlements match mobile config.",z)}catch(M){return mc("ios.expo-native-projection",M instanceof Error?M.message:"Expo iOS native projection could not be validated.",P,"Run `absolute mobile build ios` to regenerate the production Expo CNG project.")}},pkt=async(v,P)=>{let M=Ba(v.nativeProjectDirectory,"ios"),z=Ba(P,".absolutejs","mobile","expo-dev-session","journal.json"),ce=[await MY(z,"ios")];ce.push(v.iosVersion?cu("ios.marketing-version",`The iOS marketing version is ${v.iosVersion}.`):mc("ios.marketing-version","iOS has no explicit App Store marketing version.",P,"Add mobile.ios.version to absolutejs.config.ts, for example 1.0.0.")),ce.push(...await Promise.all([oje(v,P),cje(v),ive(v.bundleDirectory),LY(v,P,"ios",v.bundleDirectory),jY(v,"ios",v.bundleDirectory),fkt(v,M),pje(M)]));let ve=await JY(v,"ios");if(ve)ce.push(ve);return ce.map((qe)=>({...qe,path:qe.path?hE(P,qe.path).replaceAll("\\","/")||".":void 0}))},dkt=async(v,P)=>{let M=Ba(v.nativeProjectDirectory,"ios","App","App"),z=Ba(M,"capacitor.config.json"),ce=Ba(M,"Info.plist"),ve=Ba(M,"public"),qe=Ba(P,".absolutejs","mobile","ios-dev-session","journal.json"),at=[await MY(qe,"ios")],ht=v.updates?await fje(v,"ios"):void 0;if(!v.iosVersion)at.push(mc("ios.marketing-version","iOS has no explicit App Store marketing version.",P,"Add mobile.ios.version to absolutejs.config.ts, for example 1.0.0."));else at.push(cu("ios.marketing-version",`The iOS marketing version is ${v.iosVersion}.`));if(!await j2(z))at.push(mc("ios.capacitor-config","The generated iOS Capacitor config is missing.",z,"Run `absolute mobile sync ios` before release validation."));else if(ije(await El(z,"utf8")))at.push(mc("ios.capacitor-config","iOS Capacitor config contains a development server URL, cleartext transport, navigation allowlist, or invalid JSON.",z,"Run `absolute mobile sync ios`; do not ship development transport overrides."));else at.push(cu("ios.capacitor-config","iOS Capacitor config contains no development transport overrides.",z));if(at.push(await sje(v,"ios",z)),!await j2(ce))at.push(mc("ios.transport-security","The iOS Info.plist is missing.",ce,"Run `absolute mobile sync ios` before release validation."));else{let Pr=await El(ce,"utf8");at.push(/<key>NSAllowsArbitraryLoads<\/key>\s*<true\s*\/>/u.test(Pr)?mc("ios.transport-security","iOS App Transport Security permits arbitrary network loads.",ce,"Remove NSAllowsArbitraryLoads from the release Info.plist."):cu("ios.transport-security","iOS App Transport Security does not permit arbitrary loads.",ce))}let cr=await rve(ve);at.push(cr?mc("ios.hmr-assets","A packaged iOS asset contains the development HMR client.",cr,"Rebuild the production mobile bundle and run Capacitor sync again."):cu("ios.hmr-assets","Packaged iOS assets contain no development HMR markers.",ve)),at.push(await LY(v,P,"ios",ve),await jY(v,"ios",ve),await pje(Ba(v.nativeProjectDirectory,"ios")),await ekt(v,Ba(v.nativeProjectDirectory,"ios")));let mr=await JY(v,"ios");if(mr)at.push(mr);if(ht)at.push(ht);return at.map((Pr)=>({...Pr,path:Pr.path?hE(P,Pr.path).replaceAll("\\","/")||".":void 0}))};var dje=async(v,P)=>{let z=(await Promise.all([Promise.resolve(G2t(v,P)),Promise.resolve(X2t(v,P)),H2t(P),v.engine==="expo"?z2t(v):J2t(v,P),j2t(v,P),L2t(v,P)])).filter((qe)=>qe!==void 0).map((qe)=>({...qe,path:qe.path?hE(P,qe.path).replaceAll("\\","/")||".":void 0}));if(v.platforms.includes("android"))z.push(...v.engine==="expo"?await _kt(v,P):await ukt(v,P));if(v.platforms.includes("ios"))z.push(...v.engine==="expo"?await pkt(v,P):await dkt(v,P));let ce=tkt(P);if(ce)z.push({...ce,path:ce.path?hE(P,ce.path).replaceAll("\\","/")||".":void 0});let ve=await lkt(v,P);return z.push({...ve,path:ve.path?hE(P,ve.path).replaceAll("\\","/")||".":void 0}),{checks:z,ready:z.length>0&&z.every((qe)=>qe.status!=="fail")}};import{createHash as ove}from"crypto";import{access as mkt,copyFile as hje,mkdir as zY,mkdtemp as yje,readdir as cve,readFile as VY,rename as gkt,rm as vje,stat as qY,writeFile as lve}from"fs/promises";import{basename as mje,dirname as sve,isAbsolute as bje,join as Sf,relative as L7,resolve as WY,sep as ave}from"path";var hkt=1,ykt=(v)=>{if(v===void 0)return;let P=v.trim().toUpperCase();if(!/^[A-Z0-9]{10}$/u.test(P))throw TypeError("iOS development team must contain ten letters or digits.");return`DEVELOPMENT_TEAM=${P}`},j7=(v)=>typeof v==="object"&&v!==null&&!Array.isArray(v),vkt=(v)=>{if(!j7(v)||typeof v.appBuild!=="string"||typeof v.appId!=="string"||typeof v.runtime!=="string")throw TypeError("Invalid embedded AbsoluteJS mobile manifest.");return{appBuild:v.appBuild,appId:v.appId,deviceCapabilities:Array.isArray(v.deviceCapabilities)?v.deviceCapabilities.filter((P)=>typeof P==="string"):[],runtime:v.runtime}},bkt=/<key>aps-environment<\/key>\s*<string>([^<]*)<\/string>/,Skt=async(v)=>{let P=Sf(v.staging,"push-entitlement-check");if(v.capture(["ditto","-x","-k",v.artifactPath,P]).exitCode!==0)throw TypeError("Could not unpack the exported IPA to check its push entitlement.");let M=await OB(Sf(P,"Payload"),".app");if(!M)throw TypeError("The exported IPA does not contain an app bundle.");let z=v.capture(["codesign","--display","--entitlements",":-",M]);if(z.exitCode!==0)throw TypeError("Could not read the exported app's signed entitlements.");let ce=bkt.exec(z.stdout)?.[1];if(ce!=="production")throw TypeError(`The app uses push notifications, but its signed aps-environment entitlement is ${ce?`"${ce}"`:"missing"}, not "production". APNs production would reject its device tokens, so no installed user would receive push. Sign the release with an App Store distribution profile whose App ID has Push Notifications enabled.`)},u6=async(v)=>{try{return await mkt(v),!0}catch{return!1}},uve=async(v)=>{let P=Sf(v,"App","App.xcworkspace");if(await u6(P))return["-workspace",P];let M=Sf(v,"App","App.xcodeproj");if(await u6(M))return["-project",M];throw TypeError(`Neither App.xcworkspace nor App.xcodeproj exists under ${Sf(v,"App")}. Generate the native project with "absolute mobile sync ios".`)},Tkt=async(v,P={})=>Bun.spawn(v,{cwd:P.cwd,env:P.env,stderr:"inherit",stdin:"inherit",stdout:"inherit"}).exited,Sje=(v,P={})=>{try{let M=Bun.spawnSync(v,{cwd:P.cwd,env:P.env,stderr:"pipe",stdin:"ignore",stdout:"pipe"});return{exitCode:M.exitCode,stderr:M.stderr.toString(),stdout:M.stdout.toString()}}catch(M){return{exitCode:1,stderr:M instanceof Error?M.message:String(M),stdout:""}}},xkt=new Set(["Pods","DerivedData","build","xcuserdata",".swiftpm","swiftpm"]),Tje=async(v,P=v,M={})=>{let z=await cve(P,{withFileTypes:!0});return(await Promise.all(z.sort((ve,qe)=>ve.name.localeCompare(qe.name)).map(async(ve)=>{let qe=Sf(P,ve.name),at=L7(v,qe).replaceAll("\\","/");if(ve.isDirectory()&&(xkt.has(ve.name)||at==="App/App/public"&&M.includePublicBundle!==!0))return[];if(ve.isDirectory())return Tje(v,qe,M);return ve.isFile()?[qe]:[]}))).flat()},_ve=async(v,P={})=>{let M=ove("sha256"),z=await Tje(v,v,P),ce=await Promise.all(z.map((ve)=>VY(ve)));return z.forEach((ve,qe)=>{M.update(L7(v,ve).replaceAll("\\","/")),M.update("\x00"),M.update(ce[qe]??new Uint8Array),M.update("\x00")}),M.digest("hex")},kkt=(v,P)=>{let M=WY(v),z=WY(M,P??".absolutejs/mobile/releases/ios"),ce=L7(M,z);if(ce===".."||ce.startsWith(`..${ave}`)||bje(ce))throw TypeError("mobile build --outdir must remain inside the project.");return z},$Y=async(v)=>ove("sha256").update(await VY(v)).digest("hex"),Ckt=async(v,P)=>{if(!P.registeredDevice)return;let M=Sf(v,P.registeredDevice.artifact),[z,ce]=await Promise.all([qY(M).then(({size:ve})=>ve),$Y(M)]);if(z!==P.registeredDevice.bytes||ce!==P.registeredDevice.sha256)throw TypeError(`Immutable iOS release ${P.releaseId} registered-device artifact is missing or modified.`);return M},Ekt=async(v,P,M)=>{if(!P.registeredDevice)return;if(!M)throw TypeError("iOS release metadata requires a registered-device artifact.");await hje(M,Sf(v,P.registeredDevice.artifact))},OB=async(v,P)=>{if(!await u6(v))return;let M=await cve(v,{withFileTypes:!0});return(await Promise.all(M.map(async(ce)=>{let ve=Sf(v,ce.name);if(ce.isDirectory()&&ce.name.endsWith(P))return ve;if(ce.isFile()&&ce.name.endsWith(P))return ve;return ce.isDirectory()?OB(ve,P):void 0}))).find((ce)=>ce!==void 0)},UY=async(v,P,M={})=>{if(!await u6(v))return[];let z=await cve(v,{withFileTypes:!0});return(await Promise.all(z.map(async(ve)=>{let qe=Sf(v,ve.name);if(ve.name.endsWith(P))return[qe];if(!ve.isDirectory()||M.excludedDirectories?.has(ve.name))return[];return UY(qe,P,M)}))).flat().sort()},wkt=(v)=>{let P=mje(v);return(P==="project.xcworkspace"?mje(sve(v)):P).replace(/\.(xcodeproj|xcworkspace)$/,"")},Akt=(v,P,M)=>{let z=M(["xcodebuild","-list","-json",...v],{cwd:P});if(z.exitCode!==0)return[];try{let ce=JSON.parse(z.stdout),ve=j7(ce)?ce.workspace??ce.project:void 0,qe=j7(ve)?ve.schemes:void 0;return Array.isArray(qe)?qe.filter((at)=>typeof at==="string"):[]}catch{return[]}},fve=async(v,P={})=>{let M=P.workspacePath?WY(v,P.workspacePath):void 0;if(M){let xe=L7(v,M);if(xe===".."||xe.startsWith(`..${ave}`)||bje(xe))throw TypeError("iOS release workspacePath must remain inside the native iOS project.")}let z=M?[M]:await UY(v,".xcworkspace",{excludedDirectories:new Set(["Pods","DerivedData","build"])});if(z.length>1)throw TypeError(`iOS release found multiple Xcode workspaces: ${z.map((xe)=>L7(v,xe)).join(", ")}. Pass an explicit workspacePath.`);let[ce]=z,ve;if(ce&&await u6(ce))ve=["-workspace",ce];else if(M)throw TypeError("iOS release could not find the requested Xcode workspace.");else{let xe=await UY(v,".xcodeproj",{excludedDirectories:new Set(["Pods","DerivedData","build"])});if(xe.length>1)throw TypeError(`iOS release found multiple Xcode projects: ${xe.map((Nt)=>L7(v,Nt)).join(", ")}.`);let[qn]=xe;if(!qn||!await u6(qn))throw TypeError("iOS release could not find an Xcode workspace or project.");ve=["-project",qn]}if(P.scheme)return{scheme:P.scheme,target:ve};let qe=await UY(v,".xcscheme",{excludedDirectories:new Set(["Pods","DerivedData","build"])}),at=[...new Set(qe.map((xe)=>xe.slice(xe.lastIndexOf(ave)+1,-9)))];if(at.length>1)throw TypeError(`iOS release found multiple shared Xcode schemes: ${at.join(", ")}. Pass an explicit scheme.`);if(at[0])return{scheme:at[0],target:ve};let ht=ve[1]??"",cr=wkt(ht),mr=Akt(ve,v,P.capture??Sje),Pr=mr.length===1?mr[0]:mr.find((xe)=>xe===cr);if(Pr)return{scheme:Pr,target:ve};throw TypeError(mr.length>0?`iOS release found Xcode schemes ${mr.join(", ")}, none shared or named ${cr}. Pass an explicit scheme.`:"iOS release could not find a shared Xcode scheme.")},xje=(v)=>`<?xml version="1.0" encoding="UTF-8"?>
|
|
2711
2711
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
2712
2712
|
<plist version="1.0"><dict>
|
|
2713
2713
|
<key>destination</key><string>export</string>
|
|
@@ -1,3 +1,27 @@
|
|
|
1
|
+
// src/utils/cspNonceRef.ts
|
|
2
|
+
var GETTER_KEY = Symbol.for("absolutejs.cspNonceGetter");
|
|
3
|
+
var readCspNonce = () => {
|
|
4
|
+
const getter = Reflect.get(globalThis, GETTER_KEY);
|
|
5
|
+
if (typeof getter !== "function")
|
|
6
|
+
return;
|
|
7
|
+
const nonce = getter();
|
|
8
|
+
return typeof nonce === "string" ? nonce : undefined;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
// src/utils/fontAssets.ts
|
|
12
|
+
var MIME_BY_EXTENSION = {
|
|
13
|
+
otf: "font/otf",
|
|
14
|
+
ttf: "font/ttf",
|
|
15
|
+
woff: "font/woff",
|
|
16
|
+
woff2: "font/woff2"
|
|
17
|
+
};
|
|
18
|
+
var fontMimeType = (href) => {
|
|
19
|
+
const extension = /\.([a-z0-9]+)(?:[?#].*)?$/i.exec(href)?.[1]?.toLowerCase();
|
|
20
|
+
return (extension && MIME_BY_EXTENSION[extension]) ?? "font/woff2";
|
|
21
|
+
};
|
|
22
|
+
var isRemote = (href) => /^https?:\/\//i.test(href);
|
|
23
|
+
var fontPreconnectOrigins = (fonts) => fonts.stylesheets.some(isRemote) ? ["https://fonts.googleapis.com", "https://fonts.gstatic.com"] : [];
|
|
24
|
+
|
|
1
25
|
// src/utils/iconVersion.ts
|
|
2
26
|
var iconMimeType = (icon) => {
|
|
3
27
|
if (icon.endsWith(".svg"))
|
|
@@ -9,11 +33,23 @@ var iconMimeType = (icon) => {
|
|
|
9
33
|
var resolver;
|
|
10
34
|
var applyIconVersion = (href) => resolver ? resolver(href) : href;
|
|
11
35
|
|
|
36
|
+
// src/utils/escapeScriptContent.ts
|
|
37
|
+
var ESCAPE_LOOKUP = {
|
|
38
|
+
"\u2028": "\\u2028",
|
|
39
|
+
"\u2029": "\\u2029",
|
|
40
|
+
"<": "\\u003C"
|
|
41
|
+
};
|
|
42
|
+
var ESCAPE_REGEX = /[<\u2028\u2029]/g;
|
|
43
|
+
var escapeScriptContent = (content) => content.replace(ESCAPE_REGEX, (char) => {
|
|
44
|
+
const escaped = ESCAPE_LOOKUP[char];
|
|
45
|
+
return escaped !== undefined ? escaped : char;
|
|
46
|
+
});
|
|
47
|
+
|
|
12
48
|
// src/utils/jsonLd.ts
|
|
13
49
|
var serializeJsonLd = (schema) => {
|
|
14
50
|
const schemaOrgContext = "https://schema.org";
|
|
15
51
|
const data = Array.isArray(schema) ? { "@context": schemaOrgContext, "@graph": schema } : { "@context": schemaOrgContext, ...schema };
|
|
16
|
-
return JSON.stringify(data);
|
|
52
|
+
return escapeScriptContent(JSON.stringify(data));
|
|
17
53
|
};
|
|
18
54
|
|
|
19
55
|
// src/utils/generateHeadElement.ts
|
|
@@ -167,6 +203,29 @@ var toCrossOrigin = (value) => {
|
|
|
167
203
|
return value;
|
|
168
204
|
return "anonymous";
|
|
169
205
|
};
|
|
206
|
+
var FontLinks = ({ fonts }) => /* @__PURE__ */ jsxs(Fragment, {
|
|
207
|
+
children: [
|
|
208
|
+
fontPreconnectOrigins(fonts).map((origin) => /* @__PURE__ */ jsx("link", {
|
|
209
|
+
crossOrigin: origin.includes("gstatic") ? "anonymous" : undefined,
|
|
210
|
+
href: origin,
|
|
211
|
+
rel: "preconnect"
|
|
212
|
+
}, `preconnect:${origin}`)),
|
|
213
|
+
fonts.preload.map((href) => /* @__PURE__ */ jsx("link", {
|
|
214
|
+
as: "font",
|
|
215
|
+
crossOrigin: "anonymous",
|
|
216
|
+
href,
|
|
217
|
+
rel: "preload",
|
|
218
|
+
suppressHydrationWarning: true,
|
|
219
|
+
type: fontMimeType(href)
|
|
220
|
+
}, `preload:${href}`)),
|
|
221
|
+
fonts.stylesheets.map((href) => /* @__PURE__ */ jsx("link", {
|
|
222
|
+
"data-absolute-fonts": "",
|
|
223
|
+
href,
|
|
224
|
+
rel: "stylesheet",
|
|
225
|
+
suppressHydrationWarning: true
|
|
226
|
+
}, `stylesheet:${href}`))
|
|
227
|
+
]
|
|
228
|
+
});
|
|
170
229
|
var SpeculationRulesScript = ({
|
|
171
230
|
rules
|
|
172
231
|
}) => {
|
|
@@ -175,6 +234,8 @@ var SpeculationRulesScript = ({
|
|
|
175
234
|
return null;
|
|
176
235
|
return /* @__PURE__ */ jsx("script", {
|
|
177
236
|
dangerouslySetInnerHTML: { __html: body },
|
|
237
|
+
nonce: readCspNonce(),
|
|
238
|
+
suppressHydrationWarning: true,
|
|
178
239
|
type: "speculationrules"
|
|
179
240
|
});
|
|
180
241
|
};
|
|
@@ -183,8 +244,10 @@ var Head = ({
|
|
|
183
244
|
description = "A page created using AbsoluteJS",
|
|
184
245
|
icon = "/assets/ico/favicon.ico",
|
|
185
246
|
font,
|
|
247
|
+
fonts,
|
|
186
248
|
cssPath,
|
|
187
249
|
canonical,
|
|
250
|
+
alternates,
|
|
188
251
|
openGraph,
|
|
189
252
|
twitter,
|
|
190
253
|
robots,
|
|
@@ -218,6 +281,11 @@ var Head = ({
|
|
|
218
281
|
href: canonical,
|
|
219
282
|
rel: "canonical"
|
|
220
283
|
}),
|
|
284
|
+
alternates?.map(({ href, hreflang }) => /* @__PURE__ */ jsx("link", {
|
|
285
|
+
href,
|
|
286
|
+
hrefLang: hreflang,
|
|
287
|
+
rel: "alternate"
|
|
288
|
+
}, `alternate:${hreflang}`)),
|
|
221
289
|
openGraph && /* @__PURE__ */ jsx(OpenGraphTags, {
|
|
222
290
|
description,
|
|
223
291
|
openGraph,
|
|
@@ -253,6 +321,9 @@ var Head = ({
|
|
|
253
321
|
})
|
|
254
322
|
]
|
|
255
323
|
}),
|
|
324
|
+
fonts && /* @__PURE__ */ jsx(FontLinks, {
|
|
325
|
+
fonts
|
|
326
|
+
}),
|
|
256
327
|
preload?.map((link) => /* @__PURE__ */ jsx("link", {
|
|
257
328
|
as: link.module ? undefined : link.as,
|
|
258
329
|
crossOrigin: toCrossOrigin(link.crossorigin),
|
|
@@ -270,6 +341,8 @@ var Head = ({
|
|
|
270
341
|
}, path)),
|
|
271
342
|
jsonLd && /* @__PURE__ */ jsx("script", {
|
|
272
343
|
dangerouslySetInnerHTML: { __html: serializeJsonLd(jsonLd) },
|
|
344
|
+
nonce: readCspNonce(),
|
|
345
|
+
suppressHydrationWarning: true,
|
|
273
346
|
type: "application/ld+json"
|
|
274
347
|
})
|
|
275
348
|
]
|
|
@@ -515,6 +588,20 @@ import {
|
|
|
515
588
|
useContext
|
|
516
589
|
} from "react";
|
|
517
590
|
|
|
591
|
+
// src/dev/client/cspNonce.ts
|
|
592
|
+
var applyPageNonce = (element) => {
|
|
593
|
+
const nonce = readPageNonce();
|
|
594
|
+
if (nonce)
|
|
595
|
+
element.nonce = nonce;
|
|
596
|
+
return element;
|
|
597
|
+
};
|
|
598
|
+
var readPageNonce = () => {
|
|
599
|
+
if (typeof document === "undefined")
|
|
600
|
+
return;
|
|
601
|
+
const carrier = document.querySelector("script[nonce], style[nonce]");
|
|
602
|
+
return carrier?.nonce || undefined;
|
|
603
|
+
};
|
|
604
|
+
|
|
518
605
|
// src/client/prefetch.ts
|
|
519
606
|
var PREFETCH_CACHE_LIMIT = 16;
|
|
520
607
|
var HOVER_DEBOUNCE_MS = 250;
|
|
@@ -789,7 +876,7 @@ var speculate = (url) => {
|
|
|
789
876
|
liveSpeculationRules.get(oldest.value)?.remove();
|
|
790
877
|
liveSpeculationRules.delete(oldest.value);
|
|
791
878
|
}
|
|
792
|
-
const script = document.createElement("script");
|
|
879
|
+
const script = applyPageNonce(document.createElement("script"));
|
|
793
880
|
script.type = "speculationrules";
|
|
794
881
|
script.textContent = JSON.stringify({
|
|
795
882
|
prerender: [{ eagerness: "immediate", urls: [url] }]
|
|
@@ -808,6 +895,7 @@ var scheduleHoverPrefetch = (url, options = {}) => {
|
|
|
808
895
|
prefetch(url, { kind: options.kind ?? "route" });
|
|
809
896
|
if (options.prerender)
|
|
810
897
|
speculate(url);
|
|
898
|
+
options.onPrefetch?.();
|
|
811
899
|
}, HOVER_DEBOUNCE_MS);
|
|
812
900
|
return {
|
|
813
901
|
cancel: () => window.clearTimeout(timer)
|
|
@@ -822,8 +910,10 @@ var handleIntersections = (entries) => {
|
|
|
822
910
|
const target = viewportTargets.get(entry.target);
|
|
823
911
|
viewportObserver?.unobserve(entry.target);
|
|
824
912
|
viewportTargets.delete(entry.target);
|
|
825
|
-
if (target)
|
|
826
|
-
|
|
913
|
+
if (!target)
|
|
914
|
+
continue;
|
|
915
|
+
prefetch(target.url, { kind: target.options.kind });
|
|
916
|
+
target.options.onVisible?.();
|
|
827
917
|
}
|
|
828
918
|
};
|
|
829
919
|
var getViewportObserver = () => {
|