mirror of
https://github.com/VibedByKaKi/t3-code-android-nightly.git
synced 2026-10-10 12:21:16 +02:00
Some checks are pending
CI / Lint (push) Waiting to run
CI / Typecheck (push) Waiting to run
CI / Build (push) Waiting to run
CI / Test (push) Waiting to run
CI / Test Web (push) Waiting to run
CI / Test Server 1 (push) Waiting to run
CI / Test Server 2 (push) Waiting to run
CI / Test Server 3 (push) Waiting to run
CI / Test Server 4 (push) Waiting to run
CI / Test Server 5 (push) Waiting to run
CI / Test Server 6 (push) Waiting to run
CI / Transfer report artifact (push) Blocked by required conditions
CI / Rust (push) Waiting to run
CI / Mobile Native Changes (push) Waiting to run
CI / Mobile Native Static Analysis (push) Blocked by required conditions
CI / Release Smoke (push) Waiting to run
CI / Check (push) Blocked by required conditions
Forward to Cursor hygiene / POST to Cursor (push) Waiting to run
Deploy T3 Connect relay / Deploy production relay (push) Waiting to run
Mobile EAS Production / EAS production (push) Waiting to run
502 lines
19 KiB
TypeScript
502 lines
19 KiB
TypeScript
import type { ExpoConfig } from "expo/config";
|
|
|
|
import { BRAND_ASSET_PATHS } from "../../scripts/lib/brand-assets.ts";
|
|
import { loadRepoEnv } from "../../scripts/lib/public-config.ts";
|
|
|
|
type AppVariant = "development" | "preview" | "production";
|
|
|
|
const repoEnv = loadRepoEnv();
|
|
Object.assign(process.env, repoEnv);
|
|
|
|
const APP_VARIANT = resolveAppVariant(repoEnv.APP_VARIANT);
|
|
const isIosPersonalTeamBuild = repoEnv.T3CODE_IOS_PERSONAL_TEAM === "1";
|
|
const runtimeVersionPolicy =
|
|
process.env.MOBILE_VERSION_POLICY ??
|
|
(APP_VARIANT === "development" ? "appVersion" : "fingerprint");
|
|
|
|
const personalTeamBundleIdentifier = repoEnv.T3CODE_IOS_PERSONAL_TEAM_BUNDLE_ID?.trim();
|
|
const IOS_BUNDLE_IDENTIFIER_PATTERN = /^[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)+$/;
|
|
|
|
const fromRepoRoot = (relativePath: string) => `../../${relativePath}`;
|
|
// Android layers are rendered by scripts/export-android-icons.ts from the Icon Composer sources.
|
|
// The wordmark sits inside the adaptive safe zone; the variant artwork is a full-bleed background.
|
|
const androidAdaptiveForeground = "./assets/android-icon-foreground.png";
|
|
|
|
if (
|
|
isIosPersonalTeamBuild &&
|
|
(!personalTeamBundleIdentifier ||
|
|
!IOS_BUNDLE_IDENTIFIER_PATTERN.test(personalTeamBundleIdentifier))
|
|
) {
|
|
throw new Error(
|
|
"T3CODE_IOS_PERSONAL_TEAM_BUNDLE_ID must be a reverse-DNS identifier such as com.example.t3code when T3CODE_IOS_PERSONAL_TEAM=1.",
|
|
);
|
|
}
|
|
|
|
const DEVELOPMENT_ASSETS = {
|
|
appIcon: fromRepoRoot(BRAND_ASSET_PATHS.developmentIosIconPng),
|
|
iosIcon: fromRepoRoot(BRAND_ASSET_PATHS.developmentIconComposerProject),
|
|
splashIcon: fromRepoRoot(BRAND_ASSET_PATHS.developmentIosIconPng),
|
|
androidAdaptiveForeground,
|
|
androidAdaptiveBackgroundColor: "#347FF8",
|
|
androidAdaptiveBackgroundImage: "./assets/android-icon-background-dev.png",
|
|
androidSplashIcon: "./assets/android-splash-icon-dev.png",
|
|
androidMonochromeIcon: "./assets/android-icon-mark.png",
|
|
androidNotificationIcon: "./assets/android-notification-icon.png",
|
|
androidNotificationColor: "#00639B",
|
|
} as const;
|
|
|
|
const PREVIEW_ASSETS = {
|
|
appIcon: fromRepoRoot(BRAND_ASSET_PATHS.nightlyIosIconPng),
|
|
iosIcon: fromRepoRoot(BRAND_ASSET_PATHS.nightlyIconComposerProject),
|
|
splashIcon: fromRepoRoot(BRAND_ASSET_PATHS.nightlyIosIconPng),
|
|
androidAdaptiveForeground,
|
|
androidAdaptiveBackgroundColor: "#111533",
|
|
androidAdaptiveBackgroundImage: "./assets/android-icon-background-nightly.png",
|
|
androidSplashIcon: "./assets/android-splash-icon-nightly.png",
|
|
androidMonochromeIcon: "./assets/android-icon-mark.png",
|
|
androidNotificationIcon: "./assets/android-notification-icon.png",
|
|
androidNotificationColor: "#7565C7",
|
|
} as const;
|
|
|
|
const RELEASE_ASSETS = {
|
|
appIcon: fromRepoRoot(BRAND_ASSET_PATHS.productionIosIconPng),
|
|
iosIcon: fromRepoRoot(BRAND_ASSET_PATHS.productionIconComposerProject),
|
|
splashIcon: fromRepoRoot(BRAND_ASSET_PATHS.productionIosIconPng),
|
|
androidAdaptiveForeground,
|
|
androidAdaptiveBackgroundColor: "#000000",
|
|
androidAdaptiveBackgroundImage: undefined,
|
|
androidSplashIcon: "./assets/android-splash-icon-prod.png",
|
|
androidMonochromeIcon: "./assets/android-icon-mark.png",
|
|
androidNotificationIcon: "./assets/android-notification-icon.png",
|
|
androidNotificationColor: "#FFFFFF",
|
|
} as const;
|
|
|
|
const VARIANT_CONFIG = {
|
|
development: {
|
|
appName: "T3 Code Dev",
|
|
scheme: "t3code-dev",
|
|
iosBundleIdentifier: "com.t3tools.t3code.dev",
|
|
androidPackage: "com.t3tools.t3code.dev",
|
|
relyingParty: "clerk.t3.codes",
|
|
assets: DEVELOPMENT_ASSETS,
|
|
},
|
|
preview: {
|
|
appName: "T3 Code Preview",
|
|
scheme: "t3code-preview",
|
|
iosBundleIdentifier: "com.t3tools.t3code.preview",
|
|
androidPackage: "com.t3tools.t3code.preview",
|
|
relyingParty: "clerk.t3.codes",
|
|
assets: PREVIEW_ASSETS,
|
|
},
|
|
production: {
|
|
appName: "T3 Code",
|
|
scheme: "t3code",
|
|
iosBundleIdentifier: "com.t3tools.t3code",
|
|
androidPackage: "com.t3tools.t3code",
|
|
relyingParty: "clerk.t3.codes",
|
|
assets: RELEASE_ASSETS,
|
|
},
|
|
} as const;
|
|
|
|
function resolveAppVariant(value: string | undefined): AppVariant {
|
|
switch (value) {
|
|
case "development":
|
|
case "preview":
|
|
case "production":
|
|
return value;
|
|
default:
|
|
return "production";
|
|
}
|
|
}
|
|
|
|
const variant = VARIANT_CONFIG[APP_VARIANT];
|
|
const iosBundleIdentifier = isIosPersonalTeamBuild
|
|
? personalTeamBundleIdentifier!
|
|
: variant.iosBundleIdentifier;
|
|
|
|
const dmSansFonts = {
|
|
regular: "@expo-google-fonts/dm-sans/400Regular/DMSans_400Regular.ttf",
|
|
medium: "@expo-google-fonts/dm-sans/500Medium/DMSans_500Medium.ttf",
|
|
bold: "@expo-google-fonts/dm-sans/700Bold/DMSans_700Bold.ttf",
|
|
} as const;
|
|
|
|
const widgetsPlugin: NonNullable<ExpoConfig["plugins"]>[number] = [
|
|
"expo-widgets",
|
|
{
|
|
bundleIdentifier: `${iosBundleIdentifier}.widgets`,
|
|
groupIdentifier: `group.${iosBundleIdentifier}`,
|
|
enablePushNotifications: true,
|
|
// Agent activity can update many times an hour; without the
|
|
// frequent-updates entitlement iOS throttles the update budget sooner.
|
|
frequentUpdates: true,
|
|
enableAndroid: true,
|
|
widgets: [
|
|
{
|
|
name: "SubscriptionUsage",
|
|
displayName: "Subscription usage",
|
|
description: "Subscription quotas from your connected T3 Code environments.",
|
|
ios: {
|
|
configuration: {
|
|
title: "Subscription usage",
|
|
description:
|
|
"Both shows Session and Weekly when available. The Lock Screen shows the tightest selected limit.",
|
|
parameters: {
|
|
codexPeriod: {
|
|
title: "Codex limits",
|
|
type: "enum",
|
|
default: "auto",
|
|
values: [
|
|
{ name: "Both", value: "auto" },
|
|
{ name: "Session", value: "session" },
|
|
{ name: "Weekly", value: "weekly" },
|
|
],
|
|
},
|
|
claudePeriod: {
|
|
title: "Claude limits",
|
|
type: "enum",
|
|
default: "auto",
|
|
values: [
|
|
{ name: "Both", value: "auto" },
|
|
{ name: "Session", value: "session" },
|
|
{ name: "Weekly", value: "weekly" },
|
|
],
|
|
},
|
|
},
|
|
},
|
|
supportedFamilies: [
|
|
"systemSmall",
|
|
"systemMedium",
|
|
"systemLarge",
|
|
"systemExtraLarge",
|
|
"accessoryRectangular",
|
|
],
|
|
},
|
|
android: {
|
|
minWidth: 250,
|
|
minHeight: 180,
|
|
targetCellWidth: 4,
|
|
targetCellHeight: 3,
|
|
resizeMode: "both",
|
|
// Embeds the layout in the APK so the widget renders before the app
|
|
// has run once; the app replaces it with stored props on publish.
|
|
initialLayout: "./src/widgets/SubscriptionUsage.android.tsx",
|
|
},
|
|
},
|
|
{
|
|
name: "AgentActivity",
|
|
displayName: "Agent Activity",
|
|
description: "Shows the current state of active T3 Code agents.",
|
|
// Live Activity companion; there is no Android presentation for it.
|
|
android: null,
|
|
ios: { supportedFamilies: ["systemSmall", "systemMedium", "accessoryRectangular"] },
|
|
},
|
|
],
|
|
},
|
|
];
|
|
|
|
const sharingPlugin: NonNullable<ExpoConfig["plugins"]>[number] = [
|
|
"expo-sharing",
|
|
{
|
|
ios: {
|
|
// Personal Teams cannot sign App Groups or extension targets. Keep the
|
|
// reduced-capability local build usable while release builds expose the
|
|
// real system share target.
|
|
enabled: !isIosPersonalTeamBuild,
|
|
extensionBundleIdentifier: `${iosBundleIdentifier}.sharing`,
|
|
appGroupId: `group.${iosBundleIdentifier}`,
|
|
activationRule: {
|
|
supportsText: true,
|
|
supportsWebUrlWithMaxCount: 1,
|
|
supportsImageWithMaxCount: 8,
|
|
supportsMovieWithMaxCount: 8,
|
|
supportsFileWithMaxCount: 8,
|
|
},
|
|
},
|
|
android: {
|
|
enabled: true,
|
|
singleShareMimeTypes: ["*/*"],
|
|
multipleShareMimeTypes: ["*/*"],
|
|
},
|
|
},
|
|
];
|
|
|
|
// These aliases match the fonts' PostScript names on iOS. Register the same
|
|
// names on Android so React Native and the native composer use one set of
|
|
// family names without waiting for runtime font loading.
|
|
|
|
const config: ExpoConfig = {
|
|
name: variant.appName,
|
|
slug: "t3-code",
|
|
platforms: ["ios", "android"],
|
|
scheme: variant.scheme,
|
|
version: "2.0.0",
|
|
runtimeVersion: {
|
|
// Development manifests resolve on every launch, so avoid fingerprint's
|
|
// expensive native-project calculation there. Preview and production stay
|
|
// fingerprinted so OTAs only reach binaries with matching native projects.
|
|
policy: runtimeVersionPolicy,
|
|
},
|
|
orientation: "portrait",
|
|
icon: variant.assets.appIcon,
|
|
userInterfaceStyle: "automatic",
|
|
updates: {
|
|
enabled: repoEnv.T3CODE_MOBILE_UPDATES_ENABLED !== "0",
|
|
url: "https://u.expo.dev/d763fcb8-d37c-41ea-a773-b54a0ab4a454",
|
|
checkAutomatically: "ON_LOAD",
|
|
fallbackToCacheTimeout: 0,
|
|
},
|
|
ios: {
|
|
icon: variant.assets.iosIcon,
|
|
supportsTablet: true,
|
|
// Multitasking-capable iPad apps cannot rotate programmatically, so the
|
|
// showcase capture build requires full screen (see infoPlist below).
|
|
requireFullScreen: process.env.T3_SHOWCASE_CAPTURE_BUILD === "1",
|
|
bundleIdentifier: iosBundleIdentifier,
|
|
// Pin code signing to the T3 Tools team so non-interactive `expo run:ios`
|
|
// does not fall back to a personal team (which cannot sign app groups,
|
|
// Sign in with Apple, or push notification entitlements).
|
|
appleTeamId: "ARK85ZXQ4Z",
|
|
associatedDomains: [
|
|
`applinks:${variant.relyingParty}`,
|
|
`webcredentials:${variant.relyingParty}`,
|
|
],
|
|
entitlements: {
|
|
"keychain-access-groups": [`$(AppIdentifierPrefix)${variant.iosBundleIdentifier}`],
|
|
},
|
|
infoPlist: {
|
|
UISupportedInterfaceOrientations: [
|
|
"UIInterfaceOrientationPortrait",
|
|
"UIInterfaceOrientationLandscapeLeft",
|
|
"UIInterfaceOrientationLandscapeRight",
|
|
],
|
|
NSAppTransportSecurity: {
|
|
NSAllowsArbitraryLoads: true,
|
|
},
|
|
NSLocalNetworkUsageDescription:
|
|
"Allow T3 Code to connect to T3 Code servers on your local network or tailnet.",
|
|
NSPhotoLibraryAddUsageDescription: "Allow T3 Code to save images to your photo library.",
|
|
// "Audio, AirPlay, and Picture in Picture": the browser screen's system
|
|
// picture in picture needs it to start and to stay up outside the app.
|
|
UIBackgroundModes: ["audio"],
|
|
ITSAppUsesNonExemptEncryption: false,
|
|
// The App Store screenshot harness rotates the iPad interface from
|
|
// inside the app (CI denies osascript the Accessibility access that
|
|
// Simulator menu scripting needs), and iPadOS ignores programmatic
|
|
// orientation requests for multitasking-capable apps — so the capture
|
|
// build opts out of multitasking and declares landscape support.
|
|
...(process.env.T3_SHOWCASE_CAPTURE_BUILD === "1"
|
|
? {
|
|
"UISupportedInterfaceOrientations~ipad": [
|
|
"UIInterfaceOrientationPortrait",
|
|
"UIInterfaceOrientationPortraitUpsideDown",
|
|
"UIInterfaceOrientationLandscapeLeft",
|
|
"UIInterfaceOrientationLandscapeRight",
|
|
],
|
|
}
|
|
: {}),
|
|
},
|
|
},
|
|
android: {
|
|
icon: variant.assets.appIcon,
|
|
package: variant.androidPackage,
|
|
...(repoEnv.T3CODE_ANDROID_GOOGLE_SERVICES_FILE
|
|
? { googleServicesFile: repoEnv.T3CODE_ANDROID_GOOGLE_SERVICES_FILE }
|
|
: {}),
|
|
adaptiveIcon: {
|
|
backgroundColor: variant.assets.androidAdaptiveBackgroundColor,
|
|
...(variant.assets.androidAdaptiveBackgroundImage
|
|
? { backgroundImage: variant.assets.androidAdaptiveBackgroundImage }
|
|
: {}),
|
|
foregroundImage: variant.assets.androidAdaptiveForeground,
|
|
monochromeImage: variant.assets.androidMonochromeIcon,
|
|
},
|
|
// Opts into OnBackInvokedCallback-based back dispatch (Android 13+).
|
|
// JS back handling survives it via react-native's Android 16 shim plus
|
|
// withAndroidPredictiveBackCompat on Android 13-15.
|
|
predictiveBackGestureEnabled: true,
|
|
// expo-sensors declares this for its pedometer, which the app does not use.
|
|
blockedPermissions: ["android.permission.ACTIVITY_RECOGNITION"],
|
|
},
|
|
web: {
|
|
favicon: variant.assets.appIcon,
|
|
},
|
|
plugins: [
|
|
"expo-asset",
|
|
[
|
|
"expo-font",
|
|
{
|
|
ios: {
|
|
fonts: [dmSansFonts.regular, dmSansFonts.medium, dmSansFonts.bold],
|
|
},
|
|
android: {
|
|
fonts: [
|
|
{
|
|
fontFamily: "DMSans-Regular",
|
|
fontDefinitions: [{ path: dmSansFonts.regular, weight: 400 }],
|
|
},
|
|
{
|
|
fontFamily: "DMSans-Medium",
|
|
fontDefinitions: [{ path: dmSansFonts.medium, weight: 500 }],
|
|
},
|
|
{
|
|
fontFamily: "DMSans-Bold",
|
|
fontDefinitions: [{ path: dmSansFonts.bold, weight: 700 }],
|
|
},
|
|
],
|
|
},
|
|
},
|
|
],
|
|
"expo-secure-store",
|
|
"expo-sqlite",
|
|
...(isIosPersonalTeamBuild
|
|
? [sharingPlugin]
|
|
: ["./plugins/withShareExtensionDisplayName.cjs", sharingPlugin]),
|
|
[
|
|
"expo-notifications",
|
|
{
|
|
icon: variant.assets.androidNotificationIcon,
|
|
color: variant.assets.androidNotificationColor,
|
|
mode: APP_VARIANT === "development" ? "development" : "production",
|
|
},
|
|
],
|
|
// appleSignIn must be gated here: withoutIosPersonalTeamCapabilities.cjs runs before
|
|
// plugins earlier in this array, so it cannot strip the entitlement Clerk would add.
|
|
["@clerk/expo", { theme: "./clerk-theme.json", appleSignIn: !isIosPersonalTeamBuild }],
|
|
"expo-web-browser",
|
|
[
|
|
"expo-quick-actions",
|
|
{
|
|
// Adaptive launcher-shortcut icon; referenced by resource name from
|
|
// the shortcut items set in src/features/shortcuts.
|
|
androidIcons: {
|
|
shortcut_icon: {
|
|
foregroundImage: variant.assets.androidAdaptiveForeground,
|
|
backgroundColor: variant.assets.androidAdaptiveBackgroundColor,
|
|
...(variant.assets.androidAdaptiveBackgroundImage
|
|
? { backgroundImage: variant.assets.androidAdaptiveBackgroundImage }
|
|
: {}),
|
|
},
|
|
},
|
|
},
|
|
],
|
|
[
|
|
"expo-audio",
|
|
{
|
|
microphonePermission: "Allow T3 Code to use your microphone for voice input.",
|
|
recordAudioAndroid: false,
|
|
enableBackgroundPlayback: false,
|
|
enableBackgroundRecording: false,
|
|
},
|
|
],
|
|
[
|
|
"expo-camera",
|
|
{
|
|
cameraPermission: "Allow T3 Code to access your camera so you can scan pairing QR codes.",
|
|
microphonePermission: false,
|
|
barcodeScannerEnabled: true,
|
|
recordAudioAndroid: false,
|
|
},
|
|
],
|
|
["expo-image-picker", { photosPermission: false, microphonePermission: false }],
|
|
[
|
|
"expo-splash-screen",
|
|
{
|
|
image: variant.assets.splashIcon,
|
|
resizeMode: "contain",
|
|
backgroundColor: "#ffffff",
|
|
imageWidth: 220,
|
|
dark: {
|
|
image: variant.assets.splashIcon,
|
|
backgroundColor: "#0a0a0a",
|
|
},
|
|
android: {
|
|
// Android 12+ masks the splash icon to a circle over the central two thirds of
|
|
// its 288dp canvas, so the iOS export's corners get cut. A full-canvas image of
|
|
// the composed adaptive layers puts the wordmark in the same frame the launcher
|
|
// icon uses.
|
|
image: variant.assets.androidSplashIcon,
|
|
imageWidth: 288,
|
|
dark: { image: variant.assets.androidSplashIcon },
|
|
},
|
|
},
|
|
],
|
|
[
|
|
"expo-build-properties",
|
|
{
|
|
android: {
|
|
// Keep the supported floor explicit and covered by native notification tests.
|
|
minSdkVersion: 24,
|
|
// kotlinx-io uses Kotlin 2.3's return-value checker annotation, while
|
|
// SDK 58 builds with Kotlin 2.2. It has no runtime behavior.
|
|
//
|
|
// WorkManager 2.9 keeps InputMerger classes but not their constructors,
|
|
// and R8 full mode no longer keeps a default constructor implicitly.
|
|
// Without it no work request can start, so the Glance session behind
|
|
// the widget never renders and it stays on "Loading widget". WorkManager
|
|
// 2.10 ships this rule itself; drop it once the resolved version gets there.
|
|
extraProguardRules: [
|
|
"-dontwarn kotlin.MustUseReturnValues",
|
|
"-keep class * extends androidx.work.InputMerger { <init>(); }",
|
|
].join("\n"),
|
|
},
|
|
ios: {
|
|
deploymentTarget: "18.0",
|
|
// AppCheckCore 11.3+ includes Swift and needs module maps for these Objective-C dependencies.
|
|
extraPods: [
|
|
{ name: "GoogleUtilities", modular_headers: true },
|
|
{ name: "RecaptchaInterop", modular_headers: true },
|
|
],
|
|
},
|
|
},
|
|
],
|
|
"./plugins/withIosCocoaPodsUuidCache.cjs",
|
|
// Only the accelerometer is used (device viewer shake). Compile out the
|
|
// pedometer so iOS needs no motion purpose string.
|
|
["expo-sensors", { motionPermission: false }],
|
|
// Must be listed BEFORE expo-widgets: same-type mods run last-registered-
|
|
// first, so registering earlier makes this plugin's mods run AFTER
|
|
// expo-widgets' — its dangerous mod wipes ios/ExpoWidgetsTarget/ (which
|
|
// would delete the asset catalog) and its xcodeproj mod creates the widget
|
|
// target (which must exist before the compile phase can be attached).
|
|
...(!isIosPersonalTeamBuild ? ["./plugins/withWidgetLogoAsset.cjs", widgetsPlugin] : []),
|
|
"./plugins/withAndroidCleartextTraffic.cjs",
|
|
"./plugins/withAndroidGradleHeap.cjs",
|
|
"./plugins/withAndroidInputBackground.cjs",
|
|
"./plugins/withAndroidModernPopupMenu.cjs",
|
|
"./plugins/withAndroidModernAlertDialog.cjs",
|
|
"./plugins/withAndroidPredictiveBackCompat.cjs",
|
|
"./plugins/withAndroidTabletOrientation.cjs",
|
|
...(isIosPersonalTeamBuild ? ["./plugins/withoutIosPersonalTeamCapabilities.cjs"] : []),
|
|
],
|
|
extra: {
|
|
appVariant: APP_VARIANT,
|
|
iosPersonalTeamBuild: isIosPersonalTeamBuild,
|
|
relay: {
|
|
url: repoEnv.T3CODE_RELAY_URL ?? null,
|
|
},
|
|
clerk: {
|
|
publishableKey: repoEnv.EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY ?? null,
|
|
jwtTemplate: repoEnv.EXPO_PUBLIC_CLERK_JWT_TEMPLATE ?? null,
|
|
},
|
|
// Native Google sign-in credentials. @clerk/expo reads these from `extra`
|
|
// under their exact env-var names (not nested), and its config plugin reads
|
|
// the iOS URL scheme at prebuild to register it in Info.plist.
|
|
// Unset values must be omitted (not null): the public manifest serializes
|
|
// null to {}, which is truthy and would defeat Clerk's fallback checks.
|
|
EXPO_PUBLIC_CLERK_GOOGLE_WEB_CLIENT_ID: repoEnv.EXPO_PUBLIC_CLERK_GOOGLE_WEB_CLIENT_ID,
|
|
EXPO_PUBLIC_CLERK_GOOGLE_IOS_CLIENT_ID: repoEnv.EXPO_PUBLIC_CLERK_GOOGLE_IOS_CLIENT_ID,
|
|
EXPO_PUBLIC_CLERK_GOOGLE_ANDROID_CLIENT_ID: repoEnv.EXPO_PUBLIC_CLERK_GOOGLE_ANDROID_CLIENT_ID,
|
|
EXPO_PUBLIC_CLERK_GOOGLE_IOS_URL_SCHEME: repoEnv.EXPO_PUBLIC_CLERK_GOOGLE_IOS_URL_SCHEME,
|
|
observability: {
|
|
tracesUrl: repoEnv.EXPO_PUBLIC_OTLP_TRACES_URL ?? "https://api.axiom.co/v1/traces",
|
|
tracesDataset: repoEnv.EXPO_PUBLIC_OTLP_TRACES_DATASET ?? null,
|
|
tracesToken: repoEnv.EXPO_PUBLIC_OTLP_TRACES_TOKEN ?? null,
|
|
},
|
|
eas: {
|
|
projectId: "d763fcb8-d37c-41ea-a773-b54a0ab4a454",
|
|
},
|
|
},
|
|
owner: "pingdotgg",
|
|
};
|
|
|
|
export default config;
|