@interop/did-cli 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +341 -0
- package/LICENSE.md +21 -0
- package/README.md +1307 -0
- package/dist/commands/did.d.ts +3 -0
- package/dist/commands/did.d.ts.map +1 -0
- package/dist/commands/did.js +605 -0
- package/dist/commands/did.js.map +1 -0
- package/dist/commands/key.d.ts +3 -0
- package/dist/commands/key.d.ts.map +1 -0
- package/dist/commands/key.js +430 -0
- package/dist/commands/key.js.map +1 -0
- package/dist/commands/vc.d.ts +79 -0
- package/dist/commands/vc.d.ts.map +1 -0
- package/dist/commands/vc.js +528 -0
- package/dist/commands/vc.js.map +1 -0
- package/dist/commands/wallet.d.ts +14 -0
- package/dist/commands/wallet.d.ts.map +1 -0
- package/dist/commands/wallet.js +48 -0
- package/dist/commands/wallet.js.map +1 -0
- package/dist/commands/was.d.ts +500 -0
- package/dist/commands/was.d.ts.map +1 -0
- package/dist/commands/was.js +1833 -0
- package/dist/commands/was.js.map +1 -0
- package/dist/commands/zcap.d.ts +85 -0
- package/dist/commands/zcap.d.ts.map +1 -0
- package/dist/commands/zcap.js +447 -0
- package/dist/commands/zcap.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/keys/ecdsa.d.ts +40 -0
- package/dist/keys/ecdsa.d.ts.map +1 -0
- package/dist/keys/ecdsa.js +73 -0
- package/dist/keys/ecdsa.js.map +1 -0
- package/dist/meta.d.ts +164 -0
- package/dist/meta.d.ts.map +1 -0
- package/dist/meta.js +286 -0
- package/dist/meta.js.map +1 -0
- package/dist/storage.d.ts +191 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +307 -0
- package/dist/storage.js.map +1 -0
- package/dist/table.d.ts +43 -0
- package/dist/table.d.ts.map +1 -0
- package/dist/table.js +61 -0
- package/dist/table.js.map +1 -0
- package/dist/vc/fixtures/welcomeCredential.d.ts +22 -0
- package/dist/vc/fixtures/welcomeCredential.d.ts.map +1 -0
- package/dist/vc/fixtures/welcomeCredential.js +25 -0
- package/dist/vc/fixtures/welcomeCredential.js.map +1 -0
- package/dist/vc/issue.d.ts +24 -0
- package/dist/vc/issue.d.ts.map +1 -0
- package/dist/vc/issue.js +211 -0
- package/dist/vc/issue.js.map +1 -0
- package/dist/vc/registries.d.ts +30 -0
- package/dist/vc/registries.d.ts.map +1 -0
- package/dist/vc/registries.js +53 -0
- package/dist/vc/registries.js.map +1 -0
- package/dist/vc/registryManager.d.ts +25 -0
- package/dist/vc/registryManager.d.ts.map +1 -0
- package/dist/vc/registryManager.js +29 -0
- package/dist/vc/registryManager.js.map +1 -0
- package/dist/vc/suites/expirationSuite.d.ts +23 -0
- package/dist/vc/suites/expirationSuite.d.ts.map +1 -0
- package/dist/vc/suites/expirationSuite.js +84 -0
- package/dist/vc/suites/expirationSuite.js.map +1 -0
- package/dist/vc/suites/issuerDetailsSuite.d.ts +22 -0
- package/dist/vc/suites/issuerDetailsSuite.d.ts.map +1 -0
- package/dist/vc/suites/issuerDetailsSuite.js +69 -0
- package/dist/vc/suites/issuerDetailsSuite.js.map +1 -0
- package/dist/vc/verify.d.ts +46 -0
- package/dist/vc/verify.d.ts.map +1 -0
- package/dist/vc/verify.js +147 -0
- package/dist/vc/verify.js.map +1 -0
- package/dist/was/address.d.ts +44 -0
- package/dist/was/address.d.ts.map +1 -0
- package/dist/was/address.js +98 -0
- package/dist/was/address.js.map +1 -0
- package/dist/was/capability.d.ts +65 -0
- package/dist/was/capability.d.ts.map +1 -0
- package/dist/was/capability.js +108 -0
- package/dist/was/capability.js.map +1 -0
- package/dist/was/client.d.ts +108 -0
- package/dist/was/client.d.ts.map +1 -0
- package/dist/was/client.js +142 -0
- package/dist/was/client.js.map +1 -0
- package/dist/was/io.d.ts +71 -0
- package/dist/was/io.d.ts.map +1 -0
- package/dist/was/io.js +146 -0
- package/dist/was/io.js.map +1 -0
- package/dist/was/registry.d.ts +79 -0
- package/dist/was/registry.d.ts.map +1 -0
- package/dist/was/registry.js +99 -0
- package/dist/was/registry.js.map +1 -0
- package/dist/zcap/create.d.ts +20 -0
- package/dist/zcap/create.d.ts.map +1 -0
- package/dist/zcap/create.js +29 -0
- package/dist/zcap/create.js.map +1 -0
- package/dist/zcap/delegate.d.ts +44 -0
- package/dist/zcap/delegate.d.ts.map +1 -0
- package/dist/zcap/delegate.js +77 -0
- package/dist/zcap/delegate.js.map +1 -0
- package/dist/zcap/encoding.d.ts +17 -0
- package/dist/zcap/encoding.d.ts.map +1 -0
- package/dist/zcap/encoding.js +37 -0
- package/dist/zcap/encoding.js.map +1 -0
- package/dist/zcap/signer.d.ts +20 -0
- package/dist/zcap/signer.d.ts.map +1 -0
- package/dist/zcap/signer.js +62 -0
- package/dist/zcap/signer.js.map +1 -0
- package/dist/zcap/ttl.d.ts +19 -0
- package/dist/zcap/ttl.d.ts.map +1 -0
- package/dist/zcap/ttl.js +40 -0
- package/dist/zcap/ttl.js.map +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1,528 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `vc` command -- Verifiable Credential operations.
|
|
3
|
+
*
|
|
4
|
+
* `vc verify` reads a VC as JSON (from a file, an http(s) URL, or stdin) and
|
|
5
|
+
* runs full verification (cryptographic signature, expiration,
|
|
6
|
+
* revocation/status, and issuer registry recognition) via the verify adapter
|
|
7
|
+
* over @interop/verifier-core. By default it prints the full verifier-core
|
|
8
|
+
* result; `--summary` prints a compact flattened object. `vc issue` signs an
|
|
9
|
+
* unsigned credential with a locally stored DID. `vc import` stores an
|
|
10
|
+
* existing credential in local wallet storage (`~/.config/did-cli-wallet/credentials/`)
|
|
11
|
+
* along with a `.meta.json` metadata sidecar (creation timestamp plus
|
|
12
|
+
* `--handle` / `--description` when given); `vc issue --save` does the same
|
|
13
|
+
* for a freshly issued credential. `list` renders a metadata table of the
|
|
14
|
+
* saved credentials, `show` prints one back (`--meta` for its metadata),
|
|
15
|
+
* `meta` edits the metadata sidecar, and `remove` deletes a stored
|
|
16
|
+
* credential.
|
|
17
|
+
*
|
|
18
|
+
* Exit codes: 0 on success, 1 on a verification/issuance/import error, 2 on a
|
|
19
|
+
* fetch/read/parse error or a malformed credential the verifier could not
|
|
20
|
+
* structurally parse.
|
|
21
|
+
*/
|
|
22
|
+
import { createHash } from 'node:crypto';
|
|
23
|
+
import { readFile } from 'node:fs/promises';
|
|
24
|
+
import { Command } from 'commander';
|
|
25
|
+
import { issueCredential } from '../vc/issue.js';
|
|
26
|
+
import { loadKnownRegistries } from '../vc/registries.js';
|
|
27
|
+
import { findParseFailure, toSummary, verifyCredentialFully } from '../vc/verify.js';
|
|
28
|
+
import { listCollection, loadFromCollection, loadMetaFromCollection, removeFromCollection, saveMetaToCollection, saveToCollection, sanitizeStorageId } from '../storage.js';
|
|
29
|
+
import { resolveCredentialRef } from '../meta.js';
|
|
30
|
+
import { renderTable } from '../table.js';
|
|
31
|
+
/**
|
|
32
|
+
* Reads all of stdin to a string. Used when no file argument is given.
|
|
33
|
+
*
|
|
34
|
+
* @returns {Promise<string>}
|
|
35
|
+
*/
|
|
36
|
+
async function readStdin() {
|
|
37
|
+
const chunks = [];
|
|
38
|
+
for await (const chunk of process.stdin) {
|
|
39
|
+
chunks.push(chunk);
|
|
40
|
+
}
|
|
41
|
+
return Buffer.concat(chunks).toString('utf8');
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Reads and parses the credential JSON from an http(s) URL or a file (when
|
|
45
|
+
* given) or stdin. Logs to stderr and returns undefined on a fetch, read, or
|
|
46
|
+
* parse error.
|
|
47
|
+
*
|
|
48
|
+
* @param source {string | undefined} An http(s) URL or a path to read, or
|
|
49
|
+
* undefined for stdin.
|
|
50
|
+
* @returns {Promise<object | undefined>}
|
|
51
|
+
*/
|
|
52
|
+
async function readCredentialJson(source) {
|
|
53
|
+
try {
|
|
54
|
+
let raw;
|
|
55
|
+
if (source && /^https?:\/\//.test(source)) {
|
|
56
|
+
const response = await fetch(source, {
|
|
57
|
+
headers: { accept: 'application/json' }
|
|
58
|
+
});
|
|
59
|
+
if (!response.ok) {
|
|
60
|
+
throw new Error(`GET ${source} returned ${response.status} ${response.statusText}`);
|
|
61
|
+
}
|
|
62
|
+
raw = await response.text();
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
raw = source ? await readFile(source, 'utf8') : await readStdin();
|
|
66
|
+
}
|
|
67
|
+
return JSON.parse(raw);
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
console.error(`Could not read credential: ${err instanceof Error ? err.message : String(err)}`);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Derives a filesystem-safe storage id for a credential: its `id` when it has
|
|
76
|
+
* one (a credential's `id` property is optional), otherwise a digest of its
|
|
77
|
+
* JSON content -- deterministic, so re-importing the same id-less credential
|
|
78
|
+
* overwrites rather than duplicates.
|
|
79
|
+
*
|
|
80
|
+
* @param options {object}
|
|
81
|
+
* @param options.credential {StoredCredential}
|
|
82
|
+
* @returns {string}
|
|
83
|
+
*/
|
|
84
|
+
export function credentialStorageId({ credential }) {
|
|
85
|
+
if (credential.id) {
|
|
86
|
+
return sanitizeStorageId(credential.id);
|
|
87
|
+
}
|
|
88
|
+
const digest = createHash('sha256')
|
|
89
|
+
.update(JSON.stringify(credential))
|
|
90
|
+
.digest('hex');
|
|
91
|
+
return `sha256-${digest.slice(0, 24)}`;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Returns whether a parsed JSON object structurally looks like a Verifiable
|
|
95
|
+
* Credential: its `type` includes `VerifiableCredential`.
|
|
96
|
+
*
|
|
97
|
+
* @param value {object}
|
|
98
|
+
* @returns {boolean}
|
|
99
|
+
*/
|
|
100
|
+
function isCredential(value) {
|
|
101
|
+
const type = value.type;
|
|
102
|
+
const types = Array.isArray(type) ? type : [type];
|
|
103
|
+
return types.includes('VerifiableCredential');
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Build the human-readable type label shown in list/show output: the first
|
|
107
|
+
* entry of the credential's `type` that is not the generic
|
|
108
|
+
* `VerifiableCredential` (e.g. `OpenBadgeCredential`), falling back to
|
|
109
|
+
* `VerifiableCredential` itself.
|
|
110
|
+
*
|
|
111
|
+
* @param options {object}
|
|
112
|
+
* @param options.credential {StoredCredential}
|
|
113
|
+
* @returns {string}
|
|
114
|
+
*/
|
|
115
|
+
function credentialTypeLabel({ credential }) {
|
|
116
|
+
const types = Array.isArray(credential.type)
|
|
117
|
+
? credential.type
|
|
118
|
+
: credential.type
|
|
119
|
+
? [credential.type]
|
|
120
|
+
: [];
|
|
121
|
+
return types.find(type => type !== 'VerifiableCredential') ?? types[0] ?? '';
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Extract the issuer id of a credential, accommodating both the DID-string
|
|
125
|
+
* and the embedded-object (`{ id, ... }`) forms of the `issuer` property.
|
|
126
|
+
*
|
|
127
|
+
* @param options {object}
|
|
128
|
+
* @param options.credential {StoredCredential}
|
|
129
|
+
* @returns {string}
|
|
130
|
+
*/
|
|
131
|
+
function credentialIssuerId({ credential }) {
|
|
132
|
+
const issuer = credential.issuer;
|
|
133
|
+
return (typeof issuer === 'string' ? issuer : issuer?.id) ?? '';
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Save a credential to the wallet `credentials` collection together with its
|
|
137
|
+
* `.meta.json` metadata sidecar (creation timestamp plus handle and
|
|
138
|
+
* description when given). When the credential is already stored, its
|
|
139
|
+
* existing metadata is preserved (and updated with the given handle /
|
|
140
|
+
* description) rather than reset.
|
|
141
|
+
*
|
|
142
|
+
* @param options {object}
|
|
143
|
+
* @param options.credential {StoredCredential}
|
|
144
|
+
* @param [options.handle] {string}
|
|
145
|
+
* @param [options.description] {string}
|
|
146
|
+
* @returns {Promise<string>} The credential file path.
|
|
147
|
+
*/
|
|
148
|
+
async function saveCredential({ credential, handle, description }) {
|
|
149
|
+
const storageId = credentialStorageId({ credential });
|
|
150
|
+
const existingMeta = await loadMetaFromCollection({
|
|
151
|
+
collection: 'credentials',
|
|
152
|
+
storageId
|
|
153
|
+
});
|
|
154
|
+
const filePath = await saveToCollection('credentials', storageId, credential);
|
|
155
|
+
const meta = {
|
|
156
|
+
created: new Date().toISOString(),
|
|
157
|
+
...existingMeta
|
|
158
|
+
};
|
|
159
|
+
if (handle) {
|
|
160
|
+
meta.handle = handle;
|
|
161
|
+
}
|
|
162
|
+
if (description) {
|
|
163
|
+
meta.description = description;
|
|
164
|
+
}
|
|
165
|
+
await saveMetaToCollection({ collection: 'credentials', storageId, meta });
|
|
166
|
+
return filePath;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Reads, verifies, and prints a credential, returning the process exit code:
|
|
170
|
+
* `0` when verified, `1` when not verified, and `2` on a read/parse error or a
|
|
171
|
+
* structurally malformed credential. Kept separate from the command action so
|
|
172
|
+
* the exit-code logic is directly testable without stubbing `process.exit`.
|
|
173
|
+
*
|
|
174
|
+
* @param file {string | undefined} Path to read, or undefined for stdin.
|
|
175
|
+
* @param options {object}
|
|
176
|
+
* @param [options.summary] {boolean} Print the compact summary instead of the
|
|
177
|
+
* full verifier-core result.
|
|
178
|
+
* @returns {Promise<number>} The process exit code.
|
|
179
|
+
*/
|
|
180
|
+
export async function runVerify(file, options) {
|
|
181
|
+
const credential = await readCredentialJson(file);
|
|
182
|
+
if (credential === undefined) {
|
|
183
|
+
return 2;
|
|
184
|
+
}
|
|
185
|
+
const registries = await loadKnownRegistries();
|
|
186
|
+
const result = await verifyCredentialFully({ credential, registries });
|
|
187
|
+
const output = options.summary ? toSummary(result) : result;
|
|
188
|
+
console.log(JSON.stringify(output, null, 2));
|
|
189
|
+
if (findParseFailure(result)) {
|
|
190
|
+
return 2;
|
|
191
|
+
}
|
|
192
|
+
return result.verified ? 0 : 1;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Reads, issues (signs), and prints a credential, returning the process exit
|
|
196
|
+
* code: `0` when issued, `1` on an issuance error (an unauthorized key, a
|
|
197
|
+
* missing DID or key file, an unknown suite, an issuer that does not match the
|
|
198
|
+
* signing DID, or a signing failure), and `2` on a read/parse error. Kept
|
|
199
|
+
* separate from the command action so the exit-code logic is directly testable
|
|
200
|
+
* without stubbing `process.exit`.
|
|
201
|
+
*
|
|
202
|
+
* @param file {string | undefined} Path to read, or undefined for stdin.
|
|
203
|
+
* @param options {object}
|
|
204
|
+
* @param options.did {string} The id of the stored DID to issue (sign) with.
|
|
205
|
+
* @param [options.key] {string} The verification method id to use.
|
|
206
|
+
* @param [options.suite] {string} The signature suite to use.
|
|
207
|
+
* @param [options.save] {boolean} Save the issued credential to local
|
|
208
|
+
* wallet storage.
|
|
209
|
+
* @param [options.handle] {string} Short tag stored in the metadata sidecar.
|
|
210
|
+
* @param [options.description] {string} Longer description stored in the
|
|
211
|
+
* metadata sidecar.
|
|
212
|
+
* @returns {Promise<number>} The process exit code.
|
|
213
|
+
*/
|
|
214
|
+
export async function runIssue(file, options) {
|
|
215
|
+
const credential = await readCredentialJson(file);
|
|
216
|
+
if (credential === undefined) {
|
|
217
|
+
return 2;
|
|
218
|
+
}
|
|
219
|
+
try {
|
|
220
|
+
const signed = await issueCredential({
|
|
221
|
+
credential,
|
|
222
|
+
did: options.did,
|
|
223
|
+
keyId: options.key,
|
|
224
|
+
suite: options.suite
|
|
225
|
+
});
|
|
226
|
+
if (options.save) {
|
|
227
|
+
const filePath = await saveCredential({
|
|
228
|
+
credential: signed,
|
|
229
|
+
handle: options.handle,
|
|
230
|
+
description: options.description
|
|
231
|
+
});
|
|
232
|
+
console.error(`Credential saved to ${filePath}`);
|
|
233
|
+
}
|
|
234
|
+
console.log(JSON.stringify(signed, null, 2));
|
|
235
|
+
return 0;
|
|
236
|
+
}
|
|
237
|
+
catch (err) {
|
|
238
|
+
console.error(`Could not issue credential: ${err instanceof Error ? err.message : String(err)}`);
|
|
239
|
+
return 1;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Reads a credential and stores it in local wallet storage, returning the
|
|
244
|
+
* process exit code: `0` when imported, `1` when the input is not a
|
|
245
|
+
* Verifiable Credential, and `2` on a fetch/read/parse error. Kept separate
|
|
246
|
+
* from the command action so the exit-code logic is directly testable without
|
|
247
|
+
* stubbing `process.exit`.
|
|
248
|
+
*
|
|
249
|
+
* @param source {string | undefined} An http(s) URL or a path to read, or
|
|
250
|
+
* undefined for stdin.
|
|
251
|
+
* @param options {object}
|
|
252
|
+
* @param [options.handle] {string} Short tag stored in the metadata sidecar.
|
|
253
|
+
* @param [options.description] {string} Longer description stored in the
|
|
254
|
+
* metadata sidecar.
|
|
255
|
+
* @returns {Promise<number>} The process exit code.
|
|
256
|
+
*/
|
|
257
|
+
export async function runImport(source, options) {
|
|
258
|
+
const credential = await readCredentialJson(source);
|
|
259
|
+
if (credential === undefined) {
|
|
260
|
+
return 2;
|
|
261
|
+
}
|
|
262
|
+
if (!isCredential(credential)) {
|
|
263
|
+
console.error('Input does not look like a Verifiable Credential ' +
|
|
264
|
+
"(its 'type' does not include 'VerifiableCredential')");
|
|
265
|
+
return 1;
|
|
266
|
+
}
|
|
267
|
+
const filePath = await saveCredential({
|
|
268
|
+
credential,
|
|
269
|
+
handle: options.handle,
|
|
270
|
+
description: options.description
|
|
271
|
+
});
|
|
272
|
+
console.error(`Credential saved to ${filePath}`);
|
|
273
|
+
return 0;
|
|
274
|
+
}
|
|
275
|
+
export function makeVcCommand() {
|
|
276
|
+
const vc = new Command('vc').description('Manage Verifiable Credentials');
|
|
277
|
+
vc.command('verify [file]')
|
|
278
|
+
.description('Verify a Verifiable Credential (JSON from a file or stdin)')
|
|
279
|
+
.option('--summary', 'print a compact summary instead of the full result')
|
|
280
|
+
.action(async (file, options) => {
|
|
281
|
+
const code = await runVerify(file, options);
|
|
282
|
+
if (code !== 0) {
|
|
283
|
+
process.exit(code);
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
vc.command('issue [file]')
|
|
287
|
+
.description('Issue (sign) an unsigned Verifiable Credential (JSON from a file or stdin)')
|
|
288
|
+
.requiredOption('--did <did>', 'id of the stored DID to issue (sign) with')
|
|
289
|
+
.option('--key <keyId>', 'verification method id to use (default: first assertionMethod key)')
|
|
290
|
+
.option('--suite <suite>', 'signature suite (ed25519: eddsa-rdfc-2022 | Ed25519Signature2020; ' +
|
|
291
|
+
'ecdsa: ecdsa-rdfc-2019); defaults to the signing key type')
|
|
292
|
+
.option('--save', 'save the issued credential to local wallet storage (~/.config/did-cli-wallet/credentials/)')
|
|
293
|
+
.option('--handle <handle>', 'short tag for the saved credential (requires --save)')
|
|
294
|
+
.option('--description <description>', 'longer description of the saved credential (requires --save)')
|
|
295
|
+
.action(async (file, options) => {
|
|
296
|
+
if ((options.handle !== undefined || options.description !== undefined) &&
|
|
297
|
+
!options.save) {
|
|
298
|
+
console.error('--handle and --description require --save');
|
|
299
|
+
process.exit(1);
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
const code = await runIssue(file, options);
|
|
303
|
+
if (code !== 0) {
|
|
304
|
+
process.exit(code);
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
vc.command('import [source]')
|
|
308
|
+
.description('Import a Verifiable Credential (JSON from a file, an http(s) URL, or ' +
|
|
309
|
+
'stdin) into local wallet storage (~/.config/did-cli-wallet/credentials/)')
|
|
310
|
+
.option('--handle <handle>', 'short tag for the saved credential')
|
|
311
|
+
.option('--description <description>', 'longer description of the saved credential')
|
|
312
|
+
.action(async (source, options) => {
|
|
313
|
+
const code = await runImport(source, options);
|
|
314
|
+
if (code !== 0) {
|
|
315
|
+
process.exit(code);
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
vc.command('list')
|
|
319
|
+
.description('List locally stored credentials with their metadata')
|
|
320
|
+
.option('--json', 'output the list as a JSON array of objects with metadata')
|
|
321
|
+
.option('--plain', 'output one credential id per line, sorted (no metadata)')
|
|
322
|
+
.action(async (options) => {
|
|
323
|
+
const storageIds = await listCollection('credentials');
|
|
324
|
+
if (options.plain) {
|
|
325
|
+
const credentialIds = [];
|
|
326
|
+
for (const storageId of storageIds) {
|
|
327
|
+
const credential = await loadFromCollection('credentials', storageId);
|
|
328
|
+
// An id-less credential is listed by its storage id, which is how
|
|
329
|
+
// `show` / `remove` address it.
|
|
330
|
+
credentialIds.push(credential.id ?? storageId);
|
|
331
|
+
}
|
|
332
|
+
credentialIds.sort();
|
|
333
|
+
for (const credentialId of credentialIds) {
|
|
334
|
+
console.log(credentialId);
|
|
335
|
+
}
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
const entries = [];
|
|
339
|
+
for (const storageId of storageIds) {
|
|
340
|
+
const credential = await loadFromCollection('credentials', storageId);
|
|
341
|
+
const meta = await loadMetaFromCollection({
|
|
342
|
+
collection: 'credentials',
|
|
343
|
+
storageId
|
|
344
|
+
});
|
|
345
|
+
entries.push({
|
|
346
|
+
id: credential.id ?? storageId,
|
|
347
|
+
type: credentialTypeLabel({ credential }),
|
|
348
|
+
issuer: credentialIssuerId({ credential }),
|
|
349
|
+
...meta
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
if (options.json) {
|
|
353
|
+
const output = entries.map(entry => ({
|
|
354
|
+
id: entry.id,
|
|
355
|
+
type: entry.type,
|
|
356
|
+
issuer: entry.issuer,
|
|
357
|
+
...(entry.created && { created: entry.created }),
|
|
358
|
+
...(entry.handle && { handle: entry.handle }),
|
|
359
|
+
...(entry.description && { description: entry.description })
|
|
360
|
+
}));
|
|
361
|
+
console.log(JSON.stringify(output, null, 2));
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
if (entries.length === 0) {
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
const rows = entries.map(entry => [
|
|
368
|
+
entry.handle ?? '',
|
|
369
|
+
entry.type,
|
|
370
|
+
entry.issuer,
|
|
371
|
+
entry.created?.slice(0, 10) ?? '',
|
|
372
|
+
entry.id,
|
|
373
|
+
entry.description ?? ''
|
|
374
|
+
]);
|
|
375
|
+
console.log(renderTable({
|
|
376
|
+
columns: [
|
|
377
|
+
{ header: 'HANDLE', maxWidth: 16 },
|
|
378
|
+
{ header: 'TYPE', maxWidth: 24 },
|
|
379
|
+
{ header: 'ISSUER', maxWidth: 28 },
|
|
380
|
+
{ header: 'CREATED' },
|
|
381
|
+
{ header: 'ID', maxWidth: 44 },
|
|
382
|
+
{ header: 'DESCRIPTION', maxWidth: 40 }
|
|
383
|
+
],
|
|
384
|
+
rows
|
|
385
|
+
}));
|
|
386
|
+
});
|
|
387
|
+
vc.command('show <id>')
|
|
388
|
+
.aliases(['view', 'cat'])
|
|
389
|
+
.description('Show a locally stored credential by its credential id or metadata handle')
|
|
390
|
+
.option('--meta', 'show the credential metadata instead of the credential')
|
|
391
|
+
.option('--json', 'with --meta, output the metadata as JSON')
|
|
392
|
+
.action(async (id, options) => {
|
|
393
|
+
let resolved;
|
|
394
|
+
try {
|
|
395
|
+
resolved = await resolveCredentialRef({ ref: id });
|
|
396
|
+
}
|
|
397
|
+
catch (err) {
|
|
398
|
+
console.error(err.message);
|
|
399
|
+
process.exit(1);
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
if (!resolved) {
|
|
403
|
+
console.error(`No locally stored credential found for ${id}`);
|
|
404
|
+
process.exit(1);
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
if (options.meta) {
|
|
408
|
+
const credentialId = resolved.credential.id ?? resolved.storageId;
|
|
409
|
+
const type = credentialTypeLabel({ credential: resolved.credential });
|
|
410
|
+
const issuer = credentialIssuerId({ credential: resolved.credential });
|
|
411
|
+
const validFrom = resolved.credential.validFrom ?? resolved.credential.issuanceDate;
|
|
412
|
+
const expires = resolved.credential.validUntil ?? resolved.credential.expirationDate;
|
|
413
|
+
if (options.json) {
|
|
414
|
+
const output = {
|
|
415
|
+
id: credentialId,
|
|
416
|
+
type,
|
|
417
|
+
...(resolved.meta?.created && { created: resolved.meta.created }),
|
|
418
|
+
...(resolved.meta?.handle && { handle: resolved.meta.handle }),
|
|
419
|
+
...(resolved.meta?.description && {
|
|
420
|
+
description: resolved.meta.description
|
|
421
|
+
}),
|
|
422
|
+
...(issuer && { issuer }),
|
|
423
|
+
...(validFrom && { validFrom }),
|
|
424
|
+
...(expires && { expires })
|
|
425
|
+
};
|
|
426
|
+
console.log(JSON.stringify(output, null, 2));
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
const rows = [
|
|
430
|
+
['ID', credentialId],
|
|
431
|
+
['Type', type],
|
|
432
|
+
['Handle', resolved.meta?.handle ?? ''],
|
|
433
|
+
['Created', resolved.meta?.created ?? ''],
|
|
434
|
+
['Description', resolved.meta?.description ?? ''],
|
|
435
|
+
['Issuer', issuer],
|
|
436
|
+
['Valid From', validFrom ?? ''],
|
|
437
|
+
['Expires', expires ?? '']
|
|
438
|
+
];
|
|
439
|
+
console.log(renderTable({
|
|
440
|
+
columns: [{ header: 'FIELD' }, { header: 'VALUE' }],
|
|
441
|
+
rows
|
|
442
|
+
}));
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
// A stored credential holds no secret material (its proof is public),
|
|
446
|
+
// so it is safe to print as-is.
|
|
447
|
+
console.log(JSON.stringify(resolved.credential, null, 2));
|
|
448
|
+
});
|
|
449
|
+
vc.command('meta <id>')
|
|
450
|
+
.description('Show or edit the metadata of a locally stored credential (by ' +
|
|
451
|
+
'credential id or handle); with no options, prints the current metadata')
|
|
452
|
+
.option('--handle <handle>', 'set the handle (an empty string clears it)')
|
|
453
|
+
.option('--description <description>', 'set the description (an empty string clears it)')
|
|
454
|
+
.action(async (id, options) => {
|
|
455
|
+
let resolved;
|
|
456
|
+
try {
|
|
457
|
+
resolved = await resolveCredentialRef({ ref: id });
|
|
458
|
+
}
|
|
459
|
+
catch (err) {
|
|
460
|
+
console.error(err.message);
|
|
461
|
+
process.exit(1);
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
if (!resolved) {
|
|
465
|
+
console.error(`No locally stored credential found for ${id}`);
|
|
466
|
+
process.exit(1);
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
const hasEdits = options.handle !== undefined || options.description !== undefined;
|
|
470
|
+
if (!hasEdits) {
|
|
471
|
+
console.log(JSON.stringify(resolved.meta ?? {}, null, 2));
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
const meta = { ...(resolved.meta ?? {}) };
|
|
475
|
+
if (options.handle !== undefined) {
|
|
476
|
+
if (options.handle === '') {
|
|
477
|
+
delete meta.handle;
|
|
478
|
+
}
|
|
479
|
+
else {
|
|
480
|
+
meta.handle = options.handle;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
if (options.description !== undefined) {
|
|
484
|
+
if (options.description === '') {
|
|
485
|
+
delete meta.description;
|
|
486
|
+
}
|
|
487
|
+
else {
|
|
488
|
+
meta.description = options.description;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
const filePath = await saveMetaToCollection({
|
|
492
|
+
collection: 'credentials',
|
|
493
|
+
storageId: resolved.storageId,
|
|
494
|
+
meta
|
|
495
|
+
});
|
|
496
|
+
console.error(`Metadata saved to ${filePath}`);
|
|
497
|
+
console.log(JSON.stringify(meta, null, 2));
|
|
498
|
+
});
|
|
499
|
+
vc.command('remove <id>')
|
|
500
|
+
.aliases(['delete', 'rm'])
|
|
501
|
+
.description('Remove a locally stored credential and its metadata sidecar (by ' +
|
|
502
|
+
'credential id or handle)')
|
|
503
|
+
.action(async (id) => {
|
|
504
|
+
let resolved;
|
|
505
|
+
try {
|
|
506
|
+
resolved = await resolveCredentialRef({ ref: id });
|
|
507
|
+
}
|
|
508
|
+
catch (err) {
|
|
509
|
+
console.error(err.message);
|
|
510
|
+
process.exit(1);
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
if (!resolved) {
|
|
514
|
+
console.error(`No locally stored credential found for ${id}`);
|
|
515
|
+
process.exit(1);
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
const removed = await removeFromCollection({
|
|
519
|
+
collection: 'credentials',
|
|
520
|
+
storageId: resolved.storageId
|
|
521
|
+
});
|
|
522
|
+
for (const filePath of removed) {
|
|
523
|
+
console.error(`Removed ${filePath}`);
|
|
524
|
+
}
|
|
525
|
+
});
|
|
526
|
+
return vc;
|
|
527
|
+
}
|
|
528
|
+
//# sourceMappingURL=vc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vc.js","sourceRoot":"","sources":["../../src/commands/vc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AACzD,OAAO,EACL,gBAAgB,EAChB,SAAS,EACT,qBAAqB,EACtB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,EAElB,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,oBAAoB,EAAyB,MAAM,YAAY,CAAA;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAEzC;;;;GAIG;AACH,KAAK,UAAU,SAAS;IACtB,MAAM,MAAM,GAAa,EAAE,CAAA;IAC3B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QACxC,MAAM,CAAC,IAAI,CAAC,KAAe,CAAC,CAAA;IAC9B,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;AAC/C,CAAC;AAED;;;;;;;;GAQG;AACH,KAAK,UAAU,kBAAkB,CAC/B,MAA0B;IAE1B,IAAI,CAAC;QACH,IAAI,GAAW,CAAA;QACf,IAAI,MAAM,IAAI,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1C,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,MAAM,EAAE;gBACnC,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE;aACxC,CAAC,CAAA;YACF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CACb,OAAO,MAAM,aAAa,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CACnE,CAAA;YACH,CAAC;YACD,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;QAC7B,CAAC;aAAM,CAAC;YACN,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,SAAS,EAAE,CAAA;QACnE,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAW,CAAA;IAClC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CACX,8BAA8B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CACjF,CAAA;QACD,OAAM;IACR,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CAAC,EAClC,UAAU,EAGX;IACC,IAAI,UAAU,CAAC,EAAE,EAAE,CAAC;QAClB,OAAO,iBAAiB,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;IACzC,CAAC;IACD,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC;SAChC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;SAClC,MAAM,CAAC,KAAK,CAAC,CAAA;IAChB,OAAO,UAAU,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAA;AACxC,CAAC;AAED;;;;;;GAMG;AACH,SAAS,YAAY,CAAC,KAAa;IACjC,MAAM,IAAI,GAAI,KAA0B,CAAC,IAAI,CAAA;IAC7C,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;IACjD,OAAO,KAAK,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CAAA;AAC/C,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,mBAAmB,CAAC,EAC3B,UAAU,EAGX;IACC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC;QAC1C,CAAC,CAAC,UAAU,CAAC,IAAI;QACjB,CAAC,CAAC,UAAU,CAAC,IAAI;YACf,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;YACnB,CAAC,CAAC,EAAE,CAAA;IACR,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,KAAK,sBAAsB,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;AAC9E,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,kBAAkB,CAAC,EAC1B,UAAU,EAGX;IACC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAA;IAChC,OAAO,CAAC,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,EAAE,CAAA;AACjE,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,KAAK,UAAU,cAAc,CAAC,EAC5B,UAAU,EACV,MAAM,EACN,WAAW,EAKZ;IACC,MAAM,SAAS,GAAG,mBAAmB,CAAC,EAAE,UAAU,EAAE,CAAC,CAAA;IACrD,MAAM,YAAY,GAAG,MAAM,sBAAsB,CAAC;QAChD,UAAU,EAAE,aAAa;QACzB,SAAS;KACV,CAAC,CAAA;IACF,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,aAAa,EAAE,SAAS,EAAE,UAAU,CAAC,CAAA;IAC7E,MAAM,IAAI,GAAiB;QACzB,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACjC,GAAG,YAAY;KAChB,CAAA;IACD,IAAI,MAAM,EAAE,CAAC;QACX,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;IACD,IAAI,WAAW,EAAE,CAAC;QAChB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAA;IAChC,CAAC;IACD,MAAM,oBAAoB,CAAC,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAC1E,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,IAAwB,EACxB,OAA8B;IAE9B,MAAM,UAAU,GAAG,MAAM,kBAAkB,CAAC,IAAI,CAAC,CAAA;IACjD,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,CAAC,CAAA;IACV,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,mBAAmB,EAAE,CAAA;IAC9C,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,CAAA;IAEtE,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAA;IAC3D,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;IAE5C,IAAI,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,CAAA;IACV,CAAC;IACD,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAChC,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,IAAwB,EACxB,OAOC;IAED,MAAM,UAAU,GAAG,MAAM,kBAAkB,CAAC,IAAI,CAAC,CAAA;IACjD,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,CAAC,CAAA;IACV,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC;YACnC,UAAU;YACV,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,KAAK,EAAE,OAAO,CAAC,GAAG;YAClB,KAAK,EAAE,OAAO,CAAC,KAAK;SACrB,CAAC,CAAA;QACF,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC;gBACpC,UAAU,EAAE,MAA0B;gBACtC,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,WAAW,EAAE,OAAO,CAAC,WAAW;aACjC,CAAC,CAAA;YACF,OAAO,CAAC,KAAK,CAAC,uBAAuB,QAAQ,EAAE,CAAC,CAAA;QAClD,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;QAC5C,OAAO,CAAC,CAAA;IACV,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CACX,+BAA+B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAClF,CAAA;QACD,OAAO,CAAC,CAAA;IACV,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,MAA0B,EAC1B,OAAkD;IAElD,MAAM,UAAU,GAAG,MAAM,kBAAkB,CAAC,MAAM,CAAC,CAAA;IACnD,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,CAAC,CAAA;IACV,CAAC;IACD,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,KAAK,CACX,mDAAmD;YACjD,sDAAsD,CACzD,CAAA;QACD,OAAO,CAAC,CAAA;IACV,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC;QACpC,UAAU;QACV,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,WAAW,EAAE,OAAO,CAAC,WAAW;KACjC,CAAC,CAAA;IACF,OAAO,CAAC,KAAK,CAAC,uBAAuB,QAAQ,EAAE,CAAC,CAAA;IAChD,OAAO,CAAC,CAAA;AACV,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,MAAM,EAAE,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,+BAA+B,CAAC,CAAA;IAEzE,EAAE,CAAC,OAAO,CAAC,eAAe,CAAC;SACxB,WAAW,CAAC,4DAA4D,CAAC;SACzE,MAAM,CAAC,WAAW,EAAE,oDAAoD,CAAC;SACzE,MAAM,CACL,KAAK,EAAE,IAAwB,EAAE,OAA8B,EAAE,EAAE;QACjE,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QAC3C,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACpB,CAAC;IACH,CAAC,CACF,CAAA;IAEH,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC;SACvB,WAAW,CACV,4EAA4E,CAC7E;SACA,cAAc,CAAC,aAAa,EAAE,2CAA2C,CAAC;SAC1E,MAAM,CACL,eAAe,EACf,oEAAoE,CACrE;SACA,MAAM,CACL,iBAAiB,EACjB,oEAAoE;QAClE,2DAA2D,CAC9D;SACA,MAAM,CACL,QAAQ,EACR,4FAA4F,CAC7F;SACA,MAAM,CACL,mBAAmB,EACnB,sDAAsD,CACvD;SACA,MAAM,CACL,6BAA6B,EAC7B,8DAA8D,CAC/D;SACA,MAAM,CACL,KAAK,EACH,IAAwB,EACxB,OAOC,EACD,EAAE;QACF,IACE,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS,CAAC;YACnE,CAAC,OAAO,CAAC,IAAI,EACb,CAAC;YACD,OAAO,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAA;YAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACf,OAAM;QACR,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QAC1C,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACpB,CAAC;IACH,CAAC,CACF,CAAA;IAEH,EAAE,CAAC,OAAO,CAAC,iBAAiB,CAAC;SAC1B,WAAW,CACV,uEAAuE;QACrE,0EAA0E,CAC7E;SACA,MAAM,CAAC,mBAAmB,EAAE,oCAAoC,CAAC;SACjE,MAAM,CACL,6BAA6B,EAC7B,4CAA4C,CAC7C;SACA,MAAM,CACL,KAAK,EACH,MAA0B,EAC1B,OAAkD,EAClD,EAAE;QACF,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QAC7C,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACpB,CAAC;IACH,CAAC,CACF,CAAA;IAEH,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,qDAAqD,CAAC;SAClE,MAAM,CACL,QAAQ,EACR,0DAA0D,CAC3D;SACA,MAAM,CACL,SAAS,EACT,yDAAyD,CAC1D;SACA,MAAM,CAAC,KAAK,EAAE,OAA4C,EAAE,EAAE;QAC7D,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,aAAa,CAAC,CAAA;QACtD,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YAClB,MAAM,aAAa,GAAa,EAAE,CAAA;YAClC,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;gBACnC,MAAM,UAAU,GAAG,MAAM,kBAAkB,CACzC,aAAa,EACb,SAAS,CACV,CAAA;gBACD,kEAAkE;gBAClE,gCAAgC;gBAChC,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,IAAI,SAAS,CAAC,CAAA;YAChD,CAAC;YACD,aAAa,CAAC,IAAI,EAAE,CAAA;YACpB,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE,CAAC;gBACzC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;YAC3B,CAAC;YACD,OAAM;QACR,CAAC;QAED,MAAM,OAAO,GAIS,EAAE,CAAA;QACxB,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,MAAM,UAAU,GAAG,MAAM,kBAAkB,CACzC,aAAa,EACb,SAAS,CACV,CAAA;YACD,MAAM,IAAI,GAAG,MAAM,sBAAsB,CAAC;gBACxC,UAAU,EAAE,aAAa;gBACzB,SAAS;aACV,CAAC,CAAA;YACF,OAAO,CAAC,IAAI,CAAC;gBACX,EAAE,EAAE,UAAU,CAAC,EAAE,IAAI,SAAS;gBAC9B,IAAI,EAAE,mBAAmB,CAAC,EAAE,UAAU,EAAE,CAAC;gBACzC,MAAM,EAAE,kBAAkB,CAAC,EAAE,UAAU,EAAE,CAAC;gBAC1C,GAAG,IAAI;aACR,CAAC,CAAA;QACJ,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBACnC,EAAE,EAAE,KAAK,CAAC,EAAE;gBACZ,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,GAAG,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;gBAChD,GAAG,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;gBAC7C,GAAG,CAAC,KAAK,CAAC,WAAW,IAAI,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC;aAC7D,CAAC,CAAC,CAAA;YACH,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;YAC5C,OAAM;QACR,CAAC;QAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAM;QACR,CAAC;QACD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAChC,KAAK,CAAC,MAAM,IAAI,EAAE;YAClB,KAAK,CAAC,IAAI;YACV,KAAK,CAAC,MAAM;YACZ,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE;YACjC,KAAK,CAAC,EAAE;YACR,KAAK,CAAC,WAAW,IAAI,EAAE;SACxB,CAAC,CAAA;QACF,OAAO,CAAC,GAAG,CACT,WAAW,CAAC;YACV,OAAO,EAAE;gBACP,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE;gBAClC,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE;gBAChC,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE;gBAClC,EAAE,MAAM,EAAE,SAAS,EAAE;gBACrB,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE;gBAC9B,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,EAAE,EAAE;aACxC;YACD,IAAI;SACL,CAAC,CACH,CAAA;IACH,CAAC,CAAC,CAAA;IAEJ,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC;SACpB,OAAO,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;SACxB,WAAW,CACV,0EAA0E,CAC3E;SACA,MAAM,CAAC,QAAQ,EAAE,wDAAwD,CAAC;SAC1E,MAAM,CAAC,QAAQ,EAAE,0CAA0C,CAAC;SAC5D,MAAM,CAAC,KAAK,EAAE,EAAU,EAAE,OAA2C,EAAE,EAAE;QACxE,IAAI,QAAQ,CAAA;QACZ,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,oBAAoB,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAA;QACpD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAE,GAAa,CAAC,OAAO,CAAC,CAAA;YACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACf,OAAM;QACR,CAAC;QACD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,CAAC,KAAK,CAAC,0CAA0C,EAAE,EAAE,CAAC,CAAA;YAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACf,OAAM;QACR,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,MAAM,YAAY,GAAG,QAAQ,CAAC,UAAU,CAAC,EAAE,IAAI,QAAQ,CAAC,SAAS,CAAA;YACjE,MAAM,IAAI,GAAG,mBAAmB,CAAC,EAAE,UAAU,EAAE,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAA;YACrE,MAAM,MAAM,GAAG,kBAAkB,CAAC,EAAE,UAAU,EAAE,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAA;YACtE,MAAM,SAAS,GACb,QAAQ,CAAC,UAAU,CAAC,SAAS,IAAI,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAA;YACnE,MAAM,OAAO,GACX,QAAQ,CAAC,UAAU,CAAC,UAAU,IAAI,QAAQ,CAAC,UAAU,CAAC,cAAc,CAAA;YACtE,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;gBACjB,MAAM,MAAM,GAAG;oBACb,EAAE,EAAE,YAAY;oBAChB,IAAI;oBACJ,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;oBACjE,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;oBAC9D,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,WAAW,IAAI;wBAChC,WAAW,EAAE,QAAQ,CAAC,IAAI,CAAC,WAAW;qBACvC,CAAC;oBACF,GAAG,CAAC,MAAM,IAAI,EAAE,MAAM,EAAE,CAAC;oBACzB,GAAG,CAAC,SAAS,IAAI,EAAE,SAAS,EAAE,CAAC;oBAC/B,GAAG,CAAC,OAAO,IAAI,EAAE,OAAO,EAAE,CAAC;iBAC5B,CAAA;gBACD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;gBAC5C,OAAM;YACR,CAAC;YACD,MAAM,IAAI,GAAG;gBACX,CAAC,IAAI,EAAE,YAAY,CAAC;gBACpB,CAAC,MAAM,EAAE,IAAI,CAAC;gBACd,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,IAAI,EAAE,CAAC;gBACvC,CAAC,SAAS,EAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,IAAI,EAAE,CAAC;gBACzC,CAAC,aAAa,EAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,IAAI,EAAE,CAAC;gBACjD,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAClB,CAAC,YAAY,EAAE,SAAS,IAAI,EAAE,CAAC;gBAC/B,CAAC,SAAS,EAAE,OAAO,IAAI,EAAE,CAAC;aAC3B,CAAA;YACD,OAAO,CAAC,GAAG,CACT,WAAW,CAAC;gBACV,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;gBACnD,IAAI;aACL,CAAC,CACH,CAAA;YACD,OAAM;QACR,CAAC;QAED,sEAAsE;QACtE,gCAAgC;QAChC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;IAC3D,CAAC,CAAC,CAAA;IAEJ,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC;SACpB,WAAW,CACV,+DAA+D;QAC7D,wEAAwE,CAC3E;SACA,MAAM,CAAC,mBAAmB,EAAE,4CAA4C,CAAC;SACzE,MAAM,CACL,6BAA6B,EAC7B,iDAAiD,CAClD;SACA,MAAM,CACL,KAAK,EACH,EAAU,EACV,OAAkD,EAClD,EAAE;QACF,IAAI,QAAQ,CAAA;QACZ,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,oBAAoB,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAA;QACpD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAE,GAAa,CAAC,OAAO,CAAC,CAAA;YACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACf,OAAM;QACR,CAAC;QACD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,CAAC,KAAK,CAAC,0CAA0C,EAAE,EAAE,CAAC,CAAA;YAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACf,OAAM;QACR,CAAC;QAED,MAAM,QAAQ,GACZ,OAAO,CAAC,MAAM,KAAK,SAAS,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS,CAAA;QACnE,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;YACzD,OAAM;QACR,CAAC;QAED,MAAM,IAAI,GAAiB,EAAE,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,CAAA;QACvD,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACjC,IAAI,OAAO,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;gBAC1B,OAAO,IAAI,CAAC,MAAM,CAAA;YACpB,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAA;YAC9B,CAAC;QACH,CAAC;QACD,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;YACtC,IAAI,OAAO,CAAC,WAAW,KAAK,EAAE,EAAE,CAAC;gBAC/B,OAAO,IAAI,CAAC,WAAW,CAAA;YACzB,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAA;YACxC,CAAC;QACH,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC;YAC1C,UAAU,EAAE,aAAa;YACzB,SAAS,EAAE,QAAQ,CAAC,SAAS;YAC7B,IAAI;SACL,CAAC,CAAA;QACF,OAAO,CAAC,KAAK,CAAC,qBAAqB,QAAQ,EAAE,CAAC,CAAA;QAC9C,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;IAC5C,CAAC,CACF,CAAA;IAEH,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC;SACtB,OAAO,CAAC,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;SACzB,WAAW,CACV,kEAAkE;QAChE,0BAA0B,CAC7B;SACA,MAAM,CAAC,KAAK,EAAE,EAAU,EAAE,EAAE;QAC3B,IAAI,QAAQ,CAAA;QACZ,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,oBAAoB,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAA;QACpD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAE,GAAa,CAAC,OAAO,CAAC,CAAA;YACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACf,OAAM;QACR,CAAC;QACD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,CAAC,KAAK,CAAC,0CAA0C,EAAE,EAAE,CAAC,CAAA;YAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACf,OAAM;QACR,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAAC;YACzC,UAAU,EAAE,aAAa;YACzB,SAAS,EAAE,QAAQ,CAAC,SAAS;SAC9B,CAAC,CAAA;QACF,KAAK,MAAM,QAAQ,IAAI,OAAO,EAAE,CAAC;YAC/B,OAAO,CAAC,KAAK,CAAC,WAAW,QAAQ,EAAE,CAAC,CAAA;QACtC,CAAC;IACH,CAAC,CAAC,CAAA;IAEJ,OAAO,EAAE,CAAA;AACX,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `wallet` command group reports on local wallet storage (`~/.config/did-cli-wallet/`)
|
|
3
|
+
* as a whole. `ls` prints a summary of how many items are saved in each
|
|
4
|
+
* collection (keys, DIDs, zcaps, credentials, WAS spaces).
|
|
5
|
+
*/
|
|
6
|
+
import { Command } from 'commander';
|
|
7
|
+
/**
|
|
8
|
+
* Count the items saved in each wallet collection.
|
|
9
|
+
*
|
|
10
|
+
* @returns {Promise<Record<string, number>>} collection label to item count.
|
|
11
|
+
*/
|
|
12
|
+
export declare function countCollections(): Promise<Record<string, number>>;
|
|
13
|
+
export declare function makeWalletCommand(): Command;
|
|
14
|
+
//# sourceMappingURL=wallet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallet.d.ts","sourceRoot":"","sources":["../../src/commands/wallet.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAGnC;;;;GAIG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAexE;AAED,wBAAgB,iBAAiB,IAAI,OAAO,CAwB3C"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `wallet` command group reports on local wallet storage (`~/.config/did-cli-wallet/`)
|
|
3
|
+
* as a whole. `ls` prints a summary of how many items are saved in each
|
|
4
|
+
* collection (keys, DIDs, zcaps, credentials, WAS spaces).
|
|
5
|
+
*/
|
|
6
|
+
import { Command } from 'commander';
|
|
7
|
+
import { listCollection, listDids } from '../storage.js';
|
|
8
|
+
/**
|
|
9
|
+
* Count the items saved in each wallet collection.
|
|
10
|
+
*
|
|
11
|
+
* @returns {Promise<Record<string, number>>} collection label to item count.
|
|
12
|
+
*/
|
|
13
|
+
export async function countCollections() {
|
|
14
|
+
const [keys, dids, zcaps, vcs, spaces] = await Promise.all([
|
|
15
|
+
listCollection('keys'),
|
|
16
|
+
listDids(),
|
|
17
|
+
listCollection('zcaps'),
|
|
18
|
+
listCollection('credentials'),
|
|
19
|
+
listCollection('was-spaces')
|
|
20
|
+
]);
|
|
21
|
+
return {
|
|
22
|
+
keys: keys.length,
|
|
23
|
+
dids: dids.length,
|
|
24
|
+
zcaps: zcaps.length,
|
|
25
|
+
vcs: vcs.length,
|
|
26
|
+
spaces: spaces.length
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export function makeWalletCommand() {
|
|
30
|
+
const wallet = new Command('wallet').description('Inspect local wallet storage');
|
|
31
|
+
wallet
|
|
32
|
+
.command('ls')
|
|
33
|
+
.alias('list')
|
|
34
|
+
.description('Show a summary of local wallet storage (item counts per collection)')
|
|
35
|
+
.option('--json', 'output the summary as a JSON object')
|
|
36
|
+
.action(async (options) => {
|
|
37
|
+
const counts = await countCollections();
|
|
38
|
+
if (options.json) {
|
|
39
|
+
console.log(JSON.stringify(counts, null, 2));
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
for (const [collection, count] of Object.entries(counts)) {
|
|
43
|
+
console.log(`${collection}: ${count}`);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
return wallet;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=wallet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallet.js","sourceRoot":"","sources":["../../src/commands/wallet.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAExD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACzD,cAAc,CAAC,MAAM,CAAC;QACtB,QAAQ,EAAE;QACV,cAAc,CAAC,OAAO,CAAC;QACvB,cAAc,CAAC,aAAa,CAAC;QAC7B,cAAc,CAAC,YAAY,CAAC;KAC7B,CAAC,CAAA;IACF,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,MAAM;QACjB,IAAI,EAAE,IAAI,CAAC,MAAM;QACjB,KAAK,EAAE,KAAK,CAAC,MAAM;QACnB,GAAG,EAAE,GAAG,CAAC,MAAM;QACf,MAAM,EAAE,MAAM,CAAC,MAAM;KACtB,CAAA;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,MAAM,MAAM,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,CAC9C,8BAA8B,CAC/B,CAAA;IAED,MAAM;SACH,OAAO,CAAC,IAAI,CAAC;SACb,KAAK,CAAC,MAAM,CAAC;SACb,WAAW,CACV,qEAAqE,CACtE;SACA,MAAM,CAAC,QAAQ,EAAE,qCAAqC,CAAC;SACvD,MAAM,CAAC,KAAK,EAAE,OAA2B,EAAE,EAAE;QAC5C,MAAM,MAAM,GAAG,MAAM,gBAAgB,EAAE,CAAA;QACvC,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;YAC5C,OAAM;QACR,CAAC;QACD,KAAK,MAAM,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACzD,OAAO,CAAC,GAAG,CAAC,GAAG,UAAU,KAAK,KAAK,EAAE,CAAC,CAAA;QACxC,CAAC;IACH,CAAC,CAAC,CAAA;IAEJ,OAAO,MAAM,CAAA;AACf,CAAC"}
|