UNPKG

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