@@ -6,7 +6,24 @@ import type { Package } from "./createPackage.js";
6
6
import { createCompilerHosts , type CompilerHosts , CompilerHostWrapper } from "./multiCompilerHost.js" ;
7
7
import type { CheckResult , EntrypointInfo , EntrypointResolutionAnalysis , Resolution , ResolutionKind } from "./types.js" ;
8
8
9
- export async function checkPackage ( pkg : Package ) : Promise < CheckResult > {
9
+ export interface CheckPackageOptions {
10
+ /**
11
+ * Exhaustive list of entrypoints to check. The package root is `"."`.
12
+ * Specifying this option disables automatic entrypoint discovery,
13
+ * and overrides the `includeEntrypoints` and `excludeEntrypoints` options.
14
+ */
15
+ entrypoints ?: string [ ] ;
16
+ /**
17
+ * Entrypoints to check in addition to automatically discovered ones.
18
+ */
19
+ includeEntrypoints ?: string [ ] ;
20
+ /**
21
+ * Entrypoints to exclude from checking.
22
+ */
23
+ excludeEntrypoints ?: ( string | RegExp ) [ ] ;
24
+ }
25
+
26
+ export async function checkPackage ( pkg : Package , options ?: CheckPackageOptions ) : Promise < CheckResult > {
10
27
const files = pkg . listFiles ( ) ;
11
28
const types = files . some ( ts . hasTSFileExtension ) ? "included" : false ;
12
29
const parts = files [ 0 ] . split ( "/" ) ;
@@ -21,7 +38,7 @@ export async function checkPackage(pkg: Package): Promise<CheckResult> {
21
38
}
22
39
23
40
const hosts = createCompilerHosts ( pkg ) ;
24
- const entrypointResolutions = getEntrypointInfo ( packageName , pkg , hosts ) ;
41
+ const entrypointResolutions = getEntrypointInfo ( packageName , pkg , hosts , options ) ;
25
42
const entrypointResolutionProblems = getEntrypointResolutionProblems ( entrypointResolutions , hosts ) ;
26
43
const resolutionBasedFileProblems = getResolutionBasedFileProblems ( packageName , entrypointResolutions , hosts ) ;
27
44
const fileProblems = getFileProblems ( entrypointResolutions , hosts ) ;
@@ -35,6 +52,46 @@ export async function checkPackage(pkg: Package): Promise<CheckResult> {
35
52
} ;
36
53
}
37
54
55
+ function getEntrypoints ( fs : Package , exportsObject : any , options : CheckPackageOptions | undefined ) : string [ ] {
56
+ if ( options ?. entrypoints ) {
57
+ return options . entrypoints . map ( ( e ) => formatEntrypointString ( e , fs . packageName ) ) ;
58
+ }
59
+ if ( exportsObject === undefined && fs ) {
60
+ return getProxyDirectories ( `/node_modules/${ fs . packageName } ` , fs ) ;
61
+ }
62
+ const detectedSubpaths = getSubpaths ( exportsObject ) ;
63
+ if ( detectedSubpaths . length === 0 ) {
64
+ detectedSubpaths . push ( "." ) ;
65
+ }
66
+ const included = Array . from (
67
+ new Set ( [
68
+ ...detectedSubpaths ,
69
+ ...( options ?. includeEntrypoints ?. map ( ( e ) => formatEntrypointString ( e , fs . packageName ) ) ?? [ ] ) ,
70
+ ] )
71
+ ) ;
72
+ if ( ! options ?. excludeEntrypoints ) {
73
+ return included ;
74
+ }
75
+ return included . filter ( ( entrypoint ) => {
76
+ return ! options . excludeEntrypoints ! . some ( ( exclusion ) => {
77
+ if ( typeof exclusion === "string" ) {
78
+ return formatEntrypointString ( exclusion , fs . packageName ) === entrypoint ;
79
+ }
80
+ return exclusion . test ( entrypoint ) ;
81
+ } ) ;
82
+ } ) ;
83
+ }
84
+
85
+ function formatEntrypointString ( path : string , packageName : string ) {
86
+ return (
87
+ path === "." || path . startsWith ( "./" )
88
+ ? path
89
+ : path . startsWith ( `${ packageName } /` )
90
+ ? `.${ path . slice ( packageName . length ) } `
91
+ : `./${ path } `
92
+ ) . trim ( ) ;
93
+ }
94
+
38
95
function getSubpaths ( exportsObject : any ) : string [ ] {
39
96
if ( ! exportsObject || typeof exportsObject !== "object" || Array . isArray ( exportsObject ) ) {
40
97
return [ ] ;
@@ -62,13 +119,14 @@ function getProxyDirectories(rootDir: string, fs: Package) {
62
119
. filter ( ( f ) => f !== "./" ) ;
63
120
}
64
121
65
- function getEntrypointInfo ( packageName : string , fs : Package , hosts : CompilerHosts ) : Record < string , EntrypointInfo > {
122
+ function getEntrypointInfo (
123
+ packageName : string ,
124
+ fs : Package ,
125
+ hosts : CompilerHosts ,
126
+ options : CheckPackageOptions | undefined
127
+ ) : Record < string , EntrypointInfo > {
66
128
const packageJson = JSON . parse ( fs . readFile ( `/node_modules/${ packageName } /package.json` ) ) ;
67
- const subpaths = getSubpaths ( packageJson . exports ) ;
68
- const entrypoints = subpaths . length ? subpaths : [ "." ] ;
69
- if ( ! packageJson . exports ) {
70
- entrypoints . push ( ...getProxyDirectories ( `/node_modules/${ packageName } ` , fs ) ) ;
71
- }
129
+ const entrypoints = getEntrypoints ( fs , packageJson . exports , options ) ;
72
130
const result : Record < string , EntrypointInfo > = { } ;
73
131
for ( const entrypoint of entrypoints ) {
74
132
const resolutions : Record < ResolutionKind , EntrypointResolutionAnalysis > = {
0 commit comments