36 lines
1.4 KiB
JavaScript
36 lines
1.4 KiB
JavaScript
'use strict';
|
|
|
|
const { parse } = require('./registry');
|
|
const { validate } = require('./validation');
|
|
const MAX_MESSAGE_BYTES = 2 * 1024 * 1024;
|
|
|
|
async function boundedJson(response) {
|
|
const chunks = [];
|
|
let bytes = 0;
|
|
for await (const chunk of response.body) {
|
|
bytes += chunk.length;
|
|
if (bytes > MAX_MESSAGE_BYTES) throw new Error('Source plugin response exceeds limit');
|
|
chunks.push(chunk);
|
|
}
|
|
return JSON.parse(Buffer.concat(chunks).toString('utf8'));
|
|
}
|
|
|
|
async function parseSource(plugin, operation, input) {
|
|
const endpoint = plugin === 'mangadex' ? process.env.MANGADEX_PLUGIN_URL : process.env.SOURCE_PLUGIN_URL;
|
|
if (!endpoint) return validate(plugin, operation, parse(plugin, operation, input));
|
|
const url = new URL('/v1/parse', endpoint);
|
|
if (!['http:', 'https:'].includes(url.protocol)) throw new Error('Invalid source plugin endpoint');
|
|
const body = JSON.stringify({ plugin, operation, input });
|
|
if (Buffer.byteLength(body) > MAX_MESSAGE_BYTES) throw new Error('Source plugin request exceeds limit');
|
|
const response = await fetch(url, {
|
|
method: 'POST',
|
|
headers: { 'content-type': 'application/json' },
|
|
body,
|
|
signal: AbortSignal.timeout(10000),
|
|
});
|
|
if (!response.ok) throw new Error(`Source parser unavailable (${response.status}); checkpoint preserved`);
|
|
return validate(plugin, operation, await boundedJson(response));
|
|
}
|
|
|
|
module.exports = { parseSource };
|