URL
@voltage/url generates URLs from controller classes. Point it at a controller and an action method, pass any route parameters, and it returns the correct path. Routes are read directly from @Controller() and route decorator metadata — you do not register anything manually.
Installation
Section titled “Installation”yarn add @voltage/urlBasic usage
Section titled “Basic usage”Call forRoot() once in your root module:
import { URLModule } from '@voltage/url';
@Module({ imports: [URLModule.forRoot()],})export class AppModule {}The module is global — inject URLGenerator anywhere without importing the module again:
import { URLGenerator } from '@voltage/url';
@Injectable()export class AuthService { constructor(private readonly url: URLGenerator) {}
async loginUrl() { return this.url.generate(AuthController, 'login'); }}Generating URLs
Section titled “Generating URLs”generate() accepts a controller class and an optional action name. The action is typed to only accept method names on the controller — passing a non-existent method is a compile error:
// Controller root pathawait this.url.generate(AuthController);// → "/auth"
// Specific actionawait this.url.generate(AuthController, 'login');// → "/auth/login"Route parameters
Section titled “Route parameters”Pass params to substitute :param placeholders. Undefined values are omitted from the path:
@Controller('account/verify/:id')export class VerifyController { @Get() view() {} @Post('resend') resend() {}}
await this.url.generate(VerifyController, { params: { id: token.id } });// → "/account/verify/abc-123"
await this.url.generate(VerifyController, 'resend', { params: { id: token.id } });// → "/account/verify/abc-123/resend"Query parameters
Section titled “Query parameters”Pass query to append a query string. Undefined values are omitted:
await this.url.generate(HotelController, 'list', { query: { page: 2, city: 'Berlin' },});// → "/hotels/list?page=2&city=Berlin"Host, prefix, and suffix
Section titled “Host, prefix, and suffix”// Full URL with hostawait this.url.generate(AuthController, 'login', { host: 'https://app.example.com',});// → "https://app.example.com/auth/login"
// Prefix and suffixawait this.url.generate(AuthController, 'login', { prefix: '/v2', suffix: '.json',});// → "/v2/auth/login.json"Options
Section titled “Options”interface GenerateOptions { /** Route parameters substituted into `:param` placeholders. Undefined values are omitted. */ params?: Record<string, string | number | boolean | undefined>; /** Query string parameters. Undefined values are omitted. */ query?: Record<string, string | number | boolean | undefined>; /** Prepended before the route path. */ prefix?: string; /** Appended after the route path. */ suffix?: string; /** Full host prepended to the URL, e.g. `'https://app.example.com'`. */ host?: string;}GenerateEvent
Section titled “GenerateEvent”Before assembling the final URL, URLGenerator emits a GenerateEvent. Listeners can modify event.options — this is how @voltage/intl injects locale prefixes transparently. You can use the same mechanism to add custom logic, such as always prepending an API base path for a specific controller:
import { OnEvent } from '@voltage/event-manager';import { GenerateEvent } from '@voltage/url';
@Injectable()export class ApiPrefixListener { @OnEvent(GenerateEvent) onGenerate(event: GenerateEvent) { if (event.controller === ApiController) { event.options.prefix = '/api/v2'; } }}