.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / stylelint / lib / augmentConfig.js
diff --git a/.config/coc/extensions/node_modules/coc-prettier/node_modules/stylelint/lib/augmentConfig.js b/.config/coc/extensions/node_modules/coc-prettier/node_modules/stylelint/lib/augmentConfig.js
new file mode 100644 (file)
index 0000000..ee2b700
--- /dev/null
@@ -0,0 +1,363 @@
+/* @flow */
+"use strict";
+const _ = require("lodash");
+const configurationError = require("./utils/configurationError");
+const dynamicRequire = require("./dynamicRequire");
+const getModulePath = require("./utils/getModulePath");
+const globjoin = require("globjoin");
+const normalizeRuleSettings = require("./normalizeRuleSettings");
+const path = require("path");
+const rules = require("./rules");
+
+// - Merges config and configOverrides
+// - Makes all paths absolute
+// - Merges extends
+function augmentConfigBasic(
+  stylelint /*: stylelint$internalApi*/,
+  config /*: stylelint$config*/,
+  configDir /*: string*/,
+  allowOverrides /*:: ?: boolean*/
+) /*: Promise<stylelint$config>*/ {
+  return Promise.resolve()
+    .then(() => {
+      if (!allowOverrides) return config;
+      return _.merge(config, stylelint._options.configOverrides);
+    })
+    .then(augmentedConfig => {
+      return extendConfig(stylelint, augmentedConfig, configDir);
+    })
+    .then(augmentedConfig => {
+      return absolutizePaths(augmentedConfig, configDir);
+    });
+}
+
+// Extended configs need to be run through augmentConfigBasic
+// but do not need the full treatment. Things like pluginFunctions
+// will be resolved and added by the parent config.
+function augmentConfigExtended(
+  stylelint /*: stylelint$internalApi*/,
+  cosmiconfigResultArg /*: ?{
+     config: stylelint$config,
+     filepath: string,
+   }*/
+) /*: Promise<?{ config: stylelint$config, filepath: string }>*/ {
+  const cosmiconfigResult = cosmiconfigResultArg; // Lock in for Flow
+  if (!cosmiconfigResult) return Promise.resolve(null);
+
+  const configDir = path.dirname(cosmiconfigResult.filepath || "");
+  const cleanedConfig = _.omit(cosmiconfigResult.config, "ignoreFiles");
+  return augmentConfigBasic(stylelint, cleanedConfig, configDir).then(
+    augmentedConfig => {
+      return {
+        config: augmentedConfig,
+        filepath: cosmiconfigResult.filepath
+      };
+    }
+  );
+}
+
+function augmentConfigFull(
+  stylelint /*: stylelint$internalApi*/,
+  cosmiconfigResultArg /*: ?{
+   config: stylelint$config,
+   filepath: string,
+  }*/
+) /*: Promise<?{ config: stylelint$config, filepath: string }>*/ {
+  const cosmiconfigResult = cosmiconfigResultArg; // Lock in for Flow
+  if (!cosmiconfigResult) return Promise.resolve(null);
+
+  const config = cosmiconfigResult.config,
+    filepath = cosmiconfigResult.filepath;
+
+  const configDir =
+    stylelint._options.configBasedir || path.dirname(filepath || "");
+
+  return augmentConfigBasic(stylelint, config, configDir, true)
+    .then(augmentedConfig => {
+      return addPluginFunctions(augmentedConfig);
+    })
+    .then(augmentedConfig => {
+      return addProcessorFunctions(augmentedConfig);
+    })
+    .then(augmentedConfig => {
+      if (!augmentedConfig.rules) {
+        throw configurationError(
+          'No rules found within configuration. Have you provided a "rules" property?'
+        );
+      }
+
+      return normalizeAllRuleSettings(augmentedConfig);
+    })
+    .then(augmentedConfig => {
+      return {
+        config: augmentedConfig,
+        filepath: cosmiconfigResult.filepath
+      };
+    });
+}
+
+// Make all paths in the config absolute:
+// - ignoreFiles
+// - plugins
+// - processors
+// (extends handled elsewhere)
+function absolutizePaths(
+  config /*: stylelint$config*/,
+  configDir /*: string*/
+) /*: stylelint$config*/ {
+  if (config.ignoreFiles) {
+    config.ignoreFiles = [].concat(config.ignoreFiles).map(glob => {
+      if (path.isAbsolute(glob.replace(/^!/, ""))) return glob;
+      return globjoin(configDir, glob);
+    });
+  }
+
+  if (config.plugins) {
+    config.plugins = [].concat(config.plugins).map(lookup => {
+      return getModulePath(configDir, lookup);
+    });
+  }
+
+  if (config.processors) {
+    config.processors = absolutizeProcessors(config.processors, configDir);
+  }
+
+  return config;
+}
+
+// Processors are absolutized in their own way because
+// they can be and return a string or an array
+function absolutizeProcessors(
+  processors /*: stylelint$configProcessors*/,
+  configDir /*: string*/
+) /*: stylelint$configProcessors*/ {
+  const normalizedProcessors = Array.isArray(processors)
+    ? processors
+    : [processors];
+
+  return normalizedProcessors.map(item => {
+    if (typeof item === "string") {
+      return getModulePath(configDir, item);
+    }
+
+    return [getModulePath(configDir, item[0]), item[1]];
+  });
+}
+
+function extendConfig(
+  stylelint /*: stylelint$internalApi*/,
+  config /*: stylelint$config*/,
+  configDir /*: string*/
+) /*: Promise<stylelint$config>*/ {
+  if (config.extends === undefined) return Promise.resolve(config);
+  const normalizedExtends = Array.isArray(config.extends)
+    ? config.extends
+    : [config.extends];
+
+  const originalWithoutExtends = _.omit(config, "extends");
+  const loadExtends = normalizedExtends.reduce(
+    (resultPromise, extendLookup) => {
+      return resultPromise.then(resultConfig => {
+        return loadExtendedConfig(
+          stylelint,
+          resultConfig,
+          configDir,
+          extendLookup
+        ).then(extendResult => {
+          if (!extendResult) return resultConfig;
+          return mergeConfigs(resultConfig, extendResult.config);
+        });
+      });
+    },
+    Promise.resolve(originalWithoutExtends)
+  );
+
+  return loadExtends.then(resultConfig => {
+    return mergeConfigs(resultConfig, originalWithoutExtends);
+  });
+}
+
+function loadExtendedConfig(
+  stylelint /*: stylelint$internalApi*/,
+  config /*: stylelint$config*/,
+  configDir /*: string*/,
+  extendLookup /*: string*/
+) /*: Promise<?{ config: stylelint$config, filepath: string }>*/ {
+  const extendPath = getModulePath(configDir, extendLookup);
+  return stylelint._extendExplorer.load(null, extendPath);
+}
+
+// When merging configs (via extends)
+// - plugin and processor arrays are joined
+// - rules are merged via Object.assign, so there is no attempt made to
+//   merge any given rule's settings. If b contains the same rule as a,
+//   b's rule settings will override a's rule settings entirely.
+// - Everything else is merged via Object.assign
+function mergeConfigs(
+  a /*: stylelint$config*/,
+  b /*: stylelint$config*/
+) /*: stylelint$config*/ {
+  const pluginMerger = {};
+  if (a.plugins || b.plugins) {
+    pluginMerger.plugins = [];
+    if (a.plugins) {
+      pluginMerger.plugins = pluginMerger.plugins.concat(a.plugins);
+    }
+    if (b.plugins) {
+      pluginMerger.plugins = _.uniq(pluginMerger.plugins.concat(b.plugins));
+    }
+  }
+
+  const processorMerger = {};
+  if (a.processors || b.processors) {
+    processorMerger.processors = [];
+    if (a.processors) {
+      processorMerger.processors = processorMerger.processors.concat(
+        a.processors
+      );
+    }
+    if (b.processors) {
+      processorMerger.processors = _.uniq(
+        processorMerger.processors.concat(b.processors)
+      );
+    }
+  }
+
+  const rulesMerger = {};
+  if (a.rules || b.rules) {
+    rulesMerger.rules = Object.assign({}, a.rules, b.rules);
+  }
+
+  const result = Object.assign(
+    {},
+    a,
+    b,
+    processorMerger,
+    pluginMerger,
+    rulesMerger
+  );
+  return result;
+}
+
+function addPluginFunctions(
+  config /*: stylelint$config*/
+) /*: stylelint$config*/ {
+  if (!config.plugins) return config;
+
+  const normalizedPlugins = Array.isArray(config.plugins)
+    ? config.plugins
+    : [config.plugins];
+
+  const pluginFunctions = normalizedPlugins.reduce((result, pluginLookup) => {
+    let pluginImport = dynamicRequire(pluginLookup);
+    // Handle either ES6 or CommonJS modules
+    pluginImport = pluginImport.default || pluginImport;
+
+    // A plugin can export either a single rule definition
+    // or an array of them
+    const normalizedPluginImport = Array.isArray(pluginImport)
+      ? pluginImport
+      : [pluginImport];
+
+    normalizedPluginImport.forEach(pluginRuleDefinition => {
+      if (!pluginRuleDefinition.ruleName) {
+        throw configurationError(
+          "stylelint v3+ requires plugins to expose a ruleName. " +
+            `The plugin "${
+              pluginLookup
+            }" is not doing this, so will not work ` +
+            "with stylelint v3+. Please file an issue with the plugin."
+        );
+      }
+
+      if (!_.includes(pluginRuleDefinition.ruleName, "/")) {
+        throw configurationError(
+          "stylelint v7+ requires plugin rules to be namspaced, " +
+            "i.e. only `plugin-namespace/plugin-rule-name` plugin rule names are supported. " +
+            `The plugin rule "${
+              pluginRuleDefinition.ruleName
+            }" does not do this, so will not work. ` +
+            "Please file an issue with the plugin."
+        );
+      }
+
+      result[pluginRuleDefinition.ruleName] = pluginRuleDefinition.rule;
+    });
+
+    return result;
+  }, {});
+
+  config.pluginFunctions = pluginFunctions;
+  return config;
+}
+
+function normalizeAllRuleSettings(
+  config /*: stylelint$config*/
+) /*: stylelint$config*/ {
+  const normalizedRules = {};
+  if (!config.rules) return config;
+  Object.keys(config.rules).forEach(ruleName => {
+    const rawRuleSettings = _.get(config, ["rules", ruleName]);
+    const rule =
+      rules[ruleName] || _.get(config, ["pluginFunctions", ruleName]);
+    if (!rule) {
+      throw configurationError(`Undefined rule ${ruleName}`);
+    }
+    normalizedRules[ruleName] = normalizeRuleSettings(
+      rawRuleSettings,
+      ruleName,
+      _.get(rule, "primaryOptionArray")
+    );
+  });
+  config.rules = normalizedRules;
+  return config;
+}
+
+// Given an array of processors strings, we want to add two
+// properties to the augmented config:
+// - codeProcessors: functions that will run on code as it comes in
+// - resultProcessors: functions that will run on results as they go out
+//
+// To create these properties, we need to:
+// - Find the processor module
+// - Intialize the processor module by calling its functions with any
+//   provided options
+// - Push the processor's code and result processors to their respective arrays
+const processorCache = new Map();
+function addProcessorFunctions(
+  config /*: stylelint$config*/
+) /*: stylelint$config*/ {
+  if (!config.processors) return config;
+
+  const codeProcessors = [];
+  const resultProcessors = [];
+  [].concat(config.processors).forEach(processorConfig => {
+    const processorKey = JSON.stringify(processorConfig);
+
+    let initializedProcessor;
+    if (processorCache.has(processorKey)) {
+      initializedProcessor = processorCache.get(processorKey);
+    } else {
+      processorConfig = [].concat(processorConfig);
+      const processorLookup = processorConfig[0];
+      const processorOptions = processorConfig[1];
+      let processor = dynamicRequire(processorLookup);
+      processor = processor.default || processor;
+      initializedProcessor = processor(processorOptions);
+      processorCache.set(processorKey, initializedProcessor);
+    }
+
+    if (initializedProcessor && initializedProcessor.code) {
+      codeProcessors.push(initializedProcessor.code);
+    }
+    if (initializedProcessor && initializedProcessor.result) {
+      resultProcessors.push(initializedProcessor.result);
+    }
+  });
+
+  config.codeProcessors = codeProcessors;
+  config.resultProcessors = resultProcessors;
+  return config;
+}
+
+module.exports = { augmentConfigExtended, augmentConfigFull };