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,88 @@
import { AndroidGradleAarProjectDescriptor, AndroidGradlePluginDescriptor, AndroidPublication, RawExpoModuleConfig, RawModuleConfigApple, SupportedPlatform } from './types';
export declare class ExpoAndroidModuleConfig {
classifier: string;
name: string | null;
constructor(classifier: string, name: string | null);
}
export declare class ExpoAndroidProjectConfig {
name: string;
path: string;
modules?: ExpoAndroidModuleConfig[] | undefined;
services?: string[] | undefined;
publication?: AndroidPublication | undefined;
gradleAarProjects?: AndroidGradleAarProjectDescriptor[] | undefined;
shouldUsePublicationScriptPath?: string | undefined;
/**
* Whether this project is the root one.
*/
isDefault: boolean;
constructor(name: string, path: string, modules?: ExpoAndroidModuleConfig[] | undefined, services?: string[] | undefined, publication?: AndroidPublication | undefined, gradleAarProjects?: AndroidGradleAarProjectDescriptor[] | undefined, shouldUsePublicationScriptPath?: string | undefined,
/**
* Whether this project is the root one.
*/
isDefault?: boolean);
}
/**
* A class that wraps the raw config (`expo-module.json` or `unimodule.json`).
*/
export declare class ExpoModuleConfig {
readonly rawConfig: RawExpoModuleConfig;
constructor(rawConfig: RawExpoModuleConfig);
/**
* Whether the module supports given platform.
*/
supportsPlatform(platform: SupportedPlatform): boolean;
/**
* Returns the generic config for all Apple platforms with a fallback to the legacy iOS config.
*/
getAppleConfig(): RawModuleConfigApple | null;
/**
* Returns a list of names of Swift native modules classes to put to the generated modules provider file.
*/
appleModules(): (string | import("./types").RawAppleModuleConfig)[];
/**
* Returns a list of names of Swift classes that receives AppDelegate life-cycle events.
*/
appleAppDelegateSubscribers(): string[];
/**
* Returns a list of names of Swift classes that implement `ExpoReactDelegateHandler`.
*/
appleReactDelegateHandlers(): string[];
/**
* Returns podspec paths defined by the module author.
*/
applePodspecPaths(): string[];
/**
* Returns the product module names, if defined by the module author.
*/
appleSwiftModuleNames(): string[];
/**
* Returns whether this module will be added only to the debug configuration
*/
appleDebugOnly(): boolean;
/**
* Returns information about Android projects defined by the module author.
*/
androidProjects(defaultProjectName: string): ExpoAndroidProjectConfig[];
/**
* Returns gradle plugins descriptors defined by the module author.
*/
androidGradlePlugins(): AndroidGradlePluginDescriptor[];
/**
* Returns gradle projects containing AAR files defined by the module author.
*/
androidGradleAarProjects(): AndroidGradleAarProjectDescriptor[];
/**
* Returns the publication config for Android.
*/
androidPublication(): AndroidPublication | undefined;
/**
* Returns core features required by the module author.
*/
coreFeatures(): string[];
/**
* Returns serializable raw config.
*/
toJSON(): RawExpoModuleConfig;
}
export declare const discoverExpoModuleConfigAsync: import("./memoize").MemoizableAsyncFn<any[], ExpoModuleConfig | null>;

View File

@@ -0,0 +1,194 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.discoverExpoModuleConfigAsync = exports.ExpoModuleConfig = exports.ExpoAndroidProjectConfig = exports.ExpoAndroidModuleConfig = void 0;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const memoize_1 = require("./memoize");
function arrayize(value) {
if (Array.isArray(value)) {
return value;
}
return value != null ? [value] : [];
}
class ExpoAndroidModuleConfig {
classifier;
name;
constructor(classifier, name) {
this.classifier = classifier;
this.name = name;
}
}
exports.ExpoAndroidModuleConfig = ExpoAndroidModuleConfig;
class ExpoAndroidProjectConfig {
name;
path;
modules;
services;
publication;
gradleAarProjects;
shouldUsePublicationScriptPath;
isDefault;
constructor(name, path, modules, services, publication, gradleAarProjects, shouldUsePublicationScriptPath,
/**
* Whether this project is the root one.
*/
isDefault = false) {
this.name = name;
this.path = path;
this.modules = modules;
this.services = services;
this.publication = publication;
this.gradleAarProjects = gradleAarProjects;
this.shouldUsePublicationScriptPath = shouldUsePublicationScriptPath;
this.isDefault = isDefault;
}
}
exports.ExpoAndroidProjectConfig = ExpoAndroidProjectConfig;
/**
* A class that wraps the raw config (`expo-module.json` or `unimodule.json`).
*/
class ExpoModuleConfig {
rawConfig;
constructor(rawConfig) {
this.rawConfig = rawConfig;
}
/**
* Whether the module supports given platform.
*/
supportsPlatform(platform) {
const supportedPlatforms = this.rawConfig.platforms ?? [];
if (platform === 'web') {
// Web platform is implicitly supported for autolinking resolution but has no special behavior
return true;
}
else if (platform === 'apple') {
// Apple platform is supported when any of iOS, macOS and tvOS is supported.
return supportedPlatforms.some((supportedPlatform) => {
return ['apple', 'ios', 'macos', 'tvos'].includes(supportedPlatform);
});
}
switch (platform) {
case 'ios':
case 'macos':
case 'tvos':
// ios|macos|tvos are supported when the module supports "apple" as a platform in general
return supportedPlatforms.includes(platform) || supportedPlatforms.includes('apple');
default:
return supportedPlatforms.includes(platform);
}
}
/**
* Returns the generic config for all Apple platforms with a fallback to the legacy iOS config.
*/
getAppleConfig() {
return this.rawConfig.apple ?? this.rawConfig.ios ?? null;
}
/**
* Returns a list of names of Swift native modules classes to put to the generated modules provider file.
*/
appleModules() {
const appleConfig = this.getAppleConfig();
return appleConfig?.modules ?? [];
}
/**
* Returns a list of names of Swift classes that receives AppDelegate life-cycle events.
*/
appleAppDelegateSubscribers() {
return this.getAppleConfig()?.appDelegateSubscribers ?? [];
}
/**
* Returns a list of names of Swift classes that implement `ExpoReactDelegateHandler`.
*/
appleReactDelegateHandlers() {
return this.getAppleConfig()?.reactDelegateHandlers ?? [];
}
/**
* Returns podspec paths defined by the module author.
*/
applePodspecPaths() {
return arrayize(this.getAppleConfig()?.podspecPath);
}
/**
* Returns the product module names, if defined by the module author.
*/
appleSwiftModuleNames() {
return arrayize(this.getAppleConfig()?.swiftModuleName);
}
/**
* Returns whether this module will be added only to the debug configuration
*/
appleDebugOnly() {
return this.getAppleConfig()?.debugOnly ?? false;
}
/**
* Returns information about Android projects defined by the module author.
*/
androidProjects(defaultProjectName) {
const androidProjects = [];
// Adding the "root" Android project - it might not be valide.
androidProjects.push(new ExpoAndroidProjectConfig(this.rawConfig.android?.name ?? defaultProjectName, this.rawConfig.android?.path ?? 'android', this.rawConfig.android?.modules?.map((module) => typeof module === 'string'
? new ExpoAndroidModuleConfig(module, null)
: new ExpoAndroidModuleConfig(module.class, module.name)), this.rawConfig.android?.services, this.rawConfig.android?.publication, this.rawConfig.android?.gradleAarProjects, this.rawConfig.android?.shouldUsePublicationScriptPath, !this.rawConfig.android?.path // it's default project because path is not defined
));
this.rawConfig.android?.projects?.forEach((project) => {
androidProjects.push(new ExpoAndroidProjectConfig(project.name, project.path, project.modules?.map((module) => typeof module === 'string'
? new ExpoAndroidModuleConfig(module, null)
: new ExpoAndroidModuleConfig(module.class, module.name)), project.services, project.publication, project.gradleAarProjects, project.shouldUsePublicationScriptPath));
});
return androidProjects;
}
/**
* Returns gradle plugins descriptors defined by the module author.
*/
androidGradlePlugins() {
return arrayize(this.rawConfig.android?.gradlePlugins ?? []);
}
/**
* Returns gradle projects containing AAR files defined by the module author.
*/
androidGradleAarProjects() {
return arrayize(this.rawConfig.android?.gradleAarProjects ?? []);
}
/**
* Returns the publication config for Android.
*/
androidPublication() {
return this.rawConfig.android?.publication;
}
/**
* Returns core features required by the module author.
*/
coreFeatures() {
return arrayize(this.rawConfig.coreFeatures ?? []);
}
/**
* Returns serializable raw config.
*/
toJSON() {
return this.rawConfig;
}
}
exports.ExpoModuleConfig = ExpoModuleConfig;
/** Names of Expo Module config files (highest to lowest priority) */
const EXPO_MODULE_CONFIG_FILENAMES = ['expo-module.config.json', 'unimodule.json'];
exports.discoverExpoModuleConfigAsync = (0, memoize_1.memoize)(async function discoverExpoModuleConfigAsync(directoryPath) {
for (let idx = 0; idx < EXPO_MODULE_CONFIG_FILENAMES.length; idx++) {
// TODO: Validate the raw config against a schema.
// TODO: Support for `*.js` files, not only static `*.json`.
const targetPath = path_1.default.join(directoryPath, EXPO_MODULE_CONFIG_FILENAMES[idx]);
let text;
try {
text = await fs_1.default.promises.readFile(targetPath, 'utf8');
}
catch {
// try the next file
continue;
}
return new ExpoModuleConfig(JSON.parse(text));
}
return null;
});
//# sourceMappingURL=ExpoModuleConfig.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,13 @@
import { AutolinkingOptions } from '../commands/autolinkingOptions';
import { type DependencyResolution } from '../dependencies';
import { PackageRevision, SearchResults, SupportedPlatform } from '../types';
export declare function resolveExpoModule(resolution: DependencyResolution, platform: SupportedPlatform, excludeNames: Set<string>): Promise<PackageRevision | null>;
interface FindModulesParams {
appRoot: string;
autolinkingOptions: AutolinkingOptions & {
platform: SupportedPlatform;
};
}
/** Searches for modules to link based on given config. */
export declare function findModulesAsync({ appRoot, autolinkingOptions, }: FindModulesParams): Promise<SearchResults>;
export {};

View File

@@ -0,0 +1,45 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveExpoModule = resolveExpoModule;
exports.findModulesAsync = findModulesAsync;
const ExpoModuleConfig_1 = require("../ExpoModuleConfig");
const dependencies_1 = require("../dependencies");
const memoize_1 = require("../memoize");
async function resolveExpoModule(resolution, platform, excludeNames) {
if (excludeNames.has(resolution.name)) {
return null;
}
const expoModuleConfig = await (0, ExpoModuleConfig_1.discoverExpoModuleConfigAsync)(resolution.path);
if (expoModuleConfig && expoModuleConfig.supportsPlatform(platform)) {
return {
name: resolution.name,
path: resolution.path,
version: resolution.version,
config: expoModuleConfig,
duplicates: resolution.duplicates?.map((duplicate) => ({
name: duplicate.name,
path: duplicate.path,
version: duplicate.version,
})) ?? [],
};
}
else {
return null;
}
}
/** Searches for modules to link based on given config. */
async function findModulesAsync({ appRoot, autolinkingOptions, }) {
const memoizer = (0, memoize_1.createMemoizer)();
const excludeNames = new Set(autolinkingOptions.exclude);
// custom native modules should be resolved first so that they can override other modules
const searchPaths = autolinkingOptions.nativeModulesDir
? [autolinkingOptions.nativeModulesDir, ...autolinkingOptions.searchPaths]
: autolinkingOptions.searchPaths;
return memoizer.withMemoizer(async () => {
return (0, dependencies_1.filterMapResolutionResult)((0, dependencies_1.mergeResolutionResults)(await Promise.all([
...searchPaths.map((searchPath) => (0, dependencies_1.scanDependenciesInSearchPath)(searchPath)),
(0, dependencies_1.scanDependenciesRecursively)(appRoot),
])), (resolution) => resolveExpoModule(resolution, autolinkingOptions.platform, excludeNames));
});
}
//# sourceMappingURL=findModules.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"findModules.js","sourceRoot":"","sources":["../../src/autolinking/findModules.ts"],"names":[],"mappings":";;AAYA,8CAyBC;AAQD,4CAuBC;AApED,0DAAoE;AAEpE,kDAMyB;AACzB,wCAA4C;AAGrC,KAAK,UAAU,iBAAiB,CACrC,UAAgC,EAChC,QAA2B,EAC3B,YAAyB;IAEzB,IAAI,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,gBAAgB,GAAG,MAAM,IAAA,gDAA6B,EAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAC9E,IAAI,gBAAgB,IAAI,gBAAgB,CAAC,gBAAgB,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpE,OAAO;YACL,IAAI,EAAE,UAAU,CAAC,IAAI;YACrB,IAAI,EAAE,UAAU,CAAC,IAAI;YACrB,OAAO,EAAE,UAAU,CAAC,OAAO;YAC3B,MAAM,EAAE,gBAAgB;YACxB,UAAU,EACR,UAAU,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;gBACzC,IAAI,EAAE,SAAS,CAAC,IAAI;gBACpB,IAAI,EAAE,SAAS,CAAC,IAAI;gBACpB,OAAO,EAAE,SAAS,CAAC,OAAO;aAC3B,CAAC,CAAC,IAAI,EAAE;SACZ,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAOD,0DAA0D;AACnD,KAAK,UAAU,gBAAgB,CAAC,EACrC,OAAO,EACP,kBAAkB,GACA;IAClB,MAAM,QAAQ,GAAG,IAAA,wBAAc,GAAE,CAAC;IAClC,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAEzD,yFAAyF;IACzF,MAAM,WAAW,GAAG,kBAAkB,CAAC,gBAAgB;QACrD,CAAC,CAAC,CAAC,kBAAkB,CAAC,gBAAgB,EAAE,GAAG,kBAAkB,CAAC,WAAW,CAAC;QAC1E,CAAC,CAAC,kBAAkB,CAAC,WAAW,CAAC;IAEnC,OAAO,QAAQ,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE;QACtC,OAAO,IAAA,wCAAyB,EAC9B,IAAA,qCAAsB,EACpB,MAAM,OAAO,CAAC,GAAG,CAAC;YAChB,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,IAAA,2CAA4B,EAAC,UAAU,CAAC,CAAC;YAC5E,IAAA,0CAA2B,EAAC,OAAO,CAAC;SACrC,CAAC,CACH,EACD,CAAC,UAAU,EAAE,EAAE,CAAC,iBAAiB,CAAC,UAAU,EAAE,kBAAkB,CAAC,QAAQ,EAAE,YAAY,CAAC,CACzF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { discoverExpoModuleConfigAsync } from '../ExpoModuleConfig';\nimport { AutolinkingOptions } from '../commands/autolinkingOptions';\nimport {\n type DependencyResolution,\n scanDependenciesRecursively,\n scanDependenciesInSearchPath,\n filterMapResolutionResult,\n mergeResolutionResults,\n} from '../dependencies';\nimport { createMemoizer } from '../memoize';\nimport { PackageRevision, SearchResults, SupportedPlatform } from '../types';\n\nexport async function resolveExpoModule(\n resolution: DependencyResolution,\n platform: SupportedPlatform,\n excludeNames: Set<string>\n): Promise<PackageRevision | null> {\n if (excludeNames.has(resolution.name)) {\n return null;\n }\n const expoModuleConfig = await discoverExpoModuleConfigAsync(resolution.path);\n if (expoModuleConfig && expoModuleConfig.supportsPlatform(platform)) {\n return {\n name: resolution.name,\n path: resolution.path,\n version: resolution.version,\n config: expoModuleConfig,\n duplicates:\n resolution.duplicates?.map((duplicate) => ({\n name: duplicate.name,\n path: duplicate.path,\n version: duplicate.version,\n })) ?? [],\n };\n } else {\n return null;\n }\n}\n\ninterface FindModulesParams {\n appRoot: string;\n autolinkingOptions: AutolinkingOptions & { platform: SupportedPlatform };\n}\n\n/** Searches for modules to link based on given config. */\nexport async function findModulesAsync({\n appRoot,\n autolinkingOptions,\n}: FindModulesParams): Promise<SearchResults> {\n const memoizer = createMemoizer();\n const excludeNames = new Set(autolinkingOptions.exclude);\n\n // custom native modules should be resolved first so that they can override other modules\n const searchPaths = autolinkingOptions.nativeModulesDir\n ? [autolinkingOptions.nativeModulesDir, ...autolinkingOptions.searchPaths]\n : autolinkingOptions.searchPaths;\n\n return memoizer.withMemoizer(async () => {\n return filterMapResolutionResult(\n mergeResolutionResults(\n await Promise.all([\n ...searchPaths.map((searchPath) => scanDependenciesInSearchPath(searchPath)),\n scanDependenciesRecursively(appRoot),\n ])\n ),\n (resolution) => resolveExpoModule(resolution, autolinkingOptions.platform, excludeNames)\n );\n });\n}\n"]}

View File

@@ -0,0 +1,10 @@
import { ModuleDescriptor, SupportedPlatform } from '../types';
interface GenerateModulesProviderParams {
platform: SupportedPlatform;
targetPath: string;
entitlementPath: string | null;
}
/** Generates ExpoModulesProvider file listing all packages to link (Apple-only)
*/
export declare function generateModulesProviderAsync(modules: ModuleDescriptor[], params: GenerateModulesProviderParams): Promise<void>;
export {};

View File

@@ -0,0 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateModulesProviderAsync = generateModulesProviderAsync;
const platforms_1 = require("../platforms");
/** Generates ExpoModulesProvider file listing all packages to link (Apple-only)
*/
async function generateModulesProviderAsync(modules, params) {
const platformLinking = (0, platforms_1.getLinkingImplementationForPlatform)(params.platform);
if (!('generateModulesProviderAsync' in platformLinking)) {
throw new Error(`Generating modules provider is not available for platform "${params.platform}"`);
}
await platformLinking.generateModulesProviderAsync(modules, params.targetPath, params.entitlementPath);
}
//# sourceMappingURL=generatePackageList.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"generatePackageList.js","sourceRoot":"","sources":["../../src/autolinking/generatePackageList.ts"],"names":[],"mappings":";;AAWA,oEAeC;AA1BD,4CAAmE;AASnE;GACG;AACI,KAAK,UAAU,4BAA4B,CAChD,OAA2B,EAC3B,MAAqC;IAErC,MAAM,eAAe,GAAG,IAAA,+CAAmC,EAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC7E,IAAI,CAAC,CAAC,8BAA8B,IAAI,eAAe,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,KAAK,CACb,8DAA8D,MAAM,CAAC,QAAQ,GAAG,CACjF,CAAC;IACJ,CAAC;IACD,MAAM,eAAe,CAAC,4BAA4B,CAChD,OAAgC,EAChC,MAAM,CAAC,UAAU,EACjB,MAAM,CAAC,eAAe,CACvB,CAAC;AACJ,CAAC","sourcesContent":["import { getLinkingImplementationForPlatform } from '../platforms';\nimport { ModuleDescriptor, ModuleDescriptorIos, SupportedPlatform } from '../types';\n\ninterface GenerateModulesProviderParams {\n platform: SupportedPlatform;\n targetPath: string;\n entitlementPath: string | null;\n}\n\n/** Generates ExpoModulesProvider file listing all packages to link (Apple-only)\n */\nexport async function generateModulesProviderAsync(\n modules: ModuleDescriptor[],\n params: GenerateModulesProviderParams\n) {\n const platformLinking = getLinkingImplementationForPlatform(params.platform);\n if (!('generateModulesProviderAsync' in platformLinking)) {\n throw new Error(\n `Generating modules provider is not available for platform \"${params.platform}\"`\n );\n }\n await platformLinking.generateModulesProviderAsync(\n modules as ModuleDescriptorIos[],\n params.targetPath,\n params.entitlementPath\n );\n}\n"]}

View File

@@ -0,0 +1,9 @@
import { AutolinkingOptions } from '../commands/autolinkingOptions';
import type { SupportedPlatform } from '../types';
interface GetConfigurationParams {
autolinkingOptions: AutolinkingOptions & {
platform: SupportedPlatform;
};
}
export declare function getConfiguration({ autolinkingOptions, }: GetConfigurationParams): Record<string, any> | undefined;
export {};

View File

@@ -0,0 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getConfiguration = getConfiguration;
const platforms_1 = require("../platforms");
function getConfiguration({ autolinkingOptions, }) {
const platformLinking = (0, platforms_1.getLinkingImplementationForPlatform)(autolinkingOptions.platform);
if ('getConfiguration' in platformLinking) {
return platformLinking.getConfiguration(autolinkingOptions);
}
else {
return undefined;
}
}
//# sourceMappingURL=getConfiguration.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"getConfiguration.js","sourceRoot":"","sources":["../../src/autolinking/getConfiguration.ts"],"names":[],"mappings":";;AAQA,4CASC;AAhBD,4CAAmE;AAOnE,SAAgB,gBAAgB,CAAC,EAC/B,kBAAkB,GACK;IACvB,MAAM,eAAe,GAAG,IAAA,+CAAmC,EAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IACzF,IAAI,kBAAkB,IAAI,eAAe,EAAE,CAAC;QAC1C,OAAO,eAAe,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,CAAC;IAC9D,CAAC;SAAM,CAAC;QACN,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC","sourcesContent":["import { AutolinkingOptions } from '../commands/autolinkingOptions';\nimport { getLinkingImplementationForPlatform } from '../platforms';\nimport type { SupportedPlatform } from '../types';\n\ninterface GetConfigurationParams {\n autolinkingOptions: AutolinkingOptions & { platform: SupportedPlatform };\n}\n\nexport function getConfiguration({\n autolinkingOptions,\n}: GetConfigurationParams): Record<string, any> | undefined {\n const platformLinking = getLinkingImplementationForPlatform(autolinkingOptions.platform);\n if ('getConfiguration' in platformLinking) {\n return platformLinking.getConfiguration(autolinkingOptions);\n } else {\n return undefined;\n }\n}\n"]}

View File

@@ -0,0 +1,23 @@
import { AutolinkingOptions } from '../commands/autolinkingOptions';
import { ExtraDependencies, ModuleDescriptor, SearchResults, SupportedPlatform } from '../types';
export { getConfiguration } from './getConfiguration';
export { generateModulesProviderAsync } from './generatePackageList';
/** @deprecated */
export interface SearchOptions extends Partial<AutolinkingOptions> {
projectRoot: string;
platform: SupportedPlatform;
[extra: string]: unknown;
}
/** @deprecated */
export interface ResolveOptions {
projectRoot: string;
platform: SupportedPlatform;
[extra: string]: unknown;
}
/** @deprecated */
declare function apiFindModulesAsync(providedOptions: SearchOptions): Promise<SearchResults>;
/** @deprecated */
declare function apiResolveExtraBuildDependenciesAsync(providedOptions: ResolveOptions): Promise<ExtraDependencies>;
/** @deprecated */
declare function apiResolveModulesAsync(searchResults: SearchResults, providedOptions: SearchOptions): Promise<ModuleDescriptor[]>;
export { apiFindModulesAsync as findModulesAsync, apiResolveExtraBuildDependenciesAsync as resolveExtraBuildDependenciesAsync, apiResolveModulesAsync as resolveModulesAsync, };

View File

@@ -0,0 +1,34 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateModulesProviderAsync = exports.getConfiguration = void 0;
exports.findModulesAsync = apiFindModulesAsync;
exports.resolveExtraBuildDependenciesAsync = apiResolveExtraBuildDependenciesAsync;
exports.resolveModulesAsync = apiResolveModulesAsync;
const autolinkingOptions_1 = require("../commands/autolinkingOptions");
const findModules_1 = require("./findModules");
const resolveModules_1 = require("./resolveModules");
var getConfiguration_1 = require("./getConfiguration");
Object.defineProperty(exports, "getConfiguration", { enumerable: true, get: function () { return getConfiguration_1.getConfiguration; } });
var generatePackageList_1 = require("./generatePackageList");
Object.defineProperty(exports, "generateModulesProviderAsync", { enumerable: true, get: function () { return generatePackageList_1.generateModulesProviderAsync; } });
/** @deprecated */
async function apiFindModulesAsync(providedOptions) {
const autolinkingOptionsLoader = (0, autolinkingOptions_1.createAutolinkingOptionsLoader)(providedOptions);
return (0, findModules_1.findModulesAsync)({
appRoot: await autolinkingOptionsLoader.getAppRoot(),
autolinkingOptions: await autolinkingOptionsLoader.getPlatformOptions(providedOptions.platform),
});
}
/** @deprecated */
async function apiResolveExtraBuildDependenciesAsync(providedOptions) {
return (0, resolveModules_1.resolveExtraBuildDependenciesAsync)({
commandRoot: providedOptions.projectRoot,
platform: providedOptions.platform,
});
}
/** @deprecated */
async function apiResolveModulesAsync(searchResults, providedOptions) {
const autolinkingOptionsLoader = (0, autolinkingOptions_1.createAutolinkingOptionsLoader)(providedOptions);
return (0, resolveModules_1.resolveModulesAsync)(searchResults, await autolinkingOptionsLoader.getPlatformOptions(providedOptions.platform));
}
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/autolinking/index.ts"],"names":[],"mappings":";;;AAsDyB,+CAAgB;AACE,mFAAkC;AACjD,qDAAmB;AAxD/C,uEAAoG;AAEpG,+CAAiD;AACjD,qDAA2F;AAE3F,uDAAsD;AAA7C,oHAAA,gBAAgB,OAAA;AACzB,6DAAqE;AAA5D,mIAAA,4BAA4B,OAAA;AAgBrC,kBAAkB;AAClB,KAAK,UAAU,mBAAmB,CAAC,eAA8B;IAC/D,MAAM,wBAAwB,GAAG,IAAA,mDAA8B,EAAC,eAAe,CAAC,CAAC;IACjF,OAAO,IAAA,8BAAgB,EAAC;QACtB,OAAO,EAAE,MAAM,wBAAwB,CAAC,UAAU,EAAE;QACpD,kBAAkB,EAAE,MAAM,wBAAwB,CAAC,kBAAkB,CAAC,eAAe,CAAC,QAAQ,CAAC;KAChG,CAAC,CAAC;AACL,CAAC;AAED,kBAAkB;AAClB,KAAK,UAAU,qCAAqC,CAClD,eAA+B;IAE/B,OAAO,IAAA,mDAAkC,EAAC;QACxC,WAAW,EAAE,eAAe,CAAC,WAAW;QACxC,QAAQ,EAAE,eAAe,CAAC,QAAQ;KACnC,CAAC,CAAC;AACL,CAAC;AAED,kBAAkB;AAClB,KAAK,UAAU,sBAAsB,CACnC,aAA4B,EAC5B,eAA8B;IAE9B,MAAM,wBAAwB,GAAG,IAAA,mDAA8B,EAAC,eAAe,CAAC,CAAC;IACjF,OAAO,IAAA,oCAAmB,EACxB,aAAa,EACb,MAAM,wBAAwB,CAAC,kBAAkB,CAAC,eAAe,CAAC,QAAQ,CAAC,CAC5E,CAAC;AACJ,CAAC","sourcesContent":["import { AutolinkingOptions, createAutolinkingOptionsLoader } from '../commands/autolinkingOptions';\nimport { ExtraDependencies, ModuleDescriptor, SearchResults, SupportedPlatform } from '../types';\nimport { findModulesAsync } from './findModules';\nimport { resolveExtraBuildDependenciesAsync, resolveModulesAsync } from './resolveModules';\n\nexport { getConfiguration } from './getConfiguration';\nexport { generateModulesProviderAsync } from './generatePackageList';\n\n/** @deprecated */\nexport interface SearchOptions extends Partial<AutolinkingOptions> {\n projectRoot: string;\n platform: SupportedPlatform;\n [extra: string]: unknown;\n}\n\n/** @deprecated */\nexport interface ResolveOptions {\n projectRoot: string;\n platform: SupportedPlatform;\n [extra: string]: unknown;\n}\n\n/** @deprecated */\nasync function apiFindModulesAsync(providedOptions: SearchOptions): Promise<SearchResults> {\n const autolinkingOptionsLoader = createAutolinkingOptionsLoader(providedOptions);\n return findModulesAsync({\n appRoot: await autolinkingOptionsLoader.getAppRoot(),\n autolinkingOptions: await autolinkingOptionsLoader.getPlatformOptions(providedOptions.platform),\n });\n}\n\n/** @deprecated */\nasync function apiResolveExtraBuildDependenciesAsync(\n providedOptions: ResolveOptions\n): Promise<ExtraDependencies> {\n return resolveExtraBuildDependenciesAsync({\n commandRoot: providedOptions.projectRoot,\n platform: providedOptions.platform,\n });\n}\n\n/** @deprecated */\nasync function apiResolveModulesAsync(\n searchResults: SearchResults,\n providedOptions: SearchOptions\n): Promise<ModuleDescriptor[]> {\n const autolinkingOptionsLoader = createAutolinkingOptionsLoader(providedOptions);\n return resolveModulesAsync(\n searchResults,\n await autolinkingOptionsLoader.getPlatformOptions(providedOptions.platform)\n );\n}\n\nexport {\n apiFindModulesAsync as findModulesAsync,\n apiResolveExtraBuildDependenciesAsync as resolveExtraBuildDependenciesAsync,\n apiResolveModulesAsync as resolveModulesAsync,\n};\n"]}

View File

@@ -0,0 +1,13 @@
import { AutolinkingOptions } from '../commands/autolinkingOptions';
import type { ExtraDependencies, ModuleDescriptor, SearchResults, SupportedPlatform } from '../types';
/** Resolves search results to a list of platform-specific configuration. */
export declare function resolveModulesAsync(searchResults: SearchResults, autolinkingOptions: AutolinkingOptions & {
platform: SupportedPlatform;
}): Promise<ModuleDescriptor[]>;
interface ResolveExtraBuildDependenciesParams {
commandRoot: string;
platform: SupportedPlatform;
}
/** Resolves the extra build dependencies for the project, such as additional Maven repositories or CocoaPods pods. */
export declare function resolveExtraBuildDependenciesAsync({ commandRoot, platform, }: ResolveExtraBuildDependenciesParams): Promise<ExtraDependencies>;
export {};

View File

@@ -0,0 +1,36 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveModulesAsync = resolveModulesAsync;
exports.resolveExtraBuildDependenciesAsync = resolveExtraBuildDependenciesAsync;
const concurrency_1 = require("../concurrency");
const platforms_1 = require("../platforms");
/** Resolves search results to a list of platform-specific configuration. */
async function resolveModulesAsync(searchResults, autolinkingOptions) {
const platformLinking = (0, platforms_1.getLinkingImplementationForPlatform)(autolinkingOptions.platform);
// Additional output property for Cocoapods flags
const extraOutput = { flags: autolinkingOptions.flags };
const moduleDescriptorList = await (0, concurrency_1.taskAll)(Object.entries(searchResults), async ([packageName, revision]) => {
const resolvedModule = await platformLinking.resolveModuleAsync(packageName, revision, extraOutput);
return resolvedModule
? {
...resolvedModule,
packageVersion: revision.version,
packageName: resolvedModule.packageName ?? packageName,
}
: null;
});
return moduleDescriptorList
.filter((moduleDescriptor) => moduleDescriptor != null)
.sort((a, b) => a.packageName.localeCompare(b.packageName));
}
/** Resolves the extra build dependencies for the project, such as additional Maven repositories or CocoaPods pods. */
async function resolveExtraBuildDependenciesAsync({ commandRoot, platform, }) {
const platformLinking = (0, platforms_1.getLinkingImplementationForPlatform)(platform);
const extraDependencies = await platformLinking.resolveExtraBuildDependenciesAsync(
// NOTE: We assume we must be inside the native folder here
// The `resolve` command either is invoked in the CWD of `./{android,ios}` or has a `--project-root`
// that's in the native directory
commandRoot);
return extraDependencies ?? [];
}
//# sourceMappingURL=resolveModules.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"resolveModules.js","sourceRoot":"","sources":["../../src/autolinking/resolveModules.ts"],"names":[],"mappings":";;AAWA,kDA6BC;AAQD,gFAYC;AA3DD,gDAAyC;AACzC,4CAAmE;AAQnE,4EAA4E;AACrE,KAAK,UAAU,mBAAmB,CACvC,aAA4B,EAC5B,kBAAwE;IAExE,MAAM,eAAe,GAAG,IAAA,+CAAmC,EAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IACzF,iDAAiD;IACjD,MAAM,WAAW,GAAG,EAAE,KAAK,EAAE,kBAAkB,CAAC,KAAK,EAAE,CAAC;IAExD,MAAM,oBAAoB,GAAG,MAAM,IAAA,qBAAO,EACxC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,EAC7B,KAAK,EAAE,CAAC,WAAW,EAAE,QAAQ,CAAC,EAAE,EAAE;QAChC,MAAM,cAAc,GAAG,MAAM,eAAe,CAAC,kBAAkB,CAC7D,WAAW,EACX,QAAQ,EACR,WAAW,CACZ,CAAC;QACF,OAAO,cAAc;YACnB,CAAC,CAAC;gBACE,GAAG,cAAc;gBACjB,cAAc,EAAE,QAAQ,CAAC,OAAO;gBAChC,WAAW,EAAE,cAAc,CAAC,WAAW,IAAI,WAAW;aACvD;YACH,CAAC,CAAC,IAAI,CAAC;IACX,CAAC,CACF,CAAC;IAEF,OAAO,oBAAoB;SACxB,MAAM,CAAC,CAAC,gBAAgB,EAAE,EAAE,CAAC,gBAAgB,IAAI,IAAI,CAAC;SACtD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;AAChE,CAAC;AAOD,sHAAsH;AAC/G,KAAK,UAAU,kCAAkC,CAAC,EACvD,WAAW,EACX,QAAQ,GAC4B;IACpC,MAAM,eAAe,GAAG,IAAA,+CAAmC,EAAC,QAAQ,CAAC,CAAC;IACtE,MAAM,iBAAiB,GAAG,MAAM,eAAe,CAAC,kCAAkC;IAChF,2DAA2D;IAC3D,oGAAoG;IACpG,iCAAiC;IACjC,WAAW,CACZ,CAAC;IACF,OAAO,iBAAiB,IAAI,EAAE,CAAC;AACjC,CAAC","sourcesContent":["import { AutolinkingOptions } from '../commands/autolinkingOptions';\nimport { taskAll } from '../concurrency';\nimport { getLinkingImplementationForPlatform } from '../platforms';\nimport type {\n ExtraDependencies,\n ModuleDescriptor,\n SearchResults,\n SupportedPlatform,\n} from '../types';\n\n/** Resolves search results to a list of platform-specific configuration. */\nexport async function resolveModulesAsync(\n searchResults: SearchResults,\n autolinkingOptions: AutolinkingOptions & { platform: SupportedPlatform }\n): Promise<ModuleDescriptor[]> {\n const platformLinking = getLinkingImplementationForPlatform(autolinkingOptions.platform);\n // Additional output property for Cocoapods flags\n const extraOutput = { flags: autolinkingOptions.flags };\n\n const moduleDescriptorList = await taskAll(\n Object.entries(searchResults),\n async ([packageName, revision]) => {\n const resolvedModule = await platformLinking.resolveModuleAsync(\n packageName,\n revision,\n extraOutput\n );\n return resolvedModule\n ? {\n ...resolvedModule,\n packageVersion: revision.version,\n packageName: resolvedModule.packageName ?? packageName,\n }\n : null;\n }\n );\n\n return moduleDescriptorList\n .filter((moduleDescriptor) => moduleDescriptor != null)\n .sort((a, b) => a.packageName.localeCompare(b.packageName));\n}\n\ninterface ResolveExtraBuildDependenciesParams {\n commandRoot: string;\n platform: SupportedPlatform;\n}\n\n/** Resolves the extra build dependencies for the project, such as additional Maven repositories or CocoaPods pods. */\nexport async function resolveExtraBuildDependenciesAsync({\n commandRoot,\n platform,\n}: ResolveExtraBuildDependenciesParams): Promise<ExtraDependencies> {\n const platformLinking = getLinkingImplementationForPlatform(platform);\n const extraDependencies = await platformLinking.resolveExtraBuildDependenciesAsync(\n // NOTE: We assume we must be inside the native folder here\n // The `resolve` command either is invoked in the CWD of `./{android,ios}` or has a `--project-root`\n // that's in the native directory\n commandRoot\n );\n return extraDependencies ?? [];\n}\n"]}

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

View File

@@ -0,0 +1,5 @@
export interface Limiter {
<Arguments extends unknown[], ReturnType>(fn: (...args: Arguments) => PromiseLike<ReturnType> | ReturnType, ...args: Arguments): Promise<ReturnType>;
}
export declare const createLimiter: (limit: number) => Limiter;
export declare const taskAll: <T, R>(inputs: T[], map: (input: T) => Promise<R>) => Promise<R[]>;

View File

@@ -0,0 +1,59 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.taskAll = exports.createLimiter = void 0;
const createLimiter = (limit) => {
let running = 0;
let head = null;
let tail = null;
const enqueue = () => new Promise((resolve) => {
const item = { resolve, next: null };
if (tail) {
tail.next = item;
tail = item;
}
else {
head = item;
tail = item;
}
});
const dequeue = () => {
if (running < limit && head !== null) {
const { resolve, next } = head;
head.next = null;
head = next;
if (head === null) {
tail = null;
}
running++;
resolve();
}
};
return async (fn, ...args) => {
if (running < limit) {
running++;
}
else {
await enqueue();
}
try {
return await fn(...args);
}
finally {
running--;
dequeue();
}
};
};
exports.createLimiter = createLimiter;
const taskAll = (inputs, map) => {
// NOTE: This doesn't depend on CPU cores, but instead is hard-coded depending on
// number of concurrent IO-bound tasks. `taskAll` can be called concurrently, and
// we don't keep track of concurrent `taskAll` calls in expo-modules-autolinking.
// There's a fixed number of concurrent pending IO operations that Node.js handles
// nicely. It seems that expo-modules-autolinking behaves nicely when this number
// is around ~8, but this may be higher if disk + core speed is higher.
const limiter = (0, exports.createLimiter)(8);
return Promise.all(inputs.map((input) => limiter(map, input)));
};
exports.taskAll = taskAll;
//# sourceMappingURL=concurrency.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"concurrency.js","sourceRoot":"","sources":["../src/concurrency.ts"],"names":[],"mappings":";;;AAYO,MAAM,aAAa,GAAG,CAAC,KAAa,EAAW,EAAE;IACtD,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,IAAI,GAAqB,IAAI,CAAC;IAClC,IAAI,IAAI,GAAqB,IAAI,CAAC;IAElC,MAAM,OAAO,GAAG,GAAG,EAAE,CACnB,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QAC5B,MAAM,IAAI,GAAc,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QAChD,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;YACjB,IAAI,GAAG,IAAI,CAAC;QACd,CAAC;aAAM,CAAC;YACN,IAAI,GAAG,IAAI,CAAC;YACZ,IAAI,GAAG,IAAI,CAAC;QACd,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,IAAI,OAAO,GAAG,KAAK,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YACrC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;YAC/B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;YACjB,IAAI,GAAG,IAAI,CAAC;YACZ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;gBAClB,IAAI,GAAG,IAAI,CAAC;YACd,CAAC;YACD,OAAO,EAAE,CAAC;YACV,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,KAAK,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE;QAC3B,IAAI,OAAO,GAAG,KAAK,EAAE,CAAC;YACpB,OAAO,EAAE,CAAC;QACZ,CAAC;aAAM,CAAC;YACN,MAAM,OAAO,EAAE,CAAC;QAClB,CAAC;QACD,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;QAC3B,CAAC;gBAAS,CAAC;YACT,OAAO,EAAE,CAAC;YACV,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC,CAAC;AACJ,CAAC,CAAC;AA3CW,QAAA,aAAa,iBA2CxB;AAEK,MAAM,OAAO,GAAG,CAAO,MAAW,EAAE,GAA6B,EAAgB,EAAE;IACxF,iFAAiF;IACjF,iFAAiF;IACjF,iFAAiF;IACjF,kFAAkF;IAClF,iFAAiF;IACjF,uEAAuE;IACvE,MAAM,OAAO,GAAG,IAAA,qBAAa,EAAC,CAAC,CAAC,CAAC;IACjC,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC,CAAC;AATW,QAAA,OAAO,WASlB","sourcesContent":["export interface Limiter {\n <Arguments extends unknown[], ReturnType>(\n fn: (...args: Arguments) => PromiseLike<ReturnType> | ReturnType,\n ...args: Arguments\n ): Promise<ReturnType>;\n}\n\ninterface QueueItem {\n resolve(): void;\n next: QueueItem | null;\n}\n\nexport const createLimiter = (limit: number): Limiter => {\n let running = 0;\n let head: QueueItem | null = null;\n let tail: QueueItem | null = null;\n\n const enqueue = () =>\n new Promise<void>((resolve) => {\n const item: QueueItem = { resolve, next: null };\n if (tail) {\n tail.next = item;\n tail = item;\n } else {\n head = item;\n tail = item;\n }\n });\n\n const dequeue = () => {\n if (running < limit && head !== null) {\n const { resolve, next } = head;\n head.next = null;\n head = next;\n if (head === null) {\n tail = null;\n }\n running++;\n resolve();\n }\n };\n\n return async (fn, ...args) => {\n if (running < limit) {\n running++;\n } else {\n await enqueue();\n }\n try {\n return await fn(...args);\n } finally {\n running--;\n dequeue();\n }\n };\n};\n\nexport const taskAll = <T, R>(inputs: T[], map: (input: T) => Promise<R>): Promise<R[]> => {\n // NOTE: This doesn't depend on CPU cores, but instead is hard-coded depending on\n // number of concurrent IO-bound tasks. `taskAll` can be called concurrently, and\n // we don't keep track of concurrent `taskAll` calls in expo-modules-autolinking.\n // There's a fixed number of concurrent pending IO operations that Node.js handles\n // nicely. It seems that expo-modules-autolinking behaves nicely when this number\n // is around ~8, but this may be higher if disk + core speed is higher.\n const limiter = createLimiter(8);\n return Promise.all(inputs.map((input) => limiter(map, input)));\n};\n"]}

View File

@@ -0,0 +1,21 @@
import { PackageRevision, SupportedPlatform } from '../types';
import { type ResolutionResult } from './types';
import { type Memoizer } from '../memoize';
import { RNConfigReactNativeProjectConfig } from '../reactNativeConfig';
export interface CachedDependenciesSearchOptions {
excludeNames: Set<string>;
searchPaths: string[];
}
export interface CachedDependenciesLinker {
memoizer: Memoizer;
getOptionsForPlatform(platform: SupportedPlatform): Promise<CachedDependenciesSearchOptions>;
loadReactNativeProjectConfig(): Promise<RNConfigReactNativeProjectConfig | null>;
scanDependenciesFromRNProjectConfig(): Promise<ResolutionResult>;
scanDependenciesRecursively(): Promise<ResolutionResult>;
scanDependenciesInSearchPath(searchPath: string): Promise<ResolutionResult>;
}
export declare function makeCachedDependenciesLinker(params: {
projectRoot: string;
}): CachedDependenciesLinker;
export declare function scanDependencyResolutionsForPlatform(linker: CachedDependenciesLinker, platform: SupportedPlatform, include?: string[]): Promise<ResolutionResult>;
export declare function scanExpoModuleResolutionsForPlatform(linker: CachedDependenciesLinker, platform: SupportedPlatform): Promise<Record<string, PackageRevision>>;

View File

@@ -0,0 +1,130 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.makeCachedDependenciesLinker = makeCachedDependenciesLinker;
exports.scanDependencyResolutionsForPlatform = scanDependencyResolutionsForPlatform;
exports.scanExpoModuleResolutionsForPlatform = scanExpoModuleResolutionsForPlatform;
const fs_1 = __importDefault(require("fs"));
const resolution_1 = require("./resolution");
const rncliLocal_1 = require("./rncliLocal");
const scanning_1 = require("./scanning");
const utils_1 = require("./utils");
const findModules_1 = require("../autolinking/findModules");
const autolinkingOptions_1 = require("../commands/autolinkingOptions");
const memoize_1 = require("../memoize");
const reactNativeConfig_1 = require("../reactNativeConfig");
const config_1 = require("../reactNativeConfig/config");
function makeCachedDependenciesLinker(params) {
const memoizer = (0, memoize_1.createMemoizer)();
const autolinkingOptionsLoader = (0, autolinkingOptions_1.createAutolinkingOptionsLoader)({
projectRoot: params.projectRoot,
});
let appRoot;
const getAppRoot = () => appRoot || (appRoot = autolinkingOptionsLoader.getAppRoot());
const dependenciesResultBySearchPath = new Map();
let reactNativeProjectConfig;
let reactNativeProjectConfigDependencies;
let recursiveDependencies;
return {
memoizer,
async getOptionsForPlatform(platform) {
const options = await autolinkingOptionsLoader.getPlatformOptions(platform);
return makeCachedDependenciesSearchOptions(options);
},
async loadReactNativeProjectConfig() {
if (reactNativeProjectConfig === undefined) {
reactNativeProjectConfig = memoizer.call(config_1.loadConfigAsync, await getAppRoot());
}
return reactNativeProjectConfig;
},
async scanDependenciesFromRNProjectConfig() {
if (reactNativeProjectConfigDependencies === undefined) {
reactNativeProjectConfigDependencies = memoizer.withMemoizer(async () => {
return await (0, rncliLocal_1.scanDependenciesFromRNProjectConfig)(await getAppRoot(), await this.loadReactNativeProjectConfig());
});
}
return reactNativeProjectConfigDependencies;
},
async scanDependenciesRecursively() {
if (recursiveDependencies === undefined) {
recursiveDependencies = memoizer.withMemoizer(async () => {
return (0, resolution_1.scanDependenciesRecursively)(await getAppRoot());
});
}
return recursiveDependencies;
},
async scanDependenciesInSearchPath(searchPath) {
let result = dependenciesResultBySearchPath.get(searchPath);
if (!result) {
dependenciesResultBySearchPath.set(searchPath, (result = memoizer.withMemoizer(scanning_1.scanDependenciesInSearchPath, searchPath)));
}
return result;
},
};
}
async function scanDependencyResolutionsForPlatform(linker, platform, include) {
const { excludeNames, searchPaths } = await linker.getOptionsForPlatform(platform);
const includeNames = new Set(include);
const reactNativeProjectConfig = await linker.loadReactNativeProjectConfig();
const resolutions = (0, utils_1.mergeResolutionResults)(await Promise.all([
linker.scanDependenciesFromRNProjectConfig(),
...searchPaths.map((searchPath) => {
return linker.scanDependenciesInSearchPath(searchPath);
}),
linker.scanDependenciesRecursively(),
]));
return await linker.memoizer.withMemoizer(async () => {
const dependencies = await (0, utils_1.filterMapResolutionResult)(resolutions, async (resolution) => {
if (excludeNames.has(resolution.name)) {
return null;
}
else if (includeNames.has(resolution.name)) {
return resolution;
}
else if (resolution.source === 2 /* DependencyResolutionSource.RN_CLI_LOCAL */) {
// If the dependency was resolved frpom the React Native project config, we'll only
// attempt to resolve it as a React Native module
const reactNativeModuleDesc = await (0, reactNativeConfig_1.resolveReactNativeModule)(resolution, reactNativeProjectConfig, platform, excludeNames);
if (!reactNativeModuleDesc) {
return null;
}
}
else {
const [reactNativeModule, expoModule] = await Promise.all([
(0, reactNativeConfig_1.resolveReactNativeModule)(resolution, reactNativeProjectConfig, platform, excludeNames),
(0, findModules_1.resolveExpoModule)(resolution, platform, excludeNames),
]);
if (!reactNativeModule && !expoModule) {
return null;
}
}
return resolution;
});
return dependencies;
});
}
async function scanExpoModuleResolutionsForPlatform(linker, platform) {
const { excludeNames, searchPaths } = await linker.getOptionsForPlatform(platform);
const resolutions = (0, utils_1.mergeResolutionResults)(await Promise.all([
...searchPaths.map((searchPath) => {
return linker.scanDependenciesInSearchPath(searchPath);
}),
linker.scanDependenciesRecursively(),
].filter((x) => x != null)));
return await linker.memoizer.withMemoizer(async () => {
return await (0, utils_1.filterMapResolutionResult)(resolutions, async (resolution) => {
return !excludeNames.has(resolution.name)
? await (0, findModules_1.resolveExpoModule)(resolution, platform, excludeNames)
: null;
});
});
}
const makeCachedDependenciesSearchOptions = (options) => ({
excludeNames: new Set(options.exclude),
searchPaths: options.nativeModulesDir && fs_1.default.existsSync(options.nativeModulesDir)
? [options.nativeModulesDir, ...(options.searchPaths ?? [])]
: (options.searchPaths ?? []),
});
//# sourceMappingURL=CachedDependenciesLinker.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,6 @@
export { scanDependenciesRecursively } from './resolution';
export { scanDependenciesInSearchPath } from './scanning';
export { scanDependenciesFromRNProjectConfig } from './rncliLocal';
export { filterMapResolutionResult, mergeResolutionResults } from './utils';
export * from './CachedDependenciesLinker';
export * from './types';

View File

@@ -0,0 +1,29 @@
"use strict";
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.mergeResolutionResults = exports.filterMapResolutionResult = exports.scanDependenciesFromRNProjectConfig = exports.scanDependenciesInSearchPath = exports.scanDependenciesRecursively = void 0;
var resolution_1 = require("./resolution");
Object.defineProperty(exports, "scanDependenciesRecursively", { enumerable: true, get: function () { return resolution_1.scanDependenciesRecursively; } });
var scanning_1 = require("./scanning");
Object.defineProperty(exports, "scanDependenciesInSearchPath", { enumerable: true, get: function () { return scanning_1.scanDependenciesInSearchPath; } });
var rncliLocal_1 = require("./rncliLocal");
Object.defineProperty(exports, "scanDependenciesFromRNProjectConfig", { enumerable: true, get: function () { return rncliLocal_1.scanDependenciesFromRNProjectConfig; } });
var utils_1 = require("./utils");
Object.defineProperty(exports, "filterMapResolutionResult", { enumerable: true, get: function () { return utils_1.filterMapResolutionResult; } });
Object.defineProperty(exports, "mergeResolutionResults", { enumerable: true, get: function () { return utils_1.mergeResolutionResults; } });
__exportStar(require("./CachedDependenciesLinker"), exports);
__exportStar(require("./types"), exports);
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/dependencies/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,2CAA2D;AAAlD,yHAAA,2BAA2B,OAAA;AACpC,uCAA0D;AAAjD,wHAAA,4BAA4B,OAAA;AACrC,2CAAmE;AAA1D,iIAAA,mCAAmC,OAAA;AAC5C,iCAA4E;AAAnE,kHAAA,yBAAyB,OAAA;AAAE,+GAAA,sBAAsB,OAAA;AAC1D,6DAA2C;AAC3C,0CAAwB","sourcesContent":["export { scanDependenciesRecursively } from './resolution';\nexport { scanDependenciesInSearchPath } from './scanning';\nexport { scanDependenciesFromRNProjectConfig } from './rncliLocal';\nexport { filterMapResolutionResult, mergeResolutionResults } from './utils';\nexport * from './CachedDependenciesLinker';\nexport * from './types';\n"]}

View File

@@ -0,0 +1,10 @@
import { type ResolutionResult } from './types';
declare module 'node:module' {
function _nodeModulePaths(base: string): readonly string[];
}
interface ResolutionOptions {
shouldIncludeDependency?(name: string): boolean;
limitDepth?: number;
}
export declare function scanDependenciesRecursively(rawPath: string, { shouldIncludeDependency, limitDepth }?: ResolutionOptions): Promise<ResolutionResult>;
export {};

View File

@@ -0,0 +1,137 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.scanDependenciesRecursively = scanDependenciesRecursively;
const node_module_1 = __importDefault(require("node:module"));
const utils_1 = require("./utils");
const concurrency_1 = require("../concurrency");
const utils_2 = require("../utils");
// NOTE(@kitten): There's no need to search very deep for modules
// We don't expect native modules to be excessively nested in the dependency tree
const MAX_DEPTH = 8;
const createNodeModulePathsCreator = () => {
const _nodeModulePathCache = new Map();
return async function getNodeModulePaths(packagePath) {
const outputPaths = [];
const nodeModulePaths = node_module_1.default._nodeModulePaths(packagePath);
for (let idx = 0; idx < nodeModulePaths.length; idx++) {
const nodeModulePath = nodeModulePaths[idx];
let target = _nodeModulePathCache.get(nodeModulePath);
if (target === undefined) {
target = await (0, utils_2.maybeRealpath)(nodeModulePath);
if (idx !== 0) {
_nodeModulePathCache.set(nodeModulePath, target);
}
}
if (target != null) {
outputPaths.push(target);
}
}
return outputPaths;
};
};
async function resolveDependencies(packageJson, nodeModulePaths, depth, shouldIncludeDependency) {
const dependencies = Object.create(null);
if (packageJson.dependencies != null && typeof packageJson.dependencies === 'object') {
Object.assign(dependencies, packageJson.dependencies);
}
// NOTE(@kitten): Also traverse devDependencies for top-level package.json
if (depth === 0 &&
packageJson.devDependencies != null &&
typeof packageJson.devDependencies === 'object') {
Object.assign(dependencies, packageJson.devDependencies);
}
if (packageJson.peerDependencies != null && typeof packageJson.peerDependencies === 'object') {
const peerDependenciesMeta = packageJson.peerDependenciesMeta != null &&
typeof packageJson.peerDependenciesMeta === 'object'
? packageJson.peerDependenciesMeta
: undefined;
for (const dependencyName in packageJson.peerDependencies) {
// NOTE(@kitten): We only check peer dependencies because some package managers auto-install them
// which would mean they'd have no reference in any dependencies. However, optional peer dependencies
// don't auto-install and we can skip them
if (!isOptionalPeerDependencyMeta(peerDependenciesMeta, dependencyName)) {
dependencies[dependencyName] = '';
}
}
}
const resolveDependency = async (dependencyName) => {
for (let idx = 0; idx < nodeModulePaths.length; idx++) {
const originPath = (0, utils_2.fastJoin)(nodeModulePaths[idx], dependencyName);
const nodeModulePath = await (0, utils_2.maybeRealpath)(originPath);
if (nodeModulePath != null) {
return {
source: 0 /* DependencyResolutionSource.RECURSIVE_RESOLUTION */,
name: dependencyName,
version: '',
path: nodeModulePath,
originPath,
duplicates: null,
depth,
};
}
}
return null;
};
const modules = await (0, concurrency_1.taskAll)(Object.keys(dependencies).filter((dependencyName) => shouldIncludeDependency(dependencyName)), (dependencyName) => resolveDependency(dependencyName));
return modules.filter((resolution) => resolution != null);
}
async function scanDependenciesRecursively(rawPath, { shouldIncludeDependency = utils_1.defaultShouldIncludeDependency, limitDepth } = {}) {
const rootPath = await (0, utils_2.maybeRealpath)(rawPath);
if (!rootPath) {
return {};
}
const _visitedPackagePaths = new Set();
const getNodeModulePaths = createNodeModulePathsCreator();
const maxDepth = limitDepth != null ? limitDepth : MAX_DEPTH;
const recurse = async (resolution, depth = 0) => {
const searchResults = Object.create(null);
if (_visitedPackagePaths.has(resolution.path)) {
return searchResults;
}
else {
_visitedPackagePaths.add(resolution.path);
}
const [nodeModulePaths, packageJson] = await Promise.all([
getNodeModulePaths(resolution.path),
(0, utils_2.loadPackageJson)((0, utils_2.fastJoin)(resolution.path, 'package.json')),
]);
if (!packageJson) {
return searchResults;
}
else {
resolution.version = packageJson.version || '';
}
const modules = await resolveDependencies(packageJson, nodeModulePaths, depth, shouldIncludeDependency);
for (let idx = 0; idx < modules.length; idx++) {
searchResults[modules[idx].name] = modules[idx];
}
if (depth + 1 < maxDepth) {
const childResults = await (0, concurrency_1.taskAll)(modules, (resolution) => recurse(resolution, depth + 1));
return (0, utils_1.mergeResolutionResults)(childResults, searchResults);
}
else {
return searchResults;
}
};
const searchResults = await recurse({
source: 0 /* DependencyResolutionSource.RECURSIVE_RESOLUTION */,
name: '',
version: '',
path: rootPath,
originPath: rawPath,
duplicates: null,
depth: -1,
});
return searchResults;
}
const isOptionalPeerDependencyMeta = (peerDependenciesMeta, packageName) => {
return (peerDependenciesMeta &&
peerDependenciesMeta[packageName] != null &&
typeof peerDependenciesMeta[packageName] === 'object' &&
'optional' in peerDependenciesMeta[packageName] &&
!!peerDependenciesMeta[packageName].optional);
};
//# sourceMappingURL=resolution.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
import { type ResolutionResult } from './types';
import { RNConfigReactNativeProjectConfig } from '../reactNativeConfig';
interface ResolutionOptions {
shouldIncludeDependency?(name: string): boolean;
}
export declare function scanDependenciesFromRNProjectConfig(rawPath: string, projectConfig: RNConfigReactNativeProjectConfig | null, { shouldIncludeDependency }?: ResolutionOptions): Promise<ResolutionResult>;
export {};

View File

@@ -0,0 +1,37 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.scanDependenciesFromRNProjectConfig = scanDependenciesFromRNProjectConfig;
const path_1 = __importDefault(require("path"));
const utils_1 = require("./utils");
const concurrency_1 = require("../concurrency");
const utils_2 = require("../utils");
async function scanDependenciesFromRNProjectConfig(rawPath, projectConfig, { shouldIncludeDependency = utils_1.defaultShouldIncludeDependency } = {}) {
const rootPath = await (0, utils_2.maybeRealpath)(rawPath);
const searchResults = Object.create(null);
if (!rootPath || !projectConfig || !projectConfig.dependencies) {
return searchResults;
}
await (0, concurrency_1.taskAll)(Object.keys(projectConfig.dependencies).filter((dependencyName) => shouldIncludeDependency(dependencyName)), async (dependencyName) => {
const dependencyConfig = projectConfig.dependencies[dependencyName];
if (dependencyConfig && dependencyConfig.root && typeof dependencyConfig.root === 'string') {
const originPath = path_1.default.resolve(rootPath, dependencyConfig.root);
const realPath = await (0, utils_2.maybeRealpath)(originPath);
if (realPath) {
searchResults[dependencyName] = {
source: 2 /* DependencyResolutionSource.RN_CLI_LOCAL */,
name: dependencyName,
version: '',
path: realPath,
originPath,
duplicates: null,
depth: 0,
};
}
}
});
return searchResults;
}
//# sourceMappingURL=rncliLocal.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"rncliLocal.js","sourceRoot":"","sources":["../../src/dependencies/rncliLocal.ts"],"names":[],"mappings":";;;;;AAYA,kFAoCC;AAhDD,gDAAwB;AAGxB,mCAAyD;AACzD,gDAAyC;AAEzC,oCAAyC;AAMlC,KAAK,UAAU,mCAAmC,CACvD,OAAe,EACf,aAAsD,EACtD,EAAE,uBAAuB,GAAG,sCAA8B,KAAwB,EAAE;IAEpF,MAAM,QAAQ,GAAG,MAAM,IAAA,qBAAa,EAAC,OAAO,CAAC,CAAC;IAC9C,MAAM,aAAa,GAAqB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC5D,IAAI,CAAC,QAAQ,IAAI,CAAC,aAAa,IAAI,CAAC,aAAa,CAAC,YAAY,EAAE,CAAC;QAC/D,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,MAAM,IAAA,qBAAO,EACX,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,cAAc,EAAE,EAAE,CAChE,uBAAuB,CAAC,cAAc,CAAC,CACxC,EACD,KAAK,EAAE,cAAc,EAAE,EAAE;QACvB,MAAM,gBAAgB,GAAG,aAAa,CAAC,YAAa,CAAC,cAAc,CAAC,CAAC;QACrE,IAAI,gBAAgB,IAAI,gBAAgB,CAAC,IAAI,IAAI,OAAO,gBAAgB,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC3F,MAAM,UAAU,GAAG,cAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACjE,MAAM,QAAQ,GAAG,MAAM,IAAA,qBAAa,EAAC,UAAU,CAAC,CAAC;YACjD,IAAI,QAAQ,EAAE,CAAC;gBACb,aAAa,CAAC,cAAc,CAAC,GAAG;oBAC9B,MAAM,iDAAyC;oBAC/C,IAAI,EAAE,cAAc;oBACpB,OAAO,EAAE,EAAE;oBACX,IAAI,EAAE,QAAQ;oBACd,UAAU;oBACV,UAAU,EAAE,IAAI;oBAChB,KAAK,EAAE,CAAC;iBACT,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC,CACF,CAAC;IAEF,OAAO,aAAa,CAAC;AACvB,CAAC","sourcesContent":["import path from 'path';\n\nimport { DependencyResolutionSource, type ResolutionResult } from './types';\nimport { defaultShouldIncludeDependency } from './utils';\nimport { taskAll } from '../concurrency';\nimport { RNConfigReactNativeProjectConfig } from '../reactNativeConfig';\nimport { maybeRealpath } from '../utils';\n\ninterface ResolutionOptions {\n shouldIncludeDependency?(name: string): boolean;\n}\n\nexport async function scanDependenciesFromRNProjectConfig(\n rawPath: string,\n projectConfig: RNConfigReactNativeProjectConfig | null,\n { shouldIncludeDependency = defaultShouldIncludeDependency }: ResolutionOptions = {}\n): Promise<ResolutionResult> {\n const rootPath = await maybeRealpath(rawPath);\n const searchResults: ResolutionResult = Object.create(null);\n if (!rootPath || !projectConfig || !projectConfig.dependencies) {\n return searchResults;\n }\n\n await taskAll(\n Object.keys(projectConfig.dependencies).filter((dependencyName) =>\n shouldIncludeDependency(dependencyName)\n ),\n async (dependencyName) => {\n const dependencyConfig = projectConfig.dependencies![dependencyName];\n if (dependencyConfig && dependencyConfig.root && typeof dependencyConfig.root === 'string') {\n const originPath = path.resolve(rootPath, dependencyConfig.root);\n const realPath = await maybeRealpath(originPath);\n if (realPath) {\n searchResults[dependencyName] = {\n source: DependencyResolutionSource.RN_CLI_LOCAL,\n name: dependencyName,\n version: '',\n path: realPath,\n originPath,\n duplicates: null,\n depth: 0,\n };\n }\n }\n }\n );\n\n return searchResults;\n}\n"]}

View File

@@ -0,0 +1,6 @@
import { type ResolutionResult } from './types';
interface ResolutionOptions {
shouldIncludeDependency?(name: string): boolean;
}
export declare function scanDependenciesInSearchPath(rawPath: string, { shouldIncludeDependency }?: ResolutionOptions): Promise<ResolutionResult>;
export {};

View File

@@ -0,0 +1,112 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.scanDependenciesInSearchPath = scanDependenciesInSearchPath;
const fs_1 = __importDefault(require("fs"));
const concurrency_1 = require("../concurrency");
const utils_1 = require("./utils");
const utils_2 = require("../utils");
async function resolveDependency(basePath, dependencyName, shouldIncludeDependency) {
if (dependencyName && !shouldIncludeDependency(dependencyName)) {
return null;
}
const originPath = dependencyName ? (0, utils_2.fastJoin)(basePath, dependencyName) : basePath;
const realPath = await (0, utils_2.maybeRealpath)(originPath);
const packageJson = await (0, utils_2.loadPackageJson)((0, utils_2.fastJoin)(realPath || originPath, 'package.json'));
if (packageJson) {
return {
source: 1 /* DependencyResolutionSource.SEARCH_PATH */,
name: packageJson.name || '',
version: packageJson.version || '',
path: realPath || originPath,
originPath,
duplicates: null,
depth: 0,
};
}
else if (dependencyName && realPath) {
return {
source: 1 /* DependencyResolutionSource.SEARCH_PATH */,
name: dependencyName.toLowerCase(),
version: '',
path: realPath,
originPath,
duplicates: null,
depth: 0,
};
}
else {
return null;
}
}
async function scanDependenciesInSearchPath(rawPath, { shouldIncludeDependency = utils_1.defaultShouldIncludeDependency } = {}) {
const rootPath = await (0, utils_2.maybeRealpath)(rawPath);
const searchResults = Object.create(null);
if (!rootPath) {
return searchResults;
}
const resolvedDependencies = [];
const localModuleTarget = await (0, utils_2.maybeRealpath)((0, utils_2.fastJoin)(rootPath, 'package.json'));
if (localModuleTarget) {
// If we have a `package.json` file in the search path, we're already dealing with a node module
// and can skip the rest. This is a special case created by create-expo-module's `nativeModulesDir: ../`
const resolution = await resolveDependency(rootPath, null, shouldIncludeDependency);
if (resolution)
resolvedDependencies.push(resolution);
}
else {
const dirents = await fs_1.default.promises.readdir(rootPath, { withFileTypes: true });
await (0, concurrency_1.taskAll)(dirents, async (entry) => {
if (entry.isSymbolicLink()) {
const resolution = await resolveDependency(rootPath, entry.name, shouldIncludeDependency);
if (resolution)
resolvedDependencies.push(resolution);
}
else if (entry.isDirectory()) {
if (entry.name === 'node_modules') {
// Ignore nested node_modules folder
}
if (entry.name[0] === '.') {
// Ignore hidden folders
}
else if (entry.name[0] === '@') {
// NOTE: We don't expect @-scope folders to be symlinks
const entryPath = (0, utils_2.fastJoin)(rootPath, entry.name);
const childEntries = await fs_1.default.promises.readdir(entryPath, { withFileTypes: true });
await Promise.all(childEntries.map(async (child) => {
const dependencyName = `${entry.name}/${child.name}`;
if (child.isDirectory() || child.isSymbolicLink()) {
const resolution = await resolveDependency(rootPath, dependencyName, shouldIncludeDependency);
if (resolution)
resolvedDependencies.push(resolution);
}
}));
}
else {
const resolution = await resolveDependency(rootPath, entry.name, shouldIncludeDependency);
if (resolution)
resolvedDependencies.push(resolution);
}
}
});
}
for (let idx = 0; idx < resolvedDependencies.length; idx++) {
const resolution = resolvedDependencies[idx];
const prevEntry = searchResults[resolution.name];
if (prevEntry != null && resolution.path !== prevEntry.path) {
(prevEntry.duplicates ?? (prevEntry.duplicates = [])).push({
name: resolution.name,
version: resolution.version,
path: resolution.path,
originPath: resolution.originPath,
});
}
else if (prevEntry == null) {
searchResults[resolution.name] = resolution;
}
}
return searchResults;
}
//# sourceMappingURL=scanning.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,18 @@
export declare const enum DependencyResolutionSource {
RECURSIVE_RESOLUTION = 0,
SEARCH_PATH = 1,
RN_CLI_LOCAL = 2
}
export interface BaseDependencyResolution {
name: string;
version: string;
path: string;
originPath: string;
}
export interface DependencyResolution extends BaseDependencyResolution {
source: DependencyResolutionSource;
duplicates: BaseDependencyResolution[] | null;
depth: number;
[prop: string]: unknown;
}
export type ResolutionResult = Record<string, DependencyResolution | undefined>;

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=types.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/dependencies/types.ts"],"names":[],"mappings":"","sourcesContent":["export const enum DependencyResolutionSource {\n RECURSIVE_RESOLUTION,\n SEARCH_PATH,\n RN_CLI_LOCAL,\n}\n\nexport interface BaseDependencyResolution {\n name: string;\n version: string;\n path: string;\n originPath: string;\n}\n\nexport interface DependencyResolution extends BaseDependencyResolution {\n source: DependencyResolutionSource;\n duplicates: BaseDependencyResolution[] | null;\n depth: number;\n [prop: string]: unknown;\n}\n\nexport type ResolutionResult = Record<string, DependencyResolution | undefined>;\n"]}

View File

@@ -0,0 +1,7 @@
import { type DependencyResolution, type ResolutionResult } from './types';
export declare function defaultShouldIncludeDependency(dependencyName: string): boolean;
export declare function mergeWithDuplicate(a: DependencyResolution, b: DependencyResolution): DependencyResolution;
export declare function filterMapResolutionResult<T extends {
name: string;
}>(results: ResolutionResult, filterMap: (resolution: DependencyResolution) => Promise<T | null> | T | null): Promise<Record<string, T>>;
export declare function mergeResolutionResults(results: ResolutionResult[], base?: ResolutionResult): ResolutionResult;

View File

@@ -0,0 +1,142 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.defaultShouldIncludeDependency = defaultShouldIncludeDependency;
exports.mergeWithDuplicate = mergeWithDuplicate;
exports.filterMapResolutionResult = filterMapResolutionResult;
exports.mergeResolutionResults = mergeResolutionResults;
const path_1 = __importDefault(require("path"));
const concurrency_1 = require("../concurrency");
const NODE_MODULES_PATTERN = `${path_1.default.sep}node_modules${path_1.default.sep}`;
// The default dependencies we exclude don't contain dependency chains leading to autolinked modules
function defaultShouldIncludeDependency(dependencyName) {
const scopeName = dependencyName[0] === '@' ? dependencyName.slice(1, dependencyName.indexOf('/')) : null;
if (scopeName === 'babel' ||
scopeName === 'types' ||
scopeName === 'eslint' ||
scopeName === 'typescript-eslint' ||
scopeName === 'testing-library' ||
scopeName === 'aws-crypto' ||
scopeName === 'aws-sdk') {
return false;
}
switch (dependencyName) {
case '@expo/cli':
case '@expo/config':
case '@expo/metro-config':
case '@expo/package-manager':
case '@expo/prebuild-config':
case '@expo/webpack-config':
case '@expo/env':
case '@react-native/codegen':
case '@react-native/community-cli-plugin':
case 'eslint':
case 'eslint-config-expo':
case 'eslint-plugin-expo':
case 'eslint-plugin-import':
case 'jest-expo':
case 'jest':
case 'metro':
case 'ts-node':
case 'typescript':
case 'webpack':
return false;
default:
return true;
}
}
function mergeWithDuplicate(a, b) {
let target;
let duplicate;
if (a.depth < b.depth) {
target = a;
duplicate = b;
}
else if (b.depth < a.depth) {
target = b;
duplicate = a;
}
else {
// If both are equal, then the shallowest path wins
const pathDepthA = a.originPath.split(NODE_MODULES_PATTERN).length;
const pathDepthB = b.originPath.split(NODE_MODULES_PATTERN).length;
if (pathDepthA < pathDepthB) {
target = a;
duplicate = b;
}
else if (pathDepthB < pathDepthA) {
target = b;
duplicate = a;
}
else {
target = a;
duplicate = b;
}
}
const duplicates = target.duplicates || (target.duplicates = []);
if (target.path !== duplicate.path) {
if (duplicates.every((parent) => parent.path !== duplicate.path)) {
duplicates.push({
name: duplicate.name,
version: duplicate.version,
path: duplicate.path,
originPath: duplicate.originPath,
});
}
}
else if (!target.version && duplicate.version) {
target.version = duplicate.version;
}
if (duplicate.duplicates?.length) {
duplicates.push(...duplicate.duplicates.filter((child) => duplicates.every((parent) => parent.path !== child.path)));
}
return target;
}
async function filterMapResolutionResult(results, filterMap) {
const resolutions = await (0, concurrency_1.taskAll)(Object.keys(results), async (key) => {
const resolution = results[key];
const result = resolution ? await filterMap(resolution) : null;
// If we failed to find a matching resolution from `searchPaths`, also try the other duplicates
// to see if the `searchPaths` result is not a module but another is
if (resolution?.source === 1 /* DependencyResolutionSource.SEARCH_PATH */ && !result) {
for (let idx = 0; resolution.duplicates && idx < resolution.duplicates.length; idx++) {
const duplicate = resolution.duplicates[idx];
const duplicateResult = await filterMap({ ...resolution, ...duplicate });
if (duplicateResult != null) {
return duplicateResult;
}
}
}
return result;
});
const output = Object.create(null);
for (let idx = 0; idx < resolutions.length; idx++) {
const resolution = resolutions[idx];
if (resolution != null) {
output[resolution.name] = resolution;
}
}
return output;
}
function mergeResolutionResults(results, base) {
if (base == null && results.length === 1) {
return results[0];
}
const output = base == null ? Object.create(null) : base;
for (let idx = 0; idx < results.length; idx++) {
for (const key in results[idx]) {
const resolution = results[idx][key];
const prevResolution = output[key];
if (prevResolution != null) {
output[key] = mergeWithDuplicate(prevResolution, resolution);
}
else {
output[key] = resolution;
}
}
}
return output;
}
//# sourceMappingURL=utils.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,18 @@
import { AutolinkingCommonArguments, AutolinkingOptions } from './commands/autolinkingOptions';
import { ModuleDescriptor, SupportedPlatform } from './types';
export * from './types';
export * from './autolinking';
export * from './platforms';
export { ResolutionResult, BaseDependencyResolution, DependencyResolution, DependencyResolutionSource, CachedDependenciesLinker, CachedDependenciesSearchOptions, makeCachedDependenciesLinker, scanDependencyResolutionsForPlatform, scanExpoModuleResolutionsForPlatform, } from './dependencies';
/** @deprecated */
export declare function mergeLinkingOptionsAsync<Options extends Partial<AutolinkingCommonArguments>>(argumentsOptions: Options): Promise<Options & AutolinkingOptions>;
interface QueryAutolinkingModulesFromProjectParams extends Partial<AutolinkingCommonArguments> {
platform: SupportedPlatform;
[extra: string]: unknown;
}
/** @deprecated */
export declare function queryAutolinkingModulesFromProjectAsync(projectRoot: string, options: QueryAutolinkingModulesFromProjectParams): Promise<ModuleDescriptor[]>;
/** @deprecated */
export declare function findProjectRootSync(cwd?: string): string;
/** @deprecated */
export declare function resolveSearchPathsAsync(searchPaths: string[] | null, cwd: string): Promise<string[]>;

72
node_modules/expo-modules-autolinking/build/exports.js generated vendored Normal file
View File

@@ -0,0 +1,72 @@
"use strict";
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.scanExpoModuleResolutionsForPlatform = exports.scanDependencyResolutionsForPlatform = exports.makeCachedDependenciesLinker = void 0;
exports.mergeLinkingOptionsAsync = mergeLinkingOptionsAsync;
exports.queryAutolinkingModulesFromProjectAsync = queryAutolinkingModulesFromProjectAsync;
exports.findProjectRootSync = findProjectRootSync;
exports.resolveSearchPathsAsync = resolveSearchPathsAsync;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const findModules_1 = require("./autolinking/findModules");
const resolveModules_1 = require("./autolinking/resolveModules");
const autolinkingOptions_1 = require("./commands/autolinkingOptions");
__exportStar(require("./types"), exports);
__exportStar(require("./autolinking"), exports);
__exportStar(require("./platforms"), exports);
var dependencies_1 = require("./dependencies");
Object.defineProperty(exports, "makeCachedDependenciesLinker", { enumerable: true, get: function () { return dependencies_1.makeCachedDependenciesLinker; } });
Object.defineProperty(exports, "scanDependencyResolutionsForPlatform", { enumerable: true, get: function () { return dependencies_1.scanDependencyResolutionsForPlatform; } });
Object.defineProperty(exports, "scanExpoModuleResolutionsForPlatform", { enumerable: true, get: function () { return dependencies_1.scanExpoModuleResolutionsForPlatform; } });
/** @deprecated */
async function mergeLinkingOptionsAsync(argumentsOptions) {
const autolinkingOptionsLoader = (0, autolinkingOptions_1.createAutolinkingOptionsLoader)(argumentsOptions);
return {
...argumentsOptions,
...(await autolinkingOptionsLoader.getPlatformOptions()),
projectRoot: autolinkingOptionsLoader.getAppRoot(),
};
}
/** @deprecated */
async function queryAutolinkingModulesFromProjectAsync(projectRoot, options) {
const autolinkingOptionsLoader = (0, autolinkingOptions_1.createAutolinkingOptionsLoader)({
...options,
// NOTE(@kitten): This has always been duplicated
projectRoot: options.projectRoot ?? projectRoot,
});
const appRoot = await autolinkingOptionsLoader.getAppRoot();
const autolinkingOptions = await autolinkingOptionsLoader.getPlatformOptions(options.platform);
const searchResults = await (0, findModules_1.findModulesAsync)({ appRoot, autolinkingOptions });
return await (0, resolveModules_1.resolveModulesAsync)(searchResults, autolinkingOptions);
}
/** @deprecated */
function findProjectRootSync(cwd = process.cwd()) {
for (let dir = cwd; 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 "${cwd}"`);
}
/** @deprecated */
async function resolveSearchPathsAsync(searchPaths, cwd) {
return (0, autolinkingOptions_1.filterMapSearchPaths)(searchPaths, cwd) ?? [];
}
//# sourceMappingURL=exports.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"exports.js","sourceRoot":"","sources":["../src/exports.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AA8BA,4DASC;AAQD,0FAaC;AAGD,kDAQC;AAGD,0DAKC;AA/ED,4CAAoB;AACpB,gDAAwB;AAExB,2DAA6D;AAC7D,iEAAmE;AACnE,sEAKuC;AAGvC,0CAAwB;AACxB,gDAA8B;AAC9B,8CAA4B;AAE5B,+CAUwB;AAHtB,4HAAA,4BAA4B,OAAA;AAC5B,oIAAA,oCAAoC,OAAA;AACpC,oIAAA,oCAAoC,OAAA;AAGtC,kBAAkB;AACX,KAAK,UAAU,wBAAwB,CAC5C,gBAAyB;IAEzB,MAAM,wBAAwB,GAAG,IAAA,mDAA8B,EAAC,gBAAgB,CAAC,CAAC;IAClF,OAAO;QACL,GAAG,gBAAgB;QACnB,GAAG,CAAC,MAAM,wBAAwB,CAAC,kBAAkB,EAAE,CAAC;QACxD,WAAW,EAAE,wBAAwB,CAAC,UAAU,EAAE;KACnD,CAAC;AACJ,CAAC;AAOD,kBAAkB;AACX,KAAK,UAAU,uCAAuC,CAC3D,WAAmB,EACnB,OAAiD;IAEjD,MAAM,wBAAwB,GAAG,IAAA,mDAA8B,EAAC;QAC9D,GAAG,OAAO;QACV,iDAAiD;QACjD,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,WAAW;KAChD,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,MAAM,wBAAwB,CAAC,UAAU,EAAE,CAAC;IAC5D,MAAM,kBAAkB,GAAG,MAAM,wBAAwB,CAAC,kBAAkB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC/F,MAAM,aAAa,GAAG,MAAM,IAAA,8BAAgB,EAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAC;IAC9E,OAAO,MAAM,IAAA,oCAAmB,EAAC,aAAa,EAAE,kBAAkB,CAAC,CAAC;AACtE,CAAC;AAED,kBAAkB;AAClB,SAAgB,mBAAmB,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IAC7D,KAAK,IAAI,GAAG,GAAG,GAAG,EAAE,cAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,EAAE,GAAG,GAAG,cAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACvE,MAAM,IAAI,GAAG,cAAI,CAAC,OAAO,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;QAC/C,IAAI,YAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,8CAA8C,GAAG,GAAG,CAAC,CAAC;AACxE,CAAC;AAED,kBAAkB;AACX,KAAK,UAAU,uBAAuB,CAC3C,WAA4B,EAC5B,GAAW;IAEX,OAAO,IAAA,yCAAoB,EAAC,WAAW,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC;AACtD,CAAC","sourcesContent":["import fs from 'fs';\nimport path from 'path';\n\nimport { findModulesAsync } from './autolinking/findModules';\nimport { resolveModulesAsync } from './autolinking/resolveModules';\nimport {\n AutolinkingCommonArguments,\n AutolinkingOptions,\n createAutolinkingOptionsLoader,\n filterMapSearchPaths,\n} from './commands/autolinkingOptions';\nimport { ModuleDescriptor, SupportedPlatform } from './types';\n\nexport * from './types';\nexport * from './autolinking';\nexport * from './platforms';\n\nexport {\n ResolutionResult,\n BaseDependencyResolution,\n DependencyResolution,\n DependencyResolutionSource,\n CachedDependenciesLinker,\n CachedDependenciesSearchOptions,\n makeCachedDependenciesLinker,\n scanDependencyResolutionsForPlatform,\n scanExpoModuleResolutionsForPlatform,\n} from './dependencies';\n\n/** @deprecated */\nexport async function mergeLinkingOptionsAsync<Options extends Partial<AutolinkingCommonArguments>>(\n argumentsOptions: Options\n): Promise<Options & AutolinkingOptions> {\n const autolinkingOptionsLoader = createAutolinkingOptionsLoader(argumentsOptions);\n return {\n ...argumentsOptions,\n ...(await autolinkingOptionsLoader.getPlatformOptions()),\n projectRoot: autolinkingOptionsLoader.getAppRoot(),\n };\n}\n\ninterface QueryAutolinkingModulesFromProjectParams extends Partial<AutolinkingCommonArguments> {\n platform: SupportedPlatform;\n [extra: string]: unknown;\n}\n\n/** @deprecated */\nexport async function queryAutolinkingModulesFromProjectAsync(\n projectRoot: string,\n options: QueryAutolinkingModulesFromProjectParams\n): Promise<ModuleDescriptor[]> {\n const autolinkingOptionsLoader = createAutolinkingOptionsLoader({\n ...options,\n // NOTE(@kitten): This has always been duplicated\n projectRoot: options.projectRoot ?? projectRoot,\n });\n const appRoot = await autolinkingOptionsLoader.getAppRoot();\n const autolinkingOptions = await autolinkingOptionsLoader.getPlatformOptions(options.platform);\n const searchResults = await findModulesAsync({ appRoot, autolinkingOptions });\n return await resolveModulesAsync(searchResults, autolinkingOptions);\n}\n\n/** @deprecated */\nexport function findProjectRootSync(cwd: string = process.cwd()): string {\n for (let dir = cwd; path.dirname(dir) !== dir; dir = path.dirname(dir)) {\n const file = path.resolve(dir, 'package.json');\n if (fs.existsSync(file)) {\n return file;\n }\n }\n throw new Error(`Couldn't find \"package.json\" up from path \"${cwd}\"`);\n}\n\n/** @deprecated */\nexport async function resolveSearchPathsAsync(\n searchPaths: string[] | null,\n cwd: string\n): Promise<string[]> {\n return filterMapSearchPaths(searchPaths, cwd) ?? [];\n}\n"]}

View File

@@ -0,0 +1 @@
export {};

27
node_modules/expo-modules-autolinking/build/index.js generated vendored Normal file
View File

@@ -0,0 +1,27 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const commander_1 = __importDefault(require("commander"));
const generateModulesProviderCommand_1 = require("./commands/generateModulesProviderCommand");
const reactNativeConfigCommand_1 = require("./commands/reactNativeConfigCommand");
const resolveCommand_1 = require("./commands/resolveCommand");
const searchCommand_1 = require("./commands/searchCommand");
const verifyCommand_1 = require("./commands/verifyCommand");
const memoize_1 = require("./memoize");
async function main(args) {
const cli = commander_1.default
.version(require('expo-modules-autolinking/package.json').version)
.description('CLI command that searches for native modules to autolink them.');
(0, verifyCommand_1.verifyCommand)(cli);
(0, searchCommand_1.searchCommand)(cli);
(0, resolveCommand_1.resolveCommand)(cli);
(0, generateModulesProviderCommand_1.generateModulesProviderCommand)(cli);
(0, reactNativeConfigCommand_1.reactNativeConfigCommand)(cli);
await (0, memoize_1.createMemoizer)().withMemoizer(async () => {
await cli.parseAsync(args, { from: 'user' });
});
}
module.exports = main;
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;AAAA,0DAAkC;AAElC,8FAA2F;AAC3F,kFAA+E;AAC/E,8DAA2D;AAC3D,4DAAyD;AACzD,4DAAyD;AACzD,uCAA2C;AAE3C,KAAK,UAAU,IAAI,CAAC,IAAc;IAChC,MAAM,GAAG,GAAG,mBAAS;SAClB,OAAO,CAAC,OAAO,CAAC,uCAAuC,CAAC,CAAC,OAAO,CAAC;SACjE,WAAW,CAAC,gEAAgE,CAAC,CAAC;IAEjF,IAAA,6BAAa,EAAC,GAAG,CAAC,CAAC;IACnB,IAAA,6BAAa,EAAC,GAAG,CAAC,CAAC;IACnB,IAAA,+BAAc,EAAC,GAAG,CAAC,CAAC;IACpB,IAAA,+DAA8B,EAAC,GAAG,CAAC,CAAC;IACpC,IAAA,mDAAwB,EAAC,GAAG,CAAC,CAAC;IAE9B,MAAM,IAAA,wBAAc,GAAE,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE;QAC7C,MAAM,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC","sourcesContent":["import commander from 'commander';\n\nimport { generateModulesProviderCommand } from './commands/generateModulesProviderCommand';\nimport { reactNativeConfigCommand } from './commands/reactNativeConfigCommand';\nimport { resolveCommand } from './commands/resolveCommand';\nimport { searchCommand } from './commands/searchCommand';\nimport { verifyCommand } from './commands/verifyCommand';\nimport { createMemoizer } from './memoize';\n\nasync function main(args: string[]) {\n const cli = commander\n .version(require('expo-modules-autolinking/package.json').version)\n .description('CLI command that searches for native modules to autolink them.');\n\n verifyCommand(cli);\n searchCommand(cli);\n resolveCommand(cli);\n generateModulesProviderCommand(cli);\n reactNativeConfigCommand(cli);\n\n await createMemoizer().withMemoizer(async () => {\n await cli.parseAsync(args, { from: 'user' });\n });\n}\n\nmodule.exports = main;\n"]}

View File

@@ -0,0 +1,16 @@
export interface Memoizer {
/** Calls a function with a memoizer cache, caching its return value */
call<T, Args extends any[], Fn extends MemoizableAsyncFn<Args, T>>(fn: Fn, input: string, ...args: Args): Promise<T>;
/** Invokes an async context with a memoizer cache */
withMemoizer<R>(callback: () => R): R;
withMemoizer<R, TArgs extends any[]>(callback: (...args: TArgs) => R, ...args: TArgs): R;
}
export interface MemoizableAsyncFn<Args extends any[] = any[], T = any> {
(input: string, ...args: Args): Promise<T>;
}
/** Wraps a function in a memoizer, using the memoizer async local storage */
export declare function memoize<Args extends any[], T, Fn extends MemoizableAsyncFn<Args, T>>(fn: Fn): MemoizableAsyncFn<Args, T>;
/** Creates a memoizer that can provide a cache to memoized functions */
export declare function createMemoizer(): Memoizer;
/** @internal Used in tests to verify the memoizer was freed */
export declare function _verifyMemoizerFreed(): boolean;

84
node_modules/expo-modules-autolinking/build/memoize.js generated vendored Normal file
View File

@@ -0,0 +1,84 @@
"use strict";
// expo-modules-autolinking has a few memoizable operations that we don't want to repeat.
// However, memoizing them naively means that we may hold on to the cached values for too long.
// Instead, we wrap all calls with a `Memoizer`.
//
// This could use AsyncLocalStorage, but those are expensive. Instead, we only share one
// cache for all calls, and assume that all memoizable return values may be memoized and
// shared globally.
//
// Memoizers are created once per run, and then shared between all subsequent calls. They
// are freed when their usage count to zero, after one tick.
//
// NOTE: If you need to debug whether the memoizer is properly used, change when the
// `console.warn` appears to see if you have any uncached calls. We allow uncached calls
// for backwards-compatibility, since, at worst, we have an uncached call, if the
// Memoizer is missing.
Object.defineProperty(exports, "__esModule", { value: true });
exports.memoize = memoize;
exports.createMemoizer = createMemoizer;
exports._verifyMemoizerFreed = _verifyMemoizerFreed;
const MAX_SIZE = 5_000;
let currentMemoizer;
let currentContexts = 0;
/** Wraps a function in a memoizer, using the memoizer async local storage */
function memoize(fn) {
return (input, ...args) => {
// We either use the current memoizer (sync) or the memoize context (async)
if (!currentMemoizer) {
if (process.env.NODE_ENV === 'test') {
console.warn(`expo-modules-autolinking: Memoized function called without memoize context (${fn.name})\n` +
new Error().stack);
}
return fn(input, ...args);
}
return currentMemoizer.call(fn, input, ...args);
};
}
/** Creates a memoizer that can provide a cache to memoized functions */
function createMemoizer() {
// If we already have a memoizer, reuse it, since we can share them globally
if (currentMemoizer) {
return currentMemoizer;
}
const cacheByFn = new Map();
const memoizer = {
async call(fn, input, ...args) {
let cache = cacheByFn.get(fn);
if (!cache) {
cache = new Map();
cacheByFn.set(fn, cache);
}
if (!cache.has(input)) {
const value = await memoizer.withMemoizer(fn, input, ...args);
if (cache.size > MAX_SIZE) {
cache.clear();
}
cache.set(input, value);
return value;
}
return cache.get(input);
},
async withMemoizer(fn, ...args) {
currentMemoizer = memoizer;
currentContexts++;
try {
return await fn(...args);
}
finally {
if (currentContexts > 0) {
currentContexts--;
}
if (currentContexts === 0) {
currentMemoizer = undefined;
}
}
},
};
return memoizer;
}
/** @internal Used in tests to verify the memoizer was freed */
function _verifyMemoizerFreed() {
return currentMemoizer === undefined && currentContexts === 0;
}
//# sourceMappingURL=memoize.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,39 @@
import { AutolinkingOptions } from '../../commands/autolinkingOptions';
import type { ExtraDependencies, ModuleDescriptorAndroid, PackageRevision } from '../../types';
interface AndroidConfigurationOutput {
buildFromSource: string[];
}
export declare function getConfiguration(options: AutolinkingOptions): AndroidConfigurationOutput | undefined;
export declare function isAndroidProject(projectRoot: string): boolean;
export declare function resolveModuleAsync(packageName: string, revision: PackageRevision): Promise<ModuleDescriptorAndroid | null>;
export declare function resolveExtraBuildDependenciesAsync(projectNativeRoot: string): Promise<ExtraDependencies | null>;
export declare function resolveGradlePropertyAsync(projectNativeRoot: string, propertyKey: string): Promise<string | null>;
/**
* Converts the package name to Android's project name.
* `/` path will transform as `-`
*
* Example: `@expo/example` + `android/build.gradle` → `expo-example`
*/
export declare function convertPackageToProjectName(packageName: string): string;
/**
* Converts the package name and gradle file path to Android's project name.
* `$` to indicate subprojects
* `/` path will transform as `-`
*
* Example: `@expo/example` + `android/build.gradle` → `expo-example`
*
* Example: multiple projects
* - `expo-test` + `android/build.gradle` → `react-native-third-party`
* - `expo-test` + `subproject/build.gradle` → `react-native-third-party$subproject`
*/
export declare function convertPackageWithGradleToProjectName(packageName: string, buildGradleFile: string): string;
/**
* Given the contents of a `gradle.properties` file,
* searches for a property with the given name.
*
* This function will return the first property found with the given name.
* The implementation follows config-plugins and
* tries to align the behavior with the `withGradleProperties` plugin.
*/
export declare function searchGradlePropertyFirst(contents: string, propertyName: string): string | null;
export {};

View File

@@ -0,0 +1,175 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getConfiguration = getConfiguration;
exports.isAndroidProject = isAndroidProject;
exports.resolveModuleAsync = resolveModuleAsync;
exports.resolveExtraBuildDependenciesAsync = resolveExtraBuildDependenciesAsync;
exports.resolveGradlePropertyAsync = resolveGradlePropertyAsync;
exports.convertPackageToProjectName = convertPackageToProjectName;
exports.convertPackageWithGradleToProjectName = convertPackageWithGradleToProjectName;
exports.searchGradlePropertyFirst = searchGradlePropertyFirst;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const concurrency_1 = require("../../concurrency");
const utils_1 = require("../../utils");
const ANDROID_PROPERTIES_FILE = 'gradle.properties';
const ANDROID_EXTRA_BUILD_DEPS_KEY = 'android.extraMavenRepos';
function getConfiguration(options) {
return options.buildFromSource ? { buildFromSource: options.buildFromSource } : undefined;
}
function isAndroidProject(projectRoot) {
return (fs_1.default.existsSync(path_1.default.join(projectRoot, 'build.gradle')) ||
fs_1.default.existsSync(path_1.default.join(projectRoot, 'build.gradle.kts')));
}
async function resolveModuleAsync(packageName, revision) {
// TODO: Relative source dir should be configurable through the module config.
// Don't link itself... :D
if (packageName === '@unimodules/react-native-adapter') {
return null;
}
const plugins = (revision.config?.androidGradlePlugins() ?? []).map(({ id, group, sourceDir, applyToRootProject }) => ({
id,
group,
sourceDir: path_1.default.join(revision.path, sourceDir),
applyToRootProject: applyToRootProject ?? true,
}));
const defaultProjectName = convertPackageToProjectName(packageName);
const androidProjects = revision.config
?.androidProjects(defaultProjectName)
?.filter((project) => {
return !project.isDefault || isAndroidProject(path_1.default.join(revision.path, project.path));
});
// Just in case where the module doesn't have its own `build.gradle`/`settings.gradle`.
if (!androidProjects?.length) {
if (!plugins.length) {
return null;
}
return {
packageName,
plugins,
};
}
const projects = await (0, concurrency_1.taskAll)(androidProjects, async (project) => {
const projectPath = path_1.default.join(revision.path, project.path);
const aarProjects = (project.gradleAarProjects ?? [])?.map((aarProject) => {
const projectName = `${defaultProjectName}$${aarProject.name}`;
const projectDir = path_1.default.join(projectPath, 'build', projectName);
return {
name: projectName,
aarFilePath: path_1.default.join(revision.path, aarProject.aarFilePath),
projectDir,
};
});
const { publication } = project;
const shouldUsePublicationScriptPath = project.shouldUsePublicationScriptPath
? path_1.default.join(revision.path, project.shouldUsePublicationScriptPath)
: undefined;
const packages = new Set();
for await (const file of (0, utils_1.scanFilesRecursively)(projectPath)) {
if (!file.name.endsWith('Package.java') && !file.name.endsWith('Package.kt')) {
continue;
}
const fileContent = await fs_1.default.promises.readFile(file.path, 'utf8');
// Very naive check to skip non-expo packages
if (!/\bimport\s+expo\.modules\.core\.(interfaces\.Package|BasePackage)\b/.test(fileContent)) {
continue;
}
const classPathMatches = fileContent.match(/^package ([\w.]+)\b/m);
if (classPathMatches) {
const basename = path_1.default.basename(file.name, path_1.default.extname(file.name));
packages.add(`${classPathMatches[1]}.${basename}`);
}
}
return {
name: project.name,
sourceDir: projectPath,
modules: project.modules ?? [],
services: project.services ?? [],
packages: [...packages].sort((a, b) => a.localeCompare(b)),
...(shouldUsePublicationScriptPath ? { shouldUsePublicationScriptPath } : {}),
...(publication ? { publication } : {}),
...(aarProjects?.length > 0 ? { aarProjects } : {}),
};
});
const coreFeatures = revision.config?.coreFeatures() ?? [];
return {
packageName,
projects,
...(plugins?.length > 0 ? { plugins } : {}),
...(coreFeatures.length > 0 ? { coreFeatures } : {}),
};
}
async function resolveExtraBuildDependenciesAsync(projectNativeRoot) {
const extraMavenReposString = await resolveGradlePropertyAsync(projectNativeRoot, ANDROID_EXTRA_BUILD_DEPS_KEY);
if (extraMavenReposString) {
try {
return JSON.parse(extraMavenReposString);
}
catch { }
}
return null;
}
async function resolveGradlePropertyAsync(projectNativeRoot, propertyKey) {
const propsFile = path_1.default.join(projectNativeRoot, ANDROID_PROPERTIES_FILE);
try {
const contents = await fs_1.default.promises.readFile(propsFile, 'utf8');
const propertyValue = searchGradlePropertyFirst(contents, propertyKey);
if (propertyValue) {
return propertyValue;
}
}
catch { }
return null;
}
/**
* Converts the package name to Android's project name.
* `/` path will transform as `-`
*
* Example: `@expo/example` + `android/build.gradle` → `expo-example`
*/
function convertPackageToProjectName(packageName) {
return packageName.replace(/^@/g, '').replace(/\W+/g, '-');
}
/**
* Converts the package name and gradle file path to Android's project name.
* `$` to indicate subprojects
* `/` path will transform as `-`
*
* Example: `@expo/example` + `android/build.gradle` → `expo-example`
*
* Example: multiple projects
* - `expo-test` + `android/build.gradle` → `react-native-third-party`
* - `expo-test` + `subproject/build.gradle` → `react-native-third-party$subproject`
*/
function convertPackageWithGradleToProjectName(packageName, buildGradleFile) {
const name = convertPackageToProjectName(packageName);
const baseDir = path_1.default.dirname(buildGradleFile).replace(/\//g, '-');
return baseDir === 'android' ? name : `${name}$${baseDir}`;
}
/**
* Given the contents of a `gradle.properties` file,
* searches for a property with the given name.
*
* This function will return the first property found with the given name.
* The implementation follows config-plugins and
* tries to align the behavior with the `withGradleProperties` plugin.
*/
function searchGradlePropertyFirst(contents, propertyName) {
const lines = contents.split('\n');
for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim();
if (line && !line.startsWith('#')) {
const eok = line.indexOf('=');
const key = line.slice(0, eok);
if (key === propertyName) {
const value = line.slice(eok + 1, line.length);
return value;
}
}
}
return null;
}
//# sourceMappingURL=android.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
export { getConfiguration, resolveModuleAsync, resolveExtraBuildDependenciesAsync, } from './android';

View File

@@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveExtraBuildDependenciesAsync = exports.resolveModuleAsync = exports.getConfiguration = void 0;
var android_1 = require("./android");
Object.defineProperty(exports, "getConfiguration", { enumerable: true, get: function () { return android_1.getConfiguration; } });
Object.defineProperty(exports, "resolveModuleAsync", { enumerable: true, get: function () { return android_1.resolveModuleAsync; } });
Object.defineProperty(exports, "resolveExtraBuildDependenciesAsync", { enumerable: true, get: function () { return android_1.resolveExtraBuildDependenciesAsync; } });
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/platforms/android/index.ts"],"names":[],"mappings":";;;AAAA,qCAImB;AAHjB,2GAAA,gBAAgB,OAAA;AAChB,6GAAA,kBAAkB,OAAA;AAClB,6HAAA,kCAAkC,OAAA","sourcesContent":["export {\n getConfiguration,\n resolveModuleAsync,\n resolveExtraBuildDependenciesAsync,\n} from './android';\n"]}

View File

@@ -0,0 +1,15 @@
import type { ExtraDependencies, ModuleDescriptorIos, ModuleIosPodspecInfo, PackageRevision } from '../../types';
export declare function getSwiftModuleNames(pods: ModuleIosPodspecInfo[], swiftModuleNames: string[] | undefined): string[];
/** Resolves module search result with additional details required for iOS platform. */
export declare function resolveModuleAsync(packageName: string, revision: PackageRevision, extraOutput: {
flags?: Record<string, any>;
}): Promise<ModuleDescriptorIos | null>;
export declare function resolveExtraBuildDependenciesAsync(projectNativeRoot: string): Promise<ExtraDependencies | null>;
/**
* Generates Swift file that contains all autolinked Swift packages.
*/
export declare function generateModulesProviderAsync(modules: ModuleDescriptorIos[], targetPath: string, entitlementPath: string | null): Promise<void>;
/**
* Formats an array of modules to Swift's array containing ReactDelegateHandlers
*/
export declare function formatArrayOfReactDelegateHandler(modules: ModuleDescriptorIos[]): string;

View File

@@ -0,0 +1,221 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getSwiftModuleNames = getSwiftModuleNames;
exports.resolveModuleAsync = resolveModuleAsync;
exports.resolveExtraBuildDependenciesAsync = resolveExtraBuildDependenciesAsync;
exports.generateModulesProviderAsync = generateModulesProviderAsync;
exports.formatArrayOfReactDelegateHandler = formatArrayOfReactDelegateHandler;
const spawn_async_1 = __importDefault(require("@expo/spawn-async"));
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const utils_1 = require("../../utils");
const APPLE_PROPERTIES_FILE = 'Podfile.properties.json';
const APPLE_EXTRA_BUILD_DEPS_KEY = 'apple.extraPods';
const indent = ' ';
/** Find all *.podspec files in top-level directories */
async function findPodspecFiles(revision) {
const configPodspecPaths = revision.config?.applePodspecPaths();
if (configPodspecPaths && configPodspecPaths.length) {
return configPodspecPaths;
}
else {
return await (0, utils_1.listFilesInDirectories)(revision.path, (basename) => basename.endsWith('.podspec'));
}
}
function getSwiftModuleNames(pods, swiftModuleNames) {
if (swiftModuleNames && swiftModuleNames.length) {
return swiftModuleNames;
}
// by default, non-alphanumeric characters in the pod name are replaced by _ in the module name
return pods.map((pod) => pod.podName.replace(/[^a-zA-Z0-9]/g, '_'));
}
/** Resolves module search result with additional details required for iOS platform. */
async function resolveModuleAsync(packageName, revision, extraOutput) {
const podspecFiles = await findPodspecFiles(revision);
if (!podspecFiles.length) {
return null;
}
const pods = podspecFiles.map((podspecFile) => ({
podName: path_1.default.basename(podspecFile, path_1.default.extname(podspecFile)),
podspecDir: path_1.default.dirname(path_1.default.join(revision.path, podspecFile)),
}));
const swiftModuleNames = getSwiftModuleNames(pods, revision.config?.appleSwiftModuleNames());
const coreFeatures = revision.config?.coreFeatures() ?? [];
return {
packageName,
pods,
swiftModuleNames,
flags: extraOutput.flags,
modules: revision.config
?.appleModules()
.map((module) => (typeof module === 'string' ? { name: null, class: module } : module)) ??
[],
appDelegateSubscribers: revision.config?.appleAppDelegateSubscribers() ?? [],
reactDelegateHandlers: revision.config?.appleReactDelegateHandlers() ?? [],
debugOnly: revision.config?.appleDebugOnly() ?? false,
...(coreFeatures.length > 0 ? { coreFeatures } : {}),
};
}
async function resolveExtraBuildDependenciesAsync(projectNativeRoot) {
const propsFile = path_1.default.join(projectNativeRoot, APPLE_PROPERTIES_FILE);
try {
const contents = await fs_1.default.promises.readFile(propsFile, 'utf8');
const podfileJson = JSON.parse(contents);
if (podfileJson[APPLE_EXTRA_BUILD_DEPS_KEY]) {
// expo-build-properties would serialize the extraPods as JSON string, we should parse it again.
const extraPods = JSON.parse(podfileJson[APPLE_EXTRA_BUILD_DEPS_KEY]);
return extraPods;
}
}
catch { }
return null;
}
/**
* Generates Swift file that contains all autolinked Swift packages.
*/
async function generateModulesProviderAsync(modules, targetPath, entitlementPath) {
const className = path_1.default.basename(targetPath, path_1.default.extname(targetPath));
const entitlements = await parseEntitlementsAsync(entitlementPath);
const generatedFileContent = await generatePackageListFileContentAsync(modules, className, entitlements);
const parentPath = path_1.default.dirname(targetPath);
await fs_1.default.promises.mkdir(parentPath, { recursive: true });
await fs_1.default.promises.writeFile(targetPath, generatedFileContent, 'utf8');
}
/**
* Generates the string to put into the generated package list.
*/
async function generatePackageListFileContentAsync(modules, className, entitlements) {
const iosModules = modules.filter((module) => module.modules.length ||
module.appDelegateSubscribers.length ||
module.reactDelegateHandlers.length);
const modulesToImport = iosModules.filter((module) => !module.debugOnly);
const debugOnlyModules = iosModules.filter((module) => module.debugOnly);
const swiftModules = []
.concat(...modulesToImport.map((module) => module.swiftModuleNames))
.filter(Boolean);
const debugOnlySwiftModules = []
.concat(...debugOnlyModules.map((module) => module.swiftModuleNames))
.filter(Boolean);
const modulesClassNames = []
.concat(...modulesToImport.map((module) => module.modules))
.filter(Boolean);
const debugOnlyModulesClassNames = []
.concat(...debugOnlyModules.map((module) => module.modules))
.filter(Boolean);
const appDelegateSubscribers = [].concat(...modulesToImport.map((module) => module.appDelegateSubscribers));
const debugOnlyAppDelegateSubscribers = [].concat(...debugOnlyModules.map((module) => module.appDelegateSubscribers));
const reactDelegateHandlerModules = modulesToImport.filter((module) => !!module.reactDelegateHandlers.length);
const debugOnlyReactDelegateHandlerModules = debugOnlyModules.filter((module) => !!module.reactDelegateHandlers.length);
return `/**
* Automatically generated by expo-modules-autolinking.
*
* This autogenerated class provides a list of classes of native Expo modules,
* but only these that are written in Swift and use the new API for creating Expo modules.
*/
internal import ExpoModulesCore
${generateCommonImportList(swiftModules)}
${generateDebugOnlyImportList(debugOnlySwiftModules)}
@objc(${className})
internal class ${className}: ModulesProvider {
public override func getModuleClasses() -> [ExpoModuleTupleType] {
${generateModuleClasses(modulesClassNames, debugOnlyModulesClassNames)}
}
public override func getAppDelegateSubscribers() -> [ExpoAppDelegateSubscriber.Type] {
${generateClasses(appDelegateSubscribers, debugOnlyAppDelegateSubscribers)}
}
public override func getReactDelegateHandlers() -> [ExpoReactDelegateHandlerTupleType] {
${generateReactDelegateHandlers(reactDelegateHandlerModules, debugOnlyReactDelegateHandlerModules)}
}
public override func getAppCodeSignEntitlements() -> AppCodeSignEntitlements {
return AppCodeSignEntitlements.from(json: #"${JSON.stringify(entitlements)}"#)
}
}
`;
}
function generateCommonImportList(swiftModules) {
return swiftModules.map((moduleName) => `internal import ${moduleName}`).join('\n');
}
function generateDebugOnlyImportList(swiftModules) {
if (!swiftModules.length) {
return '';
}
return (wrapInDebugConfigurationCheck(0, swiftModules.map((moduleName) => `internal import ${moduleName}`).join('\n')) + '\n');
}
function generateModuleClasses(modules, debugOnlyModules) {
const commonClassNames = formatArrayOfModuleTuples(modules);
if (debugOnlyModules.length > 0) {
return wrapInDebugConfigurationCheck(2, `return ${formatArrayOfModuleTuples(modules.concat(debugOnlyModules))}`, `return ${commonClassNames}`);
}
else {
return `${indent.repeat(2)}return ${commonClassNames}`;
}
}
/**
* Formats an array of modules config to Swift's array of module tuples.
*/
function formatArrayOfModuleTuples(modules) {
return `[${modules.map((module) => `\n${indent.repeat(3)}(module: ${module.class}.self, name: ${module.name ? `"${module.name}"` : 'nil'})`).join(',')}
${indent.repeat(2)}]`;
}
function generateClasses(classNames, debugOnlyClassName) {
const commonClassNames = formatArrayOfClassNames(classNames);
if (debugOnlyClassName.length > 0) {
return wrapInDebugConfigurationCheck(2, `return ${formatArrayOfClassNames(classNames.concat(debugOnlyClassName))}`, `return ${commonClassNames}`);
}
else {
return `${indent.repeat(2)}return ${commonClassNames}`;
}
}
/**
* Formats an array of class names to Swift's array containing these classes.
*/
function formatArrayOfClassNames(classNames) {
return `[${classNames.map((className) => `\n${indent.repeat(3)}${className}.self`).join(',')}
${indent.repeat(2)}]`;
}
function generateReactDelegateHandlers(module, debugOnlyModules) {
const commonModules = formatArrayOfReactDelegateHandler(module);
if (debugOnlyModules.length > 0) {
return wrapInDebugConfigurationCheck(2, `return ${formatArrayOfReactDelegateHandler(module.concat(debugOnlyModules))}`, `return ${commonModules}`);
}
else {
return `${indent.repeat(2)}return ${commonModules}`;
}
}
/**
* Formats an array of modules to Swift's array containing ReactDelegateHandlers
*/
function formatArrayOfReactDelegateHandler(modules) {
const values = [];
for (const module of modules) {
for (const handler of module.reactDelegateHandlers) {
values.push(`(packageName: "${module.packageName}", handler: ${handler}.self)`);
}
}
return `[${values.map((value) => `\n${indent.repeat(3)}${value}`).join(',')}
${indent.repeat(2)}]`;
}
function wrapInDebugConfigurationCheck(indentationLevel, debugBlock, releaseBlock = null) {
if (releaseBlock) {
return `${indent.repeat(indentationLevel)}#if EXPO_CONFIGURATION_DEBUG\n${indent.repeat(indentationLevel)}${debugBlock}\n${indent.repeat(indentationLevel)}#else\n${indent.repeat(indentationLevel)}${releaseBlock}\n${indent.repeat(indentationLevel)}#endif`;
}
return `${indent.repeat(indentationLevel)}#if EXPO_CONFIGURATION_DEBUG\n${indent.repeat(indentationLevel)}${debugBlock}\n${indent.repeat(indentationLevel)}#endif`;
}
async function parseEntitlementsAsync(entitlementPath) {
if (!entitlementPath || !(await (0, utils_1.fileExistsAsync)(entitlementPath))) {
return {};
}
const { stdout } = await (0, spawn_async_1.default)('plutil', ['-convert', 'json', '-o', '-', entitlementPath]);
const entitlementsJson = JSON.parse(stdout);
return {
appGroups: entitlementsJson['com.apple.security.application-groups'] || undefined,
};
}
//# sourceMappingURL=apple.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
export { generateModulesProviderAsync, resolveModuleAsync, resolveExtraBuildDependenciesAsync, } from './apple';

View File

@@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveExtraBuildDependenciesAsync = exports.resolveModuleAsync = exports.generateModulesProviderAsync = void 0;
var apple_1 = require("./apple");
Object.defineProperty(exports, "generateModulesProviderAsync", { enumerable: true, get: function () { return apple_1.generateModulesProviderAsync; } });
Object.defineProperty(exports, "resolveModuleAsync", { enumerable: true, get: function () { return apple_1.resolveModuleAsync; } });
Object.defineProperty(exports, "resolveExtraBuildDependenciesAsync", { enumerable: true, get: function () { return apple_1.resolveExtraBuildDependenciesAsync; } });
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/platforms/apple/index.ts"],"names":[],"mappings":";;;AAAA,iCAIiB;AAHf,qHAAA,4BAA4B,OAAA;AAC5B,2GAAA,kBAAkB,OAAA;AAClB,2HAAA,kCAAkC,OAAA","sourcesContent":["export {\n generateModulesProviderAsync,\n resolveModuleAsync,\n resolveExtraBuildDependenciesAsync,\n} from './apple';\n"]}

View File

@@ -0,0 +1,3 @@
import type { ExtraDependencies, ModuleDescriptorDevTools, PackageRevision } from '../types';
export declare function resolveModuleAsync(packageName: string, revision: PackageRevision): Promise<ModuleDescriptorDevTools | null>;
export declare function resolveExtraBuildDependenciesAsync(_projectNativeRoot: string): Promise<ExtraDependencies | null>;

View File

@@ -0,0 +1,26 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveModuleAsync = resolveModuleAsync;
exports.resolveExtraBuildDependenciesAsync = resolveExtraBuildDependenciesAsync;
const path_1 = __importDefault(require("path"));
async function resolveModuleAsync(packageName, revision) {
const devtoolsConfig = revision.config?.toJSON().devtools;
if (devtoolsConfig == null) {
return null;
}
return {
packageName,
packageRoot: revision.path,
webpageRoot: devtoolsConfig.webpageRoot
? path_1.default.join(revision.path, devtoolsConfig.webpageRoot)
: undefined,
cliExtensions: devtoolsConfig.cliExtensions,
};
}
async function resolveExtraBuildDependenciesAsync(_projectNativeRoot) {
return null;
}
//# sourceMappingURL=devtools.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"devtools.js","sourceRoot":"","sources":["../../src/platforms/devtools.ts"],"names":[],"mappings":";;;;;AAIA,gDAiBC;AAED,gFAIC;AA3BD,gDAAwB;AAIjB,KAAK,UAAU,kBAAkB,CACtC,WAAmB,EACnB,QAAyB;IAEzB,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,QAAQ,CAAC;IAC1D,IAAI,cAAc,IAAI,IAAI,EAAE,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO;QACL,WAAW;QACX,WAAW,EAAE,QAAQ,CAAC,IAAI;QAC1B,WAAW,EAAE,cAAc,CAAC,WAAW;YACrC,CAAC,CAAC,cAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC,WAAW,CAAC;YACtD,CAAC,CAAC,SAAS;QACb,aAAa,EAAE,cAAc,CAAC,aAAa;KAC5C,CAAC;AACJ,CAAC;AAEM,KAAK,UAAU,kCAAkC,CACtD,kBAA0B;IAE1B,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["import path from 'path';\n\nimport type { ExtraDependencies, ModuleDescriptorDevTools, PackageRevision } from '../types';\n\nexport async function resolveModuleAsync(\n packageName: string,\n revision: PackageRevision\n): Promise<ModuleDescriptorDevTools | null> {\n const devtoolsConfig = revision.config?.toJSON().devtools;\n if (devtoolsConfig == null) {\n return null;\n }\n\n return {\n packageName,\n packageRoot: revision.path,\n webpageRoot: devtoolsConfig.webpageRoot\n ? path.join(revision.path, devtoolsConfig.webpageRoot)\n : undefined,\n cliExtensions: devtoolsConfig.cliExtensions,\n };\n}\n\nexport async function resolveExtraBuildDependenciesAsync(\n _projectNativeRoot: string\n): Promise<ExtraDependencies | null> {\n return null;\n}\n"]}

View File

@@ -0,0 +1,17 @@
import { SupportedPlatform } from '../types';
interface PlatformImplementations {
ios: typeof import('./apple/apple');
macos: typeof import('./apple/apple');
tvos: typeof import('./apple/apple');
apple: typeof import('./apple/apple');
android: typeof import('./android/android');
devtools: typeof import('./devtools');
web: typeof import('./web');
}
declare function getLinkingImplementationForPlatform<Platform extends keyof PlatformImplementations>(platform: Platform): PlatformImplementations[Platform];
declare function getLinkingImplementationForPlatform(platform: 'ios' | 'macos' | 'tvos' | 'apple'): PlatformImplementations['apple'];
declare function getLinkingImplementationForPlatform(platform: 'android'): PlatformImplementations['android'];
declare function getLinkingImplementationForPlatform(platform: 'devtools'): PlatformImplementations['devtools'];
declare function getLinkingImplementationForPlatform(platform: 'web'): PlatformImplementations['web'];
declare function getLinkingImplementationForPlatform(platform: SupportedPlatform): PlatformImplementations[keyof PlatformImplementations];
export { getLinkingImplementationForPlatform };

View File

@@ -0,0 +1,24 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getLinkingImplementationForPlatform = getLinkingImplementationForPlatform;
function getLinkingImplementationForPlatform(platform) {
if (!platform) {
throw new Error(`No platform was specified, but linking commands require a specific platform.`);
}
switch (platform) {
case 'ios':
case 'macos':
case 'tvos':
case 'apple':
return require('../platforms/apple');
case 'android':
return require('../platforms/android');
case 'devtools':
return require('../platforms/devtools');
case 'web':
return require('../platforms/web');
default:
throw new Error(`No linking implementation is available for platform "${platform}"`);
}
}
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/platforms/index.ts"],"names":[],"mappings":";;AAoDS,kFAAmC;AAvB5C,SAAS,mCAAmC,CAC1C,QAA2B;IAE3B,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,8EAA8E,CAAC,CAAC;IAClG,CAAC;IACD,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,KAAK,CAAC;QACX,KAAK,OAAO,CAAC;QACb,KAAK,MAAM,CAAC;QACZ,KAAK,OAAO;YACV,OAAO,OAAO,CAAC,oBAAoB,CAAC,CAAC;QACvC,KAAK,SAAS;YACZ,OAAO,OAAO,CAAC,sBAAsB,CAAC,CAAC;QACzC,KAAK,UAAU;YACb,OAAO,OAAO,CAAC,uBAAuB,CAAC,CAAC;QAC1C,KAAK,KAAK;YACR,OAAO,OAAO,CAAC,kBAAkB,CAAC,CAAC;QACrC;YACE,MAAM,IAAI,KAAK,CAAC,wDAAwD,QAAQ,GAAG,CAAC,CAAC;IACzF,CAAC;AACH,CAAC","sourcesContent":["import { SupportedPlatform } from '../types';\n\ninterface PlatformImplementations {\n ios: typeof import('./apple/apple');\n macos: typeof import('./apple/apple');\n tvos: typeof import('./apple/apple');\n apple: typeof import('./apple/apple');\n android: typeof import('./android/android');\n devtools: typeof import('./devtools');\n web: typeof import('./web');\n}\n\nfunction getLinkingImplementationForPlatform<Platform extends keyof PlatformImplementations>(\n platform: Platform\n): PlatformImplementations[Platform];\nfunction getLinkingImplementationForPlatform(\n platform: 'ios' | 'macos' | 'tvos' | 'apple'\n): PlatformImplementations['apple'];\nfunction getLinkingImplementationForPlatform(\n platform: 'android'\n): PlatformImplementations['android'];\nfunction getLinkingImplementationForPlatform(\n platform: 'devtools'\n): PlatformImplementations['devtools'];\nfunction getLinkingImplementationForPlatform(platform: 'web'): PlatformImplementations['web'];\nfunction getLinkingImplementationForPlatform(\n platform: SupportedPlatform\n): PlatformImplementations[keyof PlatformImplementations];\n\nfunction getLinkingImplementationForPlatform(\n platform: SupportedPlatform\n): PlatformImplementations[keyof PlatformImplementations] {\n if (!platform) {\n throw new Error(`No platform was specified, but linking commands require a specific platform.`);\n }\n switch (platform) {\n case 'ios':\n case 'macos':\n case 'tvos':\n case 'apple':\n return require('../platforms/apple');\n case 'android':\n return require('../platforms/android');\n case 'devtools':\n return require('../platforms/devtools');\n case 'web':\n return require('../platforms/web');\n default:\n throw new Error(`No linking implementation is available for platform \"${platform}\"`);\n }\n}\n\nexport { getLinkingImplementationForPlatform };\n"]}

View File

@@ -0,0 +1,3 @@
import type { ExtraDependencies, ModuleDescriptorWeb, PackageRevision } from '../types';
export declare function resolveModuleAsync(packageName: string, revision: PackageRevision): Promise<ModuleDescriptorWeb | null>;
export declare function resolveExtraBuildDependenciesAsync(_projectNativeRoot: string): Promise<ExtraDependencies | null>;

View File

@@ -0,0 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveModuleAsync = resolveModuleAsync;
exports.resolveExtraBuildDependenciesAsync = resolveExtraBuildDependenciesAsync;
async function resolveModuleAsync(packageName, revision) {
return {
packageName,
packageRoot: revision.path,
};
}
async function resolveExtraBuildDependenciesAsync(_projectNativeRoot) {
return null;
}
//# sourceMappingURL=web.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/platforms/web.ts"],"names":[],"mappings":";;AAEA,gDAQC;AAED,gFAIC;AAdM,KAAK,UAAU,kBAAkB,CACtC,WAAmB,EACnB,QAAyB;IAEzB,OAAO;QACL,WAAW;QACX,WAAW,EAAE,QAAQ,CAAC,IAAI;KAC3B,CAAC;AACJ,CAAC;AAEM,KAAK,UAAU,kCAAkC,CACtD,kBAA0B;IAE1B,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["import type { ExtraDependencies, ModuleDescriptorWeb, PackageRevision } from '../types';\n\nexport async function resolveModuleAsync(\n packageName: string,\n revision: PackageRevision\n): Promise<ModuleDescriptorWeb | null> {\n return {\n packageName,\n packageRoot: revision.path,\n };\n}\n\nexport async function resolveExtraBuildDependenciesAsync(\n _projectNativeRoot: string\n): Promise<ExtraDependencies | null> {\n return null;\n}\n"]}

View File

@@ -0,0 +1,21 @@
import type { RNConfigDependencyAndroid, RNConfigReactNativePlatformsConfigAndroid } from './reactNativeConfig.types';
import type { ExpoModuleConfig } from '../ExpoModuleConfig';
export declare function resolveDependencyConfigImplAndroidAsync(packageRoot: string, reactNativeConfig: RNConfigReactNativePlatformsConfigAndroid | null | undefined, expoModuleConfig?: ExpoModuleConfig | null): Promise<RNConfigDependencyAndroid | null>;
/**
* Parse the `RNConfigDependencyAndroid.packageName`
*/
export declare function parsePackageNameAsync(manifestPath: string | null, gradlePath: string | null): Promise<string | null>;
/**
* Parse the Java or Kotlin class name to for `ReactPackage` or `(Base|Turbo)ReactPackage`.
*/
export declare function parseNativePackageClassNameAsync(packageRoot: string, androidDir: string): Promise<string | null>;
export declare function matchNativePackageClassName(_filePath: string, contents: Buffer): string | null;
export declare function parseLibraryNameAsync(androidDir: string, packageJson: any): Promise<string | null>;
export declare function parseComponentDescriptorsAsync(packageRoot: string, packageJson: any): Promise<string[]>;
export declare function findGradleAndManifestAsync({ androidDir, isLibrary, }: {
androidDir: string;
isLibrary: boolean;
}): Promise<{
gradle: string | null;
manifest: string | null;
}>;

View File

@@ -0,0 +1,279 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveDependencyConfigImplAndroidAsync = resolveDependencyConfigImplAndroidAsync;
exports.parsePackageNameAsync = parsePackageNameAsync;
exports.parseNativePackageClassNameAsync = parseNativePackageClassNameAsync;
exports.matchNativePackageClassName = matchNativePackageClassName;
exports.parseLibraryNameAsync = parseLibraryNameAsync;
exports.parseComponentDescriptorsAsync = parseComponentDescriptorsAsync;
exports.findGradleAndManifestAsync = findGradleAndManifestAsync;
const promises_1 = __importDefault(require("fs/promises"));
const path_1 = __importDefault(require("path"));
const concurrency_1 = require("../concurrency");
const utils_1 = require("../utils");
async function resolveDependencyConfigImplAndroidAsync(packageRoot, reactNativeConfig, expoModuleConfig) {
if (reactNativeConfig === null) {
// Skip autolinking for this package.
return null;
}
// NOTE(@kitten): We allow `reactNativeConfig === undefined` here. That indicates a missing config file
// However, React Native modules with left out config files are explicitly supported and valid
const sourceDir = reactNativeConfig?.sourceDir || 'android';
const androidDir = path_1.default.join(packageRoot, sourceDir);
const { gradle, manifest } = await findGradleAndManifestAsync({ androidDir, isLibrary: true });
const isPureCxxDependency = reactNativeConfig?.cxxModuleCMakeListsModuleName != null &&
reactNativeConfig?.cxxModuleCMakeListsPath != null &&
reactNativeConfig?.cxxModuleHeaderName != null &&
!manifest &&
!gradle;
if (!manifest && !gradle && !isPureCxxDependency) {
return null;
}
if (reactNativeConfig === undefined && expoModuleConfig?.supportsPlatform('android')) {
if (!!gradle && !expoModuleConfig?.rawConfig.android?.gradlePath) {
// If the React Native module has a gradle file and the Expo module doesn't redirect it,
// they will conflict and we can't link both at the same time
return null;
}
}
let packageInstance = null;
let packageImportPath = null;
if (!isPureCxxDependency) {
const packageName = reactNativeConfig?.packageName || (await parsePackageNameAsync(manifest, gradle));
if (!packageName) {
return null;
}
const nativePackageClassName = await parseNativePackageClassNameAsync(packageRoot, androidDir);
if (!nativePackageClassName) {
return null;
}
packageImportPath =
reactNativeConfig?.packageImportPath || `import ${packageName}.${nativePackageClassName};`;
packageInstance = reactNativeConfig?.packageInstance || `new ${nativePackageClassName}()`;
}
const packageJson = await (0, utils_1.loadPackageJson)((0, utils_1.fastJoin)(packageRoot, 'package.json'));
const buildTypes = reactNativeConfig?.buildTypes || [];
const dependencyConfiguration = reactNativeConfig?.dependencyConfiguration;
const libraryName = reactNativeConfig?.libraryName || (await parseLibraryNameAsync(androidDir, packageJson));
const componentDescriptors = reactNativeConfig?.componentDescriptors ||
(await parseComponentDescriptorsAsync(packageRoot, packageJson));
let cmakeListsPath = reactNativeConfig?.cmakeListsPath
? path_1.default.join(androidDir, reactNativeConfig?.cmakeListsPath)
: path_1.default.join(androidDir, 'build/generated/source/codegen/jni/CMakeLists.txt');
const cxxModuleCMakeListsModuleName = reactNativeConfig?.cxxModuleCMakeListsModuleName || null;
const cxxModuleHeaderName = reactNativeConfig?.cxxModuleHeaderName || null;
let cxxModuleCMakeListsPath = reactNativeConfig?.cxxModuleCMakeListsPath
? path_1.default.join(androidDir, reactNativeConfig?.cxxModuleCMakeListsPath)
: null;
if (process.platform === 'win32') {
cmakeListsPath = cmakeListsPath.replace(/\\/g, '/');
if (cxxModuleCMakeListsPath) {
cxxModuleCMakeListsPath = cxxModuleCMakeListsPath.replace(/\\/g, '/');
}
}
const result = {
sourceDir: androidDir,
packageImportPath,
packageInstance,
dependencyConfiguration,
buildTypes,
libraryName,
componentDescriptors,
cmakeListsPath,
cxxModuleCMakeListsModuleName,
cxxModuleCMakeListsPath,
cxxModuleHeaderName,
isPureCxxDependency,
};
if (!result.libraryName) {
delete result.libraryName;
}
if (!result.dependencyConfiguration) {
delete result.dependencyConfiguration;
}
return result;
}
/**
* Parse the `RNConfigDependencyAndroid.packageName`
*/
async function parsePackageNameAsync(manifestPath, gradlePath) {
if (gradlePath) {
const gradleContents = await promises_1.default.readFile(gradlePath, 'utf8');
const match = gradleContents.match(/namespace\s*[=]*\s*["'](.+?)["']/);
if (match) {
return match[1];
}
}
if (manifestPath) {
const manifestContents = await promises_1.default.readFile(manifestPath, 'utf8');
const match = manifestContents.match(/package="(.+?)"/);
if (match) {
return match[1];
}
}
return null;
}
/**
* Parse the Java or Kotlin class name to for `ReactPackage` or `(Base|Turbo)ReactPackage`.
*/
async function parseNativePackageClassNameAsync(packageRoot, androidDir) {
// Search for **/*Package.{java,kt} files first
for await (const entry of (0, utils_1.scanFilesRecursively)(androidDir, undefined, true)) {
if (entry.name.endsWith('Package.java') || entry.name.endsWith('Package.kt')) {
try {
const contents = await promises_1.default.readFile(entry.path);
const matched = matchNativePackageClassName(entry.path, contents);
if (matched) {
return matched;
}
}
catch {
continue;
}
}
}
// Early return if the module is an Expo module
if (await (0, utils_1.fileExistsAsync)(path_1.default.join(packageRoot, 'expo-module.config.json'))) {
return null;
}
// Search all **/*.{java,kt} files
for await (const entry of (0, utils_1.scanFilesRecursively)(androidDir, undefined, true)) {
if (entry.name.endsWith('.java') || entry.name.endsWith('.kt')) {
const contents = await promises_1.default.readFile(entry.path);
const matched = matchNativePackageClassName(entry.path, contents);
if (matched) {
return matched;
}
}
}
return null;
}
let lazyReactPackageRegex = null;
let lazyTurboReactPackageRegex = null;
function matchNativePackageClassName(_filePath, contents) {
const fileContents = contents.toString();
// [0] Match ReactPackage
if (!lazyReactPackageRegex) {
lazyReactPackageRegex =
/class\s+(\w+[^(\s]*)[\s\w():]*(\s+implements\s+|:)[\s\w():,]*[^{]*ReactPackage/;
}
const matchReactPackage = fileContents.match(lazyReactPackageRegex);
if (matchReactPackage) {
return matchReactPackage[1];
}
// [1] Match (Base|Turbo)ReactPackage
if (!lazyTurboReactPackageRegex) {
lazyTurboReactPackageRegex =
/class\s+(\w+[^(\s]*)[\s\w():]*(\s+extends\s+|:)[\s\w():,]*[^{]*(Base|Turbo)ReactPackage/;
}
const matchTurboReactPackage = fileContents.match(lazyTurboReactPackageRegex);
if (matchTurboReactPackage) {
return matchTurboReactPackage[1];
}
return null;
}
async function parseLibraryNameAsync(androidDir, packageJson) {
// [0] `codegenConfig.name` from package.json
if (packageJson.codegenConfig?.name) {
return packageJson.codegenConfig.name;
}
const libraryNameRegExp = /libraryName = ["'](.+)["']/;
const gradlePath = path_1.default.join(androidDir, 'build.gradle');
// [1] `libraryName` from build.gradle
if (await (0, utils_1.fileExistsAsync)(gradlePath)) {
const buildGradleContents = await promises_1.default.readFile(gradlePath, 'utf8');
const match = buildGradleContents.match(libraryNameRegExp);
if (match) {
return match[1];
}
}
// [2] `libraryName` from build.gradle.kts
const gradleKtsPath = path_1.default.join(androidDir, 'build.gradle.kts');
if (await (0, utils_1.fileExistsAsync)(gradleKtsPath)) {
const buildGradleContents = await promises_1.default.readFile(gradleKtsPath, 'utf8');
const match = buildGradleContents.match(libraryNameRegExp);
if (match) {
return match[1];
}
}
return null;
}
async function parseComponentDescriptorsAsync(packageRoot, packageJson) {
const jsRoot = packageJson?.codegenConfig?.jsSrcsDir
? path_1.default.join(packageRoot, packageJson.codegenConfig.jsSrcsDir)
: packageRoot;
const extRe = /\.[tj]sx?$/;
const results = new Set();
for await (const entry of (0, utils_1.scanFilesRecursively)(jsRoot)) {
if (extRe.test(entry.name)) {
const contents = await promises_1.default.readFile(entry.path, 'utf8');
const matched = matchComponentDescriptors(entry.path, contents);
if (matched) {
results.add(matched);
}
}
}
return [...results].sort((a, b) => a.localeCompare(b));
}
let lazyCodegenComponentRegex = null;
function matchComponentDescriptors(_filePath, contents) {
if (!lazyCodegenComponentRegex) {
lazyCodegenComponentRegex =
/codegenNativeComponent(<.*>)?\s*\(\s*["'`](\w+)["'`](,?[\s\S]+interfaceOnly:\s*(\w+))?/m;
}
const match = contents.match(lazyCodegenComponentRegex);
if (!(match?.[4] === 'true') && match?.[2]) {
return `${match[2]}ComponentDescriptor`;
}
return null;
}
const findAndroidManifestsAsync = async (targetPath) => {
const files = (0, utils_1.scanFilesRecursively)(targetPath, (parentPath, name) => {
switch (name) {
case 'build':
case 'debug':
case 'Pods':
return false;
case 'Examples':
case 'examples':
// Only ignore top-level examples directories in `targetPath` but not nested ones
return parentPath !== targetPath;
case 'android':
return !/[\\/]sdks[\\/]hermes$/.test(parentPath);
case 'androidTest':
case 'test':
return !/[\\/]src$/.test(parentPath);
default:
return true;
}
});
const manifestPaths = [];
for await (const entry of files) {
if (entry.name === 'AndroidManifest.xml') {
manifestPaths.push(entry.path);
}
}
return manifestPaths.sort((a, b) => a.localeCompare(b));
};
const getFileCandidatesAsync = async (targetPath, fileNames) => {
const gradlePaths = await (0, concurrency_1.taskAll)(fileNames, (fileName) => (0, utils_1.fileExistsAsync)(path_1.default.join(targetPath, fileName)));
return gradlePaths.filter((file) => file != null).sort((a, b) => a.localeCompare(b));
};
async function findGradleAndManifestAsync({ androidDir, isLibrary, }) {
const [manifests, gradles] = await Promise.all([
findAndroidManifestsAsync(androidDir),
getFileCandidatesAsync(isLibrary ? androidDir : path_1.default.join(androidDir, 'app'), [
'build.gradle',
'build.gradle.kts',
]),
]);
// TODO(@kitten): We can't optimise this because of the prior `includes()` pattern. Is this meant to be startsWith?
const manifest = manifests.find((manifest) => manifest.includes('src/main/')) ??
manifests.sort((a, b) => a.localeCompare(b))[0];
const gradle = gradles.sort((a, b) => a.localeCompare(b))[0];
return { gradle: gradle || null, manifest: manifest || null };
}
//# sourceMappingURL=androidResolver.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
import type { RNConfigReactNativeConfig } from './reactNativeConfig.types';
type LoadConfigAsync = <T extends RNConfigReactNativeConfig>(packageRoot: string) => Promise<T | null>;
/**
* Load the `react-native.config.js` or `react-native.config.ts` from the package.
*/
export declare const loadConfigAsync: LoadConfigAsync;
export {};

View File

@@ -0,0 +1,33 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.loadConfigAsync = void 0;
const require_utils_1 = require("@expo/require-utils");
const promises_1 = __importDefault(require("fs/promises"));
const path_1 = __importDefault(require("path"));
const memoize_1 = require("../memoize");
const utils_1 = require("../utils");
const mockedNativeModules = path_1.default.join(__dirname, '..', '..', 'node_modules_mock');
/**
* Load the `react-native.config.js` or `react-native.config.ts` from the package.
*/
exports.loadConfigAsync = (0, memoize_1.memoize)(async function loadConfigAsync(packageRoot) {
const configPath = (await Promise.all(['react-native.config.js', 'react-native.config.ts'].map(async (fileName) => {
const file = path_1.default.join(packageRoot, fileName);
return (await (0, utils_1.fileExistsAsync)(file)) ? file : null;
}))).find((path) => path != null);
if (configPath) {
const mod = (0, require_utils_1.evalModule)(await promises_1.default.readFile(configPath, 'utf8'), configPath,
// NOTE: We need to mock the Community CLI temporarily, because
// some packages are checking the version of the CLI in the `react-native.config.js` file.
// We can remove this once we remove this check from packages.
{ paths: [mockedNativeModules] });
return mod.default ?? mod ?? null;
}
else {
return null;
}
});
//# sourceMappingURL=config.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/reactNativeConfig/config.ts"],"names":[],"mappings":";;;;;;AAAA,uDAAiD;AACjD,2DAA6B;AAC7B,gDAAwB;AAExB,wCAAqC;AACrC,oCAA2C;AAM3C,MAAM,mBAAmB,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,mBAAmB,CAAC,CAAC;AAMlF;;GAEG;AACU,QAAA,eAAe,GAAoB,IAAA,iBAAO,EAAC,KAAK,UAAU,eAAe,CAEpF,WAAmB;IACnB,MAAM,UAAU,GAAG,CACjB,MAAM,OAAO,CAAC,GAAG,CACf,CAAC,wBAAwB,EAAE,wBAAwB,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;QAC1E,MAAM,IAAI,GAAG,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QAC9C,OAAO,CAAC,MAAM,IAAA,uBAAe,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACrD,CAAC,CAAC,CACH,CACF,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;IAC/B,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,GAAG,GAAG,IAAA,0BAAU,EACpB,MAAM,kBAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,EACrC,UAAU;QACV,+DAA+D;QAC/D,0FAA0F;QAC1F,8DAA8D;QAC9D,EAAE,KAAK,EAAE,CAAC,mBAAmB,CAAC,EAAE,CACjC,CAAC;QACF,OAAO,GAAG,CAAC,OAAO,IAAI,GAAG,IAAI,IAAI,CAAC;IACpC,CAAC;SAAM,CAAC;QACN,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC,CAAC,CAAC","sourcesContent":["import { evalModule } from '@expo/require-utils';\nimport fs from 'fs/promises';\nimport path from 'path';\n\nimport { memoize } from '../memoize';\nimport { fileExistsAsync } from '../utils';\nimport type {\n RNConfigReactNativeConfig,\n RNConfigReactNativeProjectConfig,\n} from './reactNativeConfig.types';\n\nconst mockedNativeModules = path.join(__dirname, '..', '..', 'node_modules_mock');\n\ntype LoadConfigAsync = <T extends RNConfigReactNativeConfig>(\n packageRoot: string\n) => Promise<T | null>;\n\n/**\n * Load the `react-native.config.js` or `react-native.config.ts` from the package.\n */\nexport const loadConfigAsync: LoadConfigAsync = memoize(async function loadConfigAsync<\n T extends RNConfigReactNativeConfig,\n>(packageRoot: string): Promise<T | null> {\n const configPath = (\n await Promise.all(\n ['react-native.config.js', 'react-native.config.ts'].map(async (fileName) => {\n const file = path.join(packageRoot, fileName);\n return (await fileExistsAsync(file)) ? file : null;\n })\n )\n ).find((path) => path != null);\n if (configPath) {\n const mod = evalModule(\n await fs.readFile(configPath, 'utf8'),\n configPath,\n // NOTE: We need to mock the Community CLI temporarily, because\n // some packages are checking the version of the CLI in the `react-native.config.js` file.\n // We can remove this once we remove this check from packages.\n { paths: [mockedNativeModules] }\n );\n return mod.default ?? mod ?? null;\n } else {\n return null;\n }\n});\n"]}

View File

@@ -0,0 +1,2 @@
export * from './reactNativeConfig';
export * from './reactNativeConfig.types';

View File

@@ -0,0 +1,19 @@
"use strict";
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./reactNativeConfig"), exports);
__exportStar(require("./reactNativeConfig.types"), exports);
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/reactNativeConfig/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,sDAAoC;AACpC,4DAA0C","sourcesContent":["export * from './reactNativeConfig';\nexport * from './reactNativeConfig.types';\n"]}

View File

@@ -0,0 +1,6 @@
import type { RNConfigDependencyIos, RNConfigReactNativePlatformsConfigIos } from './reactNativeConfig.types';
import type { ExpoModuleConfig } from '../ExpoModuleConfig';
export declare function resolveDependencyConfigImplIosAsync(resolution: {
path: string;
version: string;
}, reactNativeConfig: RNConfigReactNativePlatformsConfigIos | null | undefined, expoModuleConfig?: ExpoModuleConfig | null): Promise<RNConfigDependencyIos | null>;

Some files were not shown because too many files have changed in this diff Show More