angular-cn/dev-infra/release/versioning/npm-registry.ts

67 lines
2.6 KiB
TypeScript

/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import fetch from 'node-fetch';
import * as semver from 'semver';
import {ReleaseConfig} from '../config/index';
/** Type describing an NPM package fetched from the registry. */
export interface NpmPackageInfo {
/** Maps of versions and their package JSON objects. */
'versions': {[name: string]: undefined|object};
/** Map of NPM dist-tags and their chosen version. */
'dist-tags': {[tagName: string]: string|undefined};
/** Map of versions and their ISO release time. */
'time': {[name: string]: string};
}
/**
* Cache for requested NPM package information. A cache is desirable as the NPM
* registry requests are usually very large and slow.
*/
export const _npmPackageInfoCache: {[pkgName: string]: Promise<NpmPackageInfo>} = {};
/**
* Fetches the NPM package representing the project. Angular repositories usually contain
* multiple packages in a monorepo scheme, but packages dealt with as part of the release
* tooling are released together with the same versioning and branching. This means that
* a single package can be used as source of truth for NPM package queries.
*/
export async function fetchProjectNpmPackageInfo(config: ReleaseConfig): Promise<NpmPackageInfo> {
const pkgName = getRepresentativeNpmPackage(config);
return await fetchPackageInfoFromNpmRegistry(pkgName);
}
/** Gets whether the given version is published to NPM or not */
export async function isVersionPublishedToNpm(
version: semver.SemVer, config: ReleaseConfig): Promise<boolean> {
const {versions} = await fetchProjectNpmPackageInfo(config);
return versions[version.format()] !== undefined;
}
/**
* Gets the representative NPM package for the specified release configuration. Angular
* repositories usually contain multiple packages in a monorepo scheme, but packages dealt with
* as part of the release tooling are released together with the same versioning and branching.
* This means that a single package can be used as source of truth for NPM package queries.
*/
function getRepresentativeNpmPackage(config: ReleaseConfig) {
return config.npmPackages[0];
}
/** Fetches the specified NPM package from the NPM registry. */
async function fetchPackageInfoFromNpmRegistry(pkgName: string): Promise<NpmPackageInfo> {
if (_npmPackageInfoCache[pkgName] !== undefined) {
return await _npmPackageInfoCache[pkgName];
}
const result = _npmPackageInfoCache[pkgName] =
fetch(`https://registry.npmjs.org/${pkgName}`).then(r => r.json());
return await result;
}