binhend 2.1.15 → 2.1.17

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/demo.js CHANGED
@@ -1,10 +1,45 @@
1
1
 
2
- const { HttpCodes, ConfigLoader, WebBuilder } = require('./index');
2
+ const { HttpCodes, ConfigLoader, WebBuilder, HttpError, validation } = require('./index');
3
3
 
4
- HttpCodes.ACCEPTED;
4
+ // HttpCodes.ACCEPTED;
5
5
 
6
- new ConfigLoader({}).cli;
6
+ // new ConfigLoader({}).cli;
7
7
 
8
8
  // const builder = new WebBuilder('src', { output: 'build/bundle' });
9
9
 
10
- // builder.bundle();
10
+ // builder.bundle();
11
+
12
+ // throw new HttpError(HttpCodes.BAD_REQUEST, '[BINHEND][VALIDATION] Must be a string.');
13
+ // throw new HttpError(HttpCodes.BAD_REQUEST, '[BINHEND][VALIDATION] MUST BE A STRING.');
14
+ // var typeName = `array`;
15
+ // throw new HttpError(HttpCodes.BAD_REQUEST, `Invalid input: value not passed custom validator.`);
16
+ // throw new HttpError(HttpCodes.BAD_REQUEST, `Invalid input: unknown reason.`);
17
+ // throw new HttpError(HttpCodes.BAD_REQUEST, `Invalid input: value must be type of \`${typeName}\`.`);
18
+ // throw new HttpError(HttpCodes.BAD_REQUEST, `Invalid input: Field "title" must be type of \`${typeName}\`.`);
19
+
20
+ // validation.String('a', {});
21
+
22
+ validation.String('a');
23
+ // validation.String(null);
24
+ // validation.String(1, { name: 'myNum', message: 'Require string for this field' });
25
+
26
+ // validation.Validator('this is me', (input) => {
27
+ // if (!input.startsWith('It')) validation.throwError(`"title" must start with 'it' or 'It'`)
28
+ // return input.length < 5;
29
+ // }, { message: '"title" must not exceed max length of 5' })
30
+
31
+
32
+ validation.NotNull(1);
33
+ // validation.NotNullish(null, { required: true, default: null });
34
+ // validation.String(null, { required: true, default: 1 });
35
+
36
+ validation.DateLike('2022-10-29a', { default: new Date().getTime() });
37
+ validation.Date(new Date());
38
+
39
+ function Abc(a) {
40
+ this.a = a;
41
+ }
42
+
43
+ console.log(JSON.stringify(new Abc(123)));
44
+
45
+ validation.Object(new Abc(123));
package/index.js CHANGED
@@ -22,8 +22,9 @@ const cors = require('./src/middleware/cors');
22
22
 
23
23
  const createCSD = require('./src/csd');
24
24
  const security = require('./src/security');
25
- const typeOf = require('./src/utils/typeOf');
26
- const Bromise = require('./src/utils/bromise');
25
+ const types = require('./src/utils/types');
26
+ const validation = require('./src/utils/validation');
27
+ const Bromise = require('./src/utils/Bromise.js');
27
28
 
28
29
  /** CLIENT - Frontend */
29
30
  const { WebBuilder } = require('./src/web');
@@ -44,7 +45,8 @@ module.exports = {
44
45
  cors,
45
46
  createCSD,
46
47
  security,
47
- typeOf,
48
+ types,
49
+ validation,
48
50
  Bromise,
49
51
  WebBuilder,
50
52
  binh
package/jsconfig.json CHANGED
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "compilerOptions": {
3
+ "forceConsistentCasingInFileNames": true,
3
4
  "moduleResolution": "node",
4
5
  "target": "ES2017",
5
6
  "checkJs": true,
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "binhend",
3
- "version": "2.1.15",
3
+ "version": "2.1.17",
4
4
  "description": "",
5
5
  "main": "index.js",
6
+ "types": "src/types/index.d.ts",
6
7
  "author": "Nguyen Duc Binh",
7
8
  "license": "UNLICENSED",
8
9
  "bin": {
package/src/api/Router.js CHANGED
@@ -1,6 +1,6 @@
1
1
 
2
2
  const { ServerResponse } = require('http');
3
- const { isFunction } = require('../utils/typeOf');
3
+ const { isFunction } = require('../utils/types');
4
4
  const responseErrorByDefault = require('./responseErrorByDefault');
5
5
  const trycatch = require('./trycatch');
6
6
  const express = require('express');
package/src/api/routes.js CHANGED
@@ -1,6 +1,6 @@
1
1
  const { readdir, stat } = require('fs/promises');
2
2
  const { join, parse, resolve } = require('path');
3
- const { isUndefined } = require('../utils/typeOf');
3
+ const { isUndefined } = require('../utils/types');
4
4
  const { server } = require('../server');
5
5
  const cors = require('../middleware/cors');
6
6
  const express = require('express');
@@ -1,6 +1,6 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
- const { isEmptyArray, isArray, isObject } = require('./utils/typeOf');
3
+ const { isEmptyArray, isArray, isObject } = require('./utils/types');
4
4
 
5
5
  // @ts-ignore
6
6
  function ConfigLoader(configObject, { module } = {}) {
@@ -1,5 +1,5 @@
1
1
 
2
- const { isEmptyObject, isString } = require('../utils/typeOf');
2
+ const { isEmptyObject, isString } = require('../utils/types');
3
3
  const trycatch = require('../api/trycatch');
4
4
  const HttpError = require('../api/HttpError');
5
5
 
@@ -1,5 +1,5 @@
1
1
 
2
- const { isArray, mustArray, mustNumber } = require('../utils/typeOf');
2
+ const { isArray, mustArray, mustNumber } = require('../utils/types');
3
3
 
4
4
  const defaultOptions = {
5
5
  origins: [],
@@ -1,4 +1,4 @@
1
- const { isString } = require('../utils/typeOf');
1
+ const { isString } = require('../utils/types');
2
2
 
3
3
  module.exports = (request, response, next) => {
4
4
  var authString = request.headers['authorization'];
@@ -0,0 +1,10 @@
1
+
2
+ /**
3
+ * @typedef {Object<string, any>} ObjectType
4
+ */
5
+
6
+ /**
7
+ * @typedef {(Date|string|number)} DateType
8
+ */
9
+
10
+ export {};
@@ -0,0 +1,2 @@
1
+
2
+ export * from './common.d.ts';
@@ -7,6 +7,10 @@ function isObject(input) {
7
7
  return typeOf(input) === 'Object';
8
8
  }
9
9
 
10
+ function mustObject(input, defaultValue = {}) {
11
+ return isObject(input) ? input : isObject(defaultValue) ? defaultValue : {};
12
+ }
13
+
10
14
  function isEmptyObject(input) {
11
15
  return isObject(input) && Object.keys(input).length === 0;
12
16
  }
@@ -17,8 +21,8 @@ function isEmptyArray(input) {
17
21
  return isArray(input) && input.length === 0;
18
22
  }
19
23
 
20
- function mustArray(input, defaultOutput = []) {
21
- return isArray(input) ? input : isArray(defaultOutput) ? defaultOutput : [defaultOutput];
24
+ function mustArray(input, defaultValue = []) {
25
+ return isArray(input) ? input : isArray(defaultValue) ? defaultValue : [];
22
26
  }
23
27
 
24
28
  function isFunction(input) {
@@ -45,6 +49,15 @@ function mustNumber(input, defaultValue) {
45
49
  return isNumber(input) ? input : isNumber(defaultValue) ? defaultValue : 0;
46
50
  }
47
51
 
52
+ function isDate(input) {
53
+ return typeOf(input) === 'Date' && !isNaN(input.getTime());
54
+ }
55
+
56
+ function isDateLike(value) {
57
+ const date = new Date(value);
58
+ return !isNaN(date.getTime());
59
+ }
60
+
48
61
  function isBigInt(input) {
49
62
  return typeof input === 'bigint';
50
63
  }
@@ -69,10 +82,15 @@ function isNullOrUndefined(input) {
69
82
  return isNull(input) || isUndefined(input);
70
83
  }
71
84
 
85
+ function isNullish(input) {
86
+ return input == null;
87
+ }
88
+
72
89
  module.exports = {
73
90
  typeOf,
74
91
  isObject,
75
92
  isEmptyObject,
93
+ mustObject,
76
94
  isArray,
77
95
  isEmptyArray,
78
96
  mustArray,
@@ -80,6 +98,7 @@ module.exports = {
80
98
  isNull,
81
99
  isUndefined,
82
100
  isNullOrUndefined,
101
+ isNullish,
83
102
  isBoolean,
84
103
  isNumber,
85
104
  mustNumber,
@@ -87,5 +106,7 @@ module.exports = {
87
106
  isEmptyString,
88
107
  mustString,
89
108
  isSymbol,
90
- isBigInt
109
+ isBigInt,
110
+ isDate,
111
+ isDateLike
91
112
  };
@@ -0,0 +1,272 @@
1
+ const HttpError = require('../api/HttpError');
2
+ const HttpCodes = require('../api/HttpCodes');
3
+ const types = require('./types');
4
+
5
+ /**
6
+ * @typedef {Object} Options
7
+ * @property {string=} message - Any custom error message
8
+ * @property {string=} type - Expected type name of value, e.g. string, number, array, etc.
9
+ * @property {string=} name - The variable/property name holding value
10
+ * @property {boolean=} required - The variable/property name holding value
11
+ * @property {*=} default - The variable/property name holding value
12
+ */
13
+
14
+ /**
15
+ * Throw error by default for invalid input.
16
+ * A `HttpError` is thrown for `router` sending response to client.
17
+ *
18
+ * @param {string=} message - Optional error message.
19
+ * @throws {HttpError}
20
+ */
21
+ function throwError(message) {
22
+ message = types.isString(message) ? message : `unknown reason`;
23
+ throw new HttpError(HttpCodes.BAD_REQUEST, `Invalid input: ${message}.`);
24
+ }
25
+
26
+ /**
27
+ * Throw a type error with formatted message.
28
+ *
29
+ * @param {string=} typeName - The expected type name
30
+ * @param {string=} variableName - The name of the variable/property
31
+ * @throws {HttpError}
32
+ */
33
+ function throwTypeError(typeName, variableName) {
34
+ typeName = types.isString(typeName) ? typeName : '?';
35
+ variableName = types.isString(variableName) ? `"${variableName}"` : `value`;
36
+ throwError(`${variableName} must be type of \`${typeName}\``);
37
+ }
38
+
39
+ /**
40
+ * Throw a validator error with formatted message.
41
+ *
42
+ * @param {string=} variableName - The name of the variable/property
43
+ * @throws {HttpError}
44
+ */
45
+ function throwValidatorError(variableName) {
46
+ variableName = types.isString(variableName) ? `"${variableName}"` : `value`;
47
+ throwError(`${variableName} not passed custom validator`);
48
+ }
49
+
50
+ /**
51
+ * Validate an input being string
52
+ *
53
+ * @param {*} input - Input value needs to be validated.
54
+ * @param {Options} options - Additional options for validation.
55
+ * @returns {string} - The validated input
56
+ * @throws {HttpError} - If validation fails
57
+ */
58
+ function String(input, options = {}) {
59
+ return Validator(input, types.isString, { ...options, type: 'string' });
60
+ }
61
+
62
+ /**
63
+ * Validate an input being number
64
+ *
65
+ * @param {*} input - Input value needs to be validated.
66
+ * @param {Options} options - Additional options for validation.
67
+ * @returns {number} - The validated input
68
+ * @throws {HttpError} - If validation fails
69
+ */
70
+ function Number(input, options = {}) {
71
+ return Validator(input, types.isNumber, { ...options, type: 'number' });
72
+ }
73
+
74
+ /**
75
+ * Validate an input being an integer
76
+ *
77
+ * @param {*} input - Input value needs to be validated.
78
+ * @param {Options} options - Additional options for validation.
79
+ * @returns {number} - The validated input
80
+ * @throws {HttpError} - If validation fails
81
+ */
82
+ function Integer(input, options = {}) {
83
+ return Validator(input, global.Number.isInteger, { ...options, type: 'integer' });
84
+ }
85
+
86
+ /**
87
+ * Validate an input being boolean
88
+ *
89
+ * @param {*} input - Input value needs to be validated.
90
+ * @param {Options} options - Additional options for validation.
91
+ * @returns {boolean} - The validated input
92
+ * @throws {HttpError} - If validation fails
93
+ */
94
+ function Boolean(input, options = {}) {
95
+ return Validator(input, types.isBoolean, { ...options, type: 'boolean' });
96
+ }
97
+
98
+ /**
99
+ * Validate an input being an array
100
+ *
101
+ * @param {*} input - Input value needs to be validated.
102
+ * @param {Options} options - Additional options for validation.
103
+ * @returns {Array} - The validated input
104
+ * @throws {HttpError} - If validation fails
105
+ */
106
+ function Array(input, options = {}) {
107
+ return Validator(input, types.isArray, { ...options, type: 'array' });
108
+ }
109
+
110
+ /**
111
+ * Validate an input being an object (non-array)
112
+ *
113
+ * @param {*} input - Input value needs to be validated.
114
+ * @param {Options} options - Additional options for validation.
115
+ * @returns {Object} - The validated input
116
+ * @throws {HttpError} - If validation fails
117
+ */
118
+ function Object(input, options = {}) {
119
+ return Validator(input, types.isObject, { ...options, type: 'object' });
120
+ }
121
+
122
+ /**
123
+ * Validate an input being a function
124
+ *
125
+ * @param {*} input - Input value needs to be validated.
126
+ * @param {Options} options - Additional options for validation.
127
+ * @returns {Function} - The validated input
128
+ * @throws {HttpError} - If validation fails
129
+ */
130
+ function Function(input, options = {}) {
131
+ return Validator(input, types.isFunction, { ...options, type: 'function' });
132
+ }
133
+
134
+ /**
135
+ * Validate an input being a date
136
+ *
137
+ * @param {*} input - Input value needs to be validated.
138
+ * @param {Options} options - Additional options for validation.
139
+ * @returns {Date} - The validated input
140
+ * @throws {HttpError} - If validation fails
141
+ */
142
+ function Date(input, options = {}) {
143
+ return Validator(input, types.isDate, { ...options, type: 'date' });
144
+ }
145
+
146
+ /**
147
+ * Validate an input being a date format
148
+ *
149
+ * @param {*} input - Input value needs to be validated.
150
+ * @param {Options} options - Additional options for validation.
151
+ * @returns {Date|string|number} - The validated input
152
+ * @throws {HttpError} - If validation fails
153
+ */
154
+ function DateLike(input, options = {}) {
155
+ return Validator(input, types.isDateLike, { ...options, type: 'date-like' });
156
+ }
157
+
158
+ /**
159
+ * Validate an input being one of the specified enum values
160
+ *
161
+ * @param {*} input - Input value needs to be validated.
162
+ * @param {Array|Object} enumValues - Array of allowed values or object whose keys are allowed values
163
+ * @param {Options} options - Additional options for validation.
164
+ * @returns {*} - The validated input
165
+ * @throws {HttpError} - If validation fails
166
+ */
167
+ function Enum(input, enumValues, options = {}) {
168
+ var validArray = types.isArray(enumValues),
169
+ validObject = types.isObject(enumValues);
170
+
171
+ if (!(validArray || validObject)) {
172
+ throwError('Enum validator requires an array or object of allowed values');
173
+ }
174
+
175
+ var method = validArray ? 'includes' : 'hasOwnProperty';
176
+
177
+ return Validator(
178
+ input, (input) => enumValues[method](input),
179
+ { ...options, message: options.message || `${input} is not defined in enum` }
180
+ );
181
+ }
182
+
183
+ /**
184
+ * Validate an input being defined (not undefined)
185
+ *
186
+ * @param {*} input - Input value needs to be validated.
187
+ * @param {Options} options - Additional options for validation.
188
+ * @returns {*} - The validated input
189
+ * @throws {HttpError} - If validation fails
190
+ */
191
+ function Defined(input, options = {}) {
192
+ return Validator(input, (input) => !types.isUndefined(input), { ...options, type: 'defined' });
193
+ }
194
+
195
+ /**
196
+ * Validate an input not being null (but accept undefined)
197
+ *
198
+ * @param {*} input - Input value needs to be validated.
199
+ * @param {Options} options - Additional options for validation.
200
+ * @returns {*} - The validated input
201
+ * @throws {HttpError} - If validation fails
202
+ */
203
+ function NotNull(input, options = {}) {
204
+ return Validator(input, (input) => !types.isNull(input), { ...options, type: 'not null', required: true });
205
+ }
206
+
207
+ /**
208
+ * Validate an input not being null or undefined
209
+ *
210
+ * @param {*} input - Input value needs to be validated.
211
+ * @param {Options} options - Additional options for validation.
212
+ * @returns {*} - The validated input
213
+ * @throws {HttpError} - If validation fails
214
+ */
215
+ function NotNullish(input, options = {}) {
216
+ return Validator(input, (input) => !types.isNullish(input), { ...options, type: 'not nullish', required: true });
217
+ }
218
+
219
+ /**
220
+ * Generic validator that accepts a validation function
221
+ *
222
+ * @param {*} input - Input value needs to be validated.
223
+ * @param {Function} validate - Validation function that returns boolean
224
+ * @param {Options} options - Additional options for validation.
225
+ * @returns {*} - The validated input
226
+ * @throws {HttpError} - If validation fails
227
+ */
228
+ function Validator(input, validate, options = {}) {
229
+ if (validate(input)) {
230
+ return input;
231
+ }
232
+
233
+ // use default value (options.default - must also be valid) if has, when input is invalid
234
+ if (options.hasOwnProperty('default') && validate(options.default)) {
235
+ return options.default;
236
+ }
237
+
238
+ // allow null or undefined by default, set `options.required=true` for not allowing
239
+ if (!options.required && types.isNullish(input)) {
240
+ return input;
241
+ }
242
+
243
+ var { message, type, name } = options;
244
+
245
+ if (message) {
246
+ throwError(message);
247
+ }
248
+ else if (type) {
249
+ throwTypeError(type, name);
250
+ }
251
+ else {
252
+ throwValidatorError(name)
253
+ }
254
+ }
255
+
256
+ module.exports = {
257
+ String,
258
+ Number,
259
+ Integer,
260
+ Boolean,
261
+ Array,
262
+ Object,
263
+ Function,
264
+ Date,
265
+ DateLike,
266
+ Enum,
267
+ Defined,
268
+ NotNull,
269
+ NotNullish,
270
+ Validator,
271
+ throwError
272
+ };
@@ -4,7 +4,7 @@ const path = require('path');
4
4
  const fs = require('fs');
5
5
  const UglifyCSS = require('uglifycss');
6
6
  const Component = require('./component');
7
- const { isString } = require('../utils/typeOf');
7
+ const { isString } = require('../utils/types');
8
8
 
9
9
  const binh = {};
10
10
 
package/src/web/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // @ts-nocheck
2
2
 
3
3
  const path = require('path');
4
- const { isEmptyString, isString, mustString } = require('../utils/typeOf');
4
+ const { isEmptyString, isString, mustString } = require('../utils/types');
5
5
  const ComponentFormat = require('./component.format');
6
6
  const ComponentBuild = require('./component.build');
7
7
  const Component = require('./component');
File without changes