1 | 'use strict'
|
2 |
|
3 | const semver = require('semver')
|
4 | const console = require('console')
|
5 | const extractPluginName = require('./stackParser')
|
6 | const { join, dirname } = require('path')
|
7 |
|
8 | let count = 0
|
9 |
|
10 | function plugin (fn, options = {}) {
|
11 | let autoName = false
|
12 |
|
13 | if (typeof fn.default !== 'undefined') {
|
14 | fn = fn.default
|
15 | }
|
16 |
|
17 | if (typeof fn !== 'function') {
|
18 | throw new TypeError(`fastify-plugin expects a function, instead got a '${typeof fn}'`)
|
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 | checkVersion(options, pluginName)
|
27 | options = {}
|
28 | }
|
29 |
|
30 | if (typeof options !== 'object' || Array.isArray(options) || options === null) {
|
31 | throw new TypeError('The options object should be an object')
|
32 | }
|
33 |
|
34 | if (!options.name) {
|
35 | autoName = true
|
36 | options.name = pluginName + '-auto-' + count++
|
37 | }
|
38 |
|
39 | fn[Symbol.for('fastify.display-name')] = options.name
|
40 |
|
41 | if (options.fastify) {
|
42 | checkVersion(options.fastify, pluginName)
|
43 | }
|
44 |
|
45 | fn[Symbol.for('plugin-meta')] = options
|
46 |
|
47 |
|
48 | if (!fn.default) {
|
49 | fn.default = fn
|
50 | }
|
51 |
|
52 |
|
53 |
|
54 |
|
55 | const camelCase = toCamelCase(options.name)
|
56 | if (!autoName && !fn[camelCase]) {
|
57 | fn[camelCase] = fn
|
58 | }
|
59 |
|
60 | return fn
|
61 | }
|
62 |
|
63 | function checkName (fn) {
|
64 | if (fn.name.length > 0) return fn.name
|
65 |
|
66 | try {
|
67 | throw new Error('anonymous function')
|
68 | } catch (e) {
|
69 | return extractPluginName(e.stack)
|
70 | }
|
71 | }
|
72 |
|
73 | function toCamelCase (name) {
|
74 | const newName = name.replace(/-(.)/g, function (match, g1) {
|
75 | return g1.toUpperCase()
|
76 | })
|
77 | return newName
|
78 | }
|
79 |
|
80 | function resolvePkgPath (mainFilename) {
|
81 | return join(dirname(require.resolve('fastify', { paths: [mainFilename] })), 'package.json')
|
82 | }
|
83 |
|
84 | function tryGetPath (p) {
|
85 | var pkgPath
|
86 | try {
|
87 | pkgPath = resolvePkgPath(p)
|
88 | } catch (_) {
|
89 | }
|
90 | return pkgPath
|
91 | }
|
92 |
|
93 | function checkVersion (version, pluginName) {
|
94 | if (typeof version !== 'string') {
|
95 | throw new TypeError(`fastify-plugin expects a version string, instead got '${typeof version}'`)
|
96 | }
|
97 |
|
98 |
|
99 | var fastifyVersion
|
100 | var pkgPath
|
101 | if (require.main && require.main.filename) {
|
102 |
|
103 | pkgPath = tryGetPath(require.main.filename)
|
104 | }
|
105 | if (!pkgPath && process.argv[1]) {
|
106 |
|
107 | pkgPath = tryGetPath(process.argv[1])
|
108 | }
|
109 | if (!pkgPath) {
|
110 |
|
111 | pkgPath = 'fastify/package.json'
|
112 | }
|
113 |
|
114 | try {
|
115 | fastifyVersion = semver.coerce(require(pkgPath).version)
|
116 | } catch (_) {
|
117 | console.info('fastify not found, proceeding anyway')
|
118 | }
|
119 |
|
120 | if (fastifyVersion && !semver.satisfies(fastifyVersion, version)) {
|
121 | throw new Error(`fastify-plugin: ${pluginName} - expected '${version}' fastify version, '${fastifyVersion}' is installed`)
|
122 | }
|
123 | }
|
124 |
|
125 | module.exports = plugin
|