Skip to content
This repository was archived by the owner on Jul 1, 2024. It is now read-only.

Commit a289014

Browse files
committed
Get monthly download count for the month up to the lastPushDate
Actually, use the month up to a week before `lastPushDate`, in case it takes npm some time to update the numbers. This should make the download numbers stable, avoiding the wobble seen in DefinitelyTyped/DefinitelyTyped#46778. Fixes #209.
1 parent 39247a9 commit a289014

File tree

4 files changed

+19
-13
lines changed

4 files changed

+19
-13
lines changed

src/_tests/fixturedActions.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ async function testFixture(dir: string) {
3737
const derived = await deriveStateForPR(
3838
response,
3939
(expr: string) => Promise.resolve(files[expr] as string),
40-
(name: string) => name in downloads ? downloads[name] : 0,
40+
(name: string, _until?: Date) => name in downloads ? downloads[name] : 0,
4141
() => new Date(readJSON(derivedPath).now)
4242
);
4343

src/commands/create-fixture.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ export default async function main(directory: string, overwriteInfo: boolean) {
7070
writeFileSync(downloadsJSONPath, "{}"); // one-time initialization of an empty storage
7171
return getDownloadsAndWriteToFile;
7272
}
73-
async function getDownloadsAndWriteToFile(packageName: string) {
74-
downloadsFetched[packageName] = await getMonthlyDownloadCount(packageName);
73+
async function getDownloadsAndWriteToFile(packageName: string, until?: Date) {
74+
downloadsFetched[packageName] = await getMonthlyDownloadCount(packageName, until);
7575
writeFileSync(downloadsJSONPath, JSON.stringify(downloadsFetched, null, " "));
7676
return downloadsFetched[packageName];
7777
}

src/pr-info.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -194,22 +194,22 @@ export async function deriveStateForPR(
194194
const headCommit = getHeadCommit(prInfo);
195195
if (headCommit == null) return botError(prInfo.number, "No head commit found");
196196

197-
const pkgInfoEtc = await getPackageInfosEtc(
198-
noNulls(prInfo.files?.nodes).map(f => f.path).sort(),
199-
headCommit.oid, fetchFile, getDownloads);
200-
if (pkgInfoEtc instanceof Error) return botError(prInfo.number, pkgInfoEtc.message);
201-
const { pkgInfo, popularityLevel } = pkgInfoEtc;
202-
if (!pkgInfo.some(p => p.name)) return botNoPackages(prInfo.number);
203-
204197
const author = prInfo.author.login;
205-
206198
const isFirstContribution = prInfo.authorAssociation === CommentAuthorAssociation.FIRST_TIME_CONTRIBUTOR;
207199

208200
const createdDate = new Date(prInfo.createdAt);
209201
const lastPushDate = new Date(headCommit.pushedDate);
210202
const lastCommentDate = getLastCommentishActivityDate(prInfo.timelineItems, prInfo.reviews) || lastPushDate;
211203
const lastBlessing = getLastMaintainerBlessingDate(prInfo.timelineItems);
212204
const reopenedDate = getReopenedDate(prInfo.timelineItems);
205+
206+
const pkgInfoEtc = await getPackageInfosEtc(
207+
noNulls(prInfo.files?.nodes).map(f => f.path).sort(),
208+
headCommit.oid, fetchFile, async name => await getDownloads(name, lastPushDate));
209+
if (pkgInfoEtc instanceof Error) return botError(prInfo.number, pkgInfoEtc.message);
210+
const { pkgInfo, popularityLevel } = pkgInfoEtc;
211+
if (!pkgInfo.some(p => p.name)) return botNoPackages(prInfo.number);
212+
213213
const now = getNow().toISOString();
214214
const reviews = getReviews(prInfo);
215215
const latestReview = latestDate(...reviews.map(r => r.date));

src/util/npm.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
import { fetchText } from "./io";
22

3-
export async function getMonthlyDownloadCount(packageName: string): Promise<number> {
4-
const url = `https://api.npmjs.org/downloads/point/last-month/@types/${packageName}`;
3+
const DAY = 1000 * 60 * 60 * 24;
4+
const toDateStr = (d: Date, days: number) =>
5+
(new Date(d.getTime() - days * DAY)).toISOString().replace(/T.*$/, "");
6+
7+
export async function getMonthlyDownloadCount(packageName: string, until?: Date): Promise<number> {
8+
// use the month up to a week before the given date, in case it takes npm some time to update the numbers
9+
const range = !until ? "last-month" : `${toDateStr(until, 37)}:${toDateStr(until, 7)}`;
10+
const url = `https://api.npmjs.org/downloads/point/${range}/@types/${packageName}`;
511
const result = JSON.parse(await fetchText(url)) as { downloads?: number };
612
// For a package not on NPM, just return 0.
713
return result.downloads === undefined ? 0 : result.downloads;

0 commit comments

Comments
 (0)