1 | # fastify-plugin
|
2 |
|
3 | ![CI workflow](https://github.com/fastify/fastify-plugin/workflows/CI%20workflow/badge.svg?branch=master)
|
4 | [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](http://standardjs.com/)
|
5 |
|
6 | `fastify-plugin` is a plugin helper for [Fastify](https://github.com/fastify/fastify).
|
7 |
|
8 | 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:
|
9 | 1. Use the `skip-override` hidden property
|
10 | 2. Use this module
|
11 |
|
12 | __Note: the v2.x series of this module covers Fastify v3. For Fastify v2
|
13 | support refert to the v1.x series.__
|
14 |
|
15 | ## Usage
|
16 | `fastify-plugin` can do three things for you:
|
17 | - Add the `skip-override` hidden property
|
18 | - Check the bare-minimum version of Fastify
|
19 | - Pass some custom metadata of the plugin to Fastify
|
20 |
|
21 | Example:
|
22 | ```js
|
23 | const fp = require('fastify-plugin')
|
24 |
|
25 | module.exports = fp(function (fastify, opts, next) {
|
26 | // your plugin code
|
27 | next()
|
28 | })
|
29 | ```
|
30 |
|
31 | ## Metadata
|
32 | 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.
|
33 |
|
34 | #### Fastify version
|
35 | If you need to set a bare-minimum version of Fastify for your plugin, just add the [semver](http://semver.org/) range that you need:
|
36 | ```js
|
37 | const fp = require('fastify-plugin')
|
38 |
|
39 | module.exports = fp(function (fastify, opts, next) {
|
40 | // your plugin code
|
41 | next()
|
42 | }, { fastify: '3.x' })
|
43 | ```
|
44 |
|
45 | If you need to check the Fastify version only, you can pass just the version string.
|
46 |
|
47 | You can check [here](https://github.com/npm/node-semver#ranges) how to define a `semver` range.
|
48 |
|
49 | #### Name
|
50 | Fastify uses this option to validate dependency graph. On one hand it makes sure that no name collision occurs. On the other hand it makes possible to perform [dependency check](https://github.com/fastify/fastify-plugin#dependencies).
|
51 | ```js
|
52 | const fp = require('fastify-plugin')
|
53 |
|
54 | function plugin (fastify, opts, next) {
|
55 | // your plugin code
|
56 | next()
|
57 | }
|
58 |
|
59 | module.exports = fp(plugin, {
|
60 | fastify: '3.x',
|
61 | name: 'your-plugin-name'
|
62 | })
|
63 | ```
|
64 |
|
65 | #### Dependencies
|
66 | You can also check if the `plugins` and `decorators` which your plugin intend to use are present in the dependency graph.
|
67 | > *Note:* This is the point where registering `name` of the plugins become important, because you can reference `plugin` dependencies by their [name](https://github.com/fastify/fastify-plugin#name).
|
68 | ```js
|
69 | const fp = require('fastify-plugin')
|
70 |
|
71 | function plugin (fastify, opts, next) {
|
72 | // your plugin code
|
73 | next()
|
74 | }
|
75 |
|
76 | module.exports = fp(plugin, {
|
77 | fastify: '3.x',
|
78 | decorators: {
|
79 | fastify: ['plugin1', 'plugin2'],
|
80 | reply: ['compress']
|
81 | },
|
82 | dependencies: ['plugin1-name', 'plugin2-name']
|
83 | })
|
84 | ```
|
85 |
|
86 | #### Bundlers and Typescript
|
87 | `fastify-plugin` adds a `.default` and `[name]` property to the passed in function.
|
88 | The type definition would have to be updated to leverage this.
|
89 |
|
90 | ## Known Issue: TypeScript Contextual Inference
|
91 |
|
92 | [Documentation Reference](https://www.typescriptlang.org/docs/handbook/functions.html#inferring-the-types)
|
93 |
|
94 | It is common for developers to inline their plugin with fastify-plugin such as:
|
95 |
|
96 | ```js
|
97 | fp((fastify, opts, next) => { next() })
|
98 | fp(async (fastify, opts) => { return })
|
99 | ```
|
100 |
|
101 | 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:
|
102 |
|
103 | 1. The third argument `next` (the callback part)
|
104 | 2. The return type `FastifyPluginCallback` or `FastifyPluginAsync`
|
105 |
|
106 | At this time, TypeScript inference is not smart enough to differentiate by definition argument length alone.
|
107 |
|
108 | Thus, if you are a TypeScript developer please use on the following patterns instead:
|
109 |
|
110 | ```ts
|
111 | // Callback
|
112 |
|
113 | // Assign type directly
|
114 | const pluginCallback: FastifyPluginCallback = (fastify, options, next) => { }
|
115 | fp(pluginCallback)
|
116 |
|
117 | // or define your own function declaration that satisfies the existing definitions
|
118 | const pluginCallbackWithTypes = (fastify: FastifyInstance, options: FastifyPluginOptions, next: (error?: FastifyError) => void): void => { }
|
119 | fp(pluginCallbackWithTypes)
|
120 | // or inline
|
121 | fp((fastify: FastifyInstance, options: FastifyPluginOptions, next: (error?: FastifyError) => void): void => { })
|
122 |
|
123 | // Async
|
124 |
|
125 | // Assign type directly
|
126 | const pluginAsync: FastifyPluginAsync = async (fastify, options) => { }
|
127 | fp(pluginAsync)
|
128 |
|
129 | // or define your own function declaration that satisfies the existing definitions
|
130 | const pluginAsyncWithTypes = async (fastify: FastifyInstance, options: FastifyPluginOptions): Promise<void> => { }
|
131 | fp(pluginAsyncWithTypes)
|
132 | // or inline
|
133 | fp(async (fastify: FastifyInstance, options: FastifyPluginOptions): Promise<void> => { })
|
134 | ```
|
135 |
|
136 | ## Acknowledgements
|
137 |
|
138 | This project is kindly sponsored by:
|
139 | - [nearForm](http://nearform.com)
|
140 | - [LetzDoIt](http://www.letzdoitapp.com/)
|
141 |
|
142 | ## License
|
143 |
|
144 | Licensed under [MIT](./LICENSE).
|