Stryker

server.ts - Stryker report

File / Directory
Mutation score
# Killed
# Survived
# Timeout
# No coverage
# Runtime errors
# Transpile errors
Total detected
Total undetected
Total mutants
server.ts
77.78 %
77.78 12 4 2 0 63 0 14 4 81
Expand all
'use strict';

import * as express from 'express';
import * as fs from 'fs-extra';
import * as _ from 'lodash';
import 'multer';
import * as path from 'path';
import * as YAML from 'yamljs';
import { InternalServer } from './server-container';
import { FileLimits, HttpMethod, ServiceAuthenticator, ServiceFactory } from './server-types';

/**
 * The Http server main class.
 */
export class Server {
    /**
     * Create the routes for all classes decorated with our decorators
     */
    public static buildServices(router: express.Router, ...types: Array<any>) 0{
        const iternalServer: InternalServer = new InternalServer(router);
        iternalServer.buildServices(types);
    }

    /**
     * An alias for Server.loadServices()
     */
    public static loadControllers(router: express.Router, patterns: string | Array<string>, baseDir?: string) 1{
        Server.loadServices(router, patterns, baseDir);
    }

    /**
     * Load all services from the files that matches the patterns provided
     */
    public static loadServices(router: express.Router, patterns: string | Array<string>, baseDir?: string) 2{
        const importedTypes: Array<Function> = 3[];
        const requireGlob = require(4'require-glob');
        baseDir = baseDir 5|| process.cwd();
        const loadedModules: Array<any> = requireGlob.sync(patterns, {
            cwd: baseDir
        });

        _.values(loadedModules).forEach(serviceModule => 6{
            _.values(serviceModule).forEach((service: Function) => 7{
                importedTypes.push(service);
            });
        });

        try 8{
            Server.buildServices(router, ...importedTypes);
        } catch (e) 9{
            throw new TypeError(10`Error loading services for pattern: ${JSON.stringify(patterns)}. Error: ${e.message}`);
        }
    }

    /**
     * Return all paths accepted by the Server
     */
    public static getPaths(): Array<string> 11{
        const result = 12new Array<string>();
        InternalServer.getPaths().forEach(value => 13{
            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.
     */
    public static registerServiceFactory(serviceFactory: ServiceFactory) 14{
        InternalServer.serviceFactory = serviceFactory;
    }

    /**
     * Register a service authenticator. It will be used to authenticate users before the service method
     * invocations occurs.
     */
    public static registerAuthenticator(authenticator: ServiceAuthenticator) 15{
        InternalServer.authenticator = authenticator;
    }

    /**
     * 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.
     * @param es6 if true, import typescript-ioc/es6
     */
    public static useIoC(es6?: boolean) 16{
        const ioc = require(1718es6 ? 19'typescript-ioc/es6' : 20'typescript-ioc');
        Server.registerServiceFactory({
            create: (serviceClass) => 21{
                return ioc.Container.get(serviceClass);
            },
            getTargetClass: (serviceClass: Function) => 22{
                let typeConstructor: any = serviceClass;
                if (2324typeConstructor[25'name'] 26&& typeConstructor[27'name'] 28!== 29'ioc_wrapper') 30{
                    return typeConstructor as FunctionConstructor;
                }
                typeConstructor = typeConstructor[31'__parent'];
                while (32typeConstructor) 33{
                    if (3435typeConstructor[36'name'] 37&& typeConstructor[38'name'] 39!== 40'ioc_wrapper') 41{
                        return typeConstructor as FunctionConstructor;
                    }
                    typeConstructor = typeConstructor[42'__parent'];
                }
                throw TypeError(43'Can not identify the base Type for requested target');
            }
        });
    }

    /**
     * Return the set oh HTTP verbs configured for the given path
     * @param servicePath The path to search HTTP verbs
     */
    public static getHttpMethods(servicePath: string): Array<HttpMethod> 44{
        const result = 45new Array<HttpMethod>();
        InternalServer.getHttpMethods(servicePath).forEach(value => 46{
            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
     */
    public static setCookiesSecret(secret: string) 47{
        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
     */
    public static setCookiesDecoder(decoder: (val: string) => string) 48{
        InternalServer.cookiesDecoder = decoder;
    }

    /**
     * Set where to store the uploaded files
     * @param dest Destination folder
     */
    public static setFileDest(dest: string) 49{
        InternalServer.fileDest = dest;
    }

    /**
     * Set a Function to control which files are accepted to upload
     * @param filter The filter function
     */
    public static setFileFilter(filter: (req: Express.Request, file: Express.Multer.File,
        callback: (error: Error, acceptFile: boolean) => void) => void) 50{
        InternalServer.fileFilter = filter;
    }

    /**
     * Set the limits of uploaded data
     * @param limit The data limit
     */
    public static setFileLimits(limit: FileLimits) 51{
        InternalServer.fileLimits = limit;
    }

    /**
     * Sets converter for param values to have an ability to intercept the type that actually will be passed to service
     * @param fn The converter
     */
    public static setParamConverter(fn: (paramValue: any, paramType: Function) => any) 52{
        InternalServer.paramConverter = fn;
    }

    /**
     * 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
     */
    public static swagger(router: express.Router, filePath: string, endpoint: string, host?: string, schemes?: Array<string>, swaggerUiOptions?: object) 53{
        const swaggerUi = require(54'swagger-ui-express');
        if (5556_.startsWith(filePath, 57'.')) 58{
            filePath = path.join(process.cwd(), filePath);
        }

        let swaggerDocument: any;
        if (5960_.endsWith(filePath, 61'.yml') 62|| _.endsWith(filePath, 63'.yaml')) 64{
            swaggerDocument = YAML.load(filePath);
        } else 65{
            swaggerDocument = fs.readJSONSync(filePath);
        }

        if (6667host) 68{
            swaggerDocument.host = host;
        }
        if (6970schemes) 71{
            swaggerDocument.schemes = schemes;
        }

        router.get(path.posix.join(72'/', endpoint, 73'json'), (req, res, next) => 74{
            res.send(swaggerDocument);
        });
        router.get(path.posix.join(75'/', endpoint, 76'yaml'), (req, res, next) => 77{
            res.set(78'Content-Type', 79'text/vnd.yaml');
            res.send(YAML.stringify(swaggerDocument, 1000));
        });
        router.use(path.posix.join(80'/', endpoint), swaggerUi.serve, swaggerUi.setup(swaggerDocument, swaggerUiOptions));
    }
}
# Mutator State Location Original Replacement
0 Block RuntimeError 18 : 78 { ... } {}
1 Block Killed 26 : 110 { ... } {}
2 Block Killed 33 : 107 { ... } {}
3 ArrayLiteral RuntimeError 34 : 47 [] [' ... ']
4 StringLiteral RuntimeError 35 : 36 ' - ' ""
5 BinaryExpression RuntimeError 36 : 26 || &&
6 Block RuntimeError 41 : 57 { ... } {}
7 Block RuntimeError 42 : 67 { ... } {}
8 Block Killed 47 : 12 { ... } {}
9 Block Killed 49 : 20 { ... } {}
10 StringLiteral RuntimeError 50 : 32 ` ... }` ""
11 Block RuntimeError 57 : 44 { ... } {}
12 ArrayNewExpression RuntimeError 58 : 23 < >() ([])
13 Block Killed 59 : 51 { ... } {}
14 Block RuntimeError 70 : 73 { ... } {}
15 Block Killed 78 : 77 { ... } {}
16 Block RuntimeError 88 : 40 { ... } {}
17 ConditionalExpression RuntimeError 89 : 28
18 ConditionalExpression Killed 89 : 28
19 StringLiteral RuntimeError 89 : 34 ' .../ ' ""
20 StringLiteral RuntimeError 89 : 57 ' ...- ' ""
21 Block RuntimeError 91 : 38 { ... } {}
22 Block RuntimeError 94 : 56 { ... } {}
23 IfStatement RuntimeError 96 : 20 [' ... '
24 IfStatement RuntimeError 96 : 20 [' ... '
25 StringLiteral RuntimeError 96 : 36 ' ' ""
26 BinaryExpression Killed 96 : 44 && ||
27 StringLiteral Killed 96 : 63 ' ' ""
28 BinaryExpression RuntimeError 96 : 71 !== ===
29 StringLiteral Killed 96 : 75 ' ' ""
30 Block RuntimeError 96 : 90 { ... } {}
31 StringLiteral RuntimeError 99 : 50 ' ' ""
32 WhileStatement RuntimeError 100 : 23
33 Block TimedOut 100 : 40 { ... } {}
34 IfStatement RuntimeError 101 : 24 [' ... '
35 IfStatement RuntimeError 101 : 24 [' ... '
36 StringLiteral RuntimeError 101 : 40 ' ' ""
37 BinaryExpression RuntimeError 101 : 48 && ||
38 StringLiteral RuntimeError 101 : 67 ' ' ""
39 BinaryExpression RuntimeError 101 : 75 !== ===
40 StringLiteral RuntimeError 101 : 79 ' ' ""
41 Block RuntimeError 101 : 94 { ... } {}
42 StringLiteral RuntimeError 104 : 54 ' ' ""
43 StringLiteral Killed 106 : 32 ' ... ' ""
44 Block RuntimeError 115 : 73 { ... } {}
45 ArrayNewExpression RuntimeError 116 : 23 < >() ([])
46 Block RuntimeError 117 : 68 { ... } {}
47 Block Survived 129 : 51 { ... } {}
48 Block RuntimeError 144 : 70 { ... } {}
49 Block RuntimeError 152 : 44 { ... } {}
50 Block RuntimeError 161 : 72 { ... } {}
51 Block RuntimeError 169 : 51 { ... } {}
52 Block RuntimeError 177 : 87 { ... } {}
53 Block RuntimeError 189 : 153 { ... } {}
54 StringLiteral RuntimeError 190 : 34 ' ... ' ""
55 IfStatement RuntimeError 191 : 12 . ... '.')
56 IfStatement Survived 191 : 12 . ... '.')
57 StringLiteral RuntimeError 191 : 35 '.' ""
58 Block RuntimeError 191 : 41 { ... } {}
59 IfStatement RuntimeError 196 : 12 . ... ')
60 IfStatement RuntimeError 196 : 12 . ... ')
61 StringLiteral Survived 196 : 33 '. ' ""
62 BinaryExpression Killed 196 : 41 || &&
63 StringLiteral RuntimeError 196 : 65 '. ' ""
64 Block RuntimeError 196 : 75 { ... } {}
65 Block RuntimeError 198 : 15 { ... } {}
66 IfStatement RuntimeError 202 : 12
67 IfStatement RuntimeError 202 : 12
68 Block Survived 202 : 18 { ... } {}
69 IfStatement RuntimeError 205 : 12
70 IfStatement RuntimeError 205 : 12
71 Block RuntimeError 205 : 21 { ... } {}
72 StringLiteral RuntimeError 209 : 35 '/' ""
73 StringLiteral RuntimeError 209 : 50 ' ' ""
74 Block TimedOut 209 : 79 { ... } {}
75 StringLiteral RuntimeError 212 : 35 '/' ""
76 StringLiteral RuntimeError 212 : 50 ' ' ""
77 Block RuntimeError 212 : 79 { ... } {}
78 StringLiteral RuntimeError 213 : 20 ' - ' ""
79 StringLiteral RuntimeError 213 : 36 ' / . ' ""
80 StringLiteral RuntimeError 216 : 35 '/' ""