1import chalk from 'chalk';
2
3import { TransformPipeline } from '.';
4
5export function postTransforms(versionName: string): TransformPipeline {
6  return {
7    logHeader(filePath: string) {
8      console.log(`Post-transforming ${chalk.magenta(filePath)}:`);
9    },
10    transforms: [
11      // react-native
12      {
13        paths: ['RCTRedBox.m', 'RCTLog.mm'],
14        replace: /#if (ABI\d+_\d+_\d+)RCT_DEBUG/g,
15        with: '#if $1RCT_DEV',
16      },
17      {
18        paths: ['NSTextStorage+FontScaling.h', 'NSTextStorage+FontScaling.m'],
19        replace: /NSTextStorage \(FontScaling\)/,
20        with: `NSTextStorage (${versionName}FontScaling)`,
21      },
22      {
23        paths: [
24          'NSTextStorage+FontScaling.h',
25          'NSTextStorage+FontScaling.m',
26          'RCTTextShadowView.m',
27        ],
28        replace: /\b(scaleFontSizeToFitSize|scaleFontSizeWithRatio|compareToSize)\b/g,
29        with: `${versionName.toLowerCase()}_rct_$1`,
30      },
31      {
32        paths: 'RCTWebView.m',
33        replace: /@"ABI\d+_\d+_\d+React-js-navigation"/,
34        with: '@"react-js-navigation"',
35      },
36      {
37        replace: new RegExp(`FB${versionName}ReactNativeSpec`, 'g'),
38        with: 'FBReactNativeSpec',
39      },
40      {
41        replace: new RegExp('\\b(Native\\w+Spec)\\b', 'g'),
42        with: `${versionName}$1`,
43      },
44      {
45        paths: 'RCTInspectorPackagerConnection.m',
46        replace: /\b(RECONNECT_DELAY_MS)\b/g,
47        with: `${versionName}$1`,
48      },
49      {
50        paths: `${versionName}FBReactNativeSpec`,
51        replace: /\b(NSStringToNativeAppearanceColorSchemeName|NativeAppearanceColorSchemeNameToNSString)\b/g,
52        with: `${versionName}$1`,
53      },
54      {
55        paths: 'RCTView.m',
56        replace: /\b(SwitchAccessibilityTrait)\b/g,
57        with: `${versionName}$1`,
58      },
59      {
60        paths: 'RCTSpringAnimation.m',
61        replace: /\b(MAX_DELTA_TIME)\b/g,
62        with: `${versionName}$1`,
63      },
64      {
65        paths: 'ModuleRegistry.cpp',
66        replace: /(std::string normalizeName\(std::string name\) \{)/,
67        with: `$1\n  if (name.compare(0, ${versionName.length}, "${versionName}") == 0) {\n    name = name.substr(${versionName.length});\n  }\n`,
68      },
69      {
70        paths: 'ModuleRegistry.cpp',
71        replace: /(\(name\.compare\(\d+, \d+, ")([^"]+)(RCT"\))/,
72        with: '$1$3',
73      },
74
75      // Universal modules
76      {
77        paths: `UniversalModules/${versionName}EXScoped`,
78        replace: /(EXScopedABI\d+_\d+_\d+ReactNative)/g,
79        with: 'EXScopedReactNative',
80      },
81      {
82        paths: `${versionName}EXFileSystem`,
83        replace: new RegExp(`NSData\\+${versionName}EXFileSystem\\.h`, 'g'),
84        with: `${versionName}NSData+EXFileSystem.h`,
85      },
86      {
87        paths: [`${versionName}EXNotifications`, `${versionName}EXUpdates`],
88        replace: new RegExp(
89          `NSDictionary\\+${versionName}(EXNotificationsVerifyingClass|EXUpdatesRawManifest)\\.h`,
90          'g'
91        ),
92        with: `${versionName}NSDictionary+$1.h`,
93      },
94      {
95        paths: [`${versionName}EXNotifications`, `${versionName}EXAppState`],
96        replace: new RegExp(`EXModuleRegistryHolder${versionName}React`, 'g'),
97        with: 'EXModuleRegistryHolderReact',
98      },
99      {
100        // Versioned ExpoKit has to use versioned modules provider
101        paths: 'EXVersionManager.mm',
102        replace: /@"(ExpoModulesProvider)"/,
103        with: `@"${versionName}$1"`,
104      },
105
106      // react-native-maps
107      {
108        paths: 'AIRMapWMSTile',
109        replace: /\b(TileOverlay)\b/g,
110        with: `${versionName}$1`,
111      },
112      {
113        paths: 'AIRGoogleMapWMSTile',
114        replace: /\b(WMSTileOverlay)\b/g,
115        with: `${versionName}$1`,
116      },
117
118      // react-native-svg
119      {
120        paths: 'RNSVGRenderable.m',
121        replace: /\b(saturate)\(/g,
122        with: `${versionName}$1(`,
123      },
124      {
125        paths: 'RNSVGPainter.m',
126        replace: /\b(PatternFunction)\b/g,
127        with: `${versionName}$1`,
128      },
129      {
130        paths: 'RNSVGFontData.m',
131        replace: /\b(AbsoluteFontWeight|bolder|lighter|nearestFontWeight)\(/gi,
132        with: `${versionName}$1(`,
133      },
134      {
135        paths: 'RNSVGTSpan.m',
136        replace: new RegExp(`\\b(${versionName}RNSVGTopAlignedLabel\\s*\\*\\s*label)\\b`, 'gi'),
137        with: 'static $1',
138      },
139      {
140        paths: 'RNSVGMarker.m',
141        replace: /\b(deg2rad)\b/g,
142        with: `${versionName}$1`,
143      },
144      {
145        paths: 'RNSVGMarkerPosition.m',
146        replace: /\b(PathIsDone|rad2deg|SlopeAngleRadians|CurrentAngle|subtract|ExtractPathElementFeatures|UpdateFromPathElement)\b/g,
147        with: `${versionName}$1`,
148      },
149      {
150        paths: 'RNSVGMarkerPosition.m',
151        replace: /\b(positions_|element_index_|origin_|subpath_start_|in_slope_|out_slope_|auto_start_reverse_)\b/g,
152        with: `${versionName}$1`,
153      },
154      {
155        paths: 'RNSVGPathMeasure.m',
156        replace: /\b(distance|subdivideBezierAtT)\b/g,
157        with: `${versionName}$1`,
158      },
159
160      // react-native-webview
161      {
162        paths: 'RNCWebView.m',
163        replace: new RegExp(`#import "objc/${versionName}runtime\\.h"`, ''),
164        with: '#import "objc/runtime.h"',
165      },
166      {
167        paths: 'RNCWebView.m',
168        replace: /\b(_SwizzleHelperWK)\b/g,
169        with: `${versionName}$1`,
170      },
171      {
172        // see issue: https://github.com/expo/expo/issues/4463
173        paths: 'RNCWebView.m',
174        replace: /MessageHandlerName = @"ABI\d+_\d+_\d+ReactNativeWebView";/,
175        with: `MessageHandlerName = @"ReactNativeWebView";`,
176      },
177
178      // react-native-reanimated
179      {
180        paths: 'EXVersionManager.mm',
181        replace: /(_bridge_reanimated)/g,
182        with: `${versionName}$1`,
183      },
184      {
185        paths: 'NativeProxy.mm',
186        replace: /@"ABI\d+_\d+_\d+RCTView"/g,
187        with: `@"RCTView"`,
188      },
189
190      // react-native-shared-element
191      {
192        paths: 'RNSharedElementNode.m',
193        replace: /\b(NSArray\s*\*\s*_imageResolvers)\b/,
194        with: 'static $1',
195      },
196
197      // react-native-safe-area-context
198      {
199        paths: [
200          'RCTView+SafeAreaCompat.h',
201          'RCTView+SafeAreaCompat.m',
202          'RNCSafeAreaProvider.m',
203          'RNCSafeAreaView.m',
204        ],
205        replace: /\b(UIEdgeInsetsEqualToEdgeInsetsWithThreshold)\b/g,
206        with: `${versionName}$1`,
207      },
208    ],
209  };
210}
211