mock-fs-require-fix
Version:
Fork of the tschaub/mock-fs project.
96 lines (84 loc) • 3.9 kB
JavaScript
;
const util = require('util');
const URL = require('url').URL;
const urlBinding = process.binding('url');
const platform = process.platform;
const isWindows = platform === 'win32';
const searchParamsSymbolName = 'query';
const symbols = Reflect.ownKeys(new URL('about:blank'));
const searchParams = symbols.find(symbol => util.inspect(symbol) === `Symbol(${searchParamsSymbolName})`);
const errCodes = {
'ERR_INVALID_FILE_URL_PATH': 'File URL path %s',
'ERR_INVALID_FILE_URL_HOST': 'File URL host %s',
'ERR_INVALID_URL_SCHEME': 'The URL must be of scheme %s',
'ERR_MISSING_ARGS': 'The "%s" argument must be specified'
};
function domainToUnicode(domain) {
if (arguments.length < 1)
throw Object.assign(new TypeError(util.format(errCodes.ERR_MISSING_ARGS,
'domain')), {name: 'TypeError [ERR_MISSING_ARGS]', code: 'ERR_MISSING_ARGS'});
// toUSVString is not needed.
return urlBinding.domainToUnicode(`${domain}`);
}
function getPathFromURLWin32(url) {
var hostname = url.hostname;
var pathname = url.pathname;
for (var n = 0; n < pathname.length; n++) {
if (pathname[n] === '%') {
var third = pathname.codePointAt(n + 2) | 0x20;
if ((pathname[n + 1] === '2' && third === 102) || // 2f 2F /
(pathname[n + 1] === '5' && third === 99)) { // 5c 5C \
return Object.assign(new TypeError(util.format(errCodes.ERR_INVALID_FILE_URL_PATH,
'must not include encoded \\ or / characters')), {name: 'TypeError [ERR_INVALID_FILE_URL_PATH]', code: 'ERR_INVALID_FILE_URL_PATH'});
}
}
}
pathname = decodeURIComponent(pathname);
if (hostname !== '') {
// If hostname is set, then we have a UNC path
// Pass the hostname through domainToUnicode just in case
// it is an IDN using punycode encoding. We do not need to worry
// about percent encoding because the URL parser will have
// already taken care of that for us. Note that this only
// causes IDNs with an appropriate `xn--` prefix to be decoded.
return `//${domainToUnicode(hostname)}${pathname}`;
} else {
// Otherwise, it's a local path that requires a drive letter
var letter = pathname.codePointAt(1) | 0x20;
var sep = pathname[2];
if (letter < 97 || letter > 122 || // a..z A..Z
(sep !== ':')) {
return Object.assign(new TypeError(util.format(errCodes.ERR_INVALID_FILE_URL_PATH,
'must be absolute')), {name: 'TypeError [ERR_INVALID_FILE_URL_PATH]', code: 'ERR_INVALID_FILE_URL_PATH'});
}
return pathname.slice(1);
}
}
function getPathFromURLPosix(url) {
if (url.hostname !== '') {
return Object.assign(new TypeError(util.format(errCodes.ERR_INVALID_FILE_URL_HOST,
`must be "localhost" or empty on ${platform}`)), {name: 'TypeError [ERR_INVALID_FILE_URL_HOST]', code: 'ERR_INVALID_FILE_URL_HOST'});
}
var pathname = url.pathname;
for (var n = 0; n < pathname.length; n++) {
if (pathname[n] === '%') {
var third = pathname.codePointAt(n + 2) | 0x20;
if (pathname[n + 1] === '2' && third === 102) {
return Object.assign(new TypeError(util.format(errCodes.ERR_INVALID_FILE_URL_PATH,
'must not include encoded / characters')), {name: 'TypeError [ERR_INVALID_FILE_URL_PATH]', code: 'ERR_INVALID_FILE_URL_PATH'});
}
}
}
return decodeURIComponent(pathname);
}
function getPathFromURL(path) {
if (path == null || !path[searchParams] ||
!path[searchParams][searchParams]) {
return path;
}
if (path.protocol !== 'file:')
return Object.assign(new TypeError(util.format(errCodes.ERR_INVALID_URL_SCHEME,
`file`)), {name: 'TypeError [ERR_INVALID_URL_SCHEME]', code: 'ERR_INVALID_URL_SCHEME'});
return isWindows ? getPathFromURLWin32(path) : getPathFromURLPosix(path);
}
exports.getPathFromURL = getPathFromURL;