@awesomeness-js/utils 1.0.18 → 1.0.20
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 +47 -0
- package/package.json +13 -10
- package/schemas/schema1.js +121 -0
- package/schemas/schema2.js +121 -0
- package/schemas.js +15 -0
- package/secrets/dev.env +2 -1
- package/secrets/local.env +2 -1
- package/src/clean/array.js +43 -0
- package/src/clean/boolean.js +22 -0
- package/src/clean/integer.js +55 -0
- package/src/clean/number.js +75 -0
- package/src/clean/object.js +67 -0
- package/src/clean/string.js +58 -0
- package/src/clean/thing.js +31 -0
- package/src/clean/timestamp.js +56 -0
- package/src/clean/uuid.js +33 -0
- package/src/combineFiles.js +10 -1
- package/src/decrypt.js +19 -0
- package/src/each.js +10 -0
- package/src/encrypt.js +29 -0
- package/src/password/check.js +9 -0
- package/src/password/hash.js +11 -0
- package/src/setLocalEnvs.js +9 -4
- package/src/thingType.js +33 -0
- package/src/validateSchema.js +78 -0
- package/test/js/abc.test.js +6 -0
- package/test/secret.test.js +7 -1
- 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/types/clean/array.d.ts +2 -0
- package/types/clean/boolean.d.ts +3 -0
- package/types/clean/integer.d.ts +5 -0
- package/types/clean/number.d.ts +7 -0
- package/types/clean/object.d.ts +2 -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/decrypt.d.ts +1 -0
- package/types/each.d.ts +10 -1
- package/types/encrypt.d.ts +5 -0
- package/types/hashPassword.d.ts +1 -0
- package/types/index.d.ts +47 -0
- package/types/password/check.d.ts +1 -0
- package/types/password/hash.d.ts +1 -0
- package/types/thingType.d.ts +2 -0
- package/types/validatePassword.d.ts +1 -0
- package/types/validateSchema.d.ts +2 -0
- package/vitest.config.js +6 -0
- package/test.js +0 -42
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export default function cleanString(x, {
|
|
2
|
+
required = false,
|
|
3
|
+
minLength = false,
|
|
4
|
+
maxLength = false,
|
|
5
|
+
allowHtml = false,
|
|
6
|
+
allowScripts = false
|
|
7
|
+
} = {}){
|
|
8
|
+
|
|
9
|
+
try {
|
|
10
|
+
|
|
11
|
+
if(typeof x !== 'string') {
|
|
12
|
+
throw {
|
|
13
|
+
name: 'TypeError',
|
|
14
|
+
message: 'Input must be a string',
|
|
15
|
+
value: x
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if(minLength !== false && x.length < minLength) {
|
|
20
|
+
throw {
|
|
21
|
+
message: `String length must be between ${minLength} `,
|
|
22
|
+
length: x.length,
|
|
23
|
+
value: x
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if(maxLength !== false && x.length > maxLength) {
|
|
28
|
+
throw {
|
|
29
|
+
message: `String length must be less than or equal to ${maxLength}`,
|
|
30
|
+
length: x.length,
|
|
31
|
+
value: x
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if(!allowHtml && /<[^>]*>/g.test(x)) {
|
|
36
|
+
throw {
|
|
37
|
+
message: 'HTML tags are not allowed',
|
|
38
|
+
value: x
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if(!allowScripts && /<script[^>]*>.*<\/script>/g.test(x)) {
|
|
43
|
+
throw {
|
|
44
|
+
message: 'Script tags are not allowed',
|
|
45
|
+
value: x
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return x;
|
|
50
|
+
|
|
51
|
+
} catch (e) {
|
|
52
|
+
|
|
53
|
+
if(required) { throw e; } else { return null; }
|
|
54
|
+
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
}
|
|
58
|
+
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import thingType from '../thingType.js';
|
|
2
|
+
|
|
3
|
+
export default (thing, schema) => {
|
|
4
|
+
|
|
5
|
+
const type = thingType(thing);
|
|
6
|
+
|
|
7
|
+
let validTypes = [
|
|
8
|
+
'array',
|
|
9
|
+
'boolean',
|
|
10
|
+
'integer',
|
|
11
|
+
'number',
|
|
12
|
+
'object',
|
|
13
|
+
'string',
|
|
14
|
+
'timestamp',
|
|
15
|
+
'uuid'
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
if(!validTypes.includes(type)){
|
|
19
|
+
throw {
|
|
20
|
+
message: `Invalid type "${type}" for thing`,
|
|
21
|
+
thing
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const cleanFnImported = import(`./${type}.js`);
|
|
26
|
+
const cleanedThing = cleanFnImported(thing, schema);
|
|
27
|
+
|
|
28
|
+
return cleanedThing;
|
|
29
|
+
|
|
30
|
+
}
|
|
31
|
+
|
|
@@ -0,0 +1,56 @@
|
|
|
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
|
+
if(maxDaysInFuture === false && maxDaysInFPast === false) {
|
|
26
|
+
return isoDateTimeString;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const now = new Date();
|
|
30
|
+
|
|
31
|
+
if(maxDaysInFuture !== false && (date - now) > maxDaysInFuture * 24 * 60 * 60 * 1000) {
|
|
32
|
+
throw {
|
|
33
|
+
message: `Date is more than ${maxDaysInFuture} days in the future`,
|
|
34
|
+
isoDateTimeString
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if(maxDaysInFPast !== false && (now - date) > maxDaysInFPast * 24 * 60 * 60 * 1000) {
|
|
39
|
+
throw {
|
|
40
|
+
message: `Date is more than ${maxDaysInFPast} days in the past`,
|
|
41
|
+
value: isoDateTimeString
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return isoDateTimeString;
|
|
46
|
+
|
|
47
|
+
} catch (e) {
|
|
48
|
+
|
|
49
|
+
if(required) { throw e; } else { return null; }
|
|
50
|
+
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
}
|
|
56
|
+
|
|
@@ -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
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { createDecipheriv } from 'crypto';
|
|
2
|
+
|
|
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
|
+
}
|
|
8
|
+
|
|
9
|
+
const { iv, authTag, cipherText } = encryptedData;
|
|
10
|
+
|
|
11
|
+
const decipher = createDecipheriv('aes-256-gcm', key, Buffer.from(iv, 'hex'));
|
|
12
|
+
decipher.setAuthTag(Buffer.from(authTag, 'hex'));
|
|
13
|
+
|
|
14
|
+
let decrypted = decipher.update(cipherText, 'hex', 'utf8');
|
|
15
|
+
decrypted += decipher.final('utf8');
|
|
16
|
+
|
|
17
|
+
return decrypted;
|
|
18
|
+
|
|
19
|
+
}
|
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
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { randomBytes, createCipheriv } from 'crypto';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
// Encrypt plaintext using AES-256-GCM
|
|
5
|
+
export default function encrypt(plainText, key = process.env.AWESOMENESS_ENCRYPTION_KEY) {
|
|
6
|
+
|
|
7
|
+
if(!key){
|
|
8
|
+
throw new Error('Encryption key is not set. Please set the AWESOMENESS_ENCRYPTION_KEY environment variable.');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// GCM typically uses a 12- or 16-byte IV/nonce
|
|
12
|
+
const iv = randomBytes(12);
|
|
13
|
+
|
|
14
|
+
const cipher = createCipheriv('aes-256-gcm', key, iv);
|
|
15
|
+
let encrypted = cipher.update(plainText, 'utf8', 'hex');
|
|
16
|
+
encrypted += cipher.final('hex');
|
|
17
|
+
|
|
18
|
+
// GCM provides an auth tag, which is required for decryption
|
|
19
|
+
const authTag = cipher.getAuthTag().toString('hex');
|
|
20
|
+
|
|
21
|
+
// Return all parts needed for safe decryption
|
|
22
|
+
return {
|
|
23
|
+
iv: iv.toString('hex'),
|
|
24
|
+
authTag,
|
|
25
|
+
cipherText: encrypted
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
}
|
|
29
|
+
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { pbkdf2Sync } from 'crypto';
|
|
2
|
+
|
|
3
|
+
// Compare a plain-text password to a stored salt+hash
|
|
4
|
+
export default function validatePassword(password, storedHash) {
|
|
5
|
+
const [salt, originalHash] = storedHash.split('::');
|
|
6
|
+
const derivedKey = pbkdf2Sync(password, salt, 100000, 64, 'sha512');
|
|
7
|
+
return derivedKey.toString('hex') === originalHash;
|
|
8
|
+
}
|
|
9
|
+
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { randomBytes, pbkdf2Sync } from 'crypto';
|
|
2
|
+
|
|
3
|
+
// Hash a password using Node.js built-in crypto (no external deps).
|
|
4
|
+
export default function hashPassword(password) {
|
|
5
|
+
// Generate a random 16-byte salt
|
|
6
|
+
const salt = randomBytes(16).toString('hex');
|
|
7
|
+
// Derive a 64-byte key using PBKDF2 with 100k iterations (adjust as needed)
|
|
8
|
+
const derivedKey = pbkdf2Sync(password, salt, 100000, 64, 'sha512');
|
|
9
|
+
// Return salt and hash combined as a single string
|
|
10
|
+
return `${salt}::${derivedKey.toString('hex')}`;
|
|
11
|
+
}
|
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,33 @@
|
|
|
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
|
+
|
|
32
|
+
}
|
|
33
|
+
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import each from './each.js';
|
|
2
|
+
|
|
3
|
+
function validateSchema(schema){
|
|
4
|
+
|
|
5
|
+
// ref todo
|
|
6
|
+
if(schema.ref){ return true; }
|
|
7
|
+
|
|
8
|
+
let schemaType = typeof schema;
|
|
9
|
+
|
|
10
|
+
if(schemaType !== 'object' || schema === null) {
|
|
11
|
+
throw {
|
|
12
|
+
message: 'Input must be an object',
|
|
13
|
+
schema
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// object properties dont have type
|
|
18
|
+
if(!schema.type && schema.properties){ schema.type = 'object'; }
|
|
19
|
+
|
|
20
|
+
const validTypes = [
|
|
21
|
+
'array',
|
|
22
|
+
'boolean',
|
|
23
|
+
'integer',
|
|
24
|
+
'number',
|
|
25
|
+
'object',
|
|
26
|
+
'string',
|
|
27
|
+
'timestamp',
|
|
28
|
+
'uuid'
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
if(!schema.type || !validTypes.includes(schema.type)) {
|
|
32
|
+
throw {
|
|
33
|
+
message: `Schema must have a valid type.`,
|
|
34
|
+
validTypes,
|
|
35
|
+
schema
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
if(schema.type === 'object') {
|
|
41
|
+
|
|
42
|
+
if(schema.properties){
|
|
43
|
+
|
|
44
|
+
// run through each property
|
|
45
|
+
each(schema.properties, (v,k) => {
|
|
46
|
+
validateSchema(v);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
} else {
|
|
50
|
+
|
|
51
|
+
throw {
|
|
52
|
+
message: 'Object invalid - needs "properties"',
|
|
53
|
+
schema
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if(schema.type === 'array') {
|
|
61
|
+
|
|
62
|
+
if(!schema.items){
|
|
63
|
+
throw {
|
|
64
|
+
message: 'Array schema must have items defined.',
|
|
65
|
+
schema
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
validateSchema(schema.items);
|
|
70
|
+
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return true;
|
|
74
|
+
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export default validateSchema;
|
|
78
|
+
|
package/test/js/abc.test.js
CHANGED
package/test/secret.test.js
CHANGED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// example.test.js
|
|
2
|
+
import { expect, test } from 'vitest'
|
|
3
|
+
import utils from '../index.js';
|
|
4
|
+
|
|
5
|
+
let combineTest = utils.combineFiles('./src', 'js');
|
|
6
|
+
|
|
7
|
+
let combineTestBrowser = utils.combineFiles('./src', 'js', {
|
|
8
|
+
moduleToBrowser: true
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
test('combineFiles - combine all files in src/js', () => {
|
|
12
|
+
expect(combineTest).toBeDefined();
|
|
13
|
+
expect(combineTestBrowser).toBeDefined();
|
|
14
|
+
expect(combineTest.length).toBeGreaterThan(combineTestBrowser.length);
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
test('has import', () => {
|
|
19
|
+
expect(combineTest.includes('import')).toBe(true);
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
test('should not have import', () => {
|
|
23
|
+
expect(combineTestBrowser.includes('import')).toBe(false);
|
|
24
|
+
})
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// example.test.js
|
|
2
|
+
import { expect, test } from 'vitest'
|
|
3
|
+
import utils from '../index.js';
|
|
4
|
+
|
|
5
|
+
let convertBytesTest = utils.convertBytes(1024);
|
|
6
|
+
test('convertBytes 1024 => 1.00 KB', () => {
|
|
7
|
+
expect(convertBytesTest).toBeDefined();
|
|
8
|
+
expect(convertBytesTest).toEqual('1.00 KB');
|
|
9
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// example.test.js
|
|
2
|
+
import { expect, test } from 'vitest'
|
|
3
|
+
import utils from '../index.js';
|
|
4
|
+
|
|
5
|
+
await utils.setLocalEnvs('./secrets/local.env');
|
|
6
|
+
|
|
7
|
+
const env1 = process.env.JUST_A_TEST;
|
|
8
|
+
|
|
9
|
+
test('localEnv - should be testValue', () => {
|
|
10
|
+
expect(env1).toBe('Local just a test');
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
await utils.setLocalEnvs('./secrets/dev.env');
|
|
14
|
+
|
|
15
|
+
test('localEnv - should be testValue', () => {
|
|
16
|
+
expect(process.env.JUST_A_TEST).toBe('Dev just a test');
|
|
17
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// example.test.js
|
|
2
|
+
import { expect, test } from 'vitest'
|
|
3
|
+
import utils from '../index.js';
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
let fileList2 = utils.getAllFiles('./test', {
|
|
7
|
+
// fileTypes: ['.css'],
|
|
8
|
+
// fileTypes: ['.js'],
|
|
9
|
+
ignore: [
|
|
10
|
+
"/ignoreFolder",
|
|
11
|
+
"/ignoreFolder2/",
|
|
12
|
+
"*.env",
|
|
13
|
+
"*.test.js",
|
|
14
|
+
"/css/*.js",
|
|
15
|
+
"/js/*.css"
|
|
16
|
+
]
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test('file list of 3', () => {
|
|
20
|
+
expect(fileList2.length).toBe(3); // Adjust this number based on your test folder contents
|
|
21
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// example.test.js
|
|
2
|
+
import { expect, test } from 'vitest'
|
|
3
|
+
import utils from '../index.js';
|
|
4
|
+
|
|
5
|
+
// set AWESOMENESS_ENCRYPTION_KEY
|
|
6
|
+
//await utils.setLocalEnvs('./secrets/dev.env');
|
|
7
|
+
|
|
8
|
+
const storedHash = utils.password.hash('mySecret123');
|
|
9
|
+
|
|
10
|
+
test('correct password check', () => {
|
|
11
|
+
expect(utils.password.check('mySecret123', storedHash)).toBe(true)
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test('incorrect password check', () => {
|
|
15
|
+
expect(utils.password.check('wrongPassword', storedHash)).toBe(false)
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
// Example 256-bit key for AES-256
|
|
19
|
+
// In real usage, store this securely (e.g., an environment variable or key vault).
|
|
20
|
+
|
|
21
|
+
const secretMessage = 'This is top secret!';
|
|
22
|
+
const encrypted = utils.encrypt(secretMessage);
|
|
23
|
+
const decrypted = utils.decrypt(encrypted);
|
|
24
|
+
test('encryption and decryption', () => {
|
|
25
|
+
expect(decrypted).toBe(secretMessage)
|
|
26
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// example.test.js
|
|
2
|
+
import { expect, test } from 'vitest'
|
|
3
|
+
import utils from '../index.js';
|
|
4
|
+
|
|
5
|
+
let uuid = utils.uuid();
|
|
6
|
+
let isValid = utils.isUUID(uuid);
|
|
7
|
+
|
|
8
|
+
test('uuid create', () => {
|
|
9
|
+
expect(uuid).toBeDefined();
|
|
10
|
+
expect(uuid.length).toBe(36);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
test('uuid isValid', () => {
|
|
14
|
+
expect(isValid).toBe(true);
|
|
15
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { expect, test } from 'vitest'
|
|
2
|
+
import utils from '../index.js';
|
|
3
|
+
import schemas from '../schemas.js';
|
|
4
|
+
|
|
5
|
+
let schema1 = utils.validateSchema(schemas.schema1);
|
|
6
|
+
let schema2 = utils.validateSchema(schemas.schema2);
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
test('schema1 is valid', () => {
|
|
10
|
+
expect(schema1).toBe(true);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
test('schema2 is valid', () => {
|
|
14
|
+
expect(schema2).toBe(true);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
let expectedError;
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
utils.validateSchema({
|
|
21
|
+
notReal: true
|
|
22
|
+
});
|
|
23
|
+
expectedError = false; // should not reach here
|
|
24
|
+
} catch(e){
|
|
25
|
+
expectedError = true;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
test('invalid schema throws error', () => {
|
|
29
|
+
expect(expectedError).toBe(true);
|
|
30
|
+
});
|