in src/backend/package-stats/npm-downloads.lambda-shared.ts [55:111]
private async getDownloadsRaw(
packages: readonly string[],
period: NpmDownloadsPeriod,
throwErrors: boolean,
): Promise<NpmDownloadsOutput> {
if (packages.length > NpmDownloadsClient.MAX_PACKAGES_PER_QUERY) {
throw new Error(`Too many packages were provided (max: ${NpmDownloadsClient.MAX_PACKAGES_PER_QUERY})`);
}
if (packages.some((pkg) => this.isScopedPackage(pkg)) && packages.length > 1) {
throw new Error('Scoped packages aren\'t supported by the bulk query API.');
}
if (packages.length === 0) return new Map();
console.log(`Querying NPM for ${packages.length} package(s): [${packages.join(', ')}]`);
const result = await this.got(`${NpmDownloadsClient.NPM_DOWNLOADS_API_URL}/${period}/${packages.join(',')}`, {
timeout: 5_000, // 5 seconds
}).catch((err) => {
if (throwErrors) {
throw err;
} else {
return { body: JSON.stringify({ error: JSON.stringify(err) }) };
}
});
const data: NpmApiResult = JSON.parse(result.body);
// single package query error
// ex. { "error": "package foo not found" }
if ('error' in data) {
if (throwErrors) {
throw new Error(`Could not retrieve download metrics: ${data.error}`);
} else {
console.error(`Could not retrieve download metrics: ${data.error}`);
return new Map();
}
}
// only a single package was returned
if (isSingleDownloadsEntry(data)) {
return new Map([[packages[0], data]]);
}
// bulk query result
for (const key of Object.keys(data)) {
if (data[key] === null) {
if (throwErrors) {
throw new Error(`Could not retrieve download metrics for package ${key}`);
} else {
console.error(`Could not retrieve download metrics for package ${key}`);
delete data[key];
}
}
}
// typescript can't figure out that we removed all null values
return new Map(Object.entries(data as any));
}