Files
nest/packages/core/router/paths-explorer.ts
2022-11-21 11:00:11 +01:00

75 lines
2.1 KiB
TypeScript

import {
METHOD_METADATA,
PATH_METADATA,
VERSION_METADATA,
} from '@nestjs/common/constants';
import { RequestMethod } from '@nestjs/common/enums';
import { Controller } from '@nestjs/common/interfaces/controllers/controller.interface';
import { VersionValue } from '@nestjs/common/interfaces/version-options.interface';
import {
addLeadingSlash,
isString,
isUndefined,
} from '@nestjs/common/utils/shared.utils';
import { MetadataScanner } from '../metadata-scanner';
import { RouterProxyCallback } from './router-proxy';
export interface RouteDefinition {
path: string[];
requestMethod: RequestMethod;
targetCallback: RouterProxyCallback;
methodName: string;
version?: VersionValue;
}
export class PathsExplorer {
constructor(private readonly metadataScanner: MetadataScanner) {}
public scanForPaths(
instance: Controller,
prototype?: object,
): RouteDefinition[] {
const instancePrototype = isUndefined(prototype)
? Object.getPrototypeOf(instance)
: prototype;
return this.metadataScanner.scanFromPrototype<Controller, RouteDefinition>(
instance,
instancePrototype,
method => this.exploreMethodMetadata(instance, instancePrototype, method),
);
}
public exploreMethodMetadata(
instance: Controller,
prototype: object,
methodName: string,
): RouteDefinition {
const instanceCallback = instance[methodName];
const prototypeCallback = prototype[methodName];
const routePath = Reflect.getMetadata(PATH_METADATA, prototypeCallback);
if (isUndefined(routePath)) {
return null;
}
const requestMethod: RequestMethod = Reflect.getMetadata(
METHOD_METADATA,
prototypeCallback,
);
const version: VersionValue | undefined = Reflect.getMetadata(
VERSION_METADATA,
prototypeCallback,
);
const path = isString(routePath)
? [addLeadingSlash(routePath)]
: routePath.map((p: string) => addLeadingSlash(p));
return {
path,
requestMethod,
targetCallback: instanceCallback,
methodName,
version,
};
}
}