From 5992ed54d23f1d63870ab87c90f879eea92cc4e6 Mon Sep 17 00:00:00 2001 From: Dallas Hoffman Date: Wed, 10 Jul 2024 22:13:47 -0400 Subject: [PATCH] getDatabaseFile specifies MIME type and works with db in subfolder --- src/client.ts | 20 +++++++++++++++--- test/get-database-file.test.ts | 38 ++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 test/get-database-file.test.ts diff --git a/src/client.ts b/src/client.ts index c8d11de..82b43f1 100644 --- a/src/client.ts +++ b/src/client.ts @@ -275,9 +275,23 @@ export class SQLocal { }; getDatabaseFile = async () => { - const opfs = await navigator.storage.getDirectory(); - const fileHandle = await opfs.getFileHandle(this.databasePath); - return await fileHandle.getFile(); + const path = this.databasePath.split(/[\\/]/).filter((part) => part !== ''); + const fileName = path.pop(); + + if (!fileName) { + throw new Error('Failed to parse the database file name.'); + } + + let dirHandle = await navigator.storage.getDirectory(); + for (let dirName of path) + dirHandle = await dirHandle.getDirectoryHandle(dirName); + + const fileHandle = await dirHandle.getFileHandle(fileName); + const file = await fileHandle.getFile(); + + return new File([file], fileName, { + type: 'application/x-sqlite3', + }); }; overwriteDatabaseFile = async ( diff --git a/test/get-database-file.test.ts b/test/get-database-file.test.ts new file mode 100644 index 0000000..c3794db --- /dev/null +++ b/test/get-database-file.test.ts @@ -0,0 +1,38 @@ +import { describe, expect, it } from 'vitest'; +import { SQLocal } from '../src/index'; + +describe('getDatabaseFile', () => { + const fileName = 'get-database-file-test.sqlite3'; + const paths = [[], [''], ['top'], ['one', 'two']]; + + it('should return the requested database file', async () => { + for (let path of paths) { + const databasePath = [...path, fileName].join('/'); + const { sql, getDatabaseFile } = new SQLocal(databasePath); + + await sql`CREATE TABLE nums (num REAL NOT NULL)`; + const file = await getDatabaseFile(); + + expect(file).toBeInstanceOf(File); + expect(file.name).toBe(fileName); + expect(file.size).toBe(16384); + expect(file.type).toBe('application/x-sqlite3'); + + let dirHandle = await navigator.storage.getDirectory(); + + for (let dirName of path) { + if (dirName === '') continue; + dirHandle = await dirHandle.getDirectoryHandle(dirName); + } + + await dirHandle.removeEntry(fileName); + } + }); + + it('should throw when requested database has not been created', async () => { + const { getDatabaseFile } = new SQLocal(fileName); + expect(async () => await getDatabaseFile()).rejects.toThrowError( + 'A requested file or directory could not be found at the time an operation was processed.' + ); + }); +});