Skip to content

Commit 460e172

Browse files
linkthaithaivlinhUzlopakclimba03003
authored
Fixing files imported by module got bypass through isPluginOrModule check (#463)
* FIX: error when autoload non-module file in forceESM mode * FIX: error when autoload non-module file in forceESM mode * FIX: use mjs file name for routes instead so it could load as ESM + move importedAsModule out of isPluginOrModule function (but include a boolean check for when an mjs is empty) * UPDATE: add mock log count + more descriptive test name * Update index.js Co-authored-by: KaKa <[email protected]> Signed-off-by: Aras Abbasi <[email protected]> --------- Signed-off-by: Aras Abbasi <[email protected]> Co-authored-by: thaivlinh <[email protected]> Co-authored-by: Aras Abbasi <[email protected]> Co-authored-by: KaKa <[email protected]>
1 parent 548263b commit 460e172

File tree

8 files changed

+56
-3
lines changed

8 files changed

+56
-3
lines changed

index.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,15 @@ async function loadPlugins ({ pluginTree, options, opts, fastify }) {
6767

6868
async function loadPlugin ({ file, type, directoryPrefix, options, log }) {
6969
const { options: overrideConfig, forceESM, encapsulate } = options
70+
const importedAsModule = forceESM || type === 'module' || runtime.forceESM
7071
let content
71-
if (forceESM || type === 'module' || runtime.forceESM) {
72+
if (importedAsModule) {
7273
content = await import(pathToFileURL(file).href)
7374
} else {
7475
content = require(file)
7576
}
7677

77-
if (isPluginOrModule(content) === false) {
78+
if (isPluginOrModule(importedAsModule ? content.default : content) === false) {
7879
// We must have something that resembles a Fastify plugin function, or that
7980
// can be converted into one, that can eventually be passed to `avvio`. If
8081
// it is anything else, skip automatic loading of this item.
@@ -256,8 +257,9 @@ const pluginOrModulePattern = /\[object (?:AsyncFunction|Function|Module)\]/u
256257
* eventually passing it into `avvio`. False otherwise.
257258
*/
258259
function isPluginOrModule (input) {
259-
let result = false
260+
if (!input) return false
260261

262+
let result = false
261263
const inputType = Object.prototype.toString.call(input)
262264
if (pluginOrModulePattern.test(inputType) === true) {
263265
result = true

test/issues/462/routes/api.mjs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export default async function (app) {
2+
app.get('/api', async function (req, reply) {
3+
reply.status(200).send({ path: req.url })
4+
})
5+
}

test/issues/462/routes/empty.cjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// cjs empty file

test/issues/462/routes/empty.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// empty file

test/issues/462/routes/empty.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// mjs empty file

test/issues/462/routes/hello.mjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// file with something but not a plugin export
2+
export const hello = () => {
3+
// do something
4+
}

test/issues/462/routes/object.mjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// export default an empty object
2+
export default {}

test/issues/462/test.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
'use strict'
2+
3+
const { after, before, describe, it, mock } = require('node:test')
4+
const path = require('node:path')
5+
const Fastify = require('fastify')
6+
const autoLoad = require('../../../')
7+
const assert = require('node:assert')
8+
9+
describe('Issue 462: ignore invalid and/or empty .js and .mjs files when using esm', function () {
10+
const app = Fastify()
11+
12+
before(async function () {
13+
app.register(autoLoad, {
14+
dir: path.join(__dirname, 'routes'),
15+
forceESM: true,
16+
})
17+
mock.method(app.log, 'debug')
18+
await app.ready()
19+
})
20+
21+
after(async function () {
22+
await app.close()
23+
})
24+
25+
it('should respond correctly to /api', async function () {
26+
const res = await app.inject({ url: '/api' })
27+
28+
assert.strictEqual(res.statusCode, 200)
29+
assert.deepStrictEqual(res.json(), { path: '/api' })
30+
31+
// check debug call when importing empty/invalid esm files
32+
// 5 debug log including: empty.cjs, empty.js, empty.mjs, hello.mjs, object.mjs
33+
// api.mjs pass the check so it will not trigger the debug log
34+
// increasing this number if there are more empty/invalid esm files you want to test
35+
assert.strictEqual(app.log.debug.mock.callCount(), 5)
36+
})
37+
})

0 commit comments

Comments
 (0)