first commit

This commit is contained in:
2026-03-10 16:18:05 +00:00
commit 11f9c069b5
31635 changed files with 3187747 additions and 0 deletions

View File

@@ -0,0 +1,50 @@
import commander from 'commander';
import { SupportedPlatform } from '../types';
export interface AutolinkingOptions {
/** Only scan direct "dependencies" of a project for React Native modules, rather than including transitive dependencies.
* @remarks
* Before SDK 54, React Native modules would only be linked if they were listed as dependencies
* of a project. However, in SDK 54+ transitive React Native modules dependencies are also
* auto-linked, unless this flag is enabled.
* @defaultValue `false`
*/
legacy_shallowReactNativeLinking: boolean;
/** Extra modules directories to search for native modules.
* @defaultValue `[]`
*/
searchPaths: string[];
/** Local native modules directory to add to autolinking.
* @defaultValue `"./modules"`
*/
nativeModulesDir: string | null;
/** Native modules to exclude from autolinking by name.
* @defaultValue `[]`
*/
exclude: string[];
/** A list of package names to opt out of prebuilt Expo modules (Android-only)
* @defaultValue `[]`
*/
buildFromSource?: string[];
/** CocoaPods flags to pass to each autolinked pod (Apple/iOS-only)
* @defaultValue `[]`
*/
flags?: Record<string, any>;
}
export declare const filterMapSearchPaths: (searchPaths: unknown, basePath: string) => string[] | undefined;
/** Common commandline arguments for autolinking commands (Not to be confused with `AutolinkingOptions` */
export interface AutolinkingCommonArguments {
projectRoot?: string | null;
searchPaths?: string[] | null;
exclude?: string[] | null;
platform?: SupportedPlatform | null;
}
export declare function registerAutolinkingArguments(command: commander.Command): commander.Command;
export interface LinkingOptionsLoader {
getCommandRoot(): string;
getAppRoot(): Promise<string>;
getPlatformOptions<T extends SupportedPlatform | undefined>(platform: T): Promise<AutolinkingOptions & {
platform: T;
}>;
getPlatformOptions(): Promise<AutolinkingOptions>;
}
export declare function createAutolinkingOptionsLoader(argumentsOptions?: AutolinkingCommonArguments): LinkingOptionsLoader;

View File

@@ -0,0 +1,170 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.filterMapSearchPaths = void 0;
exports.registerAutolinkingArguments = registerAutolinkingArguments;
exports.createAutolinkingOptionsLoader = createAutolinkingOptionsLoader;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const isJSONObject = (x) => x != null && typeof x === 'object';
const resolvePathMaybe = (target, basePath) => {
if (typeof target !== 'string') {
return null;
}
let resolved = path_1.default.resolve(basePath, target);
if (fs_1.default.existsSync(resolved)) {
return resolved;
}
else if ((resolved = path_1.default.resolve(target)) && fs_1.default.existsSync(target)) {
// TODO(@kitten): This is here for legacy support. However, this *will* be inconsistent
// This relies on the current working directory, and hence, can behave differently depending
// on where the command was invoked.
return target;
}
else {
return null;
}
};
const filterMapSearchPaths = (searchPaths, basePath) => {
if (Array.isArray(searchPaths)) {
return searchPaths
.map((searchPath) => resolvePathMaybe(searchPath, basePath))
.filter((searchPath) => searchPath != null);
}
else {
return undefined;
}
};
exports.filterMapSearchPaths = filterMapSearchPaths;
const parsePackageJsonOptions = (packageJson, appRoot, platform) => {
const expo = isJSONObject(packageJson.expo) ? packageJson.expo : null;
const autolinkingOptions = expo && isJSONObject(expo.autolinking) ? expo.autolinking : null;
let platformOptions = null;
if (platform) {
platformOptions =
autolinkingOptions && isJSONObject(autolinkingOptions[platform])
? autolinkingOptions[platform]
: null;
if (!platformOptions && platform === 'apple') {
// NOTE: `platform: 'apple'` has a fallback on `ios`. This doesn't make much sense, since apple should
// be the base option for other apple platforms, but changing this now is a breaking change
platformOptions =
autolinkingOptions && isJSONObject(autolinkingOptions.ios) ? autolinkingOptions.ios : null;
}
}
const mergedOptions = { ...autolinkingOptions, ...platformOptions };
const outputOptions = {};
// legacy_shallowReactNativeLinking
if (mergedOptions.legacy_shallowReactNativeLinking != null) {
outputOptions.legacy_shallowReactNativeLinking =
!!mergedOptions.legacy_shallowReactNativeLinking;
}
// searchPaths
if (typeof mergedOptions.searchPaths === 'string' || Array.isArray(mergedOptions.searchPaths)) {
const rawSearchPaths = typeof mergedOptions.searchPaths === 'string'
? [mergedOptions.searchPaths]
: mergedOptions.searchPaths;
outputOptions.searchPaths = (0, exports.filterMapSearchPaths)(rawSearchPaths, appRoot);
}
// nativeModulesDir
if (typeof mergedOptions.nativeModulesDir === 'string') {
outputOptions.nativeModulesDir = resolvePathMaybe(mergedOptions.nativeModulesDir, appRoot);
}
// exclude
if (Array.isArray(mergedOptions.exclude)) {
outputOptions.exclude = mergedOptions.exclude.filter((x) => typeof x === 'string');
}
// buildFromSource
if (Array.isArray(mergedOptions.buildFromSource)) {
outputOptions.buildFromSource = mergedOptions.buildFromSource.filter((x) => typeof x === 'string');
}
// flags
if (isJSONObject(mergedOptions.flags)) {
outputOptions.flags = { ...mergedOptions.flags };
}
return outputOptions;
};
function registerAutolinkingArguments(command) {
return command
.option('-e, --exclude <exclude...>', 'Package names to exclude when looking up for modules.', (value, previous) => (previous ?? []).concat(value))
.option('-p, --platform [platform]', 'The platform that the resulting modules must support. Available options: "apple", "android"', 'apple')
.option(
// NOTE(@kitten): For backwards-compatibility, this is still called `project-root`, but it
// really is a replacement path for the current working directory. Henceforth called `commandRoot`
'--project-root <projectRoot>', 'The path to the root of the project. Defaults to current working directory', process.cwd());
}
const parseExtraArgumentsOptions = (args) => {
const cwd = process.cwd();
const platform = args.platform || undefined;
const commandRoot = resolvePathMaybe(args.projectRoot, cwd) || cwd;
const extraSearchPaths = (0, exports.filterMapSearchPaths)(args.searchPaths, commandRoot);
const extraExclude = args.exclude?.filter((name) => typeof name === 'string');
return {
platform,
commandRoot,
extraSearchPaths,
extraExclude,
};
};
const findPackageJsonPathAsync = async (commandRoot) => {
const root = commandRoot || process.cwd();
for (let dir = root; path_1.default.dirname(dir) !== dir; dir = path_1.default.dirname(dir)) {
const file = path_1.default.resolve(dir, 'package.json');
if (fs_1.default.existsSync(file)) {
return file;
}
}
throw new Error(`Couldn't find "package.json" up from path "${root}"`);
};
const loadPackageJSONAsync = async (packageJsonPath) => {
const packageJsonText = await fs_1.default.promises.readFile(packageJsonPath, 'utf8');
return JSON.parse(packageJsonText);
};
function createAutolinkingOptionsLoader(argumentsOptions) {
const extraArgumentsOptions = parseExtraArgumentsOptions(argumentsOptions ?? {});
const { commandRoot } = extraArgumentsOptions;
let _packageJsonPath$;
const getPackageJsonPath = () => {
return _packageJsonPath$ || (_packageJsonPath$ = findPackageJsonPathAsync(commandRoot));
};
let _packageJson$;
const getPackageJson = async () => _packageJson$ || (_packageJson$ = loadPackageJSONAsync(await getPackageJsonPath()));
const getAppRoot = async () => path_1.default.dirname(await getPackageJsonPath());
return {
getCommandRoot: () => commandRoot,
getAppRoot,
async getPlatformOptions(platform = extraArgumentsOptions.platform) {
const packageJson = await getPackageJson();
const appRoot = await getAppRoot();
const options = parsePackageJsonOptions(packageJson, appRoot, platform);
if (extraArgumentsOptions.extraSearchPaths) {
options.searchPaths = [
...extraArgumentsOptions.extraSearchPaths,
...(options.searchPaths ?? []),
];
}
if (extraArgumentsOptions.extraExclude) {
options.exclude = [...(options.exclude ?? []), ...extraArgumentsOptions.extraExclude];
}
return {
...normalizeAutolinkingOptions(options, appRoot),
platform,
};
},
};
}
const normalizeAutolinkingOptions = (options, appRoot) => {
return {
legacy_shallowReactNativeLinking: options.legacy_shallowReactNativeLinking ?? false,
searchPaths: options.searchPaths ?? [],
nativeModulesDir: options.nativeModulesDir
? (resolvePathMaybe(options.nativeModulesDir, appRoot) ?? null)
: (resolvePathMaybe('./modules', appRoot) ?? null),
exclude: options.exclude ?? [],
buildFromSource: options.buildFromSource,
flags: options.flags,
};
};
//# sourceMappingURL=autolinkingOptions.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,3 @@
import commander from 'commander';
/** Generates a source file listing all packages to link in the runtime */
export declare function generateModulesProviderCommand(cli: commander.CommanderStatic): commander.Command;

View File

@@ -0,0 +1,36 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateModulesProviderCommand = generateModulesProviderCommand;
const autolinkingOptions_1 = require("./autolinkingOptions");
const findModules_1 = require("../autolinking/findModules");
const generatePackageList_1 = require("../autolinking/generatePackageList");
const resolveModules_1 = require("../autolinking/resolveModules");
/** Generates a source file listing all packages to link in the runtime */
function generateModulesProviderCommand(cli) {
return (0, autolinkingOptions_1.registerAutolinkingArguments)(cli.command('generate-modules-provider [searchPaths...]'))
.option('-t, --target <path>', 'Path to the target file, where the package list should be written to.')
.option('--entitlement <path>', 'Path to the Apple code signing entitlements file.')
.option('-p, --packages <packages...>', 'Names of the packages to include in the generated modules provider.')
.option('--app-root <path>', 'Path to the app root directory.')
.action(async (searchPaths, commandArguments) => {
const platform = commandArguments.platform ?? 'apple';
const autolinkingOptionsLoader = (0, autolinkingOptions_1.createAutolinkingOptionsLoader)({
...commandArguments,
searchPaths,
});
const autolinkingOptions = await autolinkingOptionsLoader.getPlatformOptions(platform);
const expoModulesSearchResults = await (0, findModules_1.findModulesAsync)({
autolinkingOptions: await autolinkingOptionsLoader.getPlatformOptions(platform),
appRoot: commandArguments.appRoot ?? (await autolinkingOptionsLoader.getAppRoot()),
});
const expoModulesResolveResults = await (0, resolveModules_1.resolveModulesAsync)(expoModulesSearchResults, autolinkingOptions);
const includeModules = new Set(commandArguments.packages ?? []);
const filteredModules = expoModulesResolveResults.filter((module) => includeModules.has(module.packageName));
await (0, generatePackageList_1.generateModulesProviderAsync)(filteredModules, {
platform,
targetPath: commandArguments.target,
entitlementPath: commandArguments.entitlement ?? null,
});
});
}
//# sourceMappingURL=generateModulesProviderCommand.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"generateModulesProviderCommand.js","sourceRoot":"","sources":["../../src/commands/generateModulesProviderCommand.ts"],"names":[],"mappings":";;AAmBA,wEA0CC;AA3DD,6DAI8B;AAC9B,4DAA8D;AAC9D,4EAAkF;AAClF,kEAAoE;AASpE,0EAA0E;AAC1E,SAAgB,8BAA8B,CAAC,GAA8B;IAC3E,OAAO,IAAA,iDAA4B,EAAC,GAAG,CAAC,OAAO,CAAC,4CAA4C,CAAC,CAAC;SAC3F,MAAM,CACL,qBAAqB,EACrB,uEAAuE,CACxE;SACA,MAAM,CAAC,sBAAsB,EAAE,mDAAmD,CAAC;SACnF,MAAM,CACL,8BAA8B,EAC9B,qEAAqE,CACtE;SACA,MAAM,CAAC,mBAAmB,EAAE,iCAAiC,CAAC;SAC9D,MAAM,CACL,KAAK,EAAE,WAA4B,EAAE,gBAAkD,EAAE,EAAE;QACzF,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,IAAI,OAAO,CAAC;QACtD,MAAM,wBAAwB,GAAG,IAAA,mDAA8B,EAAC;YAC9D,GAAG,gBAAgB;YACnB,WAAW;SACZ,CAAC,CAAC;QACH,MAAM,kBAAkB,GAAG,MAAM,wBAAwB,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QAEvF,MAAM,wBAAwB,GAAG,MAAM,IAAA,8BAAgB,EAAC;YACtD,kBAAkB,EAAE,MAAM,wBAAwB,CAAC,kBAAkB,CAAC,QAAQ,CAAC;YAC/E,OAAO,EAAE,gBAAgB,CAAC,OAAO,IAAI,CAAC,MAAM,wBAAwB,CAAC,UAAU,EAAE,CAAC;SACnF,CAAC,CAAC;QACH,MAAM,yBAAyB,GAAG,MAAM,IAAA,oCAAmB,EACzD,wBAAwB,EACxB,kBAAkB,CACnB,CAAC;QAEF,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,gBAAgB,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;QAChE,MAAM,eAAe,GAAG,yBAAyB,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAClE,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CACvC,CAAC;QAEF,MAAM,IAAA,kDAA4B,EAAC,eAAe,EAAE;YAClD,QAAQ;YACR,UAAU,EAAE,gBAAgB,CAAC,MAAM;YACnC,eAAe,EAAE,gBAAgB,CAAC,WAAW,IAAI,IAAI;SACtD,CAAC,CAAC;IACL,CAAC,CACF,CAAC;AACN,CAAC","sourcesContent":["import commander from 'commander';\n\nimport {\n AutolinkingCommonArguments,\n createAutolinkingOptionsLoader,\n registerAutolinkingArguments,\n} from './autolinkingOptions';\nimport { findModulesAsync } from '../autolinking/findModules';\nimport { generateModulesProviderAsync } from '../autolinking/generatePackageList';\nimport { resolveModulesAsync } from '../autolinking/resolveModules';\n\ninterface GenerateModulesProviderArguments extends AutolinkingCommonArguments {\n target: string;\n entitlement?: string;\n packages?: string[] | null;\n appRoot?: string;\n}\n\n/** Generates a source file listing all packages to link in the runtime */\nexport function generateModulesProviderCommand(cli: commander.CommanderStatic) {\n return registerAutolinkingArguments(cli.command('generate-modules-provider [searchPaths...]'))\n .option(\n '-t, --target <path>',\n 'Path to the target file, where the package list should be written to.'\n )\n .option('--entitlement <path>', 'Path to the Apple code signing entitlements file.')\n .option(\n '-p, --packages <packages...>',\n 'Names of the packages to include in the generated modules provider.'\n )\n .option('--app-root <path>', 'Path to the app root directory.')\n .action(\n async (searchPaths: string[] | null, commandArguments: GenerateModulesProviderArguments) => {\n const platform = commandArguments.platform ?? 'apple';\n const autolinkingOptionsLoader = createAutolinkingOptionsLoader({\n ...commandArguments,\n searchPaths,\n });\n const autolinkingOptions = await autolinkingOptionsLoader.getPlatformOptions(platform);\n\n const expoModulesSearchResults = await findModulesAsync({\n autolinkingOptions: await autolinkingOptionsLoader.getPlatformOptions(platform),\n appRoot: commandArguments.appRoot ?? (await autolinkingOptionsLoader.getAppRoot()),\n });\n const expoModulesResolveResults = await resolveModulesAsync(\n expoModulesSearchResults,\n autolinkingOptions\n );\n\n const includeModules = new Set(commandArguments.packages ?? []);\n const filteredModules = expoModulesResolveResults.filter((module) =>\n includeModules.has(module.packageName)\n );\n\n await generateModulesProviderAsync(filteredModules, {\n platform,\n targetPath: commandArguments.target,\n entitlementPath: commandArguments.entitlement ?? null,\n });\n }\n );\n}\n"]}

View File

@@ -0,0 +1,3 @@
import commander from 'commander';
/** The react-native-config command (like RN CLI linking) */
export declare function reactNativeConfigCommand(cli: commander.CommanderStatic): commander.Command;

View File

@@ -0,0 +1,36 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.reactNativeConfigCommand = reactNativeConfigCommand;
const autolinkingOptions_1 = require("./autolinkingOptions");
const reactNativeConfig_1 = require("../reactNativeConfig");
/** The react-native-config command (like RN CLI linking) */
function reactNativeConfigCommand(cli) {
return (0, autolinkingOptions_1.registerAutolinkingArguments)(cli.command('react-native-config [searchPaths...]'))
.option('-p, --platform [platform]', 'The platform that the resulting modules must support. Available options: "android", "ios"', 'ios')
.option('--source-dir <sourceDir>', 'The path to the native source directory')
.option('-j, --json', 'Output results in the plain JSON format.', () => true, false)
.action(async (searchPaths, commandArguments) => {
// TODO(@kitten): Do we need to restrict this?
const platform = commandArguments.platform ?? 'ios';
if (platform !== 'android' && platform !== 'ios') {
throw new Error(`Unsupported platform: ${platform}`);
}
const autolinkingOptionsLoader = (0, autolinkingOptions_1.createAutolinkingOptionsLoader)({
...commandArguments,
searchPaths,
});
const reactNativeConfig = await (0, reactNativeConfig_1.createReactNativeConfigAsync)({
autolinkingOptions: await autolinkingOptionsLoader.getPlatformOptions(platform),
appRoot: await autolinkingOptionsLoader.getAppRoot(),
// NOTE(@kitten): This is currently not validated, and assumed to be validated later
sourceDir: commandArguments.sourceDir ?? undefined,
});
if (commandArguments.json) {
console.log(JSON.stringify(reactNativeConfig));
}
else {
console.log(require('util').inspect(reactNativeConfig, false, null, true));
}
});
}
//# sourceMappingURL=reactNativeConfigCommand.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"reactNativeConfigCommand.js","sourceRoot":"","sources":["../../src/commands/reactNativeConfigCommand.ts"],"names":[],"mappings":";;AAeA,4DAkCC;AA/CD,6DAI8B;AAC9B,4DAAoE;AAOpE,4DAA4D;AAC5D,SAAgB,wBAAwB,CAAC,GAA8B;IACrE,OAAO,IAAA,iDAA4B,EAAC,GAAG,CAAC,OAAO,CAAC,sCAAsC,CAAC,CAAC;SACrF,MAAM,CACL,2BAA2B,EAC3B,2FAA2F,EAC3F,KAAK,CACN;SACA,MAAM,CAAC,0BAA0B,EAAE,yCAAyC,CAAC;SAC7E,MAAM,CAAC,YAAY,EAAE,0CAA0C,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC;SACnF,MAAM,CAAC,KAAK,EAAE,WAA4B,EAAE,gBAA4C,EAAE,EAAE;QAC3F,8CAA8C;QAC9C,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,IAAI,KAAK,CAAC;QACpD,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;YACjD,MAAM,IAAI,KAAK,CAAC,yBAAyB,QAAQ,EAAE,CAAC,CAAC;QACvD,CAAC;QAED,MAAM,wBAAwB,GAAG,IAAA,mDAA8B,EAAC;YAC9D,GAAG,gBAAgB;YACnB,WAAW;SACZ,CAAC,CAAC;QAEH,MAAM,iBAAiB,GAAG,MAAM,IAAA,gDAA4B,EAAC;YAC3D,kBAAkB,EAAE,MAAM,wBAAwB,CAAC,kBAAkB,CAAC,QAAQ,CAAC;YAC/E,OAAO,EAAE,MAAM,wBAAwB,CAAC,UAAU,EAAE;YACpD,oFAAoF;YACpF,SAAS,EAAE,gBAAgB,CAAC,SAAS,IAAI,SAAS;SACnD,CAAC,CAAC;QAEH,IAAI,gBAAgB,CAAC,IAAI,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACjD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,iBAAiB,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QAC7E,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC","sourcesContent":["import commander from 'commander';\n\nimport {\n AutolinkingCommonArguments,\n createAutolinkingOptionsLoader,\n registerAutolinkingArguments,\n} from './autolinkingOptions';\nimport { createReactNativeConfigAsync } from '../reactNativeConfig';\n\ninterface ReactNativeConfigArguments extends AutolinkingCommonArguments {\n sourceDir?: string | null;\n json?: boolean | null;\n}\n\n/** The react-native-config command (like RN CLI linking) */\nexport function reactNativeConfigCommand(cli: commander.CommanderStatic) {\n return registerAutolinkingArguments(cli.command('react-native-config [searchPaths...]'))\n .option(\n '-p, --platform [platform]',\n 'The platform that the resulting modules must support. Available options: \"android\", \"ios\"',\n 'ios'\n )\n .option('--source-dir <sourceDir>', 'The path to the native source directory')\n .option('-j, --json', 'Output results in the plain JSON format.', () => true, false)\n .action(async (searchPaths: string[] | null, commandArguments: ReactNativeConfigArguments) => {\n // TODO(@kitten): Do we need to restrict this?\n const platform = commandArguments.platform ?? 'ios';\n if (platform !== 'android' && platform !== 'ios') {\n throw new Error(`Unsupported platform: ${platform}`);\n }\n\n const autolinkingOptionsLoader = createAutolinkingOptionsLoader({\n ...commandArguments,\n searchPaths,\n });\n\n const reactNativeConfig = await createReactNativeConfigAsync({\n autolinkingOptions: await autolinkingOptionsLoader.getPlatformOptions(platform),\n appRoot: await autolinkingOptionsLoader.getAppRoot(),\n // NOTE(@kitten): This is currently not validated, and assumed to be validated later\n sourceDir: commandArguments.sourceDir ?? undefined,\n });\n\n if (commandArguments.json) {\n console.log(JSON.stringify(reactNativeConfig));\n } else {\n console.log(require('util').inspect(reactNativeConfig, false, null, true));\n }\n });\n}\n"]}

View File

@@ -0,0 +1,3 @@
import commander from 'commander';
/** Searches for available expo modules and resolves the results for given platform. */
export declare function resolveCommand(cli: commander.CommanderStatic): commander.Command;

View File

@@ -0,0 +1,63 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveCommand = resolveCommand;
const autolinkingOptions_1 = require("./autolinkingOptions");
const findModules_1 = require("../autolinking/findModules");
const getConfiguration_1 = require("../autolinking/getConfiguration");
const resolveModules_1 = require("../autolinking/resolveModules");
function hasCoreFeatures(module) {
return module.coreFeatures !== undefined;
}
/** Searches for available expo modules and resolves the results for given platform. */
function resolveCommand(cli) {
return (0, autolinkingOptions_1.registerAutolinkingArguments)(cli.command('resolve [searchPaths...]'))
.option('-j, --json', 'Output results in the plain JSON format.', () => true, false)
.action(async (searchPaths, commandArguments) => {
const platform = commandArguments.platform ?? 'apple';
const autolinkingOptionsLoader = (0, autolinkingOptions_1.createAutolinkingOptionsLoader)({
...commandArguments,
searchPaths,
});
const autolinkingOptions = await autolinkingOptionsLoader.getPlatformOptions(platform);
const appRoot = await autolinkingOptionsLoader.getAppRoot();
const expoModulesSearchResults = await (0, findModules_1.findModulesAsync)({
autolinkingOptions,
appRoot,
});
const expoModulesResolveResults = await (0, resolveModules_1.resolveModulesAsync)(expoModulesSearchResults, autolinkingOptions);
const extraDependencies = await (0, resolveModules_1.resolveExtraBuildDependenciesAsync)({
commandRoot: autolinkingOptionsLoader.getCommandRoot(),
platform,
});
const configuration = (0, getConfiguration_1.getConfiguration)({ autolinkingOptions });
const coreFeatures = [
...expoModulesResolveResults.reduce((acc, module) => {
if (hasCoreFeatures(module)) {
const features = module.coreFeatures ?? [];
for (const feature of features) {
acc.add(feature);
}
return acc;
}
return acc;
}, new Set()),
];
if (commandArguments.json) {
console.log(JSON.stringify({
extraDependencies,
coreFeatures,
modules: expoModulesResolveResults,
...(configuration ? { configuration } : {}),
}));
}
else {
console.log(require('util').inspect({
extraDependencies,
coreFeatures,
modules: expoModulesResolveResults,
...(configuration ? { configuration } : {}),
}, false, null, true));
}
});
}
//# sourceMappingURL=resolveCommand.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,2 @@
import commander from 'commander';
export declare function searchCommand(cli: commander.CommanderStatic): commander.Command;

View File

@@ -0,0 +1,27 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.searchCommand = searchCommand;
const autolinkingOptions_1 = require("./autolinkingOptions");
const findModules_1 = require("../autolinking/findModules");
function searchCommand(cli) {
return (0, autolinkingOptions_1.registerAutolinkingArguments)(cli.command('search [searchPaths...]'))
.option('-j, --json', 'Output results in the plain JSON format.', () => true, false)
.action(async (searchPaths, commandArguments) => {
const platform = commandArguments.platform ?? 'apple';
const autolinkingOptionsLoader = (0, autolinkingOptions_1.createAutolinkingOptionsLoader)({
...commandArguments,
searchPaths,
});
const expoModulesSearchResults = await (0, findModules_1.findModulesAsync)({
autolinkingOptions: await autolinkingOptionsLoader.getPlatformOptions(platform),
appRoot: await autolinkingOptionsLoader.getAppRoot(),
});
if (commandArguments.json) {
console.log(JSON.stringify(expoModulesSearchResults));
}
else {
console.log(require('util').inspect(expoModulesSearchResults, false, null, true));
}
});
}
//# sourceMappingURL=searchCommand.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"searchCommand.js","sourceRoot":"","sources":["../../src/commands/searchCommand.ts"],"names":[],"mappings":";;AAaA,sCAqBC;AAhCD,6DAI8B;AAC9B,4DAA8D;AAM9D,SAAgB,aAAa,CAAC,GAA8B;IAC1D,OAAO,IAAA,iDAA4B,EAAC,GAAG,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC;SACxE,MAAM,CAAC,YAAY,EAAE,0CAA0C,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC;SACnF,MAAM,CAAC,KAAK,EAAE,WAA4B,EAAE,gBAAiC,EAAE,EAAE;QAChF,MAAM,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,IAAI,OAAO,CAAC;QACtD,MAAM,wBAAwB,GAAG,IAAA,mDAA8B,EAAC;YAC9D,GAAG,gBAAgB;YACnB,WAAW;SACZ,CAAC,CAAC;QAEH,MAAM,wBAAwB,GAAG,MAAM,IAAA,8BAAgB,EAAC;YACtD,kBAAkB,EAAE,MAAM,wBAAwB,CAAC,kBAAkB,CAAC,QAAQ,CAAC;YAC/E,OAAO,EAAE,MAAM,wBAAwB,CAAC,UAAU,EAAE;SACrD,CAAC,CAAC;QAEH,IAAI,gBAAgB,CAAC,IAAI,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAC,CAAC;QACxD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,wBAAwB,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QACpF,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC","sourcesContent":["import commander from 'commander';\n\nimport {\n AutolinkingCommonArguments,\n createAutolinkingOptionsLoader,\n registerAutolinkingArguments,\n} from './autolinkingOptions';\nimport { findModulesAsync } from '../autolinking/findModules';\n\ninterface SearchArguments extends AutolinkingCommonArguments {\n json?: boolean | null;\n}\n\nexport function searchCommand(cli: commander.CommanderStatic) {\n return registerAutolinkingArguments(cli.command('search [searchPaths...]'))\n .option('-j, --json', 'Output results in the plain JSON format.', () => true, false)\n .action(async (searchPaths: string[] | null, commandArguments: SearchArguments) => {\n const platform = commandArguments.platform ?? 'apple';\n const autolinkingOptionsLoader = createAutolinkingOptionsLoader({\n ...commandArguments,\n searchPaths,\n });\n\n const expoModulesSearchResults = await findModulesAsync({\n autolinkingOptions: await autolinkingOptionsLoader.getPlatformOptions(platform),\n appRoot: await autolinkingOptionsLoader.getAppRoot(),\n });\n\n if (commandArguments.json) {\n console.log(JSON.stringify(expoModulesSearchResults));\n } else {\n console.log(require('util').inspect(expoModulesSearchResults, false, null, true));\n }\n });\n}\n"]}

View File

@@ -0,0 +1,13 @@
import commander from 'commander';
import { type ResolutionResult } from '../dependencies';
export declare function verifyCommand(cli: commander.CommanderStatic): commander.Command;
interface VerifyOptions {
appRoot: string;
verbose?: boolean;
json?: boolean;
}
/**
* Verifies the search results by checking whether there are no duplicates.
*/
export declare function verifySearchResults(results: ResolutionResult, options: VerifyOptions): Promise<void>;
export {};

View File

@@ -0,0 +1,125 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.verifyCommand = verifyCommand;
exports.verifySearchResults = verifySearchResults;
const chalk_1 = __importDefault(require("chalk"));
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const autolinkingOptions_1 = require("./autolinkingOptions");
const dependencies_1 = require("../dependencies");
// NOTE(@kitten): These are excluded explicitly, but we want to include them for the verify command explicitly
const INCLUDE_PACKAGES = ['react-native', 'react-native-tvos'];
function verifyCommand(cli) {
return (0, autolinkingOptions_1.registerAutolinkingArguments)(cli.command('verify'))
.option('-v, --verbose', 'Output all results instead of just warnings.', () => true, false)
.option('-j, --json', 'Output results in the plain JSON format.', () => true, false)
.option('-p, --platform [platform]', 'The platform to validate native modules for. Available options: "android", "ios", "both"', 'both')
.action(async (commandArguments) => {
const platforms = commandArguments.platform === 'both' ? ['android', 'ios'] : [commandArguments.platform];
const autolinkingOptionsLoader = (0, autolinkingOptions_1.createAutolinkingOptionsLoader)(commandArguments);
const appRoot = await autolinkingOptionsLoader.getAppRoot();
const linker = (0, dependencies_1.makeCachedDependenciesLinker)({ projectRoot: appRoot });
const results = (0, dependencies_1.mergeResolutionResults)(await Promise.all(platforms.map((platform) => (0, dependencies_1.scanDependencyResolutionsForPlatform)(linker, platform, INCLUDE_PACKAGES))));
await verifySearchResults(results, {
appRoot,
verbose: !!commandArguments.verbose,
json: !!commandArguments.json,
});
});
}
/**
* Verifies the search results by checking whether there are no duplicates.
*/
async function verifySearchResults(results, options) {
const { appRoot } = options;
async function getHumanReadableDependency(dependency) {
let version = dependency.version || null;
if (!version) {
try {
const pkgContents = await fs_1.default.promises.readFile(path_1.default.join(dependency.path, 'package.json'), 'utf8');
const pkg = JSON.parse(pkgContents);
if (pkg && typeof pkg === 'object' && 'version' in pkg && typeof pkg.version === 'string') {
version = pkg.version;
}
}
catch (error) {
version = null;
}
}
const relative = path_1.default.relative(appRoot, dependency.originPath);
return version
? `${dependency.name}@${version} (at: ${relative})`
: `${dependency.name} at: ${relative}`;
}
const groups = {
reactNativeProjectConfig: [],
searchPaths: [],
dependencies: [],
duplicates: [],
};
for (const moduleName in results) {
const revision = results[moduleName];
if (!revision) {
continue;
}
else if (revision.duplicates?.length) {
groups.duplicates.push(revision);
}
else {
switch (revision.source) {
case 2 /* DependencyResolutionSource.RN_CLI_LOCAL */:
groups.reactNativeProjectConfig.push(revision);
break;
case 1 /* DependencyResolutionSource.SEARCH_PATH */:
groups.searchPaths.push(revision);
break;
case 0 /* DependencyResolutionSource.RECURSIVE_RESOLUTION */:
groups.dependencies.push(revision);
break;
}
}
}
if (options.json) {
console.log(JSON.stringify(groups));
return;
}
if (options.verbose) {
const sortResolutions = (resolutions) => [...resolutions].sort((a, b) => a.name.localeCompare(b.name));
if (groups.reactNativeProjectConfig.length) {
console.log(`🔎 Found ${groups.reactNativeProjectConfig.length} modules from React Native project config`);
for (const revision of sortResolutions(groups.reactNativeProjectConfig)) {
console.log(` - ${await getHumanReadableDependency(revision)}`);
}
}
if (groups.searchPaths.length) {
console.log(`🔎 Found ${groups.searchPaths.length} modules in search paths`);
for (const revision of sortResolutions(groups.searchPaths)) {
console.log(` - ${await getHumanReadableDependency(revision)}`);
}
}
console.log(`🔎 Found ${groups.dependencies.length} modules in dependencies`);
for (const revision of sortResolutions(groups.dependencies)) {
console.log(` - ${await getHumanReadableDependency(revision)}`);
}
}
if (groups.duplicates.length) {
for (const revision of groups.duplicates) {
console.warn(`⚠️ Found duplicate installations for ${chalk_1.default.green(revision.name)}`);
const revisions = [revision, ...(revision.duplicates ?? [])];
for (let idx = 0; idx < revisions.length; idx++) {
const prefix = idx !== revisions.length - 1 ? '├─' : '└─';
const duplicate = revisions[idx];
console.log(` ${prefix} ${await getHumanReadableDependency(duplicate)}`);
}
}
console.warn('⚠️ Multiple versions of the same module may introduce some side effects or compatibility issues.\n' +
`Resolve your dependency issues and deduplicate your dependencies. Learn more: https://expo.fyi/resolving-dependency-issues`);
}
else {
console.log('✅ Everything is fine!');
}
}
//# sourceMappingURL=verifyCommand.js.map

File diff suppressed because one or more lines are too long