@rnx-kit/tools-react-native
Version:
A collection of supplemental react-native functions and types
202 lines • 7.65 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.getAvailablePlatforms = void 0;
exports.expandPlatformExtensions = expandPlatformExtensions;
exports.getModuleSuffixes = getModuleSuffixes;
exports.getAvailablePlatformsUncached = getAvailablePlatformsUncached;
exports.platformExtensions = platformExtensions;
exports.tryParsePlatform = tryParsePlatform;
exports.parsePlatform = parsePlatform;
exports.platformValues = platformValues;
const package_1 = require("@rnx-kit/tools-node/package");
const types_bundle_config_1 = require("@rnx-kit/types-bundle-config");
const fs = __importStar(require("node:fs"));
const path = __importStar(require("node:path"));
const context_ts_1 = require("./context.js");
/**
* Returns a list of extensions that should be tried for the target platform in
* prioritized order.
* @param platform The platform to expand platform extensions for
* @param extensions A list of extensions to expand
* @returns A list of extensions
*/
function expandPlatformExtensions(platform, extensions) {
const expanded = [];
for (const p of platformExtensions(platform)) {
for (const ext of extensions) {
expanded.push(`.${p}${ext}`);
}
}
expanded.push(...extensions);
return expanded;
}
/**
* Get the module suffixes array for a given platform, suitable for use with TypeScript's moduleSuffixes setting
* in the form of ['.ios', '.native', ''] or ['.windows', '.win', '.native', ''] or similar
*
* @param platform platform to get module suffixes for
* @param appendEmpty finish the suffixes with an empty entry, required for typescript usage
* @returns an array of suffixes to try to match a module to in order of priority
*/
function getModuleSuffixes(platform, appendEmpty = true) {
const extensions = platformExtensions(platform).map((ext) => `.${ext}`);
if (appendEmpty) {
extensions.push("");
}
return extensions;
}
function recordPlatformPackage(platformMap, pkgPath, startDir = pkgPath) {
if (!pkgPath) {
return false;
}
const manifest = (0, context_ts_1.readReactNativeConfig)(pkgPath, startDir);
if (!manifest) {
return false;
}
const { platforms } = manifest;
if (!platforms || typeof platforms !== "object") {
return false;
}
for (const [platform, info] of Object.entries(platforms)) {
if (typeof platformMap[platform] === "undefined") {
const { npmPackageName } = info;
if (npmPackageName) {
platformMap[platform] = npmPackageName;
}
}
}
return true;
}
/**
* Returns a map of available React Native platforms. The result is NOT cached.
* @param startDir The directory to look for react-native platforms from
* @param platformMap A platform-to-npm-package map of known packages
* @returns A platform-to-npm-package map, excluding "core" platforms.
*/
function getAvailablePlatformsUncached(startDir = process.cwd(), platformMap = { android: "", ios: "" }) {
const packageJson = path.join(startDir, "package.json");
if (!fs.existsSync(packageJson)) {
const parent = path.dirname(startDir);
return parent === startDir
? platformMap
: getAvailablePlatformsUncached(path.dirname(startDir), platformMap);
}
const { dependencies, peerDependencies, devDependencies } = JSON.parse(fs.readFileSync(packageJson, { encoding: "utf-8" }));
const packages = new Set(dependencies ? Object.keys(dependencies) : []);
for (const deps of [peerDependencies, devDependencies]) {
if (deps) {
for (const pkg of Object.keys(deps)) {
packages.add(pkg);
}
}
}
recordPlatformPackage(platformMap, startDir);
const options = { startDir };
for (const pkgName of packages) {
const pkgPath = (0, package_1.findPackageDependencyDir)(pkgName, options);
if (pkgPath) {
if (!recordPlatformPackage(platformMap, pkgPath, startDir)) {
// Ideally, `react-native-web` should have a `react-native.config.js`
// where it declares itself as the "web" platform. Since it doesn't, we
// special-case it here.
if (pkgName === "react-native-web") {
platformMap["web"] = pkgName;
}
}
}
}
return platformMap;
}
/**
* Returns a map of available React Native platforms. The result is cached.
* @param startDir The directory to look for react-native platforms from
* @returns A platform-to-npm-package map, excluding "core" platforms.
* @function
*/
exports.getAvailablePlatforms = (() => {
const isTesting = Boolean(process.env.NODE_TEST_CONTEXT) || process.env.NODE_ENV === "test";
let platformMap = undefined;
return (startDir = process.cwd()) => {
if (!platformMap || isTesting) {
platformMap = getAvailablePlatformsUncached(startDir);
}
return platformMap;
};
})();
/**
* Returns file extensions that can be mapped to the target platform.
* @param platform The platform to retrieve extensions for
* @returns Valid extensions for specified platform
*/
function platformExtensions(platform) {
switch (platform) {
case "web":
return [platform];
case "win32":
case "windows":
return [platform, "win", "native"];
default:
return [platform, "native"];
}
}
/**
* @returns the given string as a platform value or undefined if it is not a valid platform.
*/
function tryParsePlatform(val) {
return types_bundle_config_1.ALL_PLATFORM_VALUES.includes(val)
? val
: undefined;
}
/**
* Parse a string to ensure it maps to a valid react-native platform.
*
* @param val Input string
* @returns React-native platform name. Throws `Error` on failure.
*/
function parsePlatform(val) {
const platform = tryParsePlatform(val);
if (!platform) {
throw new Error(`Unknown platform '${val}'`);
}
return platform;
}
/**
* @returns List of all supported react-native platforms.
*/
function platformValues() {
return types_bundle_config_1.ALL_PLATFORM_VALUES;
}
//# sourceMappingURL=platform.js.map