UNPKG

@embrace-io/react-native

Version:
201 lines (199 loc) 9.74 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.addEmbraceInitializerSwift = exports.addUploadBuildPhase = exports.patchXcodeBundlePhase = exports.iosPodfileKSCrashPatch = exports.iOSPodfilePatch = exports.iosInitializeEmbrace = exports.patchPodFileWithKSCrash = exports.getIOSProjectName = exports.patchPodfile = exports.tryToPatchAppDelegate = void 0; const ios_1 = require("../util/ios"); const EmbraceLogger_1 = require("../../src/utils/EmbraceLogger"); const patch_1 = require("./patches/patch"); const common_1 = require("./common"); const path = require("path"); const fs = require("fs"); const semverGte = require("semver/functions/gte"); const LOGGER = new EmbraceLogger_1.default(console); const tryToPatchAppDelegate = (iOSProjectName) => __awaiter(void 0, void 0, void 0, function* () { const project = yield (0, ios_1.xcodePatchable)(iOSProjectName); const bridgingHeader = project.getBridgingHeaderName(iOSProjectName); const response = (0, patch_1.default)("objectivec", iOSProjectName, { bridgingHeader }); if (response) { return project.addBridgingHeader(iOSProjectName); } return (0, patch_1.default)("swift", iOSProjectName) || false; }); exports.tryToPatchAppDelegate = tryToPatchAppDelegate; /** * Getting iOS project name either from user's input ('CustomBeautifulApp') or from package.json ({ name: 'custom.beautiful.app' }) */ const getIOSProjectName = (wizard) => __awaiter(void 0, void 0, void 0, function* () { const [customProjectName, pJSON] = yield wizard.fieldValueList([ common_1.iosProjectFolderName, common_1.packageJSON, ]); return customProjectName && customProjectName !== "" ? customProjectName // if the user decided to customize the project's name when creating the app using the RN cli : pJSON.name; // fallback to what package.json contains as name }); exports.getIOSProjectName = getIOSProjectName; const iosInitializeEmbrace = { name: "iOS initialize Embrace", run: (wizard) => __awaiter(void 0, void 0, void 0, function* () { const name = yield getIOSProjectName(wizard); return tryToPatchAppDelegate(name); }), docURL: "https://embrace.io/docs/react-native/integration/add-embrace-sdk/?platform=ios#manually", }; exports.iosInitializeEmbrace = iosInitializeEmbrace; const patchPodFileWithKSCrash = () => __awaiter(void 0, void 0, void 0, function* () { return (0, ios_1.podfilePatchable)().then(podfile => { if (podfile.hasLine(ios_1.EMBR_KSCRASH_MODULAR_HEADER_POD)) { LOGGER.warn("Already has 'KSCrash' pod with modular headers enabled"); return; } podfile.addBefore("linkage = ENV['USE_FRAMEWORKS']", `${ios_1.EMBR_KSCRASH_MODULAR_HEADER_POD}\n`); return podfile.patch(); }); }); exports.patchPodFileWithKSCrash = patchPodFileWithKSCrash; const patchPodfile = (json) => { const rnVersion = (json.dependencies || {})["react-native"]; if (!rnVersion) { throw Error("react-native dependency was not found"); } const rnVersionSanitized = rnVersion.replace("^", ""); // If 6.0.0, autolink should have linked the Pod. if (semverGte("6.0.0", rnVersionSanitized)) { LOGGER.log("Skipping patching Podfile since react-native is on an autolink supported version"); return; } return (0, ios_1.podfilePatchable)().then(podfile => { if (podfile.hasLine(ios_1.EMBR_NATIVE_POD)) { LOGGER.warn("Already has 'EmbraceIO' pod"); return; } podfile.addBefore("use_react_native", `${ios_1.EMBR_NATIVE_POD}\n`); return podfile.patch(); }); }; exports.patchPodfile = patchPodfile; const iOSPodfilePatch = { name: "Podfile patch (Only React Native v < 0.6)", run: (wizard) => __awaiter(void 0, void 0, void 0, function* () { return wizard.fieldValue(common_1.packageJSON).then(patchPodfile); }), docURL: "https://embrace.io/docs/react-native/integration/add-embrace-sdk/?platform=ios#native-modules", }; exports.iOSPodfilePatch = iOSPodfilePatch; const iosPodfileKSCrashPatch = { name: "KSCrash enabling modular headers", run: (_wizard) => __awaiter(void 0, void 0, void 0, function* () { return patchPodFileWithKSCrash(); }), docURL: "https://embrace.io/docs/react-native/integration/add-embrace-sdk/?platform=ios#native-modules", }; exports.iosPodfileKSCrashPatch = iosPodfileKSCrashPatch; const patchXcodeBundlePhase = { name: "Update bundle phase", run: (wizard) => __awaiter(void 0, void 0, void 0, function* () { return getIOSProjectName(wizard) .then(ios_1.xcodePatchable) .then(project => { const bundlePhaseKey = project.findPhase(ios_1.BUNDLE_PHASE_REGEXP); if (!bundlePhaseKey) { LOGGER.error("Could not find Xcode React Native bundle phase"); return; } if (project.hasLine(bundlePhaseKey, ios_1.EXPORT_SOURCEMAP_RN_VAR)) { LOGGER.warn("Already patched Xcode React Native bundle phase"); return; } LOGGER.log("Patching Xcode React Native bundle phase"); project.modifyPhase(bundlePhaseKey, ios_1.BUNDLE_PHASE_REGEXP, `${ios_1.MKDIR_SOURCEMAP_DIR}\n${ios_1.EXPORT_SOURCEMAP_RN_VAR}\n`); return project.patch(); }); }), docURL: "https://embrace.io/docs/react-native/integration/upload-symbol-files/#uploading-source-maps", }; exports.patchXcodeBundlePhase = patchXcodeBundlePhase; const addUploadBuildPhase = { name: `Add '${ios_1.UPLOAD_SYMBOLS_PHASE}' phase`, run: (wizard) => getIOSProjectName(wizard).then((name) => __awaiter(void 0, void 0, void 0, function* () { return (0, ios_1.xcodePatchable)(name).then(project => { const uploadBuildPhaseKey = project.findPhase(ios_1.EMBR_RUN_SCRIPT); if (uploadBuildPhaseKey) { LOGGER.warn(`Already added '${ios_1.UPLOAD_SYMBOLS_PHASE}' phase`); return; } return wizard.fieldValueList([common_1.iosAppID, common_1.apiToken]).then(list => { const [appId, token] = list; const proj = project.project; proj.addBuildPhase([], "PBXShellScriptBuildPhase", ios_1.UPLOAD_SYMBOLS_PHASE, null, { shellPath: "/bin/sh", shellScript: `REACT_NATIVE_MAP_PATH="$CONFIGURATION_BUILD_DIR/embrace-assets/main.jsbundle.map" EMBRACE_ID=${appId} EMBRACE_TOKEN=${token} ${ios_1.EMBR_RUN_SCRIPT}`, }); return project.patch(); }); }); })), docURL: "https://embrace.io/docs/react-native/integration/upload-symbol-files/#uploading-native-and-javascript-symbol-files", }; exports.addUploadBuildPhase = addUploadBuildPhase; const addEmbraceInitializerSwift = { name: "Adding EmbraceInitializer.swift", run: (wizard) => __awaiter(void 0, void 0, void 0, function* () { const appId = yield wizard.fieldValue(common_1.iosAppID); const name = yield getIOSProjectName(wizard); const project = yield (0, ios_1.xcodePatchable)(name); const filePath = path.join("ios", name, "EmbraceInitializer.swift"); try { const fd = fs.openSync(filePath, "wx"); fs.writeFileSync(fd, getEmbraceInitializerContents(appId)); } catch (e) { if (e instanceof Error && e.message.includes("EEXIST")) { LOGGER.warn("EmbraceInitializer.swift already exists"); return; } else if (e instanceof Error && e.message.includes("ENOENT")) { throw `${e}. ${ios_1.ENOENT_XCODE_PROJ_ERROR_MESSAGE}`; } else { throw e; } } const nameWithCaseSensitive = (0, ios_1.findNameWithCaseSensitiveFromPath)(project.path, name); project.addFile(nameWithCaseSensitive, `${nameWithCaseSensitive}/EmbraceInitializer.swift`, "source"); return project.patch(); }), docURL: "https://embrace.io/docs/react-native/integration/add-embrace-sdk/#manually", }; exports.addEmbraceInitializerSwift = addEmbraceInitializerSwift; const getEmbraceInitializerContents = (appId) => { return `import Foundation import EmbraceIO @objcMembers class EmbraceInitializer: NSObject { // Start the EmbraceSDK with the minimum required settings, for more advanced configuration options see: // https://embrace.io/docs/ios/open-source/integration/embrace-options/ static func start() -> Void { do { try Embrace .setup( options: Embrace.Options( appId: "${appId}", platform: .reactNative ) ) .start() } catch let e { print("Error starting Embrace \\(e.localizedDescription)") } } } `; };