"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createPeersFolderSuffix = exports.depPathToFilename = exports.parse = exports.refToRelative = exports.relative = exports.getRegistryByPackageName = exports.refToAbsolute = exports.tryGetPackageId = exports.resolve = exports.isAbsolute = void 0;
const crypto_base32_hash_1 = require("@pnpm/crypto.base32-hash");
const encode_registry_1 = __importDefault(require("encode-registry"));
const semver_1 = __importDefault(require("semver"));
function isAbsolute(dependencyPath) {
    return dependencyPath[0] !== '/';
}
exports.isAbsolute = isAbsolute;
function resolve(registries, resolutionLocation) {
    if (!isAbsolute(resolutionLocation)) {
        let registryUrl;
        if (resolutionLocation[1] === '@') {
            const slashIndex = resolutionLocation.indexOf('/', 1);
            const scope = resolutionLocation.slice(1, slashIndex !== -1 ? slashIndex : 0);
            registryUrl = registries[scope] || registries.default;
        }
        else {
            registryUrl = registries.default;
        }
        const registryDirectory = (0, encode_registry_1.default)(registryUrl);
        return `${registryDirectory}${resolutionLocation}`;
    }
    return resolutionLocation;
}
exports.resolve = resolve;
function tryGetPackageId(registries, relDepPath) {
    if (relDepPath[0] !== '/') {
        return null;
    }
    const underscoreIndex = relDepPath.indexOf('_', relDepPath.lastIndexOf('/'));
    if (underscoreIndex !== -1) {
        return resolve(registries, relDepPath.slice(0, underscoreIndex));
    }
    return resolve(registries, relDepPath);
}
exports.tryGetPackageId = tryGetPackageId;
function refToAbsolute(reference, pkgName, registries) {
    if (reference.startsWith('link:')) {
        return null;
    }
    if (!reference.includes('/')) {
        const registryName = (0, encode_registry_1.default)(getRegistryByPackageName(registries, pkgName));
        return `${registryName}/${pkgName}/${reference}`;
    }
    if (reference[0] !== '/')
        return reference;
    const registryName = (0, encode_registry_1.default)(getRegistryByPackageName(registries, pkgName));
    return `${registryName}${reference}`;
}
exports.refToAbsolute = refToAbsolute;
function getRegistryByPackageName(registries, packageName) {
    if (packageName[0] !== '@')
        return registries.default;
    const scope = packageName.substring(0, packageName.indexOf('/'));
    return registries[scope] || registries.default;
}
exports.getRegistryByPackageName = getRegistryByPackageName;
function relative(registries, packageName, absoluteResolutionLoc) {
    const registryName = (0, encode_registry_1.default)(getRegistryByPackageName(registries, packageName));
    if (absoluteResolutionLoc.startsWith(`${registryName}/`)) {
        return absoluteResolutionLoc.slice(absoluteResolutionLoc.indexOf('/'));
    }
    return absoluteResolutionLoc;
}
exports.relative = relative;
function refToRelative(reference, pkgName) {
    if (reference.startsWith('link:')) {
        return null;
    }
    if (reference.startsWith('file:')) {
        return reference;
    }
    if (!reference.includes('/')) {
        return `/${pkgName}/${reference}`;
    }
    return reference;
}
exports.refToRelative = refToRelative;
function parse(dependencyPath) {
    // eslint-disable-next-line: strict-type-predicates
    if (typeof dependencyPath !== 'string') {
        throw new TypeError(`Expected \`dependencyPath\` to be of type \`string\`, got \`${
        // eslint-disable-next-line: strict-type-predicates
        dependencyPath === null ? 'null' : typeof dependencyPath}\``);
    }
    const _isAbsolute = isAbsolute(dependencyPath);
    const parts = dependencyPath.split('/');
    if (!_isAbsolute)
        parts.shift();
    const host = _isAbsolute ? parts.shift() : undefined;
    const name = parts[0].startsWith('@')
        ? `${parts.shift()}/${parts.shift()}` // eslint-disable-line @typescript-eslint/restrict-template-expressions
        : parts.shift();
    let version = parts.shift();
    if (version) {
        const underscoreIndex = version.indexOf('_');
        let peersSuffix;
        if (underscoreIndex !== -1) {
            peersSuffix = version.substring(underscoreIndex + 1);
            version = version.substring(0, underscoreIndex);
        }
        if (semver_1.default.valid(version)) {
            return {
                host,
                isAbsolute: _isAbsolute,
                name,
                peersSuffix,
                version,
            };
        }
    }
    if (!_isAbsolute)
        throw new Error(`${dependencyPath} is an invalid relative dependency path`);
    return {
        host,
        isAbsolute: _isAbsolute,
    };
}
exports.parse = parse;
function depPathToFilename(depPath) {
    const filename = depPathToFilenameUnescaped(depPath).replace(/[\\/:*?"<>|]/g, '+');
    if (filename.length > 120 || filename !== filename.toLowerCase() && !filename.startsWith('file+')) {
        return `${filename.substring(0, 50)}_${(0, crypto_base32_hash_1.createBase32Hash)(filename)}`;
    }
    return filename;
}
exports.depPathToFilename = depPathToFilename;
function depPathToFilenameUnescaped(depPath) {
    if (depPath.indexOf('file:') !== 0) {
        if (depPath.startsWith('/')) {
            depPath = depPath.substring(1);
        }
        const index = depPath.lastIndexOf('/');
        return `${depPath.substring(0, index)}@${depPath.slice(index + 1)}`;
    }
    return depPath.replace(':', '+');
}
function createPeersFolderSuffix(peers) {
    const folderName = peers.map(({ name, version }) => `${name.replace('/', '+')}@${version}`).sort().join('+');
    // We don't want the folder name to get too long.
    // Otherwise, an ENAMETOOLONG error might happen.
    // see: https://github.com/pnpm/pnpm/issues/977
    //
    // A bigger limit might be fine but the base32 encoded md5 hash will be 26 symbols,
    // so for consistency's sake, we go with 26.
    if (folderName.length > 26) {
        return `_${(0, crypto_base32_hash_1.createBase32Hash)(folderName)}`;
    }
    return `_${folderName}`;
}
exports.createPeersFolderSuffix = createPeersFolderSuffix;
//# sourceMappingURL=index.js.map