Skip to content

Commit 50ab77b

Browse files
committed
Add typing to v3 and move to vitest
1 parent adc1a40 commit 50ab77b

25 files changed

+734
-606
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
### Unreleased
22

3+
### 3.0.0-alpha.3
4+
- BREAKING: Now uses named exports
5+
- Publishes the types
6+
37
### 2.0.0-alpha.6
48
- Bugfix: `href` and `$href` can now also be used on the root API endpoint
59

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "hal-json-vuex",
3-
"version": "3.0.0-alpha.2",
3+
"version": "3.0.0-alpha.3",
44
"description": "Use a HAL JSON API with Vuex",
55
"main": "./dist/hal-json-vuex.umd.cjs",
66
"module": "./dist/hal-json-vuex.js",

src/Collection.ts

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,62 @@
1+
import type ResourceInterface from './interfaces/ResourceInterface'
2+
import type CollectionInterface from './interfaces/CollectionInterface'
3+
import type { Link, StoreDataCollection } from '@/interfaces/StoreData'
4+
15
import { isEntityReference } from './halHelpers'
26
import LoadingCollection from './LoadingCollection'
3-
import ResourceInterface from './interfaces/ResourceInterface'
4-
import CollectionInterface from './interfaces/CollectionInterface'
5-
import { Link } from './interfaces/StoreData'
67
import Resource from './Resource'
78

89
/**
910
* Filter out items that are marked as deleting (eager removal)
1011
*/
11-
function filterDeleting (array: Array<ResourceInterface>): Array<ResourceInterface> {
12+
function filterDeleting<T extends ResourceInterface> (array: Array<T>): Array<T> {
1213
return array.filter(entry => !entry._meta.deleting)
1314
}
1415

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> {
1618
/**
1719
* Get items excluding ones marked as 'deleting' (eager remove)
1820
* The items property should always be a getter, in order to make the call to mapArrayOfEntityReferences
1921
* lazy, since that potentially fetches a large number of entities from the API.
2022
*/
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))
2325
}
2426

2527
/**
2628
* Get all items including ones marked as 'deleting' (lazy remove)
2729
*/
28-
public get allItems (): Array<ResourceInterface> {
30+
public get allItems (): Array<ItemType> {
2931
return this._mapArrayOfEntityReferences(this._storeData.items)
3032
}
3133

3234
/**
3335
* Returns a promise that resolves to the collection object, once all items have been loaded
3436
*/
35-
public $loadItems () :Promise<CollectionInterface> {
37+
public $loadItems (): Promise<this> {
3638
return this._itemLoader(this._storeData.items)
3739
}
3840

3941
/**
4042
* Returns a promise that resolves to the collection object, once all items have been loaded
4143
*/
42-
private _itemLoader (array: Array<Link>) : Promise<CollectionInterface> {
44+
private _itemLoader (array: Array<ItemType>) : Promise<this> {
4345
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
4547
}
4648

4749
// eager loading of 'fetchAllUri' (e.g. parent for embedded collections)
4850
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
5052

5153
// no eager loading: replace each reference (Link) with a Resource (ResourceInterface)
5254
} else {
5355
const arrayWithReplacedReferences = this._replaceEntityReferences(array)
5456

5557
return Promise.all(
5658
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
5860
}
5961
}
6062

@@ -68,7 +70,7 @@ class Collection extends Resource {
6870
* @returns array the new array with replaced items, or a LoadingCollection if any of the array
6971
* elements is still loading.
7072
*/
71-
private _mapArrayOfEntityReferences (array: Array<Link>): Array<ResourceInterface> {
73+
private _mapArrayOfEntityReferences (array: Array<ItemType>): Array<ItemType> {
7274
if (!this._containsUnknownEntityReference(array)) {
7375
return this._replaceEntityReferences(array)
7476
}
@@ -77,27 +79,26 @@ class Collection extends Resource {
7779

7880
// eager loading of 'fetchAllUri' (e.g. parent for embedded collections)
7981
if (this.config.avoidNPlusOneRequests) {
80-
return LoadingCollection.create(itemsLoaded)
82+
return LoadingCollection.create<ItemType>(itemsLoaded)
8183

8284
// no eager loading: replace each reference (Link) with a Resource (ResourceInterface)
8385
} else {
84-
return LoadingCollection.create(itemsLoaded, this._replaceEntityReferences(array))
86+
return LoadingCollection.create<ItemType>(itemsLoaded, this._replaceEntityReferences(array))
8587
}
8688
}
8789

8890
/**
8991
* Replace each item in array with a proper Resource (or LoadingResource)
9092
*/
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)
9596
}
9697

9798
/**
9899
* Returns true if any of the items within 'array' is not yet known to the API (meaning it has never been loaded)
99100
*/
100-
private _containsUnknownEntityReference (array: Array<Link>): boolean {
101+
private _containsUnknownEntityReference (array: Array<ItemType>): boolean {
101102
return array.some(entry => isEntityReference(entry) && this.apiActions.isUnknown(entry.href))
102103
}
103104
}

0 commit comments

Comments
 (0)