From 5f21dde652946b04a8898f3874c274548592fa60 Mon Sep 17 00:00:00 2001 From: James P Date: Tue, 7 May 2024 16:09:50 -0500 Subject: [PATCH] Enabled strict mode Fixed `WebAccessFS.stat` returning undefined for invalid handles --- package-lock.json | 8 ++++---- package.json | 2 +- src/IndexedDB.ts | 6 +++--- src/access.ts | 18 ++++++++++-------- src/utils.ts | 10 ++++++++-- tsconfig.json | 1 + 6 files changed, 27 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2a5584e..718525c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,7 @@ "node": ">= 18" }, "peerDependencies": { - "@zenfs/core": "^0.9.4" + "@zenfs/core": "^0.9.7" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -452,9 +452,9 @@ "dev": true }, "node_modules/@zenfs/core": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/@zenfs/core/-/core-0.9.4.tgz", - "integrity": "sha512-BkjJU5Tbco5TOEUXdJgqXtPBERg/0MZ7ivYequs1hkr2/Fy/dy15yBNb6IEiRPa+lkNharz/BgbflqhwE4zfeA==", + "version": "0.9.7", + "resolved": "https://registry.npmjs.org/@zenfs/core/-/core-0.9.7.tgz", + "integrity": "sha512-Lmwt1DPhJy07Qx4m4JrzyB8LNBbe5SMq5Z+ZpLjJRfMcSHkoy64l+t8njADVKl0mns91tzo2hEcHNfKG/5Pxog==", "peer": true, "dependencies": { "@types/node": "^20.12.5", diff --git a/package.json b/package.json index e1f7a6d..4a1038f 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,6 @@ "typescript": "5.2.2" }, "peerDependencies": { - "@zenfs/core": "^0.9.4" + "@zenfs/core": "^0.9.7" } } diff --git a/src/IndexedDB.ts b/src/IndexedDB.ts index 8421722..d902278 100644 --- a/src/IndexedDB.ts +++ b/src/IndexedDB.ts @@ -1,13 +1,13 @@ import type { AsyncStore, AsyncStoreOptions, AsyncTransaction, Backend, Ino } from '@zenfs/core'; import { AsyncStoreFS } from '@zenfs/core'; -import { convertException } from './utils.js'; +import { convertException, type ConvertException } from './utils.js'; function wrap(request: IDBRequest): Promise { return new Promise((resolve, reject) => { request.onsuccess = () => resolve(request.result); request.onerror = e => { e.preventDefault(); - reject(convertException(request.error)); + reject(convertException(request.error!)); }; }); } @@ -45,7 +45,7 @@ export class IndexedDBTransaction implements AsyncTransaction { try { this.tx.abort(); } catch (e) { - throw convertException(e); + throw convertException(e as ConvertException); } } } diff --git a/src/access.ts b/src/access.ts index a6a0772..05c49cd 100644 --- a/src/access.ts +++ b/src/access.ts @@ -1,7 +1,7 @@ import type { Backend, FileSystemMetadata } from '@zenfs/core'; import { ApiError, Async, ErrorCode, FileSystem, FileType, InMemory, PreloadFile, Stats } from '@zenfs/core'; import { basename, dirname, join } from '@zenfs/core/emulation/path.js'; -import { convertException } from './utils.js'; +import { convertException, type ConvertException } from './utils.js'; declare global { interface FileSystemDirectoryHandle { @@ -75,7 +75,7 @@ export class WebAccessFS extends Async(FileSystem) { writable.close(); await this.unlink(oldPath); } catch (ex) { - throw convertException(ex, oldPath, 'rename'); + throw convertException(ex as ConvertException, oldPath, 'rename'); } } @@ -108,6 +108,7 @@ export class WebAccessFS extends Async(FileSystem) { const { lastModified, size } = await handle.getFile(); return new Stats({ mode: 0o777 | FileType.FILE, size, mtimeMs: lastModified }); } + throw new ApiError(ErrorCode.EBADE, 'Handle is not a directory or file', path, 'stat'); } public async openFile(path: string, flag: string): Promise> { @@ -121,7 +122,7 @@ export class WebAccessFS extends Async(FileSystem) { const stats = new Stats({ mode: 0o777 | FileType.FILE, size: file.size, mtimeMs: file.lastModified }); return new PreloadFile(this, path, flag, stats, data); } catch (ex) { - throw convertException(ex, path, 'openFile'); + throw convertException(ex as ConvertException, path, 'openFile'); } } @@ -131,7 +132,7 @@ export class WebAccessFS extends Async(FileSystem) { try { await handle.removeEntry(basename(path), { recursive: true }); } catch (ex) { - throw convertException(ex, path, 'unlink'); + throw convertException(ex as ConvertException, path, 'unlink'); } } } @@ -171,7 +172,7 @@ export class WebAccessFS extends Async(FileSystem) { protected async getHandle(path: string): Promise { if (this._handles.has(path)) { - return this._handles.get(path); + return this._handles.get(path)!; } let walked = '/'; @@ -186,13 +187,14 @@ export class WebAccessFS extends Async(FileSystem) { try { const dirHandle = await handle.getDirectoryHandle(part); this._handles.set(walked, dirHandle); - } catch (ex) { + } catch (_ex) { + const ex = _ex as DOMException; if (ex.name == 'TypeMismatchError') { try { const fileHandle = await handle.getFileHandle(part); this._handles.set(walked, fileHandle); } catch (ex) { - convertException(ex, walked, 'getHandle'); + convertException(ex as ConvertException, walked, 'getHandle'); } } @@ -204,7 +206,7 @@ export class WebAccessFS extends Async(FileSystem) { } } - return this._handles.get(path); + return this._handles.get(path)!; } } diff --git a/src/utils.ts b/src/utils.ts index 499b7ca..d392ae0 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -54,17 +54,23 @@ function errnoForDOMException(ex: DOMException): keyof typeof ErrorCode { } } +/** + * @internal + */ +export type ConvertException = ApiError | DOMException | Error; + /** * Handles converting errors, then rethrowing them + * @internal */ -export function convertException(ex: Error | ApiError | DOMException, path?: string, syscall?: string): ApiError { +export function convertException(ex: ConvertException, path?: string, syscall?: string): ApiError { if (ex instanceof ApiError) { return ex; } const code = ex instanceof DOMException ? ErrorCode[errnoForDOMException(ex)] : ErrorCode.EIO; const error = new ApiError(code, ex.message, path, syscall); - error.stack = ex.stack; + error.stack = ex.stack!; error.cause = ex.cause; return error; } diff --git a/tsconfig.json b/tsconfig.json index 9076337..88c6c9e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,6 +4,7 @@ "target": "ES2020", "outDir": "dist", "lib": ["ESNext", "DOM"], + "strict": true, "moduleResolution": "NodeNext", "declaration": true },