@interop/did-cli 0.12.0 → 0.14.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 +131 -6
- package/README.md +184 -18
- package/dist/commands/did/create.d.ts +22 -0
- package/dist/commands/did/create.d.ts.map +1 -1
- package/dist/commands/did/create.js +6 -27
- package/dist/commands/did/create.js.map +1 -1
- package/dist/commands/did/service.d.ts +19 -4
- package/dist/commands/did/service.d.ts.map +1 -1
- package/dist/commands/did/service.js +46 -45
- package/dist/commands/did/service.js.map +1 -1
- package/dist/commands/did/webvh-update.d.ts +72 -9
- package/dist/commands/did/webvh-update.d.ts.map +1 -1
- package/dist/commands/did/webvh-update.js +177 -61
- package/dist/commands/did/webvh-update.js.map +1 -1
- package/dist/commands/did.d.ts.map +1 -1
- package/dist/commands/did.js +10 -1
- package/dist/commands/did.js.map +1 -1
- package/dist/commands/key.d.ts +2 -16
- package/dist/commands/key.d.ts.map +1 -1
- package/dist/commands/key.js +64 -11
- package/dist/commands/key.js.map +1 -1
- package/dist/commands/was/request-grant.d.ts +37 -0
- package/dist/commands/was/request-grant.d.ts.map +1 -0
- package/dist/commands/was/request-grant.js +248 -0
- package/dist/commands/was/request-grant.js.map +1 -0
- package/dist/commands/was/resource.d.ts +21 -7
- package/dist/commands/was/resource.d.ts.map +1 -1
- package/dist/commands/was/resource.js +40 -15
- package/dist/commands/was/resource.js.map +1 -1
- package/dist/commands/was/shared.d.ts +43 -3
- package/dist/commands/was/shared.d.ts.map +1 -1
- package/dist/commands/was/shared.js +82 -4
- package/dist/commands/was/shared.js.map +1 -1
- package/dist/commands/was/shell/completer.d.ts +24 -0
- package/dist/commands/was/shell/completer.d.ts.map +1 -0
- package/dist/commands/was/shell/completer.js +99 -0
- package/dist/commands/was/shell/completer.js.map +1 -0
- package/dist/commands/was/shell/dispatcher.d.ts +27 -0
- package/dist/commands/was/shell/dispatcher.d.ts.map +1 -0
- package/dist/commands/was/shell/dispatcher.js +227 -0
- package/dist/commands/was/shell/dispatcher.js.map +1 -0
- package/dist/commands/was/shell/session.d.ts +37 -0
- package/dist/commands/was/shell/session.d.ts.map +1 -0
- package/dist/commands/was/shell/session.js +67 -0
- package/dist/commands/was/shell/session.js.map +1 -0
- package/dist/commands/was/shell/tokenize.d.ts +19 -0
- package/dist/commands/was/shell/tokenize.d.ts.map +1 -0
- package/dist/commands/was/shell/tokenize.js +77 -0
- package/dist/commands/was/shell/tokenize.js.map +1 -0
- package/dist/commands/was/shell.d.ts +30 -0
- package/dist/commands/was/shell.d.ts.map +1 -0
- package/dist/commands/was/shell.js +170 -0
- package/dist/commands/was/shell.js.map +1 -0
- package/dist/commands/was/tree.d.ts +6 -1
- package/dist/commands/was/tree.d.ts.map +1 -1
- package/dist/commands/was/tree.js +12 -5
- package/dist/commands/was/tree.js.map +1 -1
- package/dist/commands/was.d.ts.map +1 -1
- package/dist/commands/was.js +31 -1
- package/dist/commands/was.js.map +1 -1
- package/dist/keys/seed.d.ts +21 -0
- package/dist/keys/seed.d.ts.map +1 -0
- package/dist/keys/seed.js +41 -0
- package/dist/keys/seed.js.map +1 -0
- package/dist/keys/webvh-signer.d.ts +18 -13
- package/dist/keys/webvh-signer.d.ts.map +1 -1
- package/dist/keys/webvh-signer.js +5 -20
- package/dist/keys/webvh-signer.js.map +1 -1
- package/dist/meta.js +1 -1
- package/dist/meta.js.map +1 -1
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +57 -10
- package/dist/storage.js.map +1 -1
- package/dist/was/address.d.ts +24 -0
- package/dist/was/address.d.ts.map +1 -1
- package/dist/was/address.js +49 -3
- package/dist/was/address.js.map +1 -1
- package/dist/was/request-grant.d.ts +144 -0
- package/dist/was/request-grant.d.ts.map +1 -0
- package/dist/was/request-grant.js +249 -0
- package/dist/was/request-grant.js.map +1 -0
- package/package.json +22 -20
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The interactive shell's per-line dispatcher: tokenizes a line, handles the
|
|
3
|
+
* builtins (`cd`/`use`, `pwd`, `connect`, `did`, `help`, `exit`/`quit`, blank
|
|
4
|
+
* and `#`-comment lines, and a rejected nested `shell`), guards stdin-payload
|
|
5
|
+
* commands that would fight readline for stdin, then hands the rest to the
|
|
6
|
+
* shared command tree via `parseAsync`. Command errors are reported by the
|
|
7
|
+
* commands themselves (and swallowed as `CommanderError`s here), so a bad line
|
|
8
|
+
* never stops the loop.
|
|
9
|
+
*/
|
|
10
|
+
import { CommanderError } from 'commander';
|
|
11
|
+
import { tokenizeShellLine } from './tokenize.js';
|
|
12
|
+
import { formatCwd, resolveCwdChange } from './session.js';
|
|
13
|
+
/**
|
|
14
|
+
* A summary of the shell builtins, printed by `help` before commander's own
|
|
15
|
+
* command help.
|
|
16
|
+
*/
|
|
17
|
+
const BUILTINS_HELP = `Shell builtins:
|
|
18
|
+
cd / use <path> change the current directory (SPACE[/COLLECTION], .., /, or a full space URL)
|
|
19
|
+
pwd print the current directory and effective server/DID
|
|
20
|
+
connect <url> set the session WAS server URL (WAS_SERVER_URL)
|
|
21
|
+
did <ref> set the session signing DID (WAS_DID)
|
|
22
|
+
help show this summary and the command help
|
|
23
|
+
exit / quit leave the shell (Ctrl+D also works)
|
|
24
|
+
|
|
25
|
+
`;
|
|
26
|
+
/**
|
|
27
|
+
* Options on the stdin-reading verbs that take a following value; used to
|
|
28
|
+
* count positional arguments when guarding stdin payloads and bare `ls`.
|
|
29
|
+
*/
|
|
30
|
+
const VALUE_FLAGS = new Set([
|
|
31
|
+
'--server',
|
|
32
|
+
'--did',
|
|
33
|
+
'--capability',
|
|
34
|
+
'--resource',
|
|
35
|
+
'--content-type',
|
|
36
|
+
'--output'
|
|
37
|
+
]);
|
|
38
|
+
const STDIN_GUARD_MESSAGE = 'Provide a file argument inside the shell (the shell owns stdin).';
|
|
39
|
+
/**
|
|
40
|
+
* Splits a verb's argument tokens into positionals and notes whether
|
|
41
|
+
* `--capability` was given, skipping the values of value-taking flags. Handles
|
|
42
|
+
* the `--flag=value` form (no separate value token) as well.
|
|
43
|
+
*
|
|
44
|
+
* @param rest {string[]}
|
|
45
|
+
* @returns {{positionals: string[], hasCapability: boolean}}
|
|
46
|
+
*/
|
|
47
|
+
function splitArgs(rest) {
|
|
48
|
+
const positionals = [];
|
|
49
|
+
let hasCapability = false;
|
|
50
|
+
for (let index = 0; index < rest.length; index++) {
|
|
51
|
+
const token = rest[index];
|
|
52
|
+
if (token.startsWith('-')) {
|
|
53
|
+
const name = token.split('=')[0];
|
|
54
|
+
if (name === '--capability') {
|
|
55
|
+
hasCapability = true;
|
|
56
|
+
}
|
|
57
|
+
if (!token.includes('=') && VALUE_FLAGS.has(name)) {
|
|
58
|
+
index++;
|
|
59
|
+
}
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
positionals.push(token);
|
|
63
|
+
}
|
|
64
|
+
return { positionals, hasCapability };
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Returns a guard message when a line would run a stdin-reading verb (`put`,
|
|
68
|
+
* `add`, or `space import`) with no file argument -- which cannot work while
|
|
69
|
+
* readline owns stdin -- or undefined when the line is safe to dispatch.
|
|
70
|
+
*
|
|
71
|
+
* @param tokens {string[]}
|
|
72
|
+
* @returns {string | undefined}
|
|
73
|
+
*/
|
|
74
|
+
function guardStdinPayload(tokens) {
|
|
75
|
+
const [head, ...tail] = tokens;
|
|
76
|
+
let group;
|
|
77
|
+
let verb = head;
|
|
78
|
+
let rest = tail;
|
|
79
|
+
if (head === 'resource' || head === 'res' || head === 'space') {
|
|
80
|
+
group = head;
|
|
81
|
+
verb = tail[0];
|
|
82
|
+
rest = tail.slice(1);
|
|
83
|
+
}
|
|
84
|
+
if (verb === 'put' || verb === 'add') {
|
|
85
|
+
const { positionals, hasCapability } = splitArgs(rest);
|
|
86
|
+
const fileProvided = hasCapability
|
|
87
|
+
? positionals.length >= 1
|
|
88
|
+
: positionals.length >= 2;
|
|
89
|
+
if (!fileProvided) {
|
|
90
|
+
return STDIN_GUARD_MESSAGE;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (group === 'space' && verb === 'import') {
|
|
94
|
+
const { positionals } = splitArgs(rest);
|
|
95
|
+
if (positionals.length < 2) {
|
|
96
|
+
return STDIN_GUARD_MESSAGE;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Appends `.` to a bare `ls` when a directory is selected, so it lists the
|
|
103
|
+
* current directory (the address base turns `.` into the cwd). At the root
|
|
104
|
+
* `ls` has nothing to list and is left alone.
|
|
105
|
+
*
|
|
106
|
+
* @param options {object}
|
|
107
|
+
* @param options.tokens {string[]}
|
|
108
|
+
* @param options.session {ShellSession}
|
|
109
|
+
* @returns {string[]}
|
|
110
|
+
*/
|
|
111
|
+
function appendCwdForBareLs({ tokens, session }) {
|
|
112
|
+
if (tokens[0] !== 'ls' || session.cwd.length === 0) {
|
|
113
|
+
return tokens;
|
|
114
|
+
}
|
|
115
|
+
const { positionals } = splitArgs(tokens.slice(1));
|
|
116
|
+
return positionals.length > 0 ? tokens : [...tokens, '.'];
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Handles `cd`/`use`: updates the session cwd, adopting a full space URL's
|
|
120
|
+
* origin as the server default.
|
|
121
|
+
*/
|
|
122
|
+
function handleCd({ session, arg, output }) {
|
|
123
|
+
if (arg === undefined) {
|
|
124
|
+
session.cwd = [];
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
try {
|
|
128
|
+
const { cwd, server } = resolveCwdChange({ cwd: session.cwd, arg });
|
|
129
|
+
session.cwd = cwd;
|
|
130
|
+
if (server) {
|
|
131
|
+
process.env.WAS_SERVER_URL = server;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
output.write(`${err.message}\n`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Handles `pwd`: prints the current directory and the effective server/DID.
|
|
140
|
+
*/
|
|
141
|
+
function handlePwd({ session, output }) {
|
|
142
|
+
output.write(`${formatCwd(session.cwd)}\n`);
|
|
143
|
+
output.write(`server: ${process.env.WAS_SERVER_URL ?? '(unset)'}\n`);
|
|
144
|
+
output.write(`did: ${process.env.WAS_DID ?? '(unset)'}\n`);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Builds the per-line dispatch function bound to the command tree. The
|
|
148
|
+
* returned function reports `'exit'` when the loop should stop.
|
|
149
|
+
*
|
|
150
|
+
* @param options {object}
|
|
151
|
+
* @param options.tree {Command}
|
|
152
|
+
* @returns {(options: {line: string, session: ShellSession, output: NodeJS.WritableStream}) => Promise<'exit' | void>}
|
|
153
|
+
*/
|
|
154
|
+
export function makeWasShellDispatcher({ tree }) {
|
|
155
|
+
return async function dispatch({ line, session, output }) {
|
|
156
|
+
const trimmed = line.trim();
|
|
157
|
+
if (trimmed === '' || trimmed.startsWith('#')) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
let tokens;
|
|
161
|
+
try {
|
|
162
|
+
tokens = tokenizeShellLine(trimmed);
|
|
163
|
+
}
|
|
164
|
+
catch (err) {
|
|
165
|
+
output.write(`${err.message}\n`);
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
if (tokens.length === 0) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
const [command, ...args] = tokens;
|
|
172
|
+
switch (command) {
|
|
173
|
+
case 'exit':
|
|
174
|
+
case 'quit':
|
|
175
|
+
return 'exit';
|
|
176
|
+
case 'cd':
|
|
177
|
+
case 'use':
|
|
178
|
+
handleCd({ session, arg: args[0], output });
|
|
179
|
+
return;
|
|
180
|
+
case 'pwd':
|
|
181
|
+
handlePwd({ session, output });
|
|
182
|
+
return;
|
|
183
|
+
case 'connect':
|
|
184
|
+
if (!args[0]) {
|
|
185
|
+
output.write('Usage: connect <url>\n');
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
process.env.WAS_SERVER_URL = args[0];
|
|
189
|
+
output.write(`server: ${args[0]}\n`);
|
|
190
|
+
return;
|
|
191
|
+
case 'did':
|
|
192
|
+
if (!args[0]) {
|
|
193
|
+
output.write('Usage: did <ref>\n');
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
process.env.WAS_DID = args[0];
|
|
197
|
+
output.write(`did: ${args[0]}\n`);
|
|
198
|
+
return;
|
|
199
|
+
case 'help':
|
|
200
|
+
output.write(BUILTINS_HELP);
|
|
201
|
+
tree.outputHelp();
|
|
202
|
+
return;
|
|
203
|
+
case 'shell':
|
|
204
|
+
output.write('Already inside a shell; nested shells are not supported.\n');
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
const guardMessage = guardStdinPayload(tokens);
|
|
208
|
+
if (guardMessage) {
|
|
209
|
+
output.write(`${guardMessage}\n`);
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
try {
|
|
213
|
+
await tree.parseAsync(appendCwdForBareLs({ tokens, session }), {
|
|
214
|
+
from: 'user'
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
catch (err) {
|
|
218
|
+
// exitOverride throws after commander has already written help or the
|
|
219
|
+
// usage/error message through the configured output; nothing more to do.
|
|
220
|
+
if (err instanceof CommanderError) {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
output.write(`${err.message}\n`);
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=dispatcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["../../../../src/commands/was/shell/dispatcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The mutable interactive-shell session state. The signing server/DID defaults
|
|
3
|
+
* ride the `WAS_SERVER_URL` / `WAS_DID` environment channel (see
|
|
4
|
+
* `runWasShell`), so the session only tracks the working directory.
|
|
5
|
+
*/
|
|
6
|
+
export interface ShellSession {
|
|
7
|
+
/** The current path segments: `[]`, `[space]`, or `[space, collection]`. */
|
|
8
|
+
cwd: string[];
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Computes a new working directory from a `cd`/`use` argument. Supports an
|
|
12
|
+
* absolute path (leading `/`), `.`/`..` navigation, a relative path joined onto
|
|
13
|
+
* the current cwd, and a full space URL (which also yields the server origin to
|
|
14
|
+
* adopt as the session default). Throws when the result would descend past a
|
|
15
|
+
* collection.
|
|
16
|
+
*
|
|
17
|
+
* @param options {object}
|
|
18
|
+
* @param options.cwd {string[]} The current working directory segments.
|
|
19
|
+
* @param options.arg {string} The `cd`/`use` argument.
|
|
20
|
+
* @returns {{cwd: string[], server?: string}}
|
|
21
|
+
*/
|
|
22
|
+
export declare function resolveCwdChange({ cwd, arg }: {
|
|
23
|
+
cwd: string[];
|
|
24
|
+
arg: string;
|
|
25
|
+
}): {
|
|
26
|
+
cwd: string[];
|
|
27
|
+
server?: string;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Formats a working directory for display in the prompt (`/`, `/space`, or
|
|
31
|
+
* `/space/collection`).
|
|
32
|
+
*
|
|
33
|
+
* @param cwd {string[]}
|
|
34
|
+
* @returns {string}
|
|
35
|
+
*/
|
|
36
|
+
export declare function formatCwd(cwd: string[]): string;
|
|
37
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../../src/commands/was/shell/session.ts"],"names":[],"mappings":"AASA;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,4EAA4E;IAC5E,GAAG,EAAE,MAAM,EAAE,CAAA;CACd;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,GAAG,EACH,GAAG,EACJ,EAAE;IACD,GAAG,EAAE,MAAM,EAAE,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;CACZ,GAAG;IAAE,GAAG,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAyCrC;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,CAE/C"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The interactive shell's working-directory model: a current path of up to two
|
|
3
|
+
* segments (`[]` root, `[space]`, or `[space, collection]`) plus the `cd`/`use`
|
|
4
|
+
* math that walks it. A WAS path is at most `SPACE/COLLECTION/RESOURCE` deep,
|
|
5
|
+
* so the cwd never descends past a collection (resources are leaves you `get`,
|
|
6
|
+
* not directories you enter).
|
|
7
|
+
*/
|
|
8
|
+
import { parseWasAddress, tryParseHttpUrl } from '../../../was/address.js';
|
|
9
|
+
/**
|
|
10
|
+
* Computes a new working directory from a `cd`/`use` argument. Supports an
|
|
11
|
+
* absolute path (leading `/`), `.`/`..` navigation, a relative path joined onto
|
|
12
|
+
* the current cwd, and a full space URL (which also yields the server origin to
|
|
13
|
+
* adopt as the session default). Throws when the result would descend past a
|
|
14
|
+
* collection.
|
|
15
|
+
*
|
|
16
|
+
* @param options {object}
|
|
17
|
+
* @param options.cwd {string[]} The current working directory segments.
|
|
18
|
+
* @param options.arg {string} The `cd`/`use` argument.
|
|
19
|
+
* @returns {{cwd: string[], server?: string}}
|
|
20
|
+
*/
|
|
21
|
+
export function resolveCwdChange({ cwd, arg }) {
|
|
22
|
+
if (tryParseHttpUrl(arg)) {
|
|
23
|
+
const parsed = parseWasAddress(arg);
|
|
24
|
+
if (parsed.resourceId !== undefined) {
|
|
25
|
+
throw new Error(`Cannot cd to "${arg}": it addresses a resource, not a directory.`);
|
|
26
|
+
}
|
|
27
|
+
const next = [parsed.spaceRef];
|
|
28
|
+
if (parsed.collectionId !== undefined) {
|
|
29
|
+
next.push(parsed.collectionId);
|
|
30
|
+
}
|
|
31
|
+
return { cwd: next, server: parsed.server };
|
|
32
|
+
}
|
|
33
|
+
let next;
|
|
34
|
+
let path = arg;
|
|
35
|
+
if (path.startsWith('/')) {
|
|
36
|
+
next = [];
|
|
37
|
+
path = path.slice(1);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
next = [...cwd];
|
|
41
|
+
}
|
|
42
|
+
for (const segment of path.split('/')) {
|
|
43
|
+
if (segment === '' || segment === '.') {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (segment === '..') {
|
|
47
|
+
next = next.slice(0, -1);
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
next.push(segment);
|
|
51
|
+
}
|
|
52
|
+
if (next.length > 2) {
|
|
53
|
+
throw new Error(`Cannot cd to "${arg}": a WAS path is at most SPACE/COLLECTION deep.`);
|
|
54
|
+
}
|
|
55
|
+
return { cwd: next };
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Formats a working directory for display in the prompt (`/`, `/space`, or
|
|
59
|
+
* `/space/collection`).
|
|
60
|
+
*
|
|
61
|
+
* @param cwd {string[]}
|
|
62
|
+
* @returns {string}
|
|
63
|
+
*/
|
|
64
|
+
export function formatCwd(cwd) {
|
|
65
|
+
return `/${cwd.join('/')}`;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../../../src/commands/was/shell/session.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAY1E;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAC/B,GAAG,EACH,GAAG,EAIJ;IACC,IAAI,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,CAAA;QACnC,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CACb,iBAAiB,GAAG,8CAA8C,CACnE,CAAA;QACH,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QAC9B,IAAI,MAAM,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;YACtC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;QAChC,CAAC;QACD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAA;IAC7C,CAAC;IAED,IAAI,IAAc,CAAA;IAClB,IAAI,IAAI,GAAG,GAAG,CAAA;IACd,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACzB,IAAI,GAAG,EAAE,CAAA;QACT,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IACtB,CAAC;SAAM,CAAC;QACN,IAAI,GAAG,CAAC,GAAG,GAAG,CAAC,CAAA;IACjB,CAAC;IAED,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACtC,IAAI,OAAO,KAAK,EAAE,IAAI,OAAO,KAAK,GAAG,EAAE,CAAC;YACtC,SAAQ;QACV,CAAC;QACD,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACrB,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YACxB,SAAQ;QACV,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACpB,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CACb,iBAAiB,GAAG,iDAAiD,CACtE,CAAA;IACH,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,CAAA;AACtB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,GAAa;IACrC,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAA;AAC5B,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Splits an interactive-shell input line into argv tokens, honoring single
|
|
3
|
+
* quotes, double quotes, and backslash escapes so quoted paths and payloads
|
|
4
|
+
* survive the trip to commander. Kept dependency-free, consistent with the
|
|
5
|
+
* project's no-inquirer / no-chalk stance.
|
|
6
|
+
*
|
|
7
|
+
* Quoting rules mirror a POSIX shell closely enough for path entry: single
|
|
8
|
+
* quotes are literal (no escapes inside), double quotes allow backslash to
|
|
9
|
+
* escape the next character, and a bare backslash escapes the next character.
|
|
10
|
+
* An unterminated quote throws.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Tokenizes a shell input line into argv-style tokens.
|
|
14
|
+
*
|
|
15
|
+
* @param line {string}
|
|
16
|
+
* @returns {string[]}
|
|
17
|
+
*/
|
|
18
|
+
export declare function tokenizeShellLine(line: string): string[];
|
|
19
|
+
//# sourceMappingURL=tokenize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenize.d.ts","sourceRoot":"","sources":["../../../../src/commands/was/shell/tokenize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CA8DxD"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Splits an interactive-shell input line into argv tokens, honoring single
|
|
3
|
+
* quotes, double quotes, and backslash escapes so quoted paths and payloads
|
|
4
|
+
* survive the trip to commander. Kept dependency-free, consistent with the
|
|
5
|
+
* project's no-inquirer / no-chalk stance.
|
|
6
|
+
*
|
|
7
|
+
* Quoting rules mirror a POSIX shell closely enough for path entry: single
|
|
8
|
+
* quotes are literal (no escapes inside), double quotes allow backslash to
|
|
9
|
+
* escape the next character, and a bare backslash escapes the next character.
|
|
10
|
+
* An unterminated quote throws.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Tokenizes a shell input line into argv-style tokens.
|
|
14
|
+
*
|
|
15
|
+
* @param line {string}
|
|
16
|
+
* @returns {string[]}
|
|
17
|
+
*/
|
|
18
|
+
export function tokenizeShellLine(line) {
|
|
19
|
+
const tokens = [];
|
|
20
|
+
let current = '';
|
|
21
|
+
let hasToken = false;
|
|
22
|
+
let quote;
|
|
23
|
+
for (let index = 0; index < line.length; index++) {
|
|
24
|
+
const char = line[index];
|
|
25
|
+
if (quote) {
|
|
26
|
+
if (char === quote) {
|
|
27
|
+
quote = undefined;
|
|
28
|
+
}
|
|
29
|
+
else if (char === '\\' && quote === '"') {
|
|
30
|
+
const next = line[index + 1];
|
|
31
|
+
if (next === undefined) {
|
|
32
|
+
current += char;
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
current += next;
|
|
36
|
+
index++;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
current += char;
|
|
41
|
+
}
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (char === '"' || char === "'") {
|
|
45
|
+
quote = char;
|
|
46
|
+
hasToken = true;
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (char === '\\') {
|
|
50
|
+
const next = line[index + 1];
|
|
51
|
+
if (next !== undefined) {
|
|
52
|
+
current += next;
|
|
53
|
+
index++;
|
|
54
|
+
}
|
|
55
|
+
hasToken = true;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (char === ' ' || char === '\t') {
|
|
59
|
+
if (hasToken) {
|
|
60
|
+
tokens.push(current);
|
|
61
|
+
current = '';
|
|
62
|
+
hasToken = false;
|
|
63
|
+
}
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
current += char;
|
|
67
|
+
hasToken = true;
|
|
68
|
+
}
|
|
69
|
+
if (quote) {
|
|
70
|
+
throw new Error('Unterminated quote in input.');
|
|
71
|
+
}
|
|
72
|
+
if (hasToken) {
|
|
73
|
+
tokens.push(current);
|
|
74
|
+
}
|
|
75
|
+
return tokens;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=tokenize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenize.js","sourceRoot":"","sources":["../../../../src/commands/was/shell/tokenize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,MAAM,MAAM,GAAa,EAAE,CAAA;IAC3B,IAAI,OAAO,GAAG,EAAE,CAAA;IAChB,IAAI,QAAQ,GAAG,KAAK,CAAA;IACpB,IAAI,KAA4B,CAAA;IAEhC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QACjD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAA;QAExB,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;gBACnB,KAAK,GAAG,SAAS,CAAA;YACnB,CAAC;iBAAM,IAAI,IAAI,KAAK,IAAI,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;gBAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAA;gBAC5B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;oBACvB,OAAO,IAAI,IAAI,CAAA;gBACjB,CAAC;qBAAM,CAAC;oBACN,OAAO,IAAI,IAAI,CAAA;oBACf,KAAK,EAAE,CAAA;gBACT,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,IAAI,IAAI,CAAA;YACjB,CAAC;YACD,SAAQ;QACV,CAAC;QAED,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;YACjC,KAAK,GAAG,IAAI,CAAA;YACZ,QAAQ,GAAG,IAAI,CAAA;YACf,SAAQ;QACV,CAAC;QAED,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAClB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAA;YAC5B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,OAAO,IAAI,IAAI,CAAA;gBACf,KAAK,EAAE,CAAA;YACT,CAAC;YACD,QAAQ,GAAG,IAAI,CAAA;YACf,SAAQ;QACV,CAAC;QAED,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAClC,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;gBACpB,OAAO,GAAG,EAAE,CAAA;gBACZ,QAAQ,GAAG,KAAK,CAAA;YAClB,CAAC;YACD,SAAQ;QACV,CAAC;QAED,OAAO,IAAI,IAAI,CAAA;QACf,QAAQ,GAAG,IAAI,CAAA;IACjB,CAAC;IAED,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAA;IACjD,CAAC;IACD,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACtB,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
/**
|
|
3
|
+
* Builds the `shell [path]` command. `[path]` is the initial working directory
|
|
4
|
+
* and `--server`/`--did` seed the session defaults.
|
|
5
|
+
*
|
|
6
|
+
* @returns {Command}
|
|
7
|
+
*/
|
|
8
|
+
export declare function makeWasShellCommand(): Command;
|
|
9
|
+
/**
|
|
10
|
+
* Runs the interactive WAS shell: snapshots the env defaults, builds and
|
|
11
|
+
* shell-configures the command tree, and drives a readline question loop until
|
|
12
|
+
* `exit`/`quit` or end-of-input. Server/DID env defaults and the address base
|
|
13
|
+
* are restored on exit.
|
|
14
|
+
*
|
|
15
|
+
* @param options {object}
|
|
16
|
+
* @param [options.path] {string} Initial working directory.
|
|
17
|
+
* @param [options.server] {string} Initial `WAS_SERVER_URL` default.
|
|
18
|
+
* @param [options.did] {string} Initial `WAS_DID` default.
|
|
19
|
+
* @param [options.input] {NodeJS.ReadableStream} REPL input (defaults to stdin).
|
|
20
|
+
* @param [options.output] {NodeJS.WritableStream} REPL output (defaults to stderr).
|
|
21
|
+
* @returns {Promise<number>} The process exit code (always 0).
|
|
22
|
+
*/
|
|
23
|
+
export declare function runWasShell({ path, server, did, input, output }?: {
|
|
24
|
+
path?: string;
|
|
25
|
+
server?: string;
|
|
26
|
+
did?: string;
|
|
27
|
+
input?: NodeJS.ReadableStream;
|
|
28
|
+
output?: NodeJS.WritableStream;
|
|
29
|
+
}): Promise<number>;
|
|
30
|
+
//# sourceMappingURL=shell.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../../../src/commands/was/shell.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAWnC;;;;;GAKG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAiB7C;AA+CD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,WAAW,CAAC,EAChC,IAAI,EACJ,MAAM,EACN,GAAG,EACH,KAAqB,EACrB,MAAuB,EACxB,GAAE;IACD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC,cAAc,CAAA;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAA;CAC1B,GAAG,OAAO,CAAC,MAAM,CAAC,CAmFvB"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `was shell` -- an interactive REPL over the `was` command tree. It builds the
|
|
3
|
+
* existing `makeWasCommand()` tree once and re-`parseAsync`es it per input
|
|
4
|
+
* line, so every subcommand, the space registry, signer loading, and the
|
|
5
|
+
* address grammar are reused verbatim. A "current directory" (`cd`/`use`) makes
|
|
6
|
+
* paths relative via the `setWasAddressBase` seam, and the `setRunAndExitReporter`
|
|
7
|
+
* seam keeps a failing command from exiting the process.
|
|
8
|
+
*
|
|
9
|
+
* Session server/DID defaults ride the `WAS_SERVER_URL` / `WAS_DID` environment
|
|
10
|
+
* channel that `resolveWasTarget`/`buildWasClient` already read at the right
|
|
11
|
+
* precedence; the shell snapshots both at startup and restores them on exit.
|
|
12
|
+
*
|
|
13
|
+
* The prompt and diagnostics go to stderr (the readline `output`); command data
|
|
14
|
+
* stays on stdout via the commands' own `console.log`, so `di was shell < script`
|
|
15
|
+
* keeps a pipe-clean stdout.
|
|
16
|
+
*/
|
|
17
|
+
import { createInterface } from 'node:readline/promises';
|
|
18
|
+
import { Command } from 'commander';
|
|
19
|
+
import { setWasAddressBase } from '../../was/address.js';
|
|
20
|
+
import { didOption, serverOption, setRunAndExitReporter } from './shared.js';
|
|
21
|
+
import { makeWasShellDispatcher } from './shell/dispatcher.js';
|
|
22
|
+
import { makeShellCompleter } from './shell/completer.js';
|
|
23
|
+
import { formatCwd, resolveCwdChange } from './shell/session.js';
|
|
24
|
+
/**
|
|
25
|
+
* Builds the `shell [path]` command. `[path]` is the initial working directory
|
|
26
|
+
* and `--server`/`--did` seed the session defaults.
|
|
27
|
+
*
|
|
28
|
+
* @returns {Command}
|
|
29
|
+
*/
|
|
30
|
+
export function makeWasShellCommand() {
|
|
31
|
+
return new Command('shell')
|
|
32
|
+
.argument('[path]', 'initial working directory (SPACE[/COLLECTION])')
|
|
33
|
+
.description('Start an interactive WAS shell (REPL) for exploring spaces')
|
|
34
|
+
.addOption(serverOption())
|
|
35
|
+
.addOption(didOption())
|
|
36
|
+
.action(async (path, options) => {
|
|
37
|
+
const code = await runWasShell({ path, ...options });
|
|
38
|
+
if (code !== 0) {
|
|
39
|
+
process.exit(code);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Recursively applies `exitOverride()` (throw instead of `process.exit`) and
|
|
45
|
+
* routes commander's own output to the shell's stream, across the whole tree.
|
|
46
|
+
* `addCommand()` does not inherit these settings, so every subcommand must be
|
|
47
|
+
* configured explicitly.
|
|
48
|
+
*
|
|
49
|
+
* @param options {object}
|
|
50
|
+
* @param options.command {Command}
|
|
51
|
+
* @param options.output {NodeJS.WritableStream}
|
|
52
|
+
* @returns {void}
|
|
53
|
+
*/
|
|
54
|
+
function configureTreeForShell({ command, output }) {
|
|
55
|
+
command.exitOverride();
|
|
56
|
+
command.configureOutput({
|
|
57
|
+
writeOut: str => output.write(str),
|
|
58
|
+
writeErr: str => output.write(str)
|
|
59
|
+
});
|
|
60
|
+
for (const sub of command.commands) {
|
|
61
|
+
configureTreeForShell({ command: sub, output });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Sets or clears a process environment variable, deleting it when the value is
|
|
66
|
+
* undefined (so a snapshot restore removes vars that were unset at startup).
|
|
67
|
+
*
|
|
68
|
+
* @param options {object}
|
|
69
|
+
* @param options.key {string}
|
|
70
|
+
* @param [options.value] {string}
|
|
71
|
+
* @returns {void}
|
|
72
|
+
*/
|
|
73
|
+
function assignEnv({ key, value }) {
|
|
74
|
+
if (value === undefined) {
|
|
75
|
+
delete process.env[key];
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
process.env[key] = value;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Runs the interactive WAS shell: snapshots the env defaults, builds and
|
|
83
|
+
* shell-configures the command tree, and drives a readline question loop until
|
|
84
|
+
* `exit`/`quit` or end-of-input. Server/DID env defaults and the address base
|
|
85
|
+
* are restored on exit.
|
|
86
|
+
*
|
|
87
|
+
* @param options {object}
|
|
88
|
+
* @param [options.path] {string} Initial working directory.
|
|
89
|
+
* @param [options.server] {string} Initial `WAS_SERVER_URL` default.
|
|
90
|
+
* @param [options.did] {string} Initial `WAS_DID` default.
|
|
91
|
+
* @param [options.input] {NodeJS.ReadableStream} REPL input (defaults to stdin).
|
|
92
|
+
* @param [options.output] {NodeJS.WritableStream} REPL output (defaults to stderr).
|
|
93
|
+
* @returns {Promise<number>} The process exit code (always 0).
|
|
94
|
+
*/
|
|
95
|
+
export async function runWasShell({ path, server, did, input = process.stdin, output = process.stderr } = {}) {
|
|
96
|
+
// `makeWasCommand` is imported lazily to break the module cycle with was.ts
|
|
97
|
+
// (which wires this shell command into the tree).
|
|
98
|
+
const { makeWasCommand } = await import('../was.js');
|
|
99
|
+
const tree = makeWasCommand();
|
|
100
|
+
configureTreeForShell({ command: tree, output });
|
|
101
|
+
const savedServer = process.env.WAS_SERVER_URL;
|
|
102
|
+
const savedDid = process.env.WAS_DID;
|
|
103
|
+
if (server !== undefined) {
|
|
104
|
+
process.env.WAS_SERVER_URL = server;
|
|
105
|
+
}
|
|
106
|
+
if (did !== undefined) {
|
|
107
|
+
process.env.WAS_DID = did;
|
|
108
|
+
}
|
|
109
|
+
const session = { cwd: [] };
|
|
110
|
+
if (path) {
|
|
111
|
+
try {
|
|
112
|
+
const change = resolveCwdChange({ cwd: [], arg: path });
|
|
113
|
+
session.cwd = change.cwd;
|
|
114
|
+
if (change.server) {
|
|
115
|
+
process.env.WAS_SERVER_URL = change.server;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
catch (err) {
|
|
119
|
+
output.write(`${err.message}\n`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// Keep failing commands from exiting the process.
|
|
123
|
+
setRunAndExitReporter(() => { });
|
|
124
|
+
const terminal = Boolean(input.isTTY);
|
|
125
|
+
const rl = createInterface({
|
|
126
|
+
input,
|
|
127
|
+
output,
|
|
128
|
+
terminal,
|
|
129
|
+
completer: makeShellCompleter({ tree, session })
|
|
130
|
+
});
|
|
131
|
+
const dispatch = makeWasShellDispatcher({ tree });
|
|
132
|
+
// Ctrl+C clears the current line and re-prompts (best effort) rather than
|
|
133
|
+
// exiting; Ctrl+D / end-of-input ends the readline async iterator below.
|
|
134
|
+
let currentPrompt = '';
|
|
135
|
+
rl.on('SIGINT', () => {
|
|
136
|
+
output.write(`\n${currentPrompt}`);
|
|
137
|
+
});
|
|
138
|
+
if (terminal) {
|
|
139
|
+
output.write('Interactive WAS shell. Type "help" for builtins, "exit" to quit.\n');
|
|
140
|
+
}
|
|
141
|
+
// The readline async iterator (unlike a `question` loop) buffers input lines
|
|
142
|
+
// instead of dropping any that arrive between prompts -- essential for
|
|
143
|
+
// scripted input (`di was shell < script`).
|
|
144
|
+
const lines = rl[Symbol.asyncIterator]();
|
|
145
|
+
try {
|
|
146
|
+
for (;;) {
|
|
147
|
+
setWasAddressBase(session.cwd);
|
|
148
|
+
currentPrompt = `was:${formatCwd(session.cwd)}> `;
|
|
149
|
+
output.write(currentPrompt);
|
|
150
|
+
const next = await lines.next();
|
|
151
|
+
if (next.done) {
|
|
152
|
+
output.write('\n');
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
const outcome = await dispatch({ line: next.value, session, output });
|
|
156
|
+
if (outcome === 'exit') {
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
finally {
|
|
162
|
+
setWasAddressBase([]);
|
|
163
|
+
setRunAndExitReporter();
|
|
164
|
+
rl.close();
|
|
165
|
+
assignEnv({ key: 'WAS_SERVER_URL', value: savedServer });
|
|
166
|
+
assignEnv({ key: 'WAS_DID', value: savedDid });
|
|
167
|
+
}
|
|
168
|
+
return 0;
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=shell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell.js","sourceRoot":"","sources":["../../../src/commands/was/shell.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AACxD,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAC5E,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,EACL,SAAS,EACT,gBAAgB,EAEjB,MAAM,oBAAoB,CAAA;AAE3B;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB;IACjC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;SACxB,QAAQ,CAAC,QAAQ,EAAE,gDAAgD,CAAC;SACpE,WAAW,CAAC,4DAA4D,CAAC;SACzE,SAAS,CAAC,YAAY,EAAE,CAAC;SACzB,SAAS,CAAC,SAAS,EAAE,CAAC;SACtB,MAAM,CACL,KAAK,EACH,IAAwB,EACxB,OAA0C,EAC1C,EAAE;QACF,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,CAAC,CAAA;QACpD,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACpB,CAAC;IACH,CAAC,CACF,CAAA;AACL,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAS,qBAAqB,CAAC,EAC7B,OAAO,EACP,MAAM,EAIP;IACC,OAAO,CAAC,YAAY,EAAE,CAAA;IACtB,OAAO,CAAC,eAAe,CAAC;QACtB,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC;QAClC,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC;KACnC,CAAC,CAAA;IACF,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACnC,qBAAqB,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAA;IACjD,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,SAAS,CAAC,EAAE,GAAG,EAAE,KAAK,EAAmC;IAChE,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACzB,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;IAC1B,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,EAChC,IAAI,EACJ,MAAM,EACN,GAAG,EACH,KAAK,GAAG,OAAO,CAAC,KAAK,EACrB,MAAM,GAAG,OAAO,CAAC,MAAM,KAOrB,EAAE;IACJ,4EAA4E;IAC5E,kDAAkD;IAClD,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAA;IACpD,MAAM,IAAI,GAAG,cAAc,EAAE,CAAA;IAC7B,qBAAqB,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;IAEhD,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAA;IAC9C,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAA;IACpC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,cAAc,GAAG,MAAM,CAAA;IACrC,CAAC;IACD,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,OAAO,GAAG,GAAG,CAAA;IAC3B,CAAC;IAED,MAAM,OAAO,GAAiB,EAAE,GAAG,EAAE,EAAE,EAAE,CAAA;IACzC,IAAI,IAAI,EAAE,CAAC;QACT,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,gBAAgB,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAA;YACvD,OAAO,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAA;YACxB,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,cAAc,GAAG,MAAM,CAAC,MAAM,CAAA;YAC5C,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,KAAK,CAAC,GAAI,GAAa,CAAC,OAAO,IAAI,CAAC,CAAA;QAC7C,CAAC;IACH,CAAC;IAED,kDAAkD;IAClD,qBAAqB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;IAE/B,MAAM,QAAQ,GAAG,OAAO,CAAE,KAA2B,CAAC,KAAK,CAAC,CAAA;IAC5D,MAAM,EAAE,GAAG,eAAe,CAAC;QACzB,KAAK;QACL,MAAM;QACN,QAAQ;QACR,SAAS,EAAE,kBAAkB,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;KACjD,CAAC,CAAA;IAEF,MAAM,QAAQ,GAAG,sBAAsB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAA;IAEjD,0EAA0E;IAC1E,yEAAyE;IACzE,IAAI,aAAa,GAAG,EAAE,CAAA;IACtB,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QACnB,MAAM,CAAC,KAAK,CAAC,KAAK,aAAa,EAAE,CAAC,CAAA;IACpC,CAAC,CAAC,CAAA;IAEF,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,CAAC,KAAK,CACV,oEAAoE,CACrE,CAAA;IACH,CAAC;IAED,6EAA6E;IAC7E,uEAAuE;IACvE,4CAA4C;IAC5C,MAAM,KAAK,GAAG,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAA;IACxC,IAAI,CAAC;QACH,SAAS,CAAC;YACR,iBAAiB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YAC9B,aAAa,GAAG,OAAO,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAA;YACjD,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAA;YAC3B,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,IAAI,EAAE,CAAA;YAC/B,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;gBAClB,MAAK;YACP,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAA;YACrE,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;gBACvB,MAAK;YACP,CAAC;QACH,CAAC;IACH,CAAC;YAAS,CAAC;QACT,iBAAiB,CAAC,EAAE,CAAC,CAAA;QACrB,qBAAqB,EAAE,CAAA;QACvB,EAAE,CAAC,KAAK,EAAE,CAAA;QACV,SAAS,CAAC,EAAE,GAAG,EAAE,gBAAgB,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAA;QACxD,SAAS,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAA;IAChD,CAAC;IAED,OAAO,CAAC,CAAA;AACV,CAAC"}
|