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        // expo-gl
27        find: /\bEXWebGL([^/]*)\.def\b/,
28        replaceWith: `${prefix}EXWebGL$1.def`,
29      },
30    ],
31    content: [
32      {
33        find: /\bReact(?!Common)/g,
34        replaceWith: `${prefix}React`,
35      },
36      {
37        // Prefix symbols and imports.
38        find: /\b(EX|UM|RCT|ExpoBridgeModule)/g,
39        replaceWith: `${prefix}$1`,
40      },
41
42      // Only Swift
43
44      {
45        paths: swiftFilesPattern,
46        find: /\bimport (Expo|EX|EAS)(\w+)/g,
47        replaceWith: `import ${prefix}$1$2`,
48      },
49      {
50        paths: swiftFilesPattern,
51        find: /@objc\((Expo|EX|EAS)/g,
52        replaceWith: `@objc(${prefix}$1`,
53      },
54      {
55        paths: swiftFilesPattern,
56        find: /(for)?[rR](eactTag)/gi,
57        replaceWith: (_, p1, p2) => `${p1 ?? ''}${p1 ? prefix : prefix.toLowerCase()}R${p2}`,
58      },
59      {
60        // Prefixes name of the Expo modules provider.
61        paths: swiftFilesPattern,
62        find: /"(ExpoModulesProvider)"/g,
63        replaceWith: `"${prefix}$1"`,
64      },
65
66      // Only Objective-C
67
68      {
69        // Prefix `Expo*` frameworks in imports.
70        paths: objcFilesPattern,
71        find: /#(import|include) <(Expo|EAS)(.*?)\//g,
72        replaceWith: `#$1 <${prefix}$2$3/`,
73      },
74      {
75        paths: objcFilesPattern,
76        find: /#import <(.*?)\/(Expo|EAS)(.*?)\.h>/g,
77        replaceWith: `#import <$1/${prefix}$2$3.h>`,
78      },
79      {
80        // Rename Swift compatibility headers from frameworks starting with `Expo`.
81        paths: objcFilesPattern,
82        find: /#import "(Expo|EAS)(.+?)-Swift\.h"/g,
83        replaceWith: `#import "${prefix}$1$2-Swift.h"`,
84      },
85      {
86        paths: objcFilesPattern,
87        find: /@import (Expo|EX|EAS)(\w+)/g,
88        replaceWith: `@import ${prefix}$1$2`,
89      },
90      {
91        // Prefixes imports from other React Native libs
92        paths: objcFilesPattern,
93        find: new RegExp(`#(import|include) <(ReactCommon|jsi)/(${prefix})?`, 'g'),
94        replaceWith: `#$1 <${prefix}$2/${prefix}`,
95      },
96      {
97        // Prefixes versionable namespaces
98        paths: objcFilesPattern,
99        find: /\bnamespace (expo|facebook)\b/g,
100        replaceWith: `namespace ${prefix}$1`,
101      },
102      {
103        // Prefixes usages of versionable namespaces
104        paths: objcFilesPattern,
105        find: /\b(expo|facebook)::/g,
106        replaceWith: `${prefix}$1::`,
107      },
108
109      // Prefixes versionable namespaces (react namespace is already prefixed with uppercased "R")
110      {
111        paths: objcFilesPattern,
112        find: /\busing namespace react;/g,
113        replaceWith: `using namespace ${prefix}React;`,
114      },
115      {
116        paths: objcFilesPattern,
117        find: /::react(::|;)/g,
118        replaceWith: `::${prefix}React$1`,
119      },
120      {
121        paths: objcFilesPattern,
122        find: /\bnamespace react(\s+[^=])/g,
123        replaceWith: `namespace ${prefix}React$1`,
124      },
125      {
126        paths: objcFilesPattern,
127        find: /\b((include|import|__has_include).*\/)(JSCRuntime\.h)/g,
128        replaceWith: `$1${prefix}$3`,
129      },
130      {
131        paths: 'EXGLImageUtils.cpp',
132        find: '#define STB_IMAGE_IMPLEMENTATION',
133        replaceWith: '',
134      },
135
136      // Prefix umbrella header imports
137      {
138        paths: '*.h',
139        // Use negative look ahead regexp for `prefix` to prevent duplicated versioning
140        find: new RegExp(`\b(!?${prefix})(\w+-umbrella\.h)\b`, 'g'),
141        replaceWith: `${prefix}$1`,
142      },
143
144      {
145        // Dynamically remove the prefix from the "moduleName" method in the view manager adapter.
146        paths: 'EXViewManagerAdapter.{m,mm}',
147        find: /return (NSStringFromClass\(self\));/g,
148        replaceWith: `NSString *className = $1;\n  return [className hasPrefix:@"${prefix}"] ? [className substringFromIndex:${prefix.length}] : className;`,
149      },
150    ],
151  };
152}
153