1import { FileTransforms } from '../../../Transforms.types';
2
3const objcFilesPattern = '*.{h,m,mm}';
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)/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      // Only Objective-C
56
57      {
58        // Prefix `Expo*` frameworks in imports.
59        paths: objcFilesPattern,
60        find: /#import <(Expo|EAS)(.*?)\//g,
61        replaceWith: `#import <${prefix}$1$2/`,
62      },
63      {
64        paths: objcFilesPattern,
65        find: /#import <(.*?)\/(Expo|EAS)(.*?)\.h>/g,
66        replaceWith: `#import <$1/${prefix}$2$3.h>`,
67      },
68      {
69        // Rename Swift compatibility headers from frameworks starting with `Expo`.
70        paths: objcFilesPattern,
71        find: /#import "(Expo|EAS)(.+?)-Swift\.h"/g,
72        replaceWith: `#import "${prefix}$1$2-Swift.h"`,
73      },
74      {
75        // Unprefix imports to unversionable (e.g. expo-gl-cpp) modules.
76        paths: [objcFilesPattern, 'EXGL'],
77        find: new RegExp(`#import <${prefix}(EXGL_CPP)\\b`),
78        replaceWith: '#import <$1',
79      },
80      {
81        paths: objcFilesPattern,
82        find: /@import (Expo|EX|EAS)(\w+)/g,
83        replaceWith: `@import ${prefix}$1$2`,
84      },
85      {
86        // Prefixes Objective-C name of the Swift modules provider.
87        paths: ['EXNativeModulesProxy.mm'],
88        find: 'NSClassFromString(@"ExpoModulesProvider")',
89        replaceWith: `NSClassFromString(@"${prefix}ExpoModulesProvider")`,
90      },
91      {
92        // Prefixes Objective-C name of the Swift modules provider.
93        paths: ['EXNativeModulesProxy.mm'],
94        find: '[NSString stringWithFormat:@"%@.ExpoModulesProvider"',
95        replaceWith: `[NSString stringWithFormat:@"%@.${prefix}ExpoModulesProvider"`,
96      },
97      {
98        // Prefixes imports from other React Native libs
99        paths: objcFilesPattern,
100        find: new RegExp(`#import <(ReactCommon|jsi)/(${prefix})?`, 'g'),
101        replaceWith: `#import <${prefix}$1/${prefix}`,
102      },
103      {
104        // Prefixes versionable namespaces
105        paths: objcFilesPattern,
106        find: /\bnamespace (expo|facebook)\b/g,
107        replaceWith: `namespace ${prefix}$1`,
108      },
109      {
110        // Prefixes usages of versionable namespaces
111        paths: objcFilesPattern,
112        find: /\b(expo|facebook)::/g,
113        replaceWith: `${prefix}$1::`,
114      },
115
116      // Prefixes versionable namespaces (react namespace is already prefixed with uppercased "R")
117      {
118        paths: objcFilesPattern,
119        find: /\busing namespace react;/g,
120        replaceWith: `using namespace ${prefix}React;`,
121      },
122      {
123        paths: objcFilesPattern,
124        find: /::react(::|;)/g,
125        replaceWith: `::${prefix}React$1`,
126      },
127      {
128        paths: objcFilesPattern,
129        find: /\bnamespace react(\s+[^=])/g,
130        replaceWith: `namespace ${prefix}React$1`,
131      },
132
133      // Prefix umbrella header imports
134      {
135        paths: '*.h',
136        // Use negative look ahead regexp for `prefix` to prevent duplicated versioning
137        find: new RegExp(`\b(!?${prefix})(\w+-umbrella\.h)\b`, 'g'),
138        replaceWith: `${prefix}$1`,
139      },
140    ],
141  };
142}
143