@absolutejs/absolute 0.20.0-beta.90 → 0.20.0-beta.92
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 +12 -0
- package/changelog.json +30 -0
- package/dist/angular/components/core/streamingSlotRegistrar.js +1 -1
- package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
- package/dist/cli/{compile-5hchbcbd.js → compile-vf61bv90.js} +2 -2
- package/dist/cli/{dev-aykeaa7b.js → dev-perzmh2w.js} +1 -1
- package/dist/cli/{expoProject-dac8fqhq.js → expoProject-djc0vk7g.js} +1 -1
- package/dist/cli/{index-jqdt7841.js → index-751czk1b.js} +1 -1
- package/dist/cli/{index-tame6e2c.js → index-8zrnvazp.js} +28 -0
- package/dist/cli/{index-39j0dhq7.js → index-gxkmg2ss.js} +1 -1
- package/dist/cli/index.js +5 -5
- package/dist/cli/{mobile-bg1jy34n.js → mobile-yk7qr9qg.js} +3 -3
- package/dist/cli/{start-7jg0csqy.js → start-ef7tgbmf.js} +3 -3
- package/dist/mobile/index.js +106 -5
- package/dist/mobile/index.js.map +6 -5
- package/dist/mobile/remoteMacAgentEntry.js +28 -0
- package/dist/src/mobile/expoNativeObservability.d.ts +1 -1
- package/dist/src/mobile/index.d.ts +1 -0
- package/dist/src/mobile/iosUpgradeConformance.d.ts +16 -0
- package/package.json +3 -1
|
@@ -530,6 +530,27 @@ public final class AbsoluteMobileObservabilityModule: Module, MXMetricManagerSub
|
|
|
530
530
|
}
|
|
531
531
|
}
|
|
532
532
|
}
|
|
533
|
+
|
|
534
|
+
#if DEBUG
|
|
535
|
+
AsyncFunction("enqueueForTesting") { (options: [String: String]) -> Bool in
|
|
536
|
+
guard let testId = options["testId"],
|
|
537
|
+
testId.range(of: "^[A-Za-z0-9._:-]{1,128}$", options: .regularExpression) != nil else { return false }
|
|
538
|
+
let key = "absolute-native-observability-test-id"
|
|
539
|
+
guard UserDefaults.standard.string(forKey: key) != testId else { return false }
|
|
540
|
+
UserDefaults.standard.set(testId, forKey: key)
|
|
541
|
+
Self.queue.sync {
|
|
542
|
+
Self.enqueue(
|
|
543
|
+
kind: "crash",
|
|
544
|
+
occurredAt: Date().timeIntervalSince1970 * 1000,
|
|
545
|
+
details: [
|
|
546
|
+
"message": "token=mobile-observability-secret",
|
|
547
|
+
"source": "absolutejs-conformance"
|
|
548
|
+
]
|
|
549
|
+
)
|
|
550
|
+
}
|
|
551
|
+
return true
|
|
552
|
+
}
|
|
553
|
+
#endif
|
|
533
554
|
}
|
|
534
555
|
|
|
535
556
|
private static func root() -> URL? {
|
|
@@ -809,6 +830,7 @@ import { ABSOLUTE_MOBILE_MANIFEST } from './webAssets';
|
|
|
809
830
|
type NativeObservabilityModule = {
|
|
810
831
|
acknowledge(options: { ids: string[] }): Promise<void>;
|
|
811
832
|
crashForTesting(options: { testId: string }): Promise<boolean>;
|
|
833
|
+
enqueueForTesting(options: { testId: string }): Promise<boolean>;
|
|
812
834
|
pending(): Promise<{ reports: unknown[] }>;
|
|
813
835
|
};
|
|
814
836
|
type NativeReport = { details: Record<string, unknown>; id: string; kind: string; occurredAt: number; platform: 'android' | 'ios' };
|
|
@@ -870,6 +892,12 @@ export const startAbsoluteExpoNativeObservability = () => {
|
|
|
870
892
|
return drain();
|
|
871
893
|
};
|
|
872
894
|
export const crashAbsoluteExpoNativeObservabilityForTesting = (testId: string) => native.crashForTesting({ testId });
|
|
895
|
+
export const enqueueAbsoluteExpoNativeObservabilityForTesting = async (testId: string) => {
|
|
896
|
+
await drain();
|
|
897
|
+
const enqueued = await native.enqueueForTesting({ testId });
|
|
898
|
+
await drain();
|
|
899
|
+
return enqueued;
|
|
900
|
+
};
|
|
873
901
|
`,m0e=(x)=>new Map([[X6(x,"modules/absolute-mobile-observability/expo-module.config.json"),Lbt],[X6(x,"modules/absolute-mobile-observability/ios/AbsoluteMobileObservability.podspec"),jbt],[X6(x,"modules/absolute-mobile-observability/ios/AbsoluteMobileObservabilityModule.swift"),Bbt],[X6(x,"modules/absolute-mobile-observability/android/build.gradle"),Jbt],[X6(x,"modules/absolute-mobile-observability/android/src/main/AndroidManifest.xml"),Ubt],[X6(x,"modules/absolute-mobile-observability/android/src/main/java/expo/modules/absolutemobileobservability/AbsoluteMobileObservabilityModule.kt"),zbt],[X6(x,"src/generated/AbsoluteNativeObservability.ts"),Wbt]]),ARe=(x)=>[...m0e(x).keys()];var Pm=`// Generated by AbsoluteJS. Edit absolute.config.ts, then run absolute mobile sync.
|
|
874
902
|
`,Qbt=".absasset",IRe=".absolutejs-expo-project",YA=async(x)=>{try{return await Vbt(x),!0}catch{return!1}},sY=(x)=>typeof x==="object"&&x!==null&&!Array.isArray(x),KA=(x,N)=>{if(typeof x!=="string"||!x)throw TypeError(`AbsoluteJS mobile manifest ${N} is invalid.`);return x},Kbt=(x)=>{if(!sY(x)||!Array.isArray(x.pages)||!Array.isArray(x.routes))throw TypeError("AbsoluteJS mobile manifest is invalid.");let N=x.pages.map((X)=>{if(!sY(X))throw TypeError("AbsoluteJS mobile manifest page is invalid.");return{bundleHash:KA(X.bundleHash,"page.bundleHash"),contract:KA(X.contract,"page.contract"),pageId:KA(X.pageId,"page.pageId")}}),U=x.routes.flatMap((X)=>{if(!sY(X)||typeof X.method!=="string")throw TypeError("AbsoluteJS mobile manifest route is invalid.");if(X.method!=="GET")return[];return[{method:"GET",pageId:KA(X.pageId,"route.pageId"),pattern:KA(X.pattern,"route.pattern")}]});return{appBuild:KA(x.appBuild,"appBuild"),...sY(x.observability)&&typeof x.observability.endpoint==="string"&&typeof x.observability.project==="string"&&typeof x.observability.sampleRate==="number"?{observability:{endpoint:x.observability.endpoint,...typeof x.observability.environment==="string"?{environment:x.observability.environment}:{},project:x.observability.project,sampleRate:x.observability.sampleRate}}:{},pages:N,productionOrigin:KA(x.productionOrigin,"productionOrigin"),routes:U,runtime:KA(x.runtime,"runtime")}},oY=(x,N)=>{let U=h0e(x,N).replaceAll("\\","/");return U.startsWith(".")?U:`./${U}`},Ybt=(x)=>{let N=x.split("/").filter(Boolean);return N.map((U,X)=>{if(U.startsWith(":"))return`[${U.slice(1)}]`;if(U==="*"&&X===N.length-1)return"[...absoluteWildcard]";if(U==="."||U===".."||!/^[A-Za-z0-9._~-]+$/u.test(U))throw TypeError(`Expo native route ${x} contains an unsupported segment ${U}.`);return U})},Zbt=(x,N)=>au(x,"app",...Ybt(N),"index.tsx"),eSt=(x)=>Object.fromEntries(x.requiredPackages.map((N)=>{let U=N.lastIndexOf("@");return[N.slice(0,U),N.slice(U+1)]})),tSt=(x,N,U,X)=>({dependencies:{"@absolutejs/devices":"0.7.0","@absolutejs/devices-expo":"0.0.2",...x?{"@absolutejs/auth":w9e,[A9e]:D9e}:{},...N?{"@absolutejs/sync":P9e,[I9e]:N9e}:{},expo:"~57.0.9","expo-asset":"~57.0.15","expo-constants":"~57.0.16",...x||X?{"expo-crypto":"~57.0.2"}:{},"expo-dev-client":"~57.0.16","expo-file-system":"~57.0.6","expo-haptics":"~57.0.2","expo-linking":"~57.0.8",...N?{"expo-background-task":"~57.0.14","expo-network":"~57.0.1","expo-sqlite":"~57.0.2","expo-task-manager":"~57.0.14"}:{},...X||N?{"expo-updates":"~57.0.19"}:{},"expo-router":"~57.0.17",...x||X?{"expo-secure-store":"~57.0.2",...x?{"expo-web-browser":"~57.0.2"}:{}}:{},react:"19.2.3","react-native":"0.86.3","react-native-safe-area-context":"~5.7.0","react-native-screens":"4.26.0","react-native-webview":"13.16.1",...eSt(U)},devDependencies:{"@types/react":"~19.2.2",typescript:"~6.0.3"},main:"expo-router/entry",name:"absolutejs-expo-shell",private:!0,scripts:{android:"expo run:android",ios:"expo run:ios",start:"expo start --dev-client"},version:"0.0.0"}),rSt=(x,N,U,X,ye)=>{let Ce=G6(X),Ye=(Dr)=>{if(Dr==="camera")return"NSCameraUsageDescription";if(Dr==="photo-library")return"NSPhotoLibraryUsageDescription";if(Dr==="photo-library-add")return"NSPhotoLibraryAddUsageDescription";if(Dr==="location-always")return"NSLocationAlwaysAndWhenInUseUsageDescription";return"NSLocationWhenInUseUsageDescription"},yt=(Dr)=>{if(Dr==="camera")return`${x.appName} uses your camera when you choose to take a photo.`;if(Dr==="photo-library")return`${x.appName} accesses your photo library only for photo actions you choose.`;if(Dr.startsWith("location-"))return`${x.appName} uses your location only while you use the app and request a location-based action.`;return`${x.appName} adds to your photo library only for photo actions you choose.`},It=Object.fromEntries(Ce.iosUsageDescriptions.map((Dr)=>[Ye(Dr),yt(Dr)])),fr=[...new Set(X.capabilities.flatMap((Dr)=>X.providers[Dr]?.plugins??[]))],kr=fr.map((Dr)=>{if(Dr==="expo-image-picker")return[Dr,{cameraPermission:It.NSCameraUsageDescription,microphonePermission:!1,photosPermission:It.NSPhotoLibraryUsageDescription}];if(Dr==="expo-location")return[Dr,{locationWhenInUsePermission:It.NSLocationWhenInUseUsageDescription}];return Dr});return{expo:{android:{...fr.includes("expo-image-picker")?{blockedPermissions:["android.permission.READ_EXTERNAL_STORAGE","android.permission.RECORD_AUDIO","android.permission.WRITE_EXTERNAL_STORAGE"]}:{},intentFilters:x.deepLinkHosts.map((Dr)=>({action:"VIEW",autoVerify:!0,category:["BROWSABLE","DEFAULT"],data:[{host:Dr,pathPrefix:"/",scheme:"https"}]})),package:x.appId,permissions:Ce.androidPermissions},experiments:{typedRoutes:!0},ios:{associatedDomains:x.deepLinkHosts.map((Dr)=>`applinks:${Dr}`),bundleIdentifier:x.appId,infoPlist:It,...Ce.iosPrivacyAccessedApis.length>0?{privacyManifests:{NSPrivacyAccessedAPITypes:Ce.iosPrivacyAccessedApis.map(({api:Dr,reasons:Ee})=>({NSPrivacyAccessedAPIType:Dr,NSPrivacyAccessedAPITypeReasons:Ee}))}}:{},...x.iosVersion?{buildNumber:x.iosVersion}:{}},name:x.appName,plugins:["expo-router",["expo-dev-client",{launchMode:"most-recent"}],...N||x.updates?["expo-secure-store"]:[],...U?["expo-sqlite","expo-background-task","expo-task-manager"]:[],...kr],runtimeVersion:ye,scheme:x.deepLinkScheme,slug:x.appId.toLowerCase().replaceAll(".","-"),...x.updates?{updates:{checkAutomatically:"ON_ERROR_RECOVERY",fallbackToCacheTimeout:x.updates.bootTimeoutMs,requestHeaders:{"x-absolute-mobile-app":x.appId,"x-absolute-mobile-channel":x.updates.channel},...x.updates.expoCodeSigning?{codeSigningCertificate:"./certs/absolute-mobile-update.pem",codeSigningMetadata:{alg:x.updates.expoCodeSigning.algorithm,keyid:x.updates.expoCodeSigning.keyId}}:{},url:x.updates.manifestUrl}}:{},version:x.iosVersion??"0.1.0"}}},nSt=`${Pm}const config = require('./app.json');
|
|
875
903
|
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export declare const expoNativeObservabilityRuntimeSource = "// Generated by AbsoluteJS. Edit absolute.config.ts, then run absolute mobile sync.\nimport { requireNativeModule } from 'expo';\nimport { AppState, Platform } from 'react-native';\nimport { ABSOLUTE_MOBILE_MANIFEST } from './webAssets';\n\ntype NativeObservabilityModule = {\n\tacknowledge(options: { ids: string[] }): Promise<void>;\n\tcrashForTesting(options: { testId: string }): Promise<boolean>;\n\tpending(): Promise<{ reports: unknown[] }>;\n};\ntype NativeReport = { details: Record<string, unknown>; id: string; kind: string; occurredAt: number; platform: 'android' | 'ios' };\nconst native = requireNativeModule<NativeObservabilityModule>('AbsoluteMobileObservability');\nconst KINDS = new Set(['anr', 'app-launch', 'cpu-exception', 'crash', 'disk-write-exception', 'hang', 'initialization-failure', 'low-memory', 'native-crash', 'resource-exhaustion', 'signal']);\nconst ID = /^[A-Za-z0-9._:-]{1,128}$/;\nconst isRecord = (value: unknown): value is Record<string, unknown> => typeof value === 'object' && value !== null && !Array.isArray(value);\nconst redactText = (value: string) => value.slice(0, 8192)\n\t.replace(/\\b(Bearer)\\s+[A-Za-z0-9._~+/-]+=*/gi, '$1 [REDACTED]')\n\t.replace(/([?&](?:access_token|api_?key|authorization|code|id_token|password|refresh_token|secret|token)=)[^&#\\s]*/gi, '$1[REDACTED]')\n\t.replace(/\\b((?:access_?token|api_?key|authorization|client_?secret|cookie|id_?token|password|passwd|refresh_?token|secret|token)\\s*[:=]\\s*)[^,\\s;]+/gi, '$1[REDACTED]')\n\t.replace(/\\beyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\b/g, '[REDACTED]');\nconst redact = (value: unknown, depth = 0): unknown => {\n\tif (depth >= 8) return '[TRUNCATED]';\n\tif (typeof value === 'string') return redactText(value);\n\tif (value === null || typeof value === 'number' || typeof value === 'boolean') return value;\n\tif (Array.isArray(value)) return value.slice(0, 64).map(entry => redact(entry, depth + 1));\n\tif (!isRecord(value)) return String(value).slice(0, 8192);\n\treturn Object.fromEntries(Object.entries(value).slice(0, 128).map(([key, entry]) => [key, /(?:authorization|cookie|password|secret|token)/i.test(key) ? '[REDACTED]' : redact(entry, depth + 1)]));\n};\nconst parse = (value: unknown): NativeReport | undefined => {\n\tif (!isRecord(value) || !isRecord(value.details) || typeof value.id !== 'string' || !ID.test(value.id) || typeof value.kind !== 'string' || !KINDS.has(value.kind) || typeof value.occurredAt !== 'number' || !Number.isFinite(value.occurredAt) || value.occurredAt <= 0 || value.platform !== 'android' && value.platform !== 'ios') return;\n\tconst details = redact(value.details);\n\tif (!isRecord(details) || new TextEncoder().encode(JSON.stringify(details)).byteLength > 64 * 1024) return;\n\treturn { details, id: value.id, kind: value.kind, occurredAt: value.occurredAt, platform: value.platform };\n};\nconst sampled = (id: string, rate: number) => {\n\tif (rate >= 1) return true;\n\tlet hash = 2166136261;\n\tfor (const character of id) { hash ^= character.codePointAt(0) ?? 0; hash = Math.imul(hash, 16777619); }\n\treturn (hash >>> 0) / 4294967296 < rate;\n};\nlet drainPromise: Promise<void> | undefined;\nlet started = false;\nconst drain = () => {\n\tdrainPromise ??= (async () => {\n\t\tconst manifest = ABSOLUTE_MOBILE_MANIFEST;\n\t\tconst config = manifest?.observability;\n\t\tif (!manifest || !config || Platform.OS !== 'android' && Platform.OS !== 'ios') return;\n\t\tconst reports = (await native.pending()).reports.slice(0, 8).map(parse).filter((report): report is NativeReport => report !== undefined);\n\t\tconst discarded = reports.filter(report => !sampled(report.id, config.sampleRate));\n\t\tif (discarded.length) await native.acknowledge({ ids: discarded.map(report => report.id) });\n\t\tconst selected = reports.filter(report => sampled(report.id, config.sampleRate));\n\t\tif (!selected.length) return;\n\t\tconst response = await fetch(config.endpoint, {\n\t\t\tbody: JSON.stringify({ ...(config.environment ? { environment: config.environment } : {}), events: selected.map(report => ({ at: report.occurredAt, extra: { nativeDiagnostic: report.details, nativeDiagnosticId: report.id }, groupingKey: 'absolute-native:' + report.platform + ':' + report.kind, level: ['app-launch', 'cpu-exception', 'disk-write-exception', 'low-memory', 'resource-exhaustion', 'signal'].includes(report.kind) ? 'warning' : 'error', message: 'Native process diagnostic \u2014 ' + report.kind, name: 'AbsoluteMobileNativeDiagnostic', tags: { absoluteMobile: 'true', mobileAppBuild: manifest.appBuild, mobileEngine: 'expo', mobileFailurePhase: 'native-process', mobileManifestFormat: '1', mobileNativeRuntime: 'expo', mobilePlatform: report.platform, mobileRuntime: manifest.runtime } })), project: config.project, release: manifest.appBuild, v: 1 }),\n\t\t\theaders: { 'content-type': 'application/json' },\n\t\t\tmethod: 'POST'\n\t\t});\n\t\tif (response.ok) await native.acknowledge({ ids: selected.map(report => report.id) });\n\t})().catch(() => undefined).finally(() => { drainPromise = undefined; });\n\treturn drainPromise;\n};\nexport const startAbsoluteExpoNativeObservability = () => {\n\tif (!started) {\n\t\tstarted = true;\n\t\tAppState.addEventListener('change', state => { if (state === 'active') void drain(); });\n\t}\n\treturn drain();\n};\nexport const crashAbsoluteExpoNativeObservabilityForTesting = (testId: string) => native.crashForTesting({ testId });\n";
|
|
1
|
+
export declare const expoNativeObservabilityRuntimeSource = "// Generated by AbsoluteJS. Edit absolute.config.ts, then run absolute mobile sync.\nimport { requireNativeModule } from 'expo';\nimport { AppState, Platform } from 'react-native';\nimport { ABSOLUTE_MOBILE_MANIFEST } from './webAssets';\n\ntype NativeObservabilityModule = {\n\tacknowledge(options: { ids: string[] }): Promise<void>;\n\tcrashForTesting(options: { testId: string }): Promise<boolean>;\n\tenqueueForTesting(options: { testId: string }): Promise<boolean>;\n\tpending(): Promise<{ reports: unknown[] }>;\n};\ntype NativeReport = { details: Record<string, unknown>; id: string; kind: string; occurredAt: number; platform: 'android' | 'ios' };\nconst native = requireNativeModule<NativeObservabilityModule>('AbsoluteMobileObservability');\nconst KINDS = new Set(['anr', 'app-launch', 'cpu-exception', 'crash', 'disk-write-exception', 'hang', 'initialization-failure', 'low-memory', 'native-crash', 'resource-exhaustion', 'signal']);\nconst ID = /^[A-Za-z0-9._:-]{1,128}$/;\nconst isRecord = (value: unknown): value is Record<string, unknown> => typeof value === 'object' && value !== null && !Array.isArray(value);\nconst redactText = (value: string) => value.slice(0, 8192)\n\t.replace(/\\b(Bearer)\\s+[A-Za-z0-9._~+/-]+=*/gi, '$1 [REDACTED]')\n\t.replace(/([?&](?:access_token|api_?key|authorization|code|id_token|password|refresh_token|secret|token)=)[^&#\\s]*/gi, '$1[REDACTED]')\n\t.replace(/\\b((?:access_?token|api_?key|authorization|client_?secret|cookie|id_?token|password|passwd|refresh_?token|secret|token)\\s*[:=]\\s*)[^,\\s;]+/gi, '$1[REDACTED]')\n\t.replace(/\\beyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\b/g, '[REDACTED]');\nconst redact = (value: unknown, depth = 0): unknown => {\n\tif (depth >= 8) return '[TRUNCATED]';\n\tif (typeof value === 'string') return redactText(value);\n\tif (value === null || typeof value === 'number' || typeof value === 'boolean') return value;\n\tif (Array.isArray(value)) return value.slice(0, 64).map(entry => redact(entry, depth + 1));\n\tif (!isRecord(value)) return String(value).slice(0, 8192);\n\treturn Object.fromEntries(Object.entries(value).slice(0, 128).map(([key, entry]) => [key, /(?:authorization|cookie|password|secret|token)/i.test(key) ? '[REDACTED]' : redact(entry, depth + 1)]));\n};\nconst parse = (value: unknown): NativeReport | undefined => {\n\tif (!isRecord(value) || !isRecord(value.details) || typeof value.id !== 'string' || !ID.test(value.id) || typeof value.kind !== 'string' || !KINDS.has(value.kind) || typeof value.occurredAt !== 'number' || !Number.isFinite(value.occurredAt) || value.occurredAt <= 0 || value.platform !== 'android' && value.platform !== 'ios') return;\n\tconst details = redact(value.details);\n\tif (!isRecord(details) || new TextEncoder().encode(JSON.stringify(details)).byteLength > 64 * 1024) return;\n\treturn { details, id: value.id, kind: value.kind, occurredAt: value.occurredAt, platform: value.platform };\n};\nconst sampled = (id: string, rate: number) => {\n\tif (rate >= 1) return true;\n\tlet hash = 2166136261;\n\tfor (const character of id) { hash ^= character.codePointAt(0) ?? 0; hash = Math.imul(hash, 16777619); }\n\treturn (hash >>> 0) / 4294967296 < rate;\n};\nlet drainPromise: Promise<void> | undefined;\nlet started = false;\nconst drain = () => {\n\tdrainPromise ??= (async () => {\n\t\tconst manifest = ABSOLUTE_MOBILE_MANIFEST;\n\t\tconst config = manifest?.observability;\n\t\tif (!manifest || !config || Platform.OS !== 'android' && Platform.OS !== 'ios') return;\n\t\tconst reports = (await native.pending()).reports.slice(0, 8).map(parse).filter((report): report is NativeReport => report !== undefined);\n\t\tconst discarded = reports.filter(report => !sampled(report.id, config.sampleRate));\n\t\tif (discarded.length) await native.acknowledge({ ids: discarded.map(report => report.id) });\n\t\tconst selected = reports.filter(report => sampled(report.id, config.sampleRate));\n\t\tif (!selected.length) return;\n\t\tconst response = await fetch(config.endpoint, {\n\t\t\tbody: JSON.stringify({ ...(config.environment ? { environment: config.environment } : {}), events: selected.map(report => ({ at: report.occurredAt, extra: { nativeDiagnostic: report.details, nativeDiagnosticId: report.id }, groupingKey: 'absolute-native:' + report.platform + ':' + report.kind, level: ['app-launch', 'cpu-exception', 'disk-write-exception', 'low-memory', 'resource-exhaustion', 'signal'].includes(report.kind) ? 'warning' : 'error', message: 'Native process diagnostic \u2014 ' + report.kind, name: 'AbsoluteMobileNativeDiagnostic', tags: { absoluteMobile: 'true', mobileAppBuild: manifest.appBuild, mobileEngine: 'expo', mobileFailurePhase: 'native-process', mobileManifestFormat: '1', mobileNativeRuntime: 'expo', mobilePlatform: report.platform, mobileRuntime: manifest.runtime } })), project: config.project, release: manifest.appBuild, v: 1 }),\n\t\t\theaders: { 'content-type': 'application/json' },\n\t\t\tmethod: 'POST'\n\t\t});\n\t\tif (response.ok) await native.acknowledge({ ids: selected.map(report => report.id) });\n\t})().catch(() => undefined).finally(() => { drainPromise = undefined; });\n\treturn drainPromise;\n};\nexport const startAbsoluteExpoNativeObservability = () => {\n\tif (!started) {\n\t\tstarted = true;\n\t\tAppState.addEventListener('change', state => { if (state === 'active') void drain(); });\n\t}\n\treturn drain();\n};\nexport const crashAbsoluteExpoNativeObservabilityForTesting = (testId: string) => native.crashForTesting({ testId });\nexport const enqueueAbsoluteExpoNativeObservabilityForTesting = async (testId: string) => {\n\tawait drain();\n\tconst enqueued = await native.enqueueForTesting({ testId });\n\tawait drain();\n\treturn enqueued;\n};\n";
|
|
2
2
|
export declare const absoluteExpoNativeObservabilityFiles: (project: string) => Map<string, string>;
|
|
3
3
|
export declare const absoluteExpoNativeObservabilityPaths: (project: string) => string[];
|
|
@@ -3,6 +3,7 @@ export * from './adaptiveShell';
|
|
|
3
3
|
export * from './androidRelease';
|
|
4
4
|
export * from './androidUpgradeConformance';
|
|
5
5
|
export * from './iosRelease';
|
|
6
|
+
export * from './iosUpgradeConformance';
|
|
6
7
|
export * from './iosConformance';
|
|
7
8
|
export * from './iosSimulatorController';
|
|
8
9
|
export * from './iosPhysicalDeviceTransport';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type AbsoluteIosInstalledApp = {
|
|
2
|
+
appContainer: string;
|
|
3
|
+
appId: string;
|
|
4
|
+
buildNumber?: string;
|
|
5
|
+
dataContainer: string;
|
|
6
|
+
version?: string;
|
|
7
|
+
};
|
|
8
|
+
export type AbsoluteIosUpgradeCommandResult = {
|
|
9
|
+
exitCode: number;
|
|
10
|
+
stderr: string;
|
|
11
|
+
stdout: string;
|
|
12
|
+
};
|
|
13
|
+
export declare const inspectAbsoluteIosInstalledApp: (xcrun: string, udid: string, appId: string, run?: (command: string[]) => Promise<AbsoluteIosUpgradeCommandResult>, plutil?: string) => Promise<AbsoluteIosInstalledApp>;
|
|
14
|
+
export declare const parseAbsoluteIosInstalledAppInfo: (appId: string, appContainer: string, dataContainer: string, output: string) => AbsoluteIosInstalledApp;
|
|
15
|
+
/** Prove that Simulator inspections describe one app replaced by a newer build. */
|
|
16
|
+
export declare const assertAbsoluteIosInstalledAppUpgrade: (before: AbsoluteIosInstalledApp, after: AbsoluteIosInstalledApp) => void;
|
package/package.json
CHANGED
|
@@ -475,7 +475,9 @@
|
|
|
475
475
|
"test:native:expo:android:observability": "ABSOLUTE_TEST_NATIVE_EXPO_ANDROID=1 bun test tests/native/expo-android-observability-conformance.test.ts",
|
|
476
476
|
"test:native:expo:android:updates": "ABSOLUTE_TEST_NATIVE_EXPO_ANDROID_UPDATES=1 bun test tests/native/expo-android-update-conformance.test.ts",
|
|
477
477
|
"test:native:expo:android:upgrade": "ABSOLUTE_TEST_NATIVE_EXPO_ANDROID_UPGRADE=1 bun test tests/native/expo-android-upgrade-conformance.test.ts",
|
|
478
|
+
"test:native:expo:ios:observability": "ABSOLUTE_TEST_NATIVE_EXPO_IOS_OBSERVABILITY=1 bun test tests/native/expo-ios-observability-conformance.test.ts",
|
|
478
479
|
"test:native:expo:ios:updates": "ABSOLUTE_TEST_NATIVE_EXPO_IOS_UPDATES=1 bun test tests/native/expo-ios-update-conformance.test.ts",
|
|
480
|
+
"test:native:expo:ios:upgrade": "ABSOLUTE_TEST_NATIVE_EXPO_IOS_UPGRADE=1 bun test tests/native/expo-ios-upgrade-conformance.test.ts",
|
|
479
481
|
"test:native:ios": "bun run test:native:ios:lifecycle && bun run test:native:ios:bundle",
|
|
480
482
|
"test:native:ios:bundle": "ABSOLUTE_TEST_NATIVE_IOS=1 bun test tests/native/ios-embedded-bundle-conformance.test.ts",
|
|
481
483
|
"test:native:ios:lifecycle": "ABSOLUTE_TEST_NATIVE_IOS=1 bun test tests/native/ios-lifecycle-conformance.test.ts",
|
|
@@ -529,7 +531,7 @@
|
|
|
529
531
|
]
|
|
530
532
|
}
|
|
531
533
|
},
|
|
532
|
-
"version": "0.20.0-beta.
|
|
534
|
+
"version": "0.20.0-beta.92",
|
|
533
535
|
"workspaces": [
|
|
534
536
|
"tests/fixtures/*",
|
|
535
537
|
"tests/fixtures/_packages/*"
|