diff --git a/src/drivers/fs-lite.ts b/src/drivers/fs-lite.ts index a7ebbb31..2fff2094 100644 --- a/src/drivers/fs-lite.ts +++ b/src/drivers/fs-lite.ts @@ -40,6 +40,9 @@ export default defineDriver((opts: FSStorageOptions = {}) => { return { name: DRIVER_NAME, options: opts, + flags: { + maxDepth: true, + }, hasItem(key) { return existsSync(r(key)); }, diff --git a/src/drivers/fs.ts b/src/drivers/fs.ts index b2bcc5ed..3e7e1e1b 100644 --- a/src/drivers/fs.ts +++ b/src/drivers/fs.ts @@ -59,6 +59,9 @@ export default defineDriver((opts: FSStorageOptions = {}) => { return { name: DRIVER_NAME, options: opts, + flags: { + maxDepth: true, + }, hasItem(key) { return existsSync(r(key)); }, diff --git a/src/storage.ts b/src/storage.ts index 7cacb064..eb657847 100644 --- a/src/storage.ts +++ b/src/storage.ts @@ -348,7 +348,11 @@ export function createStorage( const mounts = getMounts(base, true); let maskedMounts: string[] = []; const allKeys = []; + let allMountsSupportMaxDepth = true; for (const mount of mounts) { + if (!mount.driver.flags?.maxDepth) { + allMountsSupportMaxDepth = false; + } const rawKeys = await asyncCall( mount.driver.getKeys, mount.relativeBase, @@ -368,10 +372,11 @@ export function createStorage( ...maskedMounts.filter((p) => !p.startsWith(mount.mountpoint)), ]; } + const shouldFilterByDepth = + opts.maxDepth !== undefined && !allMountsSupportMaxDepth; return allKeys.filter( (key) => - (opts.maxDepth === undefined || - filterKeyByDepth(key, opts.maxDepth)) && + (!shouldFilterByDepth || filterKeyByDepth(key, opts.maxDepth)) && filterKeyByBase(key, base) ); }, diff --git a/test/storage.test.ts b/test/storage.test.ts index 64f6f736..3857ce27 100644 --- a/test/storage.test.ts +++ b/test/storage.test.ts @@ -1,4 +1,5 @@ import { describe, it, expect, vi } from "vitest"; +import { resolve } from "node:path"; import { createStorage, snapshot, @@ -6,6 +7,7 @@ import { prefixStorage, } from "../src"; import memory from "../src/drivers/memory"; +import fs from "../src/drivers/fs"; const data = { "etc:conf": "test", @@ -222,4 +224,29 @@ describe("Regression", () => { await pStorage.remove("y"); expect(await pStorage.has("y")).toBe(false); }); + + it("getKeys supports maxDepth with mixed native support", async () => { + const base = resolve(__dirname, "tmp/fs"); + const mainStorage = memory(); + const secondaryStorage = fs({ base }); + const storage = createStorage({ driver: mainStorage }); + + storage.mount("/storage_b", secondaryStorage); + + try { + await storage.setItem("/storage_a/file_depth1", "contents"); + await storage.setItem("/storage_a/depth1/file_depth2", "contents"); + await storage.setItem("/storage_b/file_depth1", "contents"); + await storage.setItem("/storage_b/depth1/file_depth2", "contents"); + + const keys = await storage.getKeys(undefined, { maxDepth: 1 }); + + expect(keys.sort()).toMatchObject([ + "storage_a:file_depth1", + "storage_b:file_depth1", + ]); + } finally { + await storage.clear(); + } + }); });