@thisisagile/easy 13.6.11 → 14.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.
- package/README.md +1 -1
- package/dist/data/InMemoryGateway.d.ts +4 -4
- package/dist/data/InMemoryGateway.js +2 -2
- package/dist/data/InMemoryGateway.js.map +1 -1
- package/dist/domain/Repo.js +5 -5
- package/dist/domain/Repo.js.map +1 -1
- package/dist/domain/Typo.js +6 -6
- package/dist/domain/Typo.js.map +1 -1
- package/dist/domain/enums/Country.d.ts +2 -1
- package/dist/domain/enums/Country.js +3 -0
- package/dist/domain/enums/Country.js.map +1 -1
- package/dist/domain/enums/Locale.d.ts +2 -1
- package/dist/domain/enums/Locale.js +3 -0
- package/dist/domain/enums/Locale.js.map +1 -1
- package/dist/domain/enums/UnitOfMeasurement.js +1 -1
- package/dist/domain/enums/UnitOfMeasurement.js.map +1 -1
- package/dist/process/Search.d.ts +2 -2
- package/dist/process/Search.js +1 -1
- package/dist/process/Search.js.map +1 -1
- package/dist/services/MappedRouteGateway.d.ts +2 -2
- package/dist/services/MappedRouteGateway.js.map +1 -1
- package/dist/services/RouteGateway.js.map +1 -1
- package/dist/services/ViewRouteGateway.d.ts +2 -2
- package/dist/services/ViewRouteGateway.js.map +1 -1
- package/dist/sql/TableGateway.d.ts +2 -2
- package/dist/sql/TableGateway.js +1 -1
- package/dist/sql/TableGateway.js.map +1 -1
- package/dist/types/Enum.d.ts +1 -0
- package/dist/types/Enum.js +8 -6
- package/dist/types/Enum.js.map +1 -1
- package/dist/types/List.d.ts +24 -19
- package/dist/types/List.js +71 -30
- package/dist/types/List.js.map +1 -1
- package/dist/types/PageList.d.ts +43 -4
- package/dist/types/PageList.js +106 -9
- package/dist/types/PageList.js.map +1 -1
- package/dist/utils/If.js +1 -1
- package/dist/utils/If.js.map +1 -1
- package/dist/utils/View.js.map +1 -1
- package/package.json +2 -2
- package/src/data/InMemoryGateway.ts +5 -5
- package/src/domain/Repo.ts +6 -22
- package/src/domain/Typo.ts +7 -7
- package/src/domain/enums/Country.ts +5 -1
- package/src/domain/enums/Locale.ts +5 -1
- package/src/domain/enums/UnitOfMeasurement.ts +1 -1
- package/src/process/Search.ts +3 -3
- package/src/services/MappedRouteGateway.ts +23 -23
- package/src/services/RouteGateway.ts +45 -45
- package/src/services/ViewRouteGateway.ts +31 -31
- package/src/sql/TableGateway.ts +8 -3
- package/src/types/Enum.ts +9 -7
- package/src/types/List.ts +69 -22
- package/src/types/PageList.ts +148 -17
- package/src/utils/If.ts +5 -3
- package/src/utils/View.ts +5 -1
package/src/domain/Repo.ts
CHANGED
|
@@ -1,20 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
asList,
|
|
3
|
-
asPageList,
|
|
4
|
-
Constructor,
|
|
5
|
-
Exception,
|
|
6
|
-
FetchOptions,
|
|
7
|
-
Gateway,
|
|
8
|
-
Id,
|
|
9
|
-
isValidatable,
|
|
10
|
-
Json,
|
|
11
|
-
JsonValue,
|
|
12
|
-
Key,
|
|
13
|
-
List,
|
|
14
|
-
PageList,
|
|
15
|
-
Repository,
|
|
16
|
-
toJson,
|
|
17
|
-
} from '../types';
|
|
1
|
+
import { asList, Constructor, Exception, FetchOptions, Gateway, Id, isValidatable, Json, JsonValue, Key, List, PageList, Repository, toJson } from '../types';
|
|
18
2
|
import { when } from '../validation';
|
|
19
3
|
import { reject, resolve } from '../utils';
|
|
20
4
|
import { Struct } from './Struct';
|
|
@@ -29,7 +13,7 @@ export class Repo<T extends Struct, Options = FetchOptions> extends Repository<T
|
|
|
29
13
|
create = (item: T | Json): T => (isValidatable(item) ? item : new this.ctor(item));
|
|
30
14
|
|
|
31
15
|
all(options?: Options): Promise<PageList<T>> {
|
|
32
|
-
return this.gateway.all(options).then(js =>
|
|
16
|
+
return this.gateway.all(options).then(js => js.map(i => new this.ctor(i)));
|
|
33
17
|
}
|
|
34
18
|
|
|
35
19
|
byId(id: Id): Promise<T> {
|
|
@@ -44,19 +28,19 @@ export class Repo<T extends Struct, Options = FetchOptions> extends Repository<T
|
|
|
44
28
|
}
|
|
45
29
|
|
|
46
30
|
byKey(key: Key, options?: Options): Promise<PageList<T>> {
|
|
47
|
-
return this.gateway.by('key', key, options).then(js =>
|
|
31
|
+
return this.gateway.by('key', key, options).then(js => js.map(i => new this.ctor(i)));
|
|
48
32
|
}
|
|
49
33
|
|
|
50
34
|
by(key: keyof T, value: JsonValue, options?: Options): Promise<PageList<T>> {
|
|
51
|
-
return this.gateway.by(key.toString(), value, options).then(js =>
|
|
35
|
+
return this.gateway.by(key.toString(), value, options).then(js => js.map(i => new this.ctor(i)));
|
|
52
36
|
}
|
|
53
37
|
|
|
54
38
|
search(q: JsonValue, options?: Options): Promise<PageList<T>> {
|
|
55
|
-
return this.gateway.search(q, options).then(js =>
|
|
39
|
+
return this.gateway.search(q, options).then(js => js.map(i => new this.ctor(i)));
|
|
56
40
|
}
|
|
57
41
|
|
|
58
42
|
filter(options?: Options): Promise<PageList<T>> {
|
|
59
|
-
return this.gateway.filter(options).then(js =>
|
|
43
|
+
return this.gateway.filter(options).then(js => js.map(i => new this.ctor(i)));
|
|
60
44
|
}
|
|
61
45
|
|
|
62
46
|
exists(id: Id): Promise<boolean> {
|
package/src/domain/Typo.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Exception, FetchOptions, Gateway, Id, Json, JsonValue, Key, List, PageList, Repository
|
|
1
|
+
import { Exception, FetchOptions, Gateway, Id, Json, JsonValue, Key, List, PageList, Repository } from '../types';
|
|
2
2
|
import { when } from '../validation';
|
|
3
3
|
import { View } from '../utils';
|
|
4
4
|
|
|
@@ -10,7 +10,7 @@ export class Typo<T, Options = FetchOptions> extends Repository<T, Options> {
|
|
|
10
10
|
create = (j: Json): T => this.view.from(j);
|
|
11
11
|
|
|
12
12
|
all(options?: Options): Promise<PageList<T>> {
|
|
13
|
-
return this.gateway.all(options).then(js =>
|
|
13
|
+
return this.gateway.all(options).then(js => js.map(this.create));
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
byId(id: Id): Promise<T> {
|
|
@@ -21,23 +21,23 @@ export class Typo<T, Options = FetchOptions> extends Repository<T, Options> {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
byIds(...ids: Id[]): Promise<List<T>> {
|
|
24
|
-
return this.gateway.byIds(...ids).then(js =>
|
|
24
|
+
return this.gateway.byIds(...ids).then(js => js.map(this.create));
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
byKey(key: Key, options?: Options): Promise<PageList<T>> {
|
|
28
|
-
return this.gateway.by('key', key, options).then(js =>
|
|
28
|
+
return this.gateway.by('key', key, options).then(js => js.map(this.create));
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
by(key: keyof T, value: JsonValue, options?: Options): Promise<PageList<T>> {
|
|
32
|
-
return this.gateway.by(key.toString(), value, options).then(js =>
|
|
32
|
+
return this.gateway.by(key.toString(), value, options).then(js => js.map(this.create));
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
search(q: JsonValue, options?: Options): Promise<PageList<T>> {
|
|
36
|
-
return this.gateway.search(q, options).then(js =>
|
|
36
|
+
return this.gateway.search(q, options).then(js => js.map(this.create));
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
filter(options?: Options): Promise<PageList<T>> {
|
|
40
|
-
return this.gateway.filter(options).then(js =>
|
|
40
|
+
return this.gateway.filter(options).then(js => js.map(j => this.create(j)));
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
exists(id: Id): Promise<boolean> {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Enum, Id, text } from '../../types';
|
|
1
|
+
import { Enum, Id, Optional, text } from '../../types';
|
|
2
2
|
|
|
3
3
|
export class Country extends Enum {
|
|
4
4
|
static readonly AF = new Country('Afghanistan', 'AF');
|
|
@@ -255,6 +255,10 @@ export class Country extends Enum {
|
|
|
255
255
|
super(name, id);
|
|
256
256
|
}
|
|
257
257
|
|
|
258
|
+
static lookup(other: string): Optional<Country> {
|
|
259
|
+
return this.all<Country>().first(l => l.equals(other));
|
|
260
|
+
}
|
|
261
|
+
|
|
258
262
|
equals<E extends Enum>(other: E | Id): other is E {
|
|
259
263
|
return text(other).lower.trim.equals(this.lower);
|
|
260
264
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Enum, Id, text } from '../../types';
|
|
1
|
+
import { Enum, Id, Optional, text } from '../../types';
|
|
2
2
|
|
|
3
3
|
export class Locale extends Enum {
|
|
4
4
|
static readonly AF = new Locale('af', 'Afrikaans');
|
|
@@ -569,6 +569,10 @@ export class Locale extends Enum {
|
|
|
569
569
|
super(name, id);
|
|
570
570
|
}
|
|
571
571
|
|
|
572
|
+
static lookup(other: string): Optional<Locale> {
|
|
573
|
+
return this.all<Locale>().first(l => l.equals(other));
|
|
574
|
+
}
|
|
575
|
+
|
|
572
576
|
equals<E extends Enum>(other: E | Id): other is E {
|
|
573
577
|
return text(other).lower.trim.equals(this.lower);
|
|
574
578
|
}
|
|
@@ -3,7 +3,7 @@ import { Enum } from '../../types';
|
|
|
3
3
|
export class UnitOfMeasurement extends Enum {
|
|
4
4
|
static readonly MM = new UnitOfMeasurement('Millimeter', 'mm', 1);
|
|
5
5
|
static readonly CM = new UnitOfMeasurement('Centimeter', 'cm', 10);
|
|
6
|
-
static readonly DM = new UnitOfMeasurement('
|
|
6
|
+
static readonly DM = new UnitOfMeasurement('Decimeter', 'dm', 100);
|
|
7
7
|
static readonly M = new UnitOfMeasurement('Meter', 'm', 1000);
|
|
8
8
|
static readonly KM = new UnitOfMeasurement('Kilometer', 'km', 1000000);
|
|
9
9
|
|
package/src/process/Search.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { choose, FetchOptions, Id, JsonValue, Key, PageList, Repository,
|
|
1
|
+
import { choose, FetchOptions, Id, JsonValue, Key, List, PageList, Repository, toPageList } from '../types';
|
|
2
2
|
import { resolve } from '../utils';
|
|
3
3
|
import { Req } from '../resources';
|
|
4
4
|
|
|
@@ -9,7 +9,7 @@ export class Search<T, Options = FetchOptions> {
|
|
|
9
9
|
|
|
10
10
|
byId = (id: Id): Promise<T> => this.repo.byId(id);
|
|
11
11
|
|
|
12
|
-
byIds = (...ids: Id[]): Promise<
|
|
12
|
+
byIds = (...ids: Id[]): Promise<List<T>> => this.repo.byIds(...ids);
|
|
13
13
|
|
|
14
14
|
byKey = (key: Key, options?: Options): Promise<PageList<T>> => this.repo.byKey(key, options);
|
|
15
15
|
|
|
@@ -21,7 +21,7 @@ export class Search<T, Options = FetchOptions> {
|
|
|
21
21
|
q => q,
|
|
22
22
|
q => this.repo.search(q, options)
|
|
23
23
|
)
|
|
24
|
-
.else(() => resolve(
|
|
24
|
+
.else(() => resolve(toPageList<T>()));
|
|
25
25
|
|
|
26
26
|
filter = (options?: Options): Promise<PageList<T>> => this.repo.filter(options);
|
|
27
27
|
|
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
import {Api} from './Api';
|
|
2
|
-
import {Func, Json,
|
|
3
|
-
import {Mapper} from '../utils';
|
|
4
|
-
import {RouteGateway} from './RouteGateway';
|
|
5
|
-
import {RequestOptions} from '../http';
|
|
1
|
+
import { Api } from './Api';
|
|
2
|
+
import { Func, Json, Optional, PageList, Uri } from '../types';
|
|
3
|
+
import { Mapper } from '../utils';
|
|
4
|
+
import { RouteGateway } from './RouteGateway';
|
|
5
|
+
import { RequestOptions } from '../http';
|
|
6
6
|
|
|
7
7
|
export class MappedRouteGateway extends RouteGateway {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
constructor(readonly route: Func<Uri>, readonly routeId: Func<Uri>, readonly map = new Mapper(), readonly api: Api = new Api()) {
|
|
9
|
+
super(route, routeId, api);
|
|
10
|
+
}
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
get(uri: Uri, options?: RequestOptions): Promise<PageList<Json>> {
|
|
13
|
+
return super.get(uri, options).then(is => is.map(i => this.map.in(i)));
|
|
14
|
+
}
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
getOne(uri: Uri, options?: RequestOptions): Promise<Optional<Json>> {
|
|
17
|
+
return super
|
|
18
|
+
.get(uri, options)
|
|
19
|
+
.then(is => is.first())
|
|
20
|
+
.then(i => this.map.in(i));
|
|
21
|
+
}
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
add(item: Json): Promise<Json> {
|
|
24
|
+
return super.add(this.map.out(item));
|
|
25
|
+
}
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
update(item: Json): Promise<Json> {
|
|
28
|
+
return super.update(this.map.out(item));
|
|
29
|
+
}
|
|
30
30
|
}
|
|
@@ -1,48 +1,48 @@
|
|
|
1
|
-
import {Api, RouteOptions} from './Api';
|
|
2
|
-
import {Func, Id, Json, JsonValue, Optional, PageList, Uri} from '../types';
|
|
3
|
-
import {HttpStatus} from '../http';
|
|
4
|
-
import {ApiGateway} from './ApiGateway';
|
|
1
|
+
import { Api, RouteOptions } from './Api';
|
|
2
|
+
import { Func, Id, Json, JsonValue, Optional, PageList, Uri } from '../types';
|
|
3
|
+
import { HttpStatus } from '../http';
|
|
4
|
+
import { ApiGateway } from './ApiGateway';
|
|
5
5
|
|
|
6
6
|
export class RouteGateway extends ApiGateway {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
7
|
+
constructor(readonly route: Func<Uri>, readonly routeId: Func<Uri>, readonly api: Api = new Api()) {
|
|
8
|
+
super(api);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
all(options?: RouteOptions): Promise<PageList<Json>> {
|
|
12
|
+
return this.get(this.route(), options);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
byId(id: Id, options?: RouteOptions): Promise<Optional<Json>> {
|
|
16
|
+
return this.getOne(this.routeId().id(id));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
search(q: JsonValue, options?: RouteOptions): Promise<PageList<Json>> {
|
|
20
|
+
return this.get(this.route().query(q), options);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
exists(id: Id, options?: RouteOptions): Promise<boolean> {
|
|
24
|
+
return this.get(this.routeId().id(id))
|
|
25
|
+
.then(r => r.length === 1)
|
|
26
|
+
.catch(r => (HttpStatus.NotFound.equals(r.status) ? false : Promise.reject(r)));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
add(item: Json, options?: RouteOptions): Promise<Json> {
|
|
30
|
+
return this.post(this.route(), item, options);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
filter(options?: RouteOptions): Promise<PageList<Json>> {
|
|
34
|
+
return this.postSearch(this.route(), options);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
update(item: Json, options?: RouteOptions): Promise<Json> {
|
|
38
|
+
return this.patch(this.routeId().id(item.id), item, options);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
upsert(item: Json, options?: RouteOptions): Promise<Json> {
|
|
42
|
+
return this.put(this.routeId().id(item.id), item, options);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
remove(id: Id, options?: RouteOptions): Promise<boolean> {
|
|
46
|
+
return this.delete(this.routeId().id(id), options);
|
|
47
|
+
}
|
|
48
48
|
}
|
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
import {Api} from './Api';
|
|
2
|
-
import {Func, Json,
|
|
3
|
-
import {view} from '../utils';
|
|
4
|
-
import {RouteGateway} from './RouteGateway';
|
|
5
|
-
import {RequestOptions} from '../http';
|
|
1
|
+
import { Api } from './Api';
|
|
2
|
+
import { Func, Json, Optional, PageList, Uri } from '../types';
|
|
3
|
+
import { view } from '../utils';
|
|
4
|
+
import { RouteGateway } from './RouteGateway';
|
|
5
|
+
import { RequestOptions } from '../http';
|
|
6
6
|
|
|
7
7
|
export class ViewRouteGateway extends RouteGateway {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
8
|
+
constructor(
|
|
9
|
+
readonly route: Func<Uri>,
|
|
10
|
+
readonly routeId: Func<Uri>,
|
|
11
|
+
readonly views = {
|
|
12
|
+
in: view({}).fromSource,
|
|
13
|
+
out: view({}).fromSource,
|
|
14
|
+
},
|
|
15
|
+
readonly api: Api = new Api()
|
|
16
|
+
) {
|
|
17
|
+
super(route, routeId, api);
|
|
18
|
+
}
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
get(uri: Uri, options?: RequestOptions): Promise<PageList<Json>> {
|
|
21
|
+
return super.get(uri, options).then(is => is.map(i => this.views.in.from(i)));
|
|
22
|
+
}
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
24
|
+
getOne(uri: Uri, options?: RequestOptions): Promise<Optional<Json>> {
|
|
25
|
+
return super
|
|
26
|
+
.get(uri, options)
|
|
27
|
+
.then(is => is.first())
|
|
28
|
+
.then(i => this.views.in.from(i));
|
|
29
|
+
}
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
add(item: Json): Promise<Json> {
|
|
32
|
+
return super.add(this.views.out.from(item));
|
|
33
|
+
}
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
update(item: Json): Promise<Json> {
|
|
36
|
+
return super.update(this.views.out.from(item));
|
|
37
|
+
}
|
|
38
38
|
}
|
package/src/sql/TableGateway.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Gateway, Id, isDefined, Json,
|
|
1
|
+
import { Gateway, Id, isDefined, Json, Optional, PageList, PageOptions, toPageList } from '../types';
|
|
2
2
|
import { QueryProvider } from '../data';
|
|
3
3
|
import { when } from '../validation';
|
|
4
4
|
import { ifDefined } from '../utils';
|
|
@@ -13,10 +13,15 @@ export class TableGateway<T extends Table> extends Gateway<PageOptions> {
|
|
|
13
13
|
|
|
14
14
|
protected provide = ({ provider }: TableOptions = {}): QueryProvider => provider ?? this.provider;
|
|
15
15
|
|
|
16
|
-
all(options?: TableOptions): Promise<
|
|
16
|
+
all(options?: TableOptions): Promise<PageList<Json>> {
|
|
17
17
|
return this.provide(options)
|
|
18
18
|
.query(this.table.select())
|
|
19
|
-
.then(js =>
|
|
19
|
+
.then(js =>
|
|
20
|
+
toPageList(
|
|
21
|
+
js.map(j => this.table.in(j)),
|
|
22
|
+
options
|
|
23
|
+
)
|
|
24
|
+
);
|
|
20
25
|
}
|
|
21
26
|
|
|
22
27
|
byId(id: Id, options?: TableOptions): Promise<Optional<Json>> {
|
package/src/types/Enum.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Id } from './Id';
|
|
2
|
-
import { List } from './List';
|
|
2
|
+
import { List, toList } from './List';
|
|
3
3
|
import { isAn } from './IsA';
|
|
4
4
|
import { meta } from './Meta';
|
|
5
5
|
import { isDefined } from './Is';
|
|
@@ -16,9 +16,11 @@ export abstract class Enum implements Validatable {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
static all<E extends Enum>(): List<E> {
|
|
19
|
-
return meta(this)
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
return meta(this.allTuple<E>()).values<E>();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
protected static allTuple<E extends Enum>(): Record<Id, E> {
|
|
23
|
+
return meta(this).get(`all-${this.name}`) ?? meta(this).set(`all-${this.name}`, meta(this).values<E>().filter(isEnum).toObject('id'));
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
static filter<E extends Enum>(p: (value: E, index: number, array: E[]) => unknown, params?: unknown): List<E> {
|
|
@@ -29,12 +31,12 @@ export abstract class Enum implements Validatable {
|
|
|
29
31
|
return this.all<E>().first(p, params);
|
|
30
32
|
}
|
|
31
33
|
|
|
32
|
-
static byIds<E extends Enum>(ids
|
|
33
|
-
return
|
|
34
|
+
static byIds<E extends Enum>(ids: Id[] = []): List<E> {
|
|
35
|
+
return toList(ids).mapDefined(id => this.byId<E>(id)).distinct();
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
static byId<E extends Enum>(id: Id, alt?: Get<E, unknown>): E {
|
|
37
|
-
return this.
|
|
39
|
+
return this.allTuple<E>()[id] ?? ofGet(alt);
|
|
38
40
|
}
|
|
39
41
|
|
|
40
42
|
equals<E extends Enum>(other: E | Id): other is E {
|
package/src/types/List.ts
CHANGED
|
@@ -11,9 +11,13 @@ import { meta } from './Meta';
|
|
|
11
11
|
import { Optional } from './Types';
|
|
12
12
|
|
|
13
13
|
export class List<T = unknown> extends Array<T> {
|
|
14
|
-
asc
|
|
14
|
+
asc(p: GetProperty<T, any>): List<T> {
|
|
15
|
+
return this.sort((e1, e2) => (ofProperty(e1, p) > ofProperty(e2, p) ? 1 : -1));
|
|
16
|
+
}
|
|
15
17
|
|
|
16
|
-
desc
|
|
18
|
+
desc(p: GetProperty<T, any>): List<T> {
|
|
19
|
+
return this.sort((e1, e2) => (ofProperty(e1, p) < ofProperty(e2, p) ? 1 : -1));
|
|
20
|
+
}
|
|
17
21
|
|
|
18
22
|
first = (p?: (value: T, index: number, array: T[]) => unknown, params?: unknown): T => (p ? this.find(p, params) : this[0]) as T;
|
|
19
23
|
|
|
@@ -31,13 +35,21 @@ export class List<T = unknown> extends Array<T> {
|
|
|
31
35
|
|
|
32
36
|
overlaps = (...items: ArrayLike<T>): boolean => toList<T>(...items).some(i => this.some(t => i === t));
|
|
33
37
|
|
|
34
|
-
diff
|
|
38
|
+
diff(others: ArrayLike<T>): List<T> {
|
|
39
|
+
return this.filter(i => !others.includes(i));
|
|
40
|
+
}
|
|
35
41
|
|
|
36
|
-
diffByKey
|
|
42
|
+
diffByKey(others: ArrayLike<T>, key: keyof T): List<T> {
|
|
43
|
+
return this.filter((i: any) => !others.some((o: any) => o[key] === i[key]));
|
|
44
|
+
}
|
|
37
45
|
|
|
38
|
-
intersect
|
|
46
|
+
intersect(others: ArrayLike<T>): List<T> {
|
|
47
|
+
return this.filter(i => others.includes(i));
|
|
48
|
+
}
|
|
39
49
|
|
|
40
|
-
intersectByKey
|
|
50
|
+
intersectByKey(others: ArrayLike<T>, key: keyof T): List<T> {
|
|
51
|
+
return this.filter((i: any) => others.some((o: any) => o[key] === i[key]));
|
|
52
|
+
}
|
|
41
53
|
|
|
42
54
|
toJSON = (): Json[] =>
|
|
43
55
|
this.reduce((a, i) => {
|
|
@@ -45,49 +57,82 @@ export class List<T = unknown> extends Array<T> {
|
|
|
45
57
|
return a;
|
|
46
58
|
}, new Array<Json>());
|
|
47
59
|
|
|
48
|
-
map
|
|
60
|
+
map<U>(f: (value: T, index: number, array: T[]) => U, params?: unknown): List<U> {
|
|
61
|
+
return toList<U>(super.map(f, params));
|
|
62
|
+
}
|
|
49
63
|
|
|
50
|
-
flatMap
|
|
51
|
-
toList<U>(super.flatMap(f, params));
|
|
64
|
+
flatMap<U, This = unknown>(f: (this: This, value: T, index: number, array: T[]) => ReadonlyArray<U> | U, params?: This): List<U> {
|
|
65
|
+
return toList<U>(super.flatMap(f, params));
|
|
66
|
+
}
|
|
52
67
|
|
|
53
|
-
mapDefined
|
|
68
|
+
mapDefined<U>(f: (value: T, index: number, array: T[]) => U, params?: unknown): List<NonNullable<U>> {
|
|
69
|
+
return this.map(f, params).defined();
|
|
70
|
+
}
|
|
54
71
|
|
|
55
|
-
mapAsync
|
|
72
|
+
mapAsync(f: (i: T) => Promise<T>): Promise<List<T>> {
|
|
73
|
+
return Promise.all(super.map(e => f(e))).then(a => toList<T>(a));
|
|
74
|
+
}
|
|
56
75
|
|
|
57
|
-
distinct
|
|
76
|
+
distinct(): List<T> {
|
|
77
|
+
return this.filter((i, index) => this.indexOf(i) === index);
|
|
78
|
+
}
|
|
58
79
|
|
|
59
|
-
distinctByKey
|
|
80
|
+
distinctByKey(key: keyof T): List<T> {
|
|
81
|
+
return meta(this.toObject(key)).values();
|
|
82
|
+
}
|
|
60
83
|
|
|
61
|
-
filter
|
|
84
|
+
filter(p: (value: T, index: number, array: T[]) => unknown, params?: unknown): List<T> {
|
|
85
|
+
return toList<T>(super.filter(p, params));
|
|
86
|
+
}
|
|
62
87
|
|
|
63
88
|
sum = (p: (t: T) => number): number => this.reduce((sum: number, i) => sum + p(i), 0);
|
|
64
89
|
|
|
65
90
|
byId = (id: Id): T => this.first(i => asString((i as any).id) === asString(id));
|
|
66
91
|
|
|
67
|
-
add = (...items:
|
|
92
|
+
add = (...items: ArrayLike<T>): this => {
|
|
68
93
|
super.push(...toArray(...items));
|
|
69
94
|
return this;
|
|
70
95
|
};
|
|
71
96
|
|
|
72
|
-
|
|
97
|
+
concat(...items: ConcatArray<T>[]): List<T>;
|
|
98
|
+
concat(...items: (T | ConcatArray<T>)[]): List<T>;
|
|
99
|
+
concat(...items: (T | ConcatArray<T>)[]): List<T> {
|
|
100
|
+
return toList<T>(super.concat(...items));
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
reverse(): List<T> {
|
|
104
|
+
return toList<T>(super.reverse());
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
splice(start: number, deleteCount?: number): List<T>;
|
|
108
|
+
splice(start: number, deleteCount: number, ...items: T[]): List<T>;
|
|
109
|
+
splice(start: number, deleteCount: number, ...items: T[]): List<T> {
|
|
110
|
+
return toList<T>(super.splice(start, deleteCount, ...items));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
remove(item: T): List<T> {
|
|
73
114
|
const index = this.indexOf(item);
|
|
74
115
|
if (index > -1) {
|
|
75
116
|
this.splice(index, 1);
|
|
76
117
|
}
|
|
77
118
|
return this;
|
|
78
|
-
}
|
|
119
|
+
}
|
|
79
120
|
|
|
80
|
-
replace
|
|
121
|
+
replace(key: keyof T, item: T): List<T> {
|
|
81
122
|
tryTo(() => item[key])
|
|
82
123
|
.map(k => this.findIndex(i => i[key] === k))
|
|
83
124
|
.filter(i => i > -1)
|
|
84
125
|
.map(i => (this[i] = item));
|
|
85
126
|
return this;
|
|
86
|
-
}
|
|
127
|
+
}
|
|
87
128
|
|
|
88
|
-
switch
|
|
129
|
+
switch(item: T): List<T> {
|
|
130
|
+
return this.includes(item) ? this.remove(item) : this.add(item);
|
|
131
|
+
}
|
|
89
132
|
|
|
90
|
-
defined
|
|
133
|
+
defined(): List<NonNullable<T>> {
|
|
134
|
+
return this.reduce((l, v) => (isDefined(v) ? l.add(v) : l), toList<NonNullable<T>>());
|
|
135
|
+
}
|
|
91
136
|
|
|
92
137
|
toObject = (key: keyof T, options: { deleteKey?: boolean } = {}): Record<string | number | symbol, T> =>
|
|
93
138
|
this.reduce((o: any, i) => {
|
|
@@ -104,7 +149,9 @@ export class List<T = unknown> extends Array<T> {
|
|
|
104
149
|
return a;
|
|
105
150
|
}, {} as Record<string | number | symbol, List<T>>);
|
|
106
151
|
|
|
107
|
-
orElse
|
|
152
|
+
orElse(...alt: ArrayLike<T>): Optional<List<T>> {
|
|
153
|
+
return !isEmpty(this) ? this : !isEmpty(...alt) ? toList<T>(...alt) : undefined;
|
|
154
|
+
}
|
|
108
155
|
|
|
109
156
|
weave = (insertFrom: T[], interval: number): this => {
|
|
110
157
|
for (let i = interval, n = 0; i <= this.length && n < insertFrom.length; i += interval + 1) {
|