fastify-plugin
Advanced tools
+2
-2
| { | ||
| "name": "fastify-plugin", | ||
| "version": "2.3.2", | ||
| "version": "2.3.3", | ||
| "description": "Plugin helper for Fastify", | ||
@@ -28,3 +28,3 @@ "main": "plugin.js", | ||
| "@types/node": "^13.13.2", | ||
| "fastify": "^3.0.1", | ||
| "fastify": "^3.3.0", | ||
| "proxyquire": "^2.1.3", | ||
@@ -31,0 +31,0 @@ "standard": "^14.0.0", |
+4
-19
@@ -16,20 +16,7 @@ /// <reference types="fastify" /> | ||
| */ | ||
| export default function fp<Options>( | ||
| fn: FastifyPluginCallback<Options>, | ||
| options?: PluginMetadata, | ||
| ): FastifyPluginCallback<Options>; | ||
| export default function fp<Options>( | ||
| fn: FastifyPluginAsync<Options>, | ||
| options?: PluginMetadata, | ||
| ): FastifyPluginAsync<Options>; | ||
| export default function fp<Options>(fn: FastifyPluginAsync<Options>, options?: PluginMetadata): FastifyPluginAsync<Options>; | ||
| export default function fp<Options>(fn: FastifyPluginAsync<Options>, options?: string): FastifyPluginAsync<Options>; | ||
| export default function fp<Options>(fn: FastifyPluginCallback<Options>, options?: PluginMetadata): FastifyPluginCallback<Options>; | ||
| export default function fp<Options>(fn: FastifyPluginCallback<Options>, options?: string): FastifyPluginCallback<Options>; | ||
| export default function fp<Options>( | ||
| fn: FastifyPluginCallback<Options>, | ||
| options?: string, | ||
| ): FastifyPluginCallback<Options>; | ||
| export default function fp<Options>( | ||
| fn: FastifyPluginAsync<Options>, | ||
| options?: string, | ||
| ): FastifyPluginAsync<Options>; | ||
| export interface PluginMetadata { | ||
@@ -51,3 +38,1 @@ /** Bare-minimum version of Fastify for your plugin, just add the semver range that you need. */ | ||
| export interface PluginOptions extends PluginMetadata {} | ||
| export type NextCallback = (err?: Error) => void; |
+60
-42
| import fp from './plugin'; | ||
| import fastify, { FastifyPlugin } from 'fastify'; | ||
| import { expectError } from 'tsd' | ||
| import fastify, { FastifyPluginCallback, FastifyPluginAsync, FastifyError, FastifyInstance, FastifyPluginOptions } from 'fastify'; | ||
| import { expectAssignable, expectError } from 'tsd' | ||
| export interface TestOptions { | ||
| customNumber: number | ||
| interface Options { | ||
| foo: string | ||
| } | ||
| export const testPluginWithOptions: FastifyPlugin<TestOptions> = fp( | ||
| function (fastify, options, _next) { | ||
| fastify.decorate('utility', () => options.customNumber) | ||
| // Callback | ||
| const pluginCallback: FastifyPluginCallback = (fastify, options, next) => { } | ||
| expectAssignable<FastifyPluginCallback>(fp(pluginCallback)) | ||
| const pluginCallbackWithTypes = (fastify: FastifyInstance, options: FastifyPluginOptions, next: (error?: FastifyError) => void): void => { } | ||
| expectAssignable<FastifyPluginCallback>(fp(pluginCallbackWithTypes)) | ||
| expectAssignable<FastifyPluginCallback>(fp((fastify: FastifyInstance, options: FastifyPluginOptions, next: (error?: FastifyError) => void): void => { })) | ||
| expectAssignable<FastifyPluginCallback>(fp(pluginCallback, '' )) | ||
| expectAssignable<FastifyPluginCallback>(fp(pluginCallback, { | ||
| fastify: '', | ||
| name: '', | ||
| decorators: { | ||
| fastify: [ '' ], | ||
| reply: [ '' ], | ||
| request: [ '' ] | ||
| }, | ||
| '>=1' | ||
| ); | ||
| dependencies: [ '' ] | ||
| })) | ||
| export const testPluginWithCallback: FastifyPlugin<TestOptions> = fp( | ||
| function (fastify, _options, next) { | ||
| fastify.decorate('utility', () => { }) | ||
| next(); | ||
| return; | ||
| } | ||
| ) | ||
| const pluginCallbackWithOptions: FastifyPluginCallback<Options> = (fastify, options, next) => { | ||
| expectAssignable<string>(options.foo) | ||
| } | ||
| export const testPluginWithAsync = fp<TestOptions>( | ||
| async function (fastify, _options) { | ||
| fastify.decorate('utility', () => { }) | ||
| expectAssignable<FastifyPluginCallback<Options>>(fp(pluginCallbackWithOptions)) | ||
| // Async | ||
| const pluginAsync: FastifyPluginAsync = async (fastify, options) => { } | ||
| expectAssignable<FastifyPluginAsync>(fp(pluginAsync)) | ||
| const pluginAsyncWithTypes = async (fastify: FastifyInstance, options: FastifyPluginOptions): Promise<void> => { } | ||
| expectAssignable<FastifyPluginAsync>(fp(pluginAsyncWithTypes)) | ||
| expectAssignable<FastifyPluginAsync>(fp(async (fastify: FastifyInstance, options: FastifyPluginOptions): Promise<void> => { })) | ||
| expectAssignable<FastifyPluginAsync>(fp(pluginAsync, '' )) | ||
| expectAssignable<FastifyPluginAsync>(fp(pluginAsync, { | ||
| fastify: '', | ||
| name: '', | ||
| decorators: { | ||
| fastify: [ '' ], | ||
| reply: [ '' ], | ||
| request: [ '' ] | ||
| }, | ||
| { | ||
| fastify: '>=1', | ||
| name: 'TestPlugin', | ||
| decorators: { | ||
| request: ['log'] | ||
| } | ||
| } | ||
| ); | ||
| dependencies: [ '' ] | ||
| })) | ||
| // Register with HTTP | ||
| const server = fastify() | ||
| const pluginAsyncWithOptions: FastifyPluginAsync<Options> = async (fastify, options) => { | ||
| expectAssignable<string>(options.foo) | ||
| } | ||
| server.register(testPluginWithOptions) // register expects a FastifyPlugin | ||
| server.register(testPluginWithCallback, { customNumber: 2 }) | ||
| server.register(testPluginWithAsync, { customNumber: 3 }) | ||
| expectError(server.register(testPluginWithCallback, { })) // invalid options passed to plugin on registration | ||
| expectError(server.register(testPluginWithAsync, { customNumber: '2' })) // invalid type in options passed to plugin on registration | ||
| expectAssignable<FastifyPluginAsync<Options>>(fp(pluginAsyncWithOptions)) | ||
| // Fastify register | ||
| // Register with HTTP2 | ||
| const serverWithHttp2 = fastify({ http2: true }); | ||
| serverWithHttp2.register(testPluginWithOptions) // register expects a FastifyPlugin | ||
| serverWithHttp2.register(testPluginWithCallback) | ||
| expectError(serverWithHttp2.register({ no: 'plugin' })) // register only accept valid plugins | ||
| expectError(serverWithHttp2.register(testPluginWithAsync, { logLevel: 'invalid-log-level' })) // register options need to be valid built in fastify options | ||
| expectError(serverWithHttp2.register(testPluginWithAsync, { customNumber: 'not-a-number' })) // or valid custom options defined by plugin itself | ||
| const server = fastify() | ||
| server.register(fp(pluginCallback)) | ||
| server.register(fp(pluginCallbackWithTypes)) | ||
| server.register(fp(pluginCallbackWithOptions)) | ||
| server.register(fp(pluginAsync)) | ||
| server.register(fp(pluginAsyncWithTypes)) | ||
| server.register(fp(pluginAsyncWithOptions)) |
+46
-0
@@ -90,2 +90,48 @@ # fastify-plugin | ||
| ## Known Issue: TypeScript Contextual Inference | ||
| [Documentation Reference](https://www.typescriptlang.org/docs/handbook/functions.html#inferring-the-types) | ||
| It is common for developers to inline their plugin with fastify-plugin such as: | ||
| ```js | ||
| fp((fastify, opts, next) => { next() }) | ||
| 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 `next` (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: | ||
| ```ts | ||
| // Callback | ||
| // Assign type directly | ||
| const pluginCallback: FastifyPluginCallback = (fastify, options, next) => { } | ||
| fp(pluginCallback) | ||
| // or define your own function declaration that satisfies the existing definitions | ||
| const pluginCallbackWithTypes = (fastify: FastifyInstance, options: FastifyPluginOptions, next: (error?: FastifyError) => void): void => { } | ||
| fp(pluginCallbackWithTypes) | ||
| // or inline | ||
| fp((fastify: FastifyInstance, options: FastifyPluginOptions, next: (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 | ||
@@ -92,0 +138,0 @@ |
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
30312
8.4%145
46.46%676
-0.29%