UNPKG

@stencila/jesta

Version:

Stencila plugin for executable documents using JavaScript

125 lines (124 loc) 4.18 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.readHttp = exports.readFile = exports.readStdio = exports.read = exports.schema = void 0; const content_type_1 = __importDefault(require("content-type")); const fs_1 = __importDefault(require("fs")); const mime_1 = __importDefault(require("mime")); const path_1 = __importDefault(require("path")); const util_1 = require("util"); const errors_1 = require("./util/errors"); const http_1 = require("./util/http"); exports.schema = { title: 'read', description: 'Read content from a URL.', required: ['input'], properties: { input: { description: 'The URL to read content from.', type: 'string', pattern: '^(file|https?|stdio|stdin|string)://.*', }, cache: { description: 'Use and store cached content (for http:// URLs only).', type: 'boolean', }, }, }; /** * Read content from a URL. * * For HTTP/S URLs this function complies with [RFC 7234](http://httpwg.org/specs/rfc7234.html) * for caching of requests. Use `force` to ignore any cached content that may * exist on the machine for the URL. * * @param input The URL to read. * @param cache Should any cached content be ignored? For remote URLs only. * @returns The content that was read. */ async function read(input, cache = true) { const match = /^([a-z]{2,6}):\/\//.exec(input); if (match) { const protocol = match[1]; switch (protocol) { case 'string': return [input.slice(9), undefined]; case 'stdio': case 'stdin': return [await readStdio(), undefined]; case 'file': return readFile(input.slice(7)); case 'http': case 'https': return readHttp(input, cache); default: throw new errors_1.CapabilityError(`read over protocol "${protocol}"`); } } throw new errors_1.CapabilityError(`read from URL "${input.slice(0, 500)}"`); } exports.read = read; read.schema = exports.schema; /** * Read content from standard input * * @returns The content */ async function readStdio() { const stream = process.stdin; stream.setEncoding('utf8'); return new Promise((resolve, reject) => { let data = ''; stream.on('data', (chunk) => (data += chunk)); stream.on('end', () => resolve(data)); stream.on('error', (error) => reject(error)); }); } exports.readStdio = readStdio; /** * Read content from the local file system * * @param filePath The path to the file to read * @returns A tuple of the content and its format */ async function readFile(filePath) { const content = await util_1.promisify(fs_1.default.readFile)(filePath, 'utf8'); const { ext } = path_1.default.parse(filePath); const format = ext !== '' ? ext.slice(1) : undefined; return [content, format]; } exports.readFile = readFile; /** * Read content from a HTTP/S URL * * The format is determined from the `Content-Type` header if present, * guessed from the URL's path segment if not. * * @param url The URL to fetch * @param caching Should a cache be used to retrieve / store content. * @returns A tuple of the content and its format */ async function readHttp(url, caching = true) { var _a; const response = await http_1.get(url, caching ? {} : { cache: false }); const content = response.body; let mediaType; try { ; ({ type: mediaType } = content_type_1.default.parse(response)); } catch (error) { } let format; if (mediaType !== undefined) { format = (_a = mime_1.default.getExtension(mediaType)) !== null && _a !== void 0 ? _a : undefined; } else { const { pathname } = new URL(url); const ext = path_1.default.extname(pathname); format = ext !== '' ? ext.slice(1) : undefined; } return [content, format]; } exports.readHttp = readHttp;