react-native-node-api
Version:
Node-API for React Native
177 lines (176 loc) • 8.5 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.program = void 0;
const strict_1 = __importDefault(require("node:assert/strict"));
const node_path_1 = __importDefault(require("node:path"));
const node_stream_1 = require("node:stream");
const node_fs_1 = __importDefault(require("node:fs"));
const cli_utils_1 = require("@react-native-node-api/cli-utils");
const path_utils_1 = require("../path-utils");
const hermes_1 = require("./hermes");
const options_1 = require("./options");
const link_modules_1 = require("./link-modules");
const apple_1 = require("./apple");
const android_1 = require("./android");
const weak_node_api_1 = require("../weak-node-api");
// We're attaching a lot of listeners when spawning in parallel
node_stream_1.EventEmitter.defaultMaxListeners = 100;
exports.program = new cli_utils_1.Command("react-native-node-api").addCommand(hermes_1.command);
function getLinker(platform) {
if (platform === "android") {
return android_1.linkAndroidDir;
}
else if (platform === "apple") {
return apple_1.linkXcframework;
}
else {
throw new Error(`Unknown platform: ${platform}`);
}
}
function getPlatformDisplayName(platform) {
if (platform === "android") {
return "Android";
}
else if (platform === "apple") {
return "Apple";
}
else {
throw new Error(`Unknown platform: ${platform}`);
}
}
exports.program
.command("link")
.argument("[path]", "Some path inside the app package", process.cwd())
.option("--force", "Don't check timestamps of input files to skip unnecessary rebuilds", false)
.option("--prune", "Delete vendored modules that are no longer auto-linked", true)
.option("--android", "Link Android modules")
.option("--apple", "Link Apple modules")
.addOption(options_1.packageNameOption)
.addOption(options_1.pathSuffixOption)
.action((0, cli_utils_1.wrapAction)(async (pathArg, { force, prune, pathSuffix, android, apple, packageName }) => {
console.log("Auto-linking Node-API modules from", cli_utils_1.chalk.dim(pathArg));
const platforms = [];
if (android) {
platforms.push("android");
}
if (apple) {
platforms.push("apple");
}
if (platforms.length === 0) {
console.error(`No platform specified, pass one or more of:`, ...path_utils_1.PLATFORMS.map((platform) => cli_utils_1.chalk.bold(`\n --${platform}`)));
process.exitCode = 1;
return;
}
for (const platform of platforms) {
const platformDisplayName = getPlatformDisplayName(platform);
const platformOutputPath = (0, path_utils_1.getAutolinkPath)(platform);
const modules = await (0, cli_utils_1.oraPromise)(() => (0, link_modules_1.linkModules)({
platform,
fromPath: node_path_1.default.resolve(pathArg),
incremental: !force,
naming: { packageName, pathSuffix },
linker: getLinker(platform),
}), {
text: `Linking ${platformDisplayName} Node-API modules into ${(0, cli_utils_1.prettyPath)(platformOutputPath)}`,
successText: `Linked ${platformDisplayName} Node-API modules into ${(0, cli_utils_1.prettyPath)(platformOutputPath)}`,
failText: () => `Failed to link ${platformDisplayName} Node-API modules into ${(0, cli_utils_1.prettyPath)(platformOutputPath)}`,
});
if (modules.length === 0) {
console.log("Found no Node-API modules 🤷");
}
const failures = modules.filter((result) => "failure" in result);
const linked = modules.filter((result) => "outputPath" in result);
for (const { originalPath, outputPath, skipped } of linked) {
const prettyOutputPath = outputPath
? "→ " + (0, cli_utils_1.prettyPath)(node_path_1.default.basename(outputPath))
: "";
if (skipped) {
console.log(cli_utils_1.chalk.greenBright("-"), "Skipped", (0, cli_utils_1.prettyPath)(originalPath), prettyOutputPath, "(up to date)");
}
else {
console.log(cli_utils_1.chalk.greenBright("⚭"), "Linked", (0, cli_utils_1.prettyPath)(originalPath), prettyOutputPath);
}
}
for (const { originalPath, failure } of failures) {
(0, strict_1.default)(failure instanceof cli_utils_1.SpawnFailure);
console.error("\n", cli_utils_1.chalk.redBright("✖"), "Failed to copy", (0, cli_utils_1.prettyPath)(originalPath));
console.error(failure.message);
failure.flushOutput("both");
process.exitCode = 1;
}
if (prune) {
await (0, link_modules_1.pruneLinkedModules)(platform, modules);
}
}
if (apple) {
await (0, cli_utils_1.oraPromise)(async () => {
const xcframeworkPath = node_path_1.default.join(weak_node_api_1.weakNodeApiPath, "weak-node-api.xcframework");
await Promise.all([
node_path_1.default.join(xcframeworkPath, "macos-x86_64"),
node_path_1.default.join(xcframeworkPath, "macos-arm64"),
node_path_1.default.join(xcframeworkPath, "macos-arm64_x86_64"),
].map(async (slicePath) => {
const frameworkPath = node_path_1.default.join(slicePath, "weak-node-api.framework");
if (node_fs_1.default.existsSync(frameworkPath)) {
await (0, apple_1.restoreFrameworkLinks)(frameworkPath);
}
}));
}, {
text: "Restoring weak-node-api symlinks",
successText: "Restored weak-node-api symlinks",
failText: (error) => `Failed to restore weak-node-api symlinks: ${error.message}`,
});
}
}));
exports.program
.command("list")
.description("Lists Node-API modules")
.argument("[from-path]", "Some path inside the app package", process.cwd())
.option("--json", "Output as JSON", false)
.addOption(options_1.packageNameOption)
.addOption(options_1.pathSuffixOption)
.action((0, cli_utils_1.wrapAction)(async (fromArg, { json, pathSuffix, packageName }) => {
const rootPath = node_path_1.default.resolve(fromArg);
const dependencies = await (0, path_utils_1.findNodeApiModulePathsByDependency)({
fromPath: rootPath,
platform: path_utils_1.PLATFORMS,
includeSelf: true,
});
if (json) {
console.log(JSON.stringify(dependencies, null, 2));
}
else {
const dependencyCount = Object.keys(dependencies).length;
const xframeworkCount = Object.values(dependencies).reduce((acc, { modulePaths }) => acc + modulePaths.length, 0);
console.log("Found", cli_utils_1.chalk.greenBright(xframeworkCount), "Node-API modules in", cli_utils_1.chalk.greenBright(dependencyCount), dependencyCount === 1 ? "package" : "packages", "from", (0, cli_utils_1.prettyPath)(rootPath));
for (const [dependencyName, dependency] of Object.entries(dependencies)) {
console.log("\n" + cli_utils_1.chalk.blueBright(dependencyName), "→", (0, cli_utils_1.prettyPath)(dependency.path));
const libraryMap = (0, path_utils_1.getLibraryMap)(dependency.modulePaths.map((p) => node_path_1.default.join(dependency.path, p)), { packageName, pathSuffix });
console.log((0, path_utils_1.visualizeLibraryMap)(libraryMap));
}
}
}));
exports.program
.command("info <path>")
.description("Utility to print, module path, the hash of a single Android library")
.addOption(options_1.packageNameOption)
.addOption(options_1.pathSuffixOption)
.action((0, cli_utils_1.wrapAction)((pathInput, { pathSuffix, packageName }) => {
const resolvedModulePath = node_path_1.default.resolve(pathInput);
const normalizedModulePath = (0, path_utils_1.normalizeModulePath)(resolvedModulePath);
const context = (0, path_utils_1.determineModuleContext)(resolvedModulePath);
const libraryName = (0, path_utils_1.getLibraryName)(resolvedModulePath, {
packageName,
pathSuffix,
});
console.log({
resolvedModulePath,
normalizedModulePath,
packageName: context.packageName,
relativePath: context.relativePath,
libraryName,
});
}));