1 | import _extends from "@babel/runtime/helpers/esm/extends";
|
2 |
|
3 | function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } it = o[Symbol.iterator](); return it.next.bind(it); }
|
4 |
|
5 | function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
6 |
|
7 | function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
8 |
|
9 | import has from "lodash-es/has";
|
10 | import _snakeCase from "lodash-es/snakeCase";
|
11 | import _camelCase from "lodash-es/camelCase";
|
12 | import mapKeys from "lodash-es/mapKeys";
|
13 | import mapValues from "lodash-es/mapValues";
|
14 | import { getter } from 'property-expr';
|
15 | import MixedSchema from './mixed';
|
16 | import { object as locale } from './locale.js';
|
17 | import sortFields from './util/sortFields';
|
18 | import sortByKeyOrder from './util/sortByKeyOrder';
|
19 | import inherits from './util/inherits';
|
20 | import runTests from './util/runTests';
|
21 |
|
22 | var isObject = function isObject(obj) {
|
23 | return Object.prototype.toString.call(obj) === '[object Object]';
|
24 | };
|
25 |
|
26 | function unknown(ctx, value) {
|
27 | var known = Object.keys(ctx.fields);
|
28 | return Object.keys(value).filter(function (key) {
|
29 | return known.indexOf(key) === -1;
|
30 | });
|
31 | }
|
32 |
|
33 | export default function ObjectSchema(spec) {
|
34 | var _this2 = this;
|
35 |
|
36 | if (!(this instanceof ObjectSchema)) return new ObjectSchema(spec);
|
37 | MixedSchema.call(this, {
|
38 | type: 'object',
|
39 | default: function _default() {
|
40 | var _this = this;
|
41 |
|
42 | if (!this._nodes.length) return undefined;
|
43 | var dft = {};
|
44 |
|
45 | this._nodes.forEach(function (key) {
|
46 | dft[key] = _this.fields[key].default ? _this.fields[key].getDefault() : undefined;
|
47 | });
|
48 |
|
49 | return dft;
|
50 | }
|
51 | });
|
52 | this.fields = Object.create(null);
|
53 | this._sortErrors = sortByKeyOrder([]);
|
54 | this._nodes = [];
|
55 | this._excludedEdges = [];
|
56 | this.withMutation(function () {
|
57 | _this2.transform(function coerce(value) {
|
58 | if (typeof value === 'string') {
|
59 | try {
|
60 | value = JSON.parse(value);
|
61 | } catch (err) {
|
62 | value = null;
|
63 | }
|
64 | }
|
65 |
|
66 | if (this.isType(value)) return value;
|
67 | return null;
|
68 | });
|
69 |
|
70 | if (spec) {
|
71 | _this2.shape(spec);
|
72 | }
|
73 | });
|
74 | }
|
75 | inherits(ObjectSchema, MixedSchema, {
|
76 | _typeCheck: function _typeCheck(value) {
|
77 | return isObject(value) || typeof value === 'function';
|
78 | },
|
79 | _cast: function _cast(_value, options) {
|
80 | var _this3 = this;
|
81 |
|
82 | if (options === void 0) {
|
83 | options = {};
|
84 | }
|
85 |
|
86 | var value = MixedSchema.prototype._cast.call(this, _value);
|
87 |
|
88 |
|
89 | if (value === undefined) return this.getDefault();
|
90 | if (!this._typeCheck(value)) return value;
|
91 | var fields = this.fields;
|
92 | var strip = this._option('stripUnknown', options) === true;
|
93 |
|
94 | var props = this._nodes.concat(Object.keys(value).filter(function (v) {
|
95 | return _this3._nodes.indexOf(v) === -1;
|
96 | }));
|
97 |
|
98 | var intermediateValue = {};
|
99 |
|
100 | var innerOptions = _extends({}, options, {
|
101 | parent: intermediateValue,
|
102 | __validating: options.__validating || false
|
103 | });
|
104 |
|
105 | var isChanged = false;
|
106 |
|
107 | for (var _iterator = _createForOfIteratorHelperLoose(props), _step; !(_step = _iterator()).done;) {
|
108 | var prop = _step.value;
|
109 | var field = fields[prop];
|
110 | var exists = has(value, prop);
|
111 |
|
112 | if (field) {
|
113 | var fieldValue = void 0;
|
114 | var strict = field._options && field._options.strict;
|
115 |
|
116 | innerOptions.path = (options.path ? options.path + "." : '') + prop;
|
117 | innerOptions.value = value[prop];
|
118 | field = field.resolve(innerOptions);
|
119 |
|
120 | if (field._strip === true) {
|
121 | isChanged = isChanged || prop in value;
|
122 | continue;
|
123 | }
|
124 |
|
125 | fieldValue = !options.__validating || !strict ? field.cast(value[prop], innerOptions) : value[prop];
|
126 |
|
127 | if (fieldValue !== undefined) {
|
128 | intermediateValue[prop] = fieldValue;
|
129 | }
|
130 | } else if (exists && !strip) {
|
131 | intermediateValue[prop] = value[prop];
|
132 | }
|
133 |
|
134 | if (intermediateValue[prop] !== value[prop]) {
|
135 | isChanged = true;
|
136 | }
|
137 | }
|
138 |
|
139 | return isChanged ? intermediateValue : value;
|
140 | },
|
141 |
|
142 | |
143 |
|
144 |
|
145 |
|
146 |
|
147 |
|
148 | |
149 |
|
150 |
|
151 |
|
152 |
|
153 |
|
154 |
|
155 |
|
156 |
|
157 |
|
158 |
|
159 |
|
160 |
|
161 |
|
162 |
|
163 |
|
164 |
|
165 |
|
166 | _validate: function _validate(_value, opts, callback) {
|
167 | var _this4 = this;
|
168 |
|
169 | if (opts === void 0) {
|
170 | opts = {};
|
171 | }
|
172 |
|
173 | var errors = [];
|
174 | var _opts = opts,
|
175 | sync = _opts.sync,
|
176 | _opts$from = _opts.from,
|
177 | from = _opts$from === void 0 ? [] : _opts$from,
|
178 | _opts$originalValue = _opts.originalValue,
|
179 | originalValue = _opts$originalValue === void 0 ? _value : _opts$originalValue,
|
180 | _opts$abortEarly = _opts.abortEarly,
|
181 | abortEarly = _opts$abortEarly === void 0 ? this._options.abortEarly : _opts$abortEarly,
|
182 | _opts$recursive = _opts.recursive,
|
183 | recursive = _opts$recursive === void 0 ? this._options.recursive : _opts$recursive;
|
184 | from = [{
|
185 | schema: this,
|
186 | value: originalValue
|
187 | }].concat(from);
|
188 |
|
189 |
|
190 | opts.__validating = true;
|
191 | opts.originalValue = originalValue;
|
192 | opts.from = from;
|
193 |
|
194 | MixedSchema.prototype._validate.call(this, _value, opts, function (err, value) {
|
195 | if (err) {
|
196 | if (abortEarly) return void callback(err);
|
197 | errors.push(err);
|
198 | value = err.value;
|
199 | }
|
200 |
|
201 | if (!recursive || !isObject(value)) {
|
202 | callback(errors[0] || null, value);
|
203 | return;
|
204 | }
|
205 |
|
206 | originalValue = originalValue || value;
|
207 |
|
208 | var tests = _this4._nodes.map(function (key) {
|
209 | return function (_, cb) {
|
210 | var path = key.indexOf('.') === -1 ? (opts.path ? opts.path + "." : '') + key : (opts.path || '') + "[\"" + key + "\"]";
|
211 | var field = _this4.fields[key];
|
212 |
|
213 | if (field && field.validate) {
|
214 | field.validate(value[key], _extends({}, opts, {
|
215 | path: path,
|
216 | from: from,
|
217 |
|
218 |
|
219 |
|
220 | strict: true,
|
221 | parent: value,
|
222 | originalValue: originalValue[key]
|
223 | }), cb);
|
224 | return;
|
225 | }
|
226 |
|
227 | cb(null);
|
228 | };
|
229 | });
|
230 |
|
231 | runTests({
|
232 | sync: sync,
|
233 | tests: tests,
|
234 | value: value,
|
235 | errors: errors,
|
236 | endEarly: abortEarly,
|
237 | sort: _this4._sortErrors,
|
238 | path: opts.path
|
239 | }, callback);
|
240 | });
|
241 | },
|
242 | concat: function concat(schema) {
|
243 | var next = MixedSchema.prototype.concat.call(this, schema);
|
244 | next._nodes = sortFields(next.fields, next._excludedEdges);
|
245 | return next;
|
246 | },
|
247 | shape: function shape(schema, excludes) {
|
248 | if (excludes === void 0) {
|
249 | excludes = [];
|
250 | }
|
251 |
|
252 | var next = this.clone();
|
253 |
|
254 | var fields = _extends(next.fields, schema);
|
255 |
|
256 | next.fields = fields;
|
257 | next._sortErrors = sortByKeyOrder(Object.keys(fields));
|
258 |
|
259 | if (excludes.length) {
|
260 | if (!Array.isArray(excludes[0])) excludes = [excludes];
|
261 | var keys = excludes.map(function (_ref) {
|
262 | var first = _ref[0],
|
263 | second = _ref[1];
|
264 | return first + "-" + second;
|
265 | });
|
266 | next._excludedEdges = next._excludedEdges.concat(keys);
|
267 | }
|
268 |
|
269 | next._nodes = sortFields(fields, next._excludedEdges);
|
270 | return next;
|
271 | },
|
272 | pick: function pick(keys) {
|
273 | var picked = {};
|
274 |
|
275 | for (var _iterator2 = _createForOfIteratorHelperLoose(keys), _step2; !(_step2 = _iterator2()).done;) {
|
276 | var key = _step2.value;
|
277 | if (this.fields[key]) picked[key] = this.fields[key];
|
278 | }
|
279 |
|
280 | return this.clone().withMutation(function (next) {
|
281 | next.fields = {};
|
282 | return next.shape(picked);
|
283 | });
|
284 | },
|
285 | omit: function omit(keys) {
|
286 | var next = this.clone();
|
287 | var fields = next.fields;
|
288 | next.fields = {};
|
289 |
|
290 | for (var _iterator3 = _createForOfIteratorHelperLoose(keys), _step3; !(_step3 = _iterator3()).done;) {
|
291 | var key = _step3.value;
|
292 | delete fields[key];
|
293 | }
|
294 |
|
295 | return next.withMutation(function (next) {
|
296 | return next.shape(fields);
|
297 | });
|
298 | },
|
299 | from: function from(_from, to, alias) {
|
300 | var fromGetter = getter(_from, true);
|
301 | return this.transform(function (obj) {
|
302 | if (obj == null) return obj;
|
303 | var newObj = obj;
|
304 |
|
305 | if (has(obj, _from)) {
|
306 | newObj = _extends({}, obj);
|
307 | if (!alias) delete newObj[_from];
|
308 | newObj[to] = fromGetter(obj);
|
309 | }
|
310 |
|
311 | return newObj;
|
312 | });
|
313 | },
|
314 | noUnknown: function noUnknown(noAllow, message) {
|
315 | if (noAllow === void 0) {
|
316 | noAllow = true;
|
317 | }
|
318 |
|
319 | if (message === void 0) {
|
320 | message = locale.noUnknown;
|
321 | }
|
322 |
|
323 | if (typeof noAllow === 'string') {
|
324 | message = noAllow;
|
325 | noAllow = true;
|
326 | }
|
327 |
|
328 | var next = this.test({
|
329 | name: 'noUnknown',
|
330 | exclusive: true,
|
331 | message: message,
|
332 | test: function test(value) {
|
333 | if (value == null) return true;
|
334 | var unknownKeys = unknown(this.schema, value);
|
335 | return !noAllow || unknownKeys.length === 0 || this.createError({
|
336 | params: {
|
337 | unknown: unknownKeys.join(', ')
|
338 | }
|
339 | });
|
340 | }
|
341 | });
|
342 | next._options.stripUnknown = noAllow;
|
343 | return next;
|
344 | },
|
345 | unknown: function unknown(allow, message) {
|
346 | if (allow === void 0) {
|
347 | allow = true;
|
348 | }
|
349 |
|
350 | if (message === void 0) {
|
351 | message = locale.noUnknown;
|
352 | }
|
353 |
|
354 | return this.noUnknown(!allow, message);
|
355 | },
|
356 | transformKeys: function transformKeys(fn) {
|
357 | return this.transform(function (obj) {
|
358 | return obj && mapKeys(obj, function (_, key) {
|
359 | return fn(key);
|
360 | });
|
361 | });
|
362 | },
|
363 | camelCase: function camelCase() {
|
364 | return this.transformKeys(_camelCase);
|
365 | },
|
366 | snakeCase: function snakeCase() {
|
367 | return this.transformKeys(_snakeCase);
|
368 | },
|
369 | constantCase: function constantCase() {
|
370 | return this.transformKeys(function (key) {
|
371 | return _snakeCase(key).toUpperCase();
|
372 | });
|
373 | },
|
374 | describe: function describe() {
|
375 | var base = MixedSchema.prototype.describe.call(this);
|
376 | base.fields = mapValues(this.fields, function (value) {
|
377 | return value.describe();
|
378 | });
|
379 | return base;
|
380 | }
|
381 | }); |
\ | No newline at end of file |