Skip to content

Commit

Permalink
fix: issues with configs
Browse files Browse the repository at this point in the history
  • Loading branch information
rubiin committed Oct 18, 2023
1 parent 90cf1ea commit bfa3273
Show file tree
Hide file tree
Showing 27 changed files with 124 additions and 73 deletions.
31 changes: 4 additions & 27 deletions src/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,17 @@
import { SWAGGER_API_ENDPOINT } from "@common/constant";
import { ClearCacheMiddleware, RealIpMiddleware } from "@common/middlewares";
import { applyRawBodyOnlyTo } from "@golevelup/nestjs-webhooks";
import { SharedModule } from "@modules/shared/shared.module";
import type { MiddlewareConsumer, NestModule } from "@nestjs/common";
import { Module, RequestMethod } from "@nestjs/common";
import { APP_GUARD, APP_INTERCEPTOR } from "@nestjs/core";
import { SentryInterceptor } from "@ntegral/nestjs-sentry";
import { CustomThrottlerGuard } from "@common/guards";
import { ClearCacheInterceptor, HttpCacheInterceptor } from "@common/interceptors";
import { ClearCacheMiddleware, RealIpMiddleware } from "@common/middlewares";
import { NestCacheModule } from "@lib/cache";
import { SharedModule } from "@modules/shared/shared.module";
import { AppController } from "app.controller";
import { SWAGGER_API_ENDPOINT } from "@common/constant";

const stripeWebhookPath = "stripe/webhook";
const excludedPaths = [stripeWebhookPath, SWAGGER_API_ENDPOINT];

@Module({
imports: [SharedModule],
controllers: [AppController],
imports: [SharedModule, NestCacheModule],
providers: [
{
provide: APP_INTERCEPTOR,
useClass: SentryInterceptor,
},
{
provide: APP_GUARD,
useClass: CustomThrottlerGuard,
},
{
provide: APP_INTERCEPTOR,
useClass: HttpCacheInterceptor,
},
{
provide: APP_INTERCEPTOR,
useClass: ClearCacheInterceptor,
},
],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
Expand Down
9 changes: 6 additions & 3 deletions src/common/constant/string.constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { capitalize } from "helper-fns";
import { readPackageSync } from "read-pkg";

export const REQUEST_ID_TOKEN_HEADER = "x-request-id";
export const VERSION_VALIDATION_MESSAGE = "Version must start with \"v\" followed by a number.";
Expand All @@ -10,8 +9,12 @@ export const THROTTLE_LIMIT_RESPONSE = "Too many requests, please try again late
export const MULTER_IMAGE_FILTER = "Only image files are allowed!.";
export const API_UNAUTHORISED_RESPONSE = "No auth token in request.";

// swagger constants
const packageJson = readPackageSync();
// swagger constants, TODO: dfix this too
const packageJson = {
name: "nestjs-boilerplate",
version: "1.0.0",
description: "NestJS Boilerplate",
};

export const APP_NAME = packageJson.name;
export const SWAGGER_API_CURRENT_VERSION = packageJson.version;
Expand Down
49 changes: 49 additions & 0 deletions src/generated/i18n-generated.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/* DO NOT EDIT, file generated by nestjs-i18n */

import { Path } from "nestjs-i18n";
export type I18nTranslations = {
"exception": {
"itemExists": string;
"itemDoesNotExist": string;
"unauthorized": string;
"internalError": string;
"otpRequired": string;
"usernameRequired": string;
"followerFollowingSame": string;
"invalidOTP": string;
"inactiveUser": string;
"invalidCredentials": string;
"invalidTwoFaCode": string;
"forbidden": string;
"userInactive": string;
"notFound": string;
"itemExpired": string;
"emailLooksGood": string;
"unsupportedFileType": string;
"incorrectOldPassword": string;
"badRequest": string;
"invalidRefreshToken": string;
"deleteDefaultError": string;
"tooManyTries": string;
"refreshToken": string;
"token": string;
"tooManyRequests": string;
"invalidCursor": string;
"cursorInvalidDate": string;
"cursorInvalidNumber": string;
"apiUnauthorizedResponse": string;
"tooManyRequest": string;
};
"validation": {
"isNotEmpty": string;
"maxLength": string;
"minLength": string;
"max": string;
"min": string;
"isPassword": string;
"isIn": string;
"isEnum": string;
"isDataType": string;
};
};
export type I18nPath = Path<I18nTranslations>;
14 changes: 4 additions & 10 deletions src/lib/i18n/i18n.module.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import path from "node:path";

import { Module } from "@nestjs/common";
import { AcceptLanguageResolver, CookieResolver, HeaderResolver, I18nModule, QueryResolver } from "nestjs-i18n";
import { ConfigModule, ConfigService } from "@nestjs/config";
import { AcceptLanguageResolver, HeaderResolver, I18nModule, QueryResolver } from "nestjs-i18n";

@Module({
imports: [
I18nModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (configService: ConfigService<Configs, true>) => ({
imports: [ConfigModule],
inject: [ConfigService],
fallbackLanguage: "en",
fallbacks: {
"np-*": "np",
Expand All @@ -26,12 +26,6 @@ import { ConfigModule, ConfigService } from "@nestjs/config";
includeSubfolders: true,
},
typesOutputPath: configService.get("app.env", { infer: true }).startsWith("prod") ? undefined : path.join(`${process.cwd()}/src/generated/i18n-generated.ts`),
resolvers: [
new HeaderResolver(["x-custom-lang"]),
AcceptLanguageResolver,
new CookieResolver(),
{ use: QueryResolver, options: ["lang", "locale"] },
],
}),
resolvers: [
{ use: QueryResolver, options: ["lang"] },
Expand All @@ -42,4 +36,4 @@ import { ConfigModule, ConfigService } from "@nestjs/config";
],
exports: [I18nModule],
})
export class NestI18nModule {}
export class NestI18nModule { }
8 changes: 4 additions & 4 deletions src/lib/pino/pino.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ const basePinoOptions = {
@Module({
imports: [
LoggerModule.forRootAsync({
useFactory: (configService: ConfigService<Configs, true>) => ({
imports: [ConfigModule],
inject: [ConfigService],
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (_configService: ConfigService<Configs, true>) => ({
pinoHttp: {
timestamp: () => `,"timestamp":"${new Date(Date.now()).toISOString()}"`,
name: "ultimate-nest",
Expand All @@ -34,7 +34,7 @@ const basePinoOptions = {
paths: redactFields,
censor: "**GDPR COMPLIANT**",
},
transport: configService.get("app.env", { infer: true }).startsWith("prod")
transport: true
? {
targets: [
{
Expand Down
5 changes: 3 additions & 2 deletions src/lib/sentry.module.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { Module } from "@nestjs/common";
import { Global, Module } from "@nestjs/common";
import { ConfigModule, ConfigService } from "@nestjs/config";
import { SentryModule } from "@ntegral/nestjs-sentry";

@Global()
@Module({
imports: [
SentryModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: async (configService: ConfigService<Configs, true>) => ({
dsn: configService.get("sentry.sentryDsn", { infer: true }),
environment: configService.get("sentry.sentryDsn", { infer: true }),
environment: configService.get("sentry.environment", { infer: true }),
debug: true,
tracesSampleRate: 1,
}),
Expand Down
10 changes: 4 additions & 6 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,27 @@
import "@total-typescript/ts-reset";

import bodyParser from "body-parser";
import chalk from "chalk";
import { AppUtils, HelperService } from "@common/helpers";
import { Logger, ValidationPipe } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { NestFactory } from "@nestjs/core";
import type { NestExpressApplication } from "@nestjs/platform-express";
import { ExpressAdapter } from "@nestjs/platform-express";
import bodyParser from "body-parser";
import chalk from "chalk";
import { useContainer } from "class-validator";
import compression from "compression";
import helmet from "helmet";
import { I18nValidationExceptionFilter } from "nestjs-i18n";
import { LoggerErrorInterceptor } from "nestjs-pino";
import { createLogger } from "@lib/pino/app.logger";
import { AppUtils, HelperService } from "@common/helpers";
import { SocketIOAdapter } from "./socket-io.adapter";
import { AppModule } from "./app.module";
import { SocketIOAdapter } from "./socket-io.adapter";

declare const module: { hot: { accept: () => void; dispose: (argument: () => Promise<void>) => void } };

const logger = new Logger("Bootstrap");

async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule, new ExpressAdapter(), {
logger: await createLogger(),
snapshot: true,
});

Expand Down
7 changes: 4 additions & 3 deletions src/modules/category/category.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@ import { BaseRepository } from "@common/database";
import type { OffsetPaginationDto } from "@common/dtos";
import { Category } from "@entities";
import { BaseService } from "@lib/crud/crud.service";
import { InjectRepository } from "@mikro-orm/nestjs";

@Injectable()
export class CategoryService extends BaseService<Category, OffsetPaginationDto> {
protected readonly queryName = "c"; // the name of the query used in the pagination
protected readonly searchField = "name"; // the field to search for when searching for tags
constructor(
// @ts-expect-error: Unused import error
// eslint-disable-next-line ts/no-unsafe-call
@InjectRepository(Category) private categoryRepository: BaseRepository<Category>,
// @ts-expect-error: Unused import error
// eslint-disable-next-line ts/no-unsafe-call
@InjectRepository(Category) private categoryRepository: BaseRepository<Category>,
) {
super(categoryRepository);
}
Expand Down
30 changes: 27 additions & 3 deletions src/modules/shared/shared.module.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Module } from "@nestjs/common";
import { ScheduleModule } from "@nestjs/schedule";
import { IsUniqueConstraint } from "@common/decorators/validation";
import { CustomThrottlerGuard } from "@common/guards";
import { ClearCacheInterceptor, HttpCacheInterceptor } from "@common/interceptors";
import { NestCacheModule } from "@lib/cache";
import { NestConfigModule } from "@lib/config/config.module";
import {
NestCaslModule,
Expand All @@ -25,6 +26,9 @@ import { ProfileModule } from "@modules/profile/profile.module";
import { TagsModule } from "@modules/tags/tags.module";
import { TwoFactorModule } from "@modules/twofa/twofa.module";
import { UserModule } from "@modules/user/user.module";
import { Module } from "@nestjs/common";
import { APP_GUARD, APP_INTERCEPTOR } from "@nestjs/core";
import { ScheduleModule } from "@nestjs/schedule";

@Module({
imports: [
Expand All @@ -44,14 +48,34 @@ import { UserModule } from "@modules/user/user.module";
NestPinoModule,
NestI18nModule,
NestCloudinaryModule,
NestCacheModule,
NestSentryModule,
NestCaslModule,
NestThrottlerModule,
NestHttpModule,
NestServeStaticModule,
NestSentryModule,
NestJwtModule,
ScheduleModule.forRoot(),
],
providers: [IsUniqueConstraint],
providers: [
IsUniqueConstraint,
// {
// provide: APP_INTERCEPTOR, // TODO: fix sentry
// useClass: SentryInterceptor,
// },
{
provide: APP_GUARD,
useClass: CustomThrottlerGuard,
},
{
provide: APP_INTERCEPTOR,
useClass: HttpCacheInterceptor,
},
{
provide: APP_INTERCEPTOR,
useClass: ClearCacheInterceptor,
},
],
})
export class SharedModule {}
2 changes: 1 addition & 1 deletion temp/BaseEntity.js.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"data":{"propertyOrder":{},"properties":{"id":{"name":"id","reference":"scalar","primary":true,"hidden":true,"index":true,"type":"number","array":false},"idx":{"name":"idx","reference":"scalar","index":true,"getter":false,"setter":false,"type":"string","array":false,"optional":true},"isActive":{"name":"isActive","reference":"scalar","getter":false,"setter":false,"type":"boolean","array":false,"optional":true},"isDeleted":{"name":"isDeleted","reference":"scalar","hidden":true,"getter":false,"setter":false,"type":"boolean","array":false,"optional":true},"deletedAt":{"name":"deletedAt","reference":"scalar","getter":false,"setter":false,"type":"Date","array":false,"optional":true},"createdAt":{"name":"createdAt","reference":"scalar","getter":false,"setter":false,"type":"Date","array":false,"optional":true},"updatedAt":{"name":"updatedAt","reference":"scalar","hidden":true,"getter":false,"setter":false,"type":"Date","array":false,"optional":true}},"props":[{"name":"id","reference":"scalar","primary":true,"hidden":true,"index":true,"type":"number","array":false},{"name":"idx","reference":"scalar","index":true,"getter":false,"setter":false,"type":"string","array":false,"optional":true},{"name":"isActive","reference":"scalar","getter":false,"setter":false,"type":"boolean","array":false,"optional":true},{"name":"isDeleted","reference":"scalar","hidden":true,"getter":false,"setter":false,"type":"boolean","array":false,"optional":true},{"name":"deletedAt","reference":"scalar","getter":false,"setter":false,"type":"Date","array":false,"optional":true},{"name":"createdAt","reference":"scalar","getter":false,"setter":false,"type":"Date","array":false,"optional":true},{"name":"updatedAt","reference":"scalar","hidden":true,"getter":false,"setter":false,"type":"Date","array":false,"optional":true}],"primaryKeys":["id"],"filters":{},"hooks":{},"indexes":[],"uniques":[],"checks":[],"concurrencyCheckKeys":{},"className":"BaseEntity","path":"./dist/common/database/base.entity.js","abstract":true,"constructorParams":[],"toJsonParams":[],"useCache":true,"compositePK":false,"simplePK":true,"relations":[]},"origin":"./dist/common/database/base.entity.js","hash":"0a512305f18ebe86f440150896ef51f0","version":"5.7.12"}
{"data":{"propertyOrder":{},"properties":{"id":{"name":"id","reference":"scalar","primary":true,"hidden":true,"index":true,"type":"number","array":false},"idx":{"name":"idx","reference":"scalar","index":true,"getter":false,"setter":false,"type":"string","array":false,"optional":true},"isActive":{"name":"isActive","reference":"scalar","getter":false,"setter":false,"type":"boolean","array":false,"optional":true},"isDeleted":{"name":"isDeleted","reference":"scalar","hidden":true,"getter":false,"setter":false,"type":"boolean","array":false,"optional":true},"deletedAt":{"name":"deletedAt","reference":"scalar","getter":false,"setter":false,"type":"Date","array":false,"optional":true},"createdAt":{"name":"createdAt","reference":"scalar","getter":false,"setter":false,"type":"Date","array":false,"optional":true},"updatedAt":{"name":"updatedAt","reference":"scalar","hidden":true,"getter":false,"setter":false,"type":"Date","array":false,"optional":true}},"props":[{"name":"id","reference":"scalar","primary":true,"hidden":true,"index":true,"type":"number","array":false},{"name":"idx","reference":"scalar","index":true,"getter":false,"setter":false,"type":"string","array":false,"optional":true},{"name":"isActive","reference":"scalar","getter":false,"setter":false,"type":"boolean","array":false,"optional":true},{"name":"isDeleted","reference":"scalar","hidden":true,"getter":false,"setter":false,"type":"boolean","array":false,"optional":true},{"name":"deletedAt","reference":"scalar","getter":false,"setter":false,"type":"Date","array":false,"optional":true},{"name":"createdAt","reference":"scalar","getter":false,"setter":false,"type":"Date","array":false,"optional":true},{"name":"updatedAt","reference":"scalar","hidden":true,"getter":false,"setter":false,"type":"Date","array":false,"optional":true}],"primaryKeys":["id"],"filters":{},"hooks":{},"indexes":[],"uniques":[],"concurrencyCheckKeys":{},"className":"BaseEntity","path":"./dist/common/database/base.entity.js","abstract":true,"constructorParams":[],"toJsonParams":[],"useCache":true,"compositePK":false,"simplePK":true,"relations":[]},"origin":"./dist/common/database/base.entity.js","hash":"a2153d72199ccfeab857a9c5b5d94af8","version":"5.8.9"}
2 changes: 1 addition & 1 deletion temp/Category.js.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"data":{"propertyOrder":{},"properties":{"name":{"name":"name","reference":"scalar","index":true,"getter":false,"setter":false,"type":"string","array":false},"description":{"name":"description","reference":"scalar","getter":false,"setter":false,"type":"string","array":false},"posts":{"name":"posts","reference":"m:n","cascade":["persist"],"type":"Post","fixedOrder":false,"array":false}},"props":[{"name":"name","reference":"scalar","index":true,"getter":false,"setter":false,"type":"string","array":false},{"name":"description","reference":"scalar","getter":false,"setter":false,"type":"string","array":false},{"name":"posts","reference":"m:n","cascade":["persist"],"type":"Post","fixedOrder":false,"array":false}],"primaryKeys":[],"filters":{},"hooks":{},"indexes":[],"uniques":[],"checks":[],"concurrencyCheckKeys":{},"className":"Category","path":"./dist/entities/category.entity.js","name":"Category","abstract":false,"constructorParams":["partial"],"toJsonParams":[],"extends":"BaseEntity","useCache":true,"relations":[{"name":"posts","reference":"m:n","cascade":["persist"],"type":"Post","fixedOrder":false,"array":false}],"collection":"category"},"origin":"./dist/entities/category.entity.js","hash":"fc4f3683c61704e000098ea26e174c85","version":"5.7.12"}
{"data":{"propertyOrder":{},"properties":{"name":{"name":"name","reference":"scalar","index":true,"getter":false,"setter":false,"type":"string","array":false},"description":{"name":"description","reference":"scalar","getter":false,"setter":false,"type":"string","array":false},"posts":{"name":"posts","reference":"m:n","cascade":["persist"],"type":"Post","fixedOrder":false,"array":false}},"props":[{"name":"name","reference":"scalar","index":true,"getter":false,"setter":false,"type":"string","array":false},{"name":"description","reference":"scalar","getter":false,"setter":false,"type":"string","array":false},{"name":"posts","reference":"m:n","cascade":["persist"],"type":"Post","fixedOrder":false,"array":false}],"primaryKeys":[],"filters":{},"hooks":{},"indexes":[],"uniques":[],"concurrencyCheckKeys":{},"className":"Category","path":"./dist/entities/category.entity.js","name":"Category","abstract":false,"constructorParams":["partial"],"toJsonParams":[],"extends":"BaseEntity","useCache":true,"relations":[{"name":"posts","reference":"m:n","cascade":["persist"],"type":"Post","fixedOrder":false,"array":false}],"collection":"category"},"origin":"./dist/entities/category.entity.js","hash":"8e2ec5a16c5fbab38c730eb820e536a7","version":"5.8.9"}
Loading

0 comments on commit bfa3273

Please sign in to comment.