5etools-utils 0.15.4 → 0.15.5
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 +1 -1
- package/bin/test-img-file-extensions.js +5 -0
- package/bin/test-img-file-sizes.js +5 -0
- package/bin/test-img-source-names-brew.js +5 -0
- package/bin/test-img-source-names-ua.js +5 -0
- package/lib/Api.js +2 -0
- package/lib/BrewTesterImg/BrewTesterImgConsts.js +31 -0
- package/lib/BrewTesterImg/BrewTesterImgFileExtensions.js +34 -0
- package/lib/BrewTesterImg/BrewTesterImgFileSizes.js +33 -0
- package/lib/BrewTesterImg/BrewTesterImgSourceNames.js +38 -0
- package/lib/BrewTesterImg.js +9 -0
- package/lib/UtilSource.js +70 -25
- package/package.json +6 -2
package/README.md
CHANGED
package/lib/Api.js
CHANGED
|
@@ -6,6 +6,7 @@ import {BrewCleaner} from "./BrewCleaner.js";
|
|
|
6
6
|
import {BrewCleanerHtml} from "./BrewCleanerHtml.js";
|
|
7
7
|
import {BrewTimestamper} from "./BrewTimestamper.js";
|
|
8
8
|
import {BrewTester} from "./BrewTester.js";
|
|
9
|
+
import {BrewTesterImg} from "./BrewTesterImg.js";
|
|
9
10
|
import {getCleanJson, getCleanString} from "./UtilClean.js";
|
|
10
11
|
import {DataTester, DataTesterBase, BraceCheck, EscapeCharacterCheck} from "./TestData.js";
|
|
11
12
|
import {ObjectWalker, SymObjectWalkerBreak} from "./ObjectWalker.js";
|
|
@@ -20,6 +21,7 @@ export {
|
|
|
20
21
|
BrewCleanerHtml,
|
|
21
22
|
BrewTimestamper,
|
|
22
23
|
BrewTester,
|
|
24
|
+
BrewTesterImg,
|
|
23
25
|
getCleanJson,
|
|
24
26
|
getCleanString,
|
|
25
27
|
DataTester,
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export const IMG_SOURCE_DIRS = [
|
|
2
|
+
"font",
|
|
3
|
+
"img",
|
|
4
|
+
"pdf",
|
|
5
|
+
];
|
|
6
|
+
|
|
7
|
+
export const IMG_ALLOWED_EXTENSIONS = {
|
|
8
|
+
"audio": new Set([
|
|
9
|
+
"mp3",
|
|
10
|
+
"wav",
|
|
11
|
+
]),
|
|
12
|
+
"font": new Set([
|
|
13
|
+
"otf",
|
|
14
|
+
"ttf",
|
|
15
|
+
"woff",
|
|
16
|
+
"woff2",
|
|
17
|
+
]),
|
|
18
|
+
"img": new Set([
|
|
19
|
+
"gif",
|
|
20
|
+
"jpeg",
|
|
21
|
+
"jpg",
|
|
22
|
+
"png",
|
|
23
|
+
"svg",
|
|
24
|
+
"webp",
|
|
25
|
+
]),
|
|
26
|
+
"pdf": new Set([
|
|
27
|
+
"pdf",
|
|
28
|
+
]),
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const MAX_IMG_FILE_SIZE_BYTES = 25 * 1024 * 1024;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import {lsRecursiveSync} from "../UtilFs.js";
|
|
3
|
+
import Um from "../UtilMisc.js";
|
|
4
|
+
import {BrewTesterBase} from "../BrewTester/BrewTesterBase.js";
|
|
5
|
+
import {IMG_ALLOWED_EXTENSIONS} from "./BrewTesterImgConsts.js";
|
|
6
|
+
|
|
7
|
+
export class BrewTesterImgFileExtensions extends BrewTesterBase {
|
|
8
|
+
_LOG_TAG = "FILE_EXT";
|
|
9
|
+
|
|
10
|
+
constructor ({allowedExtensions = null} = {}) {
|
|
11
|
+
super();
|
|
12
|
+
this._allowedExtensions = allowedExtensions || IMG_ALLOWED_EXTENSIONS;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async _pRun () {
|
|
16
|
+
Um.info(this._LOG_TAG, `Testing for incorrect file extensions...`);
|
|
17
|
+
|
|
18
|
+
const badPaths = Object.entries(this._allowedExtensions)
|
|
19
|
+
.flatMap(([dirName, allowedExts]) => {
|
|
20
|
+
if (!fs.existsSync(dirName) || !fs.statSync(dirName).isDirectory()) return [];
|
|
21
|
+
|
|
22
|
+
return lsRecursiveSync(dirName)
|
|
23
|
+
.filter(filePath => {
|
|
24
|
+
const ext = filePath.split(".").at(-1).toLowerCase();
|
|
25
|
+
return !allowedExts.has(ext);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
if (!badPaths.length) return Um.info(this._LOG_TAG, `Files had expected extensions.`);
|
|
30
|
+
|
|
31
|
+
badPaths.forEach(filePath => Um.error(this._LOG_TAG, `File extension not in allowlist: ${filePath}`));
|
|
32
|
+
throw new Error(`Test failed! See above for more info`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import {lsRecursiveSync} from "../UtilFs.js";
|
|
3
|
+
import Um from "../UtilMisc.js";
|
|
4
|
+
import {BrewTesterBase} from "../BrewTester/BrewTesterBase.js";
|
|
5
|
+
import {IMG_SOURCE_DIRS, MAX_IMG_FILE_SIZE_BYTES} from "./BrewTesterImgConsts.js";
|
|
6
|
+
|
|
7
|
+
export class BrewTesterImgFileSizes extends BrewTesterBase {
|
|
8
|
+
_LOG_TAG = "FILE_SIZE";
|
|
9
|
+
|
|
10
|
+
constructor ({dirsSource = null, maxSizeBytes = null} = {}) {
|
|
11
|
+
super();
|
|
12
|
+
this._dirsSource = dirsSource || IMG_SOURCE_DIRS;
|
|
13
|
+
this._maxSizeBytes = maxSizeBytes || MAX_IMG_FILE_SIZE_BYTES;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async _pRun () {
|
|
17
|
+
const maxSizeMb = this._maxSizeBytes / (1024 * 1024);
|
|
18
|
+
Um.info(this._LOG_TAG, `Testing for file sizes <= ${maxSizeMb} MiB...`);
|
|
19
|
+
|
|
20
|
+
const badPaths = this._dirsSource
|
|
21
|
+
.flatMap(dirName => {
|
|
22
|
+
if (!fs.existsSync(dirName) || !fs.statSync(dirName).isDirectory()) return [];
|
|
23
|
+
|
|
24
|
+
return lsRecursiveSync(dirName)
|
|
25
|
+
.filter(filePath => fs.statSync(filePath).size > this._maxSizeBytes);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
if (!badPaths.length) return Um.info(this._LOG_TAG, `Files had expected sizes.`);
|
|
29
|
+
|
|
30
|
+
badPaths.forEach(filePath => Um.error(this._LOG_TAG, `File larger than ${maxSizeMb} MiB: ${filePath}`));
|
|
31
|
+
throw new Error(`Test failed! See above for more info`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import Um from "../UtilMisc.js";
|
|
3
|
+
import {BrewTesterBase} from "../BrewTester/BrewTesterBase.js";
|
|
4
|
+
import {IMG_SOURCE_DIRS} from "./BrewTesterImgConsts.js";
|
|
5
|
+
import {UtilSource} from "../UtilSource.js";
|
|
6
|
+
|
|
7
|
+
export class BrewTesterImgSourceNames extends BrewTesterBase {
|
|
8
|
+
_LOG_TAG = "SRC_NAME";
|
|
9
|
+
|
|
10
|
+
constructor ({dirsSource = null, isPrerelease = false} = {}) {
|
|
11
|
+
super();
|
|
12
|
+
this._dirsSource = dirsSource || IMG_SOURCE_DIRS;
|
|
13
|
+
this._isPrerelease = isPrerelease;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async _pRun () {
|
|
17
|
+
const sourceType = this._isPrerelease ? "prerelease" : "homebrew";
|
|
18
|
+
Um.info(this._LOG_TAG, `Testing for valid ${sourceType} source names...`);
|
|
19
|
+
|
|
20
|
+
const fnIsValidSource = this._isPrerelease
|
|
21
|
+
? UtilSource.isValidPrereleaseSource.bind(UtilSource)
|
|
22
|
+
: UtilSource.isValidHomebrewSource.bind(UtilSource);
|
|
23
|
+
|
|
24
|
+
const badNames = this._dirsSource
|
|
25
|
+
.flatMap(dirName => {
|
|
26
|
+
if (!fs.existsSync(dirName) || !fs.statSync(dirName).isDirectory()) return [];
|
|
27
|
+
|
|
28
|
+
return fs.readdirSync(dirName)
|
|
29
|
+
.filter(name => fs.statSync(`${dirName}/${name}`).isDirectory())
|
|
30
|
+
.filter(name => !fnIsValidSource(name));
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
if (!badNames.length) return Um.info(this._LOG_TAG, `Directory names had expected sources.`);
|
|
34
|
+
|
|
35
|
+
badNames.forEach(name => Um.error(this._LOG_TAG, `Invalid ${sourceType} source directory name: ${name}`));
|
|
36
|
+
throw new Error(`Test failed! See above for more info`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import {BrewTesterImgFileExtensions} from "./BrewTesterImg/BrewTesterImgFileExtensions.js";
|
|
2
|
+
import {BrewTesterImgFileSizes} from "./BrewTesterImg/BrewTesterImgFileSizes.js";
|
|
3
|
+
import {BrewTesterImgSourceNames} from "./BrewTesterImg/BrewTesterImgSourceNames.js";
|
|
4
|
+
|
|
5
|
+
export class BrewTesterImg {
|
|
6
|
+
static pTestFileExtensions ({allowedExtensions} = {}) { return (new BrewTesterImgFileExtensions({allowedExtensions})).pRun(); }
|
|
7
|
+
static pTestFileSizes ({dirsSource, maxSizeBytes} = {}) { return (new BrewTesterImgFileSizes({dirsSource, maxSizeBytes})).pRun(); }
|
|
8
|
+
static pTestSourceNames ({dirsSource, isPrerelease} = {}) { return (new BrewTesterImgSourceNames({dirsSource, isPrerelease})).pRun(); }
|
|
9
|
+
}
|
package/lib/UtilSource.js
CHANGED
|
@@ -23,31 +23,76 @@ export class UtilSource {
|
|
|
23
23
|
/* -------------------------------------------- */
|
|
24
24
|
|
|
25
25
|
static _HOMEBREW_SOURCE_VALIDATOR = null;
|
|
26
|
+
static _PRERELEASE_SOURCE_VALIDATOR = null;
|
|
26
27
|
|
|
27
|
-
static
|
|
28
|
-
if (
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return this._HOMEBREW_SOURCE_VALIDATOR
|
|
28
|
+
static _getHomebrewSourceValidator () {
|
|
29
|
+
if (this._HOMEBREW_SOURCE_VALIDATOR) return this._HOMEBREW_SOURCE_VALIDATOR;
|
|
30
|
+
|
|
31
|
+
this._HOMEBREW_SOURCE_VALIDATOR = UtilAjv.getValidator();
|
|
32
|
+
|
|
33
|
+
[
|
|
34
|
+
"util.json",
|
|
35
|
+
"sources-homebrew-legacy.json",
|
|
36
|
+
"sources-5etools.json",
|
|
37
|
+
]
|
|
38
|
+
.forEach(fname => {
|
|
39
|
+
this._HOMEBREW_SOURCE_VALIDATOR.addSchema(
|
|
40
|
+
Uf.readJsonSync(path.join(path.join(__dirname, "..", "schema", "brew", fname))),
|
|
41
|
+
fname,
|
|
42
|
+
);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
this._HOMEBREW_SOURCE_VALIDATOR.addSchema(
|
|
46
|
+
{
|
|
47
|
+
"$ref": "util.json#/$defs/sourceJson",
|
|
48
|
+
},
|
|
49
|
+
"homebrewSource",
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
return this._HOMEBREW_SOURCE_VALIDATOR;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
static _getPrereleaseSourceValidator () {
|
|
56
|
+
if (this._PRERELEASE_SOURCE_VALIDATOR) return this._PRERELEASE_SOURCE_VALIDATOR;
|
|
57
|
+
|
|
58
|
+
this._PRERELEASE_SOURCE_VALIDATOR = UtilAjv.getValidator();
|
|
59
|
+
|
|
60
|
+
[
|
|
61
|
+
"util.json",
|
|
62
|
+
]
|
|
63
|
+
.forEach(fname => {
|
|
64
|
+
this._PRERELEASE_SOURCE_VALIDATOR.addSchema(
|
|
65
|
+
Uf.readJsonSync(path.join(path.join(__dirname, "..", "schema", "brew", fname))),
|
|
66
|
+
fname,
|
|
67
|
+
);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
this._PRERELEASE_SOURCE_VALIDATOR.addSchema(
|
|
71
|
+
{
|
|
72
|
+
"type": "string",
|
|
73
|
+
"allOf": [
|
|
74
|
+
{
|
|
75
|
+
"$ref": "util.json#/$defs/_sourceString",
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"minLength": 6,
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"pattern": "^(?:UA|XUA)[-a-zA-Z0-9&+!]+$",
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
},
|
|
85
|
+
"prereleaseSource",
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
return this._PRERELEASE_SOURCE_VALIDATOR;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
static isValidHomebrewSource (source) {
|
|
92
|
+
return this._getHomebrewSourceValidator().validate("homebrewSource", source);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
static isValidPrereleaseSource (source) {
|
|
96
|
+
return this._getPrereleaseSourceValidator().validate("prereleaseSource", source);
|
|
52
97
|
}
|
|
53
98
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "5etools-utils",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.5",
|
|
4
4
|
"description": "Shared utilities for the 5etools ecosystem.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/Api.js",
|
|
@@ -19,7 +19,11 @@
|
|
|
19
19
|
"test-file-names": "bin/test-file-names.js",
|
|
20
20
|
"test-file-locations": "bin/test-file-locations.js",
|
|
21
21
|
"test-file-props": "bin/test-file-props.js",
|
|
22
|
-
"test-edition-sources": "bin/test-edition-sources.js"
|
|
22
|
+
"test-edition-sources": "bin/test-edition-sources.js",
|
|
23
|
+
"test-img-file-extensions": "bin/test-img-file-extensions.js",
|
|
24
|
+
"test-img-file-sizes": "bin/test-img-file-sizes.js",
|
|
25
|
+
"test-img-source-names-brew": "bin/test-img-source-names-brew.js",
|
|
26
|
+
"test-img-source-names-ua": "bin/test-img-source-names-ua.js"
|
|
23
27
|
},
|
|
24
28
|
"scripts": {
|
|
25
29
|
"build:dangerous:sources": "node node/fetch-5etools-sources.js",
|