@absolutejs/absolute 0.20.0-beta.65 → 0.20.0-beta.67
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/angular/components/core/streamingSlotRegistrar.js +1 -1
- package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
- package/dist/build.js +768 -544
- package/dist/build.js.map +10 -8
- package/dist/cli/index.js +148 -5
- package/dist/dev/serverBootstrap.js +544 -6
- package/dist/index.js +905 -619
- package/dist/index.js.map +14 -11
- package/dist/mobile/index.js +5430 -5
- package/dist/mobile/index.js.map +11 -8
- package/dist/mobile/mobilePreviewClient.ts +246 -0
- package/dist/mobile/remoteMacAgentEntry.js +241 -180
- package/dist/mobile/shellAuth.js +16 -0
- package/dist/mobile/shellBootstrap.js +5427 -117
- package/dist/mobile/shellExpoAuth.js +16 -0
- package/dist/mobile/shellExpoDevices.js +16 -0
- package/dist/mobile/shellExpoSync.js +16 -0
- package/dist/mobile/shellSync.js +16 -0
- package/dist/mobile/shellUpdate.js +16 -0
- package/dist/mobile/uiPrimitives.js +16 -0
- package/dist/src/build/chainInlineSourcemaps.d.ts +2 -0
- package/dist/src/build/vueCompileCache.d.ts +43 -0
- package/dist/src/cli/config/server.d.ts +1 -1
- package/dist/src/dev/bootLifecycle.d.ts +11 -0
- package/dist/src/dev/earlyListener.d.ts +41 -0
- package/dist/src/mobile/capacitorBundle.d.ts +8 -1
- package/dist/src/mobile/config.d.ts +6 -0
- package/dist/src/mobile/index.d.ts +1 -0
- package/dist/src/mobile/mobileInspect.d.ts +14 -0
- package/dist/src/mobile/mobilePreview.d.ts +1 -1
- package/dist/src/mobile/shellBootstrap.d.ts +2 -0
- package/dist/src/mobile/shellObservability.d.ts +11 -0
- package/dist/src/mobile/transport.d.ts +6 -0
- package/dist/src/plugins/imageOptimizer.d.ts +1 -1
- package/dist/src/utils/startupTimings.d.ts +4 -0
- package/dist/types/build.d.ts +12 -0
- package/dist/types/globals.d.ts +15 -0
- package/package.json +9 -7
package/dist/cli/index.js
CHANGED
|
@@ -818,6 +818,30 @@ var APP_ID_PATTERN, SCHEME_PATTERN, APPLE_APP_ID_PREFIX_PATTERN, CERTIFICATE_FIN
|
|
|
818
818
|
throw new TypeError("mobile.ios.version must contain one to three dot-separated integer components, for example 1.4.0.");
|
|
819
819
|
}
|
|
820
820
|
return normalized;
|
|
821
|
+
}, normalizeObservability = (config, productionOrigin) => {
|
|
822
|
+
if (!config.observability)
|
|
823
|
+
return;
|
|
824
|
+
const project = requireText(config.observability.project, "mobile.observability.project");
|
|
825
|
+
if (project.length > 255)
|
|
826
|
+
throw new TypeError("mobile.observability.project must not exceed 255 characters.");
|
|
827
|
+
const environment = config.observability.environment?.trim();
|
|
828
|
+
if (environment !== undefined && (!environment || environment.length > 64))
|
|
829
|
+
throw new TypeError("mobile.observability.environment must contain 1 through 64 characters.");
|
|
830
|
+
const sampleRate = config.observability.sampleRate ?? 1;
|
|
831
|
+
if (!Number.isFinite(sampleRate) || sampleRate < 0 || sampleRate > 1)
|
|
832
|
+
throw new TypeError("mobile.observability.sampleRate must be between 0 and 1.");
|
|
833
|
+
const route = config.observability.route ?? "/api/observability/errors";
|
|
834
|
+
if (!route.startsWith("/") || route.startsWith("//"))
|
|
835
|
+
throw new TypeError("mobile.observability.route must be a root-relative trusted-server path.");
|
|
836
|
+
const endpoint = new URL(route, `${productionOrigin}/`);
|
|
837
|
+
if (endpoint.origin !== productionOrigin || endpoint.username || endpoint.password || endpoint.hash || endpoint.search)
|
|
838
|
+
throw new TypeError("mobile.observability.route must remain on productionOrigin and cannot contain credentials, a query, or a fragment.");
|
|
839
|
+
return {
|
|
840
|
+
endpoint: endpoint.href,
|
|
841
|
+
...environment ? { environment } : {},
|
|
842
|
+
project,
|
|
843
|
+
sampleRate
|
|
844
|
+
};
|
|
821
845
|
}, normalizeCertificateFingerprints = (values) => [
|
|
822
846
|
...new Set((values ?? []).map((value) => requireText(value, "mobile.deepLinks.android.sha256CertificateFingerprints").replaceAll(":", "").toUpperCase()).map((value) => {
|
|
823
847
|
if (!CERTIFICATE_FINGERPRINT_PATTERN.test(value)) {
|
|
@@ -972,6 +996,7 @@ var APP_ID_PATTERN, SCHEME_PATTERN, APPLE_APP_ID_PREFIX_PATTERN, CERTIFICATE_FIN
|
|
|
972
996
|
throw new TypeError("mobile.deepLinks.scheme is not a valid URL scheme.");
|
|
973
997
|
}
|
|
974
998
|
const updates = normalizeUpdates(config, productionOrigin, projectRoot);
|
|
999
|
+
const observability = normalizeObservability(config, productionOrigin);
|
|
975
1000
|
return {
|
|
976
1001
|
androidCertificateFingerprints: normalizeCertificateFingerprints(config.deepLinks?.android?.sha256CertificateFingerprints),
|
|
977
1002
|
appId,
|
|
@@ -986,6 +1011,7 @@ var APP_ID_PATTERN, SCHEME_PATTERN, APPLE_APP_ID_PREFIX_PATTERN, CERTIFICATE_FIN
|
|
|
986
1011
|
...config.engine === "expo" ? { expoSdkVersion: config.expo?.sdkVersion ?? 57 } : {},
|
|
987
1012
|
iosVersion: normalizeIosVersion(config.ios?.version),
|
|
988
1013
|
nativeProjectDirectory: resolveProjectPath(projectRoot, config.nativeProject?.directory ?? (config.engine === "expo" ? ".absolutejs/mobile/expo" : "mobile"), "mobile.nativeProject.directory"),
|
|
1014
|
+
...observability ? { observability } : {},
|
|
989
1015
|
platforms: normalizePlatforms(config.platforms),
|
|
990
1016
|
productionOrigin,
|
|
991
1017
|
pushAndroidGoogleServicesFile: resolveProjectPath(projectRoot, config.pushNotifications?.android?.googleServicesFile ?? "google-services.json", "mobile.pushNotifications.android.googleServicesFile"),
|
|
@@ -1969,6 +1995,14 @@ var EXPO_GENERATED_HEADER = `// Generated by AbsoluteJS. Edit absolute.config.ts
|
|
|
1969
1995
|
});
|
|
1970
1996
|
return {
|
|
1971
1997
|
appBuild: requireManifestString(value.appBuild, "appBuild"),
|
|
1998
|
+
...isRecord(value.observability) && typeof value.observability.endpoint === "string" && typeof value.observability.project === "string" && typeof value.observability.sampleRate === "number" ? {
|
|
1999
|
+
observability: {
|
|
2000
|
+
endpoint: value.observability.endpoint,
|
|
2001
|
+
...typeof value.observability.environment === "string" ? { environment: value.observability.environment } : {},
|
|
2002
|
+
project: value.observability.project,
|
|
2003
|
+
sampleRate: value.observability.sampleRate
|
|
2004
|
+
}
|
|
2005
|
+
} : {},
|
|
1972
2006
|
pages,
|
|
1973
2007
|
productionOrigin: requireManifestString(value.productionOrigin, "productionOrigin"),
|
|
1974
2008
|
routes,
|
|
@@ -2740,7 +2774,7 @@ export function AbsoluteWebHost() {
|
|
|
2740
2774
|
|
|
2741
2775
|
const styles = StyleSheet.create({ loading: { alignItems: 'center', flex: 1, justifyContent: 'center' }, web: { flex: 1 } });
|
|
2742
2776
|
`;
|
|
2743
|
-
}, webRouteSource, catchAllRouteSource, nativeRouteRuntimeSource = (auth) => `${EXPO_GENERATED_HEADER}import { useLocalSearchParams, usePathname } from 'expo-router';
|
|
2777
|
+
}, webRouteSource, catchAllRouteSource, nativeRouteRuntimeSource = (auth) => `${EXPO_GENERATED_HEADER}import { type ErrorBoundaryProps, useLocalSearchParams, usePathname } from 'expo-router';
|
|
2744
2778
|
import { type ComponentType, useEffect, useMemo, useState } from 'react';
|
|
2745
2779
|
import { ActivityIndicator, Platform, Pressable, StyleSheet, Text, View } from 'react-native';
|
|
2746
2780
|
import { ABSOLUTE_MOBILE_MANIFEST } from './webAssets';
|
|
@@ -2767,6 +2801,47 @@ type NativeRouteState<PageProps> =
|
|
|
2767
2801
|
|
|
2768
2802
|
const isRecord = (value: unknown): value is Record<string, unknown> =>
|
|
2769
2803
|
typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
2804
|
+
const redactErrorText = (value: string) => value
|
|
2805
|
+
.replace(/\\b(Bearer)\\s+[A-Za-z0-9._~+/-]+=*/gi, '$1 [REDACTED]')
|
|
2806
|
+
.replace(/([?&](?:access_token|api_?key|authorization|code|id_token|password|refresh_token|secret|token)=)[^&#\\s]*/gi, '$1[REDACTED]')
|
|
2807
|
+
.replace(/\\b((?:access_?token|api_?key|authorization|client_?secret|cookie|id_?token|password|passwd|refresh_?token|secret|token)\\s*[:=]\\s*)[^,\\s;]+/gi, '$1[REDACTED]')
|
|
2808
|
+
.replace(/\\beyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\b/g, '[REDACTED]');
|
|
2809
|
+
const captureNativeException = (value: unknown, context: { bundle?: string | undefined; contract?: string | undefined; pageId?: string | undefined; phase: string; route: string }) => {
|
|
2810
|
+
const manifest = ABSOLUTE_MOBILE_MANIFEST;
|
|
2811
|
+
const config = manifest?.observability;
|
|
2812
|
+
if (!manifest || !config || config.sampleRate === 0 || config.sampleRate < 1 && Math.random() >= config.sampleRate) return;
|
|
2813
|
+
const error = value instanceof Error ? value : new Error(String(value));
|
|
2814
|
+
const event = {
|
|
2815
|
+
level: 'error',
|
|
2816
|
+
message: redactErrorText(error.message),
|
|
2817
|
+
name: error.name,
|
|
2818
|
+
...(error.stack ? { stack: redactErrorText(error.stack) } : {}),
|
|
2819
|
+
tags: {
|
|
2820
|
+
absoluteMobile: 'true',
|
|
2821
|
+
mobileAppBuild: manifest.appBuild,
|
|
2822
|
+
mobileEngine: 'expo',
|
|
2823
|
+
mobileFailurePhase: context.phase,
|
|
2824
|
+
mobileManifestFormat: '1',
|
|
2825
|
+
mobilePlatform: Platform.OS,
|
|
2826
|
+
mobileRoute: context.route,
|
|
2827
|
+
mobileRuntime: manifest.runtime,
|
|
2828
|
+
...(context.bundle ? { mobilePageBundle: context.bundle } : {}),
|
|
2829
|
+
...(context.contract ? { mobilePageContract: context.contract } : {}),
|
|
2830
|
+
...(context.pageId ? { mobilePageId: context.pageId } : {})
|
|
2831
|
+
}
|
|
2832
|
+
};
|
|
2833
|
+
void fetch(config.endpoint, {
|
|
2834
|
+
body: JSON.stringify({
|
|
2835
|
+
...(config.environment ? { environment: config.environment } : {}),
|
|
2836
|
+
events: [event],
|
|
2837
|
+
project: config.project,
|
|
2838
|
+
release: manifest.appBuild,
|
|
2839
|
+
v: 1
|
|
2840
|
+
}),
|
|
2841
|
+
headers: { 'content-type': 'application/json' },
|
|
2842
|
+
method: 'POST'
|
|
2843
|
+
}).catch(() => undefined);
|
|
2844
|
+
};
|
|
2770
2845
|
const routeSegmentPattern = (segment: string) => {
|
|
2771
2846
|
if (segment === '*') return '.*';
|
|
2772
2847
|
if (segment.startsWith(':') && segment.endsWith('?')) return '[^/]*';
|
|
@@ -2794,6 +2869,17 @@ const productionPage = (pathname: string) => {
|
|
|
2794
2869
|
if (!page) throw new Error('The embedded AbsoluteJS page contract is incomplete.');
|
|
2795
2870
|
return page;
|
|
2796
2871
|
};
|
|
2872
|
+
export const createAbsoluteNativeRouteErrorBoundary = (pattern: string) => {
|
|
2873
|
+
return function AbsoluteNativeRouteErrorBoundary({ error, retry }: ErrorBoundaryProps) {
|
|
2874
|
+
const pathname = usePathname() || '/';
|
|
2875
|
+
useEffect(() => {
|
|
2876
|
+
let page: ReturnType<typeof productionPage> | undefined;
|
|
2877
|
+
try { if (ABSOLUTE_MOBILE_MANIFEST) page = productionPage(pathname); } catch {}
|
|
2878
|
+
captureNativeException(error, { bundle: page?.bundleHash, contract: page?.contract, pageId: page?.pageId, phase: 'native-route-render', route: pattern });
|
|
2879
|
+
}, [error, pathname]);
|
|
2880
|
+
return <View style={styles.center}><Text accessibilityRole="alert" style={styles.error}>This screen stopped unexpectedly.</Text><Pressable accessibilityRole="button" onPress={() => { void retry(); }} style={styles.button}><Text>Try again</Text></Pressable></View>;
|
|
2881
|
+
};
|
|
2882
|
+
};
|
|
2797
2883
|
const createDataRequest = (path: string) => {
|
|
2798
2884
|
const development = typeof DEV_ORIGIN === 'string' && DEV_ORIGIN.length > 0;
|
|
2799
2885
|
const origin = development ? DEV_ORIGIN : ABSOLUTE_MOBILE_MANIFEST?.productionOrigin;
|
|
@@ -2846,7 +2932,14 @@ export const createAbsoluteNativeRoute = <
|
|
|
2846
2932
|
setState({ kind: 'loading' });
|
|
2847
2933
|
void requestData<PageProps>(requestPath, controller.signal).then(
|
|
2848
2934
|
pageProps => { if (!controller.signal.aborted) setState({ kind: 'ready', pageProps }); },
|
|
2849
|
-
|
|
2935
|
+
error => {
|
|
2936
|
+
if (!controller.signal.aborted) {
|
|
2937
|
+
let page: ReturnType<typeof productionPage> | undefined;
|
|
2938
|
+
try { if (ABSOLUTE_MOBILE_MANIFEST) page = productionPage(pathname); } catch {}
|
|
2939
|
+
captureNativeException(error, { bundle: page?.bundleHash, contract: page?.contract, pageId: page?.pageId, phase: 'native-route-load', route: pattern });
|
|
2940
|
+
setState({ kind: 'error' });
|
|
2941
|
+
}
|
|
2942
|
+
}
|
|
2850
2943
|
);
|
|
2851
2944
|
return () => controller.abort();
|
|
2852
2945
|
}, [requestPath, revision]);
|
|
@@ -2864,8 +2957,9 @@ const styles = StyleSheet.create({
|
|
|
2864
2957
|
error: { color: '#b91c1c', fontSize: 16, textAlign: 'center' }
|
|
2865
2958
|
});
|
|
2866
2959
|
`, nativeWrapperSource = (wrapper, module, runtime, route) => `${EXPO_GENERATED_HEADER}import ApplicationNativeRoute from ${JSON.stringify(portableRelative(dirname4(wrapper), module).replace(/\.(?:[cm]?[jt]sx?)$/u, ""))};
|
|
2867
|
-
import { createAbsoluteNativeRoute } from ${JSON.stringify(portableRelative(dirname4(wrapper), runtime).replace(/\.(?:[cm]?[jt]sx?)$/u, ""))};
|
|
2960
|
+
import { createAbsoluteNativeRoute, createAbsoluteNativeRouteErrorBoundary } from ${JSON.stringify(portableRelative(dirname4(wrapper), runtime).replace(/\.(?:[cm]?[jt]sx?)$/u, ""))};
|
|
2868
2961
|
|
|
2962
|
+
export const ErrorBoundary = createAbsoluteNativeRouteErrorBoundary(${JSON.stringify(route)});
|
|
2869
2963
|
export default createAbsoluteNativeRoute(ApplicationNativeRoute, ${JSON.stringify(route)});
|
|
2870
2964
|
`, expoTsConfig = (projectRoot, project, auth, sync) => ({
|
|
2871
2965
|
compilerOptions: {
|
|
@@ -2930,6 +3024,7 @@ export default createAbsoluteNativeRoute(ApplicationNativeRoute, ${JSON.stringif
|
|
|
2930
3024
|
}, jsonSource = (value) => `${JSON.stringify(value, null, "\t")}
|
|
2931
3025
|
`, nativeDataManifestTypeSource = `type AbsoluteMobileManifest = {
|
|
2932
3026
|
appBuild: string;
|
|
3027
|
+
observability?: { endpoint: string; environment?: string; project: string; sampleRate: number };
|
|
2933
3028
|
pages: readonly { bundleHash: string; contract: string; pageId: string }[];
|
|
2934
3029
|
productionOrigin: string;
|
|
2935
3030
|
routes: readonly { method: 'GET'; pageId: string; pattern: string }[];
|
|
@@ -9496,7 +9591,9 @@ const absoluteMobilePushCapability = absoluteDeviceCapability${pushIndex}(absolu
|
|
|
9496
9591
|
const baseAdapterModule = capacitor ? await resolveProjectImport(projectRoot, "@absolutejs/devices-capacitor") : shellExpoDevicesModule();
|
|
9497
9592
|
const adapterImport = capacitor ? `import { installCapacitorDeviceAdapterIfNative } from ${JSON.stringify(baseAdapterModule)};` : `import { createAbsoluteExpoBridgeFetch, installAbsoluteExpoWebDeviceAdapter } from ${JSON.stringify(baseAdapterModule)};`;
|
|
9498
9593
|
const adapterInstall = capacitor ? `installCapacitorDeviceAdapterIfNative({ storagePrefix: ${JSON.stringify(storagePrefix)}${capabilityOptions ? `, ${capabilityOptions}` : ""} });` : `installAbsoluteExpoWebDeviceAdapter(${JSON.stringify(deviceCapabilities.capabilities)});`;
|
|
9499
|
-
const shellOptionProperties = [
|
|
9594
|
+
const shellOptionProperties = [
|
|
9595
|
+
`engine: ${JSON.stringify(engine)}`
|
|
9596
|
+
];
|
|
9500
9597
|
if (push) {
|
|
9501
9598
|
shellOptionProperties.push("createAuth: (config, options) => createAbsoluteMobileShellAuth(config, options)", "beforeSignOut: absoluteMobilePush.beforeSignOut", "connectPush: (auth) => absoluteMobilePush.connect(auth, absoluteMobilePushCapability)");
|
|
9502
9599
|
} else if (auth)
|
|
@@ -9516,6 +9613,7 @@ void startAbsoluteMobileShell(${shellOptions});
|
|
|
9516
9613
|
`);
|
|
9517
9614
|
const build = await Bun.build({
|
|
9518
9615
|
entrypoints: [entryPath],
|
|
9616
|
+
external: ["web-vitals", "web-vitals/*"],
|
|
9519
9617
|
minify: true,
|
|
9520
9618
|
outdir: staging,
|
|
9521
9619
|
target: "browser"
|
|
@@ -9575,6 +9673,40 @@ void startAbsoluteMobileShell(${shellOptions});
|
|
|
9575
9673
|
localBundlePath,
|
|
9576
9674
|
...localStylePath ? { localStylePath } : {}
|
|
9577
9675
|
};
|
|
9676
|
+
}, materializeAbsoluteMobileSourcemaps = async (pages, appBuild, projectRoot) => {
|
|
9677
|
+
const safeLeaf = (value, field) => {
|
|
9678
|
+
if (value === "." || value === ".." || !/^[A-Za-z0-9._-]+$/u.test(value))
|
|
9679
|
+
throw new TypeError(`${field} is not a safe source-map key.`);
|
|
9680
|
+
return value;
|
|
9681
|
+
};
|
|
9682
|
+
const release = safeLeaf(appBuild, "Mobile app build");
|
|
9683
|
+
const privateRoot = join21(projectRoot, "sourcemaps");
|
|
9684
|
+
const releaseRoot = join21(privateRoot, "mobile", release);
|
|
9685
|
+
const copied = [];
|
|
9686
|
+
const available = pages.flatMap((page) => {
|
|
9687
|
+
const source = join21(privateRoot, `${basename8(page.bundlePath)}.map`);
|
|
9688
|
+
return existsSync10(source) ? [{ page, source }] : [];
|
|
9689
|
+
});
|
|
9690
|
+
if (available.length > 0)
|
|
9691
|
+
await mkdir9(releaseRoot, { recursive: true });
|
|
9692
|
+
await Promise.all(available.map(async ({ page, source }) => {
|
|
9693
|
+
const extension = extname5(page.bundlePath) || ".js";
|
|
9694
|
+
if (!/^\.[a-z0-9]+$/iu.test(extension))
|
|
9695
|
+
throw new TypeError("Mobile page extension is not a safe source-map key.");
|
|
9696
|
+
const bundleHash = safeLeaf(page.bundleHash, "Mobile page bundle hash");
|
|
9697
|
+
const file = `${bundleHash}${extension}.map`;
|
|
9698
|
+
await copyFile4(source, join21(releaseRoot, file));
|
|
9699
|
+
copied.push({ bundleHash, file, pageId: page.pageId });
|
|
9700
|
+
}));
|
|
9701
|
+
if (copied.length > 0) {
|
|
9702
|
+
await writeFile8(join21(releaseRoot, "manifest.json"), `${JSON.stringify({
|
|
9703
|
+
appBuild,
|
|
9704
|
+
format: 1,
|
|
9705
|
+
pages: copied.sort((left, right) => left.pageId.localeCompare(right.pageId))
|
|
9706
|
+
}, null, "\t")}
|
|
9707
|
+
`);
|
|
9708
|
+
}
|
|
9709
|
+
return copied.length;
|
|
9578
9710
|
}, absoluteClientImports = async (sourcePath, buildDirectory) => {
|
|
9579
9711
|
const source = await readFile10(sourcePath, "utf8");
|
|
9580
9712
|
const extension = extname5(sourcePath).toLowerCase();
|
|
@@ -9650,6 +9782,7 @@ void startAbsoluteMobileShell(${shellOptions});
|
|
|
9650
9782
|
productionOrigin: options.config.productionOrigin,
|
|
9651
9783
|
routes: options.artifact.routes,
|
|
9652
9784
|
runtime: options.artifact.runtime,
|
|
9785
|
+
...options.config.observability ? { observability: options.config.observability } : {},
|
|
9653
9786
|
...options.config.updates ? { updates: options.config.updates } : {},
|
|
9654
9787
|
...options.sync ? {
|
|
9655
9788
|
sync: {
|
|
@@ -9673,6 +9806,7 @@ void startAbsoluteMobileShell(${shellOptions});
|
|
|
9673
9806
|
buildShellBootstrap(staging, options.auth !== undefined, options.auth !== undefined && options.sync === true, `absolutejs.${options.auth?.clientId ?? options.config.appId}.`, options.config.engine, options.config.engine === "capacitor" && options.config.updates !== undefined, options.deviceCapabilities, options.projectRoot)
|
|
9674
9807
|
]);
|
|
9675
9808
|
await installBundle(staging, destination);
|
|
9809
|
+
await materializeAbsoluteMobileSourcemaps(options.artifact.pages, options.artifact.appBuild, options.projectRoot);
|
|
9676
9810
|
return manifest;
|
|
9677
9811
|
} catch (error) {
|
|
9678
9812
|
await rm7(staging, { force: true, recursive: true });
|
|
@@ -22660,7 +22794,16 @@ var ABSOLUTE_MOBILE_INSPECTION_FORMAT = 1, MOBILE_PACKAGE_NAMES, isObject3 = (va
|
|
|
22660
22794
|
iosVersion: config.iosVersion,
|
|
22661
22795
|
nativeProjectDirectory: portablePath2(projectRoot, config.nativeProjectDirectory),
|
|
22662
22796
|
platforms: config.platforms,
|
|
22663
|
-
productionOrigin: config.productionOrigin
|
|
22797
|
+
productionOrigin: config.productionOrigin,
|
|
22798
|
+
...config.observability ? {
|
|
22799
|
+
observability: {
|
|
22800
|
+
enabled: true,
|
|
22801
|
+
endpoint: config.observability.endpoint,
|
|
22802
|
+
environment: config.observability.environment,
|
|
22803
|
+
project: config.observability.project,
|
|
22804
|
+
sampleRate: config.observability.sampleRate
|
|
22805
|
+
}
|
|
22806
|
+
} : {}
|
|
22664
22807
|
},
|
|
22665
22808
|
format: ABSOLUTE_MOBILE_INSPECTION_FORMAT,
|
|
22666
22809
|
nativeProjects: await Promise.all(config.platforms.map(async (platform6) => {
|