expo-modules-autolinking 0.5.0 → 0.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/build/ExpoModuleConfig.d.ts +4 -0
- package/build/ExpoModuleConfig.js +7 -0
- package/build/ExpoModuleConfig.js.map +1 -1
- package/build/ReactImportsPatcher.d.ts +14 -0
- package/build/ReactImportsPatcher.js +89 -0
- package/build/ReactImportsPatcher.js.map +1 -0
- package/build/index.js +10 -0
- package/build/index.js.map +1 -1
- package/build/platforms/ios.js +12 -4
- package/build/platforms/ios.js.map +1 -1
- package/build/types.d.ts +8 -0
- package/build/types.js.map +1 -1
- package/package.json +2 -2
- package/scripts/ios/react_import_patcher.rb +66 -0
- package/src/ExpoModuleConfig.ts +7 -0
- package/src/ReactImportsPatcher.ts +101 -0
- package/src/index.ts +12 -0
- package/src/platforms/ios.ts +14 -5
- package/src/types.ts +10 -0
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,28 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 0.5.4 — 2021-12-29
|
|
14
|
+
|
|
15
|
+
### 🐛 Bug fixes
|
|
16
|
+
|
|
17
|
+
- Add `expo_patch_react_imports!` support for React-Native 0.66. ([#15724](https://github.com/expo/expo/pull/15724) by [@kudo](https://github.com/kudo))
|
|
18
|
+
|
|
19
|
+
## 0.5.3 — 2021-12-28
|
|
20
|
+
|
|
21
|
+
### 🐛 Bug fixes
|
|
22
|
+
|
|
23
|
+
- Fix `expo_patch_react_imports!` error when there are pods with absolute path. ([#15699](https://github.com/expo/expo/pull/15699) by [@kudo](https://github.com/kudo))
|
|
24
|
+
|
|
25
|
+
## 0.5.2 — 2021-12-22
|
|
26
|
+
|
|
27
|
+
### 🐛 Bug fixes
|
|
28
|
+
|
|
29
|
+
- Introduce `expo_patch_react_imports!` to transform double-quoted React imports into angle-brackets in order to fix third-party libraries incompatibility with SDK 44. ([#15655](https://github.com/expo/expo/pull/15655) by [@kudo](https://github.com/kudo))
|
|
30
|
+
|
|
31
|
+
## 0.5.1 — 2021-12-15
|
|
32
|
+
|
|
33
|
+
_This version does not introduce any user-facing changes._
|
|
34
|
+
|
|
13
35
|
## 0.5.0 — 2021-12-03
|
|
14
36
|
|
|
15
37
|
### 🎉 New features
|
|
@@ -21,6 +21,10 @@ export declare class ExpoModuleConfig {
|
|
|
21
21
|
* Returns a list of names of Swift classes that implement `ExpoReactDelegateHandler`.
|
|
22
22
|
*/
|
|
23
23
|
iosReactDelegateHandlers(): string[];
|
|
24
|
+
/**
|
|
25
|
+
* Returns a podspec path defined by the module author.
|
|
26
|
+
*/
|
|
27
|
+
iosPodspecPath(): string | undefined;
|
|
24
28
|
/**
|
|
25
29
|
* Returns a list of names of Kotlin native modules classes to put to the generated package provider file.
|
|
26
30
|
*/
|
|
@@ -36,6 +36,13 @@ class ExpoModuleConfig {
|
|
|
36
36
|
var _a, _b;
|
|
37
37
|
return (_b = (_a = this.rawConfig.ios) === null || _a === void 0 ? void 0 : _a.reactDelegateHandlers) !== null && _b !== void 0 ? _b : [];
|
|
38
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Returns a podspec path defined by the module author.
|
|
41
|
+
*/
|
|
42
|
+
iosPodspecPath() {
|
|
43
|
+
var _a;
|
|
44
|
+
return (_a = this.rawConfig.ios) === null || _a === void 0 ? void 0 : _a.podspecPath;
|
|
45
|
+
}
|
|
39
46
|
/**
|
|
40
47
|
* Returns a list of names of Kotlin native modules classes to put to the generated package provider file.
|
|
41
48
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoModuleConfig.js","sourceRoot":"","sources":["../src/ExpoModuleConfig.ts"],"names":[],"mappings":";;;AAEA;;GAEG;AACH,MAAa,gBAAgB;IAC3B,YAAqB,SAA8B;QAA9B,cAAS,GAAT,SAAS,CAAqB;IAAG,CAAC;IAEvD;;OAEG;IACH,gBAAgB,CAAC,QAA2B;;QAC1C,OAAO,MAAA,MAAA,IAAI,CAAC,SAAS,CAAC,SAAS,0CAAE,QAAQ,CAAC,QAAQ,CAAC,mCAAI,KAAK,CAAC;IAC/D,CAAC;IAED;;OAEG;IACH,oBAAoB;;QAClB,OAAO,MAAA,MAAA,IAAI,CAAC,SAAS,CAAC,GAAG,0CAAE,iBAAiB,mCAAI,EAAE,CAAC;IACrD,CAAC;IAED;;OAEG;IACH,yBAAyB;;QACvB,OAAO,MAAA,MAAA,IAAI,CAAC,SAAS,CAAC,GAAG,0CAAE,sBAAsB,mCAAI,EAAE,CAAC;IAC1D,CAAC;IAED;;OAEG;IACH,wBAAwB;;QACtB,OAAO,MAAA,MAAA,IAAI,CAAC,SAAS,CAAC,GAAG,0CAAE,qBAAqB,mCAAI,EAAE,CAAC;IACzD,CAAC;IAED;;OAEG;IACH,wBAAwB;;QACtB,OAAO,MAAA,MAAA,IAAI,CAAC,SAAS,CAAC,OAAO,0CAAE,iBAAiB,mCAAI,EAAE,CAAC;IACzD,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;CACF;
|
|
1
|
+
{"version":3,"file":"ExpoModuleConfig.js","sourceRoot":"","sources":["../src/ExpoModuleConfig.ts"],"names":[],"mappings":";;;AAEA;;GAEG;AACH,MAAa,gBAAgB;IAC3B,YAAqB,SAA8B;QAA9B,cAAS,GAAT,SAAS,CAAqB;IAAG,CAAC;IAEvD;;OAEG;IACH,gBAAgB,CAAC,QAA2B;;QAC1C,OAAO,MAAA,MAAA,IAAI,CAAC,SAAS,CAAC,SAAS,0CAAE,QAAQ,CAAC,QAAQ,CAAC,mCAAI,KAAK,CAAC;IAC/D,CAAC;IAED;;OAEG;IACH,oBAAoB;;QAClB,OAAO,MAAA,MAAA,IAAI,CAAC,SAAS,CAAC,GAAG,0CAAE,iBAAiB,mCAAI,EAAE,CAAC;IACrD,CAAC;IAED;;OAEG;IACH,yBAAyB;;QACvB,OAAO,MAAA,MAAA,IAAI,CAAC,SAAS,CAAC,GAAG,0CAAE,sBAAsB,mCAAI,EAAE,CAAC;IAC1D,CAAC;IAED;;OAEG;IACH,wBAAwB;;QACtB,OAAO,MAAA,MAAA,IAAI,CAAC,SAAS,CAAC,GAAG,0CAAE,qBAAqB,mCAAI,EAAE,CAAC;IACzD,CAAC;IAED;;OAEG;IACH,cAAc;;QACZ,OAAO,MAAA,IAAI,CAAC,SAAS,CAAC,GAAG,0CAAE,WAAW,CAAC;IACzC,CAAC;IAED;;OAEG;IACH,wBAAwB;;QACtB,OAAO,MAAA,MAAA,IAAI,CAAC,SAAS,CAAC,OAAO,0CAAE,iBAAiB,mCAAI,EAAE,CAAC;IACzD,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;CACF;AAnDD,4CAmDC;AAED;;GAEG;AACH,SAAgB,iCAAiC,CAAC,IAAY;IAC5D,kDAAkD;IAClD,4DAA4D;IAC5D,OAAO,IAAI,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAwB,CAAC,CAAC;AACpE,CAAC;AAJD,8EAIC","sourcesContent":["import { RawExpoModuleConfig, SupportedPlatform } from './types';\n\n/**\n * A class that wraps the raw config (`expo-module.json` or `unimodule.json`).\n */\nexport class ExpoModuleConfig {\n constructor(readonly rawConfig: RawExpoModuleConfig) {}\n\n /**\n * Whether the module supports given platform.\n */\n supportsPlatform(platform: SupportedPlatform): boolean {\n return this.rawConfig.platforms?.includes(platform) ?? false;\n }\n\n /**\n * Returns a list of names of Swift native modules classes to put to the generated modules provider file.\n */\n iosModulesClassNames() {\n return this.rawConfig.ios?.modulesClassNames ?? [];\n }\n\n /**\n * Returns a list of names of Swift classes that receives AppDelegate life-cycle events.\n */\n iosAppDelegateSubscribers(): string[] {\n return this.rawConfig.ios?.appDelegateSubscribers ?? [];\n }\n\n /**\n * Returns a list of names of Swift classes that implement `ExpoReactDelegateHandler`.\n */\n iosReactDelegateHandlers(): string[] {\n return this.rawConfig.ios?.reactDelegateHandlers ?? [];\n }\n\n /**\n * Returns a podspec path defined by the module author.\n */\n iosPodspecPath(): string | undefined {\n return this.rawConfig.ios?.podspecPath;\n }\n\n /**\n * Returns a list of names of Kotlin native modules classes to put to the generated package provider file.\n */\n androidModulesClassNames() {\n return this.rawConfig.android?.modulesClassNames ?? [];\n }\n\n /**\n * Returns serializable raw config.\n */\n toJSON(): RawExpoModuleConfig {\n return this.rawConfig;\n }\n}\n\n/**\n * Reads the config at given path and returns the config wrapped by `ExpoModuleConfig` class.\n */\nexport function requireAndResolveExpoModuleConfig(path: string): ExpoModuleConfig {\n // TODO: Validate the raw config against a schema.\n // TODO: Support for `*.js` files, not only static `*.json`.\n return new ExpoModuleConfig(require(path) as RawExpoModuleConfig);\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { PatchReactImportsOptions } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Remove all double-quoted react header imports
|
|
4
|
+
* @param dirs target directories to patch
|
|
5
|
+
* @param options PatchReactImportsOptions
|
|
6
|
+
*/
|
|
7
|
+
export declare function patchReactImportsAsync(dirs: string[], options: PatchReactImportsOptions): Promise<void>;
|
|
8
|
+
/**
|
|
9
|
+
* Patch imports from a file
|
|
10
|
+
* @param headerSet prebuilt React-Core header set
|
|
11
|
+
* @param file target patch file
|
|
12
|
+
* @param dryRun true if not writing changes to file
|
|
13
|
+
*/
|
|
14
|
+
export declare function patchFileAsync(headerSet: Set<string>, file: string, dryRun: boolean): Promise<void>;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2018-present 650 Industries. All rights reserved.
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.patchFileAsync = exports.patchReactImportsAsync = void 0;
|
|
8
|
+
const fast_glob_1 = __importDefault(require("fast-glob"));
|
|
9
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
/**
|
|
12
|
+
* Remove all double-quoted react header imports
|
|
13
|
+
* @param dirs target directories to patch
|
|
14
|
+
* @param options PatchReactImportsOptions
|
|
15
|
+
*/
|
|
16
|
+
async function patchReactImportsAsync(dirs, options) {
|
|
17
|
+
const headerSet = await generateReactHeaderSetAsync(path_1.default.join(options.podsRoot, 'Headers', 'Public', 'React-Core', 'React'));
|
|
18
|
+
await Promise.all(dirs.map((dir) => patchDirAsync(headerSet, dir, options.dryRun)));
|
|
19
|
+
}
|
|
20
|
+
exports.patchReactImportsAsync = patchReactImportsAsync;
|
|
21
|
+
/**
|
|
22
|
+
* Generate `React-Core` public header names as a set, will transform necessary headers based on this set.
|
|
23
|
+
*/
|
|
24
|
+
async function generateReactHeaderSetAsync(reactHeaderDir) {
|
|
25
|
+
const files = await (0, fast_glob_1.default)('*.h', { cwd: reactHeaderDir });
|
|
26
|
+
return new Set(files);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Patch imports from a file
|
|
30
|
+
* @param headerSet prebuilt React-Core header set
|
|
31
|
+
* @param file target patch file
|
|
32
|
+
* @param dryRun true if not writing changes to file
|
|
33
|
+
*/
|
|
34
|
+
async function patchFileAsync(headerSet, file, dryRun) {
|
|
35
|
+
let changed = false;
|
|
36
|
+
const content = await fs_extra_1.default.readFile(file, 'utf-8');
|
|
37
|
+
let transformContent = content.replace(/^#import\s+"(.+)"$/gm, (match, headerName) => {
|
|
38
|
+
// `#import "RCTBridge.h"` -> `#import <React/RCTBridge.h>`
|
|
39
|
+
if (headerSet.has(headerName)) {
|
|
40
|
+
changed = true;
|
|
41
|
+
return `#import <React/${headerName}>`;
|
|
42
|
+
}
|
|
43
|
+
// `#import "React/RCTBridge.h"` -> `#import <React/RCTBridge.h>`
|
|
44
|
+
if (headerName.startsWith('React/')) {
|
|
45
|
+
const name = headerName.substring(6);
|
|
46
|
+
if (headerSet.has(name)) {
|
|
47
|
+
changed = true;
|
|
48
|
+
return `#import <React/${name}>`;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// Otherwise, return original import
|
|
52
|
+
return match;
|
|
53
|
+
});
|
|
54
|
+
transformContent = transformContent.replace(/^#(if|elif)\s+__has_include\("(.+)"\)$/gm, (match, ifPrefix, headerName) => {
|
|
55
|
+
// `#if __has_include("RCTBridge.h")` -> `#if __has_include(<React/RCTBridge.h>)`
|
|
56
|
+
if (headerSet.has(headerName)) {
|
|
57
|
+
changed = true;
|
|
58
|
+
return `#${ifPrefix} __has_include(<React/${headerName}>)`;
|
|
59
|
+
}
|
|
60
|
+
// `#if __has_include("React/RCTBridge.h")` -> `#if __has_include(<React/RCTBridge.h>)`
|
|
61
|
+
if (headerName.startsWith('React/')) {
|
|
62
|
+
const name = headerName.substring(6);
|
|
63
|
+
if (headerSet.has(name)) {
|
|
64
|
+
changed = true;
|
|
65
|
+
return `#${ifPrefix} __has_include(<React/${name}>)`;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// Otherwise, return original import
|
|
69
|
+
return match;
|
|
70
|
+
});
|
|
71
|
+
if (changed) {
|
|
72
|
+
console.log(`Patching imports for file: ${file}`);
|
|
73
|
+
}
|
|
74
|
+
if (!dryRun) {
|
|
75
|
+
await fs_extra_1.default.writeFile(file, transformContent);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
exports.patchFileAsync = patchFileAsync;
|
|
79
|
+
/**
|
|
80
|
+
* Patch imports from a directory
|
|
81
|
+
* @param headerSet prebuilt React-Core header set
|
|
82
|
+
* @param file target patch file
|
|
83
|
+
* @param dryRun true if not writing changes to file
|
|
84
|
+
*/
|
|
85
|
+
async function patchDirAsync(headerSet, dir, dryRun) {
|
|
86
|
+
const files = await (0, fast_glob_1.default)('**/*.{h,m,mm}', { cwd: dir, absolute: true });
|
|
87
|
+
return Promise.all(files.map((file) => patchFileAsync(headerSet, file, dryRun)));
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=ReactImportsPatcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReactImportsPatcher.js","sourceRoot":"","sources":["../src/ReactImportsPatcher.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2018-present 650 Industries. All rights reserved.\n\nimport glob from 'fast-glob';\nimport fs from 'fs-extra';\nimport path from 'path';\n\nimport { PatchReactImportsOptions } from './types';\n\n/**\n * Remove all double-quoted react header imports\n * @param dirs target directories to patch\n * @param options PatchReactImportsOptions\n */\nexport async function patchReactImportsAsync(dirs: string[], options: PatchReactImportsOptions) {\n const headerSet = await generateReactHeaderSetAsync(\n path.join(options.podsRoot, 'Headers', 'Public', 'React-Core', 'React')\n );\n await Promise.all(dirs.map((dir) => patchDirAsync(headerSet, dir, options.dryRun)));\n}\n\n/**\n * Generate `React-Core` public header names as a set, will transform necessary headers based on this set.\n */\nasync function generateReactHeaderSetAsync(reactHeaderDir: string): Promise<Set<string>> {\n const files = await glob('*.h', { cwd: reactHeaderDir });\n return new Set(files);\n}\n\n/**\n * Patch imports from a file\n * @param headerSet prebuilt React-Core header set\n * @param file target patch file\n * @param dryRun true if not writing changes to file\n */\nexport async function patchFileAsync(headerSet: Set<string>, file: string, dryRun: boolean) {\n let changed = false;\n const content = await fs.readFile(file, 'utf-8');\n let transformContent = content.replace(\n /^#import\\s+\"(.+)\"$/gm,\n (match: string, headerName: string): string => {\n // `#import \"RCTBridge.h\"` -> `#import <React/RCTBridge.h>`\n if (headerSet.has(headerName)) {\n changed = true;\n return `#import <React/${headerName}>`;\n }\n\n // `#import \"React/RCTBridge.h\"` -> `#import <React/RCTBridge.h>`\n if (headerName.startsWith('React/')) {\n const name = headerName.substring(6);\n if (headerSet.has(name)) {\n changed = true;\n return `#import <React/${name}>`;\n }\n }\n\n // Otherwise, return original import\n return match;\n }\n );\n\n transformContent = transformContent.replace(\n /^#(if|elif)\\s+__has_include\\(\"(.+)\"\\)$/gm,\n (match: string, ifPrefix: string, headerName: string): string => {\n // `#if __has_include(\"RCTBridge.h\")` -> `#if __has_include(<React/RCTBridge.h>)`\n if (headerSet.has(headerName)) {\n changed = true;\n return `#${ifPrefix} __has_include(<React/${headerName}>)`;\n }\n\n // `#if __has_include(\"React/RCTBridge.h\")` -> `#if __has_include(<React/RCTBridge.h>)`\n if (headerName.startsWith('React/')) {\n const name = headerName.substring(6);\n if (headerSet.has(name)) {\n changed = true;\n return `#${ifPrefix} __has_include(<React/${name}>)`;\n }\n }\n\n // Otherwise, return original import\n return match;\n }\n );\n\n if (changed) {\n console.log(`Patching imports for file: ${file}`);\n }\n if (!dryRun) {\n await fs.writeFile(file, transformContent);\n }\n}\n\n/**\n * Patch imports from a directory\n * @param headerSet prebuilt React-Core header set\n * @param file target patch file\n * @param dryRun true if not writing changes to file\n */\nasync function patchDirAsync(headerSet: Set<string>, dir: string, dryRun: boolean) {\n const files = await glob('**/*.{h,m,mm}', { cwd: dir, absolute: true });\n return Promise.all(files.map((file) => patchFileAsync(headerSet, file, dryRun)));\n}\n"]}
|
package/build/index.js
CHANGED
|
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const commander_1 = __importDefault(require("commander"));
|
|
7
|
+
const ReactImportsPatcher_1 = require("./ReactImportsPatcher");
|
|
7
8
|
const autolinking_1 = require("./autolinking");
|
|
8
9
|
/**
|
|
9
10
|
* Registers a command that only searches for available expo modules.
|
|
@@ -30,6 +31,14 @@ function registerSearchCommand(commandName, fn) {
|
|
|
30
31
|
function registerResolveCommand(commandName, fn) {
|
|
31
32
|
return registerSearchCommand(commandName, fn);
|
|
32
33
|
}
|
|
34
|
+
// Register for `patch-react-imports` command
|
|
35
|
+
function registerPatchReactImportsCommand() {
|
|
36
|
+
return commander_1.default
|
|
37
|
+
.command('patch-react-imports [paths...]')
|
|
38
|
+
.requiredOption('--pods-root <podsRoot>', 'The path to `Pods` directory')
|
|
39
|
+
.option('--dry-run', 'Only list files without writing changes to the file system')
|
|
40
|
+
.action(ReactImportsPatcher_1.patchReactImportsAsync);
|
|
41
|
+
}
|
|
33
42
|
module.exports = async function (args) {
|
|
34
43
|
// Searches for available expo modules.
|
|
35
44
|
registerSearchCommand('search', async (results, options) => {
|
|
@@ -65,6 +74,7 @@ module.exports = async function (args) {
|
|
|
65
74
|
.option('-t, --target <path>', 'Path to the target file, where the package list should be written to.')
|
|
66
75
|
.option('-n, --namespace <namespace>', 'Java package name under which the package list should be placed.')
|
|
67
76
|
.option('--empty', 'Whether to only generate an empty list. Might be used when the user opts-out of autolinking.', false);
|
|
77
|
+
registerPatchReactImportsCommand();
|
|
68
78
|
await commander_1.default
|
|
69
79
|
.version(require('expo-modules-autolinking/package.json').version)
|
|
70
80
|
.description('CLI command that searches for Expo modules to autolink them.')
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import commander from 'commander';\n\nimport {\n findModulesAsync,\n resolveModulesAsync,\n verifySearchResults,\n generatePackageListAsync,\n mergeLinkingOptionsAsync,\n} from './autolinking';\nimport { GenerateOptions, ResolveOptions, SearchOptions, SearchResults } from './types';\n\n/**\n * Registers a command that only searches for available expo modules.\n */\nfunction registerSearchCommand<OptionsType extends SearchOptions>(\n commandName: string,\n fn: (search: SearchResults, options: OptionsType) => any\n) {\n return commander\n .command(`${commandName} [paths...]`)\n .option<string[] | null>(\n '-i, --ignore-paths <ignorePaths...>',\n 'Paths to ignore when looking up for modules.',\n (value, previous) => (previous ?? []).concat(value)\n )\n .option<string[] | null>(\n '-e, --exclude <exclude...>',\n 'Package names to exclude when looking up for modules.',\n (value, previous) => (previous ?? []).concat(value)\n )\n .option(\n '-p, --platform [platform]',\n 'The platform that the resulting modules must support. Available options: \"ios\", \"android\"',\n 'ios'\n )\n .option('--silent', 'Silence resolution warnings')\n .action(async (searchPaths, providedOptions) => {\n const options = await mergeLinkingOptionsAsync<OptionsType>({\n ...providedOptions,\n searchPaths,\n });\n const searchResults = await findModulesAsync(options);\n return await fn(searchResults, options);\n });\n}\n\n/**\n * Registers a command that searches for modules and then resolves them for specific platform.\n */\nfunction registerResolveCommand<OptionsType extends ResolveOptions>(\n commandName: string,\n fn: (search: SearchResults, options: OptionsType) => any\n) {\n return registerSearchCommand<OptionsType>(commandName, fn);\n}\n\nmodule.exports = async function (args: string[]) {\n // Searches for available expo modules.\n registerSearchCommand<SearchOptions & { json?: boolean }>('search', async (results, options) => {\n if (options.json) {\n console.log(JSON.stringify(results));\n } else {\n console.log(require('util').inspect(results, false, null, true));\n }\n }).option<boolean>('-j, --json', 'Output results in the plain JSON format.', () => true, false);\n\n // Checks whether there are no resolving issues in the current setup.\n registerSearchCommand('verify', (results) => {\n const numberOfDuplicates = verifySearchResults(results);\n if (!numberOfDuplicates) {\n console.log('✅ Everything is fine!');\n }\n });\n\n // Searches for available expo modules and resolves the results for given platform.\n registerResolveCommand('resolve', async (results, options) => {\n const modules = await resolveModulesAsync(results, options);\n\n if (options.json) {\n console.log(JSON.stringify({ modules }));\n } else {\n console.log({ modules });\n }\n }).option<boolean>('-j, --json', 'Output results in the plain JSON format.', () => true, false);\n\n // Generates a source file listing all packages to link.\n registerResolveCommand<GenerateOptions>('generate-package-list', async (results, options) => {\n const modules = options.empty ? [] : await resolveModulesAsync(results, options);\n generatePackageListAsync(modules, options);\n })\n .option(\n '-t, --target <path>',\n 'Path to the target file, where the package list should be written to.'\n )\n .option(\n '-n, --namespace <namespace>',\n 'Java package name under which the package list should be placed.'\n )\n .option(\n '--empty',\n 'Whether to only generate an empty list. Might be used when the user opts-out of autolinking.',\n false\n );\n\n await commander\n .version(require('expo-modules-autolinking/package.json').version)\n .description('CLI command that searches for Expo modules to autolink them.')\n .parseAsync(args, { from: 'user' });\n};\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import commander from 'commander';\n\nimport { patchReactImportsAsync } from './ReactImportsPatcher';\nimport {\n findModulesAsync,\n resolveModulesAsync,\n verifySearchResults,\n generatePackageListAsync,\n mergeLinkingOptionsAsync,\n} from './autolinking';\nimport { GenerateOptions, ResolveOptions, SearchOptions, SearchResults } from './types';\n\n/**\n * Registers a command that only searches for available expo modules.\n */\nfunction registerSearchCommand<OptionsType extends SearchOptions>(\n commandName: string,\n fn: (search: SearchResults, options: OptionsType) => any\n) {\n return commander\n .command(`${commandName} [paths...]`)\n .option<string[] | null>(\n '-i, --ignore-paths <ignorePaths...>',\n 'Paths to ignore when looking up for modules.',\n (value, previous) => (previous ?? []).concat(value)\n )\n .option<string[] | null>(\n '-e, --exclude <exclude...>',\n 'Package names to exclude when looking up for modules.',\n (value, previous) => (previous ?? []).concat(value)\n )\n .option(\n '-p, --platform [platform]',\n 'The platform that the resulting modules must support. Available options: \"ios\", \"android\"',\n 'ios'\n )\n .option('--silent', 'Silence resolution warnings')\n .action(async (searchPaths, providedOptions) => {\n const options = await mergeLinkingOptionsAsync<OptionsType>({\n ...providedOptions,\n searchPaths,\n });\n const searchResults = await findModulesAsync(options);\n return await fn(searchResults, options);\n });\n}\n\n/**\n * Registers a command that searches for modules and then resolves them for specific platform.\n */\nfunction registerResolveCommand<OptionsType extends ResolveOptions>(\n commandName: string,\n fn: (search: SearchResults, options: OptionsType) => any\n) {\n return registerSearchCommand<OptionsType>(commandName, fn);\n}\n\n// Register for `patch-react-imports` command\nfunction registerPatchReactImportsCommand() {\n return commander\n .command('patch-react-imports [paths...]')\n .requiredOption('--pods-root <podsRoot>', 'The path to `Pods` directory')\n .option('--dry-run', 'Only list files without writing changes to the file system')\n .action(patchReactImportsAsync);\n}\n\nmodule.exports = async function (args: string[]) {\n // Searches for available expo modules.\n registerSearchCommand<SearchOptions & { json?: boolean }>('search', async (results, options) => {\n if (options.json) {\n console.log(JSON.stringify(results));\n } else {\n console.log(require('util').inspect(results, false, null, true));\n }\n }).option<boolean>('-j, --json', 'Output results in the plain JSON format.', () => true, false);\n\n // Checks whether there are no resolving issues in the current setup.\n registerSearchCommand('verify', (results) => {\n const numberOfDuplicates = verifySearchResults(results);\n if (!numberOfDuplicates) {\n console.log('✅ Everything is fine!');\n }\n });\n\n // Searches for available expo modules and resolves the results for given platform.\n registerResolveCommand('resolve', async (results, options) => {\n const modules = await resolveModulesAsync(results, options);\n\n if (options.json) {\n console.log(JSON.stringify({ modules }));\n } else {\n console.log({ modules });\n }\n }).option<boolean>('-j, --json', 'Output results in the plain JSON format.', () => true, false);\n\n // Generates a source file listing all packages to link.\n registerResolveCommand<GenerateOptions>('generate-package-list', async (results, options) => {\n const modules = options.empty ? [] : await resolveModulesAsync(results, options);\n generatePackageListAsync(modules, options);\n })\n .option(\n '-t, --target <path>',\n 'Path to the target file, where the package list should be written to.'\n )\n .option(\n '-n, --namespace <namespace>',\n 'Java package name under which the package list should be placed.'\n )\n .option(\n '--empty',\n 'Whether to only generate an empty list. Might be used when the user opts-out of autolinking.',\n false\n );\n\n registerPatchReactImportsCommand();\n\n await commander\n .version(require('expo-modules-autolinking/package.json').version)\n .description('CLI command that searches for Expo modules to autolink them.')\n .parseAsync(args, { from: 'user' });\n};\n"]}
|
package/build/platforms/ios.js
CHANGED
|
@@ -7,15 +7,23 @@ exports.formatArrayOfReactDelegateHandler = exports.generatePackageListAsync = e
|
|
|
7
7
|
const fast_glob_1 = __importDefault(require("fast-glob"));
|
|
8
8
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
9
9
|
const path_1 = __importDefault(require("path"));
|
|
10
|
+
async function findPodspecFile(revision) {
|
|
11
|
+
var _a;
|
|
12
|
+
if ((_a = revision.config) === null || _a === void 0 ? void 0 : _a.iosPodspecPath()) {
|
|
13
|
+
return revision.config.iosPodspecPath();
|
|
14
|
+
}
|
|
15
|
+
const [podspecFile] = await (0, fast_glob_1.default)('*/*.podspec', {
|
|
16
|
+
cwd: revision.path,
|
|
17
|
+
ignore: ['**/node_modules/**'],
|
|
18
|
+
});
|
|
19
|
+
return podspecFile;
|
|
20
|
+
}
|
|
10
21
|
/**
|
|
11
22
|
* Resolves module search result with additional details required for iOS platform.
|
|
12
23
|
*/
|
|
13
24
|
async function resolveModuleAsync(packageName, revision, options) {
|
|
14
25
|
var _a, _b, _c;
|
|
15
|
-
const
|
|
16
|
-
cwd: revision.path,
|
|
17
|
-
ignore: ['**/node_modules/**'],
|
|
18
|
-
});
|
|
26
|
+
const podspecFile = await findPodspecFile(revision);
|
|
19
27
|
if (!podspecFile) {
|
|
20
28
|
return null;
|
|
21
29
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ios.js","sourceRoot":"","sources":["../../src/platforms/ios.ts"],"names":[],"mappings":";;;;;;AAAA,0DAA6B;AAC7B,wDAA0B;AAC1B,gDAAwB;AAIxB
|
|
1
|
+
{"version":3,"file":"ios.js","sourceRoot":"","sources":["../../src/platforms/ios.ts"],"names":[],"mappings":";;;;;;AAAA,0DAA6B;AAC7B,wDAA0B;AAC1B,gDAAwB;AAIxB,KAAK,UAAU,eAAe,CAAC,QAAyB;;IACtD,IAAI,MAAA,QAAQ,CAAC,MAAM,0CAAE,cAAc,EAAE,EAAE;QACrC,OAAO,QAAQ,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;KACzC;IAED,MAAM,CAAC,WAAW,CAAC,GAAG,MAAM,IAAA,mBAAI,EAAC,aAAa,EAAE;QAC9C,GAAG,EAAE,QAAQ,CAAC,IAAI;QAClB,MAAM,EAAE,CAAC,oBAAoB,CAAC;KAC/B,CAAC,CAAC;IAEH,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,kBAAkB,CACtC,WAAmB,EACnB,QAAyB,EACzB,OAAsB;;IAEtB,MAAM,WAAW,GAAG,MAAM,eAAe,CAAC,QAAQ,CAAC,CAAC;IACpD,IAAI,CAAC,WAAW,EAAE;QAChB,OAAO,IAAI,CAAC;KACb;IAED,MAAM,OAAO,GAAG,cAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,cAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;IACtE,MAAM,UAAU,GAAG,cAAI,CAAC,OAAO,CAAC,cAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC;IAEvE,OAAO;QACL,OAAO;QACP,UAAU;QACV,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,iBAAiB,EAAE,MAAA,QAAQ,CAAC,MAAM,0CAAE,oBAAoB,EAAE;QAC1D,sBAAsB,EAAE,MAAA,QAAQ,CAAC,MAAM,0CAAE,yBAAyB,EAAE;QACpE,qBAAqB,EAAE,MAAA,QAAQ,CAAC,MAAM,0CAAE,wBAAwB,EAAE;KACnE,CAAC;AACJ,CAAC;AArBD,gDAqBC;AAED;;GAEG;AACI,KAAK,UAAU,wBAAwB,CAC5C,OAA2B,EAC3B,UAAkB;IAElB,MAAM,SAAS,GAAG,cAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,cAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IACtE,MAAM,oBAAoB,GAAG,MAAM,mCAAmC,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAE3F,MAAM,kBAAE,CAAC,UAAU,CAAC,UAAU,EAAE,oBAAoB,CAAC,CAAC;AACxD,CAAC;AARD,4DAQC;AAED;;GAEG;AACH,KAAK,UAAU,mCAAmC,CAChD,OAA2B,EAC3B,SAAiB;IAEjB,MAAM,eAAe,GAAG,OAAO,CAAC,MAAM,CACpC,CAAC,MAAM,EAAE,EAAE,CACT,MAAM,CAAC,iBAAiB,CAAC,MAAM;QAC/B,MAAM,CAAC,sBAAsB,CAAC,MAAM;QACpC,MAAM,CAAC,qBAAqB,CAAC,MAAM,CACtC,CAAC;IACF,MAAM,IAAI,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAE7D,MAAM,iBAAiB,GAAG,EAAE;SACzB,MAAM,CAAC,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;SACpE,MAAM,CAAC,OAAO,CAAC,CAAC;IAEnB,MAAM,sBAAsB,GAAG,EAAE;SAC9B,MAAM,CAAC,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;SACzE,MAAM,CAAC,OAAO,CAAC,CAAC;IAEnB,MAAM,2BAA2B,GAAG,eAAe,CAAC,MAAM,CACxD,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,qBAAqB,CAAC,MAAM,CAClD,CAAC;IAEF,OAAO;;;;;;;;EAQP,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,OAAO,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/C,SAAS;eACF,SAAS;;aAEX,uBAAuB,CAAC,iBAAiB,CAAC;;;;aAI1C,uBAAuB,CAAC,sBAAsB,CAAC;;;;aAI/C,iCAAiC,CAAC,2BAA2B,CAAC;;;CAG1E,CAAC;AACF,CAAC;AAED;;GAEG;AACH,SAAS,uBAAuB,CAAC,UAAoB;IACnD,MAAM,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,SAAS,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;EAC5F,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,SAAgB,iCAAiC,CAAC,OAA2B;IAC3E,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;QAC5B,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,qBAAqB,EAAE;YAClD,MAAM,CAAC,IAAI,CAAC,kBAAkB,MAAM,CAAC,WAAW,eAAe,OAAO,QAAQ,CAAC,CAAC;SACjF;KACF;IACD,MAAM,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;EAC3E,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC;AACtB,CAAC;AAVD,8EAUC","sourcesContent":["import glob from 'fast-glob';\nimport fs from 'fs-extra';\nimport path from 'path';\n\nimport { ModuleDescriptor, PackageRevision, SearchOptions } from '../types';\n\nasync function findPodspecFile(revision: PackageRevision): Promise<string | undefined> {\n if (revision.config?.iosPodspecPath()) {\n return revision.config.iosPodspecPath();\n }\n\n const [podspecFile] = await glob('*/*.podspec', {\n cwd: revision.path,\n ignore: ['**/node_modules/**'],\n });\n\n return podspecFile;\n}\n\n/**\n * Resolves module search result with additional details required for iOS platform.\n */\nexport async function resolveModuleAsync(\n packageName: string,\n revision: PackageRevision,\n options: SearchOptions\n): Promise<ModuleDescriptor | null> {\n const podspecFile = await findPodspecFile(revision);\n if (!podspecFile) {\n return null;\n }\n\n const podName = path.basename(podspecFile, path.extname(podspecFile));\n const podspecDir = path.dirname(path.join(revision.path, podspecFile));\n\n return {\n podName,\n podspecDir,\n flags: options.flags,\n modulesClassNames: revision.config?.iosModulesClassNames(),\n appDelegateSubscribers: revision.config?.iosAppDelegateSubscribers(),\n reactDelegateHandlers: revision.config?.iosReactDelegateHandlers(),\n };\n}\n\n/**\n * Generates Swift file that contains all autolinked Swift packages.\n */\nexport async function generatePackageListAsync(\n modules: ModuleDescriptor[],\n targetPath: string\n): Promise<void> {\n const className = path.basename(targetPath, path.extname(targetPath));\n const generatedFileContent = await generatePackageListFileContentAsync(modules, className);\n\n await fs.outputFile(targetPath, generatedFileContent);\n}\n\n/**\n * Generates the string to put into the generated package list.\n */\nasync function generatePackageListFileContentAsync(\n modules: ModuleDescriptor[],\n className: string\n): Promise<string> {\n const modulesToImport = modules.filter(\n (module) =>\n module.modulesClassNames.length ||\n module.appDelegateSubscribers.length ||\n module.reactDelegateHandlers.length\n );\n const pods = modulesToImport.map((module) => module.podName);\n\n const modulesClassNames = []\n .concat(...modulesToImport.map((module) => module.modulesClassNames))\n .filter(Boolean);\n\n const appDelegateSubscribers = []\n .concat(...modulesToImport.map((module) => module.appDelegateSubscribers))\n .filter(Boolean);\n\n const reactDelegateHandlerModules = modulesToImport.filter(\n (module) => !!module.reactDelegateHandlers.length\n );\n\n return `/**\n * Automatically generated by expo-modules-autolinking.\n *\n * This autogenerated class provides a list of classes of native Expo modules,\n * but only these that are written in Swift and use the new API for creating Expo modules.\n */\n\nimport ExpoModulesCore\n${pods.map((podName) => `import ${podName}\\n`).join('')}\n@objc(${className})\npublic class ${className}: ModulesProvider {\n public override func getModuleClasses() -> [AnyModule.Type] {\n return ${formatArrayOfClassNames(modulesClassNames)}\n }\n\n public override func getAppDelegateSubscribers() -> [ExpoAppDelegateSubscriber.Type] {\n return ${formatArrayOfClassNames(appDelegateSubscribers)}\n }\n\n public override func getReactDelegateHandlers() -> [ExpoReactDelegateHandlerTupleType] {\n return ${formatArrayOfReactDelegateHandler(reactDelegateHandlerModules)}\n }\n}\n`;\n}\n\n/**\n * Formats an array of class names to Swift's array containing these classes.\n */\nfunction formatArrayOfClassNames(classNames: string[]): string {\n const indent = ' ';\n return `[${classNames.map((className) => `\\n${indent.repeat(3)}${className}.self`).join(',')}\n${indent.repeat(2)}]`;\n}\n\n/**\n * Formats an array of modules to Swift's array containing ReactDelegateHandlers\n */\nexport function formatArrayOfReactDelegateHandler(modules: ModuleDescriptor[]): string {\n const values: string[] = [];\n for (const module of modules) {\n for (const handler of module.reactDelegateHandlers) {\n values.push(`(packageName: \"${module.packageName}\", handler: ${handler}.self)`);\n }\n }\n const indent = ' ';\n return `[${values.map((value) => `\\n${indent.repeat(3)}${value}`).join(',')}\n${indent.repeat(2)}]`;\n}\n"]}
|
package/build/types.d.ts
CHANGED
|
@@ -16,6 +16,10 @@ export interface GenerateOptions extends ResolveOptions {
|
|
|
16
16
|
namespace?: string;
|
|
17
17
|
empty?: boolean;
|
|
18
18
|
}
|
|
19
|
+
export interface PatchReactImportsOptions {
|
|
20
|
+
podsRoot: string;
|
|
21
|
+
dryRun: boolean;
|
|
22
|
+
}
|
|
19
23
|
export declare type PackageRevision = {
|
|
20
24
|
path: string;
|
|
21
25
|
version: string;
|
|
@@ -50,6 +54,10 @@ export interface RawExpoModuleConfig {
|
|
|
50
54
|
* Names of Swift classes that implement `ExpoReactDelegateHandler` to hook React instance creation.
|
|
51
55
|
*/
|
|
52
56
|
reactDelegateHandlers?: string[];
|
|
57
|
+
/**
|
|
58
|
+
* Podspec relative path.
|
|
59
|
+
*/
|
|
60
|
+
podspecPath?: string;
|
|
53
61
|
};
|
|
54
62
|
/**
|
|
55
63
|
* Android-specific config.
|
package/build/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import { ExpoModuleConfig } from './ExpoModuleConfig';\n\nexport type SupportedPlatform = 'ios' | 'android' | 'web';\n\nexport interface SearchOptions {\n // Available in the CLI\n searchPaths: string[];\n ignorePaths?: string[] | null;\n exclude?: string[] | null;\n platform: SupportedPlatform;\n silent?: boolean;\n\n // Scratched from project's config\n flags?: Record<string, any>;\n}\n\nexport interface ResolveOptions extends SearchOptions {\n json?: boolean;\n}\n\nexport interface GenerateOptions extends ResolveOptions {\n target: string;\n namespace?: string;\n empty?: boolean;\n}\n\nexport type PackageRevision = {\n path: string;\n version: string;\n config?: ExpoModuleConfig;\n duplicates?: PackageRevision[];\n};\n\nexport type SearchResults = {\n [moduleName: string]: PackageRevision;\n};\n\nexport type ModuleDescriptor = Record<string, any>;\n\n/**\n * Represents a raw config from `expo-module.json`.\n */\nexport interface RawExpoModuleConfig {\n /**\n * An array of supported platforms.\n */\n platforms?: SupportedPlatform[];\n\n /**\n * iOS-specific config.\n */\n ios?: {\n /**\n * Names of Swift native modules classes to put to the generated modules provider file.\n */\n modulesClassNames?: string[];\n\n /**\n * Names of Swift classes that hooks into `ExpoAppDelegate` to receive AppDelegate life-cycle events.\n */\n appDelegateSubscribers?: string[];\n\n /**\n * Names of Swift classes that implement `ExpoReactDelegateHandler` to hook React instance creation.\n */\n reactDelegateHandlers?: string[];\n };\n\n /**\n * Android-specific config.\n */\n android?: {\n /**\n * Full names (package + class name) of Kotlin native modules classes to put to the generated package provider file.\n */\n modulesClassNames?: string[];\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import { ExpoModuleConfig } from './ExpoModuleConfig';\n\nexport type SupportedPlatform = 'ios' | 'android' | 'web';\n\nexport interface SearchOptions {\n // Available in the CLI\n searchPaths: string[];\n ignorePaths?: string[] | null;\n exclude?: string[] | null;\n platform: SupportedPlatform;\n silent?: boolean;\n\n // Scratched from project's config\n flags?: Record<string, any>;\n}\n\nexport interface ResolveOptions extends SearchOptions {\n json?: boolean;\n}\n\nexport interface GenerateOptions extends ResolveOptions {\n target: string;\n namespace?: string;\n empty?: boolean;\n}\n\nexport interface PatchReactImportsOptions {\n podsRoot: string;\n dryRun: boolean;\n}\n\nexport type PackageRevision = {\n path: string;\n version: string;\n config?: ExpoModuleConfig;\n duplicates?: PackageRevision[];\n};\n\nexport type SearchResults = {\n [moduleName: string]: PackageRevision;\n};\n\nexport type ModuleDescriptor = Record<string, any>;\n\n/**\n * Represents a raw config from `expo-module.json`.\n */\nexport interface RawExpoModuleConfig {\n /**\n * An array of supported platforms.\n */\n platforms?: SupportedPlatform[];\n\n /**\n * iOS-specific config.\n */\n ios?: {\n /**\n * Names of Swift native modules classes to put to the generated modules provider file.\n */\n modulesClassNames?: string[];\n\n /**\n * Names of Swift classes that hooks into `ExpoAppDelegate` to receive AppDelegate life-cycle events.\n */\n appDelegateSubscribers?: string[];\n\n /**\n * Names of Swift classes that implement `ExpoReactDelegateHandler` to hook React instance creation.\n */\n reactDelegateHandlers?: string[];\n\n /**\n * Podspec relative path.\n */\n podspecPath?: string;\n };\n\n /**\n * Android-specific config.\n */\n android?: {\n /**\n * Full names (package + class name) of Kotlin native modules classes to put to the generated package provider file.\n */\n modulesClassNames?: string[];\n };\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-modules-autolinking",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4",
|
|
4
4
|
"description": "Scripts that autolink Expo modules.",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -47,5 +47,5 @@
|
|
|
47
47
|
"find-up": "^5.0.0",
|
|
48
48
|
"fs-extra": "^9.1.0"
|
|
49
49
|
},
|
|
50
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "a4ab2a9da154d6d78cc7eaafed5a263aba693ec8"
|
|
51
51
|
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Copyright 2018-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
module Expo
|
|
4
|
+
class ReactImportPatcher
|
|
5
|
+
|
|
6
|
+
public def initialize(installer, options)
|
|
7
|
+
@root = installer.sandbox.root
|
|
8
|
+
@module_dirs = get_module_dirs(installer)
|
|
9
|
+
@options = options
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
public def run!
|
|
13
|
+
args = [
|
|
14
|
+
'node',
|
|
15
|
+
'--eval',
|
|
16
|
+
'require(\'expo-modules-autolinking\')(process.argv.slice(1))',
|
|
17
|
+
'patch-react-imports',
|
|
18
|
+
'--pods-root',
|
|
19
|
+
Shellwords.escape(File.expand_path(@root)),
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
if @options[:dry_run]
|
|
23
|
+
args.append('--dry-run')
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
@module_dirs.each do |dir|
|
|
27
|
+
args.append(Shellwords.escape(File.expand_path(dir)))
|
|
28
|
+
end
|
|
29
|
+
Pod::UI.message "Executing ReactImportsPatcher node command: #{args.join(' ')}"
|
|
30
|
+
|
|
31
|
+
time_begin = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
32
|
+
system(*args)
|
|
33
|
+
elapsed_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) - time_begin
|
|
34
|
+
Pod::UI.info "expo_patch_react_imports! took #{elapsed_time.round(4)} seconds to transform files."
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private def get_module_dirs(installer)
|
|
38
|
+
unless installer.pods_project
|
|
39
|
+
Pod::UI.message '`pods_project` not found. This is expected when `:incremental_installation` is enabled in your project\'s Podfile.'
|
|
40
|
+
return []
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
result = []
|
|
44
|
+
installer.pods_project.development_pods.children.each do |pod|
|
|
45
|
+
if pod.is_a?(Xcodeproj::Project::Object::PBXFileReference) && pod.path.end_with?('.xcodeproj')
|
|
46
|
+
# Support generate_multiple_pod_projects or use_frameworks!
|
|
47
|
+
project = Xcodeproj::Project.open(File.join(installer.sandbox.root, pod.path))
|
|
48
|
+
groups = project.groups.select { |group| !(['Dependencies', 'Frameworks', 'Products'].include? group.name) }
|
|
49
|
+
groups.each do |group|
|
|
50
|
+
result.append(group.real_path.to_s)
|
|
51
|
+
end
|
|
52
|
+
else
|
|
53
|
+
result.append(pod.real_path.to_s)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
return result.select { |dir|
|
|
58
|
+
# Exclude known dirs unnecessary to patch and reduce processing time
|
|
59
|
+
!dir.include?('/react-native/') &&
|
|
60
|
+
!dir.end_with?('/react-native') &&
|
|
61
|
+
!dir.include?('/expo-')
|
|
62
|
+
}
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
end # class ReactImportPatcher
|
|
66
|
+
end # module Expo
|
package/src/ExpoModuleConfig.ts
CHANGED
|
@@ -34,6 +34,13 @@ export class ExpoModuleConfig {
|
|
|
34
34
|
return this.rawConfig.ios?.reactDelegateHandlers ?? [];
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
/**
|
|
38
|
+
* Returns a podspec path defined by the module author.
|
|
39
|
+
*/
|
|
40
|
+
iosPodspecPath(): string | undefined {
|
|
41
|
+
return this.rawConfig.ios?.podspecPath;
|
|
42
|
+
}
|
|
43
|
+
|
|
37
44
|
/**
|
|
38
45
|
* Returns a list of names of Kotlin native modules classes to put to the generated package provider file.
|
|
39
46
|
*/
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// Copyright 2018-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
import glob from 'fast-glob';
|
|
4
|
+
import fs from 'fs-extra';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
|
|
7
|
+
import { PatchReactImportsOptions } from './types';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Remove all double-quoted react header imports
|
|
11
|
+
* @param dirs target directories to patch
|
|
12
|
+
* @param options PatchReactImportsOptions
|
|
13
|
+
*/
|
|
14
|
+
export async function patchReactImportsAsync(dirs: string[], options: PatchReactImportsOptions) {
|
|
15
|
+
const headerSet = await generateReactHeaderSetAsync(
|
|
16
|
+
path.join(options.podsRoot, 'Headers', 'Public', 'React-Core', 'React')
|
|
17
|
+
);
|
|
18
|
+
await Promise.all(dirs.map((dir) => patchDirAsync(headerSet, dir, options.dryRun)));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Generate `React-Core` public header names as a set, will transform necessary headers based on this set.
|
|
23
|
+
*/
|
|
24
|
+
async function generateReactHeaderSetAsync(reactHeaderDir: string): Promise<Set<string>> {
|
|
25
|
+
const files = await glob('*.h', { cwd: reactHeaderDir });
|
|
26
|
+
return new Set(files);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Patch imports from a file
|
|
31
|
+
* @param headerSet prebuilt React-Core header set
|
|
32
|
+
* @param file target patch file
|
|
33
|
+
* @param dryRun true if not writing changes to file
|
|
34
|
+
*/
|
|
35
|
+
export async function patchFileAsync(headerSet: Set<string>, file: string, dryRun: boolean) {
|
|
36
|
+
let changed = false;
|
|
37
|
+
const content = await fs.readFile(file, 'utf-8');
|
|
38
|
+
let transformContent = content.replace(
|
|
39
|
+
/^#import\s+"(.+)"$/gm,
|
|
40
|
+
(match: string, headerName: string): string => {
|
|
41
|
+
// `#import "RCTBridge.h"` -> `#import <React/RCTBridge.h>`
|
|
42
|
+
if (headerSet.has(headerName)) {
|
|
43
|
+
changed = true;
|
|
44
|
+
return `#import <React/${headerName}>`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// `#import "React/RCTBridge.h"` -> `#import <React/RCTBridge.h>`
|
|
48
|
+
if (headerName.startsWith('React/')) {
|
|
49
|
+
const name = headerName.substring(6);
|
|
50
|
+
if (headerSet.has(name)) {
|
|
51
|
+
changed = true;
|
|
52
|
+
return `#import <React/${name}>`;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Otherwise, return original import
|
|
57
|
+
return match;
|
|
58
|
+
}
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
transformContent = transformContent.replace(
|
|
62
|
+
/^#(if|elif)\s+__has_include\("(.+)"\)$/gm,
|
|
63
|
+
(match: string, ifPrefix: string, headerName: string): string => {
|
|
64
|
+
// `#if __has_include("RCTBridge.h")` -> `#if __has_include(<React/RCTBridge.h>)`
|
|
65
|
+
if (headerSet.has(headerName)) {
|
|
66
|
+
changed = true;
|
|
67
|
+
return `#${ifPrefix} __has_include(<React/${headerName}>)`;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// `#if __has_include("React/RCTBridge.h")` -> `#if __has_include(<React/RCTBridge.h>)`
|
|
71
|
+
if (headerName.startsWith('React/')) {
|
|
72
|
+
const name = headerName.substring(6);
|
|
73
|
+
if (headerSet.has(name)) {
|
|
74
|
+
changed = true;
|
|
75
|
+
return `#${ifPrefix} __has_include(<React/${name}>)`;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Otherwise, return original import
|
|
80
|
+
return match;
|
|
81
|
+
}
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
if (changed) {
|
|
85
|
+
console.log(`Patching imports for file: ${file}`);
|
|
86
|
+
}
|
|
87
|
+
if (!dryRun) {
|
|
88
|
+
await fs.writeFile(file, transformContent);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Patch imports from a directory
|
|
94
|
+
* @param headerSet prebuilt React-Core header set
|
|
95
|
+
* @param file target patch file
|
|
96
|
+
* @param dryRun true if not writing changes to file
|
|
97
|
+
*/
|
|
98
|
+
async function patchDirAsync(headerSet: Set<string>, dir: string, dryRun: boolean) {
|
|
99
|
+
const files = await glob('**/*.{h,m,mm}', { cwd: dir, absolute: true });
|
|
100
|
+
return Promise.all(files.map((file) => patchFileAsync(headerSet, file, dryRun)));
|
|
101
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import commander from 'commander';
|
|
2
2
|
|
|
3
|
+
import { patchReactImportsAsync } from './ReactImportsPatcher';
|
|
3
4
|
import {
|
|
4
5
|
findModulesAsync,
|
|
5
6
|
resolveModulesAsync,
|
|
@@ -54,6 +55,15 @@ function registerResolveCommand<OptionsType extends ResolveOptions>(
|
|
|
54
55
|
return registerSearchCommand<OptionsType>(commandName, fn);
|
|
55
56
|
}
|
|
56
57
|
|
|
58
|
+
// Register for `patch-react-imports` command
|
|
59
|
+
function registerPatchReactImportsCommand() {
|
|
60
|
+
return commander
|
|
61
|
+
.command('patch-react-imports [paths...]')
|
|
62
|
+
.requiredOption('--pods-root <podsRoot>', 'The path to `Pods` directory')
|
|
63
|
+
.option('--dry-run', 'Only list files without writing changes to the file system')
|
|
64
|
+
.action(patchReactImportsAsync);
|
|
65
|
+
}
|
|
66
|
+
|
|
57
67
|
module.exports = async function (args: string[]) {
|
|
58
68
|
// Searches for available expo modules.
|
|
59
69
|
registerSearchCommand<SearchOptions & { json?: boolean }>('search', async (results, options) => {
|
|
@@ -102,6 +112,8 @@ module.exports = async function (args: string[]) {
|
|
|
102
112
|
false
|
|
103
113
|
);
|
|
104
114
|
|
|
115
|
+
registerPatchReactImportsCommand();
|
|
116
|
+
|
|
105
117
|
await commander
|
|
106
118
|
.version(require('expo-modules-autolinking/package.json').version)
|
|
107
119
|
.description('CLI command that searches for Expo modules to autolink them.')
|
package/src/platforms/ios.ts
CHANGED
|
@@ -4,6 +4,19 @@ import path from 'path';
|
|
|
4
4
|
|
|
5
5
|
import { ModuleDescriptor, PackageRevision, SearchOptions } from '../types';
|
|
6
6
|
|
|
7
|
+
async function findPodspecFile(revision: PackageRevision): Promise<string | undefined> {
|
|
8
|
+
if (revision.config?.iosPodspecPath()) {
|
|
9
|
+
return revision.config.iosPodspecPath();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const [podspecFile] = await glob('*/*.podspec', {
|
|
13
|
+
cwd: revision.path,
|
|
14
|
+
ignore: ['**/node_modules/**'],
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
return podspecFile;
|
|
18
|
+
}
|
|
19
|
+
|
|
7
20
|
/**
|
|
8
21
|
* Resolves module search result with additional details required for iOS platform.
|
|
9
22
|
*/
|
|
@@ -12,11 +25,7 @@ export async function resolveModuleAsync(
|
|
|
12
25
|
revision: PackageRevision,
|
|
13
26
|
options: SearchOptions
|
|
14
27
|
): Promise<ModuleDescriptor | null> {
|
|
15
|
-
const
|
|
16
|
-
cwd: revision.path,
|
|
17
|
-
ignore: ['**/node_modules/**'],
|
|
18
|
-
});
|
|
19
|
-
|
|
28
|
+
const podspecFile = await findPodspecFile(revision);
|
|
20
29
|
if (!podspecFile) {
|
|
21
30
|
return null;
|
|
22
31
|
}
|
package/src/types.ts
CHANGED
|
@@ -24,6 +24,11 @@ export interface GenerateOptions extends ResolveOptions {
|
|
|
24
24
|
empty?: boolean;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
export interface PatchReactImportsOptions {
|
|
28
|
+
podsRoot: string;
|
|
29
|
+
dryRun: boolean;
|
|
30
|
+
}
|
|
31
|
+
|
|
27
32
|
export type PackageRevision = {
|
|
28
33
|
path: string;
|
|
29
34
|
version: string;
|
|
@@ -64,6 +69,11 @@ export interface RawExpoModuleConfig {
|
|
|
64
69
|
* Names of Swift classes that implement `ExpoReactDelegateHandler` to hook React instance creation.
|
|
65
70
|
*/
|
|
66
71
|
reactDelegateHandlers?: string[];
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Podspec relative path.
|
|
75
|
+
*/
|
|
76
|
+
podspecPath?: string;
|
|
67
77
|
};
|
|
68
78
|
|
|
69
79
|
/**
|