@rosen-bridge/abstract-extractor 0.3.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/ergo/AbstractErgoExtractor.d.ts +30 -5
  3. package/dist/ergo/AbstractErgoExtractor.d.ts.map +1 -1
  4. package/dist/ergo/AbstractErgoExtractor.js +72 -7
  5. package/dist/ergo/AbstractErgoExtractorAction.d.ts +37 -10
  6. package/dist/ergo/AbstractErgoExtractorAction.d.ts.map +1 -1
  7. package/dist/ergo/AbstractErgoExtractorAction.js +134 -1
  8. package/dist/ergo/AbstractErgoExtractorEntity.d.ts +11 -0
  9. package/dist/ergo/AbstractErgoExtractorEntity.d.ts.map +1 -0
  10. package/dist/ergo/AbstractErgoExtractorEntity.js +57 -0
  11. package/dist/ergo/index.d.ts +1 -0
  12. package/dist/ergo/index.d.ts.map +1 -1
  13. package/dist/ergo/index.js +2 -1
  14. package/dist/ergo/initializable/AbstractInitializable.d.ts +4 -3
  15. package/dist/ergo/initializable/AbstractInitializable.d.ts.map +1 -1
  16. package/dist/ergo/initializable/AbstractInitializable.js +9 -5
  17. package/dist/ergo/initializable/AbstractInitializableAction.d.ts +7 -2
  18. package/dist/ergo/initializable/AbstractInitializableAction.d.ts.map +1 -1
  19. package/dist/ergo/initializable/AbstractInitializableAction.js +11 -1
  20. package/dist/ergo/interfaces.d.ts +20 -1
  21. package/dist/ergo/interfaces.d.ts.map +1 -1
  22. package/dist/ergo/interfaces.js +8 -1
  23. package/lib/ergo/AbstractErgoExtractor.ts +105 -12
  24. package/lib/ergo/AbstractErgoExtractorAction.ts +185 -18
  25. package/lib/ergo/AbstractErgoExtractorEntity.ts +28 -0
  26. package/lib/ergo/index.ts +1 -0
  27. package/lib/ergo/initializable/AbstractInitializable.ts +22 -9
  28. package/lib/ergo/initializable/AbstractInitializableAction.ts +19 -3
  29. package/lib/ergo/interfaces.ts +24 -1
  30. package/package.json +6 -2
  31. package/tests/{AbstractExtractor.mock.ts → AbstractErgoExtractor.mock.ts} +11 -4
  32. package/tests/AbstractErgoExtractor.spec.ts +281 -0
  33. package/tests/AbstractErgoExtractorAction.mock.ts +45 -0
  34. package/tests/AbstractErgoExtractorAction.spec.ts +269 -0
  35. package/tests/initializable/AbstractInitializable.mock.ts +14 -3
  36. package/tests/initializable/AbstractInitializable.spec.ts +37 -5
  37. package/tests/initializable/AbstractInitializableAction.mock.ts +45 -0
  38. package/tests/initializable/AbstractInitializableAction.spec.ts +65 -0
  39. package/tests/testData.ts +38 -0
  40. package/tests/testUtils.ts +22 -0
  41. package/tsconfig.build.tsbuildinfo +1 -1
  42. package/dist/ergo/initializable/InitializableByAddress.d.ts +0 -19
  43. package/dist/ergo/initializable/InitializableByAddress.d.ts.map +0 -1
  44. package/dist/ergo/initializable/InitializableByAddress.js +0 -30
  45. package/dist/ergo/initializable/InitializableByToken.d.ts +0 -19
  46. package/dist/ergo/initializable/InitializableByToken.d.ts.map +0 -1
  47. package/dist/ergo/initializable/InitializableByToken.js +0 -30
  48. package/dist/tsconfig.tsbuildinfo +0 -1
  49. package/tests/AbstractExtractor.spec.ts +0 -102
@@ -0,0 +1,269 @@
1
+ import { DataSource, Repository } from 'typeorm';
2
+ import { describe, it, expect, beforeEach } from 'vitest';
3
+ import { pick } from 'lodash-es';
4
+
5
+ import { TestErgoExtractorAction } from './AbstractErgoExtractorAction.mock';
6
+ import { createDatabase, TestEntity } from './testUtils';
7
+ import { block, block2, sampleEntities } from './testData';
8
+ import { SpendInfo } from '../lib';
9
+
10
+ describe('AbstractErgoExtractorAction', () => {
11
+ let dataSource: DataSource;
12
+ let action: TestErgoExtractorAction;
13
+ let repository: Repository<TestEntity>;
14
+ beforeEach(async () => {
15
+ dataSource = await createDatabase();
16
+ action = new TestErgoExtractorAction(dataSource);
17
+ repository = dataSource.getRepository(TestEntity);
18
+ });
19
+
20
+ describe('storeBoxes', () => {
21
+ /**
22
+ * @target storeBoxes should save the passed box entities to database
23
+ * @dependencies
24
+ * @scenario
25
+ * - run test (call `storeBoxes` with 2 new boxes)
26
+ * @expected
27
+ * - to save 2 new entities
28
+ * - to return 2 inserted entity data
29
+ */
30
+ it(`should save the passed box entities to database`, async () => {
31
+ const result = await action.storeBoxes(
32
+ sampleEntities.slice(0, 2),
33
+ block,
34
+ 'extractor1'
35
+ );
36
+
37
+ const [rows, rowsCount] = await repository.findAndCount();
38
+
39
+ expect(rowsCount).toEqual(2);
40
+ expect(rows[0]).toMatchObject({
41
+ ...sampleEntities[0],
42
+ extractor: 'extractor1',
43
+ block: block.hash,
44
+ height: block.height,
45
+ spendBlock: null,
46
+ spendHeight: null,
47
+ });
48
+ expect(rows[1]).toMatchObject({
49
+ ...sampleEntities[1],
50
+ extractor: 'extractor1',
51
+ block: block.hash,
52
+ height: block.height,
53
+ spendBlock: null,
54
+ spendHeight: null,
55
+ });
56
+ expect(result).toEqual(true);
57
+ });
58
+
59
+ /**
60
+ * @target storeBoxes should correctly save boxes with different extractors
61
+ * @dependencies
62
+ * @scenario
63
+ * - insert 2 boxes belonging to first-extractor
64
+ * - run test (call `storeBoxes` with same boxes for the second-extractor)
65
+ * @expected
66
+ * - to save 2 new entities belonging to second-extractor
67
+ * - to return 2 new inserted entity data
68
+ */
69
+ it(`should correctly save boxes with different extractors`, async () => {
70
+ await repository.insert([
71
+ {
72
+ ...sampleEntities[0],
73
+ extractor: 'first-extractor',
74
+ block: '1',
75
+ height: 1,
76
+ },
77
+ {
78
+ ...sampleEntities[1],
79
+ extractor: 'first-extractor',
80
+ block: '1',
81
+ height: 1,
82
+ },
83
+ ]);
84
+
85
+ const result = await action.storeBoxes(
86
+ [sampleEntities[0], sampleEntities[1]],
87
+ block,
88
+ 'second-extractor'
89
+ );
90
+
91
+ const [insertedRows] = await repository.findAndCount();
92
+ expect(insertedRows[2]).toMatchObject({
93
+ ...sampleEntities[0],
94
+ extractor: 'second-extractor',
95
+ block: 'hash',
96
+ height: block.height,
97
+ spendBlock: null,
98
+ spendHeight: null,
99
+ });
100
+
101
+ expect(insertedRows[3]).toMatchObject({
102
+ ...sampleEntities[1],
103
+ extractor: 'second-extractor',
104
+ block: 'hash',
105
+ height: block.height,
106
+ spendBlock: null,
107
+ spendHeight: null,
108
+ });
109
+ expect(result).toEqual(true);
110
+ });
111
+
112
+ /**
113
+ * @target storeBoxes should update boxes correctly
114
+ * @dependencies
115
+ * @scenario
116
+ * - insert 2 boxes
117
+ * - run test (call `storeBoxes` with the same boxes and updated info)
118
+ * @expected
119
+ * - to update the existing box in database
120
+ * - to return updated box id
121
+ */
122
+ it(`storeBoxes should update boxes correctly`, async () => {
123
+ await repository.insert([
124
+ {
125
+ ...sampleEntities[0],
126
+ extractor: 'extractor',
127
+ block: '1',
128
+ height: 1,
129
+ },
130
+ {
131
+ ...sampleEntities[1],
132
+ extractor: 'extractor',
133
+ block: '1',
134
+ height: 1,
135
+ },
136
+ ]);
137
+
138
+ const result = await action.storeBoxes(
139
+ [
140
+ {
141
+ ...sampleEntities[0],
142
+ serialized: 'updatedBoxSerialized',
143
+ },
144
+ ],
145
+ block,
146
+ 'extractor'
147
+ );
148
+ const [secondInsertRows, secondInsertRowsCount] =
149
+ await repository.findAndCount();
150
+ expect(secondInsertRowsCount).toEqual(2);
151
+ expect(secondInsertRows[0]).toMatchObject({
152
+ ...sampleEntities[0],
153
+ extractor: 'extractor',
154
+ serialized: 'updatedBoxSerialized',
155
+ block: block.hash,
156
+ height: block.height,
157
+ spendBlock: null,
158
+ spendHeight: null,
159
+ });
160
+ expect(result).toEqual(true);
161
+ });
162
+ });
163
+
164
+ describe('spendBoxes', () => {
165
+ /**
166
+ * @target spendBoxes should set spendBlock and spendHeight for a set of boxes
167
+ * @dependencies
168
+ * @scenario
169
+ * - insert two boxes
170
+ * - mock spending information for the first box
171
+ * - run test (call `spendBoxes`)
172
+ * @expected
173
+ * - spend the first box
174
+ * - return boxId and serialized of spent box
175
+ */
176
+ it(`should set spendBlock and spendHeight for a set of boxes`, async () => {
177
+ await action.storeBoxes(sampleEntities.slice(0, 2), block, 'extractor1');
178
+
179
+ const spendBlock = { ...block, hash: 'spendHash', height: 10006016 };
180
+ const spendInfos: Array<SpendInfo> = [
181
+ { txId: 'txId', boxId: sampleEntities[0].boxId, index: 0 },
182
+ ];
183
+
184
+ const spentBoxIds = await action.spendBoxes(
185
+ spendInfos,
186
+ spendBlock,
187
+ 'extractor1'
188
+ );
189
+
190
+ const spentBoxes = await repository.findOneBy({
191
+ boxId: sampleEntities[0].boxId,
192
+ extractor: 'extractor1',
193
+ });
194
+
195
+ expect(spentBoxes).toMatchObject({
196
+ ...sampleEntities[0],
197
+ block: block.hash,
198
+ height: block.height,
199
+ extractor: 'extractor1',
200
+ spendBlock: spendBlock.hash,
201
+ spendHeight: spendBlock.height,
202
+ });
203
+ expect(spentBoxIds).toEqual([pick(sampleEntities[0], ['boxId'])]);
204
+ });
205
+ });
206
+
207
+ describe('deleteBlockBoxes', () => {
208
+ /**
209
+ * @target deleteBlockBoxes should delete the boxes created in the specified block
210
+ * @dependencies
211
+ * @scenario
212
+ * - insert four boxes created in two different blocks
213
+ * - run test(call `deleteBlockBoxes` to delete block2)
214
+ * @expected
215
+ * - to delete the two boxes created in block2
216
+ * - to return the deleted entity data
217
+ */
218
+ it(`should delete the boxes created in the specified block`, async () => {
219
+ await action.storeBoxes(sampleEntities.slice(0, 2), block, 'extractor1');
220
+ await action.storeBoxes(sampleEntities.slice(2), block2, 'extractor1');
221
+
222
+ const result = await action.deleteBlockBoxes(block2.hash, 'extractor1');
223
+
224
+ const [rows, rowsCount] = await repository.findAndCount();
225
+
226
+ expect(rowsCount).toEqual(2);
227
+ expect(rows.map((row) => row.boxId)).not.toContain(
228
+ sampleEntities.slice(2).map((box) => box.boxId)
229
+ );
230
+ expect(result).toEqual({
231
+ deletedData: action.convertEntityToData(
232
+ sampleEntities.slice(2) as TestEntity[]
233
+ ),
234
+ updatedData: [],
235
+ });
236
+ });
237
+
238
+ /**
239
+ * @target deleteBlockBoxes should update the boxes spent in the specified block
240
+ * @dependencies
241
+ * @scenario
242
+ * - insert four boxes created in a block
243
+ * - spend one of the in the block2
244
+ * - run test(call `deleteBlockBoxes` to delete block2)
245
+ * @expected
246
+ * - to update the box spent in block2
247
+ * - to return the updated entity boxId and serialized
248
+ */
249
+ it(`should update the boxes spent in the specified block`, async () => {
250
+ await action.storeBoxes(sampleEntities, block, 'extractor1');
251
+ const spendInfos: Array<SpendInfo> = [
252
+ { txId: 'txId', boxId: sampleEntities[0].boxId, index: 0 },
253
+ ];
254
+ await action.spendBoxes(spendInfos, block2, 'extractor1');
255
+ const result = await action.deleteBlockBoxes(block2.hash, 'extractor1');
256
+
257
+ const [rows, rowsCount] = await repository.findAndCount();
258
+
259
+ expect(rowsCount).toEqual(4);
260
+ expect(rows.map((row) => row.boxId)).not.toContain(
261
+ sampleEntities.slice(2).map((box) => box.boxId)
262
+ );
263
+ expect(result).toEqual({
264
+ deletedData: [],
265
+ updatedData: [pick(sampleEntities[0], ['boxId'])],
266
+ });
267
+ });
268
+ });
269
+ });
@@ -3,11 +3,22 @@ import {
3
3
  AbstractInitializableErgoExtractor,
4
4
  AbstractInitializableErgoExtractorAction,
5
5
  } from '../../lib/ergo/initializable';
6
- import { OutputBox, ErgoExtractedData, BlockInfo } from '../../lib';
6
+ import {
7
+ OutputBox,
8
+ AbstractBoxData,
9
+ BlockInfo,
10
+ AbstractErgoExtractorEntity,
11
+ } from '../../lib';
7
12
  import { ergoBoxes } from './testData';
8
13
 
9
- export class MockedInitializableErgoExtractor extends AbstractInitializableErgoExtractor<ErgoExtractedData> {
10
- actions: AbstractInitializableErgoExtractorAction<ErgoExtractedData>;
14
+ export class MockedInitializableErgoExtractor extends AbstractInitializableErgoExtractor<
15
+ AbstractBoxData,
16
+ AbstractErgoExtractorEntity
17
+ > {
18
+ actions: AbstractInitializableErgoExtractorAction<
19
+ AbstractBoxData,
20
+ AbstractErgoExtractorEntity
21
+ >;
11
22
 
12
23
  getId = () => 'Test';
13
24
 
@@ -3,8 +3,9 @@ import { describe, expect, it, vi, vitest } from 'vitest';
3
3
  import {
4
4
  ErgoNetworkType,
5
5
  NodeNetwork,
6
- ErgoExtractedData,
6
+ AbstractBoxData,
7
7
  ExplorerNetwork,
8
+ AbstractErgoExtractorEntity,
8
9
  } from '../../lib';
9
10
  import { MockedInitializableErgoExtractor } from './AbstractInitializable.mock';
10
11
  import { transactionBatch } from './testData';
@@ -59,7 +60,7 @@ describe('AbstractInitializableErgoExtractor', () => {
59
60
  'node_url',
60
61
  'address'
61
62
  );
62
- const processSpy = vitest.fn();
63
+ const processSpy = vitest.fn().mockResolvedValue(true);
63
64
  extractor.processTransactions = processSpy;
64
65
  await extractor['processTransactionBatch'](transactionBatch);
65
66
  expect(processSpy).toBeCalledTimes(2);
@@ -75,6 +76,28 @@ describe('AbstractInitializableErgoExtractor', () => {
75
76
  }
76
77
  );
77
78
  });
79
+
80
+ /**
81
+ * @target processTransactionBatch should throw error when processing transactions fails for a block
82
+ * @dependencies
83
+ * @scenario
84
+ * - mock extractor
85
+ * - spy `processTransactions` to return false (always fails)
86
+ * - run test (call `processTransactionBatch`)
87
+ * @expected
88
+ * - to throw error
89
+ */
90
+ it('should throw error when processing transactions fails for a block', async () => {
91
+ const extractor = new MockedInitializableErgoExtractor(
92
+ ErgoNetworkType.Node,
93
+ 'node_url',
94
+ 'address'
95
+ );
96
+ extractor.processTransactions = vitest.fn().mockResolvedValue(false);
97
+ await expect(() =>
98
+ extractor['processTransactionBatch'](transactionBatch)
99
+ ).rejects.toThrowError();
100
+ });
78
101
  });
79
102
 
80
103
  describe('initWithRetrial', () => {
@@ -102,7 +125,10 @@ describe('AbstractInitializableErgoExtractor', () => {
102
125
  const removeSpy = vitest.fn();
103
126
  extractor['actions'] = {
104
127
  removeAllData: removeSpy,
105
- } as unknown as AbstractInitializableErgoExtractorAction<ErgoExtractedData>;
128
+ } as unknown as AbstractInitializableErgoExtractorAction<
129
+ AbstractBoxData,
130
+ AbstractErgoExtractorEntity
131
+ >;
106
132
  const initSpy = vitest.fn();
107
133
  await extractor['initWithRetrial'](initSpy);
108
134
  expect(removeSpy).not.toHaveBeenCalled();
@@ -131,7 +157,10 @@ describe('AbstractInitializableErgoExtractor', () => {
131
157
  const removeSpy = vitest.fn();
132
158
  extractor['actions'] = {
133
159
  removeAllData: removeSpy,
134
- } as unknown as AbstractInitializableErgoExtractorAction<ErgoExtractedData>;
160
+ } as unknown as AbstractInitializableErgoExtractorAction<
161
+ AbstractBoxData,
162
+ AbstractErgoExtractorEntity
163
+ >;
135
164
  const initSpy = vitest.fn();
136
165
  await extractor['initWithRetrial'](initSpy);
137
166
  expect(removeSpy).toHaveBeenCalledOnce();
@@ -161,7 +190,10 @@ describe('AbstractInitializableErgoExtractor', () => {
161
190
  const removeSpy = vitest.fn();
162
191
  extractor['actions'] = {
163
192
  removeAllData: removeSpy,
164
- } as unknown as AbstractInitializableErgoExtractorAction<ErgoExtractedData>;
193
+ } as unknown as AbstractInitializableErgoExtractorAction<
194
+ AbstractBoxData,
195
+ AbstractErgoExtractorEntity
196
+ >;
165
197
  const initSpy = vitest.fn().mockRejectedValue(0);
166
198
  await expect(
167
199
  async () => await extractor['initWithRetrial'](initSpy)
@@ -0,0 +1,45 @@
1
+ import { DataSource } from 'typeorm';
2
+ import { pick } from 'lodash-es';
3
+
4
+ import {
5
+ AbstractErgoExtractorEntity,
6
+ BlockInfo,
7
+ AbstractBoxData,
8
+ AbstractInitializableErgoExtractorAction,
9
+ } from '../../lib';
10
+ import { TestEntity } from '../testUtils';
11
+
12
+ export class TestInitializableErgoExtractorAction extends AbstractInitializableErgoExtractorAction<
13
+ AbstractBoxData,
14
+ AbstractErgoExtractorEntity
15
+ > {
16
+ constructor(dataSource: DataSource) {
17
+ super(dataSource, TestEntity);
18
+ }
19
+
20
+ /**
21
+ * create the test database entity from data and block information
22
+ */
23
+ createEntity = (
24
+ boxes: AbstractBoxData[],
25
+ block: BlockInfo,
26
+ extractor: string
27
+ ): Omit<AbstractErgoExtractorEntity, 'id'>[] => {
28
+ return boxes.map((box) => ({
29
+ boxId: box.boxId,
30
+ block: block.hash,
31
+ height: block.height,
32
+ serialized: box.serialized,
33
+ extractor: extractor,
34
+ }));
35
+ };
36
+
37
+ /**
38
+ * convert the database entity back to raw data
39
+ */
40
+ convertEntityToData = (
41
+ entities: AbstractErgoExtractorEntity[]
42
+ ): AbstractBoxData[] => {
43
+ return entities.map((data) => pick(data, ['boxId', 'serialized']));
44
+ };
45
+ }
@@ -0,0 +1,65 @@
1
+ import { DataSource, Repository } from 'typeorm';
2
+ import { describe, it, expect, beforeEach } from 'vitest';
3
+
4
+ import { TestInitializableErgoExtractorAction } from './AbstractInitializableAction.mock';
5
+ import { createDatabase, TestEntity } from '../testUtils';
6
+ import { sampleEntities } from '../testData';
7
+
8
+ describe('AbstractErgoExtractorAction', () => {
9
+ let dataSource: DataSource;
10
+ let action: TestInitializableErgoExtractorAction;
11
+ let repository: Repository<TestEntity>;
12
+ beforeEach(async () => {
13
+ dataSource = await createDatabase();
14
+ action = new TestInitializableErgoExtractorAction(dataSource);
15
+ repository = dataSource.getRepository(TestEntity);
16
+ });
17
+
18
+ describe('removeAllData', () => {
19
+ /**
20
+ * @target removeAllData should remove all available data related to this extractor
21
+ * @dependencies
22
+ * @scenario
23
+ * - insert 4 entities related to this extractor
24
+ * - run test (call `removeAllData`)
25
+ * @expected
26
+ * - to have 4 entities before removing
27
+ * - to have no remaining entities after remove
28
+ */
29
+ it(`should remove all available data related to this extractor`, async () => {
30
+ await dataSource.getRepository(TestEntity).insert(sampleEntities);
31
+ const countBefore = await repository.count();
32
+
33
+ await action.removeAllData('extractor');
34
+ const countAfter = await repository.count();
35
+
36
+ expect(countBefore).toEqual(4);
37
+ expect(countAfter).toEqual(0);
38
+ });
39
+
40
+ /**
41
+ * @target removeAllData should not remove any data related to another extractor
42
+ * @dependencies
43
+ * @scenario
44
+ * - insert 4 entities related to another extractor
45
+ * - run test (call `removeAllData`)
46
+ * @expected
47
+ * - to have 4 entities after removing
48
+ */
49
+ it(`should not remove any data related to another extractor`, async () => {
50
+ await dataSource.getRepository(TestEntity).insert(
51
+ sampleEntities.map((entity) => ({
52
+ ...entity,
53
+ extractor: 'extractor-new',
54
+ }))
55
+ );
56
+ const countBefore = await repository.count();
57
+
58
+ await action.removeAllData('extractor');
59
+ const countAfter = await repository.count();
60
+
61
+ expect(countBefore).toEqual(4);
62
+ expect(countAfter).toEqual(4);
63
+ });
64
+ });
65
+ });
package/tests/testData.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { Block } from '../lib';
2
+ import { TestEntity } from './testUtils';
2
3
 
3
4
  export const tx = {
4
5
  id: '3b91fbd2b6f4f3f971098655ffa320841001b071908de057cdf8c425cd3b3e61',
@@ -107,3 +108,40 @@ export const block: Block = {
107
108
  height: 100,
108
109
  parentHash: 'parentHash',
109
110
  } as Block;
111
+
112
+ export const block2: Block = {
113
+ hash: 'hash2',
114
+ height: 101,
115
+ parentHash: 'parentHash2',
116
+ } as Block;
117
+
118
+ export const sampleEntities: Omit<TestEntity, 'id'>[] = [
119
+ {
120
+ extractor: 'extractor',
121
+ boxId: '1',
122
+ serialized: 'serialized1',
123
+ block: 'blockId1',
124
+ height: 100,
125
+ },
126
+ {
127
+ extractor: 'extractor',
128
+ boxId: '2',
129
+ serialized: 'serialized2',
130
+ block: 'blockId2',
131
+ height: 200,
132
+ },
133
+ {
134
+ extractor: 'extractor',
135
+ boxId: '3',
136
+ serialized: 'serialized3',
137
+ block: 'blockId3',
138
+ height: 300,
139
+ },
140
+ {
141
+ extractor: 'extractor',
142
+ boxId: '4',
143
+ serialized: 'serialized4',
144
+ block: 'blockId4',
145
+ height: 400,
146
+ },
147
+ ];
@@ -0,0 +1,22 @@
1
+ import { DataSource, Entity } from 'typeorm';
2
+ import { AbstractErgoExtractorEntity } from '../lib';
3
+
4
+ @Entity('test_entity')
5
+ export class TestEntity extends AbstractErgoExtractorEntity {}
6
+
7
+ /**
8
+ * generates a dataSource with in memory database for testing
9
+ */
10
+ export const createDatabase = async (): Promise<DataSource> => {
11
+ const dataSource = new DataSource({
12
+ type: 'sqlite',
13
+ database: `:memory:`,
14
+ entities: [TestEntity],
15
+ migrations: [],
16
+ synchronize: true,
17
+ logging: false,
18
+ });
19
+ await dataSource.initialize();
20
+ await dataSource.runMigrations();
21
+ return dataSource;
22
+ };