Filesystem API

Save and open files through native system dialogs.

Overview

The Filesystem API allows your extension to save and open files through native system dialogs. All operations require user interaction, ensuring security and transparency.

import { useHaexClient } from '@haex-space/vault-sdk/vue'

const client = useHaexClient()

// All filesystem operations show native dialogs
// Users have full control over file access

// Save a file
await client.filesystem.saveFileAsync(data, options)

// Open/read a file
const file = await client.filesystem.openFileAsync(options)

// Display an image
await client.filesystem.showImageAsync(options)

All filesystem operations show native dialogs to the user. There is no silent file access.

Save File

Save data to a file using the native save dialog:

Save Text File

// saveFileAsync(data: Uint8Array, options?: SaveFileOptions): Promise<SaveFileResult | null>

// Save text as a file
const text = 'Hello, World!'
const encoder = new TextEncoder()
const data = encoder.encode(text)

const result = await client.filesystem.saveFileAsync(data, {
  defaultPath: 'hello.txt',
  filters: [
    { name: 'Text Files', extensions: ['txt'] },
    { name: 'All Files', extensions: ['*'] }
  ]
})

if (result) {
  console.log('Saved to:', result.path)
}

Save JSON File

// Save JSON data
const settings = { theme: 'dark', fontSize: 14 }
const json = JSON.stringify(settings, null, 2)
const data = new TextEncoder().encode(json)

await client.filesystem.saveFileAsync(data, {
  defaultPath: 'settings.json',
  filters: [{ name: 'JSON Files', extensions: ['json'] }]
})

Save Binary Data

// Save binary data (e.g., export)
const exportData = await generateExport()

await client.filesystem.saveFileAsync(exportData, {
  defaultPath: 'backup.dat',
  filters: [{ name: 'Backup Files', extensions: ['dat', 'bak'] }]
})

Open File

Open files using the native file picker:

Open Single File

// openFileAsync(options: OpenFileOptions): Promise<OpenFileResult>

// Open a text file
const result = await client.filesystem.openFileAsync({
  filters: [
    { name: 'Text Files', extensions: ['txt', 'md'] },
    { name: 'All Files', extensions: ['*'] }
  ],
  multiple: false
})

if (result.files.length > 0) {
  const file = result.files[0]
  console.log('File path:', file.path)
  console.log('File name:', file.name)
  console.log('File size:', file.size)

  // Read content
  const decoder = new TextDecoder()
  const content = decoder.decode(file.data)
  console.log('Content:', content)
}

Open Multiple Files

// Open multiple files
const result = await client.filesystem.openFileAsync({
  filters: [{ name: 'Images', extensions: ['png', 'jpg', 'gif'] }],
  multiple: true
})

for (const file of result.files) {
  console.log('Processing:', file.name)
  // Process each file...
}

Open and Parse JSON

// Open and parse JSON file
const result = await client.filesystem.openFileAsync({
  filters: [{ name: 'JSON Files', extensions: ['json'] }],
  multiple: false
})

if (result.files.length > 0) {
  const content = new TextDecoder().decode(result.files[0].data)
  const data = JSON.parse(content)
  console.log('Loaded data:', data)
}

Image Picker

Open an image picker with optional resizing:

// showImageAsync(options: ShowImageOptions): Promise<ShowImageResult>
// Opens an image picker and returns the selected image

const result = await client.filesystem.showImageAsync({
  maxWidth: 800,
  maxHeight: 600,
  quality: 0.8  // JPEG quality (0-1)
})

if (result.data) {
  // Use the image data
  const blob = new Blob([result.data], { type: result.mimeType })
  const url = URL.createObjectURL(blob)

  // Display in img element
  imageElement.src = url
}

No permissions are required for showImageAsync since it uses a system dialog.

Type Definitions

TypeScript interfaces for filesystem operations:

interface SaveFileOptions {
  defaultPath?: string
  filters?: FileFilter[]
}

interface SaveFileResult {
  path: string
}

interface OpenFileOptions {
  filters?: FileFilter[]
  multiple?: boolean
}

interface OpenFileResult {
  files: OpenedFile[]
}

interface OpenedFile {
  path: string
  name: string
  size: number
  data: Uint8Array
}

interface FileFilter {
  name: string      // Display name (e.g., "Text Files")
  extensions: string[]  // File extensions without dots (e.g., ["txt", "md"])
}

interface ShowImageOptions {
  maxWidth?: number
  maxHeight?: number
  quality?: number  // 0-1, JPEG quality
}

interface ShowImageResult {
  data: Uint8Array | null
  mimeType: string
  width: number
  height: number
}