@awesomeness-js/utils 1.0.19 → 1.0.21
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/build/build.js +7 -0
- package/index.js +35 -0
- package/package.json +13 -10
- package/schemas/schema1.js +121 -0
- package/schemas/schema2.js +121 -0
- package/schemas.js +15 -0
- package/src/clean/array.js +2 -0
- package/src/clean/boolean.js +22 -0
- package/src/clean/integer.js +74 -0
- package/src/clean/number.js +93 -0
- package/src/clean/object.js +3 -0
- package/src/clean/string.js +60 -0
- package/src/clean/timestamp.js +52 -0
- package/src/clean/uuid.js +33 -0
- package/src/combineFiles.js +10 -1
- package/src/decrypt.js +5 -3
- package/src/each.js +10 -0
- package/src/encrypt.js +5 -2
- package/src/setLocalEnvs.js +9 -4
- package/src/thingType.js +35 -0
- package/src/utils/clean.js +183 -0
- package/src/validateSchema.js +86 -0
- package/test/js/abc.test.js +6 -0
- package/test/secret.test.js +7 -1
- package/tests/clean/array.test.js +154 -0
- package/tests/clean/boolean.test.js +27 -0
- package/tests/clean/integer.test.js +39 -0
- package/tests/clean/number.test.js +49 -0
- package/tests/clean/object.test.js +172 -0
- package/tests/clean/string.test.js +44 -0
- package/tests/clean/timestamp.test.js +13 -0
- package/tests/clean/uuid.test.js +14 -0
- package/tests/combineFiles.test.js +24 -0
- package/tests/convertBytes.test.js +9 -0
- package/tests/env.test.js +17 -0
- package/tests/example.test.js +6 -0
- package/tests/fileList.test.js +21 -0
- package/tests/hash-and-encrypt.test.js +26 -0
- package/tests/md5.test.js +7 -0
- package/tests/uuid.test.js +15 -0
- package/tests/validateSchema.test.js +30 -0
- package/tsconfig.json +2 -1
- package/types/clean/array.d.ts +1 -0
- package/types/clean/boolean.d.ts +3 -0
- package/types/clean/integer.d.ts +6 -0
- package/types/clean/number.d.ts +8 -0
- package/types/clean/object.d.ts +1 -0
- package/types/clean/string.d.ts +7 -0
- package/types/clean/thing.d.ts +2 -0
- package/types/clean/timestamp.d.ts +5 -0
- package/types/clean/uuid.d.ts +3 -0
- package/types/each.d.ts +10 -1
- package/types/hashPassword.d.ts +1 -1
- package/types/index.d.ts +35 -0
- package/types/thingType.d.ts +2 -0
- package/types/utils/clean.d.ts +2 -0
- package/types/validatePassword.d.ts +1 -1
- package/types/validateSchema.d.ts +2 -0
- package/vitest.config.js +16 -0
- package/test.js +0 -58
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export default function cleanTimestamp( isoDateTimeString , {
|
|
2
|
+
required = false,
|
|
3
|
+
maxDaysInFuture = false,
|
|
4
|
+
maxDaysInFPast = false,
|
|
5
|
+
} = {}){
|
|
6
|
+
|
|
7
|
+
try {
|
|
8
|
+
|
|
9
|
+
if(typeof isoDateTimeString !== 'string') {
|
|
10
|
+
throw {
|
|
11
|
+
message: 'Input must be a string',
|
|
12
|
+
isoDateTimeString
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const date = new Date(isoDateTimeString);
|
|
17
|
+
|
|
18
|
+
if(isNaN(date.getTime())) {
|
|
19
|
+
throw {
|
|
20
|
+
message: 'Invalid date string',
|
|
21
|
+
isoDateTimeString
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const now = new Date();
|
|
26
|
+
|
|
27
|
+
if(maxDaysInFuture !== false && (date - now) > maxDaysInFuture * 24 * 60 * 60 * 1000) {
|
|
28
|
+
throw {
|
|
29
|
+
message: `Date is more than ${maxDaysInFuture} days in the future`,
|
|
30
|
+
isoDateTimeString
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if(maxDaysInFPast !== false && (now - date) > maxDaysInFPast * 24 * 60 * 60 * 1000) {
|
|
35
|
+
throw {
|
|
36
|
+
message: `Date is more than ${maxDaysInFPast} days in the past`,
|
|
37
|
+
value: isoDateTimeString
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return date.toISOString();
|
|
42
|
+
|
|
43
|
+
} catch (e) {
|
|
44
|
+
|
|
45
|
+
if(required) { throw e; } else { return null; }
|
|
46
|
+
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
}
|
|
52
|
+
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import isUUID from "../isUUID.js";
|
|
2
|
+
export default function cleanUUID(uuid,{
|
|
3
|
+
required = false,
|
|
4
|
+
} = {}){
|
|
5
|
+
|
|
6
|
+
try {
|
|
7
|
+
|
|
8
|
+
if(typeof uuid !== 'string'){
|
|
9
|
+
throw {
|
|
10
|
+
message: 'Input must be a string',
|
|
11
|
+
uuid
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if(!isUUID(uuid)){
|
|
16
|
+
throw {
|
|
17
|
+
message: 'Invalid UUID format',
|
|
18
|
+
uuid
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return uuid;
|
|
23
|
+
|
|
24
|
+
} catch (e) {
|
|
25
|
+
|
|
26
|
+
if(required) { throw e; } else { return null; }
|
|
27
|
+
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
}
|
|
33
|
+
|
package/src/combineFiles.js
CHANGED
|
@@ -20,7 +20,10 @@ function combineFiles(dir, fileType, {
|
|
|
20
20
|
|
|
21
21
|
if(isDir){
|
|
22
22
|
|
|
23
|
-
returnString += combineFiles(`${dir}/${stuff}`, fileType
|
|
23
|
+
returnString += combineFiles(`${dir}/${stuff}`, fileType, {
|
|
24
|
+
minify,
|
|
25
|
+
moduleToBrowser,
|
|
26
|
+
});
|
|
24
27
|
|
|
25
28
|
} else {
|
|
26
29
|
|
|
@@ -30,6 +33,7 @@ function combineFiles(dir, fileType, {
|
|
|
30
33
|
let file = stuff.split('.');
|
|
31
34
|
let ext = file[file.length - 1];
|
|
32
35
|
|
|
36
|
+
|
|
33
37
|
if(ext === fileType){
|
|
34
38
|
|
|
35
39
|
let thisData = readFileSync(`${dir}/${stuff}`, 'utf8');
|
|
@@ -39,6 +43,11 @@ function combineFiles(dir, fileType, {
|
|
|
39
43
|
// can this file be converted to browser?
|
|
40
44
|
let browserFriendly = thisData.startsWith('export default ');
|
|
41
45
|
|
|
46
|
+
if(browserFriendly){
|
|
47
|
+
browserFriendly = thisData.includes('import') === false; // no imports allowed
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
|
|
42
51
|
if(browserFriendly){
|
|
43
52
|
|
|
44
53
|
// strip properly formatted file
|
package/src/decrypt.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { createDecipheriv } from 'crypto';
|
|
2
2
|
|
|
3
|
-
export default function decrypt(encryptedData, key = process.env.AWESOMENESS_ENCRYPTION_KEY
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
export default function decrypt(encryptedData, key = process.env.AWESOMENESS_ENCRYPTION_KEY) {
|
|
4
|
+
|
|
5
|
+
if(!key){
|
|
6
|
+
throw new Error('Encryption key is not set. Please set the AWESOMENESS_ENCRYPTION_KEY environment variable.');
|
|
7
|
+
}
|
|
6
8
|
|
|
7
9
|
const { iv, authTag, cipherText } = encryptedData;
|
|
8
10
|
|
package/src/each.js
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* Iterates over elements of an array or properties of an object, invoking a callback for each element/property.
|
|
4
|
+
* The iteration stops if the callback returns `false`.
|
|
5
|
+
*
|
|
6
|
+
* @example each({ a: 1, b: 2 }, (value, key) => { console.log(value, key); });
|
|
7
|
+
* @param {Object|Array} objectOrArray - The object or array to iterate over.
|
|
8
|
+
* @param {Function} callback - The function to invoke per iteration. It is invoked with two arguments: (value, key/index).
|
|
9
|
+
* @returns {void}
|
|
10
|
+
*/
|
|
1
11
|
export default function each(objectOrArray, callback) {
|
|
2
12
|
|
|
3
13
|
if(Array.isArray(objectOrArray)){
|
package/src/encrypt.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { randomBytes, createCipheriv } from 'crypto';
|
|
2
2
|
|
|
3
|
+
|
|
3
4
|
// Encrypt plaintext using AES-256-GCM
|
|
4
|
-
export default function encrypt(plainText, key = process.env.AWESOMENESS_ENCRYPTION_KEY
|
|
5
|
+
export default function encrypt(plainText, key = process.env.AWESOMENESS_ENCRYPTION_KEY) {
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
if(!key){
|
|
8
|
+
throw new Error('Encryption key is not set. Please set the AWESOMENESS_ENCRYPTION_KEY environment variable.');
|
|
9
|
+
}
|
|
7
10
|
|
|
8
11
|
// GCM typically uses a 12- or 16-byte IV/nonce
|
|
9
12
|
const iv = randomBytes(12);
|
package/src/setLocalEnvs.js
CHANGED
|
@@ -12,7 +12,14 @@ export default async (localSecretsPath = './secrets/local.env') => {
|
|
|
12
12
|
if(line[0] === '#'){ continue; }
|
|
13
13
|
|
|
14
14
|
let parts = line.split('=');
|
|
15
|
+
|
|
15
16
|
if(parts.length === 2){
|
|
17
|
+
|
|
18
|
+
// remove \r
|
|
19
|
+
if(parts[1][parts[1].length - 1] === '\r'){
|
|
20
|
+
parts[1] = parts[1].substring(0, parts[1].length - 1);
|
|
21
|
+
}
|
|
22
|
+
|
|
16
23
|
// remove outside single quotes
|
|
17
24
|
if(
|
|
18
25
|
parts[1][0] === "'"
|
|
@@ -21,13 +28,11 @@ export default async (localSecretsPath = './secrets/local.env') => {
|
|
|
21
28
|
parts[1] = parts[1].substring(1, parts[1].length - 1);
|
|
22
29
|
}
|
|
23
30
|
|
|
24
|
-
|
|
25
|
-
if(parts[1][parts[1].length - 1] === '\r'){
|
|
26
|
-
parts[1] = parts[1].substring(0, parts[1].length - 1);
|
|
27
|
-
}
|
|
31
|
+
|
|
28
32
|
|
|
29
33
|
process.env[parts[0]] = parts[1];
|
|
30
34
|
}
|
|
31
35
|
}
|
|
32
36
|
|
|
37
|
+
|
|
33
38
|
}
|
package/src/thingType.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import isUUID from './isUUID.js'
|
|
2
|
+
export default (thing) => {
|
|
3
|
+
|
|
4
|
+
if (thing === undefined) { return 'undefined'; }
|
|
5
|
+
if (thing === null) { return 'null'; }
|
|
6
|
+
|
|
7
|
+
let type = typeof thing;
|
|
8
|
+
|
|
9
|
+
let same = ['undefined', 'null', 'boolean', 'function', 'symbol', 'bigint'].includes(type);
|
|
10
|
+
if (same) { return type; }
|
|
11
|
+
|
|
12
|
+
// array vs object
|
|
13
|
+
if (type === 'object' && thing !== null) {
|
|
14
|
+
type = Array.isArray(thing) ? 'array' : 'object';
|
|
15
|
+
return type;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// integer vs double
|
|
19
|
+
if (type === 'number') {
|
|
20
|
+
type = Number.isInteger(thing) ? 'integer' : 'number';
|
|
21
|
+
return type;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// string vs iso timestamp vs uuid
|
|
25
|
+
let is_uuid = isUUID(thing);
|
|
26
|
+
if(is_uuid){ type = 'uuid'; return type; }
|
|
27
|
+
|
|
28
|
+
let is_iso_dateTime = thing && typeof thing === 'string' && thing.match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z?$/);
|
|
29
|
+
if(is_iso_dateTime) { type = 'timestamp'; return type; }
|
|
30
|
+
|
|
31
|
+
return type;
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
}
|
|
35
|
+
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import thingType from '../thingType.js';
|
|
2
|
+
import validateSchema from '../validateSchema.js';
|
|
3
|
+
import each from '../each.js';
|
|
4
|
+
|
|
5
|
+
import cleanBoolean from '../clean/boolean.js';
|
|
6
|
+
import cleanInteger from '../clean/integer.js';
|
|
7
|
+
import cleanNumber from '../clean/number.js';
|
|
8
|
+
import cleanString from '../clean/string.js';
|
|
9
|
+
import cleanTimestamp from '../clean/timestamp.js';
|
|
10
|
+
import cleanUUID from '../clean/uuid.js';
|
|
11
|
+
|
|
12
|
+
function cleanArray(arr, schema = {}){
|
|
13
|
+
|
|
14
|
+
try {
|
|
15
|
+
|
|
16
|
+
if(!Array.isArray(arr)) {
|
|
17
|
+
throw {
|
|
18
|
+
message: 'Input must be an array',
|
|
19
|
+
arr
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
validateSchema(schema);
|
|
24
|
+
|
|
25
|
+
const cleanArrayItems = [];
|
|
26
|
+
|
|
27
|
+
const supposedToBeType = schema.items.type;
|
|
28
|
+
|
|
29
|
+
arr.forEach( (item, key) => {
|
|
30
|
+
|
|
31
|
+
const itemType = thingType(item);
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
if(itemType !== supposedToBeType){
|
|
35
|
+
|
|
36
|
+
throw {
|
|
37
|
+
message: 'type invalid',
|
|
38
|
+
itemType,
|
|
39
|
+
supposedToBeType
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
let cleanedItem = item;
|
|
45
|
+
|
|
46
|
+
if(supposedToBeType === 'boolean'){ cleanedItem = cleanBoolean(item); }
|
|
47
|
+
if(supposedToBeType === 'integer'){ cleanedItem = cleanInteger(item); }
|
|
48
|
+
if(supposedToBeType === 'number'){ cleanedItem = cleanNumber(item); }
|
|
49
|
+
if(supposedToBeType === 'string'){ cleanedItem = cleanString(item); }
|
|
50
|
+
if(supposedToBeType === 'timestamp'){ cleanedItem = cleanTimestamp(item); }
|
|
51
|
+
if(supposedToBeType === 'uuid'){ cleanedItem = cleanUUID(item); }
|
|
52
|
+
|
|
53
|
+
if(supposedToBeType === 'array'){
|
|
54
|
+
cleanedItem = cleanArray(item, schema.items);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if(supposedToBeType === 'object'){
|
|
58
|
+
cleanedItem = cleanObject(item, schema.items);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if(cleanedItem === null){
|
|
62
|
+
if(schema.required === true){
|
|
63
|
+
throw {
|
|
64
|
+
message: 'required item is null',
|
|
65
|
+
item,
|
|
66
|
+
key
|
|
67
|
+
};
|
|
68
|
+
} else {
|
|
69
|
+
return; // skip this item if it's not required and is null
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
cleanArrayItems.push(cleanedItem);
|
|
75
|
+
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
if(cleanArrayItems.length === 0){
|
|
79
|
+
throw {
|
|
80
|
+
message: 'array is empty',
|
|
81
|
+
arr
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return cleanArrayItems;
|
|
86
|
+
|
|
87
|
+
} catch (e) {
|
|
88
|
+
|
|
89
|
+
if(schema.required === true){
|
|
90
|
+
throw e
|
|
91
|
+
} else {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
function cleanObject(obj, schema){
|
|
103
|
+
|
|
104
|
+
validateSchema(schema);
|
|
105
|
+
|
|
106
|
+
if(typeof obj !== 'object' || obj === null){
|
|
107
|
+
throw {
|
|
108
|
+
message: 'Clean Object - Input must be an object',
|
|
109
|
+
obj,
|
|
110
|
+
schema
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
let keysPassed = Object.keys(obj);
|
|
115
|
+
let keysSchema = Object.keys(schema.properties);
|
|
116
|
+
|
|
117
|
+
const origLength = keysPassed.length;
|
|
118
|
+
keysPassed = keysPassed.filter(key => keysSchema.includes(key));
|
|
119
|
+
|
|
120
|
+
if(origLength !== keysPassed.length){
|
|
121
|
+
throw {
|
|
122
|
+
name: 'KeyError',
|
|
123
|
+
message: 'Object contains keys not in schema',
|
|
124
|
+
keysPassed,
|
|
125
|
+
keysSchema,
|
|
126
|
+
obj
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const cleanObj = {};
|
|
131
|
+
|
|
132
|
+
// Iterate over the schema keys
|
|
133
|
+
each(obj, (value, key) => {
|
|
134
|
+
|
|
135
|
+
const valType = thingType(value);
|
|
136
|
+
const supposedToBeType = schema.properties[key].type;
|
|
137
|
+
|
|
138
|
+
if(valType !== supposedToBeType){
|
|
139
|
+
|
|
140
|
+
throw {
|
|
141
|
+
message: 'type invalid',
|
|
142
|
+
valType,
|
|
143
|
+
supposedToBeType,
|
|
144
|
+
key
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
let cleanedValue;
|
|
150
|
+
|
|
151
|
+
if(supposedToBeType === 'boolean'){ cleanedValue = cleanBoolean(value); }
|
|
152
|
+
if(supposedToBeType === 'integer'){ cleanedValue = cleanInteger(value); }
|
|
153
|
+
if(supposedToBeType === 'number'){ cleanedValue = cleanNumber(value); }
|
|
154
|
+
if(supposedToBeType === 'string'){ cleanedValue = cleanString(value); }
|
|
155
|
+
if(supposedToBeType === 'timestamp'){ cleanedValue = cleanTimestamp(value); }
|
|
156
|
+
if(supposedToBeType === 'uuid'){ cleanedValue = cleanUUID(value); }
|
|
157
|
+
|
|
158
|
+
if(supposedToBeType === 'object'){
|
|
159
|
+
cleanedValue = cleanObject(value, schema.properties[key]);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if(supposedToBeType === 'array'){
|
|
163
|
+
cleanedValue = cleanArray(value, schema.properties[key]);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
cleanObj[key] = cleanedValue;
|
|
167
|
+
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
return cleanObj;
|
|
171
|
+
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export default {
|
|
175
|
+
array: cleanArray,
|
|
176
|
+
object: cleanObject,
|
|
177
|
+
boolean: cleanBoolean,
|
|
178
|
+
integer: cleanInteger,
|
|
179
|
+
number: cleanNumber,
|
|
180
|
+
string: cleanString,
|
|
181
|
+
timestamp: cleanTimestamp,
|
|
182
|
+
uuid: cleanUUID
|
|
183
|
+
};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import each from './each.js';
|
|
2
|
+
|
|
3
|
+
function validateSchema(schema){
|
|
4
|
+
|
|
5
|
+
if(!schema){
|
|
6
|
+
throw {
|
|
7
|
+
message: 'Schema is required.',
|
|
8
|
+
schema
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// ref todo
|
|
13
|
+
if(schema.ref){ return true; }
|
|
14
|
+
|
|
15
|
+
let schemaType = typeof schema;
|
|
16
|
+
|
|
17
|
+
if(schemaType !== 'object' || schema === null) {
|
|
18
|
+
throw {
|
|
19
|
+
message: 'Schema Invalid - Input must be an object',
|
|
20
|
+
schema,
|
|
21
|
+
schemaType
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// object properties dont have type
|
|
26
|
+
if(!schema.type && schema.properties){ schema.type = 'object'; }
|
|
27
|
+
|
|
28
|
+
const validTypes = [
|
|
29
|
+
'array',
|
|
30
|
+
'boolean',
|
|
31
|
+
'integer',
|
|
32
|
+
'number',
|
|
33
|
+
'object',
|
|
34
|
+
'string',
|
|
35
|
+
'timestamp',
|
|
36
|
+
'uuid'
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
if(!schema.type || !validTypes.includes(schema.type)) {
|
|
40
|
+
throw {
|
|
41
|
+
message: `Schema must have a valid type.`,
|
|
42
|
+
validTypes,
|
|
43
|
+
schema
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
if(schema.type === 'object') {
|
|
49
|
+
|
|
50
|
+
if(schema.properties){
|
|
51
|
+
|
|
52
|
+
// run through each property
|
|
53
|
+
each(schema.properties, (v,k) => {
|
|
54
|
+
validateSchema(v);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
} else {
|
|
58
|
+
|
|
59
|
+
throw {
|
|
60
|
+
message: 'Object invalid - needs "properties"',
|
|
61
|
+
schema
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if(schema.type === 'array') {
|
|
69
|
+
|
|
70
|
+
if(!schema.items){
|
|
71
|
+
throw {
|
|
72
|
+
message: 'Array schema must have items defined.',
|
|
73
|
+
schema
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
validateSchema(schema.items);
|
|
78
|
+
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return true;
|
|
82
|
+
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export default validateSchema;
|
|
86
|
+
|
package/test/js/abc.test.js
CHANGED
package/test/secret.test.js
CHANGED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
// example.test.js
|
|
2
|
+
import { expect, test } from 'vitest'
|
|
3
|
+
import utils from '../../index.js';
|
|
4
|
+
|
|
5
|
+
const testStringArray = [ 'a', 'b', 'c' ];
|
|
6
|
+
const testIntegerArray = [ 1, 2, 3, 4, 5 ];
|
|
7
|
+
const testBooleanArray = [true, false, true, false];
|
|
8
|
+
|
|
9
|
+
const testArrayOfArraysOfIntegers = [
|
|
10
|
+
testIntegerArray,
|
|
11
|
+
testIntegerArray,
|
|
12
|
+
testIntegerArray
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
const testArrayOfArraysOfStrings = [
|
|
16
|
+
testStringArray,
|
|
17
|
+
testStringArray,
|
|
18
|
+
testStringArray
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
const schemaForStrings = {
|
|
22
|
+
type: 'array',
|
|
23
|
+
items: {
|
|
24
|
+
type: 'string'
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const schemaForIntegers = {
|
|
29
|
+
type: 'array',
|
|
30
|
+
items: {
|
|
31
|
+
type: 'integer'
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
const schemaForBooleans = {
|
|
37
|
+
type: 'array',
|
|
38
|
+
items: {
|
|
39
|
+
type: 'boolean'
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const schemaForArrayOfArrays_integers = {
|
|
44
|
+
type: 'array',
|
|
45
|
+
items: {
|
|
46
|
+
type: 'array',
|
|
47
|
+
items: { type: 'integer' }
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const schemaForArrayOfArrays_strings = {
|
|
52
|
+
type: 'array',
|
|
53
|
+
items: {
|
|
54
|
+
type: 'array',
|
|
55
|
+
items: { type: 'string' }
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const testObject = {
|
|
60
|
+
stringProp: 'a string',
|
|
61
|
+
integerProp: 42,
|
|
62
|
+
numberProp: 3.14,
|
|
63
|
+
booleanProp: true,
|
|
64
|
+
timestampProp: new Date().toISOString(),
|
|
65
|
+
uuidProp: utils.uuid(), // generate a valid UUID
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const arrayOfObjects = [
|
|
69
|
+
{ ...testObject },
|
|
70
|
+
{ ...testObject },
|
|
71
|
+
{ ...testObject }
|
|
72
|
+
];
|
|
73
|
+
|
|
74
|
+
const objSchema = {
|
|
75
|
+
type: 'object',
|
|
76
|
+
properties: {
|
|
77
|
+
stringProp: { type: 'string', required: true },
|
|
78
|
+
integerProp: { type: 'integer', required: true },
|
|
79
|
+
numberProp: { type: 'number', required: true },
|
|
80
|
+
booleanProp: { type: 'boolean', required: true },
|
|
81
|
+
timestampProp: { type: 'timestamp', required: true },
|
|
82
|
+
uuidProp: { type: 'uuid', required: true },
|
|
83
|
+
optionalStringProp: { type: 'string', required: false },
|
|
84
|
+
optionalIntegerProp: { type: 'integer', required: false },
|
|
85
|
+
optionalNumberProp: { type: 'number', required: false },
|
|
86
|
+
optionalBooleanProp: { type: 'boolean', required: false },
|
|
87
|
+
optionalTimestampProp: { type: 'timestamp', required: false },
|
|
88
|
+
optionalUuidProp: { type: 'uuid', required: false }
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
const schemaForArrayOfObjects = {
|
|
94
|
+
type: 'array',
|
|
95
|
+
required: true,
|
|
96
|
+
items: {
|
|
97
|
+
... objSchema,
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
test('testStringArray', () => {
|
|
102
|
+
|
|
103
|
+
const x = utils.clean.array(testStringArray, schemaForStrings);
|
|
104
|
+
expect(x).toStrictEqual(testStringArray);
|
|
105
|
+
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
test('testIntegerArray', () => {
|
|
109
|
+
|
|
110
|
+
const x = utils.clean.array(testIntegerArray, schemaForIntegers);
|
|
111
|
+
expect(x).toStrictEqual(testIntegerArray);
|
|
112
|
+
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
test('testBooleanArray', () => {
|
|
116
|
+
|
|
117
|
+
const x = utils.clean.array(testBooleanArray, schemaForBooleans);
|
|
118
|
+
expect(x).toStrictEqual(testBooleanArray);
|
|
119
|
+
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
test('testBooleanArray but pass different schema', () => {
|
|
123
|
+
|
|
124
|
+
expect(()=> utils.clean.array(testBooleanArray, { ... schemaForIntegers, required: true }) ).toThrow();
|
|
125
|
+
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
test('schemaForArrayOfArrays_integers', () => {
|
|
129
|
+
|
|
130
|
+
const x = utils.clean.array(testArrayOfArraysOfIntegers, schemaForArrayOfArrays_integers);
|
|
131
|
+
expect(x).toStrictEqual(testArrayOfArraysOfIntegers);
|
|
132
|
+
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
test('schemaForArrayOfArrays_strings', () => {
|
|
136
|
+
|
|
137
|
+
const x = utils.clean.array(testArrayOfArraysOfStrings, schemaForArrayOfArrays_strings);
|
|
138
|
+
expect(x).toStrictEqual(testArrayOfArraysOfStrings);
|
|
139
|
+
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
test('schemaForArrayOfArrays_strings wrong type', () => {
|
|
143
|
+
|
|
144
|
+
const x = utils.clean.array(testArrayOfArraysOfStrings, schemaForArrayOfArrays_integers);
|
|
145
|
+
expect(x).toBe(null);
|
|
146
|
+
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
test('schemaForArrayOfObjects', () => {
|
|
150
|
+
|
|
151
|
+
const x = utils.clean.array(arrayOfObjects, schemaForArrayOfObjects);
|
|
152
|
+
expect(x).toStrictEqual(arrayOfObjects);
|
|
153
|
+
|
|
154
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// example.test.js
|
|
2
|
+
import { expect, test } from 'vitest'
|
|
3
|
+
import utils from '../../index.js';
|
|
4
|
+
|
|
5
|
+
let x = true;
|
|
6
|
+
let y = false;
|
|
7
|
+
let z = 1;
|
|
8
|
+
|
|
9
|
+
test('boolean - true', () => {
|
|
10
|
+
expect(utils.clean.boolean(x)).toBe(true);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
test('boolean - false', () => {
|
|
14
|
+
expect(utils.clean.boolean(y)).toBe(false);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test('boolean - number', () => {
|
|
18
|
+
expect(utils.clean.boolean(z)).toBe(null);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('boolean - NOT to throw', () => {
|
|
22
|
+
expect(() => utils.clean.boolean(y, { required: true })).not.toThrow();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
test('boolean - to throw', () => {
|
|
26
|
+
expect(() => utils.clean.boolean(z, { required: true })).toThrow();
|
|
27
|
+
});
|