@flighthq/dialog 0.1.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.
@@ -0,0 +1,32 @@
1
+ import type { DialogBackend, FileDialogHandle, MessageDialogOptions, MessageDialogResult, OpenDirectoryDialogOptions, OpenFileDialogOptions, PromptDialogOptions, SaveFileDialogOptions } from '@flighthq/types';
2
+ export declare function createWebDialogBackend(): DialogBackend;
3
+ export declare function getDialogBackend(): DialogBackend;
4
+ export declare function getWebDirectorySystemHandle(handle: Readonly<FileDialogHandle>): FileSystemDirectoryHandle | null;
5
+ export declare function getWebFileSystemHandle(handle: Readonly<FileDialogHandle>): FileSystemFileHandle | null;
6
+ export declare function setDialogBackend(backend: DialogBackend | null): void;
7
+ export declare function showConfirmDialog(options: Readonly<MessageDialogOptions>): Promise<boolean>;
8
+ export declare function showErrorBox(title: string, content: string): Promise<MessageDialogResult>;
9
+ export declare function showErrorDialog(options: Readonly<MessageDialogOptions>): Promise<MessageDialogResult>;
10
+ export declare function showInfoDialog(options: Readonly<MessageDialogOptions>): Promise<MessageDialogResult>;
11
+ export declare function showMessageDialog(options: Readonly<MessageDialogOptions>): Promise<MessageDialogResult>;
12
+ export declare function showOpenDirectoryDialog(options: Readonly<OpenDirectoryDialogOptions>): Promise<FileDialogHandle[]>;
13
+ export declare function showOpenFileDialog(options: Readonly<OpenFileDialogOptions>): Promise<FileDialogHandle[]>;
14
+ export declare function showPromptDialog(options: Readonly<PromptDialogOptions>): Promise<string | null>;
15
+ export declare function showSaveFileDialog(options: Readonly<SaveFileDialogOptions>): Promise<FileDialogHandle | null>;
16
+ export declare function showWarningDialog(options: Readonly<MessageDialogOptions>): Promise<MessageDialogResult>;
17
+ interface FileSystemFileHandle {
18
+ readonly kind: 'file';
19
+ readonly name: string;
20
+ getFile(): Promise<File>;
21
+ createWritable(): Promise<FileSystemWritableFileStream>;
22
+ }
23
+ interface FileSystemWritableFileStream {
24
+ write(data: BufferSource | Blob | string): Promise<void>;
25
+ close(): Promise<void>;
26
+ }
27
+ interface FileSystemDirectoryHandle {
28
+ readonly kind: 'directory';
29
+ readonly name: string;
30
+ }
31
+ export {};
32
+ //# sourceMappingURL=dialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../src/dialog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,gBAAgB,EAEhB,oBAAoB,EACpB,mBAAmB,EACnB,0BAA0B,EAC1B,qBAAqB,EACrB,mBAAmB,EACnB,qBAAqB,EACtB,MAAM,iBAAiB,CAAC;AAMzB,wBAAgB,sBAAsB,IAAI,aAAa,CA2CtD;AAGD,wBAAgB,gBAAgB,IAAI,aAAa,CAGhD;AAKD,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GAAG,yBAAyB,GAAG,IAAI,CAEhH;AAKD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GAAG,oBAAoB,GAAG,IAAI,CAEtG;AAGD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,GAAG,IAAI,CAEpE;AAGD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,QAAQ,CAAC,oBAAoB,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAE3F;AAID,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAEzF;AAGD,wBAAgB,eAAe,CAAC,OAAO,EAAE,QAAQ,CAAC,oBAAoB,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAErG;AAGD,wBAAgB,cAAc,CAAC,OAAO,EAAE,QAAQ,CAAC,oBAAoB,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAEpG;AAID,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,QAAQ,CAAC,oBAAoB,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAEvG;AAID,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,QAAQ,CAAC,0BAA0B,CAAC,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAElH;AAID,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,QAAQ,CAAC,qBAAqB,CAAC,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAExG;AAID,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,QAAQ,CAAC,mBAAmB,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAE/F;AAKD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,QAAQ,CAAC,qBAAqB,CAAC,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAE7G;AA+PD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,QAAQ,CAAC,oBAAoB,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAEvG;AAGD,UAAU,oBAAoB;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,cAAc,IAAI,OAAO,CAAC,4BAA4B,CAAC,CAAC;CACzD;AAED,UAAU,4BAA4B;IACpC,KAAK,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,UAAU,yBAAyB;IACjC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB"}
package/dist/dialog.js ADDED
@@ -0,0 +1,377 @@
1
+ // Builds the default web backend over file inputs, window dialogs, and the File System Access API
2
+ // where available. File pickers fall back to <input type=file> which cannot expose real host paths,
3
+ // so handles carry path: null on web. All API surfaces are guarded for jsdom/non-document hosts
4
+ // and resolve to sentinels rather than throwing.
5
+ export function createWebDialogBackend() {
6
+ return {
7
+ async confirm(options) {
8
+ if (typeof window === 'undefined' || typeof window.confirm !== 'function')
9
+ return false;
10
+ try {
11
+ // Coerce to a strict boolean: a real browser returns boolean, but jsdom can return undefined.
12
+ return window.confirm(options.message) === true;
13
+ }
14
+ catch {
15
+ return false;
16
+ }
17
+ },
18
+ async message(options) {
19
+ // The web platform has no multi-button/checkbox message box; alert() shows the text only and
20
+ // always yields button 0. Native hosts honor buttons, checkboxLabel, defaultId, and cancelId.
21
+ const checkboxChecked = options.checkboxChecked ?? false;
22
+ if (typeof window === 'undefined' || typeof window.alert !== 'function') {
23
+ return { buttonIndex: 0, cancelled: false, checkboxChecked };
24
+ }
25
+ try {
26
+ window.alert(options.message);
27
+ }
28
+ catch {
29
+ return { buttonIndex: 0, cancelled: false, checkboxChecked };
30
+ }
31
+ return { buttonIndex: 0, cancelled: false, checkboxChecked };
32
+ },
33
+ openDirectory(options) {
34
+ return openWebDirectoryDialog(options);
35
+ },
36
+ openFile(options) {
37
+ return openWebFileDialog(options);
38
+ },
39
+ async prompt(options) {
40
+ if (typeof window === 'undefined' || typeof window.prompt !== 'function')
41
+ return null;
42
+ try {
43
+ return window.prompt(options.message, options.defaultValue ?? '');
44
+ }
45
+ catch {
46
+ return null;
47
+ }
48
+ },
49
+ async saveFile(options) {
50
+ return saveWebFile(options);
51
+ },
52
+ };
53
+ }
54
+ // The active dialog backend, or a lazily-created web default. There is always a backend.
55
+ export function getDialogBackend() {
56
+ if (_backend === null)
57
+ _backend = createWebDialogBackend();
58
+ return _backend;
59
+ }
60
+ // Retrieves the underlying web FileSystemDirectoryHandle stashed for a dialog directory handle, if any.
61
+ // Used by @flighthq/filesystem or other I/O cells to traverse and read the directory natively.
62
+ // Returns null when the handle was produced by the legacy <input webkitdirectory> fallback.
63
+ export function getWebDirectorySystemHandle(handle) {
64
+ return _fileSystemDirectoryHandleRegistry.get(handle) ?? null;
65
+ }
66
+ // Retrieves the underlying web FileSystemFileHandle stashed for a dialog handle, if any.
67
+ // Used by @flighthq/filesystem or other I/O cells to access the writable/readable native handle.
68
+ // Returns null when the handle was produced by a legacy <input> fallback (no File System Access).
69
+ export function getWebFileSystemHandle(handle) {
70
+ return _fileSystemHandleRegistry.get(handle) ?? null;
71
+ }
72
+ // Installs a native host dialog backend; pass null to fall back to the web default.
73
+ export function setDialogBackend(backend) {
74
+ _backend = backend;
75
+ }
76
+ // Shows a yes/no confirmation. Returns false on cancel or when the host lacks the surface.
77
+ export function showConfirmDialog(options) {
78
+ return getDialogBackend().confirm(options);
79
+ }
80
+ // Shows an error-severity message box. Returns the pressed button index and final checkbox state
81
+ // (buttonIndex 0 on web alert/dismiss). Convenience over showMessageDialog({ kind: 'error' }).
82
+ export function showErrorBox(title, content) {
83
+ return getDialogBackend().message({ kind: 'error', message: content, title });
84
+ }
85
+ // Shows an error-severity message dialog. Returns the full result including cancelled flag.
86
+ export function showErrorDialog(options) {
87
+ return getDialogBackend().message({ ...options, kind: 'error' });
88
+ }
89
+ // Shows an info-severity message dialog. Returns the full result including cancelled flag.
90
+ export function showInfoDialog(options) {
91
+ return getDialogBackend().message({ ...options, kind: 'info' });
92
+ }
93
+ // Shows an informational message. Returns the pressed button index and final checkbox state
94
+ // (buttonIndex 0 and the requested checkbox value on web alert/dismiss).
95
+ export function showMessageDialog(options) {
96
+ return getDialogBackend().message(options);
97
+ }
98
+ // Shows a directory picker as a first-class call (distinct from showOpenFileDialog({ directory: true })).
99
+ // Returns selected directory handles ([] on cancel). On web, path is null in each handle.
100
+ export function showOpenDirectoryDialog(options) {
101
+ return getDialogBackend().openDirectory(options);
102
+ }
103
+ // Shows an open-file picker. Returns selected handles ([] on cancel). On web, path is null in each
104
+ // handle — browsers cannot expose real host paths. Use @flighthq/filesystem to read handle contents.
105
+ export function showOpenFileDialog(options) {
106
+ return getDialogBackend().openFile(options);
107
+ }
108
+ // Shows a text prompt. Returns the entered string, or null on cancel / when the host lacks the surface.
109
+ // Accepts an options object (title, message, defaultValue, placeholder) aligning it with its siblings.
110
+ export function showPromptDialog(options) {
111
+ return getDialogBackend().prompt(options);
112
+ }
113
+ // Shows a save-file picker. Returns a handle for the chosen destination, or null on cancel.
114
+ // On web, uses the File System Access API (showSaveFilePicker) when available, yielding a handle
115
+ // whose writable can be opened by @flighthq/filesystem. Falls back to null when the API is absent.
116
+ export function showSaveFileDialog(options) {
117
+ return getDialogBackend().saveFile(options);
118
+ }
119
+ let _backend = null;
120
+ // Builds a FileDialogFilter accept list for the File System Access API's 'types' option.
121
+ function buildFileSystemAccessTypes(filters) {
122
+ if (filters === undefined || filters.length === 0)
123
+ return undefined;
124
+ const types = [];
125
+ for (const filter of filters) {
126
+ const accept = {};
127
+ const extensions = filter.extensions.filter((e) => e !== '*').map((e) => (e.startsWith('.') ? e : `.${e}`));
128
+ if (extensions.length > 0) {
129
+ const mime = filter.mimeTypes && filter.mimeTypes.length > 0 ? filter.mimeTypes[0] : 'application/octet-stream';
130
+ accept[mime] = extensions;
131
+ }
132
+ if (filter.mimeTypes) {
133
+ for (const mime of filter.mimeTypes) {
134
+ if (!accept[mime])
135
+ accept[mime] = extensions;
136
+ }
137
+ }
138
+ if (Object.keys(accept).length === 0)
139
+ continue;
140
+ types.push({ accept, description: filter.name });
141
+ }
142
+ return types.length > 0 ? types : undefined;
143
+ }
144
+ // Builds the accept attribute value for a legacy <input type=file>.
145
+ function buildAcceptAttribute(filters) {
146
+ if (filters === undefined || filters.length === 0)
147
+ return '';
148
+ const parts = [];
149
+ for (const filter of filters) {
150
+ for (const extension of filter.extensions) {
151
+ if (extension === '*')
152
+ continue;
153
+ parts.push(extension.startsWith('.') ? extension : `.${extension}`);
154
+ }
155
+ if (filter.mimeTypes) {
156
+ for (const mime of filter.mimeTypes) {
157
+ parts.push(mime);
158
+ }
159
+ }
160
+ }
161
+ return parts.join(',');
162
+ }
163
+ // Maps a FileDialogStartIn value to a File System Access API startIn token.
164
+ // The File System Access API only accepts: 'desktop'|'documents'|'downloads'|'music'|'pictures'|'videos'
165
+ // Unsupported values ('home', 'temp', 'appData', 'cache') are silently dropped.
166
+ function toFileSystemAccessStartIn(startIn) {
167
+ const allowed = new Set(['desktop', 'documents', 'downloads', 'music', 'pictures', 'videos']);
168
+ return allowed.has(startIn) ? startIn : undefined;
169
+ }
170
+ // Opens a directory picker on web. Prefers the File System Access API showDirectoryPicker when
171
+ // available (Chrome/Edge 86+) with a readwrite mode that enables real directory handle I/O.
172
+ // Falls back to a webkitdirectory <input> (the legacy path that returns only File objects with
173
+ // no writable access), which is non-standard but broadly supported.
174
+ function openWebDirectoryDialog(options) {
175
+ // File System Access API path: showDirectoryPicker yields a real FileSystemDirectoryHandle.
176
+ if (typeof window !== 'undefined' &&
177
+ typeof window.showDirectoryPicker === 'function') {
178
+ return openDirectoryPickerAccessApi(options);
179
+ }
180
+ // Legacy fallback: <input webkitdirectory>
181
+ if (typeof document === 'undefined' || typeof document.createElement !== 'function') {
182
+ return Promise.resolve([]);
183
+ }
184
+ return new Promise((resolve) => {
185
+ try {
186
+ const input = document.createElement('input');
187
+ input.type = 'file';
188
+ if (options.multiple === true)
189
+ input.multiple = true;
190
+ // webkitdirectory is non-standard but the only browser path-less directory picker fallback.
191
+ input.webkitdirectory = true;
192
+ input.addEventListener('change', () => {
193
+ const files = input.files;
194
+ if (files === null || files.length === 0) {
195
+ resolve([]);
196
+ return;
197
+ }
198
+ // For directory inputs, each file's webkitRelativePath starts with the directory name.
199
+ // Derive unique directory handles from the top-level directory names.
200
+ const seenDirs = new Set();
201
+ const handles = [];
202
+ for (let i = 0; i < files.length; i++) {
203
+ const rel = files[i].webkitRelativePath ?? '';
204
+ const dirName = rel.split('/')[0] || files[i].name;
205
+ if (!seenDirs.has(dirName)) {
206
+ seenDirs.add(dirName);
207
+ handles.push({ kind: 'Directory', name: dirName, path: null });
208
+ }
209
+ }
210
+ resolve(handles);
211
+ });
212
+ input.addEventListener('cancel', () => resolve([]));
213
+ input.click();
214
+ }
215
+ catch {
216
+ resolve([]);
217
+ }
218
+ });
219
+ }
220
+ // Uses the File System Access API showDirectoryPicker. AbortError (user cancel) → sentinel [].
221
+ // SecurityError (permission denied) → sentinel []. Other errors → sentinel [].
222
+ // Stores the live FileSystemDirectoryHandle in the registry so @flighthq/filesystem can enumerate
223
+ // and read contents through the handle without requiring a path.
224
+ async function openDirectoryPickerAccessApi(options) {
225
+ const win = window;
226
+ if (typeof win.showDirectoryPicker !== 'function')
227
+ return [];
228
+ try {
229
+ const pickerOptions = {
230
+ // readwrite gives the most capability; if the user denies write permission the browser degrades.
231
+ mode: 'readwrite',
232
+ };
233
+ if (options.startIn !== undefined) {
234
+ const startIn = toFileSystemAccessStartIn(options.startIn);
235
+ if (startIn !== undefined)
236
+ pickerOptions.startIn = startIn;
237
+ }
238
+ const nativeHandle = await win.showDirectoryPicker(pickerOptions);
239
+ const handle = { kind: 'Directory', name: nativeHandle.name, path: null };
240
+ // Stash the live FileSystemDirectoryHandle so @flighthq/filesystem can traverse it.
241
+ _fileSystemDirectoryHandleRegistry.set(handle, nativeHandle);
242
+ return [handle];
243
+ }
244
+ catch {
245
+ // AbortError (cancel) and SecurityError (denied) both resolve to the sentinel.
246
+ return [];
247
+ }
248
+ }
249
+ // Opens a file picker on web. Uses the File System Access API (showOpenFilePicker) when available,
250
+ // stashing the live FileSystemFileHandle in the web handle registry for @flighthq/filesystem to read.
251
+ // Falls back to a transient <input type=file> for browsers without the API.
252
+ function openWebFileDialog(options) {
253
+ // File System Access API path (Chrome/Edge). Returns real writable handles.
254
+ if (typeof window !== 'undefined' &&
255
+ typeof window.showOpenFilePicker === 'function') {
256
+ return openFileSystemAccessPicker(options);
257
+ }
258
+ // Legacy <input type=file> fallback.
259
+ if (typeof document === 'undefined' || typeof document.createElement !== 'function') {
260
+ return Promise.resolve([]);
261
+ }
262
+ return new Promise((resolve) => {
263
+ try {
264
+ const input = document.createElement('input');
265
+ input.type = 'file';
266
+ if (options.multiple === true)
267
+ input.multiple = true;
268
+ if (options.directory === true) {
269
+ input.webkitdirectory = true;
270
+ }
271
+ const accept = buildAcceptAttribute(options.filters);
272
+ if (accept !== '')
273
+ input.accept = accept;
274
+ input.addEventListener('change', () => {
275
+ const files = input.files;
276
+ if (files === null || files.length === 0) {
277
+ resolve([]);
278
+ return;
279
+ }
280
+ const handles = [];
281
+ for (let i = 0; i < files.length; i++) {
282
+ handles.push({ kind: 'File', name: files[i].name, path: null });
283
+ }
284
+ resolve(handles);
285
+ });
286
+ // A cancelled picker fires no change event in many browsers; the 'cancel' event covers newer ones.
287
+ input.addEventListener('cancel', () => resolve([]));
288
+ input.click();
289
+ }
290
+ catch {
291
+ resolve([]);
292
+ }
293
+ });
294
+ }
295
+ // Uses the File System Access API showOpenFilePicker. AbortError (user cancel) → sentinel [].
296
+ // SecurityError (permission denied) → sentinel []. Other errors → sentinel [].
297
+ async function openFileSystemAccessPicker(options) {
298
+ const win = window;
299
+ const showPicker = win.showOpenFilePicker;
300
+ if (typeof showPicker !== 'function')
301
+ return [];
302
+ try {
303
+ const pickerOptions = {
304
+ multiple: options.multiple ?? false,
305
+ };
306
+ const types = buildFileSystemAccessTypes(options.filters);
307
+ if (types !== undefined)
308
+ pickerOptions.types = types;
309
+ if (options.startIn !== undefined) {
310
+ const startIn = toFileSystemAccessStartIn(options.startIn);
311
+ if (startIn !== undefined)
312
+ pickerOptions.startIn = startIn;
313
+ }
314
+ const nativeHandles = await showPicker.call(win, pickerOptions);
315
+ const handles = [];
316
+ for (const nativeHandle of nativeHandles) {
317
+ const handle = { kind: 'File', name: nativeHandle.name, path: null };
318
+ // Stash the live FileSystemFileHandle in the registry so @flighthq/filesystem can read it.
319
+ _fileSystemHandleRegistry.set(handle, nativeHandle);
320
+ handles.push(handle);
321
+ }
322
+ return handles;
323
+ }
324
+ catch {
325
+ // AbortError (cancel) and SecurityError (permission denied) both resolve to the sentinel.
326
+ return [];
327
+ }
328
+ }
329
+ // Uses the File System Access API showSaveFilePicker. Returns null on cancel or when unavailable.
330
+ async function saveWebFile(options) {
331
+ const win = window;
332
+ if (typeof win.showSaveFilePicker !== 'function') {
333
+ // The web platform cannot expose or choose a writable host path without this API.
334
+ return null;
335
+ }
336
+ try {
337
+ const pickerOptions = {};
338
+ if (options.defaultName !== undefined) {
339
+ pickerOptions.suggestedName = options.defaultName;
340
+ }
341
+ else if (options.defaultPath !== undefined) {
342
+ // Extract filename portion from the defaultPath for the suggestedName heuristic.
343
+ const parts = options.defaultPath.replace(/\\/g, '/').split('/');
344
+ pickerOptions.suggestedName = parts[parts.length - 1];
345
+ }
346
+ const types = buildFileSystemAccessTypes(options.filters);
347
+ if (types !== undefined)
348
+ pickerOptions.types = types;
349
+ if (options.startIn !== undefined) {
350
+ const startIn = toFileSystemAccessStartIn(options.startIn);
351
+ if (startIn !== undefined)
352
+ pickerOptions.startIn = startIn;
353
+ }
354
+ const nativeHandle = await win.showSaveFilePicker(pickerOptions);
355
+ const handle = { kind: 'File', name: nativeHandle.name, path: null };
356
+ // Stash the live FileSystemFileHandle for @flighthq/filesystem to write to.
357
+ _fileSystemHandleRegistry.set(handle, nativeHandle);
358
+ return handle;
359
+ }
360
+ catch {
361
+ return null;
362
+ }
363
+ }
364
+ // Registry mapping FileDialogHandle → live web FileSystemDirectoryHandle, enabling @flighthq/filesystem
365
+ // to enumerate and read directories without dialog owning the I/O. Populated by showDirectoryPicker path.
366
+ // Keys are plain FileDialogHandle objects (reference equality); values are the native handles.
367
+ const _fileSystemDirectoryHandleRegistry = new WeakMap();
368
+ // Registry mapping FileDialogHandle → live web FileSystemFileHandle, enabling @flighthq/filesystem
369
+ // to read from or write to a picked file without dialog owning the I/O. Dialog holds this registry
370
+ // because it is the only party that creates and observes the FileSystemFileHandle lifecycle.
371
+ // Keys are plain FileDialogHandle objects (reference equality); values are the native handles.
372
+ const _fileSystemHandleRegistry = new WeakMap();
373
+ // Shows a warning-severity message dialog. Returns the full result including cancelled flag.
374
+ export function showWarningDialog(options) {
375
+ return getDialogBackend().message({ ...options, kind: 'warning' });
376
+ }
377
+ //# sourceMappingURL=dialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog.js","sourceRoot":"","sources":["../src/dialog.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export * from './dialog';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export * from './dialog';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC"}
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@flighthq/dialog",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "default": "./dist/index.js"
11
+ }
12
+ },
13
+ "files": [
14
+ "dist",
15
+ "src/**/*.test.ts",
16
+ "!dist/**/*.test.js",
17
+ "!dist/**/*.test.d.ts",
18
+ "!dist/**/*.test.js.map",
19
+ "!dist/**/*.test.d.ts.map"
20
+ ],
21
+ "scripts": {
22
+ "build": "tsc -b",
23
+ "clean": "tsc -b --clean",
24
+ "test": "vitest run --config vitest.config.ts",
25
+ "test:watch": "vitest --watch --config vitest.config.ts",
26
+ "prepack": "npm run clean && npm run clean:dist && npm run build",
27
+ "clean:dist": "tsx ../../scripts/clean-package-dist.ts"
28
+ },
29
+ "dependencies": {
30
+ "@flighthq/types": "0.1.0"
31
+ },
32
+ "devDependencies": {
33
+ "typescript": "^5.3.0"
34
+ },
35
+ "description": "Native open/save file, message, confirm, and prompt dialogs over a swappable web/native backend",
36
+ "sideEffects": false
37
+ }
@@ -0,0 +1,286 @@
1
+ import type { DialogBackend, FileDialogHandle, MessageDialogResult } from '@flighthq/types';
2
+
3
+ import {
4
+ createWebDialogBackend,
5
+ getDialogBackend,
6
+ getWebDirectorySystemHandle,
7
+ getWebFileSystemHandle,
8
+ setDialogBackend,
9
+ showConfirmDialog,
10
+ showErrorBox,
11
+ showErrorDialog,
12
+ showInfoDialog,
13
+ showMessageDialog,
14
+ showOpenDirectoryDialog,
15
+ showOpenFileDialog,
16
+ showPromptDialog,
17
+ showSaveFileDialog,
18
+ showWarningDialog,
19
+ } from './dialog';
20
+
21
+ function fakeHandle(name: string): FileDialogHandle {
22
+ return { kind: 'File', name, path: '/tmp/' + name };
23
+ }
24
+
25
+ function fakeBackend(): DialogBackend & { lastPromptMessage: string | null } {
26
+ return {
27
+ lastPromptMessage: null,
28
+ async confirm() {
29
+ return true;
30
+ },
31
+ async message() {
32
+ return { buttonIndex: 2, cancelled: false, checkboxChecked: false };
33
+ },
34
+ async openDirectory() {
35
+ return [{ kind: 'Directory', name: 'mydir', path: '/tmp/mydir' }];
36
+ },
37
+ async openFile() {
38
+ return [fakeHandle('a.txt'), fakeHandle('b.txt')];
39
+ },
40
+ async prompt(options) {
41
+ this.lastPromptMessage = options.message;
42
+ return 'typed';
43
+ },
44
+ async saveFile() {
45
+ return fakeHandle('out.txt');
46
+ },
47
+ };
48
+ }
49
+
50
+ afterEach(() => setDialogBackend(null));
51
+
52
+ describe('createWebDialogBackend', () => {
53
+ it('confirm returns false in jsdom (no real confirm surface)', async () => {
54
+ const backend = createWebDialogBackend();
55
+ expect(typeof (await backend.confirm({ message: 'sure?' }))).toBe('boolean');
56
+ });
57
+
58
+ it('message returns a result object without throwing', async () => {
59
+ const backend = createWebDialogBackend();
60
+ const result = await backend.message({ message: 'hi', checkboxChecked: true });
61
+ expect(typeof result.buttonIndex).toBe('number');
62
+ expect(typeof result.checkboxChecked).toBe('boolean');
63
+ expect(typeof result.cancelled).toBe('boolean');
64
+ });
65
+
66
+ it('openDirectory returns a Promise', () => {
67
+ const backend = createWebDialogBackend();
68
+ expect(backend.openDirectory({})).toBeInstanceOf(Promise);
69
+ });
70
+
71
+ it('openFile returns a Promise', () => {
72
+ const backend = createWebDialogBackend();
73
+ expect(backend.openFile({})).toBeInstanceOf(Promise);
74
+ });
75
+
76
+ it('prompt returns a Promise', () => {
77
+ const backend = createWebDialogBackend();
78
+ // prompt opens an interactive window.prompt that may hang in jsdom; assert it returns a Promise.
79
+ expect(backend.prompt({ message: 'name?' })).toBeInstanceOf(Promise);
80
+ });
81
+
82
+ it('saveFile returns null when the File System Access API is absent', async () => {
83
+ const backend = createWebDialogBackend();
84
+ expect(await backend.saveFile({})).toBeNull();
85
+ });
86
+ });
87
+
88
+ describe('getDialogBackend', () => {
89
+ it('falls back to a web backend when none is set', () => {
90
+ expect(getDialogBackend()).not.toBeNull();
91
+ });
92
+
93
+ it('returns the registered backend', () => {
94
+ const backend = fakeBackend();
95
+ setDialogBackend(backend);
96
+ expect(getDialogBackend()).toBe(backend);
97
+ });
98
+ });
99
+
100
+ describe('getWebDirectorySystemHandle', () => {
101
+ it('returns null for a handle not produced by the File System Access API directory picker', () => {
102
+ const handle: FileDialogHandle = { kind: 'Directory', name: 'mydir', path: null };
103
+ expect(getWebDirectorySystemHandle(handle)).toBeNull();
104
+ });
105
+ });
106
+
107
+ describe('getWebFileSystemHandle', () => {
108
+ it('returns null for a handle not produced by the File System Access API', () => {
109
+ const handle: FileDialogHandle = { kind: 'File', name: 'test.txt', path: null };
110
+ expect(getWebFileSystemHandle(handle)).toBeNull();
111
+ });
112
+ });
113
+
114
+ describe('setDialogBackend', () => {
115
+ it('clears back to the web fallback when passed null', () => {
116
+ setDialogBackend(fakeBackend());
117
+ setDialogBackend(null);
118
+ expect(getDialogBackend()).not.toBeNull();
119
+ });
120
+ });
121
+
122
+ describe('showConfirmDialog', () => {
123
+ it('delegates to the active backend', async () => {
124
+ setDialogBackend(fakeBackend());
125
+ expect(await showConfirmDialog({ message: 'sure?' })).toBe(true);
126
+ });
127
+
128
+ it('returns a boolean from the web backend without throwing', async () => {
129
+ expect(typeof (await showConfirmDialog({ message: 'sure?' }))).toBe('boolean');
130
+ });
131
+ });
132
+
133
+ describe('showErrorBox', () => {
134
+ it('delegates to the active backend with kind error', async () => {
135
+ let capturedOptions: Parameters<DialogBackend['message']>[0] | null = null;
136
+ setDialogBackend({
137
+ ...fakeBackend(),
138
+ async message(options) {
139
+ capturedOptions = options;
140
+ return { buttonIndex: 0, cancelled: false, checkboxChecked: false };
141
+ },
142
+ });
143
+ await showErrorBox('Fatal', 'Something went wrong');
144
+ expect(capturedOptions).not.toBeNull();
145
+ expect(capturedOptions!.kind).toBe('error');
146
+ expect(capturedOptions!.title).toBe('Fatal');
147
+ expect(capturedOptions!.message).toBe('Something went wrong');
148
+ });
149
+
150
+ it('returns a MessageDialogResult from the web backend without throwing', async () => {
151
+ const result = await showErrorBox('Error', 'oops');
152
+ expect(typeof result.buttonIndex).toBe('number');
153
+ expect(typeof result.cancelled).toBe('boolean');
154
+ expect(typeof result.checkboxChecked).toBe('boolean');
155
+ });
156
+ });
157
+
158
+ describe('showErrorDialog', () => {
159
+ it('forces kind to error', async () => {
160
+ let capturedKind: string | undefined;
161
+ setDialogBackend({
162
+ ...fakeBackend(),
163
+ async message(options) {
164
+ capturedKind = options.kind;
165
+ return { buttonIndex: 0, cancelled: false, checkboxChecked: false };
166
+ },
167
+ });
168
+ await showErrorDialog({ message: 'boom' });
169
+ expect(capturedKind).toBe('error');
170
+ });
171
+ });
172
+
173
+ describe('showInfoDialog', () => {
174
+ it('forces kind to info', async () => {
175
+ let capturedKind: string | undefined;
176
+ setDialogBackend({
177
+ ...fakeBackend(),
178
+ async message(options) {
179
+ capturedKind = options.kind;
180
+ return { buttonIndex: 0, cancelled: false, checkboxChecked: false };
181
+ },
182
+ });
183
+ await showInfoDialog({ message: 'note' });
184
+ expect(capturedKind).toBe('info');
185
+ });
186
+ });
187
+
188
+ describe('showMessageDialog', () => {
189
+ it('delegates to the active backend', async () => {
190
+ setDialogBackend(fakeBackend());
191
+ const result = await showMessageDialog({ message: 'hello' });
192
+ expect(result.buttonIndex).toBe(2);
193
+ expect(typeof result.cancelled).toBe('boolean');
194
+ });
195
+
196
+ it('returns a result object from the web backend without throwing', async () => {
197
+ const result: MessageDialogResult = await showMessageDialog({ checkboxChecked: true, message: 'hello' });
198
+ expect(typeof result.buttonIndex).toBe('number');
199
+ expect(typeof result.checkboxChecked).toBe('boolean');
200
+ expect(typeof result.cancelled).toBe('boolean');
201
+ });
202
+ });
203
+
204
+ describe('showOpenDirectoryDialog', () => {
205
+ it('delegates to the active backend', async () => {
206
+ setDialogBackend(fakeBackend());
207
+ const handles = await showOpenDirectoryDialog({});
208
+ expect(handles).toHaveLength(1);
209
+ expect(handles[0].kind).toBe('Directory');
210
+ expect(handles[0].name).toBe('mydir');
211
+ });
212
+
213
+ it('passes startIn option to the backend', async () => {
214
+ let capturedOptions: Parameters<typeof showOpenDirectoryDialog>[0] | null = null;
215
+ setDialogBackend({
216
+ ...fakeBackend(),
217
+ async openDirectory(options) {
218
+ capturedOptions = options;
219
+ return [{ kind: 'Directory', name: 'docs', path: null }];
220
+ },
221
+ });
222
+ await showOpenDirectoryDialog({ startIn: 'documents' });
223
+ expect(capturedOptions).not.toBeNull();
224
+ expect(capturedOptions!.startIn).toBe('documents');
225
+ });
226
+
227
+ it('returns a Promise from the web backend', () => {
228
+ // Directory picker opens an interactive <input> that hangs in jsdom; assert it returns a Promise.
229
+ expect(showOpenDirectoryDialog({})).toBeInstanceOf(Promise);
230
+ });
231
+ });
232
+
233
+ describe('showOpenFileDialog', () => {
234
+ it('delegates to the active backend', async () => {
235
+ setDialogBackend(fakeBackend());
236
+ const handles = await showOpenFileDialog({ multiple: true });
237
+ expect(handles).toHaveLength(2);
238
+ expect(handles[0].kind).toBe('File');
239
+ expect(handles[0].name).toBe('a.txt');
240
+ });
241
+
242
+ it('returns handles with path from the fake backend', async () => {
243
+ setDialogBackend(fakeBackend());
244
+ const handles = await showOpenFileDialog({});
245
+ expect(handles[0].path).toBe('/tmp/a.txt');
246
+ });
247
+ });
248
+
249
+ describe('showPromptDialog', () => {
250
+ it('delegates to the active backend with options', async () => {
251
+ const backend = fakeBackend();
252
+ setDialogBackend(backend);
253
+ const result = await showPromptDialog({ message: 'name?', defaultValue: 'default' });
254
+ expect(result).toBe('typed');
255
+ expect(backend.lastPromptMessage).toBe('name?');
256
+ });
257
+ });
258
+
259
+ describe('showSaveFileDialog', () => {
260
+ it('delegates to the active backend', async () => {
261
+ setDialogBackend(fakeBackend());
262
+ const handle = await showSaveFileDialog({});
263
+ expect(handle).not.toBeNull();
264
+ expect(handle!.kind).toBe('File');
265
+ expect(handle!.name).toBe('out.txt');
266
+ });
267
+
268
+ it('returns null from the web backend when File System Access API is absent', async () => {
269
+ expect(await showSaveFileDialog({})).toBeNull();
270
+ });
271
+ });
272
+
273
+ describe('showWarningDialog', () => {
274
+ it('forces kind to warning', async () => {
275
+ let capturedKind: string | undefined;
276
+ setDialogBackend({
277
+ ...fakeBackend(),
278
+ async message(options) {
279
+ capturedKind = options.kind;
280
+ return { buttonIndex: 0, cancelled: false, checkboxChecked: false };
281
+ },
282
+ });
283
+ await showWarningDialog({ message: 'careful' });
284
+ expect(capturedKind).toBe('warning');
285
+ });
286
+ });