mirror of
https://github.com/twentyhq/twenty.git
synced 2025-01-02 01:04:12 +03:00
feat: prisma typed select (#347)
* feat: wip prisma gql select * feat: stronger api using decorator * feat: add PrismaSelect everywhere * fix: remove unused * fix: remove seed debug
This commit is contained in:
parent
eb9be6894e
commit
ca283a2196
@ -19,7 +19,8 @@
|
||||
"test:cov": "jest --coverage",
|
||||
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
|
||||
"test:e2e": "jest --config ./test/jest-e2e.json",
|
||||
"prisma:generate-client": "npx prisma generate --generator client",
|
||||
"prisma:generate-client": "npx prisma generate --generator client && yarn prisma:generate-gql-select",
|
||||
"prisma:generate-gql-select": "node scripts/generate-model-select-map.js",
|
||||
"prisma:generate-nest-graphql": "npx prisma generate --generator nestgraphql && eslint \"src/core/@generated/**\" --fix",
|
||||
"prisma:migrate": "npx prisma migrate deploy",
|
||||
"prisma:seed": "npx prisma db seed",
|
||||
@ -39,6 +40,7 @@
|
||||
"@nestjs/platform-express": "^9.0.0",
|
||||
"@nestjs/serve-static": "^3.0.0",
|
||||
"@nestjs/terminus": "^9.2.2",
|
||||
"@paljs/plugins": "^5.3.3",
|
||||
"@prisma/client": "^4.13.0",
|
||||
"apollo-server-express": "^3.12.0",
|
||||
"bcrypt": "^5.1.0",
|
||||
|
32
server/scripts/generate-model-select-map.js
Normal file
32
server/scripts/generate-model-select-map.js
Normal file
@ -0,0 +1,32 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { getDMMF, getSchemaPath } = require('@prisma/internals');
|
||||
|
||||
async function generateTypes() {
|
||||
const schemaPath = await getSchemaPath();
|
||||
const dmmf = await getDMMF({
|
||||
datamodel: fs.readFileSync(schemaPath, 'utf-8'),
|
||||
});
|
||||
|
||||
let content =
|
||||
'// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.\n';
|
||||
content += "import { Prisma } from '@prisma/client';\n\n";
|
||||
content += 'export type ModelSelectMap = {\n';
|
||||
|
||||
for (const model of dmmf.datamodel.models) {
|
||||
content += ` ${model.name}: Prisma.${model.name}Select;\n`;
|
||||
}
|
||||
|
||||
content += '};\n';
|
||||
|
||||
fs.writeFileSync(
|
||||
path.join(__dirname, '../src/utils/prisma-select/model-select-map.ts'),
|
||||
content,
|
||||
);
|
||||
}
|
||||
|
||||
generateTypes().catch((e) => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
});
|
@ -1,4 +1,4 @@
|
||||
import { PureAbility, AbilityBuilder, subject } from '@casl/ability';
|
||||
import { PureAbility, AbilityBuilder } from '@casl/ability';
|
||||
import { createPrismaAbility, PrismaQuery, Subjects } from '@casl/prisma';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import {
|
||||
|
@ -1,10 +1,8 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { CommentService } from './services/comment.service';
|
||||
import { CommentResolver } from './resolvers/comment.resolver';
|
||||
import { CommentRelationsResolver } from './resolvers/comment-relations.resolver';
|
||||
import { CommentThreadTargetService } from './services/comment-thread-target.service';
|
||||
import { CommentThreadResolver } from './resolvers/comment-thread.resolver';
|
||||
import { CommentThreadRelationsResolver } from './resolvers/comment-thread-relations.resolver';
|
||||
import { CommentThreadService } from './services/comment-thread.service';
|
||||
|
||||
@Module({
|
||||
@ -13,9 +11,7 @@ import { CommentThreadService } from './services/comment-thread.service';
|
||||
CommentThreadService,
|
||||
CommentThreadTargetService,
|
||||
CommentResolver,
|
||||
CommentRelationsResolver,
|
||||
CommentThreadResolver,
|
||||
CommentThreadRelationsResolver,
|
||||
],
|
||||
exports: [CommentService, CommentThreadService, CommentThreadTargetService],
|
||||
})
|
||||
|
@ -1,25 +0,0 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { CommentRelationsResolver } from './comment-relations.resolver';
|
||||
import { CommentService } from '../services/comment.service';
|
||||
|
||||
describe('CommentRelationsResolver', () => {
|
||||
let resolver: CommentRelationsResolver;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
CommentRelationsResolver,
|
||||
{
|
||||
provide: CommentService,
|
||||
useValue: {},
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
resolver = module.get<CommentRelationsResolver>(CommentRelationsResolver);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(resolver).toBeDefined();
|
||||
});
|
||||
});
|
@ -1,22 +0,0 @@
|
||||
import * as TypeGraphQL from '@nestjs/graphql';
|
||||
import { User } from 'src/core/@generated/user/user.model';
|
||||
import { Comment } from 'src/core/@generated/comment/comment.model';
|
||||
import { CommentService } from '../services/comment.service';
|
||||
|
||||
@TypeGraphQL.Resolver(() => Comment)
|
||||
export class CommentRelationsResolver {
|
||||
constructor(private readonly commentService: CommentService) {}
|
||||
|
||||
@TypeGraphQL.ResolveField(() => User, {
|
||||
nullable: true,
|
||||
})
|
||||
async author(@TypeGraphQL.Parent() comment: Comment): Promise<User | null> {
|
||||
return await this.commentService
|
||||
.findFirst({
|
||||
where: {
|
||||
id: comment.id,
|
||||
},
|
||||
})
|
||||
.author({});
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { CommentThreadRelationsResolver } from './comment-thread-relations.resolver';
|
||||
import { CommentService } from '../services/comment.service';
|
||||
import { CommentThreadTargetService } from '../services/comment-thread-target.service';
|
||||
|
||||
describe('CommentThreadRelationsResolver', () => {
|
||||
let resolver: CommentThreadRelationsResolver;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
CommentThreadRelationsResolver,
|
||||
{
|
||||
provide: CommentService,
|
||||
useValue: {},
|
||||
},
|
||||
{
|
||||
provide: CommentThreadTargetService,
|
||||
useValue: {},
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
resolver = module.get<CommentThreadRelationsResolver>(
|
||||
CommentThreadRelationsResolver,
|
||||
);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(resolver).toBeDefined();
|
||||
});
|
||||
});
|
@ -1,48 +0,0 @@
|
||||
import * as TypeGraphQL from '@nestjs/graphql';
|
||||
import { CommentThreadTarget } from 'src/core/@generated/comment-thread-target/comment-thread-target.model';
|
||||
import { CommentThread } from 'src/core/@generated/comment-thread/comment-thread.model';
|
||||
import { Comment } from 'src/core/@generated/comment/comment.model';
|
||||
import { CommentService } from '../services/comment.service';
|
||||
import { CommentThreadTargetService } from '../services/comment-thread-target.service';
|
||||
|
||||
@TypeGraphQL.Resolver(() => CommentThread)
|
||||
export class CommentThreadRelationsResolver {
|
||||
constructor(
|
||||
private readonly commentService: CommentService,
|
||||
private readonly commentThreadTargetService: CommentThreadTargetService,
|
||||
) {}
|
||||
|
||||
@TypeGraphQL.ResolveField(() => [Comment], {
|
||||
nullable: false,
|
||||
})
|
||||
async comments(
|
||||
@TypeGraphQL.Root() commentThread: CommentThread,
|
||||
): Promise<Comment[]> {
|
||||
return this.commentService.findMany({
|
||||
where: {
|
||||
commentThreadId: commentThread.id,
|
||||
},
|
||||
orderBy: {
|
||||
// TODO: find a way to pass it in the query
|
||||
createdAt: 'desc',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@TypeGraphQL.ResolveField(() => [CommentThreadTarget], {
|
||||
nullable: true,
|
||||
})
|
||||
async commentThreadTargets(
|
||||
@TypeGraphQL.Root() commentThread: CommentThread,
|
||||
): Promise<CommentThreadTarget[]> {
|
||||
return this.commentThreadTargetService.findMany({
|
||||
where: {
|
||||
commentThreadId: commentThread.id,
|
||||
},
|
||||
orderBy: {
|
||||
// TODO: find a way to pass it in the query
|
||||
createdAt: 'desc',
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
@ -11,6 +11,10 @@ import { CommentThreadService } from '../services/comment-thread.service';
|
||||
import { prepareFindManyArgs } from 'src/utils/prepare-find-many';
|
||||
import { UpdateOneCommentThreadArgs } from 'src/core/@generated/comment-thread/update-one-comment-thread.args';
|
||||
import { Prisma } from '@prisma/client';
|
||||
import {
|
||||
PrismaSelector,
|
||||
PrismaSelect,
|
||||
} from 'src/decorators/prisma-select.decorator';
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Resolver(() => CommentThread)
|
||||
@ -24,7 +28,9 @@ export class CommentThreadResolver {
|
||||
async createOneCommentThread(
|
||||
@Args() args: CreateOneCommentThreadArgs,
|
||||
@AuthWorkspace() workspace: Workspace,
|
||||
): Promise<CommentThread> {
|
||||
@PrismaSelector({ modelName: 'CommentThread' })
|
||||
prismaSelect: PrismaSelect<'CommentThread'>,
|
||||
): Promise<Partial<CommentThread>> {
|
||||
const newCommentData = args.data.comments?.createMany?.data
|
||||
? args.data.comments?.createMany?.data?.map((comment) => ({
|
||||
...comment,
|
||||
@ -38,6 +44,7 @@ export class CommentThreadResolver {
|
||||
...{ comments: { createMany: { data: newCommentData } } },
|
||||
...{ workspace: { connect: { id: workspace.id } } },
|
||||
},
|
||||
select: prismaSelect.value,
|
||||
});
|
||||
|
||||
return createdCommentThread;
|
||||
@ -48,10 +55,13 @@ export class CommentThreadResolver {
|
||||
})
|
||||
async updateOneCommentThread(
|
||||
@Args() args: UpdateOneCommentThreadArgs,
|
||||
): Promise<CommentThread> {
|
||||
const updatedCommentThread = await this.commentThreadService.update(
|
||||
args satisfies UpdateOneCommentThreadArgs as Prisma.CommentThreadUpdateArgs,
|
||||
);
|
||||
@PrismaSelector({ modelName: 'CommentThread' })
|
||||
prismaSelect: PrismaSelect<'CommentThread'>,
|
||||
): Promise<Partial<CommentThread>> {
|
||||
const updatedCommentThread = await this.commentThreadService.update({
|
||||
...args,
|
||||
select: prismaSelect.value,
|
||||
} as Prisma.CommentThreadUpdateArgs);
|
||||
|
||||
return updatedCommentThread;
|
||||
}
|
||||
@ -60,13 +70,18 @@ export class CommentThreadResolver {
|
||||
async findManyCommentThreads(
|
||||
@Args() args: FindManyCommentThreadArgs,
|
||||
@AuthWorkspace() workspace: Workspace,
|
||||
) {
|
||||
@PrismaSelector({ modelName: 'CommentThread' })
|
||||
prismaSelect: PrismaSelect<'CommentThread'>,
|
||||
): Promise<Partial<CommentThread>[]> {
|
||||
const preparedArgs = prepareFindManyArgs<FindManyCommentThreadArgs>(
|
||||
args,
|
||||
workspace,
|
||||
);
|
||||
|
||||
const result = await this.commentThreadService.findMany(preparedArgs);
|
||||
const result = await this.commentThreadService.findMany({
|
||||
...preparedArgs,
|
||||
select: prismaSelect.value,
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -8,6 +8,10 @@ import { Comment } from '../../../core/@generated/comment/comment.model';
|
||||
import { CreateOneCommentGuard } from '../../../guards/create-one-comment.guard';
|
||||
import { Prisma } from '@prisma/client';
|
||||
import { CommentService } from '../services/comment.service';
|
||||
import {
|
||||
PrismaSelector,
|
||||
PrismaSelect,
|
||||
} from 'src/decorators/prisma-select.decorator';
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Resolver(() => Comment)
|
||||
@ -21,12 +25,15 @@ export class CommentResolver {
|
||||
async createOneComment(
|
||||
@Args() args: CreateOneCommentArgs,
|
||||
@AuthWorkspace() workspace: Workspace,
|
||||
): Promise<Comment> {
|
||||
@PrismaSelector({ modelName: 'Comment' })
|
||||
prismaSelect: PrismaSelect<'Comment'>,
|
||||
): Promise<Partial<Comment>> {
|
||||
return this.commentService.create({
|
||||
data: {
|
||||
...args.data,
|
||||
...{ workspace: { connect: { id: workspace.id } } },
|
||||
},
|
||||
} satisfies CreateOneCommentArgs as Prisma.CommentCreateArgs);
|
||||
select: prismaSelect.value,
|
||||
} as Prisma.CommentCreateArgs);
|
||||
}
|
||||
}
|
||||
|
@ -2,40 +2,28 @@ import * as TypeGraphQL from '@nestjs/graphql';
|
||||
import { CommentThread } from 'src/core/@generated/comment-thread/comment-thread.model';
|
||||
import { Comment } from 'src/core/@generated/comment/comment.model';
|
||||
import { Company } from 'src/core/@generated/company/company.model';
|
||||
import { User } from 'src/core/@generated/user/user.model';
|
||||
import { CompanyService } from './company.service';
|
||||
import { CommentThreadService } from '../comment/services/comment-thread.service';
|
||||
import { CommentService } from '../comment/services/comment.service';
|
||||
import {
|
||||
PrismaSelect,
|
||||
PrismaSelector,
|
||||
} from 'src/decorators/prisma-select.decorator';
|
||||
|
||||
@TypeGraphQL.Resolver(() => Company)
|
||||
export class CompanyRelationsResolver {
|
||||
constructor(
|
||||
private readonly companyService: CompanyService,
|
||||
private readonly commentThreadService: CommentThreadService,
|
||||
private readonly commentService: CommentService,
|
||||
) {}
|
||||
|
||||
@TypeGraphQL.ResolveField(() => User, {
|
||||
nullable: true,
|
||||
})
|
||||
async accountOwner(
|
||||
@TypeGraphQL.Parent() company: Company,
|
||||
): Promise<User | null> {
|
||||
return this.companyService
|
||||
.findUniqueOrThrow({
|
||||
where: {
|
||||
id: company.id,
|
||||
},
|
||||
})
|
||||
.accountOwner({});
|
||||
}
|
||||
|
||||
@TypeGraphQL.ResolveField(() => [CommentThread], {
|
||||
nullable: false,
|
||||
})
|
||||
async commentThreads(
|
||||
@TypeGraphQL.Root() company: Company,
|
||||
): Promise<CommentThread[]> {
|
||||
@PrismaSelector({ modelName: 'CommentThread' })
|
||||
prismaSelect: PrismaSelect<'CommentThread'>,
|
||||
): Promise<Partial<CommentThread>[]> {
|
||||
return this.commentThreadService.findMany({
|
||||
where: {
|
||||
commentThreadTargets: {
|
||||
@ -45,13 +33,18 @@ export class CompanyRelationsResolver {
|
||||
},
|
||||
},
|
||||
},
|
||||
select: prismaSelect.value,
|
||||
});
|
||||
}
|
||||
|
||||
@TypeGraphQL.ResolveField(() => [Comment], {
|
||||
nullable: false,
|
||||
})
|
||||
async comments(@TypeGraphQL.Root() company: Company): Promise<Comment[]> {
|
||||
async comments(
|
||||
@TypeGraphQL.Root() company: Company,
|
||||
@PrismaSelector({ modelName: 'Comment' })
|
||||
prismaSelect: PrismaSelect<'Comment'>,
|
||||
): Promise<Partial<Comment>[]> {
|
||||
return this.commentService.findMany({
|
||||
where: {
|
||||
commentThread: {
|
||||
@ -63,6 +56,7 @@ export class CompanyRelationsResolver {
|
||||
},
|
||||
},
|
||||
},
|
||||
select: prismaSelect.value,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,10 @@ import { DeleteManyGuard } from '../../guards/delete-many.guard';
|
||||
import { CreateOneGuard } from '../../guards/create-one.guard';
|
||||
import { CompanyService } from './company.service';
|
||||
import { prepareFindManyArgs } from 'src/utils/prepare-find-many';
|
||||
import {
|
||||
PrismaSelect,
|
||||
PrismaSelector,
|
||||
} from 'src/decorators/prisma-select.decorator';
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Resolver(() => Company)
|
||||
@ -25,12 +29,17 @@ export class CompanyResolver {
|
||||
async findManyCompany(
|
||||
@Args() args: FindManyCompanyArgs,
|
||||
@AuthWorkspace() workspace: Workspace,
|
||||
) {
|
||||
@PrismaSelector({ modelName: 'Company' })
|
||||
prismaSelect: PrismaSelect<'Company'>,
|
||||
): Promise<Partial<Company>[]> {
|
||||
const preparedArgs = prepareFindManyArgs<FindManyCompanyArgs>(
|
||||
args,
|
||||
workspace,
|
||||
);
|
||||
return this.companyService.findMany(preparedArgs);
|
||||
return this.companyService.findMany({
|
||||
...preparedArgs,
|
||||
select: prismaSelect.value,
|
||||
});
|
||||
}
|
||||
|
||||
@UseGuards(UpdateOneGuard)
|
||||
@ -39,14 +48,17 @@ export class CompanyResolver {
|
||||
})
|
||||
async updateOneCompany(
|
||||
@Args() args: UpdateOneCompanyArgs,
|
||||
): Promise<Company | null> {
|
||||
@PrismaSelector({ modelName: 'Company' })
|
||||
prismaSelect: PrismaSelect<'Company'>,
|
||||
): Promise<Partial<Company> | null> {
|
||||
if (!args.data.accountOwner?.connect?.id) {
|
||||
args.data.accountOwner = { disconnect: true };
|
||||
}
|
||||
|
||||
return this.companyService.update({
|
||||
...args,
|
||||
} satisfies UpdateOneCompanyArgs as Prisma.CompanyUpdateArgs);
|
||||
select: prismaSelect.value,
|
||||
} as Prisma.CompanyUpdateArgs);
|
||||
}
|
||||
|
||||
@UseGuards(DeleteManyGuard)
|
||||
@ -68,12 +80,15 @@ export class CompanyResolver {
|
||||
async createOneCompany(
|
||||
@Args() args: CreateOneCompanyArgs,
|
||||
@AuthWorkspace() workspace: Workspace,
|
||||
): Promise<Company> {
|
||||
@PrismaSelector({ modelName: 'Company' })
|
||||
prismaSelect: PrismaSelect<'Company'>,
|
||||
): Promise<Partial<Company>> {
|
||||
return this.companyService.create({
|
||||
data: {
|
||||
...args.data,
|
||||
...{ workspace: { connect: { id: workspace.id } } },
|
||||
},
|
||||
} satisfies CreateOneCompanyArgs as Prisma.CompanyCreateArgs);
|
||||
select: prismaSelect.value,
|
||||
} as Prisma.CompanyCreateArgs);
|
||||
}
|
||||
}
|
||||
|
@ -1,39 +1,29 @@
|
||||
import * as TypeGraphQL from '@nestjs/graphql';
|
||||
import { CommentThread } from 'src/core/@generated/comment-thread/comment-thread.model';
|
||||
import { Comment } from 'src/core/@generated/comment/comment.model';
|
||||
import { Company } from 'src/core/@generated/company/company.model';
|
||||
import { Person } from 'src/core/@generated/person/person.model';
|
||||
import { PersonService } from './person.service';
|
||||
import { CommentThreadService } from '../comment/services/comment-thread.service';
|
||||
import { CommentService } from '../comment/services/comment.service';
|
||||
import {
|
||||
PrismaSelect,
|
||||
PrismaSelector,
|
||||
} from 'src/decorators/prisma-select.decorator';
|
||||
|
||||
@TypeGraphQL.Resolver(() => Person)
|
||||
export class PersonRelationsResolver {
|
||||
constructor(
|
||||
private readonly personService: PersonService,
|
||||
private readonly commentThreadService: CommentThreadService,
|
||||
private readonly commentService: CommentService,
|
||||
) {}
|
||||
|
||||
@TypeGraphQL.ResolveField(() => Company, {
|
||||
nullable: true,
|
||||
})
|
||||
async company(@TypeGraphQL.Parent() person: Person): Promise<Company | null> {
|
||||
return await this.personService
|
||||
.findUniqueOrThrow({
|
||||
where: {
|
||||
id: person.id,
|
||||
},
|
||||
})
|
||||
.company({});
|
||||
}
|
||||
|
||||
@TypeGraphQL.ResolveField(() => [CommentThread], {
|
||||
nullable: false,
|
||||
})
|
||||
async commentThreads(
|
||||
@TypeGraphQL.Root() person: Person,
|
||||
): Promise<CommentThread[]> {
|
||||
@PrismaSelector({ modelName: 'CommentThread' })
|
||||
prismaSelect: PrismaSelect<'CommentThread'>,
|
||||
): Promise<Partial<CommentThread>[]> {
|
||||
return await this.commentThreadService.findMany({
|
||||
where: {
|
||||
commentThreadTargets: {
|
||||
@ -43,13 +33,18 @@ export class PersonRelationsResolver {
|
||||
},
|
||||
},
|
||||
},
|
||||
select: prismaSelect.value,
|
||||
});
|
||||
}
|
||||
|
||||
@TypeGraphQL.ResolveField(() => [Comment], {
|
||||
nullable: false,
|
||||
})
|
||||
async comments(@TypeGraphQL.Root() person: Person): Promise<Comment[]> {
|
||||
async comments(
|
||||
@TypeGraphQL.Root() person: Person,
|
||||
@PrismaSelector({ modelName: 'Comment' })
|
||||
prismaSelect: PrismaSelect<'Comment'>,
|
||||
): Promise<Partial<Comment>[]> {
|
||||
return this.commentService.findMany({
|
||||
where: {
|
||||
commentThread: {
|
||||
@ -61,6 +56,7 @@ export class PersonRelationsResolver {
|
||||
},
|
||||
},
|
||||
},
|
||||
select: prismaSelect.value,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,10 @@ import { DeleteManyGuard } from '../../guards/delete-many.guard';
|
||||
import { CreateOneGuard } from '../../guards/create-one.guard';
|
||||
import { PersonService } from './person.service';
|
||||
import { prepareFindManyArgs } from 'src/utils/prepare-find-many';
|
||||
import {
|
||||
PrismaSelect,
|
||||
PrismaSelector,
|
||||
} from 'src/decorators/prisma-select.decorator';
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Resolver(() => Person)
|
||||
@ -27,13 +31,17 @@ export class PersonResolver {
|
||||
async findManyPerson(
|
||||
@Args() args: FindManyPersonArgs,
|
||||
@AuthWorkspace() workspace: Workspace,
|
||||
): Promise<Person[]> {
|
||||
@PrismaSelector({ modelName: 'Person' })
|
||||
prismaSelect: PrismaSelect<'Person'>,
|
||||
): Promise<Partial<Person>[]> {
|
||||
const preparedArgs = prepareFindManyArgs<FindManyPersonArgs>(
|
||||
args,
|
||||
workspace,
|
||||
);
|
||||
|
||||
return this.personService.findMany({
|
||||
...preparedArgs,
|
||||
select: prismaSelect.value,
|
||||
});
|
||||
}
|
||||
|
||||
@ -43,14 +51,17 @@ export class PersonResolver {
|
||||
})
|
||||
async updateOnePerson(
|
||||
@Args() args: UpdateOnePersonArgs,
|
||||
): Promise<Person | null> {
|
||||
@PrismaSelector({ modelName: 'Person' })
|
||||
prismaSelect: PrismaSelect<'Person'>,
|
||||
): Promise<Partial<Person> | null> {
|
||||
if (!args.data.company?.connect?.id) {
|
||||
args.data.company = { disconnect: true };
|
||||
}
|
||||
|
||||
return this.personService.update({
|
||||
...args,
|
||||
} satisfies UpdateOnePersonArgs as Prisma.PersonUpdateArgs);
|
||||
select: prismaSelect.value,
|
||||
} as Prisma.PersonUpdateArgs);
|
||||
}
|
||||
|
||||
@UseGuards(DeleteManyGuard)
|
||||
@ -72,12 +83,15 @@ export class PersonResolver {
|
||||
async createOnePerson(
|
||||
@Args() args: CreateOnePersonArgs,
|
||||
@AuthWorkspace() workspace: Workspace,
|
||||
): Promise<Person> {
|
||||
@PrismaSelector({ modelName: 'Person' })
|
||||
prismaSelect: PrismaSelect<'Person'>,
|
||||
): Promise<Partial<Person>> {
|
||||
return this.personService.create({
|
||||
data: {
|
||||
...args.data,
|
||||
...{ workspace: { connect: { id: workspace.id } } },
|
||||
},
|
||||
} satisfies CreateOnePersonArgs as Prisma.PersonCreateArgs);
|
||||
select: prismaSelect.value,
|
||||
} as Prisma.PersonCreateArgs);
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,8 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { PipelineService } from './services/pipeline.service';
|
||||
import { PipelineResolver } from './resolvers/pipeline.resolver';
|
||||
import { PipelineRelationsResolver } from './resolvers/pipeline-relations.resolver';
|
||||
import { PipelineStageResolver } from './resolvers/pipeline-stage.resolver';
|
||||
import { PipelineStageRelationsResolver } from './resolvers/pipeline-stage-relations.resolver';
|
||||
import { PipelineProgressResolver } from './resolvers/pipeline-progress.resolver';
|
||||
import { PipelineProgressRelationsResolver } from './resolvers/pipeline-progress-relations.resolver';
|
||||
import { PipelineStageService } from './services/pipeline-stage.service';
|
||||
import { PipelineProgressService } from './services/pipeline-progress.service';
|
||||
|
||||
@ -16,11 +13,8 @@ import { PipelineProgressService } from './services/pipeline-progress.service';
|
||||
PipelineStageService,
|
||||
PipelineProgressService,
|
||||
PipelineResolver,
|
||||
PipelineRelationsResolver,
|
||||
PipelineStageResolver,
|
||||
PipelineStageRelationsResolver,
|
||||
PipelineProgressResolver,
|
||||
PipelineProgressRelationsResolver,
|
||||
],
|
||||
exports: [PipelineService, PipelineStageService, PipelineProgressService],
|
||||
})
|
||||
|
@ -1,32 +0,0 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { PipelineProgressRelationsResolver } from './pipeline-progress-relations.resolver';
|
||||
import { PipelineStageService } from '../services/pipeline-stage.service';
|
||||
import { PipelineService } from '../services/pipeline.service';
|
||||
|
||||
describe('PipelineProgressRelationsResolver', () => {
|
||||
let resolver: PipelineProgressRelationsResolver;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
PipelineProgressRelationsResolver,
|
||||
{
|
||||
provide: PipelineStageService,
|
||||
useValue: {},
|
||||
},
|
||||
{
|
||||
provide: PipelineService,
|
||||
useValue: {},
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
resolver = module.get<PipelineProgressRelationsResolver>(
|
||||
PipelineProgressRelationsResolver,
|
||||
);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(resolver).toBeDefined();
|
||||
});
|
||||
});
|
@ -1,40 +0,0 @@
|
||||
import * as TypeGraphQL from '@nestjs/graphql';
|
||||
import { PipelineProgress } from 'src/core/@generated/pipeline-progress/pipeline-progress.model';
|
||||
import { PipelineStage } from 'src/core/@generated/pipeline-stage/pipeline-stage.model';
|
||||
import { Pipeline } from 'src/core/@generated/pipeline/pipeline.model';
|
||||
import { PipelineStageService } from '../services/pipeline-stage.service';
|
||||
import { PipelineService } from '../services/pipeline.service';
|
||||
|
||||
@TypeGraphQL.Resolver(() => PipelineProgress)
|
||||
export class PipelineProgressRelationsResolver {
|
||||
constructor(
|
||||
private readonly pipelineStageService: PipelineStageService,
|
||||
private readonly pipelineService: PipelineService,
|
||||
) {}
|
||||
|
||||
@TypeGraphQL.ResolveField(() => PipelineStage, {
|
||||
nullable: false,
|
||||
})
|
||||
async pipelineStage(
|
||||
@TypeGraphQL.Root() pipelineStage: PipelineProgress,
|
||||
): Promise<PipelineStage> {
|
||||
return this.pipelineStageService.findUniqueOrThrow({
|
||||
where: {
|
||||
id: pipelineStage.pipelineStageId,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@TypeGraphQL.ResolveField(() => Pipeline, {
|
||||
nullable: false,
|
||||
})
|
||||
async pipeline(
|
||||
@TypeGraphQL.Root() pipelineStage: PipelineProgress,
|
||||
): Promise<Pipeline> {
|
||||
return this.pipelineService.findUniqueOrThrow({
|
||||
where: {
|
||||
id: pipelineStage.pipelineId,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
@ -22,6 +22,10 @@ import {
|
||||
} from 'src/ability/handlers/pipeline-progress.ability-handler';
|
||||
import { UserAbility } from 'src/decorators/user-ability.decorator';
|
||||
import { AppAbility } from 'src/ability/ability.factory';
|
||||
import {
|
||||
PrismaSelector,
|
||||
PrismaSelect,
|
||||
} from 'src/decorators/prisma-select.decorator';
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Resolver(() => PipelineProgress)
|
||||
@ -36,13 +40,16 @@ export class PipelineProgressResolver {
|
||||
async findManyPipelineProgress(
|
||||
@Args() args: FindManyPipelineProgressArgs,
|
||||
@UserAbility() ability: AppAbility,
|
||||
) {
|
||||
@PrismaSelector({ modelName: 'PipelineProgress' })
|
||||
prismaSelect: PrismaSelect<'PipelineProgress'>,
|
||||
): Promise<Partial<PipelineProgress>[]> {
|
||||
return this.pipelineProgressService.findMany({
|
||||
...args,
|
||||
where: {
|
||||
...args.where,
|
||||
AND: [accessibleBy(ability).PipelineProgress],
|
||||
},
|
||||
select: prismaSelect.value,
|
||||
});
|
||||
}
|
||||
|
||||
@ -53,10 +60,13 @@ export class PipelineProgressResolver {
|
||||
@CheckAbilities(UpdatePipelineProgressAbilityHandler)
|
||||
async updateOnePipelineProgress(
|
||||
@Args() args: UpdateOnePipelineProgressArgs,
|
||||
): Promise<PipelineProgress | null> {
|
||||
@PrismaSelector({ modelName: 'PipelineProgress' })
|
||||
prismaSelect: PrismaSelect<'PipelineProgress'>,
|
||||
): Promise<Partial<PipelineProgress> | null> {
|
||||
return this.pipelineProgressService.update({
|
||||
...args,
|
||||
} satisfies UpdateOnePipelineProgressArgs as Prisma.PipelineProgressUpdateArgs);
|
||||
select: prismaSelect.value,
|
||||
} as Prisma.PipelineProgressUpdateArgs);
|
||||
}
|
||||
|
||||
@Mutation(() => AffectedRows, {
|
||||
@ -80,12 +90,15 @@ export class PipelineProgressResolver {
|
||||
async createOnePipelineProgress(
|
||||
@Args() args: CreateOnePipelineProgressArgs,
|
||||
@AuthWorkspace() workspace: Workspace,
|
||||
): Promise<PipelineProgress> {
|
||||
@PrismaSelector({ modelName: 'PipelineProgress' })
|
||||
prismaSelect: PrismaSelect<'PipelineProgress'>,
|
||||
): Promise<Partial<PipelineProgress>> {
|
||||
return this.pipelineProgressService.create({
|
||||
data: {
|
||||
...args.data,
|
||||
...{ workspace: { connect: { id: workspace.id } } },
|
||||
},
|
||||
} satisfies CreateOnePipelineProgressArgs as Prisma.PipelineProgressCreateArgs);
|
||||
select: prismaSelect.value,
|
||||
} as Prisma.PipelineProgressCreateArgs);
|
||||
}
|
||||
}
|
||||
|
@ -1,25 +0,0 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { PipelineRelationsResolver } from './pipeline-relations.resolver';
|
||||
import { PipelineStageService } from '../services/pipeline-stage.service';
|
||||
|
||||
describe('PipelineRelationsResolver', () => {
|
||||
let resolver: PipelineRelationsResolver;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
PipelineRelationsResolver,
|
||||
{
|
||||
provide: PipelineStageService,
|
||||
useValue: {},
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
resolver = module.get<PipelineRelationsResolver>(PipelineRelationsResolver);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(resolver).toBeDefined();
|
||||
});
|
||||
});
|
@ -1,24 +0,0 @@
|
||||
import * as TypeGraphQL from '@nestjs/graphql';
|
||||
import { PipelineStage } from 'src/core/@generated/pipeline-stage/pipeline-stage.model';
|
||||
import { Pipeline } from 'src/core/@generated/pipeline/pipeline.model';
|
||||
import { PipelineStageService } from '../services/pipeline-stage.service';
|
||||
|
||||
@TypeGraphQL.Resolver(() => Pipeline)
|
||||
export class PipelineRelationsResolver {
|
||||
constructor(private readonly pipelineStageService: PipelineStageService) {}
|
||||
|
||||
@TypeGraphQL.ResolveField(() => [PipelineStage], {
|
||||
nullable: false,
|
||||
})
|
||||
async pipelineStages(
|
||||
@TypeGraphQL.Root() pipeline: Pipeline,
|
||||
): Promise<PipelineStage[]> {
|
||||
return this.pipelineStageService.findMany({
|
||||
where: {
|
||||
pipelineId: {
|
||||
equals: pipeline.id,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { PipelineStageRelationsResolver } from './pipeline-stage-relations.resolver';
|
||||
import { PipelineProgressService } from '../services/pipeline-progress.service';
|
||||
|
||||
describe('PipelineStageRelationsResolver', () => {
|
||||
let resolver: PipelineStageRelationsResolver;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
PipelineStageRelationsResolver,
|
||||
{
|
||||
provide: PipelineProgressService,
|
||||
useValue: {},
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
resolver = module.get<PipelineStageRelationsResolver>(
|
||||
PipelineStageRelationsResolver,
|
||||
);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(resolver).toBeDefined();
|
||||
});
|
||||
});
|
@ -1,26 +0,0 @@
|
||||
import * as TypeGraphQL from '@nestjs/graphql';
|
||||
import { PipelineProgress } from 'src/core/@generated/pipeline-progress/pipeline-progress.model';
|
||||
import { PipelineStage } from 'src/core/@generated/pipeline-stage/pipeline-stage.model';
|
||||
import { PipelineProgressService } from '../services/pipeline-progress.service';
|
||||
|
||||
@TypeGraphQL.Resolver(() => PipelineStage)
|
||||
export class PipelineStageRelationsResolver {
|
||||
constructor(
|
||||
private readonly pipelineProgressService: PipelineProgressService,
|
||||
) {}
|
||||
|
||||
@TypeGraphQL.ResolveField(() => [PipelineProgress], {
|
||||
nullable: false,
|
||||
})
|
||||
async pipelineProgresses(
|
||||
@TypeGraphQL.Root() pipelineStage: PipelineStage,
|
||||
): Promise<PipelineProgress[]> {
|
||||
return this.pipelineProgressService.findMany({
|
||||
where: {
|
||||
pipelineStageId: {
|
||||
equals: pipelineStage.id,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
@ -10,6 +10,10 @@ import { CheckAbilities } from 'src/decorators/check-abilities.decorator';
|
||||
import { ReadPipelineStageAbilityHandler } from 'src/ability/handlers/pipeline-stage.ability-handler';
|
||||
import { UserAbility } from 'src/decorators/user-ability.decorator';
|
||||
import { AppAbility } from 'src/ability/ability.factory';
|
||||
import {
|
||||
PrismaSelector,
|
||||
PrismaSelect,
|
||||
} from 'src/decorators/prisma-select.decorator';
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Resolver(() => PipelineStage)
|
||||
@ -22,13 +26,16 @@ export class PipelineStageResolver {
|
||||
async findManyPipelineStage(
|
||||
@Args() args: FindManyPipelineStageArgs,
|
||||
@UserAbility() ability: AppAbility,
|
||||
) {
|
||||
@PrismaSelector({ modelName: 'PipelineStage' })
|
||||
prismaSelect: PrismaSelect<'PipelineStage'>,
|
||||
): Promise<Partial<PipelineStage>[]> {
|
||||
return this.pipelineStageService.findMany({
|
||||
...args,
|
||||
where: {
|
||||
...args.where,
|
||||
AND: [accessibleBy(ability).PipelineStage],
|
||||
},
|
||||
select: prismaSelect.value,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,10 @@ import { CheckAbilities } from 'src/decorators/check-abilities.decorator';
|
||||
import { ReadPipelineAbilityHandler } from 'src/ability/handlers/pipeline.ability-handler';
|
||||
import { UserAbility } from 'src/decorators/user-ability.decorator';
|
||||
import { AppAbility } from 'src/ability/ability.factory';
|
||||
import {
|
||||
PrismaSelector,
|
||||
PrismaSelect,
|
||||
} from 'src/decorators/prisma-select.decorator';
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Resolver(() => Pipeline)
|
||||
@ -22,13 +26,16 @@ export class PipelineResolver {
|
||||
async findManyPipeline(
|
||||
@Args() args: FindManyPipelineArgs,
|
||||
@UserAbility() ability: AppAbility,
|
||||
) {
|
||||
@PrismaSelector({ modelName: 'Pipeline' })
|
||||
prismaSelect: PrismaSelect<'Pipeline'>,
|
||||
): Promise<Partial<Pipeline>[]> {
|
||||
return this.pipelineService.findMany({
|
||||
...args,
|
||||
where: {
|
||||
...args.where,
|
||||
AND: [accessibleBy(ability).Pipeline],
|
||||
},
|
||||
select: prismaSelect.value,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,25 +0,0 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { UserRelationsResolver } from './user-relations.resolver';
|
||||
import { UserService } from './user.service';
|
||||
|
||||
describe('UserRelationsResolver', () => {
|
||||
let resolver: UserRelationsResolver;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
UserRelationsResolver,
|
||||
{
|
||||
provide: UserService,
|
||||
useValue: {},
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
resolver = module.get<UserRelationsResolver>(UserRelationsResolver);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(resolver).toBeDefined();
|
||||
});
|
||||
});
|
@ -1,46 +0,0 @@
|
||||
import * as TypeGraphQL from '@nestjs/graphql';
|
||||
import type { GraphQLResolveInfo } from 'graphql';
|
||||
import { WorkspaceMember } from 'src/core/@generated/workspace-member/workspace-member.model';
|
||||
import { User } from 'src/core/@generated/user/user.model';
|
||||
import { Company } from 'src/core/@generated/company/company.model';
|
||||
import { FindManyCompanyArgs } from 'src/core/@generated/company/find-many-company.args';
|
||||
import { UserService } from './user.service';
|
||||
|
||||
@TypeGraphQL.Resolver(() => User)
|
||||
export class UserRelationsResolver {
|
||||
constructor(private readonly userService: UserService) {}
|
||||
|
||||
@TypeGraphQL.ResolveField(() => WorkspaceMember, {
|
||||
nullable: true,
|
||||
})
|
||||
async workspaceMember(
|
||||
@TypeGraphQL.Parent() user: User,
|
||||
): Promise<WorkspaceMember | null> {
|
||||
return await this.userService
|
||||
.findFirst({
|
||||
where: {
|
||||
id: user.id,
|
||||
},
|
||||
})
|
||||
.workspaceMember({});
|
||||
}
|
||||
|
||||
@TypeGraphQL.ResolveField(() => [Company], {
|
||||
nullable: false,
|
||||
})
|
||||
async companies(
|
||||
@TypeGraphQL.Parent() user: User,
|
||||
@TypeGraphQL.Info() info: GraphQLResolveInfo,
|
||||
@TypeGraphQL.Args() args: FindManyCompanyArgs,
|
||||
): Promise<Company[]> {
|
||||
return this.userService
|
||||
.findUniqueOrThrow({
|
||||
where: {
|
||||
id: user.id,
|
||||
},
|
||||
})
|
||||
.companies({
|
||||
...args,
|
||||
});
|
||||
}
|
||||
}
|
@ -1,12 +1,11 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { UserService } from './user.service';
|
||||
import { UserResolver } from './user.resolver';
|
||||
import { UserRelationsResolver } from './user-relations.resolver';
|
||||
import { WorkspaceModule } from '../workspace/workspace.module';
|
||||
|
||||
@Module({
|
||||
imports: [WorkspaceModule],
|
||||
providers: [UserService, UserResolver, UserRelationsResolver],
|
||||
providers: [UserService, UserResolver],
|
||||
exports: [UserService],
|
||||
})
|
||||
export class UserModule {}
|
||||
|
@ -7,6 +7,10 @@ import { User } from 'src/core/@generated/user/user.model';
|
||||
import { ExceptionFilter } from 'src/filters/exception.filter';
|
||||
import { UseFilters, UseGuards } from '@nestjs/common';
|
||||
import { JwtAuthGuard } from 'src/guards/jwt.auth.guard';
|
||||
import {
|
||||
PrismaSelect,
|
||||
PrismaSelector,
|
||||
} from 'src/decorators/prisma-select.decorator';
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Resolver(() => User)
|
||||
@ -20,7 +24,9 @@ export class UserResolver {
|
||||
async findManyUser(
|
||||
@Args() args: FindManyUserArgs,
|
||||
@AuthWorkspace() workspace: Workspace,
|
||||
): Promise<User[]> {
|
||||
@PrismaSelector({ modelName: 'User' })
|
||||
prismaSelect: PrismaSelect<'User'>,
|
||||
): Promise<Partial<User>[]> {
|
||||
return await this.userService.findMany({
|
||||
...args,
|
||||
where: {
|
||||
@ -29,6 +35,7 @@ export class UserResolver {
|
||||
is: { workspace: { is: { id: { equals: workspace.id } } } },
|
||||
},
|
||||
},
|
||||
select: prismaSelect.value,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,27 +0,0 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { WorkspaceMemberRelationsResolver } from './workspace-member-relations.resolver';
|
||||
import { WorkspaceMemberService } from '../services/workspace-member.service';
|
||||
|
||||
describe('WorkspaceMemberRelationsResolver', () => {
|
||||
let resolver: WorkspaceMemberRelationsResolver;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
WorkspaceMemberRelationsResolver,
|
||||
{
|
||||
provide: WorkspaceMemberService,
|
||||
useValue: {},
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
resolver = module.get<WorkspaceMemberRelationsResolver>(
|
||||
WorkspaceMemberRelationsResolver,
|
||||
);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(resolver).toBeDefined();
|
||||
});
|
||||
});
|
@ -1,42 +0,0 @@
|
||||
import * as TypeGraphQL from '@nestjs/graphql';
|
||||
import { User } from 'src/core/@generated/user/user.model';
|
||||
import { WorkspaceMember } from 'src/core/@generated/workspace-member/workspace-member.model';
|
||||
import { Workspace } from 'src/core/@generated/workspace/workspace.model';
|
||||
import { WorkspaceMemberService } from '../services/workspace-member.service';
|
||||
|
||||
@TypeGraphQL.Resolver(() => WorkspaceMember)
|
||||
export class WorkspaceMemberRelationsResolver {
|
||||
constructor(
|
||||
private readonly workspaceMemberSercice: WorkspaceMemberService,
|
||||
) {}
|
||||
|
||||
@TypeGraphQL.ResolveField(() => User, {
|
||||
nullable: false,
|
||||
})
|
||||
async user(
|
||||
@TypeGraphQL.Parent() workspaceMember: WorkspaceMember,
|
||||
): Promise<User> {
|
||||
return await this.workspaceMemberSercice
|
||||
.findUniqueOrThrow({
|
||||
where: {
|
||||
id: workspaceMember.id,
|
||||
},
|
||||
})
|
||||
.user({});
|
||||
}
|
||||
|
||||
@TypeGraphQL.ResolveField(() => Workspace, {
|
||||
nullable: false,
|
||||
})
|
||||
async workspace(
|
||||
@TypeGraphQL.Parent() workspaceMember: WorkspaceMember,
|
||||
): Promise<Workspace> {
|
||||
return this.workspaceMemberSercice
|
||||
.findUniqueOrThrow({
|
||||
where: {
|
||||
id: workspaceMember.id,
|
||||
},
|
||||
})
|
||||
.workspace({});
|
||||
}
|
||||
}
|
@ -2,14 +2,12 @@ import { Module } from '@nestjs/common';
|
||||
import { WorkspaceService } from './services/workspace.service';
|
||||
import { WorkspaceMemberService } from './services/workspace-member.service';
|
||||
import { WorkspaceMemberResolver } from './resolvers/workspace-member.resolver';
|
||||
import { WorkspaceMemberRelationsResolver } from './resolvers/workspace-member-relations.resolver';
|
||||
|
||||
@Module({
|
||||
providers: [
|
||||
WorkspaceService,
|
||||
WorkspaceMemberService,
|
||||
WorkspaceMemberResolver,
|
||||
WorkspaceMemberRelationsResolver,
|
||||
],
|
||||
exports: [WorkspaceService, WorkspaceMemberService],
|
||||
})
|
||||
|
26
server/src/decorators/prisma-select.decorator.ts
Normal file
26
server/src/decorators/prisma-select.decorator.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
|
||||
import { GqlExecutionContext } from '@nestjs/graphql';
|
||||
import {
|
||||
PrismaSelect,
|
||||
ModelSelectMap,
|
||||
DefaultFieldsMap,
|
||||
} from 'src/utils/prisma-select';
|
||||
|
||||
export { PrismaSelect };
|
||||
|
||||
export const PrismaSelector = createParamDecorator(
|
||||
(
|
||||
data: {
|
||||
modelName: keyof ModelSelectMap;
|
||||
defaultFields?: DefaultFieldsMap;
|
||||
},
|
||||
ctx: ExecutionContext,
|
||||
): PrismaSelect<keyof ModelSelectMap> => {
|
||||
const gqlCtx = GqlExecutionContext.create(ctx);
|
||||
const info = gqlCtx.getInfo();
|
||||
|
||||
return new PrismaSelect(data.modelName, info, {
|
||||
defaultFields: data.defaultFields,
|
||||
});
|
||||
},
|
||||
);
|
56
server/src/utils/prisma-select/index.ts
Normal file
56
server/src/utils/prisma-select/index.ts
Normal file
@ -0,0 +1,56 @@
|
||||
import { PrismaSelect as PalJSPrismaSelect } from '@paljs/plugins';
|
||||
import { DMMF } from '@prisma/client/runtime';
|
||||
import { GraphQLResolveInfo } from 'graphql';
|
||||
import { ModelSelectMap } from './model-select-map';
|
||||
|
||||
export type DefaultFieldsMap = {
|
||||
readonly [K in keyof ModelSelectMap]?:
|
||||
| ModelSelectMap[K]
|
||||
| ((select: any) => ModelSelectMap[K]);
|
||||
};
|
||||
|
||||
export { ModelSelectMap };
|
||||
|
||||
export class PrismaSelect<
|
||||
K extends keyof ModelSelectMap,
|
||||
> extends PalJSPrismaSelect {
|
||||
private modelName: K;
|
||||
|
||||
constructor(
|
||||
modelName: K,
|
||||
info: GraphQLResolveInfo,
|
||||
options?: {
|
||||
readonly defaultFields?: DefaultFieldsMap;
|
||||
readonly dmmf?: readonly Pick<DMMF.Document, 'datamodel'>[];
|
||||
},
|
||||
) {
|
||||
super(info, options as any);
|
||||
this.modelName = modelName;
|
||||
}
|
||||
|
||||
get value(): ModelSelectMap[K] {
|
||||
return super.value;
|
||||
}
|
||||
|
||||
valueOf(field: string, mergeObject?: any): ModelSelectMap[K];
|
||||
valueOf<SubKey extends keyof ModelSelectMap>(
|
||||
field: string,
|
||||
filterBy: SubKey,
|
||||
mergeObject?: any,
|
||||
): ModelSelectMap[SubKey];
|
||||
valueOf(
|
||||
field: string,
|
||||
filterByOrMergeObject?: keyof ModelSelectMap | any,
|
||||
mergeObject?: any,
|
||||
) {
|
||||
if (typeof filterByOrMergeObject === 'string') {
|
||||
return super.valueOf(field, filterByOrMergeObject, mergeObject);
|
||||
} else {
|
||||
return super.valueOf(field, this.modelName, filterByOrMergeObject);
|
||||
}
|
||||
}
|
||||
|
||||
valueWithFilter(modelName: K): ModelSelectMap[K] {
|
||||
return super.valueWithFilter(modelName).select;
|
||||
}
|
||||
}
|
17
server/src/utils/prisma-select/model-select-map.ts
Normal file
17
server/src/utils/prisma-select/model-select-map.ts
Normal file
@ -0,0 +1,17 @@
|
||||
// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
import { Prisma } from '@prisma/client';
|
||||
|
||||
export type ModelSelectMap = {
|
||||
User: Prisma.UserSelect;
|
||||
Workspace: Prisma.WorkspaceSelect;
|
||||
WorkspaceMember: Prisma.WorkspaceMemberSelect;
|
||||
Company: Prisma.CompanySelect;
|
||||
Person: Prisma.PersonSelect;
|
||||
RefreshToken: Prisma.RefreshTokenSelect;
|
||||
CommentThread: Prisma.CommentThreadSelect;
|
||||
Comment: Prisma.CommentSelect;
|
||||
CommentThreadTarget: Prisma.CommentThreadTargetSelect;
|
||||
Pipeline: Prisma.PipelineSelect;
|
||||
PipelineStage: Prisma.PipelineStageSelect;
|
||||
PipelineProgress: Prisma.PipelineProgressSelect;
|
||||
};
|
859
server/yarn.lock
859
server/yarn.lock
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user