5etools-utils 0.3.0 → 0.3.1
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/lib/Api.js +1 -1
- package/lib/TestJson.js +43 -19
- package/lib/UtilMisc.js +36 -17
- package/package.json +4 -2
- package/schema/brew/bestiary/fluff-index.json +11 -0
- package/schema/brew/bestiary/index.json +11 -0
- package/schema/brew/changelog.json +35 -0
- package/schema/brew/class/index.json +11 -0
- package/schema/brew/life.json +17 -0
- package/schema/brew/spells/fluff-index.json +11 -0
- package/schema/brew/spells/index.json +11 -0
- package/schema/brew-fast/bestiary/fluff-index.json +11 -0
- package/schema/brew-fast/bestiary/index.json +11 -0
- package/schema/brew-fast/changelog.json +35 -0
- package/schema/brew-fast/class/index.json +11 -0
- package/schema/brew-fast/life.json +17 -0
- package/schema/brew-fast/spells/fluff-index.json +11 -0
- package/schema/brew-fast/spells/index.json +11 -0
- package/schema/site/bestiary/fluff-index.json +11 -0
- package/schema/site/bestiary/index.json +11 -0
- package/schema/site/changelog.json +35 -0
- package/schema/site/class/index.json +11 -0
- package/schema/site/life.json +17 -0
- package/schema/site/spells/fluff-index.json +11 -0
- package/schema/site/spells/index.json +11 -0
- package/schema/site-fast/bestiary/fluff-index.json +11 -0
- package/schema/site-fast/bestiary/index.json +11 -0
- package/schema/site-fast/changelog.json +35 -0
- package/schema/site-fast/class/index.json +11 -0
- package/schema/site-fast/life.json +17 -0
- package/schema/site-fast/spells/fluff-index.json +11 -0
- package/schema/site-fast/spells/index.json +11 -0
package/lib/Api.js
CHANGED
package/lib/TestJson.js
CHANGED
|
@@ -7,8 +7,8 @@ import Ajv2020 from "ajv/dist/2020.js";
|
|
|
7
7
|
import addFormats from "ajv-formats";
|
|
8
8
|
import * as jsonSourceMap from "json-source-map";
|
|
9
9
|
|
|
10
|
-
import * as
|
|
11
|
-
import
|
|
10
|
+
import * as Uf from "./UtilFs.js";
|
|
11
|
+
import Um from "./UtilMisc.js";
|
|
12
12
|
import {WorkerList, Deferred} from "./WorkerList.js";
|
|
13
13
|
|
|
14
14
|
const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
|
|
@@ -23,12 +23,20 @@ class JsonTester {
|
|
|
23
23
|
|
|
24
24
|
constructor (
|
|
25
25
|
{
|
|
26
|
-
|
|
26
|
+
fnGetSchemaId,
|
|
27
|
+
|
|
28
|
+
isBrew = false,
|
|
29
|
+
dirSchema = null,
|
|
27
30
|
tagLog = LOG_TAG,
|
|
28
|
-
fnGetSchemaId = () => "homebrew.json",
|
|
29
31
|
},
|
|
30
32
|
) {
|
|
31
|
-
|
|
33
|
+
if (isBrew && dirSchema) throw new Error(`"isBrew" and "dirSchema" are mutually exclusive!`);
|
|
34
|
+
if (!fnGetSchemaId) throw new Error(`"fnGetSchemaId" is required!`);
|
|
35
|
+
|
|
36
|
+
this._dirSchema = dirSchema ??
|
|
37
|
+
(isBrew
|
|
38
|
+
? path.join(__dirname, "..", "schema", "brew")
|
|
39
|
+
: path.join(__dirname, "..", "schema", "site"));
|
|
32
40
|
this._tagLog = tagLog;
|
|
33
41
|
this._fnGetSchemaId = fnGetSchemaId;
|
|
34
42
|
|
|
@@ -98,7 +106,7 @@ class JsonTester {
|
|
|
98
106
|
});
|
|
99
107
|
|
|
100
108
|
const error = this._getFileErrors({filePath});
|
|
101
|
-
|
|
109
|
+
Um.error(this._tagLog, error);
|
|
102
110
|
out.errors.push(error);
|
|
103
111
|
|
|
104
112
|
return out;
|
|
@@ -107,10 +115,10 @@ class JsonTester {
|
|
|
107
115
|
_doLoadSchema () {
|
|
108
116
|
if (this._isSchemaLoaded) return;
|
|
109
117
|
|
|
110
|
-
|
|
118
|
+
Uf.listJsonFiles(this._dirSchema)
|
|
111
119
|
.forEach(filePath => {
|
|
112
120
|
filePath = path.normalize(filePath);
|
|
113
|
-
const contents =
|
|
121
|
+
const contents = Uf.readJSON(filePath);
|
|
114
122
|
|
|
115
123
|
const relativeFilePath = path.relative(this._dirSchema, filePath)
|
|
116
124
|
.replace(/\\/g, "/");
|
|
@@ -121,12 +129,17 @@ class JsonTester {
|
|
|
121
129
|
this._isSchemaLoaded = true;
|
|
122
130
|
}
|
|
123
131
|
|
|
132
|
+
_hasSchema (schemaId) {
|
|
133
|
+
this._doLoadSchema();
|
|
134
|
+
return !!this._ajv.schemas[schemaId];
|
|
135
|
+
}
|
|
136
|
+
|
|
124
137
|
getFileErrors ({filePath} = {}) {
|
|
125
138
|
this._doLoadSchema();
|
|
126
139
|
|
|
127
|
-
|
|
140
|
+
Um.info(this._tagLog, `\tValidating "${filePath}"...`);
|
|
128
141
|
|
|
129
|
-
const data =
|
|
142
|
+
const data = Uf.readJSON(filePath);
|
|
130
143
|
this._addImplicits(data);
|
|
131
144
|
|
|
132
145
|
const isValid = this._ajv.validate(this._fnGetSchemaId(filePath), data);
|
|
@@ -136,7 +149,7 @@ class JsonTester {
|
|
|
136
149
|
}
|
|
137
150
|
|
|
138
151
|
_doRunOnDir ({isFailFast, dir, errors, errorsFull, ...opts} = {}) {
|
|
139
|
-
for (const filePath of
|
|
152
|
+
for (const filePath of Uf.listJsonFiles(dir, opts)) {
|
|
140
153
|
const {errors: errorsFile, errorsFull: errorsFullFile} = this.getFileErrors({filePath});
|
|
141
154
|
errors.push(...errorsFile);
|
|
142
155
|
errorsFull.push(...errorsFullFile);
|
|
@@ -150,7 +163,7 @@ class JsonTester {
|
|
|
150
163
|
* @param [opts.dirBlocklist]
|
|
151
164
|
*/
|
|
152
165
|
getErrors (dir, opts = {}) {
|
|
153
|
-
|
|
166
|
+
Um.info(this._tagLog, `Validating JSON against schema`);
|
|
154
167
|
|
|
155
168
|
const errors = [];
|
|
156
169
|
const errorsFull = [];
|
|
@@ -161,12 +174,12 @@ class JsonTester {
|
|
|
161
174
|
}
|
|
162
175
|
|
|
163
176
|
getErrorsOnDirs ({isFailFast = false} = {}) {
|
|
164
|
-
|
|
177
|
+
Um.info(this._tagLog, `Validating JSON against schema`);
|
|
165
178
|
|
|
166
179
|
const errors = [];
|
|
167
180
|
const errorsFull = [];
|
|
168
181
|
|
|
169
|
-
|
|
182
|
+
Uf.runOnDirs((dir) => {
|
|
170
183
|
if (isFailFast && errors.length) return;
|
|
171
184
|
return this._doRunOnDir({isFailFast, errors, errorsFull, dir});
|
|
172
185
|
});
|
|
@@ -174,19 +187,30 @@ class JsonTester {
|
|
|
174
187
|
return {errors, errorsFull};
|
|
175
188
|
}
|
|
176
189
|
|
|
177
|
-
async pGetErrorsOnDirsWorkers ({isFailFast = false} = {}) {
|
|
178
|
-
|
|
190
|
+
async pGetErrorsOnDirsWorkers ({isFailFast = false, fileList = null} = {}) {
|
|
191
|
+
Um.info(this._tagLog, `Validating JSON against schema`);
|
|
179
192
|
|
|
180
193
|
const cntWorkers = Math.max(1, os.cpus().length - 1);
|
|
181
194
|
|
|
182
195
|
const errors = [];
|
|
183
196
|
const errorsFull = [];
|
|
184
197
|
|
|
185
|
-
const fileQueue = [];
|
|
198
|
+
const fileQueue = [...(fileList || [])];
|
|
186
199
|
|
|
187
|
-
|
|
188
|
-
|
|
200
|
+
if (!fileList) {
|
|
201
|
+
Uf.runOnDirs((dir) => {
|
|
202
|
+
fileQueue.push(...Uf.listJsonFiles(dir));
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// region Verify that every file path maps to a valid schema
|
|
207
|
+
fileQueue.forEach(filePath => {
|
|
208
|
+
const schemaId = this._fnGetSchemaId(filePath);
|
|
209
|
+
if (!schemaId) throw new Error(`Failed to get schema ID for file path "${filePath}"`);
|
|
210
|
+
if (!this._hasSchema(schemaId)) throw new Error(`No schema loaded with schema ID "${schemaId}"`);
|
|
211
|
+
return schemaId;
|
|
189
212
|
});
|
|
213
|
+
// endregion
|
|
190
214
|
|
|
191
215
|
const workerList = new WorkerList();
|
|
192
216
|
|
package/lib/UtilMisc.js
CHANGED
|
@@ -1,22 +1,41 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
fn(`[${expandedTag}]`, ...args);
|
|
4
|
-
}
|
|
1
|
+
class MiscUtil {
|
|
2
|
+
/* -------------------------------------------- */
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
_taggedConsole(
|
|
8
|
-
|
|
4
|
+
// region Logging
|
|
5
|
+
static _taggedConsole (fn, tag, ...args) {
|
|
6
|
+
const expandedTag = tag.padStart(12, " ");
|
|
7
|
+
fn(`[${expandedTag}]`, ...args);
|
|
8
|
+
}
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
_taggedConsole(console.info, tag, ...args);
|
|
12
|
-
}
|
|
10
|
+
static warn (tag, ...args) { this._taggedConsole(console.warn, tag, ...args); }
|
|
11
|
+
static info (tag, ...args) { this._taggedConsole(console.info, tag, ...args); }
|
|
12
|
+
static error (tag, ...args) { this._taggedConsole(console.error, tag, ...args); }
|
|
13
|
+
// endregion
|
|
14
|
+
|
|
15
|
+
/* -------------------------------------------- */
|
|
16
|
+
|
|
17
|
+
static get (object, ...path) {
|
|
18
|
+
if (object == null) return null;
|
|
19
|
+
for (let i = 0; i < path.length; ++i) {
|
|
20
|
+
object = object[path[i]];
|
|
21
|
+
if (object == null) return object;
|
|
22
|
+
}
|
|
23
|
+
return object;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/* -------------------------------------------- */
|
|
27
|
+
|
|
28
|
+
static copyFast (obj) {
|
|
29
|
+
if ((typeof obj !== "object") || obj == null) return obj;
|
|
30
|
+
|
|
31
|
+
if (obj instanceof Array) return obj.map(MiscUtil.copyFast);
|
|
32
|
+
|
|
33
|
+
const cpy = {};
|
|
34
|
+
for (const k of Object.keys(obj)) cpy[k] = MiscUtil.copyFast(obj[k]);
|
|
35
|
+
return cpy;
|
|
36
|
+
}
|
|
13
37
|
|
|
14
|
-
|
|
15
|
-
_taggedConsole(console.error, tag, ...args);
|
|
38
|
+
/* -------------------------------------------- */
|
|
16
39
|
}
|
|
17
40
|
|
|
18
|
-
export
|
|
19
|
-
warn,
|
|
20
|
-
info,
|
|
21
|
-
error,
|
|
22
|
-
};
|
|
41
|
+
export default MiscUtil;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "5etools-utils",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Shared utilities for the 5etools ecosystem.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/Api.js",
|
|
@@ -12,9 +12,10 @@
|
|
|
12
12
|
"lib": "./lib"
|
|
13
13
|
},
|
|
14
14
|
"scripts": {
|
|
15
|
+
"build": "node node/compile-schemas.js",
|
|
15
16
|
"test": "npm run lint:js && npm run test:js",
|
|
16
17
|
"test:js": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
|
|
17
|
-
"lint:js": "eslint lib test --fix"
|
|
18
|
+
"lint:js": "eslint lib node test --fix"
|
|
18
19
|
},
|
|
19
20
|
"repository": {
|
|
20
21
|
"type": "git",
|
|
@@ -32,6 +33,7 @@
|
|
|
32
33
|
"json-source-map": "^0.6.1"
|
|
33
34
|
},
|
|
34
35
|
"devDependencies": {
|
|
36
|
+
"commander": "^9.4.1",
|
|
35
37
|
"eslint": "^8.11.0",
|
|
36
38
|
"jest": "^29.3.1"
|
|
37
39
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "changelog.json",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"type": "array",
|
|
6
|
+
"minItems": 1,
|
|
7
|
+
"uniqueItems": true,
|
|
8
|
+
"items": {
|
|
9
|
+
"type": "object",
|
|
10
|
+
"properties": {
|
|
11
|
+
"ver": {
|
|
12
|
+
"type": "string"
|
|
13
|
+
},
|
|
14
|
+
"date": {
|
|
15
|
+
"type": "string",
|
|
16
|
+
"format": "date"
|
|
17
|
+
},
|
|
18
|
+
"title": {
|
|
19
|
+
"type": "string"
|
|
20
|
+
},
|
|
21
|
+
"titleAlt": {
|
|
22
|
+
"type": "string"
|
|
23
|
+
},
|
|
24
|
+
"txt": {
|
|
25
|
+
"type": "string"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"required": [
|
|
29
|
+
"ver",
|
|
30
|
+
"date",
|
|
31
|
+
"txt"
|
|
32
|
+
],
|
|
33
|
+
"additionalProperties": false
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "life.json",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"lifeClass": true,
|
|
8
|
+
"lifeBackground": true,
|
|
9
|
+
"lifeTrinket": true
|
|
10
|
+
},
|
|
11
|
+
"required": [
|
|
12
|
+
"lifeClass",
|
|
13
|
+
"lifeBackground",
|
|
14
|
+
"lifeTrinket"
|
|
15
|
+
],
|
|
16
|
+
"additionalProperties": false
|
|
17
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "changelog.json",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"type": "array",
|
|
6
|
+
"minItems": 1,
|
|
7
|
+
"uniqueItems": true,
|
|
8
|
+
"items": {
|
|
9
|
+
"type": "object",
|
|
10
|
+
"properties": {
|
|
11
|
+
"ver": {
|
|
12
|
+
"type": "string"
|
|
13
|
+
},
|
|
14
|
+
"date": {
|
|
15
|
+
"type": "string",
|
|
16
|
+
"format": "date"
|
|
17
|
+
},
|
|
18
|
+
"title": {
|
|
19
|
+
"type": "string"
|
|
20
|
+
},
|
|
21
|
+
"titleAlt": {
|
|
22
|
+
"type": "string"
|
|
23
|
+
},
|
|
24
|
+
"txt": {
|
|
25
|
+
"type": "string"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"required": [
|
|
29
|
+
"ver",
|
|
30
|
+
"date",
|
|
31
|
+
"txt"
|
|
32
|
+
],
|
|
33
|
+
"additionalProperties": false
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "life.json",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"lifeClass": true,
|
|
8
|
+
"lifeBackground": true,
|
|
9
|
+
"lifeTrinket": true
|
|
10
|
+
},
|
|
11
|
+
"required": [
|
|
12
|
+
"lifeClass",
|
|
13
|
+
"lifeBackground",
|
|
14
|
+
"lifeTrinket"
|
|
15
|
+
],
|
|
16
|
+
"additionalProperties": false
|
|
17
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "changelog.json",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"type": "array",
|
|
6
|
+
"minItems": 1,
|
|
7
|
+
"uniqueItems": true,
|
|
8
|
+
"items": {
|
|
9
|
+
"type": "object",
|
|
10
|
+
"properties": {
|
|
11
|
+
"ver": {
|
|
12
|
+
"type": "string"
|
|
13
|
+
},
|
|
14
|
+
"date": {
|
|
15
|
+
"type": "string",
|
|
16
|
+
"format": "date"
|
|
17
|
+
},
|
|
18
|
+
"title": {
|
|
19
|
+
"type": "string"
|
|
20
|
+
},
|
|
21
|
+
"titleAlt": {
|
|
22
|
+
"type": "string"
|
|
23
|
+
},
|
|
24
|
+
"txt": {
|
|
25
|
+
"type": "string"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"required": [
|
|
29
|
+
"ver",
|
|
30
|
+
"date",
|
|
31
|
+
"txt"
|
|
32
|
+
],
|
|
33
|
+
"additionalProperties": false
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "life.json",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"lifeClass": true,
|
|
8
|
+
"lifeBackground": true,
|
|
9
|
+
"lifeTrinket": true
|
|
10
|
+
},
|
|
11
|
+
"required": [
|
|
12
|
+
"lifeClass",
|
|
13
|
+
"lifeBackground",
|
|
14
|
+
"lifeTrinket"
|
|
15
|
+
],
|
|
16
|
+
"additionalProperties": false
|
|
17
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "changelog.json",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"type": "array",
|
|
6
|
+
"minItems": 1,
|
|
7
|
+
"uniqueItems": true,
|
|
8
|
+
"items": {
|
|
9
|
+
"type": "object",
|
|
10
|
+
"properties": {
|
|
11
|
+
"ver": {
|
|
12
|
+
"type": "string"
|
|
13
|
+
},
|
|
14
|
+
"date": {
|
|
15
|
+
"type": "string",
|
|
16
|
+
"format": "date"
|
|
17
|
+
},
|
|
18
|
+
"title": {
|
|
19
|
+
"type": "string"
|
|
20
|
+
},
|
|
21
|
+
"titleAlt": {
|
|
22
|
+
"type": "string"
|
|
23
|
+
},
|
|
24
|
+
"txt": {
|
|
25
|
+
"type": "string"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"required": [
|
|
29
|
+
"ver",
|
|
30
|
+
"date",
|
|
31
|
+
"txt"
|
|
32
|
+
],
|
|
33
|
+
"additionalProperties": false
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "life.json",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"lifeClass": true,
|
|
8
|
+
"lifeBackground": true,
|
|
9
|
+
"lifeTrinket": true
|
|
10
|
+
},
|
|
11
|
+
"required": [
|
|
12
|
+
"lifeClass",
|
|
13
|
+
"lifeBackground",
|
|
14
|
+
"lifeTrinket"
|
|
15
|
+
],
|
|
16
|
+
"additionalProperties": false
|
|
17
|
+
}
|