UNPKG

typescript-rest

Version:
170 lines (152 loc) 5.96 kB
'use strict'; import * as express from 'express'; import 'multer'; import { InternalServer } from './server-container'; import { HttpMethod, ServiceFactory } from './server-types'; import * as _ from 'lodash'; import * as fs from 'fs-extra'; import * as YAML from 'yamljs'; import * as path from 'path'; /** * The Http server main class. */ export class Server { /** * Create the routes for all classes decorated with our decorators */ static buildServices(router: express.Router, ...types: any[]) { const iternalServer: InternalServer = new InternalServer(router); iternalServer.buildServices(types); } /** * Return all paths accepted by the Server */ static getPaths(): Array<string> { const result = new Array<string>(); InternalServer.getPaths().forEach(value => { result.push(value); }); return result; } /** * Register a custom serviceFactory. It will be used to instantiate the service Objects * If You plan to use a custom serviceFactory, You must ensure to call this method before any typescript-rest service declaration. */ static registerServiceFactory(serviceFactory: ServiceFactory) { InternalServer.serviceFactory = serviceFactory; } /** * Configure the Server to use [typescript-ioc](https://github.com/thiagobustamante/typescript-ioc) * to instantiate the service objects. * If You plan to use IoC, You must ensure to call this method before any typescript-rest service declaration. */ static useIoC() { const ioc = require('typescript-ioc'); Server.registerServiceFactory({ create: (serviceClass) => { return ioc.Container.get(serviceClass); }, getTargetClass: (serviceClass: Function) => { let typeConstructor: any = serviceClass; if (typeConstructor['name'] && typeConstructor['name'] !== 'ioc_wrapper') { return <FunctionConstructor>typeConstructor; } while (typeConstructor = typeConstructor['__parent']) { if (typeConstructor['name'] && typeConstructor['name'] !== 'ioc_wrapper') { return <FunctionConstructor>typeConstructor; } } throw TypeError('Can not identify the base Type for requested target'); } }); } /** * Return the set oh HTTP verbs configured for the given path * @param path The path to search HTTP verbs */ static getHttpMethods(path: string): Array<HttpMethod> { const result = new Array<HttpMethod>(); InternalServer.getHttpMethods(path).forEach(value => { result.push(value); }); return result; } /** * A string used for signing cookies. This is optional and if not specified, * will not parse signed cookies. * @param secret the secret used to sign */ static setCookiesSecret(secret: string) { InternalServer.cookiesSecret = secret; } /** * Specifies a function that will be used to decode a cookie's value. * This function can be used to decode a previously-encoded cookie value * into a JavaScript string. * The default function is the global decodeURIComponent, which will decode * any URL-encoded sequences into their byte representations. * * NOTE: if an error is thrown from this function, the original, non-decoded * cookie value will be returned as the cookie's value. * @param decoder The decoder function */ static setCookiesDecoder(decoder: (val: string) => string) { InternalServer.cookiesDecoder = decoder; } /** * Set where to store the uploaded files * @param dest Destination folder */ static setFileDest(dest: string) { InternalServer.fileDest = dest; } /** * Set a Function to control which files are accepted to upload * @param filter The filter function */ static setFileFilter(filter: (req: Express.Request, file: Express.Multer.File, callback: (error: Error, acceptFile: boolean) => void) => void) { InternalServer.fileFilter = filter; } /** * Set the limits of uploaded data * @param limit The data limit */ static setFileLimits(limit: number) { InternalServer.fileLimits = limit; } /** * Creates and endpoint to publish the swagger documentation. * @param router Express router * @param filePath the path to a swagger file (json or yaml) * @param endpoint where to publish the docs * @param host the hostname of the service * @param schemes the schemes used by the server */ static swagger(router: express.Router, filePath: string, endpoint: string, host?: string, schemes?: string[]) { const swaggerUi = require('swagger-ui-express'); if (_.startsWith(filePath, '.')) { filePath = path.join(process.cwd(), filePath); } let swaggerDocument: any; if (_.endsWith(filePath, '.yml') || _.endsWith(filePath, '.yaml')) { swaggerDocument = YAML.load(filePath); } else { swaggerDocument = fs.readJSONSync(filePath); } if (host) { swaggerDocument.host = host; } if (schemes) { swaggerDocument.schemes = schemes; } router.get(path.posix.join('/', endpoint, 'json'), (req, res, next) => { res.send(swaggerDocument); }); router.get(path.posix.join('/', endpoint, 'yaml'), (req, res, next) => { res.set('Content-Type', 'text/vnd.yaml'); res.send(YAML.stringify(swaggerDocument, 1000)); }); router.use(path.posix.join('/', endpoint), swaggerUi.serve, swaggerUi.setup(swaggerDocument)); } }