Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 12 additions & 13 deletions jslib/angular/src/services/jslib-services.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { AppIdService as AppIdServiceAbstraction } from "@/jslib/common/src/abst
import { BroadcasterService as BroadcasterServiceAbstraction } from "@/jslib/common/src/abstractions/broadcaster.service";
import { CryptoService as CryptoServiceAbstraction } from "@/jslib/common/src/abstractions/crypto.service";
import { CryptoFunctionService as CryptoFunctionServiceAbstraction } from "@/jslib/common/src/abstractions/cryptoFunction.service";
import { DirectoryFactoryAbstraction } from "@/jslib/common/src/abstractions/directory-factory.service";
import { EnvironmentService as EnvironmentServiceAbstraction } from "@/jslib/common/src/abstractions/environment.service";
import { I18nService as I18nServiceAbstraction } from "@/jslib/common/src/abstractions/i18n.service";
import { LogService } from "@/jslib/common/src/abstractions/log.service";
Expand All @@ -20,16 +19,18 @@ import { Account } from "@/jslib/common/src/models/domain/account";
import { GlobalState } from "@/jslib/common/src/models/domain/globalState";
import { ApiService } from "@/jslib/common/src/services/api.service";
import { AppIdService } from "@/jslib/common/src/services/appId.service";
import { BatchRequestBuilder } from "@/jslib/common/src/services/batch-requests.service";
import { ConsoleLogService } from "@/jslib/common/src/services/consoleLog.service";
import { CryptoService } from "@/jslib/common/src/services/crypto.service";
import { EnvironmentService } from "@/jslib/common/src/services/environment.service";
import { SingleRequestBuilder } from "@/jslib/common/src/services/single-request.service";
import { StateService } from "@/jslib/common/src/services/state.service";
import { StateMigrationService } from "@/jslib/common/src/services/stateMigration.service";
import { TokenService } from "@/jslib/common/src/services/token.service";

import { DirectoryFactoryService } from "@/src/services/directory-factory.service";
import { DirectoryFactoryService } from "@/src/abstractions/directory-factory.service";
import { StateService as StateServiceExtended } from "@/src/abstractions/state.service";
import { DefaultBatchRequestBuilder } from "@/src/services/default-batch-request-builder";
import { DefaultSingleRequestBuilder } from "@/src/services/default-single-request-builder";
import { DefaultDirectoryFactoryService } from "@/src/services/directory-factory.service";

import {
SafeInjectionToken,
Expand Down Expand Up @@ -144,19 +145,17 @@ import { ValidationService } from "./validation.service";
deps: [StorageServiceAbstraction, SECURE_STORAGE],
}),
safeProvider({
provide: BatchRequestBuilder,
useClass: BatchRequestBuilder,
useAngularDecorators: true,
provide: DefaultBatchRequestBuilder,
deps: []
}),
safeProvider({
provide: SingleRequestBuilder,
useClass: SingleRequestBuilder,
useAngularDecorators: true,
provide: DefaultSingleRequestBuilder,
deps: []
}),
safeProvider({
provide: DirectoryFactoryAbstraction,
useClass: DirectoryFactoryService,
useAngularDecorators: true,
provide: DirectoryFactoryService,
useClass: DefaultDirectoryFactoryService,
deps: [LogService, I18nServiceAbstraction, StateServiceExtended],
}),
] satisfies SafeProvider[],
})
Expand Down
15 changes: 0 additions & 15 deletions jslib/common/src/abstractions/directory-factory.service.ts

This file was deleted.

6 changes: 6 additions & 0 deletions src/abstractions/directory-factory.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { DirectoryType } from "@/src/enums/directoryType";
import { IDirectoryService } from "@/src/services/directory.service";

export abstract class DirectoryFactoryService {

Check warning on line 4 in src/abstractions/directory-factory.service.ts

View check run for this annotation

Codecov / codecov/patch

src/abstractions/directory-factory.service.ts#L4

Added line #L4 was not covered by tests
abstract createService(type: DirectoryType): IDirectoryService;
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { OrganizationImportRequest } from "@/jslib/common/src/models/request/organizationImportRequest";

import { GroupEntry } from "@/src/models/groupEntry";
import { UserEntry } from "@/src/models/userEntry";

import { OrganizationImportRequest } from "../models/request/organizationImportRequest";

export abstract class RequestBuilderAbstratction {

Check warning on line 6 in src/abstractions/request-builder.service.ts

View check run for this annotation

Codecov / codecov/patch

src/abstractions/request-builder.service.ts#L6

Added line #L6 was not covered by tests
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Abstraction suffix is not required:

Suggested change
export abstract class RequestBuilderAbstratction {
export abstract class RequestBuilder {

(then your names should be good!)

buildRequest: (
groups: GroupEntry[],
users: UserEntry[],
Expand Down
14 changes: 7 additions & 7 deletions src/app/services/services.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import { BroadcasterService as BroadcasterServiceAbstraction } from "@/jslib/common/src/abstractions/broadcaster.service";
import { CryptoService as CryptoServiceAbstraction } from "@/jslib/common/src/abstractions/crypto.service";
import { CryptoFunctionService as CryptoFunctionServiceAbstraction } from "@/jslib/common/src/abstractions/cryptoFunction.service";
import { DirectoryFactoryAbstraction } from "@/jslib/common/src/abstractions/directory-factory.service";
import { EnvironmentService as EnvironmentServiceAbstraction } from "@/jslib/common/src/abstractions/environment.service";
import { I18nService as I18nServiceAbstraction } from "@/jslib/common/src/abstractions/i18n.service";
import { LogService as LogServiceAbstraction } from "@/jslib/common/src/abstractions/log.service";
Expand All @@ -17,9 +16,7 @@
import { TokenService as TokenServiceAbstraction } from "@/jslib/common/src/abstractions/token.service";
import { StateFactory } from "@/jslib/common/src/factories/stateFactory";
import { GlobalState } from "@/jslib/common/src/models/domain/globalState";
import { BatchRequestBuilder as BatchRequestAbstraction } from "@/jslib/common/src/services/batch-requests.service";
import { ContainerService } from "@/jslib/common/src/services/container.service";
import { SingleRequestBuilder as SingleRequestAbstraction } from "@/jslib/common/src/services/single-request.service";
import { ElectronLogService } from "@/jslib/electron/src/services/electronLog.service";
import { ElectronPlatformUtilsService } from "@/jslib/electron/src/services/electronPlatformUtils.service";
import { ElectronRendererMessagingService } from "@/jslib/electron/src/services/electronRendererMessaging.service";
Expand All @@ -28,6 +25,10 @@
import { NodeApiService } from "@/jslib/node/src/services/nodeApi.service";
import { NodeCryptoFunctionService } from "@/jslib/node/src/services/nodeCryptoFunction.service";

import { DirectoryFactoryService } from "@/src/abstractions/directory-factory.service";
import { DefaultBatchRequestBuilder } from "@/src/services/default-batch-request-builder";
import { DefaultSingleRequestBuilder } from "@/src/services/default-single-request-builder";

Check warning on line 30 in src/app/services/services.module.ts

View check run for this annotation

Codecov / codecov/patch

src/app/services/services.module.ts#L28-L30

Added lines #L28 - L30 were not covered by tests

import { AuthService as AuthServiceAbstraction } from "../../abstractions/auth.service";
import { StateService as StateServiceAbstraction } from "../../abstractions/state.service";
import { Account } from "../../models/account";
Expand Down Expand Up @@ -171,16 +172,15 @@
provide: SyncService,
useClass: SyncService,
deps: [
LogServiceAbstraction,
CryptoFunctionServiceAbstraction,
ApiServiceAbstraction,
MessagingServiceAbstraction,
I18nServiceAbstraction,
EnvironmentServiceAbstraction,
StateServiceAbstraction,
BatchRequestAbstraction,
SingleRequestAbstraction,
DirectoryFactoryAbstraction,
DefaultBatchRequestBuilder,
DefaultSingleRequestBuilder,
DirectoryFactoryService,
],
}),
safeProvider(AuthGuardService),
Expand Down
21 changes: 15 additions & 6 deletions src/bwdc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,23 @@
import { StateFactory } from "@/jslib/common/src/factories/stateFactory";
import { GlobalState } from "@/jslib/common/src/models/domain/globalState";
import { AppIdService } from "@/jslib/common/src/services/appId.service";
import { BatchRequestBuilder } from "@/jslib/common/src/services/batch-requests.service";
import { ContainerService } from "@/jslib/common/src/services/container.service";
import { CryptoService } from "@/jslib/common/src/services/crypto.service";
import { EnvironmentService } from "@/jslib/common/src/services/environment.service";
import { NoopMessagingService } from "@/jslib/common/src/services/noopMessaging.service";
import { SingleRequestBuilder } from "@/jslib/common/src/services/single-request.service";
import { TokenService } from "@/jslib/common/src/services/token.service";
import { CliPlatformUtilsService } from "@/jslib/node/src/cli/services/cliPlatformUtils.service";
import { ConsoleLogService } from "@/jslib/node/src/cli/services/consoleLog.service";
import { NodeApiService } from "@/jslib/node/src/services/nodeApi.service";
import { NodeCryptoFunctionService } from "@/jslib/node/src/services/nodeCryptoFunction.service";

import { DirectoryFactoryService } from "./abstractions/directory-factory.service";
import { Account } from "./models/account";
import { Program } from "./program";
import { AuthService } from "./services/auth.service";
import { DirectoryFactoryService } from "./services/directory-factory.service";
import { DefaultBatchRequestBuilder } from "./services/default-batch-request-builder";
import { DefaultSingleRequestBuilder } from "./services/default-single-request-builder";
import { DefaultDirectoryFactoryService } from "./services/directory-factory.service";

Check warning on line 26 in src/bwdc.ts

View check run for this annotation

Codecov / codecov/patch

src/bwdc.ts#L24-L26

Added lines #L24 - L26 were not covered by tests
import { I18nService } from "./services/i18n.service";
import { KeytarSecureStorageService } from "./services/keytarSecureStorage.service";
import { LowdbStorageService } from "./services/lowdbStorage.service";
Expand Down Expand Up @@ -55,8 +56,8 @@
stateService: StateService;
stateMigrationService: StateMigrationService;
directoryFactoryService: DirectoryFactoryService;
batchRequestBuilder: BatchRequestBuilder;
singleRequestBuilder: SingleRequestBuilder;
batchRequestBuilder: DefaultBatchRequestBuilder;
singleRequestBuilder: DefaultSingleRequestBuilder;

constructor() {
const applicationName = "Bitwarden Directory Connector";
Expand Down Expand Up @@ -152,8 +153,16 @@
this.stateService,
);

this.syncService = new SyncService(
this.directoryFactoryService = new DefaultDirectoryFactoryService(

Check warning on line 156 in src/bwdc.ts

View check run for this annotation

Codecov / codecov/patch

src/bwdc.ts#L156

Added line #L156 was not covered by tests
this.logService,
this.i18nService,
this.stateService,
);

this.batchRequestBuilder = new DefaultBatchRequestBuilder();
this.singleRequestBuilder = new DefaultSingleRequestBuilder();

Check warning on line 163 in src/bwdc.ts

View check run for this annotation

Codecov / codecov/patch

src/bwdc.ts#L162-L163

Added lines #L162 - L163 were not covered by tests

this.syncService = new SyncService(

Check warning on line 165 in src/bwdc.ts

View check run for this annotation

Codecov / codecov/patch

src/bwdc.ts#L165

Added line #L165 was not covered by tests
this.cryptoFunctionService,
this.apiService,
this.messagingService,
Expand Down
4 changes: 0 additions & 4 deletions src/models/hashResult.ts

This file was deleted.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You've duplicated this file instead of renaming it (there is now a default-batch-request-builder.ts and a batch-requests-builder.ts).

Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
import { OrganizationImportRequest } from "@/jslib/common/src/models/request/organizationImportRequest";

Check warning on line 1 in src/services/default-batch-request-builder.ts

View check run for this annotation

Codecov / codecov/patch

src/services/default-batch-request-builder.ts#L1

Added line #L1 was not covered by tests

import { GroupEntry } from "@/src/models/groupEntry";
import { UserEntry } from "@/src/models/userEntry";

import { RequestBuilderAbstratction } from "../abstractions/request-builder.service";

export class BatchRequestBuilder implements RequestBuilderAbstratction {
batchSize = 2000;
import { batchSize } from "./sync.service";

Check warning on line 8 in src/services/default-batch-request-builder.ts

View check run for this annotation

Codecov / codecov/patch

src/services/default-batch-request-builder.ts#L8

Added line #L8 was not covered by tests

/**
* This class is responsible for batching large sync requests (>2k users) into multiple smaller
* requests to the /import REST endpoint. This is done to ensure we are under the default
* maximum packet size for NGINX web servers to avoid the request potentially timing out
* */
export class DefaultBatchRequestBuilder implements RequestBuilderAbstratction {

Check warning on line 15 in src/services/default-batch-request-builder.ts

View check run for this annotation

Codecov / codecov/patch

src/services/default-batch-request-builder.ts#L15

Added line #L15 was not covered by tests
buildRequest(
groups: GroupEntry[],
users: UserEntry[],
removeDisabled: boolean,
overwriteExisting: boolean,
): OrganizationImportRequest[] {
const requests: OrganizationImportRequest[] = [];

Check warning on line 22 in src/services/default-batch-request-builder.ts

View check run for this annotation

Codecov / codecov/patch

src/services/default-batch-request-builder.ts#L22

Added line #L22 was not covered by tests

if (users.length > 0) {
const usersRequest = users.map((u) => {
return {

Check warning on line 26 in src/services/default-batch-request-builder.ts

View check run for this annotation

Codecov / codecov/patch

src/services/default-batch-request-builder.ts#L25-L26

Added lines #L25 - L26 were not covered by tests
email: u.email,
externalId: u.externalId,
deleted: u.deleted || (removeDisabled && u.disabled),
Expand All @@ -26,21 +31,21 @@
});

// Partition users
for (let i = 0; i < usersRequest.length; i += this.batchSize) {
const u = usersRequest.slice(i, i + this.batchSize);
for (let i = 0; i < usersRequest.length; i += batchSize) {
const u = usersRequest.slice(i, i + batchSize);
const req = new OrganizationImportRequest({

Check warning on line 36 in src/services/default-batch-request-builder.ts

View check run for this annotation

Codecov / codecov/patch

src/services/default-batch-request-builder.ts#L34-L36

Added lines #L34 - L36 were not covered by tests
groups: [],
users: u,
largeImport: true,
overwriteExisting,
});
requests.push(req);

Check warning on line 42 in src/services/default-batch-request-builder.ts

View check run for this annotation

Codecov / codecov/patch

src/services/default-batch-request-builder.ts#L42

Added line #L42 was not covered by tests
}
}

if (groups.length > 0) {
const groupRequest = groups.map((g) => {
return {

Check warning on line 48 in src/services/default-batch-request-builder.ts

View check run for this annotation

Codecov / codecov/patch

src/services/default-batch-request-builder.ts#L47-L48

Added lines #L47 - L48 were not covered by tests
name: g.name,
externalId: g.externalId,
memberExternalIds: Array.from(g.userMemberExternalIds),
Expand All @@ -48,18 +53,18 @@
});

// Partition groups
for (let i = 0; i < groupRequest.length; i += this.batchSize) {
const g = groupRequest.slice(i, i + this.batchSize);
for (let i = 0; i < groupRequest.length; i += batchSize) {
const g = groupRequest.slice(i, i + batchSize);
const req = new OrganizationImportRequest({

Check warning on line 58 in src/services/default-batch-request-builder.ts

View check run for this annotation

Codecov / codecov/patch

src/services/default-batch-request-builder.ts#L56-L58

Added lines #L56 - L58 were not covered by tests
groups: g,
users: [],
largeImport: true,
overwriteExisting,
});
requests.push(req);

Check warning on line 64 in src/services/default-batch-request-builder.ts

View check run for this annotation

Codecov / codecov/patch

src/services/default-batch-request-builder.ts#L64

Added line #L64 was not covered by tests
}
}

return requests;

Check warning on line 68 in src/services/default-batch-request-builder.ts

View check run for this annotation

Codecov / codecov/patch

src/services/default-batch-request-builder.ts#L68

Added line #L68 was not covered by tests
}
}
Original file line number Diff line number Diff line change
@@ -1,32 +1,24 @@
import { GroupEntry } from "@/src/models/groupEntry";
import { UserEntry } from "@/src/models/userEntry";

import { BatchRequestBuilder } from "./batch-requests.service";
import { SingleRequestBuilder } from "./single-request.service";
import { DefaultBatchRequestBuilder } from "./default-batch-request-builder";
import { DefaultSingleRequestBuilder } from "./default-single-request-builder";

describe("BatchingService", () => {
let batchRequestBuilder: BatchRequestBuilder;
let singleRequestBuilder: SingleRequestBuilder;
let batchRequestBuilder: DefaultBatchRequestBuilder;
let singleRequestBuilder: DefaultSingleRequestBuilder;

function userSimulator(userCount: number) {
const simulatedArray: UserEntry[] = [];
for (let i = 0; i <= userCount; i++) {
simulatedArray.push(new UserEntry());
}
return simulatedArray;
return Array(userCount).fill(new UserEntry());
}

function groupSimulator(groupCount: number) {
const simulatedArray: GroupEntry[] = [];
for (let i = 0; i <= groupCount; i++) {
simulatedArray.push(new GroupEntry());
}
return simulatedArray;
return Array(groupCount).fill(new GroupEntry());
}

beforeEach(async () => {
batchRequestBuilder = new BatchRequestBuilder();
singleRequestBuilder = new SingleRequestBuilder();
batchRequestBuilder = new DefaultBatchRequestBuilder();
singleRequestBuilder = new DefaultSingleRequestBuilder();
});

it("BatchRequestBuilder batches requests for > 2000 users", () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,34 @@
import { OrganizationImportRequest } from "@/jslib/common/src/models/request/organizationImportRequest";

Check warning on line 1 in src/services/default-single-request-builder.ts

View check run for this annotation

Codecov / codecov/patch

src/services/default-single-request-builder.ts#L1

Added line #L1 was not covered by tests

import { GroupEntry } from "@/src/models/groupEntry";
import { UserEntry } from "@/src/models/userEntry";

import { RequestBuilderAbstratction } from "../abstractions/request-builder.service";

export class SingleRequestBuilder implements RequestBuilderAbstratction {
/**
* This class is responsible for building small (<2k users) syncs as a single
* request to the /import endpoint. This is done to be backwards compatible with
* existing functionality for sync requests that are sufficiently small enough to not
* exceed default maximum packet size limits on NGINX web servers.
* */
export class DefaultSingleRequestBuilder implements RequestBuilderAbstratction {

Check warning on line 14 in src/services/default-single-request-builder.ts

View check run for this annotation

Codecov / codecov/patch

src/services/default-single-request-builder.ts#L14

Added line #L14 was not covered by tests
buildRequest(
groups: GroupEntry[],
users: UserEntry[],
removeDisabled: boolean,
overwriteExisting: boolean,
): OrganizationImportRequest[] {
return [

Check warning on line 21 in src/services/default-single-request-builder.ts

View check run for this annotation

Codecov / codecov/patch

src/services/default-single-request-builder.ts#L21

Added line #L21 was not covered by tests
new OrganizationImportRequest({
groups: (groups ?? []).map((g) => {
return {

Check warning on line 24 in src/services/default-single-request-builder.ts

View check run for this annotation

Codecov / codecov/patch

src/services/default-single-request-builder.ts#L24

Added line #L24 was not covered by tests
name: g.name,
externalId: g.externalId,
memberExternalIds: Array.from(g.userMemberExternalIds),
};
}),
users: (users ?? []).map((u) => {
return {

Check warning on line 31 in src/services/default-single-request-builder.ts

View check run for this annotation

Codecov / codecov/patch

src/services/default-single-request-builder.ts#L31

Added line #L31 was not covered by tests
email: u.email,
externalId: u.externalId,
deleted: u.deleted || (removeDisabled && u.disabled),
Expand Down
29 changes: 15 additions & 14 deletions src/services/directory-factory.service.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,37 @@
import { DirectoryFactoryAbstraction } from "@/jslib/common/src/abstractions/directory-factory.service";
import { I18nService } from "@/jslib/common/src/abstractions/i18n.service";
import { LogService } from "@/jslib/common/src/abstractions/log.service";

import { DirectoryFactoryService } from "../abstractions/directory-factory.service";
import { StateService } from "../abstractions/state.service";
import { DirectoryType } from "../enums/directoryType";

Check warning on line 6 in src/services/directory-factory.service.ts

View check run for this annotation

Codecov / codecov/patch

src/services/directory-factory.service.ts#L6

Added line #L6 was not covered by tests

import { AzureDirectoryService } from "./azure-directory.service";
import { GSuiteDirectoryService } from "./gsuite-directory.service";
import { LdapDirectoryService } from "./ldap-directory.service";
import { OktaDirectoryService } from "./okta-directory.service";
import { OneLoginDirectoryService } from "./onelogin-directory.service";

Check warning on line 12 in src/services/directory-factory.service.ts

View check run for this annotation

Codecov / codecov/patch

src/services/directory-factory.service.ts#L8-L12

Added lines #L8 - L12 were not covered by tests

export class DirectoryFactoryService implements DirectoryFactoryAbstraction {
createService(
directoryType: DirectoryType,
logService: LogService,
i18nService: I18nService,
stateService: StateService,
) {
export class DefaultDirectoryFactoryService implements DirectoryFactoryService {

Check warning on line 14 in src/services/directory-factory.service.ts

View check run for this annotation

Codecov / codecov/patch

src/services/directory-factory.service.ts#L14

Added line #L14 was not covered by tests
constructor(
private logService: LogService,
private i18nService: I18nService,
private stateService: StateService,

Check warning on line 18 in src/services/directory-factory.service.ts

View check run for this annotation

Codecov / codecov/patch

src/services/directory-factory.service.ts#L16-L18

Added lines #L16 - L18 were not covered by tests
) {}

createService(directoryType: DirectoryType) {
switch (directoryType) {
case DirectoryType.GSuite:
return new GSuiteDirectoryService(logService, i18nService, stateService);
return new GSuiteDirectoryService(this.logService, this.i18nService, this.stateService);

Check warning on line 24 in src/services/directory-factory.service.ts

View check run for this annotation

Codecov / codecov/patch

src/services/directory-factory.service.ts#L24

Added line #L24 was not covered by tests
case DirectoryType.AzureActiveDirectory:
return new AzureDirectoryService(logService, i18nService, stateService);
return new AzureDirectoryService(this.logService, this.i18nService, this.stateService);

Check warning on line 26 in src/services/directory-factory.service.ts

View check run for this annotation

Codecov / codecov/patch

src/services/directory-factory.service.ts#L26

Added line #L26 was not covered by tests
case DirectoryType.Ldap:
return new LdapDirectoryService(logService, i18nService, stateService);
return new LdapDirectoryService(this.logService, this.i18nService, this.stateService);

Check warning on line 28 in src/services/directory-factory.service.ts

View check run for this annotation

Codecov / codecov/patch

src/services/directory-factory.service.ts#L28

Added line #L28 was not covered by tests
case DirectoryType.Okta:
return new OktaDirectoryService(logService, i18nService, stateService);
return new OktaDirectoryService(this.logService, this.i18nService, this.stateService);

Check warning on line 30 in src/services/directory-factory.service.ts

View check run for this annotation

Codecov / codecov/patch

src/services/directory-factory.service.ts#L30

Added line #L30 was not covered by tests
case DirectoryType.OneLogin:
return new OneLoginDirectoryService(logService, i18nService, stateService);
return new OneLoginDirectoryService(this.logService, this.i18nService, this.stateService);

Check warning on line 32 in src/services/directory-factory.service.ts

View check run for this annotation

Codecov / codecov/patch

src/services/directory-factory.service.ts#L32

Added line #L32 was not covered by tests
default:
return null;
throw new Error("Invalid Directory Type");

Check warning on line 34 in src/services/directory-factory.service.ts

View check run for this annotation

Codecov / codecov/patch

src/services/directory-factory.service.ts#L34

Added line #L34 was not covered by tests
}
}
}
Loading
Loading