@@ -23,6 +23,7 @@ const path = require('path');
2323async function checkDeps ( ) {
2424 const root = path . normalize ( path . join ( __dirname , '..' ) ) ;
2525 const src = path . normalize ( path . join ( __dirname , '..' , 'src' ) ) ;
26+ const packageJSON = require ( path . join ( root , 'package.json' ) ) ;
2627 const program = ts . createProgram ( {
2728 options : {
2829 allowJs : true ,
@@ -44,7 +45,7 @@ async function checkDeps() {
4445 if ( errors . length ) {
4546 console . log ( `--------------------------------------------------------` ) ;
4647 console . log ( `Changing the project structure or adding new components?` ) ;
47- console . log ( `Update DEPS in // ${ path . relative ( root , __filename ) } . ` ) ;
48+ console . log ( `Update DEPS in ./ ${ path . relative ( root , __filename ) } ` ) ;
4849 console . log ( `--------------------------------------------------------` ) ;
4950 }
5051 process . exit ( errors . length ? 1 : 0 ) ;
@@ -55,6 +56,8 @@ async function checkDeps() {
5556 const importPath = path . resolve ( path . dirname ( fileName ) , importName ) + '.ts' ;
5657 if ( ! allowImport ( fileName , importPath ) )
5758 errors . push ( `Disallowed import from ${ path . relative ( root , fileName ) } to ${ path . relative ( root , importPath ) } ` ) ;
59+ if ( ! alllowExternalImport ( fileName , importPath , importName ) )
60+ errors . push ( `Disallowed external dependency ${ importName } from ${ path . relative ( root , fileName ) } ` ) ;
5861 }
5962 ts . forEachChild ( node , x => visit ( x , fileName ) ) ;
6063 }
@@ -91,11 +94,38 @@ async function checkDeps() {
9194 }
9295 return false ;
9396 }
97+
98+
99+ function alllowExternalImport ( from , importPath , importName ) {
100+ const EXTERNAL_IMPORT_ALLOWLIST = [ 'electron' ] ;
101+ // Only external imports are relevant. Files in src/web are bundled via webpack.
102+ if ( importName . startsWith ( '.' ) || importPath . startsWith ( path . join ( src , 'web' ) ) )
103+ return true ;
104+ if ( EXTERNAL_IMPORT_ALLOWLIST . includes ( importName ) )
105+ return true ;
106+ try {
107+ const resolvedImport = require . resolve ( importName )
108+ const resolvedImportRelativeToNodeModules = path . relative ( path . join ( root , 'node_modules' ) , resolvedImport ) ;
109+ // Filter out internal Node.js modules
110+ if ( ! resolvedImportRelativeToNodeModules . startsWith ( importName ) )
111+ return true ;
112+ const resolvedImportRelativeToNodeModulesParts = resolvedImportRelativeToNodeModules . split ( path . sep ) ;
113+ if ( packageJSON . dependencies [ resolvedImportRelativeToNodeModulesParts [ 0 ] ] )
114+ return true ;
115+ // handle e.g. @babel /code-frame
116+ if ( resolvedImportRelativeToNodeModulesParts . length >= 2 && packageJSON . dependencies [ resolvedImportRelativeToNodeModulesParts . splice ( 0 , 2 ) . join ( path . sep ) ] )
117+ return true ;
118+ return false ;
119+ } catch ( error ) {
120+ if ( error . code !== 'MODULE_NOT_FOUND' )
121+ throw error
122+ }
123+ }
94124}
95125
96126function listAllFiles ( dir ) {
97127 const dirs = fs . readdirSync ( dir , { withFileTypes : true } ) ;
98- const result = [ ] ;
128+ const result = [ ] ;
99129 dirs . map ( d => {
100130 const res = path . resolve ( dir , d . name ) ;
101131 if ( d . isDirectory ( ) )
0 commit comments