All files / src api.ts

93.75% Statements 30/32
75% Branches 12/16
100% Functions 8/8
96.67% Lines 29/30
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72  4x 4x   4x   4x     8x     8x   8x       8x               5x 5x   5x 5x 5x 5x     5x 7x   7x 7x                 8x 9x   9x 8x   1x           5x 5x   5x   3x 3x   3x      
import {Server} from "./server";
import {API_ROUTE_PREFIX} from "./config";
import path from "path";
import {IApiConfig, IApiHandlerModule, ICookieMap} from "./types";
import {CookieVersionMatcher} from "./cookie-version-matcher";
 
export class Api {
    config: IApiConfig;
    versionMatcher?: CookieVersionMatcher;
    private handler: { [version: string]: IApiHandlerModule } = {};
 
    constructor(config: IApiConfig) {
        this.config = config;
 
        Iif (this.config.versionMatcher) {
            this.versionMatcher = new CookieVersionMatcher(this.config.versionMatcher);
        }
 
        this.prepareHandlers();
    }
 
    /**
     * Registers API endpoints /{API_PREFIX}/{APINAME}
     * @param {Server} app
     */
    registerEndpoints(app: Server) {
        app.addUse(`/${API_ROUTE_PREFIX}/${this.config.name}`, (req, res, next) => {
            const requestVersion = this.detectVersion(req.cookies);
 
            req.headers["originalurl"] = req.url;
            req.headers["originalpath"] = req.path;
            req.url = `/${requestVersion}${req.url}`;
            next();
        });
 
        Object.keys(this.config.versions).forEach(version => {
            const apiHandler = this.config.versions[version];
 
            apiHandler.endpoints.forEach(endpoint => {
                app.addRoute(`/${API_ROUTE_PREFIX}/${this.config.name}/${version}${endpoint.path}`, endpoint.method, this.handler[version][endpoint.controller], endpoint.middlewares);
            });
        });
    }
 
    /**
     * Resolves version handlers based on configuration
     */
    private prepareHandlers() {
        Object.keys(this.config.versions).forEach(version => {
            const configurationHandler = this.config.versions[version].handler;
 
            if (configurationHandler) {
                this.handler[version] = configurationHandler;
            } else {
                this.handler[version] = require(path.join(process.cwd(), `/src/api/`, this.config.name, version));
            }
        });
    }
 
    private detectVersion(cookie: ICookieMap): string {
        const cookieKey = this.config.testCookie;
        const cookieVersion = cookie[cookieKey] && this.config.versions[cookie[cookieKey]] ? cookie[cookieKey] : null;
 
        if (cookieVersion) return cookieVersion;
 
        const matcherVersion = this.versionMatcher ? this.versionMatcher.match(cookie) : null;
        Iif (matcherVersion && this.config.versions[matcherVersion]) return matcherVersion;
 
        return this.config.liveVersion;
    }
}