Skip to content

Commit d5d1726

Browse files
authored
fix: separate app and db model generic params (#79)
* Replace generic params * Update AbstractTraverser * Fixes * Update takes DbModelType * Fix collectionPopulator * Fix `withExitEarlyPredicate` * Adjust test
1 parent c0ee699 commit d5d1726

31 files changed

+403
-204
lines changed

__tests__/types/DefaultMigrator.test-d.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,33 @@
33
import { firestore } from 'firebase-admin';
44
import { expectError, expectType } from 'tsd';
55
import { DefaultMigrator, Traverser, createMigrator, createTraverser } from '../../src';
6-
import { D, collectionRef } from './_helpers';
6+
import { TestAppModelType, TestDbModelType, collectionRef } from './_helpers';
77

88
const defaultMigrator = createMigrator(collectionRef);
99

10-
expectType<Traverser<D>>(defaultMigrator.traverser);
10+
expectType<Traverser<TestAppModelType, TestDbModelType>>(defaultMigrator.traverser);
1111

1212
(() => {
1313
const modifiedMigrator = defaultMigrator.withPredicate((doc) => {
14-
expectType<firestore.QueryDocumentSnapshot<D>>(doc);
14+
expectType<firestore.QueryDocumentSnapshot<TestAppModelType, TestDbModelType>>(doc);
1515
return false;
1616
});
17-
expectType<DefaultMigrator<D>>(modifiedMigrator);
17+
expectType<DefaultMigrator<TestAppModelType, TestDbModelType>>(modifiedMigrator);
1818
})();
1919

2020
(() => {
2121
const traverser = createTraverser(collectionRef);
2222
const modifiedMigrator = defaultMigrator.withTraverser(traverser);
23-
expectType<DefaultMigrator<D>>(modifiedMigrator);
23+
expectType<DefaultMigrator<TestAppModelType, TestDbModelType>>(modifiedMigrator);
2424
})();
2525

2626
defaultMigrator.onBeforeBatchStart((batchDocs, batchIndex) => {
27-
expectType<firestore.QueryDocumentSnapshot<D>[]>(batchDocs);
27+
expectType<firestore.QueryDocumentSnapshot<TestAppModelType, TestDbModelType>[]>(batchDocs);
2828
expectType<number>(batchIndex);
2929
});
3030

3131
defaultMigrator.onAfterBatchComplete((batchDocs, batchIndex) => {
32-
expectType<firestore.QueryDocumentSnapshot<D>[]>(batchDocs);
32+
expectType<firestore.QueryDocumentSnapshot<TestAppModelType, TestDbModelType>[]>(batchDocs);
3333
expectType<number>(batchIndex);
3434
});
3535

@@ -52,17 +52,17 @@ defaultMigrator.set({ num: 0 }, { merge: true });
5252

5353
expectError(
5454
defaultMigrator.setWithDerivedData((doc) => {
55-
expectType<firestore.QueryDocumentSnapshot<D>>(doc);
55+
expectType<firestore.QueryDocumentSnapshot<TestAppModelType, TestDbModelType>>(doc);
5656
return { num: 0 };
5757
})
5858
);
5959
defaultMigrator.setWithDerivedData((doc) => {
60-
expectType<firestore.QueryDocumentSnapshot<D>>(doc);
60+
expectType<firestore.QueryDocumentSnapshot<TestAppModelType, TestDbModelType>>(doc);
6161
return { num: 0, text: '' };
6262
});
6363
defaultMigrator.setWithDerivedData(
6464
(doc) => {
65-
expectType<firestore.QueryDocumentSnapshot<D>>(doc);
65+
expectType<firestore.QueryDocumentSnapshot<TestAppModelType, TestDbModelType>>(doc);
6666
return { num: 0 };
6767
},
6868
{ merge: true }
@@ -78,14 +78,14 @@ defaultMigrator.update('anyField', 'anyValue');
7878

7979
expectError(
8080
defaultMigrator.updateWithDerivedData((doc) => {
81-
expectType<firestore.QueryDocumentSnapshot<D>>(doc);
81+
expectType<firestore.QueryDocumentSnapshot<TestAppModelType, TestDbModelType>>(doc);
8282
return { anyField: '' };
8383
})
8484
);
8585

8686
expectError(
8787
defaultMigrator.updateWithDerivedData((doc) => {
88-
expectType<firestore.QueryDocumentSnapshot<D>>(doc);
88+
expectType<firestore.QueryDocumentSnapshot<TestAppModelType, TestDbModelType>>(doc);
8989
return ['anyField', 'anyValue'];
9090
})
9191
);

__tests__/types/Traverser.test-d.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ import {
99
TraversalResult,
1010
Traverser,
1111
} from '../../src';
12-
import { collectionRef, D } from './_helpers';
12+
import { collectionRef, TestAppModelType, TestDbModelType } from './_helpers';
1313

1414
const traverser = createTraverser(collectionRef);
1515

16-
// TODO: Ideally we want to expect a firestore.CollectionReference<D> here because
16+
// TODO: Ideally we want to expect a firestore.CollectionReference<TestAppModelType, TestDbModelType> here because
1717
// we initialized the traverser with a collection reference.
18-
expectType<Traversable<D>>(traverser.traversable);
18+
expectType<Traversable<TestAppModelType, TestDbModelType>>(traverser.traversable);
1919

2020
expectType<TraversalConfig>(traverser.traversalConfig);
2121

@@ -27,21 +27,21 @@ expectType<TraversalConfig>(traverser.traversalConfig);
2727
maxDocCount: 0,
2828
maxConcurrentBatchCount: 0,
2929
});
30-
expectType<Traverser<D>>(modifiedTraverser);
30+
expectType<Traverser<TestAppModelType, TestDbModelType>>(modifiedTraverser);
3131
})();
3232

3333
(() => {
3434
const modifiedTraverser = traverser.withExitEarlyPredicate((batchDocs, batchIndex) => {
35-
expectType<firestore.QueryDocumentSnapshot<D>[]>(batchDocs);
35+
expectType<firestore.QueryDocumentSnapshot<TestAppModelType, TestDbModelType>[]>(batchDocs);
3636
expectType<number>(batchIndex);
3737
return false;
3838
});
39-
expectType<Traverser<D>>(modifiedTraverser);
39+
expectType<Traverser<TestAppModelType, TestDbModelType>>(modifiedTraverser);
4040
})();
4141

4242
(async () => {
4343
const traversalResult1 = await traverser.traverseEach(async (doc, docIndex, batchIndex) => {
44-
expectType<firestore.QueryDocumentSnapshot<D>>(doc);
44+
expectType<firestore.QueryDocumentSnapshot<TestAppModelType, TestDbModelType>>(doc);
4545
expectType<number>(docIndex);
4646
expectType<number>(batchIndex);
4747
});
@@ -50,7 +50,7 @@ expectType<TraversalConfig>(traverser.traversalConfig);
5050

5151
(async () => {
5252
const traversalResult2 = await traverser.traverse(async (batchDocs, batchIndex) => {
53-
expectType<firestore.QueryDocumentSnapshot<D>[]>(batchDocs);
53+
expectType<firestore.QueryDocumentSnapshot<TestAppModelType, TestDbModelType>[]>(batchDocs);
5454
expectType<number>(batchIndex);
5555
});
5656
expectType<TraversalResult>(traversalResult2);

__tests__/types/_helpers.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
import { firestore } from 'firebase-admin';
22

3-
export type D = {
3+
export type TestAppModelType = {
44
text: string;
55
num: number;
66
};
77

8-
export const collectionRef = firestore().collection('projects') as firestore.CollectionReference<D>;
8+
export type TestDbModelType = {
9+
text: string;
10+
num: number;
11+
};
12+
13+
export const collectionRef = firestore().collection('projects') as firestore.CollectionReference<
14+
TestAppModelType,
15+
TestDbModelType
16+
>;

__tests__/types/createBatchMigrator.test-d.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
import { expectType } from 'tsd';
44
import { createBatchMigrator, createTraverser, BatchMigrator } from '../../src';
5-
import { collectionRef, D } from './_helpers';
5+
import { collectionRef, TestAppModelType, TestDbModelType } from './_helpers';
66

77
// Signature 1
88

99
const traverser = createTraverser(collectionRef);
1010
const batchMigrator = createBatchMigrator(traverser);
11-
expectType<BatchMigrator<D>>(batchMigrator);
11+
expectType<BatchMigrator<TestAppModelType, TestDbModelType>>(batchMigrator);
1212

1313
// Signature 2
1414

@@ -17,4 +17,4 @@ const batchMigrator2 = createBatchMigrator(collectionRef, {
1717
sleepTimeBetweenBatches: 0,
1818
maxDocCount: 0,
1919
});
20-
expectType<BatchMigrator<D>>(batchMigrator2);
20+
expectType<BatchMigrator<TestAppModelType, TestDbModelType>>(batchMigrator2);

__tests__/types/createMigrator.test-d.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
import { expectType } from 'tsd';
44
import { createMigrator, createTraverser, DefaultMigrator } from '../../src';
5-
import { collectionRef, D } from './_helpers';
5+
import { collectionRef, TestAppModelType, TestDbModelType } from './_helpers';
66

77
// Signature 1
88

99
const traverser = createTraverser(collectionRef);
1010
const defaultMigrator = createMigrator(traverser);
11-
expectType<DefaultMigrator<D>>(defaultMigrator);
11+
expectType<DefaultMigrator<TestAppModelType, TestDbModelType>>(defaultMigrator);
1212

1313
// Signature 2
1414

@@ -18,4 +18,4 @@ const defaultMigrator2 = createMigrator(collectionRef, {
1818
maxDocCount: 0,
1919
maxConcurrentBatchCount: 0,
2020
});
21-
expectType<DefaultMigrator<D>>(defaultMigrator2);
21+
expectType<DefaultMigrator<TestAppModelType, TestDbModelType>>(defaultMigrator2);

__tests__/types/createTraverser.test-d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import { expectType } from 'tsd';
44
import { createTraverser, Traverser } from '../../src';
5-
import { collectionRef, D } from './_helpers';
5+
import { collectionRef, TestAppModelType, TestDbModelType } from './_helpers';
66

77
const traverser = createTraverser(collectionRef, {
88
batchSize: 0,
@@ -11,4 +11,4 @@ const traverser = createTraverser(collectionRef, {
1111
maxConcurrentBatchCount: 0,
1212
});
1313

14-
expectType<Traverser<D>>(traverser);
14+
expectType<Traverser<TestAppModelType, TestDbModelType>>(traverser);

__tests__/utils/collectionPopulator.ts

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,38 @@
11
import type { firestore } from 'firebase-admin';
22

3-
interface CollectionPopulatorBuilder<D> {
4-
withData(dataOrGetData: D | (() => D)): CollectionPopulator<D>;
3+
interface CollectionPopulatorBuilder<
4+
AppModelType = firestore.DocumentData,
5+
DbModelType extends firestore.DocumentData = firestore.DocumentData
6+
> {
7+
withData(
8+
dataOrGetData: AppModelType | (() => AppModelType)
9+
): CollectionPopulator<AppModelType, DbModelType>;
510
}
611

7-
interface CollectionPopulator<D> {
8-
populate(opts: { count: number }): Promise<firestore.DocumentReference<D>[]>;
12+
interface CollectionPopulator<
13+
AppModelType = firestore.DocumentData,
14+
DbModelType extends firestore.DocumentData = firestore.DocumentData
15+
> {
16+
populate(opts: {
17+
count: number;
18+
}): Promise<firestore.DocumentReference<AppModelType, DbModelType>[]>;
919
}
1020

11-
export function collectionPopulator<D>(
12-
collectionRef: firestore.CollectionReference<D>
13-
): CollectionPopulatorBuilder<D> {
21+
export function collectionPopulator<
22+
AppModelType = firestore.DocumentData,
23+
DbModelType extends firestore.DocumentData = firestore.DocumentData
24+
>(
25+
collectionRef: firestore.CollectionReference<AppModelType, DbModelType>
26+
): CollectionPopulatorBuilder<AppModelType, DbModelType> {
1427
return {
1528
withData: (dataOrGetData) => {
1629
return {
1730
populate: async ({ count: docCount }) => {
1831
const promises = new Array(docCount).fill(null).map(async () => {
1932
const data =
20-
typeof dataOrGetData === 'function' ? (dataOrGetData as () => D)() : dataOrGetData;
33+
typeof dataOrGetData === 'function'
34+
? (dataOrGetData as () => AppModelType)()
35+
: dataOrGetData;
2136
return await collectionRef.add(data);
2237
});
2338

src/api/createBatchMigrator.ts

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@ import { createTraverser } from './createTraverser';
1919
* @returns A new {@link BatchMigrator} object.
2020
* @throws {@link InvalidConfigError} Thrown if the traversal config of the specified traverser is not compatible with this migrator.
2121
*/
22-
export function createBatchMigrator<D = firestore.DocumentData>(
23-
traverser: Traverser<D>
24-
): BatchMigrator<D>;
22+
export function createBatchMigrator<
23+
AppModelType = firestore.DocumentData,
24+
DbModelType extends firestore.DocumentData = firestore.DocumentData
25+
>(traverser: Traverser<AppModelType, DbModelType>): BatchMigrator<AppModelType, DbModelType>;
2526

2627
/**
2728
* Creates a migrator that facilitates database migrations. The migrator creates a default traverser that
@@ -38,17 +39,28 @@ export function createBatchMigrator<D = firestore.DocumentData>(
3839
* @returns A new {@link BatchMigrator} object.
3940
* @throws {@link InvalidConfigError} Thrown if the specified `traversalConfig` is invalid or incompatible with this migrator.
4041
*/
41-
export function createBatchMigrator<D = firestore.DocumentData>(
42-
traversable: Traversable<D>,
42+
export function createBatchMigrator<
43+
AppModelType = firestore.DocumentData,
44+
DbModelType extends firestore.DocumentData = firestore.DocumentData
45+
>(
46+
traversable: Traversable<AppModelType, DbModelType>,
4347
traversalConfig?: Partial<TraversalConfig>
44-
): BatchMigrator<D>;
48+
): BatchMigrator<AppModelType, DbModelType>;
4549

46-
export function createBatchMigrator<D = firestore.DocumentData>(
47-
traversableOrTraverser: Traverser<D> | Traversable<D>,
50+
export function createBatchMigrator<
51+
AppModelType = firestore.DocumentData,
52+
DbModelType extends firestore.DocumentData = firestore.DocumentData
53+
>(
54+
traversableOrTraverser:
55+
| Traverser<AppModelType, DbModelType>
56+
| Traversable<AppModelType, DbModelType>,
4857
traversalConfig?: Partial<TraversalConfig>
49-
): BatchMigrator<D> {
58+
): BatchMigrator<AppModelType, DbModelType> {
5059
const traverser = isTraverser(traversableOrTraverser)
51-
? (traversableOrTraverser as Traverser<D>)
52-
: createTraverser(traversableOrTraverser as Traversable<D>, traversalConfig);
60+
? (traversableOrTraverser as Traverser<AppModelType, DbModelType>)
61+
: createTraverser(
62+
traversableOrTraverser as Traversable<AppModelType, DbModelType>,
63+
traversalConfig
64+
);
5365
return new BasicBatchMigratorImpl(traverser);
5466
}

src/api/createMigrator.ts

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@ import { createTraverser } from './createTraverser';
1313
* @param traverser - The traverser object that this migrator will use when traversing the collection and writing to documents.
1414
* @returns A new {@link DefaultMigrator} object.
1515
*/
16-
export function createMigrator<D = firestore.DocumentData>(
17-
traverser: Traverser<D>
18-
): DefaultMigrator<D>;
16+
export function createMigrator<
17+
AppModelType = firestore.DocumentData,
18+
DbModelType extends firestore.DocumentData = firestore.DocumentData
19+
>(traverser: Traverser<AppModelType, DbModelType>): DefaultMigrator<AppModelType, DbModelType>;
1920

2021
/**
2122
* Creates a migrator that facilitates database migrations. The migrator creates a default traverser that
@@ -27,17 +28,28 @@ export function createMigrator<D = firestore.DocumentData>(
2728
* @returns A new {@link DefaultMigrator} object.
2829
* @throws {@link InvalidConfigError} Thrown if the specified `traversalConfig` is invalid.
2930
*/
30-
export function createMigrator<D = firestore.DocumentData>(
31-
traversable: Traversable<D>,
31+
export function createMigrator<
32+
AppModelType = firestore.DocumentData,
33+
DbModelType extends firestore.DocumentData = firestore.DocumentData
34+
>(
35+
traversable: Traversable<AppModelType, DbModelType>,
3236
traversalConfig?: Partial<TraversalConfig>
33-
): DefaultMigrator<D>;
37+
): DefaultMigrator<AppModelType, DbModelType>;
3438

35-
export function createMigrator<D = firestore.DocumentData>(
36-
traversableOrTraverser: Traverser<D> | Traversable<D>,
39+
export function createMigrator<
40+
AppModelType = firestore.DocumentData,
41+
DbModelType extends firestore.DocumentData = firestore.DocumentData
42+
>(
43+
traversableOrTraverser:
44+
| Traverser<AppModelType, DbModelType>
45+
| Traversable<AppModelType, DbModelType>,
3746
traversalConfig?: Partial<TraversalConfig>
38-
): DefaultMigrator<D> {
47+
): DefaultMigrator<AppModelType, DbModelType> {
3948
const traverser = isTraverser(traversableOrTraverser)
40-
? (traversableOrTraverser as Traverser<D>)
41-
: createTraverser(traversableOrTraverser as Traversable<D>, traversalConfig);
49+
? (traversableOrTraverser as Traverser<AppModelType, DbModelType>)
50+
: createTraverser(
51+
traversableOrTraverser as Traversable<AppModelType, DbModelType>,
52+
traversalConfig
53+
);
4254
return new BasicDefaultMigratorImpl(traverser);
4355
}

src/api/createTraverser.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,12 @@ import type { Traversable, TraversalConfig, Traverser } from './interfaces';
2222
* @returns A new {@link Traverser} object.
2323
* @throws {@link InvalidConfigError} Thrown if the specified `config` is invalid.
2424
*/
25-
export function createTraverser<D = firestore.DocumentData>(
26-
traversable: Traversable<D>,
25+
export function createTraverser<
26+
AppModelType = firestore.DocumentData,
27+
DbModelType extends firestore.DocumentData = firestore.DocumentData
28+
>(
29+
traversable: Traversable<AppModelType, DbModelType>,
2730
config?: Partial<TraversalConfig>
28-
): Traverser<D> {
31+
): Traverser<AppModelType, DbModelType> {
2932
return new PromiseQueueBasedTraverserImpl(traversable, [], config);
3033
}

0 commit comments

Comments
 (0)