eslint 8.24.0 → 8.25.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/lib/cli.js CHANGED
@@ -25,7 +25,6 @@ const fs = require("fs"),
25
25
  RuntimeInfo = require("./shared/runtime-info");
26
26
  const { Legacy: { naming } } = require("@eslint/eslintrc");
27
27
  const { findFlatConfigFile } = require("./eslint/flat-eslint");
28
- const { gitignoreToMinimatch } = require("@humanwhocodes/gitignore-to-minimatch");
29
28
  const { ModuleImporter } = require("@humanwhocodes/module-importer");
30
29
 
31
30
  const debug = require("debug")("eslint:cli");
@@ -38,6 +37,7 @@ const debug = require("debug")("eslint:cli");
38
37
  /** @typedef {import("./eslint/eslint").LintMessage} LintMessage */
39
38
  /** @typedef {import("./eslint/eslint").LintResult} LintResult */
40
39
  /** @typedef {import("./options").ParsedCLIOptions} ParsedCLIOptions */
40
+ /** @typedef {import("./shared/types").ResultsMeta} ResultsMeta */
41
41
 
42
42
  //------------------------------------------------------------------------------
43
43
  // Helpers
@@ -145,7 +145,7 @@ async function translateOptions({
145
145
 
146
146
  if (ignorePattern) {
147
147
  overrideConfig.push({
148
- ignores: ignorePattern.map(gitignoreToMinimatch)
148
+ ignores: ignorePattern
149
149
  });
150
150
  }
151
151
 
@@ -182,7 +182,6 @@ async function translateOptions({
182
182
  fix: (fix || fixDryRun) && (quiet ? quietFixPredicate : true),
183
183
  fixTypes: fixType,
184
184
  ignore,
185
- ignorePath,
186
185
  overrideConfig,
187
186
  overrideConfigFile,
188
187
  reportUnusedDisableDirectives: reportUnusedDisableDirectives ? "error" : void 0
@@ -193,6 +192,7 @@ async function translateOptions({
193
192
  options.rulePaths = rulesdir;
194
193
  options.useEslintrc = eslintrc;
195
194
  options.extensions = ext;
195
+ options.ignorePath = ignorePath;
196
196
  }
197
197
 
198
198
  return options;
@@ -201,7 +201,7 @@ async function translateOptions({
201
201
  /**
202
202
  * Count error messages.
203
203
  * @param {LintResult[]} results The lint results.
204
- * @returns {{errorCount:number;warningCount:number}} The number of error messages.
204
+ * @returns {{errorCount:number;fatalErrorCount:number,warningCount:number}} The number of error messages.
205
205
  */
206
206
  function countErrors(results) {
207
207
  let errorCount = 0;
@@ -239,10 +239,11 @@ async function isDirectory(filePath) {
239
239
  * @param {LintResult[]} results The results to print.
240
240
  * @param {string} format The name of the formatter to use or the path to the formatter.
241
241
  * @param {string} outputFile The path for the output file.
242
+ * @param {ResultsMeta} resultsMeta Warning count and max threshold.
242
243
  * @returns {Promise<boolean>} True if the printing succeeds, false if not.
243
244
  * @private
244
245
  */
245
- async function printResults(engine, results, format, outputFile) {
246
+ async function printResults(engine, results, format, outputFile, resultsMeta) {
246
247
  let formatter;
247
248
 
248
249
  try {
@@ -252,7 +253,7 @@ async function printResults(engine, results, format, outputFile) {
252
253
  return false;
253
254
  }
254
255
 
255
- const output = await formatter.format(results);
256
+ const output = await formatter.format(results, resultsMeta);
256
257
 
257
258
  if (output) {
258
259
  if (outputFile) {
@@ -407,17 +408,24 @@ const cli = {
407
408
  resultsToPrint = ActiveESLint.getErrorResults(resultsToPrint);
408
409
  }
409
410
 
410
- if (await printResults(engine, resultsToPrint, options.format, options.outputFile)) {
411
+ const resultCounts = countErrors(results);
412
+ const tooManyWarnings = options.maxWarnings >= 0 && resultCounts.warningCount > options.maxWarnings;
413
+ const resultsMeta = tooManyWarnings
414
+ ? {
415
+ maxWarningsExceeded: {
416
+ maxWarnings: options.maxWarnings,
417
+ foundWarnings: resultCounts.warningCount
418
+ }
419
+ }
420
+ : {};
411
421
 
412
- // Errors and warnings from the original unfiltered results should determine the exit code
413
- const { errorCount, fatalErrorCount, warningCount } = countErrors(results);
422
+ if (await printResults(engine, resultsToPrint, options.format, options.outputFile, resultsMeta)) {
414
423
 
415
- const tooManyWarnings =
416
- options.maxWarnings >= 0 && warningCount > options.maxWarnings;
424
+ // Errors and warnings from the original unfiltered results should determine the exit code
417
425
  const shouldExitForFatalErrors =
418
- options.exitOnFatalError && fatalErrorCount > 0;
426
+ options.exitOnFatalError && resultCounts.fatalErrorCount > 0;
419
427
 
420
- if (!errorCount && tooManyWarnings) {
428
+ if (!resultCounts.errorCount && tooManyWarnings) {
421
429
  log.error(
422
430
  "ESLint found too many warnings (maximum: %s).",
423
431
  options.maxWarnings
@@ -428,7 +436,7 @@ const cli = {
428
436
  return 2;
429
437
  }
430
438
 
431
- return (errorCount || tooManyWarnings) ? 1 : 0;
439
+ return (resultCounts.errorCount || tooManyWarnings) ? 1 : 0;
432
440
  }
433
441
 
434
442
  return 2;
@@ -70,7 +70,7 @@ class FlatConfigArray extends ConfigArray {
70
70
  }
71
71
 
72
72
  /**
73
- * The baes config used to build the config array.
73
+ * The base config used to build the config array.
74
74
  * @type {Array<FlatConfig>}
75
75
  */
76
76
  this[originalBaseConfig] = baseConfig;
@@ -67,9 +67,9 @@ function isNonEmptyString(x) {
67
67
  }
68
68
 
69
69
  /**
70
- * Check if a given value is an array of non-empty stringss or not.
70
+ * Check if a given value is an array of non-empty strings or not.
71
71
  * @param {any} x The value to check.
72
- * @returns {boolean} `true` if `x` is an array of non-empty stringss.
72
+ * @returns {boolean} `true` if `x` is an array of non-empty strings.
73
73
  */
74
74
  function isArrayOfNonEmptyString(x) {
75
75
  return Array.isArray(x) && x.every(isNonEmptyString);
@@ -410,7 +410,6 @@ function processOptions({
410
410
  fixTypes = null, // ← should be null by default because if it's an array then it suppresses rules that don't have the `meta.type` property.
411
411
  globInputPaths = true,
412
412
  ignore = true,
413
- ignorePath = null, // ← should be null by default because if it's a string then it may throw ENOENT.
414
413
  ignorePatterns = null,
415
414
  overrideConfig = null,
416
415
  overrideConfigFile = null,
@@ -441,6 +440,9 @@ function processOptions({
441
440
  if (unknownOptionKeys.includes("globals")) {
442
441
  errors.push("'globals' has been removed. Please use the 'overrideConfig.languageOptions.globals' option instead.");
443
442
  }
443
+ if (unknownOptionKeys.includes("ignorePath")) {
444
+ errors.push("'ignorePath' has been removed.");
445
+ }
444
446
  if (unknownOptionKeys.includes("ignorePattern")) {
445
447
  errors.push("'ignorePattern' has been removed. Please use the 'overrideConfig.ignorePatterns' option instead.");
446
448
  }
@@ -493,9 +495,6 @@ function processOptions({
493
495
  if (typeof ignore !== "boolean") {
494
496
  errors.push("'ignore' must be a boolean.");
495
497
  }
496
- if (!isNonEmptyString(ignorePath) && ignorePath !== null) {
497
- errors.push("'ignorePath' must be a non-empty string or null.");
498
- }
499
498
  if (typeof overrideConfig !== "object") {
500
499
  errors.push("'overrideConfig' must be an object or null.");
501
500
  }
@@ -538,7 +537,6 @@ function processOptions({
538
537
  fixTypes,
539
538
  globInputPaths,
540
539
  ignore,
541
- ignorePath,
542
540
  ignorePatterns,
543
541
  reportUnusedDisableDirectives
544
542
  };
@@ -36,11 +36,12 @@ const { version } = require("../../package.json");
36
36
  /** @typedef {import("../shared/types").Plugin} Plugin */
37
37
  /** @typedef {import("../shared/types").Rule} Rule */
38
38
  /** @typedef {import("../shared/types").LintResult} LintResult */
39
+ /** @typedef {import("../shared/types").ResultsMeta} ResultsMeta */
39
40
 
40
41
  /**
41
42
  * The main formatter object.
42
43
  * @typedef LoadedFormatter
43
- * @property {function(LintResult[]): string | Promise<string>} format format function.
44
+ * @property {(results: LintResult[], resultsMeta: ResultsMeta) => string | Promise<string>} format format function.
44
45
  */
45
46
 
46
47
  /**
@@ -625,14 +626,16 @@ class ESLint {
625
626
  /**
626
627
  * The main formatter method.
627
628
  * @param {LintResult[]} results The lint results to format.
629
+ * @param {ResultsMeta} resultsMeta Warning count and max threshold.
628
630
  * @returns {string | Promise<string>} The formatted lint results.
629
631
  */
630
- format(results) {
632
+ format(results, resultsMeta) {
631
633
  let rulesMeta = null;
632
634
 
633
635
  results.sort(compareResultsByFilePath);
634
636
 
635
637
  return formatter(results, {
638
+ ...resultsMeta,
636
639
  get cwd() {
637
640
  return options.cwd;
638
641
  },
@@ -16,7 +16,6 @@ const findUp = require("find-up");
16
16
  const { version } = require("../../package.json");
17
17
  const { Linter } = require("../linter");
18
18
  const { getRuleFromConfig } = require("../config/flat-config-helpers");
19
- const { gitignoreToMinimatch } = require("@humanwhocodes/gitignore-to-minimatch");
20
19
  const {
21
20
  Legacy: {
22
21
  ConfigOps: {
@@ -28,7 +27,6 @@ const {
28
27
  } = require("@eslint/eslintrc");
29
28
 
30
29
  const {
31
- fileExists,
32
30
  findFiles,
33
31
  getCacheFile,
34
32
 
@@ -59,6 +57,7 @@ const LintResultCache = require("../cli-engine/lint-result-cache");
59
57
  /** @typedef {import("../shared/types").LintMessage} LintMessage */
60
58
  /** @typedef {import("../shared/types").ParserOptions} ParserOptions */
61
59
  /** @typedef {import("../shared/types").Plugin} Plugin */
60
+ /** @typedef {import("../shared/types").ResultsMeta} ResultsMeta */
62
61
  /** @typedef {import("../shared/types").RuleConf} RuleConf */
63
62
  /** @typedef {import("../shared/types").Rule} Rule */
64
63
  /** @typedef {ReturnType<ConfigArray.extractConfig>} ExtractedConfig */
@@ -76,9 +75,8 @@ const LintResultCache = require("../cli-engine/lint-result-cache");
76
75
  * @property {boolean|Function} [fix] Execute in autofix mode. If a function, should return a boolean.
77
76
  * @property {string[]} [fixTypes] Array of rule types to apply fixes for.
78
77
  * @property {boolean} [globInputPaths] Set to false to skip glob resolution of input file paths to lint (default: true). If false, each input file paths is assumed to be a non-glob path to an existing file.
79
- * @property {boolean} [ignore] False disables use of .eslintignore.
80
- * @property {string} [ignorePath] The ignore file to use instead of .eslintignore.
81
- * @property {string[]} [ignorePatterns] Ignore file patterns to use in addition to .eslintignore.
78
+ * @property {boolean} [ignore] False disables all ignore patterns except for the default ones.
79
+ * @property {string[]} [ignorePatterns] Ignore file patterns to use in addition to config ignores.
82
80
  * @property {ConfigData} [overrideConfig] Override config object, overrides all configs used with this instance
83
81
  * @property {boolean|string} [overrideConfigFile] Searches for default config file when falsy;
84
82
  * doesn't do any config file lookup when `true`; considered to be a config filename
@@ -151,30 +149,6 @@ function calculateStatsPerRun(results) {
151
149
  });
152
150
  }
153
151
 
154
- /**
155
- * Loads global ignore patterns from an ignore file (usually .eslintignore).
156
- * @param {string} filePath The filename to load.
157
- * @returns {ignore} A function encapsulating the ignore patterns.
158
- * @throws {Error} If the file cannot be read.
159
- * @private
160
- */
161
- async function loadIgnoreFilePatterns(filePath) {
162
- debug(`Loading ignore file: ${filePath}`);
163
-
164
- try {
165
- const ignoreFileText = await fs.readFile(filePath, { encoding: "utf8" });
166
-
167
- return ignoreFileText
168
- .split(/\r?\n/gu)
169
- .filter(line => line.trim() !== "" && !line.startsWith("#"));
170
-
171
- } catch (e) {
172
- debug(`Error reading ignore file: ${filePath}`);
173
- e.message = `Cannot read ignore file: ${filePath}\nError: ${e.message}`;
174
- throw e;
175
- }
176
- }
177
-
178
152
  /**
179
153
  * Create rulesMeta object.
180
154
  * @param {Map<string,Rule>} rules a map of rules from which to generate the object.
@@ -319,7 +293,6 @@ async function calculateConfigArray(eslint, {
319
293
  overrideConfig,
320
294
  configFile,
321
295
  ignore: shouldIgnore,
322
- ignorePath,
323
296
  ignorePatterns
324
297
  }) {
325
298
 
@@ -364,22 +337,6 @@ async function calculateConfigArray(eslint, {
364
337
  configs.push(...slots.defaultConfigs);
365
338
 
366
339
  let allIgnorePatterns = [];
367
- let ignoreFilePath;
368
-
369
- // load ignore file if necessary
370
- if (shouldIgnore) {
371
- if (ignorePath) {
372
- ignoreFilePath = path.resolve(cwd, ignorePath);
373
- allIgnorePatterns = await loadIgnoreFilePatterns(ignoreFilePath);
374
- } else {
375
- ignoreFilePath = path.resolve(cwd, ".eslintignore");
376
-
377
- // no error if .eslintignore doesn't exist`
378
- if (fileExists(ignoreFilePath)) {
379
- allIgnorePatterns = await loadIgnoreFilePatterns(ignoreFilePath);
380
- }
381
- }
382
- }
383
340
 
384
341
  // append command line ignore patterns
385
342
  if (ignorePatterns) {
@@ -428,7 +385,7 @@ async function calculateConfigArray(eslint, {
428
385
  * so they can override default ignores.
429
386
  */
430
387
  configs.push({
431
- ignores: allIgnorePatterns.map(gitignoreToMinimatch)
388
+ ignores: allIgnorePatterns
432
389
  });
433
390
  }
434
391
 
@@ -872,7 +829,7 @@ class FlatESLint {
872
829
  }
873
830
 
874
831
 
875
- // set up fixer for fixtypes if necessary
832
+ // set up fixer for fixTypes if necessary
876
833
  let fixer = fix;
877
834
 
878
835
  if (fix && fixTypesSet) {
@@ -1048,7 +1005,7 @@ class FlatESLint {
1048
1005
  * The following values are allowed:
1049
1006
  * - `undefined` ... Load `stylish` builtin formatter.
1050
1007
  * - A builtin formatter name ... Load the builtin formatter.
1051
- * - A thirdparty formatter name:
1008
+ * - A third-party formatter name:
1052
1009
  * - `foo` → `eslint-formatter-foo`
1053
1010
  * - `@foo` → `@foo/eslint-formatter`
1054
1011
  * - `@foo/bar` → `@foo/eslint-formatter-bar`
@@ -1114,14 +1071,16 @@ class FlatESLint {
1114
1071
  /**
1115
1072
  * The main formatter method.
1116
1073
  * @param {LintResults[]} results The lint results to format.
1074
+ * @param {ResultsMeta} resultsMeta Warning count and max threshold.
1117
1075
  * @returns {string} The formatted lint results.
1118
1076
  */
1119
- format(results) {
1077
+ format(results, resultsMeta) {
1120
1078
  let rulesMeta = null;
1121
1079
 
1122
1080
  results.sort(compareResultsByFilePath);
1123
1081
 
1124
1082
  return formatter(results, {
1083
+ ...resultsMeta,
1125
1084
  cwd,
1126
1085
  get rulesMeta() {
1127
1086
  if (!rulesMeta) {
package/lib/options.js CHANGED
@@ -67,7 +67,7 @@ const optionator = require("optionator");
67
67
  /**
68
68
  * Creates the CLI options for ESLint.
69
69
  * @param {boolean} usingFlatConfig Indicates if flat config is being used.
70
- * @returns {Object} The opinionator instance.
70
+ * @returns {Object} The optionator instance.
71
71
  */
72
72
  module.exports = function(usingFlatConfig) {
73
73
 
@@ -129,6 +129,16 @@ module.exports = function(usingFlatConfig) {
129
129
  };
130
130
  }
131
131
 
132
+ let ignorePathFlag;
133
+
134
+ if (!usingFlatConfig) {
135
+ ignorePathFlag = {
136
+ option: "ignore-path",
137
+ type: "path::String",
138
+ description: "Specify path of ignore file"
139
+ };
140
+ }
141
+
132
142
  return optionator({
133
143
  prepend: "eslint [options] file.js [file.js] [dir]",
134
144
  defaults: {
@@ -203,11 +213,7 @@ module.exports = function(usingFlatConfig) {
203
213
  {
204
214
  heading: "Ignoring files"
205
215
  },
206
- {
207
- option: "ignore-path",
208
- type: "path::String",
209
- description: "Specify path of ignore file"
210
- },
216
+ ignorePathFlag,
211
217
  {
212
218
  option: "ignore",
213
219
  type: "Boolean",
@@ -6,6 +6,45 @@
6
6
 
7
7
  "use strict";
8
8
 
9
+ //------------------------------------------------------------------------------
10
+ // Requirements
11
+ //------------------------------------------------------------------------------
12
+ const GraphemeSplitter = require("grapheme-splitter");
13
+
14
+ //------------------------------------------------------------------------------
15
+ // Helpers
16
+ //------------------------------------------------------------------------------
17
+
18
+ /**
19
+ * Checks if the string given as argument is ASCII or not.
20
+ * @param {string} value A string that you want to know if it is ASCII or not.
21
+ * @returns {boolean} `true` if `value` is ASCII string.
22
+ */
23
+ function isASCII(value) {
24
+ if (typeof value !== "string") {
25
+ return false;
26
+ }
27
+ return /^[\u0020-\u007f]*$/u.test(value);
28
+ }
29
+
30
+ /** @type {GraphemeSplitter | undefined} */
31
+ let splitter;
32
+
33
+ /**
34
+ * Gets the length of the string. If the string is not in ASCII, counts graphemes.
35
+ * @param {string} value A string that you want to get the length.
36
+ * @returns {number} The length of `value`.
37
+ */
38
+ function getStringLength(value) {
39
+ if (isASCII(value)) {
40
+ return value.length;
41
+ }
42
+ if (!splitter) {
43
+ splitter = new GraphemeSplitter();
44
+ }
45
+ return splitter.countGraphemes(value);
46
+ }
47
+
9
48
  //------------------------------------------------------------------------------
10
49
  // Rule Definition
11
50
  //------------------------------------------------------------------------------
@@ -130,8 +169,10 @@ module.exports = {
130
169
  const name = node.name;
131
170
  const parent = node.parent;
132
171
 
133
- const isShort = name.length < minLength;
134
- const isLong = name.length > maxLength;
172
+ const nameLength = getStringLength(name);
173
+
174
+ const isShort = nameLength < minLength;
175
+ const isLong = nameLength > maxLength;
135
176
 
136
177
  if (!(isShort || isLong) || exceptions.has(name) || matchesExceptionPattern(name)) {
137
178
  return; // Nothing to report
@@ -15,7 +15,7 @@ const astUtils = require("./utils/ast-utils");
15
15
  //------------------------------------------------------------------------------
16
16
 
17
17
  /**
18
- * Return an array with with any line numbers that are empty.
18
+ * Return an array with any line numbers that are empty.
19
19
  * @param {Array} lines An array of each line of the file.
20
20
  * @returns {Array} An array of line numbers.
21
21
  */
@@ -29,7 +29,7 @@ function getEmptyLineNums(lines) {
29
29
  }
30
30
 
31
31
  /**
32
- * Return an array with with any line numbers that contain comments.
32
+ * Return an array with any line numbers that contain comments.
33
33
  * @param {Array} comments An array of comment tokens.
34
34
  * @returns {Array} An array of line numbers.
35
35
  */
@@ -105,7 +105,7 @@ module.exports = {
105
105
  }
106
106
 
107
107
  /**
108
- * Converts an integer to to an object containing the integer's coefficient and order of magnitude
108
+ * Converts an integer to an object containing the integer's coefficient and order of magnitude
109
109
  * @param {string} stringInteger the string representation of the integer being converted
110
110
  * @returns {Object} the object containing the integer's coefficient and order of magnitude
111
111
  */
@@ -120,7 +120,7 @@ module.exports = {
120
120
 
121
121
  /**
122
122
  *
123
- * Converts a float to to an object containing the floats's coefficient and order of magnitude
123
+ * Converts a float to an object containing the floats's coefficient and order of magnitude
124
124
  * @param {string} stringFloat the string representation of the float being converted
125
125
  * @returns {Object} the object containing the integer's coefficient and order of magnitude
126
126
  */
@@ -68,7 +68,7 @@ function isInClassStaticInitializerRange(node, location) {
68
68
  }
69
69
 
70
70
  /**
71
- * Checks whether a given scope is the scope of a a class static initializer.
71
+ * Checks whether a given scope is the scope of a class static initializer.
72
72
  * Static initializers are static blocks and initializers of static fields.
73
73
  * @param {eslint-scope.Scope} scope A scope to check.
74
74
  * @returns {boolean} `true` if the scope is a class static initializer scope.
@@ -74,7 +74,7 @@ class Traverser {
74
74
  }
75
75
 
76
76
  /**
77
- * Gives a a copy of the ancestor nodes.
77
+ * Gives a copy of the ancestor nodes.
78
78
  * @returns {ASTNode[]} The ancestor nodes.
79
79
  */
80
80
  parents() {
@@ -190,10 +190,23 @@ module.exports = {};
190
190
  * @property {DeprecatedRuleInfo[]} usedDeprecatedRules The list of used deprecated rules.
191
191
  */
192
192
 
193
+ /**
194
+ * Information provided when the maximum warning threshold is exceeded.
195
+ * @typedef {Object} MaxWarningsExceeded
196
+ * @property {number} maxWarnings Number of warnings to trigger nonzero exit code.
197
+ * @property {number} foundWarnings Number of warnings found while linting.
198
+ */
199
+
200
+ /**
201
+ * Metadata about results for formatters.
202
+ * @typedef {Object} ResultsMeta
203
+ * @property {MaxWarningsExceeded} [maxWarningsExceeded] Present if the maxWarnings threshold was exceeded.
204
+ */
205
+
193
206
  /**
194
207
  * A formatter function.
195
208
  * @callback FormatterFunction
196
209
  * @param {LintResult[]} results The list of linting results.
197
- * @param {{cwd: string, rulesMeta: Record<string, RuleMeta>}} [context] A context object.
210
+ * @param {{cwd: string, maxWarningsExceeded?: MaxWarningsExceeded, rulesMeta: Record<string, RuleMeta>}} [context] A context object.
198
211
  * @returns {string | Promise<string>} Formatted text.
199
212
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint",
3
- "version": "8.24.0",
3
+ "version": "8.25.0",
4
4
  "author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
5
5
  "description": "An AST-based pattern checker for JavaScript.",
6
6
  "bin": {
@@ -55,9 +55,8 @@
55
55
  "homepage": "https://eslint.org",
56
56
  "bugs": "https://github.com/eslint/eslint/issues/",
57
57
  "dependencies": {
58
- "@eslint/eslintrc": "^1.3.2",
58
+ "@eslint/eslintrc": "^1.3.3",
59
59
  "@humanwhocodes/config-array": "^0.10.5",
60
- "@humanwhocodes/gitignore-to-minimatch": "^1.0.2",
61
60
  "@humanwhocodes/module-importer": "^1.0.1",
62
61
  "ajv": "^6.10.0",
63
62
  "chalk": "^4.0.0",
@@ -121,7 +120,6 @@
121
120
  "glob": "^7.1.6",
122
121
  "got": "^11.8.3",
123
122
  "gray-matter": "^4.0.3",
124
- "jsdoc": "^3.5.5",
125
123
  "karma": "^6.1.1",
126
124
  "karma-chrome-launcher": "^3.1.0",
127
125
  "karma-mocha": "^2.0.1",