react-native-node-api
Version:
Node-API for React Native
113 lines (112 loc) • 5.82 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.updateInfoPlist = updateInfoPlist;
exports.linkXcframework = linkXcframework;
const strict_1 = __importDefault(require("node:assert/strict"));
const node_path_1 = __importDefault(require("node:path"));
const node_fs_1 = __importDefault(require("node:fs"));
const node_os_1 = __importDefault(require("node:os"));
const bufout_1 = require("bufout");
const path_utils_js_1 = require("../path-utils.js");
const link_modules_js_1 = require("./link-modules.js");
/**
* Update the Info.plist file of an xcframework to use the new library name.
*/
async function updateInfoPlist({ filePath, oldLibraryName, newLibraryName, }) {
const infoPlistContents = await node_fs_1.default.promises.readFile(filePath, "utf-8");
// TODO: Use a proper plist parser
const updatedContents = infoPlistContents.replaceAll(oldLibraryName, newLibraryName);
await node_fs_1.default.promises.writeFile(filePath, updatedContents, "utf-8");
}
async function linkXcframework({ platform, modulePath, incremental, naming, }) {
// Copy the xcframework to the output directory and rename the framework and binary
const newLibraryName = (0, path_utils_js_1.getLibraryName)(modulePath, naming);
const outputPath = (0, link_modules_js_1.getLinkedModuleOutputPath)(platform, modulePath, naming);
const tempPath = await node_fs_1.default.promises.mkdtemp(node_path_1.default.join(node_os_1.default.tmpdir(), `react-native-node-api-${newLibraryName}-`));
try {
if (incremental && node_fs_1.default.existsSync(outputPath)) {
const moduleModified = (0, path_utils_js_1.getLatestMtime)(modulePath);
const outputModified = (0, path_utils_js_1.getLatestMtime)(outputPath);
if (moduleModified < outputModified) {
return {
originalPath: modulePath,
libraryName: newLibraryName,
outputPath,
skipped: true,
};
}
}
// Delete any existing xcframework (or xcodebuild will try to amend it)
await node_fs_1.default.promises.rm(outputPath, { recursive: true, force: true });
await node_fs_1.default.promises.cp(modulePath, tempPath, { recursive: true });
// Following extracted function mimics `glob("*/*.framework/")`
function globFrameworkDirs(startPath, fn) {
return node_fs_1.default
.readdirSync(startPath, { withFileTypes: true })
.filter((tripletEntry) => tripletEntry.isDirectory())
.flatMap((tripletEntry) => {
const tripletPath = node_path_1.default.join(startPath, tripletEntry.name);
return node_fs_1.default
.readdirSync(tripletPath, { withFileTypes: true })
.filter((frameworkEntry) => frameworkEntry.isDirectory() &&
node_path_1.default.extname(frameworkEntry.name) === ".framework")
.flatMap(async (frameworkEntry) => await fn(tripletPath, frameworkEntry.name));
});
}
const frameworkPaths = await Promise.all(globFrameworkDirs(tempPath, async (tripletPath, frameworkEntryName) => {
const frameworkPath = node_path_1.default.join(tripletPath, frameworkEntryName);
const oldLibraryName = node_path_1.default.basename(frameworkEntryName, ".framework");
const oldLibraryPath = node_path_1.default.join(frameworkPath, oldLibraryName);
const newFrameworkPath = node_path_1.default.join(tripletPath, `${newLibraryName}.framework`);
const newLibraryPath = node_path_1.default.join(newFrameworkPath, newLibraryName);
(0, strict_1.default)(node_fs_1.default.existsSync(oldLibraryPath), `Expected a library at '${oldLibraryPath}'`);
// Rename the library
await node_fs_1.default.promises.rename(oldLibraryPath,
// Cannot use newLibraryPath here, because the framework isn't renamed yet
node_path_1.default.join(frameworkPath, newLibraryName));
// Rename the framework
await node_fs_1.default.promises.rename(frameworkPath, newFrameworkPath);
// Expect the library in the new location
(0, strict_1.default)(node_fs_1.default.existsSync(newLibraryPath));
// Update the binary
await (0, bufout_1.spawn)("install_name_tool", [
"-id",
`@rpath/${newLibraryName}.framework/${newLibraryName}`,
newLibraryPath,
], {
outputMode: "buffered",
});
// Update the Info.plist file for the framework
await updateInfoPlist({
filePath: node_path_1.default.join(newFrameworkPath, "Info.plist"),
oldLibraryName,
newLibraryName,
});
return newFrameworkPath;
}));
// Create a new xcframework from the renamed frameworks
await (0, bufout_1.spawn)("xcodebuild", [
"-create-xcframework",
...frameworkPaths.flatMap((frameworkPath) => [
"-framework",
frameworkPath,
]),
"-output",
outputPath,
], {
outputMode: "buffered",
});
return {
originalPath: modulePath,
libraryName: newLibraryName,
outputPath,
skipped: false,
};
}
finally {
await node_fs_1.default.promises.rm(tempPath, { recursive: true, force: true });
}
}
;