Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,40 @@ fastify.register(autoLoad, {
})
```

### `appendAutoPrefix` (optional) - Default: `false`

Controls how `autoPrefix` from a plugin file is combined with the directory-derived prefix.

- `false` (default): `autoPrefix` replaces the directory-derived prefix for that plugin.
- `true`: the directory-derived prefix is kept, and `autoPrefix` is appended after it.

Example directory:

```text
routes/
children/
new-routes.js // exports autoPrefix = '/batch'
```

With default behavior (`appendAutoPrefix: false`), the route is loaded as:

```text
/your-parent-prefix/batch/entity
```

With `appendAutoPrefix: true`, the route is loaded as:

```text
/your-parent-prefix/children/batch/entity
```

```js
fastify.register(autoLoad, {
dir: path.join(__dirname, 'routes'),
appendAutoPrefix: true
})
```
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This example is not clear

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call — updated in commit c5cf899.

The README example now uses a concrete directory + �utoPrefix setup and shows the exact resulting paths for both default mode and append mode.


### `matchFilter` (optional)

Filter matching any path that should be loaded. Can be a RegExp, a string, or a function returning a boolean.
Expand Down Expand Up @@ -225,6 +259,8 @@ Any option specified here will override `plugin.autoConfig` options specified in

When setting both `options.prefix` and `plugin.autoPrefix` they will be concatenated.

By default, `plugin.autoPrefix` replaces directory-derived prefixes. Set `appendAutoPrefix: true` to keep directory prefixes and append `plugin.autoPrefix` after them.

```js
// index.js
fastify.register(autoLoad, {
Expand Down Expand Up @@ -409,6 +445,8 @@ autoConfig.prefix = '/hello'

Set routing prefix for plugin.

`plugin.autoPrefix` overrides directory-derived prefixes by default. Use the global `appendAutoPrefix` option to append `plugin.autoPrefix` to directory prefixes instead.

```js
module.exports = function (fastify, opts, next) {
fastify.get('/', (request, reply) => {
Expand Down
17 changes: 10 additions & 7 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ const defaults = {
indexPattern: /^index(?:\.ts|\.js|\.cjs|\.mjs|\.cts|\.mts)$/iu,
autoHooksPattern: /^[_.]?auto_?hooks(?:\.ts|\.js|\.cjs|\.mjs|\.cts|\.mts)$/iu,
dirNameRoutePrefix: true,
encapsulate: true
encapsulate: true,
appendAutoPrefix: false
}

const fastifyAutoload = async function autoload (fastify, options) {
Expand Down Expand Up @@ -101,7 +102,7 @@ async function loadPlugin ({ file, type, directoryPrefix, options, log }) {
plugin.autoConfig = undefined
}

handlePrefixConfig({ plugin, pluginOptions, content, directoryPrefix })
handlePrefixConfig({ plugin, pluginOptions, content, directoryPrefix, appendAutoPrefix: options.appendAutoPrefix })

return {
plugin,
Expand Down Expand Up @@ -258,16 +259,18 @@ function loadPluginOptions (content, overrideConfig) {
return { ...pluginConfig, ...overrideConfig }
}

function handlePrefixConfig ({ plugin, pluginOptions, content, directoryPrefix }) {
function handlePrefixConfig ({ plugin, pluginOptions, content, directoryPrefix, appendAutoPrefix }) {
if (pluginOptions.prefix?.endsWith('/')) {
pluginOptions.prefix = pluginOptions.prefix.slice(0, -1)
}

const autoPrefix = plugin.autoPrefix ?? content.autoPrefix

let prefix
if (plugin.autoPrefix !== undefined) {
prefix = plugin.autoPrefix
} else if (content.autoPrefix !== undefined) {
prefix = content.autoPrefix
if (appendAutoPrefix && autoPrefix !== undefined && directoryPrefix) {
prefix = `${directoryPrefix}/${autoPrefix}`
} else if (autoPrefix !== undefined) {
prefix = autoPrefix
} else {
prefix = directoryPrefix
}
Expand Down
7 changes: 7 additions & 0 deletions test/issues/205/routes/children/new-routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
'use strict'

module.exports = async function (app) {
app.get('/entity', async () => ({ ok: true }))
}

module.exports.autoPrefix = '/batch'
60 changes: 60 additions & 0 deletions test/issues/205/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
'use strict'

const { after, before, describe, it } = require('node:test')
const assert = require('node:assert')
const path = require('node:path')
const Fastify = require('fastify')
const autoLoad = require('../../../')

describe('Issue 205: append autoPrefix to directory prefixes without breaking defaults', function () {
describe('default behavior', function () {
const app = Fastify()

before(async function () {
app.register(autoLoad, {
dir: path.join(__dirname, 'routes'),
options: { prefix: '/hooked-plugin' }
})
await app.ready()
})

after(async function () {
await app.close()
})

it('keeps autoPrefix overriding directory prefixes by default', async function () {
const overridden = await app.inject({ method: 'GET', url: '/hooked-plugin/batch/entity' })
assert.strictEqual(overridden.statusCode, 200)
assert.deepStrictEqual(overridden.json(), { ok: true })

const appended = await app.inject({ method: 'GET', url: '/hooked-plugin/children/batch/entity' })
assert.strictEqual(appended.statusCode, 404)
})
})

describe('appendAutoPrefix: true', function () {
const app = Fastify()

before(async function () {
app.register(autoLoad, {
dir: path.join(__dirname, 'routes'),
options: { prefix: '/hooked-plugin' },
appendAutoPrefix: true
})
await app.ready()
})

after(async function () {
await app.close()
})

it('concatenates directory prefixes before plugin autoPrefix', async function () {
const appended = await app.inject({ method: 'GET', url: '/hooked-plugin/children/batch/entity' })
assert.strictEqual(appended.statusCode, 200)
assert.deepStrictEqual(appended.json(), { ok: true })

const overridden = await app.inject({ method: 'GET', url: '/hooked-plugin/batch/entity' })
assert.strictEqual(overridden.statusCode, 404)
})
})
})
1 change: 1 addition & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ declare namespace fastifyAutoload {
export interface AutoloadPluginOptions {
dir: string
dirNameRoutePrefix?: boolean | RewritePrefix
appendAutoPrefix?: boolean
ignoreFilter?: Filter
matchFilter?: Filter
ignorePattern?: RegExp
Expand Down
Loading