@citation-js/plugin-github
Version:
Citation.js plugin for GitHub repositories
128 lines (108 loc) • 2.55 kB
JavaScript
;
var _core = require("@citation-js/core");
var _date = require("@citation-js/date");
var _name = require("@citation-js/name");
let API_TOKEN = null;
const propMaps = {
name: 'title-short',
full_name: 'title',
description: 'abstract',
html_url: 'URL',
pushed_at: 'issued',
contributors_url: 'author'
};
async function parseValue(prop, value) {
switch (prop) {
case 'contributors_url':
{
let contributors = await api(value);
contributors = await Promise.all(contributors.map(({
url
}) => api(url)));
return contributors.map(({
name,
login
}) => name ? (0, _name.parse)(name) : {
literal: login
});
}
case 'pushed_at':
return (0, _date.parse)(value);
default:
return value;
}
}
const config = {
setApiToken(token) {
API_TOKEN = token;
}
};
async function json(input) {
const output = {
type: 'software'
};
const tags = input.tags_url ? await api(input.tags_url) : [];
for (const prop in propMaps) {
if (prop in input) {
output[propMaps[prop]] = await parseValue(prop, input[prop]);
}
}
if (tags) {
output.version = tags[0].name;
output.custom = {
versions: tags.map(tag => ({
version: tag.name
}))
};
}
return output;
}
async function api(input) {
const headers = {
Accept: 'application/vnd.github.v3+json'
};
if (API_TOKEN) {
headers.Authorization = `token ${API_TOKEN}`;
}
const output = await _core.util.fetchFileAsync(input, {
headers
});
return JSON.parse(output);
}
function url(input) {
const [, user, repo] = input.match(/^https?:\/\/github.com\/([^/]+)\/([^/]+)/);
return `https://api.github.com/repos/${user}/${repo}`;
}
_core.plugins.add('@github', {
config: config,
input: {
'@github/url': {
parseType: {
dataType: 'String',
predicate: /^https?:\/\/github\.com\/[^/]+\//,
extends: '@else/url'
},
parse: url
},
'@github/api': {
parseType: {
dataType: 'String',
predicate: /^https?:\/\/api\.github\.com\/repos\/[^/]+\//,
extends: '@else/url'
},
parseAsync: api
},
'@github/object': {
parseType: {
dataType: 'SimpleObject',
propertyConstraint: {
props: 'url',
value(url) {
return /^https?:\/\/api\.github\.com\/repos\/[^/]+\//.test(url);
}
}
},
parseAsync: json
}
}
});