UNPKG

memserver

Version:

in-memory database/ORM and http mock server you can run in-browser and node environments. Built for large frontend teams, fast tests and rapid prototyping

134 lines (104 loc) 3.82 kB
declare global { interface Window { MemserverModel: any; MemServer: any; } } import kleur from "kleur"; import TargetModel from "@memserver/model"; import "./set-pretender-context"; import Pretender from "pretender/dist/pretender.js"; import hackPretender from "./pretender-hacks"; // NOTE: check this const DEFAULT_PASSTHROUGHS = [ "http://localhost:0/chromecheckurl", "http://localhost:30820/socket.io", ]; interface MemserverOptions { logging?: boolean; initializer?: () => any | void; routes?: () => any | void; [propName: string]: any; } interface Memserver { get: (urlPath, any?) => any; put: (urlPath, any?) => any; delete: (urlPath, any?) => any; post: (urlPath, any?) => any; patch: (urlPath, any?) => any; shutdown: () => any; } // NOTE: Test for // globalizeModules: true, // globalizeModels: true, class Memserver { Models = {}; constructor(options: MemserverOptions = { logging: true }) { hackPretender(Pretender as any); const initializer = options.initializer || async function () {}; const routes = options.routes || function () {}; const logging = options.hasOwnProperty("logging") ? options.logging : true; window.MemserverModel = window.MemserverModel || TargetModel; const initializerReturn = initializer(); this.Models = window.MemserverModel._modelDefinitions; window.MemServer = startPretender(routes, Object.assign(options, { logging }), this.Models); window.MemServer.Models = this.Models; return window.MemServer; } } export default Memserver; function startPretender(routes, options, Models) { Pretender.prototype.namespace = options.namespace; Pretender.prototype.urlPrefix = options.urlPrefix; Pretender.prototype.timing = options.timing; let pretender = new Pretender( function () { const Memserver = kleur.cyan("[Memserver]"); this.Models = Models; if (options.logging) { this.handledRequest = function (verb, path, request) { const method = verb.toUpperCase(); console.log(Memserver, colorStatusCode(request.status), method, request.url); if (["POST", "PUT"].includes(method)) { console.log(`${method} REQUEST BODY IS:`, request.params); } console.log(JSON.parse(request.responseText)); }; this.passthroughRequest = function (verb, path, request) { console.log(Memserver, kleur.yellow("[PASSTHROUGH]"), verb, request.url); }; } this.unhandledRequest = function (verb, path, request) { console.log(Memserver, kleur.red("[UNHANDLED REQUEST]"), verb, path); console.log(kleur.red("UNHANDLED REQUEST WAS:\n"), request); console.log(request); }; }, { trackRequests: false } ); // HACK: Pretender this.passthrough for better UX // TODO: this doesnt passthrough full http:// https:// pretender.passthrough = function (url) { const parent = Pretender.prototype; const verbs = ["get", "post", "put", "delete"]; if (!url) { ["/**", "/", "/*"].forEach((path) => { verbs.forEach((verb) => pretender[verb](path, parent.passthrough)); }); return; } const fullUrl = (this.urlPrefix || "") + (this.namespace ? "/" + this.namespace : "") + url; verbs.forEach((verb) => pretender[verb](fullUrl, parent.passthrough)); }; DEFAULT_PASSTHROUGHS.forEach((url) => pretender.passthrough(url)); // END: Pretender this.passthrough for better UX routes.apply(pretender, []); return pretender; } function colorStatusCode(statusCode) { if (statusCode === 200 || statusCode === 201) { return kleur.green(statusCode); } else if (statusCode === 404 || statusCode === 204) { return kleur.cyan(statusCode); } return kleur.red(statusCode); }