-
Notifications
You must be signed in to change notification settings - Fork 62
/
index.js
executable file
·114 lines (81 loc) · 2.94 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
'use strict';
const Path = require('path');
const Hapi = require('@hapi/hapi');
const Hoek = require('@hapi/hoek');
const Validate = require('@hapi/validate');
const MoWalk = require('mo-walk');
const internals = {};
internals.schema = {
options: Validate.object({
relativeTo: Validate.string(),
preRegister: Validate.func().allow(false)
}),
manifest: Validate.object({
server: Validate.object(),
register: Validate.object({
plugins: Validate.array(),
options: Validate.any()
})
})
};
exports.compose = async function (manifest, options = {}) {
Validate.assert(options, internals.schema.options, 'Invalid options');
Validate.assert(manifest, internals.schema.manifest, 'Invalid manifest');
const serverOpts = await internals.parseServer(manifest.server ?? {}, options.relativeTo);
const server = Hapi.server(serverOpts);
if (options.preRegister) {
await options.preRegister(server);
}
if (manifest.register?.plugins) {
const plugins = await Promise.all(manifest.register.plugins.map((plugin) => {
return internals.parsePlugin(plugin, options.relativeTo);
}));
await server.register(plugins, manifest.register.options ?? {});
}
return server;
};
internals.parseServer = async function (serverOpts, relativeTo) {
if (!serverOpts.cache) {
return serverOpts;
}
serverOpts = Hoek.clone(serverOpts);
const caches = [];
const config = [].concat(serverOpts.cache);
for (let item of config) {
if (typeof item === 'string') {
item = { provider: { constructor: item } };
}
else {
if (typeof item.provider === 'string') {
item.provider = { constructor: item.provider };
}
}
if (typeof item.provider.constructor === 'string') {
let provider = item.provider.constructor;
provider = await internals.requireRelativeTo(provider, relativeTo);
item.provider.constructor = provider?.Engine ?? provider;
}
caches.push(item);
}
serverOpts.cache = caches;
return serverOpts;
};
internals.parsePlugin = async function (plugin, relativeTo) {
if (typeof plugin === 'string') {
return await internals.requireRelativeTo(plugin, relativeTo);
}
if (typeof plugin.plugin === 'string') {
const pluginObject = Hoek.clone(plugin, { shallow: ['options'] });
pluginObject.plugin = await internals.requireRelativeTo(plugin.plugin, relativeTo);
return pluginObject;
}
return plugin;
};
internals.requireRelativeTo = async function (path, relativeTo) {
if (path[0] === '.') {
path = Path.join(relativeTo ?? __dirname, path);
}
const result = await MoWalk.tryToResolve(path);
Hoek.assert(result, `Glue could not resolve a module at ${path}`);
return MoWalk.getDefaultExport(...result);
};