There is no way to get file path information from ctor
parameter. It's just a function that was defined somewhere.
Basically, module
and ctrl
preferably have to be provided to controller class on registration, since the path is known at this moment, i.e.:
for (const filename of filenames) {
const Ctrl = require(filename).default;
const [moduleName, ctrlName] = parseCtrlFilename(filename);
Ctrl._module = moduleName;
Ctrl._name = ctrlName;
}
The only and hacky workarount is to get file path of a place where Controller
was called. This is achieved by getting stacktrace, e.g:
const caller = require('caller-callsite');
export function Controller<T extends { new(...args: any[]): {} }> (ctor: T) {
const fullPath = caller().getFileName();
...
}
The problem is that it's the path where Controller
is called:
.../foo.ts
@Controller
export class Foo {...}
.../bar.ts
import { Foo } from '.../foo.ts';
// fullPath is still .../foo.ts
export class Bar extends Foo {}
A less hacky and more reliable way is to provide file path explicitly from the module where it is available:
@Controller(__filename)
export class Foo {...}
There is import.meta
proposal which is supported by TypeScript. It depends on Node project configuration because it works with esnext
target:
@Controller(import.meta)
export class Foo {...}
import.meta
that was passed to @Controller
can be consumed as meta.__dirname
.