strong-tie/inbound-calls
0
1'use strict'2 3const {4 kAvvioBoot,5 kChildren,6 kRoutePrefix,7 kLogLevel,8 kLogSerializers,9 kHooks,10 kSchemaController,11 kContentTypeParser,12 kReply,13 kRequest,14 kFourOhFour,15 kPluginNameChain16} = require('./symbols.js')17 18const Reply = require('./reply')19const Request = require('./request')20const SchemaController = require('./schema-controller')21const ContentTypeParser = require('./contentTypeParser')22const { buildHooks } = require('./hooks')23const pluginUtils = require('./pluginUtils')24 25// Function that runs the encapsulation magic.26// Everything that need to be encapsulated must be handled in this function.27module.exports = function override (old, fn, opts) {28 const shouldSkipOverride = pluginUtils.registerPlugin.call(old, fn)29 30 const fnName = pluginUtils.getPluginName(fn) || pluginUtils.getFuncPreview(fn)31 if (shouldSkipOverride) {32 // after every plugin registration we will enter a new name33 old[kPluginNameChain].push(fnName)34 return old35 }36 37 const instance = Object.create(old)38 old[kChildren].push(instance)39 instance.ready = old[kAvvioBoot].bind(instance)40 instance[kChildren] = []41 42 instance[kReply] = Reply.buildReply(instance[kReply])43 instance[kRequest] = Request.buildRequest(instance[kRequest])44 45 instance[kContentTypeParser] = ContentTypeParser.helpers.buildContentTypeParser(instance[kContentTypeParser])46 instance[kHooks] = buildHooks(instance[kHooks])47 instance[kRoutePrefix] = buildRoutePrefix(instance[kRoutePrefix], opts.prefix)48 instance[kLogLevel] = opts.logLevel || instance[kLogLevel]49 instance[kSchemaController] = SchemaController.buildSchemaController(old[kSchemaController])50 instance.getSchema = instance[kSchemaController].getSchema.bind(instance[kSchemaController])51 instance.getSchemas = instance[kSchemaController].getSchemas.bind(instance[kSchemaController])52 53 // Track the registered and loaded plugins since the root instance.54 // It does not track the current encapsulated plugin.55 instance[pluginUtils.kRegisteredPlugins] = Object.create(instance[pluginUtils.kRegisteredPlugins])56 57 // Track the plugin chain since the root instance.58 // When an non-encapsulated plugin is added, the chain will be updated.59 instance[kPluginNameChain] = [fnName]60 61 if (instance[kLogSerializers] || opts.logSerializers) {62 instance[kLogSerializers] = Object.assign(Object.create(instance[kLogSerializers]), opts.logSerializers)63 }64 65 if (opts.prefix) {66 instance[kFourOhFour].arrange404(instance)67 }68 69 for (const hook of instance[kHooks].onRegister) hook.call(old, instance, opts)70 71 return instance72}73 74function buildRoutePrefix (instancePrefix, pluginPrefix) {75 if (!pluginPrefix) {76 return instancePrefix77 }78 79 // Ensure that there is a '/' between the prefixes80 if (instancePrefix.endsWith('/') && pluginPrefix[0] === '/') {81 // Remove the extra '/' to avoid: '/first//second'82 pluginPrefix = pluginPrefix.slice(1)83 } else if (pluginPrefix[0] !== '/') {84 pluginPrefix = '/' + pluginPrefix85 }86 87 return instancePrefix + pluginPrefix88}89 