UNPKG

1.93 kBJavaScriptView Raw
1'use strict'
2
3const extractPluginName = require('./stackParser')
4
5let count = 0
6
7function plugin (fn, options = {}) {
8 let autoName = false
9
10 if (typeof fn.default !== 'undefined') {
11 // Support for 'export default' behaviour in transpiled ECMAScript module
12 fn = fn.default
13 }
14
15 if (typeof fn !== 'function') {
16 throw new TypeError(
17 `fastify-plugin expects a function, instead got a '${typeof fn}'`
18 )
19 }
20
21 fn[Symbol.for('skip-override')] = true
22
23 const pluginName = (options && options.name) || checkName(fn)
24
25 if (typeof options === 'string') {
26 options = {
27 fastify: options
28 }
29 }
30
31 if (
32 typeof options !== 'object' ||
33 Array.isArray(options) ||
34 options === null
35 ) {
36 throw new TypeError('The options object should be an object')
37 }
38
39 if (options.fastify !== undefined && typeof options.fastify !== 'string') {
40 throw new TypeError(`fastify-plugin expects a version string, instead got '${typeof options.fastify}'`)
41 }
42
43 if (!options.name) {
44 autoName = true
45 options.name = pluginName + '-auto-' + count++
46 }
47
48 fn[Symbol.for('fastify.display-name')] = options.name
49 fn[Symbol.for('plugin-meta')] = options
50
51 // Faux modules support
52 if (!fn.default) {
53 fn.default = fn
54 }
55
56 // TypeScript support for named imports
57 // See https://github.com/fastify/fastify/issues/2404 for more details
58 // The type definitions would have to be update to match this.
59 const camelCase = toCamelCase(options.name)
60 if (!autoName && !fn[camelCase]) {
61 fn[camelCase] = fn
62 }
63
64 return fn
65}
66
67function checkName (fn) {
68 if (fn.name.length > 0) return fn.name
69
70 try {
71 throw new Error('anonymous function')
72 } catch (e) {
73 return extractPluginName(e.stack)
74 }
75}
76
77function toCamelCase (name) {
78 const newName = name.replace(/-(.)/g, function (match, g1) {
79 return g1.toUpperCase()
80 })
81 return newName
82}
83
84plugin.default = plugin
85module.exports = plugin