UNPKG

nephele

Version:

Highly customizable and extensible WebDAV server for Node.js and Express.

217 lines (181 loc) 5.11 kB
import { HTTPStatusMessages } from './HTTPStatusMessages.js'; export class PropStatStatus { statusCode: number; statusMessage: string; body: { [k: string]: any } | undefined = undefined; prop: { [k: string]: any } | undefined = undefined; description: string | undefined = undefined; constructor(statusCode: number, statusMessage?: string) { this.statusCode = statusCode; if (statusMessage) { this.statusMessage = statusMessage; } else if (statusCode in HTTPStatusMessages) { this.statusMessage = HTTPStatusMessages[statusCode as keyof typeof HTTPStatusMessages]; } else { this.statusMessage = ''; } } toString() { return `PropStatStatus: ${this.statusCode} ${this.statusMessage}${ this.description ? ` (${this.description})` : '' }`; } /** * Add an xml2js compatible body to the element. * * The object will be spread into the body of the element. * * Under normal circumstances, you shouldn't need to use this. * * @param body An xml2js compatible object. */ setBody(body: { [k: string]: any } | undefined) { this.body = body; } /** * Add an xml2js compatible body to the prop element. * * It should be a prop object, like this for successful props: * * { * someprop: ['value'], * otherprop: ['other value'] * } * * Or like this for error props (like forbidden): * * { * someprop: {}, * otherprop: {} * } * * @param prop An xml2js compatible object. */ setProp(prop: { [k: string]: any } | undefined) { this.prop = prop; } render() { let response: { [k: string]: any } = { status: [`HTTP/1.1 ${this.statusCode} ${this.statusMessage}`], }; if (this.description != null) { response.responsedescription = [this.description]; } if (this.prop) { response.prop = this.prop; } if (this.body) { response = { ...response, ...this.body }; } return response; } } export class Status { element: string; statusCode: number; statusMessage: string; body: { [k: string]: any } | undefined = undefined; propStatStatuses: PropStatStatus[] = []; description: string | undefined = undefined; href: URL; constructor( href: URL, statusCode: number, statusMessage?: string, element: string = 'response', ) { this.href = href; this.statusCode = statusCode; this.element = element; if (statusMessage) { this.statusMessage = statusMessage; } else if (statusCode in HTTPStatusMessages) { this.statusMessage = HTTPStatusMessages[statusCode as keyof typeof HTTPStatusMessages]; } else { this.statusMessage = ''; } } toString() { return `Status: ${this.statusCode} ${this.statusMessage}${ this.description ? ` (${this.description})` : '' }`; } setDescription(description: string | undefined) { this.description = description; } /** * Add an xml2js compatible body to the element. * * The object will be spread into the body of the element. * * @param body An xml2js compatible object. */ setBody(body: { [k: string]: any } | undefined) { // TODO: Should I use these checks? // if (this.propStatStatuses.length) { // throw new Error("Can't add body to a Status with PropStatStatuses."); // } this.body = body; } addPropStatStatus(propStatStatus: PropStatStatus) { // if (this.body != null) { // throw new Error("Can't add PropStatStatus to a Status with a body."); // } this.propStatStatuses.push(propStatStatus); } render() { let response: { [k: string]: any } = { href: { _: this.href.toString() }, }; if (this.description != null) { response.responsedescription = [this.description]; } if (this.propStatStatuses.length > 0) { // propstat includes the response codes within the propstat object. response.propstat = []; for (let propStatStatus of this.propStatStatuses) { response.propstat.push(propStatStatus.render()); } } else { // Build a response object. response.status = [`HTTP/1.1 ${this.statusCode} ${this.statusMessage}`]; } if (this.body) { response = { ...response, ...this.body }; } return response; } } export class MultiStatus { statuses: Status[] = []; description: string | undefined = undefined; addStatus(status: Status) { this.statuses.push(status); } setDescription(description: string | undefined) { this.description = description; } render() { const responses: any[] = []; const xml: any = { multistatus: { $: { xmlns: 'DAV:', }, }, }; if (this.description != null) { xml.responsedescription = [this.description]; } if (this.statuses.length < 1) { return xml; } xml.multistatus.response = responses; for (let status of this.statuses) { responses.push(status.render()); } return xml; } }