UNPKG

@storm-software/eslint

Version:

A package containing the base ESLint configuration used by Storm Software across many projects.

298 lines (292 loc) 8.63 kB
'use strict'; var fs = require('fs'); var path = require('path'); // src/utils/tsconfig-path.ts // src/utils/correct-paths.ts var _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//; function normalizeWindowsPath(input = "") { if (!input) { return input; } return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase()); } var _UNC_REGEX = /^[/\\]{2}/; var _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/; var _DRIVE_LETTER_RE = /^[A-Za-z]:$/; var _ROOT_FOLDER_RE = /^\/([A-Za-z]:)?$/; var correctPaths = function(path) { if (!path || path.length === 0) { return "."; } path = normalizeWindowsPath(path); const isUNCPath = path.match(_UNC_REGEX); const isPathAbsolute = isAbsolute(path); const trailingSeparator = path[path.length - 1] === "/"; path = normalizeString(path, !isPathAbsolute); if (path.length === 0) { if (isPathAbsolute) { return "/"; } return trailingSeparator ? "./" : "."; } if (trailingSeparator) { path += "/"; } if (_DRIVE_LETTER_RE.test(path)) { path += "/"; } if (isUNCPath) { if (!isPathAbsolute) { return `//./${path}`; } return `//${path}`; } return isPathAbsolute && !isAbsolute(path) ? `/${path}` : path; }; var joinPaths = function(...segments) { let path = ""; for (const seg of segments) { if (!seg) { continue; } if (path.length > 0) { const pathTrailing = path[path.length - 1] === "/"; const segLeading = seg[0] === "/"; const both = pathTrailing && segLeading; if (both) { path += seg.slice(1); } else { path += pathTrailing || segLeading ? seg : `/${seg}`; } } else { path += seg; } } return correctPaths(path); }; function cwd() { if (typeof process !== "undefined" && typeof process.cwd === "function") { return process.cwd().replace(/\\/g, "/"); } return "/"; } var resolve = function(...arguments_) { arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument)); let resolvedPath = ""; let resolvedAbsolute = false; for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) { const path = index >= 0 ? arguments_[index] : cwd(); if (!path || path.length === 0) { continue; } resolvedPath = `${path}/${resolvedPath}`; resolvedAbsolute = isAbsolute(path); } resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute); if (resolvedAbsolute && !isAbsolute(resolvedPath)) { return `/${resolvedPath}`; } return resolvedPath.length > 0 ? resolvedPath : "."; }; function normalizeString(path, allowAboveRoot) { let res = ""; let lastSegmentLength = 0; let lastSlash = -1; let dots = 0; let char = null; for (let index = 0; index <= path.length; ++index) { if (index < path.length) { char = path[index]; } else if (char === "/") { break; } else { char = "/"; } if (char === "/") { if (lastSlash === index - 1 || dots === 1) ; else if (dots === 2) { if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") { if (res.length > 2) { const lastSlashIndex = res.lastIndexOf("/"); if (lastSlashIndex === -1) { res = ""; lastSegmentLength = 0; } else { res = res.slice(0, lastSlashIndex); lastSegmentLength = res.length - 1 - res.lastIndexOf("/"); } lastSlash = index; dots = 0; continue; } else if (res.length > 0) { res = ""; lastSegmentLength = 0; lastSlash = index; dots = 0; continue; } } if (allowAboveRoot) { res += res.length > 0 ? "/.." : ".."; lastSegmentLength = 2; } } else { if (res.length > 0) { res += `/${path.slice(lastSlash + 1, index)}`; } else { res = path.slice(lastSlash + 1, index); } lastSegmentLength = index - lastSlash - 1; } lastSlash = index; dots = 0; } else if (char === "." && dots !== -1) { ++dots; } else { dots = -1; } } return res; } var isAbsolute = function(p) { return _IS_ABSOLUTE_RE.test(p); }; var relative = function(from, to) { const _from = resolve(from).replace(_ROOT_FOLDER_RE, "$1").split("/"); const _to = resolve(to).replace(_ROOT_FOLDER_RE, "$1").split("/"); if (_to[0][1] === ":" && _from[0][1] === ":" && _from[0] !== _to[0]) { return _to.join("/"); } const _fromCopy = [..._from]; for (const segment of _fromCopy) { if (_to[0] !== segment) { break; } _from.shift(); _to.shift(); } return [..._from.map(() => ".."), ..._to].join("/"); }; var MAX_PATH_SEARCH_DEPTH = 30; var depth = 0; function findFolderUp(startPath, endFileNames = [], endDirectoryNames = []) { const _startPath = startPath ?? process.cwd(); if (endDirectoryNames.some( (endDirName) => fs.existsSync(path.join(_startPath, endDirName)) )) { return _startPath; } if (endFileNames.some((endFileName) => fs.existsSync(path.join(_startPath, endFileName)))) { return _startPath; } if (_startPath !== "/" && depth++ < MAX_PATH_SEARCH_DEPTH) { const parent = path.join(_startPath, ".."); return findFolderUp(parent, endFileNames, endDirectoryNames); } return void 0; } var rootFiles = [ "storm-workspace.json", "storm-workspace.json", "storm-workspace.yaml", "storm-workspace.yml", "storm-workspace.js", "storm-workspace.ts", ".storm-workspace.json", ".storm-workspace.yaml", ".storm-workspace.yml", ".storm-workspace.js", ".storm-workspace.ts", "lerna.json", "nx.json", "turbo.json", "npm-workspace.json", "yarn-workspace.json", "pnpm-workspace.json", "npm-workspace.yaml", "yarn-workspace.yaml", "pnpm-workspace.yaml", "npm-workspace.yml", "yarn-workspace.yml", "pnpm-workspace.yml", "npm-lock.json", "yarn-lock.json", "pnpm-lock.json", "npm-lock.yaml", "yarn-lock.yaml", "pnpm-lock.yaml", "npm-lock.yml", "yarn-lock.yml", "pnpm-lock.yml", "bun.lockb" ]; var rootDirectories = [ ".storm-workspace", ".nx", ".github", ".vscode", ".verdaccio" ]; function findWorkspaceRootSafe(pathInsideMonorepo) { if (process.env.STORM_WORKSPACE_ROOT || process.env.NX_WORKSPACE_ROOT_PATH) { return correctPaths( process.env.STORM_WORKSPACE_ROOT ?? process.env.NX_WORKSPACE_ROOT_PATH ); } return correctPaths( findFolderUp( process.cwd(), rootFiles, rootDirectories ) ); } function findWorkspaceRoot(pathInsideMonorepo) { const result = findWorkspaceRootSafe(); if (!result) { throw new Error( `Cannot find workspace root upwards from known path. Files search list includes: ${rootFiles.join( "\n" )} Path: ${process.cwd()}` ); } return result; } // src/utils/tsconfig-path.ts function getTsConfigPath(tsconfigPath, type = "app") { const workspaceRoot = findWorkspaceRoot(); if (tsconfigPath && fs.existsSync(tsconfigPath) && fs.statSync(tsconfigPath).isFile()) { return relative(workspaceRoot, tsconfigPath); } let result = checkTsConfigPath(process.cwd()); if (result) { return relative(workspaceRoot, joinPaths(process.cwd(), result)); } result = checkTsConfigPath(workspaceRoot); if (result) { return result; } console.warn( `No tsconfig.json found${tsconfigPath ? ` provided: ${tsconfigPath}` : ""}. Consider adding a tsconfig.json file to your project's ESLint configuration.` ); return workspaceRoot?.replace(/\\/g, "/").replaceAll(/\/$/g, "") === process.cwd().replace(/\\/g, "/").replaceAll(/\/$/g, "") ? "tsconfig.base.json" : `tsconfig.${type}.json`; } function checkTsConfigPath(root) { if (fs.existsSync(joinPaths(root, "tsconfig.json"))) { return "tsconfig.json"; } else if (fs.existsSync(joinPaths(root, "tsconfig.base.json"))) { return "tsconfig.base.json"; } else if (fs.existsSync(joinPaths(root, "tsconfig.app.json"))) { return "tsconfig.app.json"; } else if (fs.existsSync(joinPaths(root, "tsconfig.lib.json"))) { return "tsconfig.lib.json"; } else if (fs.existsSync(joinPaths(root, "tsconfig.eslint.json"))) { return "tsconfig.eslint.json"; } else if (fs.existsSync(joinPaths(root, "tsconfig.lint.json"))) { return "tsconfig.lint.json"; } return void 0; } exports.checkTsConfigPath = checkTsConfigPath; exports.getTsConfigPath = getTsConfigPath;