99 * @oncall react_native
1010 */
1111
12- import type { ExportMap , PackageInfo , ResolutionContext } from './types' ;
12+ import type { ExportMap , ResolutionContext , SourceFileResolution } from './types' ;
1313
14+ import path from 'path' ;
1415import invariant from 'invariant' ;
16+ import toPosixPath from './utils/toPosixPath' ;
1517
1618/**
17- * Resolve the main entry point subpath for a package.
19+ * Resolve a package subpath based on the entry points defined in the package's
20+ * "exports" field. If there is no match for the given subpath (which may be
21+ * augmented by resolution of conditional exports for the passed `context`),
22+ * returns `null`.
1823 *
1924 * Implements modern package resolution behaviour based on the [Package Entry
2025 * Points spec](https://nodejs.org/docs/latest-v19.x/api/packages.html#package-entry-points).
2126 */
22- export function getPackageEntryPointFromExports (
27+ export function resolvePackageTargetFromExports (
2328 context : ResolutionContext ,
24- packageInfo : PackageInfo ,
29+ /**
30+ * The path to the containing npm package directory.
31+ */
32+ packageRoot : string ,
33+ /**
34+ * The unresolved absolute path to the target module. This will be converted
35+ * to a package-relative subpath for comparison.
36+ */
37+ modulePath : string ,
38+ exportsField : ExportMap | string ,
2539 platform : string | null ,
26- ) : ?string {
27- return matchSubpathFromExports ( '.' , context , packageInfo , platform ) ;
40+ ) : SourceFileResolution | null {
41+ const packageSubpath = path . relative ( packageRoot , modulePath ) ;
42+ const subpath =
43+ // Convert to prefixed POSIX path for "exports" lookup
44+ packageSubpath === '' ? '.' : './' + toPosixPath ( packageSubpath ) ;
45+ const match = matchSubpathFromExports (
46+ context ,
47+ subpath ,
48+ exportsField ,
49+ platform ,
50+ ) ;
51+
52+ if ( match != null ) {
53+ const filePath = path . join ( packageRoot , match ) ;
54+
55+ if ( context . doesFileExist ( filePath ) ) {
56+ return { type : 'sourceFile' , filePath} ;
57+ }
58+ // TODO(T143882479): Throw InvalidPackageConfigurationError (entry point
59+ // missing) and log as warning in calling context.
60+ }
61+
62+ return null ;
2863}
2964
3065/**
@@ -33,22 +68,16 @@ export function getPackageEntryPointFromExports(
3368 * Implements modern package resolution behaviour based on the [Package Entry
3469 * Points spec](https://nodejs.org/docs/latest-v19.x/api/packages.html#package-entry-points).
3570 */
36- export function matchSubpathFromExports (
71+ function matchSubpathFromExports (
72+ context : ResolutionContext ,
3773 /**
3874 * The package-relative subpath (beginning with '.') to match against either
3975 * an exact subpath key or subpath pattern key in "exports".
4076 */
4177 subpath : string ,
42- context : ResolutionContext ,
43- { packageJson} : PackageInfo ,
78+ exportsField : ExportMap | string ,
4479 platform : string | null ,
4580) : ?string {
46- const { exports : exportsField } = packageJson ;
47-
48- if ( exportsField == null ) {
49- return null ;
50- }
51-
5281 const conditionNames = new Set ( [
5382 'default' ,
5483 ...context . unstable_conditionNames ,
@@ -57,15 +86,7 @@ export function matchSubpathFromExports(
5786 : [ ] ) ,
5887 ] ) ;
5988
60- let exportMap : FlattenedExportMap ;
61-
62- try {
63- exportMap = reduceExportsField ( exportsField , conditionNames ) ;
64- } catch ( e ) {
65- // TODO(T143882479): Log a warning if the "exports" field cannot be parsed
66- // NOTE: Under strict mode, this should throw an InvalidPackageConfigurationError
67- return null ;
68- }
89+ const exportMap = reduceExportsField ( exportsField , conditionNames ) ;
6990
7091 return exportMap [ subpath ] ;
7192}
@@ -93,6 +114,8 @@ function reduceExportsField(
93114 subpathOrCondition . startsWith ( '.' ) ,
94115 ) ;
95116
117+ // TODO(T143882479): Throw InvalidPackageConfigurationError and log as
118+ // warning in calling context.
96119 invariant (
97120 subpathKeys . length === 0 || subpathKeys . length === firstLevelKeys . length ,
98121 '"exports" object cannot have keys mapping both subpaths and conditions ' +
@@ -125,6 +148,8 @@ function reduceExportsField(
125148 value => value != null && ! value . startsWith ( './' ) ,
126149 ) ;
127150
151+ // TODO(T143882479): Throw InvalidPackageConfigurationError and log as
152+ // warning in calling context.
128153 invariant (
129154 invalidValues . length === 0 ,
130155 'One or more mappings for subpaths in "exports" is invalid. All values ' +
0 commit comments