| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 |
- "use strict";
- let isWindows = /^win/.test(process.platform),
- forwardSlashPattern = /\//g,
- protocolPattern = /^(\w{2,}):\/\//i,
- url = module.exports,
- jsonPointerSlash = /~1/g,
- jsonPointerTilde = /~0/g;
- // RegExp patterns to URL-encode special characters in local filesystem paths
- let urlEncodePatterns = [
- /\?/g, "%3F",
- /\#/g, "%23",
- ];
- // RegExp patterns to URL-decode special characters for local filesystem paths
- let urlDecodePatterns = [
- /\%23/g, "#",
- /\%24/g, "$",
- /\%26/g, "&",
- /\%2C/g, ",",
- /\%40/g, "@"
- ];
- exports.parse = require("url").parse;
- exports.resolve = require("url").resolve;
- /**
- * Returns the current working directory (in Node) or the current page URL (in browsers).
- *
- * @returns {string}
- */
- exports.cwd = function cwd () {
- if (process.browser) {
- return location.href;
- }
- let path = process.cwd();
- let lastChar = path.slice(-1);
- if (lastChar === "/" || lastChar === "\\") {
- return path;
- }
- else {
- return path + "/";
- }
- };
- /**
- * Returns the protocol of the given URL, or `undefined` if it has no protocol.
- *
- * @param {string} path
- * @returns {?string}
- */
- exports.getProtocol = function getProtocol (path) {
- let match = protocolPattern.exec(path);
- if (match) {
- return match[1].toLowerCase();
- }
- };
- /**
- * Returns the lowercased file extension of the given URL,
- * or an empty string if it has no extension.
- *
- * @param {string} path
- * @returns {string}
- */
- exports.getExtension = function getExtension (path) {
- let lastDot = path.lastIndexOf(".");
- if (lastDot >= 0) {
- return url.stripQuery(path.substr(lastDot).toLowerCase());
- }
- return "";
- };
- /**
- * Removes the query, if any, from the given path.
- *
- * @param {string} path
- * @returns {string}
- */
- exports.stripQuery = function stripQuery (path) {
- let queryIndex = path.indexOf("?");
- if (queryIndex >= 0) {
- path = path.substr(0, queryIndex);
- }
- return path;
- };
- /**
- * Returns the hash (URL fragment), of the given path.
- * If there is no hash, then the root hash ("#") is returned.
- *
- * @param {string} path
- * @returns {string}
- */
- exports.getHash = function getHash (path) {
- let hashIndex = path.indexOf("#");
- if (hashIndex >= 0) {
- return path.substr(hashIndex);
- }
- return "#";
- };
- /**
- * Removes the hash (URL fragment), if any, from the given path.
- *
- * @param {string} path
- * @returns {string}
- */
- exports.stripHash = function stripHash (path) {
- let hashIndex = path.indexOf("#");
- if (hashIndex >= 0) {
- path = path.substr(0, hashIndex);
- }
- return path;
- };
- /**
- * Determines whether the given path is an HTTP(S) URL.
- *
- * @param {string} path
- * @returns {boolean}
- */
- exports.isHttp = function isHttp (path) {
- let protocol = url.getProtocol(path);
- if (protocol === "http" || protocol === "https") {
- return true;
- }
- else if (protocol === undefined) {
- // There is no protocol. If we're running in a browser, then assume it's HTTP.
- return process.browser;
- }
- else {
- // It's some other protocol, such as "ftp://", "mongodb://", etc.
- return false;
- }
- };
- /**
- * Determines whether the given path is a filesystem path.
- * This includes "file://" URLs.
- *
- * @param {string} path
- * @returns {boolean}
- */
- exports.isFileSystemPath = function isFileSystemPath (path) {
- if (process.browser) {
- // We're running in a browser, so assume that all paths are URLs.
- // This way, even relative paths will be treated as URLs rather than as filesystem paths
- return false;
- }
- let protocol = url.getProtocol(path);
- return protocol === undefined || protocol === "file";
- };
- /**
- * Converts a filesystem path to a properly-encoded URL.
- *
- * This is intended to handle situations where JSON Schema $Ref Parser is called
- * with a filesystem path that contains characters which are not allowed in URLs.
- *
- * @example
- * The following filesystem paths would be converted to the following URLs:
- *
- * <"!@#$%^&*+=?'>.json ==> %3C%22!@%23$%25%5E&*+=%3F\'%3E.json
- * C:\\My Documents\\File (1).json ==> C:/My%20Documents/File%20(1).json
- * file://Project #42/file.json ==> file://Project%20%2342/file.json
- *
- * @param {string} path
- * @returns {string}
- */
- exports.fromFileSystemPath = function fromFileSystemPath (path) {
- // Step 1: On Windows, replace backslashes with forward slashes,
- // rather than encoding them as "%5C"
- if (isWindows) {
- path = path.replace(/\\/g, "/");
- }
- // Step 2: `encodeURI` will take care of MOST characters
- path = encodeURI(path);
- // Step 3: Manually encode characters that are not encoded by `encodeURI`.
- // This includes characters such as "#" and "?", which have special meaning in URLs,
- // but are just normal characters in a filesystem path.
- for (let i = 0; i < urlEncodePatterns.length; i += 2) {
- path = path.replace(urlEncodePatterns[i], urlEncodePatterns[i + 1]);
- }
- return path;
- };
- /**
- * Converts a URL to a local filesystem path.
- *
- * @param {string} path
- * @param {boolean} [keepFileProtocol] - If true, then "file://" will NOT be stripped
- * @returns {string}
- */
- exports.toFileSystemPath = function toFileSystemPath (path, keepFileProtocol) {
- // Step 1: `decodeURI` will decode characters such as Cyrillic characters, spaces, etc.
- path = decodeURI(path);
- // Step 2: Manually decode characters that are not decoded by `decodeURI`.
- // This includes characters such as "#" and "?", which have special meaning in URLs,
- // but are just normal characters in a filesystem path.
- for (let i = 0; i < urlDecodePatterns.length; i += 2) {
- path = path.replace(urlDecodePatterns[i], urlDecodePatterns[i + 1]);
- }
- // Step 3: If it's a "file://" URL, then format it consistently
- // or convert it to a local filesystem path
- let isFileUrl = path.substr(0, 7).toLowerCase() === "file://";
- if (isFileUrl) {
- // Strip-off the protocol, and the initial "/", if there is one
- path = path[7] === "/" ? path.substr(8) : path.substr(7);
- // insert a colon (":") after the drive letter on Windows
- if (isWindows && path[1] === "/") {
- path = path[0] + ":" + path.substr(1);
- }
- if (keepFileProtocol) {
- // Return the consistently-formatted "file://" URL
- path = "file:///" + path;
- }
- else {
- // Convert the "file://" URL to a local filesystem path.
- // On Windows, it will start with something like "C:/".
- // On Posix, it will start with "/"
- isFileUrl = false;
- path = isWindows ? path : "/" + path;
- }
- }
- // Step 4: Normalize Windows paths (unless it's a "file://" URL)
- if (isWindows && !isFileUrl) {
- // Replace forward slashes with backslashes
- path = path.replace(forwardSlashPattern, "\\");
- // Capitalize the drive letter
- if (path.substr(1, 2) === ":\\") {
- path = path[0].toUpperCase() + path.substr(1);
- }
- }
- return path;
- };
- /**
- * Converts a $ref pointer to a valid JSON Path.
- *
- * @param {string} pointer
- * @returns {Array<number | string>}
- */
- exports.safePointerToPath = function safePointerToPath (pointer) {
- if (pointer.length <= 1 || pointer[0] !== "#" || pointer[1] !== "/") {
- return [];
- }
- return pointer
- .slice(2)
- .split("/")
- .map((value) => {
- return decodeURIComponent(value)
- .replace(jsonPointerSlash, "/")
- .replace(jsonPointerTilde, "~");
- });
- };
|