<commit_before>import {expressTemplate} from './templates/express';
import {Metadata, Type, ArrayType, ReferenceType, Parameter, Property} from '../metadataGeneration/metadataGenerator';
import * as fs from 'fs';
import * as handlebars from 'handlebars';
import * as path from 'path';
import * as tsfmt from 'typescript-formatter';

const appRoot: string = require('app-root-path').path;

export interface Options {
    basePath: string;
    routeDir: string;
}

export class RouteGenerator {
    constructor(private readonly metadata: Metadata, private readonly options: Options) { }

    public GenerateRoutes(middlewareTemplate: string) {
        const fileName = `${this.options.routeDir}/routes.ts`;
        const content = this.buildContent(middlewareTemplate);

        return new Promise<void>((resolve, reject) => {
            tsfmt.processString(fileName, content, {} as any)
                .then(result => fs.writeFile(fileName, result.dest, (err) => resolve()));
        });
    }

    public GenerateExpressRoutes() {
        return this.GenerateRoutes(expressTemplate);
    }

    private buildContent(middlewareTemplate: string) {
        let canImportByAlias: boolean;
        try {
            require('tsoa');
            canImportByAlias = true;
        } catch (err) {
            canImportByAlias = false;
        }

        const routesTemplate = handlebars.compile(`
            /**
             * THIS IS GENERATED CODE - DO NOT EDIT
             */
            /* tslint:disable */
            import {ValidateParam} from '${canImportByAlias ? 'tsoa' : '../../src/routeGeneration/templateHelpers'}';
            {{#each controllers}}
            import { {{name}} } from '{{modulePath}}';
            {{/each}}

            const models: any = {
                {{#each models}}
                '{{name}}': {
                    {{#each properties}}
                        '{{name}}': { typeName: '{{typeName}}', required: {{required}} {{#if arrayType}}, arrayType: '{{arrayType}}' {{/if}} },
                    {{/each}}
                },
                {{/each}}
            };
        `.concat(middlewareTemplate));

        return routesTemplate({
            basePath: this.options.basePath ? `/${this.options.basePath}` : '',
            controllers: this.metadata.Controllers.map(controller => {
                return {
                    actions: controller.methods.map(method => {
                        const bodyParameter = method.parameters.find(parameter => parameter.in === 'body');
                        return {
                            bodyParamName: bodyParameter ? bodyParameter.name : undefined,
                            method: method.method.toLowerCase(),
                            name: method.name,
                            parameters: method.parameters.map(parameter => this.getTemplateProperty(parameter)),
                            path: this.getExpressPath(method.path)
                        };
                    }),
                    modulePath: this.getRelativeImportPath(controller.location),
                    name: controller.name,
                    path: controller.path
                };
            }),
            models: this.getModels()
        });
    }

    private getModels(): TemplateModel[] {
        return Object.keys(this.metadata.ReferenceTypes).map(key => {
            const referenceType = this.metadata.ReferenceTypes[key];

            return {
                name: key,
                properties: referenceType.properties.map(property => this.getTemplateProperty(property))
            };<commit_msg>fix basepath calculation<commit_after>import {expressTemplate} from './templates/express';
import {Metadata, Type, ArrayType, ReferenceType, Parameter, Property} from '../metadataGeneration/metadataGenerator';
import * as fs from 'fs';
import * as handlebars from 'handlebars';
import * as path from 'path';
import * as tsfmt from 'typescript-formatter';

const appRoot: string = require('app-root-path').path;

export interface Options {
    basePath: string;
    routeDir: string;
}

export class RouteGenerator {
    constructor(private readonly metadata: Metadata, private readonly options: Options) { }

    public GenerateRoutes(middlewareTemplate: string) {
        const fileName = `${this.options.routeDir}/routes.ts`;
        const content = this.buildContent(middlewareTemplate);

        return new Promise<void>((resolve, reject) => {
            tsfmt.processString(fileName, content, {} as any)
                .then(result => fs.writeFile(fileName, result.dest, (err) => resolve()));
        });
    }

    public GenerateExpressRoutes() {
        return this.GenerateRoutes(expressTemplate);
    }

    private buildContent(middlewareTemplate: string) {
        let canImportByAlias: boolean;
        try {
            require('tsoa');
            canImportByAlias = true;
        } catch (err) {
            canImportByAlias = false;
        }

        const routesTemplate = handlebars.compile(`
            /**
             * THIS IS GENERATED CODE - DO NOT EDIT
             */
            /* tslint:disable */
            import {ValidateParam} from '${canImportByAlias ? 'tsoa' : '../../src/routeGeneration/templateHelpers'}';
            {{#each controllers}}
            import { {{name}} } from '{{modulePath}}';
            {{/each}}

            const models: any = {
                {{#each models}}
                '{{name}}': {
                    {{#each properties}}
                        '{{name}}': { typeName: '{{typeName}}', required: {{required}} {{#if arrayType}}, arrayType: '{{arrayType}}' {{/if}} },
                    {{/each}}
                },
                {{/each}}
            };
        `.concat(middlewareTemplate));

        return routesTemplate({
            basePath: this.options.basePath === '/' ? '' : `/${this.options.basePath}`,
            controllers: this.metadata.Controllers.map(controller => {
                return {
                    actions: controller.methods.map(method => {
                        const bodyParameter = method.parameters.find(parameter => parameter.in === 'body');
                        return {
                            bodyParamName: bodyParameter ? bodyParameter.name : undefined,
                            method: method.method.toLowerCase(),
                            name: method.name,
                            parameters: method.parameters.map(parameter => this.getTemplateProperty(parameter)),
                            path: this.getExpressPath(method.path)
                        };
                    }),
                    modulePath: this.getRelativeImportPath(controller.location),
                    name: controller.name,
                    path: controller.path
                };
            }),
            models: this.getModels()
        });
    }

    private getModels(): TemplateModel[] {
        return Object.keys(this.metadata.ReferenceTypes).map(key => {
            const referenceType = this.metadata.ReferenceTypes[key];

            return {
                name: key,
                properties: referenceType.properties.map(property => this.getTemplateProperty(property))
            };
{'fraction_non_alphanumeric': 0.12243209706328416, 'fraction_numerical': 0.0, 'mean_word_length': 1.829173166926677, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2872846', 'n_tokens_mistral': 1760, 'n_tokens_neox': 1710, 'n_words': 384}