5etools-utils 0.12.78 → 0.13.0
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/bin/test-file-locations.js +1 -1
- package/bin/test-file-names.js +1 -1
- package/bin/test-file-props.js +5 -0
- package/bin/test-json-brew.js +14 -1
- package/bin/test-json-ua.js +14 -1
- package/lib/BrewIndexGenerator.js +0 -45
- package/lib/BrewTester/BrewTesterBase.js +25 -0
- package/lib/BrewTester/BrewTesterFileLocations.js +25 -0
- package/lib/BrewTester/BrewTesterFileNames.js +37 -0
- package/lib/BrewTester/BrewTesterFileProps.js +53 -0
- package/lib/BrewTester/BrewTesterJson.js +54 -0
- package/lib/BrewTester.js +9 -117
- package/package.json +3 -2
package/bin/test-file-names.js
CHANGED
package/bin/test-json-brew.js
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import {BrewTester} from "../lib/BrewTester.js";
|
|
4
|
+
import {Command} from "commander";
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
const program = new Command()
|
|
7
|
+
.argument("[file]", "File to test")
|
|
8
|
+
.option("--dir <dir>", "Directory to test")
|
|
9
|
+
;
|
|
10
|
+
|
|
11
|
+
program.parse(process.argv);
|
|
12
|
+
const opts = program.opts();
|
|
13
|
+
|
|
14
|
+
await BrewTester.pTestJson({
|
|
15
|
+
mode: "brew",
|
|
16
|
+
filepath: program.args[0],
|
|
17
|
+
dir: opts.dir,
|
|
18
|
+
});
|
package/bin/test-json-ua.js
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import {BrewTester} from "../lib/BrewTester.js";
|
|
4
|
+
import {Command} from "commander";
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
const program = new Command()
|
|
7
|
+
.argument("[file]", "File to test")
|
|
8
|
+
.option("--dir <dir>", "Directory to test")
|
|
9
|
+
;
|
|
10
|
+
|
|
11
|
+
program.parse(process.argv);
|
|
12
|
+
const opts = program.opts();
|
|
13
|
+
|
|
14
|
+
await BrewTester.pTestJson({
|
|
15
|
+
mode: "ua",
|
|
16
|
+
filepath: program.args[0],
|
|
17
|
+
dir: opts.dir,
|
|
18
|
+
});
|
|
@@ -114,50 +114,6 @@ class _BrewIndexAdventureBookIds extends _BrewIndex {
|
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
class BrewIndexGenerator {
|
|
117
|
-
static _DIR_TO_PRIMARY_PROP = {
|
|
118
|
-
"creature": [
|
|
119
|
-
"monster",
|
|
120
|
-
],
|
|
121
|
-
"book": [
|
|
122
|
-
"book",
|
|
123
|
-
"bookData",
|
|
124
|
-
],
|
|
125
|
-
"adventure": [
|
|
126
|
-
"adventure",
|
|
127
|
-
"adventureData",
|
|
128
|
-
],
|
|
129
|
-
"makebrew": [
|
|
130
|
-
"makebrewCreatureTrait",
|
|
131
|
-
],
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
static _checkFileContents () {
|
|
135
|
-
Um.info(`PROP_CHECK`, `Checking file contents...`);
|
|
136
|
-
const results = [];
|
|
137
|
-
Uf.runOnDirs((dir) => {
|
|
138
|
-
if (dir === "collection") return;
|
|
139
|
-
|
|
140
|
-
Um.info(`PROP_CHECK`, `Checking dir "${dir}"...`);
|
|
141
|
-
const dirFiles = fs.readdirSync(dir, "utf8")
|
|
142
|
-
.filter(file => file.endsWith(".json"));
|
|
143
|
-
|
|
144
|
-
dirFiles.forEach(file => {
|
|
145
|
-
const json = JSON.parse(fs.readFileSync(`${dir}/${file}`, "utf-8"));
|
|
146
|
-
const props = this._DIR_TO_PRIMARY_PROP[dir] || [dir];
|
|
147
|
-
props.forEach(prop => {
|
|
148
|
-
if (!json[prop]) results.push(`${dir}/${file} was missing a "${prop}" property!`);
|
|
149
|
-
});
|
|
150
|
-
});
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
if (results.length) {
|
|
154
|
-
results.forEach(r => Um.error(`PROP_CHECK`, r));
|
|
155
|
-
throw new Error(`${results.length} file${results.length === 1 ? " was missing a primary prop!" : "s were missing primary props!"} See above for more info.`);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
Um.info(`PROP_CHECK`, `Complete.`);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
117
|
static _buildDeepIndex () {
|
|
162
118
|
const indexes = [
|
|
163
119
|
new _BrewIndexTimestamps(),
|
|
@@ -196,7 +152,6 @@ class BrewIndexGenerator {
|
|
|
196
152
|
}
|
|
197
153
|
|
|
198
154
|
static run () {
|
|
199
|
-
this._checkFileContents();
|
|
200
155
|
this._buildDeepIndex();
|
|
201
156
|
Um.info(`INDEX`, `Complete.`);
|
|
202
157
|
return null;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import Um from "../UtilMisc.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @abstract
|
|
5
|
+
*/
|
|
6
|
+
export class BrewTesterBase {
|
|
7
|
+
_LOG_TAG;
|
|
8
|
+
|
|
9
|
+
async pRun () {
|
|
10
|
+
const tStart = Date.now();
|
|
11
|
+
try {
|
|
12
|
+
await this._pRun();
|
|
13
|
+
} finally {
|
|
14
|
+
const duration = Date.now() - tStart;
|
|
15
|
+
Um.info(this._LOG_TAG, `Ran in ${(duration / 1000).toFixed(2)}s`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @abstract
|
|
21
|
+
*/
|
|
22
|
+
async _pRun () {
|
|
23
|
+
throw new Error("Unimplemented!");
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import Um from "../UtilMisc.js";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import {BrewTesterBase} from "./BrewTesterBase.js";
|
|
4
|
+
|
|
5
|
+
export class BrewTesterFileLocations extends BrewTesterBase {
|
|
6
|
+
static _ROOT_JSON_FILES = new Set([
|
|
7
|
+
"package.json",
|
|
8
|
+
"package-lock.json",
|
|
9
|
+
]);
|
|
10
|
+
|
|
11
|
+
_LOG_TAG = `FILES_ROOT`;
|
|
12
|
+
|
|
13
|
+
async _pRun () {
|
|
14
|
+
Um.info(this._LOG_TAG, `Testing for unwanted JSON files in root dir...`);
|
|
15
|
+
|
|
16
|
+
const errors = fs.readdirSync(".", "utf8")
|
|
17
|
+
.filter(it => it.toLowerCase().endsWith(".json") && !this.constructor._ROOT_JSON_FILES.has(it))
|
|
18
|
+
.map(it => `Unwanted JSON file in root directory: ${it}`);
|
|
19
|
+
|
|
20
|
+
if (!errors.length) return Um.info(this._LOG_TAG, `No unwanted JSON files found.`);
|
|
21
|
+
|
|
22
|
+
errors.forEach(it => console.error(it));
|
|
23
|
+
throw new Error(`Test failed! See above for more info`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import Um from "../UtilMisc.js";
|
|
2
|
+
import * as Uf from "../UtilFs.js";
|
|
3
|
+
import fs from "fs";
|
|
4
|
+
import {BrewTesterBase} from "./BrewTesterBase.js";
|
|
5
|
+
|
|
6
|
+
export class BrewTesterFileNames extends BrewTesterBase {
|
|
7
|
+
_LOG_TAG = `FILE_NAME`;
|
|
8
|
+
|
|
9
|
+
static _RE_NAME_FORMAT = /^[^;]+; .+\.json$/;
|
|
10
|
+
|
|
11
|
+
async _pRun () {
|
|
12
|
+
Um.info(this._LOG_TAG, `Testing for incorrect file names...`);
|
|
13
|
+
|
|
14
|
+
const errors = [];
|
|
15
|
+
|
|
16
|
+
Uf.runOnDirs((dir) => {
|
|
17
|
+
const filenames = fs.readdirSync(dir);
|
|
18
|
+
|
|
19
|
+
errors.push(
|
|
20
|
+
...filenames
|
|
21
|
+
.filter(it => !it.endsWith(".json"))
|
|
22
|
+
.map(it => `File did not have ".json" extension: ${it}`),
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
errors.push(
|
|
26
|
+
...filenames
|
|
27
|
+
.filter(it => !this.constructor._RE_NAME_FORMAT.test(it))
|
|
28
|
+
.map(it => `Filename did not match expected pattern "${this.constructor._RE_NAME_FORMAT.toString()}" extension: ${it}`),
|
|
29
|
+
);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
if (!errors.length) return Um.info(this._LOG_TAG, `Files had expected names.`);
|
|
33
|
+
|
|
34
|
+
errors.forEach(it => console.error(it));
|
|
35
|
+
throw new Error(`Test failed! See above for more info`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import Um from "../UtilMisc.js";
|
|
2
|
+
import * as Uf from "../UtilFs.js";
|
|
3
|
+
import fs from "fs";
|
|
4
|
+
import {BrewTesterBase} from "./BrewTesterBase.js";
|
|
5
|
+
|
|
6
|
+
export class BrewTesterFileProps extends BrewTesterBase {
|
|
7
|
+
_LOG_TAG = `PROP_CHECK`;
|
|
8
|
+
|
|
9
|
+
static _DIR_TO_PRIMARY_PROP = {
|
|
10
|
+
"creature": [
|
|
11
|
+
"monster",
|
|
12
|
+
],
|
|
13
|
+
"book": [
|
|
14
|
+
"book",
|
|
15
|
+
"bookData",
|
|
16
|
+
],
|
|
17
|
+
"adventure": [
|
|
18
|
+
"adventure",
|
|
19
|
+
"adventureData",
|
|
20
|
+
],
|
|
21
|
+
"makebrew": [
|
|
22
|
+
"makebrewCreatureTrait",
|
|
23
|
+
],
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
async _pRun () {
|
|
27
|
+
Um.info(this._LOG_TAG, `Checking file contents...`);
|
|
28
|
+
|
|
29
|
+
const results = [];
|
|
30
|
+
Uf.runOnDirs((dir) => {
|
|
31
|
+
if (dir === "collection") return;
|
|
32
|
+
|
|
33
|
+
Um.info(this._LOG_TAG, `Checking dir "${dir}"...`);
|
|
34
|
+
const dirFiles = fs.readdirSync(dir, "utf8")
|
|
35
|
+
.filter(file => file.endsWith(".json"));
|
|
36
|
+
|
|
37
|
+
dirFiles.forEach(file => {
|
|
38
|
+
const json = JSON.parse(fs.readFileSync(`${dir}/${file}`, "utf-8"));
|
|
39
|
+
const props = this.constructor._DIR_TO_PRIMARY_PROP[dir] || [dir];
|
|
40
|
+
props.forEach(prop => {
|
|
41
|
+
if (!json[prop]) results.push(`${dir}/${file} was missing a "${prop}" property!`);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
if (results.length) {
|
|
47
|
+
results.forEach(r => Um.error(this._LOG_TAG, r));
|
|
48
|
+
throw new Error(`${results.length} file${results.length === 1 ? " was missing a primary prop!" : "s were missing primary props!"} See above for more info.`);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
Um.info(this._LOG_TAG, `Complete.`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import {JsonTester} from "../TestJson.js";
|
|
2
|
+
import {listJsonFiles} from "../UtilFs.js";
|
|
3
|
+
import pathlib from "path";
|
|
4
|
+
import fs from "fs";
|
|
5
|
+
import Um from "../UtilMisc.js";
|
|
6
|
+
import {BrewTesterBase} from "./BrewTesterBase.js";
|
|
7
|
+
|
|
8
|
+
export class BrewTesterJson extends BrewTesterBase {
|
|
9
|
+
_LOG_TAG = "JSON";
|
|
10
|
+
_IS_FAIL_SLOW = !!process.env.FAIL_SLOW;
|
|
11
|
+
|
|
12
|
+
constructor ({mode, filepath, dir, ...rest}) {
|
|
13
|
+
super({...rest});
|
|
14
|
+
this._mode = mode;
|
|
15
|
+
this._filepath = filepath;
|
|
16
|
+
this._dir = dir;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async _pRun () {
|
|
20
|
+
const jsonTester = new JsonTester({mode: this._mode, tagLog: this._LOG_TAG, fnGetSchemaId: () => "homebrew.json"});
|
|
21
|
+
await jsonTester.pInit();
|
|
22
|
+
|
|
23
|
+
let results;
|
|
24
|
+
if (this._filepath) {
|
|
25
|
+
results = jsonTester.getFileErrors({filePath: this._filepath});
|
|
26
|
+
} else if (this._dir) {
|
|
27
|
+
const fileList = listJsonFiles(this._dir)
|
|
28
|
+
.filter(it => pathlib.basename(it) !== "index.json");
|
|
29
|
+
results = await jsonTester.pGetErrorsOnDirsWorkers({isFailFast: !this._IS_FAIL_SLOW, fileList: fileList});
|
|
30
|
+
} else {
|
|
31
|
+
results = await jsonTester.pGetErrorsOnDirsWorkers({isFailFast: !this._IS_FAIL_SLOW});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const {errors, errorsFull, isUnknownError = false} = results;
|
|
35
|
+
|
|
36
|
+
if (errors.length) {
|
|
37
|
+
if (!process.env.CI) {
|
|
38
|
+
const outDir = fs.existsSync("_test") && fs.lstatSync("_test").isDirectory()
|
|
39
|
+
? "_test"
|
|
40
|
+
: ".";
|
|
41
|
+
fs.writeFileSync(`${outDir}/test-json.error.log`, errorsFull.join("\n\n=====\n\n"));
|
|
42
|
+
}
|
|
43
|
+
console.error(`Schema test failed (${errors.length} failure${errors.length === 1 ? "" : "s"}).`);
|
|
44
|
+
throw new Error(`Test failed! See above for more info`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (isUnknownError) {
|
|
48
|
+
console.error(`Unknown error when testing! (See above logs)`);
|
|
49
|
+
throw new Error(`Test failed! See above for more info`);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (!errors.length) Um.info(this._LOG_TAG, `Schema test passed.`);
|
|
53
|
+
}
|
|
54
|
+
}
|
package/lib/BrewTester.js
CHANGED
|
@@ -1,119 +1,11 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import {listJsonFiles} from "./UtilFs.js";
|
|
6
|
-
import * as pathlib from "path";
|
|
7
|
-
import * as Uf from "./UtilFs.js";
|
|
1
|
+
import {BrewTesterJson} from "./BrewTester/BrewTesterJson.js";
|
|
2
|
+
import {BrewTesterFileLocations} from "./BrewTester/BrewTesterFileLocations.js";
|
|
3
|
+
import {BrewTesterFileNames} from "./BrewTester/BrewTesterFileNames.js";
|
|
4
|
+
import {BrewTesterFileProps} from "./BrewTester/BrewTesterFileProps.js";
|
|
8
5
|
|
|
9
|
-
class
|
|
10
|
-
static
|
|
11
|
-
static
|
|
12
|
-
|
|
13
|
-
static
|
|
14
|
-
const program = new Command()
|
|
15
|
-
.argument("[file]", "File to test")
|
|
16
|
-
.option("--dir <dir>", "Directory to test")
|
|
17
|
-
;
|
|
18
|
-
|
|
19
|
-
program.parse(args);
|
|
20
|
-
const opts = program.opts();
|
|
21
|
-
|
|
22
|
-
const jsonTester = new JsonTester({mode, tagLog: this._LOG_TAG, fnGetSchemaId: () => "homebrew.json"});
|
|
23
|
-
await jsonTester.pInit();
|
|
24
|
-
|
|
25
|
-
let results;
|
|
26
|
-
if (program.args[0]) {
|
|
27
|
-
results = jsonTester.getFileErrors({filePath: program.args[0]});
|
|
28
|
-
} else if (opts.dir) {
|
|
29
|
-
const fileList = listJsonFiles(opts.dir)
|
|
30
|
-
.filter(it => pathlib.basename(it) !== "index.json");
|
|
31
|
-
results = await jsonTester.pGetErrorsOnDirsWorkers({isFailFast: !this._IS_FAIL_SLOW, fileList: fileList});
|
|
32
|
-
} else {
|
|
33
|
-
results = await jsonTester.pGetErrorsOnDirsWorkers({isFailFast: !this._IS_FAIL_SLOW});
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const {errors, errorsFull, isUnknownError = false} = results;
|
|
37
|
-
|
|
38
|
-
if (errors.length) {
|
|
39
|
-
if (!process.env.CI) {
|
|
40
|
-
const outDir = fs.existsSync("_test") && fs.lstatSync("_test").isDirectory()
|
|
41
|
-
? "_test"
|
|
42
|
-
: ".";
|
|
43
|
-
fs.writeFileSync(`${outDir}/test-json.error.log`, errorsFull.join("\n\n=====\n\n"));
|
|
44
|
-
}
|
|
45
|
-
console.error(`Schema test failed (${errors.length} failure${errors.length === 1 ? "" : "s"}).`);
|
|
46
|
-
process.exit(1);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (isUnknownError) {
|
|
50
|
-
console.error(`Unknown error when testing! (See above logs)`);
|
|
51
|
-
process.exit(1);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
if (!errors.length) Um.info(this._LOG_TAG, `Schema test passed.`);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
class _BrewTesterFileLocations {
|
|
59
|
-
static _ROOT_JSON_FILES = new Set([
|
|
60
|
-
"package.json",
|
|
61
|
-
"package-lock.json",
|
|
62
|
-
]);
|
|
63
|
-
|
|
64
|
-
static _LOG_TAG = `FILES_ROOT`;
|
|
65
|
-
|
|
66
|
-
static run () {
|
|
67
|
-
Um.info(this._LOG_TAG, `Testing for unwanted JSON files in root dir...`);
|
|
68
|
-
|
|
69
|
-
const errors = fs.readdirSync(".", "utf8")
|
|
70
|
-
.filter(it => it.toLowerCase().endsWith(".json") && !this._ROOT_JSON_FILES.has(it))
|
|
71
|
-
.map(it => `Unwanted JSON file in root directory: ${it}`);
|
|
72
|
-
|
|
73
|
-
if (!errors.length) return Um.info(this._LOG_TAG, `No unwanted JSON files found.`);
|
|
74
|
-
|
|
75
|
-
errors.forEach(it => console.error(it));
|
|
76
|
-
process.exit(1);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
class _BrewTesterFileNames {
|
|
81
|
-
static _LOG_TAG = `FILE_NAME`;
|
|
82
|
-
|
|
83
|
-
static _RE_NAME_FORMAT = /^[^;]+; .+\.json$/;
|
|
84
|
-
|
|
85
|
-
static run () {
|
|
86
|
-
Um.info(this._LOG_TAG, `Testing for incorrect file names...`);
|
|
87
|
-
|
|
88
|
-
const errors = [];
|
|
89
|
-
|
|
90
|
-
Uf.runOnDirs((dir) => {
|
|
91
|
-
const filenames = fs.readdirSync(dir);
|
|
92
|
-
|
|
93
|
-
errors.push(
|
|
94
|
-
...filenames
|
|
95
|
-
.filter(it => !it.endsWith(".json"))
|
|
96
|
-
.map(it => `File did not have ".json" extension: ${it}`),
|
|
97
|
-
);
|
|
98
|
-
|
|
99
|
-
errors.push(
|
|
100
|
-
...filenames
|
|
101
|
-
.filter(it => !this._RE_NAME_FORMAT.test(it))
|
|
102
|
-
.map(it => `Filename did not match expected pattern "${this._RE_NAME_FORMAT.toString()}" extension: ${it}`),
|
|
103
|
-
);
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
if (!errors.length) return Um.info(this._LOG_TAG, `Files had expected names.`);
|
|
107
|
-
|
|
108
|
-
errors.forEach(it => console.error(it));
|
|
109
|
-
process.exit(1);
|
|
110
|
-
}
|
|
6
|
+
export class BrewTester {
|
|
7
|
+
static async pTestJson ({mode, filepath, dir}) { return (new BrewTesterJson({mode, filepath, dir})).pRun(); }
|
|
8
|
+
static pTestFileLocations () { return (new BrewTesterFileLocations()).pRun(); }
|
|
9
|
+
static pTestFileNames () { return (new BrewTesterFileNames()).pRun(); }
|
|
10
|
+
static pTestFileProps () { return (new BrewTesterFileProps()).pRun(); }
|
|
111
11
|
}
|
|
112
|
-
|
|
113
|
-
class BrewTester {
|
|
114
|
-
static async pTestJson (args, opts) { return _BrewTesterJson.pRun(args, opts); }
|
|
115
|
-
static testFileLocations () { return _BrewTesterFileLocations.run(); }
|
|
116
|
-
static testFileNames () { return _BrewTesterFileNames.run(); }
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
export {BrewTester};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "5etools-utils",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "Shared utilities for the 5etools ecosystem.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/Api.js",
|
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
"test-json-brew": "bin/test-json-brew.js",
|
|
16
16
|
"test-json-ua": "bin/test-json-ua.js",
|
|
17
17
|
"test-file-names": "bin/test-file-names.js",
|
|
18
|
-
"test-file-locations": "bin/test-file-locations.js"
|
|
18
|
+
"test-file-locations": "bin/test-file-locations.js",
|
|
19
|
+
"test-file-props": "bin/test-file-props.js"
|
|
19
20
|
},
|
|
20
21
|
"scripts": {
|
|
21
22
|
"build:dangerous:sources": "node node/fetch-5etools-sources.js",
|