UNPKG

webserv

Version:

a quick, flexible, fully typed development server

142 lines 6.64 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; (function (factory) { if (typeof module === "object" && typeof module.exports === "object") { var v = factory(require, exports); if (v !== undefined) module.exports = v; } else if (typeof define === "function" && define.amd) { define(["require", "exports", "../guards/method", "../guards/path", "../HttpError", "../processors/before/body.processor", "../transforms/json.transform", "../util/request"], factory); } })(function (require, exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const method_1 = require("../guards/method"); const path_1 = require("../guards/path"); const HttpError_1 = require("../HttpError"); const body_processor_1 = require("../processors/before/body.processor"); const json_transform_1 = require("../transforms/json.transform"); const request_1 = require("../util/request"); function isRecord(value) { return value && typeof value === 'object' && typeof value.id === 'string'; } exports.isRecord = isRecord; const DELETED = Symbol(); function defaultLoader(id) { if (id) { return undefined; } return []; } /** * The CRUD service provides basic in-memory Create Read Update Delete and List support on a record * centered around the provided path. * * - supported operations may be defined in properties * - a set of records may be provided to initialize the store * - a loader function can be used to load in records from another source (e.g. disk) * * List: GET {path}/ * Returns a list of all records * * Create: POST {path}/ * Create a new record to be stored in-memory * * Read: GET {path}/{id} * Returns a record if found; or returns a 404 status * * Update: PUT {path}/ * Updates a record if found; or returns a 404 status * * Delete: DELETE {path}/{id} * Deletes a record from the in-memory store */ function crudService(props) { const { route = '/', data = [], operations = ['list', 'create', 'read', 'update', 'delete'], dataLoader = defaultLoader } = props; const expandedRoute = route.charAt(route.length - 1) === '*' ? route : `${route}*`; const store = new Map(data.map((data) => [data.id, data])); const getRecord = (id) => (store.has(id) ? store.get(id) : dataLoader(id)); const middlewares = { create: { guards: [method_1.method.post()], middleware: (request) => { const { body } = request_1.getParams(request, 'body'); if (isRecord(body)) { store.set(body.id, body); } else { throw new HttpError_1.HttpError(400 /* BadRequest */); } } }, read: { guards: [method_1.method.get('/:id')], middleware: (request) => __awaiter(this, void 0, void 0, function* () { const { params } = request_1.getParams(request, 'params'); if (params.id) { const record = yield getRecord(params.id); if (isRecord(record)) { store.set(record.id, record); return record; } } throw new HttpError_1.HttpError(404 /* NotFound */); }) }, delete: { guards: [method_1.method.delete('/:id')], middleware: (request) => __awaiter(this, void 0, void 0, function* () { const { params } = request_1.getParams(request, 'params'); if (params.id) { const record = yield getRecord(params.id); if (isRecord(record)) { store.set(record.id, DELETED); return record; } } throw new HttpError_1.HttpError(404 /* NotFound */); }) }, update: { guards: [method_1.method.put()], middleware: (request) => __awaiter(this, void 0, void 0, function* () { const { body } = request_1.getParams(request, 'body'); if (isRecord(body)) { const record = yield getRecord(body.id); if (isRecord(record)) { store.set(body.id, Object.assign(Object.assign({}, record), body)); return store.get(body.id); } } throw new HttpError_1.HttpError(404 /* NotFound */); }) }, list: { guards: [method_1.method.get('/')], middleware: () => __awaiter(this, void 0, void 0, function* () { const fileData = yield dataLoader(); return [...fileData.filter((record) => !store.has(record.id)), ...store.values()].filter(isRecord); }) } }; return { route: { guards: [path_1.pathGuard({ match: expandedRoute })], before: [body_processor_1.body({})], transforms: [json_transform_1.jsonTransform], middleware: Object.entries(middlewares) .filter(([op]) => operations.includes(op)) .map(([, desc]) => desc) } }; } exports.crudService = crudService; }); //# sourceMappingURL=crud.service.js.map