refactor source code

This commit is contained in:
2024-10-29 17:42:54 +07:00
parent 3b23d9e0b7
commit 152bb50da8
83 changed files with 8473 additions and 7577 deletions

View File

@@ -1,11 +1,11 @@
{
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
"vcs": { "enabled": false, "clientKind": "git", "useIgnoreFile": false },
"files": { "ignoreUnknown": false, "ignore": [] },
"files": { "ignoreUnknown": false, "ignore": ["dist"] },
"formatter": {
"enabled": true,
"useEditorconfig": true,
"formatWithErrors": false,
"formatWithErrors": true,
"indentStyle": "space",
"indentWidth": 2,
"lineEnding": "lf",

View File

@@ -1,4 +1,4 @@
import type { CodegenConfig } from '@graphql-codegen/cli';
import type { CodegenConfig } from '@graphql-codegen/cli'
const config: CodegenConfig = {
overwrite: true,
@@ -8,6 +8,6 @@ const config: CodegenConfig = {
plugins: ['typescript', 'typescript-resolvers'],
},
},
};
}
export default config;
export default config

View File

@@ -20,7 +20,7 @@
"prisma:format": "npx prisma format --schema=./epess-database/prisma/schema.prisma",
"prisma:studio": "npx prisma studio --schema=./epess-database/prisma/schema.prisma",
"biome:check": "biome check",
"biome:fix": "biome fix",
"biome:fix": "biome fix --write",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"prettier": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"test": "jest",
@@ -123,19 +123,13 @@
"ws": "^8.18.0"
},
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"moduleFileExtensions": ["js", "json", "ts"],
"rootDir": "src",
"testRegex": ".*\\.spec\\.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"collectCoverageFrom": [
"**/*.(t|j)s"
],
"collectCoverageFrom": ["**/*.(t|j)s"],
"coverageDirectory": "../coverage",
"testEnvironment": "node"
},

View File

@@ -1,5 +1,5 @@
import { AdminNoteSchema } from './adminnote.schema';
import { Module } from '@nestjs/common';
import { AdminNoteSchema } from './adminnote.schema'
import { Module } from '@nestjs/common'
@Module({
providers: [AdminNoteSchema],

View File

@@ -1,12 +1,12 @@
import { Inject, Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common'
import {
Pothos,
PothosRef,
PothosSchema,
SchemaBuilderToken,
} from '@smatch-corp/nestjs-pothos';
import { Builder } from '../Graphql/graphql.builder';
import { PrismaService } from '../Prisma/prisma.service';
} from '@smatch-corp/nestjs-pothos'
import { Builder } from '../Graphql/graphql.builder'
import { PrismaService } from '../Prisma/prisma.service'
@Injectable()
export class AdminNoteSchema extends PothosSchema {
@@ -14,7 +14,7 @@ export class AdminNoteSchema extends PothosSchema {
@Inject(SchemaBuilderToken) private readonly builder: Builder,
private readonly prisma: PrismaService,
) {
super();
super()
}
@PothosRef()
@@ -71,7 +71,7 @@ export class AdminNoteSchema extends PothosSchema {
description: 'The resume the admin note is associated with.',
}),
}),
});
})
}
@Pothos()
@@ -81,18 +81,18 @@ export class AdminNoteSchema extends PothosSchema {
type: this.adminNote(),
args: this.builder.generator.findUniqueArgs('AdminNote'),
description: 'Retrieve a single admin note by its unique identifier.',
resolve: async (query, root, args, ctx, info) => {
resolve: async (query, _root, args, _ctx, _info) => {
return await this.prisma.adminNote.findUnique({
...query,
where: args.where,
});
})
},
}),
adminNotes: t.prismaField({
type: [this.adminNote()],
args: this.builder.generator.findManyArgs('AdminNote'),
description: 'Retrieve a list of admin notes.',
resolve: async (query, root, args, ctx, info) => {
resolve: async (query, _root, args, _ctx, _info) => {
return await this.prisma.adminNote.findMany({
...query,
where: args.filter ?? undefined,
@@ -100,10 +100,10 @@ export class AdminNoteSchema extends PothosSchema {
cursor: args.cursor ?? undefined,
skip: args.skip ?? undefined,
take: args.take ?? undefined,
});
})
},
}),
}));
}))
// Mutations
this.builder.mutationFields((t) => ({
@@ -115,11 +115,11 @@ export class AdminNoteSchema extends PothosSchema {
required: true,
}),
},
resolve: async (query, root, args, ctx, info) => {
resolve: async (query, _root, args, _ctx, _info) => {
return await this.prisma.adminNote.create({
...query,
data: args.input,
});
})
},
}),
@@ -135,12 +135,12 @@ export class AdminNoteSchema extends PothosSchema {
required: true,
}),
},
resolve: async (query, root, args, ctx, info) => {
resolve: async (query, _root, args, _ctx, _info) => {
return await this.prisma.adminNote.update({
...query,
where: args.where,
data: args.data,
});
})
},
}),
@@ -152,13 +152,13 @@ export class AdminNoteSchema extends PothosSchema {
required: true,
}),
},
resolve: async (query, root, args, ctx, info) => {
resolve: async (query, _root, args, _ctx, _info) => {
return await this.prisma.adminNote.delete({
...query,
where: args.where,
});
})
},
}),
}));
}))
}
}

View File

@@ -1,7 +1,7 @@
import { Global, Module } from '@nestjs/common';
import { Global, Module } from '@nestjs/common'
import { AppConfigSchema } from './appconfig.schema';
import { AppConfigService } from './appconfig.service';
import { AppConfigSchema } from './appconfig.schema'
import { AppConfigService } from './appconfig.service'
@Global()
@Module({

View File

@@ -1,12 +1,12 @@
import { Inject, Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common'
import {
PothosRef,
PothosSchema,
SchemaBuilderToken,
} from '@smatch-corp/nestjs-pothos';
import { Builder } from 'src/Graphql/graphql.builder';
import { AppConfigService } from './appconfig.service';
import { PrismaService } from 'src/Prisma/prisma.service';
} from '@smatch-corp/nestjs-pothos'
import { Builder } from 'src/Graphql/graphql.builder'
import { AppConfigService } from './appconfig.service'
import { PrismaService } from 'src/Prisma/prisma.service'
@Injectable()
export class AppConfigSchema extends PothosSchema {
@@ -15,7 +15,7 @@ export class AppConfigSchema extends PothosSchema {
private readonly appConfigService: AppConfigService,
private readonly prisma: PrismaService,
) {
super();
super()
}
@PothosRef()
@@ -39,7 +39,7 @@ export class AppConfigSchema extends PothosSchema {
description: 'Whether the config is visible',
}),
}),
});
})
}
@PothosRef()
@@ -57,7 +57,7 @@ export class AppConfigSchema extends PothosSchema {
cursor: args.cursor ?? undefined,
skip: args.skip ?? undefined,
take: args.take ?? undefined,
});
})
},
}),
appConfig: t.prismaField({
@@ -68,10 +68,10 @@ export class AppConfigSchema extends PothosSchema {
return await this.prisma.config.findUnique({
...query,
where: args.where ?? undefined,
});
})
},
}),
}));
}))
// Mutations
this.builder.mutationFields((t) => ({
@@ -88,7 +88,7 @@ export class AppConfigSchema extends PothosSchema {
return await this.prisma.config.create({
...query,
data: args.input,
});
})
},
}),
createAppConfigs: t.prismaField({
@@ -104,9 +104,9 @@ export class AppConfigSchema extends PothosSchema {
return await this.prisma.config.createManyAndReturn({
...query,
data: args.input,
});
})
},
}),
}));
}))
}
}

View File

@@ -1,5 +1,5 @@
import { Module } from '@nestjs/common';
import { CategorySchema } from './category.schema';
import { Module } from '@nestjs/common'
import { CategorySchema } from './category.schema'
@Module({
providers: [CategorySchema],

View File

@@ -1,12 +1,12 @@
import { Inject, Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common'
import {
Pothos,
PothosRef,
PothosSchema,
SchemaBuilderToken,
} from '@smatch-corp/nestjs-pothos';
import { Builder } from '../Graphql/graphql.builder';
import { PrismaService } from '../Prisma/prisma.service';
} from '@smatch-corp/nestjs-pothos'
import { Builder } from '../Graphql/graphql.builder'
import { PrismaService } from '../Prisma/prisma.service'
@Injectable()
export class CategorySchema extends PothosSchema {
@@ -14,7 +14,7 @@ export class CategorySchema extends PothosSchema {
@Inject(SchemaBuilderToken) private readonly builder: Builder,
private readonly prisma: PrismaService,
) {
super();
super()
}
@PothosRef()
@@ -32,7 +32,7 @@ export class CategorySchema extends PothosSchema {
description: 'The subcategory of the category.',
}),
}),
});
})
}
@PothosRef()
@@ -58,7 +58,7 @@ export class CategorySchema extends PothosSchema {
'The service and category that the subcategory belongs to.',
}),
}),
});
})
}
@Pothos()
@@ -76,7 +76,7 @@ export class CategorySchema extends PothosSchema {
take: args.take ?? undefined,
orderBy: args.orderBy ?? undefined,
where: args.filter ?? undefined,
});
})
},
}),
category: t.prismaField({
@@ -87,7 +87,7 @@ export class CategorySchema extends PothosSchema {
return await this.prisma.category.findUnique({
...query,
where: args.where ?? undefined,
});
})
},
}),
subCategories: t.prismaField({
@@ -102,10 +102,10 @@ export class CategorySchema extends PothosSchema {
orderBy: args.orderBy ?? undefined,
skip: args.skip ?? undefined,
take: args.take ?? undefined,
});
})
},
}),
}));
}))
// mutation
this.builder.mutationFields((t) => ({
@@ -121,7 +121,7 @@ export class CategorySchema extends PothosSchema {
resolve: async (query, root, args) => {
return await this.prisma.category.create({
data: args.input,
});
})
},
}),
createManyCategories: t.prismaField({
@@ -137,7 +137,7 @@ export class CategorySchema extends PothosSchema {
return await this.prisma.category.createManyAndReturn({
data: args.data,
skipDuplicates: true,
});
})
},
}),
@@ -153,9 +153,9 @@ export class CategorySchema extends PothosSchema {
resolve: async (query, root, args) => {
return await this.prisma.subCategory.create({
data: args.input,
});
})
},
}),
}));
}))
}
}

View File

@@ -1,5 +1,5 @@
import { Module } from '@nestjs/common';
import { CenterSchema } from './center.schema';
import { Module } from '@nestjs/common'
import { CenterSchema } from './center.schema'
@Module({
providers: [CenterSchema],

View File

@@ -1,15 +1,15 @@
import { Inject, Injectable, Logger } from '@nestjs/common';
import { Inject, Injectable, Logger } from '@nestjs/common'
import {
Pothos,
PothosRef,
PothosSchema,
SchemaBuilderToken,
} from '@smatch-corp/nestjs-pothos';
import { Builder } from '../Graphql/graphql.builder';
import { PrismaService } from '../Prisma/prisma.service';
import { MinioService } from '../Minio/minio.service';
import { CenterStatus, Role } from '@prisma/client';
import { MailService } from '../Mail/mail.service';
} from '@smatch-corp/nestjs-pothos'
import { Builder } from '../Graphql/graphql.builder'
import { PrismaService } from '../Prisma/prisma.service'
import { MinioService } from '../Minio/minio.service'
import { CenterStatus, Role } from '@prisma/client'
import { MailService } from '../Mail/mail.service'
@Injectable()
export class CenterSchema extends PothosSchema {
constructor(
@@ -18,7 +18,7 @@ export class CenterSchema extends PothosSchema {
private readonly minioService: MinioService,
private readonly mailService: MailService,
) {
super();
super()
}
@PothosRef()
@@ -85,7 +85,7 @@ export class CenterSchema extends PothosSchema {
description: 'The ID of the uploaded file.',
}),
}),
});
})
}
@Pothos()
@@ -96,25 +96,25 @@ export class CenterSchema extends PothosSchema {
'Retrieve a list of centers with optional filtering, ordering, and pagination.',
type: [this.center()],
args: this.builder.generator.findManyArgs('Center'),
resolve: async (query, root, args) => {
resolve: async (query, _root, args) => {
return await this.prisma.center.findMany({
...query,
skip: args.skip ?? undefined,
take: args.take ?? undefined,
orderBy: args.orderBy ?? undefined,
where: args.filter ?? undefined,
});
})
},
}),
center: t.prismaField({
type: this.center(),
description: 'Retrieve a single center by its unique identifier.',
args: this.builder.generator.findUniqueArgs('Center'),
resolve: async (query, root, args) => {
resolve: async (query, _root, args) => {
return await this.prisma.center.findUnique({
...query,
where: args.where,
});
})
},
}),
// get current center of centermentor by providing userId
@@ -124,7 +124,7 @@ export class CenterSchema extends PothosSchema {
args: {
userId: t.arg({ type: 'String', required: true }),
},
resolve: async (query, root, args) => {
resolve: async (_query, _root, args) => {
return await this.prisma.center.findFirst({
where: {
centerMentors: {
@@ -133,10 +133,10 @@ export class CenterSchema extends PothosSchema {
},
},
},
});
})
},
}),
}));
}))
// mutation section
this.builder.mutationFields((t) => ({
@@ -149,11 +149,11 @@ export class CenterSchema extends PothosSchema {
required: true,
}),
},
resolve: async (query, root, args) => {
resolve: async (query, _root, args) => {
return await this.prisma.center.create({
...query,
data: args.input,
});
})
},
}),
updateCenter: t.prismaField({
@@ -169,12 +169,12 @@ export class CenterSchema extends PothosSchema {
required: true,
}),
},
resolve: async (query, root, args) => {
resolve: async (query, _root, args) => {
return await this.prisma.center.update({
...query,
where: args.where,
data: args.input,
});
})
},
}),
deleteCenter: t.prismaField({
@@ -186,11 +186,11 @@ export class CenterSchema extends PothosSchema {
required: true,
}),
},
resolve: async (query, root, args) => {
resolve: async (query, _root, args) => {
return await this.prisma.center.delete({
...query,
where: args.where,
});
})
},
}),
approveOrRejectCenter: t.prismaField({
@@ -210,33 +210,33 @@ export class CenterSchema extends PothosSchema {
required: false,
}),
},
resolve: async (query, root, args) => {
resolve: async (query, _root, args) => {
return await this.prisma.$transaction(async (prisma) => {
const center = await prisma.center.findUnique({
...query,
where: {
id: args.centerId,
},
});
})
if (!center) {
throw new Error('Center not found');
throw new Error('Center not found')
}
// check if center is already approved or rejected
if (center.centerStatus !== CenterStatus.PENDING) {
throw new Error('Center is already approved or rejected');
throw new Error('Center is already approved or rejected')
}
// find user and promote to center owner
const centerOwnerId = center.centerOwnerId;
const centerOwnerId = center.centerOwnerId
if (!centerOwnerId) {
throw new Error('User not found');
throw new Error('User not found')
}
const centerOwner = await prisma.user.findUnique({
where: {
id: centerOwnerId,
},
});
})
if (!centerOwner) {
throw new Error('User not found');
throw new Error('User not found')
}
await prisma.user.update({
where: {
@@ -245,7 +245,7 @@ export class CenterSchema extends PothosSchema {
data: {
role: Role.CENTER_OWNER,
},
});
})
// update center status
const updatedCenter = await prisma.center.update({
...query,
@@ -257,7 +257,7 @@ export class CenterSchema extends PothosSchema {
? CenterStatus.APPROVED
: CenterStatus.REJECTED,
},
});
})
// mail to center owner if approved
if (args.approve) {
try {
@@ -268,9 +268,9 @@ export class CenterSchema extends PothosSchema {
{
CENTER_NAME: center.name,
},
);
)
} catch (error) {
Logger.error(error, 'CenterSchema');
Logger.error(error, 'CenterSchema')
}
}
if (!args.approve) {
@@ -284,15 +284,15 @@ export class CenterSchema extends PothosSchema {
CENTER_NAME: center.name,
ADMIN_NOTE: args.adminNote,
},
);
)
} catch (error) {
Logger.error(error, 'CenterSchema');
Logger.error(error, 'CenterSchema')
}
}
return updatedCenter;
});
return updatedCenter
})
},
}),
}));
}))
}
}

View File

@@ -1,6 +1,6 @@
import { CenterMentorSchema } from './centermentor.schema';
import { Module } from '@nestjs/common';
import { UserModule } from 'src/User/user.module';
import { CenterMentorSchema } from './centermentor.schema'
import { Module } from '@nestjs/common'
import { UserModule } from 'src/User/user.module'
@Module({
imports: [UserModule],

View File

@@ -1,5 +1,5 @@
import { Module } from '@nestjs/common';
import { ChatroomSchema } from './chatroom.schema';
import { Module } from '@nestjs/common'
import { ChatroomSchema } from './chatroom.schema'
@Module({
providers: [ChatroomSchema],

View File

@@ -1,13 +1,13 @@
import { Inject, Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common'
import {
Pothos,
PothosRef,
PothosSchema,
SchemaBuilderToken,
} from '@smatch-corp/nestjs-pothos';
import { Builder } from '../Graphql/graphql.builder';
import { PrismaService } from '../Prisma/prisma.service';
import { ChatRoomType } from '@prisma/client';
} from '@smatch-corp/nestjs-pothos'
import { Builder } from '../Graphql/graphql.builder'
import { PrismaService } from '../Prisma/prisma.service'
import { ChatRoomType } from '@prisma/client'
@Injectable()
export class ChatroomSchema extends PothosSchema {
@@ -15,7 +15,7 @@ export class ChatroomSchema extends PothosSchema {
@Inject(SchemaBuilderToken) private readonly builder: Builder,
private readonly prisma: PrismaService,
) {
super();
super()
}
@PothosRef()
@@ -59,7 +59,7 @@ export class ChatroomSchema extends PothosSchema {
description: 'The meeting room.',
}),
}),
});
})
}
@Pothos()
@@ -69,11 +69,11 @@ export class ChatroomSchema extends PothosSchema {
type: this.chatRoom(),
description: 'Retrieve a single chat room by its unique identifier.',
args: this.builder.generator.findUniqueArgs('ChatRoom'),
resolve: async (query, root, args, ctx, info) => {
resolve: async (query, _root, args, _ctx, _info) => {
return await this.prisma.chatRoom.findUnique({
...query,
where: args.where,
});
})
},
}),
@@ -82,16 +82,16 @@ export class ChatroomSchema extends PothosSchema {
description:
'Retrieve a list of chat rooms with optional filtering, ordering, and pagination.',
args: this.builder.generator.findManyArgs('ChatRoom'),
resolve: async (query, root, args, ctx, info) => {
resolve: async (query, _root, args, _ctx, _info) => {
return await this.prisma.chatRoom.findMany({
...query,
skip: args.skip ?? undefined,
take: args.take ?? undefined,
orderBy: args.orderBy ?? undefined,
where: args.filter ?? undefined,
});
})
},
}),
}));
}))
}
}

View File

@@ -5,9 +5,9 @@ import {
ExecutionContext,
Inject,
UnauthorizedException,
} from '@nestjs/common';
import Clerk from '@clerk/express';
import { GqlExecutionContext } from '@nestjs/graphql';
} from '@nestjs/common'
import Clerk from '@clerk/express'
import { GqlExecutionContext } from '@nestjs/graphql'
@Injectable()
export class ClerkAuthGuard implements CanActivate {
@@ -15,36 +15,36 @@ export class ClerkAuthGuard implements CanActivate {
async canActivate(context: ExecutionContext): Promise<boolean> {
// For GraphQL, get the request from the GQL context
const ctx = GqlExecutionContext.create(context);
const request = ctx.getContext().req;
const ctx = GqlExecutionContext.create(context)
const request = ctx.getContext().req
// Get the token from the Authorization header
const authHeader = request.headers['authorization'];
const authHeader = request.headers['authorization']
if (!authHeader) {
throw new UnauthorizedException('Authorization header not found');
throw new UnauthorizedException('Authorization header not found')
}
const token = authHeader.split(' ')[1]; // Assuming 'Bearer TOKEN'
const token = authHeader.split(' ')[1] // Assuming 'Bearer TOKEN'
if (!token) {
throw new UnauthorizedException('Token not found');
throw new UnauthorizedException('Token not found')
}
try {
// Verify the token with Clerk
const session = await this.clerk.verifyToken(token, {});
const session = await this.clerk.verifyToken(token, {})
if (!session) {
throw new UnauthorizedException('Invalid session');
throw new UnauthorizedException('Invalid session')
}
// Attach user info to the request context if needed
request.user = session.user;
request.user = session.user
return true;
return true
} catch (error: any) {
throw new UnauthorizedException(error.message);
throw new UnauthorizedException(error.message)
}
}
}

View File

@@ -7,9 +7,9 @@ import {
Param,
Body,
Headers,
} from '@nestjs/common';
import { ClerkService } from './clerk.service';
import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger';
} from '@nestjs/common'
import { ClerkService } from './clerk.service'
import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger'
@ApiTags('Clerk')
@Controller('clerk')
export class ClerkController {
@@ -19,8 +19,8 @@ export class ClerkController {
@ApiOperation({ summary: 'Clerk Webhook' })
@ApiResponse({ status: 200, description: 'Webhook created successfully' })
webhook(@Headers() headers: any, @Body() body: any) {
return this.clerkService.webhook(body);
return this.clerkService.webhook(body)
}
}
export default ClerkController;
export default ClerkController

View File

@@ -1,7 +1,7 @@
import { Module, Global } from '@nestjs/common';
import Clerk from '@clerk/express';
import { ClerkService } from './clerk.service';
import ClerkController from './clerk.controller';
import { Module, Global } from '@nestjs/common'
import Clerk from '@clerk/express'
import { ClerkService } from './clerk.service'
import ClerkController from './clerk.controller'
@Global()
@Module({
providers: [

View File

@@ -1,17 +1,17 @@
import { Injectable, Logger } from '@nestjs/common';
import { Injectable, Logger } from '@nestjs/common'
import { PrismaService } from '../Prisma/prisma.service';
import { clerkClient } from '@clerk/express';
import { PrismaService } from '../Prisma/prisma.service'
import { clerkClient } from '@clerk/express'
@Injectable()
export class ClerkService {
constructor(private readonly prisma: PrismaService) {}
webhook(body: any) {
// get the event type
const eventType = body.type;
const eventType = body.type
// dispatch the event
this.dispatchEvent(eventType, body.data);
return { message: `Webhook received: ${eventType}` };
this.dispatchEvent(eventType, body.data)
return { message: `Webhook received: ${eventType}` }
}
// dispatch the event
dispatchEvent(eventType: string, data: any) {
@@ -23,53 +23,53 @@ export class ClerkService {
// session.removed
// session.ended
// email.created
console.log(eventType, data);
console.log(eventType, data)
if (eventType === 'user.created') {
this.eventUserCreated(data);
this.eventUserCreated(data)
}
if (eventType === 'user.updated') {
this.eventUserUpdated(data);
this.eventUserUpdated(data)
}
if (eventType === 'session.created') {
this.eventSessionCreated(data);
this.eventSessionCreated(data)
}
if (eventType === 'session.revoked') {
this.eventSessionRevoked(data);
this.eventSessionRevoked(data)
}
if (eventType === 'session.removed') {
this.eventSessionRemoved(data);
this.eventSessionRemoved(data)
}
if (eventType === 'session.ended') {
this.eventSessionEnded(data);
this.eventSessionEnded(data)
}
if (eventType === 'email.created') {
this.eventEmailCreated(data);
this.eventEmailCreated(data)
}
}
async eventUserCreated(data: any) {
const primary_email_address_id = data.primary_email_address_id;
const primary_email_address_id = data.primary_email_address_id
// get primary email address on email_addresses by querying email_addresses with primary_email_address_id
let primary_email_address = data.email_addresses.find(
(email: any) => email.id === primary_email_address_id,
);
console.log(primary_email_address);
)
console.log(primary_email_address)
if (!primary_email_address) {
primary_email_address = '';
primary_email_address = ''
}
// get user id
const user_id = data.id;
const user_id = data.id
// get created at and convert to date
const created_at = new Date(data.created_at);
const created_at = new Date(data.created_at)
// get name by combining first_name and last_name
const name = `${data.first_name} ${data.last_name}`;
const role = 'CUSTOMER';
const phoneNumber = '';
const name = `${data.first_name} ${data.last_name}`
const role = 'CUSTOMER'
const phoneNumber = ''
// create user in database
try {
await this.prisma.user.create({
@@ -81,32 +81,32 @@ export class ClerkService {
createdAt: created_at,
phoneNumber: phoneNumber ?? '',
},
});
})
} catch (err) {
Logger.error(err);
Logger.error(err)
}
}
async eventUserUpdated(data: any) {
console.log(data);
const user_id = data.id;
const name = `${data.first_name} ${data.last_name}`;
console.log(data)
const user_id = data.id
const name = `${data.first_name} ${data.last_name}`
await this.prisma.user.update({
where: { id: user_id },
data: { name: name },
});
})
}
async eventSessionCreated(data: any) {
console.log(data);
console.log(data)
// check if user exists in database or create user
const user = await this.prisma.user.findUnique({
where: { id: data.user_id },
});
})
if (!user) {
// get user info from clerk
const userInfo = await clerkClient.users.getUser(data.user_id);
console.log(userInfo);
const userInfo = await clerkClient.users.getUser(data.user_id)
console.log(userInfo)
try {
await this.prisma.user.create({
data: {
@@ -115,27 +115,27 @@ export class ClerkService {
name: `${userInfo.firstName} ${userInfo.lastName}`,
avatarUrl: userInfo.imageUrl,
},
});
})
} catch (err) {
Logger.error(err);
Logger.error(err)
}
}
// to do: get session info
}
eventSessionRevoked(data: any) {
console.log(data);
console.log(data)
}
eventSessionRemoved(data: any) {
console.log(data);
console.log(data)
}
eventSessionEnded(data: any) {
console.log(data);
console.log(data)
}
eventEmailCreated(data: any) {
console.log(data);
console.log(data)
}
}

View File

@@ -1,82 +1,82 @@
import { DateTimeResolver, JSONObjectResolver } from 'graphql-scalars';
import { DateTimeResolver, JSONObjectResolver } from 'graphql-scalars'
import PrismaPlugin, {
PothosPrismaDatamodel,
PrismaClient,
} from '@pothos/plugin-prisma';
import { Request, Response } from 'express';
} from '@pothos/plugin-prisma'
import { Request, Response } from 'express'
import SmartSubscriptionPlugin, {
subscribeOptionsFromIterator,
} from '@pothos/plugin-smart-subscriptions';
} from '@pothos/plugin-smart-subscriptions'
import AuthzPlugin from '@pothos/plugin-authz';
import ErrorsPlugin from '@pothos/plugin-errors';
import type { FileUpload } from 'graphql-upload/processRequest.js';
import GraphQLUpload from 'graphql-upload/GraphQLUpload.js';
import { Injectable } from '@nestjs/common';
import { PrismaCrudGenerator } from './graphql.generator';
import type PrismaTypes from '../types/pothos.generated';
import PrismaUtils from '@pothos/plugin-prisma-utils';
import { PubSub } from 'graphql-subscriptions';
import RelayPlugin from '@pothos/plugin-relay';
import SchemaBuilder from '@pothos/core';
import SimpleObjectPlugin from '@pothos/plugin-simple-objects';
import { User } from '@prisma/client';
import { getDatamodel } from '../types/pothos.generated';
import AuthzPlugin from '@pothos/plugin-authz'
import ErrorsPlugin from '@pothos/plugin-errors'
import type { FileUpload } from 'graphql-upload/processRequest.js'
import GraphQLUpload from 'graphql-upload/GraphQLUpload.js'
import { Injectable } from '@nestjs/common'
import { PrismaCrudGenerator } from './graphql.generator'
import type PrismaTypes from '../types/pothos.generated'
import PrismaUtils from '@pothos/plugin-prisma-utils'
import { PubSub } from 'graphql-subscriptions'
import RelayPlugin from '@pothos/plugin-relay'
import SchemaBuilder from '@pothos/core'
import SimpleObjectPlugin from '@pothos/plugin-simple-objects'
import { User } from '@prisma/client'
import { getDatamodel } from '../types/pothos.generated'
// import { rules } from '../common/graphql/common.graphql.auth-rule';
export type SchemaContext =
| {
isSubscription: true;
isSubscription: true
websocket: {
pubSub: PubSub;
me: User;
generator: PrismaCrudGenerator<BuilderTypes>;
};
pubSub: PubSub
me: User
generator: PrismaCrudGenerator<BuilderTypes>
}
}
| {
isSubscription: false;
isSubscription: false
http: {
req: Request;
res: Response;
me: User;
pubSub: PubSub;
generator: PrismaCrudGenerator<BuilderTypes>;
};
};
req: Request
res: Response
me: User
pubSub: PubSub
generator: PrismaCrudGenerator<BuilderTypes>
}
}
// extend prisma types to contain string type
export interface SchemaBuilderOption {
Context: SchemaContext;
PrismaTypes: PrismaTypes;
DataModel: PothosPrismaDatamodel;
Context: SchemaContext
PrismaTypes: PrismaTypes
DataModel: PothosPrismaDatamodel
Connection: {
totalCount: number | (() => number | Promise<number>);
};
totalCount: number | (() => number | Promise<number>)
}
// AuthZRule: keyof typeof rules;
Scalars: {
DateTime: {
Input: Date;
Output: Date;
};
Input: Date
Output: Date
}
Json: {
Input: JSON;
Output: JSON;
};
Input: JSON
Output: JSON
}
Upload: {
Input: FileUpload;
Output: FileUpload;
};
Input: FileUpload
Output: FileUpload
}
Int: {
Input: number;
Output: number | bigint | string;
};
};
Input: number
Output: number | bigint | string
}
}
}
@Injectable()
export class Builder extends SchemaBuilder<SchemaBuilderOption> {
public generator: PrismaCrudGenerator<BuilderTypes>;
public generator: PrismaCrudGenerator<BuilderTypes>
constructor(private readonly prisma: PrismaClient) {
super({
@@ -93,9 +93,9 @@ export class Builder extends SchemaBuilder<SchemaBuilderOption> {
debounceDelay: 1000,
...subscribeOptionsFromIterator((name, ctx) => {
if (ctx.isSubscription) {
return ctx.websocket.pubSub.asyncIterator(name);
return ctx.websocket.pubSub.asyncIterator(name)
}
return ctx.http.pubSub.asyncIterator(name);
return ctx.http.pubSub.asyncIterator(name)
}),
},
relay: {},
@@ -109,15 +109,15 @@ export class Builder extends SchemaBuilder<SchemaBuilderOption> {
errors: {
defaultTypes: [],
},
});
this.generator = new PrismaCrudGenerator<BuilderTypes>(this);
this.addScalarType('DateTime', DateTimeResolver);
this.addScalarType('Json', JSONObjectResolver);
this.addScalarType('Upload', GraphQLUpload);
})
this.generator = new PrismaCrudGenerator<BuilderTypes>(this)
this.addScalarType('DateTime', DateTimeResolver)
this.addScalarType('Json', JSONObjectResolver)
this.addScalarType('Upload', GraphQLUpload)
this.queryType({});
this.mutationType({});
this.subscriptionType({});
this.queryType({})
this.mutationType({})
this.subscriptionType({})
this.globalConnectionField('totalCount', (t) =>
t.int({
@@ -127,10 +127,10 @@ export class Builder extends SchemaBuilder<SchemaBuilderOption> {
? parent.totalCount()
: parent.totalCount,
}),
);
)
// test print ManagedServiceWhereUniqueInput
}
}
export type BuilderTypes =
PothosSchemaTypes.ExtendDefaultTypes<SchemaBuilderOption>;
PothosSchemaTypes.ExtendDefaultTypes<SchemaBuilderOption>

View File

@@ -1,4 +1,4 @@
import { Inject, Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common'
import {
type BaseEnum,
@@ -7,14 +7,14 @@ import {
type InputType,
type InputTypeParam,
type SchemaTypes,
} from '@pothos/core';
import { type PrismaModelTypes, getModel } from '@pothos/plugin-prisma';
import type { FilterOps } from '@pothos/plugin-prisma-utils';
import * as Prisma from '@prisma/client';
import { SchemaBuilderToken } from '@smatch-corp/nestjs-pothos';
} from '@pothos/core'
import { type PrismaModelTypes, getModel } from '@pothos/plugin-prisma'
import type { FilterOps } from '@pothos/plugin-prisma-utils'
import * as Prisma from '@prisma/client'
import { SchemaBuilderToken } from '@smatch-corp/nestjs-pothos'
const filterOps = ['equals', 'in', 'notIn', 'not'] as const;
const sortableFilterProps = ['lt', 'lte', 'gt', 'gte'] as const;
const filterOps = ['equals', 'in', 'notIn', 'not'] as const
const sortableFilterProps = ['lt', 'lte', 'gt', 'gte'] as const
const stringFilterOps = [
...filterOps,
'contains',
@@ -22,26 +22,26 @@ const stringFilterOps = [
'endsWith',
'mode',
'search',
] as const;
const sortableTypes = ['String', 'Int', 'Float', 'DateTime', 'BigInt'] as const;
const listOps = ['every', 'some', 'none'] as const;
] as const
const sortableTypes = ['String', 'Int', 'Float', 'DateTime', 'BigInt'] as const
const listOps = ['every', 'some', 'none'] as const
const scalarListOps = [
'has',
'hasSome',
'hasEvery',
'isEmpty',
'equals',
] as const;
const JsonFilterOps = ['equals', 'in', 'notIn', 'not'] as const;
const EnumFilterOps = ['equals', 'not'] as const;
] as const
const JsonFilterOps = ['equals', 'in', 'notIn', 'not'] as const
const EnumFilterOps = ['equals', 'not'] as const
@Injectable()
export class PrismaCrudGenerator<Types extends SchemaTypes> {
private refCache = new Map<
InputType<Types> | string,
Map<string, InputObjectRef<Types, unknown>>
>();
>()
private enumRefs = new Map<string, EnumRef<Types, unknown>>();
private enumRefs = new Map<string, EnumRef<Types, unknown>>()
constructor(
//
@@ -75,7 +75,7 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
type: 'Int',
required: false,
}),
}));
}))
}
findUniqueArgs<Name extends string & keyof Types['PrismaTypes']>(
@@ -86,7 +86,7 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
type: this.getWhereUnique(modelName),
required: true,
}),
}));
}))
}
getWhere<Name extends string & keyof Types['PrismaTypes']>(
@@ -95,19 +95,19 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
) {
const withoutName = (without ?? [])
.map((name) => `Without${capitalize(name)}`)
.join('');
const fullName = `${modelName}${withoutName}Filter`;
.join('')
const fullName = `${modelName}${withoutName}Filter`
return this.getRef(modelName, fullName, () => {
const model = getModel(modelName, this.builder);
const model = getModel(modelName, this.builder)
return this.builder.prismaWhere(modelName, {
name: fullName,
fields: (() => {
const fields: Record<string, InputType<Types>> = {};
const fields: Record<string, InputType<Types>> = {}
const withoutFields = model.fields.filter((field) =>
without?.includes(field.name),
);
)
model.fields
.filter(
@@ -119,7 +119,7 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
),
)
.forEach((field) => {
let type;
let type
switch (field.kind) {
case 'scalar':
type = field.isList
@@ -128,49 +128,49 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
)
: this.getFilter(
this.mapScalarType(field.type) as InputType<Types>,
);
break;
)
break
case 'enum':
type = field.isList
? this.getScalarListFilter(this.getEnum(field.type))
: this.getFilter(this.getEnum(field.type));
break;
: this.getFilter(this.getEnum(field.type))
break
case 'object':
type = field.isList
? this.getListFilter(this.getWhere(field.type as Name))
: this.getWhere(field.type as Name);
break;
: this.getWhere(field.type as Name)
break
case 'unsupported':
break;
break
default:
throw new Error(`Unknown field kind ${field.kind}`);
throw new Error(`Unknown field kind ${field.kind}`)
}
if (!type) {
return;
return
}
fields[field.name] = type;
});
fields[field.name] = type
})
return fields;
return fields
}) as never,
}) as InputObjectRef<
Types,
(PrismaModelTypes & Types['PrismaTypes'][Name])['Where']
>;
});
>
})
}
getWhereUnique<Name extends string & keyof Types['PrismaTypes']>(
modelName: Name,
) {
const name = `${modelName}UniqueFilter`;
const name = `${modelName}UniqueFilter`
return this.getRef(modelName, name, () => {
const model = getModel(modelName, this.builder);
const model = getModel(modelName, this.builder)
return this.builder.prismaWhereUnique(modelName, {
name,
fields: (() => {
const fields: Record<string, InputType<Types>> = {};
const fields: Record<string, InputType<Types>> = {}
model.fields
.filter(
@@ -183,73 +183,73 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
model.primaryKey?.fields.includes(field.name),
)
.forEach((field) => {
let type;
let type
switch (field.kind) {
case 'scalar':
type = this.mapScalarType(field.type) as InputType<Types>;
break;
type = this.mapScalarType(field.type) as InputType<Types>
break
case 'enum':
type = this.getEnum(field.type);
break;
type = this.getEnum(field.type)
break
case 'object':
case 'unsupported':
break;
break
default:
throw new Error(`Unknown field kind ${field.kind}`);
throw new Error(`Unknown field kind ${field.kind}`)
}
if (!type) {
return;
return
}
fields[field.name] = type;
});
fields[field.name] = type
})
return fields;
return fields
}) as never,
}) as InputObjectRef<
Types,
(PrismaModelTypes & Types['PrismaTypes'][Name])['WhereUnique']
>;
});
>
})
}
getOrderBy<Name extends string & keyof Types['PrismaTypes']>(
modelName: Name,
) {
const name = `${modelName}OrderBy`;
const name = `${modelName}OrderBy`
return this.getRef(modelName, name, () => {
const model = getModel(modelName, this.builder);
const model = getModel(modelName, this.builder)
return this.builder.prismaOrderBy(modelName, {
name,
fields: () => {
const fields: Record<string, InputType<Types> | boolean> = {};
const fields: Record<string, InputType<Types> | boolean> = {}
model.fields.forEach((field) => {
let type;
let type
switch (field.kind) {
case 'scalar':
case 'enum':
type = true;
break;
type = true
break
case 'object':
type = this.getOrderBy(field.type as Name);
break;
type = this.getOrderBy(field.type as Name)
break
case 'unsupported':
break;
break
default:
throw new Error(`Unknown field kind ${field.kind}`);
throw new Error(`Unknown field kind ${field.kind}`)
}
if (type) {
fields[field.name] = type;
fields[field.name] = type
}
});
})
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
return fields as {};
return fields as {}
},
});
});
})
})
}
getCreateInput<Name extends string & keyof Types['PrismaTypes']>(
@@ -258,21 +258,21 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
) {
const withoutName = (without ?? [])
.map((name) => `Without${capitalize(name)}`)
.join('');
const fullName = `${modelName}Create${withoutName}Input`;
.join('')
const fullName = `${modelName}Create${withoutName}Input`
return this.getRef(modelName, fullName, () => {
const model = getModel(modelName, this.builder);
const model = getModel(modelName, this.builder)
return this.builder.prismaCreate(modelName, {
name: fullName,
fields: (() => {
const fields: Record<string, InputTypeParam<Types>> = {};
const fields: Record<string, InputTypeParam<Types>> = {}
const withoutFields = model.fields.filter((field) =>
without?.includes(field.name),
);
)
const relationIds = model.fields.flatMap(
(field) => field.relationFromFields ?? [],
);
)
model.fields
.filter(
@@ -284,35 +284,35 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
) && !relationIds.includes(field.name),
)
.forEach((field) => {
let type;
let type
switch (field.kind) {
case 'scalar':
type = this.mapScalarType(field.type) as InputType<Types>;
break;
type = this.mapScalarType(field.type) as InputType<Types>
break
case 'enum':
type = this.getEnum(field.type);
break;
type = this.getEnum(field.type)
break
case 'object':
type = this.getCreateRelationInput(modelName, field.name);
break;
type = this.getCreateRelationInput(modelName, field.name)
break
case 'unsupported':
break;
break
default:
throw new Error(`Unknown field kind ${field.kind}`);
throw new Error(`Unknown field kind ${field.kind}`)
}
if (type) {
fields[field.name] = type;
fields[field.name] = type
}
});
})
return fields;
return fields
}) as never,
}) as InputObjectRef<
Types,
(PrismaModelTypes & Types['PrismaTypes'][Name])['Create']
>;
});
>
})
}
getCreateRelationInput<
@@ -327,30 +327,30 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
`${modelName}${capitalize(relation)}`,
'CreateRelationInput',
() => {
const model = getModel(modelName, this.builder);
const model = getModel(modelName, this.builder)
return this.builder.prismaCreateRelation(modelName, relation, {
fields: () => {
const relationField = model.fields.find(
(field) => field.name === relation,
)!;
const relatedModel = getModel(relationField.type, this.builder);
)!
const relatedModel = getModel(relationField.type, this.builder)
const relatedFieldName = relatedModel.fields.find(
(field) => field.relationName === relationField.relationName,
)!;
)!
return {
create: this.getCreateInput(relationField.type as Name, [
relatedFieldName.name,
]),
connect: this.getWhereUnique(relationField.type as Name),
};
}
},
} as never) as InputObjectRef<
Types,
NonNullable<Model['Create'][Relation & keyof Model['Update']]>
>;
>
},
);
)
}
getCreateManyInput<Name extends string & keyof Types['PrismaTypes']>(
@@ -359,22 +359,22 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
) {
const withoutName = (without ?? [])
.map((name) => `Without${capitalize(name)}`)
.join('');
const fullName = `${modelName}Create${withoutName}Input`;
.join('')
const fullName = `${modelName}Create${withoutName}Input`
return this.getRef(modelName, fullName, () => {
const model = getModel(modelName, this.builder);
const model = getModel(modelName, this.builder)
return this.builder.prismaCreateMany(modelName, {
name: fullName,
fields: (() => {
const fields: Record<string, InputTypeParam<Types>> = {};
const fields: Record<string, InputTypeParam<Types>> = {}
const withoutFields = model.fields.filter((field) =>
without?.includes(field.name),
);
)
const relationIds = model.fields.flatMap(
(field) => field.relationFromFields ?? [],
);
)
model.fields
.filter(
@@ -386,32 +386,32 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
) && !relationIds.includes(field.name),
)
.forEach((field) => {
let type;
let type
switch (field.kind) {
case 'scalar':
type = this.mapScalarType(field.type) as InputType<Types>;
break;
type = this.mapScalarType(field.type) as InputType<Types>
break
case 'enum':
type = this.getEnum(field.type);
break;
type = this.getEnum(field.type)
break
case 'unsupported':
break;
break
default:
throw new Error(`Unknown field kind ${field.kind}`);
throw new Error(`Unknown field kind ${field.kind}`)
}
if (type) {
fields[field.name] = type;
fields[field.name] = type
}
});
})
return fields;
return fields
}) as never,
}) as InputObjectRef<
Types,
(PrismaModelTypes & Types['PrismaTypes'][Name])['Create']
>;
});
>
})
}
getUpdateInput<Name extends string & keyof Types['PrismaTypes']>(
@@ -420,21 +420,21 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
) {
const withoutName = (without ?? [])
.map((name) => `Without${capitalize(name)}`)
.join('');
const fullName = `${modelName}Update${withoutName}Input`;
.join('')
const fullName = `${modelName}Update${withoutName}Input`
return this.getRef(modelName, fullName, () => {
const model = getModel(modelName, this.builder);
const model = getModel(modelName, this.builder)
return this.builder.prismaUpdate(modelName, {
name: fullName,
fields: (() => {
const fields: Record<string, InputTypeParam<Types>> = {};
const fields: Record<string, InputTypeParam<Types>> = {}
const withoutFields = model.fields.filter((field) =>
without?.includes(field.name),
);
)
const relationIds = model.fields.flatMap(
(field) => field.relationFromFields ?? [],
);
)
model.fields
.filter(
@@ -446,35 +446,35 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
) && !relationIds.includes(field.name),
)
.forEach((field) => {
let type;
let type
switch (field.kind) {
case 'scalar':
type = this.mapScalarType(field.type) as InputType<Types>;
break;
type = this.mapScalarType(field.type) as InputType<Types>
break
case 'enum':
type = this.getEnum(field.type);
break;
type = this.getEnum(field.type)
break
case 'object':
type = this.getUpdateRelationInput(modelName, field.name);
break;
type = this.getUpdateRelationInput(modelName, field.name)
break
case 'unsupported':
break;
break
default:
throw new Error(`Unknown field kind ${field.kind}`);
throw new Error(`Unknown field kind ${field.kind}`)
}
if (type) {
fields[field.name] = type;
fields[field.name] = type
}
});
})
return fields;
return fields
}) as never,
}) as InputObjectRef<
Types,
(PrismaModelTypes & Types['PrismaTypes'][Name])['Update']
>;
});
>
})
}
getUpdateRelationInput<
Name extends string & keyof Types['PrismaTypes'],
@@ -488,16 +488,16 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
`${modelName}${capitalize(relation)}`,
'UpdateRelationInput',
() => {
const model = getModel(modelName, this.builder);
const model = getModel(modelName, this.builder)
return this.builder.prismaUpdateRelation(modelName, relation, {
fields: () => {
const relationField = model.fields.find(
(field) => field.name === relation,
)!;
const relatedModel = getModel(relationField.type, this.builder);
)!
const relatedModel = getModel(relationField.type, this.builder)
const relatedFieldName = relatedModel.fields.find(
(field) => field.relationName === relationField.relationName,
)!.name;
)!.name
if (relationField.isList) {
return {
@@ -531,7 +531,7 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
deleteMany: this.getWhere(relationField.type as Name, [
relatedFieldName,
]),
};
}
}
return {
@@ -544,38 +544,38 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
connect: this.getWhereUnique(relationField.type as Name),
disconnect: relationField.isRequired ? undefined : 'Boolean',
delete: relationField.isRequired ? undefined : 'Boolean',
};
}
},
} as never) as InputObjectRef<
Types,
NonNullable<Model['Update'][Relation & keyof Model['Update']]>
>;
>
},
);
)
}
private getFilter(type: InputType<Types>) {
return this.getRef(type, `${String(type)}Filter`, () => {
const ops: FilterOps[] = [...filterOps];
const ops: FilterOps[] = [...filterOps]
if (type === 'String') {
ops.push(...stringFilterOps);
ops.push(...stringFilterOps)
}
if (sortableTypes.includes(type as never)) {
ops.push(...sortableFilterProps);
ops.push(...sortableFilterProps)
}
if (type === 'Json') {
ops.push(...JsonFilterOps);
ops.push(...JsonFilterOps)
}
// type enum
if (type === 'Enum') {
ops.push(...EnumFilterOps);
ops.push(...EnumFilterOps)
}
return this.builder.prismaFilter(type, {
ops,
});
});
})
})
}
private getScalarListFilter(type: InputType<Types>) {
@@ -583,7 +583,7 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
this.builder.prismaScalarListFilter(type, {
ops: scalarListOps,
}),
);
)
}
private getListFilter(type: InputType<Types>) {
@@ -591,7 +591,7 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
this.builder.prismaListFilter(type, {
ops: listOps,
}),
);
)
}
private getEnum(name: string) {
@@ -601,12 +601,12 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
{
name,
},
);
)
this.enumRefs.set(name, enumRef);
this.enumRefs.set(name, enumRef)
}
return this.enumRefs.get(name)!;
return this.enumRefs.get(name)!
}
private mapScalarType(type: string) {
@@ -617,9 +617,9 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
case 'Float':
case 'DateTime':
case 'Json':
return type;
return type
default:
return null;
return null
}
}
@@ -629,24 +629,24 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
create: () => T,
): T {
if (!this.refCache.has(key)) {
this.refCache.set(key, new Map());
this.refCache.set(key, new Map())
}
const cache = this.refCache.get(key)!;
const cache = this.refCache.get(key)!
if (cache.has(name)) {
return cache.get(name)! as T;
return cache.get(name)! as T
}
const ref = new InputObjectRef<Types, unknown>(name);
const ref = new InputObjectRef<Types, unknown>(name)
cache.set(name, ref);
cache.set(name, ref)
this.builder.configStore.associateParamWithRef(ref, create());
this.builder.configStore.associateParamWithRef(ref, create())
return ref as T;
return ref as T
}
}
function capitalize(str: string) {
return str[0].toUpperCase() + str.slice(1);
return str[0].toUpperCase() + str.slice(1)
}

View File

@@ -1,44 +1,44 @@
import { Global, Module } from '@nestjs/common';
import { Global, Module } from '@nestjs/common'
import { AdminNoteModule } from '../AdminNote/adminnote.module';
import { ApolloDriverConfig } from '@nestjs/apollo';
import { AppConfigModule } from '../AppConfig/appconfig.module';
import { Builder } from './graphql.builder';
import { CategoryModule } from '../Category/category.module';
import { CenterMentorModule } from '../CenterMentor/centermentor.module';
import { CenterModule } from '../Center/center.module';
import { ChatroomModule } from '../ChatRoom/chatroom.module';
import { CommonModule } from '../common/common.module';
import { ConfigModule } from '@nestjs/config';
import { GraphQLModule } from '@nestjs/graphql';
import { GraphqlService } from './graphql.service';
import { ManagedServiceModule } from '../ManagedService/managedservice.module';
import { MessageModule } from '../Message/message.module';
import { MilestoneModule } from '../Milestone/milestone.module';
import { OrderModule } from '../Order/order.module';
import { PaymentModule } from '../Payment/payment.module';
import { PothosApolloDriver } from '@smatch-corp/nestjs-pothos-apollo-driver';
import { PothosModule } from '@smatch-corp/nestjs-pothos';
import { PrismaCrudGenerator } from './graphql.generator';
import { PrismaModule } from '../Prisma/prisma.module';
import { PrismaService } from '../Prisma/prisma.service';
import { RedisModule } from 'src/Redis/redis.module';
import { RedisService } from 'src/Redis/redis.service';
import { RefundTicketModule } from '../RefundTicket/refundticket.module';
import { Request } from 'express';
import { ResumeModule } from '../Resume/resume.module';
import { ScheduleModule } from '../Schedule/schedule.module';
import { ServiceAndCategoryModule } from '../ServiceAndCategory/serviceandcategory.module';
import { ServiceFeedbackModule } from '../ServiceFeedback/servicefeedback.module';
import { ServiceMeetingRoomModule } from '../ServiceMeetingRoom/servicemeetingroom.module';
import { ServiceModule } from '../Service/service.module';
import { UploadedFileModule } from '../UploadedFile/uploadedfile.module';
import { UserModule } from '../User/user.module';
import { WorkshopMeetingRoomModule } from '../WorkshopMeetingRoom/workshopmeetingroom.module';
import { WorkshopModule } from '../Workshop/workshop.module';
import { WorkshopOrganizationModule } from '../WorkshopOrganization/workshoporganization.module';
import { WorkshopSubscriptionModule } from '../WorkshopSubscription/workshopsubscription.module';
import { initContextCache } from '@pothos/core';
import { AdminNoteModule } from '../AdminNote/adminnote.module'
import { ApolloDriverConfig } from '@nestjs/apollo'
import { AppConfigModule } from '../AppConfig/appconfig.module'
import { Builder } from './graphql.builder'
import { CategoryModule } from '../Category/category.module'
import { CenterMentorModule } from '../CenterMentor/centermentor.module'
import { CenterModule } from '../Center/center.module'
import { ChatroomModule } from '../ChatRoom/chatroom.module'
import { CommonModule } from '../common/common.module'
import { ConfigModule } from '@nestjs/config'
import { GraphQLModule } from '@nestjs/graphql'
import { GraphqlService } from './graphql.service'
import { ManagedServiceModule } from '../ManagedService/managedservice.module'
import { MessageModule } from '../Message/message.module'
import { MilestoneModule } from '../Milestone/milestone.module'
import { OrderModule } from '../Order/order.module'
import { PaymentModule } from '../Payment/payment.module'
import { PothosApolloDriver } from '@smatch-corp/nestjs-pothos-apollo-driver'
import { PothosModule } from '@smatch-corp/nestjs-pothos'
import { PrismaCrudGenerator } from './graphql.generator'
import { PrismaModule } from '../Prisma/prisma.module'
import { PrismaService } from '../Prisma/prisma.service'
import { RedisModule } from 'src/Redis/redis.module'
import { RedisService } from 'src/Redis/redis.service'
import { RefundTicketModule } from '../RefundTicket/refundticket.module'
import { Request } from 'express'
import { ResumeModule } from '../Resume/resume.module'
import { ScheduleModule } from '../Schedule/schedule.module'
import { ServiceAndCategoryModule } from '../ServiceAndCategory/serviceandcategory.module'
import { ServiceFeedbackModule } from '../ServiceFeedback/servicefeedback.module'
import { ServiceMeetingRoomModule } from '../ServiceMeetingRoom/servicemeetingroom.module'
import { ServiceModule } from '../Service/service.module'
import { UploadedFileModule } from '../UploadedFile/uploadedfile.module'
import { UserModule } from '../User/user.module'
import { WorkshopMeetingRoomModule } from '../WorkshopMeetingRoom/workshopmeetingroom.module'
import { WorkshopModule } from '../Workshop/workshop.module'
import { WorkshopOrganizationModule } from '../WorkshopOrganization/workshoporganization.module'
import { WorkshopSubscriptionModule } from '../WorkshopSubscription/workshopsubscription.module'
import { initContextCache } from '@pothos/core'
@Global()
@Module({

View File

@@ -3,13 +3,13 @@ import {
Injectable,
Logger,
UnauthorizedException,
} from '@nestjs/common';
} from '@nestjs/common'
import { PrismaService } from '../Prisma/prisma.service';
import { Request } from 'express';
import { clerkClient } from '@clerk/express';
import { PrismaService } from '../Prisma/prisma.service'
import { Request } from 'express'
import { clerkClient } from '@clerk/express'
import { RedisService } from '../Redis/redis.service';
import { RedisService } from '../Redis/redis.service'
@Injectable()
export class GraphqlService {
@@ -20,37 +20,37 @@ export class GraphqlService {
async acquireContext(req: Request) {
// get x-session-id from headers
let sessionId: string;
const disableAuth = process.env.DISABLE_AUTH === 'true';
let sessionId: string
const disableAuth = process.env.DISABLE_AUTH === 'true'
try {
sessionId = req.headers['x-session-id'] as string;
sessionId = req.headers['x-session-id'] as string
} catch (error) {
Logger.error('Error acquiring context', error);
Logger.error('Error acquiring context', error)
if (disableAuth) {
return null;
return null
}
throw new UnauthorizedException('Must provide a session ID');
throw new UnauthorizedException('Must provide a session ID')
}
if (disableAuth) {
return null;
return null
}
// redis context cache
const cachedUser = await this.redis.getUser(sessionId);
const cachedUser = await this.redis.getUser(sessionId)
if (cachedUser) {
return cachedUser;
return cachedUser
}
// check if the token is valid
const session = await clerkClient.sessions.getSession(sessionId as string);
const session = await clerkClient.sessions.getSession(sessionId as string)
if (!session) {
throw new UnauthorizedException('Invalid session');
throw new UnauthorizedException('Invalid session')
}
const user = await this.prisma.user.findUnique({
where: { id: session.userId },
});
})
if (!user) {
throw new UnauthorizedException('User not found');
throw new UnauthorizedException('User not found')
}
await this.redis.setUser(sessionId, user, session.expireAt);
return user;
await this.redis.setUser(sessionId, user, session.expireAt)
return user
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,11 @@
import * as path from 'path';
import * as path from 'path'
import { Global, Module } from '@nestjs/common';
import { Global, Module } from '@nestjs/common'
import { MailService } from './mail.service';
import { MailerModule } from '@nestjs-modules/mailer';
import { OpenaiModule } from '../OpenAI/openai.module';
import { PugAdapter } from '@nestjs-modules/mailer/dist/adapters/pug.adapter';
import { MailService } from './mail.service'
import { MailerModule } from '@nestjs-modules/mailer'
import { OpenaiModule } from '../OpenAI/openai.module'
import { PugAdapter } from '@nestjs-modules/mailer/dist/adapters/pug.adapter'
@Global()
@Module({

View File

@@ -1,8 +1,8 @@
import { Injectable, Logger } from '@nestjs/common';
import { Injectable, Logger } from '@nestjs/common'
import { MailerService } from '@nestjs-modules/mailer';
import { OpenaiService } from '../OpenAI/openai.service';
import { User } from '@prisma/client';
import { MailerService } from '@nestjs-modules/mailer'
import { OpenaiService } from '../OpenAI/openai.service'
import { User } from '@prisma/client'
@Injectable()
export class MailService {
@@ -16,16 +16,16 @@ export class MailService {
const mailContent = `
<h1>${subject}</h1>
<p>${text}</p>
`;
`
const result = await this.mailerService.sendMail({
to,
subject,
text: mailContent ?? text,
});
Logger.log(result, 'MailService');
})
Logger.log(result, 'MailService')
} catch (error) {
Logger.error(error, 'MailService');
Logger.error(error, 'MailService')
}
}
@@ -41,10 +41,10 @@ export class MailService {
subject,
template,
context,
});
Logger.log(result, 'MailService');
})
Logger.log(result, 'MailService')
} catch (error) {
Logger.error(error, 'MailService');
Logger.error(error, 'MailService')
}
}
}

View File

@@ -1,5 +1,5 @@
import { Module } from '@nestjs/common';
import { ManagedServiceSchema } from './managedservice.schema';
import { Module } from '@nestjs/common'
import { ManagedServiceSchema } from './managedservice.schema'
@Module({
providers: [ManagedServiceSchema],

View File

@@ -1,12 +1,12 @@
import { Inject, Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common'
import {
Pothos,
PothosRef,
PothosSchema,
SchemaBuilderToken,
} from '@smatch-corp/nestjs-pothos';
import { Builder } from '../Graphql/graphql.builder';
import { PrismaService } from '../Prisma/prisma.service';
} from '@smatch-corp/nestjs-pothos'
import { Builder } from '../Graphql/graphql.builder'
import { PrismaService } from '../Prisma/prisma.service'
@Injectable()
export class ManagedServiceSchema extends PothosSchema {
@@ -14,7 +14,7 @@ export class ManagedServiceSchema extends PothosSchema {
@Inject(SchemaBuilderToken) private readonly builder: Builder,
private readonly prisma: PrismaService,
) {
super();
super()
}
@PothosRef()
@@ -41,7 +41,7 @@ export class ManagedServiceSchema extends PothosSchema {
description: 'The service.',
}),
}),
});
})
}
@Pothos()
@@ -53,7 +53,7 @@ export class ManagedServiceSchema extends PothosSchema {
resolve: async (parent, args, ctx) => {
return this.prisma.managedService.findUnique({
where: args.where,
});
})
},
}),
@@ -67,10 +67,10 @@ export class ManagedServiceSchema extends PothosSchema {
cursor: args.cursor ?? undefined,
take: args.take ?? undefined,
skip: args.skip ?? undefined,
});
})
},
}),
}));
}))
this.builder.mutationFields((t) => ({
createManagedService: t.prismaField({
@@ -87,9 +87,9 @@ export class ManagedServiceSchema extends PothosSchema {
return await this.prisma.managedService.create({
...query,
data: args.input,
});
})
},
}),
}));
}))
}
}

View File

@@ -1,5 +1,5 @@
import { Module } from '@nestjs/common';
import { MessageSchema } from './message.schema';
import { Module } from '@nestjs/common'
import { MessageSchema } from './message.schema'
@Module({
providers: [MessageSchema],

View File

@@ -1,12 +1,12 @@
import { Inject, Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common'
import {
Pothos,
PothosRef,
PothosSchema,
SchemaBuilderToken,
} from '@smatch-corp/nestjs-pothos';
import { Builder } from '../Graphql/graphql.builder';
import { PrismaService } from '../Prisma/prisma.service';
} from '@smatch-corp/nestjs-pothos'
import { Builder } from '../Graphql/graphql.builder'
import { PrismaService } from '../Prisma/prisma.service'
@Injectable()
export class MessageSchema extends PothosSchema {
@@ -14,7 +14,7 @@ export class MessageSchema extends PothosSchema {
@Inject(SchemaBuilderToken) private readonly builder: Builder,
private readonly prisma: PrismaService,
) {
super();
super()
}
@PothosRef()
@@ -47,7 +47,7 @@ export class MessageSchema extends PothosSchema {
description: 'The chat room.',
}),
}),
});
})
}
@Pothos()
@@ -61,7 +61,7 @@ export class MessageSchema extends PothosSchema {
return await this.prisma.message.findUnique({
...query,
where: args.where,
});
})
},
}),
messages: t.prismaField({
@@ -76,7 +76,7 @@ export class MessageSchema extends PothosSchema {
take: args.take ?? undefined,
orderBy: args.orderBy ?? undefined,
where: args.filter ?? undefined,
});
})
},
}),
messagesByChatRoomId: t.prismaField({
@@ -87,10 +87,10 @@ export class MessageSchema extends PothosSchema {
return await this.prisma.message.findMany({
...query,
where: args.filter ?? undefined,
});
})
},
}),
}));
}))
// mutations
this.builder.mutationFields((t) => ({
@@ -108,15 +108,15 @@ export class MessageSchema extends PothosSchema {
const message = await this.prisma.message.create({
...query,
data: args.input,
});
})
if (ctx.isSubscription) {
throw new Error('Not allowed');
throw new Error('Not allowed')
}
ctx.http.pubSub.publish('MESSAGE_SENT', message);
return message;
ctx.http.pubSub.publish('MESSAGE_SENT', message)
return message
},
}),
}));
}))
// subscriptions
/* The code snippet `subscriptions` is currently commented out in the provided TypeScript class. It
@@ -128,23 +128,23 @@ export class MessageSchema extends PothosSchema {
messageSent: t.field({
subscribe: (_, __, ctx) => {
if (!ctx.isSubscription) {
throw new Error('Not allowed');
throw new Error('Not allowed')
}
return {
[Symbol.asyncIterator]: () =>
ctx.websocket.pubSub.asyncIterator('MESSAGE_SENT'),
};
}
},
type: this.message(), // Add the type property
resolve: (payload) =>
payload as {
message: 'Json';
id: string;
senderId: string;
chatRoomId: string;
sentAt: Date;
message: 'Json'
id: string
senderId: string
chatRoomId: string
sentAt: Date
},
}),
}));
}))
}
}

View File

@@ -1,5 +1,5 @@
import { Module } from '@nestjs/common';
import { MilestoneSchema } from './milestone.schema';
import { Module } from '@nestjs/common'
import { MilestoneSchema } from './milestone.schema'
@Module({
providers: [MilestoneSchema],

View File

@@ -1,12 +1,12 @@
import { Inject, Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common'
import {
Pothos,
PothosRef,
PothosSchema,
SchemaBuilderToken,
} from '@smatch-corp/nestjs-pothos';
import { Builder } from '../Graphql/graphql.builder';
import { PrismaService } from '../Prisma/prisma.service';
} from '@smatch-corp/nestjs-pothos'
import { Builder } from '../Graphql/graphql.builder'
import { PrismaService } from '../Prisma/prisma.service'
@Injectable()
export class MilestoneSchema extends PothosSchema {
@@ -14,7 +14,7 @@ export class MilestoneSchema extends PothosSchema {
@Inject(SchemaBuilderToken) private readonly builder: Builder,
private readonly prisma: PrismaService,
) {
super();
super()
}
@PothosRef()
@@ -47,7 +47,7 @@ export class MilestoneSchema extends PothosSchema {
description: 'The date and time the milestone was last updated.',
}),
}),
});
})
}
@Pothos()
@@ -66,7 +66,7 @@ export class MilestoneSchema extends PothosSchema {
cursor: args.cursor ?? undefined,
orderBy: args.orderBy ?? undefined,
where: args.filter ?? undefined,
});
})
},
}),
milestone: t.prismaField({
@@ -77,9 +77,9 @@ export class MilestoneSchema extends PothosSchema {
return await this.prisma.milestone.findUnique({
...query,
where: args.where,
});
})
},
}),
}));
}))
}
}

View File

@@ -1,6 +1,6 @@
import { Module, Global } from '@nestjs/common';
import { MinioService } from './minio.service';
import { NestMinioModule } from 'nestjs-minio';
import { Module, Global } from '@nestjs/common'
import { MinioService } from './minio.service'
import { NestMinioModule } from 'nestjs-minio'
@Global()
@Module({
imports: [

View File

@@ -1,9 +1,9 @@
import { Inject, Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { FileUpload } from 'graphql-upload/processRequest.js';
import { Client } from 'minio';
import { MINIO_CONNECTION } from 'nestjs-minio';
import { v4 as uuidv4 } from 'uuid';
import { Inject, Injectable } from '@nestjs/common'
import { ConfigService } from '@nestjs/config'
import { FileUpload } from 'graphql-upload/processRequest.js'
import { Client } from 'minio'
import { MINIO_CONNECTION } from 'nestjs-minio'
import { v4 as uuidv4 } from 'uuid'
@Injectable()
export class MinioService {
constructor(
@@ -13,10 +13,10 @@ export class MinioService {
async uploadFile(file: FileUpload, category: string) {
// sonar ignore next
const { mimetype, createReadStream, filename: actualFileName } = await file;
const filename = this.fileName();
const Name = `${category}/${filename}`;
const fileBuffer = createReadStream();
const { mimetype, createReadStream, filename: actualFileName } = await file
const filename = this.fileName()
const Name = `${category}/${filename}`
const fileBuffer = createReadStream()
const result = await this.minioClient.putObject(
this.configService.get('BUCKET_NAME') ?? 'epess',
@@ -26,15 +26,15 @@ export class MinioService {
{
'Content-Type': mimetype,
},
);
return { result, filename, mimetype, actualFileName };
)
return { result, filename, mimetype, actualFileName }
}
async getFileUrl(id: string, category: string) {
if (!id) {
return null;
return null
}
let url = null;
let url = null
try {
url = await this.minioClient.presignedUrl(
@@ -42,23 +42,23 @@ export class MinioService {
this.configService.get('BUCKET_NAME') ?? 'epess',
`${category}/${id}`,
60 * 60 * 24 * 7,
);
)
} catch (error) {
console.log(error);
console.log(error)
}
console.log(url);
return url;
console.log(url)
return url
}
async deleteFile(id: string, category: string) {
return await this.minioClient.removeObject(
this.configService.get('BUCKET_NAME') ?? 'epess',
`${category}/${id}`,
);
)
}
fileName() {
// generate a unique file name using uuid
return uuidv4();
return uuidv4()
}
}

View File

@@ -1,13 +1,13 @@
import { ClientOptions, OpenAI } from 'openai';
import { ClientOptions, OpenAI } from 'openai'
import { Module } from '@nestjs/common';
import { OpenaiService } from './openai.service';
import { Module } from '@nestjs/common'
import { OpenaiService } from './openai.service'
const openaiOptions: ClientOptions = {
apiKey: process.env.OPENAI_API_KEY,
baseURL: process.env.OPENAI_BASE_URL,
maxRetries: parseInt(process.env.OPENAI_MAX_RETRIES as string) ?? 3,
};
}
@Module({
imports: [OpenAI],

View File

@@ -1,5 +1,5 @@
import { Injectable } from '@nestjs/common';
import { OpenAI } from 'openai';
import { Injectable } from '@nestjs/common'
import { OpenAI } from 'openai'
@Injectable()
export class OpenaiService {
@@ -12,13 +12,13 @@ export class OpenaiService {
) {
const prompt = `
give me mail content for invitation to a workshop to EPESS and replace {{ mail }} with ${mail}, {{ username }} with ${username} and {{ url }} with ${url}
`;
`
const response = await this.openai.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: prompt }],
});
})
return response.choices[0].message.content;
return response.choices[0].message.content
}
}

View File

@@ -1,5 +1,5 @@
import { Module } from '@nestjs/common';
import { OrderSchema } from './order.schema';
import { Module } from '@nestjs/common'
import { OrderSchema } from './order.schema'
@Module({
providers: [OrderSchema],

View File

@@ -1,20 +1,20 @@
import { Inject, Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common'
import {
Pothos,
PothosRef,
PothosSchema,
SchemaBuilderToken,
} from '@smatch-corp/nestjs-pothos';
import { Builder } from '../Graphql/graphql.builder';
import { PrismaService } from '../Prisma/prisma.service';
import { OrderStatus } from '@prisma/client';
} from '@smatch-corp/nestjs-pothos'
import { Builder } from '../Graphql/graphql.builder'
import { PrismaService } from '../Prisma/prisma.service'
import { OrderStatus } from '@prisma/client'
@Injectable()
export class OrderSchema extends PothosSchema {
constructor(
@Inject(SchemaBuilderToken) private readonly builder: Builder,
private readonly prisma: PrismaService,
) {
super();
super()
}
// Types section
@@ -69,7 +69,7 @@ export class OrderSchema extends PothosSchema {
description: 'The schedule for the order.',
}),
}),
});
})
}
@Pothos()
@@ -88,7 +88,7 @@ export class OrderSchema extends PothosSchema {
skip: args.skip ?? undefined,
orderBy: args.orderBy ?? undefined,
where: args.filter ?? undefined,
});
})
},
}),
order: t.prismaField({
@@ -99,10 +99,10 @@ export class OrderSchema extends PothosSchema {
return await this.prisma.order.findUnique({
...query,
where: args.where,
});
})
},
}),
}));
}))
// mutation section
this.builder.mutationFields((t) => ({
createOrder: t.prismaField({
@@ -129,18 +129,17 @@ export class OrderSchema extends PothosSchema {
const order = await prisma.order.create({
...query,
data: args.data,
});
})
// check if service is valid
if (!args.data.service.connect) {
throw new Error('Service not found');
throw new Error('Service not found')
}
// check if service price is free
if (args.data.service.connect.price === 0) {
return order;
return order
}
// generate payment code by prefix 'EPESS' + 6 hex digits
const paymentCode =
'EPESS' + Math.random().toString(16).slice(2, 8);
const paymentCode = 'EPESS' + Math.random().toString(16).slice(2, 8)
// create payment
await prisma.payment.create({
data: {
@@ -149,9 +148,9 @@ export class OrderSchema extends PothosSchema {
paymentCode: paymentCode,
expiredAt: new Date(Date.now() + 1000 * 60 * 60 * 24),
},
});
return order;
});
})
return order
})
},
}),
deleteOrder: t.prismaField({
@@ -167,7 +166,7 @@ export class OrderSchema extends PothosSchema {
return await this.prisma.order.delete({
...query,
where: args.where,
});
})
},
}),
updateOrder: t.prismaField({
@@ -191,9 +190,9 @@ export class OrderSchema extends PothosSchema {
...query,
data: args.data,
where: args.where,
});
})
},
}),
}));
}))
}
}

View File

@@ -1,5 +1,5 @@
import { Module } from '@nestjs/common';
import { PaymentSchema } from './payment.schema';
import { Module } from '@nestjs/common'
import { PaymentSchema } from './payment.schema'
@Module({
providers: [PaymentSchema],

View File

@@ -1,13 +1,13 @@
import { Inject, Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common'
import {
Pothos,
PothosRef,
PothosSchema,
SchemaBuilderToken,
} from '@smatch-corp/nestjs-pothos';
import { Builder } from '../Graphql/graphql.builder';
import { PrismaService } from '../Prisma/prisma.service';
import { PaymentStatus } from '@prisma/client';
} from '@smatch-corp/nestjs-pothos'
import { Builder } from '../Graphql/graphql.builder'
import { PrismaService } from '../Prisma/prisma.service'
import { PaymentStatus } from '@prisma/client'
@Injectable()
export class PaymentSchema extends PothosSchema {
@@ -15,7 +15,7 @@ export class PaymentSchema extends PothosSchema {
@Inject(SchemaBuilderToken) private readonly builder: Builder,
private readonly prisma: PrismaService,
) {
super();
super()
}
// Types section
@@ -46,7 +46,7 @@ export class PaymentSchema extends PothosSchema {
description: 'The order for the payment.',
}),
}),
});
})
}
// Queries section
@@ -61,7 +61,7 @@ export class PaymentSchema extends PothosSchema {
return await this.prisma.payment.findUnique({
...query,
where: args.where,
});
})
},
}),
payments: t.prismaField({
@@ -77,9 +77,9 @@ export class PaymentSchema extends PothosSchema {
cursor: args.cursor ?? undefined,
take: args.take ?? undefined,
skip: args.skip ?? undefined,
});
})
},
}),
}));
}))
}
}

View File

@@ -7,9 +7,9 @@ import {
Param,
Body,
Headers,
} from '@nestjs/common';
import { PayosService } from './payos.service';
import { ApiTags, ApiOperation } from '@nestjs/swagger';
} from '@nestjs/common'
import { PayosService } from './payos.service'
import { ApiTags, ApiOperation } from '@nestjs/swagger'
@ApiTags('Payos')
@Controller('payos')
@@ -23,13 +23,13 @@ export class PayosController {
@Body() body: any,
@Headers('x-payos-signature') signature: string,
) {
return this.payosService.webhook(body, signature);
return this.payosService.webhook(body, signature)
}
// ping webhook
@Get('webhook')
@ApiOperation({ summary: 'Ping webhook' })
async ping() {
return this.payosService.ping();
return this.payosService.ping()
}
}

View File

@@ -1,6 +1,6 @@
import { Module } from '@nestjs/common';
import { PayosController } from './payos.controller';
import { PayosService } from './payos.service';
import { Module } from '@nestjs/common'
import { PayosController } from './payos.controller'
import { PayosService } from './payos.service'
@Module({
providers: [PayosService],

View File

@@ -1,29 +1,29 @@
import { Injectable, Logger } from '@nestjs/common';
import { Injectable, Logger } from '@nestjs/common'
import { PrismaService } from '../Prisma/prisma.service';
import { PrismaService } from '../Prisma/prisma.service'
@Injectable()
export class PayosService {
constructor(private readonly prisma: PrismaService) {}
async ping() {
return 'pong';
return 'pong'
}
async webhook(body: any, signature: string) {
Logger.log('Webhook received', body);
return body;
Logger.log('Webhook received', body)
return body
}
async createPaymentURL(body: any) {
return body;
return body
}
async cancelPaymentURL(body: any) {
return body;
return body
}
async refundPayment(body: any) {
return body;
return body
}
}

View File

@@ -1,5 +1,5 @@
import { Global, Module } from '@nestjs/common';
import { PrismaService } from './prisma.service';
import { Global, Module } from '@nestjs/common'
import { PrismaService } from './prisma.service'
@Global()
@Module({

View File

@@ -3,13 +3,13 @@ import {
Injectable,
Logger,
OnModuleInit,
} from '@nestjs/common';
} from '@nestjs/common'
import { PrismaClient } from '@prisma/client';
import { PrismaClient } from '@prisma/client'
@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
private readonly logger = new Logger(PrismaService.name);
private readonly logger = new Logger(PrismaService.name)
constructor() {
super({
log: [
@@ -35,44 +35,44 @@ export class PrismaService extends PrismaClient implements OnModuleInit {
maxWait: 30 * 1000,
timeout: 60 * 1000,
},
});
})
}
async onModuleInit() {
this.logger.log('Try to connect database...');
this.logger.log('Try to connect database...')
const maxRetry = parseInt(process.env.PRISMA_MAX_RETRY as string) ?? 3;
const retryDelay = 10000;
const maxRetry = parseInt(process.env.PRISMA_MAX_RETRY as string) ?? 3
const retryDelay = 10000
for (let attempt = 1; attempt <= maxRetry; attempt++) {
try {
await this.$connect();
this.logger.log('Connected.');
return;
await this.$connect()
this.logger.log('Connected.')
return
} catch (error) {
if (attempt < maxRetry) {
this.logger.warn(
`Connection attempt ${attempt} failed. Retrying in ${retryDelay}ms...`,
);
await this.delay(retryDelay);
)
await this.delay(retryDelay)
} else {
this.logger.error(
`Failed to connect to the database after ${maxRetry} attempts.`,
);
throw error;
)
throw error
}
}
}
}
private delay(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
return new Promise((resolve) => setTimeout(resolve, ms))
}
async enableShutdownHooks(app: INestApplication) {
this.$on('beforeExit' as never, async () => {
this.logger.log('Wait for application closing...');
await app.close();
});
this.logger.log('Wait for application closing...')
await app.close()
})
}
}

View File

@@ -1,6 +1,6 @@
import { Global, Module } from '@nestjs/common';
import { Global, Module } from '@nestjs/common'
import { RedisService } from './redis.service';
import { RedisService } from './redis.service'
@Global()
@Module({

View File

@@ -1,41 +1,41 @@
import { Injectable } from '@nestjs/common';
import { Redis } from 'ioredis';
import { User } from '@prisma/client';
import { Injectable } from '@nestjs/common'
import { Redis } from 'ioredis'
import { User } from '@prisma/client'
@Injectable()
export class RedisService {
private readonly redis: Redis;
private readonly redis: Redis
constructor() {
this.redis = new Redis(process.env.REDIS_URL as string);
this.redis = new Redis(process.env.REDIS_URL as string)
}
async get(key: string) {
return await this.redis.get(key);
return await this.redis.get(key)
}
async set(key: string, value: string, expireAt: number) {
return await this.redis.set(key, value, 'EXAT', expireAt);
return await this.redis.set(key, value, 'EXAT', expireAt)
}
async del(key: string) {
return await this.redis.del(key);
return await this.redis.del(key)
}
async close() {
return await this.redis.quit();
return await this.redis.quit()
}
async getUser(sessionId: string) {
const userData = await this.get(sessionId);
const userData = await this.get(sessionId)
if (!userData) {
return null;
return null
}
const retrievedUser: User = JSON.parse(userData);
return retrievedUser;
const retrievedUser: User = JSON.parse(userData)
return retrievedUser
}
async setUser(sessionId: string, user: User, expireAt: number) {
return await this.set(sessionId, JSON.stringify(user), expireAt);
return await this.set(sessionId, JSON.stringify(user), expireAt)
}
}

View File

@@ -1,5 +1,5 @@
import { Module } from '@nestjs/common';
import { RefundTicketSchema } from './refundticket.schema';
import { Module } from '@nestjs/common'
import { RefundTicketSchema } from './refundticket.schema'
@Module({
providers: [RefundTicketSchema],

View File

@@ -1,13 +1,13 @@
import { Inject, Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common'
import {
Pothos,
PothosRef,
PothosSchema,
SchemaBuilderToken,
} from '@smatch-corp/nestjs-pothos';
import { Builder } from '../Graphql/graphql.builder';
import { PrismaService } from '../Prisma/prisma.service';
import { PaymentStatus } from '@prisma/client';
} from '@smatch-corp/nestjs-pothos'
import { Builder } from '../Graphql/graphql.builder'
import { PrismaService } from '../Prisma/prisma.service'
import { PaymentStatus } from '@prisma/client'
@Injectable()
export class RefundTicketSchema extends PothosSchema {
@@ -15,7 +15,7 @@ export class RefundTicketSchema extends PothosSchema {
@Inject(SchemaBuilderToken) private readonly builder: Builder,
private readonly prisma: PrismaService,
) {
super();
super()
}
// Types section
@@ -45,7 +45,7 @@ export class RefundTicketSchema extends PothosSchema {
description: 'The order for the refund ticket.',
}),
}),
});
})
}
// Queries section
@@ -65,9 +65,9 @@ export class RefundTicketSchema extends PothosSchema {
cursor: args.cursor ?? undefined,
take: args.take ?? undefined,
skip: args.skip ?? undefined,
});
})
},
}),
}));
}))
}
}

View File

@@ -1,14 +1,6 @@
import {
Controller,
Get,
Post,
Put,
Delete,
Param,
Body,
} from '@nestjs/common';
import { RestfulService } from './restful.service';
import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger';
import { Controller, Get, Post, Put, Delete, Param, Body } from '@nestjs/common'
import { RestfulService } from './restful.service'
import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger'
@ApiTags('Restful')
@Controller('restful')
@@ -19,7 +11,7 @@ export class RestfulController {
@ApiOperation({ summary: 'Get all items' })
@ApiResponse({ status: 200, description: 'Returns all items.' })
getAllItems() {
return this.restfulService.getAllItems();
return this.restfulService.getAllItems()
}
// @Get(':id')
@@ -63,4 +55,4 @@ export class RestfulController {
// }
}
export default RestfulController;
export default RestfulController

View File

@@ -1,8 +1,8 @@
import { Module } from '@nestjs/common';
import { RestfulController } from './restful.controller';
import { RestfulService } from './restful.service';
import { ClerkModule } from '../Clerk/clerk.module';
import { PayosModule } from '../Payos/payos.module';
import { Module } from '@nestjs/common'
import { RestfulController } from './restful.controller'
import { RestfulService } from './restful.service'
import { ClerkModule } from '../Clerk/clerk.module'
import { PayosModule } from '../Payos/payos.module'
@Module({
imports: [ClerkModule, PayosModule],

View File

@@ -1,8 +1,8 @@
import { Injectable } from '@nestjs/common';
import { Injectable } from '@nestjs/common'
@Injectable()
export class RestfulService {
getAllItems() {
return 'Hello World';
return 'Hello World'
}
}

View File

@@ -1,5 +1,5 @@
import { Module } from '@nestjs/common';
import { ResumeSchema } from './resume.schema';
import { Module } from '@nestjs/common'
import { ResumeSchema } from './resume.schema'
@Module({
providers: [ResumeSchema],

View File

@@ -1,14 +1,14 @@
import { Inject, Injectable, Logger } from '@nestjs/common';
import { Inject, Injectable, Logger } from '@nestjs/common'
import {
Pothos,
PothosRef,
PothosSchema,
SchemaBuilderToken,
} from '@smatch-corp/nestjs-pothos';
import { Builder } from '../Graphql/graphql.builder';
import { PrismaService } from '../Prisma/prisma.service';
import { MinioService } from '../Minio/minio.service';
import { ResumeStatus } from '@prisma/client';
} from '@smatch-corp/nestjs-pothos'
import { Builder } from '../Graphql/graphql.builder'
import { PrismaService } from '../Prisma/prisma.service'
import { MinioService } from '../Minio/minio.service'
import { ResumeStatus } from '@prisma/client'
@Injectable()
export class ResumeSchema extends PothosSchema {
constructor(
@@ -16,7 +16,7 @@ export class ResumeSchema extends PothosSchema {
private readonly prisma: PrismaService,
private readonly minioService: MinioService,
) {
super();
super()
}
@PothosRef()
@@ -55,7 +55,7 @@ export class ResumeSchema extends PothosSchema {
description: 'The resume file for the resume.',
}),
}),
});
})
}
@PothosRef()
@@ -92,7 +92,7 @@ export class ResumeSchema extends PothosSchema {
description: 'The resume for the resume file.',
}),
}),
});
})
}
@Pothos()
init(): void {
@@ -109,7 +109,7 @@ export class ResumeSchema extends PothosSchema {
resolve: async (query, root, args, ctx, info) => {
try {
if (ctx.isSubscription) {
throw new Error('Not allowed');
throw new Error('Not allowed')
}
const resumes = await this.prisma.resume.findMany({
...query,
@@ -117,11 +117,11 @@ export class ResumeSchema extends PothosSchema {
userId: ctx.http.me.id,
status: args.status ?? undefined,
},
});
return resumes;
})
return resumes
} catch (error) {
Logger.error(error, 'myResumes');
return [];
Logger.error(error, 'myResumes')
return []
}
},
}),
@@ -137,7 +137,7 @@ export class ResumeSchema extends PothosSchema {
take: args.take ?? undefined,
orderBy: args.orderBy ?? undefined,
where: args.filter ?? undefined,
});
})
},
}),
@@ -149,8 +149,8 @@ export class ResumeSchema extends PothosSchema {
const resume = await this.prisma.resume.findUnique({
...query,
where: args.where,
});
return resume;
})
return resume
},
}),
@@ -162,11 +162,11 @@ export class ResumeSchema extends PothosSchema {
const resumeFile = await this.prisma.resumeFile.findUnique({
...query,
where: args.where,
});
})
if (!resumeFile) {
return null;
return null
}
return resumeFile;
return resumeFile
},
}),
resumeFiles: t.prismaField({
@@ -181,11 +181,11 @@ export class ResumeSchema extends PothosSchema {
take: args.take ?? undefined,
orderBy: args.orderBy ?? undefined,
where: args.filter ?? undefined,
});
return resumeFiles;
})
return resumeFiles
},
}),
}));
}))
// Mutations section
this.builder.mutationFields((t) => ({
@@ -207,15 +207,15 @@ export class ResumeSchema extends PothosSchema {
}),
},
resolve: async (query, root, args) => {
const { resumeFile } = args;
const { mimetype } = await resumeFile;
const { resumeFile } = args
const { mimetype } = await resumeFile
const { filename, actualFileName } =
await this.minioService.uploadFile(resumeFile, 'resumes');
await this.minioService.uploadFile(resumeFile, 'resumes')
const fileUrl = await this.minioService.getFileUrl(
filename,
'resumes',
);
const { userId, centerId } = args;
)
const { userId, centerId } = args
const resume = await this.prisma.resume.upsert({
...query,
where: {
@@ -245,8 +245,8 @@ export class ResumeSchema extends PothosSchema {
},
status: ResumeStatus.REQUESTED,
},
});
return resume;
})
return resume
},
}),
@@ -264,13 +264,13 @@ export class ResumeSchema extends PothosSchema {
}),
},
resolve: async (query, root, args) => {
const { resumeId, status } = args;
const { resumeId, status } = args
const resume = await this.prisma.resume.update({
...query,
where: { id: resumeId },
data: { status },
});
return resume;
})
return resume
},
}),
@@ -284,14 +284,14 @@ export class ResumeSchema extends PothosSchema {
}),
},
resolve: async (query, root, args) => {
const { resumeFileId } = args;
const { resumeFileId } = args
const resumeFile = await this.prisma.resumeFile.delete({
...query,
where: { id: resumeFileId },
});
return resumeFile;
})
return resumeFile
},
}),
}));
}))
}
}

View File

@@ -1,5 +1,5 @@
import { Module } from '@nestjs/common';
import { ScheduleSchema } from './schedule.schema';
import { Module } from '@nestjs/common'
import { ScheduleSchema } from './schedule.schema'
@Module({
providers: [ScheduleSchema],

View File

@@ -1,13 +1,13 @@
import { Inject, Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common'
import {
Pothos,
PothosRef,
PothosSchema,
SchemaBuilderToken,
} from '@smatch-corp/nestjs-pothos';
import { Builder } from '../Graphql/graphql.builder';
import { PrismaService } from '../Prisma/prisma.service';
import { ScheduleStatus } from '@prisma/client';
} from '@smatch-corp/nestjs-pothos'
import { Builder } from '../Graphql/graphql.builder'
import { PrismaService } from '../Prisma/prisma.service'
import { ScheduleStatus } from '@prisma/client'
@Injectable()
export class ScheduleSchema extends PothosSchema {
@@ -15,7 +15,7 @@ export class ScheduleSchema extends PothosSchema {
@Inject(SchemaBuilderToken) private readonly builder: Builder,
private readonly prisma: PrismaService,
) {
super();
super()
}
@PothosRef()
@@ -50,7 +50,7 @@ export class ScheduleSchema extends PothosSchema {
nullable: false,
}),
}),
});
})
}
@PothosRef()
@@ -76,7 +76,7 @@ export class ScheduleSchema extends PothosSchema {
description: 'The schedule the schedule date belongs to.',
}),
}),
});
})
}
@Pothos()
@@ -90,7 +90,7 @@ export class ScheduleSchema extends PothosSchema {
return await this.prisma.schedule.findUnique({
...query,
where: args.where,
});
})
},
}),
@@ -106,9 +106,9 @@ export class ScheduleSchema extends PothosSchema {
take: args.take ?? undefined,
orderBy: args.orderBy ?? undefined,
where: args.filter ?? undefined,
});
})
},
}),
}));
}))
}
}

View File

@@ -1,8 +1,8 @@
import * as DateTimeUtils from '../common/utils/datetime.utils';
import * as DateTimeUtils from '../common/utils/datetime.utils'
import { Injectable } from '@nestjs/common';
import { PrismaService } from 'src/Prisma/prisma.service';
import { Schedule } from '@prisma/client';
import { Injectable } from '@nestjs/common'
import { PrismaService } from 'src/Prisma/prisma.service'
import { Schedule } from '@prisma/client'
@Injectable()
export class ScheduleService {

View File

@@ -1,5 +1,5 @@
import { Module } from '@nestjs/common';
import { ServiceSchema } from './service.schema';
import { Module } from '@nestjs/common'
import { ServiceSchema } from './service.schema'
@Module({
providers: [ServiceSchema],

View File

@@ -1,15 +1,15 @@
import { Inject, Injectable, Logger } from '@nestjs/common';
import { Inject, Injectable, Logger } from '@nestjs/common'
import {
Pothos,
PothosRef,
PothosSchema,
SchemaBuilderToken,
} from '@smatch-corp/nestjs-pothos';
import { Builder } from '../Graphql/graphql.builder';
import { PrismaService } from '../Prisma/prisma.service';
import { MinioService } from '../Minio/minio.service';
import { ServiceStatus } from '@prisma/client';
import { MailService } from '../Mail/mail.service';
} from '@smatch-corp/nestjs-pothos'
import { Builder } from '../Graphql/graphql.builder'
import { PrismaService } from '../Prisma/prisma.service'
import { MinioService } from '../Minio/minio.service'
import { ServiceStatus } from '@prisma/client'
import { MailService } from '../Mail/mail.service'
@Injectable()
export class ServiceSchema extends PothosSchema {
constructor(
@@ -18,7 +18,7 @@ export class ServiceSchema extends PothosSchema {
private readonly minioService: MinioService,
private readonly mailService: MailService,
) {
super();
super()
}
@PothosRef()
@@ -107,7 +107,7 @@ export class ServiceSchema extends PothosSchema {
description: 'The managed service for the service.',
}),
}),
});
})
}
@Pothos()
@@ -122,12 +122,12 @@ export class ServiceSchema extends PothosSchema {
resolve: async (query, root, args, ctx, info) => {
return await this.prisma.service.findMany({
...query,
});
})
},
totalCount: (query) => {
return this.prisma.service.count({
...query,
});
})
},
},
{},
@@ -146,7 +146,7 @@ export class ServiceSchema extends PothosSchema {
skip: args.skip ?? undefined,
take: args.take ?? undefined,
cursor: args.cursor ?? undefined,
});
})
},
}),
service: t.prismaField({
@@ -165,10 +165,10 @@ export class ServiceSchema extends PothosSchema {
include: {
feedbacks: true,
},
});
})
},
}),
}));
}))
// Mutation section
this.builder.mutationFields((t) => ({
@@ -185,7 +185,7 @@ export class ServiceSchema extends PothosSchema {
return await this.prisma.service.create({
...query,
data: args.input,
});
})
},
}),
updateService: t.prismaField({
@@ -206,7 +206,7 @@ export class ServiceSchema extends PothosSchema {
...query,
where: args.where,
data: args.input,
});
})
},
}),
deleteService: t.prismaField({
@@ -222,7 +222,7 @@ export class ServiceSchema extends PothosSchema {
return await this.prisma.service.delete({
...query,
where: args.where,
});
})
},
}),
approveOrRejectService: t.prismaField({
@@ -244,18 +244,18 @@ export class ServiceSchema extends PothosSchema {
},
resolve: async (query, root, args, ctx, info) => {
if (ctx.isSubscription) {
throw new Error('Not allowed');
throw new Error('Not allowed')
}
return await this.prisma.$transaction(async (prisma) => {
// check if service is already approved or rejected
const service = await prisma.service.findUnique({
where: { id: args.serviceId },
});
})
if (!service) {
throw new Error('Service not found');
throw new Error('Service not found')
}
if (service.status !== ServiceStatus.PENDING) {
throw new Error('Service is already approved or rejected');
throw new Error('Service is already approved or rejected')
}
// update service status
const updatedService = await prisma.service.update({
@@ -272,33 +272,33 @@ export class ServiceSchema extends PothosSchema {
},
},
},
});
})
// mail to all mentor or center owner for the center
const center = await prisma.center.findUnique({
where: { id: service.centerId },
});
})
if (!center?.centerOwnerId) {
throw new Error('Center owner not found');
throw new Error('Center owner not found')
}
const centerOwner = await prisma.user.findUnique({
where: { id: center.centerOwnerId },
});
})
if (!centerOwner) {
throw new Error('Center owner not found');
throw new Error('Center owner not found')
}
const centerMentor = await prisma.centerMentor.findMany({
where: { centerId: service.centerId },
});
const mentorIds = centerMentor.map((mentor) => mentor.mentorId);
})
const mentorIds = centerMentor.map((mentor) => mentor.mentorId)
// get mentor emails
const mentorEmails = await prisma.user.findMany({
where: { id: { in: mentorIds } },
});
Logger.log(mentorEmails, 'ServiceSchema');
})
Logger.log(mentorEmails, 'ServiceSchema')
const emails = [
centerOwner.email,
...mentorEmails.map((mentor) => mentor.email),
];
]
if (args.approve) {
await this.mailService.sendTemplateEmail(
emails,
@@ -308,7 +308,7 @@ export class ServiceSchema extends PothosSchema {
SERVICE_NAME: service.name,
CENTER_NAME: center.name,
},
);
)
} else {
await this.mailService.sendTemplateEmail(
emails,
@@ -319,12 +319,12 @@ export class ServiceSchema extends PothosSchema {
CENTER_NAME: center.name,
ADMIN_NOTE: args.adminNote ?? 'Không có lý do',
},
);
)
}
return updatedService;
});
return updatedService
})
},
}),
}));
}))
}
}

View File

@@ -1,5 +1,5 @@
import { Module } from '@nestjs/common';
import { ServiceAndCategorySchema } from './serviceandcategory.schema';
import { Module } from '@nestjs/common'
import { ServiceAndCategorySchema } from './serviceandcategory.schema'
@Module({
providers: [ServiceAndCategorySchema],

View File

@@ -1,12 +1,12 @@
import { Inject, Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common'
import {
Pothos,
PothosRef,
PothosSchema,
SchemaBuilderToken,
} from '@smatch-corp/nestjs-pothos';
import { Builder } from '../Graphql/graphql.builder';
import { PrismaService } from '../Prisma/prisma.service';
} from '@smatch-corp/nestjs-pothos'
import { Builder } from '../Graphql/graphql.builder'
import { PrismaService } from '../Prisma/prisma.service'
@Injectable()
export class ServiceAndCategorySchema extends PothosSchema {
@@ -14,7 +14,7 @@ export class ServiceAndCategorySchema extends PothosSchema {
@Inject(SchemaBuilderToken) private readonly builder: Builder,
private readonly prisma: PrismaService,
) {
super();
super()
}
@PothosRef()
@@ -35,7 +35,7 @@ export class ServiceAndCategorySchema extends PothosSchema {
description: 'The ID of the sub category.',
}),
}),
});
})
}
@Pothos()
@@ -53,9 +53,9 @@ export class ServiceAndCategorySchema extends PothosSchema {
take: args.take ?? undefined,
orderBy: args.orderBy ?? undefined,
where: args.filter ?? undefined,
});
})
},
}),
}));
}))
}
}

View File

@@ -1,5 +1,5 @@
import { Module } from '@nestjs/common';
import { ServiceFeedbackSchema } from './servicefeedback.schema';
import { Module } from '@nestjs/common'
import { ServiceFeedbackSchema } from './servicefeedback.schema'
@Module({
providers: [ServiceFeedbackSchema],

View File

@@ -1,12 +1,12 @@
import { Inject, Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common'
import {
Pothos,
PothosRef,
PothosSchema,
SchemaBuilderToken,
} from '@smatch-corp/nestjs-pothos';
import { Builder } from '../Graphql/graphql.builder';
import { PrismaService } from '../Prisma/prisma.service';
} from '@smatch-corp/nestjs-pothos'
import { Builder } from '../Graphql/graphql.builder'
import { PrismaService } from '../Prisma/prisma.service'
@Injectable()
export class ServiceFeedbackSchema extends PothosSchema {
@@ -14,7 +14,7 @@ export class ServiceFeedbackSchema extends PothosSchema {
@Inject(SchemaBuilderToken) private readonly builder: Builder,
private readonly prisma: PrismaService,
) {
super();
super()
}
@PothosRef()
@@ -54,7 +54,7 @@ export class ServiceFeedbackSchema extends PothosSchema {
description: 'The service that was provided.',
}),
}),
});
})
}
@Pothos()
@@ -72,9 +72,9 @@ export class ServiceFeedbackSchema extends PothosSchema {
take: args.take ?? undefined,
orderBy: args.orderBy ?? undefined,
where: args.filter ?? undefined,
});
})
},
}),
}));
}))
}
}

View File

@@ -1,5 +1,5 @@
import { Module } from '@nestjs/common';
import { ServiceMeetingRoomSchema } from './servicemeetingroom.schema';
import { Module } from '@nestjs/common'
import { ServiceMeetingRoomSchema } from './servicemeetingroom.schema'
@Module({
providers: [ServiceMeetingRoomSchema],

View File

@@ -1,12 +1,12 @@
import { Inject, Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common'
import {
Pothos,
PothosRef,
PothosSchema,
SchemaBuilderToken,
} from '@smatch-corp/nestjs-pothos';
import { Builder } from '../Graphql/graphql.builder';
import { PrismaService } from '../Prisma/prisma.service';
} from '@smatch-corp/nestjs-pothos'
import { Builder } from '../Graphql/graphql.builder'
import { PrismaService } from '../Prisma/prisma.service'
@Injectable()
export class ServiceMeetingRoomSchema extends PothosSchema {
@@ -14,7 +14,7 @@ export class ServiceMeetingRoomSchema extends PothosSchema {
@Inject(SchemaBuilderToken) private readonly builder: Builder,
private readonly prisma: PrismaService,
) {
super();
super()
}
@PothosRef()
@@ -32,7 +32,7 @@ export class ServiceMeetingRoomSchema extends PothosSchema {
description: 'The chatting room.',
}),
}),
});
})
}
@Pothos()
@@ -47,7 +47,7 @@ export class ServiceMeetingRoomSchema extends PothosSchema {
return await this.prisma.serviceMeetingRoom.findUnique({
...query,
where: args.where,
});
})
},
}),
serviceMeetingRooms: t.prismaField({
@@ -62,9 +62,9 @@ export class ServiceMeetingRoomSchema extends PothosSchema {
take: args.take ?? undefined,
orderBy: args.orderBy ?? undefined,
where: args.filter ?? undefined,
});
})
},
}),
}));
}))
}
}

View File

@@ -1,6 +1,6 @@
import { Module, Global } from '@nestjs/common';
import { UploadedFileSchema } from './uploadedfile.schema';
import { MinioModule } from '../Minio/minio.module';
import { Module, Global } from '@nestjs/common'
import { UploadedFileSchema } from './uploadedfile.schema'
import { MinioModule } from '../Minio/minio.module'
@Global()
@Module({
imports: [MinioModule],

View File

@@ -1,14 +1,14 @@
import { Inject, Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common'
import {
Pothos,
PothosRef,
PothosSchema,
SchemaBuilderToken,
} from '@smatch-corp/nestjs-pothos';
import { Builder } from '../Graphql/graphql.builder';
import { PrismaService } from '../Prisma/prisma.service';
import { MinioService } from 'src/Minio/minio.service';
import { UploadedFileType } from '@prisma/client';
} from '@smatch-corp/nestjs-pothos'
import { Builder } from '../Graphql/graphql.builder'
import { PrismaService } from '../Prisma/prisma.service'
import { MinioService } from 'src/Minio/minio.service'
import { UploadedFileType } from '@prisma/client'
@Injectable()
export class UploadedFileSchema extends PothosSchema {
constructor(
@@ -16,7 +16,7 @@ export class UploadedFileSchema extends PothosSchema {
private readonly prisma: PrismaService,
private readonly minioService: MinioService,
) {
super();
super()
}
@PothosRef()
@@ -62,7 +62,7 @@ export class UploadedFileSchema extends PothosSchema {
description: 'The workshop that the file belongs to.',
}),
}),
});
})
}
@Pothos()
@@ -77,16 +77,16 @@ export class UploadedFileSchema extends PothosSchema {
const file = await this.prisma.uploadedFile.findUnique({
...query,
where: args.where,
});
})
if (!file) {
throw new Error('File not found');
throw new Error('File not found')
}
const fileUrl = await this.minioService.getFileUrl(file.id, 'files');
const fileUrl = await this.minioService.getFileUrl(file.id, 'files')
if (!fileUrl) {
throw new Error('Cannot retrieve file url');
throw new Error('Cannot retrieve file url')
}
file.fileUrl = fileUrl;
return file;
file.fileUrl = fileUrl
return file
},
}),
uploadedFiles: t.prismaField({
@@ -101,17 +101,17 @@ export class UploadedFileSchema extends PothosSchema {
take: args.take ?? undefined,
orderBy: args.orderBy ?? undefined,
where: args.filter ?? undefined,
});
})
const fileUrls = await Promise.all(
files.map((file) => this.minioService.getFileUrl(file.id, 'files')),
);
)
return files.map((file, index) => ({
...file,
fileUrl: fileUrls[index] ?? '',
}));
}))
},
}),
}));
}))
// Mutations section
this.builder.mutationFields((t) => ({
@@ -137,18 +137,18 @@ export class UploadedFileSchema extends PothosSchema {
where: {
id: args.userId,
},
});
})
if (!user) {
throw new Error('User not found');
throw new Error('User not found')
}
const { filename, mimetype, actualFileName } =
await this.minioService.uploadFile(args.file, 'files');
await this.minioService.uploadFile(args.file, 'files')
if (!mimetype) {
throw new Error('File type not supported');
throw new Error('File type not supported')
}
const fileUrl = await this.minioService.getFileUrl(filename, 'files');
const fileUrl = await this.minioService.getFileUrl(filename, 'files')
if (!fileUrl) {
throw new Error('Cannot retrieve file url, please try again later');
throw new Error('Cannot retrieve file url, please try again later')
}
const uploadedFile = await this.prisma.uploadedFile.create({
data: {
@@ -160,8 +160,8 @@ export class UploadedFileSchema extends PothosSchema {
fileUrl: fileUrl ?? '',
uploadedAt: new Date(),
},
});
return uploadedFile;
})
return uploadedFile
},
}),
@@ -187,21 +187,21 @@ export class UploadedFileSchema extends PothosSchema {
where: {
id: args.userId,
},
});
})
if (!user) {
throw new Error('User not found');
throw new Error('User not found')
}
const uploadedFiles = await Promise.all(
args.files.map((file) =>
this.minioService.uploadFile(file, 'files'),
),
);
)
// get file urls
const fileUrls = await Promise.all(
uploadedFiles.map((file) =>
this.minioService.getFileUrl(file.filename, 'files'),
),
);
)
// map uploadedFiles to db
const dbFiles = uploadedFiles.map((file, index) => ({
userId: user.id,
@@ -211,13 +211,13 @@ export class UploadedFileSchema extends PothosSchema {
actualFileName: file.actualFileName,
fileUrl: fileUrls[index] ?? '',
uploadedAt: new Date(),
}));
}))
// create files in db
const createdFiles =
await this.prisma.uploadedFile.createManyAndReturn({
data: dbFiles,
});
return createdFiles;
})
return createdFiles
},
}),
@@ -235,17 +235,17 @@ export class UploadedFileSchema extends PothosSchema {
where: {
id: args.id,
},
});
})
if (!file) {
throw new Error('File not found');
throw new Error('File not found')
}
await this.minioService.deleteFile(file.fileName, 'files');
await this.minioService.deleteFile(file.fileName, 'files')
await this.prisma.uploadedFile.delete({
where: {
id: file.id,
},
});
return file;
})
return file
},
}),
@@ -266,22 +266,22 @@ export class UploadedFileSchema extends PothosSchema {
in: args.ids,
},
},
});
})
await this.prisma.uploadedFile.deleteMany({
where: {
id: {
in: args.ids,
},
},
});
})
await Promise.all(
files.map((file) =>
this.minioService.deleteFile(file.fileName, 'files'),
),
);
return files;
)
return files
},
}),
}));
}))
}
}

View File

@@ -1,5 +1,5 @@
import { Module } from '@nestjs/common';
import { UserSchema } from './user.schema';
import { Module } from '@nestjs/common'
import { UserSchema } from './user.schema'
@Module({
providers: [UserSchema],
exports: [UserSchema],

View File

@@ -1,15 +1,15 @@
import { Inject, Injectable, Logger } from '@nestjs/common';
import { Inject, Injectable, Logger } from '@nestjs/common'
import {
Pothos,
PothosRef,
PothosSchema,
SchemaBuilderToken,
} from '@smatch-corp/nestjs-pothos';
import { Builder } from '../Graphql/graphql.builder';
import { PrismaService } from '../Prisma/prisma.service';
import { clerkClient } from '@clerk/express';
import { UnauthorizedException } from '@nestjs/common';
import { MailService } from '../Mail/mail.service';
} from '@smatch-corp/nestjs-pothos'
import { Builder } from '../Graphql/graphql.builder'
import { PrismaService } from '../Prisma/prisma.service'
import { clerkClient } from '@clerk/express'
import { UnauthorizedException } from '@nestjs/common'
import { MailService } from '../Mail/mail.service'
@Injectable()
export class UserSchema extends PothosSchema {
constructor(
@@ -17,7 +17,7 @@ export class UserSchema extends PothosSchema {
private readonly prisma: PrismaService,
private readonly mailService: MailService,
) {
super();
super()
}
// Types section
@@ -99,7 +99,7 @@ export class UserSchema extends PothosSchema {
description: 'The admin note of the user.',
}),
}),
});
})
}
// Query section
@@ -112,8 +112,8 @@ export class UserSchema extends PothosSchema {
sessionId: t.arg({ type: 'String', required: true }),
},
resolve: async (_, { sessionId }) => {
const session = await clerkClient.sessions.getSession(sessionId);
return JSON.parse(JSON.stringify(session));
const session = await clerkClient.sessions.getSession(sessionId)
return JSON.parse(JSON.stringify(session))
},
}),
newSession: t.field({
@@ -128,8 +128,8 @@ export class UserSchema extends PothosSchema {
const session = await clerkClient.signInTokens.createSignInToken({
userId,
expiresInSeconds: 60 * 60 * 24,
});
return session.id;
})
return session.id
},
}),
me: t.prismaField({
@@ -137,9 +137,9 @@ export class UserSchema extends PothosSchema {
type: this.user(),
resolve: async (query, root, args, ctx) => {
if (ctx.isSubscription) {
throw new Error('Not allowed');
throw new Error('Not allowed')
}
return ctx.http.me;
return ctx.http.me
},
}),
@@ -155,7 +155,7 @@ export class UserSchema extends PothosSchema {
skip: args.skip ?? undefined,
orderBy: args.orderBy ?? undefined,
where: args.filter ?? undefined,
});
})
},
}),
@@ -167,7 +167,7 @@ export class UserSchema extends PothosSchema {
return await this.prisma.user.findUniqueOrThrow({
...query,
where: args.where,
});
})
},
}),
userBySession: t.prismaField({
@@ -178,17 +178,17 @@ export class UserSchema extends PothosSchema {
},
resolve: async (query, root, args) => {
// check if the token is valid
const session = await clerkClient.sessions.getSession(args.sessionId);
Logger.log(session, 'Session');
const session = await clerkClient.sessions.getSession(args.sessionId)
Logger.log(session, 'Session')
return await this.prisma.user.findFirstOrThrow({
...query,
where: {
id: session.userId,
},
});
})
},
}),
}));
}))
// Mutation section
this.builder.mutationFields((t) => ({
@@ -210,7 +210,7 @@ export class UserSchema extends PothosSchema {
...query,
where: args.where,
data: args.input,
});
})
},
}),
@@ -228,10 +228,10 @@ export class UserSchema extends PothosSchema {
center_name: 'băng đĩa lậu hải ngoại',
invite_url: 'https://epess.org',
},
);
return 'Email sent';
)
return 'Email sent'
},
}),
}));
}))
}
}

View File

@@ -1,5 +1,5 @@
import { Global, Module } from '@nestjs/common';
import { WorkshopSchema } from './workshop.schema';
import { Global, Module } from '@nestjs/common'
import { WorkshopSchema } from './workshop.schema'
@Global()
@Module({

View File

@@ -1,13 +1,13 @@
import { Inject, Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common'
import {
Pothos,
PothosRef,
PothosSchema,
SchemaBuilderToken,
} from '@smatch-corp/nestjs-pothos';
import { Builder } from '../Graphql/graphql.builder';
import { PrismaService } from '../Prisma/prisma.service';
import { MinioService } from 'src/Minio/minio.service';
} from '@smatch-corp/nestjs-pothos'
import { Builder } from '../Graphql/graphql.builder'
import { PrismaService } from '../Prisma/prisma.service'
import { MinioService } from 'src/Minio/minio.service'
@Injectable()
export class WorkshopSchema extends PothosSchema {
@@ -16,7 +16,7 @@ export class WorkshopSchema extends PothosSchema {
private readonly prisma: PrismaService,
private readonly minioService: MinioService,
) {
super();
super()
}
@PothosRef()
@@ -80,7 +80,7 @@ export class WorkshopSchema extends PothosSchema {
description: 'The meeting room that the workshop is for.',
}),
}),
});
})
}
@Pothos()
@@ -94,7 +94,7 @@ export class WorkshopSchema extends PothosSchema {
return await this.prisma.workshop.findUnique({
...query,
where: args.where,
});
})
},
}),
@@ -110,10 +110,10 @@ export class WorkshopSchema extends PothosSchema {
take: args.take ?? undefined,
orderBy: args.orderBy ?? undefined,
where: args.filter ?? undefined,
});
})
},
}),
}));
}))
// Mutations section
this.builder.mutationFields((t) => ({
@@ -130,7 +130,7 @@ export class WorkshopSchema extends PothosSchema {
return await this.prisma.workshop.create({
...query,
data: args.input,
});
})
},
}),
@@ -152,9 +152,9 @@ export class WorkshopSchema extends PothosSchema {
...query,
where: args.where,
data: args.input,
});
})
},
}),
}));
}))
}
}

View File

@@ -1,5 +1,5 @@
import { Module, Global } from '@nestjs/common';
import { WorkshopMeetingRoomSchema } from './workshopmeetingroom.schema';
import { Module, Global } from '@nestjs/common'
import { WorkshopMeetingRoomSchema } from './workshopmeetingroom.schema'
@Global()
@Module({

View File

@@ -1,12 +1,12 @@
import { Inject, Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common'
import {
Pothos,
PothosRef,
PothosSchema,
SchemaBuilderToken,
} from '@smatch-corp/nestjs-pothos';
import { Builder } from '../Graphql/graphql.builder';
import { PrismaService } from '../Prisma/prisma.service';
} from '@smatch-corp/nestjs-pothos'
import { Builder } from '../Graphql/graphql.builder'
import { PrismaService } from '../Prisma/prisma.service'
@Injectable()
export class WorkshopMeetingRoomSchema extends PothosSchema {
@@ -14,7 +14,7 @@ export class WorkshopMeetingRoomSchema extends PothosSchema {
@Inject(SchemaBuilderToken) private readonly builder: Builder,
private readonly prisma: PrismaService,
) {
super();
super()
}
@PothosRef()
@@ -31,7 +31,7 @@ export class WorkshopMeetingRoomSchema extends PothosSchema {
description: 'The workshop that the meeting room is for.',
}),
}),
});
})
}
@Pothos()
@@ -44,7 +44,7 @@ export class WorkshopMeetingRoomSchema extends PothosSchema {
return await this.prisma.workshopMeetingRoom.findUnique({
...query,
where: args.where,
});
})
},
}),
workshopMeetingRooms: t.prismaField({
@@ -58,9 +58,9 @@ export class WorkshopMeetingRoomSchema extends PothosSchema {
cursor: args.cursor ?? undefined,
take: args.take ?? undefined,
skip: args.skip ?? undefined,
});
})
},
}),
}));
}))
}
}

View File

@@ -1,5 +1,5 @@
import { Module } from '@nestjs/common';
import { WorkshopOrganizationSchema } from './workshoporganization.schema';
import { Module } from '@nestjs/common'
import { WorkshopOrganizationSchema } from './workshoporganization.schema'
@Module({
providers: [WorkshopOrganizationSchema],

View File

@@ -1,12 +1,12 @@
import { Inject, Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common'
import {
Pothos,
PothosRef,
PothosSchema,
SchemaBuilderToken,
} from '@smatch-corp/nestjs-pothos';
import { Builder } from '../Graphql/graphql.builder';
import { PrismaService } from '../Prisma/prisma.service';
} from '@smatch-corp/nestjs-pothos'
import { Builder } from '../Graphql/graphql.builder'
import { PrismaService } from '../Prisma/prisma.service'
@Injectable()
export class WorkshopOrganizationSchema extends PothosSchema {
@@ -14,7 +14,7 @@ export class WorkshopOrganizationSchema extends PothosSchema {
@Inject(SchemaBuilderToken) private readonly builder: Builder,
private readonly prisma: PrismaService,
) {
super();
super()
}
@PothosRef()
workshopOrganization() {
@@ -38,6 +38,6 @@ export class WorkshopOrganizationSchema extends PothosSchema {
'The date and time the workshop organization was created.',
}),
}),
});
})
}
}

View File

@@ -1,5 +1,5 @@
import { Module } from '@nestjs/common';
import { WorkshopSubscriptionSchema } from './workshopsubscription.schema';
import { Module } from '@nestjs/common'
import { WorkshopSubscriptionSchema } from './workshopsubscription.schema'
@Module({
providers: [WorkshopSubscriptionSchema],

View File

@@ -1,12 +1,12 @@
import { Inject, Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common'
import {
Pothos,
PothosRef,
PothosSchema,
SchemaBuilderToken,
} from '@smatch-corp/nestjs-pothos';
import { Builder } from '../Graphql/graphql.builder';
import { PrismaService } from '../Prisma/prisma.service';
} from '@smatch-corp/nestjs-pothos'
import { Builder } from '../Graphql/graphql.builder'
import { PrismaService } from '../Prisma/prisma.service'
@Injectable()
export class WorkshopSubscriptionSchema extends PothosSchema {
@@ -14,7 +14,7 @@ export class WorkshopSubscriptionSchema extends PothosSchema {
@Inject(SchemaBuilderToken) private readonly builder: Builder,
private readonly prisma: PrismaService,
) {
super();
super()
}
@PothosRef()
workshopSubscription() {
@@ -39,7 +39,7 @@ export class WorkshopSubscriptionSchema extends PothosSchema {
'The date and time the workshop subscription was created.',
}),
}),
});
})
}
@Pothos()
@@ -54,7 +54,7 @@ export class WorkshopSubscriptionSchema extends PothosSchema {
return await this.prisma.workshopSubscription.findUnique({
...query,
where: args.where,
});
})
},
}),
workshopSubscriptions: t.prismaField({
@@ -69,9 +69,9 @@ export class WorkshopSubscriptionSchema extends PothosSchema {
take: args.take ?? undefined,
orderBy: args.orderBy ?? undefined,
where: args.filter ?? undefined,
});
})
},
}),
}));
}))
}
}

View File

@@ -1,9 +1,9 @@
import { ClerkModule } from './Clerk/clerk.module';
import { ConfigModule } from '@nestjs/config';
import { GraphqlModule } from './Graphql/graphql.module';
import { MailModule } from './Mail/mail.module';
import { Module } from '@nestjs/common';
import { RestfulModule } from './Restful/restful.module';
import { ClerkModule } from './Clerk/clerk.module'
import { ConfigModule } from '@nestjs/config'
import { GraphqlModule } from './Graphql/graphql.module'
import { MailModule } from './Mail/mail.module'
import { Module } from '@nestjs/common'
import { RestfulModule } from './Restful/restful.module'
@Module({
imports: [

View File

@@ -1,7 +1,7 @@
import { Global, Module } from '@nestjs/common';
import { Global, Module } from '@nestjs/common'
import { CommonGraphqlError } from './graphql/common.graphql.error';
import { JwtUtils } from './utils/jwt.utils';
import { CommonGraphqlError } from './graphql/common.graphql.error'
import { JwtUtils } from './utils/jwt.utils'
@Global()
@Module({
imports: [],

View File

@@ -1,15 +1,15 @@
import { Inject, Injectable } from '@nestjs/common';
import { Builder } from '../../Graphql/graphql.builder';
import { Inject, Injectable } from '@nestjs/common'
import { Builder } from '../../Graphql/graphql.builder'
import {
PothosRef,
PothosSchema,
SchemaBuilderToken,
} from '@smatch-corp/nestjs-pothos';
} from '@smatch-corp/nestjs-pothos'
@Injectable()
export class CommonGraphqlError extends PothosSchema {
constructor(@Inject(SchemaBuilderToken) private readonly builder: Builder) {
super();
super()
}
@PothosRef()
@@ -19,6 +19,6 @@ export class CommonGraphqlError extends PothosSchema {
fields: (t) => ({
message: t.exposeString('message'),
}),
});
})
}
}

View File

@@ -1,29 +1,29 @@
import { sign, verify } from 'jsonwebtoken';
import { sign, verify } from 'jsonwebtoken'
import { Injectable } from '@nestjs/common';
import { Injectable } from '@nestjs/common'
@Injectable()
export class JwtUtils {
signToken(payload: string, expiresIn: string) {
return sign(payload, process.env.JWT_SECRET!, { expiresIn });
return sign(payload, process.env.JWT_SECRET!, { expiresIn })
}
//eslint-disable-next-line @typescript-eslint/no-explicit-any
signTokenRS256(payload: any, expiresIn: string) {
const privateKey = process.env.JWT_RS256_PRIVATE_KEY!;
const privateKey = process.env.JWT_RS256_PRIVATE_KEY!
return sign(payload, privateKey, {
algorithm: 'RS256',
expiresIn,
});
})
}
verifyTokenRS256(token: string) {
const publicKey = process.env.JWT_RS256_PUBLIC_KEY!;
const publicKey = process.env.JWT_RS256_PUBLIC_KEY!
return verify(token, publicKey, {
algorithms: ['RS256'],
});
})
}
verifyToken(token: string) {
return verify(token, process.env.JWT_SECRET!);
return verify(token, process.env.JWT_SECRET!)
}
}

View File

@@ -1,39 +1,39 @@
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'
import { AppModule } from './app.module';
import { Logger } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { clerkMiddleware } from '@clerk/express';
import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.js';
import path from 'node:path';
import { readFileSync } from 'node:fs';
import { AppModule } from './app.module'
import { Logger } from '@nestjs/common'
import { NestFactory } from '@nestjs/core'
import { clerkMiddleware } from '@clerk/express'
import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.js'
import path from 'node:path'
import { readFileSync } from 'node:fs'
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const app = await NestFactory.create(AppModule)
// load private key and public key
const privateKey = readFileSync(
path.join(__dirname, 'KeyStore', 'private_key.pem'),
'utf8',
);
)
const publicKey = readFileSync(
path.join(__dirname, 'KeyStore', 'public_key.pem'),
'utf8',
);
)
// set private key and public key to env
process.env.JWT_RS256_PRIVATE_KEY = privateKey;
process.env.JWT_RS256_PUBLIC_KEY = publicKey;
process.env.JWT_RS256_PRIVATE_KEY = privateKey
process.env.JWT_RS256_PUBLIC_KEY = publicKey
Logger.log(
`Private key: ${privateKey.slice(0, 10).replace(/\n/g, '')}...`,
'Bootstrap',
);
)
Logger.log(
`Public key: ${publicKey.slice(0, 10).replace(/\n/g, '')}...`,
'Bootstrap',
);
)
const corsOrigin = (process.env.CORS_ORIGIN ?? '').split(','); // split by comma to array
const corsOrigin = (process.env.CORS_ORIGIN ?? '').split(',') // split by comma to array
app.enableCors({
origin: corsOrigin,
methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],
@@ -44,20 +44,20 @@ async function bootstrap() {
'x-session-id',
],
credentials: true,
});
})
// set base path for api
app.setGlobalPrefix(process.env.API_PATH ?? '/v1');
app.setGlobalPrefix(process.env.API_PATH ?? '/v1')
const config = new DocumentBuilder()
.setTitle('EPESS API')
.setDescription('API documentation for EPESS application')
.setVersion('0.0.1')
.addBearerAuth()
.build();
.build()
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup(process.env.SWAGGER_PATH ?? 'v1', app, document);
const document = SwaggerModule.createDocument(app, config)
SwaggerModule.setup(process.env.SWAGGER_PATH ?? 'v1', app, document)
document.paths[process.env.API_PATH + '/graphql'] = {
get: {
@@ -71,10 +71,10 @@ async function bootstrap() {
},
},
},
};
}
// clerk middleware
app.use(clerkMiddleware({}));
app.use(clerkMiddleware({}))
// graphql upload
app.use(
@@ -82,11 +82,11 @@ async function bootstrap() {
maxFileSize: 100 * 1024 * 1024, // 100 MB
maxFiles: 10,
}),
);
const host = process.env.LISTEN_HOST ?? '0.0.0.0';
const port = process.env.LISTEN_PORT ?? 3000; // Default to 3000 if LISTEN_PORT is not set
)
const host = process.env.LISTEN_HOST ?? '0.0.0.0'
const port = process.env.LISTEN_PORT ?? 3000 // Default to 3000 if LISTEN_PORT is not set
await app.listen(port, host, () => {
Logger.log(`Server is running on http://${host}:${port}`, 'Bootstrap');
});
Logger.log(`Server is running on http://${host}:${port}`, 'Bootstrap')
})
}
bootstrap();
bootstrap()

File diff suppressed because one or more lines are too long

View File

@@ -1,24 +1,24 @@
import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import * as request from 'supertest';
import { AppModule } from './../src/app.module';
import { Test, TestingModule } from '@nestjs/testing'
import { INestApplication } from '@nestjs/common'
import * as request from 'supertest'
import { AppModule } from './../src/app.module'
describe('AppController (e2e)', () => {
let app: INestApplication;
let app: INestApplication
beforeEach(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();
}).compile()
app = moduleFixture.createNestApplication();
await app.init();
});
app = moduleFixture.createNestApplication()
await app.init()
})
it('/ (GET)', () => {
return request(app.getHttpServer())
.get('/')
.expect(200)
.expect('Hello World!');
});
});
.expect('Hello World!')
})
})