@@ -1242,30 +1242,48 @@ func isConfigObject(value any) bool {
12421242 return ok
12431243}
12441244
1245- // relativeImportSpecifier computes the ESM import specifier for `location`
1246- // relative to `fromDir`. The result always starts with "./" or "../" so it is
1247- // treated as a relative path by the ESM loader rather than as a bare package
1248- // name.
1249- func relativeImportSpecifier (fromDir , location string ) (string , error ) {
1250- relative , err := filepath .Rel (fromDir , location )
1251- if err != nil {
1252- return "" , fmt .Errorf ("@ttsc/lint: resolve relative config import %s: %w" , location , err )
1253- }
1254- relative = filepath .ToSlash (relative )
1255- if strings .HasPrefix (relative , "../" ) || strings .HasPrefix (relative , "./" ) {
1256- return relative , nil
1257- }
1258- return "./" + relative , nil
1259- }
1260-
12611245func fileURL (location string ) string {
1246+ volume := filepath .VolumeName (location )
1247+ if volume != "" {
1248+ volumePath := filepath .ToSlash (volume )
1249+ rest := strings .TrimPrefix (filepath .ToSlash (location [len (volume ):]), "/" )
1250+ if strings .HasPrefix (volumePath , "//?/UNC" ) {
1251+ return uncFileURL (rest )
1252+ }
1253+ if strings .HasPrefix (volumePath , "//?/" ) {
1254+ pathname := "/" + strings .TrimPrefix (volumePath , "//?/" )
1255+ if rest != "" {
1256+ pathname += "/" + rest
1257+ }
1258+ return (& url.URL {Scheme : "file" , Path : pathname }).String ()
1259+ }
1260+ if strings .HasPrefix (volumePath , "//" ) {
1261+ return uncFileURL (strings .TrimPrefix (volumePath , "//" ) + "/" + rest )
1262+ }
1263+ }
12621264 pathname := filepath .ToSlash (location )
1263- if filepath . VolumeName ( location ) != "" && ! strings .HasPrefix (pathname , "/" ) {
1265+ if volume != "" && ! strings .HasPrefix (pathname , "/" ) {
12641266 pathname = "/" + pathname
12651267 }
12661268 return (& url.URL {Scheme : "file" , Path : pathname }).String ()
12671269}
12681270
1271+ func uncFileURL (pathname string ) string {
1272+ server , remainder , ok := strings .Cut (pathname , "/" )
1273+ if ! ok || server == "" {
1274+ return (& url.URL {Scheme : "file" , Path : "/" + strings .TrimPrefix (pathname , "/" )}).String ()
1275+ }
1276+ share , tail , _ := strings .Cut (remainder , "/" )
1277+ if share == "" {
1278+ return (& url.URL {Scheme : "file" , Path : "/" + strings .TrimPrefix (pathname , "/" )}).String ()
1279+ }
1280+ urlPath := "/" + share
1281+ if tail != "" {
1282+ urlPath += "/" + tail
1283+ }
1284+ return (& url.URL {Scheme : "file" , Host : server , Path : urlPath }).String ()
1285+ }
1286+
12691287// typeScriptConfigLoaderSource returns the TypeScript source of the ephemeral
12701288// loader script that ttsx executes to evaluate a TypeScript lint config file.
12711289// `importLiteral` is a JSON-encoded file URL (produced by json.Marshal). It is
0 commit comments