UNPKG

@citation-js/core

Version:

Convert different bibliographic metadata sources

87 lines 3.02 kB
import syncFetch from 'sync-fetch'; import fetchPolyfill from 'fetch-ponyfill'; import logger from '../logger.js'; import pkg from '../../package.json'; const isBrowser = typeof location !== 'undefined' && typeof navigator !== 'undefined'; const { fetch: asyncFetch, Headers: asyncHeaders } = typeof fetch === 'function' && isBrowser ? { fetch, Headers } : fetchPolyfill(); let userAgent = `Citation.js/${pkg.version}`; if (typeof process !== 'undefined' && process && process.release && process.release.name === 'node' && process.version) { userAgent += ` Node.js/${process.version}`; } function normaliseHeaders(headers) { const result = {}; const entries = headers instanceof asyncHeaders || headers instanceof syncFetch.Headers ? Array.from(headers) : Object.entries(headers); for (const [name, header] of entries) { result[name.toLowerCase()] = header.toString(); } return result; } function parseOpts(opts = {}) { const reqOpts = { headers: { accept: '*/*' }, method: 'GET', checkContentType: opts.checkContentType }; if (userAgent && !isBrowser) { reqOpts.headers['user-agent'] = userAgent; } if (opts.body) { reqOpts.method = 'POST'; const isJson = typeof opts.body !== 'string'; reqOpts.body = isJson ? JSON.stringify(opts.body) : opts.body; reqOpts.headers['content-type'] = isJson ? 'application/json' : 'text/plain'; } if (opts.headers) { Object.assign(reqOpts.headers, normaliseHeaders(opts.headers)); } return reqOpts; } function sameType(request, response) { if (!request.accept || request.accept === '*/*' || !response['content-type']) { return true; } const [a, b] = response['content-type'].split(';')[0].trim().split('/'); return request.accept.split(',').map(type => type.split(';')[0].trim().split('/')).some(([c, d]) => (c === a || c === '*') && (d === b || d === '*')); } function checkResponse(response, opts) { const { status, headers } = response; let error; if (status >= 400) { error = new Error(`Server responded with status code ${status}`); } else if (opts.checkContentType === true && !sameType(opts.headers, normaliseHeaders(headers))) { error = new Error(`Server responded with content-type ${headers.get('content-type')}`); } if (error) { error.status = status; error.headers = headers; error.body = response.body; throw error; } return response; } export function fetchFile(url, opts) { const reqOpts = parseOpts(opts); logger.http('[core]', reqOpts.method, url, reqOpts); const response = checkResponse(syncFetch(url, reqOpts), reqOpts); return response.text(); } export async function fetchFileAsync(url, opts) { const reqOpts = parseOpts(opts); logger.http('[core]', reqOpts.method, url, reqOpts); return asyncFetch(url, reqOpts).then(response => checkResponse(response, reqOpts)).then(response => response.text()); } export function setUserAgent(newUserAgent) { userAgent = newUserAgent; } export default fetchFile;