@awesomeness-js/utils 1.0.24 → 1.1.2
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/README.md +112 -86
- package/build/build.js +16 -11
- package/build/postBuild.js +8 -8
- package/eslint.config.js +90 -0
- package/index.js +108 -78
- package/package.json +26 -25
- package/schemas/schema1.js +5 -1
- package/schemas/schema2.js +5 -1
- package/schemas.js +3 -2
- package/src/build.js +88 -8
- package/src/clean/boolean.js +27 -17
- package/src/clean/integer.js +85 -69
- package/src/clean/number.js +103 -86
- package/src/clean/string.js +91 -67
- package/src/clean/timestamp.js +61 -45
- package/src/clean/uuid.js +38 -25
- package/src/collectImports.js +195 -0
- package/src/combineFiles.js +45 -36
- package/src/convertBytes.js +12 -7
- package/src/decrypt.js +17 -9
- package/src/each.js +26 -4
- package/src/eachAsync.js +35 -19
- package/src/encrypt.js +22 -17
- package/src/getAllFiles.js +56 -42
- package/src/ignoreFolder/ignoreMe.js +6 -2
- package/src/ignoreMe.js +4 -2
- package/src/isUUID.js +4 -0
- package/src/md5.js +5 -1
- package/src/password/check.js +7 -3
- package/src/password/hash.js +12 -7
- package/src/setLocalEnvs.js +16 -3
- package/src/shouldIgnore.js +99 -0
- package/src/thingType.js +62 -24
- package/src/toPennies.js +23 -5
- package/src/utils/buildExportsTree.js +45 -17
- package/src/utils/buildFileDataList.js +37 -18
- package/src/utils/clean.js +205 -120
- package/src/utils/extractJSDocComment.js +14 -7
- package/src/utils/generateFile.js +54 -18
- package/src/utils/generateFlatExportLines.js +40 -17
- package/src/utils/generateImportStatements.js +20 -8
- package/src/utils/generateNamedExports.js +55 -10
- package/src/utils/generateNamespaceCode.js +56 -24
- package/src/utils/generateNamespaceExportLines.js +27 -7
- package/src/utils/writeHotWrapper.js +42 -0
- package/src/uuid.js +9 -7
- package/src/validateSchema.js +95 -77
- package/test/collectImports.js +8 -0
- package/test/css/some.css +3 -0
- package/test/css/some.js +5 -0
- package/test/ignoreFolder/ignoreMe.js +3 -1
- package/test/ignoreFolder/ignoreMe2.js +3 -1
- package/test/ignoreFolder2/ignoreMe.js +6 -2
- package/test/js/abc.test.js +7 -3
- package/test/js/some.js +5 -0
- package/test/secret.test.js +1 -1
- package/tests/clean/array.test.js +122 -74
- package/tests/clean/boolean.test.js +18 -6
- package/tests/clean/integer.test.js +25 -9
- package/tests/clean/number.test.js +49 -13
- package/tests/clean/object.test.js +190 -119
- package/tests/clean/string.test.js +48 -17
- package/tests/clean/timestamp.test.js +12 -5
- package/tests/clean/uuid.test.js +13 -6
- package/tests/collectImports.test.js +66 -0
- package/tests/combineFiles.test.js +28 -26
- package/tests/convertBytes.test.js +8 -3
- package/tests/env.test.js +9 -3
- package/tests/example.test.js +7 -3
- package/tests/fileList.test.js +16 -12
- package/tests/hash-and-encrypt.test.js +13 -4
- package/tests/ignore.test.js +55 -0
- package/tests/md5.test.js +7 -2
- package/tests/namedExports.test.js +13 -0
- package/tests/uuid.test.js +10 -4
- package/tests/validateSchema.test.js +21 -9
- package/tsconfig.json +20 -16
- package/types/build.d.ts +5 -1
- package/types/collectImports.d.ts +6 -0
- package/types/index.d.ts +108 -78
- package/types/shouldIgnore.d.ts +1 -0
- package/types/utils/buildFileDataList.d.ts +5 -1
- package/types/utils/generateFile.d.ts +8 -1
- package/types/utils/generateFlatExportLines.d.ts +7 -1
- package/types/utils/generateImportStatements.d.ts +5 -1
- package/types/utils/generateNamedExports.d.ts +7 -1
- package/types/utils/generateNamespaceCode.d.ts +7 -1
- package/types/utils/generateNamespaceExportLines.d.ts +6 -1
- package/types/utils/writeHotWrapper.d.ts +4 -0
- package/src/utils/shouldIgnore.js +0 -43
package/src/decrypt.js
CHANGED
|
@@ -2,18 +2,26 @@ import { createDecipheriv } from 'crypto';
|
|
|
2
2
|
|
|
3
3
|
export default function decrypt(encryptedData, key = process.env.AWESOMENESS_ENCRYPTION_KEY) {
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
throw new Error('Encryption key is not set. Please set the AWESOMENESS_ENCRYPTION_KEY environment variable.');
|
|
7
|
-
}
|
|
5
|
+
if(!key){
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
throw new Error('Encryption key is not set. Please set the AWESOMENESS_ENCRYPTION_KEY environment variable.');
|
|
8
|
+
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const {
|
|
12
|
+
iv,
|
|
13
|
+
authTag,
|
|
14
|
+
cipherText
|
|
15
|
+
} = encryptedData;
|
|
10
16
|
|
|
11
|
-
|
|
12
|
-
|
|
17
|
+
const decipher = createDecipheriv('aes-256-gcm', key, Buffer.from(iv, 'hex'));
|
|
18
|
+
|
|
19
|
+
decipher.setAuthTag(Buffer.from(authTag, 'hex'));
|
|
13
20
|
|
|
14
|
-
|
|
15
|
-
|
|
21
|
+
let decrypted = decipher.update(cipherText, 'hex', 'utf8');
|
|
22
|
+
|
|
23
|
+
decrypted += decipher.final('utf8');
|
|
16
24
|
|
|
17
|
-
|
|
25
|
+
return decrypted;
|
|
18
26
|
|
|
19
27
|
}
|
package/src/each.js
CHANGED
|
@@ -13,15 +13,37 @@ export default function each(objectOrArray, callback) {
|
|
|
13
13
|
if(Array.isArray(objectOrArray)){
|
|
14
14
|
|
|
15
15
|
objectOrArray.every( (v, k) => {
|
|
16
|
-
|
|
16
|
+
|
|
17
|
+
if(callback( v, k ) === false){
|
|
18
|
+
|
|
19
|
+
return false;
|
|
20
|
+
|
|
21
|
+
} else {
|
|
22
|
+
|
|
23
|
+
return true;
|
|
24
|
+
|
|
25
|
+
}
|
|
26
|
+
|
|
17
27
|
});
|
|
18
28
|
|
|
19
29
|
} else {
|
|
20
30
|
|
|
21
|
-
Object.entries(objectOrArray).every(entry => {
|
|
22
|
-
|
|
31
|
+
Object.entries(objectOrArray).every((entry) => {
|
|
32
|
+
|
|
33
|
+
if(callback( entry[1], entry[0] ) === false){
|
|
34
|
+
|
|
35
|
+
return false;
|
|
36
|
+
|
|
37
|
+
} else {
|
|
38
|
+
|
|
39
|
+
return true;
|
|
40
|
+
|
|
41
|
+
}
|
|
42
|
+
|
|
23
43
|
});
|
|
24
44
|
|
|
25
45
|
}
|
|
26
46
|
|
|
27
|
-
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
;
|
package/src/eachAsync.js
CHANGED
|
@@ -1,21 +1,37 @@
|
|
|
1
1
|
export default async function eachAsync(objectOrArray, callback) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
2
|
+
|
|
3
|
+
if (Array.isArray(objectOrArray)) {
|
|
4
|
+
|
|
5
|
+
// Use a for...of loop for arrays
|
|
6
|
+
for (const [ k, v ] of objectOrArray.entries()) {
|
|
7
|
+
|
|
8
|
+
// Await the callback
|
|
9
|
+
if (await callback(v, k) === false) {
|
|
10
|
+
|
|
11
|
+
break;
|
|
12
|
+
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
} else {
|
|
18
|
+
|
|
19
|
+
// Use a for...in loop for objects
|
|
20
|
+
for (const k in objectOrArray) {
|
|
21
|
+
|
|
22
|
+
if (objectOrArray.hasOwnProperty(k)) {
|
|
23
|
+
|
|
24
|
+
// Await the callback
|
|
25
|
+
if (await callback(objectOrArray[k], k) === false) {
|
|
26
|
+
|
|
27
|
+
break;
|
|
28
|
+
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
}
|
|
36
|
+
|
|
21
37
|
}
|
package/src/encrypt.js
CHANGED
|
@@ -1,29 +1,34 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
randomBytes, createCipheriv
|
|
3
|
+
} from 'crypto';
|
|
2
4
|
|
|
3
5
|
|
|
4
6
|
// Encrypt plaintext using AES-256-GCM
|
|
5
7
|
export default function encrypt(plainText, key = process.env.AWESOMENESS_ENCRYPTION_KEY) {
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
throw new Error('Encryption key is not set. Please set the AWESOMENESS_ENCRYPTION_KEY environment variable.');
|
|
9
|
-
}
|
|
9
|
+
if(!key){
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
throw new Error('Encryption key is not set. Please set the AWESOMENESS_ENCRYPTION_KEY environment variable.');
|
|
12
|
+
|
|
13
|
+
}
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
encrypted += cipher.final('hex');
|
|
15
|
+
// GCM typically uses a 12- or 16-byte IV/nonce
|
|
16
|
+
const iv = randomBytes(12);
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
const cipher = createCipheriv('aes-256-gcm', key, iv);
|
|
19
|
+
let encrypted = cipher.update(plainText, 'utf8', 'hex');
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
encrypted += cipher.final('hex');
|
|
22
|
+
|
|
23
|
+
// GCM provides an auth tag, which is required for decryption
|
|
24
|
+
const authTag = cipher.getAuthTag().toString('hex');
|
|
25
|
+
|
|
26
|
+
// Return all parts needed for safe decryption
|
|
27
|
+
return {
|
|
28
|
+
iv: iv.toString('hex'),
|
|
29
|
+
authTag,
|
|
30
|
+
cipherText: encrypted
|
|
31
|
+
};
|
|
27
32
|
|
|
28
33
|
}
|
|
29
34
|
|
package/src/getAllFiles.js
CHANGED
|
@@ -1,48 +1,62 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
readdirSync, statSync
|
|
3
|
+
} from 'fs';
|
|
2
4
|
import { join } from 'path';
|
|
3
|
-
import shouldIgnore from './
|
|
5
|
+
import shouldIgnore from './shouldIgnore.js';
|
|
4
6
|
|
|
5
7
|
export default function getAllFiles(base, {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
dir = '.',
|
|
9
|
+
files = [],
|
|
10
|
+
ignore = [],
|
|
11
|
+
fileTypes = []
|
|
10
12
|
} = {}) {
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
14
|
+
const directory = join(base, dir);
|
|
15
|
+
|
|
16
|
+
const sortedFiles = readdirSync(directory).sort();
|
|
17
|
+
|
|
18
|
+
sortedFiles.forEach((file) => {
|
|
19
|
+
|
|
20
|
+
const fullPath = join(directory, file);
|
|
21
|
+
// 1) Generate the original "relative path"
|
|
22
|
+
const relativePath = join(dir, file).replace(/\\/g, '/');
|
|
23
|
+
|
|
24
|
+
// 2) Prepend a slash so patterns like "/css/*.js" will match "/css/some.js"
|
|
25
|
+
const pathForIgnore = '/' + relativePath.replace(/^\/*/, '');
|
|
26
|
+
|
|
27
|
+
// 3) Check with the leading slash path
|
|
28
|
+
if (shouldIgnore(pathForIgnore, ignore)) {
|
|
29
|
+
|
|
30
|
+
return;
|
|
31
|
+
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Recurse if it's a directory
|
|
35
|
+
if (statSync(fullPath).isDirectory()) {
|
|
36
|
+
|
|
37
|
+
getAllFiles(base, {
|
|
38
|
+
dir: join(dir, file),
|
|
39
|
+
files,
|
|
40
|
+
ignore,
|
|
41
|
+
fileTypes
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
} else {
|
|
45
|
+
|
|
46
|
+
// Filter by file types if specified
|
|
47
|
+
if (fileTypes.length > 0 && !fileTypes.some((ext) => file.endsWith(ext))) {
|
|
48
|
+
|
|
49
|
+
return;
|
|
50
|
+
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// 4) Store the original relative path (without leading slash) in `files` if you prefer
|
|
54
|
+
files.push(relativePath);
|
|
55
|
+
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
return files;
|
|
61
|
+
|
|
48
62
|
}
|
package/src/ignoreMe.js
CHANGED
package/src/isUUID.js
CHANGED
package/src/md5.js
CHANGED
package/src/password/check.js
CHANGED
|
@@ -2,8 +2,12 @@ import { pbkdf2Sync } from 'crypto';
|
|
|
2
2
|
|
|
3
3
|
// Compare a plain-text password to a stored salt+hash
|
|
4
4
|
export default function validatePassword(password, storedHash) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
|
|
6
|
+
const [ salt, originalHash ] = storedHash.split('::');
|
|
7
|
+
const derivedKey = pbkdf2Sync(password, salt, 100000, 64, 'sha512');
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
return derivedKey.toString('hex') === originalHash;
|
|
11
|
+
|
|
8
12
|
}
|
|
9
13
|
|
package/src/password/hash.js
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
randomBytes, pbkdf2Sync
|
|
3
|
+
} from 'crypto';
|
|
2
4
|
|
|
3
5
|
// Hash a password using Node.js built-in crypto (no external deps).
|
|
4
6
|
export default function hashPassword(password) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
|
|
8
|
+
// Generate a random 16-byte salt
|
|
9
|
+
const salt = randomBytes(16).toString('hex');
|
|
10
|
+
// Derive a 64-byte key using PBKDF2 with 100k iterations (adjust as needed)
|
|
11
|
+
const derivedKey = pbkdf2Sync(password, salt, 100000, 64, 'sha512');
|
|
12
|
+
// Return salt and hash combined as a single string
|
|
13
|
+
|
|
14
|
+
return `${salt}::${derivedKey.toString('hex')}`;
|
|
15
|
+
|
|
11
16
|
}
|
package/src/setLocalEnvs.js
CHANGED
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
import { readFile } from 'fs/promises';
|
|
2
|
+
|
|
2
3
|
export default async (localSecretsPath = './secrets/local.env') => {
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
// get the file
|
|
5
6
|
let localSecrets = await readFile(localSecretsPath, 'utf8');
|
|
6
7
|
|
|
7
8
|
// parse the file
|
|
8
9
|
let lines = localSecrets.split('\n');
|
|
10
|
+
|
|
11
|
+
|
|
9
12
|
for(let line of lines){
|
|
10
13
|
|
|
11
14
|
// skip #
|
|
12
|
-
if(line[0] === '#'){
|
|
15
|
+
if(line[0] === '#'){
|
|
16
|
+
|
|
17
|
+
continue;
|
|
18
|
+
|
|
19
|
+
}
|
|
13
20
|
|
|
14
21
|
let parts = line.split('=');
|
|
15
22
|
|
|
@@ -17,7 +24,9 @@ export default async (localSecretsPath = './secrets/local.env') => {
|
|
|
17
24
|
|
|
18
25
|
// remove \r
|
|
19
26
|
if(parts[1][parts[1].length - 1] === '\r'){
|
|
27
|
+
|
|
20
28
|
parts[1] = parts[1].substring(0, parts[1].length - 1);
|
|
29
|
+
|
|
21
30
|
}
|
|
22
31
|
|
|
23
32
|
// remove outside single quotes
|
|
@@ -25,14 +34,18 @@ export default async (localSecretsPath = './secrets/local.env') => {
|
|
|
25
34
|
parts[1][0] === "'"
|
|
26
35
|
&& parts[1][parts[1].length - 1] === "'"
|
|
27
36
|
){
|
|
37
|
+
|
|
28
38
|
parts[1] = parts[1].substring(1, parts[1].length - 1);
|
|
39
|
+
|
|
29
40
|
}
|
|
30
41
|
|
|
31
42
|
|
|
32
43
|
|
|
33
44
|
process.env[parts[0]] = parts[1];
|
|
45
|
+
|
|
34
46
|
}
|
|
47
|
+
|
|
35
48
|
}
|
|
36
49
|
|
|
37
50
|
|
|
38
|
-
}
|
|
51
|
+
};
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
export default function shouldIgnore(filePath, ignorePatterns) {
|
|
2
|
+
|
|
3
|
+
const normalizePath = (p) => {
|
|
4
|
+
|
|
5
|
+
let v = String(p).replace(/\\/g, '/'); // Windows → POSIX
|
|
6
|
+
|
|
7
|
+
v = v.replace(/^\.\/+/, ''); // strip leading ./
|
|
8
|
+
v = v.replace(/\/+/g, '/'); // collapse multiple slashes
|
|
9
|
+
// if the path includes /src/, make it relative to src
|
|
10
|
+
v = v.replace(/^.*\/src(\/|$)/, '/'); // ".../src/foo" → "/foo"
|
|
11
|
+
if (!v.startsWith('/')) v = '/' + v; // ensure leading slash
|
|
12
|
+
// strip trailing slash except for root
|
|
13
|
+
if (v.length > 1 && v.endsWith('/')) v = v.slice(0, -1);
|
|
14
|
+
|
|
15
|
+
return v.toLowerCase(); // case-insensitive
|
|
16
|
+
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const normalizePattern = (p) => {
|
|
20
|
+
|
|
21
|
+
let v = String(p).replace(/\\/g, '/').replace(/^\.\/+/, '').replace(/\/+/g, '/');
|
|
22
|
+
|
|
23
|
+
if (!v.includes('*') && !v.includes('.') && !v.endsWith('/')) v += '/';
|
|
24
|
+
if (!v.startsWith('/')) v = '/' + v;
|
|
25
|
+
|
|
26
|
+
return v.toLowerCase(); // case-insensitive
|
|
27
|
+
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const pathCandidates = (() => {
|
|
31
|
+
|
|
32
|
+
const p = normalizePath(filePath);
|
|
33
|
+
const noSrc = String(filePath).replace(/\\/g, '/').replace(/^\.\/+/, '');
|
|
34
|
+
const alt = (noSrc.startsWith('/') ? noSrc : '/' + noSrc).toLowerCase();
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
return Array.from(new Set([ p, alt ]));
|
|
38
|
+
|
|
39
|
+
})();
|
|
40
|
+
|
|
41
|
+
const matches = (fp, pat) => {
|
|
42
|
+
|
|
43
|
+
// 1) "*.ext" anywhere
|
|
44
|
+
if (/^\/\*\.[^/]+$/.test(pat)) {
|
|
45
|
+
|
|
46
|
+
const ext = pat.slice(2); // "*.js" -> ".js"
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
return fp.endsWith(ext);
|
|
50
|
+
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// 2) "folder/*" => only immediate children (no subfolders)
|
|
54
|
+
if (pat.endsWith('/*')) {
|
|
55
|
+
|
|
56
|
+
const base = pat.slice(0, -2);
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
return fp.startsWith(base + '/') && !fp.slice(base.length + 1).includes('/');
|
|
60
|
+
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// 3) "folder/*.ext" => files with ext in that folder (no subfolders)
|
|
64
|
+
if (pat.includes('/*')) {
|
|
65
|
+
|
|
66
|
+
const [ base, tail ] = pat.split('/*');
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
return fp.startsWith(base + '/') &&
|
|
70
|
+
fp.endsWith(tail) &&
|
|
71
|
+
!fp.slice(base.length + 1).includes('/');
|
|
72
|
+
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// 4) Plain directory "folder/" => whole dir + subdirs
|
|
76
|
+
if (pat.endsWith('/')) {
|
|
77
|
+
|
|
78
|
+
const base = pat.slice(0, -1);
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
return fp === base || fp.startsWith(base + '/');
|
|
82
|
+
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// 5) Exact file
|
|
86
|
+
return fp === pat;
|
|
87
|
+
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
return ignorePatterns.some((raw) => {
|
|
91
|
+
|
|
92
|
+
const pat = normalizePattern(raw);
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
return pathCandidates.some((fp) => matches(fp, pat));
|
|
96
|
+
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
}
|
package/src/thingType.js
CHANGED
|
@@ -1,35 +1,73 @@
|
|
|
1
|
-
import isUUID from './isUUID.js'
|
|
1
|
+
import isUUID from './isUUID.js';
|
|
2
|
+
|
|
2
3
|
export default (thing) => {
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
if (thing === undefined) {
|
|
6
|
+
|
|
7
|
+
return 'undefined';
|
|
8
|
+
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
if (thing === null) {
|
|
12
|
+
|
|
13
|
+
return 'null';
|
|
14
|
+
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let type = typeof thing;
|
|
18
|
+
|
|
19
|
+
let same = [ 'undefined', 'null', 'boolean', 'function', 'symbol', 'bigint' ].includes(type);
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
if (same) {
|
|
23
|
+
|
|
24
|
+
return type;
|
|
25
|
+
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// array vs object
|
|
29
|
+
if (type === 'object' && thing !== null) {
|
|
30
|
+
|
|
31
|
+
type = Array.isArray(thing) ? 'array' : 'object';
|
|
32
|
+
|
|
33
|
+
return type;
|
|
34
|
+
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// integer vs double
|
|
38
|
+
if (type === 'number') {
|
|
39
|
+
|
|
40
|
+
type = Number.isInteger(thing) ? 'integer' : 'number';
|
|
41
|
+
|
|
42
|
+
return type;
|
|
43
|
+
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// string vs iso timestamp vs uuid
|
|
47
|
+
let is_uuid = isUUID(thing);
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
if(is_uuid){
|
|
51
|
+
|
|
52
|
+
type = 'uuid';
|
|
53
|
+
|
|
54
|
+
return type;
|
|
55
|
+
|
|
56
|
+
}
|
|
6
57
|
|
|
7
|
-
|
|
58
|
+
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?$/);
|
|
8
59
|
|
|
9
|
-
let same = ['undefined', 'null', 'boolean', 'function', 'symbol', 'bigint'].includes(type);
|
|
10
|
-
if (same) { return type; }
|
|
11
60
|
|
|
12
|
-
|
|
13
|
-
if (type === 'object' && thing !== null) {
|
|
14
|
-
type = Array.isArray(thing) ? 'array' : 'object';
|
|
15
|
-
return type;
|
|
16
|
-
}
|
|
61
|
+
if(is_iso_dateTime) {
|
|
17
62
|
|
|
18
|
-
|
|
19
|
-
if (type === 'number') {
|
|
20
|
-
type = Number.isInteger(thing) ? 'integer' : 'number';
|
|
21
|
-
return type;
|
|
22
|
-
}
|
|
63
|
+
type = 'timestamp';
|
|
23
64
|
|
|
24
|
-
|
|
25
|
-
let is_uuid = isUUID(thing);
|
|
26
|
-
if(is_uuid){ type = 'uuid'; return type; }
|
|
65
|
+
return type;
|
|
27
66
|
|
|
28
|
-
|
|
29
|
-
if(is_iso_dateTime) { type = 'timestamp'; return type; }
|
|
67
|
+
}
|
|
30
68
|
|
|
31
|
-
|
|
69
|
+
return type;
|
|
32
70
|
|
|
33
|
-
|
|
34
|
-
}
|
|
71
|
+
|
|
72
|
+
};
|
|
35
73
|
|
package/src/toPennies.js
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
export default function toPennies(uglyMoney){
|
|
2
2
|
|
|
3
|
-
if(!uglyMoney){
|
|
4
|
-
|
|
3
|
+
if(!uglyMoney){
|
|
4
|
+
|
|
5
|
+
return 0;
|
|
6
|
+
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
if(uglyMoney.length == 0){
|
|
10
|
+
|
|
11
|
+
return 0;
|
|
12
|
+
|
|
13
|
+
}
|
|
5
14
|
|
|
6
15
|
// trim all whitespace from string
|
|
7
16
|
uglyMoney = uglyMoney.replace(/\s/g,'');
|
|
@@ -9,11 +18,20 @@ export default function toPennies(uglyMoney){
|
|
|
9
18
|
let hasDecimal = uglyMoney.includes(".");
|
|
10
19
|
let cleanMoney_v1 = uglyMoney.replace(/\D/g,'');
|
|
11
20
|
|
|
12
|
-
if(cleanMoney_v1.length == 0){
|
|
21
|
+
if(cleanMoney_v1.length == 0){
|
|
22
|
+
|
|
23
|
+
return 0;
|
|
24
|
+
|
|
25
|
+
}
|
|
13
26
|
|
|
14
27
|
let cleanMoney = cleanMoney_v1*1;
|
|
15
28
|
|
|
16
|
-
if(!hasDecimal){
|
|
29
|
+
if(!hasDecimal){
|
|
30
|
+
|
|
31
|
+
cleanMoney = cleanMoney * 100;
|
|
32
|
+
|
|
33
|
+
}
|
|
17
34
|
|
|
18
35
|
return cleanMoney;
|
|
19
|
-
|
|
36
|
+
|
|
37
|
+
}
|