// @ts-check /** * Allow HTTP / WS to staging API host via App Transport Security exception. * * Enabled when EXPO_PUBLIC_API_URL uses http:// (same rule as Android cleartext). * Host is parsed from the URL so IP:port staging endpoints work without hard-coding. */ const { withInfoPlist } = require('@expo/config-plugins'); /** * @returns {string | null} */ function getHttpExceptionHost() { const raw = process.env.EXPO_PUBLIC_API_URL ?? ''; if (!raw.startsWith('http://')) { return null; } try { return new URL(raw).hostname; } catch { return null; } } /** * @param {import('expo/config').ExpoConfig} config * @param {{ enabled?: boolean }} props */ function withIosInsecureHttp(config, props = {}) { const enabled = props.enabled ?? false; return withInfoPlist(config, (mod) => { if (!enabled) { return mod; } const host = getHttpExceptionHost(); if (!host) { console.warn( '[withIosInsecureHttp] enabled but EXPO_PUBLIC_API_URL has no http host; skipping ATS exception.', ); return mod; } const existing = mod.modResults.NSAppTransportSecurity ?? {}; const existingDomains = existing.NSExceptionDomains ?? {}; mod.modResults.NSAppTransportSecurity = { ...existing, NSExceptionDomains: { ...existingDomains, [host]: { NSExceptionAllowsInsecureHTTPLoads: true, NSIncludesSubdomains: true, }, }, }; return mod; }); } module.exports = withIosInsecureHttp;