forked from fastify/fastify-plugin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplugin.ts
100 lines (85 loc) · 3.17 KB
/
plugin.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import {
FastifyPluginOptions,
RawServerBase,
RawServerDefault,
FastifyTypeProvider,
FastifyTypeProviderDefault,
FastifyBaseLogger
} from 'fastify'
import getPluginName from './lib/getPluginName'
import {
GetPluginAsyncOrCallback,
PluginAsyncOrCallback,
PluginMetadata
} from './types'
import toCamelCase from './lib/toCamelCase'
let count = 0
/**
* This function does three things for you:
* 1. Add the `skip-override` hidden property
* 2. Check bare-minimum version of Fastify
* 3. Pass some custom metadata of the plugin to Fastify
* @param fn Fastify plugin function
* @param options Optional plugin options
*/
export default function plugin<
Options extends FastifyPluginOptions = Record<never, never>,
RawServer extends RawServerBase = RawServerDefault,
TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault,
Logger extends FastifyBaseLogger = FastifyBaseLogger,
Fn extends PluginAsyncOrCallback<Options, RawServer, TypeProvider, Logger, Fn> =
GetPluginAsyncOrCallback<Options, RawServer, TypeProvider, Logger, unknown>,
> (
fn: GetPluginAsyncOrCallback<Options, RawServer, TypeProvider, Logger, Fn> | { default: GetPluginAsyncOrCallback<Options, RawServer, TypeProvider, Logger, Fn> },
options: PluginMetadata | string = {}
): GetPluginAsyncOrCallback<Options, RawServer, TypeProvider, Logger, Fn> &
{ default: GetPluginAsyncOrCallback<Options, RawServer, TypeProvider, Logger, Fn> } &
{ [K in undefined extends Options['name'] ? string : Options['name']]?: GetPluginAsyncOrCallback<Options, RawServer, TypeProvider, Logger, Fn> } {
let autoName = false
if ('default' in fn) {
// Support for 'export default' behaviour in transpiled ECMAScript module
fn = fn.default
}
if (typeof fn !== 'function') {
throw new TypeError(
`fastify-plugin expects a function, instead got a '${typeof fn}'`
)
}
if (typeof options === 'string') {
options = {
fastify: options
}
}
if (
typeof options !== 'object' ||
Array.isArray(options) ||
options === null
) {
throw new TypeError('The options object should be an object')
}
if (options.fastify !== undefined && typeof options.fastify !== 'string') {
throw new TypeError(`fastify-plugin expects a version string, instead got '${typeof options.fastify}'`)
}
if (options.name === undefined) {
autoName = true
options.name = getPluginName(fn) + '-auto-' + String(count++)
}
Reflect.set(fn, Symbol.for('skip-override'), options.encapsulate !== true)
Reflect.set(fn, Symbol.for('fastify.display-name'), options.name)
Reflect.set(fn, Symbol.for('plugin-meta'), options)
// Faux modules support
if (!('default' in fn)) {
Reflect.set(fn, 'default', fn)
}
// TypeScript support for named imports
// See https://github.com/fastify/fastify/issues/2404 for more details
// The type definitions would have to be update to match this.
const camelCase = toCamelCase(options.name)
if (!autoName && Reflect.get(fn, camelCase) === undefined) {
Reflect.set(fn, camelCase, fn)
}
return fn as typeof fn & { default: typeof fn }
}
module.exports = plugin
module.exports.default = plugin
module.exports.fastifyPlugin = plugin