summaryrefslogtreecommitdiff
path: root/node_modules/webpack/lib/sharing
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/webpack/lib/sharing')
-rw-r--r--node_modules/webpack/lib/sharing/ConsumeSharedFallbackDependency.js33
-rw-r--r--node_modules/webpack/lib/sharing/ConsumeSharedModule.js268
-rw-r--r--node_modules/webpack/lib/sharing/ConsumeSharedPlugin.js356
-rw-r--r--node_modules/webpack/lib/sharing/ConsumeSharedRuntimeModule.js353
-rw-r--r--node_modules/webpack/lib/sharing/ProvideForSharedDependency.js33
-rw-r--r--node_modules/webpack/lib/sharing/ProvideSharedDependency.js80
-rw-r--r--node_modules/webpack/lib/sharing/ProvideSharedModule.js195
-rw-r--r--node_modules/webpack/lib/sharing/ProvideSharedModuleFactory.js35
-rw-r--r--node_modules/webpack/lib/sharing/ProvideSharedPlugin.js244
-rw-r--r--node_modules/webpack/lib/sharing/SharePlugin.js92
-rw-r--r--node_modules/webpack/lib/sharing/ShareRuntimeModule.js151
-rw-r--r--node_modules/webpack/lib/sharing/resolveMatchedConfigs.js92
-rw-r--r--node_modules/webpack/lib/sharing/utils.js394
13 files changed, 2326 insertions, 0 deletions
diff --git a/node_modules/webpack/lib/sharing/ConsumeSharedFallbackDependency.js b/node_modules/webpack/lib/sharing/ConsumeSharedFallbackDependency.js
new file mode 100644
index 00000000..bd6eefef
--- /dev/null
+++ b/node_modules/webpack/lib/sharing/ConsumeSharedFallbackDependency.js
@@ -0,0 +1,33 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const ModuleDependency = require("../dependencies/ModuleDependency");
+const makeSerializable = require("../util/makeSerializable");
+
+class ConsumeSharedFallbackDependency extends ModuleDependency {
+ /**
+ * @param {string} request the request
+ */
+ constructor(request) {
+ super(request);
+ }
+
+ get type() {
+ return "consume shared fallback";
+ }
+
+ get category() {
+ return "esm";
+ }
+}
+
+makeSerializable(
+ ConsumeSharedFallbackDependency,
+ "webpack/lib/sharing/ConsumeSharedFallbackDependency"
+);
+
+module.exports = ConsumeSharedFallbackDependency;
diff --git a/node_modules/webpack/lib/sharing/ConsumeSharedModule.js b/node_modules/webpack/lib/sharing/ConsumeSharedModule.js
new file mode 100644
index 00000000..dcf40e7f
--- /dev/null
+++ b/node_modules/webpack/lib/sharing/ConsumeSharedModule.js
@@ -0,0 +1,268 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { RawSource } = require("webpack-sources");
+const AsyncDependenciesBlock = require("../AsyncDependenciesBlock");
+const Module = require("../Module");
+const {
+ WEBPACK_MODULE_TYPE_CONSUME_SHARED_MODULE
+} = require("../ModuleTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const makeSerializable = require("../util/makeSerializable");
+const { rangeToString, stringifyHoley } = require("../util/semver");
+const ConsumeSharedFallbackDependency = require("./ConsumeSharedFallbackDependency");
+
+/** @typedef {import("../../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../ChunkGroup")} ChunkGroup */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
+/** @typedef {import("../Module").CodeGenerationContext} CodeGenerationContext */
+/** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */
+/** @typedef {import("../Module").LibIdentOptions} LibIdentOptions */
+/** @typedef {import("../Module").NeedBuildContext} NeedBuildContext */
+/** @typedef {import("../Module").SourceTypes} SourceTypes */
+/** @typedef {import("../RequestShortener")} RequestShortener */
+/** @typedef {import("../ResolverFactory").ResolverWithOptions} ResolverWithOptions */
+/** @typedef {import("../WebpackError")} WebpackError */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/Hash")} Hash */
+/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
+/** @typedef {import("../util/semver").SemVerRange} SemVerRange */
+
+/**
+ * @typedef {object} ConsumeOptions
+ * @property {string=} import fallback request
+ * @property {string=} importResolved resolved fallback request
+ * @property {string} shareKey global share key
+ * @property {string} shareScope share scope
+ * @property {SemVerRange | false | undefined} requiredVersion version requirement
+ * @property {string=} packageName package name to determine required version automatically
+ * @property {boolean} strictVersion don't use shared version even if version isn't valid
+ * @property {boolean} singleton use single global version
+ * @property {boolean} eager include the fallback module in a sync way
+ */
+
+const TYPES = new Set(["consume-shared"]);
+
+class ConsumeSharedModule extends Module {
+ /**
+ * @param {string} context context
+ * @param {ConsumeOptions} options consume options
+ */
+ constructor(context, options) {
+ super(WEBPACK_MODULE_TYPE_CONSUME_SHARED_MODULE, context);
+ this.options = options;
+ }
+
+ /**
+ * @returns {string} a unique identifier of the module
+ */
+ identifier() {
+ const {
+ shareKey,
+ shareScope,
+ importResolved,
+ requiredVersion,
+ strictVersion,
+ singleton,
+ eager
+ } = this.options;
+ return `${WEBPACK_MODULE_TYPE_CONSUME_SHARED_MODULE}|${shareScope}|${shareKey}|${
+ requiredVersion && rangeToString(requiredVersion)
+ }|${strictVersion}|${importResolved}|${singleton}|${eager}`;
+ }
+
+ /**
+ * @param {RequestShortener} requestShortener the request shortener
+ * @returns {string} a user readable identifier of the module
+ */
+ readableIdentifier(requestShortener) {
+ const {
+ shareKey,
+ shareScope,
+ importResolved,
+ requiredVersion,
+ strictVersion,
+ singleton,
+ eager
+ } = this.options;
+ return `consume shared module (${shareScope}) ${shareKey}@${
+ requiredVersion ? rangeToString(requiredVersion) : "*"
+ }${strictVersion ? " (strict)" : ""}${singleton ? " (singleton)" : ""}${
+ importResolved
+ ? ` (fallback: ${requestShortener.shorten(importResolved)})`
+ : ""
+ }${eager ? " (eager)" : ""}`;
+ }
+
+ /**
+ * @param {LibIdentOptions} options options
+ * @returns {string | null} an identifier for library inclusion
+ */
+ libIdent(options) {
+ const { shareKey, shareScope, import: request } = this.options;
+ return `${
+ this.layer ? `(${this.layer})/` : ""
+ }webpack/sharing/consume/${shareScope}/${shareKey}${
+ request ? `/${request}` : ""
+ }`;
+ }
+
+ /**
+ * @param {NeedBuildContext} context context info
+ * @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
+ * @returns {void}
+ */
+ needBuild(context, callback) {
+ callback(null, !this.buildInfo);
+ }
+
+ /**
+ * @param {WebpackOptions} options webpack options
+ * @param {Compilation} compilation the compilation
+ * @param {ResolverWithOptions} resolver the resolver
+ * @param {InputFileSystem} fs the file system
+ * @param {function(WebpackError=): void} callback callback function
+ * @returns {void}
+ */
+ build(options, compilation, resolver, fs, callback) {
+ this.buildMeta = {};
+ this.buildInfo = {};
+ if (this.options.import) {
+ const dep = new ConsumeSharedFallbackDependency(this.options.import);
+ if (this.options.eager) {
+ this.addDependency(dep);
+ } else {
+ const block = new AsyncDependenciesBlock({});
+ block.addDependency(dep);
+ this.addBlock(block);
+ }
+ }
+ callback();
+ }
+
+ /**
+ * @returns {SourceTypes} types available (do not mutate)
+ */
+ getSourceTypes() {
+ return TYPES;
+ }
+
+ /**
+ * @param {string=} type the source type for which the size should be estimated
+ * @returns {number} the estimated size of the module (must be non-zero)
+ */
+ size(type) {
+ return 42;
+ }
+
+ /**
+ * @param {Hash} hash the hash used to track dependencies
+ * @param {UpdateHashContext} context context
+ * @returns {void}
+ */
+ updateHash(hash, context) {
+ hash.update(JSON.stringify(this.options));
+ super.updateHash(hash, context);
+ }
+
+ /**
+ * @param {CodeGenerationContext} context context for code generation
+ * @returns {CodeGenerationResult} result
+ */
+ codeGeneration({ chunkGraph, moduleGraph, runtimeTemplate }) {
+ const runtimeRequirements = new Set([RuntimeGlobals.shareScopeMap]);
+ const {
+ shareScope,
+ shareKey,
+ strictVersion,
+ requiredVersion,
+ import: request,
+ singleton,
+ eager
+ } = this.options;
+ let fallbackCode;
+ if (request) {
+ if (eager) {
+ const dep = this.dependencies[0];
+ fallbackCode = runtimeTemplate.syncModuleFactory({
+ dependency: dep,
+ chunkGraph,
+ runtimeRequirements,
+ request: this.options.import
+ });
+ } else {
+ const block = this.blocks[0];
+ fallbackCode = runtimeTemplate.asyncModuleFactory({
+ block,
+ chunkGraph,
+ runtimeRequirements,
+ request: this.options.import
+ });
+ }
+ }
+
+ const args = [
+ JSON.stringify(shareScope),
+ JSON.stringify(shareKey),
+ JSON.stringify(eager)
+ ];
+ if (requiredVersion) {
+ args.push(stringifyHoley(requiredVersion));
+ }
+ if (fallbackCode) {
+ args.push(fallbackCode);
+ }
+
+ let fn;
+
+ if (requiredVersion) {
+ if (strictVersion) {
+ fn = singleton ? "loadStrictSingletonVersion" : "loadStrictVersion";
+ } else {
+ fn = singleton ? "loadSingletonVersion" : "loadVersion";
+ }
+ } else {
+ fn = singleton ? "loadSingleton" : "load";
+ }
+
+ const code = runtimeTemplate.returningFunction(`${fn}(${args.join(", ")})`);
+ const sources = new Map();
+ sources.set("consume-shared", new RawSource(code));
+ return {
+ runtimeRequirements,
+ sources
+ };
+ }
+
+ /**
+ * @param {ObjectSerializerContext} context context
+ */
+ serialize(context) {
+ const { write } = context;
+ write(this.options);
+ super.serialize(context);
+ }
+
+ /**
+ * @param {ObjectDeserializerContext} context context
+ */
+ deserialize(context) {
+ const { read } = context;
+ this.options = read();
+ super.deserialize(context);
+ }
+}
+
+makeSerializable(
+ ConsumeSharedModule,
+ "webpack/lib/sharing/ConsumeSharedModule"
+);
+
+module.exports = ConsumeSharedModule;
diff --git a/node_modules/webpack/lib/sharing/ConsumeSharedPlugin.js b/node_modules/webpack/lib/sharing/ConsumeSharedPlugin.js
new file mode 100644
index 00000000..efc52490
--- /dev/null
+++ b/node_modules/webpack/lib/sharing/ConsumeSharedPlugin.js
@@ -0,0 +1,356 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const ModuleNotFoundError = require("../ModuleNotFoundError");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const WebpackError = require("../WebpackError");
+const { parseOptions } = require("../container/options");
+const LazySet = require("../util/LazySet");
+const createSchemaValidation = require("../util/create-schema-validation");
+const { parseRange } = require("../util/semver");
+const ConsumeSharedFallbackDependency = require("./ConsumeSharedFallbackDependency");
+const ConsumeSharedModule = require("./ConsumeSharedModule");
+const ConsumeSharedRuntimeModule = require("./ConsumeSharedRuntimeModule");
+const ProvideForSharedDependency = require("./ProvideForSharedDependency");
+const { resolveMatchedConfigs } = require("./resolveMatchedConfigs");
+const {
+ isRequiredVersion,
+ getDescriptionFile,
+ getRequiredVersionFromDescriptionFile
+} = require("./utils");
+
+/** @typedef {import("../../declarations/plugins/sharing/ConsumeSharedPlugin").ConsumeSharedPluginOptions} ConsumeSharedPluginOptions */
+/** @typedef {import("../../declarations/plugins/sharing/ConsumeSharedPlugin").ConsumesConfig} ConsumesConfig */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../ResolverFactory").ResolveOptionsWithDependencyType} ResolveOptionsWithDependencyType */
+/** @typedef {import("../util/semver").SemVerRange} SemVerRange */
+/** @typedef {import("./ConsumeSharedModule").ConsumeOptions} ConsumeOptions */
+/** @typedef {import("./utils").DescriptionFile} DescriptionFile */
+
+const validate = createSchemaValidation(
+ require("../../schemas/plugins/sharing/ConsumeSharedPlugin.check.js"),
+ () => require("../../schemas/plugins/sharing/ConsumeSharedPlugin.json"),
+ {
+ name: "Consume Shared Plugin",
+ baseDataPath: "options"
+ }
+);
+
+/** @type {ResolveOptionsWithDependencyType} */
+const RESOLVE_OPTIONS = { dependencyType: "esm" };
+const PLUGIN_NAME = "ConsumeSharedPlugin";
+
+class ConsumeSharedPlugin {
+ /**
+ * @param {ConsumeSharedPluginOptions} options options
+ */
+ constructor(options) {
+ if (typeof options !== "string") {
+ validate(options);
+ }
+
+ /** @type {[string, ConsumeOptions][]} */
+ this._consumes = parseOptions(
+ options.consumes,
+ (item, key) => {
+ if (Array.isArray(item)) throw new Error("Unexpected array in options");
+ /** @type {ConsumeOptions} */
+ const result =
+ item === key || !isRequiredVersion(item)
+ ? // item is a request/key
+ {
+ import: key,
+ shareScope: options.shareScope || "default",
+ shareKey: key,
+ requiredVersion: undefined,
+ packageName: undefined,
+ strictVersion: false,
+ singleton: false,
+ eager: false
+ }
+ : // key is a request/key
+ // item is a version
+ {
+ import: key,
+ shareScope: options.shareScope || "default",
+ shareKey: key,
+ requiredVersion: parseRange(item),
+ strictVersion: true,
+ packageName: undefined,
+ singleton: false,
+ eager: false
+ };
+ return result;
+ },
+ (item, key) => ({
+ import: item.import === false ? undefined : item.import || key,
+ shareScope: item.shareScope || options.shareScope || "default",
+ shareKey: item.shareKey || key,
+ requiredVersion:
+ typeof item.requiredVersion === "string"
+ ? parseRange(item.requiredVersion)
+ : item.requiredVersion,
+ strictVersion:
+ typeof item.strictVersion === "boolean"
+ ? item.strictVersion
+ : item.import !== false && !item.singleton,
+ packageName: item.packageName,
+ singleton: Boolean(item.singleton),
+ eager: Boolean(item.eager)
+ })
+ );
+ }
+
+ /**
+ * Apply the plugin
+ * @param {Compiler} compiler the compiler instance
+ * @returns {void}
+ */
+ apply(compiler) {
+ compiler.hooks.thisCompilation.tap(
+ PLUGIN_NAME,
+ (compilation, { normalModuleFactory }) => {
+ compilation.dependencyFactories.set(
+ ConsumeSharedFallbackDependency,
+ normalModuleFactory
+ );
+
+ /** @type {Map<string, ConsumeOptions>} */
+ let unresolvedConsumes;
+ /** @type {Map<string, ConsumeOptions>} */
+ let resolvedConsumes;
+ /** @type {Map<string, ConsumeOptions>} */
+ let prefixedConsumes;
+ const promise = resolveMatchedConfigs(compilation, this._consumes).then(
+ ({ resolved, unresolved, prefixed }) => {
+ resolvedConsumes = resolved;
+ unresolvedConsumes = unresolved;
+ prefixedConsumes = prefixed;
+ }
+ );
+
+ const resolver = compilation.resolverFactory.get(
+ "normal",
+ RESOLVE_OPTIONS
+ );
+
+ /**
+ * @param {string} context issuer directory
+ * @param {string} request request
+ * @param {ConsumeOptions} config options
+ * @returns {Promise<ConsumeSharedModule>} create module
+ */
+ const createConsumeSharedModule = (context, request, config) => {
+ /**
+ * @param {string} details details
+ */
+ const requiredVersionWarning = details => {
+ const error = new WebpackError(
+ `No required version specified and unable to automatically determine one. ${details}`
+ );
+ error.file = `shared module ${request}`;
+ compilation.warnings.push(error);
+ };
+ const directFallback =
+ config.import &&
+ /^(\.\.?(\/|$)|\/|[A-Za-z]:|\\\\)/.test(config.import);
+ return Promise.all([
+ new Promise(
+ /**
+ * @param {(value?: string) => void} resolve resolve
+ */
+ resolve => {
+ if (!config.import) {
+ resolve();
+ return;
+ }
+ const resolveContext = {
+ /** @type {LazySet<string>} */
+ fileDependencies: new LazySet(),
+ /** @type {LazySet<string>} */
+ contextDependencies: new LazySet(),
+ /** @type {LazySet<string>} */
+ missingDependencies: new LazySet()
+ };
+ resolver.resolve(
+ {},
+ directFallback ? compiler.context : context,
+ config.import,
+ resolveContext,
+ (err, result) => {
+ compilation.contextDependencies.addAll(
+ resolveContext.contextDependencies
+ );
+ compilation.fileDependencies.addAll(
+ resolveContext.fileDependencies
+ );
+ compilation.missingDependencies.addAll(
+ resolveContext.missingDependencies
+ );
+ if (err) {
+ compilation.errors.push(
+ new ModuleNotFoundError(null, err, {
+ name: `resolving fallback for shared module ${request}`
+ })
+ );
+ return resolve();
+ }
+ resolve(/** @type {string} */ (result));
+ }
+ );
+ }
+ ),
+ new Promise(
+ /**
+ * @param {(value?: SemVerRange) => void} resolve resolve
+ */
+ resolve => {
+ if (config.requiredVersion !== undefined) {
+ resolve(/** @type {SemVerRange} */ (config.requiredVersion));
+ return;
+ }
+ let packageName = config.packageName;
+ if (packageName === undefined) {
+ if (/^(\/|[A-Za-z]:|\\\\)/.test(request)) {
+ // For relative or absolute requests we don't automatically use a packageName.
+ // If wished one can specify one with the packageName option.
+ resolve();
+ return;
+ }
+ const match = /^((?:@[^\\/]+[\\/])?[^\\/]+)/.exec(request);
+ if (!match) {
+ requiredVersionWarning(
+ "Unable to extract the package name from request."
+ );
+ resolve();
+ return;
+ }
+ packageName = match[0];
+ }
+
+ getDescriptionFile(
+ compilation.inputFileSystem,
+ context,
+ ["package.json"],
+ (err, result) => {
+ if (err) {
+ requiredVersionWarning(
+ `Unable to read description file: ${err}`
+ );
+ return resolve();
+ }
+ const { data, path: descriptionPath } =
+ /** @type {DescriptionFile} */ (result);
+ if (!data) {
+ requiredVersionWarning(
+ `Unable to find description file in ${context}.`
+ );
+ return resolve();
+ }
+ if (data.name === packageName) {
+ // Package self-referencing
+ return resolve();
+ }
+ const requiredVersion =
+ getRequiredVersionFromDescriptionFile(data, packageName);
+ if (typeof requiredVersion !== "string") {
+ requiredVersionWarning(
+ `Unable to find required version for "${packageName}" in description file (${descriptionPath}). It need to be in dependencies, devDependencies or peerDependencies.`
+ );
+ return resolve();
+ }
+ resolve(parseRange(requiredVersion));
+ }
+ );
+ }
+ )
+ ]).then(
+ ([importResolved, requiredVersion]) =>
+ new ConsumeSharedModule(
+ directFallback ? compiler.context : context,
+ {
+ ...config,
+ importResolved,
+ import: importResolved ? config.import : undefined,
+ requiredVersion
+ }
+ )
+ );
+ };
+
+ normalModuleFactory.hooks.factorize.tapPromise(
+ PLUGIN_NAME,
+ ({ context, request, dependencies }) =>
+ // wait for resolving to be complete
+ promise.then(() => {
+ if (
+ dependencies[0] instanceof ConsumeSharedFallbackDependency ||
+ dependencies[0] instanceof ProvideForSharedDependency
+ ) {
+ return;
+ }
+ const match = unresolvedConsumes.get(request);
+ if (match !== undefined) {
+ return createConsumeSharedModule(context, request, match);
+ }
+ for (const [prefix, options] of prefixedConsumes) {
+ if (request.startsWith(prefix)) {
+ const remainder = request.slice(prefix.length);
+ return createConsumeSharedModule(context, request, {
+ ...options,
+ import: options.import
+ ? options.import + remainder
+ : undefined,
+ shareKey: options.shareKey + remainder
+ });
+ }
+ }
+ })
+ );
+ normalModuleFactory.hooks.createModule.tapPromise(
+ PLUGIN_NAME,
+ ({ resource }, { context, dependencies }) => {
+ if (
+ dependencies[0] instanceof ConsumeSharedFallbackDependency ||
+ dependencies[0] instanceof ProvideForSharedDependency
+ ) {
+ return Promise.resolve();
+ }
+ const options = resolvedConsumes.get(
+ /** @type {string} */ (resource)
+ );
+ if (options !== undefined) {
+ return createConsumeSharedModule(
+ context,
+ /** @type {string} */ (resource),
+ options
+ );
+ }
+ return Promise.resolve();
+ }
+ );
+ compilation.hooks.additionalTreeRuntimeRequirements.tap(
+ PLUGIN_NAME,
+ (chunk, set) => {
+ set.add(RuntimeGlobals.module);
+ set.add(RuntimeGlobals.moduleCache);
+ set.add(RuntimeGlobals.moduleFactoriesAddOnly);
+ set.add(RuntimeGlobals.shareScopeMap);
+ set.add(RuntimeGlobals.initializeSharing);
+ set.add(RuntimeGlobals.hasOwnProperty);
+ compilation.addRuntimeModule(
+ chunk,
+ new ConsumeSharedRuntimeModule(set)
+ );
+ }
+ );
+ }
+ );
+ }
+}
+
+module.exports = ConsumeSharedPlugin;
diff --git a/node_modules/webpack/lib/sharing/ConsumeSharedRuntimeModule.js b/node_modules/webpack/lib/sharing/ConsumeSharedRuntimeModule.js
new file mode 100644
index 00000000..7dc3209b
--- /dev/null
+++ b/node_modules/webpack/lib/sharing/ConsumeSharedRuntimeModule.js
@@ -0,0 +1,353 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+const {
+ parseVersionRuntimeCode,
+ versionLtRuntimeCode,
+ rangeToStringRuntimeCode,
+ satisfyRuntimeCode
+} = require("../util/semver");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Chunk").ChunkId} ChunkId */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../ChunkGraph").ModuleId} ModuleId */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */
+/** @typedef {import("./ConsumeSharedModule")} ConsumeSharedModule */
+
+class ConsumeSharedRuntimeModule extends RuntimeModule {
+ /**
+ * @param {ReadOnlyRuntimeRequirements} runtimeRequirements runtime requirements
+ */
+ constructor(runtimeRequirements) {
+ super("consumes", RuntimeModule.STAGE_ATTACH);
+ this._runtimeRequirements = runtimeRequirements;
+ }
+
+ /**
+ * @returns {string | null} runtime code
+ */
+ generate() {
+ const compilation = /** @type {Compilation} */ (this.compilation);
+ const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph);
+ const { runtimeTemplate, codeGenerationResults } = compilation;
+ /** @type {Record<ChunkId, (string | number)[]>} */
+ const chunkToModuleMapping = {};
+ /** @type {Map<string | number, Source>} */
+ const moduleIdToSourceMapping = new Map();
+ /** @type {(string | number)[]} */
+ const initialConsumes = [];
+ /**
+ * @param {Iterable<Module>} modules modules
+ * @param {Chunk} chunk the chunk
+ * @param {(string | number)[]} list list of ids
+ */
+ const addModules = (modules, chunk, list) => {
+ for (const m of modules) {
+ const module = m;
+ const id = /** @type {ModuleId} */ (chunkGraph.getModuleId(module));
+ list.push(id);
+ moduleIdToSourceMapping.set(
+ id,
+ codeGenerationResults.getSource(
+ module,
+ chunk.runtime,
+ "consume-shared"
+ )
+ );
+ }
+ };
+ for (const chunk of /** @type {Chunk} */ (this.chunk).getAllAsyncChunks()) {
+ const modules = chunkGraph.getChunkModulesIterableBySourceType(
+ chunk,
+ "consume-shared"
+ );
+ if (!modules) continue;
+ addModules(
+ modules,
+ chunk,
+ (chunkToModuleMapping[/** @type {ChunkId} */ (chunk.id)] = [])
+ );
+ }
+ for (const chunk of /** @type {Chunk} */ (
+ this.chunk
+ ).getAllInitialChunks()) {
+ const modules = chunkGraph.getChunkModulesIterableBySourceType(
+ chunk,
+ "consume-shared"
+ );
+ if (!modules) continue;
+ addModules(modules, chunk, initialConsumes);
+ }
+ if (moduleIdToSourceMapping.size === 0) return null;
+ return Template.asString([
+ parseVersionRuntimeCode(runtimeTemplate),
+ versionLtRuntimeCode(runtimeTemplate),
+ rangeToStringRuntimeCode(runtimeTemplate),
+ satisfyRuntimeCode(runtimeTemplate),
+ `var exists = ${runtimeTemplate.basicFunction("scope, key", [
+ `return scope && ${RuntimeGlobals.hasOwnProperty}(scope, key);`
+ ])}`,
+ `var get = ${runtimeTemplate.basicFunction("entry", [
+ "entry.loaded = 1;",
+ "return entry.get()"
+ ])};`,
+ `var eagerOnly = ${runtimeTemplate.basicFunction("versions", [
+ `return Object.keys(versions).reduce(${runtimeTemplate.basicFunction(
+ "filtered, version",
+ Template.indent([
+ "if (versions[version].eager) {",
+ Template.indent(["filtered[version] = versions[version];"]),
+ "}",
+ "return filtered;"
+ ])
+ )}, {});`
+ ])};`,
+ `var findLatestVersion = ${runtimeTemplate.basicFunction(
+ "scope, key, eager",
+ [
+ "var versions = eager ? eagerOnly(scope[key]) : scope[key];",
+ `var key = Object.keys(versions).reduce(${runtimeTemplate.basicFunction(
+ "a, b",
+ ["return !a || versionLt(a, b) ? b : a;"]
+ )}, 0);`,
+ "return key && versions[key];"
+ ]
+ )};`,
+ `var findSatisfyingVersion = ${runtimeTemplate.basicFunction(
+ "scope, key, requiredVersion, eager",
+ [
+ "var versions = eager ? eagerOnly(scope[key]) : scope[key];",
+ `var key = Object.keys(versions).reduce(${runtimeTemplate.basicFunction(
+ "a, b",
+ [
+ "if (!satisfy(requiredVersion, b)) return a;",
+ "return !a || versionLt(a, b) ? b : a;"
+ ]
+ )}, 0);`,
+ "return key && versions[key]"
+ ]
+ )};`,
+ `var findSingletonVersionKey = ${runtimeTemplate.basicFunction(
+ "scope, key, eager",
+ [
+ "var versions = eager ? eagerOnly(scope[key]) : scope[key];",
+ `return Object.keys(versions).reduce(${runtimeTemplate.basicFunction(
+ "a, b",
+ ["return !a || (!versions[a].loaded && versionLt(a, b)) ? b : a;"]
+ )}, 0);`
+ ]
+ )};`,
+ `var getInvalidSingletonVersionMessage = ${runtimeTemplate.basicFunction(
+ "scope, key, version, requiredVersion",
+ [
+ 'return "Unsatisfied version " + version + " from " + (version && scope[key][version].from) + " of shared singleton module " + key + " (required " + rangeToString(requiredVersion) + ")"'
+ ]
+ )};`,
+ `var getInvalidVersionMessage = ${runtimeTemplate.basicFunction(
+ "scope, scopeName, key, requiredVersion, eager",
+ [
+ "var versions = scope[key];",
+ 'return "No satisfying version (" + rangeToString(requiredVersion) + ")" + (eager ? " for eager consumption" : "") + " of shared module " + key + " found in shared scope " + scopeName + ".\\n" +',
+ `\t"Available versions: " + Object.keys(versions).map(${runtimeTemplate.basicFunction(
+ "key",
+ ['return key + " from " + versions[key].from;']
+ )}).join(", ");`
+ ]
+ )};`,
+ `var fail = ${runtimeTemplate.basicFunction("msg", [
+ "throw new Error(msg);"
+ ])}`,
+ `var failAsNotExist = ${runtimeTemplate.basicFunction("scopeName, key", [
+ 'return fail("Shared module " + key + " doesn\'t exist in shared scope " + scopeName);'
+ ])}`,
+ `var warn = /*#__PURE__*/ ${
+ compilation.outputOptions.ignoreBrowserWarnings
+ ? runtimeTemplate.basicFunction("", "")
+ : runtimeTemplate.basicFunction("msg", [
+ 'if (typeof console !== "undefined" && console.warn) console.warn(msg);'
+ ])
+ };`,
+ `var init = ${runtimeTemplate.returningFunction(
+ Template.asString([
+ "function(scopeName, key, eager, c, d) {",
+ Template.indent([
+ `var promise = ${RuntimeGlobals.initializeSharing}(scopeName);`,
+ // if we require eager shared, we expect it to be already loaded before it requested, no need to wait the whole scope loaded.
+ "if (promise && promise.then && !eager) { ",
+ Template.indent([
+ `return promise.then(fn.bind(fn, scopeName, ${RuntimeGlobals.shareScopeMap}[scopeName], key, false, c, d));`
+ ]),
+ "}",
+ `return fn(scopeName, ${RuntimeGlobals.shareScopeMap}[scopeName], key, eager, c, d);`
+ ]),
+ "}"
+ ]),
+ "fn"
+ )};`,
+ "",
+ `var useFallback = ${runtimeTemplate.basicFunction(
+ "scopeName, key, fallback",
+ ["return fallback ? fallback() : failAsNotExist(scopeName, key);"]
+ )}`,
+ `var load = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
+ "scopeName, scope, key, eager, fallback",
+ [
+ "if (!exists(scope, key)) return useFallback(scopeName, key, fallback);",
+ "return get(findLatestVersion(scope, key, eager));"
+ ]
+ )});`,
+ `var loadVersion = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
+ "scopeName, scope, key, eager, requiredVersion, fallback",
+ [
+ "if (!exists(scope, key)) return useFallback(scopeName, key, fallback);",
+ "var satisfyingVersion = findSatisfyingVersion(scope, key, requiredVersion, eager);",
+ "if (satisfyingVersion) return get(satisfyingVersion);",
+ "warn(getInvalidVersionMessage(scope, scopeName, key, requiredVersion, eager))",
+ "return get(findLatestVersion(scope, key, eager));"
+ ]
+ )});`,
+ `var loadStrictVersion = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
+ "scopeName, scope, key, eager, requiredVersion, fallback",
+ [
+ "if (!exists(scope, key)) return useFallback(scopeName, key, fallback);",
+ "var satisfyingVersion = findSatisfyingVersion(scope, key, requiredVersion, eager);",
+ "if (satisfyingVersion) return get(satisfyingVersion);",
+ "if (fallback) return fallback();",
+ "fail(getInvalidVersionMessage(scope, scopeName, key, requiredVersion, eager));"
+ ]
+ )});`,
+ `var loadSingleton = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
+ "scopeName, scope, key, eager, fallback",
+ [
+ "if (!exists(scope, key)) return useFallback(scopeName, key, fallback);",
+ "var version = findSingletonVersionKey(scope, key, eager);",
+ "return get(scope[key][version]);"
+ ]
+ )});`,
+ `var loadSingletonVersion = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
+ "scopeName, scope, key, eager, requiredVersion, fallback",
+ [
+ "if (!exists(scope, key)) return useFallback(scopeName, key, fallback);",
+ "var version = findSingletonVersionKey(scope, key, eager);",
+ "if (!satisfy(requiredVersion, version)) {",
+ Template.indent([
+ "warn(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion));"
+ ]),
+ "}",
+ "return get(scope[key][version]);"
+ ]
+ )});`,
+ `var loadStrictSingletonVersion = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
+ "scopeName, scope, key, eager, requiredVersion, fallback",
+ [
+ "if (!exists(scope, key)) return useFallback(scopeName, key, fallback);",
+ "var version = findSingletonVersionKey(scope, key, eager);",
+ "if (!satisfy(requiredVersion, version)) {",
+ Template.indent([
+ "fail(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion));"
+ ]),
+ "}",
+ "return get(scope[key][version]);"
+ ]
+ )});`,
+ "var installedModules = {};",
+ "var moduleToHandlerMapping = {",
+ Template.indent(
+ Array.from(
+ moduleIdToSourceMapping,
+ ([key, source]) => `${JSON.stringify(key)}: ${source.source()}`
+ ).join(",\n")
+ ),
+ "};",
+
+ initialConsumes.length > 0
+ ? Template.asString([
+ `var initialConsumes = ${JSON.stringify(initialConsumes)};`,
+ `initialConsumes.forEach(${runtimeTemplate.basicFunction("id", [
+ `${
+ RuntimeGlobals.moduleFactories
+ }[id] = ${runtimeTemplate.basicFunction("module", [
+ "// Handle case when module is used sync",
+ "installedModules[id] = 0;",
+ `delete ${RuntimeGlobals.moduleCache}[id];`,
+ "var factory = moduleToHandlerMapping[id]();",
+ 'if(typeof factory !== "function") throw new Error("Shared module is not available for eager consumption: " + id);',
+ "module.exports = factory();"
+ ])}`
+ ])});`
+ ])
+ : "// no consumes in initial chunks",
+ this._runtimeRequirements.has(RuntimeGlobals.ensureChunkHandlers)
+ ? Template.asString([
+ `var chunkMapping = ${JSON.stringify(
+ chunkToModuleMapping,
+ null,
+ "\t"
+ )};`,
+ "var startedInstallModules = {};",
+ `${
+ RuntimeGlobals.ensureChunkHandlers
+ }.consumes = ${runtimeTemplate.basicFunction("chunkId, promises", [
+ `if(${RuntimeGlobals.hasOwnProperty}(chunkMapping, chunkId)) {`,
+ Template.indent([
+ `chunkMapping[chunkId].forEach(${runtimeTemplate.basicFunction(
+ "id",
+ [
+ `if(${RuntimeGlobals.hasOwnProperty}(installedModules, id)) return promises.push(installedModules[id]);`,
+ "if(!startedInstallModules[id]) {",
+ `var onFactory = ${runtimeTemplate.basicFunction(
+ "factory",
+ [
+ "installedModules[id] = 0;",
+ `${
+ RuntimeGlobals.moduleFactories
+ }[id] = ${runtimeTemplate.basicFunction("module", [
+ `delete ${RuntimeGlobals.moduleCache}[id];`,
+ "module.exports = factory();"
+ ])}`
+ ]
+ )};`,
+ "startedInstallModules[id] = true;",
+ `var onError = ${runtimeTemplate.basicFunction("error", [
+ "delete installedModules[id];",
+ `${
+ RuntimeGlobals.moduleFactories
+ }[id] = ${runtimeTemplate.basicFunction("module", [
+ `delete ${RuntimeGlobals.moduleCache}[id];`,
+ "throw error;"
+ ])}`
+ ])};`,
+ "try {",
+ Template.indent([
+ "var promise = moduleToHandlerMapping[id]();",
+ "if(promise.then) {",
+ Template.indent(
+ "promises.push(installedModules[id] = promise.then(onFactory)['catch'](onError));"
+ ),
+ "} else onFactory(promise);"
+ ]),
+ "} catch(e) { onError(e); }",
+ "}"
+ ]
+ )});`
+ ]),
+ "}"
+ ])}`
+ ])
+ : "// no chunk loading of consumes"
+ ]);
+ }
+}
+
+module.exports = ConsumeSharedRuntimeModule;
diff --git a/node_modules/webpack/lib/sharing/ProvideForSharedDependency.js b/node_modules/webpack/lib/sharing/ProvideForSharedDependency.js
new file mode 100644
index 00000000..4de679a6
--- /dev/null
+++ b/node_modules/webpack/lib/sharing/ProvideForSharedDependency.js
@@ -0,0 +1,33 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const ModuleDependency = require("../dependencies/ModuleDependency");
+const makeSerializable = require("../util/makeSerializable");
+
+class ProvideForSharedDependency extends ModuleDependency {
+ /**
+ * @param {string} request request string
+ */
+ constructor(request) {
+ super(request);
+ }
+
+ get type() {
+ return "provide module for shared";
+ }
+
+ get category() {
+ return "esm";
+ }
+}
+
+makeSerializable(
+ ProvideForSharedDependency,
+ "webpack/lib/sharing/ProvideForSharedDependency"
+);
+
+module.exports = ProvideForSharedDependency;
diff --git a/node_modules/webpack/lib/sharing/ProvideSharedDependency.js b/node_modules/webpack/lib/sharing/ProvideSharedDependency.js
new file mode 100644
index 00000000..2df18a61
--- /dev/null
+++ b/node_modules/webpack/lib/sharing/ProvideSharedDependency.js
@@ -0,0 +1,80 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const Dependency = require("../Dependency");
+const makeSerializable = require("../util/makeSerializable");
+
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+
+class ProvideSharedDependency extends Dependency {
+ /**
+ * @param {string} shareScope share scope
+ * @param {string} name module name
+ * @param {string | false} version version
+ * @param {string} request request
+ * @param {boolean} eager true, if this is an eager dependency
+ */
+ constructor(shareScope, name, version, request, eager) {
+ super();
+ this.shareScope = shareScope;
+ this.name = name;
+ this.version = version;
+ this.request = request;
+ this.eager = eager;
+ }
+
+ get type() {
+ return "provide shared module";
+ }
+
+ /**
+ * @returns {string | null} an identifier to merge equal requests
+ */
+ getResourceIdentifier() {
+ return `provide module (${this.shareScope}) ${this.request} as ${
+ this.name
+ } @ ${this.version}${this.eager ? " (eager)" : ""}`;
+ }
+
+ /**
+ * @param {ObjectSerializerContext} context context
+ */
+ serialize(context) {
+ context.write(this.shareScope);
+ context.write(this.name);
+ context.write(this.request);
+ context.write(this.version);
+ context.write(this.eager);
+ super.serialize(context);
+ }
+
+ /**
+ * @param {ObjectDeserializerContext} context context
+ * @returns {ProvideSharedDependency} deserialize fallback dependency
+ */
+ static deserialize(context) {
+ const { read } = context;
+ const obj = new ProvideSharedDependency(
+ read(),
+ read(),
+ read(),
+ read(),
+ read()
+ );
+ this.shareScope = context.read();
+ obj.deserialize(context);
+ return obj;
+ }
+}
+
+makeSerializable(
+ ProvideSharedDependency,
+ "webpack/lib/sharing/ProvideSharedDependency"
+);
+
+module.exports = ProvideSharedDependency;
diff --git a/node_modules/webpack/lib/sharing/ProvideSharedModule.js b/node_modules/webpack/lib/sharing/ProvideSharedModule.js
new file mode 100644
index 00000000..22848391
--- /dev/null
+++ b/node_modules/webpack/lib/sharing/ProvideSharedModule.js
@@ -0,0 +1,195 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra and Zackary Jackson @ScriptedAlchemy
+*/
+
+"use strict";
+
+const AsyncDependenciesBlock = require("../AsyncDependenciesBlock");
+const Module = require("../Module");
+const { WEBPACK_MODULE_TYPE_PROVIDE } = require("../ModuleTypeConstants");
+const RuntimeGlobals = require("../RuntimeGlobals");
+const makeSerializable = require("../util/makeSerializable");
+const ProvideForSharedDependency = require("./ProvideForSharedDependency");
+
+/** @typedef {import("../../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../ChunkGroup")} ChunkGroup */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Module").CodeGenerationContext} CodeGenerationContext */
+/** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */
+/** @typedef {import("../Module").LibIdentOptions} LibIdentOptions */
+/** @typedef {import("../Module").NeedBuildContext} NeedBuildContext */
+/** @typedef {import("../Module").SourceTypes} SourceTypes */
+/** @typedef {import("../RequestShortener")} RequestShortener */
+/** @typedef {import("../ResolverFactory").ResolverWithOptions} ResolverWithOptions */
+/** @typedef {import("../WebpackError")} WebpackError */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
+/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
+/** @typedef {import("../util/Hash")} Hash */
+/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
+
+const TYPES = new Set(["share-init"]);
+
+class ProvideSharedModule extends Module {
+ /**
+ * @param {string} shareScope shared scope name
+ * @param {string} name shared key
+ * @param {string | false} version version
+ * @param {string} request request to the provided module
+ * @param {boolean} eager include the module in sync way
+ */
+ constructor(shareScope, name, version, request, eager) {
+ super(WEBPACK_MODULE_TYPE_PROVIDE);
+ this._shareScope = shareScope;
+ this._name = name;
+ this._version = version;
+ this._request = request;
+ this._eager = eager;
+ }
+
+ /**
+ * @returns {string} a unique identifier of the module
+ */
+ identifier() {
+ return `provide module (${this._shareScope}) ${this._name}@${this._version} = ${this._request}`;
+ }
+
+ /**
+ * @param {RequestShortener} requestShortener the request shortener
+ * @returns {string} a user readable identifier of the module
+ */
+ readableIdentifier(requestShortener) {
+ return `provide shared module (${this._shareScope}) ${this._name}@${
+ this._version
+ } = ${requestShortener.shorten(this._request)}`;
+ }
+
+ /**
+ * @param {LibIdentOptions} options options
+ * @returns {string | null} an identifier for library inclusion
+ */
+ libIdent(options) {
+ return `${this.layer ? `(${this.layer})/` : ""}webpack/sharing/provide/${
+ this._shareScope
+ }/${this._name}`;
+ }
+
+ /**
+ * @param {NeedBuildContext} context context info
+ * @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
+ * @returns {void}
+ */
+ needBuild(context, callback) {
+ callback(null, !this.buildInfo);
+ }
+
+ /**
+ * @param {WebpackOptions} options webpack options
+ * @param {Compilation} compilation the compilation
+ * @param {ResolverWithOptions} resolver the resolver
+ * @param {InputFileSystem} fs the file system
+ * @param {function(WebpackError=): void} callback callback function
+ * @returns {void}
+ */
+ build(options, compilation, resolver, fs, callback) {
+ this.buildMeta = {};
+ this.buildInfo = {
+ strict: true
+ };
+
+ this.clearDependenciesAndBlocks();
+ const dep = new ProvideForSharedDependency(this._request);
+ if (this._eager) {
+ this.addDependency(dep);
+ } else {
+ const block = new AsyncDependenciesBlock({});
+ block.addDependency(dep);
+ this.addBlock(block);
+ }
+
+ callback();
+ }
+
+ /**
+ * @param {string=} type the source type for which the size should be estimated
+ * @returns {number} the estimated size of the module (must be non-zero)
+ */
+ size(type) {
+ return 42;
+ }
+
+ /**
+ * @returns {SourceTypes} types available (do not mutate)
+ */
+ getSourceTypes() {
+ return TYPES;
+ }
+
+ /**
+ * @param {CodeGenerationContext} context context for code generation
+ * @returns {CodeGenerationResult} result
+ */
+ codeGeneration({ runtimeTemplate, moduleGraph, chunkGraph }) {
+ const runtimeRequirements = new Set([RuntimeGlobals.initializeSharing]);
+ const code = `register(${JSON.stringify(this._name)}, ${JSON.stringify(
+ this._version || "0"
+ )}, ${
+ this._eager
+ ? runtimeTemplate.syncModuleFactory({
+ dependency: this.dependencies[0],
+ chunkGraph,
+ request: this._request,
+ runtimeRequirements
+ })
+ : runtimeTemplate.asyncModuleFactory({
+ block: this.blocks[0],
+ chunkGraph,
+ request: this._request,
+ runtimeRequirements
+ })
+ }${this._eager ? ", 1" : ""});`;
+ const sources = new Map();
+ const data = new Map();
+ data.set("share-init", [
+ {
+ shareScope: this._shareScope,
+ initStage: 10,
+ init: code
+ }
+ ]);
+ return { sources, data, runtimeRequirements };
+ }
+
+ /**
+ * @param {ObjectSerializerContext} context context
+ */
+ serialize(context) {
+ const { write } = context;
+ write(this._shareScope);
+ write(this._name);
+ write(this._version);
+ write(this._request);
+ write(this._eager);
+ super.serialize(context);
+ }
+
+ /**
+ * @param {ObjectDeserializerContext} context context
+ * @returns {ProvideSharedModule} deserialize fallback dependency
+ */
+ static deserialize(context) {
+ const { read } = context;
+ const obj = new ProvideSharedModule(read(), read(), read(), read(), read());
+ obj.deserialize(context);
+ return obj;
+ }
+}
+
+makeSerializable(
+ ProvideSharedModule,
+ "webpack/lib/sharing/ProvideSharedModule"
+);
+
+module.exports = ProvideSharedModule;
diff --git a/node_modules/webpack/lib/sharing/ProvideSharedModuleFactory.js b/node_modules/webpack/lib/sharing/ProvideSharedModuleFactory.js
new file mode 100644
index 00000000..d5bcc829
--- /dev/null
+++ b/node_modules/webpack/lib/sharing/ProvideSharedModuleFactory.js
@@ -0,0 +1,35 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra and Zackary Jackson @ScriptedAlchemy
+*/
+
+"use strict";
+
+const ModuleFactory = require("../ModuleFactory");
+const ProvideSharedModule = require("./ProvideSharedModule");
+
+/** @typedef {import("../ModuleFactory").ModuleFactoryCreateData} ModuleFactoryCreateData */
+/** @typedef {import("../ModuleFactory").ModuleFactoryResult} ModuleFactoryResult */
+/** @typedef {import("./ProvideSharedDependency")} ProvideSharedDependency */
+
+class ProvideSharedModuleFactory extends ModuleFactory {
+ /**
+ * @param {ModuleFactoryCreateData} data data object
+ * @param {function((Error | null)=, ModuleFactoryResult=): void} callback callback
+ * @returns {void}
+ */
+ create(data, callback) {
+ const dep = /** @type {ProvideSharedDependency} */ (data.dependencies[0]);
+ callback(null, {
+ module: new ProvideSharedModule(
+ dep.shareScope,
+ dep.name,
+ dep.version,
+ dep.request,
+ dep.eager
+ )
+ });
+ }
+}
+
+module.exports = ProvideSharedModuleFactory;
diff --git a/node_modules/webpack/lib/sharing/ProvideSharedPlugin.js b/node_modules/webpack/lib/sharing/ProvideSharedPlugin.js
new file mode 100644
index 00000000..c57b7632
--- /dev/null
+++ b/node_modules/webpack/lib/sharing/ProvideSharedPlugin.js
@@ -0,0 +1,244 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra and Zackary Jackson @ScriptedAlchemy
+*/
+
+"use strict";
+
+const WebpackError = require("../WebpackError");
+const { parseOptions } = require("../container/options");
+const createSchemaValidation = require("../util/create-schema-validation");
+const ProvideForSharedDependency = require("./ProvideForSharedDependency");
+const ProvideSharedDependency = require("./ProvideSharedDependency");
+const ProvideSharedModuleFactory = require("./ProvideSharedModuleFactory");
+
+/** @typedef {import("../../declarations/plugins/sharing/ProvideSharedPlugin").ProvideSharedPluginOptions} ProvideSharedPluginOptions */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../NormalModuleFactory").NormalModuleCreateData} NormalModuleCreateData */
+
+const validate = createSchemaValidation(
+ require("../../schemas/plugins/sharing/ProvideSharedPlugin.check.js"),
+ () => require("../../schemas/plugins/sharing/ProvideSharedPlugin.json"),
+ {
+ name: "Provide Shared Plugin",
+ baseDataPath: "options"
+ }
+);
+
+/**
+ * @typedef {object} ProvideOptions
+ * @property {string} shareKey
+ * @property {string} shareScope
+ * @property {string | undefined | false} version
+ * @property {boolean} eager
+ */
+
+/** @typedef {Map<string, { config: ProvideOptions, version: string | undefined | false }>} ResolvedProvideMap */
+
+class ProvideSharedPlugin {
+ /**
+ * @param {ProvideSharedPluginOptions} options options
+ */
+ constructor(options) {
+ validate(options);
+
+ this._provides = /** @type {[string, ProvideOptions][]} */ (
+ parseOptions(
+ options.provides,
+ item => {
+ if (Array.isArray(item))
+ throw new Error("Unexpected array of provides");
+ /** @type {ProvideOptions} */
+ const result = {
+ shareKey: item,
+ version: undefined,
+ shareScope: options.shareScope || "default",
+ eager: false
+ };
+ return result;
+ },
+ item => ({
+ shareKey: item.shareKey,
+ version: item.version,
+ shareScope: item.shareScope || options.shareScope || "default",
+ eager: Boolean(item.eager)
+ })
+ )
+ );
+ this._provides.sort(([a], [b]) => {
+ if (a < b) return -1;
+ if (b < a) return 1;
+ return 0;
+ });
+ }
+
+ /**
+ * Apply the plugin
+ * @param {Compiler} compiler the compiler instance
+ * @returns {void}
+ */
+ apply(compiler) {
+ /** @type {WeakMap<Compilation, ResolvedProvideMap>} */
+ const compilationData = new WeakMap();
+
+ compiler.hooks.compilation.tap(
+ "ProvideSharedPlugin",
+ (compilation, { normalModuleFactory }) => {
+ /** @type {ResolvedProvideMap} */
+ const resolvedProvideMap = new Map();
+ /** @type {Map<string, ProvideOptions>} */
+ const matchProvides = new Map();
+ /** @type {Map<string, ProvideOptions>} */
+ const prefixMatchProvides = new Map();
+ for (const [request, config] of this._provides) {
+ if (/^(\/|[A-Za-z]:\\|\\\\|\.\.?(\/|$))/.test(request)) {
+ // relative request
+ resolvedProvideMap.set(request, {
+ config,
+ version: config.version
+ });
+ } else if (/^(\/|[A-Za-z]:\\|\\\\)/.test(request)) {
+ // absolute path
+ resolvedProvideMap.set(request, {
+ config,
+ version: config.version
+ });
+ } else if (request.endsWith("/")) {
+ // module request prefix
+ prefixMatchProvides.set(request, config);
+ } else {
+ // module request
+ matchProvides.set(request, config);
+ }
+ }
+ compilationData.set(compilation, resolvedProvideMap);
+ /**
+ * @param {string} key key
+ * @param {ProvideOptions} config config
+ * @param {NormalModuleCreateData["resource"]} resource resource
+ * @param {NormalModuleCreateData["resourceResolveData"]} resourceResolveData resource resolve data
+ */
+ const provideSharedModule = (
+ key,
+ config,
+ resource,
+ resourceResolveData
+ ) => {
+ let version = config.version;
+ if (version === undefined) {
+ let details = "";
+ if (!resourceResolveData) {
+ details = "No resolve data provided from resolver.";
+ } else {
+ const descriptionFileData =
+ resourceResolveData.descriptionFileData;
+ if (!descriptionFileData) {
+ details =
+ "No description file (usually package.json) found. Add description file with name and version, or manually specify version in shared config.";
+ } else if (!descriptionFileData.version) {
+ details = `No version in description file (usually package.json). Add version to description file ${resourceResolveData.descriptionFilePath}, or manually specify version in shared config.`;
+ } else {
+ version = descriptionFileData.version;
+ }
+ }
+ if (!version) {
+ const error = new WebpackError(
+ `No version specified and unable to automatically determine one. ${details}`
+ );
+ error.file = `shared module ${key} -> ${resource}`;
+ compilation.warnings.push(error);
+ }
+ }
+ resolvedProvideMap.set(resource, {
+ config,
+ version
+ });
+ };
+ normalModuleFactory.hooks.module.tap(
+ "ProvideSharedPlugin",
+ (module, { resource, resourceResolveData }, resolveData) => {
+ if (resolvedProvideMap.has(/** @type {string} */ (resource))) {
+ return module;
+ }
+ const { request } = resolveData;
+ {
+ const config = matchProvides.get(request);
+ if (config !== undefined) {
+ provideSharedModule(
+ request,
+ config,
+ /** @type {string} */ (resource),
+ resourceResolveData
+ );
+ resolveData.cacheable = false;
+ }
+ }
+ for (const [prefix, config] of prefixMatchProvides) {
+ if (request.startsWith(prefix)) {
+ const remainder = request.slice(prefix.length);
+ provideSharedModule(
+ /** @type {string} */ (resource),
+ {
+ ...config,
+ shareKey: config.shareKey + remainder
+ },
+ /** @type {string} */ (resource),
+ resourceResolveData
+ );
+ resolveData.cacheable = false;
+ }
+ }
+ return module;
+ }
+ );
+ }
+ );
+ compiler.hooks.finishMake.tapPromise("ProvideSharedPlugin", compilation => {
+ const resolvedProvideMap = compilationData.get(compilation);
+ if (!resolvedProvideMap) return Promise.resolve();
+ return Promise.all(
+ Array.from(
+ resolvedProvideMap,
+ ([resource, { config, version }]) =>
+ new Promise((resolve, reject) => {
+ compilation.addInclude(
+ compiler.context,
+ new ProvideSharedDependency(
+ config.shareScope,
+ config.shareKey,
+ version || false,
+ resource,
+ config.eager
+ ),
+ {
+ name: undefined
+ },
+ err => {
+ if (err) return reject(err);
+ resolve(null);
+ }
+ );
+ })
+ )
+ ).then(() => {});
+ });
+
+ compiler.hooks.compilation.tap(
+ "ProvideSharedPlugin",
+ (compilation, { normalModuleFactory }) => {
+ compilation.dependencyFactories.set(
+ ProvideForSharedDependency,
+ normalModuleFactory
+ );
+
+ compilation.dependencyFactories.set(
+ ProvideSharedDependency,
+ new ProvideSharedModuleFactory()
+ );
+ }
+ );
+ }
+}
+
+module.exports = ProvideSharedPlugin;
diff --git a/node_modules/webpack/lib/sharing/SharePlugin.js b/node_modules/webpack/lib/sharing/SharePlugin.js
new file mode 100644
index 00000000..65935b30
--- /dev/null
+++ b/node_modules/webpack/lib/sharing/SharePlugin.js
@@ -0,0 +1,92 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra and Zackary Jackson @ScriptedAlchemy
+*/
+
+"use strict";
+
+const { parseOptions } = require("../container/options");
+const ConsumeSharedPlugin = require("./ConsumeSharedPlugin");
+const ProvideSharedPlugin = require("./ProvideSharedPlugin");
+const { isRequiredVersion } = require("./utils");
+
+/** @typedef {import("../../declarations/plugins/sharing/ConsumeSharedPlugin").ConsumeSharedPluginOptions} ConsumeSharedPluginOptions */
+/** @typedef {import("../../declarations/plugins/sharing/ConsumeSharedPlugin").ConsumesConfig} ConsumesConfig */
+/** @typedef {import("../../declarations/plugins/sharing/ProvideSharedPlugin").ProvideSharedPluginOptions} ProvideSharedPluginOptions */
+/** @typedef {import("../../declarations/plugins/sharing/ProvideSharedPlugin").ProvidesConfig} ProvidesConfig */
+/** @typedef {import("../../declarations/plugins/sharing/SharePlugin").SharePluginOptions} SharePluginOptions */
+/** @typedef {import("../../declarations/plugins/sharing/SharePlugin").SharedConfig} SharedConfig */
+/** @typedef {import("../Compiler")} Compiler */
+
+class SharePlugin {
+ /**
+ * @param {SharePluginOptions} options options
+ */
+ constructor(options) {
+ /** @type {[string, SharedConfig][]} */
+ const sharedOptions = parseOptions(
+ options.shared,
+ (item, key) => {
+ if (typeof item !== "string")
+ throw new Error("Unexpected array in shared");
+ /** @type {SharedConfig} */
+ const config =
+ item === key || !isRequiredVersion(item)
+ ? {
+ import: item
+ }
+ : {
+ import: key,
+ requiredVersion: item
+ };
+ return config;
+ },
+ item => item
+ );
+ /** @type {Record<string, ConsumesConfig>[]} */
+ const consumes = sharedOptions.map(([key, options]) => ({
+ [key]: {
+ import: options.import,
+ shareKey: options.shareKey || key,
+ shareScope: options.shareScope,
+ requiredVersion: options.requiredVersion,
+ strictVersion: options.strictVersion,
+ singleton: options.singleton,
+ packageName: options.packageName,
+ eager: options.eager
+ }
+ }));
+ /** @type {Record<string, ProvidesConfig>[]} */
+ const provides = sharedOptions
+ .filter(([, options]) => options.import !== false)
+ .map(([key, options]) => ({
+ [options.import || key]: {
+ shareKey: options.shareKey || key,
+ shareScope: options.shareScope,
+ version: options.version,
+ eager: options.eager
+ }
+ }));
+ this._shareScope = options.shareScope;
+ this._consumes = consumes;
+ this._provides = provides;
+ }
+
+ /**
+ * Apply the plugin
+ * @param {Compiler} compiler the compiler instance
+ * @returns {void}
+ */
+ apply(compiler) {
+ new ConsumeSharedPlugin({
+ shareScope: this._shareScope,
+ consumes: this._consumes
+ }).apply(compiler);
+ new ProvideSharedPlugin({
+ shareScope: this._shareScope,
+ provides: this._provides
+ }).apply(compiler);
+ }
+}
+
+module.exports = SharePlugin;
diff --git a/node_modules/webpack/lib/sharing/ShareRuntimeModule.js b/node_modules/webpack/lib/sharing/ShareRuntimeModule.js
new file mode 100644
index 00000000..0f63ef68
--- /dev/null
+++ b/node_modules/webpack/lib/sharing/ShareRuntimeModule.js
@@ -0,0 +1,151 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RuntimeGlobals = require("../RuntimeGlobals");
+const RuntimeModule = require("../RuntimeModule");
+const Template = require("../Template");
+const {
+ compareModulesByIdentifier,
+ compareStrings
+} = require("../util/comparators");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../ChunkGraph")} ChunkGraph */
+/** @typedef {import("../Compilation")} Compilation */
+
+class ShareRuntimeModule extends RuntimeModule {
+ constructor() {
+ super("sharing");
+ }
+
+ /**
+ * @returns {string | null} runtime code
+ */
+ generate() {
+ const compilation = /** @type {Compilation} */ (this.compilation);
+ const {
+ runtimeTemplate,
+ codeGenerationResults,
+ outputOptions: { uniqueName, ignoreBrowserWarnings }
+ } = compilation;
+ const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph);
+ /** @type {Map<string, Map<number, Set<string>>>} */
+ const initCodePerScope = new Map();
+ for (const chunk of /** @type {Chunk} */ (
+ this.chunk
+ ).getAllReferencedChunks()) {
+ const modules = chunkGraph.getOrderedChunkModulesIterableBySourceType(
+ chunk,
+ "share-init",
+ compareModulesByIdentifier
+ );
+ if (!modules) continue;
+ for (const m of modules) {
+ const data = codeGenerationResults.getData(
+ m,
+ chunk.runtime,
+ "share-init"
+ );
+ if (!data) continue;
+ for (const item of data) {
+ const { shareScope, initStage, init } = item;
+ let stages = initCodePerScope.get(shareScope);
+ if (stages === undefined) {
+ initCodePerScope.set(shareScope, (stages = new Map()));
+ }
+ let list = stages.get(initStage || 0);
+ if (list === undefined) {
+ stages.set(initStage || 0, (list = new Set()));
+ }
+ list.add(init);
+ }
+ }
+ }
+ return Template.asString([
+ `${RuntimeGlobals.shareScopeMap} = {};`,
+ "var initPromises = {};",
+ "var initTokens = {};",
+ `${RuntimeGlobals.initializeSharing} = ${runtimeTemplate.basicFunction(
+ "name, initScope",
+ [
+ "if(!initScope) initScope = [];",
+ "// handling circular init calls",
+ "var initToken = initTokens[name];",
+ "if(!initToken) initToken = initTokens[name] = {};",
+ "if(initScope.indexOf(initToken) >= 0) return;",
+ "initScope.push(initToken);",
+ "// only runs once",
+ "if(initPromises[name]) return initPromises[name];",
+ "// creates a new share scope if needed",
+ `if(!${RuntimeGlobals.hasOwnProperty}(${RuntimeGlobals.shareScopeMap}, name)) ${RuntimeGlobals.shareScopeMap}[name] = {};`,
+ "// runs all init snippets from all modules reachable",
+ `var scope = ${RuntimeGlobals.shareScopeMap}[name];`,
+ `var warn = ${
+ ignoreBrowserWarnings
+ ? runtimeTemplate.basicFunction("", "")
+ : runtimeTemplate.basicFunction("msg", [
+ 'if (typeof console !== "undefined" && console.warn) console.warn(msg);'
+ ])
+ };`,
+ `var uniqueName = ${JSON.stringify(uniqueName || undefined)};`,
+ `var register = ${runtimeTemplate.basicFunction(
+ "name, version, factory, eager",
+ [
+ "var versions = scope[name] = scope[name] || {};",
+ "var activeVersion = versions[version];",
+ "if(!activeVersion || (!activeVersion.loaded && (!eager != !activeVersion.eager ? eager : uniqueName > activeVersion.from))) versions[version] = { get: factory, from: uniqueName, eager: !!eager };"
+ ]
+ )};`,
+ `var initExternal = ${runtimeTemplate.basicFunction("id", [
+ `var handleError = ${runtimeTemplate.expressionFunction(
+ 'warn("Initialization of sharing external failed: " + err)',
+ "err"
+ )};`,
+ "try {",
+ Template.indent([
+ `var module = ${RuntimeGlobals.require}(id);`,
+ "if(!module) return;",
+ `var initFn = ${runtimeTemplate.returningFunction(
+ `module && module.init && module.init(${RuntimeGlobals.shareScopeMap}[name], initScope)`,
+ "module"
+ )}`,
+ "if(module.then) return promises.push(module.then(initFn, handleError));",
+ "var initResult = initFn(module);",
+ "if(initResult && initResult.then) return promises.push(initResult['catch'](handleError));"
+ ]),
+ "} catch(err) { handleError(err); }"
+ ])}`,
+ "var promises = [];",
+ "switch(name) {",
+ ...Array.from(initCodePerScope)
+ .sort(([a], [b]) => compareStrings(a, b))
+ .map(([name, stages]) =>
+ Template.indent([
+ `case ${JSON.stringify(name)}: {`,
+ Template.indent(
+ Array.from(stages)
+ .sort(([a], [b]) => a - b)
+ .map(([, initCode]) =>
+ Template.asString(Array.from(initCode))
+ )
+ ),
+ "}",
+ "break;"
+ ])
+ ),
+ "}",
+ "if(!promises.length) return initPromises[name] = 1;",
+ `return initPromises[name] = Promise.all(promises).then(${runtimeTemplate.returningFunction(
+ "initPromises[name] = 1"
+ )});`
+ ]
+ )};`
+ ]);
+ }
+}
+
+module.exports = ShareRuntimeModule;
diff --git a/node_modules/webpack/lib/sharing/resolveMatchedConfigs.js b/node_modules/webpack/lib/sharing/resolveMatchedConfigs.js
new file mode 100644
index 00000000..a54a76ab
--- /dev/null
+++ b/node_modules/webpack/lib/sharing/resolveMatchedConfigs.js
@@ -0,0 +1,92 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const ModuleNotFoundError = require("../ModuleNotFoundError");
+const LazySet = require("../util/LazySet");
+
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../ResolverFactory").ResolveOptionsWithDependencyType} ResolveOptionsWithDependencyType */
+
+/**
+ * @template T
+ * @typedef {object} MatchedConfigs
+ * @property {Map<string, T>} resolved
+ * @property {Map<string, T>} unresolved
+ * @property {Map<string, T>} prefixed
+ */
+
+/** @type {ResolveOptionsWithDependencyType} */
+const RESOLVE_OPTIONS = { dependencyType: "esm" };
+
+/**
+ * @template T
+ * @param {Compilation} compilation the compilation
+ * @param {[string, T][]} configs to be processed configs
+ * @returns {Promise<MatchedConfigs<T>>} resolved matchers
+ */
+module.exports.resolveMatchedConfigs = (compilation, configs) => {
+ /** @type {Map<string, T>} */
+ const resolved = new Map();
+ /** @type {Map<string, T>} */
+ const unresolved = new Map();
+ /** @type {Map<string, T>} */
+ const prefixed = new Map();
+ const resolveContext = {
+ /** @type {LazySet<string>} */
+ fileDependencies: new LazySet(),
+ /** @type {LazySet<string>} */
+ contextDependencies: new LazySet(),
+ /** @type {LazySet<string>} */
+ missingDependencies: new LazySet()
+ };
+ const resolver = compilation.resolverFactory.get("normal", RESOLVE_OPTIONS);
+ const context = compilation.compiler.context;
+
+ return Promise.all(
+ // eslint-disable-next-line array-callback-return
+ configs.map(([request, config]) => {
+ if (/^\.\.?(\/|$)/.test(request)) {
+ // relative request
+ return new Promise(resolve => {
+ resolver.resolve(
+ {},
+ context,
+ request,
+ resolveContext,
+ (err, result) => {
+ if (err || result === false) {
+ err = err || new Error(`Can't resolve ${request}`);
+ compilation.errors.push(
+ new ModuleNotFoundError(null, err, {
+ name: `shared module ${request}`
+ })
+ );
+ return resolve(null);
+ }
+ resolved.set(/** @type {string} */ (result), config);
+ resolve(null);
+ }
+ );
+ });
+ } else if (/^(\/|[A-Za-z]:\\|\\\\)/.test(request)) {
+ // absolute path
+ resolved.set(request, config);
+ } else if (request.endsWith("/")) {
+ // module request prefix
+ prefixed.set(request, config);
+ } else {
+ // module request
+ unresolved.set(request, config);
+ }
+ })
+ ).then(() => {
+ compilation.contextDependencies.addAll(resolveContext.contextDependencies);
+ compilation.fileDependencies.addAll(resolveContext.fileDependencies);
+ compilation.missingDependencies.addAll(resolveContext.missingDependencies);
+ return { resolved, unresolved, prefixed };
+ });
+};
diff --git a/node_modules/webpack/lib/sharing/utils.js b/node_modules/webpack/lib/sharing/utils.js
new file mode 100644
index 00000000..29aa4d6e
--- /dev/null
+++ b/node_modules/webpack/lib/sharing/utils.js
@@ -0,0 +1,394 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { join, dirname, readJson } = require("../util/fs");
+
+/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
+/** @typedef {import("../util/fs").JsonObject} JsonObject */
+/** @typedef {import("../util/fs").JsonPrimitive} JsonPrimitive */
+
+// Extreme shorthand only for github. eg: foo/bar
+const RE_URL_GITHUB_EXTREME_SHORT = /^[^/@:.\s][^/@:\s]*\/[^@:\s]*[^/@:\s]#\S+/;
+
+// Short url with specific protocol. eg: github:foo/bar
+const RE_GIT_URL_SHORT = /^(github|gitlab|bitbucket|gist):\/?[^/.]+\/?/i;
+
+// Currently supported protocols
+const RE_PROTOCOL =
+ /^((git\+)?(ssh|https?|file)|git|github|gitlab|bitbucket|gist):$/i;
+
+// Has custom protocol
+const RE_CUSTOM_PROTOCOL = /^((git\+)?(ssh|https?|file)|git):\/\//i;
+
+// Valid hash format for npm / yarn ...
+const RE_URL_HASH_VERSION = /#(?:semver:)?(.+)/;
+
+// Simple hostname validate
+const RE_HOSTNAME = /^(?:[^/.]+(\.[^/]+)+|localhost)$/;
+
+// For hostname with colon. eg: ssh://user@github.com:foo/bar
+const RE_HOSTNAME_WITH_COLON =
+ /([^/@#:.]+(?:\.[^/@#:.]+)+|localhost):([^#/0-9]+)/;
+
+// Reg for url without protocol
+const RE_NO_PROTOCOL = /^([^/@#:.]+(?:\.[^/@#:.]+)+)/;
+
+// RegExp for version string
+const VERSION_PATTERN_REGEXP = /^([\d^=v<>~]|[*xX]$)/;
+
+// Specific protocol for short url without normal hostname
+const PROTOCOLS_FOR_SHORT = [
+ "github:",
+ "gitlab:",
+ "bitbucket:",
+ "gist:",
+ "file:"
+];
+
+// Default protocol for git url
+const DEF_GIT_PROTOCOL = "git+ssh://";
+
+// thanks to https://github.com/npm/hosted-git-info/blob/latest/git-host-info.js
+const extractCommithashByDomain = {
+ /**
+ * @param {string} pathname pathname
+ * @param {string} hash hash
+ * @returns {string | undefined} hash
+ */
+ "github.com": (pathname, hash) => {
+ let [, user, project, type, commithash] = pathname.split("/", 5);
+ if (type && type !== "tree") {
+ return;
+ }
+
+ commithash = !type ? hash : `#${commithash}`;
+
+ if (project && project.endsWith(".git")) {
+ project = project.slice(0, -4);
+ }
+
+ if (!user || !project) {
+ return;
+ }
+
+ return commithash;
+ },
+ /**
+ * @param {string} pathname pathname
+ * @param {string} hash hash
+ * @returns {string | undefined} hash
+ */
+ "gitlab.com": (pathname, hash) => {
+ const path = pathname.slice(1);
+ if (path.includes("/-/") || path.includes("/archive.tar.gz")) {
+ return;
+ }
+
+ const segments = path.split("/");
+ let project = /** @type {string} */ (segments.pop());
+ if (project.endsWith(".git")) {
+ project = project.slice(0, -4);
+ }
+
+ const user = segments.join("/");
+ if (!user || !project) {
+ return;
+ }
+
+ return hash;
+ },
+ /**
+ * @param {string} pathname pathname
+ * @param {string} hash hash
+ * @returns {string | undefined} hash
+ */
+ "bitbucket.org": (pathname, hash) => {
+ let [, user, project, aux] = pathname.split("/", 4);
+ if (["get"].includes(aux)) {
+ return;
+ }
+
+ if (project && project.endsWith(".git")) {
+ project = project.slice(0, -4);
+ }
+
+ if (!user || !project) {
+ return;
+ }
+
+ return hash;
+ },
+ /**
+ * @param {string} pathname pathname
+ * @param {string} hash hash
+ * @returns {string | undefined} hash
+ */
+ "gist.github.com": (pathname, hash) => {
+ let [, user, project, aux] = pathname.split("/", 4);
+ if (aux === "raw") {
+ return;
+ }
+
+ if (!project) {
+ if (!user) {
+ return;
+ }
+
+ project = user;
+ }
+
+ if (project.endsWith(".git")) {
+ project = project.slice(0, -4);
+ }
+
+ return hash;
+ }
+};
+
+/**
+ * extract commit hash from parsed url
+ * @inner
+ * @param {URL} urlParsed parsed url
+ * @returns {string} commithash
+ */
+function getCommithash(urlParsed) {
+ let { hostname, pathname, hash } = urlParsed;
+ hostname = hostname.replace(/^www\./, "");
+
+ try {
+ hash = decodeURIComponent(hash);
+ // eslint-disable-next-line no-empty
+ } catch (_err) {}
+
+ if (
+ extractCommithashByDomain[
+ /** @type {keyof extractCommithashByDomain} */ (hostname)
+ ]
+ ) {
+ return (
+ extractCommithashByDomain[
+ /** @type {keyof extractCommithashByDomain} */ (hostname)
+ ](pathname, hash) || ""
+ );
+ }
+
+ return hash;
+}
+
+/**
+ * make url right for URL parse
+ * @inner
+ * @param {string} gitUrl git url
+ * @returns {string} fixed url
+ */
+function correctUrl(gitUrl) {
+ // like:
+ // proto://hostname.com:user/repo -> proto://hostname.com/user/repo
+ return gitUrl.replace(RE_HOSTNAME_WITH_COLON, "$1/$2");
+}
+
+/**
+ * make url protocol right for URL parse
+ * @inner
+ * @param {string} gitUrl git url
+ * @returns {string} fixed url
+ */
+function correctProtocol(gitUrl) {
+ // eg: github:foo/bar#v1.0. Should not add double slash, in case of error parsed `pathname`
+ if (RE_GIT_URL_SHORT.test(gitUrl)) {
+ return gitUrl;
+ }
+
+ // eg: user@github.com:foo/bar
+ if (!RE_CUSTOM_PROTOCOL.test(gitUrl)) {
+ return `${DEF_GIT_PROTOCOL}${gitUrl}`;
+ }
+
+ return gitUrl;
+}
+
+/**
+ * extract git dep version from hash
+ * @inner
+ * @param {string} hash hash
+ * @returns {string} git dep version
+ */
+function getVersionFromHash(hash) {
+ const matched = hash.match(RE_URL_HASH_VERSION);
+
+ return (matched && matched[1]) || "";
+}
+
+/**
+ * if string can be decoded
+ * @inner
+ * @param {string} str str to be checked
+ * @returns {boolean} if can be decoded
+ */
+function canBeDecoded(str) {
+ try {
+ decodeURIComponent(str);
+ } catch (_err) {
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * get right dep version from git url
+ * @inner
+ * @param {string} gitUrl git url
+ * @returns {string} dep version
+ */
+function getGitUrlVersion(gitUrl) {
+ const oriGitUrl = gitUrl;
+ // github extreme shorthand
+ gitUrl = RE_URL_GITHUB_EXTREME_SHORT.test(gitUrl)
+ ? `github:${gitUrl}`
+ : correctProtocol(gitUrl);
+
+ gitUrl = correctUrl(gitUrl);
+
+ let parsed;
+ try {
+ parsed = new URL(gitUrl);
+ // eslint-disable-next-line no-empty
+ } catch (_err) {}
+
+ if (!parsed) {
+ return "";
+ }
+
+ const { protocol, hostname, pathname, username, password } = parsed;
+ if (!RE_PROTOCOL.test(protocol)) {
+ return "";
+ }
+
+ // pathname shouldn't be empty or URL malformed
+ if (!pathname || !canBeDecoded(pathname)) {
+ return "";
+ }
+
+ // without protocol, there should have auth info
+ if (RE_NO_PROTOCOL.test(oriGitUrl) && !username && !password) {
+ return "";
+ }
+
+ if (!PROTOCOLS_FOR_SHORT.includes(protocol.toLowerCase())) {
+ if (!RE_HOSTNAME.test(hostname)) {
+ return "";
+ }
+
+ const commithash = getCommithash(parsed);
+ return getVersionFromHash(commithash) || commithash;
+ }
+
+ // for protocol short
+ return getVersionFromHash(gitUrl);
+}
+
+/**
+ * @param {string} str maybe required version
+ * @returns {boolean} true, if it looks like a version
+ */
+function isRequiredVersion(str) {
+ return VERSION_PATTERN_REGEXP.test(str);
+}
+
+module.exports.isRequiredVersion = isRequiredVersion;
+
+/**
+ * @see https://docs.npmjs.com/cli/v7/configuring-npm/package-json#urls-as-dependencies
+ * @param {string} versionDesc version to be normalized
+ * @returns {string} normalized version
+ */
+function normalizeVersion(versionDesc) {
+ versionDesc = (versionDesc && versionDesc.trim()) || "";
+
+ if (isRequiredVersion(versionDesc)) {
+ return versionDesc;
+ }
+
+ // add handle for URL Dependencies
+ return getGitUrlVersion(versionDesc.toLowerCase());
+}
+
+module.exports.normalizeVersion = normalizeVersion;
+
+/** @typedef {{ data: JsonObject, path: string }} DescriptionFile */
+
+/**
+ * @param {InputFileSystem} fs file system
+ * @param {string} directory directory to start looking into
+ * @param {string[]} descriptionFiles possible description filenames
+ * @param {function((Error | null)=, DescriptionFile=): void} callback callback
+ */
+const getDescriptionFile = (fs, directory, descriptionFiles, callback) => {
+ let i = 0;
+ const tryLoadCurrent = () => {
+ if (i >= descriptionFiles.length) {
+ const parentDirectory = dirname(fs, directory);
+ if (!parentDirectory || parentDirectory === directory) return callback();
+ return getDescriptionFile(
+ fs,
+ parentDirectory,
+ descriptionFiles,
+ callback
+ );
+ }
+ const filePath = join(fs, directory, descriptionFiles[i]);
+ readJson(fs, filePath, (err, data) => {
+ if (err) {
+ if ("code" in err && err.code === "ENOENT") {
+ i++;
+ return tryLoadCurrent();
+ }
+ return callback(err);
+ }
+ if (!data || typeof data !== "object" || Array.isArray(data)) {
+ return callback(
+ new Error(`Description file ${filePath} is not an object`)
+ );
+ }
+ callback(null, { data, path: filePath });
+ });
+ };
+ tryLoadCurrent();
+};
+module.exports.getDescriptionFile = getDescriptionFile;
+
+/**
+ * @param {JsonObject} data description file data i.e.: package.json
+ * @param {string} packageName name of the dependency
+ * @returns {string | undefined} normalized version
+ */
+const getRequiredVersionFromDescriptionFile = (data, packageName) => {
+ const dependencyTypes = [
+ "optionalDependencies",
+ "dependencies",
+ "peerDependencies",
+ "devDependencies"
+ ];
+
+ for (const dependencyType of dependencyTypes) {
+ const dependency = /** @type {JsonObject} */ (data[dependencyType]);
+ if (
+ dependency &&
+ typeof dependency === "object" &&
+ packageName in dependency
+ ) {
+ return normalizeVersion(
+ /** @type {Exclude<JsonPrimitive, null | boolean| number>} */ (
+ dependency[packageName]
+ )
+ );
+ }
+ }
+};
+module.exports.getRequiredVersionFromDescriptionFile =
+ getRequiredVersionFromDescriptionFile;