binhend 2.3.3 → 2.3.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "binhend",
3
- "version": "2.3.3",
3
+ "version": "2.3.5",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "author": "Nguyen Duc Binh",
@@ -5,9 +5,9 @@ const types = require('@binhend/types');
5
5
  * @typedef {Object} Options
6
6
  * @property {string=} message - Any custom error message
7
7
  * @property {string=} type - Expected type name of value, e.g. string, number, array, etc.
8
- * @property {string=} name - The variable/property name holding value
9
- * @property {boolean=} required - The variable/property name holding value
10
- * @property {*=} default - The variable/property name holding value
8
+ * @property {string=} name - The name of variable/property holding value
9
+ * @property {boolean=} required - The value must not be null or undefined
10
+ * @property {*=} default - The default value being used if null or undefined
11
11
  */
12
12
 
13
13
  /**
@@ -109,15 +109,160 @@ function Array(input, options = {}) {
109
109
  /**
110
110
  * Validate an input being an object (non-array)
111
111
  *
112
- * @param {*} input - Input value needs to be validated.
113
- * @param {Options} options - Additional options for validation.
114
- * @returns {Object} - The validated input
112
+ * @template {Record<string, any>} [T={}]
113
+ *
114
+ * @param {T=} input - Input value needs to be validated.
115
+ * @param {Options} options - Options for validation.
116
+ * @returns {T & Record<string, any>} - The validated input
115
117
  * @throws {HttpError} - If validation fails
116
118
  */
117
119
  function Object(input, options = {}) {
118
120
  return Validator(input, types.isObject, { ...options, type: 'object' });
119
121
  }
120
122
 
123
+ /**
124
+ * Return an object fragment from an object via a specific key
125
+ * only if the value is defined (accept null), and pass validation.
126
+ *
127
+ * @template {string} K
128
+ * @template V
129
+ * @param {K} key - A property name
130
+ * @param {*} object - Any target that may have properties (objects or primitives)
131
+ * @param {((value: any, options: Options) => V)} [validator] - An optional validation function
132
+ * @param {Options=} options - Options for validation.
133
+ * @returns {{ [P in K]?: V }} - An object fragment with a single key/value at most
134
+ * @throws {HttpError} - If validation fails
135
+ */
136
+ function PropIf(key, object, validator, options) {
137
+ var value = object != null ? object[key] : undefined;
138
+
139
+ if (validator instanceof Function) {
140
+ value = validator(value, { ...options, name: key });
141
+ }
142
+
143
+ if (object == null || !Object.prototype.hasOwnProperty.call(object, key)) {
144
+ return /** @type {{ [P in K]: V }} */ ({});
145
+ }
146
+
147
+ return /** @type {{ [P in K]: V }} */ ({ [key]: value });
148
+ }
149
+
150
+ /**
151
+ * Return an object fragment from an object via a specific key
152
+ * even if the value is undefined, but must pass validation.
153
+ *
154
+ * @template {string} K
155
+ * @template V
156
+ * @param {K} key - A property name
157
+ * @param {*} object - Any target that may have properties (objects or primitives)
158
+ * @param {((value: any, options: Options) => V)} [validator] - An optional validation function
159
+ * @param {Options=} options - Options for validation.
160
+ * @returns {{ [P in K]: V }} - An object fragment with a single key/value at most
161
+ * @throws {HttpError} - If validation fails
162
+ */
163
+ function Prop(key, object, validator, options) {
164
+ return /** @type {{ [P in K]: V }} */ ({ [key]: PropIf(key, object, validator, options)[key] });
165
+ }
166
+
167
+ /**
168
+ * Return an object fragment from a value with a specific key
169
+ * only if the value is defined (accept null), and pass validation.
170
+ *
171
+ * @template {string} K
172
+ * @template V
173
+ * @param {K} key - A property name
174
+ * @param {*} value - A value
175
+ * @param {((value: any, options: Options) => V)} [validator] - An optional validation function
176
+ * @param {Options=} options - Options for validation.
177
+ * @returns {{ [P in K]?: V }} - An object fragment with a single key/value at most
178
+ * @throws {HttpError} - If validation fails
179
+ */
180
+ function AssignIf(key, value, validator, options) {
181
+ return PropIf(key, { [key]: value }, validator, options);
182
+ }
183
+
184
+ /**
185
+ * Return an object fragment from a value with a specific key
186
+ * even if the value is undefined, but must pass validation.
187
+ *
188
+ * @template {string} K
189
+ * @template V
190
+ * @param {K} key - A property name
191
+ * @param {*} value - A value
192
+ * @param {((value: any, options: Options) => V)} [validator] - An optional validation function
193
+ * @param {Options=} options - Options for validation.
194
+ * @returns {{ [P in K]: V }} - An object fragment with a single key/value at most
195
+ * @throws {HttpError} - If validation fails
196
+ */
197
+ function Assign(key, value, validator, options) {
198
+ return /** @type {{ [P in K]: V }} */ ({ [key]: AssignIf(key, value, validator, options)[key] });
199
+ }
200
+
201
+ /**
202
+ * Return an object fragment with a specific key,
203
+ * only if the value is defined. (accept null, but not undefined)
204
+ *
205
+ * @template {string} K
206
+ * @template V
207
+ * @param {K} key - A property name
208
+ * @param {V | undefined} value - A value
209
+ * @returns {{ [P in K]?: V }} - An object fragment with a single key/value at most
210
+ */
211
+ function Value(key, value) {
212
+ if (value === undefined) {
213
+ return /** @type {{ [P in K]?: V }} */ ({});
214
+ }
215
+
216
+ return /** @type {{ [P in K]?: V }} */ ({ [key]: value });
217
+ }
218
+
219
+ /**
220
+ * Return a new plain object containing keys with defined values only. (accept null)
221
+ *
222
+ * @template {Record<string, any>} T
223
+ * @param {T=} object
224
+ * @returns {{ [K in keyof T]?: T[K] }}
225
+ */
226
+ function Optional(object) {
227
+ var key, output = {};
228
+
229
+ for (key in object) {
230
+ if (object[key] !== undefined) {
231
+ output[key] = object[key];
232
+ }
233
+ }
234
+
235
+ return output;
236
+ }
237
+
238
+ /**
239
+ * Return an object fragment with a specific key
240
+ * only if the key exists AND validation is passed.
241
+ *
242
+ * @template {string} K
243
+ * @template V
244
+ * @param {K} key - A property name
245
+ * @param {*} object - Any target that may have properties (objects or primitives)
246
+ * @param {((value: any, options: Options) => V)} [validator] - An optional validation function
247
+ * @param {Options=} options - Options for validation.
248
+ * @returns {{ [P in K]?: V }}
249
+ */
250
+ function Prop(key, object, validator, options) {
251
+ var value = object != null ? object[key] : undefined;
252
+
253
+ if (validator instanceof Function) {
254
+ value = validator(value, { ...options, name: key });
255
+ }
256
+
257
+ if (object == null || !Object.prototype.hasOwnProperty.call(object, key)) {
258
+ return /** @type {{ [P in K]?: V }} */ ({});
259
+ }
260
+
261
+ return /** @type {{ [P in K]?: V }} */ ({
262
+ [key]: value
263
+ });
264
+ }
265
+
121
266
  /**
122
267
  * Validate an input being a function
123
268
  *
@@ -273,6 +418,9 @@ module.exports = {
273
418
  Boolean,
274
419
  Array,
275
420
  Object,
421
+ PropIf, Prop,
422
+ AssignIf, Assign,
423
+ Value, Optional,
276
424
  Function,
277
425
  AsyncFunction,
278
426
  Date,