Skip to content

Commit bedb401

Browse files
willy.ovalle@klarna.commamodom
authored andcommitted
fix: throw if CustomRepository does not inherit from Base
Co-authored-by: Maximo Dominguez <[email protected]>
1 parent 8d356b6 commit bedb401

File tree

3 files changed

+69
-5
lines changed

3 files changed

+69
-5
lines changed

src/BaseFirestoreRepository.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,18 @@ import {
2929
SubCollectionMetadata,
3030
} from './MetadataStorage';
3131

32+
/**
33+
* Dummy class created with the sole purpose to be able to
34+
* check if other classes are instances of BaseFirestoreRepository.
35+
* Typescript is not capable to check instances of generics.
36+
*
37+
* @export
38+
* @class BaseRepository
39+
*/
40+
export class BaseRepository {}
41+
3242
export default class BaseFirestoreRepository<T extends IEntity>
43+
extends BaseRepository
3344
implements IRepository<T>, IQueryBuilder<T>, IQueryExecutor<T> {
3445
public collectionType: FirestoreCollectionType;
3546
private readonly firestoreColRef: CollectionReference;
@@ -44,6 +55,7 @@ export default class BaseFirestoreRepository<T extends IEntity>
4455
protected readonly docId?: string,
4556
protected readonly subColName?: string
4657
) {
58+
super();
4759
const {
4860
firestoreRef,
4961
getCollection,

src/Decorators/CustomRepository.spec.ts

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import CustomRepository from './CustomRepository';
22
import { expect } from 'chai';
33
import { MetadataStorage, Initialize } from '../MetadataStorage';
4+
import { BaseFirestoreRepository } from '..';
45

56
describe('CustomRepositoryDecorator', () => {
67
const store = { metadataStorage: new MetadataStorage() };
@@ -16,14 +17,51 @@ describe('CustomRepositoryDecorator', () => {
1617
}
1718

1819
@CustomRepository(Entity)
19-
class EntityRepo {}
20+
class EntityRepo extends BaseFirestoreRepository<Entity> {}
2021

2122
const repository = store.metadataStorage.repositories.get(Entity);
2223
expect(store.metadataStorage.repositories.size).to.eql(1);
2324
expect(repository.entity).to.eql(Entity);
2425
expect(repository.target).to.eql(EntityRepo);
2526
});
2627

27-
it('should enforce that custom repository inherits from BaseRepository');
28-
it('should only register a repository once');
28+
it('should only register a repository once', () => {
29+
class Entity {
30+
id: string;
31+
}
32+
33+
expect(() => {
34+
@CustomRepository(Entity)
35+
class EntityRepo extends BaseFirestoreRepository<Entity> {}
36+
37+
@CustomRepository(Entity)
38+
class EntityRepo2 extends BaseFirestoreRepository<Entity> {}
39+
}).to.throw;
40+
});
41+
42+
it('should only register a repository once', () => {
43+
class Entity {
44+
id: string;
45+
}
46+
47+
@CustomRepository(Entity)
48+
@CustomRepository(Entity)
49+
class EntityRepo extends BaseFirestoreRepository<Entity> {}
50+
51+
const repository = store.metadataStorage.repositories.get(Entity);
52+
expect(store.metadataStorage.repositories.size).to.eql(1);
53+
expect(repository.entity).to.eql(Entity);
54+
expect(repository.target).to.eql(EntityRepo);
55+
});
56+
57+
it('should enforce that custom repository inherits from BaseRepository', () => {
58+
class Entity {
59+
id: string;
60+
}
61+
62+
expect(() => {
63+
@CustomRepository(Entity)
64+
class EntityRepo {}
65+
}).to.throw;
66+
});
2967
});

src/MetadataStorage.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { InstanstiableIEntity } from './types';
21
import { Firestore } from '@google-cloud/firestore';
2+
import { BaseRepository } from './BaseFirestoreRepository';
33
let store: IMetadataStore = null;
44

55
export interface IMetadataStore {
@@ -60,11 +60,25 @@ export class MetadataStorage {
6060
this.subCollections.push(subCol);
6161
};
6262

63-
public getRepository = (param: string | InstanstiableIEntity) => {
63+
public getRepository = (param: Function) => {
6464
return this.repositories.get(param);
6565
};
6666

6767
public setRepository = (repo: RepositoryMetadata) => {
68+
const savedRepo = this.getRepository(repo.entity);
69+
70+
if (savedRepo && repo.target !== savedRepo.target) {
71+
throw new Error(
72+
'Cannot register a custom repository twice with two different targets'
73+
);
74+
}
75+
76+
if (!(repo.target.prototype instanceof BaseRepository)) {
77+
throw new Error(
78+
'Cannot register a custom repository on a class that does not inherit from BaseFirestoreRepository'
79+
);
80+
}
81+
6882
this.repositories.set(repo.entity, repo);
6983
};
7084

0 commit comments

Comments
 (0)