UNPKG

standardlint

Version:
319 lines (316 loc) 9.67 kB
import { writeResultsToDisk } from "./chunk-L32Q6UKV.mjs"; import { InvalidFiletreeError, MissingChecksError } from "./chunk-5SV5B36E.mjs"; import { checkForPresenceLicense } from "./chunk-362CGRNA.mjs"; import { checkForPresenceReadme } from "./chunk-6ZWM5VZF.mjs"; import { checkForPresenceSecurity } from "./chunk-J4LRGQSA.mjs"; import { checkForPresenceServiceMetadata } from "./chunk-SHYXWNSB.mjs"; import { checkForPresenceTemplateIssues } from "./chunk-EBQNDNYD.mjs"; import { checkForPresenceTemplatePullRequests } from "./chunk-LSIVFAXG.mjs"; import { checkForPresenceTests } from "./chunk-NIDKLSVY.mjs"; import { checkForThrowingPlainErrors } from "./chunk-37FSA54G.mjs"; import { checkForDefinedTags } from "./chunk-447E4RBH.mjs"; import { checkForPresenceApiSchema } from "./chunk-GUTXS3F4.mjs"; import { checkForPresenceChangelog } from "./chunk-ZW7NUELL.mjs"; import { checkForPresenceCiConfig } from "./chunk-XDCL32SQ.mjs"; import { checkForPresenceCodeowners } from "./chunk-V6647XWN.mjs"; import { checkForPresenceContributing } from "./chunk-PEDPJZRW.mjs"; import { checkForPresenceDiagramsFolder } from "./chunk-ETP4RFGG.mjs"; import { checkForPresenceIacConfig } from "./chunk-QBAQ5LU2.mjs"; import { getStatusCount } from "./chunk-32NR4PF5.mjs"; import { checkForConflictingLockfiles } from "./chunk-4T33K72S.mjs"; import { checkForConsoleUsage } from "./chunk-7VY2ZK2D.mjs"; import { checkForDefinedRelations } from "./chunk-PL2C7SFI.mjs"; import { checkForDefinedServiceLevelObjectives } from "./chunk-CIPMB3MM.mjs"; import { exists } from "./chunk-DRBJPZVI.mjs"; // src/domain/StandardLint.ts function createNewStandardLint(config, filetree) { return new StandardLint(config, filetree); } var StandardLint = class { defaultBasePathFallback = "."; defaultSeverityFallback = "error"; defaultIgnorePathsFallback = []; config; filetree = []; constructor(config, filetree) { this.config = this.makeConfig(config); if (filetree) { if (this.validateFiletree(filetree)) this.filetree = filetree; else throw new InvalidFiletreeError(); } } /** * @description Validate that the filetree is a non-empty array with only strings. */ validateFiletree(filetree) { if (filetree && Array.isArray(filetree) && filetree.length > 0) { if (filetree.every((path) => typeof path === "string")) return true; } return false; } /** * @description Validates and sanitizes user input and returns a valid Configuration. */ makeConfig(configInput) { const basePath = configInput?.basePath && exists(configInput.basePath) ? configInput.basePath : this.defaultBasePathFallback; const defaultSeverity = configInput?.defaultSeverity ? this.getValidatedSeverityLevel(configInput.defaultSeverity) : this.defaultSeverityFallback; const ignorePaths = configInput?.ignorePaths ? this.getSanitizedPaths(configInput.ignorePaths) : this.defaultIgnorePathsFallback; const checkList = Array.isArray(configInput?.checks) ? configInput?.checks : []; const checks = this.getValidatedChecks( checkList, defaultSeverity, ignorePaths ); return { basePath, checks, defaultSeverity }; } /** * @description Validates and sanitizes a requested Severity level. */ getValidatedSeverityLevel(severity) { const validSeverityLevels = ["warn", "error"]; if (validSeverityLevels.includes(severity)) return severity; return this.defaultSeverityFallback; } /** * @description Sanitizes provided paths or return empty array if none is provided. */ getSanitizedPaths(ignorePaths) { if (ignorePaths.length === 0) return []; return ignorePaths.filter((path) => typeof path === "string"); } /** * @description Validates and sanitizes a requested list of checks. * * Provide `defaultSeverity` as it's not yet available in the class `config` object * when running the validation. */ getValidatedChecks(checks, defaultSeverity, ignorePaths) { const validCheckNames = [ "all", "checkForConflictingLockfiles", "checkForConsoleUsage", "checkForDefinedRelations", "checkForDefinedServiceLevelObjectives", "checkForDefinedTags", "checkForPresenceApiSchema", "checkForPresenceChangelog", "checkForPresenceCiConfig", "checkForPresenceCodeowners", "checkForPresenceContributing", "checkForPresenceDiagramsFolder", "checkForPresenceIacConfig", "checkForPresenceLicense", "checkForPresenceReadme", "checkForPresenceSecurity", "checkForPresenceServiceMetadata", "checkForPresenceTemplateIssues", "checkForPresenceTemplatePullRequests", "checkForPresenceTests", "checkForThrowingPlainErrors" ]; const isValidCheckName = (name) => validCheckNames.includes(name); if (checks.includes("all")) { checks = validCheckNames; validCheckNames.shift(); } const validatedChecks = checks.map((check) => { if (typeof check === "string" && isValidCheckName(check)) return { name: check, severity: defaultSeverity, ignorePaths }; if (typeof check === "object" && isValidCheckName(check.name)) return { name: check.name, path: check.path || "", severity: this.getValidatedSeverityLevel( check.severity || defaultSeverity ), ignorePaths }; return { name: "" }; }).filter((check) => check.name); return validatedChecks; } /** * @description Orchestrates the running of all checks. */ check(writeOutputToDisk = false) { if (this.config.checks.length === 0) throw new MissingChecksError(); const results = this.config.checks.map( (check) => this.test(check) ); const checkResults = { passes: getStatusCount("pass", results), warnings: getStatusCount("warn", results), failures: getStatusCount("fail", results), results }; if (writeOutputToDisk) writeResultsToDisk(checkResults); return checkResults; } /** * @description Run test on an individual Check. */ test(check) { const { name, severity, path, ignorePaths } = check; const checksList = { checkForConflictingLockfiles: () => checkForConflictingLockfiles( severity, this.config.basePath, this.filetree ), checkForConsoleUsage: () => checkForConsoleUsage(severity, this.config.basePath, path, ignorePaths), checkForDefinedRelations: () => checkForDefinedRelations(severity, this.config.basePath, path), checkForDefinedServiceLevelObjectives: () => checkForDefinedServiceLevelObjectives( severity, this.config.basePath, path ), checkForDefinedTags: () => checkForDefinedTags(severity, this.config.basePath, path), checkForPresenceApiSchema: () => checkForPresenceApiSchema( severity, this.config.basePath, path, this.filetree ), checkForPresenceChangelog: () => checkForPresenceChangelog( severity, this.config.basePath, this.filetree ), checkForPresenceCiConfig: () => checkForPresenceCiConfig( severity, this.config.basePath, path, this.filetree ), checkForPresenceCodeowners: () => checkForPresenceCodeowners( severity, this.config.basePath, this.filetree ), checkForPresenceContributing: () => checkForPresenceContributing( severity, this.config.basePath, this.filetree ), checkForPresenceDiagramsFolder: () => checkForPresenceDiagramsFolder( severity, this.config.basePath, path, this.filetree ), checkForPresenceIacConfig: () => checkForPresenceIacConfig( severity, this.config.basePath, path, this.filetree ), checkForPresenceLicense: () => checkForPresenceLicense(severity, this.config.basePath, this.filetree), checkForPresenceReadme: () => checkForPresenceReadme(severity, this.config.basePath, this.filetree), checkForPresenceSecurity: () => checkForPresenceSecurity(severity, this.config.basePath, this.filetree), checkForPresenceServiceMetadata: () => checkForPresenceServiceMetadata( severity, this.config.basePath, path, this.filetree ), checkForPresenceTemplateIssues: () => checkForPresenceTemplateIssues( severity, this.config.basePath, path, this.filetree ), checkForPresenceTemplatePullRequests: () => checkForPresenceTemplatePullRequests( severity, this.config.basePath, path, this.filetree ), checkForPresenceTests: () => checkForPresenceTests( severity, this.config.basePath, path, ignorePaths ), checkForThrowingPlainErrors: () => checkForThrowingPlainErrors( severity, this.config.basePath, path, ignorePaths ) }; const result = checksList[name](); this.logResult(result); return result; } /** * @description Outputs a log with the check result. */ logResult(checkResult) { const { status, name } = checkResult; if (status === "pass") console.log("\u2705 PASS:", name); if (status === "warn") console.warn("\u26A0\uFE0F WARN:", name); if (status === "fail") console.error("\u274C FAIL:", name); } }; export { createNewStandardLint };