1import chalk from 'chalk';
2
3import { TransformPipeline } from '.';
4
5export function injectMacros(versionName: string): TransformPipeline {
6  return {
7    logHeader(filePath: string) {
8      console.log(`Injecting macros at ${chalk.magenta(filePath)}:`);
9    },
10    transforms: [
11      {
12        // add a macro ABIXX_0_0EX_REMOVE_VERSION(str) to RCTDefines
13        paths: 'RCTDefines.h',
14        replace: /(.|\s)$/,
15        with: `$1\n#define ${versionName}EX_REMOVE_VERSION(string) (([string hasPrefix:@"${versionName}"]) ? [string stringByReplacingCharactersInRange:(NSRange){0,@"${versionName}".length} withString:@""] : string)\n`,
16      },
17      {
18        // use the macro on the return value of `RCTBridgeModuleNameForClass`
19        // to pass unversioned native module names to JS
20        paths: 'RCTBridge.m',
21        replace: /(return ABI\d+_\d+_\d+RCTDropABI\d+_\d+_\d+ReactPrefixes)\(name\)/g,
22        with: `$1(${versionName}EX_REMOVE_VERSION(name))`,
23      },
24      {
25        // use the macro on the return value of `moduleNameForClass`
26        // to pass unversioned native module names to JS
27        paths: 'RCTComponentData.m',
28        replace: /(if \(\[name hasPrefix:@"RK"\]\) \{\n)/g,
29        with: `name = ${versionName}EX_REMOVE_VERSION(name);\n  $1`,
30      },
31      {
32        // injects macro into `enqueueJSCall:method:args:completion:` method of RCTCxxBridge
33        paths: 'RCTCxxBridge.mm',
34        replace: /callJSFunction(\s*?\(\s*?)\[module UTF8String\],/,
35        with: `callJSFunction$1[${versionName}EX_REMOVE_VERSION(module) UTF8String],`,
36      },
37      {
38        // now that this code is versioned, remove meaningless EX_UNVERSIONED declaration
39        paths: ['EXUnversioned.h', 'EXServerRegistrationModule.m'],
40        replace: /(#define symbol[.\S\s]+?(?=\n\n)\n\n)/g,
41        with: '\n',
42      },
43    ],
44  };
45}
46