joi 14.2.0 → 17.2.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/LICENSE.md +10 -0
- package/README.md +9 -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 -347
- 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/extend.js
ADDED
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const Assert = require('@hapi/hoek/lib/assert');
|
|
4
|
+
const Clone = require('@hapi/hoek/lib/clone');
|
|
5
|
+
|
|
6
|
+
const Common = require('./common');
|
|
7
|
+
const Messages = require('./messages');
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
const internals = {};
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
exports.type = function (from, options) {
|
|
14
|
+
|
|
15
|
+
const base = Object.getPrototypeOf(from);
|
|
16
|
+
const prototype = Clone(base);
|
|
17
|
+
const schema = from._assign(Object.create(prototype));
|
|
18
|
+
const def = Object.assign({}, options); // Shallow cloned
|
|
19
|
+
delete def.base;
|
|
20
|
+
|
|
21
|
+
prototype._definition = def;
|
|
22
|
+
|
|
23
|
+
const parent = base._definition || {};
|
|
24
|
+
def.messages = Messages.merge(parent.messages, def.messages);
|
|
25
|
+
def.properties = Object.assign({}, parent.properties, def.properties);
|
|
26
|
+
|
|
27
|
+
// Type
|
|
28
|
+
|
|
29
|
+
schema.type = def.type;
|
|
30
|
+
|
|
31
|
+
// Flags
|
|
32
|
+
|
|
33
|
+
def.flags = Object.assign({}, parent.flags, def.flags);
|
|
34
|
+
|
|
35
|
+
// Terms
|
|
36
|
+
|
|
37
|
+
const terms = Object.assign({}, parent.terms);
|
|
38
|
+
if (def.terms) {
|
|
39
|
+
for (const name in def.terms) { // Only apply own terms
|
|
40
|
+
const term = def.terms[name];
|
|
41
|
+
Assert(schema.$_terms[name] === undefined, 'Invalid term override for', def.type, name);
|
|
42
|
+
schema.$_terms[name] = term.init;
|
|
43
|
+
terms[name] = term;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
def.terms = terms;
|
|
48
|
+
|
|
49
|
+
// Constructor arguments
|
|
50
|
+
|
|
51
|
+
if (!def.args) {
|
|
52
|
+
def.args = parent.args;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Prepare
|
|
56
|
+
|
|
57
|
+
def.prepare = internals.prepare(def.prepare, parent.prepare);
|
|
58
|
+
|
|
59
|
+
// Coerce
|
|
60
|
+
|
|
61
|
+
if (def.coerce) {
|
|
62
|
+
if (typeof def.coerce === 'function') {
|
|
63
|
+
def.coerce = { method: def.coerce };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (def.coerce.from &&
|
|
67
|
+
!Array.isArray(def.coerce.from)) {
|
|
68
|
+
|
|
69
|
+
def.coerce = { method: def.coerce.method, from: [].concat(def.coerce.from) };
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
def.coerce = internals.coerce(def.coerce, parent.coerce);
|
|
74
|
+
|
|
75
|
+
// Validate
|
|
76
|
+
|
|
77
|
+
def.validate = internals.validate(def.validate, parent.validate);
|
|
78
|
+
|
|
79
|
+
// Rules
|
|
80
|
+
|
|
81
|
+
const rules = Object.assign({}, parent.rules);
|
|
82
|
+
if (def.rules) {
|
|
83
|
+
for (const name in def.rules) {
|
|
84
|
+
const rule = def.rules[name];
|
|
85
|
+
Assert(typeof rule === 'object', 'Invalid rule definition for', def.type, name);
|
|
86
|
+
|
|
87
|
+
let method = rule.method;
|
|
88
|
+
if (method === undefined) {
|
|
89
|
+
method = function () {
|
|
90
|
+
|
|
91
|
+
return this.$_addRule(name);
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (method) {
|
|
96
|
+
Assert(!prototype[name], 'Rule conflict in', def.type, name);
|
|
97
|
+
prototype[name] = method;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
Assert(!rules[name], 'Rule conflict in', def.type, name);
|
|
101
|
+
rules[name] = rule;
|
|
102
|
+
|
|
103
|
+
if (rule.alias) {
|
|
104
|
+
const aliases = [].concat(rule.alias);
|
|
105
|
+
for (const alias of aliases) {
|
|
106
|
+
prototype[alias] = rule.method;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (rule.args) {
|
|
111
|
+
rule.argsByName = new Map();
|
|
112
|
+
rule.args = rule.args.map((arg) => {
|
|
113
|
+
|
|
114
|
+
if (typeof arg === 'string') {
|
|
115
|
+
arg = { name: arg };
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
Assert(!rule.argsByName.has(arg.name), 'Duplicated argument name', arg.name);
|
|
119
|
+
|
|
120
|
+
if (Common.isSchema(arg.assert)) {
|
|
121
|
+
arg.assert = arg.assert.strict().label(arg.name);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
rule.argsByName.set(arg.name, arg);
|
|
125
|
+
return arg;
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
def.rules = rules;
|
|
132
|
+
|
|
133
|
+
// Modifiers
|
|
134
|
+
|
|
135
|
+
const modifiers = Object.assign({}, parent.modifiers);
|
|
136
|
+
if (def.modifiers) {
|
|
137
|
+
for (const name in def.modifiers) {
|
|
138
|
+
Assert(!prototype[name], 'Rule conflict in', def.type, name);
|
|
139
|
+
|
|
140
|
+
const modifier = def.modifiers[name];
|
|
141
|
+
Assert(typeof modifier === 'function', 'Invalid modifier definition for', def.type, name);
|
|
142
|
+
|
|
143
|
+
const method = function (arg) {
|
|
144
|
+
|
|
145
|
+
return this.rule({ [name]: arg });
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
prototype[name] = method;
|
|
149
|
+
modifiers[name] = modifier;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
def.modifiers = modifiers;
|
|
154
|
+
|
|
155
|
+
// Overrides
|
|
156
|
+
|
|
157
|
+
if (def.overrides) {
|
|
158
|
+
prototype._super = base;
|
|
159
|
+
schema.$_super = {}; // Backwards compatibility
|
|
160
|
+
for (const override in def.overrides) {
|
|
161
|
+
Assert(base[override], 'Cannot override missing', override);
|
|
162
|
+
def.overrides[override][Common.symbols.parent] = base[override];
|
|
163
|
+
schema.$_super[override] = base[override].bind(schema); // Backwards compatibility
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
Object.assign(prototype, def.overrides);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Casts
|
|
170
|
+
|
|
171
|
+
def.cast = Object.assign({}, parent.cast, def.cast);
|
|
172
|
+
|
|
173
|
+
// Manifest
|
|
174
|
+
|
|
175
|
+
const manifest = Object.assign({}, parent.manifest, def.manifest);
|
|
176
|
+
manifest.build = internals.build(def.manifest && def.manifest.build, parent.manifest && parent.manifest.build);
|
|
177
|
+
def.manifest = manifest;
|
|
178
|
+
|
|
179
|
+
// Rebuild
|
|
180
|
+
|
|
181
|
+
def.rebuild = internals.rebuild(def.rebuild, parent.rebuild);
|
|
182
|
+
|
|
183
|
+
return schema;
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
// Helpers
|
|
188
|
+
|
|
189
|
+
internals.build = function (child, parent) {
|
|
190
|
+
|
|
191
|
+
if (!child ||
|
|
192
|
+
!parent) {
|
|
193
|
+
|
|
194
|
+
return child || parent;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return function (obj, desc) {
|
|
198
|
+
|
|
199
|
+
return parent(child(obj, desc), desc);
|
|
200
|
+
};
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
internals.coerce = function (child, parent) {
|
|
205
|
+
|
|
206
|
+
if (!child ||
|
|
207
|
+
!parent) {
|
|
208
|
+
|
|
209
|
+
return child || parent;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return {
|
|
213
|
+
from: child.from && parent.from ? [...new Set([...child.from, ...parent.from])] : null,
|
|
214
|
+
method(value, helpers) {
|
|
215
|
+
|
|
216
|
+
let coerced;
|
|
217
|
+
if (!parent.from ||
|
|
218
|
+
parent.from.includes(typeof value)) {
|
|
219
|
+
|
|
220
|
+
coerced = parent.method(value, helpers);
|
|
221
|
+
if (coerced) {
|
|
222
|
+
if (coerced.errors ||
|
|
223
|
+
coerced.value === undefined) {
|
|
224
|
+
|
|
225
|
+
return coerced;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
value = coerced.value;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (!child.from ||
|
|
233
|
+
child.from.includes(typeof value)) {
|
|
234
|
+
|
|
235
|
+
const own = child.method(value, helpers);
|
|
236
|
+
if (own) {
|
|
237
|
+
return own;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return coerced;
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
internals.prepare = function (child, parent) {
|
|
248
|
+
|
|
249
|
+
if (!child ||
|
|
250
|
+
!parent) {
|
|
251
|
+
|
|
252
|
+
return child || parent;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
return function (value, helpers) {
|
|
256
|
+
|
|
257
|
+
const prepared = child(value, helpers);
|
|
258
|
+
if (prepared) {
|
|
259
|
+
if (prepared.errors ||
|
|
260
|
+
prepared.value === undefined) {
|
|
261
|
+
|
|
262
|
+
return prepared;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
value = prepared.value;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
return parent(value, helpers) || prepared;
|
|
269
|
+
};
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
internals.rebuild = function (child, parent) {
|
|
274
|
+
|
|
275
|
+
if (!child ||
|
|
276
|
+
!parent) {
|
|
277
|
+
|
|
278
|
+
return child || parent;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return function (schema) {
|
|
282
|
+
|
|
283
|
+
parent(schema);
|
|
284
|
+
child(schema);
|
|
285
|
+
};
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
internals.validate = function (child, parent) {
|
|
290
|
+
|
|
291
|
+
if (!child ||
|
|
292
|
+
!parent) {
|
|
293
|
+
|
|
294
|
+
return child || parent;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
return function (value, helpers) {
|
|
298
|
+
|
|
299
|
+
const result = parent(value, helpers);
|
|
300
|
+
if (result) {
|
|
301
|
+
if (result.errors &&
|
|
302
|
+
(!Array.isArray(result.errors) || result.errors.length)) {
|
|
303
|
+
|
|
304
|
+
return result;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
value = result.value;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
return child(value, helpers) || result;
|
|
311
|
+
};
|
|
312
|
+
};
|