"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getFilePathInCafs = exports.getFilePathByModeInCafs = exports.checkFilesIntegrity = void 0;
const getStream = require("get-stream");
const path = require("path");
const exists = require("path-exists");
const pathTemp = require("path-temp");
const renameOverwrite = require("rename-overwrite");
const ssri = require("ssri");
const addFilesFromDir_1 = require("./addFilesFromDir");
const addFilesFromTarball_1 = require("./addFilesFromTarball");
const checkFilesIntegrity_1 = require("./checkFilesIntegrity");
exports.checkFilesIntegrity = checkFilesIntegrity_1.default;
const getFilePathInCafs_1 = require("./getFilePathInCafs");
exports.getFilePathInCafs = getFilePathInCafs_1.default;
Object.defineProperty(exports, "getFilePathByModeInCafs", { enumerable: true, get: function () { return getFilePathInCafs_1.getFilePathByModeInCafs; } });
const writeFile_1 = require("./writeFile");
function createCafs(cafsDir, ignore) {
    const locker = new Map();
    const _writeBufferToCafs = writeBufferToCafs.bind(null, locker, cafsDir);
    const addStream = addStreamToCafs.bind(null, _writeBufferToCafs);
    const addBuffer = addBufferToCafs.bind(null, _writeBufferToCafs);
    return {
        addFilesFromDir: addFilesFromDir_1.default.bind(null, { addBuffer, addStream }),
        addFilesFromTarball: addFilesFromTarball_1.default.bind(null, addStream, ignore !== null && ignore !== void 0 ? ignore : null),
    };
}
exports.default = createCafs;
async function addStreamToCafs(writeBufferToCafs, fileStream, mode) {
    const buffer = await getStream.buffer(fileStream);
    return addBufferToCafs(writeBufferToCafs, buffer, mode);
}
async function addBufferToCafs(writeBufferToCafs, buffer, mode) {
    const integrity = ssri.fromData(buffer);
    const isExecutable = getFilePathInCafs_1.modeIsExecutable(mode);
    const fileDest = getFilePathInCafs_1.contentPathFromHex(isExecutable ? 'exec' : 'nonexec', integrity.hexDigest());
    await writeBufferToCafs(buffer, fileDest, isExecutable ? 0o755 : undefined);
    return integrity;
}
async function writeBufferToCafs(locker, cafsDir, buffer, fileDest, mode) {
    fileDest = path.join(cafsDir, fileDest);
    if (locker.has(fileDest)) {
        await locker.get(fileDest);
        return;
    }
    const p = (async () => {
        // This is a slow operation. Should be rewritten
        if (await exists(fileDest))
            return;
        // This might be too cautious.
        // The write is atomic, so in case pnpm crashes, no broken file
        // will be added to the store.
        // It might be a redundant step though, as we verify the contents of the
        // files before linking
        //
        // If we don't allow --no-verify-store-integrity then we probably can write
        // to the final file directly.
        const temp = pathTemp(path.dirname(fileDest));
        await writeFile_1.default(temp, buffer, mode);
        await renameOverwrite(temp, fileDest);
    })();
    locker.set(fileDest, p);
    await p;
}
//# sourceMappingURL=index.js.map