11import { execSync } from 'node:child_process' ;
22import Debug from 'debug' ;
33import exitHook from 'exit-hook' ;
4- import { isWindows , uncPathIsSafe , uncPathOptionsAreSafe , uncPathOptionsHaveCredentials } from './validators.js' ;
5- const debug = Debug ( 'windows-unc-path-connect' ) ;
4+ import { DEBUG_NAMESPACE } from './debug.config.js' ;
5+ import { driveLetterIsSafe , isWindows , uncPathIsSafe , uncPathOptionsAreSafe , uncPathOptionsHaveCredentials } from './validators.js' ;
6+ const timeoutMilliseconds = 30_000 ;
7+ const debug = Debug ( `${ DEBUG_NAMESPACE } :index` ) ;
68export function connectToUncPath ( uncPathOptions , connectOptions ) {
79 if ( ! isWindows ( ) || ! uncPathOptionsAreSafe ( uncPathOptions ) ) {
810 return false ;
911 }
1012 debug ( `Connecting to share: ${ uncPathOptions . uncPath } ` ) ;
11- let command = `net use "${ uncPathOptions . uncPath } "` ;
13+ const commandPieces = [ 'net use' ] ;
14+ if ( connectOptions ?. driveLetter ) {
15+ commandPieces . push ( connectOptions . driveLetter ) ;
16+ }
17+ commandPieces . push ( `"${ uncPathOptions . uncPath } "` ) ;
18+ if ( connectOptions ?. persistent ) {
19+ commandPieces . push ( '/persistent:yes' ) ;
20+ }
1221 if ( uncPathOptionsHaveCredentials ( uncPathOptions ) ) {
13- command += ` /user:"${ uncPathOptions . userName } " "${ uncPathOptions . password } "`;
22+ commandPieces . push ( ` /user:"${ uncPathOptions . userName } " "${ uncPathOptions . password } "`) ;
1423 }
1524 try {
16- const output = execSync ( command , { stdio : 'pipe' } ) ;
25+ const output = execSync ( commandPieces . join ( ' ' ) , {
26+ stdio : 'pipe' ,
27+ timeout : timeoutMilliseconds
28+ } ) ;
1729 debug ( output . toString ( ) . trim ( ) ) ;
1830 if ( connectOptions ?. deleteOnExit ?? false ) {
1931 exitHook ( ( ) => {
20- disconnectUncPath ( uncPathOptions . uncPath ) ;
32+ disconnectUncPath ( connectOptions ?. driveLetter ?? uncPathOptions . uncPath ) ;
2133 } ) ;
2234 }
2335 return output . includes ( 'command completed successfully' ) ;
@@ -28,20 +40,30 @@ export function connectToUncPath(uncPathOptions, connectOptions) {
2840 . includes ( 'Multiple connections to a server or shared resource' ) ;
2941 }
3042}
31- export function disconnectUncPath ( uncPath ) {
32- if ( ! isWindows ( ) || ! uncPathIsSafe ( uncPath ) ) {
43+ export function disconnectUncPath ( uncPathOrDriveLetter ) {
44+ if ( ! isWindows ( ) ||
45+ ( ! uncPathIsSafe ( uncPathOrDriveLetter ) &&
46+ ! driveLetterIsSafe ( uncPathOrDriveLetter ) ) ) {
3347 return false ;
3448 }
35- debug ( `Disconnecting share: ${ uncPath } ` ) ;
36- const command = `net use "${ uncPath } " /delete` ;
49+ debug ( `Disconnecting share: ${ uncPathOrDriveLetter } ` ) ;
50+ const command = `net use "${ uncPathOrDriveLetter } " /delete` ;
3751 try {
38- const output = execSync ( command , { stdio : 'pipe' } ) ;
52+ const output = execSync ( command , {
53+ stdio : 'pipe' ,
54+ timeout : timeoutMilliseconds
55+ } ) ;
3956 debug ( output . toString ( ) . trim ( ) ) ;
4057 return ( output . includes ( 'deleted successfully' ) ||
4158 output . includes ( 'connection could not be found' ) ) ;
4259 }
43- catch {
60+ catch ( error ) {
61+ const errorString = error . toString ( ) ;
62+ if ( errorString . includes ( 'network connection could not be found' ) ) {
63+ return true ;
64+ }
65+ debug ( errorString ) ;
4466 return false ;
4567 }
4668}
47- export { isWindows , uncPathIsSafe , uncPathOptionsAreSafe } from './validators.js' ;
69+ export { driveLetterIsSafe , isWindows , uncPathIsSafe , uncPathOptionsAreSafe } from './validators.js' ;
0 commit comments