1
+ import type ResourceInterface from './interfaces/ResourceInterface'
2
+ import type CollectionInterface from './interfaces/CollectionInterface'
3
+ import type { Link , StoreDataCollection } from '@/interfaces/StoreData'
4
+
1
5
import { isEntityReference } from './halHelpers'
2
6
import LoadingCollection from './LoadingCollection'
3
- import ResourceInterface from './interfaces/ResourceInterface'
4
- import CollectionInterface from './interfaces/CollectionInterface'
5
- import { Link } from './interfaces/StoreData'
6
7
import Resource from './Resource'
7
8
8
9
/**
9
10
* Filter out items that are marked as deleting (eager removal)
10
11
*/
11
- function filterDeleting ( array : Array < ResourceInterface > ) : Array < ResourceInterface > {
12
+ function filterDeleting < T extends ResourceInterface > ( array : Array < T > ) : Array < T > {
12
13
return array . filter ( entry => ! entry . _meta . deleting )
13
14
}
14
15
15
- class Collection extends Resource {
16
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
+ class Collection < ItemType extends ResourceInterface , ResourceType extends CollectionInterface < ItemType , ResourceType > = any > extends Resource < ResourceType , StoreDataCollection < ResourceType > > implements CollectionInterface < ItemType , ResourceType > {
16
18
/**
17
19
* Get items excluding ones marked as 'deleting' (eager remove)
18
20
* The items property should always be a getter, in order to make the call to mapArrayOfEntityReferences
19
21
* lazy, since that potentially fetches a large number of entities from the API.
20
22
*/
21
- public get items ( ) : Array < ResourceInterface > {
22
- return filterDeleting ( this . _mapArrayOfEntityReferences ( this . _storeData . items ) )
23
+ public get items ( ) : Array < ItemType > {
24
+ return filterDeleting < ItemType > ( this . _mapArrayOfEntityReferences ( this . _storeData . items ) )
23
25
}
24
26
25
27
/**
26
28
* Get all items including ones marked as 'deleting' (lazy remove)
27
29
*/
28
- public get allItems ( ) : Array < ResourceInterface > {
30
+ public get allItems ( ) : Array < ItemType > {
29
31
return this . _mapArrayOfEntityReferences ( this . _storeData . items )
30
32
}
31
33
32
34
/**
33
35
* Returns a promise that resolves to the collection object, once all items have been loaded
34
36
*/
35
- public $loadItems ( ) : Promise < CollectionInterface > {
37
+ public $loadItems ( ) : Promise < this > {
36
38
return this . _itemLoader ( this . _storeData . items )
37
39
}
38
40
39
41
/**
40
42
* Returns a promise that resolves to the collection object, once all items have been loaded
41
43
*/
42
- private _itemLoader ( array : Array < Link > ) : Promise < CollectionInterface > {
44
+ private _itemLoader ( array : Array < ItemType > ) : Promise < this > {
43
45
if ( ! this . _containsUnknownEntityReference ( array ) ) {
44
- return Promise . resolve ( this as unknown as CollectionInterface ) // we know that this object must be of type CollectionInterface
46
+ return Promise . resolve ( this ) // we know that this object must be of type CollectionInterface
45
47
}
46
48
47
49
// eager loading of 'fetchAllUri' (e.g. parent for embedded collections)
48
50
if ( this . config . avoidNPlusOneRequests ) {
49
- return this . apiActions . reload ( this as unknown as CollectionInterface ) as Promise < CollectionInterface > // we know that reload resolves to a type CollectionInterface
51
+ return this . apiActions . reload < ItemType > ( this ) as unknown as Promise < this > // we know that reload resolves to a type CollectionInterface
50
52
51
53
// no eager loading: replace each reference (Link) with a Resource (ResourceInterface)
52
54
} else {
53
55
const arrayWithReplacedReferences = this . _replaceEntityReferences ( array )
54
56
55
57
return Promise . all (
56
58
arrayWithReplacedReferences . map ( entry => entry . _meta . load )
57
- ) . then ( ( ) => this as unknown as CollectionInterface ) // we know that this object must be of type CollectionInterface
59
+ ) . then ( ( ) => this ) // we know that this object must be of type CollectionInterface
58
60
}
59
61
}
60
62
@@ -68,7 +70,7 @@ class Collection extends Resource {
68
70
* @returns array the new array with replaced items, or a LoadingCollection if any of the array
69
71
* elements is still loading.
70
72
*/
71
- private _mapArrayOfEntityReferences ( array : Array < Link > ) : Array < ResourceInterface > {
73
+ private _mapArrayOfEntityReferences ( array : Array < ItemType > ) : Array < ItemType > {
72
74
if ( ! this . _containsUnknownEntityReference ( array ) ) {
73
75
return this . _replaceEntityReferences ( array )
74
76
}
@@ -77,27 +79,26 @@ class Collection extends Resource {
77
79
78
80
// eager loading of 'fetchAllUri' (e.g. parent for embedded collections)
79
81
if ( this . config . avoidNPlusOneRequests ) {
80
- return LoadingCollection . create ( itemsLoaded )
82
+ return LoadingCollection . create < ItemType > ( itemsLoaded )
81
83
82
84
// no eager loading: replace each reference (Link) with a Resource (ResourceInterface)
83
85
} else {
84
- return LoadingCollection . create ( itemsLoaded , this . _replaceEntityReferences ( array ) )
86
+ return LoadingCollection . create < ItemType > ( itemsLoaded , this . _replaceEntityReferences ( array ) )
85
87
}
86
88
}
87
89
88
90
/**
89
91
* Replace each item in array with a proper Resource (or LoadingResource)
90
92
*/
91
- private _replaceEntityReferences ( array : Array < Link > ) : Array < ResourceInterface > {
92
- return array
93
- . filter ( entry => isEntityReference ( entry ) )
94
- . map ( entry => this . apiActions . get ( entry . href ) )
93
+ private _replaceEntityReferences ( array : Array < ItemType > ) : Array < ItemType > {
94
+ const links = array . filter ( entry => isEntityReference ( entry ) ) as unknown as Link [ ]
95
+ return links . map ( entry => this . apiActions . get < ItemType > ( entry . href ) as ItemType )
95
96
}
96
97
97
98
/**
98
99
* Returns true if any of the items within 'array' is not yet known to the API (meaning it has never been loaded)
99
100
*/
100
- private _containsUnknownEntityReference ( array : Array < Link > ) : boolean {
101
+ private _containsUnknownEntityReference ( array : Array < ItemType > ) : boolean {
101
102
return array . some ( entry => isEntityReference ( entry ) && this . apiActions . isUnknown ( entry . href ) )
102
103
}
103
104
}
0 commit comments