@flighthq/shell 0.5.1-next.820.97b3830 → 0.5.1-next.903.f434bc2
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 +2 -2
- package/package.json +2 -2
- package/src/shell.test.ts +84 -37
package/README.md
CHANGED
|
@@ -13,5 +13,5 @@ Import the supported application-facing API from `@flighthq/shell`. The `@flight
|
|
|
13
13
|
This package is part of the locked-version Flight SDK graph. Applications may instead install and import `@flighthq/sdk` when package-level tree shaking is sufficient.
|
|
14
14
|
|
|
15
15
|
- [Flight project](https://github.com/flighthq/flight)
|
|
16
|
-
- [Source for @flighthq/shell@0.5.1-next.
|
|
17
|
-
- [License](https://github.com/flighthq/flight/blob/
|
|
16
|
+
- [Source for @flighthq/shell@0.5.1-next.903.f434bc2](https://github.com/flighthq/flight/tree/f434bc233778d75aeea61995df3a8cfaec459a85/packages/shell)
|
|
17
|
+
- [License](https://github.com/flighthq/flight/blob/f434bc233778d75aeea61995df3a8cfaec459a85/LICENSE.md)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flighthq/shell",
|
|
3
|
-
"version": "0.5.1-next.
|
|
3
|
+
"version": "0.5.1-next.903.f434bc2",
|
|
4
4
|
"author": "Joshua Granick and other contributors",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"clean:dist": "tsx ../../scripts/clean-package-dist.ts"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@flighthq/types": "0.5.1-next.
|
|
41
|
+
"@flighthq/types": "0.5.1-next.903.f434bc2"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@flighthq/entity": "*",
|
package/src/shell.test.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { allocateEntity, finishEntity } from '@flighthq/entity/contract';
|
|
2
2
|
import type {
|
|
3
3
|
EntityRuntimeKey,
|
|
4
4
|
HasShellBeep,
|
|
@@ -50,12 +50,14 @@ describe('moveShellItemsToTrash', () => {
|
|
|
50
50
|
const paths: string[] = [];
|
|
51
51
|
const resolvers: Array<(outcome: { reason: 'ok' | 'operation-failed' }) => void> = [];
|
|
52
52
|
const host = trashHost(
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
(() => {
|
|
54
|
+
const out = allocateEntity<any>();
|
|
55
|
+
out.moveToTrash = (path: string) => {
|
|
55
56
|
paths.push(path);
|
|
56
57
|
return new Promise((resolve) => resolvers.push(resolve));
|
|
57
|
-
}
|
|
58
|
-
|
|
58
|
+
};
|
|
59
|
+
return finishEntity(out);
|
|
60
|
+
})(),
|
|
59
61
|
);
|
|
60
62
|
|
|
61
63
|
const outcomes = moveShellItemsToTrash(host, ['/first', '/second']);
|
|
@@ -75,7 +77,18 @@ describe('moveShellItemsToTrash', () => {
|
|
|
75
77
|
describe('moveShellItemToTrash', () => {
|
|
76
78
|
it('routes through the supplied trash provider', async () => {
|
|
77
79
|
const moveToTrash = vi.fn(async () => ({ reason: 'ok' as const }));
|
|
78
|
-
await expect(
|
|
80
|
+
await expect(
|
|
81
|
+
moveShellItemToTrash(
|
|
82
|
+
trashHost(
|
|
83
|
+
(() => {
|
|
84
|
+
const out = allocateEntity<any>();
|
|
85
|
+
out.moveToTrash = moveToTrash;
|
|
86
|
+
return finishEntity(out);
|
|
87
|
+
})(),
|
|
88
|
+
),
|
|
89
|
+
'/item',
|
|
90
|
+
),
|
|
91
|
+
).resolves.toEqual({
|
|
79
92
|
reason: 'ok',
|
|
80
93
|
});
|
|
81
94
|
expect(moveToTrash).toHaveBeenCalledWith('/item');
|
|
@@ -91,7 +104,13 @@ describe('openShellExternalUrl', () => {
|
|
|
91
104
|
|
|
92
105
|
it('blocks before dispatch when the scheme is not allowed', async () => {
|
|
93
106
|
const open = vi.fn(async () => ({ reason: 'ok' as const }));
|
|
94
|
-
const host = externalHost(
|
|
107
|
+
const host = externalHost(
|
|
108
|
+
(() => {
|
|
109
|
+
const out = allocateEntity<any>();
|
|
110
|
+
out.open = open;
|
|
111
|
+
return finishEntity(out);
|
|
112
|
+
})(),
|
|
113
|
+
);
|
|
95
114
|
await expect(openShellExternalUrl(host, 'file:///etc/passwd', { allowedSchemes: ['https'] })).resolves.toEqual({
|
|
96
115
|
reason: 'blocked-scheme',
|
|
97
116
|
});
|
|
@@ -101,20 +120,24 @@ describe('openShellExternalUrl', () => {
|
|
|
101
120
|
it('keeps two live hosts isolated', async () => {
|
|
102
121
|
const calls: string[] = [];
|
|
103
122
|
const first = externalHost(
|
|
104
|
-
|
|
105
|
-
|
|
123
|
+
(() => {
|
|
124
|
+
const out = allocateEntity<any>();
|
|
125
|
+
out.open = async (url: string) => {
|
|
106
126
|
calls.push(`first:${url}`);
|
|
107
127
|
return { reason: 'ok' };
|
|
108
|
-
}
|
|
109
|
-
|
|
128
|
+
};
|
|
129
|
+
return finishEntity(out);
|
|
130
|
+
})(),
|
|
110
131
|
);
|
|
111
132
|
const second = externalHost(
|
|
112
|
-
|
|
113
|
-
|
|
133
|
+
(() => {
|
|
134
|
+
const out = allocateEntity<any>();
|
|
135
|
+
out.open = async (url: string) => {
|
|
114
136
|
calls.push(`second:${url}`);
|
|
115
137
|
return { reason: 'operation-failed' };
|
|
116
|
-
}
|
|
117
|
-
|
|
138
|
+
};
|
|
139
|
+
return finishEntity(out);
|
|
140
|
+
})(),
|
|
118
141
|
);
|
|
119
142
|
await expect(openShellExternalUrl(first, 'https://one.test', HTTPS_ONLY)).resolves.toEqual({ reason: 'ok' });
|
|
120
143
|
await expect(openShellExternalUrl(second, 'https://two.test', HTTPS_ONLY)).resolves.toEqual({
|
|
@@ -126,12 +149,11 @@ describe('openShellExternalUrl', () => {
|
|
|
126
149
|
|
|
127
150
|
describe('openShellPath', () => {
|
|
128
151
|
it('preserves a provider failure and its message', async () => {
|
|
129
|
-
const provider =
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
await expect(openShellPath(pathOpenHost(provider), '/missing')).resolves.toEqual({
|
|
152
|
+
const provider = allocateEntity<ShellPathOpenBackend>();
|
|
153
|
+
provider.open = async () => {
|
|
154
|
+
return { message: '', reason: 'operation-failed' as const };
|
|
155
|
+
};
|
|
156
|
+
await expect(openShellPath(pathOpenHost(finishEntity(provider)), '/missing')).resolves.toEqual({
|
|
135
157
|
message: '',
|
|
136
158
|
reason: 'operation-failed',
|
|
137
159
|
});
|
|
@@ -151,7 +173,18 @@ describe('readShellShortcutLink', () => {
|
|
|
151
173
|
describe('revealShellPath', () => {
|
|
152
174
|
it('returns the reveal-specific outcome', async () => {
|
|
153
175
|
const reveal = vi.fn(async () => ({ reason: 'operation-failed' as const }));
|
|
154
|
-
await expect(
|
|
176
|
+
await expect(
|
|
177
|
+
revealShellPath(
|
|
178
|
+
pathRevealHost(
|
|
179
|
+
(() => {
|
|
180
|
+
const out = allocateEntity<any>();
|
|
181
|
+
out.reveal = reveal;
|
|
182
|
+
return finishEntity(out);
|
|
183
|
+
})(),
|
|
184
|
+
),
|
|
185
|
+
'/item',
|
|
186
|
+
),
|
|
187
|
+
).resolves.toEqual({
|
|
155
188
|
reason: 'operation-failed',
|
|
156
189
|
});
|
|
157
190
|
});
|
|
@@ -160,7 +193,15 @@ describe('revealShellPath', () => {
|
|
|
160
193
|
describe('shellBeep', () => {
|
|
161
194
|
it('dispatches synchronously', () => {
|
|
162
195
|
const beep = vi.fn();
|
|
163
|
-
shellBeep(
|
|
196
|
+
shellBeep(
|
|
197
|
+
beepHost(
|
|
198
|
+
(() => {
|
|
199
|
+
const out = allocateEntity<any>();
|
|
200
|
+
out.beep = beep;
|
|
201
|
+
return finishEntity(out);
|
|
202
|
+
})(),
|
|
203
|
+
),
|
|
204
|
+
);
|
|
164
205
|
expect(beep).toHaveBeenCalledOnce();
|
|
165
206
|
});
|
|
166
207
|
});
|
|
@@ -176,7 +217,13 @@ describe('spawnShellProcess', () => {
|
|
|
176
217
|
it('forwards the command, argument vector, and options to the host backend unchanged', () => {
|
|
177
218
|
const process = shellProcess();
|
|
178
219
|
const spawn = vi.fn(() => process);
|
|
179
|
-
const host = processHost(
|
|
220
|
+
const host = processHost(
|
|
221
|
+
(() => {
|
|
222
|
+
const out = allocateEntity<any>();
|
|
223
|
+
out.spawn = spawn;
|
|
224
|
+
return finishEntity(out);
|
|
225
|
+
})(),
|
|
226
|
+
);
|
|
180
227
|
const args = ['--flag', 'value'] as const;
|
|
181
228
|
const options = { cwd: '/work', environment: { MODE: 'test' } } as const;
|
|
182
229
|
|
|
@@ -222,13 +269,13 @@ function processHost(process: ShellProcessBackend): ShellProcessHost {
|
|
|
222
269
|
}
|
|
223
270
|
|
|
224
271
|
function shellProcess(): ShellProcess {
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
272
|
+
const out = allocateEntity<any>();
|
|
273
|
+
out.exit = Promise.resolve({ code: 0, signal: null });
|
|
274
|
+
out.stderr = new ReadableStream<Uint8Array>();
|
|
275
|
+
out.stdin = new WritableStream<Uint8Array>();
|
|
276
|
+
out.stdout = new ReadableStream<Uint8Array>();
|
|
277
|
+
out.terminate = vi.fn();
|
|
278
|
+
return finishEntity(out);
|
|
232
279
|
}
|
|
233
280
|
|
|
234
281
|
function shortcutLinkHost(shortcutLink: ShellShortcutLinkBackend): HasShellShortcutLink {
|
|
@@ -236,12 +283,12 @@ function shortcutLinkHost(shortcutLink: ShellShortcutLinkBackend): HasShellShort
|
|
|
236
283
|
}
|
|
237
284
|
|
|
238
285
|
function shortcutLinkProvider(): ShellShortcutLinkBackend & { write: ReturnType<typeof vi.fn> } {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
286
|
+
const out = allocateEntity<any>();
|
|
287
|
+
out.read = async () => {
|
|
288
|
+
return { link: { target: '/app' }, reason: 'ok' };
|
|
289
|
+
};
|
|
290
|
+
out.write = vi.fn(async () => ({ reason: 'ok' as const }));
|
|
291
|
+
return finishEntity(out);
|
|
245
292
|
}
|
|
246
293
|
|
|
247
294
|
function trashHost(trash: ShellTrashBackend): HasShellTrash {
|