ba me oi con thanh cong roi
This commit is contained in:
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -1,3 +1,4 @@
|
|||||||
{
|
{
|
||||||
"dependi.npm.lockFileEnabled": false
|
"dependi.npm.lockFileEnabled": false,
|
||||||
|
"typescript.tsdk": "node_modules\\typescript\\lib"
|
||||||
}
|
}
|
||||||
@@ -40,7 +40,7 @@ export default [
|
|||||||
|
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
project: 'tsconfig.json',
|
project: 'tsconfig.json',
|
||||||
tsconfigRootDir: 'C:\\Users\\AliensVN\\EPESS\\epess-web-backend',
|
tsconfigRootDir: __dirname,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ export default [
|
|||||||
'@typescript-eslint/interface-name-prefix': 'off',
|
'@typescript-eslint/interface-name-prefix': 'off',
|
||||||
'@typescript-eslint/explicit-function-return-type': 'off',
|
'@typescript-eslint/explicit-function-return-type': 'off',
|
||||||
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||||
'@typescript-eslint/no-explicit-any': 'on',
|
'@typescript-eslint/no-explicit-any': 'error',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
88
package-lock.json
generated
88
package-lock.json
generated
@@ -39,7 +39,10 @@
|
|||||||
"epess-web-backend": "file:",
|
"epess-web-backend": "file:",
|
||||||
"graphql": "^16.9.0",
|
"graphql": "^16.9.0",
|
||||||
"graphql-scalars": "^1.23.0",
|
"graphql-scalars": "^1.23.0",
|
||||||
|
"graphql-subscriptions": "^2.0.0",
|
||||||
"graphql-tools": "^9.0.1",
|
"graphql-tools": "^9.0.1",
|
||||||
|
"graphql-upload": "15.0.2",
|
||||||
|
"graphql-ws": "^5.16.0",
|
||||||
"jsonwebtoken": "^9.0.2",
|
"jsonwebtoken": "^9.0.2",
|
||||||
"minio": "^8.0.1",
|
"minio": "^8.0.1",
|
||||||
"nestjs-minio": "^2.6.2",
|
"nestjs-minio": "^2.6.2",
|
||||||
@@ -5179,6 +5182,15 @@
|
|||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/busboy": {
|
||||||
|
"version": "1.5.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/busboy/-/busboy-1.5.4.tgz",
|
||||||
|
"integrity": "sha512-kG7WrUuAKK0NoyxfQHsVE6j1m01s6kMma64E+OZenQABMQyTJop1DumUWcLwAQ2JzpefU7PDYoRDKl8uZosFjw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/connect": {
|
"node_modules/@types/connect": {
|
||||||
"version": "3.4.38",
|
"version": "3.4.38",
|
||||||
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
|
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
|
||||||
@@ -5347,6 +5359,12 @@
|
|||||||
"form-data": "^4.0.0"
|
"form-data": "^4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/object-path": {
|
||||||
|
"version": "0.11.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/object-path/-/object-path-0.11.4.tgz",
|
||||||
|
"integrity": "sha512-4tgJ1Z3elF/tOMpA8JLVuR9spt9Ynsf7+JjqsQ2IqtiPJtcLoHoXcT6qU4E10cPFqyXX5HDm9QwIzZhBSkLxsw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@types/passport": {
|
"node_modules/@types/passport": {
|
||||||
"version": "1.0.16",
|
"version": "1.0.16",
|
||||||
"resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.16.tgz",
|
"resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.16.tgz",
|
||||||
@@ -9164,6 +9182,15 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fs-capacitor": {
|
||||||
|
"version": "6.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs-capacitor/-/fs-capacitor-6.2.0.tgz",
|
||||||
|
"integrity": "sha512-nKcE1UduoSKX27NSZlg879LdQc94OtbOsEmKMN2MBNudXREvijRKx2GEBsTMTfws+BrbkJoEuynbGSVRSpauvw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fs-extra": {
|
"node_modules/fs-extra": {
|
||||||
"version": "10.1.0",
|
"version": "10.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||||
@@ -9515,6 +9542,18 @@
|
|||||||
"integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==",
|
"integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==",
|
||||||
"license": "0BSD"
|
"license": "0BSD"
|
||||||
},
|
},
|
||||||
|
"node_modules/graphql-subscriptions": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/graphql-subscriptions/-/graphql-subscriptions-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-s6k2b8mmt9gF9pEfkxsaO1lTxaySfKoEJzEfmwguBbQ//Oq23hIXCfR1hm4kdh5hnR20RdwB+s3BCb+0duHSZA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"iterall": "^1.3.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"graphql": "^15.7.2 || ^16.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/graphql-tag": {
|
"node_modules/graphql-tag": {
|
||||||
"version": "2.12.6",
|
"version": "2.12.6",
|
||||||
"resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz",
|
"resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz",
|
||||||
@@ -9583,6 +9622,40 @@
|
|||||||
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
|
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/graphql-upload": {
|
||||||
|
"version": "15.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/graphql-upload/-/graphql-upload-15.0.2.tgz",
|
||||||
|
"integrity": "sha512-ufJAkZJBKWRDD/4wJR3VZMy9QWTwqIYIciPtCEF5fCNgWF+V1p7uIgz+bP2YYLiS4OJBhCKR8rnqE/Wg3XPUiw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/busboy": "^1.5.0",
|
||||||
|
"@types/node": "*",
|
||||||
|
"@types/object-path": "^0.11.1",
|
||||||
|
"busboy": "^1.6.0",
|
||||||
|
"fs-capacitor": "^6.2.0",
|
||||||
|
"http-errors": "^2.0.0",
|
||||||
|
"object-path": "^0.11.8"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^14.17.0 || ^16.0.0 || >= 18.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/jaydenseric"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/express": "^4.0.29",
|
||||||
|
"@types/koa": "^2.11.4",
|
||||||
|
"graphql": "^16.3.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/express": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@types/koa": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/graphql-ws": {
|
"node_modules/graphql-ws": {
|
||||||
"version": "5.16.0",
|
"version": "5.16.0",
|
||||||
"resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-5.16.0.tgz",
|
"resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-5.16.0.tgz",
|
||||||
@@ -11986,6 +12059,15 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/object-path": {
|
||||||
|
"version": "0.11.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.8.tgz",
|
||||||
|
"integrity": "sha512-YJjNZrlXJFM42wTBn6zgOJVar9KFJvzx6sTWDte8sWZF//cnjl0BxHNpfZx+ZffXX63A9q0b1zsFiBX4g4X5KA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.12.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/on-finished": {
|
"node_modules/on-finished": {
|
||||||
"version": "2.4.1",
|
"version": "2.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
|
||||||
@@ -15069,9 +15151,9 @@
|
|||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/yaml": {
|
"node_modules/yaml": {
|
||||||
"version": "2.5.1",
|
"version": "2.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.0.tgz",
|
||||||
"integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==",
|
"integrity": "sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
"start:prod": "node dist/main",
|
"start:prod": "node dist/main",
|
||||||
"prisma:generate": "npx prisma generate --schema=./epess-database/prisma/schema.prisma",
|
"prisma:generate": "npx prisma generate --schema=./epess-database/prisma/schema.prisma",
|
||||||
"prisma:migrate": "npx prisma migrate dev --schema=./epess-database/prisma/schema.prisma",
|
"prisma:migrate": "npx prisma migrate dev --schema=./epess-database/prisma/schema.prisma",
|
||||||
|
"prisma:push": "npx prisma db push --schema=./epess-database/prisma/schema.prisma",
|
||||||
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
|
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"test:watch": "jest --watch",
|
"test:watch": "jest --watch",
|
||||||
@@ -53,7 +54,10 @@
|
|||||||
"epess-web-backend": "file:",
|
"epess-web-backend": "file:",
|
||||||
"graphql": "^16.9.0",
|
"graphql": "^16.9.0",
|
||||||
"graphql-scalars": "^1.23.0",
|
"graphql-scalars": "^1.23.0",
|
||||||
|
"graphql-subscriptions": "^2.0.0",
|
||||||
"graphql-tools": "^9.0.1",
|
"graphql-tools": "^9.0.1",
|
||||||
|
"graphql-upload": "15.0.2",
|
||||||
|
"graphql-ws": "^5.16.0",
|
||||||
"jsonwebtoken": "^9.0.2",
|
"jsonwebtoken": "^9.0.2",
|
||||||
"minio": "^8.0.1",
|
"minio": "^8.0.1",
|
||||||
"nestjs-minio": "^2.6.2",
|
"nestjs-minio": "^2.6.2",
|
||||||
|
|||||||
@@ -9,12 +9,15 @@ import type PrismaTypes from '../types/pothos.generated';
|
|||||||
import { getDatamodel } from '../types/pothos.generated';
|
import { getDatamodel } from '../types/pothos.generated';
|
||||||
import { DateTimeResolver, JSONObjectResolver } from 'graphql-scalars';
|
import { DateTimeResolver, JSONObjectResolver } from 'graphql-scalars';
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import GraphQLUpload from 'graphql-upload/GraphQLUpload.js';
|
||||||
|
import type { FileUpload } from 'graphql-upload/processRequest.js';
|
||||||
import { PrismaCrudGenerator } from './graphql.generator';
|
import { PrismaCrudGenerator } from './graphql.generator';
|
||||||
|
import { PubSub } from 'graphql-subscriptions';
|
||||||
export interface SchemaContext {
|
export interface SchemaContext {
|
||||||
req: Request;
|
req: Request;
|
||||||
res: Response;
|
res: Response;
|
||||||
generator: PrismaCrudGenerator<BuilderTypes>;
|
generator: PrismaCrudGenerator<BuilderTypes>;
|
||||||
|
pubSub: PubSub;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SchemaBuilderOption {
|
export interface SchemaBuilderOption {
|
||||||
@@ -30,6 +33,10 @@ export interface SchemaBuilderOption {
|
|||||||
Input: JSON;
|
Input: JSON;
|
||||||
Output: JSON;
|
Output: JSON;
|
||||||
};
|
};
|
||||||
|
Upload: {
|
||||||
|
Input: FileUpload;
|
||||||
|
Output: FileUpload;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,6 +58,7 @@ export class Builder extends SchemaBuilder<SchemaBuilderOption> {
|
|||||||
this.generator = new PrismaCrudGenerator<BuilderTypes>(this);
|
this.generator = new PrismaCrudGenerator<BuilderTypes>(this);
|
||||||
this.addScalarType('DateTime', DateTimeResolver);
|
this.addScalarType('DateTime', DateTimeResolver);
|
||||||
this.addScalarType('Json', JSONObjectResolver);
|
this.addScalarType('Json', JSONObjectResolver);
|
||||||
|
this.addScalarType('Upload', GraphQLUpload);
|
||||||
|
|
||||||
this.queryType({});
|
this.queryType({});
|
||||||
this.mutationType({});
|
this.mutationType({});
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import type { FilterOps } from '@pothos/plugin-prisma-utils';
|
|||||||
import * as Prisma from '@prisma/client';
|
import * as Prisma from '@prisma/client';
|
||||||
import { SchemaBuilderToken } from '@smatch-corp/nestjs-pothos';
|
import { SchemaBuilderToken } from '@smatch-corp/nestjs-pothos';
|
||||||
|
|
||||||
//
|
|
||||||
const filterOps = ['equals', 'in', 'notIn', 'not', 'is'] as const;
|
const filterOps = ['equals', 'in', 'notIn', 'not', 'is'] as const;
|
||||||
const sortableFilterProps = ['lt', 'lte', 'gt', 'gte'] as const;
|
const sortableFilterProps = ['lt', 'lte', 'gt', 'gte'] as const;
|
||||||
const stringFilterOps = [
|
const stringFilterOps = [
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import { MilestoneModule } from '../Milestone/milestone.module';
|
|||||||
import { ScheduleModule } from '../Schedule/schedule.module';
|
import { ScheduleModule } from '../Schedule/schedule.module';
|
||||||
import { MessageModule } from '../Message/message.module';
|
import { MessageModule } from '../Message/message.module';
|
||||||
import { ServiceMeetingRoomModule } from '../ServiceMeetingRoom/servicemeetingroom.module';
|
import { ServiceMeetingRoomModule } from '../ServiceMeetingRoom/servicemeetingroom.module';
|
||||||
import { UploadedDocumentModule } from '../UploadedDocument/uploadeddocument.module';
|
import { UploadedFileModule } from '../UploadedFile/uploadedfile.module';
|
||||||
@Global()
|
@Global()
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -53,7 +53,7 @@ import { UploadedDocumentModule } from '../UploadedDocument/uploadeddocument.mod
|
|||||||
ScheduleModule,
|
ScheduleModule,
|
||||||
MessageModule,
|
MessageModule,
|
||||||
ServiceMeetingRoomModule,
|
ServiceMeetingRoomModule,
|
||||||
UploadedDocumentModule,
|
UploadedFileModule,
|
||||||
PothosModule.forRoot({
|
PothosModule.forRoot({
|
||||||
builder: {
|
builder: {
|
||||||
inject: [PrismaService],
|
inject: [PrismaService],
|
||||||
@@ -65,6 +65,10 @@ import { UploadedDocumentModule } from '../UploadedDocument/uploadeddocument.mod
|
|||||||
path: process.env.API_PATH + '/graphql',
|
path: process.env.API_PATH + '/graphql',
|
||||||
playground: true,
|
playground: true,
|
||||||
introspection: true,
|
introspection: true,
|
||||||
|
installSubscriptionHandlers: true,
|
||||||
|
subscriptions: {
|
||||||
|
'graphql-ws': true,
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
|
|||||||
@@ -59,5 +59,17 @@ export class MessageSchema extends PothosSchema {
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
// mutations
|
||||||
|
|
||||||
|
// subscriptions
|
||||||
|
// this.builder.subscriptionFields((t) => ({
|
||||||
|
// messageSent: t.field({
|
||||||
|
// subscribe: (_parent, _args, ctx) => {
|
||||||
|
// return ctx.pubSub.asyncIterator('MESSAGE_SENT');
|
||||||
|
// },
|
||||||
|
// resolve: (payload) => payload as any,
|
||||||
|
// }),
|
||||||
|
// }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,20 @@
|
|||||||
import { Module, Global } from '@nestjs/common';
|
import { Module, Global } from '@nestjs/common';
|
||||||
|
import { MinioService } from './minio.service';
|
||||||
|
import { NestMinioModule } from 'nestjs-minio';
|
||||||
|
import { ConfigModule } from '@nestjs/config';
|
||||||
@Global()
|
@Global()
|
||||||
@Module({})
|
@Module({
|
||||||
|
imports: [
|
||||||
|
ConfigModule.forRoot(),
|
||||||
|
NestMinioModule.register({
|
||||||
|
endPoint: process.env.MINIO_ENDPOINT ?? '10.0.27.1',
|
||||||
|
accessKey: process.env.MINIO_ACCESS_KEY ?? 'minioadmin',
|
||||||
|
secretKey: process.env.MINIO_SECRET_KEY ?? 'minioadmin',
|
||||||
|
useSSL: false,
|
||||||
|
port: 9000,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
providers: [MinioService],
|
||||||
|
exports: [MinioService],
|
||||||
|
})
|
||||||
export class MinioModule {}
|
export class MinioModule {}
|
||||||
|
|||||||
@@ -1,9 +1,45 @@
|
|||||||
// import { Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
// import { NestMinioService } from 'nestjs-minio';
|
import { ConfigService } from '@nestjs/config';
|
||||||
// import { ConfigService } from '@nestjs/config';
|
import { FileUpload } from 'graphql-upload/processRequest.js';
|
||||||
// @Injectable()
|
import { Client } from 'Minio';
|
||||||
// export class MinioService extends NestMinioService {
|
import { MINIO_CONNECTION } from 'nestjs-minio';
|
||||||
// constructor(configService: ConfigService) {
|
@Injectable()
|
||||||
// super(configService);
|
export class MinioService {
|
||||||
// }
|
constructor(
|
||||||
// }
|
private readonly configService: ConfigService,
|
||||||
|
@Inject(MINIO_CONNECTION) private readonly minioClient: Client,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async uploadFile(file: FileUpload, category: string) {
|
||||||
|
const { filename, mimetype, createReadStream, encoding } = await file;
|
||||||
|
const Name = `${category}/${filename}`;
|
||||||
|
const fileBuffer = createReadStream();
|
||||||
|
|
||||||
|
const result = await this.minioClient.putObject(
|
||||||
|
this.configService.get('BUCKET_NAME') ?? 'epess',
|
||||||
|
Name,
|
||||||
|
fileBuffer,
|
||||||
|
undefined,
|
||||||
|
{
|
||||||
|
'Content-Type': mimetype,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return { result, filename, mimetype };
|
||||||
|
}
|
||||||
|
|
||||||
|
async getFileUrl(fileName: string, category: string) {
|
||||||
|
return await this.minioClient.presignedUrl(
|
||||||
|
'GET',
|
||||||
|
this.configService.get('BUCKET_NAME') ?? 'epess',
|
||||||
|
`${category}/${fileName}`,
|
||||||
|
3600,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteFile(fileName: string) {
|
||||||
|
return await this.minioClient.removeObject(
|
||||||
|
this.configService.get('BUCKET_NAME') ?? 'epess',
|
||||||
|
fileName,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ export class ServiceAndCategorySchema extends PothosSchema {
|
|||||||
return this.builder.prismaObject('ServiceAndCategory', {
|
return this.builder.prismaObject('ServiceAndCategory', {
|
||||||
fields: (t) => ({
|
fields: (t) => ({
|
||||||
serviceId: t.exposeID('serviceId'),
|
serviceId: t.exposeID('serviceId'),
|
||||||
categoryId: t.exposeID('categoryId'),
|
|
||||||
service: t.relation('service'),
|
service: t.relation('service'),
|
||||||
subCategory: t.relation('SubCategory'),
|
subCategory: t.relation('SubCategory'),
|
||||||
subCategoryId: t.exposeID('subCategoryId'),
|
subCategoryId: t.exposeID('subCategoryId'),
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
import { Module, Global } from '@nestjs/common';
|
|
||||||
import { UploadedDocumentSchema } from './uploadeddocument.schema';
|
|
||||||
|
|
||||||
@Global()
|
|
||||||
@Module({
|
|
||||||
providers: [UploadedDocumentSchema],
|
|
||||||
exports: [UploadedDocumentSchema],
|
|
||||||
})
|
|
||||||
export class UploadedDocumentModule {}
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
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';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class UploadedDocumentSchema extends PothosSchema {
|
|
||||||
constructor(
|
|
||||||
@Inject(SchemaBuilderToken) private readonly builder: Builder,
|
|
||||||
private readonly prisma: PrismaService,
|
|
||||||
) {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
@PothosRef()
|
|
||||||
uploadedDocument() {
|
|
||||||
return this.builder.prismaObject('UploadedDocument', {
|
|
||||||
fields: (t) => ({
|
|
||||||
id: t.exposeID('id'),
|
|
||||||
userId: t.exposeID('userId'),
|
|
||||||
documentName: t.exposeString('documentName'),
|
|
||||||
documentType: t.exposeString('documentType'),
|
|
||||||
status: t.exposeString('status'),
|
|
||||||
type: t.exposeString('type'),
|
|
||||||
documentUrl: t.exposeString('documentUrl'),
|
|
||||||
uploadedAt: t.expose('uploadedAt', { type: 'DateTime' }),
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Pothos()
|
|
||||||
init(): void {
|
|
||||||
this.builder.queryFields((t) => ({
|
|
||||||
uploadedDocument: t.prismaField({
|
|
||||||
type: this.uploadedDocument(),
|
|
||||||
args: this.builder.generator.findUniqueArgs('UploadedDocument'),
|
|
||||||
resolve: async (query, root, args, ctx, info) => {
|
|
||||||
return await this.prisma.uploadedDocument.findUnique({
|
|
||||||
...query,
|
|
||||||
where: args.where,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
uploadedDocuments: t.prismaField({
|
|
||||||
type: [this.uploadedDocument()],
|
|
||||||
args: this.builder.generator.findManyArgs('UploadedDocument'),
|
|
||||||
resolve: async (query, root, args, ctx, info) => {
|
|
||||||
return await this.prisma.uploadedDocument.findMany({
|
|
||||||
...query,
|
|
||||||
skip: args.skip ?? 0,
|
|
||||||
take: args.take ?? 10,
|
|
||||||
orderBy: args.orderBy ?? undefined,
|
|
||||||
where: args.filter ?? undefined,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Mutations section
|
|
||||||
this.builder.mutationFields((t) => ({
|
|
||||||
createUploadedDocument: t.prismaField({
|
|
||||||
type: this.uploadedDocument(),
|
|
||||||
args: {
|
|
||||||
input: t.arg({
|
|
||||||
type: this.builder.generator.getCreateInput('UploadedDocument'),
|
|
||||||
required: true,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
resolve: async (query, root, args, ctx, info) => {
|
|
||||||
return await this.prisma.uploadedDocument.create({
|
|
||||||
...query,
|
|
||||||
data: args.input,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
10
src/UploadedFile/uploadedfile.module.ts
Normal file
10
src/UploadedFile/uploadedfile.module.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { Module, Global } from '@nestjs/common';
|
||||||
|
import { UploadedFileSchema } from './uploadedfile.schema';
|
||||||
|
import { MinioModule } from '../Minio/minio.module';
|
||||||
|
@Global()
|
||||||
|
@Module({
|
||||||
|
imports: [MinioModule],
|
||||||
|
providers: [UploadedFileSchema],
|
||||||
|
exports: [UploadedFileSchema],
|
||||||
|
})
|
||||||
|
export class UploadedFileModule {}
|
||||||
113
src/UploadedFile/uploadedfile.schema.ts
Normal file
113
src/UploadedFile/uploadedfile.schema.ts
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
import { Inject, Injectable, UploadedFiles } 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';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class UploadedFileSchema extends PothosSchema {
|
||||||
|
constructor(
|
||||||
|
@Inject(SchemaBuilderToken) private readonly builder: Builder,
|
||||||
|
private readonly prisma: PrismaService,
|
||||||
|
private readonly minioService: MinioService,
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PothosRef()
|
||||||
|
uploadedFile() {
|
||||||
|
return this.builder.prismaObject('UploadedFile', {
|
||||||
|
fields: (t) => ({
|
||||||
|
id: t.exposeID('id'),
|
||||||
|
userId: t.exposeID('userId'),
|
||||||
|
fileName: t.exposeString('fileName'),
|
||||||
|
type: t.exposeString('type'),
|
||||||
|
fileUrl: t.exposeString('fileUrl'),
|
||||||
|
uploadedAt: t.expose('uploadedAt', { type: 'DateTime' }),
|
||||||
|
user: t.relation('user'),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pothos()
|
||||||
|
init(): void {
|
||||||
|
this.builder.queryFields((t) => ({
|
||||||
|
uploadedDocument: t.prismaField({
|
||||||
|
type: this.uploadedFile(),
|
||||||
|
args: this.builder.generator.findUniqueArgs('UploadedFile'),
|
||||||
|
resolve: async (query, root, args, ctx, info) => {
|
||||||
|
return await this.prisma.uploadedFile.findUnique({
|
||||||
|
...query,
|
||||||
|
where: args.where,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
uploadedDocuments: t.prismaField({
|
||||||
|
type: [this.uploadedFile()],
|
||||||
|
args: this.builder.generator.findManyArgs('UploadedFile'),
|
||||||
|
resolve: async (query, root, args, ctx, info) => {
|
||||||
|
return await this.prisma.uploadedFile.findMany({
|
||||||
|
...query,
|
||||||
|
skip: args.skip ?? 0,
|
||||||
|
take: args.take ?? 10,
|
||||||
|
orderBy: args.orderBy ?? undefined,
|
||||||
|
where: args.filter ?? undefined,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Mutations section
|
||||||
|
this.builder.mutationFields((t) => ({
|
||||||
|
singleUpload: t.prismaField({
|
||||||
|
type: this.uploadedFile(),
|
||||||
|
args: {
|
||||||
|
userId: t.arg({
|
||||||
|
type: 'String',
|
||||||
|
required: true,
|
||||||
|
}),
|
||||||
|
file: t.arg({
|
||||||
|
type: 'Upload',
|
||||||
|
required: true,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
resolve: async (query, root, args, ctx, info) => {
|
||||||
|
const user = await this.prisma.user.findUnique({
|
||||||
|
where: {
|
||||||
|
id: args.userId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (!user) {
|
||||||
|
throw new Error('User not found');
|
||||||
|
}
|
||||||
|
// convert graphql upload to file
|
||||||
|
// upload file to minio
|
||||||
|
const { filename, mimetype } = await this.minioService.uploadFile(
|
||||||
|
args.file,
|
||||||
|
'files',
|
||||||
|
);
|
||||||
|
// getFileUrl
|
||||||
|
let fileUrl = await this.minioService.getFileUrl(filename, 'files');
|
||||||
|
if (!fileUrl) {
|
||||||
|
fileUrl = '';
|
||||||
|
}
|
||||||
|
const uploadedFile = await this.prisma.uploadedFile.create({
|
||||||
|
data: {
|
||||||
|
userId: user.id,
|
||||||
|
fileName: filename,
|
||||||
|
type: mimetype,
|
||||||
|
fileUrl: fileUrl,
|
||||||
|
uploadedAt: new Date(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return uploadedFile;
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { NestFactory } from '@nestjs/core';
|
import { NestFactory } from '@nestjs/core';
|
||||||
import { AppModule } from './app.module';
|
import { AppModule } from './app.module';
|
||||||
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
|
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
|
||||||
|
import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.js';
|
||||||
|
|
||||||
async function bootstrap() {
|
async function bootstrap() {
|
||||||
const app = await NestFactory.create(AppModule);
|
const app = await NestFactory.create(AppModule);
|
||||||
@@ -40,6 +41,14 @@ async function bootstrap() {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// graphql upload
|
||||||
|
app.use(
|
||||||
|
graphqlUploadExpress({
|
||||||
|
maxFileSize: 100 * 1024 * 1024, // 100 MB
|
||||||
|
maxFiles: 10,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
const port = process.env.LISTEN_PORT ?? 3000; // Default to 3000 if LISTEN_PORT is not set
|
const port = process.env.LISTEN_PORT ?? 3000; // Default to 3000 if LISTEN_PORT is not set
|
||||||
await app.listen(port);
|
await app.listen(port);
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"module": "commonjs",
|
"module": "NodeNext",
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"removeComments": true,
|
"removeComments": true,
|
||||||
"emitDecoratorMetadata": true,
|
"emitDecoratorMetadata": true,
|
||||||
@@ -18,5 +18,7 @@
|
|||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"noFallthroughCasesInSwitch": true,
|
"noFallthroughCasesInSwitch": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
|
"allowJs": true,
|
||||||
|
"maxNodeModuleJsDepth": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user