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,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"]}