1*01430c5eSTomasz Sapetaimport { Podspec } from '../../../CocoaPods'; 2941f41afSTomasz Sapetaimport { FileTransforms } from '../../../Transforms.types'; 3*01430c5eSTomasz Sapetaimport { VersioningModuleConfig } from '../types'; 4941f41afSTomasz Sapeta 50e34784dSTomasz Sapetaconst objcFilesPattern = '*.{h,m,mm,cpp}'; 6941f41afSTomasz Sapetaconst swiftFilesPattern = '*.swift'; 7941f41afSTomasz Sapeta 8*01430c5eSTomasz Sapetaexport function getCommonExpoModulesTransforms(prefix: string): FileTransforms { 9941f41afSTomasz Sapeta return { 10941f41afSTomasz Sapeta path: [ 11941f41afSTomasz Sapeta // Here we prefix names of Objective-C/C++ files. 12941f41afSTomasz Sapeta // There is no need to do the same for Swift files 13941f41afSTomasz Sapeta // as we don't change the symbols inside. In Swift we don't use `EX` nor `UM` 14941f41afSTomasz Sapeta // for symbols as the framework name takes part of the symbol signature, 15941f41afSTomasz Sapeta // so there is no way we'll get duplicate symbols compilation errors. 16941f41afSTomasz Sapeta // Files starting with `Expo` needs to be prefixed though, 17941f41afSTomasz Sapeta // for umbrella headers (e.g. `ExpoModulesCore.h`). 18941f41afSTomasz Sapeta { 192239438eSTomasz Sapeta find: /\b(Expo|EX|UM|EAS)([^/]*\.)(h|m|mm|cpp)\b/, 20941f41afSTomasz Sapeta replaceWith: `${prefix}$1$2$3`, 21941f41afSTomasz Sapeta }, 22370fa39dSKudo Chien { 23370fa39dSKudo Chien // versioning category files, e.g. RCTComponentData+Privates.h 24370fa39dSKudo Chien find: /\b(RCT)([^/]*)\+([^/]*\.)(h|m|mm|cpp)\b/, 25370fa39dSKudo Chien replaceWith: `${prefix}$1$2+$3$4`, 26370fa39dSKudo Chien }, 279caeeb0dSWojciech Kozyra { 286297d8c7SWojciech Kozyra // expo-gl 299caeeb0dSWojciech Kozyra find: /\bEXWebGL([^/]*)\.def\b/, 309caeeb0dSWojciech Kozyra replaceWith: `${prefix}EXWebGL$1.def`, 319caeeb0dSWojciech Kozyra }, 32941f41afSTomasz Sapeta ], 33941f41afSTomasz Sapeta content: [ 34941f41afSTomasz Sapeta { 35cdae24b7STomasz Sapeta find: /\bReact(?!Common)/g, 36941f41afSTomasz Sapeta replaceWith: `${prefix}React`, 37941f41afSTomasz Sapeta }, 38941f41afSTomasz Sapeta { 39941f41afSTomasz Sapeta // Prefix symbols and imports. 400e34784dSTomasz Sapeta find: /\b(EX|UM|RCT|ExpoBridgeModule)/g, 41941f41afSTomasz Sapeta replaceWith: `${prefix}$1`, 42941f41afSTomasz Sapeta }, 43941f41afSTomasz Sapeta 44941f41afSTomasz Sapeta // Only Swift 45941f41afSTomasz Sapeta 46941f41afSTomasz Sapeta { 47941f41afSTomasz Sapeta paths: swiftFilesPattern, 482239438eSTomasz Sapeta find: /\bimport (Expo|EX|EAS)(\w+)/g, 49941f41afSTomasz Sapeta replaceWith: `import ${prefix}$1$2`, 50941f41afSTomasz Sapeta }, 51941f41afSTomasz Sapeta { 52941f41afSTomasz Sapeta paths: swiftFilesPattern, 530e34784dSTomasz Sapeta find: /@objc\((Expo|EX|EAS)/g, 540e34784dSTomasz Sapeta replaceWith: `@objc(${prefix}$1`, 55941f41afSTomasz Sapeta }, 56370fa39dSKudo Chien { 57370fa39dSKudo Chien paths: swiftFilesPattern, 58c01d02daSTomasz Sapeta find: /(for)?[rR](eactTag)/gi, 59c01d02daSTomasz Sapeta replaceWith: (_, p1, p2) => `${p1 ?? ''}${p1 ? prefix : prefix.toLowerCase()}R${p2}`, 60370fa39dSKudo Chien }, 6106b29f12STomasz Sapeta { 6206b29f12STomasz Sapeta // Prefixes name of the Expo modules provider. 6306b29f12STomasz Sapeta paths: swiftFilesPattern, 6406b29f12STomasz Sapeta find: /"(ExpoModulesProvider)"/g, 6506b29f12STomasz Sapeta replaceWith: `"${prefix}$1"`, 6606b29f12STomasz Sapeta }, 67941f41afSTomasz Sapeta 68941f41afSTomasz Sapeta // Only Objective-C 69941f41afSTomasz Sapeta 70941f41afSTomasz Sapeta { 71941f41afSTomasz Sapeta // Prefix `Expo*` frameworks in imports. 72941f41afSTomasz Sapeta paths: objcFilesPattern, 73453643feSKudo Chien find: /#(import |include |if __has_include\()<(Expo|EAS)(.*?)\//g, 746185d13dSKudo Chien replaceWith: `#$1<${prefix}$2$3/`, 75941f41afSTomasz Sapeta }, 76941f41afSTomasz Sapeta { 77941f41afSTomasz Sapeta paths: objcFilesPattern, 78453643feSKudo Chien find: /#(import |include |if __has_include\()<(.*?)\/(Expo|EAS)(.*?)\.h>/g, 79453643feSKudo Chien replaceWith: `#$1<$2/${prefix}$3$4.h>`, 80941f41afSTomasz Sapeta }, 81941f41afSTomasz Sapeta { 82941f41afSTomasz Sapeta // Rename Swift compatibility headers from frameworks starting with `Expo`. 83941f41afSTomasz Sapeta paths: objcFilesPattern, 842239438eSTomasz Sapeta find: /#import "(Expo|EAS)(.+?)-Swift\.h"/g, 852239438eSTomasz Sapeta replaceWith: `#import "${prefix}$1$2-Swift.h"`, 86941f41afSTomasz Sapeta }, 87941f41afSTomasz Sapeta { 882239438eSTomasz Sapeta paths: objcFilesPattern, 892239438eSTomasz Sapeta find: /@import (Expo|EX|EAS)(\w+)/g, 902239438eSTomasz Sapeta replaceWith: `@import ${prefix}$1$2`, 912239438eSTomasz Sapeta }, 922239438eSTomasz Sapeta { 93cdae24b7STomasz Sapeta // Prefixes imports from other React Native libs 94cdae24b7STomasz Sapeta paths: objcFilesPattern, 950e34784dSTomasz Sapeta find: new RegExp(`#(import|include) <(ReactCommon|jsi)/(${prefix})?`, 'g'), 960e34784dSTomasz Sapeta replaceWith: `#$1 <${prefix}$2/${prefix}`, 97cdae24b7STomasz Sapeta }, 98cdae24b7STomasz Sapeta { 99cdae24b7STomasz Sapeta // Prefixes versionable namespaces 100cdae24b7STomasz Sapeta paths: objcFilesPattern, 101cdae24b7STomasz Sapeta find: /\bnamespace (expo|facebook)\b/g, 102cdae24b7STomasz Sapeta replaceWith: `namespace ${prefix}$1`, 103cdae24b7STomasz Sapeta }, 104cdae24b7STomasz Sapeta { 105cdae24b7STomasz Sapeta // Prefixes usages of versionable namespaces 106cdae24b7STomasz Sapeta paths: objcFilesPattern, 107cdae24b7STomasz Sapeta find: /\b(expo|facebook)::/g, 108cdae24b7STomasz Sapeta replaceWith: `${prefix}$1::`, 109cdae24b7STomasz Sapeta }, 110cdae24b7STomasz Sapeta 111cdae24b7STomasz Sapeta // Prefixes versionable namespaces (react namespace is already prefixed with uppercased "R") 112cdae24b7STomasz Sapeta { 113cdae24b7STomasz Sapeta paths: objcFilesPattern, 114370fa39dSKudo Chien find: /\busing namespace react;/g, 115370fa39dSKudo Chien replaceWith: `using namespace ${prefix}React;`, 116cdae24b7STomasz Sapeta }, 117cdae24b7STomasz Sapeta { 118cdae24b7STomasz Sapeta paths: objcFilesPattern, 119370fa39dSKudo Chien find: /::react(::|;)/g, 120370fa39dSKudo Chien replaceWith: `::${prefix}React$1`, 121370fa39dSKudo Chien }, 122370fa39dSKudo Chien { 123370fa39dSKudo Chien paths: objcFilesPattern, 124370fa39dSKudo Chien find: /\bnamespace react(\s+[^=])/g, 125370fa39dSKudo Chien replaceWith: `namespace ${prefix}React$1`, 126cdae24b7STomasz Sapeta }, 1279caeeb0dSWojciech Kozyra { 1286185d13dSKudo Chien paths: objcFilesPattern, 1296185d13dSKudo Chien find: /\b((include|import|__has_include).*\/)(JSCRuntime\.h)/g, 1306185d13dSKudo Chien replaceWith: `$1${prefix}$3`, 1316185d13dSKudo Chien }, 1326185d13dSKudo Chien { 1339caeeb0dSWojciech Kozyra paths: 'EXGLImageUtils.cpp', 1349caeeb0dSWojciech Kozyra find: '#define STB_IMAGE_IMPLEMENTATION', 1359caeeb0dSWojciech Kozyra replaceWith: '', 1369caeeb0dSWojciech Kozyra }, 137cdae24b7STomasz Sapeta 138cdae24b7STomasz Sapeta // Prefix umbrella header imports 139cdae24b7STomasz Sapeta { 140cdae24b7STomasz Sapeta paths: '*.h', 141370fa39dSKudo Chien // Use negative look ahead regexp for `prefix` to prevent duplicated versioning 142453643feSKudo Chien find: new RegExp(`[\b/](!?${prefix})(\w+-umbrella\.h)\b`, 'g'), 143cdae24b7STomasz Sapeta replaceWith: `${prefix}$1`, 144a272999eSBartosz Kaszubowski }, 1459318cb9fSTomasz Sapeta 1469318cb9fSTomasz Sapeta { 1479318cb9fSTomasz Sapeta // Dynamically remove the prefix from the "moduleName" method in the view manager adapter. 1489318cb9fSTomasz Sapeta paths: 'EXViewManagerAdapter.{m,mm}', 1499318cb9fSTomasz Sapeta find: /return (NSStringFromClass\(self\));/g, 1509318cb9fSTomasz Sapeta replaceWith: `NSString *className = $1;\n return [className hasPrefix:@"${prefix}"] ? [className substringFromIndex:${prefix.length}] : className;`, 1519318cb9fSTomasz Sapeta }, 152941f41afSTomasz Sapeta ], 153941f41afSTomasz Sapeta }; 154941f41afSTomasz Sapeta} 155*01430c5eSTomasz Sapeta 156*01430c5eSTomasz Sapetaexport function getVersioningExpoModuleConfig( 157*01430c5eSTomasz Sapeta prefix: string, 158*01430c5eSTomasz Sapeta moduleName: string 159*01430c5eSTomasz Sapeta): VersioningModuleConfig { 160*01430c5eSTomasz Sapeta const config: Record<string, VersioningModuleConfig> = { 161*01430c5eSTomasz Sapeta 'expo-constants': { 162*01430c5eSTomasz Sapeta mutatePodspec: removeScriptPhasesAndResourceBundles, 163*01430c5eSTomasz Sapeta }, 164*01430c5eSTomasz Sapeta 'expo-updates': { 165*01430c5eSTomasz Sapeta mutatePodspec: removeScriptPhasesAndResourceBundles, 166*01430c5eSTomasz Sapeta }, 167*01430c5eSTomasz Sapeta 'expo-screen-orientation': { 168*01430c5eSTomasz Sapeta // Versioned expo-screen-orientation shouldn't include its own registry, it should use the unversioned one instead. 169*01430c5eSTomasz Sapeta transforms: { 170*01430c5eSTomasz Sapeta path: [], 171*01430c5eSTomasz Sapeta content: [ 172*01430c5eSTomasz Sapeta { 173*01430c5eSTomasz Sapeta paths: 'ScreenOrientationRegistry.swift', 174*01430c5eSTomasz Sapeta find: /(.|\n)*/, 175*01430c5eSTomasz Sapeta replaceWith: [ 176*01430c5eSTomasz Sapeta '// The original implementations of `ScreenOrientationRegistry` and `ScreenOrientationController`', 177*01430c5eSTomasz Sapeta '// were removed from this file as part of the versioning process to always use their "unversioned" version.', 178*01430c5eSTomasz Sapeta 'import ExpoScreenOrientation', 179*01430c5eSTomasz Sapeta '', 180*01430c5eSTomasz Sapeta 'typealias ScreenOrientationRegistry = ExpoScreenOrientation.ScreenOrientationRegistry', 181*01430c5eSTomasz Sapeta 'typealias ScreenOrientationController = ExpoScreenOrientation.ScreenOrientationController', 182*01430c5eSTomasz Sapeta '', 183*01430c5eSTomasz Sapeta ].join('\n'), 184*01430c5eSTomasz Sapeta }, 185*01430c5eSTomasz Sapeta ], 186*01430c5eSTomasz Sapeta }, 187*01430c5eSTomasz Sapeta mutatePodspec(podspec: Podspec) { 188*01430c5eSTomasz Sapeta // Versioned screen orientation must depend on unversioned copy to use unversioned singleton object. 189*01430c5eSTomasz Sapeta addDependency(podspec, podspec.name.replace(prefix, '')); 190*01430c5eSTomasz Sapeta }, 191*01430c5eSTomasz Sapeta }, 192*01430c5eSTomasz Sapeta }; 193*01430c5eSTomasz Sapeta return config[moduleName] ?? {}; 194*01430c5eSTomasz Sapeta} 195*01430c5eSTomasz Sapeta 196*01430c5eSTomasz Sapetafunction removeScriptPhasesAndResourceBundles(podspec: Podspec): void { 197*01430c5eSTomasz Sapeta // For expo-updates and expo-constants in Expo Go, we don't need app.config and app.manifest in versioned code. 198*01430c5eSTomasz Sapeta delete podspec['script_phases']; 199*01430c5eSTomasz Sapeta delete podspec['resource_bundles']; 200*01430c5eSTomasz Sapeta} 201*01430c5eSTomasz Sapeta 202*01430c5eSTomasz Sapetafunction addDependency(podspec: Podspec, dependencyName: string) { 203*01430c5eSTomasz Sapeta if (!podspec.dependencies) { 204*01430c5eSTomasz Sapeta podspec.dependencies = {}; 205*01430c5eSTomasz Sapeta } 206*01430c5eSTomasz Sapeta podspec.dependencies[dependencyName] = []; 207*01430c5eSTomasz Sapeta} 208