1import { FileTransforms } from '../../../Transforms.types';
2
3const objcFilesPattern = '*.{h,m,mm,cpp}';
4const swiftFilesPattern = '*.swift';
5
6export function expoModulesTransforms(prefix: string): FileTransforms {
7  return {
8    path: [
9      // Here we prefix names of Objective-C/C++ files.
10      // There is no need to do the same for Swift files
11      // as we don't change the symbols inside. In Swift we don't use `EX` nor `UM`
12      // for symbols as the framework name takes part of the symbol signature,
13      // so there is no way we'll get duplicate symbols compilation errors.
14      // Files starting with `Expo` needs to be prefixed though,
15      // for umbrella headers (e.g. `ExpoModulesCore.h`).
16      {
17        find: /\b(Expo|EX|UM|EAS)([^/]*\.)(h|m|mm|cpp)\b/,
18        replaceWith: `${prefix}$1$2$3`,
19      },
20      {
21        // versioning category files, e.g. RCTComponentData+Privates.h
22        find: /\b(RCT)([^/]*)\+([^/]*\.)(h|m|mm|cpp)\b/,
23        replaceWith: `${prefix}$1$2+$3$4`,
24      },
25    ],
26    content: [
27      {
28        find: /\bReact(?!Common)/g,
29        replaceWith: `${prefix}React`,
30      },
31      {
32        // Prefix symbols and imports.
33        find: /\b(EX|UM|RCT|ExpoBridgeModule)/g,
34        replaceWith: `${prefix}$1`,
35      },
36
37      // Only Swift
38
39      {
40        paths: swiftFilesPattern,
41        find: /\bimport (Expo|EX|EAS)(\w+)/g,
42        replaceWith: `import ${prefix}$1$2`,
43      },
44      {
45        paths: swiftFilesPattern,
46        find: /@objc\((Expo|EX|EAS)/g,
47        replaceWith: `@objc(${prefix}$1`,
48      },
49      {
50        paths: swiftFilesPattern,
51        find: /r(eactTag)/gi,
52        replaceWith: (_, p1) => `${prefix.toLowerCase()}R${p1}`,
53      },
54      {
55        // Prefixes name of the Expo modules provider.
56        paths: swiftFilesPattern,
57        find: /"(ExpoModulesProvider)"/g,
58        replaceWith: `"${prefix}$1"`,
59      },
60
61      // Only Objective-C
62
63      {
64        // Prefix `Expo*` frameworks in imports.
65        paths: objcFilesPattern,
66        find: /#import <(Expo|EAS)(.*?)\//g,
67        replaceWith: `#import <${prefix}$1$2/`,
68      },
69      {
70        paths: objcFilesPattern,
71        find: /#import <(.*?)\/(Expo|EAS)(.*?)\.h>/g,
72        replaceWith: `#import <$1/${prefix}$2$3.h>`,
73      },
74      {
75        // Rename Swift compatibility headers from frameworks starting with `Expo`.
76        paths: objcFilesPattern,
77        find: /#import "(Expo|EAS)(.+?)-Swift\.h"/g,
78        replaceWith: `#import "${prefix}$1$2-Swift.h"`,
79      },
80      {
81        // Unprefix imports to unversionable (e.g. expo-gl-cpp) modules.
82        paths: [objcFilesPattern, 'EXGL'],
83        find: new RegExp(`#import <${prefix}(EXGL_CPP)\\b`),
84        replaceWith: '#import <$1',
85      },
86      {
87        paths: objcFilesPattern,
88        find: /@import (Expo|EX|EAS)(\w+)/g,
89        replaceWith: `@import ${prefix}$1$2`,
90      },
91      {
92        // Prefixes imports from other React Native libs
93        paths: objcFilesPattern,
94        find: new RegExp(`#(import|include) <(ReactCommon|jsi)/(${prefix})?`, 'g'),
95        replaceWith: `#$1 <${prefix}$2/${prefix}`,
96      },
97      {
98        // Prefixes versionable namespaces
99        paths: objcFilesPattern,
100        find: /\bnamespace (expo|facebook)\b/g,
101        replaceWith: `namespace ${prefix}$1`,
102      },
103      {
104        // Prefixes usages of versionable namespaces
105        paths: objcFilesPattern,
106        find: /\b(expo|facebook)::/g,
107        replaceWith: `${prefix}$1::`,
108      },
109
110      // Prefixes versionable namespaces (react namespace is already prefixed with uppercased "R")
111      {
112        paths: objcFilesPattern,
113        find: /\busing namespace react;/g,
114        replaceWith: `using namespace ${prefix}React;`,
115      },
116      {
117        paths: objcFilesPattern,
118        find: /::react(::|;)/g,
119        replaceWith: `::${prefix}React$1`,
120      },
121      {
122        paths: objcFilesPattern,
123        find: /\bnamespace react(\s+[^=])/g,
124        replaceWith: `namespace ${prefix}React$1`,
125      },
126
127      // Prefix umbrella header imports
128      {
129        paths: '*.h',
130        // Use negative look ahead regexp for `prefix` to prevent duplicated versioning
131        find: new RegExp(`\b(!?${prefix})(\w+-umbrella\.h)\b`, 'g'),
132        replaceWith: `${prefix}$1`,
133      },
134
135      {
136        // Dynamically remove the prefix from the "moduleName" method in the view manager adapter.
137        paths: 'EXViewManagerAdapter.{m,mm}',
138        find: /return (NSStringFromClass\(self\));/g,
139        replaceWith: `NSString *className = $1;\n  return [className hasPrefix:@"${prefix}"] ? [className substringFromIndex:${prefix.length}] : className;`,
140      },
141    ],
142  };
143}
144