5etools-utils 0.15.4 → 0.15.6
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/BrewCleaner.js +3 -11
- 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,
|
package/lib/BrewCleaner.js
CHANGED
|
@@ -158,7 +158,7 @@ export class BrewCleaner {
|
|
|
158
158
|
jsonOut = getCleanJson(jsonOut);
|
|
159
159
|
|
|
160
160
|
if (isDry) {
|
|
161
|
-
if (jsonOut !== raw)
|
|
161
|
+
if (jsonOut !== raw) Um.warn(`CLEANER`, `"${file}" would be reformatted!`);
|
|
162
162
|
continue;
|
|
163
163
|
}
|
|
164
164
|
|
|
@@ -170,27 +170,19 @@ export class BrewCleaner {
|
|
|
170
170
|
throw new Error(`Errors were found. See above.`);
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
return
|
|
173
|
+
return files.length;
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
static run ({isDry = false} = {}) {
|
|
177
177
|
const tStart = Date.now();
|
|
178
178
|
|
|
179
179
|
let ttlFiles = 0;
|
|
180
|
-
let ttlErrors = 0;
|
|
181
180
|
|
|
182
181
|
Uf.runOnDirs((dir) => {
|
|
183
182
|
Um.info(`CLEANER`, `${isDry ? "Checking" : "Cleaning"} dir "${dir}"...`);
|
|
184
|
-
|
|
185
|
-
ttlFiles += cntFiles;
|
|
186
|
-
ttlErrors += cntErrors;
|
|
183
|
+
ttlFiles += this._cleanFolder({dir, isDry});
|
|
187
184
|
});
|
|
188
185
|
|
|
189
186
|
Um.info(`CLEANER`, `${isDry ? "Check" : "Cleaning"} complete. ${isDry ? "Checked" : "Cleaned"} ${ttlFiles} file${ttlFiles === 1 ? "" : "s"}. Ran in ${((Date.now() - tStart) / 1000).toFixed(2)}s.`);
|
|
190
|
-
|
|
191
|
-
if (ttlErrors && isDry) {
|
|
192
|
-
Um.info(`CLEANER`, `Found ${ttlErrors} error${ttlErrors === 1 ? "" : "s"}!`);
|
|
193
|
-
process.exit(1);
|
|
194
|
-
}
|
|
195
187
|
}
|
|
196
188
|
}
|
|
@@ -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.6",
|
|
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",
|