From 1813e4e3786a69f3d0cee8e5187dcf5b11f21a36 Mon Sep 17 00:00:00 2001 From: Andrew Chou Date: Tue, 7 Jan 2025 15:22:20 -0500 Subject: [PATCH] feat: update runtime.selectFile() to also return the file name --- src/main/app.js | 10 +++++++++- src/preload/main-window.js | 30 +++++++++++++++++++++++++----- src/preload/runtime.d.ts | 9 ++++++++- 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/src/main/app.js b/src/main/app.js index 9dbe630..2bb0b65 100644 --- a/src/main/app.js +++ b/src/main/app.js @@ -1,4 +1,5 @@ import { randomBytes } from 'node:crypto' +import { basename } from 'node:path' import { fileURLToPath } from 'node:url' import { defineMessages } from '@formatjs/intl' import debug from 'debug' @@ -243,7 +244,14 @@ function initMainWindow({ appMode, services }) { : undefined, }) - return result.filePaths[0] + const selectedFilePath = result.filePaths[0] + + if (!selectedFilePath) return undefined + + return { + name: basename(selectedFilePath), + path: selectedFilePath, + } }) APP_STATE.browserWindows.set(mainWindow, { diff --git a/src/preload/main-window.js b/src/preload/main-window.js index dfd7bfd..407d976 100644 --- a/src/preload/main-window.js +++ b/src/preload/main-window.js @@ -28,16 +28,36 @@ const runtimeApi = { // Files async selectFile(extensionFilters) { - const filePath = await ipcRenderer.invoke('files:select', { + /** @type {unknown} */ + const result = await ipcRenderer.invoke('files:select', { extensionFilters, }) - if (!(typeof filePath === 'string' || typeof filePath === 'undefined')) { - throw new Error(`File path is unexpected type: ${typeof filePath}`) - } + if (!result) return undefined + + validateSelectedFileResult(result) - return filePath + return result }, } +/** + * @param {NonNullable} value + * + * @returns {asserts value is import('./runtime.js').SelectedFile} + */ +function validateSelectedFileResult(value) { + if (!('path' in value && 'name' in value)) { + throw new Error('Value has invalid shape') + } + + if (typeof value.path !== 'string') { + throw new Error('Value has invalid path field') + } + + if (typeof value.name !== 'string') { + throw new Error('Value has invalid name field') + } +} + contextBridge.exposeInMainWorld('runtime', runtimeApi) diff --git a/src/preload/runtime.d.ts b/src/preload/runtime.d.ts index ed7ef7c..b423aba 100644 --- a/src/preload/runtime.d.ts +++ b/src/preload/runtime.d.ts @@ -1,5 +1,12 @@ +export type SelectedFile = { + name: string + path: string +} + export type RuntimeApi = { getLocale: () => Promise updateLocale: (locale: string) => void - selectFile: (extensionFilters?: Array) => Promise + selectFile: ( + extensionFilters?: Array, + ) => Promise }