@thisisagile/easy 12.7.21 → 12.7.27
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/dist/data/Condition.js.map +1 -1
- package/dist/domain/Repo.d.ts +2 -1
- package/dist/domain/Repo.js +3 -1
- package/dist/domain/Repo.js.map +1 -1
- package/dist/domain/Typo.d.ts +2 -7
- package/dist/domain/Typo.js +3 -20
- package/dist/domain/Typo.js.map +1 -1
- package/dist/domain/enums/Currency.js +3 -1
- package/dist/domain/enums/Currency.js.map +1 -1
- package/dist/domain/index.d.ts +1 -0
- package/dist/domain/index.js +1 -0
- package/dist/domain/index.js.map +1 -1
- package/dist/http/CacheControl.js +12 -9
- package/dist/http/CacheControl.js.map +1 -1
- package/dist/http/LocalRequestStore.d.ts +7 -0
- package/dist/http/LocalRequestStore.js +15 -0
- package/dist/http/LocalRequestStore.js.map +1 -0
- package/dist/http/RestResult.js.map +1 -1
- package/dist/process/Manage.d.ts +1 -2
- package/dist/process/Manage.js.map +1 -1
- package/dist/process/Search.d.ts +5 -5
- package/dist/process/Search.js.map +1 -1
- package/dist/services/Api.d.ts +5 -3
- package/dist/services/Api.js +12 -10
- package/dist/services/Api.js.map +1 -1
- package/dist/services/RouteGateway.d.ts +3 -3
- package/dist/services/RouteGateway.js +11 -11
- package/dist/services/RouteGateway.js.map +1 -1
- package/dist/types/Cache.d.ts +5 -3
- package/dist/types/Cache.js +11 -0
- package/dist/types/Cache.js.map +1 -1
- package/dist/types/CacheAge.js +1 -1
- package/dist/types/CacheAge.js.map +1 -1
- package/dist/types/Constructor.js.map +1 -1
- package/dist/types/Gateway.d.ts +1 -2
- package/dist/types/Gateway.js.map +1 -1
- package/dist/types/List.d.ts +1 -0
- package/dist/types/List.js +3 -1
- package/dist/types/List.js.map +1 -1
- package/dist/types/Repository.d.ts +15 -0
- package/dist/types/Repository.js +45 -0
- package/dist/types/Repository.js.map +1 -0
- package/dist/types/Uri.d.ts +3 -3
- package/dist/types/Uri.js +3 -3
- package/dist/types/Uri.js.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -1
- package/dist/utils/View.js +1 -1
- package/dist/utils/View.js.map +1 -1
- package/package.json +2 -2
- package/src/data/Condition.ts +3 -5
- package/src/domain/Repo.ts +5 -2
- package/src/domain/Typo.ts +5 -39
- package/src/domain/enums/Currency.ts +3 -1
- package/src/domain/index.ts +1 -0
- package/src/http/CacheControl.ts +26 -24
- package/src/http/LocalRequestStore.ts +12 -0
- package/src/http/RestResult.ts +1 -1
- package/src/process/Manage.ts +1 -2
- package/src/process/Search.ts +4 -4
- package/src/services/Api.ts +57 -68
- package/src/services/RouteGateway.ts +88 -78
- package/src/types/Cache.ts +18 -6
- package/src/types/CacheAge.ts +48 -48
- package/src/types/Constructor.ts +3 -3
- package/src/types/Gateway.ts +1 -3
- package/src/types/List.ts +4 -1
- package/src/types/PageList.ts +2 -2
- package/src/types/Repository.ts +52 -0
- package/src/types/Types.ts +0 -1
- package/src/types/Uri.ts +6 -6
- package/src/types/index.ts +1 -0
- package/src/utils/View.ts +9 -11
- package/dist/http/NoRequestStore.d.ts +0 -6
- package/dist/http/NoRequestStore.js +0 -10
- package/dist/http/NoRequestStore.js.map +0 -1
- package/src/http/NoRequestStore.ts +0 -9
package/src/services/Api.ts
CHANGED
|
@@ -1,81 +1,70 @@
|
|
|
1
|
-
import {FetchOptions, Uri} from '../types';
|
|
2
|
-
import {HttpVerb, RequestOptions, RequestProvider, Response, toPageOptions} from '../http';
|
|
3
|
-
import {AxiosProvider} from './AxiosProvider';
|
|
1
|
+
import { FetchOptions, Store, Uri } from '../types';
|
|
2
|
+
import { HttpVerb, Request, RequestOptions, RequestProvider, Response, toPageOptions } from '../http';
|
|
3
|
+
import { AxiosProvider } from './AxiosProvider';
|
|
4
4
|
|
|
5
5
|
export type RouteOptions = RequestOptions | FetchOptions;
|
|
6
6
|
|
|
7
7
|
export class Api {
|
|
8
|
-
|
|
9
|
-
}
|
|
8
|
+
constructor(readonly provider: RequestProvider = new AxiosProvider(), protected store?: Store<Response, Request>) {}
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
10
|
+
get(uri: Uri, options?: RouteOptions, transform?: (r: any) => any, transformError = (r: any) => r): Promise<Response> {
|
|
11
|
+
return this.execute({
|
|
12
|
+
uri: uri.skip(toPageOptions(options)?.skip).take(toPageOptions(options)?.take),
|
|
13
|
+
verb: HttpVerb.Get,
|
|
14
|
+
transform,
|
|
15
|
+
transformError,
|
|
16
|
+
options: this.options(HttpVerb.Get, options),
|
|
17
|
+
});
|
|
18
|
+
}
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
body,
|
|
32
|
-
transform,
|
|
33
|
-
transformError,
|
|
34
|
-
options: this.options(HttpVerb.Post, options)
|
|
35
|
-
});
|
|
36
|
-
}
|
|
20
|
+
post(uri: Uri, body?: unknown, options: RouteOptions = RequestOptions.Json, transform?: (r: any) => any, transformError = (r: any) => r): Promise<Response> {
|
|
21
|
+
return this.execute({
|
|
22
|
+
uri,
|
|
23
|
+
verb: HttpVerb.Post,
|
|
24
|
+
body,
|
|
25
|
+
transform,
|
|
26
|
+
transformError,
|
|
27
|
+
options: this.options(HttpVerb.Post, options),
|
|
28
|
+
});
|
|
29
|
+
}
|
|
37
30
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
31
|
+
put(uri: Uri, body?: unknown, options: RouteOptions = RequestOptions.Json, transform?: (r: any) => any, transformError = (r: any) => r): Promise<Response> {
|
|
32
|
+
return this.execute({
|
|
33
|
+
uri,
|
|
34
|
+
verb: HttpVerb.Put,
|
|
35
|
+
body,
|
|
36
|
+
transform,
|
|
37
|
+
transformError,
|
|
38
|
+
options: this.options(HttpVerb.Put, options),
|
|
39
|
+
});
|
|
40
|
+
}
|
|
48
41
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
body,
|
|
60
|
-
transform,
|
|
61
|
-
transformError,
|
|
62
|
-
options: this.options(HttpVerb.Patch, options)
|
|
63
|
-
});
|
|
64
|
-
}
|
|
42
|
+
patch(uri: Uri, body?: unknown, options: RouteOptions = RequestOptions.Json, transform?: (r: any) => any, transformError = (r: any) => r): Promise<Response> {
|
|
43
|
+
return this.execute({
|
|
44
|
+
uri,
|
|
45
|
+
verb: HttpVerb.Patch,
|
|
46
|
+
body,
|
|
47
|
+
transform,
|
|
48
|
+
transformError,
|
|
49
|
+
options: this.options(HttpVerb.Patch, options),
|
|
50
|
+
});
|
|
51
|
+
}
|
|
65
52
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
53
|
+
delete(uri: Uri, options: RouteOptions = RequestOptions.Json, transform?: (b: any) => any, transformError = (r: any) => r): Promise<Response> {
|
|
54
|
+
return this.execute({
|
|
55
|
+
uri,
|
|
56
|
+
verb: HttpVerb.Delete,
|
|
57
|
+
transform,
|
|
58
|
+
transformError,
|
|
59
|
+
options: this.options(HttpVerb.Delete, options),
|
|
60
|
+
});
|
|
61
|
+
}
|
|
75
62
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
63
|
+
options(verb: HttpVerb, options?: RouteOptions): RequestOptions {
|
|
64
|
+
return options instanceof RequestOptions ? options : RequestOptions.Json;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
execute = (req: Request): Promise<Response> => (this.store ? this.store.execute(req, () => this.provider.execute(req)) : this.provider.execute(req));
|
|
79
68
|
}
|
|
80
69
|
|
|
81
70
|
export const api: Api = new Api();
|
|
@@ -1,81 +1,91 @@
|
|
|
1
|
-
import {Api, RouteOptions} from './Api';
|
|
2
|
-
import {FetchOptions, Filter, Func, Gateway, Id, Json, JsonValue, PageList, toPageList, Uri} from '../types';
|
|
3
|
-
import {HttpStatus, RequestOptions, toPageOptions} from '../http';
|
|
1
|
+
import { Api, RouteOptions } from './Api';
|
|
2
|
+
import { FetchOptions, Filter, Func, Gateway, Id, Json, JsonValue, PageList, toPageList, Uri } from '../types';
|
|
3
|
+
import { HttpStatus, RequestOptions, toPageOptions } from '../http';
|
|
4
4
|
|
|
5
5
|
export class RouteGateway extends Gateway<RouteOptions> {
|
|
6
|
-
|
|
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
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
6
|
+
constructor(readonly route: Func<Uri>, readonly routeId: Func<Uri>, readonly api: Api = new Api()) {
|
|
7
|
+
super();
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
get(uri: Uri, options?: RouteOptions): Promise<PageList<Json>> {
|
|
11
|
+
return this.api.get(uri, options).then(r =>
|
|
12
|
+
toPageList<Json>(
|
|
13
|
+
r.body.data?.items,
|
|
14
|
+
toPageOptions(options) && {
|
|
15
|
+
total: r.body.data?.totalItems,
|
|
16
|
+
filters: r.body.data?.meta?.filters as Filter[],
|
|
17
|
+
}
|
|
18
|
+
)
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
getOne(uri: Uri, options?: RouteOptions): Promise<Json | undefined> {
|
|
23
|
+
return this.get(uri, options).then(r => r.first());
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
all(options?: RouteOptions): Promise<PageList<Json>> {
|
|
27
|
+
return this.get(this.route(), options);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
byId(id: Id, options?: RouteOptions): Promise<Json | undefined> {
|
|
31
|
+
return this.getOne(this.routeId().id(id));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
search(q: JsonValue, options?: RouteOptions): Promise<PageList<Json>> {
|
|
35
|
+
return this.get(this.route().query(q), options);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
exists(id: Id, options?: RouteOptions): Promise<boolean> {
|
|
39
|
+
return this.get(this.routeId().id(id))
|
|
40
|
+
.then(r => r.length === 1)
|
|
41
|
+
.catch(r => (HttpStatus.NotFound.equals(r.status) ? false : Promise.reject(r)));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
add(item: Json, options?: RouteOptions): Promise<Json> {
|
|
45
|
+
return this.post(this.route(), item, options);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
filter(options?: RouteOptions): Promise<PageList<Json>> {
|
|
49
|
+
return this.postSearch(this.route(), options);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
update(item: Json, options?: RouteOptions): Promise<Json> {
|
|
53
|
+
return this.patch(this.routeId().id(item.id), item, options);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
upsert(item: Json, options?: RouteOptions): Promise<Json> {
|
|
57
|
+
return this.put(this.routeId().id(item.id), item, options);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
remove(id: Id, options?: RouteOptions): Promise<boolean> {
|
|
61
|
+
return this.delete(this.routeId().id(id), options);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
post(uri: Uri, item?: Json, options?: RouteOptions): Promise<Json> {
|
|
65
|
+
return this.api.post(uri, item, options).then(r => r.body.data?.items.first() ?? {});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
postSearch(uri: Uri, options?: RequestOptions | FetchOptions): Promise<PageList<Json>> {
|
|
69
|
+
return this.api.post(uri, options).then(r =>
|
|
70
|
+
toPageList<Json>(
|
|
71
|
+
r.body.data?.items,
|
|
72
|
+
toPageOptions(options) && {
|
|
73
|
+
total: r.body.data?.totalItems,
|
|
74
|
+
filters: r.body.data?.meta?.filters as Filter[],
|
|
75
|
+
}
|
|
76
|
+
)
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
patch(uri: Uri, item: Json, options?: RouteOptions): Promise<Json> {
|
|
81
|
+
return this.api.patch(uri, item, options).then(r => r.body.data?.items.first() ?? {});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
put(uri: Uri, item: Json, options?: RouteOptions): Promise<Json> {
|
|
85
|
+
return this.api.put(uri, item, options).then(r => r.body.data?.items.first() ?? {});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
delete(uri: Uri, options?: RouteOptions): Promise<boolean> {
|
|
89
|
+
return this.api.delete(uri, options).then(() => true);
|
|
90
|
+
}
|
|
81
91
|
}
|
package/src/types/Cache.ts
CHANGED
|
@@ -1,12 +1,24 @@
|
|
|
1
|
-
import {Func} from
|
|
2
|
-
import {CacheAge} from
|
|
3
|
-
import {Construct} from
|
|
1
|
+
import { Func } from './Func';
|
|
2
|
+
import { CacheAge } from './CacheAge';
|
|
3
|
+
import { Construct } from './Constructor';
|
|
4
|
+
import { meta } from './Meta';
|
|
4
5
|
|
|
5
6
|
export interface Store<To = any, From = any> {
|
|
6
|
-
|
|
7
|
+
execute: (fetch: From, f: Func<Promise<To>, From>) => Promise<To>;
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
export type CacheOptions = {
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
expiresIn?: CacheAge;
|
|
12
|
+
store?: Construct<Store>;
|
|
12
13
|
};
|
|
14
|
+
|
|
15
|
+
export const toCacheOptions = (co: Partial<CacheOptions>): CacheOptions => ({
|
|
16
|
+
expiresIn: co.expiresIn ?? '5m',
|
|
17
|
+
store: co.store,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export const cache =
|
|
21
|
+
(options: Partial<CacheOptions>): ClassDecorator =>
|
|
22
|
+
(subject: unknown): void => {
|
|
23
|
+
meta(subject).set('cache', toCacheOptions(options));
|
|
24
|
+
};
|
package/src/types/CacheAge.ts
CHANGED
|
@@ -1,55 +1,55 @@
|
|
|
1
|
-
import {asNumber, asString, choose} from
|
|
1
|
+
import { asNumber, asString, choose } from './index';
|
|
2
2
|
|
|
3
3
|
export type CacheAge = `${number}${'ms' | 's' | 'm' | 'h' | 'd'}` | number;
|
|
4
4
|
|
|
5
5
|
const ageNumber = (s: string): number => asNumber(s.replace(/[a-z]/g, ''));
|
|
6
6
|
|
|
7
7
|
export const cacheAge = {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
8
|
+
toMilliseconds: (ca: CacheAge): number =>
|
|
9
|
+
choose(asString(ca))
|
|
10
|
+
.case(
|
|
11
|
+
c => c.endsWith('ms'),
|
|
12
|
+
c => ageNumber(c)
|
|
13
|
+
)
|
|
14
|
+
.case(
|
|
15
|
+
c => c.endsWith('s'),
|
|
16
|
+
c => ageNumber(c) * 1000
|
|
17
|
+
)
|
|
18
|
+
.case(
|
|
19
|
+
c => c.endsWith('m'),
|
|
20
|
+
c => ageNumber(c) * 60 * 1000
|
|
21
|
+
)
|
|
22
|
+
.case(
|
|
23
|
+
c => c.endsWith('h'),
|
|
24
|
+
c => ageNumber(c) * 3600 * 1000
|
|
25
|
+
)
|
|
26
|
+
.case(
|
|
27
|
+
c => c.endsWith('d'),
|
|
28
|
+
c => ageNumber(c) * 24 * 3600 * 1000
|
|
29
|
+
)
|
|
30
|
+
.else(ca as number),
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
32
|
+
toSeconds: (ca: CacheAge): number =>
|
|
33
|
+
choose(asString(ca))
|
|
34
|
+
.case(
|
|
35
|
+
c => c.endsWith('ms'),
|
|
36
|
+
c => ageNumber(c) / 1000
|
|
37
|
+
)
|
|
38
|
+
.case(
|
|
39
|
+
c => c.endsWith('s'),
|
|
40
|
+
c => ageNumber(c)
|
|
41
|
+
)
|
|
42
|
+
.case(
|
|
43
|
+
c => c.endsWith('m'),
|
|
44
|
+
c => ageNumber(c) * 60
|
|
45
|
+
)
|
|
46
|
+
.case(
|
|
47
|
+
c => c.endsWith('h'),
|
|
48
|
+
c => ageNumber(c) * 3600
|
|
49
|
+
)
|
|
50
|
+
.case(
|
|
51
|
+
c => c.endsWith('d'),
|
|
52
|
+
c => ageNumber(c) * 24 * 3600
|
|
53
|
+
)
|
|
54
|
+
.else(ca as number),
|
|
55
|
+
};
|
package/src/types/Constructor.ts
CHANGED
|
@@ -13,6 +13,6 @@ export const ofConstruct = <T>(c: Construct<T>, ...args: unknown[]): T => (isCon
|
|
|
13
13
|
export const toName = (subject?: unknown, postfix = ''): string => (subject as any)?.constructor?.name?.replace(postfix, '').toLowerCase() ?? '';
|
|
14
14
|
|
|
15
15
|
export const on = <T>(t: T, f: (t: T) => unknown): T => {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
};
|
|
16
|
+
f(t);
|
|
17
|
+
return t;
|
|
18
|
+
};
|
package/src/types/Gateway.ts
CHANGED
|
@@ -4,10 +4,8 @@ import { Exception } from './Exception';
|
|
|
4
4
|
import { reject } from '../utils';
|
|
5
5
|
import { PageList, PageOptions } from './PageList';
|
|
6
6
|
import { List } from './List';
|
|
7
|
-
import {CacheOptions} from "./Cache";
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
export type FetchOptions = PageOptions & CacheOptions;
|
|
8
|
+
export type FetchOptions = PageOptions;
|
|
11
9
|
|
|
12
10
|
export abstract class Gateway<Options = FetchOptions> {
|
|
13
11
|
all(options?: Options): Promise<PageList<Json>> {
|
package/src/types/List.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { Get, GetProperty, ofGet, ofProperty } from './Get';
|
|
|
7
7
|
import { Id } from './Id';
|
|
8
8
|
import { asString } from './Text';
|
|
9
9
|
import { tryTo } from './Try';
|
|
10
|
+
import { meta } from './Meta';
|
|
10
11
|
|
|
11
12
|
export class List<T = unknown> extends Array<T> {
|
|
12
13
|
asc = (p: GetProperty<T, any>): List<T> => this.sort((e1, e2) => (ofProperty(e1, p) > ofProperty(e2, p) ? 1 : -1));
|
|
@@ -54,6 +55,8 @@ export class List<T = unknown> extends Array<T> {
|
|
|
54
55
|
|
|
55
56
|
distinct = (): List<T> => this.filter((i, index) => this.indexOf(i) === index);
|
|
56
57
|
|
|
58
|
+
distinctByKey = (key: keyof T): List<T> => meta(this.toObject(key)).values();
|
|
59
|
+
|
|
57
60
|
filter = (p: (value: T, index: number, array: T[]) => unknown, params?: unknown): List<T> => toList<T>(super.filter(p, params));
|
|
58
61
|
|
|
59
62
|
sum = (p: (t: T) => number): number => this.reduce((sum: number, i) => sum + p(i), 0);
|
|
@@ -77,7 +80,7 @@ export class List<T = unknown> extends Array<T> {
|
|
|
77
80
|
tryTo(() => item[key])
|
|
78
81
|
.map(k => this.findIndex(i => i[key] === k))
|
|
79
82
|
.filter(i => i > -1)
|
|
80
|
-
.map(i => this[i] = item);
|
|
83
|
+
.map(i => (this[i] = item));
|
|
81
84
|
return this;
|
|
82
85
|
};
|
|
83
86
|
|
package/src/types/PageList.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { isList, List, toList } from './List';
|
|
|
2
2
|
import { Construct, ofConstruct } from './Constructor';
|
|
3
3
|
import { isA } from './IsA';
|
|
4
4
|
|
|
5
|
-
export type Sort =
|
|
5
|
+
export type Sort = { key: string; value: -1 | 1 };
|
|
6
6
|
|
|
7
7
|
export type FilterValue = { label?: string; value: any };
|
|
8
8
|
export type Filter = { label?: string; field: string; values: FilterValue[] };
|
|
@@ -26,5 +26,5 @@ export const toPageList = <T>(items?: T[], options?: Omit<PageOptions, 'sort'> &
|
|
|
26
26
|
export const asPageList = <T, U>(c: Construct<T>, items = toPageList<U>()): PageList<T> =>
|
|
27
27
|
toPageList<T>(
|
|
28
28
|
items.map(i => ofConstruct(c, i)),
|
|
29
|
-
items
|
|
29
|
+
items
|
|
30
30
|
);
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Exception, Id, Json, JsonValue, Key, List, PageList, PageOptions } from './index';
|
|
2
|
+
import { reject } from '../utils';
|
|
3
|
+
|
|
4
|
+
export class Repository<T> {
|
|
5
|
+
all(options?: PageOptions): Promise<PageList<T>> {
|
|
6
|
+
return reject(Exception.IsNotImplemented);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
byId(id: Id): Promise<T> {
|
|
10
|
+
return reject(Exception.IsNotImplemented);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
byIds(...ids: Id[]): Promise<List<T>> {
|
|
14
|
+
return reject(Exception.IsNotImplemented);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
byKey(key: Key, options?: PageOptions): Promise<PageList<T>> {
|
|
18
|
+
return reject(Exception.IsNotImplemented);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
by(key: keyof T, value: JsonValue, options?: PageOptions): Promise<PageList<T>> {
|
|
22
|
+
return reject(Exception.IsNotImplemented);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
search(q: JsonValue, options?: PageOptions): Promise<PageList<T>> {
|
|
26
|
+
return reject(Exception.IsNotImplemented);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
filter(options?: PageOptions): Promise<PageList<T>> {
|
|
30
|
+
return reject(Exception.IsNotImplemented);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
exists(id: Id): Promise<boolean> {
|
|
34
|
+
return reject(Exception.IsNotImplemented);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
add(t: T | Json): Promise<T> {
|
|
38
|
+
return reject(Exception.IsNotImplemented);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
update(id: Id, json: Json): Promise<T> {
|
|
42
|
+
return reject(Exception.IsNotImplemented);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
remove(id: Id): Promise<boolean> {
|
|
46
|
+
return reject(Exception.IsNotImplemented);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
upsert(id: Id, item: Json): Promise<T> {
|
|
50
|
+
return reject(Exception.IsNotImplemented);
|
|
51
|
+
}
|
|
52
|
+
}
|
package/src/types/Types.ts
CHANGED
package/src/types/Uri.ts
CHANGED
|
@@ -8,19 +8,19 @@ import { tryTo } from './Try';
|
|
|
8
8
|
|
|
9
9
|
export type Segment = Text & { key?: string; segment?: string; query?: (value: unknown) => string };
|
|
10
10
|
|
|
11
|
-
const toSegment = (key?:
|
|
12
|
-
key,
|
|
11
|
+
const toSegment = (key?: Text, { segment, query }: { segment?: string; query?: (value: unknown) => string } = {}): Segment => ({
|
|
12
|
+
key: asString(key),
|
|
13
13
|
segment,
|
|
14
14
|
query,
|
|
15
|
-
toString: () => key
|
|
15
|
+
toString: () => asString(key),
|
|
16
16
|
});
|
|
17
17
|
|
|
18
18
|
export const uri = {
|
|
19
19
|
host: (key?: string): Segment => toSegment(key, { segment: key ?? ctx.env.host ?? '$host' }),
|
|
20
20
|
resource: (resource: Uri): Segment => toSegment(toName(resource, 'Uri'), { segment: toName(resource, 'Uri') }),
|
|
21
|
-
segment: (key?:
|
|
22
|
-
path: (key:
|
|
23
|
-
query: (key:
|
|
21
|
+
segment: (key?: Text): Segment => toSegment(key, { segment: asString(key) }),
|
|
22
|
+
path: (key: Text): Segment => toSegment(key, { segment: `:${key}` }),
|
|
23
|
+
query: (key: Text): Segment => toSegment(key, { query: (value: unknown): string => (isDefined(value) ? `${key}=${value}` : '') }),
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
type Prop = { segment: Segment; value: any };
|
package/src/types/index.ts
CHANGED
package/src/utils/View.ts
CHANGED
|
@@ -36,9 +36,9 @@ const toFunc = (a: any, col: string, f: Func = a => a): Func =>
|
|
|
36
36
|
const toViewer = (key: string, value: unknown): Viewer =>
|
|
37
37
|
choose(value)
|
|
38
38
|
.is.not.defined(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
v => v,
|
|
40
|
+
() => toViewer(key, () => undefined)
|
|
41
|
+
)
|
|
42
42
|
.type(isBoolean, b => toViewer(key, () => b))
|
|
43
43
|
.type(isNumber, n => toViewer(key, () => n))
|
|
44
44
|
.type(isString, s => toViewer(key, (a: any) => toFunc(a, s)(a)))
|
|
@@ -55,15 +55,13 @@ const toViewers = (views: Views): Viewer[] =>
|
|
|
55
55
|
.map(([k, v]) => toViewer(k, v));
|
|
56
56
|
|
|
57
57
|
export class View<V = Json> {
|
|
58
|
-
constructor(private views: Views<V> = {} as Views<V>, readonly startsFrom: 'scratch' | 'source' = 'scratch', readonly viewers: Viewer[] = toViewers(views)) {
|
|
59
|
-
}
|
|
58
|
+
constructor(private views: Views<V> = {} as Views<V>, readonly startsFrom: 'scratch' | 'source' = 'scratch', readonly viewers: Viewer[] = toViewers(views)) {}
|
|
60
59
|
|
|
61
60
|
get fromSource(): View<V> {
|
|
62
61
|
return new View(this.views, 'source', this.viewers);
|
|
63
62
|
}
|
|
64
63
|
|
|
65
|
-
from = <T = unknown>(source: T | T[]): T extends [] ? V[] : V =>
|
|
66
|
-
isArray(source) ? source.map(s => this.reduce(asJson(s))) : this.reduce(asJson(source));
|
|
64
|
+
from = <T = unknown>(source: T | T[]): T extends [] ? V[] : V => (isArray(source) ? source.map(s => this.reduce(asJson(s))) : this.reduce(asJson(source)));
|
|
67
65
|
|
|
68
66
|
same = (one?: unknown, another?: unknown): boolean => isEqual(this.from(one), this.from(another));
|
|
69
67
|
|
|
@@ -80,11 +78,11 @@ export const views = {
|
|
|
80
78
|
keepOr: (alt?: string) => (a: unknown, key?: string) => traverse(a, key) ?? alt,
|
|
81
79
|
or:
|
|
82
80
|
(key: string, alt = '') =>
|
|
83
|
-
|
|
84
|
-
|
|
81
|
+
(a: unknown) =>
|
|
82
|
+
traverse(a, key) ?? alt,
|
|
85
83
|
value: (value: unknown) => () => value,
|
|
86
84
|
to:
|
|
87
85
|
<T>(ctor: Constructor<T>) =>
|
|
88
|
-
|
|
89
|
-
|
|
86
|
+
(a: unknown, key?: string) =>
|
|
87
|
+
new ctor(traverse(a, key)),
|
|
90
88
|
};
|