Aktueller Stand

This commit is contained in:
2026-01-22 19:05:45 +01:00
parent 85dee61a4d
commit e280e4eadb
1967 changed files with 397327 additions and 74093 deletions

2
backend/node_modules/fastify-plugin/.gitattributes generated vendored Normal file
View File

@@ -0,0 +1,2 @@
# Set default behavior to automatically convert line endings
* text=auto eol=lf

View File

@@ -9,5 +9,5 @@ updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
interval: "monthly"
open-pull-requests-limit: 10

View File

@@ -4,7 +4,6 @@ on:
push:
branches:
- main
- master
- next
- 'v*'
paths-ignore:
@@ -15,9 +14,15 @@ on:
- 'docs/**'
- '*.md'
permissions:
contents: read
jobs:
test:
uses: fastify/workflows/.github/workflows/plugins-ci.yml@v3
permissions:
contents: write
pull-requests: write
uses: fastify/workflows/.github/workflows/plugins-ci.yml@v5
with:
lint: true
license-check: true
lint: true

View File

@@ -1,7 +0,0 @@
ts: false
jsx: false
flow: false
coverage: true
files:
- test/**/*.js

View File

@@ -1,6 +1,8 @@
MIT License
Copyright (c) 2017 Fastify
Copyright (c) 2017-present The Fastify team
The Fastify team members are listed at https://github.com/fastify/fastify#team.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -1,18 +1,24 @@
# fastify-plugin
![CI](https://github.com/fastify/fastify-plugin/workflows/CI/badge.svg?branch=master)
[![CI](https://github.com/fastify/fastify-plugin/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/fastify/fastify-plugin/actions/workflows/ci.yml)
[![NPM version](https://img.shields.io/npm/v/fastify-plugin.svg?style=flat)](https://www.npmjs.com/package/fastify-plugin)
[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://standardjs.com/)
[![neostandard javascript style](https://img.shields.io/badge/code_style-neostandard-brightgreen?style=flat)](https://github.com/neostandard/neostandard)
`fastify-plugin` is a plugin helper for [Fastify](https://github.com/fastify/fastify).
When you build plugins for Fastify and you want that them to be accessible in the same context where you require them, you have two ways:
When you build plugins for Fastify and you want them to be accessible in the same context where you require them, you have two ways:
1. Use the `skip-override` hidden property
2. Use this module
__Note: the v4.x series of this module covers Fastify v4__
__Note: the v2.x & v3.x series of this module covers Fastify v3. For Fastify v2 support, refer to the v1.x series.__
## Install
```sh
npm i fastify-plugin
```
## Usage
`fastify-plugin` can do three things for you:
- Add the `skip-override` hidden property
@@ -51,7 +57,7 @@ const fp = require('fastify-plugin')
module.exports = fp(function (fastify, opts, done) {
// your plugin code
done()
}, { fastify: '4.x' })
}, { fastify: '5.x' })
```
If you need to check the Fastify version only, you can pass just the version string.
@@ -70,7 +76,7 @@ function plugin (fastify, opts, done) {
}
module.exports = fp(plugin, {
fastify: '4.x',
fastify: '5.x',
name: 'your-plugin-name'
})
```
@@ -87,7 +93,7 @@ function plugin (fastify, opts, done) {
}
module.exports = fp(plugin, {
fastify: '4.x',
fastify: '5.x',
decorators: {
fastify: ['plugin1', 'plugin2'],
reply: ['compress']
@@ -111,7 +117,7 @@ function plugin (fastify, opts, done) {
module.exports = fp(plugin, {
name: 'my-encapsulated-plugin',
fastify: '4.x',
fastify: '5.x',
decorators: {
fastify: ['plugin1', 'plugin2'],
reply: ['compress']
@@ -136,7 +142,7 @@ fp((fastify, opts, done) => { done() })
fp(async (fastify, opts) => { return })
```
TypeScript can sometimes infer the types of the arguments for these functions. Plugins in fastify are recommended to be typed using either `FastifyPluginCallback` or `FastifyPluginAsync`. These two definitions only differ in two ways:
TypeScript can sometimes infer the types of the arguments for these functions. Plugins in Fastify are recommended to be typed using either `FastifyPluginCallback` or `FastifyPluginAsync`. These two definitions only differ in two ways:
1. The third argument `done` (the callback part)
2. The return type `FastifyPluginCallback` or `FastifyPluginAsync`
@@ -171,7 +177,7 @@ fp(pluginAsyncWithTypes)
fp(async (fastify: FastifyInstance, options: FastifyPluginOptions): Promise<void> => { })
```
## Acknowledgements
## Acknowledgments
This project is kindly sponsored by:
- [nearForm](https://nearform.com)

6
backend/node_modules/fastify-plugin/eslint.config.js generated vendored Normal file
View File

@@ -0,0 +1,6 @@
'use strict'
module.exports = require('neostandard')({
ignores: require('neostandard').resolveIgnoresFromGitignore(),
ts: true
})

View File

@@ -1,6 +1,6 @@
'use strict'
const fpStackTracePattern = /at\s{1}(?:.*\.)?plugin\s{1}.*\n\s*(.*)/
const fpStackTracePattern = /at\s(?:.*\.)?plugin\s.*\n\s*(.*)/
const fileNamePattern = /(\w*(\.\w*)*)\..*/
module.exports = function getPluginName (fn) {

View File

@@ -4,8 +4,7 @@ module.exports = function toCamelCase (name) {
if (name[0] === '@') {
name = name.slice(1).replace('/', '-')
}
const newName = name.replace(/-(.)/g, function (match, g1) {
return name.replace(/-(.)/g, function (match, g1) {
return g1.toUpperCase()
})
return newName
}

View File

@@ -1,13 +1,16 @@
{
"name": "fastify-plugin",
"version": "4.5.1",
"version": "5.1.0",
"description": "Plugin helper for Fastify",
"main": "plugin.js",
"type": "commonjs",
"types": "types/plugin.d.ts",
"scripts": {
"lint": "standard",
"lint": "eslint",
"lint:fix": "eslint --fix",
"test": "npm run test:unit && npm run test:typescript",
"test:unit": "tap",
"test:unit": "c8 --100 node --test",
"test:coverage": "c8 node --test && c8 report --reporter=html",
"test:typescript": "tsd"
},
"repository": {
@@ -20,18 +23,48 @@
"fastify"
],
"author": "Tomas Della Vedova - @delvedor (http://delved.org)",
"contributors": [
{
"name": "Matteo Collina",
"email": "hello@matteocollina.com"
},
{
"name": "Manuel Spigolon",
"email": "behemoth89@gmail.com"
},
{
"name": "Aras Abbasi",
"email": "aras.abbasi@gmail.com"
},
{
"name": "Frazer Smith",
"email": "frazer.dev@icloud.com",
"url": "https://github.com/fdawgs"
}
],
"license": "MIT",
"bugs": {
"url": "https://github.com/fastify/fastify-plugin/issues"
},
"homepage": "https://github.com/fastify/fastify-plugin#readme",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/fastify"
},
{
"type": "opencollective",
"url": "https://opencollective.com/fastify"
}
],
"devDependencies": {
"@fastify/type-provider-typebox": "^3.0.0",
"@types/node": "^20.1.0",
"fastify": "^4.0.1",
"@fastify/type-provider-typebox": "^5.1.0",
"@types/node": "^24.0.8",
"c8": "^10.1.2",
"eslint": "^9.17.0",
"fastify": "^5.0.0",
"neostandard": "^0.12.0",
"proxyquire": "^2.1.3",
"standard": "^17.0.0",
"tap": "^16.0.1",
"tsd": "^0.28.0"
"tsd": "^0.33.0"
}
}

View File

@@ -8,7 +8,7 @@ let count = 0
function plugin (fn, options = {}) {
let autoName = false
if (typeof fn.default !== 'undefined') {
if (fn.default !== undefined) {
// Support for 'export default' behaviour in transpiled ECMAScript module
fn = fn.default
}

View File

@@ -1,12 +1,12 @@
'use strict'
const { test } = require('tap')
const { test } = require('node:test')
const fp = require('../plugin')
test('webpack removes require.main.filename', (t) => {
test('webpack removes require.main.filename', t => {
const filename = require.main.filename
const info = console.info
t.teardown(() => {
t.after(() => {
require.main.filename = filename
console.info = info
})
@@ -14,97 +14,88 @@ test('webpack removes require.main.filename', (t) => {
require.main.filename = null
console.info = function (msg) {
t.fail('logged: ' + msg)
t.assert.fail('logged: ' + msg)
}
fp((fastify, opts, next) => {
fp((_fastify, _opts, next) => {
next()
}, {
fastify: '^4.0.0'
fastify: '^5.0.0'
})
t.end()
})
test('support faux modules', (t) => {
const plugin = fp((fastify, opts, next) => {
const plugin = fp((_fastify, _opts, next) => {
next()
})
t.equal(plugin.default, plugin)
t.end()
t.assert.strictEqual(plugin.default, plugin)
})
test('support faux modules does not override existing default field in babel module', (t) => {
const module = {
default: (fastify, opts, next) => next()
default: (_fastify, _opts, next) => next()
}
module.default.default = 'Existing default field'
const plugin = fp(module)
t.equal(plugin.default, 'Existing default field')
t.end()
t.assert.strictEqual(plugin.default, 'Existing default field')
})
test('support ts named imports', (t) => {
const plugin = fp((fastify, opts, next) => {
const plugin = fp((_fastify, _opts, next) => {
next()
}, {
name: 'hello'
})
t.equal(plugin.hello, plugin)
t.end()
t.assert.strictEqual(plugin.hello, plugin)
})
test('from kebab-case to camelCase', (t) => {
const plugin = fp((fastify, opts, next) => {
const plugin = fp((_fastify, _opts, next) => {
next()
}, {
name: 'hello-world'
})
t.equal(plugin.helloWorld, plugin)
t.end()
t.assert.strictEqual(plugin.helloWorld, plugin)
})
test('from @-prefixed named imports', (t) => {
const plugin = fp((fastify, opts, next) => {
const plugin = fp((_fastify, _opts, next) => {
next()
}, {
name: '@hello/world'
})
t.equal(plugin.helloWorld, plugin)
t.end()
t.assert.strictEqual(plugin.helloWorld, plugin)
})
test('from @-prefixed named kebab-case to camelCase', (t) => {
const plugin = fp((fastify, opts, next) => {
const plugin = fp((_fastify, _opts, next) => {
next()
}, {
name: '@hello/my-world'
})
t.equal(plugin.helloMyWorld, plugin)
t.end()
t.assert.strictEqual(plugin.helloMyWorld, plugin)
})
test('from kebab-case to camelCase multiple words', (t) => {
const plugin = fp((fastify, opts, next) => {
const plugin = fp((_fastify, _opts, next) => {
next()
}, {
name: 'hello-long-world'
})
t.equal(plugin.helloLongWorld, plugin)
t.end()
t.assert.strictEqual(plugin.helloLongWorld, plugin)
})
test('from kebab-case to camelCase multiple words does not override', (t) => {
const fn = (fastify, opts, next) => {
const fn = (_fastify, _opts, next) => {
next()
}
@@ -115,6 +106,5 @@ test('from kebab-case to camelCase multiple words does not override', (t) => {
name: 'hello-long-world'
})
t.equal(plugin.helloLongWorld, foobar)
t.end()
t.assert.strictEqual(plugin.helloLongWorld, foobar)
})

View File

@@ -1,32 +1,30 @@
'use strict'
const { test } = require('tap')
const { test } = require('node:test')
const fp = require('../plugin')
test('checkVersion having require.main.filename', (t) => {
const info = console.info
t.ok(require.main.filename)
t.teardown(() => {
t.assert.ok(require.main.filename)
t.after(() => {
console.info = info
})
console.info = function (msg) {
t.fail('logged: ' + msg)
t.assert.fail('logged: ' + msg)
}
fp((fastify, opts, next) => {
fp((_fastify, _opts, next) => {
next()
}, {
fastify: '^4.0.0'
fastify: '^5.0.0'
})
t.end()
})
test('checkVersion having no require.main.filename but process.argv[1]', (t) => {
const filename = require.main.filename
const info = console.info
t.teardown(() => {
t.after(() => {
require.main.filename = filename
console.info = info
})
@@ -34,23 +32,21 @@ test('checkVersion having no require.main.filename but process.argv[1]', (t) =>
require.main.filename = null
console.info = function (msg) {
t.fail('logged: ' + msg)
t.assert.fail('logged: ' + msg)
}
fp((fastify, opts, next) => {
fp((_fastify, _opts, next) => {
next()
}, {
fastify: '^4.0.0'
fastify: '^5.0.0'
})
t.end()
})
test('checkVersion having no require.main.filename and no process.argv[1]', (t) => {
const filename = require.main.filename
const argv = process.argv
const info = console.info
t.teardown(() => {
t.after(() => {
require.main.filename = filename
process.argv = argv
console.info = info
@@ -60,14 +56,12 @@ test('checkVersion having no require.main.filename and no process.argv[1]', (t)
process.argv[1] = null
console.info = function (msg) {
t.fail('logged: ' + msg)
t.assert.fail('logged: ' + msg)
}
fp((fastify, opts, next) => {
fp((_fastify, _opts, next) => {
next()
}, {
fastify: '^4.0.0'
fastify: '^5.0.0'
})
t.end()
})

View File

@@ -1,16 +1,14 @@
'use strict'
const t = require('tap')
const test = t.test
const { test } = require('node:test')
const fp = require('../plugin')
test('anonymous function should be named composite.test0', t => {
test('anonymous function should be named composite.test0', (t) => {
t.plan(2)
const fn = fp((fastify, opts, next) => {
const fn = fp((_fastify, _opts, next) => {
next()
})
t.equal(fn[Symbol.for('plugin-meta')].name, 'composite.test-auto-0')
t.equal(fn[Symbol.for('fastify.display-name')], 'composite.test-auto-0')
t.assert.strictEqual(fn[Symbol.for('plugin-meta')].name, 'composite.test-auto-0')
t.assert.strictEqual(fn[Symbol.for('fastify.display-name')], 'composite.test-auto-0')
})

View File

@@ -1,13 +1,11 @@
import t from 'tap'
import { test } from 'node:test'
import fp from '../../plugin.js'
t.test('esm base support', async t => {
fp((fastify, opts, next) => {
test('esm base support', (t) => {
fp((_fastify, _opts, next) => {
next()
}, {
fastify: '^3.0.0'
fastify: '^5.0.0'
})
t.end()
t.assert.ok(true, 'fp function called without throwing an error')
})

View File

@@ -1,6 +1,6 @@
'use strict'
const t = require('tap')
const { test } = require('node:test')
const extractPluginName = require('../lib/getPluginName').extractPluginName
const winStack = `Error: anonymous function
@@ -41,8 +41,9 @@ at TAP.test (/home/leonardo/desktop/fastify-plugin/node_modules/tap/lib/test.js:
const anonymousStack = 'Unable to parse this'
t.plan(3)
t.equal(extractPluginName(winStack), 'hello.test')
t.equal(extractPluginName(nixStack), 'this.is.a.test')
t.equal(extractPluginName(anonymousStack), 'anonymous')
test('extractPluginName tests', (t) => {
t.plan(3)
t.assert.strictEqual(extractPluginName(winStack), 'hello.test')
t.assert.strictEqual(extractPluginName(nixStack), 'this.is.a.test')
t.assert.strictEqual(extractPluginName(anonymousStack), 'anonymous')
})

View File

@@ -1,16 +1,15 @@
'use strict'
const t = require('tap')
const test = t.test
const { test } = require('node:test')
const fp = require('../plugin')
test('anonymous function should be named mu1tip1e.composite.test', t => {
test('anonymous function should be named mu1tip1e.composite.test', (t) => {
t.plan(2)
const fn = fp((fastify, opts, next) => {
const fn = fp((_fastify, _opts, next) => {
next()
})
t.equal(fn[Symbol.for('plugin-meta')].name, 'mu1tip1e.composite.test-auto-0')
t.equal(fn[Symbol.for('fastify.display-name')], 'mu1tip1e.composite.test-auto-0')
t.assert.strictEqual(fn[Symbol.for('plugin-meta')].name, 'mu1tip1e.composite.test-auto-0')
t.assert.strictEqual(fn[Symbol.for('fastify.display-name')], 'mu1tip1e.composite.test-auto-0')
})

View File

@@ -1,28 +1,29 @@
'use strict'
const t = require('tap')
const { test } = require('node:test')
const proxyquire = require('proxyquire')
const test = t.test
const fp = require('../plugin')
const Fastify = require('fastify')
test('fastify-plugin is a function', t => {
const pkg = require('../package.json')
test('fastify-plugin is a function', (t) => {
t.plan(1)
t.type(fp, 'function')
t.assert.ok(typeof fp === 'function')
})
test('should return the function with the skip-override Symbol', t => {
test('should return the function with the skip-override Symbol', (t) => {
t.plan(1)
function plugin (fastify, opts, next) {
function plugin (_fastify, _opts, next) {
next()
}
fp(plugin)
t.ok(plugin[Symbol.for('skip-override')])
t.assert.ok(plugin[Symbol.for('skip-override')])
})
test('should support "default" function from babel module', t => {
test('should support "default" function from babel module', (t) => {
t.plan(1)
const plugin = {
@@ -31,248 +32,241 @@ test('should support "default" function from babel module', t => {
try {
fp(plugin)
t.pass()
t.assert.ok(true)
} catch (e) {
t.equal(e.message, 'fastify-plugin expects a function, instead got a \'object\'')
t.assert.strictEqual(e.message, 'fastify-plugin expects a function, instead got a \'object\'')
}
})
test('should throw if the plugin is not a function', t => {
test('should throw if the plugin is not a function', (t) => {
t.plan(1)
try {
fp('plugin')
t.fail()
t.assert.fail()
} catch (e) {
t.equal(e.message, 'fastify-plugin expects a function, instead got a \'string\'')
t.assert.strictEqual(e.message, 'fastify-plugin expects a function, instead got a \'string\'')
}
})
test('should check the fastify version', t => {
test('should check the fastify version', (t) => {
t.plan(1)
function plugin (fastify, opts, next) {
function plugin (_fastify, _opts, next) {
next()
}
try {
fp(plugin, { fastify: '>=0.10.0' })
t.pass()
} catch (e) {
t.fail()
t.assert.ok(true)
} catch {
t.assert.fail()
}
})
test('should check the fastify version', t => {
test('should check the fastify version', (t) => {
t.plan(1)
function plugin (fastify, opts, next) {
function plugin (_fastify, _opts, next) {
next()
}
try {
fp(plugin, '>=0.10.0')
t.pass()
} catch (e) {
t.fail()
t.assert.ok(true)
} catch {
t.assert.fail()
}
})
test('the options object should be an object', t => {
test('the options object should be an object', (t) => {
t.plan(2)
try {
fp(() => { }, null)
t.fail()
t.assert.fail()
} catch (e) {
t.equal(e.message, 'The options object should be an object')
t.assert.strictEqual(e.message, 'The options object should be an object')
}
try {
fp(() => { }, [])
t.fail()
t.assert.fail()
} catch (e) {
t.equal(e.message, 'The options object should be an object')
t.assert.strictEqual(e.message, 'The options object should be an object')
}
})
test('should throw if the version number is not a string', t => {
test('should throw if the version number is not a string', (t) => {
t.plan(1)
try {
fp(() => { }, { fastify: 12 })
t.fail()
t.assert.fail()
} catch (e) {
t.equal(e.message, 'fastify-plugin expects a version string, instead got \'number\'')
t.assert.strictEqual(e.message, 'fastify-plugin expects a version string, instead got \'number\'')
}
})
test('Should accept an option object', t => {
test('Should accept an option object', (t) => {
t.plan(2)
const opts = { hello: 'world' }
function plugin (fastify, opts, next) {
function plugin (_fastify, _opts, next) {
next()
}
fp(plugin, opts)
t.ok(plugin[Symbol.for('skip-override')])
t.same(plugin[Symbol.for('plugin-meta')], opts)
t.assert.ok(plugin[Symbol.for('skip-override')], 'skip-override symbol should be present')
t.assert.deepStrictEqual(plugin[Symbol.for('plugin-meta')], opts, 'plugin-meta should match opts')
})
test('Should accept an option object and checks the version', t => {
test('Should accept an option object and checks the version', (t) => {
t.plan(2)
const opts = { hello: 'world', fastify: '>=0.10.0' }
function plugin (fastify, opts, next) {
function plugin (_fastify, _opts, next) {
next()
}
fp(plugin, opts)
t.ok(plugin[Symbol.for('skip-override')])
t.same(plugin[Symbol.for('plugin-meta')], opts)
t.assert.ok(plugin[Symbol.for('skip-override')])
t.assert.deepStrictEqual(plugin[Symbol.for('plugin-meta')], opts)
})
test('should set anonymous function name to file it was called from with a counter', t => {
test('should set anonymous function name to file it was called from with a counter', (t) => {
const fp = proxyquire('../plugin.js', { stubs: {} })
const fn = fp((fastify, opts, next) => {
const fn = fp((_fastify, _opts, next) => {
next()
})
t.equal(fn[Symbol.for('plugin-meta')].name, 'test-auto-0')
t.equal(fn[Symbol.for('fastify.display-name')], 'test-auto-0')
t.assert.strictEqual(fn[Symbol.for('plugin-meta')].name, 'test-auto-0')
t.assert.strictEqual(fn[Symbol.for('fastify.display-name')], 'test-auto-0')
const fn2 = fp((fastify, opts, next) => {
const fn2 = fp((_fastify, _opts, next) => {
next()
})
t.equal(fn2[Symbol.for('plugin-meta')].name, 'test-auto-1')
t.equal(fn2[Symbol.for('fastify.display-name')], 'test-auto-1')
t.end()
t.assert.strictEqual(fn2[Symbol.for('plugin-meta')].name, 'test-auto-1')
t.assert.strictEqual(fn2[Symbol.for('fastify.display-name')], 'test-auto-1')
})
test('should set function name if Error.stackTraceLimit is set to 0', t => {
test('should set function name if Error.stackTraceLimit is set to 0', (t) => {
const stackTraceLimit = Error.stackTraceLimit = 0
const fp = proxyquire('../plugin.js', { stubs: {} })
const fn = fp((fastify, opts, next) => {
const fn = fp((_fastify, _opts, next) => {
next()
})
t.equal(fn[Symbol.for('plugin-meta')].name, 'test-auto-0')
t.equal(fn[Symbol.for('fastify.display-name')], 'test-auto-0')
t.assert.strictEqual(fn[Symbol.for('plugin-meta')].name, 'test-auto-0')
t.assert.strictEqual(fn[Symbol.for('fastify.display-name')], 'test-auto-0')
const fn2 = fp((fastify, opts, next) => {
const fn2 = fp((_fastify, _opts, next) => {
next()
})
t.equal(fn2[Symbol.for('plugin-meta')].name, 'test-auto-1')
t.equal(fn2[Symbol.for('fastify.display-name')], 'test-auto-1')
t.assert.strictEqual(fn2[Symbol.for('plugin-meta')].name, 'test-auto-1')
t.assert.strictEqual(fn2[Symbol.for('fastify.display-name')], 'test-auto-1')
Error.stackTraceLimit = stackTraceLimit
t.end()
})
test('should set display-name to meta name', t => {
test('should set display-name to meta name', (t) => {
t.plan(2)
const functionName = 'superDuperSpecialFunction'
const fn = fp((fastify, opts, next) => next(), {
const fn = fp((_fastify, _opts, next) => next(), {
name: functionName
})
t.equal(fn[Symbol.for('plugin-meta')].name, functionName)
t.equal(fn[Symbol.for('fastify.display-name')], functionName)
t.assert.strictEqual(fn[Symbol.for('plugin-meta')].name, functionName)
t.assert.strictEqual(fn[Symbol.for('fastify.display-name')], functionName)
})
test('should preserve fastify version in meta', t => {
test('should preserve fastify version in meta', (t) => {
t.plan(1)
const opts = { hello: 'world', fastify: '>=0.10.0' }
const fn = fp((fastify, opts, next) => next(), opts)
const fn = fp((_fastify, _opts, next) => next(), opts)
t.equal(fn[Symbol.for('plugin-meta')].fastify, '>=0.10.0')
t.assert.strictEqual(fn[Symbol.for('plugin-meta')].fastify, '>=0.10.0')
})
test('should check fastify dependency graph - plugin', t => {
test('should check fastify dependency graph - plugin', async (t) => {
t.plan(1)
const fastify = Fastify()
fastify.register(fp((fastify, opts, next) => next(), {
fastify: '4.x',
fastify.register(fp((_fastify, _opts, next) => next(), {
fastify: '5.x',
name: 'plugin1-name'
}))
fastify.register(fp((fastify, opts, next) => next(), {
fastify: '4.x',
fastify.register(fp((_fastify, _opts, next) => next(), {
fastify: '5.x',
name: 'test',
dependencies: ['plugin1-name', 'plugin2-name']
}))
fastify.ready(err => {
t.equal(err.message, "The dependency 'plugin2-name' of plugin 'test' is not registered")
})
await t.assert.rejects(fastify.ready(), { message: "The dependency 'plugin2-name' of plugin 'test' is not registered" })
})
test('should check fastify dependency graph - decorate', t => {
test('should check fastify dependency graph - decorate', async (t) => {
t.plan(1)
const fastify = Fastify()
fastify.decorate('plugin1', fp((fastify, opts, next) => next(), {
fastify: '4.x',
fastify.decorate('plugin1', fp((_fastify, _opts, next) => next(), {
fastify: '5.x',
name: 'plugin1-name'
}))
fastify.register(fp((fastify, opts, next) => next(), {
fastify: '4.x',
fastify.register(fp((_fastify, _opts, next) => next(), {
fastify: '5.x',
name: 'test',
decorators: { fastify: ['plugin1', 'plugin2'] }
}))
fastify.ready(err => {
t.equal(err.message, "The decorator 'plugin2' required by 'test' is not present in Fastify")
})
await t.assert.rejects(fastify.ready(), { message: "The decorator 'plugin2' required by 'test' is not present in Fastify" })
})
test('should check fastify dependency graph - decorateReply', t => {
test('should check fastify dependency graph - decorateReply', async (t) => {
t.plan(1)
const fastify = Fastify()
fastify.decorateReply('plugin1', fp((fastify, opts, next) => next(), {
fastify: '4.x',
fastify.decorateReply('plugin1', fp((_fastify, _opts, next) => next(), {
fastify: '5.x',
name: 'plugin1-name'
}))
fastify.register(fp((fastify, opts, next) => next(), {
fastify: '4.x',
fastify.register(fp((_fastify, _opts, next) => next(), {
fastify: '5.x',
name: 'test',
decorators: { reply: ['plugin1', 'plugin2'] }
}))
fastify.ready(err => {
t.equal(err.message, "The decorator 'plugin2' required by 'test' is not present in Reply")
})
await t.assert.rejects(fastify.ready(), { message: "The decorator 'plugin2' required by 'test' is not present in Reply" })
})
test('should accept an option to encapsulate', t => {
t.plan(4)
test('should accept an option to encapsulate', async (t) => {
t.plan(3)
const fastify = Fastify()
fastify.register(fp((fastify, opts, next) => {
fastify.register(fp((fastify, _opts, next) => {
fastify.decorate('accessible', true)
next()
}, {
name: 'accessible-plugin'
}))
fastify.register(fp((fastify, opts, next) => {
fastify.register(fp((fastify, _opts, next) => {
fastify.decorate('alsoAccessible', true)
next()
}, {
@@ -280,7 +274,7 @@ test('should accept an option to encapsulate', t => {
encapsulate: false
}))
fastify.register(fp((fastify, opts, next) => {
fastify.register(fp((fastify, _opts, next) => {
fastify.decorate('encapsulated', true)
next()
}, {
@@ -288,105 +282,103 @@ test('should accept an option to encapsulate', t => {
encapsulate: true
}))
fastify.ready(err => {
t.error(err)
t.ok(fastify.hasDecorator('accessible'))
t.ok(fastify.hasDecorator('alsoAccessible'))
t.notOk(fastify.hasDecorator('encapsulated'))
})
await fastify.ready()
t.assert.ok(fastify.hasDecorator('accessible'))
t.assert.ok(fastify.hasDecorator('alsoAccessible'))
t.assert.ok(!fastify.hasDecorator('encapsulated'))
})
test('should check dependencies when encapsulated', t => {
test('should check dependencies when encapsulated', async (t) => {
t.plan(1)
const fastify = Fastify()
fastify.register(fp((fastify, opts, next) => next(), {
fastify.register(fp((_fastify, _opts, next) => next(), {
name: 'test',
dependencies: ['missing-dependency-name'],
encapsulate: true
}))
fastify.ready(err => {
t.equal(err.message, "The dependency 'missing-dependency-name' of plugin 'test' is not registered")
})
await t.assert.rejects(fastify.ready(), { message: "The dependency 'missing-dependency-name' of plugin 'test' is not registered" })
})
test('should check version when encapsulated', t => {
t.plan(1)
const fastify = Fastify()
test(
'should check version when encapsulated',
{ skip: /\d-.+/.test(pkg.devDependencies.fastify) },
async (t) => {
t.plan(1)
const fastify = Fastify()
fastify.register(fp((fastify, opts, next) => next(), {
name: 'test',
fastify: '<=2.10.0',
encapsulate: true
}))
fastify.register(fp((_fastify, _opts, next) => next(), {
name: 'test',
fastify: '<=2.10.0',
encapsulate: true
}))
fastify.ready(err => {
t.match(err.message, /fastify-plugin: test - expected '<=2.10.0' fastify version, '\d.\d+.\d+' is installed/)
})
})
await t.assert.rejects(fastify.ready(), { message: /fastify-plugin: test - expected '<=2.10.0' fastify version, '\d.\d+.\d+' is installed/ })
}
)
test('should check decorators when encapsulated', t => {
test('should check decorators when encapsulated', async (t) => {
t.plan(1)
const fastify = Fastify()
fastify.decorate('plugin1', 'foo')
fastify.register(fp((fastify, opts, next) => next(), {
fastify: '4.x',
fastify.register(fp((_fastify, _opts, next) => next(), {
fastify: '5.x',
name: 'test',
encapsulate: true,
decorators: { fastify: ['plugin1', 'plugin2'] }
}))
fastify.ready(err => {
t.equal(err.message, "The decorator 'plugin2' required by 'test' is not present in Fastify")
})
await t.assert.rejects(fastify.ready(), { message: "The decorator 'plugin2' required by 'test' is not present in Fastify" })
})
test('plugin name when encapsulated', async t => {
test('plugin name when encapsulated', async (t) => {
t.plan(6)
const fastify = Fastify()
fastify.register(function plugin (instance, opts, next) {
fastify.register(function plugin (_instance, _opts, next) {
next()
})
fastify.register(fp(getFn('hello'), {
fastify: '4.x',
fastify: '5.x',
name: 'hello',
encapsulate: true
}))
fastify.register(function plugin (fastify, opts, next) {
fastify.register(function plugin (fastify, _opts, next) {
fastify.register(fp(getFn('deep'), {
fastify: '4.x',
fastify: '5.x',
name: 'deep',
encapsulate: true
}))
fastify.register(fp(function genericPlugin (fastify, opts, next) {
t.equal(fastify.pluginName, 'deep-deep', 'should be deep-deep')
fastify.register(fp(function genericPlugin (fastify, _opts, next) {
t.assert.strictEqual(fastify.pluginName, 'deep-deep', 'should be deep-deep')
fastify.register(fp(getFn('deep-deep-deep'), {
fastify: '4.x',
fastify: '5.x',
name: 'deep-deep-deep',
encapsulate: true
}))
fastify.register(fp(getFn('deep-deep -> not-encapsulated-2'), {
fastify: '4.x',
fastify: '5.x',
name: 'not-encapsulated-2'
}))
next()
}, {
fastify: '4.x',
fastify: '5.x',
name: 'deep-deep',
encapsulate: true
}))
fastify.register(fp(getFn('plugin -> not-encapsulated'), {
fastify: '4.x',
fastify: '5.x',
name: 'not-encapsulated'
}))
@@ -396,8 +388,8 @@ test('plugin name when encapsulated', async t => {
await fastify.ready()
function getFn (expectedName) {
return function genericPlugin (fastify, opts, next) {
t.equal(fastify.pluginName, expectedName, `should be ${expectedName}`)
return function genericPlugin (fastify, _opts, next) {
t.assert.strictEqual(fastify.pluginName, expectedName, `should be ${expectedName}`)
next()
}
}

View File

@@ -1,24 +1,24 @@
'use strict'
const { test } = require('tap')
const { test } = require('node:test')
const toCamelCase = require('../lib/toCamelCase')
test('from kebab-case to camelCase', (t) => {
t.plan(1)
t.equal(toCamelCase('hello-world'), 'helloWorld')
t.assert.strictEqual(toCamelCase('hello-world'), 'helloWorld')
})
test('from @-prefixed named imports', (t) => {
t.plan(1)
t.equal(toCamelCase('@hello/world'), 'helloWorld')
t.assert.strictEqual(toCamelCase('@hello/world'), 'helloWorld')
})
test('from @-prefixed named kebab-case to camelCase', (t) => {
t.plan(1)
t.equal(toCamelCase('@hello/my-world'), 'helloMyWorld')
t.assert.strictEqual(toCamelCase('@hello/my-world'), 'helloMyWorld')
})
test('from kebab-case to camelCase multiple words', (t) => {
t.plan(1)
t.equal(toCamelCase('hello-long-world'), 'helloLongWorld')
t.assert.strictEqual(toCamelCase('hello-long-world'), 'helloLongWorld')
})

View File

@@ -1,6 +1,6 @@
import { FastifyPluginAsync } from "fastify";
import { FastifyPluginAsync } from 'fastify'
type FastifyExampleAsync = FastifyPluginAsync<fastifyExampleAsync.FastifyExampleAsyncOptions>;
type FastifyExampleAsync = FastifyPluginAsync<fastifyExampleAsync.FastifyExampleAsyncOptions>
declare namespace fastifyExampleAsync {
@@ -14,6 +14,6 @@ declare namespace fastifyExampleAsync {
export { fastifyExampleAsync as default }
}
declare function fastifyExampleAsync(...params: Parameters<FastifyExampleAsync>): ReturnType<FastifyExampleAsync>
declare function fastifyExampleAsync (...params: Parameters<FastifyExampleAsync>): ReturnType<FastifyExampleAsync>
export default fastifyExampleAsync

View File

@@ -1,6 +1,6 @@
import { FastifyPluginCallback } from "fastify";
import { FastifyPluginCallback } from 'fastify'
type FastifyExampleCallback = FastifyPluginCallback<fastifyExampleCallback.FastifyExampleCallbackOptions>;
type FastifyExampleCallback = FastifyPluginCallback<fastifyExampleCallback.FastifyExampleCallbackOptions>
declare namespace fastifyExampleCallback {
@@ -14,6 +14,6 @@ declare namespace fastifyExampleCallback {
export { fastifyExampleCallback as default }
}
declare function fastifyExampleCallback(...params: Parameters<FastifyExampleCallback>): ReturnType<FastifyExampleCallback>
declare function fastifyExampleCallback (...params: Parameters<FastifyExampleCallback>): ReturnType<FastifyExampleCallback>
export default fastifyExampleCallback

View File

@@ -10,7 +10,6 @@ import {
FastifyTypeProviderDefault,
FastifyBaseLogger,
} from 'fastify'
import { IncomingMessage, Server, ServerResponse } from 'http'
type FastifyPlugin = typeof fastifyPlugin
@@ -34,7 +33,7 @@ declare namespace fastifyPlugin {
* @deprecated Use PluginMetadata instead
*/
export interface PluginOptions extends PluginMetadata {}
export const fastifyPlugin: FastifyPlugin
export { fastifyPlugin as default }
}
@@ -54,9 +53,9 @@ declare function fastifyPlugin<
TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault,
Logger extends FastifyBaseLogger = FastifyBaseLogger,
Fn extends FastifyPluginCallback<Options, RawServer, TypeProvider, Logger> | FastifyPluginAsync<Options, RawServer, TypeProvider, Logger> = FastifyPluginCallback<Options, RawServer, TypeProvider, Logger>
>(
> (
fn: Fn extends unknown ? Fn extends (...args: any) => Promise<any> ? FastifyPluginAsync<Options, RawServer, TypeProvider, Logger> : FastifyPluginCallback<Options, RawServer, TypeProvider, Logger> : Fn,
options?: fastifyPlugin.PluginMetadata | string
): Fn;
): Fn
export = fastifyPlugin

View File

@@ -1,10 +1,10 @@
import fastifyPlugin from '..';
import fastify, { FastifyPluginCallback, FastifyPluginAsync, FastifyError, FastifyInstance, FastifyPluginOptions, RawServerDefault, FastifyTypeProviderDefault, FastifyBaseLogger } from 'fastify';
import fastifyPlugin from '..'
import fastify, { FastifyPluginCallback, FastifyPluginAsync, FastifyError, FastifyInstance, FastifyPluginOptions, RawServerDefault, FastifyTypeProviderDefault, FastifyBaseLogger } from 'fastify'
import { expectAssignable, expectError, expectNotType, expectType } from 'tsd'
import { Server } from "node:https"
import { TypeBoxTypeProvider } from "@fastify/type-provider-typebox"
import fastifyExampleCallback from './example-callback.test-d';
import fastifyExampleAsync from './example-async.test-d';
import { Server } from 'node:https'
import { TypeBoxTypeProvider } from '@fastify/type-provider-typebox'
import fastifyExampleCallback from './example-callback.test-d'
import fastifyExampleAsync from './example-async.test-d'
interface Options {
foo: string
@@ -14,15 +14,15 @@ const testSymbol = Symbol('foobar')
// Callback
const pluginCallback: FastifyPluginCallback = (fastify, options, next) => { }
const pluginCallback: FastifyPluginCallback = (_fastify, _options, _next) => { }
expectType<FastifyPluginCallback>(fastifyPlugin(pluginCallback))
const pluginCallbackWithTypes = (fastify: FastifyInstance, options: FastifyPluginOptions, next: (error?: FastifyError) => void): void => { }
const pluginCallbackWithTypes = (_fastify: FastifyInstance, _options: FastifyPluginOptions, _next: (error?: FastifyError) => void): void => { }
expectAssignable<FastifyPluginCallback>(fastifyPlugin(pluginCallbackWithTypes))
expectNotType<any>(fastifyPlugin(pluginCallbackWithTypes))
expectAssignable<FastifyPluginCallback>(fastifyPlugin((fastify: FastifyInstance, options: FastifyPluginOptions, next: (error?: FastifyError) => void): void => { }))
expectNotType<any>(fastifyPlugin((fastify: FastifyInstance, options: FastifyPluginOptions, next: (error?: FastifyError) => void): void => { }))
expectAssignable<FastifyPluginCallback>(fastifyPlugin((_fastify: FastifyInstance, _options: FastifyPluginOptions, _next: (error?: FastifyError) => void): void => { }))
expectNotType<any>(fastifyPlugin((_fastify: FastifyInstance, _options: FastifyPluginOptions, _next: (error?: FastifyError) => void): void => { }))
expectType<FastifyPluginCallback>(fastifyPlugin(pluginCallback, ''))
expectType<FastifyPluginCallback>(fastifyPlugin(pluginCallback, {
@@ -37,31 +37,31 @@ expectType<FastifyPluginCallback>(fastifyPlugin(pluginCallback, {
encapsulate: true
}))
const pluginCallbackWithOptions: FastifyPluginCallback<Options> = (fastify, options, next) => {
const pluginCallbackWithOptions: FastifyPluginCallback<Options> = (_fastify, options, _next) => {
expectType<string>(options.foo)
}
expectType<FastifyPluginCallback<Options>>(fastifyPlugin(pluginCallbackWithOptions))
const pluginCallbackWithServer: FastifyPluginCallback<Options, Server> = (fastify, options, next) => {
const pluginCallbackWithServer: FastifyPluginCallback<Options, Server> = (fastify, _options, _next) => {
expectType<Server>(fastify.server)
}
expectType<FastifyPluginCallback<Options, Server>>(fastifyPlugin(pluginCallbackWithServer))
const pluginCallbackWithTypeProvider: FastifyPluginCallback<Options, Server, TypeBoxTypeProvider> = (fastify, options, next) => { }
const pluginCallbackWithTypeProvider: FastifyPluginCallback<Options, Server, TypeBoxTypeProvider> = (_fastify, _options, _next) => { }
expectType<FastifyPluginCallback<Options, Server, TypeBoxTypeProvider>>(fastifyPlugin(pluginCallbackWithTypeProvider))
// Async
const pluginAsync: FastifyPluginAsync = async (fastify, options) => { }
const pluginAsync: FastifyPluginAsync = async (_fastify, _options) => { }
expectType<FastifyPluginAsync>(fastifyPlugin(pluginAsync))
const pluginAsyncWithTypes = async (fastify: FastifyInstance, options: FastifyPluginOptions): Promise<void> => { }
const pluginAsyncWithTypes = async (_fastify: FastifyInstance, _options: FastifyPluginOptions): Promise<void> => { }
expectType<FastifyPluginAsync<FastifyPluginOptions, RawServerDefault, FastifyTypeProviderDefault>>(fastifyPlugin(pluginAsyncWithTypes))
expectType<FastifyPluginAsync<FastifyPluginOptions, RawServerDefault, FastifyTypeProviderDefault>>(fastifyPlugin(async (fastify: FastifyInstance, options: FastifyPluginOptions): Promise<void> => { }))
expectType<FastifyPluginAsync<FastifyPluginOptions, RawServerDefault, FastifyTypeProviderDefault>>(fastifyPlugin(async (_fastify: FastifyInstance, _options: FastifyPluginOptions): Promise<void> => { }))
expectType<FastifyPluginAsync>(fastifyPlugin(pluginAsync, ''))
expectType<FastifyPluginAsync>(fastifyPlugin(pluginAsync, {
fastify: '',
@@ -75,19 +75,19 @@ expectType<FastifyPluginAsync>(fastifyPlugin(pluginAsync, {
encapsulate: true
}))
const pluginAsyncWithOptions: FastifyPluginAsync<Options> = async (fastify, options) => {
const pluginAsyncWithOptions: FastifyPluginAsync<Options> = async (_fastify, options) => {
expectType<string>(options.foo)
}
expectType<FastifyPluginAsync<Options>>(fastifyPlugin(pluginAsyncWithOptions))
const pluginAsyncWithServer: FastifyPluginAsync<Options, Server> = async (fastify, options) => {
const pluginAsyncWithServer: FastifyPluginAsync<Options, Server> = async (fastify, _options) => {
expectType<Server>(fastify.server)
}
expectType<FastifyPluginAsync<Options, Server>>(fastifyPlugin(pluginAsyncWithServer))
const pluginAsyncWithTypeProvider: FastifyPluginAsync<Options, Server, TypeBoxTypeProvider> = async (fastify, options) => { }
const pluginAsyncWithTypeProvider: FastifyPluginAsync<Options, Server, TypeBoxTypeProvider> = async (_fastify, _options) => { }
expectType<FastifyPluginAsync<Options, Server, TypeBoxTypeProvider>>(fastifyPlugin(pluginAsyncWithTypeProvider))
@@ -95,15 +95,15 @@ expectType<FastifyPluginAsync<Options, Server, TypeBoxTypeProvider>>(fastifyPlug
const server = fastify()
server.register(fastifyPlugin(pluginCallback))
server.register(fastifyPlugin(pluginCallbackWithTypes))
server.register(fastifyPlugin(pluginCallbackWithOptions))
server.register(fastifyPlugin(pluginCallbackWithServer))
server.register(fastifyPlugin(pluginCallbackWithTypeProvider))
server.register(fastifyPlugin(pluginCallbackWithTypes), { foo: 'bar' })
server.register(fastifyPlugin(pluginCallbackWithOptions), { foo: 'bar' })
server.register(fastifyPlugin(pluginCallbackWithServer), { foo: 'bar' })
server.register(fastifyPlugin(pluginCallbackWithTypeProvider), { foo: 'bar' })
server.register(fastifyPlugin(pluginAsync))
server.register(fastifyPlugin(pluginAsyncWithTypes))
server.register(fastifyPlugin(pluginAsyncWithOptions))
server.register(fastifyPlugin(pluginAsyncWithServer))
server.register(fastifyPlugin(pluginAsyncWithTypeProvider))
server.register(fastifyPlugin(pluginAsyncWithTypes), { foo: 'bar' })
server.register(fastifyPlugin(pluginAsyncWithOptions), { foo: 'bar' })
server.register(fastifyPlugin(pluginAsyncWithServer), { foo: 'bar' })
server.register(fastifyPlugin(pluginAsyncWithTypeProvider), { foo: 'bar' })
// properly handling callback and async
fastifyPlugin(function (fastify, options, next) {
@@ -123,8 +123,8 @@ fastifyPlugin<Options>(async function (fastify, options) {
expectType<Options>(options)
})
expectAssignable<FastifyPluginAsync<Options, RawServerDefault, FastifyTypeProviderDefault, FastifyBaseLogger>>(fastifyPlugin(async function (fastify: FastifyInstance, options: Options) { }))
expectNotType<any>(fastifyPlugin(async function (fastify: FastifyInstance, options: Options) { }))
expectAssignable<FastifyPluginAsync<Options, RawServerDefault, FastifyTypeProviderDefault, FastifyBaseLogger>>(fastifyPlugin(async function (_fastify: FastifyInstance, _options: Options) { }))
expectNotType<any>(fastifyPlugin(async function (_fastify: FastifyInstance, _options: Options) { }))
fastifyPlugin(async function (fastify, options: Options) {
expectType<FastifyInstance>(fastify)
@@ -137,13 +137,13 @@ fastifyPlugin(async function (fastify, options) {
})
expectError(
fastifyPlugin(async function (fastify, options: Options, next) {
fastifyPlugin(async function (fastify, options: Options, _next) {
expectType<FastifyInstance>(fastify)
expectType<Options>(options)
})
)
expectAssignable<FastifyPluginCallback<Options>>(fastifyPlugin(function (fastify, options, next) { }))
expectNotType<any>(fastifyPlugin(function (fastify, options, next) { }))
expectAssignable<FastifyPluginCallback<Options>>(fastifyPlugin(function (_fastify, _options, _next) { }))
expectNotType<any>(fastifyPlugin(function (_fastify, _options, _next) { }))
fastifyPlugin(function (fastify, options: Options, next) {
expectType<FastifyInstance>(fastify)
@@ -152,7 +152,7 @@ fastifyPlugin(function (fastify, options: Options, next) {
})
expectError(
fastifyPlugin(function (fastify, options: Options, next) {
fastifyPlugin(function (fastify, options: Options, _next) {
expectType<FastifyInstance>(fastify)
expectType<Options>(options)
return Promise.resolve()