Add workspacePreQueryHook module (#3879)
* rebase * reorganise messaging folders * fix * fix after review * fix yarn lock
This commit is contained in:
@ -81,6 +81,7 @@
|
|||||||
"graphql-upload": "^13.0.0",
|
"graphql-upload": "^13.0.0",
|
||||||
"graphql-yoga": "^4.0.4",
|
"graphql-yoga": "^4.0.4",
|
||||||
"lodash.camelcase": "^4.3.0",
|
"lodash.camelcase": "^4.3.0",
|
||||||
|
"lodash.groupby": "^4.6.0",
|
||||||
"lodash.isempty": "^4.4.0",
|
"lodash.isempty": "^4.4.0",
|
||||||
"lodash.isobject": "^3.0.2",
|
"lodash.isobject": "^3.0.2",
|
||||||
"lodash.kebabcase": "^4.1.1",
|
"lodash.kebabcase": "^4.1.1",
|
||||||
|
|||||||
@ -34,11 +34,11 @@ import {
|
|||||||
import { EnvironmentService } from 'src/integrations/environment/environment.service';
|
import { EnvironmentService } from 'src/integrations/environment/environment.service';
|
||||||
import { User } from 'src/core/user/user.entity';
|
import { User } from 'src/core/user/user.entity';
|
||||||
import { RefreshToken } from 'src/core/refresh-token/refresh-token.entity';
|
import { RefreshToken } from 'src/core/refresh-token/refresh-token.entity';
|
||||||
import { Workspace } from 'src/core/workspace/workspace.entity';
|
|
||||||
import { ValidatePasswordResetToken } from 'src/core/auth/dto/validate-password-reset-token.entity';
|
import { ValidatePasswordResetToken } from 'src/core/auth/dto/validate-password-reset-token.entity';
|
||||||
import { EmailService } from 'src/integrations/email/email.service';
|
import { EmailService } from 'src/integrations/email/email.service';
|
||||||
import { InvalidatePassword } from 'src/core/auth/dto/invalidate-password.entity';
|
import { InvalidatePassword } from 'src/core/auth/dto/invalidate-password.entity';
|
||||||
import { EmailPasswordResetLink } from 'src/core/auth/dto/email-password-reset-link.entity';
|
import { EmailPasswordResetLink } from 'src/core/auth/dto/email-password-reset-link.entity';
|
||||||
|
import { JwtData } from 'src/core/auth/types/jwt-data.type';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class TokenService {
|
export class TokenService {
|
||||||
@ -192,10 +192,7 @@ export class TokenService {
|
|||||||
return !!token;
|
return !!token;
|
||||||
}
|
}
|
||||||
|
|
||||||
async validateToken(request: Request): Promise<{
|
async validateToken(request: Request): Promise<JwtData> {
|
||||||
user?: User;
|
|
||||||
workspace: Workspace;
|
|
||||||
}> {
|
|
||||||
const token = ExtractJwt.fromAuthHeaderAsBearerToken()(request);
|
const token = ExtractJwt.fromAuthHeaderAsBearerToken()(request);
|
||||||
|
|
||||||
if (!token) {
|
if (!token) {
|
||||||
|
|||||||
@ -0,0 +1,7 @@
|
|||||||
|
import { User } from 'src/core/user/user.entity';
|
||||||
|
import { Workspace } from 'src/core/workspace/workspace.entity';
|
||||||
|
|
||||||
|
export type JwtData = {
|
||||||
|
user?: User | undefined;
|
||||||
|
workspace: Workspace;
|
||||||
|
};
|
||||||
@ -22,6 +22,7 @@ import { EnvironmentService } from 'src/integrations/environment/environment.ser
|
|||||||
import { useExceptionHandler } from 'src/integrations/exception-handler/hooks/use-exception-handler.hook';
|
import { useExceptionHandler } from 'src/integrations/exception-handler/hooks/use-exception-handler.hook';
|
||||||
import { User } from 'src/core/user/user.entity';
|
import { User } from 'src/core/user/user.entity';
|
||||||
import { useThrottler } from 'src/integrations/throttler/hooks/use-throttler';
|
import { useThrottler } from 'src/integrations/throttler/hooks/use-throttler';
|
||||||
|
import { JwtData } from 'src/core/auth/types/jwt-data.type';
|
||||||
|
|
||||||
import { CreateContextFactory } from './factories/create-context.factory';
|
import { CreateContextFactory } from './factories/create-context.factory';
|
||||||
|
|
||||||
@ -60,7 +61,7 @@ export class GraphQLConfigService
|
|||||||
|
|
||||||
user = data.user;
|
user = data.user;
|
||||||
|
|
||||||
return await this.createSchema(context, data.workspace);
|
return await this.createSchema(context, data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof UnauthorizedException) {
|
if (error instanceof UnauthorizedException) {
|
||||||
throw new GraphQLError('Unauthenticated', {
|
throw new GraphQLError('Unauthenticated', {
|
||||||
@ -125,7 +126,7 @@ export class GraphQLConfigService
|
|||||||
|
|
||||||
async createSchema(
|
async createSchema(
|
||||||
context: YogaDriverServerContext<'express'> & YogaInitialContext,
|
context: YogaDriverServerContext<'express'> & YogaInitialContext,
|
||||||
workspace: Workspace,
|
data: JwtData,
|
||||||
): Promise<GraphQLSchemaWithContext<YogaDriverServerContext<'express'>>> {
|
): Promise<GraphQLSchemaWithContext<YogaDriverServerContext<'express'>>> {
|
||||||
// Create a new contextId for each request
|
// Create a new contextId for each request
|
||||||
const contextId = ContextIdFactory.create();
|
const contextId = ContextIdFactory.create();
|
||||||
@ -142,6 +143,9 @@ export class GraphQLConfigService
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
return await workspaceFactory.createGraphQLSchema(workspace.id);
|
return await workspaceFactory.createGraphQLSchema(
|
||||||
|
data.workspace.id,
|
||||||
|
data.user?.id,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,10 +17,10 @@ import { EmailSenderJob } from 'src/integrations/email/email-sender.job';
|
|||||||
import { UserModule } from 'src/core/user/user.module';
|
import { UserModule } from 'src/core/user/user.module';
|
||||||
import { EnvironmentModule } from 'src/integrations/environment/environment.module';
|
import { EnvironmentModule } from 'src/integrations/environment/environment.module';
|
||||||
import { FeatureFlagEntity } from 'src/core/feature-flag/feature-flag.entity';
|
import { FeatureFlagEntity } from 'src/core/feature-flag/feature-flag.entity';
|
||||||
import { FetchAllWorkspacesMessagesJob } from 'src/workspace/messaging/crons/fetch-all-workspaces-messages.job';
|
import { FetchAllWorkspacesMessagesJob } from 'src/workspace/messaging/commands/crons/fetch-all-workspaces-messages.job';
|
||||||
import { ConnectedAccountModule } from 'src/workspace/messaging/connected-account/connected-account.module';
|
import { ConnectedAccountModule } from 'src/workspace/messaging/repositories/connected-account/connected-account.module';
|
||||||
import { MatchMessageParticipantJob } from 'src/workspace/messaging/jobs/match-message-participant.job';
|
import { MatchMessageParticipantJob } from 'src/workspace/messaging/jobs/match-message-participant.job';
|
||||||
import { MessageParticipantModule } from 'src/workspace/messaging/message-participant/message-participant.module';
|
import { MessageParticipantModule } from 'src/workspace/messaging/repositories/message-participant/message-participant.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import {
|
|||||||
} from 'src/core/feature-flag/feature-flag.entity';
|
} from 'src/core/feature-flag/feature-flag.entity';
|
||||||
import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants';
|
import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants';
|
||||||
import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service';
|
import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service';
|
||||||
import { ConnectedAccountService } from 'src/workspace/messaging/connected-account/connected-account.service';
|
import { ConnectedAccountService } from 'src/workspace/messaging/repositories/connected-account/connected-account.service';
|
||||||
import {
|
import {
|
||||||
GmailPartialSyncJobData,
|
GmailPartialSyncJobData,
|
||||||
GmailPartialSyncJob,
|
GmailPartialSyncJob,
|
||||||
@ -6,7 +6,7 @@ import { TypeORMModule } from 'src/database/typeorm/typeorm.module';
|
|||||||
import { DataSourceModule } from 'src/metadata/data-source/data-source.module';
|
import { DataSourceModule } from 'src/metadata/data-source/data-source.module';
|
||||||
import { GmailFullSyncCommand } from 'src/workspace/messaging/commands/gmail-full-sync.command';
|
import { GmailFullSyncCommand } from 'src/workspace/messaging/commands/gmail-full-sync.command';
|
||||||
import { GmailPartialSyncCommand } from 'src/workspace/messaging/commands/gmail-partial-sync.command';
|
import { GmailPartialSyncCommand } from 'src/workspace/messaging/commands/gmail-partial-sync.command';
|
||||||
import { ConnectedAccountModule } from 'src/workspace/messaging/connected-account/connected-account.module';
|
import { ConnectedAccountModule } from 'src/workspace/messaging/repositories/connected-account/connected-account.module';
|
||||||
import { StartFetchAllWorkspacesMessagesCronCommand } from 'src/workspace/messaging/commands/start-fetch-all-workspaces-messages.cron.command';
|
import { StartFetchAllWorkspacesMessagesCronCommand } from 'src/workspace/messaging/commands/start-fetch-all-workspaces-messages.cron.command';
|
||||||
import { StopFetchAllWorkspacesMessagesCronCommand } from 'src/workspace/messaging/commands/stop-fetch-all-workspaces-messages.cron.command';
|
import { StopFetchAllWorkspacesMessagesCronCommand } from 'src/workspace/messaging/commands/stop-fetch-all-workspaces-messages.cron.command';
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import {
|
|||||||
GmailFullSyncJobData,
|
GmailFullSyncJobData,
|
||||||
GmailFullSyncJob,
|
GmailFullSyncJob,
|
||||||
} from 'src/workspace/messaging/jobs/gmail-full-sync.job';
|
} from 'src/workspace/messaging/jobs/gmail-full-sync.job';
|
||||||
import { ConnectedAccountService } from 'src/workspace/messaging/connected-account/connected-account.service';
|
import { ConnectedAccountService } from 'src/workspace/messaging/repositories/connected-account/connected-account.service';
|
||||||
|
|
||||||
interface GmailFullSyncOptions {
|
interface GmailFullSyncOptions {
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import {
|
|||||||
GmailPartialSyncJob,
|
GmailPartialSyncJob,
|
||||||
GmailPartialSyncJobData,
|
GmailPartialSyncJobData,
|
||||||
} from 'src/workspace/messaging/jobs/gmail-partial-sync.job';
|
} from 'src/workspace/messaging/jobs/gmail-partial-sync.job';
|
||||||
import { ConnectedAccountService } from 'src/workspace/messaging/connected-account/connected-account.service';
|
import { ConnectedAccountService } from 'src/workspace/messaging/repositories/connected-account/connected-account.service';
|
||||||
|
|
||||||
interface GmailPartialSyncOptions {
|
interface GmailPartialSyncOptions {
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
|
|||||||
@ -4,8 +4,8 @@ import { Command, CommandRunner } from 'nest-commander';
|
|||||||
|
|
||||||
import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants';
|
import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants';
|
||||||
import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service';
|
import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service';
|
||||||
import { fetchAllWorkspacesMessagesCronPattern } from 'src/workspace/messaging/crons/fetch-all-workspaces-messages.cron.pattern';
|
import { fetchAllWorkspacesMessagesCronPattern } from 'src/workspace/messaging/commands/crons/fetch-all-workspaces-messages.cron.pattern';
|
||||||
import { FetchAllWorkspacesMessagesJob } from 'src/workspace/messaging/crons/fetch-all-workspaces-messages.job';
|
import { FetchAllWorkspacesMessagesJob } from 'src/workspace/messaging/commands/crons/fetch-all-workspaces-messages.job';
|
||||||
|
|
||||||
@Command({
|
@Command({
|
||||||
name: 'fetch-all-workspaces-messages:cron:start',
|
name: 'fetch-all-workspaces-messages:cron:start',
|
||||||
|
|||||||
@ -4,8 +4,8 @@ import { Command, CommandRunner } from 'nest-commander';
|
|||||||
|
|
||||||
import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants';
|
import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants';
|
||||||
import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service';
|
import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service';
|
||||||
import { fetchAllWorkspacesMessagesCronPattern } from 'src/workspace/messaging/crons/fetch-all-workspaces-messages.cron.pattern';
|
import { fetchAllWorkspacesMessagesCronPattern } from 'src/workspace/messaging/commands/crons/fetch-all-workspaces-messages.cron.pattern';
|
||||||
import { FetchAllWorkspacesMessagesJob } from 'src/workspace/messaging/crons/fetch-all-workspaces-messages.job';
|
import { FetchAllWorkspacesMessagesJob } from 'src/workspace/messaging/commands/crons/fetch-all-workspaces-messages.job';
|
||||||
|
|
||||||
@Command({
|
@Command({
|
||||||
name: 'fetch-all-workspaces-messages:cron:stop',
|
name: 'fetch-all-workspaces-messages:cron:stop',
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { Injectable, Logger } from '@nestjs/common';
|
|||||||
|
|
||||||
import { MessageQueueJob } from 'src/integrations/message-queue/interfaces/message-queue-job.interface';
|
import { MessageQueueJob } from 'src/integrations/message-queue/interfaces/message-queue-job.interface';
|
||||||
|
|
||||||
import { MessageChannelMessageAssociationService } from 'src/workspace/messaging/message-channel-message-association/message-channel-message-association.service';
|
import { MessageChannelMessageAssociationService } from 'src/workspace/messaging/repositories/message-channel-message-association/message-channel-message-association.service';
|
||||||
|
|
||||||
export type DeleteMessageChannelMessageAssociationJobData = {
|
export type DeleteMessageChannelMessageAssociationJobData = {
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common';
|
|||||||
|
|
||||||
import { MessageQueueJob } from 'src/integrations/message-queue/interfaces/message-queue-job.interface';
|
import { MessageQueueJob } from 'src/integrations/message-queue/interfaces/message-queue-job.interface';
|
||||||
|
|
||||||
import { MessageParticipantService } from 'src/workspace/messaging/message-participant/message-participant.service';
|
import { MessageParticipantService } from 'src/workspace/messaging/repositories/message-participant/message-participant.service';
|
||||||
|
|
||||||
export type MatchMessageParticipantsJobData = {
|
export type MatchMessageParticipantsJobData = {
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
|
|||||||
@ -1,25 +1,25 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
import { ConnectedAccountModule } from 'src/workspace/messaging/connected-account/connected-account.module';
|
import { ConnectedAccountModule } from 'src/workspace/messaging/repositories/connected-account/connected-account.module';
|
||||||
import { MessageChannelMessageAssociationModule } from 'src/workspace/messaging/message-channel-message-association/message-channel-message-assocation.module';
|
import { MessageChannelMessageAssociationModule } from 'src/workspace/messaging/repositories/message-channel-message-association/message-channel-message-assocation.module';
|
||||||
import { MessageChannelModule } from 'src/workspace/messaging/message-channel/message-channel.module';
|
import { MessageChannelModule } from 'src/workspace/messaging/repositories/message-channel/message-channel.module';
|
||||||
import { MessageThreadModule } from 'src/workspace/messaging/message-thread/message-thread.module';
|
import { MessageThreadModule } from 'src/workspace/messaging/repositories/message-thread/message-thread.module';
|
||||||
import { EnvironmentModule } from 'src/integrations/environment/environment.module';
|
import { EnvironmentModule } from 'src/integrations/environment/environment.module';
|
||||||
import { MessagingPersonListener } from 'src/workspace/messaging/listeners/messaging-person.listener';
|
import { MessagingPersonListener } from 'src/workspace/messaging/listeners/messaging-person.listener';
|
||||||
import { MessageModule } from 'src/workspace/messaging/message/message.module';
|
import { MessageModule } from 'src/workspace/messaging/repositories/message/message.module';
|
||||||
import { GmailClientProvider } from 'src/workspace/messaging/providers/gmail/gmail-client.provider';
|
import { GmailClientProvider } from 'src/workspace/messaging/services/providers/gmail/gmail-client.provider';
|
||||||
import { CreateContactService } from 'src/workspace/messaging/create-contact/create-contact.service';
|
import { CreateContactService } from 'src/workspace/messaging/services/create-contact/create-contact.service';
|
||||||
import { CreateCompanyService } from 'src/workspace/messaging/create-company/create-company.service';
|
import { CreateCompanyService } from 'src/workspace/messaging/services/create-company/create-company.service';
|
||||||
import { FetchMessagesByBatchesService } from 'src/workspace/messaging/services/fetch-messages-by-batches.service';
|
import { FetchMessagesByBatchesService } from 'src/workspace/messaging/services/fetch-messages-by-batches.service';
|
||||||
import { GmailFullSyncService } from 'src/workspace/messaging/services/gmail-full-sync.service';
|
import { GmailFullSyncService } from 'src/workspace/messaging/services/gmail-full-sync.service';
|
||||||
import { GmailPartialSyncService } from 'src/workspace/messaging/services/gmail-partial-sync.service';
|
import { GmailPartialSyncService } from 'src/workspace/messaging/services/gmail-partial-sync.service';
|
||||||
import { GmailRefreshAccessTokenService } from 'src/workspace/messaging/services/gmail-refresh-access-token.service';
|
import { GmailRefreshAccessTokenService } from 'src/workspace/messaging/services/gmail-refresh-access-token.service';
|
||||||
import { WorkspaceDataSourceModule } from 'src/workspace/workspace-datasource/workspace-datasource.module';
|
import { WorkspaceDataSourceModule } from 'src/workspace/workspace-datasource/workspace-datasource.module';
|
||||||
import { MessageParticipantModule } from 'src/workspace/messaging/message-participant/message-participant.module';
|
import { MessageParticipantModule } from 'src/workspace/messaging/repositories/message-participant/message-participant.module';
|
||||||
import { MessagingWorkspaceMemberListener } from 'src/workspace/messaging/listeners/messaging-workspace-member.listener';
|
import { MessagingWorkspaceMemberListener } from 'src/workspace/messaging/listeners/messaging-workspace-member.listener';
|
||||||
import { MessagingMessageChannelListener } from 'src/workspace/messaging/listeners/messaging-message-channel.listener';
|
import { MessagingMessageChannelListener } from 'src/workspace/messaging/listeners/messaging-message-channel.listener';
|
||||||
import { MessageService } from 'src/workspace/messaging/message/message.service';
|
import { MessageService } from 'src/workspace/messaging/repositories/message/message.service';
|
||||||
|
import { WorkspaceMemberModule } from 'src/workspace/messaging/repositories/workspace-member/workspace-member.module';
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
EnvironmentModule,
|
EnvironmentModule,
|
||||||
@ -30,6 +30,7 @@ import { MessageService } from 'src/workspace/messaging/message/message.service'
|
|||||||
MessageModule,
|
MessageModule,
|
||||||
MessageThreadModule,
|
MessageThreadModule,
|
||||||
MessageParticipantModule,
|
MessageParticipantModule,
|
||||||
|
WorkspaceMemberModule,
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
GmailFullSyncService,
|
GmailFullSyncService,
|
||||||
|
|||||||
@ -0,0 +1,94 @@
|
|||||||
|
import {
|
||||||
|
BadRequestException,
|
||||||
|
ForbiddenException,
|
||||||
|
Injectable,
|
||||||
|
NotFoundException,
|
||||||
|
} from '@nestjs/common';
|
||||||
|
|
||||||
|
import { groupBy } from 'lodash';
|
||||||
|
|
||||||
|
import { WorkspacePreQueryHook } from 'src/workspace/workspace-query-runner/workspace-pre-query-hook/interfaces/workspace-pre-query-hook.interface';
|
||||||
|
import { FindManyResolverArgs } from 'src/workspace/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||||
|
|
||||||
|
import { MessageChannelMessageAssociationService } from 'src/workspace/messaging/repositories/message-channel-message-association/message-channel-message-association.service';
|
||||||
|
import { MessageChannelService } from 'src/workspace/messaging/repositories/message-channel/message-channel.service';
|
||||||
|
import { ConnectedAccountService } from 'src/workspace/messaging/repositories/connected-account/connected-account.service';
|
||||||
|
import { WorkspaceMemberService } from 'src/workspace/messaging/repositories/workspace-member/workspace-member.service';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class MessageFindManyPreQueryHook implements WorkspacePreQueryHook {
|
||||||
|
constructor(
|
||||||
|
private readonly messageChannelMessageAssociationService: MessageChannelMessageAssociationService,
|
||||||
|
private readonly messageChannelService: MessageChannelService,
|
||||||
|
private readonly connectedAccountService: ConnectedAccountService,
|
||||||
|
private readonly workspaceMemberService: WorkspaceMemberService,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async execute(
|
||||||
|
userId: string,
|
||||||
|
workspaceId: string,
|
||||||
|
payload: FindManyResolverArgs,
|
||||||
|
): Promise<void> {
|
||||||
|
if (!payload?.filter?.messageThreadId?.eq) {
|
||||||
|
throw new BadRequestException('messageThreadId filter is required');
|
||||||
|
}
|
||||||
|
|
||||||
|
const messageChannelMessageAssociations =
|
||||||
|
await this.messageChannelMessageAssociationService.getByMessageThreadId(
|
||||||
|
payload?.filter?.messageThreadId?.eq,
|
||||||
|
workspaceId,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (messageChannelMessageAssociations.length === 0) {
|
||||||
|
throw new NotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.canAccessMessageThread(
|
||||||
|
userId,
|
||||||
|
workspaceId,
|
||||||
|
messageChannelMessageAssociations,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async canAccessMessageThread(
|
||||||
|
userId: string,
|
||||||
|
workspaceId: string,
|
||||||
|
messageChannelMessageAssociations: any[],
|
||||||
|
) {
|
||||||
|
const messageChannels = await this.messageChannelService.getByIds(
|
||||||
|
messageChannelMessageAssociations.map(
|
||||||
|
(association) => association.messageChannelId,
|
||||||
|
),
|
||||||
|
workspaceId,
|
||||||
|
);
|
||||||
|
|
||||||
|
const messageChannelsGroupByVisibility = groupBy(
|
||||||
|
messageChannels,
|
||||||
|
(channel) => channel.visibility,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (messageChannelsGroupByVisibility.share_everything) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentWorkspaceMember =
|
||||||
|
await this.workspaceMemberService.getByIdOrFail(userId, workspaceId);
|
||||||
|
|
||||||
|
const messageChannelsConnectedAccounts =
|
||||||
|
await this.connectedAccountService.getByIds(
|
||||||
|
messageChannels.map((channel) => channel.connectedAccountId),
|
||||||
|
workspaceId,
|
||||||
|
);
|
||||||
|
|
||||||
|
const messageChannelsWorkspaceMemberIds =
|
||||||
|
messageChannelsConnectedAccounts.map(
|
||||||
|
(connectedAccount) => connectedAccount.accountOwnerId,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (messageChannelsWorkspaceMemberIds.includes(currentWorkspaceMember.id)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ForbiddenException();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||||
|
import { BadRequestException, Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { WorkspacePreQueryHook } from 'src/workspace/workspace-query-runner/workspace-pre-query-hook/interfaces/workspace-pre-query-hook.interface';
|
||||||
|
import { FindOneResolverArgs } from 'src/workspace/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class MessageFindOnePreQueryHook implements WorkspacePreQueryHook {
|
||||||
|
async execute(
|
||||||
|
_userId: string,
|
||||||
|
_workspaceId: string,
|
||||||
|
_payload: FindOneResolverArgs,
|
||||||
|
): Promise<void> {
|
||||||
|
throw new BadRequestException('Method not implemented.');
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { MessageFindManyPreQueryHook } from 'src/workspace/messaging/query-hooks/message/message-find-many.pre-query.hook';
|
||||||
|
import { MessageFindOnePreQueryHook } from 'src/workspace/messaging/query-hooks/message/message-find-one.pre-query-hook';
|
||||||
|
import { ConnectedAccountModule } from 'src/workspace/messaging/repositories/connected-account/connected-account.module';
|
||||||
|
import { MessageChannelMessageAssociationModule } from 'src/workspace/messaging/repositories/message-channel-message-association/message-channel-message-assocation.module';
|
||||||
|
import { MessageChannelModule } from 'src/workspace/messaging/repositories/message-channel/message-channel.module';
|
||||||
|
import { WorkspaceMemberModule } from 'src/workspace/messaging/repositories/workspace-member/workspace-member.module';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [
|
||||||
|
MessageChannelMessageAssociationModule,
|
||||||
|
MessageChannelModule,
|
||||||
|
ConnectedAccountModule,
|
||||||
|
WorkspaceMemberModule,
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
provide: MessageFindOnePreQueryHook.name,
|
||||||
|
useClass: MessageFindOnePreQueryHook,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: MessageFindManyPreQueryHook.name,
|
||||||
|
useClass: MessageFindManyPreQueryHook,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class MessagingQueryHookModule {}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
import { ConnectedAccountService } from 'src/workspace/messaging/connected-account/connected-account.service';
|
import { ConnectedAccountService } from 'src/workspace/messaging/repositories/connected-account/connected-account.service';
|
||||||
import { WorkspaceDataSourceModule } from 'src/workspace/workspace-datasource/workspace-datasource.module';
|
import { WorkspaceDataSourceModule } from 'src/workspace/workspace-datasource/workspace-datasource.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||||
|
|
||||||
import { EntityManager } from 'typeorm';
|
import { EntityManager } from 'typeorm';
|
||||||
|
|
||||||
@ -27,6 +27,22 @@ export class ConnectedAccountService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async getByIds(
|
||||||
|
connectedAccountIds: string[],
|
||||||
|
workspaceId: string,
|
||||||
|
transactionManager?: EntityManager,
|
||||||
|
): Promise<ObjectRecord<ConnectedAccountObjectMetadata>[]> {
|
||||||
|
const dataSourceSchema =
|
||||||
|
this.workspaceDataSourceService.getSchemaName(workspaceId);
|
||||||
|
|
||||||
|
return await this.workspaceDataSourceService.executeRawQuery(
|
||||||
|
`SELECT * FROM ${dataSourceSchema}."connectedAccount" WHERE "id" = ANY($1)`,
|
||||||
|
[connectedAccountIds],
|
||||||
|
workspaceId,
|
||||||
|
transactionManager,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public async getByIdOrFail(
|
public async getByIdOrFail(
|
||||||
connectedAccountId: string,
|
connectedAccountId: string,
|
||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
@ -44,7 +60,7 @@ export class ConnectedAccountService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!connectedAccounts || connectedAccounts.length === 0) {
|
if (!connectedAccounts || connectedAccounts.length === 0) {
|
||||||
throw new Error('No connected account found');
|
throw new NotFoundException('No connected account found');
|
||||||
}
|
}
|
||||||
|
|
||||||
return connectedAccounts[0];
|
return connectedAccounts[0];
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
import { MessageChannelMessageAssociationService } from 'src/workspace/messaging/message-channel-message-association/message-channel-message-association.service';
|
import { MessageChannelMessageAssociationService } from 'src/workspace/messaging/repositories/message-channel-message-association/message-channel-message-association.service';
|
||||||
import { WorkspaceDataSourceModule } from 'src/workspace/workspace-datasource/workspace-datasource.module';
|
import { WorkspaceDataSourceModule } from 'src/workspace/workspace-datasource/workspace-datasource.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
@ -154,4 +154,21 @@ export class MessageChannelMessageAssociationService {
|
|||||||
transactionManager,
|
transactionManager,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async getByMessageThreadId(
|
||||||
|
messageThreadId: string,
|
||||||
|
workspaceId: string,
|
||||||
|
transactionManager?: EntityManager,
|
||||||
|
): Promise<ObjectRecord<MessageChannelMessageAssociationObjectMetadata>[]> {
|
||||||
|
const dataSourceSchema =
|
||||||
|
this.workspaceDataSourceService.getSchemaName(workspaceId);
|
||||||
|
|
||||||
|
return await this.workspaceDataSourceService.executeRawQuery(
|
||||||
|
`SELECT * FROM ${dataSourceSchema}."messageChannelMessageAssociation"
|
||||||
|
WHERE "messageThreadId" = $1`,
|
||||||
|
[messageThreadId],
|
||||||
|
workspaceId,
|
||||||
|
transactionManager,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
import { MessageChannelService } from 'src/workspace/messaging/message-channel/message-channel.service';
|
import { MessageChannelService } from 'src/workspace/messaging/repositories/message-channel/message-channel.service';
|
||||||
import { WorkspaceDataSourceModule } from 'src/workspace/workspace-datasource/workspace-datasource.module';
|
import { WorkspaceDataSourceModule } from 'src/workspace/workspace-datasource/workspace-datasource.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
@ -43,4 +43,20 @@ export class MessageChannelService {
|
|||||||
|
|
||||||
return messageChannels[0];
|
return messageChannels[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async getByIds(
|
||||||
|
ids: string[],
|
||||||
|
workspaceId: string,
|
||||||
|
transactionManager?: EntityManager,
|
||||||
|
): Promise<ObjectRecord<MessageChannelObjectMetadata>[]> {
|
||||||
|
const dataSourceSchema =
|
||||||
|
this.workspaceDataSourceService.getSchemaName(workspaceId);
|
||||||
|
|
||||||
|
return await this.workspaceDataSourceService.executeRawQuery(
|
||||||
|
`SELECT * FROM ${dataSourceSchema}."messageChannel" WHERE "id" = ANY($1)`,
|
||||||
|
[ids],
|
||||||
|
workspaceId,
|
||||||
|
transactionManager,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -1,8 +1,8 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
import { CreateCompanyModule } from 'src/workspace/messaging/create-company/create-company.module';
|
import { CreateCompanyModule } from 'src/workspace/messaging/services/create-company/create-company.module';
|
||||||
import { CreateContactModule } from 'src/workspace/messaging/create-contact/create-contact.module';
|
import { CreateContactModule } from 'src/workspace/messaging/services/create-contact/create-contact.module';
|
||||||
import { MessageParticipantService } from 'src/workspace/messaging/message-participant/message-participant.service';
|
import { MessageParticipantService } from 'src/workspace/messaging/repositories/message-participant/message-participant.service';
|
||||||
import { WorkspaceDataSourceModule } from 'src/workspace/workspace-datasource/workspace-datasource.module';
|
import { WorkspaceDataSourceModule } from 'src/workspace/workspace-datasource/workspace-datasource.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
@ -7,8 +7,8 @@ import { MessageParticipantObjectMetadata } from 'src/workspace/workspace-sync-m
|
|||||||
import { ObjectRecord } from 'src/workspace/workspace-sync-metadata/types/object-record';
|
import { ObjectRecord } from 'src/workspace/workspace-sync-metadata/types/object-record';
|
||||||
import { DataSourceEntity } from 'src/metadata/data-source/data-source.entity';
|
import { DataSourceEntity } from 'src/metadata/data-source/data-source.entity';
|
||||||
import { Participant } from 'src/workspace/messaging/types/gmail-message';
|
import { Participant } from 'src/workspace/messaging/types/gmail-message';
|
||||||
import { CreateContactService } from 'src/workspace/messaging/create-contact/create-contact.service';
|
import { CreateContactService } from 'src/workspace/messaging/services/create-contact/create-contact.service';
|
||||||
import { CreateCompanyService } from 'src/workspace/messaging/create-company/create-company.service';
|
import { CreateCompanyService } from 'src/workspace/messaging/services/create-company/create-company.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class MessageParticipantService {
|
export class MessageParticipantService {
|
||||||
@ -1,7 +1,7 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
import { MessageChannelMessageAssociationModule } from 'src/workspace/messaging/message-channel-message-association/message-channel-message-assocation.module';
|
import { MessageChannelMessageAssociationModule } from 'src/workspace/messaging/repositories/message-channel-message-association/message-channel-message-assocation.module';
|
||||||
import { MessageThreadService } from 'src/workspace/messaging/message-thread/message-thread.service';
|
import { MessageThreadService } from 'src/workspace/messaging/repositories/message-thread/message-thread.service';
|
||||||
import { WorkspaceDataSourceModule } from 'src/workspace/workspace-datasource/workspace-datasource.module';
|
import { WorkspaceDataSourceModule } from 'src/workspace/workspace-datasource/workspace-datasource.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
@ -5,7 +5,7 @@ import { v4 } from 'uuid';
|
|||||||
|
|
||||||
import { WorkspaceDataSourceService } from 'src/workspace/workspace-datasource/workspace-datasource.service';
|
import { WorkspaceDataSourceService } from 'src/workspace/workspace-datasource/workspace-datasource.service';
|
||||||
import { DataSourceEntity } from 'src/metadata/data-source/data-source.entity';
|
import { DataSourceEntity } from 'src/metadata/data-source/data-source.entity';
|
||||||
import { MessageChannelMessageAssociationService } from 'src/workspace/messaging/message-channel-message-association/message-channel-message-association.service';
|
import { MessageChannelMessageAssociationService } from 'src/workspace/messaging/repositories/message-channel-message-association/message-channel-message-association.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class MessageThreadService {
|
export class MessageThreadService {
|
||||||
@ -1,9 +1,9 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
import { MessageChannelMessageAssociationModule } from 'src/workspace/messaging/message-channel-message-association/message-channel-message-assocation.module';
|
import { MessageChannelMessageAssociationModule } from 'src/workspace/messaging/repositories/message-channel-message-association/message-channel-message-assocation.module';
|
||||||
import { MessageParticipantModule } from 'src/workspace/messaging/message-participant/message-participant.module';
|
import { MessageParticipantModule } from 'src/workspace/messaging/repositories/message-participant/message-participant.module';
|
||||||
import { MessageThreadModule } from 'src/workspace/messaging/message-thread/message-thread.module';
|
import { MessageThreadModule } from 'src/workspace/messaging/repositories/message-thread/message-thread.module';
|
||||||
import { MessageService } from 'src/workspace/messaging/message/message.service';
|
import { MessageService } from 'src/workspace/messaging/repositories/message/message.service';
|
||||||
import { WorkspaceDataSourceModule } from 'src/workspace/workspace-datasource/workspace-datasource.module';
|
import { WorkspaceDataSourceModule } from 'src/workspace/workspace-datasource/workspace-datasource.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
@ -9,11 +9,10 @@ import { ObjectRecord } from 'src/workspace/workspace-sync-metadata/types/object
|
|||||||
import { DataSourceEntity } from 'src/metadata/data-source/data-source.entity';
|
import { DataSourceEntity } from 'src/metadata/data-source/data-source.entity';
|
||||||
import { GmailMessage } from 'src/workspace/messaging/types/gmail-message';
|
import { GmailMessage } from 'src/workspace/messaging/types/gmail-message';
|
||||||
import { ConnectedAccountObjectMetadata } from 'src/workspace/workspace-sync-metadata/standard-objects/connected-account.object-metadata';
|
import { ConnectedAccountObjectMetadata } from 'src/workspace/workspace-sync-metadata/standard-objects/connected-account.object-metadata';
|
||||||
import { MessageChannelMessageAssociationService } from 'src/workspace/messaging/message-channel-message-association/message-channel-message-association.service';
|
import { MessageChannelMessageAssociationService } from 'src/workspace/messaging/repositories/message-channel-message-association/message-channel-message-association.service';
|
||||||
import { MessageThreadService } from 'src/workspace/messaging/message-thread/message-thread.service';
|
import { MessageParticipantService } from 'src/workspace/messaging/repositories/message-participant/message-participant.service';
|
||||||
import { MessageParticipantService } from 'src/workspace/messaging/message-participant/message-participant.service';
|
import { MessageThreadService } from 'src/workspace/messaging/repositories/message-thread/message-thread.service';
|
||||||
import { isPersonEmail } from 'src/workspace/messaging/utils/is-person-email.util';
|
import { isPersonEmail } from 'src/workspace/messaging/utils/is-person-email.util';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class MessageService {
|
export class MessageService {
|
||||||
constructor(
|
constructor(
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { WorkspaceMemberService } from 'src/workspace/messaging/repositories/workspace-member/workspace-member.service';
|
||||||
|
import { WorkspaceDataSourceModule } from 'src/workspace/workspace-datasource/workspace-datasource.module';
|
||||||
|
|
||||||
|
// TODO: Move outside of the messaging module
|
||||||
|
@Module({
|
||||||
|
imports: [WorkspaceDataSourceModule],
|
||||||
|
providers: [WorkspaceMemberService],
|
||||||
|
exports: [WorkspaceMemberService],
|
||||||
|
})
|
||||||
|
export class WorkspaceMemberModule {}
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { WorkspaceDataSourceService } from 'src/workspace/workspace-datasource/workspace-datasource.service';
|
||||||
|
import { WorkspaceMemberObjectMetadata } from 'src/workspace/workspace-sync-metadata/standard-objects/workspace-member.object-metadata';
|
||||||
|
import { ObjectRecord } from 'src/workspace/workspace-sync-metadata/types/object-record';
|
||||||
|
|
||||||
|
// TODO: Move outside of the messaging module
|
||||||
|
@Injectable()
|
||||||
|
export class WorkspaceMemberService {
|
||||||
|
constructor(
|
||||||
|
private readonly workspaceDataSourceService: WorkspaceDataSourceService,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public async getByIds(
|
||||||
|
userIds: string[],
|
||||||
|
workspaceId: string,
|
||||||
|
): Promise<ObjectRecord<WorkspaceMemberObjectMetadata>[]> {
|
||||||
|
const dataSourceSchema =
|
||||||
|
this.workspaceDataSourceService.getSchemaName(workspaceId);
|
||||||
|
|
||||||
|
const result = await this.workspaceDataSourceService.executeRawQuery(
|
||||||
|
`SELECT * FROM ${dataSourceSchema}."workspaceMember" WHERE "userId" = ANY($1)`,
|
||||||
|
[userIds],
|
||||||
|
workspaceId,
|
||||||
|
);
|
||||||
|
|
||||||
|
return result.rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getByIdOrFail(
|
||||||
|
userId: string,
|
||||||
|
workspaceId: string,
|
||||||
|
): Promise<ObjectRecord<WorkspaceMemberObjectMetadata>> {
|
||||||
|
const dataSourceSchema =
|
||||||
|
this.workspaceDataSourceService.getSchemaName(workspaceId);
|
||||||
|
|
||||||
|
const workspaceMembers =
|
||||||
|
await this.workspaceDataSourceService.executeRawQuery(
|
||||||
|
`SELECT * FROM ${dataSourceSchema}."workspaceMember" WHERE "userId" = $1`,
|
||||||
|
[userId],
|
||||||
|
workspaceId,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!workspaceMembers || workspaceMembers.length === 0) {
|
||||||
|
throw new NotFoundException('No workspace member found');
|
||||||
|
}
|
||||||
|
|
||||||
|
return workspaceMembers[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
import { CreateCompanyService } from 'src/workspace/messaging/create-company/create-company.service';
|
import { CreateCompanyService } from 'src/workspace/messaging/services/create-company/create-company.service';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [],
|
imports: [],
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
import { CreateContactService } from 'src/workspace/messaging/create-contact/create-contact.service';
|
import { CreateContactService } from 'src/workspace/messaging/services/create-contact/create-contact.service';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [],
|
imports: [],
|
||||||
@ -1,18 +1,18 @@
|
|||||||
import { Inject, Injectable, Logger } from '@nestjs/common';
|
import { Inject, Injectable, Logger } from '@nestjs/common';
|
||||||
|
|
||||||
import { FetchMessagesByBatchesService } from 'src/workspace/messaging/services/fetch-messages-by-batches.service';
|
import { FetchMessagesByBatchesService } from 'src/workspace/messaging/services/fetch-messages-by-batches.service';
|
||||||
import { GmailClientProvider } from 'src/workspace/messaging/providers/gmail/gmail-client.provider';
|
import { GmailClientProvider } from 'src/workspace/messaging/services/providers/gmail/gmail-client.provider';
|
||||||
import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants';
|
import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants';
|
||||||
import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service';
|
import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service';
|
||||||
import {
|
import {
|
||||||
GmailFullSyncJobData,
|
GmailFullSyncJobData,
|
||||||
GmailFullSyncJob,
|
GmailFullSyncJob,
|
||||||
} from 'src/workspace/messaging/jobs/gmail-full-sync.job';
|
} from 'src/workspace/messaging/jobs/gmail-full-sync.job';
|
||||||
import { ConnectedAccountService } from 'src/workspace/messaging/connected-account/connected-account.service';
|
import { ConnectedAccountService } from 'src/workspace/messaging/repositories/connected-account/connected-account.service';
|
||||||
import { MessageChannelService } from 'src/workspace/messaging/message-channel/message-channel.service';
|
import { MessageChannelService } from 'src/workspace/messaging/repositories/message-channel/message-channel.service';
|
||||||
import { MessageChannelMessageAssociationService } from 'src/workspace/messaging/message-channel-message-association/message-channel-message-association.service';
|
import { MessageChannelMessageAssociationService } from 'src/workspace/messaging/repositories/message-channel-message-association/message-channel-message-association.service';
|
||||||
import { WorkspaceDataSourceService } from 'src/workspace/workspace-datasource/workspace-datasource.service';
|
import { WorkspaceDataSourceService } from 'src/workspace/workspace-datasource/workspace-datasource.service';
|
||||||
import { MessageService } from 'src/workspace/messaging/message/message.service';
|
import { MessageService } from 'src/workspace/messaging/repositories/message/message.service';
|
||||||
import { createQueriesFromMessageIds } from 'src/workspace/messaging/utils/create-queries-from-message-ids.util';
|
import { createQueriesFromMessageIds } from 'src/workspace/messaging/utils/create-queries-from-message-ids.util';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
|||||||
@ -3,17 +3,17 @@ import { Inject, Injectable, Logger } from '@nestjs/common';
|
|||||||
import { gmail_v1 } from 'googleapis';
|
import { gmail_v1 } from 'googleapis';
|
||||||
|
|
||||||
import { FetchMessagesByBatchesService } from 'src/workspace/messaging/services/fetch-messages-by-batches.service';
|
import { FetchMessagesByBatchesService } from 'src/workspace/messaging/services/fetch-messages-by-batches.service';
|
||||||
import { GmailClientProvider } from 'src/workspace/messaging/providers/gmail/gmail-client.provider';
|
import { GmailClientProvider } from 'src/workspace/messaging/services/providers/gmail/gmail-client.provider';
|
||||||
import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service';
|
import { MessageQueueService } from 'src/integrations/message-queue/services/message-queue.service';
|
||||||
import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants';
|
import { MessageQueue } from 'src/integrations/message-queue/message-queue.constants';
|
||||||
import {
|
import {
|
||||||
GmailFullSyncJob,
|
GmailFullSyncJob,
|
||||||
GmailFullSyncJobData,
|
GmailFullSyncJobData,
|
||||||
} from 'src/workspace/messaging/jobs/gmail-full-sync.job';
|
} from 'src/workspace/messaging/jobs/gmail-full-sync.job';
|
||||||
import { ConnectedAccountService } from 'src/workspace/messaging/connected-account/connected-account.service';
|
import { ConnectedAccountService } from 'src/workspace/messaging/repositories/connected-account/connected-account.service';
|
||||||
import { WorkspaceDataSourceService } from 'src/workspace/workspace-datasource/workspace-datasource.service';
|
import { WorkspaceDataSourceService } from 'src/workspace/workspace-datasource/workspace-datasource.service';
|
||||||
import { MessageChannelService } from 'src/workspace/messaging/message-channel/message-channel.service';
|
import { MessageChannelService } from 'src/workspace/messaging/repositories/message-channel/message-channel.service';
|
||||||
import { MessageService } from 'src/workspace/messaging/message/message.service';
|
import { MessageService } from 'src/workspace/messaging/repositories/message/message.service';
|
||||||
import { createQueriesFromMessageIds } from 'src/workspace/messaging/utils/create-queries-from-message-ids.util';
|
import { createQueriesFromMessageIds } from 'src/workspace/messaging/utils/create-queries-from-message-ids.util';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { Injectable } from '@nestjs/common';
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
|
||||||
import { EnvironmentService } from 'src/integrations/environment/environment.service';
|
import { EnvironmentService } from 'src/integrations/environment/environment.service';
|
||||||
import { ConnectedAccountService } from 'src/workspace/messaging/connected-account/connected-account.service';
|
import { ConnectedAccountService } from 'src/workspace/messaging/repositories/connected-account/connected-account.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class GmailRefreshAccessTokenService {
|
export class GmailRefreshAccessTokenService {
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
import { EnvironmentModule } from 'src/integrations/environment/environment.module';
|
import { EnvironmentModule } from 'src/integrations/environment/environment.module';
|
||||||
import { GmailClientProvider } from 'src/workspace/messaging/providers/gmail/gmail-client.provider';
|
import { GmailClientProvider } from 'src/workspace/messaging/services/providers/gmail/gmail-client.provider';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [EnvironmentModule],
|
imports: [EnvironmentModule],
|
||||||
@ -5,6 +5,7 @@ import { ObjectMetadataInterface } from 'src/metadata/field-metadata/interfaces/
|
|||||||
|
|
||||||
export interface WorkspaceQueryRunnerOptions {
|
export interface WorkspaceQueryRunnerOptions {
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
|
userId: string | undefined;
|
||||||
info: GraphQLResolveInfo;
|
info: GraphQLResolveInfo;
|
||||||
objectMetadataItem: ObjectMetadataInterface;
|
objectMetadataItem: ObjectMetadataInterface;
|
||||||
fieldMetadataCollection: FieldMetadataInterface[];
|
fieldMetadataCollection: FieldMetadataInterface[];
|
||||||
|
|||||||
@ -0,0 +1,9 @@
|
|||||||
|
import { ResolverArgs } from 'src/workspace/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||||
|
|
||||||
|
export interface WorkspacePreQueryHook {
|
||||||
|
execute(
|
||||||
|
userId: string | undefined,
|
||||||
|
workspaceId: string,
|
||||||
|
payload: ResolverArgs,
|
||||||
|
): Promise<void>;
|
||||||
|
}
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
import {
|
||||||
|
CreateManyResolverArgs,
|
||||||
|
CreateOneResolverArgs,
|
||||||
|
DeleteManyResolverArgs,
|
||||||
|
DeleteOneResolverArgs,
|
||||||
|
FindManyResolverArgs,
|
||||||
|
FindOneResolverArgs,
|
||||||
|
UpdateManyResolverArgs,
|
||||||
|
UpdateOneResolverArgs,
|
||||||
|
} from 'src/workspace/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
||||||
|
|
||||||
|
export type ExecutePreHookMethod =
|
||||||
|
| 'createMany'
|
||||||
|
| 'createOne'
|
||||||
|
| 'deleteMany'
|
||||||
|
| 'deleteOne'
|
||||||
|
| 'findMany'
|
||||||
|
| 'findOne'
|
||||||
|
| 'updateMany'
|
||||||
|
| 'updateOne';
|
||||||
|
|
||||||
|
export type ObjectName = string;
|
||||||
|
|
||||||
|
export type HookName = string;
|
||||||
|
|
||||||
|
export type WorkspaceQueryHook = {
|
||||||
|
[key in ObjectName]: {
|
||||||
|
[key in ExecutePreHookMethod]?: HookName[];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export type WorkspacePreQueryHookPayload<T> = T extends 'createMany'
|
||||||
|
? CreateManyResolverArgs
|
||||||
|
: T extends 'createOne'
|
||||||
|
? CreateOneResolverArgs
|
||||||
|
: T extends 'deleteMany'
|
||||||
|
? DeleteManyResolverArgs
|
||||||
|
: T extends 'deleteOne'
|
||||||
|
? DeleteOneResolverArgs
|
||||||
|
: T extends 'findMany'
|
||||||
|
? FindManyResolverArgs
|
||||||
|
: T extends 'findOne'
|
||||||
|
? FindOneResolverArgs
|
||||||
|
: T extends 'updateMany'
|
||||||
|
? UpdateManyResolverArgs
|
||||||
|
: T extends 'updateOne'
|
||||||
|
? UpdateOneResolverArgs
|
||||||
|
: never;
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
import { MessageFindManyPreQueryHook } from 'src/workspace/messaging/query-hooks/message/message-find-many.pre-query.hook';
|
||||||
|
import { MessageFindOnePreQueryHook } from 'src/workspace/messaging/query-hooks/message/message-find-one.pre-query-hook';
|
||||||
|
import { WorkspaceQueryHook } from 'src/workspace/workspace-query-runner/workspace-pre-query-hook/types/workspace-query-hook.type';
|
||||||
|
|
||||||
|
// TODO: move to a decorator
|
||||||
|
export const workspacePreQueryHooks: WorkspaceQueryHook = {
|
||||||
|
message: {
|
||||||
|
findOne: [MessageFindOnePreQueryHook.name],
|
||||||
|
findMany: [MessageFindManyPreQueryHook.name],
|
||||||
|
},
|
||||||
|
};
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { MessagingQueryHookModule } from 'src/workspace/messaging/query-hooks/messaging-query-hook.module';
|
||||||
|
import { WorkspacePreQueryHookService } from 'src/workspace/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.service';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [MessagingQueryHookModule],
|
||||||
|
providers: [WorkspacePreQueryHookService],
|
||||||
|
exports: [WorkspacePreQueryHookService],
|
||||||
|
})
|
||||||
|
export class WorkspacePreQueryHookModule {}
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { ModuleRef } from '@nestjs/core';
|
||||||
|
|
||||||
|
import { WorkspacePreQueryHook } from 'src/workspace/workspace-query-runner/workspace-pre-query-hook/interfaces/workspace-pre-query-hook.interface';
|
||||||
|
|
||||||
|
import {
|
||||||
|
ExecutePreHookMethod,
|
||||||
|
WorkspacePreQueryHookPayload,
|
||||||
|
} from 'src/workspace/workspace-query-runner/workspace-pre-query-hook/types/workspace-query-hook.type';
|
||||||
|
import { workspacePreQueryHooks } from 'src/workspace/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.config';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class WorkspacePreQueryHookService {
|
||||||
|
constructor(private readonly workspaceQueryHookModuleRef: ModuleRef) {}
|
||||||
|
|
||||||
|
public async executePreHooks<T extends ExecutePreHookMethod>(
|
||||||
|
userId: string | undefined,
|
||||||
|
workspaceId: string,
|
||||||
|
objectName: string,
|
||||||
|
method: T,
|
||||||
|
payload: WorkspacePreQueryHookPayload<T>,
|
||||||
|
): Promise<void> {
|
||||||
|
const hooks = workspacePreQueryHooks[objectName] || [];
|
||||||
|
|
||||||
|
for (const hookName of Object.values(hooks[method] ?? [])) {
|
||||||
|
const hook: WorkspacePreQueryHook =
|
||||||
|
await this.workspaceQueryHookModuleRef.get(hookName, {
|
||||||
|
strict: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
await hook.execute(userId, workspaceId, payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,11 +2,16 @@ import { Module } from '@nestjs/common';
|
|||||||
|
|
||||||
import { WorkspaceQueryBuilderModule } from 'src/workspace/workspace-query-builder/workspace-query-builder.module';
|
import { WorkspaceQueryBuilderModule } from 'src/workspace/workspace-query-builder/workspace-query-builder.module';
|
||||||
import { WorkspaceDataSourceModule } from 'src/workspace/workspace-datasource/workspace-datasource.module';
|
import { WorkspaceDataSourceModule } from 'src/workspace/workspace-datasource/workspace-datasource.module';
|
||||||
|
import { WorkspacePreQueryHookModule } from 'src/workspace/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.module';
|
||||||
|
|
||||||
import { WorkspaceQueryRunnerService } from './workspace-query-runner.service';
|
import { WorkspaceQueryRunnerService } from './workspace-query-runner.service';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [WorkspaceQueryBuilderModule, WorkspaceDataSourceModule],
|
imports: [
|
||||||
|
WorkspaceQueryBuilderModule,
|
||||||
|
WorkspaceDataSourceModule,
|
||||||
|
WorkspacePreQueryHookModule,
|
||||||
|
],
|
||||||
providers: [WorkspaceQueryRunnerService],
|
providers: [WorkspaceQueryRunnerService],
|
||||||
exports: [WorkspaceQueryRunnerService],
|
exports: [WorkspaceQueryRunnerService],
|
||||||
})
|
})
|
||||||
|
|||||||
@ -38,6 +38,7 @@ import { computeObjectTargetTable } from 'src/workspace/utils/compute-object-tar
|
|||||||
import { ObjectRecordDeleteEvent } from 'src/integrations/event-emitter/types/object-record-delete.event';
|
import { ObjectRecordDeleteEvent } from 'src/integrations/event-emitter/types/object-record-delete.event';
|
||||||
import { ObjectRecordCreateEvent } from 'src/integrations/event-emitter/types/object-record-create.event';
|
import { ObjectRecordCreateEvent } from 'src/integrations/event-emitter/types/object-record-create.event';
|
||||||
import { ObjectRecordUpdateEvent } from 'src/integrations/event-emitter/types/object-record-update.event';
|
import { ObjectRecordUpdateEvent } from 'src/integrations/event-emitter/types/object-record-update.event';
|
||||||
|
import { WorkspacePreQueryHookService } from 'src/workspace/workspace-query-runner/workspace-pre-query-hook/workspace-pre-query-hook.service';
|
||||||
|
|
||||||
import { WorkspaceQueryRunnerOptions } from './interfaces/query-runner-option.interface';
|
import { WorkspaceQueryRunnerOptions } from './interfaces/query-runner-option.interface';
|
||||||
import {
|
import {
|
||||||
@ -53,6 +54,7 @@ export class WorkspaceQueryRunnerService {
|
|||||||
@Inject(MessageQueue.webhookQueue)
|
@Inject(MessageQueue.webhookQueue)
|
||||||
private readonly messageQueueService: MessageQueueService,
|
private readonly messageQueueService: MessageQueueService,
|
||||||
private readonly eventEmitter: EventEmitter2,
|
private readonly eventEmitter: EventEmitter2,
|
||||||
|
private readonly workspacePreQueryHookService: WorkspacePreQueryHookService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async findMany<
|
async findMany<
|
||||||
@ -63,7 +65,7 @@ export class WorkspaceQueryRunnerService {
|
|||||||
args: FindManyResolverArgs<Filter, OrderBy>,
|
args: FindManyResolverArgs<Filter, OrderBy>,
|
||||||
options: WorkspaceQueryRunnerOptions,
|
options: WorkspaceQueryRunnerOptions,
|
||||||
): Promise<IConnection<Record> | undefined> {
|
): Promise<IConnection<Record> | undefined> {
|
||||||
const { workspaceId, objectMetadataItem } = options;
|
const { workspaceId, userId, objectMetadataItem } = options;
|
||||||
const start = performance.now();
|
const start = performance.now();
|
||||||
|
|
||||||
const query = await this.workspaceQueryBuilderFactory.findMany(
|
const query = await this.workspaceQueryBuilderFactory.findMany(
|
||||||
@ -71,6 +73,14 @@ export class WorkspaceQueryRunnerService {
|
|||||||
options,
|
options,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await this.workspacePreQueryHookService.executePreHooks(
|
||||||
|
userId,
|
||||||
|
workspaceId,
|
||||||
|
objectMetadataItem.nameSingular,
|
||||||
|
'findMany',
|
||||||
|
args,
|
||||||
|
);
|
||||||
|
|
||||||
const result = await this.execute(query, workspaceId);
|
const result = await this.execute(query, workspaceId);
|
||||||
const end = performance.now();
|
const end = performance.now();
|
||||||
|
|
||||||
@ -97,11 +107,20 @@ export class WorkspaceQueryRunnerService {
|
|||||||
if (!args.filter || Object.keys(args.filter).length === 0) {
|
if (!args.filter || Object.keys(args.filter).length === 0) {
|
||||||
throw new BadRequestException('Missing filter argument');
|
throw new BadRequestException('Missing filter argument');
|
||||||
}
|
}
|
||||||
const { workspaceId, objectMetadataItem } = options;
|
const { workspaceId, userId, objectMetadataItem } = options;
|
||||||
const query = await this.workspaceQueryBuilderFactory.findOne(
|
const query = await this.workspaceQueryBuilderFactory.findOne(
|
||||||
args,
|
args,
|
||||||
options,
|
options,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await this.workspacePreQueryHookService.executePreHooks(
|
||||||
|
userId,
|
||||||
|
workspaceId,
|
||||||
|
objectMetadataItem.nameSingular,
|
||||||
|
'findOne',
|
||||||
|
args,
|
||||||
|
);
|
||||||
|
|
||||||
const result = await this.execute(query, workspaceId);
|
const result = await this.execute(query, workspaceId);
|
||||||
const parsedResult = this.parseResult<IConnection<Record>>(
|
const parsedResult = this.parseResult<IConnection<Record>>(
|
||||||
result,
|
result,
|
||||||
@ -170,6 +189,7 @@ export class WorkspaceQueryRunnerService {
|
|||||||
args,
|
args,
|
||||||
options,
|
options,
|
||||||
);
|
);
|
||||||
|
|
||||||
const result = await this.execute(query, workspaceId);
|
const result = await this.execute(query, workspaceId);
|
||||||
|
|
||||||
const parsedResults = this.parseResult<PGGraphQLMutation<Record>>(
|
const parsedResults = this.parseResult<PGGraphQLMutation<Record>>(
|
||||||
@ -232,6 +252,7 @@ export class WorkspaceQueryRunnerService {
|
|||||||
args,
|
args,
|
||||||
options,
|
options,
|
||||||
);
|
);
|
||||||
|
|
||||||
const result = await this.execute(query, workspaceId);
|
const result = await this.execute(query, workspaceId);
|
||||||
|
|
||||||
const parsedResults = this.parseResult<PGGraphQLMutation<Record>>(
|
const parsedResults = this.parseResult<PGGraphQLMutation<Record>>(
|
||||||
@ -338,7 +359,7 @@ export class WorkspaceQueryRunnerService {
|
|||||||
const result = graphqlResult?.[0]?.resolve?.data?.[entityKey];
|
const result = graphqlResult?.[0]?.resolve?.data?.[entityKey];
|
||||||
const errors = graphqlResult?.[0]?.resolve?.errors;
|
const errors = graphqlResult?.[0]?.resolve?.errors;
|
||||||
|
|
||||||
if (!result) {
|
if (errors && errors.length > 0) {
|
||||||
throw new InternalServerErrorException(
|
throw new InternalServerErrorException(
|
||||||
`GraphQL errors on ${command}${
|
`GraphQL errors on ${command}${
|
||||||
objectMetadataItem.nameSingular
|
objectMetadataItem.nameSingular
|
||||||
|
|||||||
@ -28,6 +28,7 @@ export class CreateManyResolverFactory
|
|||||||
return this.workspaceQueryRunnerService.createMany(args, {
|
return this.workspaceQueryRunnerService.createMany(args, {
|
||||||
objectMetadataItem: internalContext.objectMetadataItem,
|
objectMetadataItem: internalContext.objectMetadataItem,
|
||||||
workspaceId: internalContext.workspaceId,
|
workspaceId: internalContext.workspaceId,
|
||||||
|
userId: internalContext.userId,
|
||||||
info,
|
info,
|
||||||
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
||||||
objectMetadataCollection: internalContext.objectMetadataCollection,
|
objectMetadataCollection: internalContext.objectMetadataCollection,
|
||||||
|
|||||||
@ -28,6 +28,7 @@ export class CreateOneResolverFactory
|
|||||||
return this.workspaceQueryRunnerService.createOne(args, {
|
return this.workspaceQueryRunnerService.createOne(args, {
|
||||||
objectMetadataItem: internalContext.objectMetadataItem,
|
objectMetadataItem: internalContext.objectMetadataItem,
|
||||||
workspaceId: internalContext.workspaceId,
|
workspaceId: internalContext.workspaceId,
|
||||||
|
userId: internalContext.userId,
|
||||||
info,
|
info,
|
||||||
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
||||||
objectMetadataCollection: internalContext.objectMetadataCollection,
|
objectMetadataCollection: internalContext.objectMetadataCollection,
|
||||||
|
|||||||
@ -28,6 +28,7 @@ export class DeleteManyResolverFactory
|
|||||||
return this.workspaceQueryRunnerService.deleteMany(args, {
|
return this.workspaceQueryRunnerService.deleteMany(args, {
|
||||||
objectMetadataItem: internalContext.objectMetadataItem,
|
objectMetadataItem: internalContext.objectMetadataItem,
|
||||||
workspaceId: internalContext.workspaceId,
|
workspaceId: internalContext.workspaceId,
|
||||||
|
userId: internalContext.userId,
|
||||||
info,
|
info,
|
||||||
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
||||||
objectMetadataCollection: internalContext.objectMetadataCollection,
|
objectMetadataCollection: internalContext.objectMetadataCollection,
|
||||||
|
|||||||
@ -28,6 +28,7 @@ export class DeleteOneResolverFactory
|
|||||||
return this.workspaceQueryRunnerService.deleteOne(args, {
|
return this.workspaceQueryRunnerService.deleteOne(args, {
|
||||||
objectMetadataItem: internalContext.objectMetadataItem,
|
objectMetadataItem: internalContext.objectMetadataItem,
|
||||||
workspaceId: internalContext.workspaceId,
|
workspaceId: internalContext.workspaceId,
|
||||||
|
userId: internalContext.userId,
|
||||||
info,
|
info,
|
||||||
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
||||||
objectMetadataCollection: internalContext.objectMetadataCollection,
|
objectMetadataCollection: internalContext.objectMetadataCollection,
|
||||||
|
|||||||
@ -33,6 +33,7 @@ export class ExecuteQuickActionOnOneResolverFactory
|
|||||||
return (_source, args, context, info) => {
|
return (_source, args, context, info) => {
|
||||||
return this.executeQuickActionOnOne(args, {
|
return this.executeQuickActionOnOne(args, {
|
||||||
objectMetadataItem: internalContext.objectMetadataItem,
|
objectMetadataItem: internalContext.objectMetadataItem,
|
||||||
|
userId: internalContext.userId,
|
||||||
workspaceId: internalContext.workspaceId,
|
workspaceId: internalContext.workspaceId,
|
||||||
info,
|
info,
|
||||||
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
||||||
|
|||||||
@ -28,6 +28,7 @@ export class FindManyResolverFactory
|
|||||||
return this.workspaceQueryRunnerService.findMany(args, {
|
return this.workspaceQueryRunnerService.findMany(args, {
|
||||||
objectMetadataItem: internalContext.objectMetadataItem,
|
objectMetadataItem: internalContext.objectMetadataItem,
|
||||||
workspaceId: internalContext.workspaceId,
|
workspaceId: internalContext.workspaceId,
|
||||||
|
userId: internalContext.userId,
|
||||||
info,
|
info,
|
||||||
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
||||||
objectMetadataCollection: internalContext.objectMetadataCollection,
|
objectMetadataCollection: internalContext.objectMetadataCollection,
|
||||||
|
|||||||
@ -28,6 +28,7 @@ export class FindOneResolverFactory
|
|||||||
return this.workspaceQueryRunnerService.findOne(args, {
|
return this.workspaceQueryRunnerService.findOne(args, {
|
||||||
objectMetadataItem: internalContext.objectMetadataItem,
|
objectMetadataItem: internalContext.objectMetadataItem,
|
||||||
workspaceId: internalContext.workspaceId,
|
workspaceId: internalContext.workspaceId,
|
||||||
|
userId: internalContext.userId,
|
||||||
info,
|
info,
|
||||||
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
||||||
objectMetadataCollection: internalContext.objectMetadataCollection,
|
objectMetadataCollection: internalContext.objectMetadataCollection,
|
||||||
|
|||||||
@ -28,6 +28,7 @@ export class UpdateManyResolverFactory
|
|||||||
return this.workspaceQueryRunnerService.updateMany(args, {
|
return this.workspaceQueryRunnerService.updateMany(args, {
|
||||||
objectMetadataItem: internalContext.objectMetadataItem,
|
objectMetadataItem: internalContext.objectMetadataItem,
|
||||||
workspaceId: internalContext.workspaceId,
|
workspaceId: internalContext.workspaceId,
|
||||||
|
userId: internalContext.userId,
|
||||||
info,
|
info,
|
||||||
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
||||||
objectMetadataCollection: internalContext.objectMetadataCollection,
|
objectMetadataCollection: internalContext.objectMetadataCollection,
|
||||||
|
|||||||
@ -28,6 +28,7 @@ export class UpdateOneResolverFactory
|
|||||||
return this.workspaceQueryRunnerService.updateOne(args, {
|
return this.workspaceQueryRunnerService.updateOne(args, {
|
||||||
objectMetadataItem: internalContext.objectMetadataItem,
|
objectMetadataItem: internalContext.objectMetadataItem,
|
||||||
workspaceId: internalContext.workspaceId,
|
workspaceId: internalContext.workspaceId,
|
||||||
|
userId: internalContext.userId,
|
||||||
info,
|
info,
|
||||||
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
fieldMetadataCollection: internalContext.fieldMetadataCollection,
|
||||||
objectMetadataCollection: internalContext.objectMetadataCollection,
|
objectMetadataCollection: internalContext.objectMetadataCollection,
|
||||||
|
|||||||
@ -73,3 +73,13 @@ export interface WorkspaceResolverBuilderMethods {
|
|||||||
readonly queries: readonly WorkspaceResolverBuilderQueryMethodNames[];
|
readonly queries: readonly WorkspaceResolverBuilderQueryMethodNames[];
|
||||||
readonly mutations: readonly WorkspaceResolverBuilderMutationMethodNames[];
|
readonly mutations: readonly WorkspaceResolverBuilderMutationMethodNames[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ResolverArgs =
|
||||||
|
| CreateManyResolverArgs
|
||||||
|
| CreateOneResolverArgs
|
||||||
|
| DeleteManyResolverArgs
|
||||||
|
| DeleteOneResolverArgs
|
||||||
|
| FindManyResolverArgs
|
||||||
|
| FindOneResolverArgs
|
||||||
|
| UpdateManyResolverArgs
|
||||||
|
| UpdateOneResolverArgs;
|
||||||
|
|||||||
@ -39,6 +39,7 @@ export class WorkspaceResolverFactory {
|
|||||||
|
|
||||||
async create(
|
async create(
|
||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
|
userId: string | undefined,
|
||||||
objectMetadataCollection: ObjectMetadataInterface[],
|
objectMetadataCollection: ObjectMetadataInterface[],
|
||||||
workspaceResolverBuilderMethods: WorkspaceResolverBuilderMethods,
|
workspaceResolverBuilderMethods: WorkspaceResolverBuilderMethods,
|
||||||
): Promise<IResolvers> {
|
): Promise<IResolvers> {
|
||||||
@ -79,6 +80,7 @@ export class WorkspaceResolverFactory {
|
|||||||
|
|
||||||
resolvers.Query[resolverName] = resolverFactory.create({
|
resolvers.Query[resolverName] = resolverFactory.create({
|
||||||
workspaceId,
|
workspaceId,
|
||||||
|
userId,
|
||||||
objectMetadataItem: objectMetadata,
|
objectMetadataItem: objectMetadata,
|
||||||
fieldMetadataCollection: objectMetadata.fields,
|
fieldMetadataCollection: objectMetadata.fields,
|
||||||
objectMetadataCollection: objectMetadataCollection,
|
objectMetadataCollection: objectMetadataCollection,
|
||||||
@ -102,6 +104,7 @@ export class WorkspaceResolverFactory {
|
|||||||
|
|
||||||
resolvers.Mutation[resolverName] = resolverFactory.create({
|
resolvers.Mutation[resolverName] = resolverFactory.create({
|
||||||
workspaceId,
|
workspaceId,
|
||||||
|
userId,
|
||||||
objectMetadataItem: objectMetadata,
|
objectMetadataItem: objectMetadata,
|
||||||
fieldMetadataCollection: objectMetadata.fields,
|
fieldMetadataCollection: objectMetadata.fields,
|
||||||
objectMetadataCollection: objectMetadataCollection,
|
objectMetadataCollection: objectMetadataCollection,
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { ObjectMetadataInterface } from 'src/metadata/field-metadata/interfaces/
|
|||||||
|
|
||||||
export interface WorkspaceSchemaBuilderContext {
|
export interface WorkspaceSchemaBuilderContext {
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
|
userId: string | undefined;
|
||||||
objectMetadataItem: ObjectMetadataInterface;
|
objectMetadataItem: ObjectMetadataInterface;
|
||||||
fieldMetadataCollection: FieldMetadataInterface[];
|
fieldMetadataCollection: FieldMetadataInterface[];
|
||||||
objectMetadataCollection: ObjectMetadataInterface[];
|
objectMetadataCollection: ObjectMetadataInterface[];
|
||||||
|
|||||||
@ -26,6 +26,7 @@ export class WorkspaceFactory {
|
|||||||
|
|
||||||
async createGraphQLSchema(
|
async createGraphQLSchema(
|
||||||
workspaceId: string | undefined,
|
workspaceId: string | undefined,
|
||||||
|
userId: string | undefined,
|
||||||
): Promise<GraphQLSchema> {
|
): Promise<GraphQLSchema> {
|
||||||
if (!workspaceId) {
|
if (!workspaceId) {
|
||||||
return new GraphQLSchema({});
|
return new GraphQLSchema({});
|
||||||
@ -89,6 +90,7 @@ export class WorkspaceFactory {
|
|||||||
|
|
||||||
const autoGeneratedResolvers = await this.workspaceResolverFactory.create(
|
const autoGeneratedResolvers = await this.workspaceResolverFactory.create(
|
||||||
workspaceId,
|
workspaceId,
|
||||||
|
userId,
|
||||||
objectMetadataCollection,
|
objectMetadataCollection,
|
||||||
workspaceResolverBuilderMethodNames,
|
workspaceResolverBuilderMethodNames,
|
||||||
);
|
);
|
||||||
|
|||||||
@ -43532,6 +43532,7 @@ __metadata:
|
|||||||
graphql-yoga: "npm:^4.0.4"
|
graphql-yoga: "npm:^4.0.4"
|
||||||
jest: "npm:29.7.0"
|
jest: "npm:29.7.0"
|
||||||
lodash.camelcase: "npm:^4.3.0"
|
lodash.camelcase: "npm:^4.3.0"
|
||||||
|
lodash.groupby: "npm:^4.6.0"
|
||||||
lodash.isempty: "npm:^4.4.0"
|
lodash.isempty: "npm:^4.4.0"
|
||||||
lodash.isobject: "npm:^3.0.2"
|
lodash.isobject: "npm:^3.0.2"
|
||||||
lodash.kebabcase: "npm:^4.1.1"
|
lodash.kebabcase: "npm:^4.1.1"
|
||||||
|
|||||||
Reference in New Issue
Block a user