You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					141 lines
				
				3.4 KiB
			
		
		
			
		
	
	
					141 lines
				
				3.4 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								'use strict'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const semver = require('semver')
							 | 
						||
| 
								 | 
							
								const assert = require('assert')
							 | 
						||
| 
								 | 
							
								const registeredPlugins = Symbol.for('registered-plugin')
							 | 
						||
| 
								 | 
							
								const {
							 | 
						||
| 
								 | 
							
								  kTestInternals
							 | 
						||
| 
								 | 
							
								} = require('./symbols.js')
							 | 
						||
| 
								 | 
							
								const { exist, existReply, existRequest } = require('./decorate')
							 | 
						||
| 
								 | 
							
								const { FST_ERR_PLUGIN_VERSION_MISMATCH } = require('./errors')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function getMeta (fn) {
							 | 
						||
| 
								 | 
							
								  return fn[Symbol.for('plugin-meta')]
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function getPluginName (func) {
							 | 
						||
| 
								 | 
							
								  const display = getDisplayName(func)
							 | 
						||
| 
								 | 
							
								  if (display) {
							 | 
						||
| 
								 | 
							
								    return display
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // let's see if this is a file, and in that case use that
							 | 
						||
| 
								 | 
							
								  // this is common for plugins
							 | 
						||
| 
								 | 
							
								  const cache = require.cache
							 | 
						||
| 
								 | 
							
								  const keys = Object.keys(cache)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (let i = 0; i < keys.length; i++) {
							 | 
						||
| 
								 | 
							
								    const key = keys[i]
							 | 
						||
| 
								 | 
							
								    if (cache[key].exports === func) {
							 | 
						||
| 
								 | 
							
								      return key
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // if not maybe it's a named function, so use that
							 | 
						||
| 
								 | 
							
								  if (func.name) {
							 | 
						||
| 
								 | 
							
								    return func.name
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return null
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function getFuncPreview (func) {
							 | 
						||
| 
								 | 
							
								  // takes the first two lines of the function if nothing else works
							 | 
						||
| 
								 | 
							
								  return func.toString().split('\n').slice(0, 2).map(s => s.trim()).join(' -- ')
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function getDisplayName (fn) {
							 | 
						||
| 
								 | 
							
								  return fn[Symbol.for('fastify.display-name')]
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function shouldSkipOverride (fn) {
							 | 
						||
| 
								 | 
							
								  return !!fn[Symbol.for('skip-override')]
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function checkDependencies (fn) {
							 | 
						||
| 
								 | 
							
								  const meta = getMeta(fn)
							 | 
						||
| 
								 | 
							
								  if (!meta) return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const dependencies = meta.dependencies
							 | 
						||
| 
								 | 
							
								  if (!dependencies) return
							 | 
						||
| 
								 | 
							
								  assert(Array.isArray(dependencies), 'The dependencies should be an array of strings')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  dependencies.forEach(dependency => {
							 | 
						||
| 
								 | 
							
								    assert(
							 | 
						||
| 
								 | 
							
								      this[registeredPlugins].indexOf(dependency) > -1,
							 | 
						||
| 
								 | 
							
								      `The dependency '${dependency}' of plugin '${meta.name}' is not registered`
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function checkDecorators (fn) {
							 | 
						||
| 
								 | 
							
								  const meta = getMeta(fn)
							 | 
						||
| 
								 | 
							
								  if (!meta) return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const { decorators, name } = meta
							 | 
						||
| 
								 | 
							
								  if (!decorators) return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (decorators.fastify) _checkDecorators(this, 'Fastify', decorators.fastify, name)
							 | 
						||
| 
								 | 
							
								  if (decorators.reply) _checkDecorators(this, 'Reply', decorators.reply, name)
							 | 
						||
| 
								 | 
							
								  if (decorators.request) _checkDecorators(this, 'Request', decorators.request, name)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const checks = {
							 | 
						||
| 
								 | 
							
								  Fastify: exist,
							 | 
						||
| 
								 | 
							
								  Request: existRequest,
							 | 
						||
| 
								 | 
							
								  Reply: existReply
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function _checkDecorators (that, instance, decorators, name) {
							 | 
						||
| 
								 | 
							
								  assert(Array.isArray(decorators), 'The decorators should be an array of strings')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  decorators.forEach(decorator => {
							 | 
						||
| 
								 | 
							
								    const withPluginName = typeof name === 'string' ? ` required by '${name}'` : ''
							 | 
						||
| 
								 | 
							
								    if (!checks[instance].call(that, decorator)) {
							 | 
						||
| 
								 | 
							
								      throw new Error(`The decorator '${decorator}'${withPluginName} is not present in ${instance}`)
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function checkVersion (fn) {
							 | 
						||
| 
								 | 
							
								  const meta = getMeta(fn)
							 | 
						||
| 
								 | 
							
								  if (!meta) return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const requiredVersion = meta.fastify
							 | 
						||
| 
								 | 
							
								  if (!requiredVersion) return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (!semver.satisfies(this.version, requiredVersion)) throw new FST_ERR_PLUGIN_VERSION_MISMATCH(meta.name, requiredVersion, this.version)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function registerPluginName (fn) {
							 | 
						||
| 
								 | 
							
								  const meta = getMeta(fn)
							 | 
						||
| 
								 | 
							
								  if (!meta) return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const name = meta.name
							 | 
						||
| 
								 | 
							
								  if (!name) return
							 | 
						||
| 
								 | 
							
								  this[registeredPlugins].push(name)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function registerPlugin (fn) {
							 | 
						||
| 
								 | 
							
								  registerPluginName.call(this, fn)
							 | 
						||
| 
								 | 
							
								  checkVersion.call(this, fn)
							 | 
						||
| 
								 | 
							
								  checkDecorators.call(this, fn)
							 | 
						||
| 
								 | 
							
								  checkDependencies.call(this, fn)
							 | 
						||
| 
								 | 
							
								  return shouldSkipOverride(fn)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = {
							 | 
						||
| 
								 | 
							
								  getPluginName,
							 | 
						||
| 
								 | 
							
								  getFuncPreview,
							 | 
						||
| 
								 | 
							
								  registeredPlugins,
							 | 
						||
| 
								 | 
							
								  getDisplayName,
							 | 
						||
| 
								 | 
							
								  registerPlugin
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports[kTestInternals] = {
							 | 
						||
| 
								 | 
							
								  shouldSkipOverride,
							 | 
						||
| 
								 | 
							
								  getMeta,
							 | 
						||
| 
								 | 
							
								  checkDecorators,
							 | 
						||
| 
								 | 
							
								  checkDependencies
							 | 
						||
| 
								 | 
							
								}
							 |