joi 14.3.0 → 17.2.1
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/LICENSE.md +10 -0
- package/README.md +8 -118
- package/dist/joi-browser.min.js +1 -0
- package/lib/annotate.js +175 -0
- package/lib/base.js +1068 -0
- package/lib/cache.js +143 -0
- package/lib/common.js +216 -0
- package/lib/compile.js +283 -0
- package/lib/errors.js +160 -269
- package/lib/extend.js +312 -0
- package/lib/index.d.ts +2200 -0
- package/lib/index.js +179 -364
- package/lib/manifest.js +476 -0
- package/lib/messages.js +178 -0
- package/lib/modify.js +267 -0
- package/lib/ref.js +386 -25
- package/lib/schemas.js +291 -15
- package/lib/state.js +152 -0
- package/lib/template.js +427 -0
- package/lib/trace.js +346 -0
- package/lib/types/alternatives.js +329 -0
- package/lib/types/any.js +174 -0
- package/lib/types/array.js +775 -0
- package/lib/types/binary.js +98 -0
- package/lib/types/boolean.js +150 -0
- package/lib/types/date.js +233 -0
- package/lib/types/function.js +93 -0
- package/lib/types/keys.js +1043 -0
- package/lib/types/link.js +168 -0
- package/lib/types/number.js +335 -0
- package/lib/types/object.js +22 -0
- package/lib/types/string.js +820 -0
- package/lib/types/symbol.js +102 -0
- package/lib/validator.js +650 -0
- package/lib/values.js +263 -0
- package/package.json +34 -29
- package/CHANGELOG.md +0 -3
- package/LICENSE +0 -25
- package/lib/cast.js +0 -64
- package/lib/language.js +0 -166
- package/lib/set.js +0 -191
- package/lib/types/alternatives/index.js +0 -218
- package/lib/types/any/index.js +0 -978
- package/lib/types/any/settings.js +0 -36
- package/lib/types/array/index.js +0 -707
- package/lib/types/binary/index.js +0 -100
- package/lib/types/boolean/index.js +0 -100
- package/lib/types/date/index.js +0 -182
- package/lib/types/func/index.js +0 -90
- package/lib/types/lazy/index.js +0 -82
- package/lib/types/number/index.js +0 -248
- package/lib/types/object/index.js +0 -957
- package/lib/types/state.js +0 -11
- package/lib/types/string/index.js +0 -703
- package/lib/types/string/ip.js +0 -54
- package/lib/types/string/rfc3986.js +0 -219
- package/lib/types/string/uri.js +0 -46
- package/lib/types/symbol/index.js +0 -93
- package/lib/types/symbols.js +0 -5
package/lib/index.js
CHANGED
|
@@ -1,467 +1,282 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const Assert = require('@hapi/hoek/lib/assert');
|
|
4
|
+
const Clone = require('@hapi/hoek/lib/clone');
|
|
4
5
|
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
6
|
+
const Cache = require('./cache');
|
|
7
|
+
const Common = require('./common');
|
|
8
|
+
const Compile = require('./compile');
|
|
8
9
|
const Errors = require('./errors');
|
|
9
|
-
const
|
|
10
|
+
const Extend = require('./extend');
|
|
11
|
+
const Manifest = require('./manifest');
|
|
10
12
|
const Ref = require('./ref');
|
|
11
|
-
const
|
|
13
|
+
const Template = require('./template');
|
|
14
|
+
const Trace = require('./trace');
|
|
12
15
|
|
|
16
|
+
let Schemas;
|
|
13
17
|
|
|
14
|
-
// Declare internals
|
|
15
18
|
|
|
16
19
|
const internals = {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
schema = this._defaults(schema);
|
|
20
|
+
types: {
|
|
21
|
+
alternatives: require('./types/alternatives'),
|
|
22
|
+
any: require('./types/any'),
|
|
23
|
+
array: require('./types/array'),
|
|
24
|
+
boolean: require('./types/boolean'),
|
|
25
|
+
date: require('./types/date'),
|
|
26
|
+
function: require('./types/function'),
|
|
27
|
+
link: require('./types/link'),
|
|
28
|
+
number: require('./types/number'),
|
|
29
|
+
object: require('./types/object'),
|
|
30
|
+
string: require('./types/string'),
|
|
31
|
+
symbol: require('./types/symbol')
|
|
32
|
+
},
|
|
33
|
+
aliases: {
|
|
34
|
+
alt: 'alternatives',
|
|
35
|
+
bool: 'boolean',
|
|
36
|
+
func: 'function'
|
|
35
37
|
}
|
|
36
|
-
|
|
37
|
-
schema._currentJoi = this;
|
|
38
|
-
|
|
39
|
-
return schema._init(...args);
|
|
40
38
|
};
|
|
41
39
|
|
|
42
|
-
internals.root = function () {
|
|
43
|
-
|
|
44
|
-
const any = new Any();
|
|
45
|
-
|
|
46
|
-
const root = any.clone();
|
|
47
|
-
Any.prototype._currentJoi = root;
|
|
48
|
-
root._currentJoi = root;
|
|
49
|
-
root._binds = new Set(['any', 'alternatives', 'alt', 'array', 'boolean', 'binary', 'date', 'func', 'number', 'object', 'string', 'symbol', 'validate', 'describe', 'compile', 'assert', 'attempt', 'lazy', 'defaults', 'extend']);
|
|
50
|
-
|
|
51
|
-
root.any = function (...args) {
|
|
52
|
-
|
|
53
|
-
Hoek.assert(args.length === 0, 'Joi.any() does not allow arguments.');
|
|
54
|
-
|
|
55
|
-
return internals.callWithDefaults.call(this, any, args);
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
root.alternatives = root.alt = function (...args) {
|
|
59
|
-
|
|
60
|
-
return internals.callWithDefaults.call(this, internals.alternatives, args);
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
root.array = function (...args) {
|
|
64
40
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
};
|
|
41
|
+
if (Buffer) { // $lab:coverage:ignore$
|
|
42
|
+
internals.types.binary = require('./types/binary');
|
|
43
|
+
}
|
|
69
44
|
|
|
70
|
-
root.boolean = root.bool = function (...args) {
|
|
71
45
|
|
|
72
|
-
|
|
46
|
+
internals.root = function () {
|
|
73
47
|
|
|
74
|
-
|
|
48
|
+
const root = {
|
|
49
|
+
_types: new Set(Object.keys(internals.types))
|
|
75
50
|
};
|
|
76
51
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
Hoek.assert(args.length === 0, 'Joi.binary() does not allow arguments.');
|
|
80
|
-
|
|
81
|
-
return internals.callWithDefaults.call(this, internals.binary, args);
|
|
82
|
-
};
|
|
52
|
+
// Types
|
|
83
53
|
|
|
84
|
-
|
|
54
|
+
for (const type of root._types) {
|
|
55
|
+
root[type] = function (...args) {
|
|
85
56
|
|
|
86
|
-
|
|
57
|
+
Assert(!args.length || ['alternatives', 'link', 'object'].includes(type), 'The', type, 'type does not allow arguments');
|
|
58
|
+
return internals.generate(this, internals.types[type], args);
|
|
59
|
+
};
|
|
60
|
+
}
|
|
87
61
|
|
|
88
|
-
|
|
89
|
-
};
|
|
62
|
+
// Shortcuts
|
|
90
63
|
|
|
91
|
-
|
|
64
|
+
for (const method of ['allow', 'custom', 'disallow', 'equal', 'exist', 'forbidden', 'invalid', 'not', 'only', 'optional', 'options', 'prefs', 'preferences', 'required', 'strip', 'valid', 'when']) {
|
|
65
|
+
root[method] = function (...args) {
|
|
92
66
|
|
|
93
|
-
|
|
67
|
+
return this.any()[method](...args);
|
|
68
|
+
};
|
|
69
|
+
}
|
|
94
70
|
|
|
95
|
-
|
|
96
|
-
};
|
|
71
|
+
// Methods
|
|
97
72
|
|
|
98
|
-
root.
|
|
73
|
+
Object.assign(root, internals.methods);
|
|
99
74
|
|
|
100
|
-
|
|
75
|
+
// Aliases
|
|
101
76
|
|
|
102
|
-
|
|
103
|
-
|
|
77
|
+
for (const alias in internals.aliases) {
|
|
78
|
+
const target = internals.aliases[alias];
|
|
79
|
+
root[alias] = root[target];
|
|
80
|
+
}
|
|
104
81
|
|
|
105
|
-
root.
|
|
82
|
+
root.x = root.expression;
|
|
106
83
|
|
|
107
|
-
|
|
108
|
-
};
|
|
84
|
+
// Trace
|
|
109
85
|
|
|
110
|
-
|
|
86
|
+
if (Trace.setup) { // $lab:coverage:ignore$
|
|
87
|
+
Trace.setup(root);
|
|
88
|
+
}
|
|
111
89
|
|
|
112
|
-
|
|
90
|
+
return root;
|
|
91
|
+
};
|
|
113
92
|
|
|
114
|
-
return internals.callWithDefaults.call(this, internals.string, args);
|
|
115
|
-
};
|
|
116
93
|
|
|
117
|
-
|
|
94
|
+
internals.methods = {
|
|
118
95
|
|
|
119
|
-
|
|
96
|
+
ValidationError: Errors.ValidationError,
|
|
97
|
+
version: Common.version,
|
|
98
|
+
cache: Cache.provider,
|
|
120
99
|
|
|
121
|
-
|
|
122
|
-
};
|
|
100
|
+
assert(value, schema, ...args /* [message], [options] */) {
|
|
123
101
|
|
|
124
|
-
|
|
102
|
+
internals.assert(value, schema, true, args);
|
|
103
|
+
},
|
|
125
104
|
|
|
126
|
-
|
|
127
|
-
};
|
|
105
|
+
attempt(value, schema, ...args /* [message], [options] */) {
|
|
128
106
|
|
|
129
|
-
|
|
107
|
+
return internals.assert(value, schema, false, args);
|
|
108
|
+
},
|
|
130
109
|
|
|
131
|
-
|
|
132
|
-
};
|
|
110
|
+
build(desc) {
|
|
133
111
|
|
|
134
|
-
|
|
112
|
+
Assert(typeof Manifest.build === 'function', 'Manifest functionality disabled');
|
|
113
|
+
return Manifest.build(this, desc);
|
|
114
|
+
},
|
|
135
115
|
|
|
136
|
-
|
|
137
|
-
const callback = typeof last === 'function' ? last : null;
|
|
116
|
+
checkPreferences(prefs) {
|
|
138
117
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
return any.validate(value, callback);
|
|
142
|
-
}
|
|
118
|
+
Common.checkPreferences(prefs);
|
|
119
|
+
},
|
|
143
120
|
|
|
144
|
-
|
|
145
|
-
const schema = this.compile(args[0]);
|
|
121
|
+
compile(schema, options) {
|
|
146
122
|
|
|
147
|
-
return
|
|
148
|
-
}
|
|
123
|
+
return Compile.compile(this, schema, options);
|
|
124
|
+
},
|
|
149
125
|
|
|
150
|
-
|
|
126
|
+
defaults(modifier) {
|
|
151
127
|
|
|
152
|
-
|
|
153
|
-
return schema.describe();
|
|
154
|
-
};
|
|
128
|
+
Assert(typeof modifier === 'function', 'modifier must be a function');
|
|
155
129
|
|
|
156
|
-
|
|
130
|
+
const joi = Object.assign({}, this);
|
|
131
|
+
for (const type of joi._types) {
|
|
132
|
+
const schema = modifier(joi[type]());
|
|
133
|
+
Assert(Common.isSchema(schema), 'modifier must return a valid schema object');
|
|
157
134
|
|
|
158
|
-
|
|
159
|
-
return Cast.schema(this, schema);
|
|
160
|
-
}
|
|
161
|
-
catch (err) {
|
|
162
|
-
if (err.hasOwnProperty('path')) {
|
|
163
|
-
err.message = err.message + '(' + err.path + ')';
|
|
164
|
-
}
|
|
135
|
+
joi[type] = function (...args) {
|
|
165
136
|
|
|
166
|
-
|
|
137
|
+
return internals.generate(this, schema, args);
|
|
138
|
+
};
|
|
167
139
|
}
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
root.assert = function (value, schema, message) {
|
|
171
|
-
|
|
172
|
-
this.attempt(value, schema, message);
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
root.attempt = function (value, schema, message) {
|
|
176
|
-
|
|
177
|
-
const result = this.validate(value, schema);
|
|
178
|
-
const error = result.error;
|
|
179
|
-
if (error) {
|
|
180
|
-
if (!message) {
|
|
181
|
-
if (typeof error.annotate === 'function') {
|
|
182
|
-
error.message = error.annotate();
|
|
183
|
-
}
|
|
184
140
|
|
|
185
|
-
|
|
186
|
-
|
|
141
|
+
return joi;
|
|
142
|
+
},
|
|
187
143
|
|
|
188
|
-
|
|
189
|
-
if (typeof error.annotate === 'function') {
|
|
190
|
-
error.message = `${message} ${error.annotate()}`;
|
|
191
|
-
}
|
|
144
|
+
expression(...args) {
|
|
192
145
|
|
|
193
|
-
|
|
194
|
-
|
|
146
|
+
return new Template(...args);
|
|
147
|
+
},
|
|
195
148
|
|
|
196
|
-
|
|
197
|
-
}
|
|
149
|
+
extend(...extensions) {
|
|
198
150
|
|
|
199
|
-
|
|
200
|
-
};
|
|
151
|
+
Common.verifyFlat(extensions, 'extend');
|
|
201
152
|
|
|
202
|
-
|
|
153
|
+
Schemas = Schemas || require('./schemas');
|
|
203
154
|
|
|
204
|
-
|
|
205
|
-
|
|
155
|
+
Assert(extensions.length, 'You need to provide at least one extension');
|
|
156
|
+
this.assert(extensions, Schemas.extensions);
|
|
206
157
|
|
|
207
|
-
const
|
|
158
|
+
const joi = Object.assign({}, this);
|
|
159
|
+
joi._types = new Set(joi._types);
|
|
208
160
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
const children = sourceSchema._inner.children;
|
|
214
|
-
if (!children) {
|
|
215
|
-
return;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
const key = schemaPath.shift();
|
|
219
|
-
for (let i = 0; i < children.length; ++i) {
|
|
220
|
-
const child = children[i];
|
|
221
|
-
if (child.key === key) {
|
|
222
|
-
return reach(child.schema, schemaPath);
|
|
223
|
-
}
|
|
161
|
+
for (let extension of extensions) {
|
|
162
|
+
if (typeof extension === 'function') {
|
|
163
|
+
extension = extension(joi);
|
|
224
164
|
}
|
|
225
|
-
};
|
|
226
165
|
|
|
227
|
-
|
|
166
|
+
this.assert(extension, Schemas.extension);
|
|
228
167
|
|
|
229
|
-
|
|
230
|
-
|
|
168
|
+
const expanded = internals.expandExtension(extension, joi);
|
|
169
|
+
for (const item of expanded) {
|
|
170
|
+
Assert(joi[item.type] === undefined || joi._types.has(item.type), 'Cannot override name', item.type);
|
|
231
171
|
|
|
232
|
-
|
|
172
|
+
const base = item.base || this.any();
|
|
173
|
+
const schema = Extend.type(base, item);
|
|
233
174
|
|
|
234
|
-
|
|
235
|
-
|
|
175
|
+
joi._types.add(item.type);
|
|
176
|
+
joi[item.type] = function (...args) {
|
|
236
177
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
Hoek.assert(typeof fn === 'function', 'Defaults must be a function');
|
|
240
|
-
|
|
241
|
-
let joi = Object.create(this.any());
|
|
242
|
-
joi = fn(joi);
|
|
243
|
-
|
|
244
|
-
Hoek.assert(joi && joi instanceof this.constructor, 'defaults() must return a schema');
|
|
245
|
-
|
|
246
|
-
Object.assign(joi, this, joi.clone()); // Re-add the types from `this` but also keep the settings from joi's potential new defaults
|
|
247
|
-
|
|
248
|
-
joi._defaults = (schema) => {
|
|
249
|
-
|
|
250
|
-
if (this._defaults) {
|
|
251
|
-
schema = this._defaults(schema);
|
|
252
|
-
Hoek.assert(schema instanceof this.constructor, 'defaults() must return a schema');
|
|
178
|
+
return internals.generate(this, schema, args);
|
|
179
|
+
};
|
|
253
180
|
}
|
|
254
|
-
|
|
255
|
-
schema = fn(schema);
|
|
256
|
-
Hoek.assert(schema instanceof this.constructor, 'defaults() must return a schema');
|
|
257
|
-
return schema;
|
|
258
|
-
};
|
|
259
|
-
|
|
260
|
-
return joi;
|
|
261
|
-
};
|
|
262
|
-
|
|
263
|
-
root.bind = function () {
|
|
264
|
-
|
|
265
|
-
const joi = Object.create(this);
|
|
266
|
-
|
|
267
|
-
joi._binds.forEach((bind) => {
|
|
268
|
-
|
|
269
|
-
joi[bind] = joi[bind].bind(joi);
|
|
270
|
-
});
|
|
181
|
+
}
|
|
271
182
|
|
|
272
183
|
return joi;
|
|
273
|
-
}
|
|
184
|
+
},
|
|
274
185
|
|
|
275
|
-
|
|
186
|
+
isError: Errors.ValidationError.isError,
|
|
187
|
+
isExpression: Template.isTemplate,
|
|
188
|
+
isRef: Ref.isRef,
|
|
189
|
+
isSchema: Common.isSchema,
|
|
276
190
|
|
|
277
|
-
|
|
278
|
-
Hoek.assert(extensions.length > 0, 'You need to provide at least one extension');
|
|
191
|
+
in(...args) {
|
|
279
192
|
|
|
280
|
-
|
|
193
|
+
return Ref.in(...args);
|
|
194
|
+
},
|
|
281
195
|
|
|
282
|
-
|
|
283
|
-
Object.assign(joi, this);
|
|
284
|
-
joi._currentJoi = joi;
|
|
285
|
-
joi._binds = new Set(joi._binds);
|
|
196
|
+
override: Common.symbols.override,
|
|
286
197
|
|
|
287
|
-
|
|
288
|
-
let extension = extensions[i];
|
|
289
|
-
|
|
290
|
-
if (typeof extension === 'function') {
|
|
291
|
-
extension = extension(joi);
|
|
292
|
-
}
|
|
198
|
+
ref(...args) {
|
|
293
199
|
|
|
294
|
-
|
|
200
|
+
return Ref.create(...args);
|
|
201
|
+
},
|
|
295
202
|
|
|
296
|
-
|
|
297
|
-
const ctor = base.constructor;
|
|
298
|
-
const type = class extends ctor { // eslint-disable-line no-loop-func
|
|
203
|
+
types() {
|
|
299
204
|
|
|
300
|
-
|
|
205
|
+
const types = {};
|
|
206
|
+
for (const type of this._types) {
|
|
207
|
+
types[type] = this[type]();
|
|
208
|
+
}
|
|
301
209
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
}
|
|
210
|
+
for (const target in internals.aliases) {
|
|
211
|
+
types[target] = this[target]();
|
|
212
|
+
}
|
|
306
213
|
|
|
307
|
-
|
|
214
|
+
return types;
|
|
215
|
+
}
|
|
216
|
+
};
|
|
308
217
|
|
|
309
|
-
if (extension.language) {
|
|
310
|
-
this._settings = Settings.concat(this._settings, {
|
|
311
|
-
language: {
|
|
312
|
-
[extension.name]: extension.language
|
|
313
|
-
}
|
|
314
|
-
});
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
218
|
|
|
318
|
-
|
|
219
|
+
// Helpers
|
|
319
220
|
|
|
320
|
-
|
|
321
|
-
type.prototype._coerce = function (value, state, options) {
|
|
221
|
+
internals.assert = function (value, schema, annotate, args /* [message], [options] */) {
|
|
322
222
|
|
|
323
|
-
|
|
324
|
-
|
|
223
|
+
const message = args[0] instanceof Error || typeof args[0] === 'string' ? args[0] : null;
|
|
224
|
+
const options = message ? args[1] : args[0];
|
|
225
|
+
const result = schema.validate(value, Common.preferences({ errors: { stack: true } }, options || {}));
|
|
325
226
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
227
|
+
let error = result.error;
|
|
228
|
+
if (!error) {
|
|
229
|
+
return result.value;
|
|
230
|
+
}
|
|
329
231
|
|
|
330
|
-
|
|
331
|
-
|
|
232
|
+
if (message instanceof Error) {
|
|
233
|
+
throw message;
|
|
234
|
+
}
|
|
332
235
|
|
|
333
|
-
|
|
334
|
-
if (ret instanceof Errors.Err) {
|
|
335
|
-
return { value, errors: ret };
|
|
336
|
-
}
|
|
236
|
+
const display = annotate && typeof error.annotate === 'function' ? error.annotate() : error.message;
|
|
337
237
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
238
|
+
if (error instanceof Errors.ValidationError === false) {
|
|
239
|
+
error = Clone(error);
|
|
240
|
+
}
|
|
341
241
|
|
|
342
|
-
|
|
343
|
-
|
|
242
|
+
error.message = message ? `${message} ${display}` : display;
|
|
243
|
+
throw error;
|
|
244
|
+
};
|
|
344
245
|
|
|
345
|
-
if (ctor.prototype._base) {
|
|
346
|
-
const baseRet = ctor.prototype._base.call(this, value, state, options);
|
|
347
246
|
|
|
348
|
-
|
|
349
|
-
return baseRet;
|
|
350
|
-
}
|
|
247
|
+
internals.generate = function (root, schema, args) {
|
|
351
248
|
|
|
352
|
-
|
|
353
|
-
}
|
|
249
|
+
Assert(root, 'Must be invoked on a Joi instance.');
|
|
354
250
|
|
|
355
|
-
|
|
356
|
-
if (ret instanceof Errors.Err) {
|
|
357
|
-
return { value, errors: ret };
|
|
358
|
-
}
|
|
251
|
+
schema.$_root = root;
|
|
359
252
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
}
|
|
253
|
+
if (!schema._definition.args ||
|
|
254
|
+
!args.length) {
|
|
363
255
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
const rule = extension.rules[j];
|
|
367
|
-
const ruleArgs = rule.params ?
|
|
368
|
-
(rule.params instanceof Any ? rule.params._inner.children.map((k) => k.key) : Object.keys(rule.params)) :
|
|
369
|
-
[];
|
|
370
|
-
const validateArgs = rule.params ? Cast.schema(this, rule.params) : null;
|
|
371
|
-
|
|
372
|
-
type.prototype[rule.name] = function (...rArgs) { // eslint-disable-line no-loop-func
|
|
373
|
-
|
|
374
|
-
if (rArgs.length > ruleArgs.length) {
|
|
375
|
-
throw new Error('Unexpected number of arguments');
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
let hasRef = false;
|
|
379
|
-
let arg = {};
|
|
380
|
-
|
|
381
|
-
for (let k = 0; k < ruleArgs.length; ++k) {
|
|
382
|
-
arg[ruleArgs[k]] = rArgs[k];
|
|
383
|
-
if (!hasRef && Ref.isRef(rArgs[k])) {
|
|
384
|
-
hasRef = true;
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
if (validateArgs) {
|
|
389
|
-
arg = joi.attempt(arg, validateArgs);
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
let schema;
|
|
393
|
-
if (rule.validate) {
|
|
394
|
-
const validate = function (value, state, options) {
|
|
395
|
-
|
|
396
|
-
return rule.validate.call(this, arg, value, state, options);
|
|
397
|
-
};
|
|
398
|
-
|
|
399
|
-
schema = this._test(rule.name, arg, validate, {
|
|
400
|
-
description: rule.description,
|
|
401
|
-
hasRef
|
|
402
|
-
});
|
|
403
|
-
}
|
|
404
|
-
else {
|
|
405
|
-
schema = this.clone();
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
if (rule.setup) {
|
|
409
|
-
const newSchema = rule.setup.call(schema, arg);
|
|
410
|
-
if (newSchema !== undefined) {
|
|
411
|
-
Hoek.assert(newSchema instanceof Any, `Setup of extension Joi.${this._type}().${rule.name}() must return undefined or a Joi object`);
|
|
412
|
-
schema = newSchema;
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
return schema;
|
|
417
|
-
};
|
|
418
|
-
}
|
|
419
|
-
}
|
|
256
|
+
return schema;
|
|
257
|
+
}
|
|
420
258
|
|
|
421
|
-
|
|
422
|
-
|
|
259
|
+
return schema._definition.args(schema, ...args);
|
|
260
|
+
};
|
|
423
261
|
|
|
424
|
-
const description = ctor.prototype.describe.call(this);
|
|
425
|
-
return extension.describe.call(this, description);
|
|
426
|
-
};
|
|
427
|
-
}
|
|
428
262
|
|
|
429
|
-
|
|
430
|
-
joi[extension.name] = function (...extArgs) {
|
|
263
|
+
internals.expandExtension = function (extension, joi) {
|
|
431
264
|
|
|
432
|
-
|
|
433
|
-
|
|
265
|
+
if (typeof extension.type === 'string') {
|
|
266
|
+
return [extension];
|
|
267
|
+
}
|
|
434
268
|
|
|
435
|
-
|
|
269
|
+
const extended = [];
|
|
270
|
+
for (const type of joi._types) {
|
|
271
|
+
if (extension.type.test(type)) {
|
|
272
|
+
const item = Object.assign({}, extension);
|
|
273
|
+
item.type = type;
|
|
274
|
+
item.base = joi[type]();
|
|
275
|
+
extended.push(item);
|
|
436
276
|
}
|
|
277
|
+
}
|
|
437
278
|
|
|
438
|
-
|
|
439
|
-
};
|
|
440
|
-
|
|
441
|
-
root.extensionSchema = internals.object.keys({
|
|
442
|
-
base: internals.object.type(Any, 'Joi object'),
|
|
443
|
-
name: internals.string.required(),
|
|
444
|
-
coerce: internals.func.arity(3),
|
|
445
|
-
pre: internals.func.arity(3),
|
|
446
|
-
language: internals.object,
|
|
447
|
-
describe: internals.func.arity(1),
|
|
448
|
-
rules: internals.array.items(internals.object.keys({
|
|
449
|
-
name: internals.string.required(),
|
|
450
|
-
setup: internals.func.arity(1),
|
|
451
|
-
validate: internals.func.arity(4),
|
|
452
|
-
params: [
|
|
453
|
-
internals.object.pattern(/.*/, internals.object.type(Any, 'Joi object')),
|
|
454
|
-
internals.object.type(internals.object.constructor, 'Joi object')
|
|
455
|
-
],
|
|
456
|
-
description: [internals.string, internals.func.arity(1)]
|
|
457
|
-
}).or('setup', 'validate'))
|
|
458
|
-
}).strict();
|
|
459
|
-
|
|
460
|
-
root.extensionsSchema = internals.array.items([internals.object, internals.func.arity(1)]).strict();
|
|
461
|
-
|
|
462
|
-
root.version = require('../package.json').version;
|
|
463
|
-
|
|
464
|
-
return root;
|
|
279
|
+
return extended;
|
|
465
280
|
};
|
|
466
281
|
|
|
467
282
|
|