@learncard/core 9.4.23 → 9.4.25
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/core.cjs.development.cjs.map +2 -2
- package/dist/core.cjs.production.min.cjs.map +2 -2
- package/dist/core.esm.js.map +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/types/LearnCard.d.ts.map +1 -1
- package/dist/wallet/base/helpers.d.ts.map +1 -1
- package/dist/wallet/base/wallet.d.ts.map +1 -1
- package/dist/wallet/plugins/test-cache/types.d.ts.map +1 -1
- package/dist/wallet/plugins/test-index/types.d.ts.map +1 -1
- package/dist/wallet/plugins/test-storage/types.d.ts.map +1 -1
- package/package.json +60 -58
- package/src/index.ts +8 -0
- package/src/polyfills.ts +22 -0
- package/src/types/LearnCard.ts +7 -0
- package/src/types/global.d.ts +4 -0
- package/src/types/helpers.ts +4 -0
- package/src/types/planes.ts +212 -0
- package/src/types/utilities.ts +39 -0
- package/src/types/wallet.ts +176 -0
- package/src/wallet/base/crypto.ts +5 -0
- package/src/wallet/base/helpers.ts +73 -0
- package/src/wallet/base/index.ts +2 -0
- package/src/wallet/base/wallet.ts +832 -0
- package/src/wallet/plugins/index.ts +3 -0
- package/src/wallet/plugins/test-cache/index.ts +67 -0
- package/src/wallet/plugins/test-cache/types.ts +3 -0
- package/src/wallet/plugins/test-index/index.ts +37 -0
- package/src/wallet/plugins/test-index/types.ts +3 -0
- package/src/wallet/plugins/test-storage/index.ts +82 -0
- package/src/wallet/plugins/test-storage/types.ts +3 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CredentialRecord,
|
|
3
|
+
StoredCredentialEnvelope,
|
|
4
|
+
VC,
|
|
5
|
+
VP,
|
|
6
|
+
JWKWithPrivateKey,
|
|
7
|
+
} from '@learncard/types';
|
|
8
|
+
import { Query } from 'sift';
|
|
9
|
+
import { Plugin } from './wallet';
|
|
10
|
+
import { OmitNevers } from './helpers';
|
|
11
|
+
import { DeepPartial } from './utilities';
|
|
12
|
+
|
|
13
|
+
export type CacheStrategy = 'cache-only' | 'cache-first' | 'skip-cache';
|
|
14
|
+
|
|
15
|
+
export type PlaneOptions = {
|
|
16
|
+
cache?: CacheStrategy;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export type ControlPlane = 'read' | 'store' | 'index' | 'cache' | 'id' | 'context';
|
|
20
|
+
|
|
21
|
+
export type FilterForPlane<Plugins extends Plugin[], Plane extends ControlPlane> = [
|
|
22
|
+
Plugins
|
|
23
|
+
] extends [1 & Plugins]
|
|
24
|
+
? any
|
|
25
|
+
: {
|
|
26
|
+
[Index in keyof Plugins]: undefined extends Plugins[Index][Plane]
|
|
27
|
+
? never
|
|
28
|
+
: Plugins[Index]['name'];
|
|
29
|
+
}[number];
|
|
30
|
+
|
|
31
|
+
export type GetPlanesForPlugins<Plugins extends Plugin[]> = any[] extends Plugins
|
|
32
|
+
? never
|
|
33
|
+
: {
|
|
34
|
+
[Index in keyof Plugins]: {
|
|
35
|
+
[Key in ControlPlane]: undefined extends Plugins[Index][Key] ? never : Key;
|
|
36
|
+
}[ControlPlane];
|
|
37
|
+
}[number];
|
|
38
|
+
|
|
39
|
+
export type GetPlaneProviders<
|
|
40
|
+
Plugins extends Plugin[],
|
|
41
|
+
Plane extends ControlPlane
|
|
42
|
+
> = any[] extends Plugins
|
|
43
|
+
? any
|
|
44
|
+
: {
|
|
45
|
+
[Index in keyof Plugins]: undefined extends Plugins[Index][Plane]
|
|
46
|
+
? never
|
|
47
|
+
: OmitNevers<{
|
|
48
|
+
[Name in Plugins[number]['name']]: Name extends Plugins[Index]['name']
|
|
49
|
+
? { name: Name; displayName?: string; description?: string }
|
|
50
|
+
: never;
|
|
51
|
+
}>;
|
|
52
|
+
}[number];
|
|
53
|
+
|
|
54
|
+
// --- Read --- \\
|
|
55
|
+
|
|
56
|
+
export type ReadPlane = {
|
|
57
|
+
get: (
|
|
58
|
+
uri?: string,
|
|
59
|
+
options?: PlaneOptions
|
|
60
|
+
) => Promise<VC | VP | StoredCredentialEnvelope | undefined>;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export type PluginReadPlane = ReadPlane;
|
|
64
|
+
|
|
65
|
+
export type LearnCardReadPlane<Plugins extends Plugin[]> = ReadPlane & {
|
|
66
|
+
providers: GetPlaneProviders<Plugins, 'read'>;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// --- Store --- \\
|
|
70
|
+
|
|
71
|
+
export type EncryptionParams = {
|
|
72
|
+
recipients: string[];
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export type StorePlane = {
|
|
76
|
+
upload: (vc: VC | VP | StoredCredentialEnvelope, options?: PlaneOptions) => Promise<string>;
|
|
77
|
+
uploadMany?: (
|
|
78
|
+
vcs: Array<VC | VP | StoredCredentialEnvelope>,
|
|
79
|
+
options?: PlaneOptions
|
|
80
|
+
) => Promise<string[]>;
|
|
81
|
+
uploadEncrypted?: (
|
|
82
|
+
vc: VC | VP | StoredCredentialEnvelope,
|
|
83
|
+
params?: EncryptionParams,
|
|
84
|
+
options?: PlaneOptions
|
|
85
|
+
) => Promise<string>;
|
|
86
|
+
delete?: (uri: string, options?: PlaneOptions) => Promise<boolean>;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export type PluginStorePlane = StorePlane;
|
|
90
|
+
|
|
91
|
+
export type LearnCardStorePlane<Plugins extends Plugin[]> = Record<
|
|
92
|
+
FilterForPlane<Plugins, 'store'>,
|
|
93
|
+
StorePlane
|
|
94
|
+
> & {
|
|
95
|
+
providers: GetPlaneProviders<Plugins, 'store'>;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
// --- Index --- \\
|
|
99
|
+
|
|
100
|
+
export type IndexPlane = {
|
|
101
|
+
get: <Metadata extends Record<string, any> = Record<never, never>>(
|
|
102
|
+
query?: Partial<Query<CredentialRecord<Metadata>>>,
|
|
103
|
+
options?: PlaneOptions
|
|
104
|
+
) => Promise<CredentialRecord<Metadata>[]>;
|
|
105
|
+
getPage?: <Metadata extends Record<string, any> = Record<never, never>>(
|
|
106
|
+
query?: Partial<Query<CredentialRecord<Metadata>>>,
|
|
107
|
+
paginationOptions?: { limit?: number; cursor?: string; sort?: string },
|
|
108
|
+
options?: PlaneOptions
|
|
109
|
+
) => Promise<{ records: CredentialRecord<Metadata>[]; hasMore: boolean; cursor?: string }>;
|
|
110
|
+
getCount?: <Metadata extends Record<string, any> = Record<never, never>>(
|
|
111
|
+
query?: Partial<Query<CredentialRecord<Metadata>>>,
|
|
112
|
+
options?: PlaneOptions
|
|
113
|
+
) => Promise<number>;
|
|
114
|
+
add: <Metadata extends Record<string, any> = Record<never, never>>(
|
|
115
|
+
record: CredentialRecord<Metadata>,
|
|
116
|
+
options?: PlaneOptions
|
|
117
|
+
) => Promise<boolean>;
|
|
118
|
+
addMany?: <Metadata extends Record<string, any> = Record<never, never>>(
|
|
119
|
+
records: CredentialRecord<Metadata>[],
|
|
120
|
+
options?: PlaneOptions
|
|
121
|
+
) => Promise<boolean>;
|
|
122
|
+
update: <Metadata extends Record<string, any> = Record<never, never>>(
|
|
123
|
+
id: string,
|
|
124
|
+
updates: DeepPartial<CredentialRecord<Metadata>>,
|
|
125
|
+
options?: PlaneOptions
|
|
126
|
+
) => Promise<boolean>;
|
|
127
|
+
remove: (id: string, options?: PlaneOptions) => Promise<boolean>;
|
|
128
|
+
removeAll?: (options?: PlaneOptions) => Promise<boolean>;
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
export type PluginIndexPlane = IndexPlane;
|
|
132
|
+
|
|
133
|
+
export type LearnCardIndexPlane<Plugins extends Plugin[]> = {
|
|
134
|
+
all: Pick<IndexPlane, 'get'>;
|
|
135
|
+
providers: GetPlaneProviders<Plugins, 'index'>;
|
|
136
|
+
} & Record<FilterForPlane<Plugins, 'index'>, IndexPlane>;
|
|
137
|
+
|
|
138
|
+
// --- Cache --- \\
|
|
139
|
+
|
|
140
|
+
export type CachePlane = {
|
|
141
|
+
getIndex: <Metadata extends Record<string, any> = Record<never, never>>(
|
|
142
|
+
name: string,
|
|
143
|
+
query: Partial<Query<CredentialRecord<Metadata>>>
|
|
144
|
+
) => Promise<CredentialRecord<Metadata>[] | undefined>;
|
|
145
|
+
setIndex: <Metadata extends Record<string, any> = Record<never, never>>(
|
|
146
|
+
name: string,
|
|
147
|
+
query: Partial<Query<CredentialRecord<Metadata>>>,
|
|
148
|
+
value: CredentialRecord<Metadata>[]
|
|
149
|
+
) => Promise<boolean>;
|
|
150
|
+
getIndexPage: <Metadata extends Record<string, any> = Record<never, never>>(
|
|
151
|
+
name: string,
|
|
152
|
+
query: Partial<Query<CredentialRecord<Metadata>>>,
|
|
153
|
+
paginationOptions?: { limit?: number; cursor?: string; sort?: string }
|
|
154
|
+
) => Promise<
|
|
155
|
+
{ records: CredentialRecord<Metadata>[]; hasMore: boolean; cursor?: string } | undefined
|
|
156
|
+
>;
|
|
157
|
+
setIndexPage: <Metadata extends Record<string, any> = Record<never, never>>(
|
|
158
|
+
name: string,
|
|
159
|
+
query: Partial<Query<CredentialRecord<Metadata>>>,
|
|
160
|
+
value: { records: CredentialRecord<Metadata>[]; hasMore: boolean; cursor?: string },
|
|
161
|
+
paginationOptions?: { limit?: number; cursor?: string }
|
|
162
|
+
) => Promise<boolean>;
|
|
163
|
+
getIndexCount?: <Metadata extends Record<string, any> = Record<never, never>>(
|
|
164
|
+
name: string,
|
|
165
|
+
query: Partial<Query<CredentialRecord<Metadata>>>
|
|
166
|
+
) => Promise<number | undefined>;
|
|
167
|
+
setIndexCount?: <Metadata extends Record<string, any> = Record<never, never>>(
|
|
168
|
+
name: string,
|
|
169
|
+
query: Partial<Query<CredentialRecord<Metadata>>>,
|
|
170
|
+
value: number
|
|
171
|
+
) => Promise<boolean>;
|
|
172
|
+
flushIndex: () => Promise<boolean>;
|
|
173
|
+
getVc: (uri: string) => Promise<VC | VP | StoredCredentialEnvelope | undefined>;
|
|
174
|
+
setVc: (uri: string, value: VC | VP | StoredCredentialEnvelope | undefined) => Promise<boolean>;
|
|
175
|
+
flushVc: () => Promise<boolean>;
|
|
176
|
+
};
|
|
177
|
+
export type PluginCachePlane = CachePlane;
|
|
178
|
+
|
|
179
|
+
export type LearnCardCachePlane<Plugins extends Plugin[]> = CachePlane & {
|
|
180
|
+
providers: GetPlaneProviders<Plugins, 'cache'>;
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
// --- Identity --- \\
|
|
184
|
+
|
|
185
|
+
export type IdPlane = {
|
|
186
|
+
did: (method?: string, options?: PlaneOptions) => string;
|
|
187
|
+
keypair: (algorithm?: string, options?: PlaneOptions) => JWKWithPrivateKey;
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
export type PluginIdPlane = IdPlane;
|
|
191
|
+
|
|
192
|
+
export type LearnCardIdPlane<Plugins extends Plugin[]> = IdPlane & {
|
|
193
|
+
providers: GetPlaneProviders<Plugins, 'id'>;
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
// --- Contexts --- \\
|
|
197
|
+
|
|
198
|
+
export type ContextPlane = {
|
|
199
|
+
resolveDocument: (
|
|
200
|
+
uri: string,
|
|
201
|
+
allowRemote?: boolean
|
|
202
|
+
) => Promise<Record<string, any> | undefined>;
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
export type PluginContextPlane = {
|
|
206
|
+
resolveStaticDocument: (uri: string) => Promise<Record<string, any> | undefined>;
|
|
207
|
+
resolveRemoteDocument?: (uri: string) => Promise<Record<string, any> | undefined>;
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
export type LearnCardContextPlane<Plugins extends Plugin[]> = ContextPlane & {
|
|
211
|
+
providers: GetPlaneProviders<Plugins, 'context'>;
|
|
212
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/** @group Utility Types */
|
|
2
|
+
export type Tail<T extends any[]> = T extends [any, ...infer R] ? R : never;
|
|
3
|
+
|
|
4
|
+
/** @group Utility Types */
|
|
5
|
+
export type Last<T extends any[]> = T extends [...any[], infer R] ? R : never;
|
|
6
|
+
|
|
7
|
+
/** @group Utility Types */
|
|
8
|
+
export type RemoveLast<T extends any[]> = T extends [...infer R, any] ? R : [];
|
|
9
|
+
|
|
10
|
+
/** @group Utility Types */
|
|
11
|
+
export type RemoveFirstArg<T extends (...args: any[]) => any> = (
|
|
12
|
+
args: Tail<Parameters<T>>
|
|
13
|
+
) => ReturnType<T>;
|
|
14
|
+
|
|
15
|
+
/** @group Utility Types */
|
|
16
|
+
export type RemoveLastArg<T extends (...args: any[]) => any> = (
|
|
17
|
+
args: RemoveLast<Parameters<T>>
|
|
18
|
+
) => ReturnType<T>;
|
|
19
|
+
|
|
20
|
+
/** @group Utility Types */
|
|
21
|
+
export type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
|
|
22
|
+
k: infer I
|
|
23
|
+
) => void
|
|
24
|
+
? I
|
|
25
|
+
: never;
|
|
26
|
+
|
|
27
|
+
/** @group Utility Types */
|
|
28
|
+
export type MergeObjects<Objects extends Record<string, any>[]> = undefined extends Objects[2]
|
|
29
|
+
? Omit<Objects[0], keyof Objects[1]> & Objects[1]
|
|
30
|
+
: Omit<MergeObjects<RemoveLast<Objects>>, keyof Last<Objects>> & Last<Objects>;
|
|
31
|
+
|
|
32
|
+
/** @group Utility Types */
|
|
33
|
+
export type DeepPartial<T> = T extends object
|
|
34
|
+
? {
|
|
35
|
+
[P in keyof T]?: DeepPartial<T[P]>;
|
|
36
|
+
}
|
|
37
|
+
: T;
|
|
38
|
+
|
|
39
|
+
export type IsAnyOrNever<T> = [T] extends [1 & T] ? true : false;
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ControlPlane,
|
|
3
|
+
GetPlanesForPlugins,
|
|
4
|
+
PluginReadPlane,
|
|
5
|
+
PluginStorePlane,
|
|
6
|
+
PluginIndexPlane,
|
|
7
|
+
PluginCachePlane,
|
|
8
|
+
PluginIdPlane,
|
|
9
|
+
PluginContextPlane,
|
|
10
|
+
LearnCardReadPlane,
|
|
11
|
+
LearnCardStorePlane,
|
|
12
|
+
LearnCardIndexPlane,
|
|
13
|
+
LearnCardCachePlane,
|
|
14
|
+
LearnCardIdPlane,
|
|
15
|
+
LearnCardContextPlane,
|
|
16
|
+
} from './planes';
|
|
17
|
+
import { UnionToIntersection, MergeObjects, IsAnyOrNever } from './utilities';
|
|
18
|
+
|
|
19
|
+
export type GenerateLearnCard<
|
|
20
|
+
NewControlPlanes extends ControlPlane = never,
|
|
21
|
+
NewMethods extends Record<string, (...args: any[]) => any> = Record<never, never>,
|
|
22
|
+
ControlPlanes extends ControlPlane = never,
|
|
23
|
+
Methods extends Record<string, (...args: any[]) => any> = Record<never, never>
|
|
24
|
+
> = LearnCard<
|
|
25
|
+
any,
|
|
26
|
+
IsAnyOrNever<ControlPlanes> extends true
|
|
27
|
+
? NewControlPlanes
|
|
28
|
+
: IsAnyOrNever<NewControlPlanes> extends true
|
|
29
|
+
? ControlPlanes
|
|
30
|
+
: ControlPlanes | NewControlPlanes,
|
|
31
|
+
NewMethods & Methods
|
|
32
|
+
>;
|
|
33
|
+
|
|
34
|
+
export type AddImplicitLearnCardArgument<
|
|
35
|
+
Functions extends Record<string, (...args: any[]) => any> = Record<never, never>,
|
|
36
|
+
ControlPlanes extends ControlPlane = never,
|
|
37
|
+
Methods extends Record<string, (...args: any[]) => any> = Record<never, never>,
|
|
38
|
+
DependentControlPlanes extends ControlPlane = never,
|
|
39
|
+
DependentMethods extends Record<string, (...args: any[]) => any> = Record<never, never>
|
|
40
|
+
> = {
|
|
41
|
+
[Key in keyof Functions]: <
|
|
42
|
+
T extends GenerateLearnCard<
|
|
43
|
+
ControlPlanes,
|
|
44
|
+
Methods,
|
|
45
|
+
DependentControlPlanes,
|
|
46
|
+
DependentMethods
|
|
47
|
+
>
|
|
48
|
+
>(
|
|
49
|
+
learnCard: T,
|
|
50
|
+
...args: Parameters<Functions[Key]>
|
|
51
|
+
) => ReturnType<Functions[Key]>;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/** @group Universal Wallets */
|
|
55
|
+
export type GetPluginMethods<Plugins extends Plugin[]> = undefined extends Plugins[1]
|
|
56
|
+
? NonNullable<Plugins[0]['_methods']>
|
|
57
|
+
: UnionToIntersection<
|
|
58
|
+
NonNullable<
|
|
59
|
+
MergeObjects<{ [Key in keyof Plugins]: NonNullable<Plugins[Key]['_methods']> }>
|
|
60
|
+
>
|
|
61
|
+
>;
|
|
62
|
+
|
|
63
|
+
/** @group Universal Wallets */
|
|
64
|
+
export type Plugin<
|
|
65
|
+
Name extends string = string,
|
|
66
|
+
ControlPlanes extends ControlPlane = any,
|
|
67
|
+
Methods extends Record<string, (...args: any[]) => any> = Record<never, never>,
|
|
68
|
+
DependentControlPlanes extends ControlPlane = never,
|
|
69
|
+
DependentMethods extends Record<string, (...args: any[]) => any> = Record<never, never>
|
|
70
|
+
> = {
|
|
71
|
+
name: Name;
|
|
72
|
+
displayName?: string;
|
|
73
|
+
description?: string;
|
|
74
|
+
methods: AddImplicitLearnCardArgument<
|
|
75
|
+
Methods,
|
|
76
|
+
ControlPlanes,
|
|
77
|
+
Methods,
|
|
78
|
+
DependentControlPlanes,
|
|
79
|
+
DependentMethods
|
|
80
|
+
>;
|
|
81
|
+
_methods?: Methods;
|
|
82
|
+
read?: {};
|
|
83
|
+
store?: {};
|
|
84
|
+
index?: {};
|
|
85
|
+
cache?: {};
|
|
86
|
+
id?: {};
|
|
87
|
+
context?: {};
|
|
88
|
+
} & (IsAnyOrNever<ControlPlanes> extends true
|
|
89
|
+
? {}
|
|
90
|
+
: ('read' extends ControlPlanes
|
|
91
|
+
? {
|
|
92
|
+
read: AddImplicitLearnCardArgument<
|
|
93
|
+
PluginReadPlane,
|
|
94
|
+
ControlPlanes,
|
|
95
|
+
Methods,
|
|
96
|
+
DependentControlPlanes,
|
|
97
|
+
DependentMethods
|
|
98
|
+
>;
|
|
99
|
+
}
|
|
100
|
+
: {}) &
|
|
101
|
+
('store' extends ControlPlanes
|
|
102
|
+
? {
|
|
103
|
+
store: AddImplicitLearnCardArgument<
|
|
104
|
+
PluginStorePlane,
|
|
105
|
+
ControlPlanes,
|
|
106
|
+
Methods,
|
|
107
|
+
DependentControlPlanes,
|
|
108
|
+
DependentMethods
|
|
109
|
+
>;
|
|
110
|
+
}
|
|
111
|
+
: {}) &
|
|
112
|
+
('index' extends ControlPlanes
|
|
113
|
+
? {
|
|
114
|
+
index: AddImplicitLearnCardArgument<
|
|
115
|
+
PluginIndexPlane,
|
|
116
|
+
ControlPlanes,
|
|
117
|
+
Methods,
|
|
118
|
+
DependentControlPlanes,
|
|
119
|
+
DependentMethods
|
|
120
|
+
>;
|
|
121
|
+
}
|
|
122
|
+
: {}) &
|
|
123
|
+
('cache' extends ControlPlanes
|
|
124
|
+
? {
|
|
125
|
+
cache: AddImplicitLearnCardArgument<
|
|
126
|
+
PluginCachePlane,
|
|
127
|
+
ControlPlanes,
|
|
128
|
+
Methods,
|
|
129
|
+
DependentControlPlanes,
|
|
130
|
+
DependentMethods
|
|
131
|
+
>;
|
|
132
|
+
}
|
|
133
|
+
: {}) &
|
|
134
|
+
('id' extends ControlPlanes
|
|
135
|
+
? {
|
|
136
|
+
id: AddImplicitLearnCardArgument<
|
|
137
|
+
PluginIdPlane,
|
|
138
|
+
ControlPlanes,
|
|
139
|
+
Methods,
|
|
140
|
+
DependentControlPlanes,
|
|
141
|
+
DependentMethods
|
|
142
|
+
>;
|
|
143
|
+
}
|
|
144
|
+
: {}) &
|
|
145
|
+
('context' extends ControlPlanes
|
|
146
|
+
? {
|
|
147
|
+
context: AddImplicitLearnCardArgument<
|
|
148
|
+
PluginContextPlane,
|
|
149
|
+
ControlPlanes,
|
|
150
|
+
Methods,
|
|
151
|
+
DependentControlPlanes,
|
|
152
|
+
DependentMethods
|
|
153
|
+
>;
|
|
154
|
+
}
|
|
155
|
+
: {}));
|
|
156
|
+
|
|
157
|
+
/** @group Universal Wallets */
|
|
158
|
+
export type LearnCard<
|
|
159
|
+
Plugins extends Plugin[] = [],
|
|
160
|
+
ControlPlanes extends ControlPlane = GetPlanesForPlugins<Plugins>,
|
|
161
|
+
PluginMethods = GetPluginMethods<Plugins>
|
|
162
|
+
> = {
|
|
163
|
+
plugins: Plugins;
|
|
164
|
+
invoke: PluginMethods;
|
|
165
|
+
addPlugin: <NewPlugin extends Plugin>(
|
|
166
|
+
plugin: NewPlugin
|
|
167
|
+
) => Promise<LearnCard<[...Plugins, NewPlugin]>>;
|
|
168
|
+
debug?: typeof console.log;
|
|
169
|
+
} & (IsAnyOrNever<ControlPlanes> extends true
|
|
170
|
+
? {}
|
|
171
|
+
: ('read' extends ControlPlanes ? { read: LearnCardReadPlane<Plugins> } : {}) &
|
|
172
|
+
('store' extends ControlPlanes ? { store: LearnCardStorePlane<Plugins> } : {}) &
|
|
173
|
+
('index' extends ControlPlanes ? { index: LearnCardIndexPlane<Plugins> } : {}) &
|
|
174
|
+
('cache' extends ControlPlanes ? { cache: LearnCardCachePlane<Plugins> } : {}) &
|
|
175
|
+
('id' extends ControlPlanes ? { id: LearnCardIdPlane<Plugins> } : {}) &
|
|
176
|
+
('context' extends ControlPlanes ? { context: LearnCardContextPlane<Plugins> } : {}));
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { LearnCard, Plugin } from '../../types/wallet';
|
|
2
|
+
import { ControlPlane } from '../../types/planes';
|
|
3
|
+
|
|
4
|
+
/** Type guard for removing null/undefined */
|
|
5
|
+
export const isNotNull = <T>(item?: T | null): item is T => !!item;
|
|
6
|
+
|
|
7
|
+
/** Removes null/undefined from items in an array */
|
|
8
|
+
export const filterNulls = <T>(array: (T | null | undefined)[]) => array.filter(isNotNull);
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Loops through an array, running a callback over it until that callback returns a value. Once the
|
|
12
|
+
* first value is found, it is returned. If no value is found, undefined is returned instead
|
|
13
|
+
*/
|
|
14
|
+
export const findFirstResult = <T, U>(
|
|
15
|
+
array: T[],
|
|
16
|
+
callback: (item: T) => U | undefined
|
|
17
|
+
): U | undefined => {
|
|
18
|
+
return array.reduce<U | undefined>((result, item) => {
|
|
19
|
+
if (result !== undefined) return result;
|
|
20
|
+
|
|
21
|
+
return callback(item);
|
|
22
|
+
}, undefined);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const pluginImplementsPlane = <Plane extends ControlPlane>(
|
|
26
|
+
plugin: Plugin,
|
|
27
|
+
plane: Plane
|
|
28
|
+
): plugin is Plugin<any, Plane> => {
|
|
29
|
+
if (plane === 'read') return 'get' in (plugin.read ?? {});
|
|
30
|
+
if (plane === 'store') return 'upload' in (plugin.store ?? {});
|
|
31
|
+
if (plane === 'index') return 'get' in (plugin.index ?? {});
|
|
32
|
+
if (plane === 'cache') return 'getIndex' in (plugin.cache ?? {});
|
|
33
|
+
if (plane === 'id') return 'did' in (plugin.id ?? {});
|
|
34
|
+
if (plane === 'context') return 'resolveStaticDocument' in (plugin.context ?? {});
|
|
35
|
+
|
|
36
|
+
return false;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const learnCardImplementsPlane = <Plane extends ControlPlane>(
|
|
40
|
+
learnCard: LearnCard<any, any, any>,
|
|
41
|
+
plane: Plane
|
|
42
|
+
): learnCard is LearnCard<any, Plane> => {
|
|
43
|
+
if (plane === 'read') return 'read' in learnCard;
|
|
44
|
+
if (plane === 'store') return 'store' in learnCard;
|
|
45
|
+
if (plane === 'index') return 'index' in learnCard;
|
|
46
|
+
if (plane === 'cache') return 'cache' in learnCard;
|
|
47
|
+
if (plane === 'id') return 'id' in learnCard;
|
|
48
|
+
if (plane === 'context') return 'context' in learnCard;
|
|
49
|
+
|
|
50
|
+
return false;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export const mapObject = <T extends string, U, V>(
|
|
54
|
+
obj: Record<T, U>,
|
|
55
|
+
callback: (value: U, index: number) => V
|
|
56
|
+
): Record<T, V> => {
|
|
57
|
+
return Object.fromEntries(
|
|
58
|
+
Object.entries<U>(obj).map(([key, value], index) => [key, callback(value, index)])
|
|
59
|
+
) as any;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export const isFulfilledAndNotEmpty = <T>(
|
|
63
|
+
input: PromiseSettledResult<T>
|
|
64
|
+
): input is PromiseFulfilledResult<T> => input.status === 'fulfilled' && !!input.value;
|
|
65
|
+
|
|
66
|
+
export const uniqBy = <Obj extends Record<string, any>>(
|
|
67
|
+
array: Obj[],
|
|
68
|
+
key: keyof Obj | ((obj: Obj) => any)
|
|
69
|
+
) => {
|
|
70
|
+
return [
|
|
71
|
+
...new Map(array.map(obj => [key instanceof Function ? key(obj) : obj[key], obj])).values(),
|
|
72
|
+
];
|
|
73
|
+
};
|