<commit_before>import {APIGatewayEvent, Callback, Context} from "aws-lambda";
import * as _ from "lodash";
import {IAuthorizer, IHandlerParamDecorator} from "./router-decorators";
const RouteRecognizer = require("route-recognizer"); // tslint:disable-line:no-require-imports no-var-requires
import {Result} from "route-recognizer";
import {RouterException} from "./router-exceptions";

export enum HTTPVerb {
    ANY, CONNECT, DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT, TRACE,
}

class Route {
    public handler: () => any;
    public signature: IHandlerParamDecorator[];
    public params: { [name: string]: string };
    public restriction: IAuthorizer;

    constructor(routeMatch: Result) {
        this.handler = routeMatch.handler[0];
        this.signature = routeMatch.handler[1];
        this.params = routeMatch.params as { [name: string]: string };
        this.restriction = routeMatch.handler[2];
    }
}

class Paths {
    private routeRecognizer = new RouteRecognizer();

    constructor(public verb: HTTPVerb) {
    }

    public add(path: string, handler: () => any, signature: IHandlerParamDecorator[], restriction: IAuthorizer): void {
        this.routeRecognizer.add([{
            handler: [handler, signature, restriction],
            path,
        }]);
    }

    public match(path: string): Route {
        const results: Result[] = this.routeRecognizer.recognize(path);
        if (results && results.length === 1) {
            return new Route(results[0]);
        }
        return null;
    }
}

class AnyCallAuthorizer implements IAuthorizer {

    public authorize(event: APIGatewayEvent, context: Context, handlerArgs?: any): Promise<boolean> {
        return new Promise((res) => {
            res(true);
        });
    }
}

export interface IRouterResourceRegistration {
    handlers: Array<{
        path: string,
        propertyKey: string,
        verb: HTTPVerb,
    }>;
    params: { [name: string]: IHandlerParamDecorator[] };
    restrictions: { [name: string]: IAuthorizer };
    target: object;
}

export class RouterResourceRegistry {

    public static registerHandler(verb: HTTPVerb, paths: string[], target: object, propertyKey: string): void {
        const registration = this.getRegistrationByTarget(target);
        for (const path of paths) {
            registration.handlers.push({path, propertyKey, verb});
        }
    }

    public static markRestricted(authorizer: IAuthorizer, target: object, propertyKey: string): void {
        const registration = this.getRegistrationByTarget(target);
        registration.restrictions[propertyKey] = authorizer;
    }

    public static registerParam(param: IHandlerParamDecorator): void {
        const registration = this.getRegistrationByTarget(param.target);
        registration.params[param.propertyKey] = registration.params[param.propertyKey] || [];
        registration.params[param.propertyKey][param.parameterIndex] = param;
    }

    public static find(resource: object): IRouterResourceRegistration {
        for (const reg of this.registrations) {
            if (resource instanceof reg.constructor) {
                return reg;
            }
        }
        return null;
    }

    private static registrations: IRouterResourceRegistration[] = [];

    private static getRegistrationByTarget(target: object): IRouterResourceRegistration {
        let registration = null;
        for (const reg of this.registrations) {
            if (reg.target === target) {
                registration = reg;
                break;
            }
        }
        if (!registration) {
            registration = {
                handlers: [],
                params: {},
                restrictions: {},
                target,
            };
            this.registrations.push(registration);
        }
        return registration;
    }<commit_msg>fixed bug that always matched the first handler for any resource<commit_after>import {APIGatewayEvent, Callback, Context} from "aws-lambda";
import * as _ from "lodash";
import {IAuthorizer, IHandlerParamDecorator} from "./router-decorators";
const RouteRecognizer = require("route-recognizer"); // tslint:disable-line:no-require-imports no-var-requires
import {Result} from "route-recognizer";
import {RouterException} from "./router-exceptions";

export enum HTTPVerb {
    ANY, CONNECT, DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT, TRACE,
}

class Route {
    public handler: () => any;
    public signature: IHandlerParamDecorator[];
    public params: { [name: string]: string };
    public restriction: IAuthorizer;

    constructor(routeMatch: Result) {
        this.handler = routeMatch.handler[0];
        this.signature = routeMatch.handler[1];
        this.params = routeMatch.params as { [name: string]: string };
        this.restriction = routeMatch.handler[2];
    }
}

class Paths {
    private routeRecognizer = new RouteRecognizer();

    constructor(public verb: HTTPVerb) {
    }

    public add(path: string, handler: () => any, signature: IHandlerParamDecorator[], restriction: IAuthorizer): void {
        this.routeRecognizer.add([{
            handler: [handler, signature, restriction],
            path,
        }]);
    }

    public match(path: string): Route {
        const results: Result[] = this.routeRecognizer.recognize(path);
        if (results && results.length === 1) {
            return new Route(results[0]);
        }
        return null;
    }
}

class AnyCallAuthorizer implements IAuthorizer {

    public authorize(event: APIGatewayEvent, context: Context, handlerArgs?: any): Promise<boolean> {
        return new Promise((res) => {
            res(true);
        });
    }
}

export interface IRouterResourceRegistration {
    handlers: Array<{
        path: string,
        propertyKey: string,
        verb: HTTPVerb,
    }>;
    params: { [name: string]: IHandlerParamDecorator[] };
    restrictions: { [name: string]: IAuthorizer };
    target: object;
}

export class RouterResourceRegistry {

    public static registerHandler(verb: HTTPVerb, paths: string[], target: object, propertyKey: string): void {
        const registration = this.getRegistrationByTarget(target);
        for (const path of paths) {
            registration.handlers.push({path, propertyKey, verb});
        }
    }

    public static markRestricted(authorizer: IAuthorizer, target: object, propertyKey: string): void {
        const registration = this.getRegistrationByTarget(target);
        registration.restrictions[propertyKey] = authorizer;
    }

    public static registerParam(param: IHandlerParamDecorator): void {
        const registration = this.getRegistrationByTarget(param.target);
        registration.params[param.propertyKey] = registration.params[param.propertyKey] || [];
        registration.params[param.propertyKey][param.parameterIndex] = param;
    }

    public static find(resource: object): IRouterResourceRegistration {
        for (const reg of this.registrations) {
            if (resource instanceof reg.target.constructor) {
                return reg;
            }
        }
        return null;
    }

    private static registrations: IRouterResourceRegistration[] = [];

    private static getRegistrationByTarget(target: object): IRouterResourceRegistration {
        let registration = null;
        for (const reg of this.registrations) {
            if (reg.target === target) {
                registration = reg;
                break;
            }
        }
        if (!registration) {
            registration = {
                handlers: [],
                params: {},
                restrictions: {},
                target,
            };
            this.registrations.push(registration);
        }
        return registration;
    }
{'fraction_non_alphanumeric': 0.10875706214689265, 'fraction_numerical': 0.0012840267077555213, 'mean_word_length': 2.687973484848485, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 13, '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': '7516997', 'n_tokens_mistral': 2087, 'n_tokens_neox': 2047, 'n_words': 514}