UNPKG

liefern

Version:

Node Webserver without dependencies

278 lines (236 loc) 6.49 kB
# liefern.io Simple, fast and no-dependency web server for nodejs. # Table of Contents 1. [Installation](#installation) 2. [Quick Start](#quick-start) 3. [Examples](#examples) - [Hello World](#hello-world) - [Static files](#static-files) - [Testing with supertest](#testing-with-supertest) 4. [Features](#features) 4. [Requirements](#requirements) 4. [Documentation](#documentation) - [Liefern](#liefern) - [Constructor](#constructor) - [.start](#start) - [.stop](#stop) - [.use](#use) - [.cors](#cors) - [.get](#get) - [.head](#head) - [.post](#post) - [.put](#put) - [.delete](#delete) - [.patch](#patch) - [.connect](#connect) - [.trace](#trace) - [.options](#options) - [.all](#all) - [Controller](#controller) - [ControllerParams](#controllerparams) - [UrlMatcherType](#urlmatchertype) - [UrlParams](#urlparams) - [SharedObject](#sharedobject) - [Request](#request) - [Response](#response) ## Installation ```console $ npm install liefern ``` ## Quick Start ```console $ mkdir myapp $ cd myapp $ npm init $ npm install liefern ``` ## Examples ### Hello World import { Liefern } from 'liefern' const server = Liefern() server.use(({ request, sharedData }) => { sharedData.requestIp = request.socket.remoteAddress }) server.get('/', ({ send: { text }, sharedData }) => { text(`Hello World! (${sharedData.requestIp})`) }) server.post('/', async ({ send: { text }, body }) => { console.log(await body()) text('Hello World!') }) server.start(1337) ### Static files import { Liefern } from 'liefern' const server = Liefern() server.static('/', `/absolutPath/to/publicHtml`) server.start(1337) ### Testing with supertest import { Liefern } from 'liefern' const server = Liefern({ name: 'TestServer' }) server.get('/', ({ send: { ok }}) => { ok() }) await supertest(server.httpServer) .get('/') .expect(200) ## Features - [x] routing - [x] regex url-pattern - [x] url-pattern-matching customizable - [x] all-helper for html-verb independed routes - [x] logging - [x] customizable - [x] full async - [x] exitable by signal - [x] appendable with middlewares - [x] shared data (middleware -> controller) - [x] serving static files - [x] even with middleware handling - [x] typescript - [x] ESM & CJS - [x] CORS - [x] helper for incomming request-body (json, text) - [x] plain node testrunner ## Requirements - node - we using "node:" protocol imports (https://nodejs.org/api/esm.html#node-imports) so we need a node-version supporting this - 14.13.1 (if you using "import") - 16.0.0 (if you use "require") ## Documentation ### Liefern #### Constructor new Liefern({ name?: string logger?: Logger urlMatcher?: UrlMatcherType }) #### .start const server = new Liefern() async server.start(8080) #### .stop const server = new Liefern() async server.start(8080) async server.stop() #### .use const server = new Liefern() server.use(({ request, sharedData }) => { sharedData.requestIp = request.socket.remoteAddress }) #### .cors server.cors({ origin?: string[] | '*', allowMethods?: string[] | '*', exposeHeaders?: string[], allowHeaders?: string[] | '*', maxAge?: number, credentials?: boolean, secureContext?: boolean, privateNetworkAccess?: boolean }) #### .get server.get('/api/user/(\\d+)', ({ send: { json }, urlParams }) => { const [userId] = urlParams json({ testData: true, id: userId }) }) #### .head server.head('/', ({ send: { ok }}) => { ok() }) #### .post server.post('/', ({ send: { ok }}) => { ok() }) #### .put server.put('/', ({ send: { ok }}) => { ok() }) #### .delete server.delete('/', ({ send: { ok }}) => { ok() }) #### .patch server.patch('/', ({ send: { ok }}) => { ok() }) #### .connect server.connect('/', ({ send: { forbidden }}) => { forbidden() }) #### .trace server.trace('/', ({ send: { notFound }}) => { notFound() }) #### .options server.options('/', ({ send: { ok }}) => { ok() }) #### .all server.all('/', ({ send: { ok }}) => { ok() }) ### Controller type Controller = (params: ControllerParams) => void | Promise<void> #### ControllerParams type ControllerParams = { sharedData: SharedObject request: Request response: Response urlParams: UrlParams statusCode: (statusCode: number) => void body: undefined | string | JsonType contentType: { textHtml: () => void textPlain: () => void applicationJson: () => void } setHeader: (name: string, value: string | number | readonly string[]) => void statusCodes: { ok: () => void created: () => void noContent: () => void movedPermanently: () => void notModified: () => void badRequest: () => void unauthorized: () => void paymentRequired: () => void forbidden: () => void notFound: () => void internalServerError: () => void notImplemented: () => void } send: { json: (data: JsonType) => void text: (data: string) => void html: (data: string) => void ok: () => void created: () => void noContent: () => void movedPermanently: (url: string) => void notModified: () => void badRequest: () => void unauthorized: () => void paymentRequired: () => void forbidden: () => void notFound: () => void methodNotAllow: () => void internalServerError: () => void notImplemented: () => void } } ### UrlMatcherType type UrlMatcherType = ( url: string, pattern: string | RegExp, ) => false | UrlParams | Promise<false | UrlParams> ### UrlParams type UrlParams = string[] ### SharedObject type SharedObject = Record<string, unknown> & { body: undefined | string | JsonType } ### Request type Request = http.IncomingMessage ### Response type Response = http.ServerResponse<http.IncomingMessage> & { req: http.IncomingMessage }