UNPKG

3.04 kBJavaScriptView Raw
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 kPluginNameChain
16} = 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 name
33 old[kPluginNameChain].push(fnName)
34 return old
35 }
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(this, instance, opts)
70
71 return instance
72}
73
74function buildRoutePrefix (instancePrefix, pluginPrefix) {
75 if (!pluginPrefix) {
76 return instancePrefix
77 }
78
79 // Ensure that there is a '/' between the prefixes
80 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 = '/' + pluginPrefix
85 }
86
87 return instancePrefix + pluginPrefix
88}