11import { once } from "node:events" ;
22import fs from "node:fs/promises" ;
3- import nodePath , { basename , dirname } from "node:path" ;
3+ import nodePath , { basename } from "node:path" ;
44
55import { type FSWatcher , watch } from "chokidar" ;
66import createDebug from "debug" ;
@@ -18,6 +18,11 @@ import { ModuleDependencyGraph } from "./module-dependency-graph.js";
1818import type { Module , Registry } from "./registry.js" ;
1919import { ScenarioRegistry } from "./scenario-registry.js" ;
2020import { uncachedImport } from "./uncached-import.js" ;
21+ import {
22+ toForwardSlashPath ,
23+ pathDirname ,
24+ pathRelative ,
25+ } from "../util/forward-slash-path.js" ;
2126import { unescapePathForWindows } from "../util/windows-escape.js" ;
2227
2328const { uncachedRequire } = await import ( "./uncached-require.cjs" ) ;
@@ -69,10 +74,13 @@ export class ModuleLoader extends EventTarget {
6974 scenarioRegistry ?: ScenarioRegistry ,
7075 ) {
7176 super ( ) ;
72- this . basePath = basePath . replaceAll ( "\\" , "/" ) ;
77+ this . basePath = toForwardSlashPath ( basePath ) ;
7378 this . registry = registry ;
7479 this . contextRegistry = contextRegistry ;
75- this . scenariosPath = scenariosPath ?. replaceAll ( "\\" , "/" ) ;
80+ this . scenariosPath =
81+ scenariosPath === undefined
82+ ? undefined
83+ : toForwardSlashPath ( scenariosPath ) ;
7684 this . scenarioRegistry = scenarioRegistry ;
7785 this . fileDiscovery = new FileDiscovery ( this . basePath ) ;
7886 }
@@ -98,7 +106,7 @@ export class ModuleLoader extends EventTarget {
98106 )
99107 return ;
100108
101- const pathName = pathNameOriginal . replaceAll ( "\\" , "/" ) ;
109+ const pathName = toForwardSlashPath ( pathNameOriginal ) ;
102110
103111 if ( pathName . includes ( "$.context" ) && eventName === "add" ) {
104112 process . stdout . write (
@@ -114,17 +122,18 @@ export class ModuleLoader extends EventTarget {
114122
115123 const parts = nodePath . parse ( pathName . replace ( this . basePath , "" ) ) ;
116124 const url = unescapePathForWindows (
117- `/${ parts . dir } /${ parts . name } `
118- . replaceAll ( "\\" , "/" )
119- . replaceAll ( / \/ + / gu, "/" ) ,
125+ toForwardSlashPath ( `/${ parts . dir } /${ parts . name } ` ) . replaceAll (
126+ / \/ + / gu,
127+ "/" ,
128+ ) ,
120129 ) ;
121130
122131 if ( eventName === "unlink" ) {
123132 this . registry . remove ( url ) ;
124133 this . dispatchEvent ( new Event ( "remove" ) ) ;
125134 if ( this . isContextFile ( pathName ) ) {
126135 this . contextRegistry . remove (
127- unescapePathForWindows ( parts . dir ) . replaceAll ( "\\" , "/" ) || "/" ,
136+ unescapePathForWindows ( toForwardSlashPath ( parts . dir ) ) || "/" ,
128137 ) ;
129138 }
130139 return ;
@@ -155,7 +164,7 @@ export class ModuleLoader extends EventTarget {
155164
156165 if ( ! [ "add" , "change" , "unlink" ] . includes ( eventName ) ) return ;
157166
158- const pathName = pathNameOriginal . replaceAll ( "\\" , "/" ) ;
167+ const pathName = toForwardSlashPath ( pathNameOriginal ) ;
159168
160169 if ( eventName === "unlink" ) {
161170 const fileKey = this . scenarioFileKey ( pathName ) ;
@@ -215,18 +224,18 @@ export class ModuleLoader extends EventTarget {
215224 }
216225
217226 private scenarioFileKey ( pathName : string ) : string {
218- const normalizedScenariosPath = ( this . scenariosPath ?? "" ) . replaceAll (
219- "\\" ,
220- "/" ,
227+ const normalizedScenariosPath = toForwardSlashPath (
228+ this . scenariosPath ?? "" ,
221229 ) ;
222- const directory = dirname (
230+ const directory = pathDirname (
223231 pathName . slice ( normalizedScenariosPath . length ) ,
224- ) . replaceAll ( "\\" , "/" ) ;
232+ ) ;
225233 const name = nodePath . parse ( basename ( pathName ) ) . name ;
226234 const url = unescapePathForWindows (
227- `/${ nodePath . join ( directory , name ) } `
228- . replaceAll ( "\\" , "/" )
229- . replaceAll ( / \/ + / gu, "/" ) ,
235+ toForwardSlashPath ( `/${ nodePath . join ( directory , name ) } ` ) . replaceAll (
236+ / \/ + / gu,
237+ "/" ,
238+ ) ,
230239 ) ;
231240
232241 return url . slice ( 1 ) ; // strip leading "/"
@@ -258,15 +267,12 @@ export class ModuleLoader extends EventTarget {
258267 private async loadEndpoint ( pathName : string ) {
259268 debug ( "importing module: %s" , pathName ) ;
260269
261- const directory = dirname ( pathName . slice ( this . basePath . length ) ) . replaceAll (
262- "\\" ,
263- "/" ,
264- ) ;
270+ const directory = pathDirname ( pathName . slice ( this . basePath . length ) ) ;
265271
266272 const url = unescapePathForWindows (
267- `/ ${ nodePath . join ( directory , nodePath . parse ( basename ( pathName ) ) . name ) } `
268- . replaceAll ( "\\" , "/" )
269- . replaceAll ( / \/ + / gu, "/" ) ,
273+ toForwardSlashPath (
274+ `/ ${ nodePath . join ( directory , nodePath . parse ( basename ( pathName ) ) . name ) } ` ,
275+ ) . replaceAll ( / \/ + / gu, "/" ) ,
270276 ) ;
271277
272278 debug ( `loading pathName from dependencyGraph: ${ pathName } ` ) ;
@@ -290,9 +296,10 @@ export class ModuleLoader extends EventTarget {
290296 importError instanceof SyntaxError ||
291297 String ( importError ) . startsWith ( "SyntaxError:" ) ;
292298
293- const displayPath = nodePath
294- . relative ( process . cwd ( ) , unescapePathForWindows ( pathName ) )
295- . replaceAll ( "\\" , "/" ) ;
299+ const displayPath = pathRelative (
300+ process . cwd ( ) ,
301+ unescapePathForWindows ( pathName ) ,
302+ ) ;
296303
297304 const message = isSyntaxError
298305 ? `There is a syntax error in the route file: ${ displayPath } `
0 commit comments