UNPKG

5.09 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.fetchPackageManifest = exports.fetchPackageMetadata = void 0;
4const fs_1 = require("fs");
5const os_1 = require("os");
6const path = require("path");
7const ini = require('ini');
8const lockfile = require('@yarnpkg/lockfile');
9const pacote = require('pacote');
10let npmrc;
11function ensureNpmrc(logger, usingYarn, verbose) {
12 if (!npmrc) {
13 try {
14 npmrc = readOptions(logger, false, verbose);
15 }
16 catch (_a) { }
17 if (usingYarn) {
18 try {
19 npmrc = { ...npmrc, ...readOptions(logger, true, verbose) };
20 }
21 catch (_b) { }
22 }
23 }
24}
25function readOptions(logger, yarn = false, showPotentials = false) {
26 const cwd = process.cwd();
27 const baseFilename = yarn ? 'yarnrc' : 'npmrc';
28 const dotFilename = '.' + baseFilename;
29 let globalPrefix;
30 if (process.env.PREFIX) {
31 globalPrefix = process.env.PREFIX;
32 }
33 else {
34 globalPrefix = path.dirname(process.execPath);
35 if (process.platform !== 'win32') {
36 globalPrefix = path.dirname(globalPrefix);
37 }
38 }
39 const defaultConfigLocations = [
40 (!yarn && process.env.NPM_CONFIG_GLOBALCONFIG) || path.join(globalPrefix, 'etc', baseFilename),
41 (!yarn && process.env.NPM_CONFIG_USERCONFIG) || path.join(os_1.homedir(), dotFilename),
42 ];
43 const projectConfigLocations = [path.join(cwd, dotFilename)];
44 const root = path.parse(cwd).root;
45 for (let curDir = path.dirname(cwd); curDir && curDir !== root; curDir = path.dirname(curDir)) {
46 projectConfigLocations.unshift(path.join(curDir, dotFilename));
47 }
48 if (showPotentials) {
49 logger.info(`Locating potential ${baseFilename} files:`);
50 }
51 let options = {};
52 for (const location of [...defaultConfigLocations, ...projectConfigLocations]) {
53 if (fs_1.existsSync(location)) {
54 if (showPotentials) {
55 logger.info(`Trying '${location}'...found.`);
56 }
57 const data = fs_1.readFileSync(location, 'utf8');
58 options = {
59 ...options,
60 ...(yarn ? lockfile.parse(data) : ini.parse(data)),
61 };
62 if (options.cafile) {
63 const cafile = path.resolve(path.dirname(location), options.cafile);
64 delete options.cafile;
65 try {
66 options.ca = fs_1.readFileSync(cafile, 'utf8').replace(/\r?\n/, '\\n');
67 }
68 catch (_a) { }
69 }
70 }
71 else if (showPotentials) {
72 logger.info(`Trying '${location}'...not found.`);
73 }
74 }
75 // Substitute any environment variable references
76 for (const key in options) {
77 if (typeof options[key] === 'string') {
78 options[key] = options[key].replace(/\$\{([^\}]+)\}/, (_, name) => process.env[name] || '');
79 }
80 }
81 return options;
82}
83function normalizeManifest(rawManifest) {
84 // TODO: Fully normalize and sanitize
85 return {
86 dependencies: {},
87 devDependencies: {},
88 peerDependencies: {},
89 optionalDependencies: {},
90 ...rawManifest,
91 };
92}
93async function fetchPackageMetadata(name, logger, options) {
94 const { usingYarn, verbose, registry } = {
95 registry: undefined,
96 usingYarn: false,
97 verbose: false,
98 ...options,
99 };
100 ensureNpmrc(logger, usingYarn, verbose);
101 const response = await pacote.packument(name, {
102 fullMetadata: true,
103 ...npmrc,
104 ...(registry ? { registry } : {}),
105 });
106 // Normalize the response
107 const metadata = {
108 name: response.name,
109 tags: {},
110 versions: {},
111 };
112 if (response.versions) {
113 for (const [version, manifest] of Object.entries(response.versions)) {
114 metadata.versions[version] = normalizeManifest(manifest);
115 }
116 }
117 if (response['dist-tags']) {
118 // Store this for use with other npm utility packages
119 metadata['dist-tags'] = response['dist-tags'];
120 for (const [tag, version] of Object.entries(response['dist-tags'])) {
121 const manifest = metadata.versions[version];
122 if (manifest) {
123 metadata.tags[tag] = manifest;
124 }
125 else if (verbose) {
126 logger.warn(`Package ${metadata.name} has invalid version metadata for '${tag}'.`);
127 }
128 }
129 }
130 return metadata;
131}
132exports.fetchPackageMetadata = fetchPackageMetadata;
133async function fetchPackageManifest(name, logger, options) {
134 const { usingYarn, verbose, registry } = {
135 registry: undefined,
136 usingYarn: false,
137 verbose: false,
138 ...options,
139 };
140 ensureNpmrc(logger, usingYarn, verbose);
141 const response = await pacote.manifest(name, {
142 fullMetadata: true,
143 ...npmrc,
144 ...(registry ? { registry } : {}),
145 });
146 return normalizeManifest(response);
147}
148exports.fetchPackageManifest = fetchPackageManifest;