-
Notifications
You must be signed in to change notification settings - Fork 3
/
index.js
86 lines (67 loc) · 1.83 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
'use strict';
const { hasOneElement } = require('r-assign/lib/internal/array-checks');
/**
* @template [T = any]
* @typedef {import('r-assign').TransformSchema<T>} TransformSchema
*/
/**
* @template {TransformSchema} S
* @typedef {import('r-assign').InferType<S>} InferType
*/
const { assign, entries } = Object;
const invalidSchema = 'Invalid schema argument type, object expected';
/**
* Extract one source object or merge an array of source objects
* @template {Record<string, any>} S
* @param {S[]} sources
* @returns {S}
*/
const getSource = (sources) => {
// Check for one source object
if (
hasOneElement(sources) &&
typeof sources[0] === 'object' &&
sources[0] !== null
) {
return sources[0];
}
return assign({}, ...sources);
};
/**
* Returns message for invalid schema property error
* @param {string} key
* @returns {string}
*/
const invalidSchemaProperty = (key) => {
return `Invalid property type, "${key}" property expected to be a function`;
};
/**
* Assign object properties and transform result based on the provided schema
* @template {TransformSchema<any>} S
* @param {S} schema
* @param {Record<string, any>[]} sources
* @returns {InferType<S>}
*/
const rAssign = (schema, ...sources) => {
// Check for valid schema provided
if (typeof schema !== 'object' || schema === null) {
throw TypeError(invalidSchema);
}
const source = getSource(sources);
/** @type {any} */
const result = {};
// Populate result properties
entries(schema).forEach(([key, transform]) => {
// Check for valid schema properties
if (typeof transform !== 'function') {
throw TypeError(invalidSchemaProperty(key));
}
const value = transform(source[key], key, source);
// Skip values that are undefined
if (value !== undefined) {
result[key] = value;
}
});
return result;
};
module.exports = rAssign;