@depup/hapi 18.1.0-depup.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/methods.js ADDED
@@ -0,0 +1,123 @@
1
+ 'use strict';
2
+
3
+ const Boom = require('boom');
4
+ const Hoek = require('hoek');
5
+
6
+ const Config = require('./config');
7
+
8
+
9
+ const internals = {
10
+ methodNameRx: /^[_$a-zA-Z][$\w]*(?:\.[_$a-zA-Z][$\w]*)*$/
11
+ };
12
+
13
+
14
+ exports = module.exports = internals.Methods = class {
15
+
16
+ constructor(core) {
17
+
18
+ this.core = core;
19
+ this.methods = {};
20
+ }
21
+
22
+ add(name, method, options, realm) {
23
+
24
+ if (typeof name !== 'object') {
25
+ return this._add(name, method, options, realm);
26
+ }
27
+
28
+ // {} or [{}, {}]
29
+
30
+ const items = [].concat(name);
31
+ for (let item of items) {
32
+ item = Config.apply('methodObject', item);
33
+ this._add(item.name, item.method, item.options || {}, realm);
34
+ }
35
+ }
36
+
37
+ _add(name, method, options, realm) {
38
+
39
+ Hoek.assert(typeof method === 'function', 'method must be a function');
40
+ Hoek.assert(typeof name === 'string', 'name must be a string');
41
+ Hoek.assert(name.match(internals.methodNameRx), 'Invalid name:', name);
42
+ Hoek.assert(!Hoek.reach(this.methods, name, { functions: false }), 'Server method function name already exists:', name);
43
+
44
+ options = Config.apply('method', options, name);
45
+
46
+ const settings = Hoek.cloneWithShallow(options, ['bind']);
47
+ settings.generateKey = settings.generateKey || internals.generateKey;
48
+
49
+ const bind = settings.bind || realm.settings.bind || null;
50
+ const bound = !bind ? method : (...args) => method.apply(bind, args);
51
+
52
+ // Not cached
53
+
54
+ if (!settings.cache) {
55
+ return this._assign(name, bound);
56
+ }
57
+
58
+ // Cached
59
+
60
+ Hoek.assert(!settings.cache.generateFunc, 'Cannot set generateFunc with method caching:', name);
61
+ Hoek.assert(settings.cache.generateTimeout !== undefined, 'Method caching requires a timeout value in generateTimeout:', name);
62
+
63
+ settings.cache.generateFunc = (id, flags) => bound(...id.args, flags);
64
+ const cache = this.core._cachePolicy(settings.cache, '#' + name);
65
+
66
+ const func = function (...args) {
67
+
68
+ const key = settings.generateKey.apply(bind, args);
69
+ if (typeof key !== 'string') {
70
+ return Promise.reject(Boom.badImplementation('Invalid method key when invoking: ' + name, { name, args }));
71
+ }
72
+
73
+ return cache.get({ id: key, args });
74
+ };
75
+
76
+ func.cache = {
77
+ drop: function (...args) {
78
+
79
+ const key = settings.generateKey.apply(bind, args);
80
+ if (typeof key !== 'string') {
81
+ return Promise.reject(Boom.badImplementation('Invalid method key when invoking: ' + name, { name, args }));
82
+ }
83
+
84
+ return cache.drop(key);
85
+ },
86
+ stats: cache.stats
87
+ };
88
+
89
+ this._assign(name, func, func);
90
+ }
91
+
92
+ _assign(name, method) {
93
+
94
+ const path = name.split('.');
95
+ let ref = this.methods;
96
+ for (let i = 0; i < path.length; ++i) {
97
+ if (!ref[path[i]]) {
98
+ ref[path[i]] = (i + 1 === path.length ? method : {});
99
+ }
100
+
101
+ ref = ref[path[i]];
102
+ }
103
+ }
104
+ };
105
+
106
+
107
+ internals.supportedArgs = ['string', 'number', 'boolean'];
108
+
109
+
110
+ internals.generateKey = function (...args) {
111
+
112
+ let key = '';
113
+ for (let i = 0; i < args.length; ++i) {
114
+ const arg = args[i];
115
+ if (!internals.supportedArgs.includes(typeof arg)) {
116
+ return null;
117
+ }
118
+
119
+ key = key + (i ? ':' : '') + encodeURIComponent(arg.toString());
120
+ }
121
+
122
+ return key;
123
+ };