chore: hoppscotch-backend code formatting, minor lint fixes, and refactoring (#5061)

* chore: prettier formatting applied

* chore: added some lint fixed

* fix: few lint errors

* chore: prisma and pubsub are now global module

* chore: add encapsulation consistency in service files

* chore: made a cast function private

* chore: cast function made private

* refactor: module imports

* refactor: posthog spelling
This commit is contained in:
Mir Arif Hasan 2025-05-09 15:37:20 +06:00 committed by GitHub
parent c28e4103a8
commit 46e5792965
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
66 changed files with 275 additions and 421 deletions

View file

@ -4,7 +4,6 @@ import {
Controller,
Delete,
Get,
HttpStatus,
Param,
ParseIntPipe,
Post,

View file

@ -1,18 +1,12 @@
import { Module } from '@nestjs/common';
import { AccessTokenController } from './access-token.controller';
import { PrismaModule } from 'src/prisma/prisma.module';
import { AccessTokenService } from './access-token.service';
import { TeamCollectionModule } from 'src/team-collection/team-collection.module';
import { TeamEnvironmentsModule } from 'src/team-environments/team-environments.module';
import { TeamModule } from 'src/team/team.module';
@Module({
imports: [
PrismaModule,
TeamCollectionModule,
TeamEnvironmentsModule,
TeamModule,
],
imports: [TeamCollectionModule, TeamEnvironmentsModule, TeamModule],
controllers: [AccessTokenController],
providers: [AccessTokenService],
exports: [AccessTokenService],

View file

@ -12,6 +12,7 @@ import {
import { CreateAccessTokenResponse } from './helper';
import { PersonalAccessToken } from '@prisma/client';
import { AccessToken } from 'src/types/AccessToken';
@Injectable()
export class AccessTokenService {
constructor(private readonly prisma: PrismaService) {}

View file

@ -1,8 +1,6 @@
import { Module } from '@nestjs/common';
import { AdminResolver } from './admin.resolver';
import { AdminService } from './admin.service';
import { PrismaModule } from '../prisma/prisma.module';
import { PubSubModule } from '../pubsub/pubsub.module';
import { UserModule } from '../user/user.module';
import { TeamModule } from '../team/team.module';
import { TeamInvitationModule } from '../team-invitation/team-invitation.module';
@ -16,8 +14,6 @@ import { UserHistoryModule } from 'src/user-history/user-history.module';
@Module({
imports: [
PrismaModule,
PubSubModule,
UserModule,
TeamModule,
TeamInvitationModule,

View file

@ -2,9 +2,7 @@ import {
Args,
ID,
Mutation,
Parent,
Query,
ResolveField,
Resolver,
Subscription,
} from '@nestjs/graphql';
@ -33,7 +31,7 @@ import { UserDeletionResult } from 'src/user/user.model';
@Resolver(() => Admin)
export class AdminResolver {
constructor(
private adminService: AdminService,
private readonly adminService: AdminService,
private readonly pubsub: PubSubService,
) {}

View file

@ -16,7 +16,6 @@ import {
ONLY_ONE_ADMIN_ACCOUNT,
USER_ALREADY_INVITED,
USER_INVITATION_DELETION_FAILED,
USER_NOT_FOUND,
} from '../errors';
import { ShortcodeService } from 'src/shortcode/shortcode.service';
import { ConfigService } from '@nestjs/config';
@ -44,8 +43,8 @@ const adminService = new AdminService(
mockTeamRequestService,
mockTeamEnvironmentsService,
mockTeamInvitationService,
mockPubSub as any,
mockPrisma as any,
mockPubSub,
mockPrisma,
mockMailerService,
mockShortcodeService,
mockConfigService,
@ -99,14 +98,11 @@ const dbAdminUsers: DbUser[] = [
describe('AdminService', () => {
describe('fetchInvitedUsers', () => {
test('should resolve right and apply pagination correctly', async () => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
mockPrisma.user.findMany.mockResolvedValue([dbAdminUsers[0]]);
// @ts-ignore
mockPrisma.invitedUsers.findMany.mockResolvedValue(invitedUsers);
const paginationArgs: OffsetPaginationArgs = { take: 5, skip: 2 };
const results = await adminService.fetchInvitedUsers(paginationArgs);
await adminService.fetchInvitedUsers(paginationArgs);
expect(mockPrisma.invitedUsers.findMany).toHaveBeenCalledWith({
...paginationArgs,
@ -126,10 +122,7 @@ describe('AdminService', () => {
test('should resolve right and return an array of invited users', async () => {
const paginationArgs: OffsetPaginationArgs = { take: 10, skip: 0 };
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
mockPrisma.user.findMany.mockResolvedValue([dbAdminUsers[0]]);
// @ts-ignore
mockPrisma.invitedUsers.findMany.mockResolvedValue(invitedUsers);
const results = await adminService.fetchInvitedUsers(paginationArgs);
@ -217,7 +210,6 @@ describe('AdminService', () => {
});
test('should resolve right and return deleted invitee email', async () => {
const adminUid = 'adminUid';
mockPrisma.invitedUsers.deleteMany.mockResolvedValueOnce({ count: 1 });
const result = await adminService.revokeUserInvitations([

View file

@ -12,7 +12,6 @@ import {
INVALID_EMAIL,
ONLY_ONE_ADMIN_ACCOUNT,
TEAM_INVITE_ALREADY_MEMBER,
TEAM_INVITE_NO_INVITE_FOUND,
USERS_NOT_FOUND,
USER_ALREADY_INVITED,
USER_INVITATION_DELETION_FAILED,
@ -464,7 +463,7 @@ export class AdminService {
});
const nonAdminUsers = allUsersList.filter((user) => !user.isAdmin);
let deletedUserEmails: string[] = [];
const deletedUserEmails: string[] = [];
// step 3: delete non-admin users
const deletionPromises = nonAdminUsers.map((user) => {

View file

@ -39,8 +39,8 @@ import { ServiceStatus } from 'src/infra-config/helper';
@Resolver(() => Infra)
export class InfraResolver {
constructor(
private adminService: AdminService,
private infraConfigService: InfraConfigService,
private readonly adminService: AdminService,
private readonly infraConfigService: InfraConfigService,
) {}
@Query(() => Infra, {

View file

@ -8,7 +8,10 @@ import { UserSettingsModule } from './user-settings/user-settings.module';
import { UserEnvironmentsModule } from './user-environment/user-environments.module';
import { UserRequestModule } from './user-request/user-request.module';
import { UserHistoryModule } from './user-history/user-history.module';
import { subscriptionContextCookieParser, extractAccessTokenFromAuthRecords } from './auth/helper';
import {
subscriptionContextCookieParser,
extractAccessTokenFromAuthRecords,
} from './auth/helper';
import { TeamModule } from './team/team.module';
import { TeamEnvironmentsModule } from './team-environments/team-environments.module';
import { TeamCollectionModule } from './team-collection/team-collection.module';
@ -24,12 +27,14 @@ import { ConfigModule, ConfigService } from '@nestjs/config';
import { InfraConfigModule } from './infra-config/infra-config.module';
import { loadInfraConfiguration } from './infra-config/helper';
import { MailerModule } from './mailer/mailer.module';
import { PosthogModule } from './posthog/posthog.module';
import { PostHogModule } from './posthog/posthog.module';
import { ScheduleModule } from '@nestjs/schedule';
import { HealthModule } from './health/health.module';
import { AccessTokenModule } from './access-token/access-token.module';
import { UserLastActiveOnInterceptor } from './interceptors/user-last-active-on.interceptor';
import { InfraTokenModule } from './infra-token/infra-token.module';
import { PrismaModule } from './prisma/prisma.module';
import { PubSubModule } from './pubsub/pubsub.module';
@Module({
imports: [
@ -56,8 +61,9 @@ import { InfraTokenModule } from './infra-token/infra-token.module';
const websocketHeaders = websocket?.upgradeReq?.headers;
try {
const accessToken = extractAccessTokenFromAuthRecords(connectionParams);
const authorization = `Bearer ${accessToken}`
const accessToken =
extractAccessTokenFromAuthRecords(connectionParams);
const authorization = `Bearer ${accessToken}`;
return { headers: { ...websocketHeaders, authorization } };
} catch (authError) {
@ -74,7 +80,7 @@ import { InfraTokenModule } from './infra-token/infra-token.module';
return { headers: { ...websocketHeaders, cookies } };
}
}
},
},
},
context: ({ req, res, connection }) => ({
@ -95,6 +101,8 @@ import { InfraTokenModule } from './infra-token/infra-token.module';
},
],
}),
PrismaModule,
PubSubModule,
MailerModule.register(),
UserModule,
AuthModule.register(),
@ -111,7 +119,7 @@ import { InfraTokenModule } from './infra-token/infra-token.module';
UserCollectionModule,
ShortcodeModule,
InfraConfigModule,
PosthogModule,
PostHogModule,
ScheduleModule.forRoot(),
HealthModule,
AccessTokenModule,

View file

@ -204,7 +204,7 @@ export class AuthController {
if (!redirectUri || !redirectUri.startsWith('http://localhost')) {
throwHTTPErr({
message: 'Invalid desktop callback URL',
statusCode: 400
statusCode: 400,
});
}

View file

@ -2,7 +2,6 @@ import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { UserModule } from 'src/user/user.module';
import { PrismaModule } from 'src/prisma/prisma.module';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { JwtStrategy } from './strategies/jwt.strategy';
@ -20,7 +19,6 @@ import { InfraConfigModule } from 'src/infra-config/infra-config.module';
@Module({
imports: [
PrismaModule,
UserModule,
PassportModule,
JwtModule.registerAsync({

View file

@ -1,7 +1,7 @@
import { HttpStatus } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { Account, VerificationToken } from '@prisma/client';
import { mockDeep, mockFn } from 'jest-mock-extended';
import { mockDeep } from 'jest-mock-extended';
import {
INVALID_EMAIL,
INVALID_MAGIC_LINK_DATA,
@ -82,9 +82,6 @@ let nowPlus30 = new Date();
nowPlus30.setMinutes(nowPlus30.getMinutes() + 30000);
nowPlus30 = new Date(nowPlus30);
const encodedRefreshToken =
'$argon2id$v=19$m=65536,t=3,p=4$JTP8yZ8YXMHdafb5pB9Rfg$tdZrILUxMb9dQbu0uuyeReLgKxsgYnyUNbc5ZxQmy5I';
describe('signInMagicLink', () => {
test('Should throw error if email is not in valid format', async () => {
const result = await authService.signInMagicLink('bbbgmail.com', 'admin');

View file

@ -34,12 +34,12 @@ import { InfraConfigService } from 'src/infra-config/infra-config.service';
@Injectable()
export class AuthService {
constructor(
private usersService: UserService,
private prismaService: PrismaService,
private jwtService: JwtService,
private readonly usersService: UserService,
private readonly prisma: PrismaService,
private readonly jwtService: JwtService,
private readonly mailerService: MailerService,
private readonly configService: ConfigService,
private infraConfigService: InfraConfigService,
private readonly infraConfigService: InfraConfigService,
) {}
/**
@ -59,7 +59,7 @@ export class AuthService {
.toISO()
.toString();
const idToken = await this.prismaService.verificationToken.create({
const idToken = await this.prisma.verificationToken.create({
data: {
deviceIdentifier: salt,
userUid: user.uid,
@ -78,15 +78,14 @@ export class AuthService {
*/
private async validatePasswordlessTokens(magicLinkTokens: VerifyMagicDto) {
try {
const tokens =
await this.prismaService.verificationToken.findUniqueOrThrow({
where: {
passwordless_deviceIdentifier_tokens: {
deviceIdentifier: magicLinkTokens.deviceIdentifier,
token: magicLinkTokens.token,
},
const tokens = await this.prisma.verificationToken.findUniqueOrThrow({
where: {
passwordless_deviceIdentifier_tokens: {
deviceIdentifier: magicLinkTokens.deviceIdentifier,
token: magicLinkTokens.token,
},
});
},
});
return O.some(tokens);
} catch (error) {
return O.none;
@ -160,7 +159,7 @@ export class AuthService {
) {
try {
const deletedPasswordlessToken =
await this.prismaService.verificationToken.delete({
await this.prisma.verificationToken.delete({
where: {
passwordless_deviceIdentifier_tokens: {
deviceIdentifier: passwordlessTokens.deviceIdentifier,
@ -182,7 +181,7 @@ export class AuthService {
* @returns Either of existing user provider Account
*/
async checkIfProviderAccountExists(user: AuthUser, SSOUserData) {
const provider = await this.prismaService.account.findUnique({
const provider = await this.prisma.account.findUnique({
where: {
verifyProviderAccount: {
provider: SSOUserData.provider,
@ -256,9 +255,8 @@ export class AuthService {
async verifyMagicLinkTokens(
magicLinkIDTokens: VerifyMagicDto,
): Promise<E.Right<AuthTokens> | E.Left<RESTError>> {
const passwordlessTokens = await this.validatePasswordlessTokens(
magicLinkIDTokens,
);
const passwordlessTokens =
await this.validatePasswordlessTokens(magicLinkIDTokens);
if (O.isNone(passwordlessTokens))
return E.left({
message: INVALID_MAGIC_LINK_DATA,

View file

@ -3,7 +3,12 @@ import { DateTime } from 'luxon';
import { AuthTokens } from 'src/types/AuthTokens';
import { Response } from 'express';
import * as cookie from 'cookie';
import { AUTH_HEADER_NOT_FOUND, AUTH_PROVIDER_NOT_SPECIFIED, COOKIES_NOT_FOUND, INVALID_AUTH_HEADER } from 'src/errors';
import {
AUTH_HEADER_NOT_FOUND,
AUTH_PROVIDER_NOT_SPECIFIED,
COOKIES_NOT_FOUND,
INVALID_AUTH_HEADER,
} from 'src/errors';
import { throwErr } from 'src/utils';
import { ConfigService } from '@nestjs/config';
import { IncomingHttpHeaders } from 'http';
@ -118,8 +123,8 @@ export function authProviderCheck(
const envVariables = VITE_ALLOWED_AUTH_PROVIDERS
? VITE_ALLOWED_AUTH_PROVIDERS.split(',').map((provider) =>
provider.trim().toUpperCase(),
)
provider.trim().toUpperCase(),
)
: [];
if (!envVariables.includes(provider.toUpperCase())) return false;
@ -132,8 +137,11 @@ export function authProviderCheck(
* @param headers HTTP request headers containing auth tokens
* @returns Cookie's key-value pairs
*/
export const extractCookieAsKeyValuesFromHeaders = (headers: IncomingHttpHeaders) => {
const cookieHeader = headers['cookie'] || headers['Cookie'] || headers['COOKIE'];
export const extractCookieAsKeyValuesFromHeaders = (
headers: IncomingHttpHeaders,
) => {
const cookieHeader =
headers['cookie'] || headers['Cookie'] || headers['COOKIE'];
if (!cookieHeader) {
throw new HttpException(COOKIES_NOT_FOUND, 400, {
@ -141,15 +149,21 @@ export const extractCookieAsKeyValuesFromHeaders = (headers: IncomingHttpHeaders
});
}
const cookieStr = Array.isArray(cookieHeader) ? cookieHeader[0] : cookieHeader;
const cookieStr = Array.isArray(cookieHeader)
? cookieHeader[0]
: cookieHeader;
const kv = cookieStr.split(';')
.map(cookie => cookie.trim())
.reduce((acc, curr) => {
const [key, value] = curr.split('=');
acc[key] = value;
return acc;
}, {} as Record<string, string>);
const kv = cookieStr
.split(';')
.map((cookie) => cookie.trim())
.reduce(
(acc, curr) => {
const [key, value] = curr.split('=');
acc[key] = value;
return acc;
},
{} as Record<string, string>,
);
return kv;
};
@ -159,10 +173,15 @@ export const extractCookieAsKeyValuesFromHeaders = (headers: IncomingHttpHeaders
* @param headers HTTP request headers containing auth tokens
* @returns AuthTokens for JWT strategy to use
*/
export const extractAuthTokensFromCookieHeaders = (headers: IncomingHttpHeaders) => {
export const extractAuthTokensFromCookieHeaders = (
headers: IncomingHttpHeaders,
) => {
const cookieKV = extractCookieAsKeyValuesFromHeaders(headers);
if (!cookieKV[AuthTokenType.ACCESS_TOKEN] || !cookieKV[AuthTokenType.REFRESH_TOKEN]) {
if (
!cookieKV[AuthTokenType.ACCESS_TOKEN] ||
!cookieKV[AuthTokenType.REFRESH_TOKEN]
) {
throw new HttpException(COOKIES_NOT_FOUND, 400, {
cause: new Error(COOKIES_NOT_FOUND),
});
@ -179,7 +198,9 @@ export const extractAuthTokensFromCookieHeaders = (headers: IncomingHttpHeaders)
* @param headers HTTP request headers containing access tokens
* @returns AccessTokens for JWT strategy to use
*/
export const extractAccessTokensFromCookieHeaders = (headers: IncomingHttpHeaders) => {
export const extractAccessTokensFromCookieHeaders = (
headers: IncomingHttpHeaders,
) => {
const cookieKV = extractCookieAsKeyValuesFromHeaders(headers);
if (!cookieKV[AuthTokenType.ACCESS_TOKEN]) {
@ -198,7 +219,9 @@ export const extractAccessTokensFromCookieHeaders = (headers: IncomingHttpHeader
* @param headers HTTP request headers containing bearer token
* @returns AccessTokens for JWT strategy
*/
export const extractAccessTokenFromAuthRecords = (headers: IncomingHttpHeaders) => {
export const extractAccessTokenFromAuthRecords = (
headers: IncomingHttpHeaders,
) => {
const authHeader = headers['authorization'] || headers['Authorization'];
if (!authHeader) {
throw new HttpException(AUTH_HEADER_NOT_FOUND, 400, {

View file

@ -1,6 +1,10 @@
import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, ForbiddenException, UnauthorizedException } from '@nestjs/common';
import {
Injectable,
ForbiddenException,
UnauthorizedException,
} from '@nestjs/common';
import { AccessTokenPayload } from 'src/types/AuthTokens';
import { UserService } from 'src/user/user.service';
import { ConfigService } from '@nestjs/config';
@ -8,7 +12,11 @@ import { Request } from 'express';
import * as O from 'fp-ts/Option';
import * as E from 'fp-ts/Either';
import { pipe } from 'fp-ts/function';
import { COOKIES_NOT_FOUND, INVALID_ACCESS_TOKEN, USER_NOT_FOUND } from 'src/errors';
import {
COOKIES_NOT_FOUND,
INVALID_ACCESS_TOKEN,
USER_NOT_FOUND,
} from 'src/errors';
/**
* Extracts an access token from a cookie in the request.
@ -19,7 +27,7 @@ import { COOKIES_NOT_FOUND, INVALID_ACCESS_TOKEN, USER_NOT_FOUND } from 'src/err
const extractFromCookie = (request: Request): O.Option<string> =>
pipe(
O.fromNullable(request.cookies),
O.chain(cookies => O.fromNullable(cookies['access_token']))
O.chain((cookies) => O.fromNullable(cookies['access_token'])),
);
/**
@ -35,13 +43,15 @@ const extractFromAuthHeaders = (request: Request): O.Option<string> =>
// see `gql-auth.guard` for more info.
O.fromNullable(
request?.headers?.authorization ||
(request && 'authorization' in request ? request['authorization'] : undefined)
(request && 'authorization' in request
? request['authorization']
: undefined),
),
O.chain(auth =>
O.chain((auth) =>
typeof auth === 'string' && auth.startsWith('Bearer ')
? O.some(auth.slice(7))
: O.none
)
: O.none,
),
);
/**
@ -59,7 +69,7 @@ const extractToken = (request: Request): E.Either<Error, string> =>
// `COOKIES_NOT_FOUND` for backwards compatibility.
E.fromOption(() => {
return new ForbiddenException(COOKIES_NOT_FOUND);
})
}),
);
@Injectable()
@ -74,9 +84,13 @@ export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') {
pipe(
extractToken(request),
E.fold(
error => { throw error; },
token => { return token }
)
(error) => {
throw error;
},
(token) => {
return token;
},
),
),
]),
secretOrKey: configService.get('JWT_SECRET'),

View file

@ -27,7 +27,7 @@ export class RTJwtStrategy extends PassportStrategy(Strategy, 'jwt-refresh') {
(request: Request) => {
const RTCookie = request.cookies['refresh_token'];
if (!RTCookie) {
console.error("`refresh_token` not found")
console.error('`refresh_token` not found');
throw new ForbiddenException(COOKIES_NOT_FOUND);
}
return RTCookie;

View file

@ -36,9 +36,7 @@ export class PATAuthGuard implements CanActivate {
const today = DateTime.now().toISO();
if (accessToken.expiresOn.toISOString() > today) return true;
throw new BadRequestException(
createCLIErrorResponse(ACCESS_TOKEN_EXPIRED),
);
throw new BadRequestException(createCLIErrorResponse(ACCESS_TOKEN_EXPIRED));
}
private extractTokenFromHeader(request: Request): string | undefined {

View file

@ -1,10 +1,9 @@
import { Module } from '@nestjs/common';
import { HealthController } from './health.controller';
import { PrismaModule } from 'src/prisma/prisma.module';
import { TerminusModule } from '@nestjs/terminus';
@Module({
imports: [PrismaModule, TerminusModule],
imports: [TerminusModule],
controllers: [HealthController],
})
export class HealthModule {}

View file

@ -1,7 +1,6 @@
import { AuthProvider } from 'src/auth/helper';
import {
AUTH_PROVIDER_NOT_CONFIGURED,
DATABASE_TABLE_NOT_EXIST,
ENV_INVALID_DATA_ENCRYPTION_KEY,
} from 'src/errors';
import { PrismaService } from 'src/prisma/prisma.service';
@ -68,7 +67,7 @@ export async function loadInfraConfiguration() {
const infraConfigs = await prisma.infraConfig.findMany();
let environmentObject: Record<string, any> = {};
const environmentObject: Record<string, any> = {};
infraConfigs.forEach((infraConfig) => {
if (infraConfig.isEncrypted) {
environmentObject[infraConfig.name] = decrypt(infraConfig.value);
@ -323,7 +322,7 @@ export async function syncInfraConfigWithEnvFile() {
const updateRequiredObjs: (Partial<InfraConfig> & { id: string })[] = [];
for (const dbConfig of dbInfraConfigs) {
let envValue = process.env[dbConfig.name];
const envValue = process.env[dbConfig.name];
// lastSyncedEnvFileValue null check for backward compatibility from 2024.10.2 and below
if (!dbConfig.lastSyncedEnvFileValue && envValue) {
@ -398,7 +397,7 @@ export function stopApp() {
export function getConfiguredSSOProvidersFromEnvFile() {
const allowedAuthProviders: string[] =
process.env.VITE_ALLOWED_AUTH_PROVIDERS.split(',');
let configuredAuthProviders: string[] = [];
const configuredAuthProviders: string[] = [];
const addProviderIfConfigured = (provider) => {
const configParameters: string[] = AuthProviderConfigurations[provider];
@ -439,7 +438,7 @@ export async function getConfiguredSSOProvidersFromInfraConfig() {
const allowedAuthProviders: string[] =
env['INFRA'].VITE_ALLOWED_AUTH_PROVIDERS.split(',');
let configuredAuthProviders: string[] = [];
const configuredAuthProviders: string[] = [];
const addProviderIfConfigured = (provider) => {
const configParameters: string[] = AuthProviderConfigurations[provider];

View file

@ -1,12 +1,9 @@
import { Module } from '@nestjs/common';
import { InfraConfigService } from './infra-config.service';
import { PrismaModule } from 'src/prisma/prisma.module';
import { SiteController } from './infra-config.controller';
import { InfraConfigResolver } from './infra-config.resolver';
import { PubSubModule } from 'src/pubsub/pubsub.module';
@Module({
imports: [PrismaModule, PubSubModule],
providers: [InfraConfigResolver, InfraConfigService],
exports: [InfraConfigService],
controllers: [SiteController],

View file

@ -19,8 +19,6 @@ const mockPrisma = mockDeep<PrismaService>();
const mockConfigService = mockDeep<ConfigService>();
const mockPubsub = mockDeep<PubSubService>();
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const infraConfigService = new InfraConfigService(
mockPrisma,
mockConfigService,
@ -66,90 +64,84 @@ beforeEach(() => {
describe('InfraConfigService', () => {
describe('update', () => {
it('should update the infra config without backend server restart', async () => {
const name = InfraConfigEnum.GOOGLE_CLIENT_ID;
const value = 'true';
const name = dbInfraConfigs[0].name;
const value = 'newValue';
// @ts-ignore
mockPrisma.infraConfig.findUnique.mockResolvedValueOnce({
isEncrypted: false,
});
mockPrisma.infraConfig.findUnique.mockResolvedValueOnce(
dbInfraConfigs[0],
);
mockPrisma.infraConfig.update.mockResolvedValueOnce({
id: '',
...dbInfraConfigs[0],
name,
value,
lastSyncedEnvFileValue: value,
isEncrypted: false,
createdOn: new Date(),
updatedOn: new Date(),
});
jest.spyOn(helper, 'stopApp').mockReturnValueOnce();
const result = await infraConfigService.update(name, value);
const result = await infraConfigService.update(
name as InfraConfigEnum,
value,
);
expect(helper.stopApp).not.toHaveBeenCalled();
expect(result).toEqualRight({ name, value });
});
it('should update the infra config with backend server restart', async () => {
const name = InfraConfigEnum.GOOGLE_CLIENT_ID;
const value = 'true';
const name = dbInfraConfigs[0].name;
const value = 'newValue';
// @ts-ignore
mockPrisma.infraConfig.findUnique.mockResolvedValueOnce({
isEncrypted: false,
});
mockPrisma.infraConfig.findUnique.mockResolvedValueOnce(
dbInfraConfigs[0],
);
mockPrisma.infraConfig.update.mockResolvedValueOnce({
id: '',
...dbInfraConfigs[0],
name,
value,
lastSyncedEnvFileValue: value,
isEncrypted: false,
createdOn: new Date(),
updatedOn: new Date(),
});
jest.spyOn(helper, 'stopApp').mockReturnValueOnce();
const result = await infraConfigService.update(name, value, true);
const result = await infraConfigService.update(
name as InfraConfigEnum,
value,
true,
);
expect(helper.stopApp).toHaveBeenCalledTimes(1);
expect(result).toEqualRight({ name, value });
});
it('should update the infra config', async () => {
const name = InfraConfigEnum.GOOGLE_CLIENT_ID;
const value = 'true';
const name = dbInfraConfigs[0].name;
const value = 'newValue';
// @ts-ignore
mockPrisma.infraConfig.findUnique.mockResolvedValueOnce({
isEncrypted: false,
});
mockPrisma.infraConfig.findUnique.mockResolvedValueOnce(
dbInfraConfigs[0],
);
mockPrisma.infraConfig.update.mockResolvedValueOnce({
id: '',
...dbInfraConfigs[0],
name,
value,
lastSyncedEnvFileValue: value,
isEncrypted: false,
createdOn: new Date(),
updatedOn: new Date(),
});
jest.spyOn(helper, 'stopApp').mockReturnValueOnce();
const result = await infraConfigService.update(name, value);
const result = await infraConfigService.update(
name as InfraConfigEnum,
value,
);
expect(result).toEqualRight({ name, value });
});
it('should pass correct params to prisma update', async () => {
const name = InfraConfigEnum.GOOGLE_CLIENT_ID;
const value = 'true';
const name = dbInfraConfigs[0].name;
const value = 'newValue';
// @ts-ignore
mockPrisma.infraConfig.findUnique.mockResolvedValueOnce({
isEncrypted: false,
});
mockPrisma.infraConfig.findUnique.mockResolvedValueOnce(
dbInfraConfigs[0],
);
jest.spyOn(helper, 'stopApp').mockReturnValueOnce();
await infraConfigService.update(name, value);
await infraConfigService.update(name as InfraConfigEnum, value);
expect(mockPrisma.infraConfig.update).toHaveBeenCalledWith({
where: { name },
@ -171,19 +163,13 @@ describe('InfraConfigService', () => {
describe('get', () => {
it('should get the infra config', async () => {
const name = InfraConfigEnum.GOOGLE_CLIENT_ID;
const value = 'true';
const name = dbInfraConfigs[0].name;
const value = dbInfraConfigs[0].value;
mockPrisma.infraConfig.findUniqueOrThrow.mockResolvedValueOnce({
id: '',
name,
value,
lastSyncedEnvFileValue: value,
isEncrypted: false,
createdOn: new Date(),
updatedOn: new Date(),
});
const result = await infraConfigService.get(name);
mockPrisma.infraConfig.findUniqueOrThrow.mockResolvedValueOnce(
dbInfraConfigs[0],
);
const result = await infraConfigService.get(name as InfraConfigEnum);
expect(result).toEqualRight({ name, value });
});

View file

@ -134,7 +134,7 @@ export class InfraConfigService implements OnModuleInit {
* @param dbInfraConfig database InfraConfig
* @returns InfraConfig model
*/
cast(dbInfraConfig: DBInfraConfig) {
private cast(dbInfraConfig: DBInfraConfig) {
switch (dbInfraConfig.name) {
case InfraConfigEnum.USER_HISTORY_STORE_ENABLED:
dbInfraConfig.value =

View file

@ -1,5 +1,4 @@
import { Module } from '@nestjs/common';
import { PrismaModule } from 'src/prisma/prisma.module';
import { InfraTokenResolver } from './infra-token.resolver';
import { InfraTokenService } from './infra-token.service';
import { InfraTokensController } from './infra-token.controller';
@ -7,7 +6,7 @@ import { AdminModule } from 'src/admin/admin.module';
import { UserModule } from 'src/user/user.module';
@Module({
imports: [PrismaModule, AdminModule, UserModule],
imports: [AdminModule, UserModule],
controllers: [InfraTokensController],
providers: [InfraTokenResolver, InfraTokenService],
})

View file

@ -1,10 +1,9 @@
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { Expose, Transform, Type } from 'class-transformer';
import { Expose, Type } from 'class-transformer';
import {
ArrayMinSize,
IsArray,
IsBoolean,
IsEmail,
IsNotEmpty,
IsOptional,
IsString,

View file

@ -28,7 +28,7 @@ export class MailerModule {
// If mailer is ENABLED, return the module with configuration (service, etc.)
// Determine transport configuration based on custom config flag
let transportOption = getTransportOption(env, config);
const transportOption = getTransportOption(env, config);
// Get mailer address from environment or config
const mailerAddressFrom = getMailerAddressFrom(env, config);

View file

@ -8,7 +8,6 @@ import { emitGQLSchemaFile } from './gql-schema';
import { checkEnvironmentAuthProvider } from './utils';
import { ConfigService } from '@nestjs/config';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { InfraTokensController } from './infra-token/infra-token.controller';
import { InfraTokenModule } from './infra-token/infra-token.module';
function setupSwagger(app) {

View file

@ -1,9 +1,7 @@
import { Module } from '@nestjs/common';
import { PosthogService } from './posthog.service';
import { PrismaModule } from 'src/prisma/prisma.module';
import { PostHogService } from './posthog.service';
@Module({
imports: [PrismaModule],
providers: [PosthogService],
providers: [PostHogService],
})
export class PosthogModule {}
export class PostHogModule {}

View file

@ -1,20 +1,21 @@
import { Injectable } from '@nestjs/common';
import { PostHog } from 'posthog-node';
import { Cron, CronExpression, SchedulerRegistry } from '@nestjs/schedule';
import { CronExpression, SchedulerRegistry } from '@nestjs/schedule';
import { ConfigService } from '@nestjs/config';
import { PrismaService } from 'src/prisma/prisma.service';
import { CronJob } from 'cron';
import { POSTHOG_CLIENT_NOT_INITIALIZED } from 'src/errors';
import { throwErr } from 'src/utils';
@Injectable()
export class PosthogService {
export class PostHogService {
private postHogClient: PostHog;
private POSTHOG_API_KEY = 'phc_9CipPajQC22mSkk2wxe2TXsUA0Ysyupe8dt5KQQELqx';
constructor(
private readonly configService: ConfigService,
private readonly prismaService: PrismaService,
private schedulerRegistry: SchedulerRegistry,
private readonly prisma: PrismaService,
private readonly schedulerRegistry: SchedulerRegistry,
) {}
async onModuleInit() {
@ -48,8 +49,8 @@ export class PosthogService {
event: 'sh_instance',
properties: {
type: 'COMMUNITY',
total_user_count: await this.prismaService.user.count(),
total_workspace_count: await this.prismaService.team.count(),
total_user_count: await this.prisma.user.count(),
total_workspace_count: await this.prisma.team.count(),
version: this.configService.get('npm_package_version'),
},
});

View file

@ -1,6 +1,7 @@
import { Module } from '@nestjs/common/decorators';
import { Global, Module } from '@nestjs/common/decorators';
import { PrismaService } from './prisma.service';
@Global()
@Module({
providers: [PrismaService],
exports: [PrismaService],

View file

@ -1,6 +1,7 @@
import { Module } from '@nestjs/common';
import { Global, Module } from '@nestjs/common';
import { PubSubService } from './pubsub.service';
@Global()
@Module({
providers: [PubSubService],
exports: [PubSubService],

View file

@ -1,5 +1,4 @@
import { Field, ID, ObjectType } from '@nestjs/graphql';
import { User } from 'src/user/user.model';
@ObjectType()
export class Shortcode {

View file

@ -1,12 +1,10 @@
import { Module } from '@nestjs/common';
import { PrismaModule } from 'src/prisma/prisma.module';
import { PubSubModule } from 'src/pubsub/pubsub.module';
import { UserModule } from 'src/user/user.module';
import { ShortcodeResolver } from './shortcode.resolver';
import { ShortcodeService } from './shortcode.service';
@Module({
imports: [PrismaModule, UserModule, PubSubModule],
imports: [UserModule],
providers: [ShortcodeService, ShortcodeResolver],
exports: [ShortcodeService],
})

View file

@ -8,7 +8,7 @@ import {
} from '@nestjs/graphql';
import * as E from 'fp-ts/Either';
import { UseGuards } from '@nestjs/common';
import { Shortcode, ShortcodeWithUserEmail } from './shortcode.model';
import { Shortcode } from './shortcode.model';
import { ShortcodeService } from './shortcode.service';
import { throwErr } from 'src/utils';
import { GqlUser } from 'src/decorators/gql-user.decorator';
@ -19,7 +19,6 @@ import { AuthUser } from '../types/AuthUser';
import { PaginationArgs } from 'src/types/input-types.args';
import { GqlThrottlerGuard } from 'src/guards/gql-throttler.guard';
import { SkipThrottle } from '@nestjs/throttler';
import { GqlAdminGuard } from 'src/admin/guards/gql-admin.guard';
@UseGuards(GqlThrottlerGuard)
@Resolver(() => Shortcode)

View file

@ -1,7 +1,6 @@
import { mockDeep, mockReset } from 'jest-mock-extended';
import { PrismaService } from '../prisma/prisma.service';
import {
INVALID_EMAIL,
SHORTCODE_INVALID_PROPERTIES_JSON,
SHORTCODE_INVALID_REQUEST_JSON,
SHORTCODE_NOT_FOUND,
@ -11,27 +10,15 @@ import { Shortcode, ShortcodeWithUserEmail } from './shortcode.model';
import { ShortcodeService } from './shortcode.service';
import { UserService } from 'src/user/user.service';
import { AuthUser } from 'src/types/AuthUser';
import { PubSubService } from 'src/pubsub/pubsub.service';
const mockPrisma = mockDeep<PrismaService>();
const mockPubSub = mockDeep<PubSubService>();
const mockUserService = mockDeep<UserService>();
const mockPubSub = {
publish: jest.fn().mockResolvedValue(null),
};
const mockDocFunc = jest.fn();
const mockFB = {
firestore: {
doc: mockDocFunc,
},
};
const mockUserService = new UserService(mockPrisma as any, mockPubSub as any);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const shortcodeService = new ShortcodeService(
mockPrisma,
mockPubSub as any,
mockPubSub,
mockUserService,
);
@ -286,7 +273,7 @@ describe('ShortcodeService', () => {
);
mockPrisma.shortcode.create.mockResolvedValueOnce(mockShortcode);
const result = await shortcodeService.createShortcode('{}', null, user);
await shortcodeService.createShortcode('{}', null, user);
expect(mockPubSub.publish).toHaveBeenCalledWith(
`shortcode/${mockShortcode.creatorUid}/created`,
@ -306,7 +293,7 @@ describe('ShortcodeService', () => {
);
mockPrisma.shortcode.create.mockResolvedValueOnce(mockEmbed);
const result = await shortcodeService.createShortcode('{}', '{}', user);
await shortcodeService.createShortcode('{}', '{}', user);
expect(mockPubSub.publish).toHaveBeenCalledWith(
`shortcode/${mockEmbed.creatorUid}/created`,
@ -365,7 +352,7 @@ describe('ShortcodeService', () => {
test('should send pubsub message to `shortcode/{uid}/revoked` on successful deletion of Shortcode', async () => {
mockPrisma.shortcode.delete.mockResolvedValueOnce(mockEmbed);
const result = await shortcodeService.revokeShortCode(
await shortcodeService.revokeShortCode(
mockEmbed.id,
mockEmbed.creatorUid,
);
@ -456,7 +443,7 @@ describe('ShortcodeService', () => {
embedProperties: '{"foo":"bar"}',
});
const result = await shortcodeService.updateEmbedProperties(
await shortcodeService.updateEmbedProperties(
mockEmbed.id,
user.uid,
'{"foo":"bar"}',

View file

@ -36,9 +36,8 @@ export class GqlCollectionTeamMemberGuard implements CanActivate {
const { collectionID } = gqlExecCtx.getArgs<{ collectionID: string }>();
if (!collectionID) throw new Error(BUG_TEAM_COLL_NO_COLL_ID);
const collection = await this.teamCollectionService.getCollection(
collectionID,
);
const collection =
await this.teamCollectionService.getCollection(collectionID);
if (E.isLeft(collection)) throw new Error(TEAM_INVALID_COLL_ID);
const member = await this.teamService.getTeamMember(

View file

@ -1,15 +1,13 @@
import { Module } from '@nestjs/common';
import { PrismaModule } from '../prisma/prisma.module';
import { TeamCollectionService } from './team-collection.service';
import { TeamCollectionResolver } from './team-collection.resolver';
import { GqlCollectionTeamMemberGuard } from './guards/gql-collection-team-member.guard';
import { TeamModule } from '../team/team.module';
import { UserModule } from '../user/user.module';
import { PubSubModule } from '../pubsub/pubsub.module';
import { TeamCollectionController } from './team-collection.controller';
@Module({
imports: [PrismaModule, TeamModule, UserModule, PubSubModule],
imports: [TeamModule, UserModule],
providers: [
TeamCollectionService,
TeamCollectionResolver,

View file

@ -94,9 +94,8 @@ export class TeamCollectionResolver {
@Args({ name: 'teamID', description: 'ID of the team', type: () => ID })
teamID: string,
) {
const jsonString = await this.teamCollectionService.exportCollectionsToJSON(
teamID,
);
const jsonString =
await this.teamCollectionService.exportCollectionsToJSON(teamID);
if (E.isLeft(jsonString)) throwErr(jsonString.left as string);
return jsonString.right;
@ -167,9 +166,8 @@ export class TeamCollectionResolver {
})
collectionID: string,
) {
const teamCollections = await this.teamCollectionService.getCollection(
collectionID,
);
const teamCollections =
await this.teamCollectionService.getCollection(collectionID);
if (E.isLeft(teamCollections)) throwErr(teamCollections.left);
return <TeamCollection>{
@ -307,9 +305,8 @@ export class TeamCollectionResolver {
})
collectionID: string,
) {
const result = await this.teamCollectionService.deleteCollection(
collectionID,
);
const result =
await this.teamCollectionService.deleteCollection(collectionID);
if (E.isLeft(result)) throwErr(result.left);
return result.right;

View file

@ -84,13 +84,6 @@ const rootTeamCollection_2: DBTeamCollection = {
updatedOn: currentTime,
};
const rootTeamCollection_2Casted: TeamCollection = {
id: 'erv',
parentID: null,
data: JSON.stringify(rootTeamCollection_2.data),
title: 'Root Collection 1',
};
const childTeamCollection: DBTeamCollection = {
id: 'rfe',
orderIndex: 1,
@ -537,9 +530,8 @@ describe('getParentOfCollection', () => {
test('should return null with invalid collectionID', async () => {
mockPrisma.teamCollection.findUnique.mockResolvedValueOnce(null);
const result = await teamCollectionService.getParentOfCollection(
'invalidID',
);
const result =
await teamCollectionService.getParentOfCollection('invalidID');
expect(result).toEqual(null);
});
});
@ -756,7 +748,7 @@ describe('createCollection', () => {
mockPrisma.teamCollection.findMany.mockResolvedValueOnce([]);
mockPrisma.teamCollection.create.mockResolvedValueOnce(childTeamCollection);
const result = await teamCollectionService.createCollection(
await teamCollectionService.createCollection(
childTeamCollection.teamID,
childTeamCollection.title,
JSON.stringify(rootTeamCollection.data),
@ -779,7 +771,7 @@ describe('createCollection', () => {
mockPrisma.teamCollection.findMany.mockResolvedValueOnce([]);
mockPrisma.teamCollection.create.mockResolvedValueOnce(rootTeamCollection);
const result = await teamCollectionService.createCollection(
await teamCollectionService.createCollection(
rootTeamCollection.teamID,
'abcdefg',
JSON.stringify(rootTeamCollection.data),
@ -849,7 +841,7 @@ describe('renameCollection', () => {
title: 'NewTitle',
});
const result = await teamCollectionService.renameCollection(
await teamCollectionService.renameCollection(
rootTeamCollection.id,
'NewTitle',
);
@ -938,9 +930,7 @@ describe('deleteCollection', () => {
// deleteCollectionData --> removeUserCollection
mockPrisma.teamCollection.delete.mockResolvedValueOnce(rootTeamCollection);
const result = await teamCollectionService.deleteCollection(
rootTeamCollection.id,
);
await teamCollectionService.deleteCollection(rootTeamCollection.id);
expect(mockPubSub.publish).toHaveBeenCalledWith(
`team_coll/${rootTeamCollection.teamID}/coll_removed`,
rootTeamCollection.id,
@ -1113,10 +1103,7 @@ describe('moveCollection', () => {
orderIndex: 2,
});
const result = await teamCollectionService.moveCollection(
childTeamCollection.id,
null,
);
await teamCollectionService.moveCollection(childTeamCollection.id, null);
expect(mockPubSub.publish).toHaveBeenCalledWith(
`team_coll/${childTeamCollection.teamID}/coll_moved`,
{
@ -1194,7 +1181,7 @@ describe('moveCollection', () => {
orderIndex: 1,
});
const result = await teamCollectionService.moveCollection(
await teamCollectionService.moveCollection(
rootTeamCollection.id,
childTeamCollection_2.id,
);
@ -1275,7 +1262,7 @@ describe('moveCollection', () => {
orderIndex: 1,
});
const result = await teamCollectionService.moveCollection(
await teamCollectionService.moveCollection(
childTeamCollection.id,
childTeamCollection_2.id,
);
@ -1372,7 +1359,7 @@ describe('updateCollectionOrder', () => {
orderIndex: rootTeamCollectionList.length,
});
const result = await teamCollectionService.updateCollectionOrder(
await teamCollectionService.updateCollectionOrder(
rootTeamCollectionList[4].id,
null,
);
@ -1453,7 +1440,7 @@ describe('updateCollectionOrder', () => {
.mockResolvedValueOnce(childTeamCollectionList[4])
.mockResolvedValueOnce(childTeamCollectionList[2]);
const result = await teamCollectionService.updateCollectionOrder(
await teamCollectionService.updateCollectionOrder(
childTeamCollectionList[4].id,
childTeamCollectionList[2].id,
);
@ -1520,7 +1507,7 @@ describe('importCollectionsFromJSON', () => {
mockPrisma.teamCollection.findMany.mockResolvedValueOnce([]);
mockPrisma.$transaction.mockResolvedValueOnce([rootTeamCollection]);
const result = await teamCollectionService.importCollectionsFromJSON(
await teamCollectionService.importCollectionsFromJSON(
jsonString,
rootTeamCollection.teamID,
null,
@ -1639,7 +1626,7 @@ describe('replaceCollectionsWithJSON', () => {
mockPrisma.teamCollection.findMany.mockResolvedValueOnce([]);
mockPrisma.$transaction.mockResolvedValueOnce([rootTeamCollection]);
const result = await teamCollectionService.replaceCollectionsWithJSON(
await teamCollectionService.replaceCollectionsWithJSON(
jsonString,
rootTeamCollection.teamID,
null,
@ -1731,7 +1718,7 @@ describe('updateTeamCollection', () => {
test('should send pubsub message to "team_coll/<teamID>/coll_updated" if TeamCollection is updated successfully', async () => {
mockPrisma.teamCollection.update.mockResolvedValueOnce(rootTeamCollection);
const result = await teamCollectionService.updateTeamCollection(
await teamCollectionService.updateTeamCollection(
rootTeamCollection.id,
JSON.stringify(rootTeamCollection.data),
rootTeamCollection.title,

View file

@ -932,7 +932,7 @@ export class TeamCollectionService {
},
});
// Step 2: Update orderIndex of collection to length of list
const updatedTeamCollection = await tx.teamCollection.update({
await tx.teamCollection.update({
where: { id: collection.right.id },
data: {
orderIndex: await this.getCollectionCount(
@ -989,7 +989,7 @@ export class TeamCollectionService {
},
});
// Step 3: Update OrderIndex of collection
const updatedTeamCollection = await tx.teamCollection.update({
await tx.teamCollection.update({
where: { id: collection.right.id },
data: {
orderIndex: isMovingUp
@ -1262,9 +1262,8 @@ export class TeamCollectionService {
)
SELECT * FROM collection_tree;
`;
const res = await this.prisma.$queryRaw<ParentTreeQueryReturnType[]>(
query,
);
const res =
await this.prisma.$queryRaw<ParentTreeQueryReturnType[]>(query);
const collectionParentTree = this.generateParentTree(res);
return E.right(collectionParentTree);
@ -1353,9 +1352,8 @@ export class TeamCollectionService {
SELECT * FROM request_collection_tree;
`;
const res = await this.prisma.$queryRaw<ParentTreeQueryReturnType[]>(
query,
);
const res =
await this.prisma.$queryRaw<ParentTreeQueryReturnType[]>(query);
const requestParentTree = this.generateParentTree(res);
return E.right(requestParentTree);

View file

@ -2,14 +2,12 @@ import { Module } from '@nestjs/common';
import { TeamEnvironmentsService } from './team-environments.service';
import { TeamEnvironmentsResolver } from './team-environments.resolver';
import { UserModule } from 'src/user/user.module';
import { PubSubModule } from 'src/pubsub/pubsub.module';
import { TeamModule } from 'src/team/team.module';
import { PrismaModule } from 'src/prisma/prisma.module';
import { GqlTeamEnvTeamGuard } from './gql-team-env-team.guard';
import { TeamEnvsTeamResolver } from './team.resolver';
@Module({
imports: [PrismaModule, PubSubModule, UserModule, TeamModule],
imports: [UserModule, TeamModule],
providers: [
TeamEnvironmentsResolver,
TeamEnvironmentsService,

View file

@ -1,8 +1,6 @@
import { UseGuards } from '@nestjs/common';
import { Resolver, Mutation, Args, Subscription, ID } from '@nestjs/graphql';
import { SkipThrottle } from '@nestjs/throttler';
import { pipe } from 'fp-ts/function';
import * as TE from 'fp-ts/TaskEither';
import { GqlAuthGuard } from 'src/guards/gql-auth.guard';
import { GqlThrottlerGuard } from 'src/guards/gql-throttler.guard';
import { PubSubService } from 'src/pubsub/pubsub.service';
@ -61,9 +59,8 @@ export class TeamEnvironmentsResolver {
})
id: string,
): Promise<boolean> {
const isDeleted = await this.teamEnvironmentsService.deleteTeamEnvironment(
id,
);
const isDeleted =
await this.teamEnvironmentsService.deleteTeamEnvironment(id);
if (E.isLeft(isDeleted)) throwErr(isDeleted.left);
return isDeleted.right;
@ -125,9 +122,8 @@ export class TeamEnvironmentsResolver {
})
id: string,
): Promise<TeamEnvironment> {
const res = await this.teamEnvironmentsService.createDuplicateEnvironment(
id,
);
const res =
await this.teamEnvironmentsService.createDuplicateEnvironment(id);
if (E.isLeft(res)) throwErr(res.left);
return res.right;

View file

@ -3,7 +3,6 @@ import { PrismaService } from 'src/prisma/prisma.service';
import { TeamEnvironment } from './team-environments.model';
import { TeamEnvironmentsService } from './team-environments.service';
import {
JSON_INVALID,
TEAM_ENVIRONMENT_NOT_FOUND,
TEAM_ENVIRONMENT_SHORT_NAME,
TEAM_MEMBER_NOT_FOUND,
@ -92,7 +91,7 @@ describe('TeamEnvironmentsService', () => {
test('should send pubsub message to "team_environment/<teamID>/created" if team environment is created successfully', async () => {
mockPrisma.teamEnvironment.create.mockResolvedValue(teamEnvironment);
const result = await teamEnvironmentsService.createTeamEnvironment(
await teamEnvironmentsService.createTeamEnvironment(
teamEnvironment.name,
teamEnvironment.teamID,
JSON.stringify(teamEnvironment.variables),
@ -122,9 +121,8 @@ describe('TeamEnvironmentsService', () => {
test('should throw TEAM_ENVIRONMMENT_NOT_FOUND if given id is invalid', async () => {
mockPrisma.teamEnvironment.delete.mockRejectedValue('RecordNotFound');
const result = await teamEnvironmentsService.deleteTeamEnvironment(
'invalidid',
);
const result =
await teamEnvironmentsService.deleteTeamEnvironment('invalidid');
expect(result).toEqualLeft(TEAM_ENVIRONMENT_NOT_FOUND);
});
@ -132,9 +130,7 @@ describe('TeamEnvironmentsService', () => {
test('should send pubsub message to "team_environment/<teamID>/deleted" if team environment is deleted successfully', async () => {
mockPrisma.teamEnvironment.delete.mockResolvedValueOnce(teamEnvironment);
const result = await teamEnvironmentsService.deleteTeamEnvironment(
teamEnvironment.id,
);
await teamEnvironmentsService.deleteTeamEnvironment(teamEnvironment.id);
expect(mockPubSub.publish).toHaveBeenCalledWith(
`team_environment/${teamEnvironment.teamID}/deleted`,
@ -244,7 +240,7 @@ describe('TeamEnvironmentsService', () => {
test('should send pubsub message to "team_environment/<teamID>/updated" if team environment is updated successfully', async () => {
mockPrisma.teamEnvironment.update.mockResolvedValueOnce(teamEnvironment);
const result = await teamEnvironmentsService.updateTeamEnvironment(
await teamEnvironmentsService.updateTeamEnvironment(
teamEnvironment.id,
teamEnvironment.name,
JSON.stringify([{ key: 'value' }]),
@ -289,10 +285,9 @@ describe('TeamEnvironmentsService', () => {
test('should send pubsub message to "team_environment/<teamID>/updated" if team environment is updated successfully', async () => {
mockPrisma.teamEnvironment.update.mockResolvedValueOnce(teamEnvironment);
const result =
await teamEnvironmentsService.deleteAllVariablesFromTeamEnvironment(
teamEnvironment.id,
);
await teamEnvironmentsService.deleteAllVariablesFromTeamEnvironment(
teamEnvironment.id,
);
expect(mockPubSub.publish).toHaveBeenCalledWith(
`team_environment/${teamEnvironment.teamID}/updated`,
@ -348,7 +343,7 @@ describe('TeamEnvironmentsService', () => {
...teamEnvironment,
});
const result = await teamEnvironmentsService.createDuplicateEnvironment(
await teamEnvironmentsService.createDuplicateEnvironment(
teamEnvironment.id,
);

View file

@ -1,6 +1,4 @@
import { Module } from '@nestjs/common';
import { PrismaModule } from 'src/prisma/prisma.module';
import { PubSubModule } from 'src/pubsub/pubsub.module';
import { TeamModule } from 'src/team/team.module';
import { UserModule } from 'src/user/user.module';
import { TeamInvitationResolver } from './team-invitation.resolver';
@ -11,7 +9,7 @@ import { TeamInviteeGuard } from './team-invitee.guard';
import { TeamTeamInviteExtResolver } from './team-teaminvite-ext.resolver';
@Module({
imports: [PrismaModule, TeamModule, PubSubModule, UserModule],
imports: [TeamModule, UserModule],
providers: [
TeamInvitationService,
TeamInvitationResolver,

View file

@ -41,7 +41,6 @@ export class TeamInvitationResolver {
private readonly userService: UserService,
private readonly teamService: TeamService,
private readonly teamInvitationService: TeamInvitationService,
private readonly pubsub: PubSubService,
) {}
@ -85,9 +84,8 @@ export class TeamInvitationResolver {
})
inviteID: string,
): Promise<TeamInvitation> {
const teamInvitation = await this.teamInvitationService.getInvitation(
inviteID,
);
const teamInvitation =
await this.teamInvitationService.getInvitation(inviteID);
if (O.isNone(teamInvitation)) throwErr(TEAM_INVITE_NO_INVITE_FOUND);
return teamInvitation.value;
}
@ -125,9 +123,8 @@ export class TeamInvitationResolver {
})
inviteID: string,
): Promise<true> {
const isRevoked = await this.teamInvitationService.revokeInvitation(
inviteID,
);
const isRevoked =
await this.teamInvitationService.revokeInvitation(inviteID);
if (E.isLeft(isRevoked)) throwErr(isRevoked.left);
return true;
}

View file

@ -38,7 +38,7 @@ export class TeamInvitationService {
* @param dbTeamInvitation database TeamInvitation
* @returns TeamInvitation model
*/
cast(dbTeamInvitation: DBTeamInvitation): TeamInvitation {
private cast(dbTeamInvitation: DBTeamInvitation): TeamInvitation {
return {
...dbTeamInvitation,
inviteeRole: TeamAccessRole[dbTeamInvitation.inviteeRole],

View file

@ -36,9 +36,8 @@ export class GqlRequestTeamMemberGuard implements CanActivate {
const { requestID } = gqlExecCtx.getArgs<{ requestID: string }>();
if (!requestID) throw new Error(BUG_TEAM_REQ_NO_REQ_ID);
const team = await this.teamRequestService.getTeamOfRequestFromID(
requestID,
);
const team =
await this.teamRequestService.getTeamOfRequestFromID(requestID);
if (O.isNone(team)) throw new Error(TEAM_REQ_NOT_FOUND);
const member = await this.teamService.getTeamMember(

View file

@ -1,21 +1,13 @@
import { Module } from '@nestjs/common';
import { TeamRequestService } from './team-request.service';
import { TeamRequestResolver } from './team-request.resolver';
import { PrismaModule } from '../prisma/prisma.module';
import { TeamModule } from '../team/team.module';
import { TeamCollectionModule } from '../team-collection/team-collection.module';
import { GqlRequestTeamMemberGuard } from './guards/gql-request-team-member.guard';
import { UserModule } from '../user/user.module';
import { PubSubModule } from 'src/pubsub/pubsub.module';
@Module({
imports: [
PrismaModule,
TeamModule,
TeamCollectionModule,
UserModule,
PubSubModule,
],
imports: [TeamModule, TeamCollectionModule, UserModule],
providers: [
TeamRequestService,
TeamRequestResolver,

View file

@ -57,9 +57,8 @@ export class TeamRequestResolver {
complexity: 3,
})
async collection(@Parent() req: TeamRequest) {
const teamCollection = await this.teamRequestService.getCollectionOfRequest(
req,
);
const teamCollection =
await this.teamRequestService.getCollectionOfRequest(req);
if (E.isLeft(teamCollection)) throwErr(teamCollection.left);
return teamCollection.right;
}
@ -196,9 +195,8 @@ export class TeamRequestResolver {
})
requestID: string,
) {
const isDeleted = await this.teamRequestService.deleteTeamRequest(
requestID,
);
const isDeleted =
await this.teamRequestService.deleteTeamRequest(requestID);
if (E.isLeft(isDeleted)) throwErr(isDeleted.left);
return isDeleted.right;
}

View file

@ -4,11 +4,9 @@ import { TeamResolver } from './team.resolver';
import { UserModule } from '../user/user.module';
import { TeamMemberResolver } from './team-member.resolver';
import { GqlTeamMemberGuard } from './guards/gql-team-member.guard';
import { PrismaModule } from '../prisma/prisma.module';
import { PubSubModule } from '../pubsub/pubsub.module';
@Module({
imports: [UserModule, PubSubModule, PrismaModule],
imports: [UserModule],
providers: [
TeamService,
TeamResolver,

View file

@ -1,12 +1,10 @@
import { Module } from '@nestjs/common';
import { UserCollectionService } from './user-collection.service';
import { UserCollectionResolver } from './user-collection.resolver';
import { PrismaModule } from 'src/prisma/prisma.module';
import { UserModule } from 'src/user/user.module';
import { PubSubModule } from 'src/pubsub/pubsub.module';
@Module({
imports: [PrismaModule, UserModule, PubSubModule],
imports: [UserModule],
providers: [UserCollectionService, UserCollectionResolver],
exports: [UserCollectionService],
})

View file

@ -139,9 +139,8 @@ export class UserCollectionResolver {
})
userCollectionID: string,
) {
const userCollection = await this.userCollectionService.getUserCollection(
userCollectionID,
);
const userCollection =
await this.userCollectionService.getUserCollection(userCollectionID);
if (E.isLeft(userCollection)) throwErr(userCollection.left);
return <UserCollection>{

View file

@ -23,11 +23,7 @@ import { UserCollection } from './user-collections.model';
const mockPrisma = mockDeep<PrismaService>();
const mockPubSub = mockDeep<PubSubService>();
// @ts-ignore
const userCollectionService = new UserCollectionService(
mockPrisma,
mockPubSub as any,
);
const userCollectionService = new UserCollectionService(mockPrisma, mockPubSub);
const currentTime = new Date();
@ -99,36 +95,6 @@ const rootRESTUserCollection_2: DBUserCollection = {
data: {},
};
const rootRESTUserCollection_2Casted: UserCollection = {
id: '4gf',
parentID: null,
title: 'Root Collection 2',
userID: user.uid,
type: ReqType.REST,
data: JSON.stringify(rootRESTUserCollection_2.data),
};
const rootGQLUserCollection_2: DBUserCollection = {
id: '4gf',
orderIndex: 2,
parentID: null,
title: 'Root Collection 2',
userUid: user.uid,
type: ReqType.GQL,
createdOn: currentTime,
updatedOn: currentTime,
data: {},
};
const rootGQLUserCollection_2Casted: UserCollection = {
id: '4gf',
parentID: null,
title: 'Root Collection 2',
userID: user.uid,
type: ReqType.GQL,
data: JSON.stringify(rootGQLUserCollection_2.data),
};
const childRESTUserCollection: DBUserCollection = {
id: '234',
orderIndex: 1,
@ -192,27 +158,6 @@ const childRESTUserCollection_2Casted: UserCollection = {
data: JSON.stringify({}),
};
const childGQLUserCollection_2: DBUserCollection = {
id: '0kn',
orderIndex: 2,
parentID: rootRESTUserCollection_2.id,
title: 'Child Collection 2',
userUid: user.uid,
type: ReqType.GQL,
createdOn: currentTime,
updatedOn: currentTime,
data: {},
};
const childGQLUserCollection_2Casted: UserCollection = {
id: '0kn',
parentID: rootRESTUserCollection_2.id,
title: 'Child Collection 2',
userID: user.uid,
type: ReqType.GQL,
data: JSON.stringify({}),
};
const childRESTUserCollectionList: DBUserCollection[] = [
{
id: '234',
@ -639,9 +584,8 @@ describe('getParentOfUserCollection', () => {
childRESTUserCollection,
);
const result = await userCollectionService.getParentOfUserCollection(
'invalidId',
);
const result =
await userCollectionService.getParentOfUserCollection('invalidId');
//TODO: check it not null
expect(result).toEqual(null);
});
@ -899,7 +843,7 @@ describe('createUserCollection', () => {
childRESTUserCollection,
);
const result = await userCollectionService.createUserCollection(
await userCollectionService.createUserCollection(
user,
childRESTUserCollection.title,
JSON.stringify(childRESTUserCollection.data),
@ -924,7 +868,7 @@ describe('createUserCollection', () => {
childGQLUserCollection,
);
const result = await userCollectionService.createUserCollection(
await userCollectionService.createUserCollection(
user,
childGQLUserCollection.title,
JSON.stringify(childGQLUserCollection.data),
@ -949,7 +893,7 @@ describe('createUserCollection', () => {
rootRESTUserCollection,
);
const result = await userCollectionService.createUserCollection(
await userCollectionService.createUserCollection(
user,
rootRESTUserCollection.title,
JSON.stringify(rootRESTUserCollection.data),
@ -974,7 +918,7 @@ describe('createUserCollection', () => {
rootGQLUserCollection,
);
const result = await userCollectionService.createUserCollection(
await userCollectionService.createUserCollection(
user,
rootGQLUserCollection.title,
JSON.stringify(rootGQLUserCollection.data),
@ -1057,7 +1001,7 @@ describe('renameUserCollection', () => {
title: 'NewTitle',
});
const result = await userCollectionService.renameUserCollection(
await userCollectionService.renameUserCollection(
'NewTitle',
rootRESTUserCollection.id,
user.uid,
@ -1162,7 +1106,7 @@ describe('deleteUserCollection', () => {
rootRESTUserCollection,
);
const result = await userCollectionService.deleteUserCollection(
await userCollectionService.deleteUserCollection(
rootRESTUserCollection.id,
user.uid,
);
@ -1384,7 +1328,7 @@ describe('moveUserCollection', () => {
orderIndex: 2,
});
const result = await userCollectionService.moveUserCollection(
await userCollectionService.moveUserCollection(
childRESTUserCollection.id,
null,
user.uid,
@ -1507,7 +1451,7 @@ describe('moveUserCollection', () => {
orderIndex: 1,
});
const result = await userCollectionService.moveUserCollection(
await userCollectionService.moveUserCollection(
rootRESTUserCollection.id,
childRESTUserCollection.id,
user.uid,
@ -1624,7 +1568,7 @@ describe('updateUserCollectionOrder', () => {
orderIndex: childRESTUserCollectionList.length,
});
const result = await userCollectionService.updateUserCollectionOrder(
await userCollectionService.updateUserCollectionOrder(
childRESTUserCollectionList[4].id,
null,
user.uid,
@ -1711,7 +1655,7 @@ describe('updateUserCollectionOrder', () => {
.mockResolvedValueOnce(childRESTUserCollectionList[4])
.mockResolvedValueOnce(childRESTUserCollectionList[2]);
const result = await userCollectionService.updateUserCollectionOrder(
await userCollectionService.updateUserCollectionOrder(
childRESTUserCollectionList[4].id,
childRESTUserCollectionList[2].id,
user.uid,
@ -1818,7 +1762,7 @@ describe('updateUserCollection', () => {
rootRESTUserCollection,
);
const result = await userCollectionService.updateUserCollection(
await userCollectionService.updateUserCollection(
'new_title',
JSON.stringify({ foo: 'bar' }),
rootRESTUserCollection.id,

View file

@ -744,7 +744,7 @@ export class UserCollectionService {
},
});
// Step 2: Update orderIndex of collection to length of list
const updatedUserCollection = await tx.userCollection.update({
await tx.userCollection.update({
where: { id: collection.right.id },
data: {
orderIndex: await this.getCollectionCount(
@ -805,7 +805,7 @@ export class UserCollectionService {
},
});
// Step 3: Update OrderIndex of collection
const updatedUserCollection = await tx.userCollection.update({
await tx.userCollection.update({
where: { id: collection.right.id },
data: {
orderIndex: isMovingUp

View file

@ -1,5 +1,4 @@
import { ObjectType, Field, ID, registerEnumType } from '@nestjs/graphql';
import { User } from '@prisma/client';
import { ReqType } from 'src/types/RequestTypes';
import { UserRequest } from 'src/user-request/user-request.model';

View file

@ -1,13 +1,11 @@
import { Module } from '@nestjs/common';
import { PrismaModule } from '../prisma/prisma.module';
import { PubSubModule } from '../pubsub/pubsub.module';
import { UserModule } from '../user/user.module';
import { UserEnvsUserResolver } from './user.resolver';
import { UserEnvironmentsResolver } from './user-environments.resolver';
import { UserEnvironmentsService } from './user-environments.service';
@Module({
imports: [PrismaModule, PubSubModule, UserModule],
imports: [UserModule],
providers: [
UserEnvironmentsResolver,
UserEnvironmentsService,

View file

@ -8,6 +8,7 @@ import { throwErr } from '../utils';
@Resolver(() => User)
export class UserEnvsUserResolver {
constructor(private userEnvironmentsService: UserEnvironmentsService) {}
@ResolveField(() => [UserEnvironment], {
description: 'Returns a list of users personal environments',
})

View file

@ -1,6 +1,4 @@
import { Module } from '@nestjs/common';
import { PrismaModule } from '../prisma/prisma.module';
import { PubSubModule } from '../pubsub/pubsub.module';
import { UserModule } from '../user/user.module';
import { UserHistoryUserResolver } from './user.resolver';
import { UserHistoryResolver } from './user-history.resolver';
@ -8,7 +6,7 @@ import { UserHistoryService } from './user-history.service';
import { InfraConfigModule } from 'src/infra-config/infra-config.module';
@Module({
imports: [PrismaModule, PubSubModule, UserModule, InfraConfigModule],
imports: [UserModule, InfraConfigModule],
providers: [UserHistoryResolver, UserHistoryService, UserHistoryUserResolver],
exports: [UserHistoryService],
})

View file

@ -8,6 +8,7 @@ import { PaginationArgs } from '../types/input-types.args';
@Resolver(() => User)
export class UserHistoryUserResolver {
constructor(private userHistoryService: UserHistoryService) {}
@ResolveField(() => [UserHistory], {
description: 'Returns a users REST history',
})

View file

@ -1,7 +1,6 @@
import { UseGuards } from '@nestjs/common';
import {
Args,
Context,
ID,
Mutation,
Query,

View file

@ -1,13 +1,11 @@
import { Module } from '@nestjs/common';
import { UserCollectionModule } from 'src/user-collection/user-collection.module';
import { PrismaModule } from '../prisma/prisma.module';
import { PubSubModule } from '../pubsub/pubsub.module';
import { UserRequestUserCollectionResolver } from './resolvers/user-collection.resolver';
import { UserRequestResolver } from './resolvers/user-request.resolver';
import { UserRequestService } from './user-request.service';
@Module({
imports: [PrismaModule, PubSubModule, UserCollectionModule],
imports: [UserCollectionModule],
providers: [
UserRequestResolver,
UserRequestUserCollectionResolver,

View file

@ -27,10 +27,9 @@ const mockPrisma = mockDeep<PrismaService>();
const mockPubSub = mockDeep<PubSubService>();
const mockUserCollectionService = mockDeep<UserCollectionService>();
// @ts-ignore
const userRequestService = new UserRequestService(
mockPrisma,
mockPubSub as any,
mockPubSub,
mockUserCollectionService,
);
@ -541,7 +540,7 @@ describe('UserRequestService', () => {
mockPrisma.userRequest.findFirst.mockResolvedValue(dbUserRequests[0]);
mockPrisma.userRequest.delete.mockResolvedValue(null);
const result = await userRequestService.deleteRequest(id, user);
await userRequestService.deleteRequest(id, user);
expect(mockPubSub.publish).toHaveBeenCalledWith(
`user_request/${dbUserRequests[0].userUid}/deleted`,

View file

@ -120,9 +120,8 @@ export class UserRequestService {
const jsonRequest = stringToJson(request);
if (E.isLeft(jsonRequest)) return E.left(jsonRequest.left);
const collection = await this.userCollectionService.getUserCollection(
collectionID,
);
const collection =
await this.userCollectionService.getUserCollection(collectionID);
if (E.isLeft(collection)) return E.left(collection.left);
if (collection.right.userUid !== user.uid)
@ -132,9 +131,8 @@ export class UserRequestService {
return E.left(USER_REQUEST_INVALID_TYPE);
try {
const requestCount = await this.getRequestsCountInCollection(
collectionID,
);
const requestCount =
await this.getRequestsCountInCollection(collectionID);
const request = await this.prisma.userRequest.create({
data: {

View file

@ -1,13 +1,11 @@
import { Module } from '@nestjs/common';
import { PrismaModule } from 'src/prisma/prisma.module';
import { PubSubModule } from 'src/pubsub/pubsub.module';
import { UserModule } from 'src/user/user.module';
import { UserSettingsResolver } from './user-settings.resolver';
import { UserSettingsService } from './user-settings.service';
import { UserSettingsUserResolver } from './user.resolver';
@Module({
imports: [PrismaModule, PubSubModule, UserModule],
imports: [UserModule],
providers: [
UserSettingsResolver,
UserSettingsService,

View file

@ -79,11 +79,11 @@ export class UserDeletionResult {
@Field(() => Boolean, {
description: 'Flag to determine if user deletion was successful or not',
})
isDeleted: Boolean;
isDeleted: boolean;
@Field({
nullable: true,
description: 'Error message if user deletion was not successful',
})
errorMessage: String;
errorMessage: string;
}

View file

@ -1,11 +1,8 @@
import { Module } from '@nestjs/common';
import { UserResolver } from './user.resolver';
import { PubSubModule } from 'src/pubsub/pubsub.module';
import { UserService } from './user.service';
import { PrismaModule } from 'src/prisma/prisma.module';
@Module({
imports: [PubSubModule, PrismaModule],
providers: [UserResolver, UserService],
exports: [UserService],
})

View file

@ -26,7 +26,7 @@ import { TeamAccessRole } from 'src/team/team.model';
@Injectable()
export class UserService {
constructor(
private prisma: PrismaService,
private readonly prisma: PrismaService,
private readonly pubsub: PubSubService,
) {}