fix: support flexible path API for FileSystemStorage (v3.43.2 regression)

Root Cause:
- API mismatch between BrainyConfig.storage and StorageOptions
- Users pass `path: './data'` but storageFactory expected `rootDirectory`
- Result: user-specified paths were ignored, fallback used instead
- This caused 0 files to be written when custom paths were specified

The Fix (DRY + Zero-Config):
- Created getFileSystemPath() helper as single source of truth
- Supports ALL API variants:
  1. Official: { rootDirectory: '...' }
  2. User-friendly: { path: '...' }
  3. Nested: { options: { rootDirectory: '...' } }
  4. Nested path: { options: { path: '...' } }
- Maintains zero-config fallback: './brainy-data'

Impact:
- CRITICAL FIX: Restores filesystem persistence for all users
- No breaking changes - backward compatible with all APIs
- Tested: test-persistence script + 20 unit tests passed

Resolves: v3.43.2 critical regression (Bug #6)
This commit is contained in:
David Snelling 2025-10-14 13:32:43 -07:00
parent f0d2f473c8
commit 067335329d

View file

@ -52,6 +52,16 @@ export interface StorageOptions {
*/
rootDirectory?: string
/**
* Nested options object for backward compatibility with BrainyConfig.storage.options
* Supports flexible API patterns
*/
options?: {
rootDirectory?: string
path?: string
[key: string]: any
}
/**
* Configuration for Amazon S3 storage
*/
@ -259,6 +269,21 @@ export interface StorageOptions {
}
}
/**
* Extract filesystem root directory from options
* Single source of truth for path resolution - supports all API variants
* Zero-config philosophy: flexible input, predictable output
*/
function getFileSystemPath(options: StorageOptions): string {
return (
options.rootDirectory || // Official storageFactory API
(options as any).path || // User-friendly API
options.options?.rootDirectory || // Nested options API
options.options?.path || // Nested path API
'./brainy-data' // Zero-config fallback
)
}
/**
* Create a storage adapter based on the environment and configuration
* @param options Options for creating the storage adapter
@ -286,7 +311,7 @@ export async function createStorage(
const { FileSystemStorage } = await import(
'./adapters/fileSystemStorage.js'
)
return new FileSystemStorage(options.rootDirectory || './brainy-data')
return new FileSystemStorage(getFileSystemPath(options))
} catch (error) {
console.warn(
'Failed to load FileSystemStorage, falling back to memory storage:',
@ -339,7 +364,7 @@ export async function createStorage(
const { FileSystemStorage } = await import(
'./adapters/fileSystemStorage.js'
)
return new FileSystemStorage(options.rootDirectory || './brainy-data')
return new FileSystemStorage(getFileSystemPath(options))
} catch (error) {
console.warn(
'Failed to load FileSystemStorage, falling back to memory storage:',
@ -518,7 +543,7 @@ export async function createStorage(
const { FileSystemStorage } = await import(
'./adapters/fileSystemStorage.js'
)
return new FileSystemStorage(options.rootDirectory || './brainy-data')
return new FileSystemStorage(getFileSystemPath(options))
} catch (fsError) {
console.warn(
'Failed to load FileSystemStorage, falling back to memory storage:',