chore: first commit

This commit is contained in:
mahyargdz
2025-06-24 11:26:06 +03:30
commit ccbf743ecb
186 changed files with 22258 additions and 0 deletions
+19
View File
@@ -0,0 +1,19 @@
import { SharedBullAsyncConfiguration } from "@nestjs/bullmq";
import { ConfigService } from "@nestjs/config";
export function bullMqConfig(): SharedBullAsyncConfiguration {
return {
inject: [ConfigService],
useFactory: async (configService: ConfigService) => ({
connection: {
url: configService.getOrThrow<string>("REDIS_URI"),
},
prefix: "dmail",
defaultJobOptions: {
removeOnComplete: true,
removeOnFail: false,
attempts: 5,
},
}),
};
}
+16
View File
@@ -0,0 +1,16 @@
import KeyvRedis from "@keyv/redis";
import { CacheModuleAsyncOptions } from "@nestjs/cache-manager";
import { ConfigService } from "@nestjs/config";
export function cacheConfig(): CacheModuleAsyncOptions {
return {
inject: [ConfigService],
isGlobal: true,
useFactory: async (configService: ConfigService) => {
return {
ttl: configService.getOrThrow<string>("CACHE_TTL"),
stores: [new KeyvRedis(configService.getOrThrow<string>("REDIS_URI"), { namespace: "dmail:" })],
};
},
};
}
+16
View File
@@ -0,0 +1,16 @@
import { HttpModuleAsyncOptions } from "@nestjs/axios";
import { ConfigService } from "@nestjs/config";
export function httpConfig(): HttpModuleAsyncOptions {
return {
inject: [ConfigService],
global: true,
useFactory: async (configService: ConfigService) => {
return {
timeout: configService.getOrThrow<number>("AXIOS_TIMEOUT"),
headers: { "Content-Type": "application/json" },
global: true,
};
},
};
}
+16
View File
@@ -0,0 +1,16 @@
import { ConfigService } from "@nestjs/config";
import { JwtModuleAsyncOptions } from "@nestjs/jwt";
export function jwtConfig(): JwtModuleAsyncOptions {
return {
inject: [ConfigService],
useFactory: (configService: ConfigService) => {
return {
secret: configService.getOrThrow<string>("JWT_SECRET"),
signOptions: {
issuer: configService.getOrThrow<string>("JWT_ISSUER"),
},
};
},
};
}
+53
View File
@@ -0,0 +1,53 @@
import { MikroOrmModuleAsyncOptions } from "@mikro-orm/nestjs";
import { PostgreSqlDriver } from "@mikro-orm/postgresql";
import { Logger } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { MIKRO_ORM_QUERY_LOGGER, MikroOrmQueryLogger } from "../common/providers/mikro-orm-logger";
export const databaseConfig: MikroOrmModuleAsyncOptions = {
inject: [ConfigService, MIKRO_ORM_QUERY_LOGGER],
providers: [MikroOrmQueryLogger],
useFactory: (configService: ConfigService, logger: Logger) => {
const DB_PASS = configService.getOrThrow<string>("DB_PASS");
const DB_USER = configService.getOrThrow<string>("DB_USER");
const DB_HOST = configService.getOrThrow<string>("DB_HOST");
const DB_PORT = configService.getOrThrow<number>("DB_PORT");
const encodedPassword = encodeURIComponent(DB_PASS);
return {
driver: PostgreSqlDriver,
autoLoadEntities: true,
dbName: configService.getOrThrow<string>("DB_NAME"),
debug: configService.get<string>("NODE_ENV") !== "production",
clientUrl: `postgres://${DB_USER}:${encodedPassword}@${DB_HOST}:${DB_PORT}`,
ensureDatabase: { forceCheck: true, create: true, schema: "update" },
forceUtcTimezone: true,
pool: {
min: 2,
max: 15,
idleTimeoutMillis: 10000,
acquireTimeoutMillis: 10000,
reapIntervalMillis: 1000,
createTimeoutMillis: 3000,
destroyTimeoutMillis: 5000,
},
logger: (message) => logger.debug(message),
schemaGenerator: {
createForeignKey: true,
disableForeignKeys: false,
createIndex: true,
},
migrations: {
path: "./database/migrations",
pathTs: "./database/migrations",
tableName: "migrations",
transactional: true,
allOrNothing: true,
dropTables: false,
safe: true,
emit: "ts",
},
};
},
};
+21
View File
@@ -0,0 +1,21 @@
import { ThrottlerStorageRedisService } from "@nest-lab/throttler-storage-redis";
import { ConfigService } from "@nestjs/config";
import { ThrottlerAsyncOptions } from "@nestjs/throttler";
import { AuthMessage } from "../common/enums/message.enum";
export function rateLimitConfig(): ThrottlerAsyncOptions {
return {
inject: [ConfigService],
useFactory: (configService: ConfigService) => ({
throttlers: [
{
ttl: configService.getOrThrow("THROTTLE_TTL"),
limit: configService.getOrThrow("THROTTLE_LIMIT"),
},
],
errorMessage: AuthMessage.TOO_MANY_REQUESTS,
storage: new ThrottlerStorageRedisService(configService.getOrThrow("REDIS_URI")),
}),
};
}
+26
View File
@@ -0,0 +1,26 @@
import { ConfigService } from "@nestjs/config";
export function S3Configs() {
return {
inject: [ConfigService],
useFactory(configService: ConfigService) {
return {
accessKeyId: configService.getOrThrow<string>("BUCKET_ACCESS_KEY"),
secretAccessKey: configService.getOrThrow<string>("BUCKET_SECRET_KEY"),
endpoint: configService.getOrThrow<string>("BUCKET_URL"),
region: configService.getOrThrow<string>("BUCKET_REGION"),
bucket: configService.getOrThrow<string>("BUCKET_NAME"),
url: configService.getOrThrow<string>("BUCKET_UPLOAD_URL"),
};
},
};
}
export interface IS3Configs {
accessKeyId: string;
secretAccessKey: string;
endpoint: string;
region: string;
bucket: string;
url: string;
}
+49
View File
@@ -0,0 +1,49 @@
import { ConfigService } from "@nestjs/config";
export function smsConfigs() {
return {
inject: [ConfigService],
useFactory(configService: ConfigService) {
return {
API_URL: configService.getOrThrow<string>("SMS_API_URL"),
API_KEY: configService.getOrThrow<string>("SMS_API_KEY"),
SMS_PATTERN_OTP: configService.getOrThrow<string>("SMS_PATTERN_OTP"),
SMS_PATTERN_INVOICE: configService.getOrThrow<string>("SMS_PATTERN_INVOICE"),
SMS_PATTERN_LOGIN: configService.getOrThrow<string>("SMS_PATTERN_LOGIN"),
SMS_PATTERN_INVOICE_CREATED: configService.getOrThrow<string>("SMS_PATTERN_INVOICE_CREATED"),
SMS_PATTERN_ANNOUNCEMENT: configService.getOrThrow<string>("SMS_PATTERN_ANNOUNCEMENT"),
SMS_PATTERN_TICKET_CREATED: configService.getOrThrow<string>("SMS_PATTERN_TICKET_CREATED"),
SMS_PATTERN_TICKET_ASSIGNED_ADMIN: configService.getOrThrow<string>("SMS_PATTERN_TICKET_ASSIGNED_ADMIN"),
SMS_PATTERN_INVOICE_APPROVED: configService.getOrThrow<string>("SMS_PATTERN_INVOICE_APPROVED"),
SMS_PATTERN_INVOICE_PAID: configService.getOrThrow<string>("SMS_PATTERN_INVOICE_PAID"),
SMS_PATTERN_RECURRING_INVOICE_DRAFT: configService.getOrThrow<string>("SMS_PATTERN_RECURRING_INVOICE_DRAFT"),
SMS_PATTERN_SUBSCRIPTION_CANCELLED: configService.getOrThrow<string>("SMS_PATTERN_SUBSCRIPTION_CANCELLED"),
SMS_PATTERN_INVOICE_REMINDER: configService.getOrThrow<string>("SMS_PATTERN_INVOICE_REMINDER"),
SMS_PATTERN_INVOICE_OVERDUE: configService.getOrThrow<string>("SMS_PATTERN_INVOICE_OVERDUE"),
SMS_PATTERN_PAYMENT_REMINDER: configService.getOrThrow<string>("SMS_PATTERN_PAYMENT_REMINDER"),
SMS_PATTERN_PAYMENT_CANCELLATION: configService.getOrThrow<string>("SMS_PATTERN_PAYMENT_CANCELLATION"),
};
},
};
}
export interface ISmsConfigs {
API_URL: string;
API_KEY: string;
SMS_PATTERN_OTP: string;
SMS_PATTERN_INVOICE: string;
SMS_PATTERN_LOGIN: string;
SMS_PATTERN_INVOICE_CREATED: string;
SMS_PATTERN_ANNOUNCEMENT: string;
SMS_PATTERN_TICKET_CREATED: string;
SMS_PATTERN_TICKET_ANSWERED: string;
SMS_PATTERN_TICKET_ASSIGNED_ADMIN: string;
SMS_PATTERN_INVOICE_APPROVED: string;
SMS_PATTERN_INVOICE_PAID: string;
SMS_PATTERN_RECURRING_INVOICE_DRAFT: string;
SMS_PATTERN_SUBSCRIPTION_CANCELLED: string;
SMS_PATTERN_INVOICE_REMINDER: string;
SMS_PATTERN_INVOICE_OVERDUE: string;
SMS_PATTERN_PAYMENT_REMINDER: string;
SMS_PATTERN_PAYMENT_CANCELLATION: string;
}
+24
View File
@@ -0,0 +1,24 @@
import { NestFastifyApplication } from "@nestjs/platform-fastify";
import { DocumentBuilder, SwaggerModule } from "@nestjs/swagger";
export function getSwaggerDocument(app: NestFastifyApplication) {
const swaggerConfig = new DocumentBuilder()
.setTitle("The dmail api document")
.setDescription("The dmail API description")
.addBearerAuth(
{
type: "http",
scheme: "bearer",
bearerFormat: "JWT",
name: "authorization",
in: "header",
},
"authorization",
)
.setVersion("1.0.0")
.build();
const swaggerDocument = SwaggerModule.createDocument(app, swaggerConfig);
SwaggerModule.setup("api-docs", app, swaggerDocument);
}
+11
View File
@@ -0,0 +1,11 @@
import { ConfigService } from "@nestjs/config";
export const wildduckConfig = () => ({
inject: [ConfigService],
useFactory: (configService: ConfigService) => ({
baseUrl: configService.getOrThrow<string>("WILDDUCK_BASE_URL"),
accessToken: configService.getOrThrow<string>("WILDDUCK_ACCESS_TOKEN"),
timeout: configService.getOrThrow<number>("WILDDUCK_TIMEOUT"),
retries: configService.getOrThrow<number>("WILDDUCK_RETRIES"),
}),
});
+18
View File
@@ -0,0 +1,18 @@
import { ConfigService } from "@nestjs/config";
export function zarinpalConfig() {
return {
inject: [ConfigService],
useFactory: (configService: ConfigService) => ({
gatewayApiUrl: configService.getOrThrow<string>("ZARINPAL_API_URL"),
callBackUrl: configService.getOrThrow<string>("CALLBACK_URL"),
ipgType: configService.getOrThrow<string>("IPG_TYPE"),
}),
};
}
export interface IZarinpalConfig {
gatewayApiUrl: string;
callBackUrl: string;
ipgType: string;
}