npm-fetch-changelog
Version:
fetch the changelog for an npm package from GitHub
349 lines (348 loc) • 15.9 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.describeFilter = describeFilter;
exports.fetchChangelog = fetchChangelog;
exports.getChangelogFromFile = void 0;
exports.includeFilter = includeFilter;
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _npmRegistryFetch = _interopRequireDefault(require("npm-registry-fetch"));
var _jsBase = require("js-base64");
var _parseChangelog = _interopRequireDefault(require("./parseChangelog.js"));
var _semver = _interopRequireDefault(require("semver"));
var _getConfig = _interopRequireDefault(require("./getConfig.js"));
var _octokit = require("octokit");
var _memoize = _interopRequireDefault(require("./util/memoize.js"));
var _once = _interopRequireDefault(require("./util/once.js"));
var _debug = require("./util/debug.js");
var _chalk = _interopRequireDefault(require("chalk"));
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
var getOctokit = (0, _once["default"])( /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee() {
var _yield$getConfig, githubToken;
return _regenerator["default"].wrap(function _callee$(_context) {
while (1) switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return (0, _getConfig["default"])();
case 2:
_yield$getConfig = _context.sent;
githubToken = _yield$getConfig.githubToken;
return _context.abrupt("return", new _octokit.Octokit(_objectSpread({}, githubToken ? {
auth: "token ".concat(githubToken)
} : {})));
case 5:
case "end":
return _context.stop();
}
}, _callee);
})));
function doOctokit(_x, _x2, _x3) {
return _doOctokit.apply(this, arguments);
}
function _doOctokit() {
_doOctokit = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee3(resource, method, arg) {
var octokit, result;
return _regenerator["default"].wrap(function _callee3$(_context3) {
while (1) switch (_context3.prev = _context3.next) {
case 0:
_context3.next = 2;
return getOctokit();
case 2:
octokit = _context3.sent;
(0, _debug.debug)("calling... octokit.rest.".concat(resource, ".").concat(method, "(").concat(JSON.stringify(arg), ")"));
_context3.prev = 4;
_context3.next = 7;
return octokit.rest[resource][method](arg);
case 7:
result = _context3.sent;
(0, _debug.debug)("call success octokit.rest.".concat(resource, ".").concat(method, "(").concat(JSON.stringify(arg), ")"));
return _context3.abrupt("return", result);
case 12:
_context3.prev = 12;
_context3.t0 = _context3["catch"](4);
(0, _debug.debug)("cail failed octokit.rest.".concat(resource, ".").concat(method, "(").concat(JSON.stringify(arg), ")"), _context3.t0);
throw _context3.t0;
case 16:
case "end":
return _context3.stop();
}
}, _callee3, null, [[4, 12]]);
}));
return _doOctokit.apply(this, arguments);
}
var getChangelogFromFile = exports.getChangelogFromFile = (0, _memoize["default"])( /*#__PURE__*/function () {
var _ref2 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2(owner, repo) {
var changelog, lastError, _i, _arr, file, _yield$doOctokit, _data, data;
return _regenerator["default"].wrap(function _callee2$(_context2) {
while (1) switch (_context2.prev = _context2.next) {
case 0:
_i = 0, _arr = ['CHANGELOG.md', 'changelog.md'];
case 1:
if (!(_i < _arr.length)) {
_context2.next = 22;
break;
}
file = _arr[_i];
_context2.prev = 3;
_context2.next = 6;
return doOctokit('repos', 'getContent', {
owner: owner,
repo: repo,
path: file
});
case 6:
_yield$doOctokit = _context2.sent;
_data = _yield$doOctokit.data;
data = Array.isArray(_data) ? _data[0] : _data;
if (!(data.type !== 'file')) {
_context2.next = 11;
break;
}
throw new Error("content isn't a file");
case 11:
changelog = data.content ? _jsBase.Base64.decode(data.content) : undefined;
return _context2.abrupt("break", 22);
case 15:
_context2.prev = 15;
_context2.t0 = _context2["catch"](3);
lastError = _context2.t0;
return _context2.abrupt("continue", 19);
case 19:
_i++;
_context2.next = 1;
break;
case 22:
if (changelog) {
_context2.next = 24;
break;
}
throw lastError || new Error("failed to find changelog file");
case 24:
_context2.next = 26;
return (0, _parseChangelog["default"])(changelog);
case 26:
return _context2.abrupt("return", _context2.sent);
case 27:
case "end":
return _context2.stop();
}
}, _callee2, null, [[3, 15]]);
}));
return function (_x4, _x5) {
return _ref2.apply(this, arguments);
};
}(), function (owner, repo) {
return "".concat(owner, "/").concat(repo);
});
function parseRepositoryUrl(url) {
var match = /github\.com[:/]([^\\]+)\/([^\\]+)/i.exec(url);
if (!match) throw new Error("repository.url not supported: ".concat(url));
var _match = (0, _slicedToArray2["default"])(match, 3),
owner = _match[1],
repo = _match[2];
return {
owner: owner,
repo: repo.replace(/\.git$/, '')
};
}
function includeFilter(include) {
if (!include) return function () {
return true;
};
if (typeof include === 'function') return include;
var range = include.range,
prerelease = include.prerelease,
minor = include.minor,
_include$patch = include.patch,
patch = _include$patch === void 0 ? minor : _include$patch;
return function (version) {
if (range && !_semver["default"].satisfies(version, range)) return false;
if (!prerelease && _semver["default"].prerelease(version)) return false;
if (minor === false && _semver["default"].minor(version)) return false;
if (patch === false && _semver["default"].patch(version)) return false;
return true;
};
}
function describeFilter(_ref3) {
var pkg = _ref3.pkg,
include = _ref3.include,
highlight = _ref3.highlight;
if (typeof include === 'function') {
return "versions matching custom function";
}
var _ref4 = include || {},
range = _ref4.range,
prerelease = _ref4.prerelease,
minor = _ref4.minor,
patch = _ref4.patch;
var types = [].concat((0, _toConsumableArray2["default"])(prerelease ? ['prerelease'] : []), ['major'], (0, _toConsumableArray2["default"])(minor === false ? [] : ['minor']), (0, _toConsumableArray2["default"])(patch === false ? [] : ['patch']));
return [].concat((0, _toConsumableArray2["default"])(range ? [] : [highlight ? _chalk["default"].greenBright('all') : 'all']), [types.slice(0, Math.max(1, types.length - 1)).join(', ')], (0, _toConsumableArray2["default"])(types.length > 1 ? ["and ".concat(types[types.length - 1])] : []), ['versions'], (0, _toConsumableArray2["default"])(pkg ? ["of ".concat(highlight ? _chalk["default"].bold(pkg) : pkg)] : []), (0, _toConsumableArray2["default"])(range ? [/^[<>]/.test(range) ? "".concat(highlight ? _chalk["default"].greenBright(range) : range) : "satisfying ".concat(highlight ? _chalk["default"].greenBright(range) : range)] : [])).join(' ');
}
function fetchChangelog(_x6) {
return _fetchChangelog.apply(this, arguments);
}
function _fetchChangelog() {
_fetchChangelog = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee5(pkg) {
var _ref5,
include,
_yield$getConfig2,
npmToken,
npmInfo,
versions,
releases,
_args5 = arguments;
return _regenerator["default"].wrap(function _callee5$(_context5) {
while (1) switch (_context5.prev = _context5.next) {
case 0:
_ref5 = _args5.length > 1 && _args5[1] !== undefined ? _args5[1] : {}, include = _ref5.include;
_context5.next = 3;
return (0, _getConfig["default"])();
case 3:
_yield$getConfig2 = _context5.sent;
npmToken = _yield$getConfig2.npmToken;
(0, _debug.debug)("fetchChangelog(".concat(JSON.stringify(pkg), ", ").concat(JSON.stringify({
include: include
}), ")"));
_context5.next = 8;
return _npmRegistryFetch["default"].json(pkg, {
forceAuth: {
token: npmToken
}
});
case 8:
npmInfo = _context5.sent;
(0, _debug.debug)("npmInfo.versions:\n ".concat(Object.keys(npmInfo.versions).join('\n ')));
versions = Object.keys(npmInfo.versions).filter(includeFilter(include));
(0, _debug.debug)("filtered versions:\n ".concat(versions.join('\n ')));
_context5.next = 14;
return Promise.all(versions.map( /*#__PURE__*/function () {
var _ref6 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee4(version) {
var release, _ref7, url, _parseRepositoryUrl, _owner, _repo, _yield$doOctokit$catc, body, parsed, v, _parsed$v, header, _body, changelog, _ref8, _header, _body2;
return _regenerator["default"].wrap(function _callee4$(_context4) {
while (1) switch (_context4.prev = _context4.next) {
case 0:
release = {
version: version,
header: "# ".concat(version),
date: new Date(npmInfo.time[version])
};
_ref7 = npmInfo.versions[version].repository || npmInfo.repository || {}, url = _ref7.url;
if (!url) {
release.error = new Error('failed to get repository url from npm');
}
_context4.prev = 3;
_parseRepositoryUrl = parseRepositoryUrl(url), _owner = _parseRepositoryUrl.owner, _repo = _parseRepositoryUrl.repo;
_context4.prev = 5;
_context4.next = 8;
return doOctokit('repos', 'getReleaseByTag', {
owner: _owner,
repo: _repo,
tag: "v".concat(version)
})["catch"](function () {
return doOctokit('repos', 'getReleaseByTag', {
owner: _owner,
repo: _repo,
tag: version
});
});
case 8:
_context4.t1 = _yield$doOctokit$catc = _context4.sent.data.body;
_context4.t0 = _context4.t1 !== null;
if (!_context4.t0) {
_context4.next = 12;
break;
}
_context4.t0 = _yield$doOctokit$catc !== void 0;
case 12:
if (!_context4.t0) {
_context4.next = 16;
break;
}
_context4.t2 = _yield$doOctokit$catc;
_context4.next = 17;
break;
case 16:
_context4.t2 = undefined;
case 17:
body = _context4.t2;
release.body = body;
if (!body) {
_context4.next = 31;
break;
}
parsed = (0, _parseChangelog["default"])(body);
_context4.t3 = _regenerator["default"].keys(parsed);
case 22:
if ((_context4.t4 = _context4.t3()).done) {
_context4.next = 31;
break;
}
v = _context4.t4.value;
if (!(v === version)) {
_context4.next = 29;
break;
}
_parsed$v = parsed[v], header = _parsed$v.header, _body = _parsed$v.body;
if (header) release.header = header;
if (_body) release.body = _body;
return _context4.abrupt("break", 31);
case 29:
_context4.next = 22;
break;
case 31:
_context4.next = 41;
break;
case 33:
_context4.prev = 33;
_context4.t5 = _context4["catch"](5);
_context4.next = 37;
return getChangelogFromFile(_owner, _repo);
case 37:
changelog = _context4.sent;
_ref8 = changelog[version] || {}, _header = _ref8.header, _body2 = _ref8.body;
if (_header) release.header = _header;
release.body = _body2;
case 41:
if (!release.body) {
release.error = new Error("failed to find GitHub release or changelog entry for version ".concat(version));
}
_context4.next = 47;
break;
case 44:
_context4.prev = 44;
_context4.t6 = _context4["catch"](3);
release.error = _context4.t6 instanceof Error ? _context4.t6 : new Error(String(_context4.t6));
case 47:
return _context4.abrupt("return", release);
case 48:
case "end":
return _context4.stop();
}
}, _callee4, null, [[3, 44], [5, 33]]);
}));
return function (_x7) {
return _ref6.apply(this, arguments);
};
}()));
case 14:
releases = _context5.sent;
return _context5.abrupt("return", Object.fromEntries(releases.sort(function (a, b) {
return _semver["default"].compare(a.version, b.version);
}).map(function (release) {
return [release.version, release];
})));
case 16:
case "end":
return _context5.stop();
}
}, _callee5);
}));
return _fetchChangelog.apply(this, arguments);
}