Buckets:
tahamajs/Other_Lessons / AP /TA_1 /AP-ECE-UT.github.io /node_modules /webpack /lib /ModuleFilenameHelpers.js
| /* | |
| MIT License http://www.opensource.org/licenses/mit-license.php | |
| Author Tobias Koppers @sokra | |
| */ | |
| ; | |
| const NormalModule = require("./NormalModule"); | |
| const createHash = require("./util/createHash"); | |
| const memoize = require("./util/memoize"); | |
| /** @typedef {import("./ChunkGraph")} ChunkGraph */ | |
| /** @typedef {import("./Module")} Module */ | |
| /** @typedef {import("./RequestShortener")} RequestShortener */ | |
| /** @typedef {typeof import("./util/Hash")} Hash */ | |
| /** @typedef {string | RegExp | (string | RegExp)[]} Matcher */ | |
| /** @typedef {{test?: Matcher, include?: Matcher, exclude?: Matcher }} MatchObject */ | |
| const ModuleFilenameHelpers = module.exports; | |
| // TODO webpack 6: consider removing these | |
| ModuleFilenameHelpers.ALL_LOADERS_RESOURCE = "[all-loaders][resource]"; | |
| ModuleFilenameHelpers.REGEXP_ALL_LOADERS_RESOURCE = | |
| /\[all-?loaders\]\[resource\]/gi; | |
| ModuleFilenameHelpers.LOADERS_RESOURCE = "[loaders][resource]"; | |
| ModuleFilenameHelpers.REGEXP_LOADERS_RESOURCE = /\[loaders\]\[resource\]/gi; | |
| ModuleFilenameHelpers.RESOURCE = "[resource]"; | |
| ModuleFilenameHelpers.REGEXP_RESOURCE = /\[resource\]/gi; | |
| ModuleFilenameHelpers.ABSOLUTE_RESOURCE_PATH = "[absolute-resource-path]"; | |
| // cSpell:words olute | |
| ModuleFilenameHelpers.REGEXP_ABSOLUTE_RESOURCE_PATH = | |
| /\[abs(olute)?-?resource-?path\]/gi; | |
| ModuleFilenameHelpers.RESOURCE_PATH = "[resource-path]"; | |
| ModuleFilenameHelpers.REGEXP_RESOURCE_PATH = /\[resource-?path\]/gi; | |
| ModuleFilenameHelpers.ALL_LOADERS = "[all-loaders]"; | |
| ModuleFilenameHelpers.REGEXP_ALL_LOADERS = /\[all-?loaders\]/gi; | |
| ModuleFilenameHelpers.LOADERS = "[loaders]"; | |
| ModuleFilenameHelpers.REGEXP_LOADERS = /\[loaders\]/gi; | |
| ModuleFilenameHelpers.QUERY = "[query]"; | |
| ModuleFilenameHelpers.REGEXP_QUERY = /\[query\]/gi; | |
| ModuleFilenameHelpers.ID = "[id]"; | |
| ModuleFilenameHelpers.REGEXP_ID = /\[id\]/gi; | |
| ModuleFilenameHelpers.HASH = "[hash]"; | |
| ModuleFilenameHelpers.REGEXP_HASH = /\[hash\]/gi; | |
| ModuleFilenameHelpers.NAMESPACE = "[namespace]"; | |
| ModuleFilenameHelpers.REGEXP_NAMESPACE = /\[namespace\]/gi; | |
| /** @typedef {() => string} ReturnStringCallback */ | |
| /** | |
| * Returns a function that returns the part of the string after the token | |
| * @param {ReturnStringCallback} strFn the function to get the string | |
| * @param {string} token the token to search for | |
| * @returns {ReturnStringCallback} a function that returns the part of the string after the token | |
| */ | |
| const getAfter = (strFn, token) => () => { | |
| const str = strFn(); | |
| const idx = str.indexOf(token); | |
| return idx < 0 ? "" : str.slice(idx); | |
| }; | |
| /** | |
| * Returns a function that returns the part of the string before the token | |
| * @param {ReturnStringCallback} strFn the function to get the string | |
| * @param {string} token the token to search for | |
| * @returns {ReturnStringCallback} a function that returns the part of the string before the token | |
| */ | |
| const getBefore = (strFn, token) => () => { | |
| const str = strFn(); | |
| const idx = str.lastIndexOf(token); | |
| return idx < 0 ? "" : str.slice(0, idx); | |
| }; | |
| /** | |
| * Returns a function that returns a hash of the string | |
| * @param {ReturnStringCallback} strFn the function to get the string | |
| * @param {string | Hash=} hashFunction the hash function to use | |
| * @returns {ReturnStringCallback} a function that returns the hash of the string | |
| */ | |
| const getHash = | |
| (strFn, hashFunction = "md4") => | |
| () => { | |
| const hash = createHash(hashFunction); | |
| hash.update(strFn()); | |
| const digest = /** @type {string} */ (hash.digest("hex")); | |
| return digest.slice(0, 4); | |
| }; | |
| /** | |
| * Returns a function that returns the string with the token replaced with the replacement | |
| * @param {string|RegExp} test A regular expression string or Regular Expression object | |
| * @returns {RegExp} A regular expression object | |
| * @example | |
| * ```js | |
| * const test = asRegExp("test"); | |
| * test.test("test"); // true | |
| * | |
| * const test2 = asRegExp(/test/); | |
| * test2.test("test"); // true | |
| * ``` | |
| */ | |
| const asRegExp = test => { | |
| if (typeof test === "string") { | |
| // Escape special characters in the string to prevent them from being interpreted as special characters in a regular expression. Do this by | |
| // adding a backslash before each special character | |
| test = new RegExp(`^${test.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&")}`); | |
| } | |
| return test; | |
| }; | |
| /** | |
| * @template T | |
| * Returns a lazy object. The object is lazy in the sense that the properties are | |
| * only evaluated when they are accessed. This is only obtained by setting a function as the value for each key. | |
| * @param {Record<string, () => T>} obj the object to convert to a lazy access object | |
| * @returns {object} the lazy access object | |
| */ | |
| const lazyObject = obj => { | |
| const newObj = {}; | |
| for (const key of Object.keys(obj)) { | |
| const fn = obj[key]; | |
| Object.defineProperty(newObj, key, { | |
| get: () => fn(), | |
| set: v => { | |
| Object.defineProperty(newObj, key, { | |
| value: v, | |
| enumerable: true, | |
| writable: true | |
| }); | |
| }, | |
| enumerable: true, | |
| configurable: true | |
| }); | |
| } | |
| return newObj; | |
| }; | |
| const SQUARE_BRACKET_TAG_REGEXP = /\[\\*([\w-]+)\\*\]/gi; | |
| /** | |
| * @param {Module | string} module the module | |
| * @param {TODO} options options | |
| * @param {object} contextInfo context info | |
| * @param {RequestShortener} contextInfo.requestShortener requestShortener | |
| * @param {ChunkGraph} contextInfo.chunkGraph chunk graph | |
| * @param {string | Hash=} contextInfo.hashFunction the hash function to use | |
| * @returns {string} the filename | |
| */ | |
| ModuleFilenameHelpers.createFilename = ( | |
| // eslint-disable-next-line default-param-last | |
| module = "", | |
| options, | |
| { requestShortener, chunkGraph, hashFunction = "md4" } | |
| ) => { | |
| const opts = { | |
| namespace: "", | |
| moduleFilenameTemplate: "", | |
| ...(typeof options === "object" | |
| ? options | |
| : { | |
| moduleFilenameTemplate: options | |
| }) | |
| }; | |
| let absoluteResourcePath; | |
| let hash; | |
| /** @type {ReturnStringCallback} */ | |
| let identifier; | |
| /** @type {ReturnStringCallback} */ | |
| let moduleId; | |
| /** @type {ReturnStringCallback} */ | |
| let shortIdentifier; | |
| if (typeof module === "string") { | |
| shortIdentifier = | |
| /** @type {ReturnStringCallback} */ | |
| (memoize(() => requestShortener.shorten(module))); | |
| identifier = shortIdentifier; | |
| moduleId = () => ""; | |
| absoluteResourcePath = () => module.split("!").pop(); | |
| hash = getHash(identifier, hashFunction); | |
| } else { | |
| shortIdentifier = memoize(() => | |
| module.readableIdentifier(requestShortener) | |
| ); | |
| identifier = | |
| /** @type {ReturnStringCallback} */ | |
| (memoize(() => requestShortener.shorten(module.identifier()))); | |
| moduleId = | |
| /** @type {ReturnStringCallback} */ | |
| (() => chunkGraph.getModuleId(module)); | |
| absoluteResourcePath = () => | |
| module instanceof NormalModule | |
| ? module.resource | |
| : module.identifier().split("!").pop(); | |
| hash = getHash(identifier, hashFunction); | |
| } | |
| const resource = | |
| /** @type {ReturnStringCallback} */ | |
| (memoize(() => shortIdentifier().split("!").pop())); | |
| const loaders = getBefore(shortIdentifier, "!"); | |
| const allLoaders = getBefore(identifier, "!"); | |
| const query = getAfter(resource, "?"); | |
| const resourcePath = () => { | |
| const q = query().length; | |
| return q === 0 ? resource() : resource().slice(0, -q); | |
| }; | |
| if (typeof opts.moduleFilenameTemplate === "function") { | |
| return opts.moduleFilenameTemplate( | |
| lazyObject({ | |
| identifier, | |
| shortIdentifier, | |
| resource, | |
| resourcePath: memoize(resourcePath), | |
| absoluteResourcePath: memoize(absoluteResourcePath), | |
| loaders: memoize(loaders), | |
| allLoaders: memoize(allLoaders), | |
| query: memoize(query), | |
| moduleId: memoize(moduleId), | |
| hash: memoize(hash), | |
| namespace: () => opts.namespace | |
| }) | |
| ); | |
| } | |
| // TODO webpack 6: consider removing alternatives without dashes | |
| /** @type {Map<string, function(): string>} */ | |
| const replacements = new Map([ | |
| ["identifier", identifier], | |
| ["short-identifier", shortIdentifier], | |
| ["resource", resource], | |
| ["resource-path", resourcePath], | |
| // cSpell:words resourcepath | |
| ["resourcepath", resourcePath], | |
| ["absolute-resource-path", absoluteResourcePath], | |
| ["abs-resource-path", absoluteResourcePath], | |
| // cSpell:words absoluteresource | |
| ["absoluteresource-path", absoluteResourcePath], | |
| // cSpell:words absresource | |
| ["absresource-path", absoluteResourcePath], | |
| // cSpell:words resourcepath | |
| ["absolute-resourcepath", absoluteResourcePath], | |
| // cSpell:words resourcepath | |
| ["abs-resourcepath", absoluteResourcePath], | |
| // cSpell:words absoluteresourcepath | |
| ["absoluteresourcepath", absoluteResourcePath], | |
| // cSpell:words absresourcepath | |
| ["absresourcepath", absoluteResourcePath], | |
| ["all-loaders", allLoaders], | |
| // cSpell:words allloaders | |
| ["allloaders", allLoaders], | |
| ["loaders", loaders], | |
| ["query", query], | |
| ["id", moduleId], | |
| ["hash", hash], | |
| ["namespace", () => opts.namespace] | |
| ]); | |
| // TODO webpack 6: consider removing weird double placeholders | |
| return /** @type {string} */ (opts.moduleFilenameTemplate) | |
| .replace(ModuleFilenameHelpers.REGEXP_ALL_LOADERS_RESOURCE, "[identifier]") | |
| .replace( | |
| ModuleFilenameHelpers.REGEXP_LOADERS_RESOURCE, | |
| "[short-identifier]" | |
| ) | |
| .replace(SQUARE_BRACKET_TAG_REGEXP, (match, content) => { | |
| if (content.length + 2 === match.length) { | |
| const replacement = replacements.get(content.toLowerCase()); | |
| if (replacement !== undefined) { | |
| return replacement(); | |
| } | |
| } else if (match.startsWith("[\\") && match.endsWith("\\]")) { | |
| return `[${match.slice(2, -2)}]`; | |
| } | |
| return match; | |
| }); | |
| }; | |
| /** | |
| * Replaces duplicate items in an array with new values generated by a callback function. | |
| * The callback function is called with the duplicate item, the index of the duplicate item, and the number of times the item has been replaced. | |
| * The callback function should return the new value for the duplicate item. | |
| * @template T | |
| * @param {T[]} array the array with duplicates to be replaced | |
| * @param {(duplicateItem: T, duplicateItemIndex: number, numberOfTimesReplaced: number) => T} fn callback function to generate new values for the duplicate items | |
| * @param {(firstElement:T, nextElement:T) => -1 | 0 | 1} [comparator] optional comparator function to sort the duplicate items | |
| * @returns {T[]} the array with duplicates replaced | |
| * @example | |
| * ```js | |
| * const array = ["a", "b", "c", "a", "b", "a"]; | |
| * const result = ModuleFilenameHelpers.replaceDuplicates(array, (item, index, count) => `${item}-${count}`); | |
| * // result: ["a-1", "b-1", "c", "a-2", "b-2", "a-3"] | |
| * ``` | |
| */ | |
| ModuleFilenameHelpers.replaceDuplicates = (array, fn, comparator) => { | |
| const countMap = Object.create(null); | |
| const posMap = Object.create(null); | |
| for (const [idx, item] of array.entries()) { | |
| countMap[item] = countMap[item] || []; | |
| countMap[item].push(idx); | |
| posMap[item] = 0; | |
| } | |
| if (comparator) { | |
| for (const item of Object.keys(countMap)) { | |
| countMap[item].sort(comparator); | |
| } | |
| } | |
| return array.map((item, i) => { | |
| if (countMap[item].length > 1) { | |
| if (comparator && countMap[item][0] === i) return item; | |
| return fn(item, i, posMap[item]++); | |
| } | |
| return item; | |
| }); | |
| }; | |
| /** | |
| * Tests if a string matches a RegExp or an array of RegExp. | |
| * @param {string} str string to test | |
| * @param {Matcher} test value which will be used to match against the string | |
| * @returns {boolean} true, when the RegExp matches | |
| * @example | |
| * ```js | |
| * ModuleFilenameHelpers.matchPart("foo.js", "foo"); // true | |
| * ModuleFilenameHelpers.matchPart("foo.js", "foo.js"); // true | |
| * ModuleFilenameHelpers.matchPart("foo.js", "foo."); // false | |
| * ModuleFilenameHelpers.matchPart("foo.js", "foo*"); // false | |
| * ModuleFilenameHelpers.matchPart("foo.js", "foo.*"); // true | |
| * ModuleFilenameHelpers.matchPart("foo.js", /^foo/); // true | |
| * ModuleFilenameHelpers.matchPart("foo.js", [/^foo/, "bar"]); // true | |
| * ModuleFilenameHelpers.matchPart("foo.js", [/^foo/, "bar"]); // true | |
| * ModuleFilenameHelpers.matchPart("foo.js", [/^foo/, /^bar/]); // true | |
| * ModuleFilenameHelpers.matchPart("foo.js", [/^baz/, /^bar/]); // false | |
| * ``` | |
| */ | |
| ModuleFilenameHelpers.matchPart = (str, test) => { | |
| if (!test) return true; | |
| if (Array.isArray(test)) { | |
| return test.map(asRegExp).some(regExp => regExp.test(str)); | |
| } | |
| return asRegExp(test).test(str); | |
| }; | |
| /** | |
| * Tests if a string matches a match object. The match object can have the following properties: | |
| * - `test`: a RegExp or an array of RegExp | |
| * - `include`: a RegExp or an array of RegExp | |
| * - `exclude`: a RegExp or an array of RegExp | |
| * | |
| * The `test` property is tested first, then `include` and then `exclude`. | |
| * @param {MatchObject} obj a match object to test against the string | |
| * @param {string} str string to test against the matching object | |
| * @returns {boolean} true, when the object matches | |
| * @example | |
| * ```js | |
| * ModuleFilenameHelpers.matchObject({ test: "foo.js" }, "foo.js"); // true | |
| * ModuleFilenameHelpers.matchObject({ test: /^foo/ }, "foo.js"); // true | |
| * ModuleFilenameHelpers.matchObject({ test: [/^foo/, "bar"] }, "foo.js"); // true | |
| * ModuleFilenameHelpers.matchObject({ test: [/^foo/, "bar"] }, "baz.js"); // false | |
| * ModuleFilenameHelpers.matchObject({ include: "foo.js" }, "foo.js"); // true | |
| * ModuleFilenameHelpers.matchObject({ include: "foo.js" }, "bar.js"); // false | |
| * ModuleFilenameHelpers.matchObject({ include: /^foo/ }, "foo.js"); // true | |
| * ModuleFilenameHelpers.matchObject({ include: [/^foo/, "bar"] }, "foo.js"); // true | |
| * ModuleFilenameHelpers.matchObject({ include: [/^foo/, "bar"] }, "baz.js"); // false | |
| * ModuleFilenameHelpers.matchObject({ exclude: "foo.js" }, "foo.js"); // false | |
| * ModuleFilenameHelpers.matchObject({ exclude: [/^foo/, "bar"] }, "foo.js"); // false | |
| * ``` | |
| */ | |
| ModuleFilenameHelpers.matchObject = (obj, str) => { | |
| if (obj.test && !ModuleFilenameHelpers.matchPart(str, obj.test)) { | |
| return false; | |
| } | |
| if (obj.include && !ModuleFilenameHelpers.matchPart(str, obj.include)) { | |
| return false; | |
| } | |
| if (obj.exclude && ModuleFilenameHelpers.matchPart(str, obj.exclude)) { | |
| return false; | |
| } | |
| return true; | |
| }; | |
Xet Storage Details
- Size:
- 13.8 kB
- Xet hash:
- c5a86088dbd61403243d1d2ab28f3a399d51b3f86d3b00ae9a1ca115576854de
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.