1 | import { identity } from './utilities';
|
2 | import { assert, isBoolean, isString, isObject, isFunction, isUndefined } from './assertions';
|
3 | import isPlainObject from 'lodash.isplainobject';
|
4 | const internal = {};
|
5 |
|
6 | internal.Property = module.exports = (property) => {
|
7 |
|
8 | assert(isObject(property), `'property' must be an object`);
|
9 |
|
10 | let {
|
11 | name,
|
12 | coerce = identity,
|
13 | defaultValue
|
14 | } = property;
|
15 |
|
16 |
|
17 | assert(isString(name), `Invalid property: 'name' must be a string`);
|
18 | assert(isFunction(coerce), `Invalid '${name}' property: 'coerce' must be a function`);
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 | if (!isUndefined(defaultValue) && coerce !== identity) {
|
32 |
|
33 | if (isUndefined(coerce(defaultValue))) {
|
34 | defaultValue = null;
|
35 | console.warn(`Invalid '${name}' property: 'coerce' called with 'defaultValue' has returned undefined`);
|
36 | }
|
37 | }
|
38 |
|
39 | return Object.freeze(Object.assign(property, {
|
40 | name,
|
41 | coerce,
|
42 | defaultValue
|
43 | }));
|
44 | };
|
45 |
|
46 | internal.Property.array = (options = {}) => Object.assign({
|
47 | coerce: value => Array.isArray(value) ? value : (!value ? null : [value]),
|
48 | defaultValue: [],
|
49 | }, options);
|
50 |
|
51 | internal.Property.object = (options = {}) => Object.assign({
|
52 | defaultValue: {},
|
53 | coerce: value => isUndefined(value) || !isObject(value) ? void 0 : value
|
54 | }, options);
|
55 |
|
56 |
|
57 | internal.Property.plain = (options = {}) => internal.Property.object(
|
58 | Object.assign({
|
59 | coerce: value => isUndefined(value) || !isPlainObject(value) ? void 0 : value
|
60 | }, options)
|
61 | );
|
62 |
|
63 | internal.Property.boolean = (options = {}) => Object.assign({
|
64 | coerce: Boolean,
|
65 | defaultValue: false
|
66 | }, options);
|
67 |
|