UNPKG

22.9 kBJavaScriptView Raw
1/**
2 * Define a struct error.
3 *
4 * @type {StructError}
5 */
6
7class StructError extends TypeError {
8
9 constructor(attrs) {
10 const { data, value, type, path, errors = [] } = attrs;
11 const message = `Expected a value of type \`${type}\`${path.length ? ` for \`${path.join('.')}\`` : ''} but received \`${value}\`.`;
12 super(message);
13 this.data = data;
14 this.path = path;
15 this.value = value;
16 this.type = type;
17 this.errors = errors;
18 if (!errors.length) errors.push(this);
19 if (Error.captureStackTrace) {
20 Error.captureStackTrace(this, this.constructor);
21 } else {
22 this.stack = new Error().stack;
23 }
24 }
25
26}
27
28var toString = Object.prototype.toString;
29
30var kindOf = function kindOf(val) {
31 if (val === void 0) return 'undefined';
32 if (val === null) return 'null';
33
34 var type = typeof val;
35 if (type === 'boolean') return 'boolean';
36 if (type === 'string') return 'string';
37 if (type === 'number') return 'number';
38 if (type === 'symbol') return 'symbol';
39 if (type === 'function') {
40 return isGeneratorFn(val) ? 'generatorfunction' : 'function';
41 }
42
43 if (isArray(val)) return 'array';
44 if (isBuffer(val)) return 'buffer';
45 if (isArguments(val)) return 'arguments';
46 if (isDate(val)) return 'date';
47 if (isError(val)) return 'error';
48 if (isRegexp(val)) return 'regexp';
49
50 switch (ctorName(val)) {
51 case 'Symbol': return 'symbol';
52 case 'Promise': return 'promise';
53
54 // Set, Map, WeakSet, WeakMap
55 case 'WeakMap': return 'weakmap';
56 case 'WeakSet': return 'weakset';
57 case 'Map': return 'map';
58 case 'Set': return 'set';
59
60 // 8-bit typed arrays
61 case 'Int8Array': return 'int8array';
62 case 'Uint8Array': return 'uint8array';
63 case 'Uint8ClampedArray': return 'uint8clampedarray';
64
65 // 16-bit typed arrays
66 case 'Int16Array': return 'int16array';
67 case 'Uint16Array': return 'uint16array';
68
69 // 32-bit typed arrays
70 case 'Int32Array': return 'int32array';
71 case 'Uint32Array': return 'uint32array';
72 case 'Float32Array': return 'float32array';
73 case 'Float64Array': return 'float64array';
74 }
75
76 if (isGeneratorObj(val)) {
77 return 'generator';
78 }
79
80 // Non-plain objects
81 type = toString.call(val);
82 switch (type) {
83 case '[object Object]': return 'object';
84 // iterators
85 case '[object Map Iterator]': return 'mapiterator';
86 case '[object Set Iterator]': return 'setiterator';
87 case '[object String Iterator]': return 'stringiterator';
88 case '[object Array Iterator]': return 'arrayiterator';
89 }
90
91 // other
92 return type.slice(8, -1).toLowerCase().replace(/\s/g, '');
93};
94
95function ctorName(val) {
96 return val.constructor ? val.constructor.name : null;
97}
98
99function isArray(val) {
100 if (Array.isArray) return Array.isArray(val);
101 return val instanceof Array;
102}
103
104function isError(val) {
105 return val instanceof Error || (typeof val.message === 'string' && val.constructor && typeof val.constructor.stackTraceLimit === 'number');
106}
107
108function isDate(val) {
109 if (val instanceof Date) return true;
110 return typeof val.toDateString === 'function'
111 && typeof val.getDate === 'function'
112 && typeof val.setDate === 'function';
113}
114
115function isRegexp(val) {
116 if (val instanceof RegExp) return true;
117 return typeof val.flags === 'string'
118 && typeof val.ignoreCase === 'boolean'
119 && typeof val.multiline === 'boolean'
120 && typeof val.global === 'boolean';
121}
122
123function isGeneratorFn(name, val) {
124 return ctorName(name) === 'GeneratorFunction';
125}
126
127function isGeneratorObj(val) {
128 return typeof val.throw === 'function'
129 && typeof val.return === 'function'
130 && typeof val.next === 'function';
131}
132
133function isArguments(val) {
134 try {
135 if (typeof val.length === 'number' && typeof val.callee === 'function') {
136 return true;
137 }
138 } catch (err) {
139 if (err.message.indexOf('callee') !== -1) {
140 return true;
141 }
142 }
143 return false;
144}
145
146/**
147 * If you need to support Safari 5-7 (8-10 yr-old browser),
148 * take a look at https://github.com/feross/is-buffer
149 */
150
151function isBuffer(val) {
152 if (val.constructor && typeof val.constructor.isBuffer === 'function') {
153 return val.constructor.isBuffer(val);
154 }
155 return false;
156}
157
158/**
159 * A private string to identify structs by.
160 *
161 * @type {String}
162 */
163
164const IS_STRUCT = '@@__STRUCT__@@';
165
166/**
167 * A private string to refer to a struct's kind.
168 *
169 * @type {String}
170 */
171
172const KIND = '@@__KIND__@@';
173
174/**
175 * Check if a `value` is a struct.
176 *
177 * @param {Any} value
178 * @return {Boolean}
179 */
180
181function isStruct(value) {
182 return !!(value && value[IS_STRUCT]);
183}
184
185/**
186 * Resolve a `defaults` value.
187 *
188 * @param {Function|Any} defaults
189 * @return {Any}
190 */
191
192function resolveDefaults(defaults) {
193 return typeof defaults === 'function' ? defaults() : defaults;
194}
195
196/**
197 * Kind.
198 *
199 * @type {Kind}
200 */
201
202class Kind {
203
204 constructor(name, type, validate) {
205 this.name = name;
206 this.type = type;
207 this.validate = validate;
208 }
209
210}
211
212/**
213 * Any.
214 *
215 * @param {Array|Function|Object|String} schema
216 * @param {Any} defaults
217 * @param {Object} options
218 */
219
220function any(schema, defaults, options) {
221 if (isStruct(schema)) return schema[KIND];
222 if (schema instanceof Kind) return schema;
223
224 switch (kindOf(schema)) {
225 case 'array':
226 {
227 return schema.length > 1 ? tuple(schema, defaults, options) : list(schema, defaults, options);
228 }
229
230 case 'function':
231 {
232 return func(schema, defaults, options);
233 }
234
235 case 'object':
236 {
237 return object(schema, defaults, options);
238 }
239
240 case 'string':
241 {
242 let required = true;
243 let type;
244
245 if (schema.endsWith('?')) {
246 required = false;
247 schema = schema.slice(0, -1);
248 }
249
250 if (schema.includes('|')) {
251 const scalars = schema.split(/\s*\|\s*/g);
252 type = union(scalars, defaults, options);
253 } else if (schema.includes('&')) {
254 const scalars = schema.split(/\s*&\s*/g);
255 type = intersection(scalars, defaults, options);
256 } else {
257 type = scalar(schema, defaults, options);
258 }
259
260 if (!required) {
261 type = optional(type, undefined, options);
262 }
263
264 return type;
265 }
266 }
267
268 if (process.env.NODE_ENV !== 'production') {
269 throw new Error(`A schema definition must be an object, array, string or function, but you passed: ${schema}`);
270 } else {
271 throw new Error(`Invalid schema: ${schema}`);
272 }
273}
274
275/**
276 * Dict.
277 *
278 * @param {Array} schema
279 * @param {Object} defaults
280 * @param {Object} options
281 */
282
283function dict(schema, defaults, options) {
284 if (kindOf(schema) !== 'array' || schema.length !== 2) {
285 if (process.env.NODE_ENV !== 'production') {
286 throw new Error(`Dict structs must be defined as an array with two elements, but you passed: ${schema}`);
287 } else {
288 throw new Error(`Invalid schema: ${schema}`);
289 }
290 }
291
292 const obj = scalar('object', undefined, options);
293 const keys = any(schema[0], undefined, options);
294 const values = any(schema[1], undefined, options);
295 const name = 'dict';
296 const type = `dict<${keys.type},${values.type}>`;
297 const validate = (value = resolveDefaults(defaults)) => {
298 const [error] = obj.validate(value);
299
300 if (error) {
301 error.type = type;
302 return [error];
303 }
304
305 const ret = {};
306 const errors = [];
307
308 for (let k in value) {
309 const v = value[k];
310 const [e, r] = keys.validate(k);
311
312 if (e) {
313 e.path = [k].concat(e.path);
314 e.data = value;
315 errors.push(e);
316 continue;
317 }
318
319 k = r;
320 const [e2, r2] = values.validate(v);
321
322 if (e2) {
323 e2.path = [k].concat(e2.path);
324 e2.data = value;
325 errors.push(e2);
326 continue;
327 }
328
329 ret[k] = r2;
330 }
331
332 if (errors.length) {
333 const first = errors[0];
334 first.errors = errors;
335 return [first];
336 }
337
338 return [undefined, ret];
339 };
340
341 return new Kind(name, type, validate);
342}
343
344/**
345 * Enum.
346 *
347 * @param {Array} schema
348 * @param {Any} defaults
349 * @param {Object} options
350 */
351
352function en(schema, defaults, options) {
353 if (kindOf(schema) !== 'array') {
354 if (process.env.NODE_ENV !== 'production') {
355 throw new Error(`Enum structs must be defined as an array, but you passed: ${schema}`);
356 } else {
357 throw new Error(`Invalid schema: ${schema}`);
358 }
359 }
360
361 const name = 'enum';
362 const type = schema.map(s => {
363 try {
364 return JSON.stringify(s);
365 } catch (e) {
366 return String(s);
367 }
368 }).join(' | ');
369
370 const validate = (value = resolveDefaults(defaults)) => {
371 return schema.includes(value) ? [undefined, value] : [{ data: value, path: [], value, type }];
372 };
373
374 return new Kind(name, type, validate);
375}
376
377/**
378 * Enums.
379 *
380 * @param {Array} schema
381 * @param {Any} defaults
382 * @param {Object} options
383 */
384
385function enums(schema, defaults, options) {
386 const e = en(schema, undefined, options);
387 const l = list([e], defaults, options);
388 return l;
389}
390
391/**
392 * Function.
393 *
394 * @param {Function} schema
395 * @param {Any} defaults
396 * @param {Object} options
397 */
398
399function func(schema, defaults, options) {
400 if (kindOf(schema) !== 'function') {
401 if (process.env.NODE_ENV !== 'production') {
402 throw new Error(`Function structs must be defined as a function, but you passed: ${schema}`);
403 } else {
404 throw new Error(`Invalid schema: ${schema}`);
405 }
406 }
407
408 const name = 'function';
409 const type = '<function>';
410 const validate = (value = resolveDefaults(defaults)) => {
411 return schema(value) ? [undefined, value] : [{ type, value, data: value, path: [] }];
412 };
413
414 return new Kind(name, type, validate);
415}
416
417/**
418 * Instance.
419 *
420 * @param {Array} schema
421 * @param {Any} defaults
422 * @param {Object} options
423 */
424
425function instance(schema, defaults, options) {
426 const name = 'instance';
427 const type = `instance<${schema.name}>`;
428 const validate = (value = resolveDefaults(defaults)) => {
429 return value instanceof schema ? [undefined, value] : [{ data: value, path: [], value, type }];
430 };
431
432 return new Kind(name, type, validate);
433}
434
435/**
436 * Interface.
437 *
438 * @param {Object} schema
439 * @param {Object} defaults
440 * @param {Object} options
441 */
442
443function inter(schema, defaults, options) {
444 if (kindOf(schema) !== 'object') {
445 if (process.env.NODE_ENV !== 'production') {
446 throw new Error(`Interface structs must be defined as an object, but you passed: ${schema}`);
447 } else {
448 throw new Error(`Invalid schema: ${schema}`);
449 }
450 }
451
452 const ks = [];
453 const properties = {};
454
455 for (const key in schema) {
456 ks.push(key);
457 const s = schema[key];
458 const kind = any(s, undefined, options);
459 properties[key] = kind;
460 }
461
462 const name = 'interface';
463 const type = `{${ks.join()}}`;
464 const validate = (value = resolveDefaults(defaults)) => {
465 const errors = [];
466
467 for (const key in properties) {
468 const v = value[key];
469 const kind = properties[key];
470 const [e] = kind.validate(v);
471
472 if (e) {
473 e.path = [key].concat(e.path);
474 e.data = value;
475 errors.push(e);
476 continue;
477 }
478 }
479
480 if (errors.length) {
481 const first = errors[0];
482 first.errors = errors;
483 return [first];
484 }
485
486 return [undefined, value];
487 };
488
489 return new Kind(name, type, validate);
490}
491
492/**
493 * List.
494 *
495 * @param {Array} schema
496 * @param {Array} defaults
497 * @param {Object} options
498 */
499
500function list(schema, defaults, options) {
501 if (kindOf(schema) !== 'array' || schema.length !== 1) {
502 if (process.env.NODE_ENV !== 'production') {
503 throw new Error(`List structs must be defined as an array with a single element, but you passed: ${schema}`);
504 } else {
505 throw new Error(`Invalid schema: ${schema}`);
506 }
507 }
508
509 const array = scalar('array', undefined, options);
510 const element = any(schema[0], undefined, options);
511 const name = 'list';
512 const type = `[${element.type}]`;
513 const validate = (value = resolveDefaults(defaults)) => {
514 const [error, result] = array.validate(value);
515
516 if (error) {
517 error.type = type;
518 return [error];
519 }
520
521 value = result;
522 const errors = [];
523 const ret = [];
524
525 for (let i = 0; i < value.length; i++) {
526 const v = value[i];
527 const [e, r] = element.validate(v);
528
529 if (e) {
530 e.path = [i].concat(e.path);
531 e.data = value;
532 errors.push(e);
533 continue;
534 }
535
536 ret[i] = r;
537 }
538
539 if (errors.length) {
540 const first = errors[0];
541 first.errors = errors;
542 return [first];
543 }
544
545 return [undefined, ret];
546 };
547
548 return new Kind(name, type, validate);
549}
550
551/**
552 * Literal.
553 *
554 * @param {Array} schema
555 * @param {Any} defaults
556 * @param {Object} options
557 */
558
559function literal(schema, defaults, options) {
560 const name = 'literal';
561 const type = `literal: ${JSON.stringify(schema)}`;
562 const validate = (value = resolveDefaults(defaults)) => {
563 return value === schema ? [undefined, value] : [{ data: value, path: [], value, type }];
564 };
565
566 return new Kind(name, type, validate);
567}
568
569/**
570 * Object.
571 *
572 * @param {Object} schema
573 * @param {Object} defaults
574 * @param {Object} options
575 */
576
577function object(schema, defaults, options) {
578 if (kindOf(schema) !== 'object') {
579 if (process.env.NODE_ENV !== 'production') {
580 throw new Error(`Object structs must be defined as an object, but you passed: ${schema}`);
581 } else {
582 throw new Error(`Invalid schema: ${schema}`);
583 }
584 }
585
586 const obj = scalar('object', undefined, options);
587 const ks = [];
588 const properties = {};
589
590 for (const key in schema) {
591 ks.push(key);
592 const s = schema[key];
593 const kind = any(s, undefined, options);
594 properties[key] = kind;
595 }
596
597 const name = 'object';
598 const type = `{${ks.join()}}`;
599 const validate = (value = resolveDefaults(defaults)) => {
600 const [error] = obj.validate(value);
601
602 if (error) {
603 error.type = type;
604 return [error];
605 }
606
607 const errors = [];
608 const ret = {};
609 const valueKeys = Object.keys(value);
610 const propertiesKeys = Object.keys(properties);
611 const keys = new Set(valueKeys.concat(propertiesKeys));
612
613 keys.forEach(key => {
614 let v = value[key];
615 const kind = properties[key];
616
617 if (v === undefined) {
618 const d = defaults && defaults[key];
619 v = resolveDefaults(d);
620 }
621
622 if (!kind) {
623 const e = { data: value, path: [key], value: v };
624 errors.push(e);
625 return;
626 }
627 const [e, r] = kind.validate(v);
628
629 if (e) {
630 e.path = [key].concat(e.path);
631 e.data = value;
632 errors.push(e);
633 return;
634 }
635
636 if (key in value || r !== undefined) {
637 ret[key] = r;
638 }
639 });
640
641 if (errors.length) {
642 const first = errors[0];
643 first.errors = errors;
644 return [first];
645 }
646
647 return [undefined, ret];
648 };
649
650 return new Kind(name, type, validate);
651}
652
653/**
654 * Optional.
655 *
656 * @param {Any} schema
657 * @param {Any} defaults
658 * @param {Object} options
659 */
660
661function optional(schema, defaults, options) {
662 return union([schema, 'undefined'], defaults, options);
663}
664
665/**
666 * Scalar.
667 *
668 * @param {String} schema
669 * @param {Any} defaults
670 * @param {Object} options
671 */
672
673function scalar(schema, defaults, options) {
674 if (kindOf(schema) !== 'string') {
675 if (process.env.NODE_ENV !== 'production') {
676 throw new Error(`Scalar structs must be defined as a string, but you passed: ${schema}`);
677 } else {
678 throw new Error(`Invalid schema: ${schema}`);
679 }
680 }
681
682 const { types } = options;
683 const fn = types[schema];
684
685 if (kindOf(fn) !== 'function') {
686 if (process.env.NODE_ENV !== 'production') {
687 throw new Error(`No struct validator function found for type "${schema}".`);
688 } else {
689 throw new Error(`Invalid type: ${schema}`);
690 }
691 }
692
693 const kind = func(fn, defaults, options);
694 const name = 'scalar';
695 const type = schema;
696 const validate = value => {
697 const [error, result] = kind.validate(value);
698
699 if (error) {
700 error.type = type;
701 return [error];
702 }
703
704 return [undefined, result];
705 };
706
707 return new Kind(name, type, validate);
708}
709
710/**
711 * Tuple.
712 *
713 * @param {Array} schema
714 * @param {Array} defaults
715 * @param {Object} options
716 */
717
718function tuple(schema, defaults, options) {
719 if (kindOf(schema) !== 'array') {
720 if (process.env.NODE_ENV !== 'production') {
721 throw new Error(`Tuple structs must be defined as an array, but you passed: ${schema}`);
722 } else {
723 throw new Error(`Invalid schema: ${schema}`);
724 }
725 }
726
727 const kinds = schema.map(s => any(s, undefined, options));
728 const array = scalar('array', undefined, options);
729 const name = 'tuple';
730 const type = `[${kinds.map(k => k.type).join()}]`;
731 const validate = (value = resolveDefaults(defaults)) => {
732 const [error] = array.validate(value);
733
734 if (error) {
735 error.type = type;
736 return [error];
737 }
738
739 const ret = [];
740 const errors = [];
741 const length = Math.max(value.length, kinds.length);
742
743 for (let i = 0; i < length; i++) {
744 const kind = kinds[i];
745 const v = value[i];
746
747 if (!kind) {
748 const e = { data: value, path: [i], value: v };
749 errors.push(e);
750 continue;
751 }
752
753 const [e, r] = kind.validate(v);
754
755 if (e) {
756 e.path = [i].concat(e.path);
757 e.data = value;
758 errors.push(e);
759 continue;
760 }
761
762 ret[i] = r;
763 }
764
765 if (errors.length) {
766 const first = errors[0];
767 first.errors = errors;
768 return [first];
769 }
770
771 return [undefined, ret];
772 };
773
774 return new Kind(name, type, validate);
775}
776
777/**
778 * Union.
779 *
780 * @param {Array} schema
781 * @param {Any} defaults
782 * @param {Object} options
783 */
784
785function union(schema, defaults, options) {
786 if (kindOf(schema) !== 'array') {
787 if (process.env.NODE_ENV !== 'production') {
788 throw new Error(`Union structs must be defined as an array, but you passed: ${schema}`);
789 } else {
790 throw new Error(`Invalid schema: ${schema}`);
791 }
792 }
793
794 const kinds = schema.map(s => any(s, undefined, options));
795 const name = 'union';
796 const type = kinds.map(k => k.type).join(' | ');
797 const validate = (value = resolveDefaults(defaults)) => {
798 let error;
799
800 for (const k of kinds) {
801 const [e, r] = k.validate(value);
802 if (!e) return [undefined, r];
803 error = e;
804 }
805
806 error.type = type;
807 return [error];
808 };
809
810 return new Kind(name, type, validate);
811}
812
813/**
814 * Intersection.
815 *
816 * @param {Array} schema
817 * @param {Any} defaults
818 * @param {Object} options
819 */
820
821function intersection(schema, defaults, options) {
822 if (kindOf(schema) !== 'array') {
823 if (process.env.NODE_ENV !== 'production') {
824 throw new Error(`Intersection structs must be defined as an array, but you passed: ${schema}`);
825 } else {
826 throw new Error(`Invalid schema: ${schema}`);
827 }
828 }
829
830 const types = schema.map(s => any(s, undefined, options));
831 const name = 'intersection';
832 const type = types.map(t => t.type).join(' & ');
833 const validate = (value = resolveDefaults(defaults)) => {
834 let v = value;
835
836 for (const t of types) {
837 const [e, r] = t.validate(v);
838
839 if (e) {
840 e.type = type;
841 return [e];
842 }
843
844 v = r;
845 }
846
847 return [undefined, v];
848 };
849
850 return new Kind(name, type, validate);
851}
852
853/**
854 * Kinds.
855 *
856 * @type {Object}
857 */
858
859const Kinds = {
860 any,
861 dict,
862 enum: en,
863 enums,
864 function: func,
865 instance,
866 interface: inter,
867 list,
868 literal,
869 object,
870 optional,
871 scalar,
872 tuple,
873 union,
874 intersection
875
876 /**
877 * Export.
878 *
879 * @type {Object}
880 */
881
882};
883
884/**
885 * The types that `kind-of` supports.
886 *
887 * @type {Array}
888 */
889
890const TYPES = ['arguments', 'array', 'boolean', 'buffer', 'date', 'error', 'float32array', 'float64array', 'function', 'generatorfunction', 'int16array', 'int32array', 'int8array', 'map', 'null', 'number', 'object', 'promise', 'regexp', 'set', 'string', 'symbol', 'uint16array', 'uint32array', 'uint8array', 'uint8clampedarray', 'undefined', 'weakmap', 'weakset'];
891
892/**
893 * The default types that Superstruct ships with.
894 *
895 * @type {Object}
896 */
897
898const Types = {
899 any: value => value !== undefined
900};
901
902TYPES.forEach(type => {
903 Types[type] = value => kindOf(value) === type;
904});
905
906var _extends = Object.assign || function (target) {
907 for (var i = 1; i < arguments.length; i++) {
908 var source = arguments[i];
909
910 for (var key in source) {
911 if (Object.prototype.hasOwnProperty.call(source, key)) {
912 target[key] = source[key];
913 }
914 }
915 }
916
917 return target;
918};
919
920/**
921 * Create a struct factory with a `config`.
922 *
923 * @param {Object} config
924 * @return {Function}
925 */
926
927function superstruct(config = {}) {
928 const types = _extends({}, Types, config.types || {});
929
930 /**
931 * Create a `kind` struct with `schema`, `defaults` and `options`.
932 *
933 * @param {Any} schema
934 * @param {Any} defaults
935 * @param {Object} options
936 * @return {Function}
937 */
938
939 function struct(schema, defaults$$1, options = {}) {
940 if (isStruct(schema)) {
941 schema = schema.schema;
942 }
943
944 const kind = Kinds.any(schema, defaults$$1, _extends({}, options, { types }));
945
946 function Struct(data) {
947 if (this instanceof Struct) {
948 if (process.env.NODE_ENV !== 'production') {
949 throw new Error('The `Struct` creation function should not be used with the `new` keyword.');
950 } else {
951 throw new Error('Invalid `new` keyword!');
952 }
953 }
954
955 return Struct.assert(data);
956 }
957
958 Object.defineProperty(Struct, IS_STRUCT, { value: true });
959 Object.defineProperty(Struct, KIND, { value: kind });
960
961 Struct.kind = kind.name;
962 Struct.type = kind.type;
963 Struct.schema = schema;
964 Struct.defaults = defaults$$1;
965 Struct.options = options;
966
967 Struct.assert = value => {
968 const [error, result] = kind.validate(value);
969 if (error) throw new StructError(error);
970 return result;
971 };
972
973 Struct.test = value => {
974 const [error] = kind.validate(value);
975 return !error;
976 };
977
978 Struct.validate = value => {
979 const [error, result] = kind.validate(value);
980 if (error) return [new StructError(error)];
981 return [undefined, result];
982 };
983
984 return Struct;
985 }
986
987 /**
988 * Mix in a factory for each specific kind of struct.
989 */
990
991 Object.keys(Kinds).forEach(name => {
992 const kind = Kinds[name];
993
994 struct[name] = (schema, defaults$$1, options) => {
995 const type = kind(schema, defaults$$1, _extends({}, options, { types }));
996 const s = struct(type, defaults$$1, options);
997 return s;
998 };
999 });
1000
1001 /**
1002 * Return the struct factory.
1003 */
1004
1005 return struct;
1006}
1007
1008/**
1009 * Create a convenience `struct` factory for the default types.
1010 *
1011 * @type {Function}
1012 */
1013
1014const struct = superstruct();
1015
1016export { struct, superstruct, isStruct, StructError };
1017//# sourceMappingURL=index.es.js.map