binhend 2.3.4 → 2.3.6

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.4",
3
+ "version": "2.3.6",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "author": "Nguyen Duc Binh",
@@ -110,17 +110,131 @@ function Array(input, options = {}) {
110
110
  * Validate an input being an object (non-array)
111
111
  *
112
112
  * @template {Record<string, any>} [T={}]
113
- * @template {Record<string, any>} [O={}]
114
113
  *
115
114
  * @param {T=} input - Input value needs to be validated.
116
- * @param {Options & { optional?: O }} options - Options for validation with extra option { optional } for listing optional properties.
117
- * @returns {T & O & Record<string, any>} - The validated input
115
+ * @param {Options} options - Options for validation.
116
+ * @returns {T & Record<string, any>} - The validated input
118
117
  * @throws {HttpError} - If validation fails
119
118
  */
120
119
  function Object(input, options = {}) {
121
120
  return Validator(input, types.isObject, { ...options, type: 'object' });
122
121
  }
123
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
+
124
238
  /**
125
239
  * Return an object fragment with a specific key
126
240
  * only if the key exists AND validation is passed.
@@ -173,7 +287,7 @@ function AsyncFunction(input, options = {}) {
173
287
  return Validator(input, (input) => input instanceof AsyncFunctionConstructor, { ...options, type: 'async function' });
174
288
  }
175
289
 
176
- const AsyncFunctionConstructor = global.Object.getPrototypeOf(async function() {}).constructor;
290
+ const AsyncFunctionConstructor = global.Object.getPrototypeOf(async function () { }).constructor;
177
291
 
178
292
  /**
179
293
  * Validate an input being a date
@@ -200,30 +314,49 @@ function DateLike(input, options = {}) {
200
314
  }
201
315
 
202
316
  /**
203
- * Validate an input being one of the specified enum values
317
+ * Validate an input being one of allowed values
204
318
  *
319
+ * @template {string | number | boolean | symbol | bigint} T
205
320
  * @param {*} input - Input value needs to be validated.
206
- * @param {Array|Object} enumValues - Array of allowed values or object whose keys are allowed values
207
- * @param {Options} options - Additional options for validation.
208
- * @returns {*} - The validated input
209
- * @throws {HttpError} - If validation fails
321
+ * @param {readonly T[]} enumValues - Array of allowed values.
322
+ * @param {Options} options - Options for validation.
323
+ * @returns {T} - The validated input.
324
+ * @throws {HttpError} - If validation fails.
210
325
  */
211
326
  function Enum(input, enumValues, options = {}) {
212
- var validArray = types.isArray(enumValues),
213
- validObject = types.isObject(enumValues);
214
-
215
- if (!(validArray || validObject)) {
216
- throwError('Enum validator requires an array or object of allowed values');
327
+ if (!types.isArray(enumValues)) {
328
+ throwError('Enum validator requires an array of allowed values');
217
329
  }
218
330
 
219
- var method = validArray ? 'includes' : 'hasOwnProperty';
220
-
221
331
  return Validator(
222
- input, (input) => enumValues[method](input),
223
- { ...options, message: options.message || `${input} is not defined in enum` }
332
+ input, (input) => enumValues.includes(input),
333
+ { ...options, message: options.message || `Value {${input}} is not defined in enum` }
224
334
  );
225
335
  }
226
336
 
337
+ /**
338
+ * Return all keys of an object.
339
+ * Returns an array of names of the enumerable properties and methods of an object.
340
+ *
341
+ * @template {{ [key: PropertyKey]: any }} T
342
+ * @param {T} object - An object with keys and values
343
+ * @returns {(keyof T)[]} - List of all keys
344
+ */
345
+ function Keys(object) {
346
+ return global.Object.keys(object);
347
+ }
348
+
349
+ /**
350
+ * Returns an array of values owned by the enumerable properties of an object.
351
+ *
352
+ * @template {{ [key: PropertyKey]: any }} T
353
+ * @param {T} object
354
+ * @returns {T[keyof T][]}
355
+ */
356
+ function Values(object) {
357
+ return global.Object.values(object);
358
+ }
359
+
227
360
  /**
228
361
  * Validate an input being defined (not undefined)
229
362
  *
@@ -304,12 +437,14 @@ module.exports = {
304
437
  Boolean,
305
438
  Array,
306
439
  Object,
307
- Prop,
440
+ PropIf, Prop,
441
+ AssignIf, Assign,
442
+ Value, Optional,
308
443
  Function,
309
444
  AsyncFunction,
310
445
  Date,
311
446
  DateLike,
312
- Enum,
447
+ Enum, Keys, Values,
313
448
  Defined,
314
449
  NotNull,
315
450
  NotNullish,