2020-09-09 08:42:34 -04:00
|
|
|
/**
|
|
|
|
* @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> {
|
2020-10-10 15:02:47 -04:00
|
|
|
if (_npmPackageInfoCache[pkgName] === undefined) {
|
|
|
|
_npmPackageInfoCache[pkgName] =
|
|
|
|
fetch(`https://registry.npmjs.org/${pkgName}`).then(r => r.json());
|
2020-09-09 08:42:34 -04:00
|
|
|
}
|
2020-10-10 15:02:47 -04:00
|
|
|
return await _npmPackageInfoCache[pkgName];
|
2020-09-09 08:42:34 -04:00
|
|
|
}
|