Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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