UNPKG

snakey

Version:

An Obeserver-based web microframework for Node.js

93 lines (83 loc) 3.04 kB
import { ServerResponse } from "http"; import { Observer, OperatorFunction } from "rxjs"; import { isString } from "util"; import { map } from "rxjs/operators"; import { Context } from "./index"; export type HeaderMap = {[name: string]: string | number | string[]}; export type ResponderParams = { body?: string | {toString(): string}, status?: number, headers?: HeaderMap, encoding?: string, endResponse?: boolean } /** * A Responder is an object that collects the information needed to construct a response * to the client, and provides a method which sends the response. */ export class Responder { readonly body: string | {toString(): string}; readonly status: number; readonly headers: HeaderMap; readonly encoding: string; readonly endResponse; constructor(readonly resObj: ServerResponse, {body = "", status = 200, headers = {}, encoding = "utf-8", endResponse = true}: ResponderParams) { this.body = body; this.status = status; this.headers = headers; this.encoding = encoding; this.endResponse = endResponse; } respond() { this.resObj.writeHead(this.status, this.headers); const chunk: string = (isString(this.body)) ? this.body : this.body.toString(); if(this.endResponse) { this.resObj.end(chunk, this.encoding); } else { this.resObj.write(chunk, this.encoding); } } } /** * Creates a new OperatorFunction that takes a Context and constructs a Responder. * * The responder will write `text` to the client, with an HTTP status code of `status`. * * @param text The text that will be written to the client * @param status The HTTP status code. * @param encoding The encoding of the string */ export function textResponse(text: string, status: number = 200, encoding: string = "utf-8"): OperatorFunction<Context, Responder> { return map((ctx: Context) => new Responder(ctx.response, {body: text, status: status, encoding: encoding})) } /** * Creates a new OperatorFunction that takes a Context and constructs a Responder. * * The Responder will write `o` as a JSON string to the client, with an HTTP status code of `status`. * The appropriate content-type header will be set. * @param o * @param status */ export function jsonResponse(o: Object, status: number = 200): OperatorFunction<Context, Responder> { return map((ctx: Context) => new Responder(ctx.response, { body: JSON.stringify(o), status: status, headers: {"Content-Type": "application/json"} })); } /** * Observer for a stream of Responder. */ export class ResponderObserver implements Observer<Responder> { next(res): void { res.respond(); } error(err): void { console.error(err); } complete(): void { } }