UNPKG

react-native-acoustic-connect-beta

Version:

BETA: React native plugin for Acoustic Connect

160 lines 8.56 kB
"use strict"; // Copyright (C) 2026 Acoustic, L.P. All rights reserved. // // NOTICE: This file contains material that is confidential and proprietary to // Acoustic, L.P. and/or other developers. No license is granted under any // intellectual or industrial property rights of Acoustic, L.P. except as may // be provided in an agreement with Acoustic, L.P. Any unauthorized copying or // distribution of content from this file is prohibited. var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.withConnectAndroidGoogleServicesMatch = exports.withConnectAndroidConfig = exports.appendConfigGradleApply = exports.CONFIG_GRADLE_APPLY = void 0; const config_plugins_1 = require("@expo/config-plugins"); const fs = __importStar(require("fs")); const path = __importStar(require("path")); // The Gradle snippet that runs the SDK's config.gradle. config.gradle reads // the consumer app's ConnectConfig.json (`$project.rootDir/../ConnectConfig.json`) // and writes AppKey / PostMessageUrl / KillSwitchUrl (and the Tealeaf + EOCore // configs) into the SDK module's `src/main/assets/*` at Gradle configuration // time — so the collector the app reports to is driven by ConnectConfig.json. // // This mirrors the line `scripts/gradleParser.js` appends for the bare-workflow // sample (Examples/bare-workflow/android/app/build.gradle). The Expo Android // project is gitignored and regenerated by `expo prebuild`, so the line cannot // be committed there — this mod re-injects it on every prebuild instead. // // The ':react-native-acoustic-connect-beta' Gradle project is provided by // React Native autolinking and resolves in the Expo app the same way it does // in bare-workflow. exports.CONFIG_GRADLE_APPLY = `apply from: project(':react-native-acoustic-connect-beta')` + `.projectDir.getPath() + "/config.gradle"`; /** * Append the config.gradle `apply from:` line to an app `build.gradle` body. * * Idempotent: a no-op when the line is already present, so repeated prebuilds * (and a prebuild over an already-patched, non-`--clean` project) don't stack * duplicate applies. */ function appendConfigGradleApply(contents) { if (contents.includes('/config.gradle')) { return contents; } return `${contents}\n\n${exports.CONFIG_GRADLE_APPLY}\n`; } exports.appendConfigGradleApply = appendConfigGradleApply; /** * Expo config mod: wire the SDK's config.gradle into the generated Android * app build so ConnectConfig.json values reach the native assets at build * time. Without it, the Android SDK ships its committed default collector * config and the app reports to the wrong endpoint (iOS is unaffected — it * uses AcousticConnectRNConfig.json via a separate flow). */ const withConnectAndroidConfig = (config) => (0, config_plugins_1.withAppBuildGradle)(config, (cfg) => { // The RN/Expo template app build.gradle is Groovy. If a future template // switches to the Kotlin DSL the append heuristic no longer applies — // warn and skip rather than corrupt the file. if (cfg.modResults.language !== 'groovy') { console.warn(`[react-native-acoustic-connect-beta] Skipping Android config ` + `propagation: app/build.gradle is '${cfg.modResults.language}', ` + `expected 'groovy'. Add the following line manually:\n` + ` ${exports.CONFIG_GRADLE_APPLY}`); return cfg; } cfg.modResults.contents = appendConfigGradleApply(cfg.modResults.contents); return cfg; }); exports.withConnectAndroidConfig = withConnectAndroidConfig; /** True when ConnectConfig.json at `projectRoot` has Connect.PushEnabled === true. */ function isPushEnabled(projectRoot) { var _a; const configPath = path.join(projectRoot, 'ConnectConfig.json'); if (!fs.existsSync(configPath)) return false; try { const parsed = JSON.parse(fs.readFileSync(configPath, 'utf8')); return ((_a = parsed.Connect) === null || _a === void 0 ? void 0 : _a.PushEnabled) === true; } catch { return false; } } /** * Fail fast at prebuild when push is enabled but `android.package` is absent * from the configured `google-services.json`. FCM matches its client by package * name, so a mismatch makes Gradle fail much later at * `:app:processDebugGoogleServices` with the opaque "No matching client found * for package name …" — and only after a full prebuild + Gradle config. Surface * it here, at the moment the native project is (re)generated, with the exact fix * (CA-144135 §10b). `acoustic-connect doctor` performs the same check up front; * this is the guard for a developer who runs `expo run:android` directly. * * Only the genuine MISMATCH throws. A missing package / googleServicesFile is * left to `doctor` and the build itself (this mod doesn't duplicate those). */ const withConnectAndroidGoogleServicesMatch = (config) => (0, config_plugins_1.withDangerousMod)(config, [ 'android', async (cfg) => { var _a, _b, _c, _d, _e; const projectRoot = (_a = cfg._internal) === null || _a === void 0 ? void 0 : _a.projectRoot; if (!projectRoot || !isPushEnabled(projectRoot)) return cfg; const androidPackage = (_b = cfg.android) === null || _b === void 0 ? void 0 : _b.package; if (!androidPackage) return cfg; // Most Expo + FCM consumers omit android.googleServicesFile and rely on // the default ./google-services.json at the project root. Mirror that // default (and `acoustic-connect doctor`'s) so the match check isn't // silently skipped for the common case. const gsFile = (_d = (_c = cfg.android) === null || _c === void 0 ? void 0 : _c.googleServicesFile) !== null && _d !== void 0 ? _d : 'google-services.json'; const gsPath = path.isAbsolute(gsFile) ? gsFile : path.join(projectRoot, gsFile); if (!fs.existsSync(gsPath)) return cfg; // missing file is doctor's / the build's concern let parsed; try { parsed = JSON.parse(fs.readFileSync(gsPath, 'utf8')); } catch { return cfg; // malformed google-services.json — doctor/build will report it } const packages = ((_e = parsed.client) !== null && _e !== void 0 ? _e : []) .map((c) => { var _a, _b; return (_b = (_a = c.client_info) === null || _a === void 0 ? void 0 : _a.android_client_info) === null || _b === void 0 ? void 0 : _b.package_name; }) .filter((p) => typeof p === 'string'); if (packages.length > 0 && !packages.includes(androidPackage)) { throw new Error(`[react-native-acoustic-connect-beta] android.package "${androidPackage}" ` + `has no matching client in ${gsFile} (it has: ${packages.join(', ')}).\n\n` + `FCM matches its client by package name, so the Android build would ` + `fail at :app:processDebugGoogleServices. Register "${androidPackage}" in ` + `the same Firebase project and re-download google-services.json, or set ` + `app.json android.package to one of the registered packages.\n` + `Note: changing android.package requires a clean prebuild — ` + `\`npx expo prebuild --platform android --clean\`.`); } return cfg; }, ]); exports.withConnectAndroidGoogleServicesMatch = withConnectAndroidGoogleServicesMatch; //# sourceMappingURL=withConnectAndroidConfig.js.map