UNPKG

@m-ld/gateway

Version:

m-ld gateway for services

101 lines 9.76 kB
import { StringReadable } from '../lib/index.js'; import { toHttpError } from './errors.js'; import { pipeline } from 'stream/promises'; import 'reflect-metadata'; export const formatter = (format) => { return (_req, res, body) => { const data = `${format.opening || ''}${format.stringify(body)}${format.closing || ''}`; res.setHeader('Content-Length', Buffer.byteLength(data)); return data; }; }; const ND_JSON_FORMAT = { stringify: JSON.stringify, separator: '\n' }; export const JSON_LD_FORMAT = { stringify: s => JSON.stringify(s, null, ' '), separator: ',\n' }; export const HTML_FORMAT = { stringify: s => JSON.stringify(s, null, ' '), opening: '<pre>', closing: '</pre>', separator: '\n' }; export async function sendChunked(res, results, status = 200) { res.header('transfer-encoding', 'chunked'); res.header('content-type', 'application/x-ndjson'); res.status(status); await pipeline(new StringReadable(results, ND_JSON_FORMAT), res); } function nextifyHandler(handler) { return function (req, res, next) { try { Promise.resolve(handler.call(this, req, res)).then(next) .catch(e => next(toHttpError(e))); } catch (e) { next(toHttpError(e)); // in case of synchronous error } }; } // noinspection JSUnusedGlobalSymbols export class EndPoint { constructor(outer, stem, beforeHandlers) { this.outer = outer; this.useHandlers = []; this.useForHandlers = {}; this.use = (...handlers) => { this.useHandlers.push(...this.nextify(handlers)); }; this.useFor = (verb, ...handlers) => { var _a; ((_a = this.useForHandlers)[verb] ?? (_a[verb] = [])).push(...this.nextify(handlers)); }; EndPoint.checkRoute(stem); const api = (route) => { EndPoint.checkRoute(route); return `${stem}${route}`; }; for (let verb of ['del', 'get', 'head', 'put', 'post', 'patch']) { this[verb] = (route, ...handlers) => outer[verb](api(route), ...this.useHandlers, ...this.useForHandlers[verb] ?? [], ...this.nextify(handlers)); } const { use, useFor } = this; beforeHandlers?.({ use, useFor }); for (let [verb, ...args] of getDecoratedHandlers(this)) this[verb].apply(this, args); } static checkRoute(route) { if (route && !route.startsWith('/')) throw new RangeError('Route must start with "/"'); } nextify(handlers) { return handlers.flat().map(handler => { if (handler.length < 3) handler = nextifyHandler(handler); return handler.bind(this); }); } } const handlersMetadataKey = Symbol('__handlers'); function getDecoratedHandlers(target) { return Reflect.getMetadata(handlersMetadataKey, target) ?? []; } function handlerDecorator(verb, opts = '') { function use(target, _handlerName, descriptor) { if (target instanceof EndPoint) { const handlers = getDecoratedHandlers(target); const handler = descriptor.value; handlers.push(verb === 'use' ? ['use', handler] : [verb, opts, handler]); Reflect.defineMetadata(handlersMetadataKey, handlers, target); } else { return handlerDecorator(verb, target); } } return use; } export const use = handlerDecorator('use'); export const del = handlerDecorator('del'); export const get = handlerDecorator('get'); export const head = handlerDecorator('head'); export const put = handlerDecorator('put'); export const post = handlerDecorator('post'); export const patch = handlerDecorator('patch'); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRW5kUG9pbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaHR0cC9FbmRQb2ludC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFJQSxPQUFPLEVBQWdCLGNBQWMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9ELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDMUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRTNDLE9BQU8sa0JBQWtCLENBQUM7QUFFMUIsTUFBTSxDQUFDLE1BQU0sU0FBUyxHQUFHLENBQUMsTUFBb0IsRUFBYSxFQUFFO0lBQzNELE9BQU8sQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxFQUFFO1FBQ3pCLE1BQU0sSUFBSSxHQUFHLEdBQUcsTUFBTSxDQUFDLE9BQU8sSUFBSSxFQUFFLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsR0FBRyxNQUFNLENBQUMsT0FBTyxJQUFJLEVBQUUsRUFBRSxDQUFDO1FBQ3ZGLEdBQUcsQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLEVBQUUsTUFBTSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQ3pELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQyxDQUFDO0FBQ0osQ0FBQyxDQUFDO0FBQ0YsTUFBTSxjQUFjLEdBQWlCLEVBQUUsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDO0FBQ3BGLE1BQU0sQ0FBQyxNQUFNLGNBQWMsR0FBaUI7SUFDMUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQztJQUM1QyxTQUFTLEVBQUUsS0FBSztDQUNqQixDQUFDO0FBQ0YsTUFBTSxDQUFDLE1BQU0sV0FBVyxHQUFpQjtJQUN2QyxTQUFTLEVBQUUs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