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 CHANGED
@@ -10,4 +10,4 @@ npx test-json-brew [file] [--dir <dir>]
10
10
  npx test-json-ua [file] [--dir <dir>]
11
11
  ```
12
12
 
13
- Programmatic: `BrewTester` includes helpers such as `pTestImgDirectories({dirAllowlist, pathImgDir})`.
13
+ And more; see `bin/`.
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {BrewTesterImg} from "../lib/BrewTesterImg.js";
4
+
5
+ await BrewTesterImg.pTestFileExtensions();
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {BrewTesterImg} from "../lib/BrewTesterImg.js";
4
+
5
+ await BrewTesterImg.pTestFileSizes();
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {BrewTesterImg} from "../lib/BrewTesterImg.js";
4
+
5
+ await BrewTesterImg.pTestSourceNames();
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {BrewTesterImg} from "../lib/BrewTesterImg.js";
4
+
5
+ await BrewTesterImg.pTestSourceNames({isPrerelease: true});
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,
@@ -158,7 +158,7 @@ export class BrewCleaner {
158
158
  jsonOut = getCleanJson(jsonOut);
159
159
 
160
160
  if (isDry) {
161
- if (jsonOut !== raw) ALL_ERRORS.push(`${file} would be reformatted!`);
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 {cntFiles: files.length, cntErrors: ALL_ERRORS.length};
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
- const {cntFiles, cntErrors} = this._cleanFolder({dir, isDry});
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 isValidHomebrewSorce (source) {
28
- if (!this._HOMEBREW_SOURCE_VALIDATOR) {
29
- this._HOMEBREW_SOURCE_VALIDATOR = UtilAjv.getValidator();
30
-
31
- [
32
- "util.json",
33
- "sources-homebrew-legacy.json",
34
- "sources-5etools.json",
35
- ]
36
- .forEach(fname => {
37
- this._HOMEBREW_SOURCE_VALIDATOR.addSchema(
38
- Uf.readJsonSync(path.join(path.join(__dirname, "..", "schema", "brew", fname))),
39
- fname,
40
- );
41
- });
42
-
43
- this._HOMEBREW_SOURCE_VALIDATOR.addSchema(
44
- {
45
- "$ref": "util.json#/$defs/sourceJson",
46
- },
47
- "homebrewSource",
48
- );
49
- }
50
-
51
- return this._HOMEBREW_SOURCE_VALIDATOR.validate("homebrewSource", source);
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.4",
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",