UNPKG

dependency-cruiser

Version:

Validate and visualize dependencies. With your rules. JavaScript, TypeScript, CoffeeScript. ES6, CommonJS, AMD.

242 lines (209 loc) 6.5 kB
import { accessSync, constants } from "node:fs"; import { isAbsolute } from "node:path"; import { RULES_FILE_NAME_SEARCH_ARRAY, DEFAULT_BASELINE_FILE_NAME, OUTPUT_TO, OUTPUT_TYPE, WEBPACK_CONFIG, TYPESCRIPT_CONFIG, BABEL_CONFIG, OLD_DEFAULT_RULES_FILE_NAME, } from "./defaults.mjs"; import { set } from "#utl/object-util.mjs"; import loadConfig from "#config-utl/extract-depcruise-config/index.mjs"; function getOptionValue(pDefault) { return (pValue) => (typeof pValue === "string" ? pValue : pDefault); } // eslint-disable-next-line complexity function normalizeConfigFileName(pCliOptions, pConfigWrapperName, pDefault) { let lOptions = structuredClone(pCliOptions); if (Object.hasOwn(lOptions, pConfigWrapperName)) { set( lOptions, `ruleSet.options.${pConfigWrapperName}.fileName`, getOptionValue(pDefault)(lOptions[pConfigWrapperName]), /* eslint security/detect-object-injection: 0 */ ); Reflect.deleteProperty(lOptions, pConfigWrapperName); } if ( (lOptions?.ruleSet?.options?.[pConfigWrapperName] ?? null) && !(lOptions?.ruleSet?.options?.[pConfigWrapperName]?.fileName ?? null) ) { set(lOptions, `ruleSet.options.${pConfigWrapperName}.fileName`, pDefault); } return lOptions; } function fileExists(pFileName) { try { accessSync(pFileName, constants.R_OK); return true; } catch (pError) { return false; } } function validateAndGetCustomRulesFileName(pValidate) { let lReturnValue = ""; if (fileExists(pValidate)) { lReturnValue = pValidate; } else { throw new Error( `Can't open config file '${pValidate}' for reading. Does it exist?\n` + ` - You can create a config file by running 'npx dependency-cruiser --init'\n` + ` - If you intended to run without a config file use --no-config\n`, ); } return lReturnValue; } function validateAndGetDefaultRulesFileName() { let lReturnValue = RULES_FILE_NAME_SEARCH_ARRAY.find(fileExists); if (typeof lReturnValue === "undefined") { throw new TypeError( `Can't open a config file (.dependency-cruiser.(c)js) at the default location. Does it exist?\n` + ` - You can create one by running 'npx dependency-cruiser --init'\n` + ` - Want to run a without a config file? Use --no-config\n`, ); } return lReturnValue; } function validateAndNormalizeRulesFileName(pValidate) { let lReturnValue = ""; if (typeof pValidate === "string") { lReturnValue = validateAndGetCustomRulesFileName(pValidate); } else { lReturnValue = validateAndGetDefaultRulesFileName(); } return lReturnValue; } function validateAndGetKnownViolationsFileName(pKnownViolations) { const lKnownViolationsFileName = typeof pKnownViolations === "string" ? pKnownViolations : DEFAULT_BASELINE_FILE_NAME; if (fileExists(lKnownViolationsFileName)) { return lKnownViolationsFileName; } else { throw new Error( `Can't open '${lKnownViolationsFileName}' for reading. Does it exist?\n` + ` (You can create a .dependency-cruiser-known-violations.json with --output-type baseline)\n`, ); } } function normalizeKnownViolationsOption(pCliOptions) { if ( !Object.hasOwn(pCliOptions, "ignoreKnown") || pCliOptions.ignoreKnown === false ) { return {}; } return { knownViolationsFile: validateAndGetKnownViolationsFileName( pCliOptions.ignoreKnown, ), }; } async function normalizeValidationOption(pCliOptions) { if (!pCliOptions.validate) { return { validate: false, }; } const rulesFile = validateAndNormalizeRulesFileName(pCliOptions.validate); return { rulesFile, ruleSet: await loadConfig( isAbsolute(rulesFile) ? rulesFile : `./${rulesFile}`, ), validate: true, }; } function normalizeProgress(pCliOptions) { if (!Object.hasOwn(pCliOptions, "progress")) { return {}; } let lProgress = pCliOptions.progress; if (lProgress === true) { lProgress = "cli-feedback"; } return { progress: lProgress }; } function normalizeCacheStrategy(pCliOptions) { if (!Object.hasOwn(pCliOptions, "cacheStrategy")) { return {}; } const lStrategy = pCliOptions.cacheStrategy === "content" ? "content" : "metadata"; let lReturnValue = {}; if (pCliOptions.cache && typeof pCliOptions.cache === "object") { lReturnValue.cache = structuredClone(pCliOptions.cache); lReturnValue.cache.strategy = lStrategy; } else { lReturnValue = { cache: { strategy: lStrategy, }, }; } return lReturnValue; } function normalizeCache(pCliOptions) { if (!Object.hasOwn(pCliOptions, "cache")) { return {}; } if (pCliOptions.cache === true) { return { cache: {} }; } if (typeof pCliOptions.cache === "string") { return { cache: { folder: pCliOptions.cache, }, }; } return { cache: false }; } /** * returns the pOptionsAsPassedFromCommander, so that the returned value contains a * valid value for each possible option * * @param {object} pOptionsAsPassedFromCommander [description] * @param {any} pKnownCliOptions [description] * @return {object} [description] */ export default async function normalizeOptions(pOptionsAsPassedFromCommander) { let lOptions = { outputTo: OUTPUT_TO, outputType: OUTPUT_TYPE, ...pOptionsAsPassedFromCommander, }; if (Object.hasOwn(lOptions, "moduleSystems")) { lOptions.moduleSystems = lOptions.moduleSystems .split(",") .map((pString) => pString.trim()); } if (Object.hasOwn(lOptions, "config")) { lOptions.validate = lOptions.config; } lOptions = { ...lOptions, ...(await normalizeValidationOption(lOptions)) }; lOptions = { ...lOptions, ...normalizeProgress(lOptions) }; lOptions = { ...lOptions, ...normalizeCache(lOptions) }; lOptions = { ...lOptions, ...normalizeCacheStrategy(lOptions) }; lOptions = { ...lOptions, ...normalizeKnownViolationsOption(lOptions) }; lOptions = normalizeConfigFileName(lOptions, "webpackConfig", WEBPACK_CONFIG); lOptions = normalizeConfigFileName(lOptions, "tsConfig", TYPESCRIPT_CONFIG); lOptions = normalizeConfigFileName(lOptions, "babelConfig", BABEL_CONFIG); if (Object.hasOwn(lOptions, "affected") && lOptions.affected !== false) { const { list } = await import("watskeburt"); lOptions.reaches = await list({ oldRevision: lOptions.affected === true ? "main" : lOptions.affected, outputType: "regex", extensions: "cjs,cjsx,coffee,csx,cts,js,json,jsx,litcoffee,ls,mjs,mts,svelte,ts,tsx,vue,vuex", }); } return lOptions; } export const determineRulesFileName = getOptionValue( OLD_DEFAULT_RULES_FILE_NAME, );