UNPKG

@bigtest/mirage

Version:

A client-side server to develop, test and prototype your app.

125 lines (110 loc) 4.07 kB
import { isBlank, typeOf } from './utils/ember-shims'; import { MirageError } from './assert'; import Response from './response'; import FunctionHandler from './route-handlers/function'; import ObjectHandler from './route-handlers/object'; import GetShorthandHandler from './route-handlers/shorthands/get'; import PostShorthandHandler from './route-handlers/shorthands/post'; import PutShorthandHandler from './route-handlers/shorthands/put'; import DeleteShorthandHandler from './route-handlers/shorthands/delete'; import HeadShorthandHandler from './route-handlers/shorthands/head'; function isNotBlankResponse(response) { return response && !((typeof response) === 'object' && Object.keys(response).length === 0) && (Array.isArray(response) || !isBlank(response)); } const DEFAULT_CODES = { get: 200, put: 204, post: 201, 'delete': 204 }; function createHandler({ verb, schema, serializerOrRegistry, path, rawHandler, options }) { let handler; let args = [schema, serializerOrRegistry, rawHandler, path, options]; let type = typeof rawHandler; if (type === 'function') { handler = new FunctionHandler(...args); } else if (type === 'object') { handler = new ObjectHandler(...args); } else if (verb === 'get') { handler = new GetShorthandHandler(...args); } else if (verb === 'post') { handler = new PostShorthandHandler(...args); } else if (verb === 'put' || verb === 'patch') { handler = new PutShorthandHandler(...args); } else if (verb === 'delete') { handler = new DeleteShorthandHandler(...args); } else if (verb === 'head') { handler = new HeadShorthandHandler(...args); } return handler; } export default class RouteHandler { constructor({ schema, verb, rawHandler, customizedCode, options, path, serializerOrRegistry }) { this.verb = verb; this.customizedCode = customizedCode; this.serializerOrRegistry = serializerOrRegistry; this.handler = createHandler({ verb, schema, path, serializerOrRegistry, rawHandler, options }); } handle(request) { return new Promise(resolve => { this._getMirageResponseForRequest(request).then(mirageResponse => { this.serialize(mirageResponse, request).then(serializedMirageResponse => { resolve(serializedMirageResponse.toRackResponse()); }); }); }); } _getMirageResponseForRequest(request) { let result; try { /* We need to do this for the #serialize convenience method. Probably is a better way. */ if (this.handler instanceof FunctionHandler) { this.handler.setRequest(request); } result = this.handler.handle(request); } catch (e) { if (e instanceof MirageError) { throw e; } else { let message = (typeOf(e) === 'string') ? e : e.message; let error = new MirageError(`Your ${request.method} handler for the url ${request.url} threw an error: ${message}`); result = new Response(500, {}, error.message); } } return this._toMirageResponse(result); } _toMirageResponse(result) { let mirageResponse; return new Promise(resolve => { Promise.resolve(result).then(response => { if (response instanceof Response) { mirageResponse = result; } else { let code = this._getCodeForResponse(response); mirageResponse = new Response(code, {}, response); } resolve(mirageResponse); }); }); } _getCodeForResponse(response) { let code; if (this.customizedCode) { code = this.customizedCode; } else { code = DEFAULT_CODES[this.verb]; if (code === 204 && isNotBlankResponse(response)) { code = 200; } } return code; } serialize(mirageResponsePromise, request) { return new Promise(resolve => { Promise.resolve(mirageResponsePromise).then(mirageResponse => { mirageResponse.data = this.serializerOrRegistry.serialize(mirageResponse.data, request); resolve(mirageResponse); }); }); } }