"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.pipeline = void 0;
exports.getParentDir = getParentDir;
exports.getSiblingFileName = getSiblingFileName;
exports.readLocalFile = readLocalFile;
exports.readLocalSymlink = readLocalSymlink;
exports.writeLocalFile = writeLocalFile;
exports.deleteLocalFile = deleteLocalFile;
exports.renameLocalFile = renameLocalFile;
exports.ensureDir = ensureDir;
exports.ensureLocalDir = ensureLocalDir;
exports.ensureCacheDir = ensureCacheDir;
exports.privateCacheDir = privateCacheDir;
exports.localPathExists = localPathExists;
exports.isValidLocalPath = isValidLocalPath;
exports.findLocalSiblingOrParent = findLocalSiblingOrParent;
exports.readLocalDirectory = readLocalDirectory;
exports.createCacheWriteStream = createCacheWriteStream;
exports.createCacheReadStream = createCacheReadStream;
exports.localPathIsFile = localPathIsFile;
exports.localPathIsSymbolicLink = localPathIsSymbolicLink;
exports.findUpLocal = findUpLocal;
exports.chmodLocalFile = chmodLocalFile;
exports.statLocalFile = statLocalFile;
exports.statCacheFile = statCacheFile;
exports.listCacheDir = listCacheDir;
exports.rmCache = rmCache;
exports.cachePathExists = cachePathExists;
exports.cachePathIsFile = cachePathIsFile;
exports.readCacheFile = readCacheFile;
exports.outputCacheFile = outputCacheFile;
exports.readSystemFile = readSystemFile;
exports.writeSystemFile = writeSystemFile;
exports.getLocalFiles = getLocalFiles;
const tslib_1 = require("tslib");
const node_stream_1 = tslib_1.__importDefault(require("node:stream"));
const node_util_1 = tslib_1.__importDefault(require("node:util"));
const is_1 = tslib_1.__importDefault(require("@sindresorhus/is"));
const find_up_1 = tslib_1.__importDefault(require("find-up"));
const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
const upath_1 = tslib_1.__importDefault(require("upath"));
const global_1 = require("../../config/global");
const logger_1 = require("../../logger");
const util_1 = require("./util");
exports.pipeline = node_util_1.default.promisify(node_stream_1.default.pipeline);
function getParentDir(fileName) {
    return upath_1.default.parse(fileName).dir;
}
function getSiblingFileName(fileName, siblingName) {
    const subDirectory = getParentDir(fileName);
    return upath_1.default.join(subDirectory, siblingName);
}
async function readLocalFile(fileName, encoding) {
    const localFileName = (0, util_1.ensureLocalPath)(fileName);
    try {
        const fileContent = encoding
            ? await fs_extra_1.default.readFile(localFileName, encoding)
            : await fs_extra_1.default.readFile(localFileName);
        return fileContent;
    }
    catch (err) {
        logger_1.logger.trace({ err }, 'Error reading local file');
        return null;
    }
}
async function readLocalSymlink(fileName) {
    const localFileName = (0, util_1.ensureLocalPath)(fileName);
    try {
        const linkContent = await fs_extra_1.default.readlink(localFileName);
        return linkContent;
    }
    catch (err) {
        logger_1.logger.trace({ err }, 'Error reading local symlink');
        return null;
    }
}
async function writeLocalFile(fileName, fileContent) {
    const localFileName = (0, util_1.ensureLocalPath)(fileName);
    await fs_extra_1.default.outputFile(localFileName, fileContent);
}
async function deleteLocalFile(fileName) {
    // This a failsafe and hopefully will never be triggered
    if (global_1.GlobalConfig.get('platform') === 'local') {
        throw new Error('Cannot delete file when platform=local');
    }
    const localDir = global_1.GlobalConfig.get('localDir');
    if (localDir) {
        const localFileName = (0, util_1.ensureLocalPath)(fileName);
        await fs_extra_1.default.remove(localFileName);
    }
}
async function renameLocalFile(fromFile, toFile) {
    const fromPath = (0, util_1.ensureLocalPath)(fromFile);
    const toPath = (0, util_1.ensureLocalPath)(toFile);
    await fs_extra_1.default.move(fromPath, toPath);
}
async function ensureDir(dirName) {
    if (is_1.default.nonEmptyString(dirName)) {
        await fs_extra_1.default.ensureDir(dirName);
    }
}
async function ensureLocalDir(dirName) {
    const fullPath = (0, util_1.ensureLocalPath)(dirName);
    await fs_extra_1.default.ensureDir(fullPath);
    return fullPath;
}
async function ensureCacheDir(name) {
    const cacheDirName = (0, util_1.ensureCachePath)(`others/${name}`);
    await fs_extra_1.default.ensureDir(cacheDirName);
    return cacheDirName;
}
/**
 * Return the path of the private cache directory. This directory is wiped
 * between repositories, so they can be used to store private registries' index
 * without risk of that information leaking to other repositories/users.
 */
function privateCacheDir() {
    const cacheDir = global_1.GlobalConfig.get('cacheDir');
    return upath_1.default.join(cacheDir, '__renovate-private-cache');
}
async function localPathExists(pathName) {
    // Works for both files as well as directories
    const path = (0, util_1.ensureLocalPath)(pathName);
    try {
        const s = await fs_extra_1.default.stat(path);
        return !!s;
    }
    catch (_) {
        return false;
    }
}
/**
 * Validate local path without throwing.
 * @param path Path to check
 * @returns `true` if given `path` is a valid local path, otherwise `false`.
 */
function isValidLocalPath(path) {
    return (0, util_1.isValidPath)(path, 'localDir');
}
/**
 * Tries to find `otherFileName` in the directory where
 * `existingFileNameWithPath` is, then in its parent directory, then in the
 * grandparent, until we reach the top-level directory. All paths
 * must be relative to `localDir`.
 */
async function findLocalSiblingOrParent(existingFileNameWithPath, otherFileName) {
    if (upath_1.default.isAbsolute(existingFileNameWithPath)) {
        return null;
    }
    if (upath_1.default.isAbsolute(otherFileName)) {
        return null;
    }
    let current = existingFileNameWithPath;
    while (current !== '') {
        current = getParentDir(current);
        const candidate = upath_1.default.join(current, otherFileName);
        if (await localPathExists(candidate)) {
            return candidate;
        }
    }
    return null;
}
/**
 * Get files by name from directory
 */
async function readLocalDirectory(path) {
    const localPath = (0, util_1.ensureLocalPath)(path);
    const fileList = await fs_extra_1.default.readdir(localPath);
    return fileList;
}
function createCacheWriteStream(path) {
    const fullPath = (0, util_1.ensureCachePath)(path);
    return fs_extra_1.default.createWriteStream(fullPath);
}
function createCacheReadStream(path) {
    const fullPath = (0, util_1.ensureCachePath)(path);
    return fs_extra_1.default.createReadStream(fullPath);
}
async function localPathIsFile(pathName) {
    const path = (0, util_1.ensureLocalPath)(pathName);
    try {
        const s = await fs_extra_1.default.stat(path);
        return s.isFile();
    }
    catch (_) {
        return false;
    }
}
async function localPathIsSymbolicLink(pathName) {
    const path = (0, util_1.ensureLocalPath)(pathName);
    try {
        const s = await fs_extra_1.default.lstat(path);
        return s.isSymbolicLink();
    }
    catch (_) {
        return false;
    }
}
/**
 * Find a file or directory by walking up parent directories within localDir
 */
async function findUpLocal(fileName, cwd) {
    const localDir = global_1.GlobalConfig.get('localDir');
    const absoluteCwd = upath_1.default.join(localDir, cwd);
    const normalizedAbsoluteCwd = upath_1.default.normalizeSafe(absoluteCwd);
    const res = await (0, find_up_1.default)(fileName, {
        cwd: normalizedAbsoluteCwd,
        type: 'file',
    });
    // Return null if nothing found
    if (!is_1.default.nonEmptyString(res) || !is_1.default.nonEmptyString(localDir)) {
        return null;
    }
    const safePath = upath_1.default.normalizeSafe(res);
    // Return relative path if file is inside of local dir
    if (safePath.startsWith(localDir)) {
        let relativePath = safePath.replace(localDir, '');
        if (relativePath.startsWith('/')) {
            relativePath = relativePath.substring(1);
        }
        return relativePath;
    }
    // Return null if found file is outside of localDir
    return null;
}
function chmodLocalFile(fileName, mode) {
    const fullFileName = (0, util_1.ensureLocalPath)(fileName);
    return fs_extra_1.default.chmod(fullFileName, mode);
}
async function statLocalFile(fileName) {
    const fullFileName = (0, util_1.ensureLocalPath)(fileName);
    try {
        return await fs_extra_1.default.stat(fullFileName);
    }
    catch (_) {
        return null;
    }
}
async function statCacheFile(pathName) {
    const path = (0, util_1.ensureCachePath)(pathName);
    try {
        return await fs_extra_1.default.stat(path);
    }
    catch (_) {
        return null;
    }
}
function listCacheDir(path, options = { recursive: false }) {
    const fullPath = (0, util_1.ensureCachePath)(path);
    return fs_extra_1.default.readdir(fullPath, {
        encoding: 'utf-8',
        recursive: options.recursive,
    });
}
async function rmCache(path) {
    const fullPath = (0, util_1.ensureCachePath)(path);
    await fs_extra_1.default.rm(fullPath, { recursive: true });
}
async function cachePathExists(pathName) {
    const path = (0, util_1.ensureCachePath)(pathName);
    try {
        const s = await fs_extra_1.default.stat(path);
        return !!s;
    }
    catch (_) {
        return false;
    }
}
async function cachePathIsFile(pathName) {
    const path = (0, util_1.ensureCachePath)(pathName);
    try {
        const s = await fs_extra_1.default.stat(path);
        return s.isFile();
    }
    catch (e) {
        return false;
    }
}
function readCacheFile(fileName, encoding) {
    const fullPath = (0, util_1.ensureCachePath)(fileName);
    return encoding ? fs_extra_1.default.readFile(fullPath, encoding) : fs_extra_1.default.readFile(fullPath);
}
function outputCacheFile(file, data) {
    const filePath = (0, util_1.ensureCachePath)(file);
    return fs_extra_1.default.outputFile(filePath, data);
}
function readSystemFile(fileName, encoding) {
    return encoding ? fs_extra_1.default.readFile(fileName, encoding) : fs_extra_1.default.readFile(fileName);
}
async function writeSystemFile(fileName, data) {
    await fs_extra_1.default.outputFile(fileName, data);
}
async function getLocalFiles(fileNames) {
    const fileContentMap = {};
    for (const fileName of fileNames) {
        fileContentMap[fileName] = await readLocalFile(fileName, 'utf8');
    }
    return fileContentMap;
}
//# sourceMappingURL=index.js.map