"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const fs_1 = require("fs"); const os_1 = require("os"); const path = require("path"); const ini = require('ini'); const lockfile = require('@yarnpkg/lockfile'); const pacote = require('pacote'); let npmrc; function ensureNpmrc(logger, usingYarn, verbose) { if (!npmrc) { try { npmrc = readOptions(logger, false, verbose); } catch (_a) { } if (usingYarn) { try { npmrc = { ...npmrc, ...readOptions(logger, true, verbose) }; } catch (_b) { } } } } function readOptions(logger, yarn = false, showPotentials = false) { const cwd = process.cwd(); const baseFilename = yarn ? 'yarnrc' : 'npmrc'; const dotFilename = '.' + baseFilename; let globalPrefix; if (process.env.PREFIX) { globalPrefix = process.env.PREFIX; } else { globalPrefix = path.dirname(process.execPath); if (process.platform !== 'win32') { globalPrefix = path.dirname(globalPrefix); } } const defaultConfigLocations = [ path.join(globalPrefix, 'etc', baseFilename), path.join(os_1.homedir(), dotFilename), ]; const projectConfigLocations = [path.join(cwd, dotFilename)]; const root = path.parse(cwd).root; for (let curDir = path.dirname(cwd); curDir && curDir !== root; curDir = path.dirname(curDir)) { projectConfigLocations.unshift(path.join(curDir, dotFilename)); } if (showPotentials) { logger.info(`Locating potential ${baseFilename} files:`); } let options = {}; for (const location of [...defaultConfigLocations, ...projectConfigLocations]) { if (fs_1.existsSync(location)) { if (showPotentials) { logger.info(`Trying '${location}'...found.`); } const data = fs_1.readFileSync(location, 'utf8'); options = { ...options, ...(yarn ? lockfile.parse(data) : ini.parse(data)), }; if (options.cafile) { const cafile = path.resolve(path.dirname(location), options.cafile); delete options.cafile; try { options.ca = fs_1.readFileSync(cafile, 'utf8').replace(/\r?\n/, '\\n'); } catch (_a) { } } } else if (showPotentials) { logger.info(`Trying '${location}'...not found.`); } } // Substitute any environment variable references for (const key in options) { if (typeof options[key] === 'string') { options[key] = options[key].replace(/\$\{([^\}]+)\}/, (_, name) => process.env[name] || ''); } } return options; } function normalizeManifest(rawManifest) { // TODO: Fully normalize and sanitize return { dependencies: {}, devDependencies: {}, peerDependencies: {}, optionalDependencies: {}, // tslint:disable-next-line:no-any ...rawManifest, }; } async function fetchPackageMetadata(name, logger, options) { const { usingYarn, verbose, registry } = { registry: undefined, usingYarn: false, verbose: false, ...options, }; ensureNpmrc(logger, usingYarn, verbose); const response = await pacote.packument(name, { 'full-metadata': true, ...npmrc, ...(registry ? { registry } : {}), }); // Normalize the response const metadata = { name: response.name, tags: {}, versions: {}, }; if (response.versions) { for (const [version, manifest] of Object.entries(response.versions)) { metadata.versions[version] = normalizeManifest(manifest); } } if (response['dist-tags']) { // Store this for use with other npm utility packages // tslint:disable-next-line: no-any metadata['dist-tags'] = response['dist-tags']; for (const [tag, version] of Object.entries(response['dist-tags'])) { const manifest = metadata.versions[version]; if (manifest) { metadata.tags[tag] = manifest; } else if (verbose) { logger.warn(`Package ${metadata.name} has invalid version metadata for '${tag}'.`); } } } return metadata; } exports.fetchPackageMetadata = fetchPackageMetadata; async function fetchPackageManifest(name, logger, options) { const { usingYarn, verbose, registry } = { registry: undefined, usingYarn: false, verbose: false, ...options, }; ensureNpmrc(logger, usingYarn, verbose); const response = await pacote.manifest(name, { 'full-metadata': true, ...npmrc, ...(registry ? { registry } : {}), }); return normalizeManifest(response); } exports.fetchPackageManifest = fetchPackageManifest;