UNPKG

4.78 kBJavaScriptView Raw
1import fs from "fs";
2
3import { execa } from "execa";
4import chalk from "chalk";
5import fetch from "node-fetch";
6
7import { cac } from "cac";
8// ES Module doesn't have require
9import { require } from "./require.js";
10
11const pkg = require("../package.json");
12const cli = cac();
13
14import {
15 getCustomRegistry,
16 addCustomRegistry,
17 removeCustomRegistry,
18} from "./registries.js";
19
20// init default and custom registries
21const defaultRegistries = require("../registries.json");
22// init in main
23let registries;
24
25/**
26 * generate equal width name with dashline
27 * @param {string} str
28 * @returns
29 */
30function dashline(str) {
31 const maxCharWidth =
32 Math.max(...Object.keys(registries).map((key) => key.length)) + 3;
33
34 const line = new Array(Math.max(1, maxCharWidth - str.length)).join("-");
35 return str + " " + line;
36}
37
38/**
39 * get default and custom registries
40 * @returns
41 */
42async function getAllRegistries() {
43 const customRegistries = await getCustomRegistry();
44 return Object.assign({}, defaultRegistries, customRegistries);
45}
46
47/**
48 * Show all npm registries
49 */
50async function listRegistries(pkgManager = "npm") {
51 let list = "";
52 const currentRegistry = await getCurrentRegistry(pkgManager);
53
54 Object.keys(registries).forEach((key) => {
55 const isCurrentRegistry = key === currentRegistry;
56 const prefix = isCurrentRegistry ? "*" : " ";
57 const item = `\n ${prefix} ${dashline(key)} ${registries[key].registry}`;
58 list += isCurrentRegistry ? chalk.green(item) : item;
59 });
60 console.log(list + "\n");
61 return list;
62}
63
64async function getCurrentRegistry(pkgManager = "npm") {
65 const { stdout } = await execa(pkgManager, ["config", "get", "registry"]);
66
67 for (const name in registries) {
68 if (registries[name].registry === stdout) {
69 return name;
70 }
71 }
72}
73
74/**
75 * https://docs.npmjs.com/cli/v7/commands/npm-config
76 * @param {string} name
77 * @param {*} pkgManager
78 * @returns
79 */
80async function setCurrentRegistry(name, pkgManager = "npm") {
81 return execa(pkgManager, [
82 "config",
83 "set",
84 `registry=${registries[name].registry}`,
85 ]);
86}
87
88/**
89 * delay time
90 * @param {string} url
91 */
92async function getDelayTime(url) {
93 const start = +new Date();
94 return fetch(url)
95 .then(() => {
96 const time = new Date() - start;
97 const msg = `${time} ms`;
98 if (time < 500) {
99 return chalk.green(msg);
100 } else if (time < 1000) {
101 return chalk.yellow(msg);
102 } else {
103 return chalk.red(msg);
104 }
105 })
106 .catch((e) => {
107 return chalk.red("Timeout");
108 });
109}
110
111/**
112 * list registries delay time
113 * @returns
114 */
115async function listDelayTime() {
116 return await Promise.all(
117 Object.keys(registries).map(async (key) => {
118 const delayTime = await getDelayTime(registries[key].registry);
119 const item = ` ${dashline(key)} ${delayTime}`;
120 console.log(item);
121 })
122 );
123}
124
125/**
126 * @param {string} pkgManager npm|yarn
127 */
128async function main(pkgManager) {
129 // init
130 registries = await getAllRegistries();
131
132 cli.command("ls", "List all the registries").action(async () => {
133 await listRegistries(pkgManager);
134 });
135
136 cli
137 .command("use [registry]", "Change registry")
138 .option("-l, --local", "set '.npmrc' for local")
139 .action(async (registry, options) => {
140 if (!registry) {
141 console.log(
142 `\n nnrm use <registry>\n Example: ${chalk.yellow(
143 "nnrm use taobao"
144 )}\n`
145 );
146 } else {
147 setCurrentRegistry(registry, pkgManager).then(() => {
148 listRegistries(pkgManager);
149 });
150 }
151
152 if (options.l || options.local) {
153 const registryText = `registry=${registries[registry].registry}`;
154 if (fs.existsSync(".npmrc")) {
155 const content = fs.readFileSync(".npmrc", "utf-8");
156 fs.writeFileSync(
157 ".npmrc",
158 content.replace(/^registry=.*/gm, registryText)
159 );
160 } else {
161 fs.writeFileSync(".npmrc", registryText);
162 }
163 }
164 });
165
166 cli
167 .command("test", "Show response time for all registries")
168 .action(async () => {
169 console.log();
170 await listDelayTime();
171 console.log();
172 });
173
174 cli
175 .command("add <registry> <url> [home]", "Add a custom registry")
176 .action(async (name, url, home) => {
177 await addCustomRegistry(name, url, home);
178 registries = getAllRegistries();
179 await listRegistries(pkgManager);
180 });
181
182 cli
183 .command("remove <registry>", "Remove a custom registry")
184 .action(async (name) => {
185 removeCustomRegistry(name);
186 registries = getAllRegistries();
187 await listRegistries(pkgManager);
188 });
189
190 cli.help();
191 cli.version(pkg.version);
192 cli.parse();
193}
194
195export { listRegistries, listDelayTime, setCurrentRegistry, main };