diff --git a/index.js b/index.js index 86b47dc..1cb5347 100644 --- a/index.js +++ b/index.js @@ -3,7 +3,7 @@ const path = require('node:path') const { fileURLToPath } = require('node:url') const { statSync } = require('node:fs') -const { glob } = require('glob') +const { glob, stat } = require('node:fs/promises') const fp = require('fastify-plugin') const send = require('@fastify/send') const encodingNegotiator = require('@fastify/accept-negotiator') @@ -139,11 +139,23 @@ async function fastifyStatic (fastify, opts) { for (let rootPath of roots) { rootPath = rootPath.split(path.win32.sep).join(path.posix.sep) !rootPath.endsWith('/') && (rootPath += '/') - const files = await glob('**/**', { - cwd: rootPath, absolute: false, follow: true, nodir: true, dot: opts.serveDotFiles, ignore: opts.globIgnore + + const patterns = ['**/**'] + if (opts.serveDotFiles) { + patterns.push('**/.*/**') + } + + const globStream = glob(patterns, { + cwd: rootPath, withFileTypes: true, exclude: opts.globIgnore }) - for (let file of files) { + for await (const entry of globStream) { + const isFile = entry.isFile() + if (!isFile) { continue } + if (!opts.serveDotFiles && entry.name.startsWith('.')) { continue } + const fullPath = path.join(entry.parentPath, entry.name) + let file = path.relative(rootPath, fullPath) + file = file.split(path.win32.sep).join(path.posix.sep) const route = prefix + file diff --git a/package.json b/package.json index 4b307bb..cdc7476 100644 --- a/package.json +++ b/package.json @@ -62,8 +62,7 @@ "@fastify/send": "^4.0.0", "content-disposition": "^1.0.1", "fastify-plugin": "^5.0.0", - "fastq": "^1.17.1", - "glob": "^11.0.0" + "fastq": "^1.17.1" }, "devDependencies": { "@fastify/compress": "^8.0.0", diff --git a/test/static.test.js b/test/static.test.js index cd5e147..2b8afc4 100644 --- a/test/static.test.js +++ b/test/static.test.js @@ -2437,13 +2437,18 @@ test('if dotfiles are properly served according to plugin options', async (t) => test('register with failing glob handler', async (t) => { const fastifyStatic = proxyquire.noCallThru()('../', { - glob: function globStub (_pattern, _options, cb) { - process.nextTick(function () { - return cb(new Error('mock glob error')) - }) + 'node:fs/promises': { + glob: function globStub (_pattern, _options) { + return { + [Symbol.asyncIterator] () { + return { + next: async () => { throw new Error('mock glob error') } + } + } + } + } } }) - const pluginOptions = { root: path.join(__dirname, '/static'), serve: true,