rf-nestjs
v0.2.0
Published
This package contains with NestJS custom modules used by Request Finance.
Downloads
95
Readme
rf-nestjs
This package contains with NestJS custom modules used by Request Finance.
It uses ES6 modules to export different features.
Installation
# Optional. The easy way. Alternatively, pick only dependencies you need
pnpm config set auto-install-peers true --location project
pnpm i rf-nestjs
About peer dependencies
If you don't use a feature, you don't need to install dependencies for that feature.
For instance, @google-cloud/pubsub
is not needed if you don't use the pubsub
feature.
NB: a missing dependency will cause a runtime error, not a compile error.
Features
config
Class-based configuration, based on class-validator
and class-transformer
. You can have multiple configuration classes (usually one per module), but they must have unique names.
Dependencies
pnpm i class-transformer class-validator dotenv-flow
Usage
// app.config.ts
import { Expose } from "class-transformer";
import { IsPort } from "class-validator";
export class AppConfig {
@IsPort()
@Expose({ name: "PORT" })
port: number;
}
// app.module.ts
import { ConfigModule } from "rf-nestjs/config";
import { AppConfig } from "./app.config.js";
@Module({
imports: [
ConfigModule.forClass(AppConfig),
// ...
],
})
export class AppModule {}
// main.ts
const config = app.get(AppConfig);
// OR in a service
@Injectable()
class MyService {
constructor(config: AppConfig) {}
}
currency
A module to inject a CurrencyManager
and a ChainManager
based on data from Currency API. Optionally refreshes data regularly.
Dependencies
pnpm i @requestnetwork/currency @nestjs/schedule
Usage
import { Module } from "@nestjs/common";
import { ScheduleModule } from "@nestjs/schedule";
import { CurrencyModule } from "rf-nestjs/currency";
@Module({
imports: [
ScheduleModule.forRoot(),
CurrencyModule.register({
apiUrl: "https://api.request.finance/currency",
// optional
autoFetch: true,
frequency: 10 * 60 * 1000,
}),
],
providers: [MyService],
})
export class MyModule {}
@Injectable()
export class MyService {
constructor(private readonly cm: CurrencyManager) {}
demo() {
console.log(this.cm.from("EUR"));
}
}
logger
Dependencies
pnpm i @rf-logger/logger @rf-logger/logger-nestjs
Usage
// logger.config.ts
import { Injectable } from "@nestjs/common";
import type { Options } from "@rf-logger/logger";
import { LogFormatEnum, type LogLevel, LogLevelEnum } from "@rf-logger/logger";
import { Expose } from "class-transformer";
import { IsEnum } from "class-validator";
@Injectable()
export class LoggerConfig implements Options {
@Expose({ name: "LOG_LEVEL" })
@IsEnum(LogLevelEnum)
level: LogLevel;
@Expose({ name: "LOG_FORMAT" })
@IsEnum(LogFormatEnum)
format: "json";
// Optional
// plugins = [AxiosPlugin];s
}
// app.module.ts
import { LoggerModule } from "rf-nestjs/logger";
import { LoggerConfig } from "./logger.config.js";
@Module({
imports: [LoggerModule.forConfig(LoggerConfig)],
})
export class AppModule {}
// main.ts
import { Logger } from "@nestjs/common";
// ...
app.useLogger(app.get(Logger));
// ...
meta
Usage
See pubsub-scanner.service.ts
in this repo.
pubsub
Dependencies
pnpm i @google-cloud/pubsub
Usage
import { Module } from "@nestjs/common";
import { ConfigModule } from "rf-nestjs/config";
import { SubscriptionModule } from "rf-nestjs/pubsub";
import { PubsubConfig } from "./pubsub.config.js";
@Module({
imports: [
SubscriptionModule.registerAsync({
imports: [ConfigModule.forClass(PubsubConfig)],
useFactory: (config: PubsubConfig) => ({
publishedBy: "sync-api",
projectId: config.googleProjectId,
// if you have multiple subscriptions, you can use the `name` argument to retrieve the right options.
getSubscription: () => ({
subscriptionName: config.subscriptionName,
maxMessages: config.maxSubscriberMessages,
}),
}),
inject: [PubsubConfig],
}),
],
})
export class PubsubModule {}
// then use in a controller like this:
import { Controller } from "@nestjs/common";
import { Subscriber } from "rf-nestjs/pubsub";
import { SyncMessageDto } from "./sync.dto.js";
@Controller()
export class SyncController {
constructor() {}
@Subscriber("my-sub-name")
async batchTransaction(message: SyncMessageDto) {
// the payload will be validated using the DTO, and the message will be rejected if invalid.
}
}
Contributing
Deploying a local package
It's recommended to use yalc to develop locally, as pnpm link
might cause depdency issues when resolving meta (ie @Subscriber
).
Running example
pnpm nest start --entryFile example/main.js