v8r 4.4.0 → 5.1.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/CHANGELOG.md CHANGED
@@ -1,5 +1,36 @@
1
1
  # Changelog
2
2
 
3
+ ## 📦 [5.1.0](https://www.npmjs.com/package/v8r/v/5.1.0) - 2025-07-20
4
+
5
+ * v8r now pre-warms the cache and fetches schemas in parallel.
6
+ This will improve decrease total run time for any run that involves fetching
7
+ more than one remote schema, or involves a schema with remote `$ref`s.
8
+ * Improve handling of empty yaml files.
9
+
10
+ ## 📦 [5.0.0](https://www.npmjs.com/package/v8r/v/5.0.0) - 2025-05-10
11
+
12
+ Following on from the deprecations in version 4.4.0,
13
+ version 5.0.0 contains a number of breaking changes:
14
+
15
+ * The `--format` CLI argument and `format` config file key have been removed.
16
+ Switch to using `--output-format` and `outputFormat`.
17
+ * v8r now ignores patterns in `.gitignore` by default.
18
+ * The `fileLocation` argument of `getSingleResultLogMessage` has been removed.
19
+ The signature is now `getSingleResultLogMessage(result, format)`.
20
+ Plugins implementing the `getSingleResultLogMessage` hook will need to to update
21
+ the signature.
22
+ If you are using `fileLocation` in the `getSingleResultLogMessage` function body,
23
+ switch to using `result.fileLocation`.
24
+ * File paths are no longer passed to plugins in dot-relative notation.
25
+ Plugins implementing the `getSingleResultLogMessage`, `getAllResultsLogMessage` and `parseInputFile`
26
+ plugin hooks may need to be updated.
27
+ * The minimum compatible node version is now Node 20.
28
+
29
+ Other changes in this release:
30
+
31
+ * v8r is now tested on node 24
32
+ * Upgrade to latest major versions of core packages (got, glob, minimatch, etc)
33
+
3
34
  ## 📦 [4.4.0](https://www.npmjs.com/package/v8r/v/4.4.0) - 2025-04-26
4
35
 
5
36
  Version 4.4.0 is a deprecation release. This release adds deprecation warnings for
@@ -3,13 +3,6 @@
3
3
  "$schema": "https://json-schema.org/draft/2019-09/schema",
4
4
  "type": "object",
5
5
  "additionalProperties": false,
6
- "allOf": [
7
- {
8
- "not": {
9
- "required": ["format", "outputFormat"]
10
- }
11
- }
12
- ],
13
6
  "properties": {
14
7
  "cacheTtl": {
15
8
  "description": "Remove cached HTTP responses older than cacheTtl seconds old. Specifying 0 clears and disables cache completely",
@@ -68,11 +61,6 @@
68
61
  "description": "Output format for validation results. 'text' and 'json' are always valid. Plugins may define additional values which are valid here.",
69
62
  "type": "string"
70
63
  },
71
- "format": {
72
- "description": "Output format for validation results. 'text' and 'json' are always valid. Plugins may define additional values which are valid here.",
73
- "type": "string",
74
- "deprecated": true
75
- },
76
64
  "ignoreErrors": {
77
65
  "description": "Exit with code 0 even if an error was encountered. True means a non-zero exit code is only issued if validation could be completed successfully and one or more files were invalid",
78
66
  "type": "boolean"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "v8r",
3
- "version": "4.4.0",
3
+ "version": "5.1.0",
4
4
  "description": "A command-line JSON, YAML and TOML validator that's on your wavelength",
5
5
  "scripts": {
6
6
  "test": "V8R_CACHE_NAME=v8r-test c8 --reporter=text mocha \"src/**/*.spec.js\"",
@@ -34,23 +34,25 @@
34
34
  "cosmiconfig": "^9.0.0",
35
35
  "decamelize": "^6.0.0",
36
36
  "flat-cache": "^6.1.4",
37
- "glob": "^10.1.0",
37
+ "glob": "^11.0.0",
38
38
  "global-agent": "^3.0.0",
39
- "got": "^13.0.0",
39
+ "got": "^14.0.0",
40
40
  "ignore": "^7.0.0",
41
41
  "is-url": "^1.2.4",
42
42
  "js-yaml": "^4.0.0",
43
43
  "json5": "^2.2.0",
44
- "minimatch": "^9.0.0",
44
+ "minimatch": "^10.0.0",
45
+ "p-limit": "^6.2.0",
46
+ "p-mutex": "^1.0.0",
45
47
  "smol-toml": "^1.0.1",
46
- "yargs": "^17.0.1"
48
+ "yargs": "^18.0.0"
47
49
  },
48
50
  "devDependencies": {
49
51
  "c8": "^10.1.2",
50
52
  "eslint": "^9.9.0",
51
53
  "eslint-config-prettier": "^10.1.2",
52
- "eslint-plugin-jsdoc": "^50.2.2",
53
- "eslint-plugin-mocha": "^10.0.3",
54
+ "eslint-plugin-jsdoc": "^51.4.1",
55
+ "eslint-plugin-mocha": "^11.0.0",
54
56
  "eslint-plugin-prettier": "^5.0.0",
55
57
  "mocha": "^11.0.1",
56
58
  "mock-cwd": "^1.0.0",
@@ -59,7 +61,7 @@
59
61
  "prettier-plugin-jsdoc": "^1.3.0"
60
62
  },
61
63
  "engines": {
62
- "node": ">=18"
64
+ "node": ">=20"
63
65
  },
64
66
  "type": "module",
65
67
  "keywords": [
package/src/bootstrap.js CHANGED
@@ -53,8 +53,8 @@ function mergeConfigs(args, config) {
53
53
  if (config.filepath) {
54
54
  mergedConfig.configFileRelativePath = getRelativeFilePath(config);
55
55
  }
56
- // https://github.com/chris48s/v8r/issues/494
57
- delete mergedConfig.format;
56
+ // hard-coded - this can't be set via CLI or config file
57
+ mergedConfig.cachePrewarm = true;
58
58
  return mergedConfig;
59
59
  }
60
60
 
@@ -81,7 +81,7 @@ function parseArgs(argv, config, documentFormats, outputFormats) {
81
81
  const ignoreFilesOpts = {
82
82
  describe: "A list of files containing glob patterns to ignore",
83
83
  };
84
- let ignoreFilesDefault = [".v8rignore"];
84
+ let ignoreFilesDefault = [".v8rignore", ".gitignore"];
85
85
  ignoreFilesOpts.defaultDescription = `${JSON.stringify(ignoreFilesDefault)}`;
86
86
  if (Object.keys(config.config).includes("ignorePatternFiles")) {
87
87
  ignoreFilesDefault = config.config.ignorePatternFiles;
@@ -122,13 +122,6 @@ function parseArgs(argv, config, documentFormats, outputFormats) {
122
122
  if (args.ignore === undefined) {
123
123
  args.ignore = true;
124
124
  }
125
-
126
- // https://github.com/chris48s/v8r/issues/494
127
- if (process.argv.includes("--format")) {
128
- logger.warning(
129
- "In v8r version 5 the --format argument will be removed. Switch to using --output-format",
130
- );
131
- }
132
125
  },
133
126
  )
134
127
  .version(
@@ -190,10 +183,7 @@ function parseArgs(argv, config, documentFormats, outputFormats) {
190
183
  type: "string",
191
184
  choices: outputFormats,
192
185
  default: "text",
193
- // https://github.com/chris48s/v8r/issues/494
194
- describe:
195
- "Output format for validation results. The '--format' alias is deprecated.",
196
- alias: "format",
186
+ describe: "Output format for validation results",
197
187
  })
198
188
  .example([
199
189
  ["$0 file.json", "Validate a single file"],
@@ -251,14 +241,6 @@ async function bootstrap(argv, config, cosmiconfigOptions = {}) {
251
241
  const configFile = await getCosmiConfig(cosmiconfigOptions);
252
242
  validateConfigAgainstSchema(configFile);
253
243
 
254
- // https://github.com/chris48s/v8r/issues/494
255
- if (configFile.config.format) {
256
- logger.warning(
257
- "In v8r version 5 the 'format' config file key will be removed. Switch to using 'outputFormat'",
258
- );
259
- configFile.config.outputFormat = configFile.config.format;
260
- }
261
-
262
244
  // load both core and user plugins
263
245
  let plugins = resolveUserPlugins(configFile.config.plugins || []);
264
246
  const { allLoadedPlugins, loadedCorePlugins, loadedUserPlugins } =
@@ -274,11 +256,6 @@ async function bootstrap(argv, config, cosmiconfigOptions = {}) {
274
256
  // parse command line arguments
275
257
  const args = parseArgs(argv, configFile, documentFormats, outputFormats);
276
258
 
277
- // https://github.com/chris48s/v8r/issues/599
278
- logger.warning(
279
- "Starting from v8r version 5, v8r will ignore patterns in .gitignore by default.",
280
- );
281
-
282
259
  return {
283
260
  config: mergeConfigs(args, configFile),
284
261
  allLoadedPlugins,
@@ -0,0 +1,87 @@
1
+ import isUrl from "is-url";
2
+ import pLimit from "p-limit";
3
+ import { getCatalogs, getMatchForFilename } from "./catalogs.js";
4
+
5
+ const limit = pLimit(10);
6
+
7
+ async function fetch(location, cache) {
8
+ return await cache.fetch(location, false);
9
+ }
10
+
11
+ function fetchWithLimit(url, cache) {
12
+ return limit(() => fetch(url, cache));
13
+ }
14
+
15
+ function normalizeUrl(ref) {
16
+ try {
17
+ const url = new URL(ref);
18
+ url.hash = "";
19
+ return url.toString();
20
+ } catch {
21
+ return null;
22
+ }
23
+ }
24
+
25
+ function getRemoteRefs(node) {
26
+ let refs = [];
27
+ if (Array.isArray(node)) {
28
+ for (const v of node) {
29
+ if (typeof v === "object" && v !== null) {
30
+ refs = refs.concat(getRemoteRefs(v));
31
+ }
32
+ }
33
+ } else if (typeof node === "object" && node !== null) {
34
+ for (const [k, v] of Object.entries(node)) {
35
+ if (k === "$ref" && typeof v === "string") {
36
+ const resolved = normalizeUrl(v);
37
+ if (resolved && isUrl(resolved)) {
38
+ refs.push(resolved);
39
+ }
40
+ }
41
+ if (typeof v === "object" && v !== null) {
42
+ refs = refs.concat(getRemoteRefs(v));
43
+ }
44
+ }
45
+ }
46
+ return Array.from(new Set(refs));
47
+ }
48
+
49
+ async function fetchAndRecurse(url, cache) {
50
+ const schema = await fetchWithLimit(url, cache);
51
+ const refs = getRemoteRefs(schema).filter(
52
+ (ref) => cache.get(ref) === undefined,
53
+ );
54
+ await Promise.all(refs.map((ref) => fetchAndRecurse(ref, cache)));
55
+ }
56
+
57
+ async function prewarmSchemaCache(filenames, config, cache) {
58
+ const catalogs = getCatalogs(config);
59
+ const schemaLocations = new Set();
60
+
61
+ for (const filename of filenames) {
62
+ let catalogMatch;
63
+ try {
64
+ catalogMatch = config.schema
65
+ ? {}
66
+ : await getMatchForFilename(catalogs, filename, "debug", cache);
67
+ } catch {
68
+ catalogMatch = {};
69
+ }
70
+ const schemaLocation = config.schema || catalogMatch.location;
71
+
72
+ if (schemaLocation) {
73
+ schemaLocations.add(schemaLocation);
74
+ }
75
+ cache.resetCounters();
76
+ }
77
+
78
+ await Promise.all(
79
+ Array.from(schemaLocations)
80
+ .filter((schemaLocation) => isUrl(schemaLocation))
81
+ .map((url) => fetchAndRecurse(url, cache)),
82
+ );
83
+ cache.persist();
84
+ cache.resetCounters();
85
+ }
86
+
87
+ export { getRemoteRefs, prewarmSchemaCache, normalizeUrl };
package/src/cache.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import got from "got";
2
+ import Mutex from "p-mutex";
2
3
  import logger from "./logger.js";
3
4
  import { parseSchema } from "./parser.js";
4
5
 
@@ -7,39 +8,53 @@ class Cache {
7
8
  this.cache = flatCache;
8
9
  this.ttl = this.cache._cache.ttl || 0;
9
10
  this.callCounter = {};
11
+ this.locks = {};
10
12
  this.callLimit = 10;
11
13
  if (this.ttl === 0) {
12
14
  this.cache.clear();
13
15
  }
14
16
  }
15
17
 
16
- limitDepth(url) {
18
+ getMutex(url) {
19
+ if (!(url in this.locks)) {
20
+ this.locks[url] = new Mutex();
21
+ }
22
+ return this.locks[url];
23
+ }
24
+
25
+ async limitDepth(url) {
17
26
  /*
18
27
  It is possible to create cyclic dependencies with external references
19
- in JSON schema. Ajv doesn't detect this when resolving external references,
28
+ in JSON schema.
29
+ We try to mitigate this issue during cache pre-warming.
30
+ Ajv doesn't detect this when resolving external references,
20
31
  so we keep a count of how many times we've called the same URL.
21
32
  If we are calling the same URL over and over we've probably hit a circular
22
33
  external reference and we need to break the loop.
23
34
  */
24
- if (url in this.callCounter) {
25
- this.callCounter[url]++;
26
- } else {
27
- this.callCounter[url] = 1;
28
- }
29
- if (this.callCounter[url] > this.callLimit) {
30
- throw new Error(
31
- `Called ${url} >${this.callLimit} times. Possible circular reference.`,
32
- );
33
- }
35
+ const mutex = this.getMutex(url);
36
+
37
+ await mutex.withLock(async () => {
38
+ if (url in this.callCounter) {
39
+ this.callCounter[url]++;
40
+ } else {
41
+ this.callCounter[url] = 1;
42
+ }
43
+ if (this.callCounter[url] > this.callLimit) {
44
+ throw new Error(
45
+ `Called ${url} >${this.callLimit} times. Possible circular reference.`,
46
+ );
47
+ }
48
+ });
34
49
  }
35
50
 
36
51
  resetCounters() {
37
52
  this.callCounter = {};
38
53
  }
39
54
 
40
- async fetch(url) {
41
- this.limitDepth(url);
42
- const cachedResponse = this.cache.getKey(url);
55
+ async fetch(url, persist = true) {
56
+ await this.limitDepth(url);
57
+ const cachedResponse = this.cache.get(url);
43
58
  if (cachedResponse !== undefined) {
44
59
  logger.debug(`Cache hit: using cached response from ${url}`);
45
60
  return cachedResponse.body;
@@ -50,8 +65,10 @@ class Cache {
50
65
  const resp = await got(url);
51
66
  const parsedBody = parseSchema(resp.body, url);
52
67
  if (this.ttl > 0) {
53
- this.cache.setKey(url, { body: parsedBody });
54
- this.cache.save(true);
68
+ this.cache.set(url, { body: parsedBody });
69
+ if (persist) {
70
+ this.cache.save(true);
71
+ }
55
72
  }
56
73
  return parsedBody;
57
74
  } catch (error) {
@@ -61,6 +78,14 @@ class Cache {
61
78
  throw new Error(`Failed fetching ${url}`);
62
79
  }
63
80
  }
81
+
82
+ persist() {
83
+ this.cache.save(true);
84
+ }
85
+
86
+ get(key) {
87
+ return this.cache.get(key);
88
+ }
64
89
  }
65
90
 
66
91
  export { Cache };
package/src/catalogs.js CHANGED
@@ -74,7 +74,7 @@ function getMultipleMatchesLogMessage(matches) {
74
74
  .join("\n");
75
75
  }
76
76
 
77
- async function getMatchForFilename(catalogs, filename, cache) {
77
+ async function getMatchForFilename(catalogs, filename, logLevel, cache) {
78
78
  for (const [i, rec] of catalogs.entries()) {
79
79
  const catalogLocation = rec.location;
80
80
  const catalog =
@@ -107,7 +107,7 @@ async function getMatchForFilename(catalogs, filename, cache) {
107
107
  (matches.length === 1 && matches[0].versions == null) ||
108
108
  (matches.length === 1 && Object.keys(matches[0].versions).length === 1)
109
109
  ) {
110
- logger.info(`Found schema in ${catalogLocation} ...`);
110
+ logger[logLevel](`Found schema in ${catalogLocation} ...`);
111
111
  return coerceMatch(matches[0]); // Exactly one match found. We're done.
112
112
  }
113
113
 
@@ -122,7 +122,7 @@ async function getMatchForFilename(catalogs, filename, cache) {
122
122
  ) {
123
123
  // We found >1 matches in the same catalog. This is always a hard error.
124
124
  const matchesLog = getMultipleMatchesLogMessage(matches);
125
- logger.info(
125
+ logger[logLevel](
126
126
  `Found multiple possible matches for ${filename}. Possible matches:\n\n${matchesLog}`,
127
127
  );
128
128
  throw new Error(
package/src/cli.js CHANGED
@@ -12,6 +12,7 @@ import { getFromUrlOrFile } from "./io.js";
12
12
  import logger from "./logger.js";
13
13
  import { getDocumentLocation } from "./output-formatters.js";
14
14
  import { parseFile } from "./parser.js";
15
+ import { prewarmSchemaCache } from "./cache-prewarm.js";
15
16
 
16
17
  const EXIT = {
17
18
  VALID: 0,
@@ -92,7 +93,7 @@ async function validateFile(filename, config, plugins, cache) {
92
93
  const catalogs = getCatalogs(config);
93
94
  const catalogMatch = config.schema
94
95
  ? {}
95
- : await getMatchForFilename(catalogs, filename, cache);
96
+ : await getMatchForFilename(catalogs, filename, "info", cache);
96
97
  schemaLocation = config.schema || catalogMatch.location;
97
98
  schema = await getFromUrlOrFile(schemaLocation, cache);
98
99
  logger.info(
@@ -144,7 +145,6 @@ async function validateFile(filename, config, plugins, cache) {
144
145
  for (const plugin of plugins) {
145
146
  const message = plugin.getSingleResultLogMessage(
146
147
  result,
147
- filename,
148
148
  config.outputFormat,
149
149
  );
150
150
  if (message != null) {
@@ -183,6 +183,12 @@ function Validator() {
183
183
  const ttl = secondsToMilliseconds(config.cacheTtl || 0);
184
184
  const cache = new Cache(getFlatCache(ttl));
185
185
 
186
+ if (config.cachePrewarm && ttl > 5000) {
187
+ logger.info("Pre-warming the cache");
188
+ await prewarmSchemaCache(filenames, config, cache);
189
+ logger.debug("Cache pre-warming complete");
190
+ }
191
+
186
192
  let results = [];
187
193
  for (const filename of filenames) {
188
194
  const fileResults = await validateFile(filename, config, plugins, cache);
package/src/glob.js CHANGED
@@ -43,10 +43,6 @@ async function readIgnoreFiles(filenames) {
43
43
  return content;
44
44
  }
45
45
 
46
- function getSeparator() {
47
- return process.platform == "win32" ? "\\" : "/";
48
- }
49
-
50
46
  async function getFiles(patterns, ignorePatternFiles) {
51
47
  let filenames = [];
52
48
 
@@ -80,10 +76,6 @@ async function getFiles(patterns, ignorePatternFiles) {
80
76
  throw new NotFound(`Could not find any files to validate`);
81
77
  }
82
78
 
83
- const sep = getSeparator();
84
- filteredFilenames = filteredFilenames.map((fn) =>
85
- !fn.startsWith(".." + sep) ? "." + sep + fn : fn,
86
- );
87
79
  return filteredFilenames;
88
80
  }
89
81
 
package/src/parser.js CHANGED
@@ -10,6 +10,9 @@ function parseFile(plugins, contents, filename, parser) {
10
10
  const maybeDocuments = Array.isArray(parsedFile)
11
11
  ? parsedFile
12
12
  : [parsedFile];
13
+ if (maybeDocuments.length === 0) {
14
+ throw new Error(`No documents to validate found in ${filename}`);
15
+ }
13
16
  for (const doc of maybeDocuments) {
14
17
  if (!(doc instanceof Document)) {
15
18
  throw new Error(
@@ -8,7 +8,7 @@ class TextOutput extends BasePlugin {
8
8
  return ["text"];
9
9
  }
10
10
 
11
- getSingleResultLogMessage(result, fileLocation, format) {
11
+ getSingleResultLogMessage(result, format) {
12
12
  if (result.valid === false && format === "text") {
13
13
  return formatErrors(getDocumentLocation(result), result.errors);
14
14
  }
package/src/plugins.js CHANGED
@@ -1,5 +1,4 @@
1
1
  import path from "node:path";
2
- import logger from "./logger.js";
3
2
 
4
3
  /**
5
4
  * Base class for all v8r plugins.
@@ -37,10 +36,7 @@ class BasePlugin {
37
36
  * Document object or an array of Document objects.
38
37
  *
39
38
  * @param {string} contents - The unparsed file content.
40
- * @param {string} fileLocation - The file path. Filenames are resolved and
41
- * normalised using dot-relative notation. This means relative paths in the
42
- * current directory will be prefixed with `./` (or `.\` on Windows) even if
43
- * this was not present in the input filename or pattern.
39
+ * @param {string} fileLocation - The file path.
44
40
  * @param {string | undefined} parser - If the user has specified a parser to
45
41
  * use for this file in a custom schema, this will be passed to
46
42
  * `parseInputFile` in the `parser` param.
@@ -76,16 +72,12 @@ class BasePlugin {
76
72
  *
77
73
  * @param {ValidationResult} result - Result of attempting to validate this
78
74
  * document.
79
- * @param {string} fileLocation - The document file path. Filenames are
80
- * resolved and normalised using dot-relative notation. This means relative
81
- * paths in the current directory will be prefixed with `./` (or `.\` on
82
- * Windows) even if this was not present in the input filename or pattern.
83
75
  * @param {string} format - The user's requested output format as specified in
84
76
  * the config file or via the `--output-format` command line argument.
85
77
  * @returns {string | undefined} Log message
86
78
  */
87
79
  // eslint-disable-next-line no-unused-vars
88
- getSingleResultLogMessage(result, fileLocation, format) {
80
+ getSingleResultLogMessage(result, format) {
89
81
  return undefined;
90
82
  }
91
83
 
@@ -124,11 +116,7 @@ class Document {
124
116
  }
125
117
  }
126
118
 
127
- function hasProperty(plugin, prop) {
128
- return Object.prototype.hasOwnProperty.call(plugin.prototype, prop);
129
- }
130
-
131
- function validatePlugin(plugin, warnings) {
119
+ function validatePlugin(plugin) {
132
120
  if (
133
121
  typeof plugin.name !== "string" ||
134
122
  !plugin.name.startsWith("v8r-plugin-")
@@ -155,29 +143,6 @@ function validatePlugin(plugin, warnings) {
155
143
  );
156
144
  }
157
145
  }
158
-
159
- if (warnings === true) {
160
- // https://github.com/chris48s/v8r/issues/500
161
- if (hasProperty(plugin, "getSingleResultLogMessage")) {
162
- logger.warning(
163
- "In v8r version 5 the fileLocation argument of getSingleResultLogMessage will be removed.\n" +
164
- " The signature will become getSingleResultLogMessage(result, format).\n" +
165
- ` ${plugin.name} will need to be updated`,
166
- );
167
- }
168
-
169
- // https://github.com/chris48s/v8r/issues/600
170
- if (
171
- hasProperty(plugin, "getSingleResultLogMessage") ||
172
- hasProperty(plugin, "getAllResultsLogMessage") ||
173
- hasProperty(plugin, "parseInputFile")
174
- ) {
175
- logger.warning(
176
- "Starting from v8r version 5 file paths will no longer be passed to plugins in dot-relative notation.\n" +
177
- ` ${plugin.name} may need to be updated`,
178
- );
179
- }
180
- }
181
146
  }
182
147
 
183
148
  function resolveUserPlugins(userPlugins) {
@@ -193,19 +158,19 @@ function resolveUserPlugins(userPlugins) {
193
158
  return plugins;
194
159
  }
195
160
 
196
- async function loadPlugins(plugins, warnings) {
161
+ async function loadPlugins(plugins) {
197
162
  let loadedPlugins = [];
198
163
  for (const plugin of plugins) {
199
164
  loadedPlugins.push(await import(plugin));
200
165
  }
201
166
  loadedPlugins = loadedPlugins.map((plugin) => plugin.default);
202
- loadedPlugins.forEach((plugin) => validatePlugin(plugin, warnings));
167
+ loadedPlugins.forEach((plugin) => validatePlugin(plugin));
203
168
  loadedPlugins = loadedPlugins.map((plugin) => new plugin());
204
169
  return loadedPlugins;
205
170
  }
206
171
 
207
172
  async function loadAllPlugins(userPlugins) {
208
- const loadedUserPlugins = await loadPlugins(userPlugins, true);
173
+ const loadedUserPlugins = await loadPlugins(userPlugins);
209
174
 
210
175
  const corePlugins = [
211
176
  "./plugins/parser-json.js",
@@ -215,7 +180,7 @@ async function loadAllPlugins(userPlugins) {
215
180
  "./plugins/output-text.js",
216
181
  "./plugins/output-json.js",
217
182
  ];
218
- const loadedCorePlugins = await loadPlugins(corePlugins, false);
183
+ const loadedCorePlugins = await loadPlugins(corePlugins);
219
184
 
220
185
  return {
221
186
  allLoadedPlugins: loadedUserPlugins.concat(loadedCorePlugins),
@@ -227,10 +192,6 @@ async function loadAllPlugins(userPlugins) {
227
192
  /**
228
193
  * @typedef {object} ValidationResult
229
194
  * @property {string} fileLocation - Path of the document that was validated.
230
- * Filenames are resolved and normalised using dot-relative notation. This
231
- * means relative paths in the current directory will be prefixed with `./`
232
- * (or `.\` on Windows) even if this was not present in the input filename or
233
- * pattern.
234
195
  * @property {number | null} documentIndex - Some file formats allow multiple
235
196
  * documents to be embedded in one file (e.g:
236
197
  * [yaml](https://www.yaml.info/learn/document.html)). In these cases,
@@ -1,4 +1,3 @@
1
- import { clearCacheById } from "flat-cache";
2
1
  import logger from "./logger.js";
3
2
 
4
3
  const origWriteOut = logger.writeOut;
@@ -7,7 +6,6 @@ const testCacheName = process.env.V8R_CACHE_NAME;
7
6
  const env = process.env;
8
7
 
9
8
  function setUp() {
10
- clearCacheById(testCacheName);
11
9
  logger.resetStdout();
12
10
  logger.resetStderr();
13
11
  logger.writeOut = function () {};
@@ -16,7 +14,6 @@ function setUp() {
16
14
  }
17
15
 
18
16
  function tearDown() {
19
- clearCacheById(testCacheName);
20
17
  logger.resetStdout();
21
18
  logger.resetStderr();
22
19
  logger.writeOut = origWriteOut;