feat(smart-app): implement complete mobile app MVP

- App.tsx: full navigation (Auth stack + Main tabs with 5 screens)
- Auth: LoginScreen, RegisterScreen, ForgotPasswordScreen
- HomeScreen: dashboard with IoT metrics, weather widget, alerts, quick actions, sensors
- MapScreen: interactive map with layer toggles (6 layers)
- MarketplaceScreen: categories (6), products (5), search
- ChatScreen: AI chat with quick prompts (4), bot responses
- ProfileScreen: user info, stats, menu (9 items), logout
- AlertsScreen: alert list with severity, acknowledge
- SensorsScreen: sensor list with type filters (6 types), search
- ZonesScreen: zone cards with stats
- SettingsScreen: language picker (FR/EN/ES/DE), privacy, about
- Stores: iotStore (sensors, zones, alerts), notificationStore, uiStore + i18n
- Hooks: useSensors, useAlerts, useNotifications, useLocation
- Components: Card, Button, LoadingSpinner, ErrorBoundary, Header
- Services: iotService, notificationService (with axios API client)
- Utils: formatters (temp, AQI, noise, dates), validators (email, password, IBAN)
- Theme: colors.ts with full design system (Blue Ocean palette)
- Ditto: fixed MongoDB connection, new JWT secrets, official gateway image
This commit is contained in:
Eric FELIXINE
2026-06-01 18:00:35 -04:00
parent 08ca495bde
commit e30ae8ed09
35578 changed files with 3703534 additions and 43 deletions

View File

@@ -0,0 +1,60 @@
import { AndroidGradlePluginDescriptor, RawExpoModuleConfig, RawModuleConfigApple, SupportedPlatform } from './types';
/**
* 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[];
/**
* 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 a list of names of Kotlin native modules classes to put to the generated package provider file.
*/
androidModules(): string[];
/**
* Returns build.gradle file paths defined by the module author.
*/
androidGradlePaths(): string[];
/**
* Returns gradle plugins descriptors defined by the module author.
*/
androidGradlePlugins(): AndroidGradlePluginDescriptor[];
/**
* Returns serializable raw config.
*/
toJSON(): RawExpoModuleConfig;
}
/**
* Reads the config at given path and returns the config wrapped by `ExpoModuleConfig` class.
*/
export declare function requireAndResolveExpoModuleConfig(path: string): ExpoModuleConfig;

View File

@@ -0,0 +1,112 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.requireAndResolveExpoModuleConfig = exports.ExpoModuleConfig = void 0;
function arrayize(value) {
if (Array.isArray(value)) {
return value;
}
return value != null ? [value] : [];
}
/**
* 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 === '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);
});
}
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();
// `modulesClassNames` is a legacy name for the same config.
return appleConfig?.modules ?? appleConfig?.modulesClassNames ?? [];
}
/**
* 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 a list of names of Kotlin native modules classes to put to the generated package provider file.
*/
androidModules() {
const androidConfig = this.rawConfig.android;
// `modulesClassNames` is a legacy name for the same config.
return androidConfig?.modules ?? androidConfig?.modulesClassNames ?? [];
}
/**
* Returns build.gradle file paths defined by the module author.
*/
androidGradlePaths() {
return arrayize(this.rawConfig.android?.gradlePath ?? []);
}
/**
* Returns gradle plugins descriptors defined by the module author.
*/
androidGradlePlugins() {
return arrayize(this.rawConfig.android?.gradlePlugins ?? []);
}
/**
* Returns serializable raw config.
*/
toJSON() {
return this.rawConfig;
}
}
exports.ExpoModuleConfig = ExpoModuleConfig;
/**
* Reads the config at given path and returns the config wrapped by `ExpoModuleConfig` class.
*/
function requireAndResolveExpoModuleConfig(path) {
// TODO: Validate the raw config against a schema.
// TODO: Support for `*.js` files, not only static `*.json`.
return new ExpoModuleConfig(require(path));
}
exports.requireAndResolveExpoModuleConfig = requireAndResolveExpoModuleConfig;
//# sourceMappingURL=ExpoModuleConfig.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,14 @@
import { PatchReactImportsOptions } from './types';
/**
* Remove all double-quoted react header imports
* @param dirs target directories to patch
* @param options PatchReactImportsOptions
*/
export declare function patchReactImportsAsync(dirs: string[], options: PatchReactImportsOptions): Promise<void>;
/**
* Patch imports from a file
* @param headerSet prebuilt React-Core header set
* @param file target patch file
* @param dryRun true if not writing changes to file
*/
export declare function patchFileAsync(headerSet: Set<string>, file: string, dryRun: boolean): Promise<void>;

View File

@@ -0,0 +1,89 @@
"use strict";
// Copyright 2018-present 650 Industries. All rights reserved.
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.patchFileAsync = exports.patchReactImportsAsync = void 0;
const fast_glob_1 = __importDefault(require("fast-glob"));
const fs_extra_1 = __importDefault(require("fs-extra"));
const path_1 = __importDefault(require("path"));
/**
* Remove all double-quoted react header imports
* @param dirs target directories to patch
* @param options PatchReactImportsOptions
*/
async function patchReactImportsAsync(dirs, options) {
const headerSet = await generateReactHeaderSetAsync(path_1.default.join(options.podsRoot, 'Headers', 'Public', 'React-Core', 'React'));
await Promise.all(dirs.map((dir) => patchDirAsync(headerSet, dir, options.dryRun)));
}
exports.patchReactImportsAsync = patchReactImportsAsync;
/**
* Generate `React-Core` public header names as a set, will transform necessary headers based on this set.
*/
async function generateReactHeaderSetAsync(reactHeaderDir) {
const files = await (0, fast_glob_1.default)('*.h', { cwd: reactHeaderDir });
return new Set(files);
}
/**
* Patch imports from a file
* @param headerSet prebuilt React-Core header set
* @param file target patch file
* @param dryRun true if not writing changes to file
*/
async function patchFileAsync(headerSet, file, dryRun) {
let changed = false;
const content = await fs_extra_1.default.readFile(file, 'utf-8');
let transformContent = content.replace(/(?<=^\s*)#import\s+"(.+)"(?=\s*$)/gm, (match, headerName) => {
// `#import "RCTBridge.h"` -> `#import <React/RCTBridge.h>`
if (headerSet.has(headerName)) {
changed = true;
return `#import <React/${headerName}>`;
}
// `#import "React/RCTBridge.h"` -> `#import <React/RCTBridge.h>`
if (headerName.startsWith('React/')) {
const name = headerName.substring(6);
if (headerSet.has(name)) {
changed = true;
return `#import <React/${name}>`;
}
}
// Otherwise, return original import
return match;
});
transformContent = transformContent.replace(/(?<=^\s*)#(if|elif)\s+__has_include\("(.+)"\)(?=\s*$)/gm, (match, ifPrefix, headerName) => {
// `#if __has_include("RCTBridge.h")` -> `#if __has_include(<React/RCTBridge.h>)`
if (headerSet.has(headerName)) {
changed = true;
return `#${ifPrefix} __has_include(<React/${headerName}>)`;
}
// `#if __has_include("React/RCTBridge.h")` -> `#if __has_include(<React/RCTBridge.h>)`
if (headerName.startsWith('React/')) {
const name = headerName.substring(6);
if (headerSet.has(name)) {
changed = true;
return `#${ifPrefix} __has_include(<React/${name}>)`;
}
}
// Otherwise, return original import
return match;
});
if (changed) {
console.log(`Patching imports for file: ${file}`);
if (!dryRun) {
await fs_extra_1.default.writeFile(file, transformContent);
}
}
}
exports.patchFileAsync = patchFileAsync;
/**
* Patch imports from a directory
* @param headerSet prebuilt React-Core header set
* @param file target patch file
* @param dryRun true if not writing changes to file
*/
async function patchDirAsync(headerSet, dir, dryRun) {
const files = await (0, fast_glob_1.default)('**/*.{h,m,mm}', { cwd: dir, absolute: true });
return Promise.all(files.map((file) => patchFileAsync(headerSet, file, dryRun)));
}
//# sourceMappingURL=ReactImportsPatcher.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,5 @@
import { SearchOptions, SearchResults } from '../types';
/**
* Searches for modules to link based on given config.
*/
export declare function findModulesAsync(providedOptions: SearchOptions): Promise<SearchResults>;

View File

@@ -0,0 +1,214 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.findModulesAsync = void 0;
const chalk_1 = __importDefault(require("chalk"));
const fast_glob_1 = __importDefault(require("fast-glob"));
const fs_extra_1 = __importDefault(require("fs-extra"));
const module_1 = require("module");
const path_1 = __importDefault(require("path"));
const mergeLinkingOptions_1 = require("./mergeLinkingOptions");
const utils_1 = require("./utils");
const ExpoModuleConfig_1 = require("../ExpoModuleConfig");
// Names of the config files. From lowest to highest priority.
const EXPO_MODULE_CONFIG_FILENAMES = ['unimodule.json', 'expo-module.config.json'];
/**
* Searches for modules to link based on given config.
*/
async function findModulesAsync(providedOptions) {
const options = await (0, mergeLinkingOptions_1.mergeLinkingOptionsAsync)(providedOptions);
const results = new Map();
const nativeModuleNames = new Set();
// custom native modules should be resolved first so that they can override other modules
const searchPaths = new Set(options.nativeModulesDir && fs_extra_1.default.existsSync(options.nativeModulesDir)
? [options.nativeModulesDir, ...options.searchPaths]
: options.searchPaths);
// `searchPaths` can be mutated to discover all "isolated modules groups", when using isolated modules
for (const searchPath of searchPaths) {
const isNativeModulesDir = searchPath === options.nativeModulesDir;
const packageConfigPaths = await findPackagesConfigPathsAsync(searchPath);
for (const packageConfigPath of packageConfigPaths) {
const packagePath = await fs_extra_1.default.realpath(path_1.default.join(searchPath, path_1.default.dirname(packageConfigPath)));
const expoModuleConfig = (0, ExpoModuleConfig_1.requireAndResolveExpoModuleConfig)(path_1.default.join(packagePath, path_1.default.basename(packageConfigPath)));
const { name, version } = resolvePackageNameAndVersion(packagePath, {
fallbackToDirName: isNativeModulesDir,
});
const maybeIsolatedModulesPath = (0, utils_1.getIsolatedModulesPath)(packagePath, name);
if (maybeIsolatedModulesPath) {
searchPaths.add(maybeIsolatedModulesPath);
}
// we ignore the `exclude` option for custom native modules
if ((!isNativeModulesDir && options.exclude?.includes(name)) ||
!expoModuleConfig.supportsPlatform(options.platform)) {
continue;
}
// add the current revision to the results
const currentRevision = {
path: packagePath,
version,
config: expoModuleConfig,
};
addRevisionToResults(results, name, currentRevision);
// if the module is a native module, we need to add it to the nativeModuleNames set
if (isNativeModulesDir && !nativeModuleNames.has(name)) {
nativeModuleNames.add(name);
}
}
}
const searchResults = Object.fromEntries(results.entries());
// It doesn't make much sense to strip modules if there is only one search path.
// (excluding custom native modules path)
// Workspace root usually doesn't specify all its dependencies (see Expo Go),
// so in this case we should link everything.
if (options.searchPaths.length <= 1 || options.onlyProjectDeps === false) {
return searchResults;
}
return await filterToProjectDependenciesAsync(searchResults, {
...providedOptions,
// Custom native modules are not filtered out
// when they're not specified in package.json dependencies.
alwaysIncludedPackagesNames: nativeModuleNames,
});
}
exports.findModulesAsync = findModulesAsync;
/**
* Returns the priority of the config at given path. Higher number means higher priority.
*/
function configPriority(fullpath) {
return EXPO_MODULE_CONFIG_FILENAMES.indexOf(path_1.default.basename(fullpath));
}
/**
* Adds {@link revision} to the {@link results} map
* or to package duplicates if it already exists.
* @param results [mutable] yet resolved packages map
* @param name resolved package name
* @param revision resolved package revision
*/
function addRevisionToResults(results, name, revision) {
if (!results.has(name)) {
// The revision that was found first will be the main one.
// An array of duplicates and the config are needed only here.
results.set(name, {
...revision,
duplicates: [],
});
}
else if (results.get(name)?.path !== revision.path &&
results.get(name)?.duplicates?.every(({ path }) => path !== revision.path)) {
const { config, duplicates, ...duplicateEntry } = revision;
results.get(name)?.duplicates?.push(duplicateEntry);
}
}
/**
* Returns paths to the highest priority config files, relative to the {@link searchPath}.
* @example
* ```
* // Given the following file exists: /foo/myapp/modules/mymodule/expo-module.config.json
* await findPackagesConfigPathsAsync('/foo/myapp/modules');
* // returns ['mymodule/expo-module.config.json']
*
* await findPackagesConfigPathsAsync('/foo/myapp/modules/mymodule');
* // returns ['expo-module.config.json']
* ```
*/
async function findPackagesConfigPathsAsync(searchPath) {
const bracedFilenames = '{' + EXPO_MODULE_CONFIG_FILENAMES.join(',') + '}';
const paths = await (0, fast_glob_1.default)([`*/${bracedFilenames}`, `@*/*/${bracedFilenames}`, `./${bracedFilenames}`], {
cwd: searchPath,
});
// If the package has multiple configs (e.g. `unimodule.json` and `expo-module.config.json` during the transition time)
// then we want to give `expo-module.config.json` the priority.
return Object.values(paths.reduce((acc, configPath) => {
const dirname = path_1.default.dirname(configPath);
if (!acc[dirname] || configPriority(configPath) > configPriority(acc[dirname])) {
acc[dirname] = configPath;
}
return acc;
}, {}));
}
/**
* Resolves package name and version for the given {@link packagePath} from its `package.json`.
* if {@link fallbackToDirName} is true, it returns the dir name when `package.json` doesn't exist.
* @returns object with `name` and `version` properties. `version` falls back to `UNVERSIONED` if cannot be resolved.
*/
function resolvePackageNameAndVersion(packagePath, { fallbackToDirName } = {}) {
try {
const { name, version } = require(path_1.default.join(packagePath, 'package.json'));
return { name, version: version || 'UNVERSIONED' };
}
catch (e) {
if (fallbackToDirName) {
// we don't have the package.json name, so we'll use the directory name
return {
name: path_1.default.basename(packagePath),
version: 'UNVERSIONED',
};
}
else {
throw e;
}
}
}
/**
* Filters out packages that are not the dependencies of the project.
*/
async function filterToProjectDependenciesAsync(results, options) {
const filteredResults = {};
const visitedPackages = new Set();
// iterate through always included package names and add them to the visited packages
// if the results contains them
for (const name of options.alwaysIncludedPackagesNames ?? []) {
if (results[name] && !visitedPackages.has(name)) {
filteredResults[name] = results[name];
visitedPackages.add(name);
}
}
// Helper for traversing the dependency hierarchy.
function visitPackage(packageJsonPath) {
const packageJson = require(packageJsonPath);
// Prevent getting into the recursive loop.
if (visitedPackages.has(packageJson.name)) {
return;
}
visitedPackages.add(packageJson.name);
// Iterate over the dependencies to find transitive modules.
for (const dependencyName in packageJson.dependencies) {
const dependencyResult = results[dependencyName];
if (!filteredResults[dependencyName]) {
let dependencyPackageJsonPath;
if (dependencyResult) {
filteredResults[dependencyName] = dependencyResult;
dependencyPackageJsonPath = path_1.default.join(dependencyResult.path, 'package.json');
}
else {
try {
/**
* Custom `require` that resolves from the current working dir instead of this script path.
* **Requires Node v12.2.0**
*/
const projectRequire = (0, module_1.createRequire)(packageJsonPath);
dependencyPackageJsonPath = projectRequire.resolve(`${dependencyName}/package.json`);
}
catch (error) {
// Some packages don't include package.json in its `exports` field,
// but none of our packages do that, so it seems fine to just ignore that type of error.
// Related issue: https://github.com/react-native-community/cli/issues/1168
if (!options.silent && error.code !== 'ERR_PACKAGE_PATH_NOT_EXPORTED') {
console.warn(chalk_1.default.yellow(`⚠️ Cannot resolve the path to "${dependencyName}" package.`));
}
continue;
}
}
// Visit the dependency package.
visitPackage(dependencyPackageJsonPath);
}
}
}
// Visit project's package.
const projectPackageJsonPath = await (0, mergeLinkingOptions_1.getProjectPackageJsonPathAsync)(options.projectRoot);
visitPackage(projectPackageJsonPath);
return filteredResults;
}
//# sourceMappingURL=findModules.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,6 @@
import { GenerateOptions, ModuleDescriptor } from '../types';
/**
* Generates a source file listing all packages to link.
* Right know it works only for Android platform.
*/
export declare function generatePackageListAsync(modules: ModuleDescriptor[], options: GenerateOptions): Promise<void>;

View File

@@ -0,0 +1,24 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.generatePackageListAsync = void 0;
const chalk_1 = __importDefault(require("chalk"));
const utils_1 = require("./utils");
/**
* Generates a source file listing all packages to link.
* Right know it works only for Android platform.
*/
async function generatePackageListAsync(modules, options) {
try {
const platformLinking = (0, utils_1.getLinkingImplementationForPlatform)(options.platform);
await platformLinking.generatePackageListAsync(modules, options.target, options.namespace);
}
catch (e) {
console.error(chalk_1.default.red(`Generating package list is not available for platform: ${options.platform}`));
throw e;
}
}
exports.generatePackageListAsync = generatePackageListAsync;
//# sourceMappingURL=generatePackageList.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"generatePackageList.js","sourceRoot":"","sources":["../../src/autolinking/generatePackageList.ts"],"names":[],"mappings":";;;;;;AAAA,kDAA0B;AAE1B,mCAA8D;AAG9D;;;GAGG;AACI,KAAK,UAAU,wBAAwB,CAC5C,OAA2B,EAC3B,OAAwB;IAExB,IAAI;QACF,MAAM,eAAe,GAAG,IAAA,2CAAmC,EAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC9E,MAAM,eAAe,CAAC,wBAAwB,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;KAC5F;IAAC,OAAO,CAAC,EAAE;QACV,OAAO,CAAC,KAAK,CACX,eAAK,CAAC,GAAG,CAAC,0DAA0D,OAAO,CAAC,QAAQ,EAAE,CAAC,CACxF,CAAC;QACF,MAAM,CAAC,CAAC;KACT;AACH,CAAC;AAbD,4DAaC","sourcesContent":["import chalk from 'chalk';\n\nimport { getLinkingImplementationForPlatform } from './utils';\nimport { GenerateOptions, ModuleDescriptor } from '../types';\n\n/**\n * Generates a source file listing all packages to link.\n * Right know it works only for Android platform.\n */\nexport async function generatePackageListAsync(\n modules: ModuleDescriptor[],\n options: GenerateOptions\n) {\n try {\n const platformLinking = getLinkingImplementationForPlatform(options.platform);\n await platformLinking.generatePackageListAsync(modules, options.target, options.namespace);\n } catch (e) {\n console.error(\n chalk.red(`Generating package list is not available for platform: ${options.platform}`)\n );\n throw e;\n }\n}\n"]}

View File

@@ -0,0 +1,12 @@
import { findModulesAsync } from './findModules';
import { getProjectPackageJsonPathAsync, mergeLinkingOptionsAsync, resolveSearchPathsAsync } from './mergeLinkingOptions';
import { resolveExtraBuildDependenciesAsync, resolveModulesAsync } from './resolveModules';
import type { ModuleDescriptor, SearchOptions } from '../types';
export { findModulesAsync, getProjectPackageJsonPathAsync, mergeLinkingOptionsAsync, resolveExtraBuildDependenciesAsync, resolveModulesAsync, resolveSearchPathsAsync, };
export { generatePackageListAsync } from './generatePackageList';
export { verifySearchResults } from './verifySearchResults';
export * from '../types';
/**
* Programmatic API to query autolinked modules for a project.
*/
export declare function queryAutolinkingModulesFromProjectAsync(projectRoot: string, options: Pick<SearchOptions, 'platform' | 'exclude' | 'onlyProjectDeps'>): Promise<ModuleDescriptor[]>;

View File

@@ -0,0 +1,42 @@
"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.queryAutolinkingModulesFromProjectAsync = exports.verifySearchResults = exports.generatePackageListAsync = exports.resolveSearchPathsAsync = exports.resolveModulesAsync = exports.resolveExtraBuildDependenciesAsync = exports.mergeLinkingOptionsAsync = exports.getProjectPackageJsonPathAsync = exports.findModulesAsync = void 0;
const findModules_1 = require("./findModules");
Object.defineProperty(exports, "findModulesAsync", { enumerable: true, get: function () { return findModules_1.findModulesAsync; } });
const mergeLinkingOptions_1 = require("./mergeLinkingOptions");
Object.defineProperty(exports, "getProjectPackageJsonPathAsync", { enumerable: true, get: function () { return mergeLinkingOptions_1.getProjectPackageJsonPathAsync; } });
Object.defineProperty(exports, "mergeLinkingOptionsAsync", { enumerable: true, get: function () { return mergeLinkingOptions_1.mergeLinkingOptionsAsync; } });
Object.defineProperty(exports, "resolveSearchPathsAsync", { enumerable: true, get: function () { return mergeLinkingOptions_1.resolveSearchPathsAsync; } });
const resolveModules_1 = require("./resolveModules");
Object.defineProperty(exports, "resolveExtraBuildDependenciesAsync", { enumerable: true, get: function () { return resolveModules_1.resolveExtraBuildDependenciesAsync; } });
Object.defineProperty(exports, "resolveModulesAsync", { enumerable: true, get: function () { return resolveModules_1.resolveModulesAsync; } });
var generatePackageList_1 = require("./generatePackageList");
Object.defineProperty(exports, "generatePackageListAsync", { enumerable: true, get: function () { return generatePackageList_1.generatePackageListAsync; } });
var verifySearchResults_1 = require("./verifySearchResults");
Object.defineProperty(exports, "verifySearchResults", { enumerable: true, get: function () { return verifySearchResults_1.verifySearchResults; } });
__exportStar(require("../types"), exports);
/**
* Programmatic API to query autolinked modules for a project.
*/
async function queryAutolinkingModulesFromProjectAsync(projectRoot, options) {
const searchPaths = await (0, mergeLinkingOptions_1.resolveSearchPathsAsync)(null, projectRoot);
const linkOptions = await (0, mergeLinkingOptions_1.mergeLinkingOptionsAsync)({ ...options, projectRoot, searchPaths });
const searchResults = await (0, findModules_1.findModulesAsync)(linkOptions);
return await (0, resolveModules_1.resolveModulesAsync)(searchResults, linkOptions);
}
exports.queryAutolinkingModulesFromProjectAsync = queryAutolinkingModulesFromProjectAsync;
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/autolinking/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,+CAAiD;AAU/C,iGAVO,8BAAgB,OAUP;AATlB,+DAI+B;AAM7B,+GATA,oDAA8B,OASA;AAC9B,yGATA,8CAAwB,OASA;AAGxB,wGAXA,6CAAuB,OAWA;AATzB,qDAA2F;AAOzF,mHAPO,mDAAkC,OAOP;AAClC,oGAR2C,oCAAmB,OAQ3C;AAGrB,6DAAiE;AAAxD,+HAAA,wBAAwB,OAAA;AACjC,6DAA4D;AAAnD,0HAAA,mBAAmB,OAAA;AAC5B,2CAAyB;AAEzB;;GAEG;AACI,KAAK,UAAU,uCAAuC,CAC3D,WAAmB,EACnB,OAAwE;IAExE,MAAM,WAAW,GAAG,MAAM,IAAA,6CAAuB,EAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IACrE,MAAM,WAAW,GAAG,MAAM,IAAA,8CAAwB,EAAC,EAAE,GAAG,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC,CAAC;IAC7F,MAAM,aAAa,GAAG,MAAM,IAAA,8BAAgB,EAAC,WAAW,CAAC,CAAC;IAC1D,OAAO,MAAM,IAAA,oCAAmB,EAAC,aAAa,EAAE,WAAW,CAAC,CAAC;AAC/D,CAAC;AARD,0FAQC","sourcesContent":["import { findModulesAsync } from './findModules';\nimport {\n getProjectPackageJsonPathAsync,\n mergeLinkingOptionsAsync,\n resolveSearchPathsAsync,\n} from './mergeLinkingOptions';\nimport { resolveExtraBuildDependenciesAsync, resolveModulesAsync } from './resolveModules';\nimport type { ModuleDescriptor, SearchOptions } from '../types';\n\nexport {\n findModulesAsync,\n getProjectPackageJsonPathAsync,\n mergeLinkingOptionsAsync,\n resolveExtraBuildDependenciesAsync,\n resolveModulesAsync,\n resolveSearchPathsAsync,\n};\nexport { generatePackageListAsync } from './generatePackageList';\nexport { verifySearchResults } from './verifySearchResults';\nexport * from '../types';\n\n/**\n * Programmatic API to query autolinked modules for a project.\n */\nexport async function queryAutolinkingModulesFromProjectAsync(\n projectRoot: string,\n options: Pick<SearchOptions, 'platform' | 'exclude' | 'onlyProjectDeps'>\n): Promise<ModuleDescriptor[]> {\n const searchPaths = await resolveSearchPathsAsync(null, projectRoot);\n const linkOptions = await mergeLinkingOptionsAsync({ ...options, projectRoot, searchPaths });\n const searchResults = await findModulesAsync(linkOptions);\n return await resolveModulesAsync(searchResults, linkOptions);\n}\n"]}

View File

@@ -0,0 +1,17 @@
import { SearchOptions } from '../types';
/**
* Find the path to the `package.json` of the closest project in the given project root.
*/
export declare function getProjectPackageJsonPathAsync(projectRoot: string): Promise<string>;
/**
* Merges autolinking options from different sources (the later the higher priority)
* - options defined in package.json's `expo.autolinking` field
* - platform-specific options from the above (e.g. `expo.autolinking.apple`)
* - options provided to the CLI command
*/
export declare function mergeLinkingOptionsAsync<OptionsType extends SearchOptions>(providedOptions: OptionsType): Promise<OptionsType>;
/**
* Resolves autolinking search paths. If none is provided, it accumulates all node_modules when
* going up through the path components. This makes workspaces work out-of-the-box without any configs.
*/
export declare function resolveSearchPathsAsync(searchPaths: string[] | null, cwd: string): Promise<string[]>;

View File

@@ -0,0 +1,91 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveSearchPathsAsync = exports.mergeLinkingOptionsAsync = exports.getProjectPackageJsonPathAsync = void 0;
const find_up_1 = __importDefault(require("find-up"));
const fs_extra_1 = __importDefault(require("fs-extra"));
const path_1 = __importDefault(require("path"));
/**
* Find the path to the `package.json` of the closest project in the given project root.
*/
async function getProjectPackageJsonPathAsync(projectRoot) {
const result = await (0, find_up_1.default)('package.json', { cwd: projectRoot });
if (!result) {
throw new Error(`Couldn't find "package.json" up from path "${projectRoot}"`);
}
return result;
}
exports.getProjectPackageJsonPathAsync = getProjectPackageJsonPathAsync;
/**
* Merges autolinking options from different sources (the later the higher priority)
* - options defined in package.json's `expo.autolinking` field
* - platform-specific options from the above (e.g. `expo.autolinking.apple`)
* - options provided to the CLI command
*/
async function mergeLinkingOptionsAsync(providedOptions) {
const packageJson = require(await getProjectPackageJsonPathAsync(providedOptions.projectRoot));
const baseOptions = packageJson.expo?.autolinking;
const platformOptions = getPlatformOptions(providedOptions.platform, baseOptions);
const finalOptions = Object.assign({}, baseOptions, platformOptions, providedOptions);
// Makes provided paths absolute or falls back to default paths if none was provided.
finalOptions.searchPaths = await resolveSearchPathsAsync(finalOptions.searchPaths, providedOptions.projectRoot);
finalOptions.nativeModulesDir = await resolveNativeModulesDirAsync(finalOptions.nativeModulesDir, providedOptions.projectRoot);
return finalOptions;
}
exports.mergeLinkingOptionsAsync = mergeLinkingOptionsAsync;
/**
* Resolves autolinking search paths. If none is provided, it accumulates all node_modules when
* going up through the path components. This makes workspaces work out-of-the-box without any configs.
*/
async function resolveSearchPathsAsync(searchPaths, cwd) {
return searchPaths && searchPaths.length > 0
? searchPaths.map((searchPath) => path_1.default.resolve(cwd, searchPath))
: await findDefaultPathsAsync(cwd);
}
exports.resolveSearchPathsAsync = resolveSearchPathsAsync;
/**
* Looks up for workspace's `node_modules` paths.
*/
async function findDefaultPathsAsync(cwd) {
const paths = [];
let dir = cwd;
let pkgJsonPath;
while ((pkgJsonPath = await (0, find_up_1.default)('package.json', { cwd: dir }))) {
dir = path_1.default.dirname(path_1.default.dirname(pkgJsonPath));
paths.push(path_1.default.join(pkgJsonPath, '..', 'node_modules'));
// This stops the infinite loop when the package.json is placed at the root dir.
if (path_1.default.dirname(dir) === dir) {
break;
}
}
return paths;
}
/**
* Finds the real path to custom native modules directory.
* - When {@link cwd} is inside the project directory, the path is searched relatively
* to the project root (directory with the `package.json` file).
* - When {@link cwd} is outside project directory (no `package.json` found), it is relative to
* the current working directory (the {@link cwd} param).
*
* @param nativeModulesDir path to custom native modules directory. Defaults to `"./modules"` if null.
* @param cwd current working directory
* @returns resolved native modules directory or `null` if it is not found or doesn't exist.
*/
async function resolveNativeModulesDirAsync(nativeModulesDir, cwd) {
const packageJsonPath = await (0, find_up_1.default)('package.json', { cwd });
const projectRoot = packageJsonPath != null ? path_1.default.join(packageJsonPath, '..') : cwd;
const resolvedPath = path_1.default.resolve(projectRoot, nativeModulesDir || 'modules');
return fs_extra_1.default.existsSync(resolvedPath) ? resolvedPath : null;
}
/**
* Gets the platform-specific autolinking options from the base options.
*/
function getPlatformOptions(platform, options) {
if (platform === 'apple') {
return options?.apple ?? options?.ios ?? {};
}
return options?.[platform] ?? {};
}
//# sourceMappingURL=mergeLinkingOptions.js.map

File diff suppressed because one or more lines are too long

View File

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

View File

@@ -0,0 +1,33 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveExtraBuildDependenciesAsync = exports.resolveModulesAsync = void 0;
const utils_1 = require("./utils");
/**
* Resolves search results to a list of platform-specific configuration.
*/
async function resolveModulesAsync(searchResults, options) {
const platformLinking = (0, utils_1.getLinkingImplementationForPlatform)(options.platform);
return (await Promise.all(Object.entries(searchResults).map(async ([packageName, revision]) => {
const resolvedModule = await platformLinking.resolveModuleAsync(packageName, revision, options);
return resolvedModule
? {
packageName,
packageVersion: revision.version,
...resolvedModule,
}
: null;
})))
.filter(Boolean)
.sort((a, b) => a.packageName.localeCompare(b.packageName));
}
exports.resolveModulesAsync = resolveModulesAsync;
/**
* Resolves the extra build dependencies for the project, such as additional Maven repositories or CocoaPods pods.
*/
async function resolveExtraBuildDependenciesAsync(options) {
const platformLinking = (0, utils_1.getLinkingImplementationForPlatform)(options.platform);
const extraDependencies = await platformLinking.resolveExtraBuildDependenciesAsync(options.projectRoot);
return extraDependencies ?? [];
}
exports.resolveExtraBuildDependenciesAsync = resolveExtraBuildDependenciesAsync;
//# sourceMappingURL=resolveModules.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"resolveModules.js","sourceRoot":"","sources":["../../src/autolinking/resolveModules.ts"],"names":[],"mappings":";;;AAAA,mCAA8D;AAG9D;;GAEG;AACI,KAAK,UAAU,mBAAmB,CACvC,aAA4B,EAC5B,OAAuB;IAEvB,MAAM,eAAe,GAAG,IAAA,2CAAmC,EAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAE9E,OAAO,CACL,MAAM,OAAO,CAAC,GAAG,CACf,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,QAAQ,CAAC,EAAE,EAAE;QAClE,MAAM,cAAc,GAAG,MAAM,eAAe,CAAC,kBAAkB,CAC7D,WAAW,EACX,QAAQ,EACR,OAAO,CACR,CAAC;QACF,OAAO,cAAc;YACnB,CAAC,CAAC;gBACE,WAAW;gBACX,cAAc,EAAE,QAAQ,CAAC,OAAO;gBAChC,GAAG,cAAc;aAClB;YACH,CAAC,CAAC,IAAI,CAAC;IACX,CAAC,CAAC,CACH,CACF;SACE,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;AAChE,CAAC;AA1BD,kDA0BC;AAED;;GAEG;AACI,KAAK,UAAU,kCAAkC,CACtD,OAAuB;IAEvB,MAAM,eAAe,GAAG,IAAA,2CAAmC,EAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC9E,MAAM,iBAAiB,GAAG,MAAM,eAAe,CAAC,kCAAkC,CAChF,OAAO,CAAC,WAAW,CACpB,CAAC;IACF,OAAO,iBAAiB,IAAI,EAAE,CAAC;AACjC,CAAC;AARD,gFAQC","sourcesContent":["import { getLinkingImplementationForPlatform } from './utils';\nimport type { ExtraDependencies, ModuleDescriptor, ResolveOptions, SearchResults } from '../types';\n\n/**\n * Resolves search results to a list of platform-specific configuration.\n */\nexport async function resolveModulesAsync(\n searchResults: SearchResults,\n options: ResolveOptions\n): Promise<ModuleDescriptor[]> {\n const platformLinking = getLinkingImplementationForPlatform(options.platform);\n\n return (\n await Promise.all(\n Object.entries(searchResults).map(async ([packageName, revision]) => {\n const resolvedModule = await platformLinking.resolveModuleAsync(\n packageName,\n revision,\n options\n );\n return resolvedModule\n ? {\n packageName,\n packageVersion: revision.version,\n ...resolvedModule,\n }\n : null;\n })\n )\n )\n .filter(Boolean)\n .sort((a, b) => a.packageName.localeCompare(b.packageName));\n}\n\n/**\n * Resolves the extra build dependencies for the project, such as additional Maven repositories or CocoaPods pods.\n */\nexport async function resolveExtraBuildDependenciesAsync(\n options: ResolveOptions\n): Promise<ExtraDependencies> {\n const platformLinking = getLinkingImplementationForPlatform(options.platform);\n const extraDependencies = await platformLinking.resolveExtraBuildDependenciesAsync(\n options.projectRoot\n );\n return extraDependencies ?? [];\n}\n"]}

View File

@@ -0,0 +1,6 @@
import { SupportedPlatform } from '../types';
export declare function getLinkingImplementationForPlatform(platform: SupportedPlatform): any;
/**
* Get the possible path to the pnpm isolated modules folder.
*/
export declare function getIsolatedModulesPath(packagePath: string, packageName: string): string | null;

View File

@@ -0,0 +1,40 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getIsolatedModulesPath = exports.getLinkingImplementationForPlatform = void 0;
const path_1 = __importDefault(require("path"));
function getLinkingImplementationForPlatform(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');
}
}
exports.getLinkingImplementationForPlatform = getLinkingImplementationForPlatform;
/**
* Get the possible path to the pnpm isolated modules folder.
*/
function getIsolatedModulesPath(packagePath, packageName) {
// Check if the project is using isolated modules, by checking
// if the parent dir of `packagePath` is a `node_modules` folder.
// Isolated modules installs dependencies in small groups such as:
// - /.pnpm/expo@50.x.x(...)/node_modules/@expo/cli
// - /.pnpm/expo@50.x.x(...)/node_modules/expo
// - /.pnpm/expo@50.x.x(...)/node_modules/expo-application
// When isolated modules are detected, expand the `searchPaths`
// to include possible nested dependencies.
const maybeIsolatedModulesPath = path_1.default.join(packagePath, packageName.startsWith('@') && packageName.includes('/') ? '../..' : '..' // scoped packages are nested deeper
);
const isIsolatedModulesPath = path_1.default.basename(maybeIsolatedModulesPath) === 'node_modules';
return isIsolatedModulesPath ? maybeIsolatedModulesPath : null;
}
exports.getIsolatedModulesPath = getIsolatedModulesPath;
//# sourceMappingURL=utils.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/autolinking/utils.ts"],"names":[],"mappings":";;;;;;AAAA,gDAAwB;AAIxB,SAAgB,mCAAmC,CAAC,QAA2B;IAC7E,QAAQ,QAAQ,EAAE;QAChB,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;KAC3C;AACH,CAAC;AAZD,kFAYC;AAED;;GAEG;AACH,SAAgB,sBAAsB,CAAC,WAAmB,EAAE,WAAmB;IAC7E,8DAA8D;IAC9D,iEAAiE;IACjE,kEAAkE;IAClE,qDAAqD;IACrD,gDAAgD;IAChD,4DAA4D;IAC5D,+DAA+D;IAC/D,2CAA2C;IAC3C,MAAM,wBAAwB,GAAG,cAAI,CAAC,IAAI,CACxC,WAAW,EACX,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,oCAAoC;KAC/G,CAAC;IACF,MAAM,qBAAqB,GAAG,cAAI,CAAC,QAAQ,CAAC,wBAAwB,CAAC,KAAK,cAAc,CAAC;IACzF,OAAO,qBAAqB,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,IAAI,CAAC;AACjE,CAAC;AAfD,wDAeC","sourcesContent":["import path from 'path';\n\nimport { SupportedPlatform } from '../types';\n\nexport function getLinkingImplementationForPlatform(platform: SupportedPlatform) {\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 }\n}\n\n/**\n * Get the possible path to the pnpm isolated modules folder.\n */\nexport function getIsolatedModulesPath(packagePath: string, packageName: string): string | null {\n // Check if the project is using isolated modules, by checking\n // if the parent dir of `packagePath` is a `node_modules` folder.\n // Isolated modules installs dependencies in small groups such as:\n // - /.pnpm/expo@50.x.x(...)/node_modules/@expo/cli\n // - /.pnpm/expo@50.x.x(...)/node_modules/expo\n // - /.pnpm/expo@50.x.x(...)/node_modules/expo-application\n // When isolated modules are detected, expand the `searchPaths`\n // to include possible nested dependencies.\n const maybeIsolatedModulesPath = path.join(\n packagePath,\n packageName.startsWith('@') && packageName.includes('/') ? '../..' : '..' // scoped packages are nested deeper\n );\n const isIsolatedModulesPath = path.basename(maybeIsolatedModulesPath) === 'node_modules';\n return isIsolatedModulesPath ? maybeIsolatedModulesPath : null;\n}\n"]}

View File

@@ -0,0 +1,5 @@
import { SearchOptions, SearchResults } from '../types';
/**
* Verifies the search results by checking whether there are no duplicates.
*/
export declare function verifySearchResults(searchResults: SearchResults, options: SearchOptions): number;

View File

@@ -0,0 +1,32 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.verifySearchResults = void 0;
const chalk_1 = __importDefault(require("chalk"));
const path_1 = __importDefault(require("path"));
/**
* Verifies the search results by checking whether there are no duplicates.
*/
function verifySearchResults(searchResults, options) {
const relativePath = (pkg) => path_1.default.relative(options.projectRoot, pkg.path);
let counter = 0;
for (const moduleName in searchResults) {
const revision = searchResults[moduleName];
if (revision.duplicates?.length) {
console.warn(`⚠️ Found multiple revisions of ${chalk_1.default.green(moduleName)}`);
console.log(` - ${chalk_1.default.magenta(relativePath(revision))} (${chalk_1.default.cyan(revision.version)})`);
for (const duplicate of revision.duplicates) {
console.log(` - ${chalk_1.default.gray(relativePath(duplicate))} (${chalk_1.default.gray(duplicate.version)})`);
}
counter++;
}
}
if (counter > 0) {
console.warn('⚠️ Please get rid of multiple revisions as it may introduce some side effects or compatibility issues');
}
return counter;
}
exports.verifySearchResults = verifySearchResults;
//# sourceMappingURL=verifySearchResults.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"verifySearchResults.js","sourceRoot":"","sources":["../../src/autolinking/verifySearchResults.ts"],"names":[],"mappings":";;;;;;AAAA,kDAA0B;AAC1B,gDAAwB;AAIxB;;GAEG;AACH,SAAgB,mBAAmB,CAAC,aAA4B,EAAE,OAAsB;IACtF,MAAM,YAAY,GAAqC,CAAC,GAAG,EAAE,EAAE,CAC7D,cAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/C,IAAI,OAAO,GAAG,CAAC,CAAC;IAEhB,KAAK,MAAM,UAAU,IAAI,aAAa,EAAE;QACtC,MAAM,QAAQ,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;QAE3C,IAAI,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE;YAC/B,OAAO,CAAC,IAAI,CAAC,mCAAmC,eAAK,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;YAC3E,OAAO,CAAC,GAAG,CAAC,MAAM,eAAK,CAAC,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,KAAK,eAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAE7F,KAAK,MAAM,SAAS,IAAI,QAAQ,CAAC,UAAU,EAAE;gBAC3C,OAAO,CAAC,GAAG,CAAC,MAAM,eAAK,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,KAAK,eAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;aAC7F;YACD,OAAO,EAAE,CAAC;SACX;KACF;IACD,IAAI,OAAO,GAAG,CAAC,EAAE;QACf,OAAO,CAAC,IAAI,CACV,wGAAwG,CACzG,CAAC;KACH;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAxBD,kDAwBC","sourcesContent":["import chalk from 'chalk';\nimport path from 'path';\n\nimport { PackageRevision, SearchOptions, SearchResults } from '../types';\n\n/**\n * Verifies the search results by checking whether there are no duplicates.\n */\nexport function verifySearchResults(searchResults: SearchResults, options: SearchOptions): number {\n const relativePath: (pkg: PackageRevision) => string = (pkg) =>\n path.relative(options.projectRoot, pkg.path);\n let counter = 0;\n\n for (const moduleName in searchResults) {\n const revision = searchResults[moduleName];\n\n if (revision.duplicates?.length) {\n console.warn(`⚠️ Found multiple revisions of ${chalk.green(moduleName)}`);\n console.log(` - ${chalk.magenta(relativePath(revision))} (${chalk.cyan(revision.version)})`);\n\n for (const duplicate of revision.duplicates) {\n console.log(` - ${chalk.gray(relativePath(duplicate))} (${chalk.gray(duplicate.version)})`);\n }\n counter++;\n }\n }\n if (counter > 0) {\n console.warn(\n '⚠️ Please get rid of multiple revisions as it may introduce some side effects or compatibility issues'\n );\n }\n return counter;\n}\n"]}

View File

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

View File

@@ -0,0 +1,129 @@
"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 path_1 = __importDefault(require("path"));
const ReactImportsPatcher_1 = require("./ReactImportsPatcher");
const autolinking_1 = require("./autolinking");
const reactNativeConfig_1 = require("./reactNativeConfig");
/**
* Registers a command that only searches for available expo modules.
*/
function registerSearchCommand(commandName, fn) {
return commander_1.default
.command(`${commandName} [paths...]`)
.option('-i, --ignore-paths <ignorePaths...>', 'Paths to ignore when looking up for modules.', (value, previous) => (previous ?? []).concat(value))
.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('--silent', 'Silence resolution warnings')
.addOption(new commander_1.default.Option('--project-root <projectRoot>', 'The path to the root of the project').default(process.cwd(), 'process.cwd()'))
.option('--only-project-deps', 'For a monorepo, include only modules that are the project dependencies.', true)
.option('--no-only-project-deps', 'Opposite of --only-project-deps', false)
.action(async (searchPaths, providedOptions) => {
const options = await (0, autolinking_1.mergeLinkingOptionsAsync)({
...providedOptions,
searchPaths,
});
const searchResults = await (0, autolinking_1.findModulesAsync)(options);
return await fn(searchResults, options);
});
}
/**
* Registers a command that searches for modules and then resolves them for specific platform.
*/
function registerResolveCommand(commandName, fn) {
return registerSearchCommand(commandName, fn);
}
// Register for `patch-react-imports` command
function registerPatchReactImportsCommand() {
return commander_1.default
.command('patch-react-imports [paths...]')
.requiredOption('--pods-root <podsRoot>', 'The path to `Pods` directory')
.option('--dry-run', 'Only list files without writing changes to the file system')
.action(ReactImportsPatcher_1.patchReactImportsAsync);
}
/**
* Registry the `react-native-config` command.
*/
function registerReactNativeConfigCommand() {
return commander_1.default
.command('react-native-config [paths...]')
.option('-p, --platform [platform]', 'The platform that the resulting modules must support. Available options: "android", "ios"', 'ios')
.addOption(new commander_1.default.Option('--project-root <projectRoot>', 'The path to the root of the project').default(process.cwd(), 'process.cwd()'))
.option('-j, --json', 'Output results in the plain JSON format.', () => true, false)
.action(async (paths, options) => {
if (!['android', 'ios'].includes(options.platform)) {
throw new Error(`Unsupported platform: ${options.platform}`);
}
const projectRoot = path_1.default.dirname(await (0, autolinking_1.getProjectPackageJsonPathAsync)(options.projectRoot));
const searchPaths = await (0, autolinking_1.resolveSearchPathsAsync)(paths, projectRoot);
const providedOptions = {
platform: options.platform,
projectRoot,
searchPaths,
};
const results = await (0, reactNativeConfig_1.createReactNativeConfigAsync)(providedOptions);
if (options.json) {
console.log(JSON.stringify(results));
}
else {
console.log(require('util').inspect(results, false, null, true));
}
});
}
module.exports = async function (args) {
// Searches for available expo modules.
registerSearchCommand('search', async (results, options) => {
if (options.json) {
console.log(JSON.stringify(results));
}
else {
console.log(require('util').inspect(results, false, null, true));
}
}).option('-j, --json', 'Output results in the plain JSON format.', () => true, false);
// Checks whether there are no resolving issues in the current setup.
registerSearchCommand('verify', (results, options) => {
const numberOfDuplicates = (0, autolinking_1.verifySearchResults)(results, options);
if (!numberOfDuplicates) {
console.log('✅ Everything is fine!');
}
});
// Searches for available expo modules and resolves the results for given platform.
registerResolveCommand('resolve', async (results, options) => {
const modules = await (0, autolinking_1.resolveModulesAsync)(results, options);
const extraDependencies = await (0, autolinking_1.resolveExtraBuildDependenciesAsync)(options);
if (options.json) {
console.log(JSON.stringify({ extraDependencies, modules }));
}
else {
console.log(require('util').inspect({ extraDependencies, modules }, false, null, true));
}
}).option('-j, --json', 'Output results in the plain JSON format.', () => true, false);
// Generates a source file listing all packages to link.
// It's deprecated, use `generate-modules-provider` instead.
registerResolveCommand('generate-package-list', async (results, options) => {
const modules = options.empty ? [] : await (0, autolinking_1.resolveModulesAsync)(results, options);
(0, autolinking_1.generatePackageListAsync)(modules, options);
})
.option('-t, --target <path>', 'Path to the target file, where the package list should be written to.')
.option('-n, --namespace <namespace>', 'Java package name under which the package list should be placed.')
.option('--empty', 'Whether to only generate an empty list. Might be used when the user opts-out of autolinking.', false);
// Generates a source file listing all packages to link in the runtime.
registerResolveCommand('generate-modules-provider', async (results, options) => {
const packages = options.packages ?? [];
const modules = await (0, autolinking_1.resolveModulesAsync)(results, options);
const filteredModules = modules.filter((module) => packages.includes(module.packageName));
(0, autolinking_1.generatePackageListAsync)(filteredModules, options);
})
.option('-t, --target <path>', 'Path to the target file, where the package list should be written to.')
.option('-p, --packages <packages...>', 'Names of the packages to include in the generated modules provider.');
registerPatchReactImportsCommand();
registerReactNativeConfigCommand();
await commander_1.default
.version(require('expo-modules-autolinking/package.json').version)
.description('CLI command that searches for Expo modules to autolink them.')
.parseAsync(args, { from: 'user' });
};
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,28 @@
import type { ExtraDependencies, ModuleDescriptorAndroid, PackageRevision } from '../types';
/**
* Generates Java file that contains all autolinked packages.
*/
export declare function generatePackageListAsync(modules: ModuleDescriptorAndroid[], targetPath: string, namespace: string): Promise<void>;
export declare function resolveModuleAsync(packageName: string, revision: PackageRevision): Promise<ModuleDescriptorAndroid | null>;
export declare function resolveExtraBuildDependenciesAsync(projectNativeRoot: string): Promise<ExtraDependencies | null>;
/**
* 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 convertPackageNameToProjectName(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;

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.searchGradlePropertyFirst = exports.convertPackageNameToProjectName = exports.resolveExtraBuildDependenciesAsync = exports.resolveModuleAsync = exports.generatePackageListAsync = void 0;
const fast_glob_1 = __importDefault(require("fast-glob"));
const fs_extra_1 = __importDefault(require("fs-extra"));
const path_1 = __importDefault(require("path"));
const ANDROID_PROPERTIES_FILE = 'gradle.properties';
const ANDROID_EXTRA_BUILD_DEPS_KEY = 'android.extraMavenRepos';
/**
* Generates Java file that contains all autolinked packages.
*/
async function generatePackageListAsync(modules, targetPath, namespace) {
const generatedFileContent = await generatePackageListFileContentAsync(modules, namespace);
await fs_extra_1.default.outputFile(targetPath, generatedFileContent);
}
exports.generatePackageListAsync = generatePackageListAsync;
async function findGradleFilesAsync(revision) {
const configGradlePaths = revision.config?.androidGradlePaths();
if (configGradlePaths && configGradlePaths.length) {
return configGradlePaths;
}
const buildGradleFiles = await (0, fast_glob_1.default)('*/build.gradle', {
cwd: revision.path,
ignore: ['**/node_modules/**'],
});
return buildGradleFiles;
}
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 buildGradleFiles = await findGradleFilesAsync(revision);
// Just in case where the module doesn't have its own `build.gradle`.
if (!buildGradleFiles.length) {
return null;
}
const projects = buildGradleFiles.map((buildGradleFile) => {
const gradleFilePath = path_1.default.join(revision.path, buildGradleFile);
return {
name: convertPackageNameToProjectName(packageName, path_1.default.relative(revision.path, gradleFilePath)),
sourceDir: path_1.default.dirname(gradleFilePath),
};
});
const plugins = (revision.config?.androidGradlePlugins() ?? []).map(({ id, group, sourceDir }) => ({
id,
group,
sourceDir: path_1.default.join(revision.path, sourceDir),
}));
return {
packageName,
projects,
...(plugins.length > 0 ? { plugins } : {}),
modules: revision.config?.androidModules() ?? [],
};
}
exports.resolveModuleAsync = resolveModuleAsync;
async function resolveExtraBuildDependenciesAsync(projectNativeRoot) {
const propsFile = path_1.default.join(projectNativeRoot, ANDROID_PROPERTIES_FILE);
try {
const contents = await fs_extra_1.default.readFile(propsFile, 'utf8');
const extraMavenReposString = searchGradlePropertyFirst(contents, ANDROID_EXTRA_BUILD_DEPS_KEY);
if (extraMavenReposString) {
const extraMavenRepos = JSON.parse(extraMavenReposString);
return extraMavenRepos;
}
}
catch { }
return null;
}
exports.resolveExtraBuildDependenciesAsync = resolveExtraBuildDependenciesAsync;
/**
* Generates the string to put into the generated package list.
*/
async function generatePackageListFileContentAsync(modules, namespace) {
// TODO: Instead of ignoring `expo` here, make the package class paths configurable from `expo-module.config.json`.
const packagesClasses = await findAndroidPackagesAsync(modules.filter((module) => module.packageName !== 'expo'));
const modulesClasses = await findAndroidModules(modules);
return `package ${namespace};
import java.util.Arrays;
import java.util.List;
import expo.modules.core.interfaces.Package;
import expo.modules.kotlin.modules.Module;
import expo.modules.kotlin.ModulesProvider;
public class ExpoModulesPackageList implements ModulesProvider {
private static class LazyHolder {
static final List<Package> packagesList = Arrays.<Package>asList(
${packagesClasses.map((packageClass) => ` new ${packageClass}()`).join(',\n')}
);
static final List<Class<? extends Module>> modulesList = Arrays.<Class<? extends Module>>asList(
${modulesClasses.map((moduleClass) => ` ${moduleClass}.class`).join(',\n')}
);
}
public static List<Package> getPackageList() {
return LazyHolder.packagesList;
}
@Override
public List<Class<? extends Module>> getModulesList() {
return LazyHolder.modulesList;
}
}
`;
}
function findAndroidModules(modules) {
const modulesToProvide = modules.filter((module) => module.modules.length > 0);
const classNames = [].concat(...modulesToProvide.map((module) => module.modules));
return classNames;
}
async function findAndroidPackagesAsync(modules) {
const classes = [];
const flattenedSourceDirList = [];
for (const module of modules) {
for (const project of module.projects) {
flattenedSourceDirList.push(project.sourceDir);
}
}
await Promise.all(flattenedSourceDirList.map(async (sourceDir) => {
const files = await (0, fast_glob_1.default)('**/*Package.{java,kt}', {
cwd: sourceDir,
});
for (const file of files) {
const fileContent = await fs_extra_1.default.readFile(path_1.default.join(sourceDir, file), 'utf8');
const packageRegex = (() => {
if (process.env.EXPO_SHOULD_USE_LEGACY_PACKAGE_INTERFACE) {
return /\bimport\s+org\.unimodules\.core\.(interfaces\.Package|BasePackage)\b/;
}
else {
return /\bimport\s+expo\.modules\.core\.(interfaces\.Package|BasePackage)\b/;
}
})();
// Very naive check to skip non-expo packages
if (!packageRegex.test(fileContent)) {
continue;
}
const classPathMatches = fileContent.match(/^package ([\w.]+)\b/m);
if (classPathMatches) {
const basename = path_1.default.basename(file, path_1.default.extname(file));
classes.push(`${classPathMatches[1]}.${basename}`);
}
}
}));
return classes.sort();
}
/**
* 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 convertPackageNameToProjectName(packageName, buildGradleFile) {
const name = packageName.replace(/^@/g, '').replace(/\W+/g, '-');
const baseDir = path_1.default.dirname(buildGradleFile).replace(/\//g, '-');
return baseDir === 'android' ? name : `${name}$${baseDir}`;
}
exports.convertPackageNameToProjectName = convertPackageNameToProjectName;
/**
* 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;
}
exports.searchGradlePropertyFirst = searchGradlePropertyFirst;
//# sourceMappingURL=android.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,15 @@
import type { ExtraDependencies, ModuleDescriptorIos, ModuleIosPodspecInfo, PackageRevision, SearchOptions } 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, options: SearchOptions): Promise<ModuleDescriptorIos | null>;
export declare function resolveExtraBuildDependenciesAsync(projectNativeRoot: string): Promise<ExtraDependencies | null>;
/**
* Generates Swift file that contains all autolinked Swift packages.
*/
export declare function generatePackageListAsync(modules: ModuleDescriptorIos[], targetPath: string): 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,186 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.formatArrayOfReactDelegateHandler = exports.generatePackageListAsync = exports.resolveExtraBuildDependenciesAsync = exports.resolveModuleAsync = exports.getSwiftModuleNames = void 0;
const fast_glob_1 = __importDefault(require("fast-glob"));
const fs_extra_1 = __importDefault(require("fs-extra"));
const path_1 = __importDefault(require("path"));
const APPLE_PROPERTIES_FILE = 'Podfile.properties.json';
const APPLE_EXTRA_BUILD_DEPS_KEY = 'apple.extraPods';
const indent = ' ';
async function findPodspecFiles(revision) {
const configPodspecPaths = revision.config?.applePodspecPaths();
if (configPodspecPaths && configPodspecPaths.length) {
return configPodspecPaths;
}
const podspecFiles = await (0, fast_glob_1.default)('*/*.podspec', {
cwd: revision.path,
ignore: ['**/node_modules/**'],
});
return podspecFiles;
}
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, '_'));
}
exports.getSwiftModuleNames = getSwiftModuleNames;
/**
* Resolves module search result with additional details required for iOS platform.
*/
async function resolveModuleAsync(packageName, revision, options) {
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());
return {
packageName,
pods,
swiftModuleNames,
flags: options.flags,
modules: revision.config?.appleModules() ?? [],
appDelegateSubscribers: revision.config?.appleAppDelegateSubscribers() ?? [],
reactDelegateHandlers: revision.config?.appleReactDelegateHandlers() ?? [],
debugOnly: revision.config?.appleDebugOnly() ?? false,
};
}
exports.resolveModuleAsync = resolveModuleAsync;
async function resolveExtraBuildDependenciesAsync(projectNativeRoot) {
const propsFile = path_1.default.join(projectNativeRoot, APPLE_PROPERTIES_FILE);
try {
const contents = await fs_extra_1.default.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;
}
exports.resolveExtraBuildDependenciesAsync = resolveExtraBuildDependenciesAsync;
/**
* Generates Swift file that contains all autolinked Swift packages.
*/
async function generatePackageListAsync(modules, targetPath) {
const className = path_1.default.basename(targetPath, path_1.default.extname(targetPath));
const generatedFileContent = await generatePackageListFileContentAsync(modules, className);
await fs_extra_1.default.outputFile(targetPath, generatedFileContent);
}
exports.generatePackageListAsync = generatePackageListAsync;
/**
* Generates the string to put into the generated package list.
*/
async function generatePackageListFileContentAsync(modules, className) {
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.
*/
import ExpoModulesCore
${generateCommonImportList(swiftModules)}
${generateDebugOnlyImportList(debugOnlySwiftModules)}
@objc(${className})
public class ${className}: ModulesProvider {
public override func getModuleClasses() -> [AnyModule.Type] {
${generateModuleClasses(modulesClassNames, debugOnlyModulesClassNames)}
}
public override func getAppDelegateSubscribers() -> [ExpoAppDelegateSubscriber.Type] {
${generateModuleClasses(appDelegateSubscribers, debugOnlyAppDelegateSubscribers)}
}
public override func getReactDelegateHandlers() -> [ExpoReactDelegateHandlerTupleType] {
${generateReactDelegateHandlers(reactDelegateHandlerModules, debugOnlyReactDelegateHandlerModules)}
}
}
`;
}
function generateCommonImportList(swiftModules) {
return swiftModules.map((moduleName) => `import ${moduleName}`).join('\n');
}
function generateDebugOnlyImportList(swiftModules) {
if (!swiftModules.length) {
return '';
}
return (wrapInDebugConfigurationCheck(0, swiftModules.map((moduleName) => `import ${moduleName}`).join('\n')) + '\n');
}
function generateModuleClasses(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)}]`;
}
exports.formatArrayOfReactDelegateHandler = formatArrayOfReactDelegateHandler;
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`;
}
//# sourceMappingURL=apple.js.map

File diff suppressed because one or more lines are too long

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,24 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveExtraBuildDependenciesAsync = exports.resolveModuleAsync = void 0;
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: path_1.default.join(revision.path, devtoolsConfig.webpageRoot),
};
}
exports.resolveModuleAsync = resolveModuleAsync;
async function resolveExtraBuildDependenciesAsync(_projectNativeRoot) {
return null;
}
exports.resolveExtraBuildDependenciesAsync = resolveExtraBuildDependenciesAsync;
//# sourceMappingURL=devtools.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"devtools.js","sourceRoot":"","sources":["../../src/platforms/devtools.ts"],"names":[],"mappings":";;;;;;AAAA,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;QAC1B,OAAO,IAAI,CAAC;KACb;IAED,OAAO;QACL,WAAW;QACX,WAAW,EAAE,QAAQ,CAAC,IAAI;QAC1B,WAAW,EAAE,cAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC,WAAW,CAAC;KAClE,CAAC;AACJ,CAAC;AAdD,gDAcC;AAEM,KAAK,UAAU,kCAAkC,CACtD,kBAA0B;IAE1B,OAAO,IAAI,CAAC;AACd,CAAC;AAJD,gFAIC","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: path.join(revision.path, devtoolsConfig.webpageRoot),\n };\n}\n\nexport async function resolveExtraBuildDependenciesAsync(\n _projectNativeRoot: string\n): Promise<ExtraDependencies | null> {\n return null;\n}\n"]}

View File

@@ -0,0 +1,19 @@
import type { RNConfigDependencyAndroid, RNConfigReactNativePlatformsConfigAndroid } from './reactNativeConfig.types';
export declare function resolveDependencyConfigImplAndroidAsync(packageRoot: string, reactNativeConfig: RNConfigReactNativePlatformsConfigAndroid | null | undefined): 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 `TurboReactPackage`.
*/
export declare function parseNativePackageClassNameAsync(packageRoot: string, androidDir: string): Promise<string | null>;
export declare function parseLibraryNameAsync(androidDir: string, packageJson: any): Promise<string | null>;
export declare function parseComponentDescriptorsAsync(packageRoot: string, pacakgeJson: any): Promise<string[]>;
export declare function findGradleAndManifestAsync({ androidDir, isLibrary, }: {
androidDir: string;
isLibrary: boolean;
}): Promise<{
gradle: string;
manifest: string;
}>;

View File

@@ -0,0 +1,208 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.findGradleAndManifestAsync = exports.parseComponentDescriptorsAsync = exports.parseLibraryNameAsync = exports.parseNativePackageClassNameAsync = exports.parsePackageNameAsync = exports.resolveDependencyConfigImplAndroidAsync = void 0;
const fast_glob_1 = __importDefault(require("fast-glob"));
const promises_1 = __importDefault(require("fs/promises"));
const path_1 = __importDefault(require("path"));
const utils_1 = require("./utils");
async function resolveDependencyConfigImplAndroidAsync(packageRoot, reactNativeConfig) {
if (reactNativeConfig === null) {
// Skip autolinking for this package.
return null;
}
const androidDir = path_1.default.join(packageRoot, 'android');
const { gradle, manifest } = await findGradleAndManifestAsync({ androidDir, isLibrary: true });
if (!manifest && !gradle) {
return null;
}
const packageName = reactNativeConfig?.packageName ||
(await parsePackageNameAsync(path_1.default.join(androidDir, manifest), path_1.default.join(androidDir, gradle)));
const nativePackageClassName = await parseNativePackageClassNameAsync(packageRoot, androidDir);
if (!nativePackageClassName) {
return null;
}
const packageJson = JSON.parse(await promises_1.default.readFile(path_1.default.join(packageRoot, 'package.json'), 'utf8'));
const packageImportPath = reactNativeConfig?.packageImportPath || `import ${packageName}.${nativePackageClassName};`;
const packageInstance = reactNativeConfig?.packageInstance || `new ${nativePackageClassName}()`;
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,
};
if (!result.libraryName) {
delete result.libraryName;
}
if (!result.dependencyConfiguration) {
delete result.dependencyConfiguration;
}
return result;
}
exports.resolveDependencyConfigImplAndroidAsync = resolveDependencyConfigImplAndroidAsync;
/**
* 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;
}
exports.parsePackageNameAsync = parsePackageNameAsync;
/**
* Parse the Java or Kotlin class name to for `ReactPackage` or `TurboReactPackage`.
*/
async function parseNativePackageClassNameAsync(packageRoot, androidDir) {
const matched = await (0, utils_1.globMatchFunctorFirstAsync)('**/*Package.{java,kt}', matchNativePackageClassName, { cwd: androidDir });
if (matched) {
return matched;
}
// 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;
}
return await (0, utils_1.globMatchFunctorFirstAsync)('**/*.{java,kt}', matchNativePackageClassName, {
cwd: androidDir,
});
}
exports.parseNativePackageClassNameAsync = parseNativePackageClassNameAsync;
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 TurboReactPackage
if (!lazyTurboReactPackageRegex) {
lazyTurboReactPackageRegex =
/class\s+(\w+[^(\s]*)[\s\w():]*(\s+extends\s+|:)[\s\w():,]*[^{]*TurboReactPackage/;
}
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;
}
exports.parseLibraryNameAsync = parseLibraryNameAsync;
async function parseComponentDescriptorsAsync(packageRoot, pacakgeJson) {
const jsRoot = pacakgeJson?.codegenConfig?.jsSrcsDir
? path_1.default.join(packageRoot, pacakgeJson.codegenConfig.jsSrcsDir)
: packageRoot;
const results = await (0, utils_1.globMatchFunctorAllAsync)('**/*.{js,jsx,ts,tsx}', matchComponentDescriptors, {
cwd: jsRoot,
ignore: ['**/node_modules/**'],
});
// Filter out duplicates as it happens that libraries contain multiple outputs due to package publishing.
// TODO: consider using "codegenConfig" to avoid this.
return Array.from(new Set(results));
}
exports.parseComponentDescriptorsAsync = parseComponentDescriptorsAsync;
let lazyCodegenComponentRegex = null;
function matchComponentDescriptors(filePath, contents) {
const fileContents = contents.toString();
if (!lazyCodegenComponentRegex) {
lazyCodegenComponentRegex =
/codegenNativeComponent(<.*>)?\s*\(\s*["'`](\w+)["'`](,?[\s\S]+interfaceOnly:\s*(\w+))?/m;
}
const match = fileContents.match(lazyCodegenComponentRegex);
if (!(match?.[4] === 'true') && match?.[2]) {
return `${match[2]}ComponentDescriptor`;
}
return null;
}
async function findGradleAndManifestAsync({ androidDir, isLibrary, }) {
const globExcludes = [
'node_modules/**',
'**/build/**',
'**/debug/**',
'Examples/**',
'examples/**',
'**/Pods/**',
'**/sdks/hermes/android/**',
'**/src/androidTest/**',
'**/src/test/**',
];
const gradlePattern = isLibrary ? 'build.gradle{,.kts}' : 'app/build.gradle{,.kts}';
const [manifests, gradles] = await Promise.all([
(0, fast_glob_1.default)('**/AndroidManifest.xml', { cwd: androidDir, ignore: globExcludes }),
(0, fast_glob_1.default)(gradlePattern, { cwd: androidDir, ignore: globExcludes }),
]);
const manifest = manifests.find((manifest) => manifest.includes('src/main/')) ?? manifests[0];
const gradle = gradles[0];
return { gradle, manifest };
}
exports.findGradleAndManifestAsync = findGradleAndManifestAsync;
//# sourceMappingURL=androidResolver.js.map

File diff suppressed because one or more lines are too long

View File

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

View File

@@ -0,0 +1,56 @@
"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 promises_1 = __importDefault(require("fs/promises"));
const path_1 = __importDefault(require("path"));
const require_from_string_1 = __importDefault(require("require-from-string"));
const resolve_from_1 = __importDefault(require("resolve-from"));
const utils_1 = require("./utils");
let tsMain = undefined;
/**
* Load the `react-native.config.js` or `react-native.config.ts` from the package.
*/
async function loadConfigAsync(packageRoot) {
const configJsPath = path_1.default.join(packageRoot, 'react-native.config.js');
if (await (0, utils_1.fileExistsAsync)(configJsPath)) {
try {
return require(configJsPath);
}
catch {
return null;
}
}
const configTsPath = path_1.default.join(packageRoot, 'react-native.config.ts');
if (await (0, utils_1.fileExistsAsync)(configTsPath)) {
if (tsMain === undefined) {
const tsPath = resolve_from_1.default.silent(packageRoot, 'typescript');
if (tsPath) {
tsMain = require(tsPath);
}
}
else if (tsMain == null) {
return null;
}
const configContents = await promises_1.default.readFile(configTsPath, 'utf8');
const transpiledContents = tsMain?.transpileModule(configContents, {
compilerOptions: {
module: tsMain.ModuleKind.NodeNext,
moduleResolution: tsMain.ModuleResolutionKind.NodeNext,
target: tsMain.ScriptTarget.ESNext,
},
});
const outputText = transpiledContents?.outputText;
let config;
try {
config = outputText ? (0, require_from_string_1.default)(outputText) : null;
}
catch { }
return config?.default ?? config ?? null;
}
return null;
}
exports.loadConfigAsync = loadConfigAsync;
//# sourceMappingURL=config.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/reactNativeConfig/config.ts"],"names":[],"mappings":";;;;;;AAAA,2DAA6B;AAC7B,gDAAwB;AACxB,8EAAoD;AACpD,gEAAuC;AAGvC,mCAA0C;AAE1C,IAAI,MAAM,GAAmD,SAAS,CAAC;AAEvE;;GAEG;AACI,KAAK,UAAU,eAAe,CACnC,WAAmB;IAEnB,MAAM,YAAY,GAAG,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,wBAAwB,CAAC,CAAC;IACtE,IAAI,MAAM,IAAA,uBAAe,EAAC,YAAY,CAAC,EAAE;QACvC,IAAI;YACF,OAAO,OAAO,CAAC,YAAY,CAAC,CAAC;SAC9B;QAAC,MAAM;YACN,OAAO,IAAI,CAAC;SACb;KACF;IAED,MAAM,YAAY,GAAG,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,wBAAwB,CAAC,CAAC;IACtE,IAAI,MAAM,IAAA,uBAAe,EAAC,YAAY,CAAC,EAAE;QACvC,IAAI,MAAM,KAAK,SAAS,EAAE;YACxB,MAAM,MAAM,GAAG,sBAAW,CAAC,MAAM,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;YAC7D,IAAI,MAAM,EAAE;gBACV,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;aAC1B;SACF;aAAM,IAAI,MAAM,IAAI,IAAI,EAAE;YACzB,OAAO,IAAI,CAAC;SACb;QAED,MAAM,cAAc,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QAC/D,MAAM,kBAAkB,GAAG,MAAM,EAAE,eAAe,CAAC,cAAc,EAAE;YACjE,eAAe,EAAE;gBACf,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,QAAQ;gBAClC,gBAAgB,EAAE,MAAM,CAAC,oBAAoB,CAAC,QAAQ;gBACtD,MAAM,EAAE,MAAM,CAAC,YAAY,CAAC,MAAM;aACnC;SACF,CAAC,CAAC;QACH,MAAM,UAAU,GAAG,kBAAkB,EAAE,UAAU,CAAC;QAClD,IAAI,MAAM,CAAC;QACX,IAAI;YACF,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,IAAA,6BAAiB,EAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;SAC5D;QAAC,MAAM,GAAE;QACV,OAAO,MAAM,EAAE,OAAO,IAAI,MAAM,IAAI,IAAI,CAAC;KAC1C;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAxCD,0CAwCC","sourcesContent":["import fs from 'fs/promises';\nimport path from 'path';\nimport requireFromString from 'require-from-string';\nimport resolveFrom from 'resolve-from';\n\nimport type { RNConfigReactNativeConfig } from './reactNativeConfig.types';\nimport { fileExistsAsync } from './utils';\n\nlet tsMain: typeof import('typescript') | null | undefined = undefined;\n\n/**\n * Load the `react-native.config.js` or `react-native.config.ts` from the package.\n */\nexport async function loadConfigAsync<T extends RNConfigReactNativeConfig>(\n packageRoot: string\n): Promise<T | null> {\n const configJsPath = path.join(packageRoot, 'react-native.config.js');\n if (await fileExistsAsync(configJsPath)) {\n try {\n return require(configJsPath);\n } catch {\n return null;\n }\n }\n\n const configTsPath = path.join(packageRoot, 'react-native.config.ts');\n if (await fileExistsAsync(configTsPath)) {\n if (tsMain === undefined) {\n const tsPath = resolveFrom.silent(packageRoot, 'typescript');\n if (tsPath) {\n tsMain = require(tsPath);\n }\n } else if (tsMain == null) {\n return null;\n }\n\n const configContents = await fs.readFile(configTsPath, 'utf8');\n const transpiledContents = tsMain?.transpileModule(configContents, {\n compilerOptions: {\n module: tsMain.ModuleKind.NodeNext,\n moduleResolution: tsMain.ModuleResolutionKind.NodeNext,\n target: tsMain.ScriptTarget.ESNext,\n },\n });\n const outputText = transpiledContents?.outputText;\n let config;\n try {\n config = outputText ? requireFromString(outputText) : null;\n } catch {}\n return config?.default ?? config ?? null;\n }\n\n return null;\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,2 @@
import type { RNConfigDependencyIos, RNConfigReactNativePlatformsConfigIos } from './reactNativeConfig.types';
export declare function resolveDependencyConfigImplIosAsync(packageRoot: string, reactNativeConfig: RNConfigReactNativePlatformsConfigIos | null | undefined): Promise<RNConfigDependencyIos | null>;

View File

@@ -0,0 +1,31 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveDependencyConfigImplIosAsync = void 0;
const fast_glob_1 = __importDefault(require("fast-glob"));
const promises_1 = __importDefault(require("fs/promises"));
const path_1 = __importDefault(require("path"));
async function resolveDependencyConfigImplIosAsync(packageRoot, reactNativeConfig) {
if (reactNativeConfig === null) {
// Skip autolinking for this package.
return null;
}
const podspecs = await (0, fast_glob_1.default)('*.podspec', { cwd: packageRoot });
if (!podspecs?.length) {
return null;
}
const mainPackagePodspec = path_1.default.basename(packageRoot) + '.podspec';
const podspecFile = podspecs.includes(mainPackagePodspec) ? mainPackagePodspec : podspecs[0];
const podspecPath = path_1.default.join(packageRoot, podspecFile);
const packageJson = JSON.parse(await promises_1.default.readFile(path_1.default.join(packageRoot, 'package.json'), 'utf8'));
return {
podspecPath,
version: packageJson.version,
configurations: reactNativeConfig?.configurations || [],
scriptPhases: reactNativeConfig?.scriptPhases || [],
};
}
exports.resolveDependencyConfigImplIosAsync = resolveDependencyConfigImplIosAsync;
//# sourceMappingURL=iosResolver.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"iosResolver.js","sourceRoot":"","sources":["../../src/reactNativeConfig/iosResolver.ts"],"names":[],"mappings":";;;;;;AAAA,0DAA6B;AAC7B,2DAA6B;AAC7B,gDAAwB;AAOjB,KAAK,UAAU,mCAAmC,CACvD,WAAmB,EACnB,iBAA2E;IAE3E,IAAI,iBAAiB,KAAK,IAAI,EAAE;QAC9B,qCAAqC;QACrC,OAAO,IAAI,CAAC;KACb;IAED,MAAM,QAAQ,GAAG,MAAM,IAAA,mBAAI,EAAC,WAAW,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;IAC/D,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE;QACrB,OAAO,IAAI,CAAC;KACb;IACD,MAAM,kBAAkB,GAAG,cAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAG,UAAU,CAAC;IACnE,MAAM,WAAW,GAAG,QAAQ,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC7F,MAAM,WAAW,GAAG,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IAExD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,kBAAE,CAAC,QAAQ,CAAC,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IAElG,OAAO;QACL,WAAW;QACX,OAAO,EAAE,WAAW,CAAC,OAAO;QAC5B,cAAc,EAAE,iBAAiB,EAAE,cAAc,IAAI,EAAE;QACvD,YAAY,EAAE,iBAAiB,EAAE,YAAY,IAAI,EAAE;KACpD,CAAC;AACJ,CAAC;AAzBD,kFAyBC","sourcesContent":["import glob from 'fast-glob';\nimport fs from 'fs/promises';\nimport path from 'path';\n\nimport type {\n RNConfigDependencyIos,\n RNConfigReactNativePlatformsConfigIos,\n} from './reactNativeConfig.types';\n\nexport async function resolveDependencyConfigImplIosAsync(\n packageRoot: string,\n reactNativeConfig: RNConfigReactNativePlatformsConfigIos | null | undefined\n): Promise<RNConfigDependencyIos | null> {\n if (reactNativeConfig === null) {\n // Skip autolinking for this package.\n return null;\n }\n\n const podspecs = await glob('*.podspec', { cwd: packageRoot });\n if (!podspecs?.length) {\n return null;\n }\n const mainPackagePodspec = path.basename(packageRoot) + '.podspec';\n const podspecFile = podspecs.includes(mainPackagePodspec) ? mainPackagePodspec : podspecs[0];\n const podspecPath = path.join(packageRoot, podspecFile);\n\n const packageJson = JSON.parse(await fs.readFile(path.join(packageRoot, 'package.json'), 'utf8'));\n\n return {\n podspecPath,\n version: packageJson.version,\n configurations: reactNativeConfig?.configurations || [],\n scriptPhases: reactNativeConfig?.scriptPhases || [],\n };\n}\n"]}

View File

@@ -0,0 +1,12 @@
import type { RNConfigCommandOptions, RNConfigDependency, RNConfigReactNativeAppProjectConfig, RNConfigReactNativeProjectConfig, RNConfigResult } from './reactNativeConfig.types';
import type { SupportedPlatform } from '../types';
/**
* Create config for react-native core autolinking.
*/
export declare function createReactNativeConfigAsync({ platform, projectRoot, searchPaths, }: RNConfigCommandOptions): Promise<RNConfigResult>;
/**
* Find all dependencies and their directories from the project.
*/
export declare function findDependencyRootsAsync(projectRoot: string, searchPaths: string[]): Promise<Record<string, string>>;
export declare function resolveDependencyConfigAsync(platform: SupportedPlatform, name: string, packageRoot: string, projectConfig: RNConfigReactNativeProjectConfig | null): Promise<RNConfigDependency | null>;
export declare function resolveAppProjectConfigAsync(projectRoot: string, platform: SupportedPlatform): Promise<RNConfigReactNativeAppProjectConfig>;

View File

@@ -0,0 +1,117 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveAppProjectConfigAsync = exports.resolveDependencyConfigAsync = exports.findDependencyRootsAsync = exports.createReactNativeConfigAsync = void 0;
const promises_1 = __importDefault(require("fs/promises"));
const path_1 = __importDefault(require("path"));
const androidResolver_1 = require("./androidResolver");
const config_1 = require("./config");
const iosResolver_1 = require("./iosResolver");
const utils_1 = require("./utils");
const utils_2 = require("../autolinking/utils");
/**
* Create config for react-native core autolinking.
*/
async function createReactNativeConfigAsync({ platform, projectRoot, searchPaths, }) {
const projectConfig = await (0, config_1.loadConfigAsync)(projectRoot);
const dependencyRoots = await findDependencyRootsAsync(projectRoot, searchPaths);
const reactNativePath = dependencyRoots['react-native'];
const dependencyConfigs = await Promise.all(Object.entries(dependencyRoots).map(async ([name, packageRoot]) => {
const config = await resolveDependencyConfigAsync(platform, name, packageRoot, projectConfig);
return [name, config];
}));
const dependencyResults = Object.fromEntries(dependencyConfigs.filter(([, config]) => config != null));
const projectData = await resolveAppProjectConfigAsync(projectRoot, platform);
return {
root: projectRoot,
reactNativePath,
dependencies: dependencyResults,
project: projectData,
};
}
exports.createReactNativeConfigAsync = createReactNativeConfigAsync;
/**
* Find all dependencies and their directories from the project.
*/
async function findDependencyRootsAsync(projectRoot, searchPaths) {
const packageJson = JSON.parse(await promises_1.default.readFile(path_1.default.join(projectRoot, 'package.json'), 'utf8'));
const dependencies = [
...Object.keys(packageJson.dependencies ?? {}),
...Object.keys(packageJson.devDependencies ?? {}),
];
const results = {};
// `searchPathSet` can be mutated to discover all "isolated modules groups", when using isolated modules
const searchPathSet = new Set(searchPaths);
for (const name of dependencies) {
for (const searchPath of searchPathSet) {
const packageConfigPath = path_1.default.resolve(searchPath, name, 'package.json');
if (await (0, utils_1.fileExistsAsync)(packageConfigPath)) {
const packageRoot = path_1.default.dirname(packageConfigPath);
results[name] = packageRoot;
const maybeIsolatedModulesPath = (0, utils_2.getIsolatedModulesPath)(packageRoot, name);
if (maybeIsolatedModulesPath) {
searchPathSet.add(maybeIsolatedModulesPath);
}
break;
}
}
}
return results;
}
exports.findDependencyRootsAsync = findDependencyRootsAsync;
async function resolveDependencyConfigAsync(platform, name, packageRoot, projectConfig) {
const libraryConfig = await (0, config_1.loadConfigAsync)(packageRoot);
const reactNativeConfig = {
...libraryConfig?.dependency,
...projectConfig?.dependencies[name],
};
if (Object.keys(libraryConfig?.platforms ?? {}).length > 0) {
// Package defines platforms would be a platform host package.
// The rnc-cli will skip this package.
// For example, the `react-native` package.
return null;
}
let platformData = null;
if (platform === 'android') {
platformData = await (0, androidResolver_1.resolveDependencyConfigImplAndroidAsync)(packageRoot, reactNativeConfig.platforms?.android);
}
else if (platform === 'ios') {
platformData = await (0, iosResolver_1.resolveDependencyConfigImplIosAsync)(packageRoot, reactNativeConfig.platforms?.ios);
}
if (!platformData) {
return null;
}
return {
root: packageRoot,
name,
platforms: {
[platform]: platformData,
},
};
}
exports.resolveDependencyConfigAsync = resolveDependencyConfigAsync;
async function resolveAppProjectConfigAsync(projectRoot, platform) {
if (platform === 'android') {
const androidDir = path_1.default.join(projectRoot, 'android');
const { gradle, manifest } = await (0, androidResolver_1.findGradleAndManifestAsync)({ androidDir, isLibrary: false });
const packageName = await (0, androidResolver_1.parsePackageNameAsync)(path_1.default.join(androidDir, manifest), path_1.default.join(androidDir, gradle));
return {
android: {
packageName: packageName ?? '',
sourceDir: path_1.default.join(projectRoot, 'android'),
},
};
}
if (platform === 'ios') {
return {
ios: {
sourceDir: path_1.default.join(projectRoot, 'ios'),
},
};
}
return {};
}
exports.resolveAppProjectConfigAsync = resolveAppProjectConfigAsync;
//# sourceMappingURL=reactNativeConfig.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,93 @@
import type { SupportedPlatform } from '../types';
/**
* Options for 'react-native-config' command.
*/
export interface RNConfigCommandOptions {
platform: SupportedPlatform;
projectRoot: string;
searchPaths: string[];
}
/**
* Dependency configuration for Android platform.
*/
export interface RNConfigDependencyAndroid {
sourceDir: string;
packageImportPath: string;
packageInstance: string;
dependencyConfiguration?: string;
buildTypes: string[];
libraryName?: string | null;
componentDescriptors?: string[] | null;
cmakeListsPath?: string | null;
cxxModuleCMakeListsModuleName?: string | null;
cxxModuleCMakeListsPath?: string | null;
cxxModuleHeaderName?: string | null;
}
/**
* Dependency configuration for iOS platform.
*/
export interface RNConfigDependencyIos {
podspecPath: string;
version: string;
configurations: string[];
scriptPhases: any[];
}
/**
* Dependency configuration.
*/
export interface RNConfigDependency {
root: string;
name: string;
platforms: {
android?: RNConfigDependencyAndroid;
ios?: RNConfigDependencyIos;
};
}
/**
* Result of 'react-native-config' command.
*/
export interface RNConfigResult {
root: string;
reactNativePath: string;
dependencies: Record<string, RNConfigDependency>;
project: {
ios?: {
sourceDir: string;
};
};
}
export type RNConfigReactNativePlatformsConfigAndroid = any;
export type RNConfigReactNativePlatformsConfigIos = any;
interface RNConfigReactNativePlatformsConfig {
platforms?: {
android?: RNConfigReactNativePlatformsConfigAndroid;
ios?: RNConfigReactNativePlatformsConfigIos;
};
}
/**
* The `react-native.config.js` config from projectRoot.
*/
export interface RNConfigReactNativeProjectConfig {
dependencies: Record<string, RNConfigReactNativePlatformsConfig>;
}
/**
* The `react-native.config.js` config from library packageRoot.
*/
export interface RNConfigReactNativeLibraryConfig {
dependency?: RNConfigReactNativePlatformsConfig;
platforms?: any;
}
export type RNConfigReactNativeConfig = RNConfigReactNativeProjectConfig | RNConfigReactNativeLibraryConfig;
/**
* The `project` config represents the app project configuration.
*/
export interface RNConfigReactNativeAppProjectConfig {
android?: {
sourceDir: string;
packageName: string;
};
ios?: {
sourceDir: string;
};
}
export {};

View File

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

View File

@@ -0,0 +1 @@
{"version":3,"file":"reactNativeConfig.types.js","sourceRoot":"","sources":["../../src/reactNativeConfig/reactNativeConfig.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { SupportedPlatform } from '../types';\n\n/**\n * Options for 'react-native-config' command.\n */\nexport interface RNConfigCommandOptions {\n platform: SupportedPlatform;\n projectRoot: string;\n searchPaths: string[];\n}\n\n/**\n * Dependency configuration for Android platform.\n */\nexport interface RNConfigDependencyAndroid {\n sourceDir: string;\n packageImportPath: string;\n packageInstance: string;\n dependencyConfiguration?: string;\n buildTypes: string[];\n libraryName?: string | null;\n componentDescriptors?: string[] | null;\n cmakeListsPath?: string | null;\n cxxModuleCMakeListsModuleName?: string | null;\n cxxModuleCMakeListsPath?: string | null;\n cxxModuleHeaderName?: string | null;\n}\n\n/**\n * Dependency configuration for iOS platform.\n */\nexport interface RNConfigDependencyIos {\n podspecPath: string;\n version: string;\n configurations: string[];\n scriptPhases: any[];\n}\n\n/**\n * Dependency configuration.\n */\nexport interface RNConfigDependency {\n root: string;\n name: string;\n platforms: {\n android?: RNConfigDependencyAndroid;\n ios?: RNConfigDependencyIos;\n };\n}\n\n/**\n * Result of 'react-native-config' command.\n */\nexport interface RNConfigResult {\n root: string;\n reactNativePath: string;\n dependencies: Record<string, RNConfigDependency>;\n project: {\n ios?: {\n sourceDir: string;\n };\n };\n}\n\nexport type RNConfigReactNativePlatformsConfigAndroid = any;\nexport type RNConfigReactNativePlatformsConfigIos = any;\n\ninterface RNConfigReactNativePlatformsConfig {\n platforms?: {\n android?: RNConfigReactNativePlatformsConfigAndroid;\n ios?: RNConfigReactNativePlatformsConfigIos;\n };\n}\n\n/**\n * The `react-native.config.js` config from projectRoot.\n */\nexport interface RNConfigReactNativeProjectConfig {\n dependencies: Record<string, RNConfigReactNativePlatformsConfig>;\n}\n\n/**\n * The `react-native.config.js` config from library packageRoot.\n */\nexport interface RNConfigReactNativeLibraryConfig {\n dependency?: RNConfigReactNativePlatformsConfig;\n platforms?: any;\n}\n\nexport type RNConfigReactNativeConfig =\n | RNConfigReactNativeProjectConfig\n | RNConfigReactNativeLibraryConfig;\n\n/**\n * The `project` config represents the app project configuration.\n */\nexport interface RNConfigReactNativeAppProjectConfig {\n android?: {\n sourceDir: string;\n packageName: string;\n };\n ios?: {\n sourceDir: string;\n };\n}\n"]}

View File

@@ -0,0 +1,20 @@
/// <reference types="node" />
import glob from 'fast-glob';
type GlobOptions = Parameters<typeof glob>[1];
/**
* A matching function that takes a file path and its contents and returns a string if it matches, or null otherwise.
*/
type MatchFunctor = (filePath: string, contents: Buffer) => string | null;
/**
* Check if the file exists.
*/
export declare function fileExistsAsync(file: string): Promise<boolean>;
/**
* Search files that match the glob pattern and return all matches from the matchFunctor.
*/
export declare function globMatchFunctorAllAsync(globPattern: string, matchFunctor: MatchFunctor, options?: GlobOptions): Promise<string[]>;
/**
* Search files that match the glob pattern and return the first match from the matchFunctor.
*/
export declare function globMatchFunctorFirstAsync(globPattern: string, matchFunctor: MatchFunctor, options?: GlobOptions): Promise<string | null>;
export {};

View File

@@ -0,0 +1,58 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.globMatchFunctorFirstAsync = exports.globMatchFunctorAllAsync = exports.fileExistsAsync = void 0;
const fast_glob_1 = __importDefault(require("fast-glob"));
const promises_1 = __importDefault(require("fs/promises"));
const path_1 = __importDefault(require("path"));
/**
* Check if the file exists.
*/
async function fileExistsAsync(file) {
return (await promises_1.default.stat(file).catch(() => null))?.isFile() ?? false;
}
exports.fileExistsAsync = fileExistsAsync;
/**
* Search files that match the glob pattern and return all matches from the matchFunctor.
*/
async function globMatchFunctorAllAsync(globPattern, matchFunctor, options) {
const globStream = fast_glob_1.default.stream(globPattern, options);
const cwd = options?.cwd ?? process.cwd();
const results = [];
for await (const file of globStream) {
let filePath = file.toString();
if (!path_1.default.isAbsolute(filePath)) {
filePath = path_1.default.resolve(cwd, filePath);
}
const contents = await promises_1.default.readFile(filePath);
const matched = matchFunctor(filePath, contents);
if (matched != null) {
results.push(matched);
}
}
return results;
}
exports.globMatchFunctorAllAsync = globMatchFunctorAllAsync;
/**
* Search files that match the glob pattern and return the first match from the matchFunctor.
*/
async function globMatchFunctorFirstAsync(globPattern, matchFunctor, options) {
const globStream = fast_glob_1.default.stream(globPattern, options);
const cwd = options?.cwd ?? process.cwd();
for await (const file of globStream) {
let filePath = file.toString();
if (!path_1.default.isAbsolute(filePath)) {
filePath = path_1.default.resolve(cwd, filePath);
}
const contents = await promises_1.default.readFile(filePath);
const matched = matchFunctor(filePath, contents);
if (matched != null) {
return matched;
}
}
return null;
}
exports.globMatchFunctorFirstAsync = globMatchFunctorFirstAsync;
//# sourceMappingURL=utils.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/reactNativeConfig/utils.ts"],"names":[],"mappings":";;;;;;AAAA,0DAA6B;AAC7B,2DAA6B;AAC7B,gDAAwB;AASxB;;GAEG;AACI,KAAK,UAAU,eAAe,CAAC,IAAY;IAChD,OAAO,CAAC,MAAM,kBAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,KAAK,CAAC;AACpE,CAAC;AAFD,0CAEC;AAED;;GAEG;AACI,KAAK,UAAU,wBAAwB,CAC5C,WAAmB,EACnB,YAA0B,EAC1B,OAAqB;IAErB,MAAM,UAAU,GAAG,mBAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IACrD,MAAM,GAAG,GAAG,OAAO,EAAE,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1C,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,UAAU,EAAE;QACnC,IAAI,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC/B,IAAI,CAAC,cAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE;YAC9B,QAAQ,GAAG,cAAI,CAAC,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;SACxC;QACD,MAAM,QAAQ,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC7C,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACjD,IAAI,OAAO,IAAI,IAAI,EAAE;YACnB,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;SACvB;KACF;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AApBD,4DAoBC;AAED;;GAEG;AACI,KAAK,UAAU,0BAA0B,CAC9C,WAAmB,EACnB,YAA0B,EAC1B,OAAqB;IAErB,MAAM,UAAU,GAAG,mBAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IACrD,MAAM,GAAG,GAAG,OAAO,EAAE,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1C,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,UAAU,EAAE;QACnC,IAAI,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC/B,IAAI,CAAC,cAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE;YAC9B,QAAQ,GAAG,cAAI,CAAC,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;SACxC;QACD,MAAM,QAAQ,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC7C,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACjD,IAAI,OAAO,IAAI,IAAI,EAAE;YACnB,OAAO,OAAO,CAAC;SAChB;KACF;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAnBD,gEAmBC","sourcesContent":["import glob from 'fast-glob';\nimport fs from 'fs/promises';\nimport path from 'path';\n\ntype GlobOptions = Parameters<typeof glob>[1];\n\n/**\n * A matching function that takes a file path and its contents and returns a string if it matches, or null otherwise.\n */\ntype MatchFunctor = (filePath: string, contents: Buffer) => string | null;\n\n/**\n * Check if the file exists.\n */\nexport async function fileExistsAsync(file: string): Promise<boolean> {\n return (await fs.stat(file).catch(() => null))?.isFile() ?? false;\n}\n\n/**\n * Search files that match the glob pattern and return all matches from the matchFunctor.\n */\nexport async function globMatchFunctorAllAsync(\n globPattern: string,\n matchFunctor: MatchFunctor,\n options?: GlobOptions\n): Promise<string[]> {\n const globStream = glob.stream(globPattern, options);\n const cwd = options?.cwd ?? process.cwd();\n const results: string[] = [];\n for await (const file of globStream) {\n let filePath = file.toString();\n if (!path.isAbsolute(filePath)) {\n filePath = path.resolve(cwd, filePath);\n }\n const contents = await fs.readFile(filePath);\n const matched = matchFunctor(filePath, contents);\n if (matched != null) {\n results.push(matched);\n }\n }\n return results;\n}\n\n/**\n * Search files that match the glob pattern and return the first match from the matchFunctor.\n */\nexport async function globMatchFunctorFirstAsync(\n globPattern: string,\n matchFunctor: MatchFunctor,\n options?: GlobOptions\n): Promise<string | null> {\n const globStream = glob.stream(globPattern, options);\n const cwd = options?.cwd ?? process.cwd();\n for await (const file of globStream) {\n let filePath = file.toString();\n if (!path.isAbsolute(filePath)) {\n filePath = path.resolve(cwd, filePath);\n }\n const contents = await fs.readFile(filePath);\n const matched = matchFunctor(filePath, contents);\n if (matched != null) {\n return matched;\n }\n }\n return null;\n}\n"]}

View File

@@ -0,0 +1,237 @@
import { ExpoModuleConfig } from './ExpoModuleConfig';
export type SupportedPlatform = 'apple' | 'ios' | 'android' | 'web' | 'macos' | 'tvos' | 'devtools';
/**
* Options that can be passed through `expo.autolinking` config in the package.json file.
*/
export type AutolinkingOptions = {
searchPaths?: string[] | null;
ignorePaths?: string[] | null;
exclude?: string[] | null;
flags?: Record<string, any>;
} & {
[key in SupportedPlatform]?: AutolinkingOptions;
};
export interface SearchOptions {
searchPaths: string[];
ignorePaths?: string[] | null;
exclude?: string[] | null;
platform: SupportedPlatform;
silent?: boolean;
nativeModulesDir?: string | null;
projectRoot: string;
/**
* Filter the search results to only include the project dependencies.
* In a monorepo, you may like to set this to false and link all modules from the monorepo.
* @default true
*/
onlyProjectDeps?: boolean;
flags?: Record<string, any>;
}
export interface ResolveOptions extends SearchOptions {
json?: boolean;
}
export interface GenerateOptions extends ResolveOptions {
target: string;
namespace?: string;
empty?: boolean;
}
export interface GenerateModulesProviderOptions extends ResolveOptions {
target: string;
packages: string[];
}
export interface PatchReactImportsOptions {
podsRoot: string;
dryRun: boolean;
}
export type PackageRevision = {
path: string;
version: string;
config?: ExpoModuleConfig;
duplicates?: PackageRevision[];
};
export type SearchResults = {
[moduleName: string]: PackageRevision;
};
export interface ModuleAndroidProjectInfo {
name: string;
sourceDir: string;
}
export interface ModuleAndroidPluginInfo {
id: string;
sourceDir: string;
}
export interface ModuleDescriptorAndroid {
packageName: string;
projects: ModuleAndroidProjectInfo[];
plugins?: ModuleAndroidPluginInfo[];
modules: string[];
}
export interface ModuleIosPodspecInfo {
podName: string;
podspecDir: string;
}
export interface ModuleDescriptorIos {
packageName: string;
pods: ModuleIosPodspecInfo[];
flags: Record<string, any> | undefined;
swiftModuleNames: string[];
modules: string[];
appDelegateSubscribers: string[];
reactDelegateHandlers: string[];
debugOnly: boolean;
}
export interface ModuleDescriptorDevTools {
packageName: string;
packageRoot: string;
webpageRoot: string;
}
export type ModuleDescriptor = ModuleDescriptorAndroid | ModuleDescriptorIos | ModuleDescriptorDevTools;
export interface AndroidGradlePluginDescriptor {
/**
* Gradle plugin ID
*/
id: string;
/**
* Artifact group
*/
group: string;
/**
* Relative path to the gradle plugin directory
*/
sourceDir: string;
}
/**
* Represents a raw config specific to Apple platforms.
*/
export type RawModuleConfigApple = {
/**
* Names of Swift native modules classes to put to the generated modules provider file.
*/
modules?: string[];
/**
* Names of Swift native modules classes to put to the generated modules provider file.
* @deprecated Deprecated in favor of `modules`. Might be removed in the future releases.
*/
modulesClassNames?: string[];
/**
* Names of Swift classes that hooks into `ExpoAppDelegate` to receive AppDelegate life-cycle events.
*/
appDelegateSubscribers?: string[];
/**
* Names of Swift classes that implement `ExpoReactDelegateHandler` to hook React instance creation.
*/
reactDelegateHandlers?: string[];
/**
* Podspec relative path.
* To have multiple podspecs, string array type is also supported.
*/
podspecPath?: string | string[];
/**
* Swift product module name. If empty, the pod name is used for Swift imports.
* To have multiple modules, string array is also supported.
*/
swiftModuleName?: string | string[];
/**
* Whether this module will be added only to the debug configuration.
* Defaults to false.
*/
debugOnly?: boolean;
};
/**
* Represents a raw config from `expo-module.json`.
*/
export interface RawExpoModuleConfig {
/**
* An array of supported platforms.
*/
platforms?: SupportedPlatform[];
/**
* A config for all Apple platforms.
*/
apple?: RawModuleConfigApple;
/**
* The legacy config previously used for iOS platform. For backwards compatibility it's used as the fallback for `apple`.
* Also due to backwards compatibility, it includes the deprecated `modulesClassNames` field.
* @deprecated As the module can now support more than iOS platform, use the generic `apple` config instead.
*/
ios?: RawModuleConfigApple;
/**
* Android-specific config.
*/
android?: {
/**
* Full names (package + class name) of Kotlin native modules classes to put to the generated package provider file.
*/
modules?: string[];
/**
* Full names (package + class name) of Kotlin native modules classes to put to the generated package provider file.
* @deprecated Deprecated in favor of `modules`. Might be removed in the future releases.
*/
modulesClassNames?: string[];
/**
* build.gradle relative path.
* To have multiple build.gradle projects, string array type is also supported.
*/
gradlePath?: string | string[];
/**
* Gradle plugins.
*/
gradlePlugins?: AndroidGradlePluginDescriptor[];
};
/**
* DevTools-specific config.
*/
devtools?: {
/**
* The webpage root directory for Expo CLI DevTools to serve the web resources.
*/
webpageRoot: string;
};
}
interface AndroidMavenRepositoryPasswordCredentials {
username: string;
password: string;
}
interface AndroidMavenRepositoryHttpHeaderCredentials {
name: string;
value: string;
}
interface AndroidMavenRepositoryAWSCredentials {
accessKey: string;
secretKey: string;
sessionToken?: string;
}
type AndroidMavenRepositoryCredentials = AndroidMavenRepositoryPasswordCredentials | AndroidMavenRepositoryHttpHeaderCredentials | AndroidMavenRepositoryAWSCredentials;
export interface AndroidMavenRepository {
/**
* The URL of the Maven repository.
*/
url: string;
/**
* The credentials to use when accessing the Maven repository.
* May be of type PasswordCredentials, HttpHeaderCredentials, or AWSCredentials.
*
* @see the authentication schemes section of [Gradle documentation](https://docs.gradle.org/current/userguide/declaring_repositories.html#sec:authentication_schemes) for more information.
*/
credentials?: AndroidMavenRepositoryCredentials;
/**
* The authentication scheme to use when accessing the Maven repository.
*/
authentication?: 'basic' | 'digest' | 'header';
}
interface ApplePod {
name: string;
version?: string;
configurations?: string[];
modular_headers?: boolean;
source?: string;
path?: string;
podspec?: string;
testspecs?: string[];
git?: string;
branch?: string;
tag?: string;
commit?: string;
}
export type ExtraDependencies = AndroidMavenRepository[] | ApplePod[];
export {};

View File

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

File diff suppressed because one or more lines are too long