@learncard/idx-plugin 1.1.24 → 1.1.26
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 +12 -7
- package/dist/idx-plugin.cjs.development.cjs +3982 -2307
- package/dist/idx-plugin.cjs.development.cjs.map +4 -4
- package/dist/idx-plugin.cjs.production.min.cjs +64 -36
- package/dist/idx-plugin.cjs.production.min.cjs.map +4 -4
- package/dist/idx-plugin.esm.js +3982 -2307
- package/dist/idx-plugin.esm.js.map +4 -4
- package/package.json +62 -60
- package/src/defaults.ts +18 -0
- package/src/idx.ts +260 -0
- package/src/index.ts +5 -0
- package/src/types.ts +88 -0
package/package.json
CHANGED
|
@@ -1,61 +1,63 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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
|
-
}
|
|
2
|
+
"name": "@learncard/idx-plugin",
|
|
3
|
+
"version": "1.1.26",
|
|
4
|
+
"description": "",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/idx-plugin.esm.js",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"development": "./src/index.ts",
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"default": "./dist/idx-plugin.esm.js"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "./dist/index.d.cts",
|
|
17
|
+
"default": "./dist/index.cjs"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist",
|
|
23
|
+
"src"
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "node ./scripts/build.mjs && shx cp ./scripts/mixedEntypoint.js ./dist/index.cjs && tsc --p tsconfig.json && shx cp ./dist/index.d.ts ./dist/index.d.cts",
|
|
27
|
+
"test": "jest --passWithNoTests",
|
|
28
|
+
"test:watch": "jest --watch",
|
|
29
|
+
"test:coverage": "jest --silent --ci --coverage --coverageReporters=\"text\" --coverageReporters=\"text-summary\""
|
|
30
|
+
},
|
|
31
|
+
"author": "Learning Economy Foundation (www.learningeconomy.io)",
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"homepage": "https://github.com/learningeconomy/LearnCard/tree/main/packages/plugins/idx/README.md",
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "https://github.com/learningeconomy/LearnCard"
|
|
37
|
+
},
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://github.com/learningeconomy/LearnCard/issues"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@glazed/types": "0.2.0",
|
|
43
|
+
"@types/jest": "^29.2.2",
|
|
44
|
+
"@types/node": "^17.0.31",
|
|
45
|
+
"aqu": "0.4.3",
|
|
46
|
+
"esbuild": "^0.27.1",
|
|
47
|
+
"esbuild-jest": "^0.5.0",
|
|
48
|
+
"esbuild-plugin-copy": "^1.3.0",
|
|
49
|
+
"jest": "^29.3.0",
|
|
50
|
+
"shx": "^0.3.4",
|
|
51
|
+
"ts-jest": "^29.0.3"
|
|
52
|
+
},
|
|
53
|
+
"types": "./dist/index.d.ts",
|
|
54
|
+
"dependencies": {
|
|
55
|
+
"@ceramicnetwork/http-client": "2.7.0",
|
|
56
|
+
"@ceramicnetwork/streamid": "2.7.0",
|
|
57
|
+
"@glazed/did-datastore": "0.3.2",
|
|
58
|
+
"@learncard/ceramic-plugin": "^1.1.26",
|
|
59
|
+
"@learncard/core": "9.4.26",
|
|
60
|
+
"@learncard/types": "5.17.5"
|
|
61
|
+
},
|
|
62
|
+
"sideEffects": false
|
|
63
|
+
}
|
package/src/defaults.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { IDXArgs } from './types';
|
|
2
|
+
|
|
3
|
+
export const DEFAULT_IDX_ARGS: IDXArgs = {
|
|
4
|
+
modelData: {
|
|
5
|
+
definitions: {
|
|
6
|
+
MyVerifiableCredentials:
|
|
7
|
+
'kjzl6cwe1jw14am5tu5hh412s19o4zm8aq3g2lpd6s4paxj2nly2lj4drp3pun2',
|
|
8
|
+
},
|
|
9
|
+
schemas: {
|
|
10
|
+
AchievementVerifiableCredential:
|
|
11
|
+
'ceramic://k3y52l7qbv1frylibw2725v8gem3hxs1onoh6pvux0szdduugczh0hddxo6qsd6o0',
|
|
12
|
+
VerifiableCredentialsList:
|
|
13
|
+
'ceramic://k3y52l7qbv1frxkcwfpyauky3fyl4n44izridy3blvjjzgftis40sk9w8g3remghs',
|
|
14
|
+
},
|
|
15
|
+
tiles: {},
|
|
16
|
+
},
|
|
17
|
+
credentialAlias: 'MyVerifiableCredentials',
|
|
18
|
+
};
|
package/src/idx.ts
ADDED
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import { DIDDataStore } from '@glazed/did-datastore';
|
|
2
|
+
import { CredentialRecordValidator, VC, CredentialRecord, VCValidator } from '@learncard/types';
|
|
3
|
+
import { LearnCard } from '@learncard/core';
|
|
4
|
+
|
|
5
|
+
import { streamIdToCeramicURI } from '@learncard/ceramic-plugin';
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
IDXPlugin,
|
|
9
|
+
CredentialsList,
|
|
10
|
+
CredentialsListValidator,
|
|
11
|
+
IDXPluginDependentMethods,
|
|
12
|
+
IDXArgs,
|
|
13
|
+
BackwardsCompatCredentialsListValidator,
|
|
14
|
+
} from './types';
|
|
15
|
+
import { DEFAULT_IDX_ARGS } from './defaults';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @group Plugins
|
|
19
|
+
*/
|
|
20
|
+
export const getIDXPlugin = async (
|
|
21
|
+
learnCard: LearnCard<any, 'read', IDXPluginDependentMethods>,
|
|
22
|
+
{ modelData, credentialAlias }: IDXArgs = DEFAULT_IDX_ARGS
|
|
23
|
+
): Promise<IDXPlugin> => {
|
|
24
|
+
const ceramic = learnCard.invoke.getCeramicClient();
|
|
25
|
+
|
|
26
|
+
const dataStore = new DIDDataStore({ ceramic, model: modelData });
|
|
27
|
+
|
|
28
|
+
const getCredentialsListFromIdx = async (alias = credentialAlias): Promise<CredentialsList> => {
|
|
29
|
+
const list = await dataStore.get(alias);
|
|
30
|
+
|
|
31
|
+
if (!list) return { credentials: [] };
|
|
32
|
+
|
|
33
|
+
const validationResult = await CredentialsListValidator.spa(list);
|
|
34
|
+
|
|
35
|
+
if (validationResult.success) return validationResult.data;
|
|
36
|
+
|
|
37
|
+
const backwardsCompatValidationResult = await BackwardsCompatCredentialsListValidator.spa(
|
|
38
|
+
list
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
if (backwardsCompatValidationResult.success) {
|
|
42
|
+
const oldCreds = backwardsCompatValidationResult.data.credentials;
|
|
43
|
+
|
|
44
|
+
const newCreds = oldCreds.map(cred => {
|
|
45
|
+
if ('uri' in cred) return cred as CredentialRecord;
|
|
46
|
+
|
|
47
|
+
const { title, id, storageType, ...rest } = cred;
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
...rest,
|
|
51
|
+
id: title,
|
|
52
|
+
uri: `lc:ceramic:${id.replace('ceramic://', '')}`,
|
|
53
|
+
} as CredentialRecord;
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const credentialsList = { credentials: newCreds };
|
|
57
|
+
|
|
58
|
+
await dataStore.set(credentialAlias, credentialsList);
|
|
59
|
+
|
|
60
|
+
return credentialsList;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
console.error(validationResult.error);
|
|
64
|
+
|
|
65
|
+
throw new Error('Invalid credentials list stored in IDX');
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const removeCredentialFromIdx = async (id: string, alias?: string) => {
|
|
69
|
+
if (!id) throw new Error('Must provide id to remove');
|
|
70
|
+
|
|
71
|
+
if (!alias) alias = credentialAlias;
|
|
72
|
+
|
|
73
|
+
const existing = await getCredentialsListFromIdx(alias);
|
|
74
|
+
|
|
75
|
+
existing.credentials = existing.credentials.filter(credential => credential.id !== id);
|
|
76
|
+
|
|
77
|
+
return dataStore.set(alias, existing);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const removeAllCredentialsFromIdx = async (alias?: string) => {
|
|
81
|
+
if (!alias) alias = credentialAlias;
|
|
82
|
+
|
|
83
|
+
return dataStore.set(alias, { credentials: [] });
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const addCredentialInIdx = async <T extends Record<string, any>>(
|
|
87
|
+
_record: CredentialRecord<T>
|
|
88
|
+
) => {
|
|
89
|
+
const record = await CredentialRecordValidator.parseAsync(_record);
|
|
90
|
+
|
|
91
|
+
if (!record) throw new Error('record is required');
|
|
92
|
+
|
|
93
|
+
if (!record.uri) throw Error('No URI provided');
|
|
94
|
+
|
|
95
|
+
// Make sure URI can be resolved
|
|
96
|
+
await learnCard.read.get(record.uri);
|
|
97
|
+
|
|
98
|
+
const existing = await getCredentialsListFromIdx(credentialAlias);
|
|
99
|
+
|
|
100
|
+
const indexOfExistingCredential = existing.credentials.findIndex(credential => {
|
|
101
|
+
return credential.id === record.id;
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
if (indexOfExistingCredential > -1) {
|
|
105
|
+
existing.credentials[indexOfExistingCredential] = record;
|
|
106
|
+
} else existing.credentials.push(record);
|
|
107
|
+
|
|
108
|
+
return streamIdToCeramicURI(await dataStore.set(credentialAlias, existing));
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
const addCredentialsInIdx = async <T extends Record<string, any>>(
|
|
112
|
+
_records: CredentialRecord<T>[]
|
|
113
|
+
) => {
|
|
114
|
+
const records = CredentialRecordValidator.array().parse(_records);
|
|
115
|
+
|
|
116
|
+
const existing = await getCredentialsListFromIdx(credentialAlias);
|
|
117
|
+
|
|
118
|
+
await Promise.all(
|
|
119
|
+
records.map(async record => {
|
|
120
|
+
// Make sure URI can be resolved
|
|
121
|
+
await learnCard.read.get(record.uri);
|
|
122
|
+
|
|
123
|
+
const indexOfExistingCredential = existing.credentials.findIndex(credential => {
|
|
124
|
+
return credential.id === record.id;
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
if (indexOfExistingCredential > -1) {
|
|
128
|
+
existing.credentials[indexOfExistingCredential] = record;
|
|
129
|
+
} else existing.credentials.push(record);
|
|
130
|
+
})
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
return streamIdToCeramicURI(await dataStore.set(credentialAlias, existing));
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
return {
|
|
137
|
+
name: 'IDX',
|
|
138
|
+
displayName: 'IDX',
|
|
139
|
+
description: 'Stores a bespoke index of credentials for an individual based on their did',
|
|
140
|
+
index: {
|
|
141
|
+
get: async _learnCard => {
|
|
142
|
+
_learnCard.debug?.('learnCard.index.IDX.get');
|
|
143
|
+
|
|
144
|
+
const list = await getCredentialsListFromIdx();
|
|
145
|
+
|
|
146
|
+
return list.credentials;
|
|
147
|
+
},
|
|
148
|
+
add: async (_learnCard, record) => {
|
|
149
|
+
_learnCard.debug?.('learnCard.index.IDX.add');
|
|
150
|
+
|
|
151
|
+
try {
|
|
152
|
+
await addCredentialInIdx(record);
|
|
153
|
+
|
|
154
|
+
return true;
|
|
155
|
+
} catch (error) {
|
|
156
|
+
console.error('Error adding credential with IDX:', error);
|
|
157
|
+
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
addMany: async (_learnCard, records) => {
|
|
162
|
+
_learnCard.debug?.('learnCard.index.IDX.add');
|
|
163
|
+
|
|
164
|
+
try {
|
|
165
|
+
await addCredentialsInIdx(records);
|
|
166
|
+
|
|
167
|
+
return true;
|
|
168
|
+
} catch (error) {
|
|
169
|
+
console.error('Error adding credential with IDX:', error);
|
|
170
|
+
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
update: async _learnCard => {
|
|
175
|
+
_learnCard.debug?.('learnCard.index.IDX.update');
|
|
176
|
+
|
|
177
|
+
// TODO: Implement update
|
|
178
|
+
return false;
|
|
179
|
+
},
|
|
180
|
+
remove: async (_learnCard, id) => {
|
|
181
|
+
_learnCard.debug?.('learnCard.index.IDX.remove');
|
|
182
|
+
|
|
183
|
+
try {
|
|
184
|
+
await removeCredentialFromIdx(id);
|
|
185
|
+
|
|
186
|
+
return true;
|
|
187
|
+
} catch (error) {
|
|
188
|
+
console.error('Error removing credential from IDX:', error);
|
|
189
|
+
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
removeAll: async _learnCard => {
|
|
194
|
+
_learnCard.debug?.('learnCard.index.IDX.removeAll');
|
|
195
|
+
|
|
196
|
+
try {
|
|
197
|
+
await removeAllCredentialsFromIdx();
|
|
198
|
+
|
|
199
|
+
return true;
|
|
200
|
+
} catch (error) {
|
|
201
|
+
console.error('Error removing credentials from IDX:', error);
|
|
202
|
+
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
methods: {
|
|
208
|
+
getCredentialsListFromIdx: async (_learnCard, alias = credentialAlias) =>
|
|
209
|
+
(await getCredentialsListFromIdx(alias)).credentials,
|
|
210
|
+
getVerifiableCredentialFromIdx: async (_learnCard, id) => {
|
|
211
|
+
const credentialList = await getCredentialsListFromIdx();
|
|
212
|
+
const credential = credentialList?.credentials?.find(cred => cred?.id === id);
|
|
213
|
+
|
|
214
|
+
const result = _learnCard.read.get(credential?.uri);
|
|
215
|
+
|
|
216
|
+
const validationResult = await VCValidator.safeParseAsync(result);
|
|
217
|
+
|
|
218
|
+
return validationResult.success ? validationResult.data : undefined;
|
|
219
|
+
},
|
|
220
|
+
getVerifiableCredentialsFromIdx: async _learnCard => {
|
|
221
|
+
const credentialList = await getCredentialsListFromIdx();
|
|
222
|
+
const uris = credentialList?.credentials?.map(credential => credential?.uri) ?? [];
|
|
223
|
+
|
|
224
|
+
return (await Promise.all(uris.map(async uri => _learnCard.read.get(uri)))).filter(
|
|
225
|
+
(vc): vc is VC => !!vc
|
|
226
|
+
);
|
|
227
|
+
},
|
|
228
|
+
addVerifiableCredentialInIdx: async (_learnCard, idxCredential) => {
|
|
229
|
+
const record = CredentialRecordValidator.parse(idxCredential);
|
|
230
|
+
|
|
231
|
+
if (!record) throw new Error('record is required');
|
|
232
|
+
|
|
233
|
+
if (!record.uri) throw Error('No URI provided');
|
|
234
|
+
|
|
235
|
+
// Make sure URI can be resolved
|
|
236
|
+
await _learnCard.read.get(record.uri);
|
|
237
|
+
|
|
238
|
+
const existing = await getCredentialsListFromIdx(credentialAlias);
|
|
239
|
+
|
|
240
|
+
const indexOfExistingCredential = existing.credentials.findIndex(credential => {
|
|
241
|
+
return credential.id === record.id;
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
if (indexOfExistingCredential > -1) {
|
|
245
|
+
existing.credentials[indexOfExistingCredential] = record;
|
|
246
|
+
} else existing.credentials.push(record);
|
|
247
|
+
|
|
248
|
+
return streamIdToCeramicURI(await dataStore.set(credentialAlias, existing));
|
|
249
|
+
},
|
|
250
|
+
removeVerifiableCredentialInIdx: async (_learnCard, id) => {
|
|
251
|
+
return removeCredentialFromIdx(id);
|
|
252
|
+
},
|
|
253
|
+
removeAllVerifiableCredentialsInIdx: async () => {
|
|
254
|
+
return removeAllCredentialsFromIdx();
|
|
255
|
+
},
|
|
256
|
+
getIDXIndex: async () => dataStore.get(credentialAlias),
|
|
257
|
+
setIDXIndex: async (_learnCard, index) => dataStore.set(credentialAlias, index),
|
|
258
|
+
},
|
|
259
|
+
};
|
|
260
|
+
};
|
package/src/index.ts
ADDED
package/src/types.ts
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { ModelAliases } from '@glazed/types';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { StreamID } from '@ceramicnetwork/streamid';
|
|
4
|
+
import { Plugin } from '@learncard/core';
|
|
5
|
+
import { VC, CredentialRecord, CredentialRecordValidator } from '@learncard/types';
|
|
6
|
+
import { CeramicClient } from '@ceramicnetwork/http-client';
|
|
7
|
+
|
|
8
|
+
/** @group IDXPlugin */
|
|
9
|
+
export type IDXIndexObject<
|
|
10
|
+
IDXMetadata extends Record<string, any>,
|
|
11
|
+
Metadata extends Record<string, any>
|
|
12
|
+
> = {
|
|
13
|
+
credentials: CredentialRecord<Metadata>[];
|
|
14
|
+
} & IDXMetadata;
|
|
15
|
+
|
|
16
|
+
/** @group IDXPlugin */
|
|
17
|
+
export type IDXArgs = {
|
|
18
|
+
modelData: ModelAliases;
|
|
19
|
+
credentialAlias: string;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/** @group IDXPlugin */
|
|
23
|
+
export type IDXPluginMethods = {
|
|
24
|
+
getCredentialsListFromIdx: <Metadata extends Record<string, any> = Record<never, never>>(
|
|
25
|
+
alias?: string
|
|
26
|
+
) => Promise<CredentialRecord<Metadata>[]>;
|
|
27
|
+
getVerifiableCredentialFromIdx: (id: string) => Promise<VC | undefined>;
|
|
28
|
+
getVerifiableCredentialsFromIdx: () => Promise<VC[]>;
|
|
29
|
+
addVerifiableCredentialInIdx: <Metadata extends Record<string, any> = Record<never, never>>(
|
|
30
|
+
cred: CredentialRecord<Metadata>
|
|
31
|
+
) => Promise<string>;
|
|
32
|
+
removeVerifiableCredentialInIdx: (title: string) => Promise<StreamID>;
|
|
33
|
+
removeAllVerifiableCredentialsInIdx: () => Promise<StreamID>;
|
|
34
|
+
getIDXIndex: <
|
|
35
|
+
IDXMetadata extends Record<string, any>,
|
|
36
|
+
Metadata extends Record<string, any>
|
|
37
|
+
>() => Promise<IDXIndexObject<IDXMetadata, Metadata> | null>;
|
|
38
|
+
setIDXIndex: <IDXMetadata extends Record<string, any>, Metadata extends Record<string, any>>(
|
|
39
|
+
index: IDXIndexObject<IDXMetadata, Metadata>
|
|
40
|
+
) => Promise<StreamID>;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/** @group IDXPlugin */
|
|
44
|
+
export type IDXPluginDependentMethods = {
|
|
45
|
+
getCeramicClient: () => CeramicClient;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/** @group IDXPlugin */
|
|
49
|
+
export type CredentialsList<Metadata extends Record<string, any> = Record<never, never>> = {
|
|
50
|
+
credentials: Array<CredentialRecord<Metadata>>;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/** @group IDXPlugin */
|
|
54
|
+
export const CredentialsListValidator: z.ZodType<CredentialsList> = z
|
|
55
|
+
.object({
|
|
56
|
+
credentials: CredentialRecordValidator.array(),
|
|
57
|
+
})
|
|
58
|
+
.catchall(z.any());
|
|
59
|
+
|
|
60
|
+
/** @group IDXPlugin */
|
|
61
|
+
export type IDXPlugin = Plugin<'IDX', 'index', IDXPluginMethods, 'read', IDXPluginDependentMethods>;
|
|
62
|
+
|
|
63
|
+
// Below types are temporary! They will be removed in the future when we are confident that everyone
|
|
64
|
+
// has moved on to the new schema
|
|
65
|
+
|
|
66
|
+
/** @group IDXPlugin */
|
|
67
|
+
export type BackwardsCompatIDXCredential<
|
|
68
|
+
Metadata extends Record<string, any> = Record<never, never>
|
|
69
|
+
> = { [key: string]: any; id: string; title: string; storageType?: 'ceramic' } & Metadata;
|
|
70
|
+
|
|
71
|
+
/** @group IDXPlugin */
|
|
72
|
+
export const BackwardsCompatIDXCredentialValidator: z.ZodType<BackwardsCompatIDXCredential> = z
|
|
73
|
+
.object({ id: z.string(), title: z.string(), storageType: z.literal('ceramic').optional() })
|
|
74
|
+
.catchall(z.any());
|
|
75
|
+
|
|
76
|
+
/** @group IDXPlugin */
|
|
77
|
+
export type BackwardsCompatCredentialsList<
|
|
78
|
+
Metadata extends Record<string, any> = Record<never, never>
|
|
79
|
+
> = {
|
|
80
|
+
credentials: Array<CredentialRecord<Metadata> | BackwardsCompatIDXCredential<Metadata>>;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/** @group IDXPlugin */
|
|
84
|
+
export const BackwardsCompatCredentialsListValidator: z.ZodType<BackwardsCompatCredentialsList> = z
|
|
85
|
+
.object({
|
|
86
|
+
credentials: CredentialRecordValidator.or(BackwardsCompatIDXCredentialValidator).array(),
|
|
87
|
+
})
|
|
88
|
+
.strict();
|