UNPKG

@haochuan9421/urm

Version:

Universal Registry Manager, manage npm and yarn registry easily.

189 lines (169 loc) 5.87 kB
const fs = require("fs"); const path = require("path"); const { eachSeries } = require("async"); const { Table } = require("console-table-printer"); const { set, unset } = require("lodash"); const { Configuration, folderUtils } = require("@yarnpkg/core"); const { xfs, npath } = require("@yarnpkg/fslib"); const { getPluginConfiguration } = require("@yarnpkg/cli"); const { parseSyml, stringifySyml } = require("@yarnpkg/parsers"); class yarnConfig2 { constructor() { this.cwd = npath.toPortablePath(process.cwd()); this.configFileTypes = ["project", "user"]; } // 获取当前生效的全部 registry 配置 async getCurRegistries() { const curRegistries = []; if (process.env.YARN_NPM_REGISTRY_SERVER) { curRegistries.push({ registry: process.env.YARN_NPM_REGISTRY_SERVER, scope: "", where: { whereType: "env", }, }); } const rcFiles = await Configuration.findRcFiles(this.cwd); const configFiles = await this.getConfigFiles(); rcFiles.forEach(({ path, data: { npmRegistryServer, npmScopes } }) => { let whereType; const configFile = configFiles.find((v) => v.path === path); if (configFile) { whereType = configFile.type; } if (npmRegistryServer && curRegistries.every((v) => v.scope !== "")) { curRegistries.push({ registry: npmRegistryServer, scope: "", where: { whereType: whereType, wherePath: path, }, }); } if (npmScopes) { for (const scope in npmScopes) { if (npmScopes[scope].npmRegistryServer && curRegistries.every((v) => v.scope !== `@${scope}`)) { curRegistries.push({ registry: npmScopes[scope].npmRegistryServer, scope: `@${scope}`, where: { whereType: whereType, wherePath: path, }, }); } } } }); if (!curRegistries.find(({ scope }) => scope === "")) { const configuration = await Configuration.find(this.cwd, getPluginConfiguration()); const registry = configuration.values.get("npmRegistryServer"); curRegistries.push({ registry, scope: "", where: { whereType: "default", }, }); } return curRegistries; } // 以表格的形式展示当前的 registry 配置 async printCurRegistriesTable() { return this.getCurRegistries().then((curRegistries) => { const currentRegistriesTable = new Table({ title: i18n.A062, columns: [ { name: "registry", alignment: "left" }, { name: "scope", alignment: "left" }, { name: "where", alignment: "left" }, ], }); currentRegistriesTable.addRows( curRegistries.map((v) => ({ ...v, where: v.where.whereType || v.where.wherePath, })), { color: "crimson" } ); currentRegistriesTable.printTable(); return curRegistries; }); } // 设置 registry async setRegistry(scope, value, { whereType, wherePath }) { if (!wherePath) { const configFiles = await this.getConfigFiles(); wherePath = configFiles.find((file) => file.type === whereType).path; } let config = xfs.existsSync(wherePath) ? parseSyml(await xfs.readFilePromise(wherePath, `utf8`)) : {}; if (scope) { set(config, `npmScopes.${scope.replace("@", "")}.npmRegistryServer`, value); } else { set(config, "npmRegistryServer", value); } await xfs.changeFilePromise(wherePath, stringifySyml(config), { automaticNewlines: true, }); } // 删除 registry async delRegistry(scope, { whereType, wherePath }) { if (!wherePath) { const configFiles = await this.getConfigFiles(); wherePath = configFiles.find((file) => file.type === whereType).path; } await fs.promises.access(wherePath, fs.constants.W_OK); let config = parseSyml(await xfs.readFilePromise(wherePath, `utf8`)); if (scope) { unset(config, `npmScopes.${scope.replace("@", "")}.npmRegistryServer`); } else { unset(config, "npmRegistryServer"); } await xfs.changeFilePromise(wherePath, stringifySyml(config), { automaticNewlines: true, }); } // 获取全部可以删除的 registry async getRemovableRegistries() { return this.getCurRegistries().then((curRegistries) => curRegistries.filter(({ where }) => Boolean(where.wherePath))); } // 清空全部 registry async clearRegistry() { const rcFiles = await Configuration.findRcFiles(this.cwd); let removeMaxNeedCount = rcFiles.length; const remove = (registries) => { if (!registries.length) { return; } if (removeMaxNeedCount <= 0) { return Promise.reject(new Error("fail to clear registry")); } removeMaxNeedCount--; return eachSeries(registries, async ({ scope, where }) => this.delRegistry(scope, where)) .then(() => this.getRemovableRegistries()) // 递归删除,直到获取不到可删除的 registry 为止 .then(remove); }; return this.getRemovableRegistries().then(remove); } // 获取配置文件的完整路径 async getConfigFiles() { const rcFilename = process.env.YARN_RC_FILENAME || ".yarnrc.yml"; const configuration = await Configuration.find(this.cwd, getPluginConfiguration()); if (!configuration.projectCwd) { return Promise.reject(new Error(`you are not in a project folder`)); } return [ { type: "project", path: path.join(configuration.projectCwd, rcFilename), }, { type: "user", path: path.join(folderUtils.getHomeFolder(), rcFilename), }, ]; } } module.exports = yarnConfig2;