Giter Club home page Giter Club logo

fastify-plugin's Introduction

fastify-plugin

CI NPM version js-standard-style

fastify-plugin is a plugin helper for Fastify.

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

npm i fastify-plugin

Usage

fastify-plugin can do three things for you:

  • Add the skip-override hidden property
  • Check the bare-minimum version of Fastify
  • Pass some custom metadata of the plugin to Fastify

Example using a callback:

const fp = require('fastify-plugin')

module.exports = fp(function (fastify, opts, done) {
  // your plugin code
  done()
})

Example using an async function:

const fp = require('fastify-plugin')

// A callback function param is not required for async functions
module.exports = fp(async function (fastify, opts) {
  // Wait for an async function to fulfill promise before proceeding
  await exampleAsyncFunction()
})

Metadata

In addition, if you use this module when creating new plugins, you can declare the dependencies, the name, and the expected Fastify version that your plugin needs.

Fastify version

If you need to set a bare-minimum version of Fastify for your plugin, just add the semver range that you need:

const fp = require('fastify-plugin')

module.exports = fp(function (fastify, opts, done) {
  // your plugin code
  done()
}, { fastify: '4.x' })

If you need to check the Fastify version only, you can pass just the version string.

You can check here how to define a semver range.

Name

Fastify uses this option to validate the dependency graph, allowing it to ensure that no name collisions occur and making it possible to perform dependency checks.

const fp = require('fastify-plugin')

function plugin (fastify, opts, done) {
  // your plugin code
  done()
}

module.exports = fp(plugin, {
  fastify: '4.x',
  name: 'your-plugin-name'
})

Dependencies

You can also check if the plugins and decorators that your plugin intend to use are present in the dependency graph.

Note: This is the point where registering name of the plugins become important, because you can reference plugin dependencies by their name.

const fp = require('fastify-plugin')

function plugin (fastify, opts, done) {
  // your plugin code
  done()
}

module.exports = fp(plugin, {
  fastify: '4.x',
  decorators: {
    fastify: ['plugin1', 'plugin2'],
    reply: ['compress']
  },
  dependencies: ['plugin1-name', 'plugin2-name']
})

Encapsulate

By default, fastify-plugin breaks the encapsulation but you can optionally keep the plugin encapsulated. This allows you to set the plugin's name and validate its dependencies without making the plugin accessible.

const fp = require('fastify-plugin')

function plugin (fastify, opts, done) {
  // the decorator is not accessible outside this plugin
  fastify.decorate('util', function() {})
  done()
}

module.exports = fp(plugin, {
  name: 'my-encapsulated-plugin',
  fastify: '4.x',
  decorators: {
    fastify: ['plugin1', 'plugin2'],
    reply: ['compress']
  },
  dependencies: ['plugin1-name', 'plugin2-name'],
  encapsulate: true
})

Bundlers and Typescript

fastify-plugin adds a .default and [name] property to the passed in function. The type definition would have to be updated to leverage this.

Known Issue: TypeScript Contextual Inference

Documentation Reference

It is common for developers to inline their plugin with fastify-plugin such as:

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:

  1. The third argument done (the callback part)
  2. The return type FastifyPluginCallback or FastifyPluginAsync

At this time, TypeScript inference is not smart enough to differentiate by definition argument length alone.

Thus, if you are a TypeScript developer please use on the following patterns instead:

// Callback

// Assign type directly
const pluginCallback: FastifyPluginCallback = (fastify, options, done) => { }
fp(pluginCallback)

// or define your own function declaration that satisfies the existing definitions
const pluginCallbackWithTypes = (fastify: FastifyInstance, options: FastifyPluginOptions, done: (error?: FastifyError) => void): void => { }
fp(pluginCallbackWithTypes)
// or inline
fp((fastify: FastifyInstance, options: FastifyPluginOptions, done: (error?: FastifyError) => void): void => { })

// Async

// Assign type directly
const pluginAsync: FastifyPluginAsync = async (fastify, options) => { }
fp(pluginAsync)

// or define your own function declaration that satisfies the existing definitions
const pluginAsyncWithTypes = async (fastify: FastifyInstance, options: FastifyPluginOptions): Promise<void> => { }
fp(pluginAsyncWithTypes)
// or inline
fp(async (fastify: FastifyInstance, options: FastifyPluginOptions): Promise<void> => { })

Acknowledgements

This project is kindly sponsored by:

License

Licensed under MIT.

fastify-plugin's People

Contributors

cemremengu avatar delvedor avatar dependabot[bot] avatar eomm avatar ethan-arrowood avatar fdawgs avatar fox1t avatar github-actions[bot] avatar greenkeeper[bot] avatar j-hoh avatar joobisb avatar jordanebelanger avatar jsumners avatar kirapc avatar lependu avatar matthyk avatar mcollina avatar nileshmali avatar nurdism avatar olyop avatar phra avatar rafaelgss avatar salmanm avatar shaenchen avatar simenb avatar smartiniongithub avatar thomheymann avatar uzlopak avatar vinicius0026 avatar zekth avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fastify-plugin's Issues

extractPluginName sometimes fails with Bun

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Fastify version

4.24.3

Plugin version

4.5.1

Node.js version

x

Operating system

macOS

Operating system version (i.e. 20.04, 11.3, 10)

14.0

Description

Hello

I've encountered an error with Bun v1.0.23 in the extractPluginName function

The logs format in node and in Bun are sometimes not the same, and for the Fastify Session plugin it's shown as "" in the logs

I've made it to work by changing

return m ? m[1].split(/[/\\]/).slice(-1)[0].match(fileNamePattern)[1] : 'anonymous'

to

return m ? m[1]?.split(/[/\\]/)?.slice(-1)?.[0]?.match(fileNamePattern)?.[1] : 'anonymous'

If you have another idea, it could be even better, but aside from that everything is working well with Bun

Steps to Reproduce

Using Nest.JS

import { Authenticator } from '@fastify/passport'
import fastifySession from '@fastify/session'

const createFileStore = await import('session-file-store')
store = new (createFileStore.default(fastifySession))({})

await app.register(fastifyCookie)
await app.register(
fastifySession,
{
store,
secret: "SECRET",
saveUninitialized: false,
cookieName: 'COOKIE_NAME',
cookie: {
maxAge: 60 * 60 * 1000,
httpOnly: true,
secure: env.NODE_ENV === 'production',
},
},
)

fastifyPassport.registerUserSerializer(async user => user)

fastifyPassport.registerUserDeserializer(async payload => payload)

await app.register(fastifyPassport.initialize())
await app.register(fastifyPassport.secureSession())

const fastifyInstance: FastifyInstance = app.getHttpAdapter().getInstance()
fastifyInstance
.decorateReply('setHeader', async function (name: string, value: unknown): Promise {
return await this.header(name, value)
})
.decorateReply('end', async function (): Promise {
return await this.send()
})

Expected Behavior

Use nullish coalescing to avoid some edge cases

Confusing name for anonymous plugins

If you register an anonymous plugin inside fastify this part leads to confusing plugin names.

For example

  fastify.register(fp((instance, opts, next) => {
    instance.decorate('anonymous', (a, b) => a + b)
    next()
  }))

will return cemre as the name of the plugin for me instead of the file name which was very confusing since it is my first name 😄

I think this is due to windows (the regex fails there) since all tests fail for me as well.

Fastify 2.0 support

Can't build my app since Fastify 2 upgrade, fastify-plugin breaks with:

Error: fastify-plugin - expected '^1.0.0' fastify version, '2.0.0' is installed

On removing that check from fastify-plugin source (~ line 65) all works fine again, not a suggestion, for sure will exists a better fix than that 😅 , but seems that this check is the only problem.

Broken Typescript types when defining options and done

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Fastify version

4.18.0

Plugin version

4.5.0

Node.js version

18

Operating system

Linux

Operating system version (i.e. 20.04, 11.3, 10)

Description

I can't define a plugin with options and done callback

import fp from "fastify-plugin";

export default fp(function Health(fastify, opts, done) {
  fastify.get("/health", (req, res) => {
    res.send();
  });
});

Results in TS7006: Parameter 'opts' implicitly has an 'any' type.

Steps to Reproduce

See description.

Workaround:

import fp from "fastify-plugin";
import { FastifyPluginCallback } from "fastify";

const plugin: FastifyPluginCallback = function Health(fastify, opts, done) {
  fastify.get("/health", (req, res) => {
    res.send();
  });

  done();
};

export default fp(plugin);

Expected Behavior

No response

An in-range update of semver is breaking the build 🚨

Version 5.5.0 of semver was just published.

Branch Build failing 🚨
Dependency semver
Current Version 5.4.1
Type dependency

This version is covered by your current version range and after updating it in your project the build failed.

semver is a direct dependency of this project, and it is very likely causing it to break. If other packages depend on yours, this update is probably also breaking those in turn.

Status Details
  • continuous-integration/travis-ci/push The Travis CI build could not complete due to an error Details

Commits

The new version differs by 7 commits.

  • 44cbc84 v5.5.0
  • 1d37529 Cleaned up coerce behavior
  • e7092b4 Improved coerce regex and added coerce to README.
  • 68cef2d Added version coercion to the module and CLI.
  • ec6f97a range.bnf: Fix invalid bracket expression
  • 906b664 travis: don't cache node_modules
  • 7184ff4 range.bnf: Remove unnecessary empty entry

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

passing route specific arguments to body parser plugin

I was trying to write a body parser to support multiple content types. To parse nimn to json, I need to pass simplified object structure to the parser which is accepted by particular route.

var nimnInstance = new nimn();
nimnInstance.addSchema(schema);
//some code here
var nimndata = nimnInstance.encode(jObj);
var jObj2 = nimnInstance.decode(nimndata);

Better error output

🚀 Feature Proposal

Add the plugin name to the output of the errors

Motivation

Right now if a module need a fastify version the error is this one:

Error: fastify-plugin - expected '<2.12.0' fastify version, '2.12.0' is installed

But I don't know which plugin is throwing the error

Example

Error: fastify-module-name - expected '<2.12.0' fastify version, '2.12.0' is installed

TS: Left side of comma operator is unused and has no side effects.

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Fastify version

3.28.0

Plugin version

No response

Node.js version

16.10

Operating system

macOS

Operating system version (i.e. 20.04, 11.3, 10)

Monterey 12.3.1

Description

When using Tap with TypeScript, ts-node fails to compile the Typescript code.

TS2695: Left side of comma operator is unused and has no side effects.
exports.default = (0, fastify_plugin_1.default)(async (fastify, _options) => {
    at createTSError (/node_modules/ts-node/src/index.ts:820:12)
    at reportTSError (/node_modules/ts-node/src/index.ts:824:19)
    at getOutput (/node_modules/ts-node/src/index.ts:1014:36)
    at Object.compile (/node_modules/ts-node/src/index.ts:1322:43)
    at Module.m._compile (/node_modules/ts-node/src/index.ts:1454:30)
    at Module.m._compile (/node_modules/ts-node/src/index.ts:1455:23)
    at module.exports (/node_modules/default-require-extensions/js.js:7:9)
    at /node_modules/append-transform/index.js:64:4
    at require.extensions.<computed> (/node_modules/ts-node/src/index.ts:1458:12)
    at /node_modules/append-transform/index.js:64:4 {
  diagnosticCodes: [ 2695 ]
}

Steps to Reproduce

tsconfig.json

{
  "compilerOptions": {
    "baseUrl": "./",
    "newLine": "lf",
    "paths": {
      "@/*": ["../src/*"],
      "@/models/*": ["../src/models/*"]
    },
    "typeRoots": ["../node_modules/@types", "../types"],
    "types": ["node"],
    "allowSyntheticDefaultImports": true,
    "target": "ES2020",
    "lib": ["ESNext"],
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "forceConsistentCasingInFileNames": true,
    "moduleResolution": "node",
    "module": "commonjs",
    "pretty": true,
    "sourceMap": false,
    "resolveJsonModule": true,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "allowUnusedLabels": true,
    "allowJs": true,
    "noEmit": false,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "noEmitHelpers": true,
    "importHelpers": true
  }
}

Plugin implementation

import mongoSanitize from 'express-mongo-sanitize'
import { FastifyInstance, FastifyPluginOptions, FastifyReply, FastifyRequest, HookHandlerDoneFunction } from 'fastify'
import fp from 'fastify-plugin'

export default fp(async (fastify: FastifyInstance, _options: FastifyPluginOptions): Promise<void> => {
  fastify.addHook('preHandler', function (request: FastifyRequest, reply: FastifyReply, done: HookHandlerDoneFunction) {
    const payload = request.body as Record<string, unknown> | unknown[]
    const isMongo = request.server.config.DB_CONNECTION === 'mongo'
    if (payload && isMongo) {
      mongoSanitize.sanitize(payload)
    }
    done()
  })
})

To register tsconfig with node-tap:

tsnode.register({
    project: './test/tsconfig.json',
    files: true
  })

Package.json

{
  "name": "Test app",
  "version": "0.0.1",
  "description": "test",
  "main": "./dist/index.js",
  "scripts": {
    "prebuild": "npm run build:clean",
    "build": "npm run tsc:build",
    "build:clean": "rm -f tsconfig.build.tsbuildinfo && rm -Rf ./dist/* ; exit 0",
    "start": "node ./dist/index.js",
    "test": "tap --ts --reporter=spec test/tests/*.test.ts",
  },
  "license": "MIT",
  "dependencies": {
    "@fastify/auth": "^2.0.0",
    "@fastify/autoload": "^4.0.1",
    "@fastify/compress": "^5.0.0",
    "@fastify/cookie": "^6.0.0",
    "@fastify/cors": "^7.0.0",
    "@fastify/env": "^3.0.0",
    "@fastify/formbody": "^6.0.0",
    "@fastify/helmet": "^8.0.0",
    "@fastify/jwt": "^5.0.1",
    "@fastify/multipart": "^6.0.0",
    "@fastify/passport": "^1.0.1",
    "@fastify/rate-limit": "^6.0.0",
    "@fastify/sensible": "^4.0.0",
    "@fastify/session": "^8.2.0",
    "@fastify/swagger": "^6.0.1",
    "@sentry/node": "^6.19.7",
    "@sentry/tracing": "^6.19.7",
    "@typegoose/typegoose": "^9.8.1",
    "axios": "^0.27.2",
    "express-mongo-sanitize": "^2.2.0",
    "fastify": "^3.28.0",
    "http-status": "^1.5.1",
    "joi": "^17.6.0",
    "json-joi-converter": "^17.2.1-f",
    "jsonwebtoken": "^8.5.1",
    "lint-staged": "^12.4.1",
    "luxon": "^2.3.2",
    "mongoose": "^6.3.2",
    "mongoose-autopopulate": "^0.16.1",
    "mongoose-findorcreate": "^3.0.0",
    "mongoose-lean-virtuals": "^0.9.1",
    "mongoose-slug-updater": "^3.3.0",
    "passport": "^0.5.2",
    "passport-jwt": "^4.0.0",
    "passport-local": "^1.0.0",
    "pino": "^7.11.0",
    "pino-pretty": "^7.6.1",
    "qs": "^6.10.3",
    "reflect-metadata": "^0.1.13",
    "tsyringe": "^4.6.0"
  },
  "devDependencies": {
    "@commitlint/cli": "^16.2.4",
    "@commitlint/config-conventional": "^16.2.4",
    "@types/busboy": "^1.5.0",
    "@types/faker": "^6.6.8",
    "@types/http-errors": "^1.8.2",
    "@types/jsonwebtoken": "^8.5.8",
    "@types/luxon": "^2.3.2",
    "@types/mongoose-lean-virtuals": "^0.5.3",
    "@types/passport-jwt": "^3.0.6",
    "@types/passport-local": "^1.0.34",
    "@types/tap": "^15.0.7",
    "@typescript-eslint/eslint-plugin": "^5.22.0",
    "@typescript-eslint/parser": "^5.22.0",
    "eslint": "^8.14.0",
    "eslint-config-prettier": "^8.5.0",
    "eslint-plugin-import": "^2.26.0",
    "eslint-plugin-prettier": "^4.0.0",
    "eslint-plugin-simple-import-sort": "^7.0.0",
    "faker": "^6.6.6",
    "husky": "^7.0.4",
    "mongodb-memory-server": "^8.5.2",
    "prettier": "^2.6.2",
    "tap": "^16.2.0",
    "ts-node": "^10.7.0",
    "ts-node-dev": "^1.1.8",
    "tsconfig-paths": "^4.0.0",
    "tscpaths": "^0.0.9",
    "tslint-config-prettier": "^1.18.0",
    "typescript": "^4.6.4"
  },
  "tap": {
    "before": "./test/index.ts"
  },
  "private": true,
  "engines": {
    "node": ">=16.0.0"
  },
  "optionalDependencies": {
    "npm-check-updates": "^12.5.11"
  }
}

Running npm run test

Expected Behavior

To pass, but it rather fails on the line of adding a hook with the already mentioned error.

`semver.coerce`?

Should semver.coerce be used here so that pre-releases of Fastify can be used without requiring an update to this module?

if (fastifyVersion && !semver.satisfies(fastifyVersion, version)) {

Update the documentation to reflect typescript changes from v 4.5.1

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the issue has not already been raised

Issue

Documentation on typescript changes in v. .4.5.1 should be made. It should be made clear that mixing callback and async-await style is not permitted, to avoid reports like #220 .
Also it should be detemined if the "TypeScript Contextual Inference" as described in the Readme.md is still an issue and corrected if necessary.

Make plugin name more accessible

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the feature has not already been requested

🚀 Feature Proposal

If I create a plugin like...

// database.ts 
const plugin: FastifyPluginAsync = async (api, options) => {
    api.decorate('db', null)
    // impl details
}

export default fp(plugin, {name:'db'})

And then I want to have another plugin that depends on that one but I don't want to hardcode the name, I can do it like this:

import dbPlugin from './database'

const plugin: FastifyPluginAsync = async (api, options) => {
    api.decorateRequest('user', null)
    // details
}

export default fp(plugin, {name:'user',dependencies:[dbPlugin.default[Symbol.for('fastify.display-name')]]})

But .default[Symbol.for('fastify.display-name')] is kind of a funky way to extract the plugin name.

Couldn't we add .pluginName directly to the the return function from fp? Or if you want to keep it a little more hidden, then can Fastify export these Symbols instead of having us reverse-engineer to find out what they are?

Motivation

Given above. Want easier access to this var. Also, TypeScript is freaking out when I try to access dbPlugin.default[Symbol.for('fastify.display-name')]]

Example

Above.

custom error handler not breaking encapsulation using fastify-plugin

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Fastify version

4.26.2

Plugin version

4.5.1

Node.js version

14.18.0

Operating system

Linux

Operating system version (i.e. 20.04, 11.3, 10)

14.3

Description

i have set 2 error handlers, i want that error handler that is sending response 'internal error' should be invoked when handler throws error, but in this external custom error handler is getting invoked and reply sent is 'external error'

const fastify = require("fastify");
const app = fastify({logger: true, caseSensitive: false});
const fp = require('fastify-plugin')
app.register(function (app,options, done){
    app.route({
        method: "post",
        url : '/testingApi', 
        handler: async (req, res) => {
            throw new Error("in api handler");
            req.result = { msg: "sent successfully"};
            res.status(200).send(req.result);
        }
    });
    app.register(fp(addErrorHandler), {});
    done();
})

const addErrorHandler = (app, options, done) => {
    app.setErrorHandler(async (err, req, res) => {
        res.status(500).send('internal error');
        return res;
    })
    done();
}

app.setErrorHandler(async (err, req, res) => {
    res.status(500).send('external error');
    return res;
})

app.addHook('onReady', (done) => {
    console.log("Service running on port: 3000");
    done();
});
app.listen({host: 'localhost', port: 3000});

Link to code that reproduces the bug

No response

Expected Behavior

should get reply 'internal error' on hitting api /testingApi

Validate if a rewrite in TS has any performance penalty

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the feature has not already been requested

🚀 Feature Proposal

Maintaining types is hard and error-prone. I opened this issue to make an experiment if a rewrite of this module in TS has any performance penalty. If this experiment succeeds, we can simplify contributions and don't have to maintain TS types separately.

  • Rewrite in TS without breaking changes
  • Validate the performance of JS and TS versions.

@kibertoad

fastify-plugin cannot be bundle

🐛 Bug Report

After that change #94 I can't bundle fastify using Webpack because require.main.filename is undefined.

To Reproduce

Steps to reproduce the behavior:

  • Download fastify-webpack.zip
  • npm ci
  • npm run build
  • node .
  • And you'll see: fastify not found, proceeding anyway

Expected behavior

Fastify plugin should handle the case where require.main.filename is undefined.

Possible solution

I think it'll would be better to mix the previous solution and new one.
Something like that should do the trick:

if (require.main.filename) {
  const pkgPath = join(dirname(require.resolve('fastify', { paths: [require.main.filename] })), 'package.json')
  fastifyVersion = semver.coerce(require(pkgPath).version)
} else {
  fastifyVersion = semver.coerce(require('fastify/package.json').version)
}

Your Environment

  • node version: 10
  • fastify version: 3.1.1
  • os: Windows

express-style fastify app inheritance

Is there any way I can not pass a function with several routes (fastify.register) and instead do something of the following nature:

const fastify = require('fastify');
const app = fastify();
const extended = fastify();

app.use('/foo', extended);

// or

app.register(extended, {});

similar to how express would do extensions for routes?

An in-range update of fastify is breaking the build 🚨

Version 1.11.2 of fastify was just published.

Branch Build failing 🚨
Dependency fastify
Current Version 1.11.1
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

fastify is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • continuous-integration/travis-ci/push: The Travis CI build could not complete due to an error (Details).

Release Notes v1.11.2

Internals

  • Handle promises in the error handler with the same logic of normal handlers - #1134
  • Rename ContentTypeParser - #1123
  • after should not cause inject() to be called - #1132

Documentation

  • Add trivikr@ to the collaborators list - #1139
  • Updated ecosystem doc - #1137
Commits

The new version differs by 13 commits.

  • 4e047a8 Bumped v1.11.2
  • c40ea62 Add trivikr@ to the collaborators list (#1139)
  • 0a27c92 Correct typos in Github Issue Template (#1140)
  • 5b18645 Updated ecosystem doc (#1137)
  • 0a874b9 Handle promises in the error handler with the same logic of normal handlers (#1134)
  • cce1a85 Rename ContentTypeParser (#1123)
  • 6d302a5 Add test for error fixed in mcollina/avvio#74 (#1132)
  • 60b85e7 Update Validation-and-Serialization.md (#1124)
  • d6982ea Remove/Merge redundant decorate functions (#1120)
  • baeebef Updated standard to v12. (#1121)
  • 7c8401d Update ContentTypeParser.js (#1122)
  • a14397d ecosystem in alphabetical order
  • 8a0c618 Update Ecosystem.md (#1125)

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Pointers on unit testing fastify plugin

Hi!

Any pointers as to unit test individual fastify plugins and on integration testing between plugins? fastify.inject is fine for HTTP, and I can decouple most plugins from fastify itself, but sometimes you need specific integrations that are error prone setting up by hand, and where you'd like to actually test it in fastify.

fn invalid parameters after 4.5.1 update

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Fastify version

4.20.0

Plugin version

4.5.1

Node.js version

20

Operating system

macOS

Operating system version (i.e. 20.04, 11.3, 10)

13.3

Description

After updating plugin to version 4.5.1, my previously existing project has stopped to work with the following error:

Argument of type '(server: FastifyInstance, _: FastifyPluginOptions, done: (err?: Error | undefined) => void) => Promise<void>' is not assignable to parameter of type 'FastifyPluginAsync<FastifyPluginOptions, RawServerDefault, FastifyTypeProviderDefault, FastifyBaseLogger>'.

I've been loking for some update where this change is described and how to update my code to make it works, but can't find anything (downgrading to version 4.5.0, it works again with no problem), but I can't find what I need to change in my call to fp() to make it works with new version.

Steps to Reproduce

After update to fastify-plugin 4.5.1, just try to call fp() with previous working parameters, like:

 fp(async (server: FastifyInstance, opts: FastifyPluginOptions, done: (err?: Error | undefined) => void)  => {
    ........
    done();
});

and it will return following error:

Argument of type '(server: FastifyInstance, opts: FastifyPluginOptions, done: (err?: Error | undefined) => void) => Promise<void>' is not assignable to parameter of type 'FastifyPluginAsync<FastifyPluginOptions, RawServerDefault, FastifyTypeProviderDefault, FastifyBaseLogger>'.

Expected Behavior

To keep working as previous versions.

Using npm-link while developing plugin fails

/test-server/index.js

const fastify = require('fastify')()
fastify.register(require('fastify-example'), (err) => {
  if (err) throw err
})

/fastify-example/plugin.js

const fp = require('fastify-plugin')
function plugin (fastify, opts, next) {
  // do something cool
  next()
}
module.exports = fp(plugin, '>=0.15.0')

/fastify-example/> npm link
/fastify-example/> cd ..
/> cd test-server
/test-server/> npm link fastify-example
/test-server/> node index.js
Error: Cannot find module 'fastify/package.json'
    at Function.Module._resolveFilename (module.js:469:15)
    at Function.Module._load (module.js:417:25)
    at Module.require (module.js:497:17)
    at require (internal/module.js:20:19)
    at plugin (/fastify-example/node_modules/fastify-plugin/index.js:15:59)
    at Object.<anonymous> (/fastify-example/plugin.js:6:18)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)

fastify-plugin can't support to load the esmodule

typescript module:
import fp from 'fastify-plugin'
import IFastifyInstance from '@airpay-sz/admin-common/dist/ts/types/IFastifyInstance'

export default fp(
(fastify: IFastifyInstance) => {
fastify.decorate('timestamp', function() {
return Date.now()
})
},
{
name: 'fastify-timestamp'
}
)
tsc to js code
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fastify_plugin_1 = __importDefault(require("fastify-plugin"));
exports = fastify_plugin_1.default((fastify) => {
fastify.decorate('timestamp', function () {
return Date.now();
});
}, {
fastify: '>=2.x',
name: 'fastify-timestamp'
});
the js code can't be load by fastify-plugin
Boot.prototype.use = function (plugin, opts) {
if (typeof plugin === 'function') { // the plugin is an object
this._addPlugin(plugin, opts, false)
} else {
throw new Error('plugin must be a function')
}

return this
}

Version 10 of node.js has been released

Version 10 of Node.js (code name Dubnium) has been released! 🎊

To see what happens to your code in Node.js 10, Greenkeeper has created a branch with the following changes:

  • Added the new Node.js version to your .travis.yml

If you’re interested in upgrading this repo to Node.js 10, you can open a PR with these changes. Please note that this issue is just intended as a friendly reminder and the PR as a possible starting point for getting your code running on Node.js 10.

More information on this issue

Greenkeeper has checked the engines key in any package.json file, the .nvmrc file, and the .travis.yml file, if present.

  • engines was only updated if it defined a single version, not a range.
  • .nvmrc was updated to Node.js 10
  • .travis.yml was only changed if there was a root-level node_js that didn’t already include Node.js 10, such as node or lts/*. In this case, the new version was appended to the list. We didn’t touch job or matrix configurations because these tend to be quite specific and complex, and it’s difficult to infer what the intentions were.

For many simpler .travis.yml configurations, this PR should suffice as-is, but depending on what you’re doing it may require additional work or may not be applicable at all. We’re also aware that you may have good reasons to not update to Node.js 10, which is why this was sent as an issue and not a pull request. Feel free to delete it without comment, I’m a humble robot and won’t feel rejected 🤖


FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Document plugin name

In fastify we reference hard to meta.name to validate the dependency graph. We should document it and explain the relation.

named exports are not right after renaming the modules

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Fastify version

x

Plugin version

4.0.0

Node.js version

x

Operating system

Linux

Operating system version (i.e. 20.04, 11.3, 10)

22.04

Description

Lets say we have a package called fastify-kafka. getCamelCase modifies the plugin name to fastifyKafka. Now I rename the module to @fastify/kafka. I would actually still expect that the named export is fastifyKafka. But no. It is @fastify/kafka

Steps to Reproduce

See
fastify/fastify-kafka#69

Expected Behavior

I would expect that the name is fastifyKafka

`fastify not found, proceeding anyway` if running ES module Node.js program

💥 Regression Report

Loading plugins which use fastify-plugin produces a warning message when running a native ES module program.

Last working version

Worked up to version: 2.0.2

Stopped working in version: 2.0.3

To Reproduce

Steps to reproduce the behavior:

Install latest fastify and fastify-static, run the following script.mjs (tested in Node.js 14.8.0):

// script.mjs
import fastifyStatic from 'fastify-static';

Expected behavior

fastify-static should validate the expected version of fastify is installed, nothing should display. Instead it prints:

fastify not found, proceeding anyway

Adding a printout of the exception shows TypeError: Cannot read property 'filename' of undefined.

Your Environment

  • node version: 14.8.0
  • fastify version: 3.2.1
  • os: Linux
  • Looks to be caused by #94 and #97

Introduce an option to encapsulate the plugin

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the feature has not already been requested

🚀 Feature Proposal

Introduce an option encapsulate?: boolean. Defaults to false. When set to true, keep the plugin encapsulated.

Motivation

fastify-plugin currently makes all plugins accessible by setting skip-override. It would be nice to have an option to keep it encapsulated, so you can set a plugin's name, metadata, etc without affecting the plugin's scope.

Would you consider a PR for this?

Example

module.exports = fp(plugin, {
  fastify: '4.x',
  decorators: {
    fastify: ['plugin1', 'plugin2'],
    reply: ['compress']
  },
  dependencies: ['plugin1-name', 'plugin2-name'],
  encapsulate: true,
})

Error creating a new TypeScript plugin using `fastify-plugin`

You have already researched for similiar issues?

Yes, didn't find anything.

What are you trying to achieve or the steps to reproduce?

I'm writing a plugin using fastify-plugin in TypeScript. I'm having issues with the types for fastify-plugin. I want to declare the types for my plugin and also pass plugin options (with plugin name and dependencies) to the plugin, but these two seem to be coupled in the fastify-plugin/plugin.d.ts type definitions.

This is my plugin code:

import fp from "fastify-plugin";

interface Options {
  someOpt: string
}

export default fp(async (server, options: Options) => {
  // do something
}, {
  fastify: "3.x",
  name: "plugin-name",
  dependencies: ["some-deps"],
});

What was the result you received?

This is the TypeScript error I'm getting:

No overload matches this call.
  The last overload gave the following error.
    Argument of type '{ fastify: string; name: string; dependencies: string[]; }' is not assignable to parameter of type 'string'.ts(2769)

What did you expect?

I expect to be able to declare plugin-specific options types that are decoupled from plugin metadata interface.

The issue seems to come from this type definition:

export default function fp<Options>(
  fn: FastifyPluginAsync<Options>,
  options?: Options & PluginOptions,
): FastifyPluginAsync<Options>;

where the Options type param is combined (using the intersection type operator) with the PluginOptions interface. It seems to me that these should not be coupled like that. Maybe something like this would work?

export default function fp<Options>(
  fn: FastifyPluginAsync<Options>,
  options?: PluginOptions,
): FastifyPluginAsync<Options>;

or, if we need a type param for the plugin metadata interface, maybe something like this:

export default function fp<Options, PluginOptions>(
  fn: FastifyPluginAsync<Options>,
  options?: PluginOptions,
): FastifyPluginAsync<Options>;

I can move this issue to the fastify-plugin repo as a bug if that's appropriate. Thank you!

Context

  • node version: 12
  • typescript version: 3.9.6
  • fastify-plugin version: 2.0.1
  • os: Mac

Typescript error on usage

🐛 Bug Report

fastify-plugin + fastify on typescript not work as expected. I understand the problem when this doc was created: https://github.com/fastify/fastify-plugin#known-issue-typescript-contextual-inference, but following the examples not works as well. I created a reproduction code https://github.com/RafaelGSS/fastify-fp-types.

To Reproduce

https://github.com/RafaelGSS/fastify-fp-types

Expected behavior

Not throw an error on runtime because of the wrong transpilation

Your Environment

  • node version: 12
  • fastify version: >=3.3.0
  • os: Linux

missing v4 release?

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the issue has not already been raised

Issue

from the README, it says

Note: the v4.x series of this module covers Fastify v4

but no v4 of this package is listed here in github.

impact: this is blocking fastify updates on other packages, because of this errors like the above

(node:87427) UnhandledPromiseRejectionWarning: FastifyError: fastify-plugin: fastify-cors - expected '3.x' fastify version, '4.2.0' is installed

Add node version check for plugins

🚀 Feature Proposal

Hi everyone.

I believe that the minimum node version of plugins maintained by Fastify is the same as Fastify. But, maybe adding a checker for fastify-plugin like:

module.exports fp(myPlugin, {
  fastify: '>=1.0.0',
  node: '>=8',
  name: 'my-plugin'
})

can be great for plugins that have written with another version of node and for some reason don't send polyfill for it.

If anyone agrees with it, I can send a PR.

Rename package? @fastify/plugin

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the issue has not already been raised

Issue

Is this package going to be renamed like cors to @fastify/plugin vs fastify-plugin?

Prefix support in the options

I was trying to add the prefix for the routes as documented here, but there I found that we cannot use the prefix option with fastify-plugin.

Be aware that if you use fastify-plugin this option won't work. ( see in the route-prefixing docs).

How can we add a prefix with the fastify-plugin package?

TypeError: fastify_plugin_1.default is not a function

🐛 Bug Report

I'm trying to use fastify-plugin with TypeScript. However, the error underneath is thrown:

TypeError: fastify_plugin_1.default is not a function

Full stack:

TypeError: fastify_plugin_1.default is not a function
    at Object.<anonymous> (/usr/src/app/build/src/plugin.js:5:57)
    at Module._compile (internal/modules/cjs/loader.js:759:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:770:10)
    at Module.load (internal/modules/cjs/loader.js:628:32)
    at Function.Module._load (internal/modules/cjs/loader.js:555:12)
    at Module.require (internal/modules/cjs/loader.js:666:19)
    at require (internal/modules/cjs/helpers.js:16:16)
    at /usr/src/app/build/src/server.js:7:25
    at Object.<anonymous> (/usr/src/app/build/src/server.js:13:3)
    at Module._compile (internal/modules/cjs/loader.js:759:30)

To Reproduce

Steps to reproduce the behavior:

File "src/plugin.ts" (taken from https://github.com/fastify/fastify-plugin/blob/master/plugin.test-d.ts)

import fp from 'fastify-plugin';
import { FastifyPlugin } from 'fastify';

export interface TestOptions {
  customNumber: number
}

export const testPluginWithOptions: FastifyPlugin<TestOptions> = fp(
  function (fastify, options, _next) {
    fastify.decorate('utility', () => options.customNumber)
  },
  '>=1'
);

File "src/server.ts"

import * as Fastify from 'fastify';

(async () => {
  try {
    const server = Fastify.fastify();
    server.register(require('./plugin'));
    await server.listen(3000, '0.0.0.0');
  } catch (err) {
    console.error(err);
  }
})();

Compile TypeScript to JavaScript. For example:

$ node_modules/.bin/tsc -p . && node build/src/server.js

Expected behavior

No TypeError

Your Environment

  • Node version: 12
  • Fastify version: 3.0.0-rc.4
  • fastify-plugin version: 2.0.0
  • TypeScript version: 3.9.5
  • os: Linux

Propagating the Plugin type

So, I'm impl some basic TS typings for fastify-static in here #66. I've made a PR but @mcollina asked me explicitly to make fastify a development dependency.

I need a propagated fastify.Plugin type for that, and some generic type parameters like HttpServer / HttpRequest / HttpResponse. I've created the respective issue in fastify too #970.

Plugin type has too many type parameters, so I need to know if it's fine to drop the excessive ones first, before making any PR's.

Fix unorganized test structure

I was reviewing this repo recently and noticed the unit-tests are unorganized. There is a root level types.test.ts file and then within the tests/ directory there are normal .js and .ts files. I'm going to take a stab at cleaning this up and additionally expose any missing typings or what not.

Needs a release.

There should be a new release issued so that plugins can be made compatible with Fastify rc releases.

Cannot pass in RawServer generic type

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Fastify version

4.3.0

Plugin version

4.1.0

Node.js version

18.7.0

Operating system

Linux

Operating system version (i.e. 20.04, 11.3, 10)

Fedora Workstation 36

Description

The default export fp only allows a Options generic. This means you cannot pass in a function of type FastifyPluginAsync<MyOptions, MyRawServer, MyTypeProvider> for instance. I believe you should be able to pass in the two other generics as it has some use cases, in my case creating a package that can accept any RawServer type.

This results in a ts error like this:

Argument of type 'FastifyPluginAsync<Options, RawServer, FastifyTypeProviderDefault>' is not assignable to parameter of type 'FastifyPluginCallback<Options, Server, FastifyTypeProviderDefault>'.
  Types of parameters 'instance' and 'instance' are incompatible.
    ...

This is the types I believe would fix this, happy to make a pull request.

export default function fp<
  Options extends FastifyPluginOptions = Record<never, never>,
  Server extends RawServerBase = RawServerDefault,
  TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault,
>(
  fn: FastifyPluginAsync<Options, Server, TypeProvider>,
  ...
): FastifyPluginAsync<Options, Server, TypeProvider>

Steps to Reproduce

Pass in a function of type FastifyPluginAsync<MyOptions, MyRawServer, MyTypeProvider> to the fp function.

Expected Behavior

You should be able to pass in the generics manually or be inferred.

Clarify usage of plugin-meta and dependency check

Hi! I found the following issues with plugin-meta definitions and dependency check:

  1. Currently the README instructions about plugin-metadata definition states that we need to pass dependencies {Object}, but fastify/fastify/lib/pluginUtils.js accepts {Array} of strings.

  2. There is no mention of decorators {Object} property which we can use for the same purpose.

  3. If I am not mistaken, in case of we pass dependencies {Array} property, the dependency chek only passes if the dependency plugin declares name property in its own plugin definition. Currently most of the plugins in the Ecosystem list lacks of that property, therefore they will result a false negative dependency check.

  4. If the previous assumption is correct and it is the intended behaviour, than we need to update the plugin definitions of the existing plugins with the name property. Up until that point it would be safer to use the decorators {Object} plugin-meta definition.

I am sorry for the TLDR, but I am aware of that this functionality is WIP and therefore there are a lot of moving parts. I am happy to create PR(s) if it is required.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.