Skip to content

Commit

Permalink
Fix root-relative URLs in @imports for legacy importers (#129)
Browse files Browse the repository at this point in the history
Closes #126
  • Loading branch information
nex3 authored Apr 13, 2022
1 parent 711a5b6 commit 1884872
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 4 deletions.
28 changes: 24 additions & 4 deletions lib/src/legacy/importer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import * as util from 'util';
import {resolvePath} from './resolve-path';
import {
fileUrlToPathCrossPlatform,
isErrnoException,
thenOr,
PromiseOr,
SyncBoolean,
Expand Down Expand Up @@ -93,10 +94,29 @@ export class LegacyImporterWrapper<sync extends 'sync' | 'async'>
// sure that all normal loads are preceded by exactly one relative load.
if (this.expectingRelativeLoad) {
if (url.startsWith('file:')) {
const resolved = resolvePath(
fileUrlToPathCrossPlatform(url),
options.fromImport
);
let resolved: string | null = null;

try {
const path = fileUrlToPathCrossPlatform(url);
resolved = resolvePath(path, options.fromImport);
} catch (error: unknown) {
if (
error instanceof TypeError &&
isErrnoException(error) &&
(error.code === 'ERR_INVALID_URL' ||
error.code === 'ERR_INVALID_FILE_URL_PATH')
) {
// It's possible for `url` to represent an invalid path for the
// current platform. For example, `@import "/foo/bar/baz"` will
// resolve to `file:///foo/bar/baz` which is an invalid URL on
// Windows. In that case, we treat it as though the file doesn't
// exist so that the user's custom importer can still handle the
// URL.
} else {
throw error;
}
}

if (resolved !== null) {
this.prev.push({url: resolved, path: true});
return pathToFileURL(resolved);
Expand Down
7 changes: 7 additions & 0 deletions lib/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,13 @@ export function protofySyntax(
}
}

/** Returns whether `error` is a NodeJS-style exception with an error code. */
export function isErrnoException(
error: unknown
): error is NodeJS.ErrnoException {
return error instanceof Error && ('errno' in error || 'code' in error);
}

/**
* Dart-style utility. See
* http://go/dart-api/stable/2.8.4/dart-core/Map/putIfAbsent.html.
Expand Down

0 comments on commit 1884872

Please sign in to comment.