summaryrefslogtreecommitdiff
path: root/node_modules/enhanced-resolve/lib/DescriptionFileUtils.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/enhanced-resolve/lib/DescriptionFileUtils.js')
-rw-r--r--node_modules/enhanced-resolve/lib/DescriptionFileUtils.js198
1 files changed, 198 insertions, 0 deletions
diff --git a/node_modules/enhanced-resolve/lib/DescriptionFileUtils.js b/node_modules/enhanced-resolve/lib/DescriptionFileUtils.js
new file mode 100644
index 00000000..cfa970bc
--- /dev/null
+++ b/node_modules/enhanced-resolve/lib/DescriptionFileUtils.js
@@ -0,0 +1,198 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const forEachBail = require("./forEachBail");
+
+/** @typedef {import("./Resolver")} Resolver */
+/** @typedef {import("./Resolver").JsonObject} JsonObject */
+/** @typedef {import("./Resolver").JsonValue} JsonValue */
+/** @typedef {import("./Resolver").ResolveContext} ResolveContext */
+/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
+
+/**
+ * @typedef {Object} DescriptionFileInfo
+ * @property {JsonObject=} content
+ * @property {string} path
+ * @property {string} directory
+ */
+
+/**
+ * @callback ErrorFirstCallback
+ * @param {Error|null=} error
+ * @param {DescriptionFileInfo=} result
+ */
+
+/**
+ * @typedef {Object} Result
+ * @property {string} path path to description file
+ * @property {string} directory directory of description file
+ * @property {JsonObject} content content of description file
+ */
+
+/**
+ * @param {Resolver} resolver resolver
+ * @param {string} directory directory
+ * @param {string[]} filenames filenames
+ * @param {DescriptionFileInfo|undefined} oldInfo oldInfo
+ * @param {ResolveContext} resolveContext resolveContext
+ * @param {ErrorFirstCallback} callback callback
+ */
+function loadDescriptionFile(
+ resolver,
+ directory,
+ filenames,
+ oldInfo,
+ resolveContext,
+ callback
+) {
+ (function findDescriptionFile() {
+ if (oldInfo && oldInfo.directory === directory) {
+ // We already have info for this directory and can reuse it
+ return callback(null, oldInfo);
+ }
+ forEachBail(
+ filenames,
+ /**
+ * @param {string} filename filename
+ * @param {(err?: null|Error, result?: null|Result) => void} callback callback
+ * @returns {void}
+ */
+ (filename, callback) => {
+ const descriptionFilePath = resolver.join(directory, filename);
+ if (resolver.fileSystem.readJson) {
+ resolver.fileSystem.readJson(descriptionFilePath, (err, content) => {
+ if (err) {
+ if (typeof err.code !== "undefined") {
+ if (resolveContext.missingDependencies) {
+ resolveContext.missingDependencies.add(descriptionFilePath);
+ }
+ return callback();
+ }
+ if (resolveContext.fileDependencies) {
+ resolveContext.fileDependencies.add(descriptionFilePath);
+ }
+ return onJson(err);
+ }
+ if (resolveContext.fileDependencies) {
+ resolveContext.fileDependencies.add(descriptionFilePath);
+ }
+ onJson(null, /** @type {JsonObject} */ (content));
+ });
+ } else {
+ resolver.fileSystem.readFile(descriptionFilePath, (err, content) => {
+ if (err) {
+ if (resolveContext.missingDependencies) {
+ resolveContext.missingDependencies.add(descriptionFilePath);
+ }
+ return callback();
+ }
+ if (resolveContext.fileDependencies) {
+ resolveContext.fileDependencies.add(descriptionFilePath);
+ }
+
+ /** @type {JsonObject | undefined} */
+ let json;
+
+ if (content) {
+ try {
+ json = JSON.parse(content.toString());
+ } catch (/** @type {unknown} */ e) {
+ return onJson(/** @type {Error} */ (e));
+ }
+ } else {
+ return onJson(new Error("No content in file"));
+ }
+
+ onJson(null, json);
+ });
+ }
+
+ /**
+ * @param {null|Error} [err] error
+ * @param {JsonObject} [content] content
+ * @returns {void}
+ */
+ function onJson(err, content) {
+ if (err) {
+ if (resolveContext.log)
+ resolveContext.log(
+ descriptionFilePath + " (directory description file): " + err
+ );
+ else
+ err.message =
+ descriptionFilePath + " (directory description file): " + err;
+ return callback(err);
+ }
+ callback(null, {
+ content: /** @type {JsonObject} */ (content),
+ directory,
+ path: descriptionFilePath
+ });
+ }
+ },
+ /**
+ * @param {null|Error} [err] error
+ * @param {null|Result} [result] result
+ * @returns {void}
+ */
+ (err, result) => {
+ if (err) return callback(err);
+ if (result) {
+ return callback(null, result);
+ } else {
+ const dir = cdUp(directory);
+ if (!dir) {
+ return callback();
+ } else {
+ directory = dir;
+ return findDescriptionFile();
+ }
+ }
+ }
+ );
+ })();
+}
+
+/**
+ * @param {JsonObject} content content
+ * @param {string|string[]} field field
+ * @returns {JsonValue | undefined} field data
+ */
+function getField(content, field) {
+ if (!content) return undefined;
+ if (Array.isArray(field)) {
+ /** @type {JsonValue} */
+ let current = content;
+ for (let j = 0; j < field.length; j++) {
+ if (current === null || typeof current !== "object") {
+ current = null;
+ break;
+ }
+ current = /** @type {JsonObject} */ (current)[field[j]];
+ }
+ return current;
+ } else {
+ return content[field];
+ }
+}
+
+/**
+ * @param {string} directory directory
+ * @returns {string|null} parent directory or null
+ */
+function cdUp(directory) {
+ if (directory === "/") return null;
+ const i = directory.lastIndexOf("/"),
+ j = directory.lastIndexOf("\\");
+ const p = i < 0 ? j : j < 0 ? i : i < j ? j : i;
+ if (p < 0) return null;
+ return directory.slice(0, p || 1);
+}
+
+exports.loadDescriptionFile = loadDescriptionFile;
+exports.getField = getField;
+exports.cdUp = cdUp;