aboutsummaryrefslogtreecommitdiff
path: root/node_modules/enhanced-resolve/lib/util
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/enhanced-resolve/lib/util')
-rw-r--r--node_modules/enhanced-resolve/lib/util/entrypoints.js667
-rw-r--r--node_modules/enhanced-resolve/lib/util/identifier.js26
-rw-r--r--node_modules/enhanced-resolve/lib/util/path.js221
-rw-r--r--node_modules/enhanced-resolve/lib/util/process-browser.js16
4 files changed, 930 insertions, 0 deletions
diff --git a/node_modules/enhanced-resolve/lib/util/entrypoints.js b/node_modules/enhanced-resolve/lib/util/entrypoints.js
new file mode 100644
index 0000000..b925d62
--- /dev/null
+++ b/node_modules/enhanced-resolve/lib/util/entrypoints.js
@@ -0,0 +1,667 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+/** @typedef {string|(string|ConditionalMapping)[]} DirectMapping */
+/** @typedef {{[k: string]: MappingValue}} ConditionalMapping */
+/** @typedef {ConditionalMapping|DirectMapping|null} MappingValue */
+/** @typedef {Record<string, MappingValue>|ConditionalMapping|DirectMapping} ExportsField */
+/** @typedef {Record<string, MappingValue>} ImportsField */
+
+/**
+ * @typedef {Object} PathTreeNode
+ * @property {Map<string, PathTreeNode>|null} children
+ * @property {MappingValue} folder
+ * @property {Map<string, MappingValue>|null} wildcards
+ * @property {Map<string, MappingValue>} files
+ */
+
+/**
+ * Processing exports/imports field
+ * @callback FieldProcessor
+ * @param {string} request request
+ * @param {Set<string>} conditionNames condition names
+ * @returns {string[]} resolved paths
+ */
+
+/*
+Example exports field:
+{
+ ".": "./main.js",
+ "./feature": {
+ "browser": "./feature-browser.js",
+ "default": "./feature.js"
+ }
+}
+Terminology:
+
+Enhanced-resolve name keys ("." and "./feature") as exports field keys.
+
+If value is string or string[], mapping is called as a direct mapping
+and value called as a direct export.
+
+If value is key-value object, mapping is called as a conditional mapping
+and value called as a conditional export.
+
+Key in conditional mapping is called condition name.
+
+Conditional mapping nested in another conditional mapping is called nested mapping.
+
+----------
+
+Example imports field:
+{
+ "#a": "./main.js",
+ "#moment": {
+ "browser": "./moment/index.js",
+ "default": "moment"
+ },
+ "#moment/": {
+ "browser": "./moment/",
+ "default": "moment/"
+ }
+}
+Terminology:
+
+Enhanced-resolve name keys ("#a" and "#moment/", "#moment") as imports field keys.
+
+If value is string or string[], mapping is called as a direct mapping
+and value called as a direct export.
+
+If value is key-value object, mapping is called as a conditional mapping
+and value called as a conditional export.
+
+Key in conditional mapping is called condition name.
+
+Conditional mapping nested in another conditional mapping is called nested mapping.
+
+*/
+
+const slashCode = "/".charCodeAt(0);
+const dotCode = ".".charCodeAt(0);
+const hashCode = "#".charCodeAt(0);
+
+/**
+ * @param {ExportsField} exportsField the exports field
+ * @returns {FieldProcessor} process callback
+ */
+module.exports.processExportsField = function processExportsField(
+ exportsField
+) {
+ return createFieldProcessor(
+ buildExportsFieldPathTree(exportsField),
+ assertExportsFieldRequest,
+ assertExportTarget
+ );
+};
+
+/**
+ * @param {ImportsField} importsField the exports field
+ * @returns {FieldProcessor} process callback
+ */
+module.exports.processImportsField = function processImportsField(
+ importsField
+) {
+ return createFieldProcessor(
+ buildImportsFieldPathTree(importsField),
+ assertImportsFieldRequest,
+ assertImportTarget
+ );
+};
+
+/**
+ * @param {PathTreeNode} treeRoot root
+ * @param {(s: string) => string} assertRequest assertRequest
+ * @param {(s: string, f: boolean) => void} assertTarget assertTarget
+ * @returns {FieldProcessor} field processor
+ */
+function createFieldProcessor(treeRoot, assertRequest, assertTarget) {
+ return function fieldProcessor(request, conditionNames) {
+ request = assertRequest(request);
+
+ const match = findMatch(request, treeRoot);
+
+ if (match === null) return [];
+
+ const [mapping, remainRequestIndex] = match;
+
+ /** @type {DirectMapping|null} */
+ let direct = null;
+
+ if (isConditionalMapping(mapping)) {
+ direct = conditionalMapping(
+ /** @type {ConditionalMapping} */ (mapping),
+ conditionNames
+ );
+
+ // matching not found
+ if (direct === null) return [];
+ } else {
+ direct = /** @type {DirectMapping} */ (mapping);
+ }
+
+ const remainingRequest =
+ remainRequestIndex === request.length + 1
+ ? undefined
+ : remainRequestIndex < 0
+ ? request.slice(-remainRequestIndex - 1)
+ : request.slice(remainRequestIndex);
+
+ return directMapping(
+ remainingRequest,
+ remainRequestIndex < 0,
+ direct,
+ conditionNames,
+ assertTarget
+ );
+ };
+}
+
+/**
+ * @param {string} request request
+ * @returns {string} updated request
+ */
+function assertExportsFieldRequest(request) {
+ if (request.charCodeAt(0) !== dotCode) {
+ throw new Error('Request should be relative path and start with "."');
+ }
+ if (request.length === 1) return "";
+ if (request.charCodeAt(1) !== slashCode) {
+ throw new Error('Request should be relative path and start with "./"');
+ }
+ if (request.charCodeAt(request.length - 1) === slashCode) {
+ throw new Error("Only requesting file allowed");
+ }
+
+ return request.slice(2);
+}
+
+/**
+ * @param {string} request request
+ * @returns {string} updated request
+ */
+function assertImportsFieldRequest(request) {
+ if (request.charCodeAt(0) !== hashCode) {
+ throw new Error('Request should start with "#"');
+ }
+ if (request.length === 1) {
+ throw new Error("Request should have at least 2 characters");
+ }
+ if (request.charCodeAt(1) === slashCode) {
+ throw new Error('Request should not start with "#/"');
+ }
+ if (request.charCodeAt(request.length - 1) === slashCode) {
+ throw new Error("Only requesting file allowed");
+ }
+
+ return request.slice(1);
+}
+
+/**
+ * @param {string} exp export target
+ * @param {boolean} expectFolder is folder expected
+ */
+function assertExportTarget(exp, expectFolder) {
+ if (
+ exp.charCodeAt(0) === slashCode ||
+ (exp.charCodeAt(0) === dotCode && exp.charCodeAt(1) !== slashCode)
+ ) {
+ throw new Error(
+ `Export should be relative path and start with "./", got ${JSON.stringify(
+ exp
+ )}.`
+ );
+ }
+
+ const isFolder = exp.charCodeAt(exp.length - 1) === slashCode;
+
+ if (isFolder !== expectFolder) {
+ throw new Error(
+ expectFolder
+ ? `Expecting folder to folder mapping. ${JSON.stringify(
+ exp
+ )} should end with "/"`
+ : `Expecting file to file mapping. ${JSON.stringify(
+ exp
+ )} should not end with "/"`
+ );
+ }
+}
+
+/**
+ * @param {string} imp import target
+ * @param {boolean} expectFolder is folder expected
+ */
+function assertImportTarget(imp, expectFolder) {
+ const isFolder = imp.charCodeAt(imp.length - 1) === slashCode;
+
+ if (isFolder !== expectFolder) {
+ throw new Error(
+ expectFolder
+ ? `Expecting folder to folder mapping. ${JSON.stringify(
+ imp
+ )} should end with "/"`
+ : `Expecting file to file mapping. ${JSON.stringify(
+ imp
+ )} should not end with "/"`
+ );
+ }
+}
+
+/**
+ * Trying to match request to field
+ * @param {string} request request
+ * @param {PathTreeNode} treeRoot path tree root
+ * @returns {[MappingValue, number]|null} match or null, number is negative and one less when it's a folder mapping, number is request.length + 1 for direct mappings
+ */
+function findMatch(request, treeRoot) {
+ if (request.length === 0) {
+ const value = treeRoot.files.get("");
+
+ return value ? [value, 1] : null;
+ }
+
+ if (
+ treeRoot.children === null &&
+ treeRoot.folder === null &&
+ treeRoot.wildcards === null
+ ) {
+ const value = treeRoot.files.get(request);
+
+ return value ? [value, request.length + 1] : null;
+ }
+
+ let node = treeRoot;
+ let lastNonSlashIndex = 0;
+ let slashIndex = request.indexOf("/", 0);
+
+ /** @type {[MappingValue, number]|null} */
+ let lastFolderMatch = null;
+
+ const applyFolderMapping = () => {
+ const folderMapping = node.folder;
+ if (folderMapping) {
+ if (lastFolderMatch) {
+ lastFolderMatch[0] = folderMapping;
+ lastFolderMatch[1] = -lastNonSlashIndex - 1;
+ } else {
+ lastFolderMatch = [folderMapping, -lastNonSlashIndex - 1];
+ }
+ }
+ };
+
+ const applyWildcardMappings = (wildcardMappings, remainingRequest) => {
+ if (wildcardMappings) {
+ for (const [key, target] of wildcardMappings) {
+ if (remainingRequest.startsWith(key)) {
+ if (!lastFolderMatch) {
+ lastFolderMatch = [target, lastNonSlashIndex + key.length];
+ } else if (lastFolderMatch[1] < lastNonSlashIndex + key.length) {
+ lastFolderMatch[0] = target;
+ lastFolderMatch[1] = lastNonSlashIndex + key.length;
+ }
+ }
+ }
+ }
+ };
+
+ while (slashIndex !== -1) {
+ applyFolderMapping();
+
+ const wildcardMappings = node.wildcards;
+
+ if (!wildcardMappings && node.children === null) return lastFolderMatch;
+
+ const folder = request.slice(lastNonSlashIndex, slashIndex);
+
+ applyWildcardMappings(wildcardMappings, folder);
+
+ if (node.children === null) return lastFolderMatch;
+
+ const newNode = node.children.get(folder);
+
+ if (!newNode) {
+ return lastFolderMatch;
+ }
+
+ node = newNode;
+ lastNonSlashIndex = slashIndex + 1;
+ slashIndex = request.indexOf("/", lastNonSlashIndex);
+ }
+
+ const remainingRequest =
+ lastNonSlashIndex > 0 ? request.slice(lastNonSlashIndex) : request;
+
+ const value = node.files.get(remainingRequest);
+
+ if (value) {
+ return [value, request.length + 1];
+ }
+
+ applyFolderMapping();
+
+ applyWildcardMappings(node.wildcards, remainingRequest);
+
+ return lastFolderMatch;
+}
+
+/**
+ * @param {ConditionalMapping|DirectMapping|null} mapping mapping
+ * @returns {boolean} is conditional mapping
+ */
+function isConditionalMapping(mapping) {
+ return (
+ mapping !== null && typeof mapping === "object" && !Array.isArray(mapping)
+ );
+}
+
+/**
+ * @param {string|undefined} remainingRequest remaining request when folder mapping, undefined for file mappings
+ * @param {boolean} subpathMapping true, for subpath mappings
+ * @param {DirectMapping|null} mappingTarget direct export
+ * @param {Set<string>} conditionNames condition names
+ * @param {(d: string, f: boolean) => void} assert asserting direct value
+ * @returns {string[]} mapping result
+ */
+function directMapping(
+ remainingRequest,
+ subpathMapping,
+ mappingTarget,
+ conditionNames,
+ assert
+) {
+ if (mappingTarget === null) return [];
+
+ if (typeof mappingTarget === "string") {
+ return [
+ targetMapping(remainingRequest, subpathMapping, mappingTarget, assert)
+ ];
+ }
+
+ const targets = [];
+
+ for (const exp of mappingTarget) {
+ if (typeof exp === "string") {
+ targets.push(
+ targetMapping(remainingRequest, subpathMapping, exp, assert)
+ );
+ continue;
+ }
+
+ const mapping = conditionalMapping(exp, conditionNames);
+ if (!mapping) continue;
+ const innerExports = directMapping(
+ remainingRequest,
+ subpathMapping,
+ mapping,
+ conditionNames,
+ assert
+ );
+ for (const innerExport of innerExports) {
+ targets.push(innerExport);
+ }
+ }
+
+ return targets;
+}
+
+/**
+ * @param {string|undefined} remainingRequest remaining request when folder mapping, undefined for file mappings
+ * @param {boolean} subpathMapping true, for subpath mappings
+ * @param {string} mappingTarget direct export
+ * @param {(d: string, f: boolean) => void} assert asserting direct value
+ * @returns {string} mapping result
+ */
+function targetMapping(
+ remainingRequest,
+ subpathMapping,
+ mappingTarget,
+ assert
+) {
+ if (remainingRequest === undefined) {
+ assert(mappingTarget, false);
+ return mappingTarget;
+ }
+ if (subpathMapping) {
+ assert(mappingTarget, true);
+ return mappingTarget + remainingRequest;
+ }
+ assert(mappingTarget, false);
+ return mappingTarget.replace(/\*/g, remainingRequest.replace(/\$/g, "$$"));
+}
+
+/**
+ * @param {ConditionalMapping} conditionalMapping_ conditional mapping
+ * @param {Set<string>} conditionNames condition names
+ * @returns {DirectMapping|null} direct mapping if found
+ */
+function conditionalMapping(conditionalMapping_, conditionNames) {
+ /** @type {[ConditionalMapping, string[], number][]} */
+ let lookup = [[conditionalMapping_, Object.keys(conditionalMapping_), 0]];
+
+ loop: while (lookup.length > 0) {
+ const [mapping, conditions, j] = lookup[lookup.length - 1];
+ const last = conditions.length - 1;
+
+ for (let i = j; i < conditions.length; i++) {
+ const condition = conditions[i];
+
+ // assert default. Could be last only
+ if (i !== last) {
+ if (condition === "default") {
+ throw new Error("Default condition should be last one");
+ }
+ } else if (condition === "default") {
+ const innerMapping = mapping[condition];
+ // is nested
+ if (isConditionalMapping(innerMapping)) {
+ const conditionalMapping = /** @type {ConditionalMapping} */ (innerMapping);
+ lookup[lookup.length - 1][2] = i + 1;
+ lookup.push([conditionalMapping, Object.keys(conditionalMapping), 0]);
+ continue loop;
+ }
+
+ return /** @type {DirectMapping} */ (innerMapping);
+ }
+
+ if (conditionNames.has(condition)) {
+ const innerMapping = mapping[condition];
+ // is nested
+ if (isConditionalMapping(innerMapping)) {
+ const conditionalMapping = /** @type {ConditionalMapping} */ (innerMapping);
+ lookup[lookup.length - 1][2] = i + 1;
+ lookup.push([conditionalMapping, Object.keys(conditionalMapping), 0]);
+ continue loop;
+ }
+
+ return /** @type {DirectMapping} */ (innerMapping);
+ }
+ }
+
+ lookup.pop();
+ }
+
+ return null;
+}
+
+/**
+ * Internal helper to create path tree node
+ * to ensure that each node gets the same hidden class
+ * @returns {PathTreeNode} node
+ */
+function createNode() {
+ return {
+ children: null,
+ folder: null,
+ wildcards: null,
+ files: new Map()
+ };
+}
+
+/**
+ * Internal helper for building path tree
+ * @param {PathTreeNode} root root
+ * @param {string} path path
+ * @param {MappingValue} target target
+ */
+function walkPath(root, path, target) {
+ if (path.length === 0) {
+ root.folder = target;
+ return;
+ }
+
+ let node = root;
+ // Typical path tree can looks like
+ // root
+ // - files: ["a.js", "b.js"]
+ // - children:
+ // node1:
+ // - files: ["a.js", "b.js"]
+ let lastNonSlashIndex = 0;
+ let slashIndex = path.indexOf("/", 0);
+
+ while (slashIndex !== -1) {
+ const folder = path.slice(lastNonSlashIndex, slashIndex);
+ let newNode;
+
+ if (node.children === null) {
+ newNode = createNode();
+ node.children = new Map();
+ node.children.set(folder, newNode);
+ } else {
+ newNode = node.children.get(folder);
+
+ if (!newNode) {
+ newNode = createNode();
+ node.children.set(folder, newNode);
+ }
+ }
+
+ node = newNode;
+ lastNonSlashIndex = slashIndex + 1;
+ slashIndex = path.indexOf("/", lastNonSlashIndex);
+ }
+
+ if (lastNonSlashIndex >= path.length) {
+ node.folder = target;
+ } else {
+ const file = lastNonSlashIndex > 0 ? path.slice(lastNonSlashIndex) : path;
+ if (file.endsWith("*")) {
+ if (node.wildcards === null) node.wildcards = new Map();
+ node.wildcards.set(file.slice(0, -1), target);
+ } else {
+ node.files.set(file, target);
+ }
+ }
+}
+
+/**
+ * @param {ExportsField} field exports field
+ * @returns {PathTreeNode} tree root
+ */
+function buildExportsFieldPathTree(field) {
+ const root = createNode();
+
+ // handle syntax sugar, if exports field is direct mapping for "."
+ if (typeof field === "string") {
+ root.files.set("", field);
+
+ return root;
+ } else if (Array.isArray(field)) {
+ root.files.set("", field.slice());
+
+ return root;
+ }
+
+ const keys = Object.keys(field);
+
+ for (let i = 0; i < keys.length; i++) {
+ const key = keys[i];
+
+ if (key.charCodeAt(0) !== dotCode) {
+ // handle syntax sugar, if exports field is conditional mapping for "."
+ if (i === 0) {
+ while (i < keys.length) {
+ const charCode = keys[i].charCodeAt(0);
+ if (charCode === dotCode || charCode === slashCode) {
+ throw new Error(
+ `Exports field key should be relative path and start with "." (key: ${JSON.stringify(
+ key
+ )})`
+ );
+ }
+ i++;
+ }
+
+ root.files.set("", field);
+ return root;
+ }
+
+ throw new Error(
+ `Exports field key should be relative path and start with "." (key: ${JSON.stringify(
+ key
+ )})`
+ );
+ }
+
+ if (key.length === 1) {
+ root.files.set("", field[key]);
+ continue;
+ }
+
+ if (key.charCodeAt(1) !== slashCode) {
+ throw new Error(
+ `Exports field key should be relative path and start with "./" (key: ${JSON.stringify(
+ key
+ )})`
+ );
+ }
+
+ walkPath(root, key.slice(2), field[key]);
+ }
+
+ return root;
+}
+
+/**
+ * @param {ImportsField} field imports field
+ * @returns {PathTreeNode} root
+ */
+function buildImportsFieldPathTree(field) {
+ const root = createNode();
+
+ const keys = Object.keys(field);
+
+ for (let i = 0; i < keys.length; i++) {
+ const key = keys[i];
+
+ if (key.charCodeAt(0) !== hashCode) {
+ throw new Error(
+ `Imports field key should start with "#" (key: ${JSON.stringify(key)})`
+ );
+ }
+
+ if (key.length === 1) {
+ throw new Error(
+ `Imports field key should have at least 2 characters (key: ${JSON.stringify(
+ key
+ )})`
+ );
+ }
+
+ if (key.charCodeAt(1) === slashCode) {
+ throw new Error(
+ `Imports field key should not start with "#/" (key: ${JSON.stringify(
+ key
+ )})`
+ );
+ }
+
+ walkPath(root, key.slice(1), field[key]);
+ }
+
+ return root;
+}
diff --git a/node_modules/enhanced-resolve/lib/util/identifier.js b/node_modules/enhanced-resolve/lib/util/identifier.js
new file mode 100644
index 0000000..0c29ae4
--- /dev/null
+++ b/node_modules/enhanced-resolve/lib/util/identifier.js
@@ -0,0 +1,26 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Ivan Kopeykin @vankop
+*/
+
+"use strict";
+
+const PATH_QUERY_FRAGMENT_REGEXP = /^(#?(?:\0.|[^?#\0])*)(\?(?:\0.|[^#\0])*)?(#.*)?$/;
+
+/**
+ * @param {string} identifier identifier
+ * @returns {[string, string, string]|null} parsed identifier
+ */
+function parseIdentifier(identifier) {
+ const match = PATH_QUERY_FRAGMENT_REGEXP.exec(identifier);
+
+ if (!match) return null;
+
+ return [
+ match[1].replace(/\0(.)/g, "$1"),
+ match[2] ? match[2].replace(/\0(.)/g, "$1") : "",
+ match[3] || ""
+ ];
+}
+
+module.exports.parseIdentifier = parseIdentifier;
diff --git a/node_modules/enhanced-resolve/lib/util/path.js b/node_modules/enhanced-resolve/lib/util/path.js
new file mode 100644
index 0000000..b84c146
--- /dev/null
+++ b/node_modules/enhanced-resolve/lib/util/path.js
@@ -0,0 +1,221 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const path = require("path");
+
+const CHAR_HASH = "#".charCodeAt(0);
+const CHAR_SLASH = "/".charCodeAt(0);
+const CHAR_BACKSLASH = "\\".charCodeAt(0);
+const CHAR_A = "A".charCodeAt(0);
+const CHAR_Z = "Z".charCodeAt(0);
+const CHAR_LOWER_A = "a".charCodeAt(0);
+const CHAR_LOWER_Z = "z".charCodeAt(0);
+const CHAR_DOT = ".".charCodeAt(0);
+const CHAR_COLON = ":".charCodeAt(0);
+
+const posixNormalize = path.posix.normalize;
+const winNormalize = path.win32.normalize;
+
+/**
+ * @enum {number}
+ */
+const PathType = Object.freeze({
+ Empty: 0,
+ Normal: 1,
+ Relative: 2,
+ AbsoluteWin: 3,
+ AbsolutePosix: 4,
+ Internal: 5
+});
+exports.PathType = PathType;
+
+/**
+ * @param {string} p a path
+ * @returns {PathType} type of path
+ */
+const getType = p => {
+ switch (p.length) {
+ case 0:
+ return PathType.Empty;
+ case 1: {
+ const c0 = p.charCodeAt(0);
+ switch (c0) {
+ case CHAR_DOT:
+ return PathType.Relative;
+ case CHAR_SLASH:
+ return PathType.AbsolutePosix;
+ case CHAR_HASH:
+ return PathType.Internal;
+ }
+ return PathType.Normal;
+ }
+ case 2: {
+ const c0 = p.charCodeAt(0);
+ switch (c0) {
+ case CHAR_DOT: {
+ const c1 = p.charCodeAt(1);
+ switch (c1) {
+ case CHAR_DOT:
+ case CHAR_SLASH:
+ return PathType.Relative;
+ }
+ return PathType.Normal;
+ }
+ case CHAR_SLASH:
+ return PathType.AbsolutePosix;
+ case CHAR_HASH:
+ return PathType.Internal;
+ }
+ const c1 = p.charCodeAt(1);
+ if (c1 === CHAR_COLON) {
+ if (
+ (c0 >= CHAR_A && c0 <= CHAR_Z) ||
+ (c0 >= CHAR_LOWER_A && c0 <= CHAR_LOWER_Z)
+ ) {
+ return PathType.AbsoluteWin;
+ }
+ }
+ return PathType.Normal;
+ }
+ }
+ const c0 = p.charCodeAt(0);
+ switch (c0) {
+ case CHAR_DOT: {
+ const c1 = p.charCodeAt(1);
+ switch (c1) {
+ case CHAR_SLASH:
+ return PathType.Relative;
+ case CHAR_DOT: {
+ const c2 = p.charCodeAt(2);
+ if (c2 === CHAR_SLASH) return PathType.Relative;
+ return PathType.Normal;
+ }
+ }
+ return PathType.Normal;
+ }
+ case CHAR_SLASH:
+ return PathType.AbsolutePosix;
+ case CHAR_HASH:
+ return PathType.Internal;
+ }
+ const c1 = p.charCodeAt(1);
+ if (c1 === CHAR_COLON) {
+ const c2 = p.charCodeAt(2);
+ if (
+ (c2 === CHAR_BACKSLASH || c2 === CHAR_SLASH) &&
+ ((c0 >= CHAR_A && c0 <= CHAR_Z) ||
+ (c0 >= CHAR_LOWER_A && c0 <= CHAR_LOWER_Z))
+ ) {
+ return PathType.AbsoluteWin;
+ }
+ }
+ return PathType.Normal;
+};
+exports.getType = getType;
+
+/**
+ * @param {string} p a path
+ * @returns {string} the normalized path
+ */
+const normalize = p => {
+ switch (getType(p)) {
+ case PathType.Empty:
+ return p;
+ case PathType.AbsoluteWin:
+ return winNormalize(p);
+ case PathType.Relative: {
+ const r = posixNormalize(p);
+ return getType(r) === PathType.Relative ? r : `./${r}`;
+ }
+ }
+ return posixNormalize(p);
+};
+exports.normalize = normalize;
+
+/**
+ * @param {string} rootPath the root path
+ * @param {string | undefined} request the request path
+ * @returns {string} the joined path
+ */
+const join = (rootPath, request) => {
+ if (!request) return normalize(rootPath);
+ const requestType = getType(request);
+ switch (requestType) {
+ case PathType.AbsolutePosix:
+ return posixNormalize(request);
+ case PathType.AbsoluteWin:
+ return winNormalize(request);
+ }
+ switch (getType(rootPath)) {
+ case PathType.Normal:
+ case PathType.Relative:
+ case PathType.AbsolutePosix:
+ return posixNormalize(`${rootPath}/${request}`);
+ case PathType.AbsoluteWin:
+ return winNormalize(`${rootPath}\\${request}`);
+ }
+ switch (requestType) {
+ case PathType.Empty:
+ return rootPath;
+ case PathType.Relative: {
+ const r = posixNormalize(rootPath);
+ return getType(r) === PathType.Relative ? r : `./${r}`;
+ }
+ }
+ return posixNormalize(rootPath);
+};
+exports.join = join;
+
+const joinCache = new Map();
+
+/**
+ * @param {string} rootPath the root path
+ * @param {string | undefined} request the request path
+ * @returns {string} the joined path
+ */
+const cachedJoin = (rootPath, request) => {
+ let cacheEntry;
+ let cache = joinCache.get(rootPath);
+ if (cache === undefined) {
+ joinCache.set(rootPath, (cache = new Map()));
+ } else {
+ cacheEntry = cache.get(request);
+ if (cacheEntry !== undefined) return cacheEntry;
+ }
+ cacheEntry = join(rootPath, request);
+ cache.set(request, cacheEntry);
+ return cacheEntry;
+};
+exports.cachedJoin = cachedJoin;
+
+const checkExportsFieldTarget = relativePath => {
+ let lastNonSlashIndex = 2;
+ let slashIndex = relativePath.indexOf("/", 2);
+ let cd = 0;
+
+ while (slashIndex !== -1) {
+ const folder = relativePath.slice(lastNonSlashIndex, slashIndex);
+
+ switch (folder) {
+ case "..": {
+ cd--;
+ if (cd < 0)
+ return new Error(
+ `Trying to access out of package scope. Requesting ${relativePath}`
+ );
+ break;
+ }
+ default:
+ cd++;
+ break;
+ }
+
+ lastNonSlashIndex = slashIndex + 1;
+ slashIndex = relativePath.indexOf("/", lastNonSlashIndex);
+ }
+};
+exports.checkExportsFieldTarget = checkExportsFieldTarget;
diff --git a/node_modules/enhanced-resolve/lib/util/process-browser.js b/node_modules/enhanced-resolve/lib/util/process-browser.js
new file mode 100644
index 0000000..277f729
--- /dev/null
+++ b/node_modules/enhanced-resolve/lib/util/process-browser.js
@@ -0,0 +1,16 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+module.exports = {
+ versions: {},
+ nextTick(fn) {
+ const args = Array.prototype.slice.call(arguments, 1);
+ Promise.resolve().then(function () {
+ fn.apply(null, args);
+ });
+ }
+};