const fetch = require('node-fetch');
const stable = require('semver-stable');
const { group } = require('d3-array');
const { map } = require('lodash');
const { format, startOfMonth, addMonths } = require('date-fns');
const { extent, zip, min, max } = require('d3-array');
const { csvFormatRows } = require('d3-dsv');
const pullStableVersions = async (name) => {
const response = await fetch(`http://registry.npmjs.org/${name}`);
const json = await response.json();
const versions = {...json['time']};
return Object.entries(versions)
.map(([ver, date]) => [ver, new Date(date)])
.filter(([ver, date]) => stable.is(ver));
}
const calcMonthlyReleaseCount = (versions) => {
const groups = group(versions, ([ver, date]) => format(date, '01/MM/YYYY'));
return [...groups.entries()].map(([date, items]) => ({ count: items.length, date, timestamp: +startOfMonth(items[0][1]) }));
}
const targetPackages = ['react', 'react-jss', '@emotion/core', 'styled-components'];
const packageInfos = targetPackages.map(package => [package, pullStableVersions(package)]);
let overall = {};
let minTimestamp = startOfMonth(Date.now());
let maxTimestamp = 0;
for (let package of targetPackages) {
const versionInfo = await pullStableVersions(package);
const monthlyReleases = calcMonthlyReleaseCount(versionInfo);
minTimestamp = Math.min(minTimestamp, min(monthlyReleases, item => item.timestamp));
maxTimestamp = Math.max(maxTimestamp, max(monthlyReleases, item => item.timestamp));
overall[package] = monthlyReleases;
}
const getMonthReleases = (date, data) => {
const result = data.find(item => item.timestamp === date);
if (result != null)
return result.count;
return 0;
}
const collectOverallMonthlyStats = (data, start, stop) => {
let date = start;
const result = [['date',...targetPackages]];
while (date < stop) {
const packageData = targetPackages.map(package => getMonthReleases(date, data[package]))
const row = [format(date, 'DD/MM/YYYY'), ...packageData];
if (packageData.some(release => release > 0))
result.push(row);
date = +addMonths(date, 1);
}
return result;
};
exports.endpoint = function(request, response) {
response.end(csvFormatRows(collectOverallMonthlyStats(overall, minTimestamp, maxTimestamp)));
}