akanjs 2.3.8-rc.2 → 2.3.8-rc.4
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/base/symbols.ts +3 -0
- package/dictionary/dictInfo.ts +58 -45
- package/dictionary/locale.ts +97 -52
- package/document/database.ts +3 -7
- package/document/filterMeta.ts +18 -2
- package/package.json +1 -1
- package/service/injectInfo.ts +26 -12
- package/service/predefinedAdaptor/cache.adaptor.ts +8 -9
- package/service/predefinedAdaptor/solidCache.adaptor.ts +3 -4
- package/signal/endpoint.ts +14 -6
- package/signal/slice.ts +11 -3
- package/types/base/symbols.d.ts +3 -0
- package/types/dictionary/base.dictionary.d.ts +1 -1
- package/types/dictionary/dictInfo.d.ts +24 -11
- package/types/dictionary/locale.d.ts +39 -40
- package/types/document/database.d.ts +3 -6
- package/types/document/filterMeta.d.ts +25 -3
- package/types/service/injectInfo.d.ts +8 -4
- package/types/service/predefinedAdaptor/cache.adaptor.d.ts +7 -12
- package/types/service/predefinedAdaptor/solidCache.adaptor.d.ts +3 -8
- package/types/signal/endpoint.d.ts +16 -6
- package/types/signal/signalRegistry.d.ts +2 -14
- package/types/signal/slice.d.ts +13 -3
package/base/symbols.ts
CHANGED
|
@@ -4,6 +4,9 @@ export const FILTER_META = Symbol.for("akan.filter");
|
|
|
4
4
|
export const LOADER_META = Symbol.for("akan.loader");
|
|
5
5
|
export const INJECT_META = Symbol.for("akan.inject");
|
|
6
6
|
export const ENDPOINT_META = Symbol.for("akan.endpoint");
|
|
7
|
+
export const ENDPOINT_DICT_SHAPE: unique symbol = Symbol.for("akan.endpoint.dictShape") as never;
|
|
8
|
+
export const SLICE_DICT_SHAPE: unique symbol = Symbol.for("akan.slice.dictShape") as never;
|
|
9
|
+
export const FILTER_DICT_SHAPE: unique symbol = Symbol.for("akan.filter.dictShape") as never;
|
|
7
10
|
export const INTERNAL_META = Symbol.for("akan.internal");
|
|
8
11
|
export const STATE_META = Symbol.for("akan.state");
|
|
9
12
|
export const STATE_INIT_META = Symbol.for("akan.state.init");
|
package/dictionary/dictInfo.ts
CHANGED
|
@@ -1,40 +1,62 @@
|
|
|
1
|
-
import type { GetStateObject } from "akanjs/base";
|
|
1
|
+
import type { ENDPOINT_DICT_SHAPE, FILTER_DICT_SHAPE, GetStateObject, SLICE_DICT_SHAPE } from "akanjs/base";
|
|
2
2
|
import { capitalize } from "akanjs/common";
|
|
3
3
|
import type { BaseInsight, BaseObject } from "akanjs/constant";
|
|
4
|
-
import type { BaseFilterQueryKey, BaseFilterSortKey, FilterCls, FilterInfo, FilterInstance } from "akanjs/document";
|
|
5
4
|
import type {
|
|
6
|
-
|
|
5
|
+
BaseFilterQueryKey,
|
|
6
|
+
BaseFilterSortKey,
|
|
7
|
+
FilterCls,
|
|
8
|
+
FilterDictShape as FilterCompactShape,
|
|
9
|
+
FilterDictArgShape,
|
|
10
|
+
FilterInfo,
|
|
11
|
+
FilterInstance,
|
|
12
|
+
} from "akanjs/document";
|
|
13
|
+
import type {
|
|
7
14
|
EndpointCls,
|
|
15
|
+
EndpointDictShape as EndpointCompactShape,
|
|
8
16
|
EndpointInfo,
|
|
9
17
|
SliceCls,
|
|
18
|
+
SliceDictShape as SliceCompactShape,
|
|
10
19
|
SliceInfo,
|
|
11
|
-
SliceInfoArgNames,
|
|
12
20
|
} from "akanjs/signal";
|
|
13
21
|
import type { DictionaryNode, RootDictionary } from "./trans";
|
|
14
22
|
|
|
15
23
|
type MutableDictionaryNode = DictionaryNode & { t?: string; desc?: DictionaryNode };
|
|
16
24
|
type EnumValueKey = string | number;
|
|
17
|
-
type
|
|
25
|
+
type DictArgShape = { [key: string]: readonly string[] };
|
|
26
|
+
type AnyFilterShape = FilterCompactShape<FilterInstance<Record<string, FilterInfo>, Record<string, unknown>>>;
|
|
18
27
|
type DictFilterShape<Filter> =
|
|
19
28
|
Filter extends FilterCls<infer FilterShape>
|
|
20
|
-
? FilterShape
|
|
21
|
-
: Filter extends
|
|
22
|
-
?
|
|
23
|
-
: Filter extends
|
|
24
|
-
? Filter
|
|
25
|
-
:
|
|
29
|
+
? FilterCompactShape<FilterShape>
|
|
30
|
+
: Filter extends { readonly [FILTER_DICT_SHAPE]: infer CompactShape extends FilterDictArgShape }
|
|
31
|
+
? CompactShape
|
|
32
|
+
: Filter extends FilterInstance
|
|
33
|
+
? FilterCompactShape<Filter>
|
|
34
|
+
: Filter extends { query: Record<string, FilterInfo>; sort: Record<string, unknown> }
|
|
35
|
+
? FilterCompactShape<Filter>
|
|
36
|
+
: Filter extends { query: DictArgShape; sort: Record<string, true> }
|
|
37
|
+
? Filter
|
|
38
|
+
: AnyFilterShape;
|
|
26
39
|
type DictSliceShape<Slice> =
|
|
27
40
|
Slice extends SliceCls<infer _SrvModule, infer SliceInfoObj>
|
|
28
|
-
? SliceInfoObj
|
|
29
|
-
: Slice extends
|
|
30
|
-
?
|
|
31
|
-
:
|
|
41
|
+
? SliceCompactShape<SliceInfoObj>
|
|
42
|
+
: Slice extends { readonly [SLICE_DICT_SHAPE]: infer CompactShape extends DictArgShape }
|
|
43
|
+
? CompactShape
|
|
44
|
+
: Slice extends DictArgShape
|
|
45
|
+
? Slice
|
|
46
|
+
: Slice extends Record<string, SliceInfo>
|
|
47
|
+
? SliceCompactShape<Slice>
|
|
48
|
+
: Record<never, never>;
|
|
32
49
|
type DictEndpointShape<Endpoint> =
|
|
33
50
|
Endpoint extends EndpointCls<infer _SrvModule, infer EndpointInfoObj>
|
|
34
|
-
? EndpointInfoObj
|
|
35
|
-
: Endpoint extends
|
|
36
|
-
?
|
|
37
|
-
:
|
|
51
|
+
? EndpointCompactShape<EndpointInfoObj>
|
|
52
|
+
: Endpoint extends { readonly [ENDPOINT_DICT_SHAPE]: infer CompactShape extends DictArgShape }
|
|
53
|
+
? CompactShape
|
|
54
|
+
: Endpoint extends DictArgShape
|
|
55
|
+
? Endpoint
|
|
56
|
+
: Endpoint extends Record<string, EndpointInfo>
|
|
57
|
+
? EndpointCompactShape<Endpoint>
|
|
58
|
+
: Record<never, never>;
|
|
59
|
+
type DictArgNames<ArgNames> = ArgNames extends readonly string[] ? ArgNames[number] : never;
|
|
38
60
|
type DictFilterQuery<Filter> = DictFilterShape<Filter>["query"];
|
|
39
61
|
type DictFilterSort<Filter> = DictFilterShape<Filter>["sort"];
|
|
40
62
|
|
|
@@ -282,22 +304,14 @@ export class ModelDictInfo<
|
|
|
282
304
|
}
|
|
283
305
|
query<Filter>(
|
|
284
306
|
translate: (fn: (trans: Languages) => FunctionTranslation<Languages>) => {
|
|
285
|
-
[K in Exclude<keyof DictFilterQuery<Filter>, QueryKey>]:
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
>
|
|
290
|
-
? FunctionTranslation<Languages, ArgNames[number]>
|
|
291
|
-
: never;
|
|
307
|
+
[K in Exclude<keyof DictFilterQuery<Filter>, QueryKey>]: FunctionTranslation<
|
|
308
|
+
Languages,
|
|
309
|
+
DictArgNames<DictFilterQuery<Filter>[K]>
|
|
310
|
+
>;
|
|
292
311
|
},
|
|
293
312
|
) {
|
|
294
313
|
Object.assign(this.queryDictionary, translate(fn), ModelDictInfo.baseQueryDictionary) as unknown as {
|
|
295
|
-
[K in keyof DictFilterQuery<Filter>]: FunctionTranslation<
|
|
296
|
-
Languages,
|
|
297
|
-
DictFilterQuery<Filter>[K] extends FilterInfo<infer ArgNames, infer _Args, infer _Model>
|
|
298
|
-
? ArgNames[number]
|
|
299
|
-
: never
|
|
300
|
-
>;
|
|
314
|
+
[K in keyof DictFilterQuery<Filter>]: FunctionTranslation<Languages, DictArgNames<DictFilterQuery<Filter>[K]>>;
|
|
301
315
|
};
|
|
302
316
|
return this as unknown as ModelDictInfo<
|
|
303
317
|
Languages,
|
|
@@ -363,10 +377,10 @@ export class ModelDictInfo<
|
|
|
363
377
|
}
|
|
364
378
|
slice<Slice>(
|
|
365
379
|
translate: (fn: (trans: Languages) => FunctionTranslation<Languages>) => {
|
|
366
|
-
[K in Exclude<keyof DictSliceShape<Slice>, SliceKey>]:
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
380
|
+
[K in Exclude<keyof DictSliceShape<Slice>, SliceKey>]: FunctionTranslation<
|
|
381
|
+
Languages,
|
|
382
|
+
DictArgNames<DictSliceShape<Slice>[K]>
|
|
383
|
+
>;
|
|
370
384
|
},
|
|
371
385
|
) {
|
|
372
386
|
Object.assign(this.sliceDictionary, translate(fn), ModelDictInfo.baseSliceDictionary) as unknown as {
|
|
@@ -388,12 +402,10 @@ export class ModelDictInfo<
|
|
|
388
402
|
}
|
|
389
403
|
endpoint<Endpoint>(
|
|
390
404
|
translate: (fn: (trans: Languages) => FunctionTranslation<Languages>) => {
|
|
391
|
-
[K in Exclude<
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
? FunctionTranslation<Languages, EndpInfoArgNames<Info>[number]>
|
|
396
|
-
: never;
|
|
405
|
+
[K in Exclude<keyof DictEndpointShape<Endpoint>, EndpointKey>]: FunctionTranslation<
|
|
406
|
+
Languages,
|
|
407
|
+
DictArgNames<DictEndpointShape<Endpoint>[K]>
|
|
408
|
+
>;
|
|
397
409
|
},
|
|
398
410
|
) {
|
|
399
411
|
Object.assign(this.endpointDictionary, translate(fn)) as unknown as {
|
|
@@ -1009,9 +1021,10 @@ export class ServiceDictInfo<
|
|
|
1009
1021
|
}
|
|
1010
1022
|
endpoint<Endpoint>(
|
|
1011
1023
|
translate: (fn: (trans: Languages) => FunctionTranslation<Languages>) => {
|
|
1012
|
-
[K in keyof DictEndpointShape<Endpoint>]:
|
|
1013
|
-
|
|
1014
|
-
|
|
1024
|
+
[K in keyof DictEndpointShape<Endpoint>]: FunctionTranslation<
|
|
1025
|
+
Languages,
|
|
1026
|
+
DictArgNames<DictEndpointShape<Endpoint>[K]>
|
|
1027
|
+
>;
|
|
1015
1028
|
},
|
|
1016
1029
|
) {
|
|
1017
1030
|
Object.assign(this.endpointDictionary, translate(fn)) as unknown as {
|
package/dictionary/locale.ts
CHANGED
|
@@ -1,7 +1,28 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
ENDPOINT_DICT_SHAPE,
|
|
3
|
+
FILTER_DICT_SHAPE,
|
|
4
|
+
GetStateObject,
|
|
5
|
+
MergedValues,
|
|
6
|
+
SLICE_DICT_SHAPE,
|
|
7
|
+
} from "akanjs/base";
|
|
2
8
|
import type { BaseInsight, BaseObject } from "akanjs/constant";
|
|
3
|
-
import type {
|
|
4
|
-
|
|
9
|
+
import type {
|
|
10
|
+
FilterCls,
|
|
11
|
+
FilterDictShape as FilterCompactShape,
|
|
12
|
+
FilterDictArgShape,
|
|
13
|
+
FilterInfo,
|
|
14
|
+
FilterInstance,
|
|
15
|
+
} from "akanjs/document";
|
|
16
|
+
import type {
|
|
17
|
+
EndpointCls,
|
|
18
|
+
EndpointDictShape as EndpointCompactShape,
|
|
19
|
+
EndpointInfo,
|
|
20
|
+
SliceCls,
|
|
21
|
+
SliceDictShape as SliceCompactShape,
|
|
22
|
+
SliceInfo,
|
|
23
|
+
SliceInfoArgNames,
|
|
24
|
+
SliceInfoRefName,
|
|
25
|
+
} from "akanjs/signal";
|
|
5
26
|
import type { ModelDictInfo, ScalarDictInfo, ServiceDictInfo } from ".";
|
|
6
27
|
|
|
7
28
|
interface Trans {
|
|
@@ -16,35 +37,61 @@ interface FnTrans<ArgKey extends string> {
|
|
|
16
37
|
desc?: string;
|
|
17
38
|
arg?: { [key in ArgKey]: FieldTrans };
|
|
18
39
|
}
|
|
19
|
-
type
|
|
40
|
+
type DictArgShape = { [key: string]: readonly string[] };
|
|
41
|
+
type AnyFilterShape = FilterCompactShape<FilterInstance<Record<string, FilterInfo>, Record<string, unknown>>>;
|
|
20
42
|
type DictFilterShape<Filter> =
|
|
21
43
|
Filter extends FilterCls<infer FilterShape>
|
|
22
|
-
? FilterShape
|
|
23
|
-
: Filter extends
|
|
24
|
-
?
|
|
25
|
-
: Filter extends
|
|
26
|
-
? Filter
|
|
27
|
-
:
|
|
44
|
+
? FilterCompactShape<FilterShape>
|
|
45
|
+
: Filter extends { readonly [FILTER_DICT_SHAPE]: infer CompactShape extends FilterDictArgShape }
|
|
46
|
+
? CompactShape
|
|
47
|
+
: Filter extends FilterInstance
|
|
48
|
+
? FilterCompactShape<Filter>
|
|
49
|
+
: Filter extends { query: Record<string, FilterInfo>; sort: Record<string, unknown> }
|
|
50
|
+
? FilterCompactShape<Filter>
|
|
51
|
+
: Filter extends { query: DictArgShape; sort: Record<string, true> }
|
|
52
|
+
? Filter
|
|
53
|
+
: AnyFilterShape;
|
|
28
54
|
type DictFilterQuery<Filter> = DictFilterShape<Filter>["query"];
|
|
29
55
|
type DictFilterSort<Filter> = DictFilterShape<Filter>["sort"];
|
|
56
|
+
type DictArgNames<ArgNames> = ArgNames extends readonly string[] ? ArgNames[number] : never;
|
|
57
|
+
type DictEndpointShape<Endpoint> =
|
|
58
|
+
Endpoint extends EndpointCls<infer _SrvModule, infer EndpointInfoObj>
|
|
59
|
+
? EndpointCompactShape<EndpointInfoObj>
|
|
60
|
+
: Endpoint extends { readonly [ENDPOINT_DICT_SHAPE]: infer CompactShape extends DictArgShape }
|
|
61
|
+
? CompactShape
|
|
62
|
+
: Endpoint extends DictArgShape
|
|
63
|
+
? Endpoint
|
|
64
|
+
: Endpoint extends Record<string, EndpointInfo>
|
|
65
|
+
? EndpointCompactShape<Endpoint>
|
|
66
|
+
: Record<never, never>;
|
|
67
|
+
type DictSliceShape<Slice> =
|
|
68
|
+
Slice extends SliceCls<infer _SrvModule, infer SliceInfoObj>
|
|
69
|
+
? SliceCompactShape<SliceInfoObj>
|
|
70
|
+
: Slice extends { readonly [SLICE_DICT_SHAPE]: infer CompactShape extends DictArgShape }
|
|
71
|
+
? CompactShape
|
|
72
|
+
: Slice extends DictArgShape
|
|
73
|
+
? Slice
|
|
74
|
+
: Slice extends Record<string, SliceInfo>
|
|
75
|
+
? SliceCompactShape<Slice>
|
|
76
|
+
: Record<never, never>;
|
|
30
77
|
type FilterTranslatorKey<Filter> = {
|
|
31
78
|
[Key in keyof DictFilterQuery<Filter> & string]:
|
|
32
79
|
| `${Key}`
|
|
33
80
|
| `${Key}.desc`
|
|
34
|
-
| (DictFilterQuery<Filter>[Key] extends
|
|
35
|
-
?
|
|
36
|
-
|
|
37
|
-
|
|
81
|
+
| (DictArgNames<DictFilterQuery<Filter>[Key]> extends string
|
|
82
|
+
?
|
|
83
|
+
| `${Key}.arg.${DictArgNames<DictFilterQuery<Filter>[Key]>}`
|
|
84
|
+
| `${Key}.arg.${DictArgNames<DictFilterQuery<Filter>[Key]>}.desc`
|
|
38
85
|
: never);
|
|
39
86
|
}[keyof DictFilterQuery<Filter> & string];
|
|
40
|
-
type EndpointTranslatorKey<Endpoint
|
|
41
|
-
[Key in keyof Endpoint & string]:
|
|
87
|
+
type EndpointTranslatorKey<Endpoint> = {
|
|
88
|
+
[Key in keyof DictEndpointShape<Endpoint> & string]:
|
|
42
89
|
| `${Key}`
|
|
43
90
|
| `${Key}.desc`
|
|
44
|
-
| `${Key}.arg.${
|
|
45
|
-
| `${Key}.arg.${
|
|
46
|
-
}[keyof Endpoint & string];
|
|
47
|
-
type
|
|
91
|
+
| `${Key}.arg.${DictArgNames<DictEndpointShape<Endpoint>[Key]>}`
|
|
92
|
+
| `${Key}.arg.${DictArgNames<DictEndpointShape<Endpoint>[Key]>}.desc`;
|
|
93
|
+
}[keyof DictEndpointShape<Endpoint> & string];
|
|
94
|
+
type FullSliceTranslatorKey<Slice> = {
|
|
48
95
|
[Key in keyof Slice & string]: Slice[Key] extends infer Info extends SliceInfo
|
|
49
96
|
?
|
|
50
97
|
| `${SliceInfoRefName<Info>}List${Capitalize<Key>}`
|
|
@@ -57,6 +104,21 @@ type SliceTranslatorKey<Slice> = {
|
|
|
57
104
|
| `${SliceInfoRefName<Info>}Insight${Capitalize<Key>}.arg.${SliceInfoArgNames<Info>[number]}.desc`
|
|
58
105
|
: never;
|
|
59
106
|
}[keyof Slice & string];
|
|
107
|
+
type CompactSliceTranslatorKey<T extends string, Slice> = {
|
|
108
|
+
[Key in keyof DictSliceShape<Slice> & string]: Key extends ""
|
|
109
|
+
? never
|
|
110
|
+
:
|
|
111
|
+
| `${T}List${Capitalize<Key>}`
|
|
112
|
+
| `${T}List${Capitalize<Key>}.desc`
|
|
113
|
+
| `${T}List${Capitalize<Key>}.arg.${DictArgNames<DictSliceShape<Slice>[Key]> | "skip" | "limit" | "sort"}`
|
|
114
|
+
| `${T}List${Capitalize<Key>}.arg.${DictArgNames<DictSliceShape<Slice>[Key]> | "skip" | "limit" | "sort"}.desc`
|
|
115
|
+
| `${T}Insight${Capitalize<Key>}`
|
|
116
|
+
| `${T}Insight${Capitalize<Key>}.desc`
|
|
117
|
+
| `${T}Insight${Capitalize<Key>}.arg.${DictArgNames<DictSliceShape<Slice>[Key]>}`
|
|
118
|
+
| `${T}Insight${Capitalize<Key>}.arg.${DictArgNames<DictSliceShape<Slice>[Key]>}.desc`;
|
|
119
|
+
}[keyof DictSliceShape<Slice> & string];
|
|
120
|
+
type SliceTranslatorKey<T extends string, Slice> =
|
|
121
|
+
Slice extends Record<string, SliceInfo> ? FullSliceTranslatorKey<Slice> : CompactSliceTranslatorKey<T, Slice>;
|
|
60
122
|
|
|
61
123
|
type SliceApiTrans<
|
|
62
124
|
T extends string,
|
|
@@ -85,8 +147,8 @@ export type ModelTrans<
|
|
|
85
147
|
Model extends BaseObject,
|
|
86
148
|
Insight extends BaseInsight,
|
|
87
149
|
Filter,
|
|
88
|
-
Slice
|
|
89
|
-
Endpoint
|
|
150
|
+
Slice,
|
|
151
|
+
Endpoint,
|
|
90
152
|
ErrorKey extends string,
|
|
91
153
|
EtcKey extends string,
|
|
92
154
|
> = {
|
|
@@ -95,35 +157,25 @@ export type ModelTrans<
|
|
|
95
157
|
model: { [K in keyof GetStateObject<Model>]: FieldTrans };
|
|
96
158
|
insight: { [K in keyof GetStateObject<Insight>]: FieldTrans };
|
|
97
159
|
query: {
|
|
98
|
-
[K in keyof DictFilterQuery<Filter>]: DictFilterQuery<Filter>[K]
|
|
99
|
-
? FnTrans<ArgNames[number]>
|
|
100
|
-
: never;
|
|
160
|
+
[K in keyof DictFilterQuery<Filter>]: FnTrans<DictArgNames<DictFilterQuery<Filter>[K]>>;
|
|
101
161
|
};
|
|
102
162
|
sort: { [K in keyof DictFilterSort<Filter>]: FieldTrans };
|
|
103
163
|
api: {
|
|
104
|
-
[K in keyof Endpoint]: FnTrans<
|
|
164
|
+
[K in keyof DictEndpointShape<Endpoint>]: FnTrans<DictArgNames<DictEndpointShape<Endpoint>[K]>>;
|
|
105
165
|
} & BaseModelCrudGetApiTrans<T> &
|
|
106
166
|
MergedValues<{
|
|
107
|
-
[K in keyof Slice]: SliceApiTrans<
|
|
167
|
+
[K in keyof DictSliceShape<Slice>]: SliceApiTrans<T, K & string, DictArgNames<DictSliceShape<Slice>[K]>>;
|
|
108
168
|
}>;
|
|
109
169
|
error: { [K in ErrorKey]: Trans };
|
|
110
170
|
} & { [K in EtcKey]: Trans };
|
|
111
|
-
export type ModelTranslatorKey<
|
|
112
|
-
T extends string,
|
|
113
|
-
Model,
|
|
114
|
-
Insight,
|
|
115
|
-
Filter,
|
|
116
|
-
Slice extends { [key: string]: SliceInfo },
|
|
117
|
-
Endpoint extends { [key: string]: EndpointInfo },
|
|
118
|
-
EtcKey extends string,
|
|
119
|
-
> =
|
|
171
|
+
export type ModelTranslatorKey<T extends string, Model, Insight, Filter, Slice, Endpoint, EtcKey extends string> =
|
|
120
172
|
| `${T}.modelName`
|
|
121
173
|
| `${T}.modelDesc`
|
|
122
174
|
| `${T}.${keyof GetStateObject<Model> & string}${"" | ".desc"}`
|
|
123
175
|
| `${T}.insight.${keyof GetStateObject<Insight> & string}${"" | ".desc"}`
|
|
124
176
|
| `${T}.query.${FilterTranslatorKey<Filter>}`
|
|
125
177
|
| `${T}.sort.${keyof DictFilterSort<Filter> & string}${"" | ".desc"}`
|
|
126
|
-
| `${T}.signal.${EndpointTranslatorKey<Endpoint> | SliceTranslatorKey<Slice>}`
|
|
178
|
+
| `${T}.signal.${EndpointTranslatorKey<Endpoint> | SliceTranslatorKey<T, Slice>}`
|
|
127
179
|
| `${T}.${EtcKey}`;
|
|
128
180
|
|
|
129
181
|
export type ScalarTrans<_T extends string, Model, ErrorKey extends string, EtcKey extends string> = {
|
|
@@ -138,22 +190,15 @@ export type ScalarTranslatorKey<T extends string, Model, EtcKey extends string>
|
|
|
138
190
|
| `${T}.${keyof GetStateObject<Model> & string}${"" | ".desc"}`
|
|
139
191
|
| `${T}.${EtcKey}`;
|
|
140
192
|
|
|
141
|
-
export type ServiceTrans<
|
|
142
|
-
_T extends string,
|
|
143
|
-
Endpoint extends { [key: string]: EndpointInfo },
|
|
144
|
-
ErrorKey extends string,
|
|
145
|
-
EtcKey extends string,
|
|
146
|
-
> = {
|
|
193
|
+
export type ServiceTrans<_T extends string, Endpoint, ErrorKey extends string, EtcKey extends string> = {
|
|
147
194
|
api: {
|
|
148
|
-
[K in keyof Endpoint]: FnTrans<
|
|
195
|
+
[K in keyof DictEndpointShape<Endpoint>]: FnTrans<DictArgNames<DictEndpointShape<Endpoint>[K]>>;
|
|
149
196
|
};
|
|
150
197
|
error: { [K in ErrorKey]: Trans };
|
|
151
198
|
} & { [K in EtcKey]: Trans };
|
|
152
|
-
export type ServiceTranslatorKey<
|
|
153
|
-
T
|
|
154
|
-
|
|
155
|
-
EtcKey extends string,
|
|
156
|
-
> = `${T}.signal.${EndpointTranslatorKey<Endpoint>}` | `${T}.${EtcKey}`;
|
|
199
|
+
export type ServiceTranslatorKey<T extends string, Endpoint, EtcKey extends string> =
|
|
200
|
+
| `${T}.signal.${EndpointTranslatorKey<Endpoint>}`
|
|
201
|
+
| `${T}.${EtcKey}`;
|
|
157
202
|
|
|
158
203
|
export type EnumTrans<EnumValue extends string | number> = {
|
|
159
204
|
[key in EnumValue]: Trans;
|
|
@@ -174,8 +219,8 @@ export const registerModelTrans = <
|
|
|
174
219
|
Model extends BaseObject,
|
|
175
220
|
Insight extends BaseInsight,
|
|
176
221
|
Filter,
|
|
177
|
-
Slice
|
|
178
|
-
Endpoint
|
|
222
|
+
Slice,
|
|
223
|
+
Endpoint,
|
|
179
224
|
ModelDict,
|
|
180
225
|
>(
|
|
181
226
|
modelDict: ModelDict,
|
|
@@ -233,7 +278,7 @@ export const registerScalarTrans = <T extends string, Model, ScalarDict>(
|
|
|
233
278
|
: never;
|
|
234
279
|
};
|
|
235
280
|
|
|
236
|
-
export const registerServiceTrans = <T extends string, Endpoint
|
|
281
|
+
export const registerServiceTrans = <T extends string, Endpoint, ServiceDict>(
|
|
237
282
|
serviceDict: ServiceDict,
|
|
238
283
|
): ServiceDict extends ServiceDictInfo<infer _Languages, infer _EndpointKey, infer ErrorKey, infer EtcKey>
|
|
239
284
|
? DictModule<ServiceTranslatorKey<T, Endpoint, EtcKey>, `${T}.error.${ErrorKey}`>
|
package/document/database.ts
CHANGED
|
@@ -1,16 +1,12 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { MergedValues, PromiseOrObject } from "akanjs/base";
|
|
2
2
|
import { Logger } from "akanjs/common";
|
|
3
3
|
import type { DocumentModel, QueryOf } from "akanjs/constant";
|
|
4
|
-
import type { CacheAdaptor } from "akanjs/service";
|
|
4
|
+
import type { CacheAdaptor, CacheSetOptions } from "akanjs/service";
|
|
5
5
|
import type { DataLoader } from "./dataLoader";
|
|
6
6
|
import type { ExtractQuery, ExtractSort, FilterInstance } from "./filterMeta";
|
|
7
7
|
import type { CRUDEventType, Mdl, SaveEventType } from "./into";
|
|
8
8
|
import type { DataInputOf, FindQueryOption, ListQueryOption } from "./types";
|
|
9
9
|
|
|
10
|
-
export interface RedisSetOptions {
|
|
11
|
-
expireAt?: Dayjs;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
10
|
export class CacheDatabase<T = unknown> {
|
|
15
11
|
private logger: Logger;
|
|
16
12
|
constructor(
|
|
@@ -19,7 +15,7 @@ export class CacheDatabase<T = unknown> {
|
|
|
19
15
|
) {
|
|
20
16
|
this.logger = new Logger(`${refName}Cache`);
|
|
21
17
|
}
|
|
22
|
-
async set(topic: string, key: string, value: string | number | Buffer, option:
|
|
18
|
+
async set(topic: string, key: string, value: string | number | Buffer, option: CacheSetOptions = {}) {
|
|
23
19
|
await this.cache.set(this.refName, `${topic}:${key}`, value, option);
|
|
24
20
|
}
|
|
25
21
|
async get<T extends string | number | Buffer>(topic: string, key: string): Promise<T | undefined> {
|
package/document/filterMeta.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Cls, MergeAllDoubleKeyOfObjects, MergeAllKeyOfTypes } from "akanjs/base";
|
|
2
|
-
import { FILTER_META } from "akanjs/base";
|
|
2
|
+
import { FILTER_DICT_SHAPE, FILTER_META } from "akanjs/base";
|
|
3
3
|
import type {
|
|
4
4
|
BaseObject,
|
|
5
5
|
ConstantFieldTypeInput,
|
|
@@ -109,6 +109,21 @@ export type FilterInstance<
|
|
|
109
109
|
query: Query;
|
|
110
110
|
sort: Sort;
|
|
111
111
|
};
|
|
112
|
+
export type FilterDictArgShape = {
|
|
113
|
+
query: { [key: string]: readonly string[] };
|
|
114
|
+
sort: { [key: string]: true };
|
|
115
|
+
};
|
|
116
|
+
export type FilterDictShape<Filter extends FilterInstance> = {
|
|
117
|
+
query: {
|
|
118
|
+
[K in keyof Filter["query"]]: Filter["query"][K] extends FilterInfo<infer ArgNames, infer _Args, infer _Model>
|
|
119
|
+
? ArgNames
|
|
120
|
+
: never;
|
|
121
|
+
};
|
|
122
|
+
sort: { [K in keyof Filter["sort"]]: true };
|
|
123
|
+
};
|
|
124
|
+
export interface FilterDictShapeCarrier<DictShape extends FilterDictArgShape = FilterDictArgShape> {
|
|
125
|
+
readonly [FILTER_DICT_SHAPE]: DictShape;
|
|
126
|
+
}
|
|
112
127
|
interface BaseQuery<Model> {
|
|
113
128
|
any: FilterInfo<[], [], Model>;
|
|
114
129
|
}
|
|
@@ -140,8 +155,9 @@ export type ExtractQuery<Filter extends FilterInstance> = {
|
|
|
140
155
|
};
|
|
141
156
|
export type ExtractSort<Filter extends FilterInstance> = keyof Filter["sort"];
|
|
142
157
|
export interface FilterCls<Filter extends FilterInstance = any, Query = unknown, Sort = unknown>
|
|
143
|
-
extends Cls<{ [key: string]:
|
|
158
|
+
extends Cls<FilterDictShapeCarrier<FilterDictShape<Filter>> & { [key: string]: unknown }> {
|
|
144
159
|
[FILTER_META]: Filter;
|
|
160
|
+
prototype: FilterDictShapeCarrier<FilterDictShape<Filter>> & { [key: string]: unknown };
|
|
145
161
|
sortField: Set<string>;
|
|
146
162
|
_Query: Query;
|
|
147
163
|
_Sort: Sort;
|
package/package.json
CHANGED
package/service/injectInfo.ts
CHANGED
|
@@ -16,7 +16,7 @@ import type {
|
|
|
16
16
|
SliceCls,
|
|
17
17
|
} from "akanjs/signal";
|
|
18
18
|
import type { Adaptor, AdaptorCls, Service, ServiceCls } from ".";
|
|
19
|
-
import type { CacheAdaptor } from "./predefinedAdaptor";
|
|
19
|
+
import type { CacheAdaptor, CacheSetOptions } from "./predefinedAdaptor";
|
|
20
20
|
|
|
21
21
|
export type InjectType = "database" | "service" | "use" | "signal" | "plug" | "env" | "memory";
|
|
22
22
|
|
|
@@ -29,6 +29,7 @@ interface InjectBuilderOptions<ReturnType> {
|
|
|
29
29
|
local?: boolean;
|
|
30
30
|
default?: unknown;
|
|
31
31
|
isMap?: boolean;
|
|
32
|
+
cacheOption?: CacheSetOptions;
|
|
32
33
|
parentRefName: string;
|
|
33
34
|
}
|
|
34
35
|
|
|
@@ -99,6 +100,7 @@ export class InjectInfo<
|
|
|
99
100
|
readonly adaptor?: AdaptorCls;
|
|
100
101
|
readonly default?: unknown;
|
|
101
102
|
readonly isMap?: boolean;
|
|
103
|
+
readonly cacheOption?: CacheSetOptions;
|
|
102
104
|
readonly parentRefName: string;
|
|
103
105
|
constructor(type: Type, options: InjectBuilderOptions<ReturnType>) {
|
|
104
106
|
this.type = type;
|
|
@@ -110,6 +112,7 @@ export class InjectInfo<
|
|
|
110
112
|
this.set = options.set;
|
|
111
113
|
this.default = options.default;
|
|
112
114
|
this.isMap = options.isMap ?? false;
|
|
115
|
+
this.cacheOption = options.cacheOption;
|
|
113
116
|
this.parentRefName = options.parentRefName;
|
|
114
117
|
}
|
|
115
118
|
static async resolveInjection(
|
|
@@ -261,9 +264,9 @@ export class InjectInfo<
|
|
|
261
264
|
const value = await cacheAdaptor.hget(topic, propKey, key);
|
|
262
265
|
return value === undefined || value === null ? undefined : getter(value);
|
|
263
266
|
};
|
|
264
|
-
const set = async (key: string, value: unknown) => {
|
|
267
|
+
const set = async (key: string, value: unknown, option?: CacheSetOptions) => {
|
|
265
268
|
const setValue = setter(value);
|
|
266
|
-
await cacheAdaptor.hset(topic, propKey, key, setValue);
|
|
269
|
+
await cacheAdaptor.hset(topic, propKey, key, setValue, option ?? injectInfo.cacheOption);
|
|
267
270
|
};
|
|
268
271
|
Object.defineProperty(instance, propKey, {
|
|
269
272
|
value: {
|
|
@@ -272,17 +275,21 @@ export class InjectInfo<
|
|
|
272
275
|
delete: async (key: string) => {
|
|
273
276
|
await cacheAdaptor.hdelete(topic, propKey, key);
|
|
274
277
|
},
|
|
275
|
-
getOrInsert: async (key: string, value: unknown) => {
|
|
278
|
+
getOrInsert: async (key: string, value: unknown, option?: CacheSetOptions) => {
|
|
276
279
|
const existingValue = await get(key);
|
|
277
280
|
if (existingValue !== undefined) return existingValue;
|
|
278
|
-
await set(key, value);
|
|
281
|
+
await set(key, value, option);
|
|
279
282
|
return value;
|
|
280
283
|
},
|
|
281
|
-
getOrInsertComputed: async (
|
|
284
|
+
getOrInsertComputed: async (
|
|
285
|
+
key: string,
|
|
286
|
+
compute: (key: string) => unknown | Promise<unknown>,
|
|
287
|
+
option?: CacheSetOptions,
|
|
288
|
+
) => {
|
|
282
289
|
const existingValue = await get(key);
|
|
283
290
|
if (existingValue !== undefined) return existingValue;
|
|
284
291
|
const value = await compute(key);
|
|
285
|
-
await set(key, value);
|
|
292
|
+
await set(key, value, option);
|
|
286
293
|
return value;
|
|
287
294
|
},
|
|
288
295
|
keys: async () => await cacheAdaptor.hkeys(topic, propKey),
|
|
@@ -306,10 +313,10 @@ export class InjectInfo<
|
|
|
306
313
|
const value = await cacheAdaptor.get("akan:memory", propKey);
|
|
307
314
|
return value === null ? value : getter(value);
|
|
308
315
|
},
|
|
309
|
-
set: async (value: unknown) => {
|
|
316
|
+
set: async (value: unknown, option?: CacheSetOptions) => {
|
|
310
317
|
const setter = injectInfo.set as unknown as (value: unknown) => string | number | Buffer;
|
|
311
318
|
const setValue = setter(value);
|
|
312
|
-
await cacheAdaptor.set("akan:memory", propKey, setValue);
|
|
319
|
+
await cacheAdaptor.set("akan:memory", propKey, setValue, option ?? injectInfo.cacheOption);
|
|
313
320
|
},
|
|
314
321
|
delete: async () => {
|
|
315
322
|
await cacheAdaptor.delete("akan:memory", propKey);
|
|
@@ -362,6 +369,7 @@ export const injectionBuilder = (parentRefName: string) => ({
|
|
|
362
369
|
local?: Local;
|
|
363
370
|
default?: DefaultValue;
|
|
364
371
|
of?: MapValue;
|
|
372
|
+
expireAt?: CacheSetOptions["expireAt"];
|
|
365
373
|
get?: GetFn;
|
|
366
374
|
set?: (value: ReturnType<GetFn>) => GetFieldValue<ValueRef, ExplicitType>;
|
|
367
375
|
} = {},
|
|
@@ -385,19 +393,24 @@ export const injectionBuilder = (parentRefName: string) => ({
|
|
|
385
393
|
: MapConstructor extends ValueRef
|
|
386
394
|
? {
|
|
387
395
|
get: (key: string) => Promise<MapFieldValue | undefined>;
|
|
388
|
-
set: (key: string, value: MapFieldValue) => Promise<void>;
|
|
396
|
+
set: (key: string, value: MapFieldValue, option?: CacheSetOptions) => Promise<void>;
|
|
389
397
|
delete: (key: string) => Promise<void>;
|
|
390
|
-
getOrInsert: (key: string, value: MapFieldValue) => Promise<MapFieldValue>;
|
|
398
|
+
getOrInsert: (key: string, value: MapFieldValue, option?: CacheSetOptions) => Promise<MapFieldValue>;
|
|
391
399
|
getOrInsertComputed: (
|
|
392
400
|
key: string,
|
|
393
401
|
compute: (key: string) => MapFieldValue | Promise<MapFieldValue>,
|
|
402
|
+
option?: CacheSetOptions,
|
|
394
403
|
) => Promise<MapFieldValue>;
|
|
395
404
|
keys: () => Promise<string[]>;
|
|
396
405
|
entries: () => Promise<[string, MapFieldValue][]>;
|
|
397
406
|
forEach: (callback: (value: MapFieldValue, key: string) => void | Promise<void>) => Promise<void>;
|
|
398
407
|
clear: () => Promise<void>;
|
|
399
408
|
}
|
|
400
|
-
: {
|
|
409
|
+
: {
|
|
410
|
+
get: () => Promise<UseValue>;
|
|
411
|
+
set: (value: UseValue, option?: CacheSetOptions) => Promise<void>;
|
|
412
|
+
delete: () => Promise<void>;
|
|
413
|
+
},
|
|
401
414
|
never,
|
|
402
415
|
ValueRef
|
|
403
416
|
>("memory", {
|
|
@@ -416,6 +429,7 @@ export const injectionBuilder = (parentRefName: string) => ({
|
|
|
416
429
|
},
|
|
417
430
|
default: opts.default as unknown,
|
|
418
431
|
isMap,
|
|
432
|
+
cacheOption: opts.expireAt ? { expireAt: opts.expireAt } : undefined,
|
|
419
433
|
parentRefName,
|
|
420
434
|
});
|
|
421
435
|
},
|
|
@@ -2,8 +2,12 @@ import type { BaseEnv, Dayjs, SshOptions } from "akanjs/base";
|
|
|
2
2
|
import type { Redis } from "ioredis";
|
|
3
3
|
import { adapt } from "../adapt";
|
|
4
4
|
|
|
5
|
+
export interface CacheSetOptions {
|
|
6
|
+
expireAt?: Dayjs;
|
|
7
|
+
}
|
|
8
|
+
|
|
5
9
|
export interface CacheAdaptor {
|
|
6
|
-
set(topic: string, key: string, value: string | number | Buffer, option?:
|
|
10
|
+
set(topic: string, key: string, value: string | number | Buffer, option?: CacheSetOptions): Promise<void>;
|
|
7
11
|
get<T extends string | number | Buffer>(topic: string, key: string): Promise<T | undefined>;
|
|
8
12
|
delete(topic: string, key: string): Promise<void>;
|
|
9
13
|
getClient?(): Redis;
|
|
@@ -12,7 +16,7 @@ export interface CacheAdaptor {
|
|
|
12
16
|
key: string,
|
|
13
17
|
subKey: string,
|
|
14
18
|
value: string | number | Buffer,
|
|
15
|
-
option?:
|
|
19
|
+
option?: CacheSetOptions,
|
|
16
20
|
): Promise<void>;
|
|
17
21
|
hget<T extends string | number | Buffer>(topic: string, key: string, subKey: string): Promise<T | undefined>;
|
|
18
22
|
hdelete(topic: string, key: string, subKey: string): Promise<void>;
|
|
@@ -63,12 +67,7 @@ export class RedisCache
|
|
|
63
67
|
}))
|
|
64
68
|
implements CacheAdaptor
|
|
65
69
|
{
|
|
66
|
-
async set(
|
|
67
|
-
topic: string,
|
|
68
|
-
key: string,
|
|
69
|
-
value: string | number | Buffer,
|
|
70
|
-
option: { expireAt?: Dayjs } = {},
|
|
71
|
-
): Promise<void> {
|
|
70
|
+
async set(topic: string, key: string, value: string | number | Buffer, option: CacheSetOptions = {}): Promise<void> {
|
|
72
71
|
const expireTime = option.expireAt?.toDate().getTime();
|
|
73
72
|
if (expireTime) await this.redis.set(`${topic}:${key}`, value, "PXAT", expireTime);
|
|
74
73
|
else await this.redis.set(`${topic}:${key}`, value);
|
|
@@ -85,7 +84,7 @@ export class RedisCache
|
|
|
85
84
|
key: string,
|
|
86
85
|
subKey: string,
|
|
87
86
|
value: string | number | Buffer,
|
|
88
|
-
option?:
|
|
87
|
+
option?: CacheSetOptions,
|
|
89
88
|
): Promise<void> {
|
|
90
89
|
const expireTime = option?.expireAt?.toDate().getTime();
|
|
91
90
|
const redisKey = `${topic}:${key}`;
|