diff --git a/lib/CachedInputFileSystem.js b/lib/CachedInputFileSystem.js index e818865..c8d304b 100644 --- a/lib/CachedInputFileSystem.js +++ b/lib/CachedInputFileSystem.js @@ -8,8 +8,10 @@ const nextTick = require("process").nextTick; /** @typedef {import("./Resolver").FileSystem} FileSystem */ +/** @typedef {import("./Resolver").PathLike} PathLike */ +/** @typedef {import("./Resolver").PathOrFileDescriptor} PathOrFileDescriptor */ /** @typedef {import("./Resolver").SyncFileSystem} SyncFileSystem */ -/** @typedef {any} BaseFileSystem */ +/** @typedef {FileSystem & SyncFileSystem} BaseFileSystem */ /** * @template T @@ -58,8 +60,8 @@ const runCallbacks = (callbacks, err, result) => { class OperationMergerBackend { /** - * @param {function} provider async method in filesystem - * @param {function} syncProvider sync method in filesystem + * @param {Function | undefined} provider async method in filesystem + * @param {Function | undefined} syncProvider sync method in filesystem * @param {BaseFileSystem} providerContext call context for the provider methods */ constructor(provider, syncProvider, providerContext) { @@ -81,7 +83,7 @@ class OperationMergerBackend { options = undefined; } if (options) { - return this._provider.call( + return /** @type {Function} */ (this._provider).call( this._providerContext, path, options, @@ -98,7 +100,8 @@ class OperationMergerBackend { return; } this._activeAsyncOperations.set(path, (callbacks = [callback])); - provider( + /** @type {Function} */ + (provider)( path, /** * @param {Error} err error @@ -118,7 +121,11 @@ class OperationMergerBackend { * @returns {any} result */ (path, options) => { - return this._syncProvider.call(this._providerContext, path, options); + return /** @type {Function} */ (this._syncProvider).call( + this._providerContext, + path, + options + ); } : null; } @@ -151,11 +158,19 @@ const STORAGE_MODE_IDLE = 0; const STORAGE_MODE_SYNC = 1; const STORAGE_MODE_ASYNC = 2; +/** + * @callback Provide + * @param {PathLike | PathOrFileDescriptor} path path + * @param {any} options options + * @param {FileSystemCallback} callback callback + * @returns {void} + */ + class CacheBackend { /** * @param {number} duration max cache duration of items - * @param {function} provider async method - * @param {function} syncProvider sync method + * @param {function | undefined} provider async method + * @param {function | undefined} syncProvider sync method * @param {BaseFileSystem} providerContext call context for the provider methods */ constructor(duration, provider, syncProvider, providerContext) { @@ -188,7 +203,7 @@ class CacheBackend { } /** - * @param {string} path path + * @param {PathLike | PathOrFileDescriptor} path path * @param {any} options options * @param {FileSystemCallback} callback callback * @returns {void} @@ -203,7 +218,7 @@ class CacheBackend { return; } if (options) { - return this._provider.call( + return /** @type {Function} */ (this._provider).call( this._providerContext, path, options, @@ -232,7 +247,8 @@ class CacheBackend { this._activeAsyncOperations.set(path, (callbacks = [callback])); // Run the operation - this._provider.call( + /** @type {Function} */ + (this._provider).call( this._providerContext, path, /** @@ -256,7 +272,7 @@ class CacheBackend { } /** - * @param {string} path path + * @param {PathLike | PathOrFileDescriptor} path path * @param {any} options options * @returns {any} result */ @@ -265,7 +281,11 @@ class CacheBackend { throw new TypeError("path must be a string"); } if (options) { - return this._syncProvider.call(this._providerContext, path, options); + return /** @type {Function} */ (this._syncProvider).call( + this._providerContext, + path, + options + ); } // In sync mode we may have to decay some cache items @@ -289,7 +309,10 @@ class CacheBackend { // When in idle mode, we will enter sync mode let result; try { - result = this._syncProvider.call(this._providerContext, path); + result = /** @type {Function} */ (this._syncProvider).call( + this._providerContext, + path + ); } catch (err) { this._storeResult(path, /** @type {Error} */ (err), undefined); this._enterSyncModeWhenIdle(); @@ -449,9 +472,9 @@ class CacheBackend { * @template {function} AsyncProvider * @template FileSystem * @param {number} duration duration in ms files are cached - * @param {Provider} provider provider - * @param {AsyncProvider} syncProvider sync provider - * @param {FileSystem} providerContext provider context + * @param {Provider | undefined} provider provider + * @param {AsyncProvider | undefined} syncProvider sync provider + * @param {BaseFileSystem} providerContext provider context * @returns {OperationMergerBackend | CacheBackend} backend */ const createBackend = (duration, provider, syncProvider, providerContext) => { diff --git a/test/CachedInputFileSystem.test.js b/test/CachedInputFileSystem.test.js index 913e9ba..2ee1d7c 100644 --- a/test/CachedInputFileSystem.test.js +++ b/test/CachedInputFileSystem.test.js @@ -20,6 +20,7 @@ describe("CachedInputFileSystem OperationMergerBackend ('stat' and 'statSync')", 100 ); }, + // @ts-ignore statSync: function (path, options) { return { path, @@ -101,6 +102,7 @@ describe("CachedInputFileSystem OperationMergerBackend ('lstat' and 'lstatSync') 100 ); }, + // @ts-ignore lstatSync: function (path, options) { return { path, @@ -185,6 +187,7 @@ describe("CachedInputFileSystem OperationMergerBackend ('realpath' and 'realpath 100 ); }, + // @ts-ignore realpathSync: function (path, options) { return { path, @@ -269,6 +272,7 @@ describe("CachedInputFileSystem CacheBackend", () => { 100 ); }, + // @ts-ignore statSync: function (path, options) { return { path, diff --git a/test/pr-53.test.js b/test/pr-53.test.js index cc4b7ce..c11db00 100644 --- a/test/pr-53.test.js +++ b/test/pr-53.test.js @@ -4,6 +4,7 @@ describe("pr-53", () => { it("should allow to readJsonSync in CachedInputFileSystem", () => { var cfs = new CachedInputFileSystem( { + // @ts-ignore readFileSync: function (path) { return JSON.stringify("abc" + path); } diff --git a/types.d.ts b/types.d.ts index 43a1b39..6c69f4f 100644 --- a/types.d.ts +++ b/types.d.ts @@ -24,6 +24,7 @@ type AliasOptionNewRequest = string | false | string[]; declare interface AliasOptions { [index: string]: AliasOptionNewRequest; } +type BaseFileSystem = FileSystem & SyncFileSystem; declare interface BaseResolveRequest { path: string | false; context?: object; @@ -52,8 +53,8 @@ type BufferEncoding = | "hex"; type BufferEncodingOption = "buffer" | { encoding: "buffer" }; declare class CachedInputFileSystem { - constructor(fileSystem: any, duration: number); - fileSystem: any; + constructor(fileSystem: BaseFileSystem, duration: number); + fileSystem: BaseFileSystem; lstat?: LStat; lstatSync?: LStatSync; stat: Stat; @@ -1025,6 +1026,15 @@ declare interface StatSyncOptions { bigint?: boolean; throwIfNoEntry?: boolean; } +declare interface SyncFileSystem { + readFileSync: ReadFileSync; + readdirSync: ReaddirSync; + readJsonSync?: (arg0: PathOrFileDescriptor) => JsonObject; + readlinkSync: ReadlinkSync; + lstatSync?: LStatSync; + statSync: StatSync; + realpathSync?: RealPathSync; +} /** * `URL` class is a global reference for `require('url').URL`