@salesforce/plugin-release-management
Version:
A plugin for preparing and publishing npm packages
133 lines • 5.14 kB
JavaScript
/*
* Copyright (c) 2020, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
import { URL } from 'node:url';
import path from 'node:path';
import os from 'node:os';
import fs from 'node:fs/promises';
import shelljs from 'shelljs';
import { SfError } from '@salesforce/core';
import { Env } from '@salesforce/kit';
export class Registry {
registryUrl;
authToken;
registryEntryLocal;
registryEntryGlobal;
env;
constructor(registryUrl, authToken) {
this.registryUrl = registryUrl;
this.authToken = authToken;
this.env = new Env();
this.registryUrl = this.env.getString('NPM_REGISTRY') ?? this.registryUrl;
this.authToken = this.env.getString('NPM_TOKEN') ?? this.authToken;
this.registryEntryLocal = shelljs.exec('npm config get registry', { silent: true }).stdout.trim();
this.registryEntryGlobal = shelljs.exec('npm config get registry -g', { silent: true }).stdout.trim();
this.loadNpmConfigs();
}
/**
* Return a properly formatted --registry string
*/
getRegistryParameter() {
if (!this.registryUrl) {
throw new SfError('registry is not set');
}
return `--registry ${this.registryUrl}`;
}
/**
* Compare this.registryUrl against npm configs and write registry entry "registry" entry to <packageDir>/.npmrc
* if either is not equal
*
* @param packageDirectory
*/
async setNpmRegistry(packageDirectory) {
if (this.registryEntryLocal !== this.registryUrl || this.registryEntryGlobal !== this.registryUrl) {
let npmrc = await this.readNpmrc(packageDirectory);
if (npmrc.find((line) => line.includes('registry='))) {
npmrc = npmrc.map((line) => {
if (line.includes('registry=')) {
if (this.registryUrl && line.endsWith(this.registryUrl))
return line;
return `registry=${this.registryUrl ?? ''}`;
}
return line;
});
}
else {
npmrc.push(`registry=${this.registryUrl ?? ''}`);
}
await this.writeNpmrc(packageDirectory, npmrc);
}
}
/**
* Examine the current npm configs to see if the registry has
* the authToken set.
* If not write the authToken to <packageDir>/.npmrc
*
* @param packageDirectory
*/
async setNpmAuth(packageDirectory) {
if (!this.authToken) {
throw new SfError('auth token has not been set');
}
let npmrc = await this.readNpmrc(packageDirectory);
const normalizedRegistry = this.normalizeRegistryUrl();
if (npmrc.find((line) => line.includes('_authToken'))) {
npmrc = npmrc.map((line) => {
if (line.includes('_authToken')) {
if (line.includes(normalizedRegistry))
return line;
return `${normalizedRegistry}:_authToken="${this.authToken ?? ''}"`;
}
return line;
});
}
else {
npmrc.push(`${normalizedRegistry}:_authToken="${this.authToken}"`);
}
npmrc.push('unsafe-perm=true');
await this.writeNpmrc(packageDirectory, npmrc);
}
loadNpmConfigs() {
// check npm configs for registry
if (!this.registryUrl) {
if (this.registryEntryLocal) {
this.registryUrl = this.registryEntryLocal;
}
else if (this.registryEntryGlobal) {
this.registryUrl = this.registryEntryGlobal;
}
else {
this.registryUrl = 'https://registry.npmjs.org/';
}
}
}
// eslint-disable-next-line class-methods-use-this
async readNpmrc(packageDir) {
try {
// check that `.npmrc` exists
await fs.access(path.join(packageDir, '.npmrc'));
}
catch (err) {
return [];
}
const npmrc = await fs.readFile(path.join(packageDir, '.npmrc'), 'utf8');
const npmrcLines = npmrc.split(os.EOL);
return [...new Set(npmrcLines).values()].filter((line) => line?.length);
}
// eslint-disable-next-line class-methods-use-this
async writeNpmrc(packageDir, npmrc) {
const npmrcLines = [...new Set(npmrc).values()].filter((line) => line?.length);
await fs.writeFile(path.join(packageDir, '.npmrc'), npmrcLines.join(os.EOL), 'utf8');
}
normalizeRegistryUrl() {
if (!this.registryUrl)
throw new SfError('registry is not set');
const registryDomain = new URL(this.registryUrl);
const pathPart = registryDomain.pathname?.length ? `${registryDomain.pathname.replace(/\/$/, '')}` : '';
return `//${registryDomain.host}${pathPart}/`;
}
}
//# sourceMappingURL=registry.js.map