eslint-linter-browserify 10.0.2 → 10.0.3

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.
Files changed (5) hide show
  1. package/linter.cjs +484 -143
  2. package/linter.js +484 -143
  3. package/linter.min.js +3 -3
  4. package/linter.mjs +484 -143
  5. package/package.json +5 -5
package/linter.cjs CHANGED
@@ -4003,7 +4003,7 @@ function requireEslintScope () {
4003
4003
  }
4004
4004
 
4005
4005
  /** @name module:escope.version */
4006
- const version = "9.1.1"; // x-release-please-version
4006
+ const version = "9.1.2"; // x-release-please-version
4007
4007
 
4008
4008
  /* vim: set sw=4 ts=4 et tw=80 : */
4009
4009
 
@@ -4216,7 +4216,7 @@ function requireEslintVisitorKeys$2 () {
4216
4216
  return eslintVisitorKeys$2;
4217
4217
  }
4218
4218
 
4219
- var version = "10.0.2";
4219
+ var version = "10.0.3";
4220
4220
  var require$$3$1 = {
4221
4221
  version: version};
4222
4222
 
@@ -22788,7 +22788,7 @@ function requireCommonjs$1 () {
22788
22788
  const openPattern = /\\{/g;
22789
22789
  const closePattern = /\\}/g;
22790
22790
  const commaPattern = /\\,/g;
22791
- const periodPattern = /\\./g;
22791
+ const periodPattern = /\\\./g;
22792
22792
  exports$1.EXPANSION_MAX = 100_000;
22793
22793
  function numeric(str) {
22794
22794
  return !isNaN(str) ? parseInt(str, 10) : str.charCodeAt(0);
@@ -23208,12 +23208,114 @@ function requireAst$1 () {
23208
23208
  if (hasRequiredAst$1) return ast$1;
23209
23209
  hasRequiredAst$1 = 1;
23210
23210
  // parse a single path portion
23211
+ var _a;
23211
23212
  Object.defineProperty(ast$1, "__esModule", { value: true });
23212
23213
  ast$1.AST = void 0;
23213
23214
  const brace_expressions_js_1 = requireBraceExpressions();
23214
23215
  const unescape_js_1 = require_unescape();
23215
23216
  const types = new Set(['!', '?', '+', '*', '@']);
23216
23217
  const isExtglobType = (c) => types.has(c);
23218
+ const isExtglobAST = (c) => isExtglobType(c.type);
23219
+ // Map of which extglob types can adopt the children of a nested extglob
23220
+ //
23221
+ // anything but ! can adopt a matching type:
23222
+ // +(a|+(b|c)|d) => +(a|b|c|d)
23223
+ // *(a|*(b|c)|d) => *(a|b|c|d)
23224
+ // @(a|@(b|c)|d) => @(a|b|c|d)
23225
+ // ?(a|?(b|c)|d) => ?(a|b|c|d)
23226
+ //
23227
+ // * can adopt anything, because 0 or repetition is allowed
23228
+ // *(a|?(b|c)|d) => *(a|b|c|d)
23229
+ // *(a|+(b|c)|d) => *(a|b|c|d)
23230
+ // *(a|@(b|c)|d) => *(a|b|c|d)
23231
+ //
23232
+ // + can adopt @, because 1 or repetition is allowed
23233
+ // +(a|@(b|c)|d) => +(a|b|c|d)
23234
+ //
23235
+ // + and @ CANNOT adopt *, because 0 would be allowed
23236
+ // +(a|*(b|c)|d) => would match "", on *(b|c)
23237
+ // @(a|*(b|c)|d) => would match "", on *(b|c)
23238
+ //
23239
+ // + and @ CANNOT adopt ?, because 0 would be allowed
23240
+ // +(a|?(b|c)|d) => would match "", on ?(b|c)
23241
+ // @(a|?(b|c)|d) => would match "", on ?(b|c)
23242
+ //
23243
+ // ? can adopt @, because 0 or 1 is allowed
23244
+ // ?(a|@(b|c)|d) => ?(a|b|c|d)
23245
+ //
23246
+ // ? and @ CANNOT adopt * or +, because >1 would be allowed
23247
+ // ?(a|*(b|c)|d) => would match bbb on *(b|c)
23248
+ // @(a|*(b|c)|d) => would match bbb on *(b|c)
23249
+ // ?(a|+(b|c)|d) => would match bbb on +(b|c)
23250
+ // @(a|+(b|c)|d) => would match bbb on +(b|c)
23251
+ //
23252
+ // ! CANNOT adopt ! (nothing else can either)
23253
+ // !(a|!(b|c)|d) => !(a|b|c|d) would fail to match on b (not not b|c)
23254
+ //
23255
+ // ! can adopt @
23256
+ // !(a|@(b|c)|d) => !(a|b|c|d)
23257
+ //
23258
+ // ! CANNOT adopt *
23259
+ // !(a|*(b|c)|d) => !(a|b|c|d) would match on bbb, not allowed
23260
+ //
23261
+ // ! CANNOT adopt +
23262
+ // !(a|+(b|c)|d) => !(a|b|c|d) would match on bbb, not allowed
23263
+ //
23264
+ // ! CANNOT adopt ?
23265
+ // x!(a|?(b|c)|d) => x!(a|b|c|d) would fail to match "x"
23266
+ const adoptionMap = new Map([
23267
+ ['!', ['@']],
23268
+ ['?', ['?', '@']],
23269
+ ['@', ['@']],
23270
+ ['*', ['*', '+', '?', '@']],
23271
+ ['+', ['+', '@']],
23272
+ ]);
23273
+ // nested extglobs that can be adopted in, but with the addition of
23274
+ // a blank '' element.
23275
+ const adoptionWithSpaceMap = new Map([
23276
+ ['!', ['?']],
23277
+ ['@', ['?']],
23278
+ ['+', ['?', '*']],
23279
+ ]);
23280
+ // union of the previous two maps
23281
+ const adoptionAnyMap = new Map([
23282
+ ['!', ['?', '@']],
23283
+ ['?', ['?', '@']],
23284
+ ['@', ['?', '@']],
23285
+ ['*', ['*', '+', '?', '@']],
23286
+ ['+', ['+', '@', '?', '*']],
23287
+ ]);
23288
+ // Extglobs that can take over their parent if they are the only child
23289
+ // the key is parent, value maps child to resulting extglob parent type
23290
+ // '@' is omitted because it's a special case. An `@` extglob with a single
23291
+ // member can always be usurped by that subpattern.
23292
+ const usurpMap = new Map([
23293
+ ['!', new Map([['!', '@']])],
23294
+ [
23295
+ '?',
23296
+ new Map([
23297
+ ['*', '*'],
23298
+ ['+', '*'],
23299
+ ]),
23300
+ ],
23301
+ [
23302
+ '@',
23303
+ new Map([
23304
+ ['!', '!'],
23305
+ ['?', '?'],
23306
+ ['@', '@'],
23307
+ ['*', '*'],
23308
+ ['+', '+'],
23309
+ ]),
23310
+ ],
23311
+ [
23312
+ '+',
23313
+ new Map([
23314
+ ['?', '*'],
23315
+ ['*', '*'],
23316
+ ]),
23317
+ ],
23318
+ ]);
23217
23319
  // Patterns that get prepended to bind to the start of either the
23218
23320
  // entire string, or just a single path portion, to prevent dots
23219
23321
  // and/or traversal patterns, when needed.
@@ -23237,6 +23339,7 @@ function requireAst$1 () {
23237
23339
  const starNoEmpty = qmark + '+?';
23238
23340
  // remove the \ chars that we added if we end up doing a nonmagic compare
23239
23341
  // const deslash = (s: string) => s.replace(/\\(.)/g, '$1')
23342
+ let ID = 0;
23240
23343
  class AST {
23241
23344
  type;
23242
23345
  #root;
@@ -23252,6 +23355,22 @@ function requireAst$1 () {
23252
23355
  // set to true if it's an extglob with no children
23253
23356
  // (which really means one child of '')
23254
23357
  #emptyExt = false;
23358
+ id = ++ID;
23359
+ get depth() {
23360
+ return (this.#parent?.depth ?? -1) + 1;
23361
+ }
23362
+ [Symbol.for('nodejs.util.inspect.custom')]() {
23363
+ return {
23364
+ '@@type': 'AST',
23365
+ id: this.id,
23366
+ type: this.type,
23367
+ root: this.#root.id,
23368
+ parent: this.#parent?.id,
23369
+ depth: this.depth,
23370
+ partsLength: this.#parts.length,
23371
+ parts: this.#parts,
23372
+ };
23373
+ }
23255
23374
  constructor(type, parent, options = {}) {
23256
23375
  this.type = type;
23257
23376
  // extglobs are inherently magical
@@ -23331,7 +23450,7 @@ function requireAst$1 () {
23331
23450
  continue;
23332
23451
  /* c8 ignore start */
23333
23452
  if (typeof p !== 'string' &&
23334
- !(p instanceof AST && p.#parent === this)) {
23453
+ !(p instanceof _a && p.#parent === this)) {
23335
23454
  throw new Error('invalid part: ' + p);
23336
23455
  }
23337
23456
  /* c8 ignore stop */
@@ -23365,7 +23484,7 @@ function requireAst$1 () {
23365
23484
  const p = this.#parent;
23366
23485
  for (let i = 0; i < this.#parentIndex; i++) {
23367
23486
  const pp = p.#parts[i];
23368
- if (!(pp instanceof AST && pp.type === '!')) {
23487
+ if (!(pp instanceof _a && pp.type === '!')) {
23369
23488
  return false;
23370
23489
  }
23371
23490
  }
@@ -23393,13 +23512,14 @@ function requireAst$1 () {
23393
23512
  this.push(part.clone(this));
23394
23513
  }
23395
23514
  clone(parent) {
23396
- const c = new AST(this.type, parent);
23515
+ const c = new _a(this.type, parent);
23397
23516
  for (const p of this.#parts) {
23398
23517
  c.copyIn(p);
23399
23518
  }
23400
23519
  return c;
23401
23520
  }
23402
- static #parseAST(str, ast, pos, opt) {
23521
+ static #parseAST(str, ast, pos, opt, extDepth) {
23522
+ const maxDepth = opt.maxExtglobRecursion ?? 2;
23403
23523
  let escaping = false;
23404
23524
  let inBrace = false;
23405
23525
  let braceStart = -1;
@@ -23436,11 +23556,17 @@ function requireAst$1 () {
23436
23556
  acc += c;
23437
23557
  continue;
23438
23558
  }
23439
- if (!opt.noext && isExtglobType(c) && str.charAt(i) === '(') {
23559
+ // we don't have to check for adoption here, because that's
23560
+ // done at the other recursion point.
23561
+ const doRecurse = !opt.noext &&
23562
+ isExtglobType(c) &&
23563
+ str.charAt(i) === '(' &&
23564
+ extDepth <= maxDepth;
23565
+ if (doRecurse) {
23440
23566
  ast.push(acc);
23441
23567
  acc = '';
23442
- const ext = new AST(c, ast);
23443
- i = AST.#parseAST(str, ext, i, opt);
23568
+ const ext = new _a(c, ast);
23569
+ i = _a.#parseAST(str, ext, i, opt, extDepth + 1);
23444
23570
  ast.push(ext);
23445
23571
  continue;
23446
23572
  }
@@ -23452,7 +23578,7 @@ function requireAst$1 () {
23452
23578
  // some kind of extglob, pos is at the (
23453
23579
  // find the next | or )
23454
23580
  let i = pos + 1;
23455
- let part = new AST(null, ast);
23581
+ let part = new _a(null, ast);
23456
23582
  const parts = [];
23457
23583
  let acc = '';
23458
23584
  while (i < str.length) {
@@ -23483,19 +23609,26 @@ function requireAst$1 () {
23483
23609
  acc += c;
23484
23610
  continue;
23485
23611
  }
23486
- if (isExtglobType(c) && str.charAt(i) === '(') {
23612
+ const doRecurse = !opt.noext &&
23613
+ isExtglobType(c) &&
23614
+ str.charAt(i) === '(' &&
23615
+ /* c8 ignore start - the maxDepth is sufficient here */
23616
+ (extDepth <= maxDepth || (ast && ast.#canAdoptType(c)));
23617
+ /* c8 ignore stop */
23618
+ if (doRecurse) {
23619
+ const depthAdd = ast && ast.#canAdoptType(c) ? 0 : 1;
23487
23620
  part.push(acc);
23488
23621
  acc = '';
23489
- const ext = new AST(c, part);
23622
+ const ext = new _a(c, part);
23490
23623
  part.push(ext);
23491
- i = AST.#parseAST(str, ext, i, opt);
23624
+ i = _a.#parseAST(str, ext, i, opt, extDepth + depthAdd);
23492
23625
  continue;
23493
23626
  }
23494
23627
  if (c === '|') {
23495
23628
  part.push(acc);
23496
23629
  acc = '';
23497
23630
  parts.push(part);
23498
- part = new AST(null, ast);
23631
+ part = new _a(null, ast);
23499
23632
  continue;
23500
23633
  }
23501
23634
  if (c === ')') {
@@ -23517,9 +23650,82 @@ function requireAst$1 () {
23517
23650
  ast.#parts = [str.substring(pos - 1)];
23518
23651
  return i;
23519
23652
  }
23653
+ #canAdoptWithSpace(child) {
23654
+ return this.#canAdopt(child, adoptionWithSpaceMap);
23655
+ }
23656
+ #canAdopt(child, map = adoptionMap) {
23657
+ if (!child ||
23658
+ typeof child !== 'object' ||
23659
+ child.type !== null ||
23660
+ child.#parts.length !== 1 ||
23661
+ this.type === null) {
23662
+ return false;
23663
+ }
23664
+ const gc = child.#parts[0];
23665
+ if (!gc || typeof gc !== 'object' || gc.type === null) {
23666
+ return false;
23667
+ }
23668
+ return this.#canAdoptType(gc.type, map);
23669
+ }
23670
+ #canAdoptType(c, map = adoptionAnyMap) {
23671
+ return !!map.get(this.type)?.includes(c);
23672
+ }
23673
+ #adoptWithSpace(child, index) {
23674
+ const gc = child.#parts[0];
23675
+ const blank = new _a(null, gc, this.options);
23676
+ blank.#parts.push('');
23677
+ gc.push(blank);
23678
+ this.#adopt(child, index);
23679
+ }
23680
+ #adopt(child, index) {
23681
+ const gc = child.#parts[0];
23682
+ this.#parts.splice(index, 1, ...gc.#parts);
23683
+ for (const p of gc.#parts) {
23684
+ if (typeof p === 'object')
23685
+ p.#parent = this;
23686
+ }
23687
+ this.#toString = undefined;
23688
+ }
23689
+ #canUsurpType(c) {
23690
+ const m = usurpMap.get(this.type);
23691
+ return !!(m?.has(c));
23692
+ }
23693
+ #canUsurp(child) {
23694
+ if (!child ||
23695
+ typeof child !== 'object' ||
23696
+ child.type !== null ||
23697
+ child.#parts.length !== 1 ||
23698
+ this.type === null ||
23699
+ this.#parts.length !== 1) {
23700
+ return false;
23701
+ }
23702
+ const gc = child.#parts[0];
23703
+ if (!gc || typeof gc !== 'object' || gc.type === null) {
23704
+ return false;
23705
+ }
23706
+ return this.#canUsurpType(gc.type);
23707
+ }
23708
+ #usurp(child) {
23709
+ const m = usurpMap.get(this.type);
23710
+ const gc = child.#parts[0];
23711
+ const nt = m?.get(gc.type);
23712
+ /* c8 ignore start - impossible */
23713
+ if (!nt)
23714
+ return false;
23715
+ /* c8 ignore stop */
23716
+ this.#parts = gc.#parts;
23717
+ for (const p of this.#parts) {
23718
+ if (typeof p === 'object') {
23719
+ p.#parent = this;
23720
+ }
23721
+ }
23722
+ this.type = nt;
23723
+ this.#toString = undefined;
23724
+ this.#emptyExt = false;
23725
+ }
23520
23726
  static fromGlob(pattern, options = {}) {
23521
- const ast = new AST(null, undefined, options);
23522
- AST.#parseAST(pattern, ast, 0, options);
23727
+ const ast = new _a(null, undefined, options);
23728
+ _a.#parseAST(pattern, ast, 0, options, 0);
23523
23729
  return ast;
23524
23730
  }
23525
23731
  // returns the regular expression if there's magic, or the unescaped
@@ -23623,16 +23829,18 @@ function requireAst$1 () {
23623
23829
  // or start or whatever) and prepend ^ or / at the Regexp construction.
23624
23830
  toRegExpSource(allowDot) {
23625
23831
  const dot = allowDot ?? !!this.#options.dot;
23626
- if (this.#root === this)
23832
+ if (this.#root === this) {
23833
+ this.#flatten();
23627
23834
  this.#fillNegs();
23628
- if (!this.type) {
23835
+ }
23836
+ if (!isExtglobAST(this)) {
23629
23837
  const noEmpty = this.isStart() &&
23630
23838
  this.isEnd() &&
23631
23839
  !this.#parts.some(s => typeof s !== 'string');
23632
23840
  const src = this.#parts
23633
23841
  .map(p => {
23634
23842
  const [re, _, hasMagic, uflag] = typeof p === 'string' ?
23635
- AST.#parseGlob(p, this.#hasMagic, noEmpty)
23843
+ _a.#parseGlob(p, this.#hasMagic, noEmpty)
23636
23844
  : p.toRegExpSource(allowDot);
23637
23845
  this.#hasMagic = this.#hasMagic || hasMagic;
23638
23846
  this.#uflag = this.#uflag || uflag;
@@ -23694,12 +23902,12 @@ function requireAst$1 () {
23694
23902
  // invalid extglob, has to at least be *something* present, if it's
23695
23903
  // the entire path portion.
23696
23904
  const s = this.toString();
23697
- this.#parts = [s];
23698
- this.type = null;
23699
- this.#hasMagic = undefined;
23905
+ const me = this;
23906
+ me.#parts = [s];
23907
+ me.type = null;
23908
+ me.#hasMagic = undefined;
23700
23909
  return [s, (0, unescape_js_1.unescape)(this.toString()), false, false];
23701
23910
  }
23702
- // XXX abstract out this map method
23703
23911
  let bodyDotAllowed = !repeated || allowDot || dot || !startNoDot ?
23704
23912
  ''
23705
23913
  : this.#partsToRegExp(true);
@@ -23735,6 +23943,42 @@ function requireAst$1 () {
23735
23943
  this.#uflag,
23736
23944
  ];
23737
23945
  }
23946
+ #flatten() {
23947
+ if (!isExtglobAST(this)) {
23948
+ for (const p of this.#parts) {
23949
+ if (typeof p === 'object') {
23950
+ p.#flatten();
23951
+ }
23952
+ }
23953
+ }
23954
+ else {
23955
+ // do up to 10 passes to flatten as much as possible
23956
+ let iterations = 0;
23957
+ let done = false;
23958
+ do {
23959
+ done = true;
23960
+ for (let i = 0; i < this.#parts.length; i++) {
23961
+ const c = this.#parts[i];
23962
+ if (typeof c === 'object') {
23963
+ c.#flatten();
23964
+ if (this.#canAdopt(c)) {
23965
+ done = false;
23966
+ this.#adopt(c, i);
23967
+ }
23968
+ else if (this.#canAdoptWithSpace(c)) {
23969
+ done = false;
23970
+ this.#adoptWithSpace(c, i);
23971
+ }
23972
+ else if (this.#canUsurp(c)) {
23973
+ done = false;
23974
+ this.#usurp(c);
23975
+ }
23976
+ }
23977
+ }
23978
+ } while (!done && ++iterations < 10);
23979
+ }
23980
+ this.#toString = undefined;
23981
+ }
23738
23982
  #partsToRegExp(dot) {
23739
23983
  return this.#parts
23740
23984
  .map(p => {
@@ -23806,6 +24050,7 @@ function requireAst$1 () {
23806
24050
  }
23807
24051
  }
23808
24052
  ast$1.AST = AST;
24053
+ _a = AST;
23809
24054
 
23810
24055
  return ast$1;
23811
24056
  }
@@ -24058,11 +24303,13 @@ function requireCommonjs () {
24058
24303
  isWindows;
24059
24304
  platform;
24060
24305
  windowsNoMagicRoot;
24306
+ maxGlobstarRecursion;
24061
24307
  regexp;
24062
24308
  constructor(pattern, options = {}) {
24063
24309
  (0, assert_valid_pattern_js_1.assertValidPattern)(pattern);
24064
24310
  options = options || {};
24065
24311
  this.options = options;
24312
+ this.maxGlobstarRecursion = options.maxGlobstarRecursion ?? 200;
24066
24313
  this.pattern = pattern;
24067
24314
  this.platform = options.platform || defaultPlatform;
24068
24315
  this.isWindows = this.platform === 'win32';
@@ -24467,7 +24714,8 @@ function requireCommonjs () {
24467
24714
  // out of pattern, then that's fine, as long as all
24468
24715
  // the parts match.
24469
24716
  matchOne(file, pattern, partial = false) {
24470
- const options = this.options;
24717
+ let fileStartIndex = 0;
24718
+ let patternStartIndex = 0;
24471
24719
  // UNC paths like //?/X:/... can match X:/... and vice versa
24472
24720
  // Drive letters in absolute drive or unc paths are always compared
24473
24721
  // case-insensitively.
@@ -24496,14 +24744,11 @@ function requireCommonjs () {
24496
24744
  file[fdi],
24497
24745
  pattern[pdi],
24498
24746
  ];
24747
+ // start matching at the drive letter index of each
24499
24748
  if (fd.toLowerCase() === pd.toLowerCase()) {
24500
24749
  pattern[pdi] = fd;
24501
- if (pdi > fdi) {
24502
- pattern = pattern.slice(pdi);
24503
- }
24504
- else if (fdi > pdi) {
24505
- file = file.slice(fdi);
24506
- }
24750
+ patternStartIndex = pdi;
24751
+ fileStartIndex = fdi;
24507
24752
  }
24508
24753
  }
24509
24754
  }
@@ -24513,99 +24758,185 @@ function requireCommonjs () {
24513
24758
  if (optimizationLevel >= 2) {
24514
24759
  file = this.levelTwoFileOptimize(file);
24515
24760
  }
24516
- this.debug('matchOne', this, { file, pattern });
24517
- this.debug('matchOne', file.length, pattern.length);
24518
- for (var fi = 0, pi = 0, fl = file.length, pl = pattern.length; fi < fl && pi < pl; fi++, pi++) {
24761
+ if (pattern.includes(exports$1.GLOBSTAR)) {
24762
+ return this.#matchGlobstar(file, pattern, partial, fileStartIndex, patternStartIndex);
24763
+ }
24764
+ return this.#matchOne(file, pattern, partial, fileStartIndex, patternStartIndex);
24765
+ }
24766
+ #matchGlobstar(file, pattern, partial, fileIndex, patternIndex) {
24767
+ // split the pattern into head, tail, and middle of ** delimited parts
24768
+ const firstgs = pattern.indexOf(exports$1.GLOBSTAR, patternIndex);
24769
+ const lastgs = pattern.lastIndexOf(exports$1.GLOBSTAR);
24770
+ // split the pattern up into globstar-delimited sections
24771
+ // the tail has to be at the end, and the others just have
24772
+ // to be found in order from the head.
24773
+ const [head, body, tail] = partial ? [
24774
+ pattern.slice(patternIndex, firstgs),
24775
+ pattern.slice(firstgs + 1),
24776
+ [],
24777
+ ] : [
24778
+ pattern.slice(patternIndex, firstgs),
24779
+ pattern.slice(firstgs + 1, lastgs),
24780
+ pattern.slice(lastgs + 1),
24781
+ ];
24782
+ // check the head, from the current file/pattern index.
24783
+ if (head.length) {
24784
+ const fileHead = file.slice(fileIndex, fileIndex + head.length);
24785
+ if (!this.#matchOne(fileHead, head, partial, 0, 0)) {
24786
+ return false;
24787
+ }
24788
+ fileIndex += head.length;
24789
+ patternIndex += head.length;
24790
+ }
24791
+ // now we know the head matches!
24792
+ // if the last portion is not empty, it MUST match the end
24793
+ // check the tail
24794
+ let fileTailMatch = 0;
24795
+ if (tail.length) {
24796
+ // if head + tail > file, then we cannot possibly match
24797
+ if (tail.length + fileIndex > file.length)
24798
+ return false;
24799
+ // try to match the tail
24800
+ let tailStart = file.length - tail.length;
24801
+ if (this.#matchOne(file, tail, partial, tailStart, 0)) {
24802
+ fileTailMatch = tail.length;
24803
+ }
24804
+ else {
24805
+ // affordance for stuff like a/**/* matching a/b/
24806
+ // if the last file portion is '', and there's more to the pattern
24807
+ // then try without the '' bit.
24808
+ if (file[file.length - 1] !== '' ||
24809
+ fileIndex + tail.length === file.length) {
24810
+ return false;
24811
+ }
24812
+ tailStart--;
24813
+ if (!this.#matchOne(file, tail, partial, tailStart, 0)) {
24814
+ return false;
24815
+ }
24816
+ fileTailMatch = tail.length + 1;
24817
+ }
24818
+ }
24819
+ // now we know the tail matches!
24820
+ // the middle is zero or more portions wrapped in **, possibly
24821
+ // containing more ** sections.
24822
+ // so a/**/b/**/c/**/d has become **/b/**/c/**
24823
+ // if it's empty, it means a/**/b, just verify we have no bad dots
24824
+ // if there's no tail, so it ends on /**, then we must have *something*
24825
+ // after the head, or it's not a matc
24826
+ if (!body.length) {
24827
+ let sawSome = !!fileTailMatch;
24828
+ for (let i = fileIndex; i < file.length - fileTailMatch; i++) {
24829
+ const f = String(file[i]);
24830
+ sawSome = true;
24831
+ if (f === '.' ||
24832
+ f === '..' ||
24833
+ (!this.options.dot && f.startsWith('.'))) {
24834
+ return false;
24835
+ }
24836
+ }
24837
+ // in partial mode, we just need to get past all file parts
24838
+ return partial || sawSome;
24839
+ }
24840
+ // now we know that there's one or more body sections, which can
24841
+ // be matched anywhere from the 0 index (because the head was pruned)
24842
+ // through to the length-fileTailMatch index.
24843
+ // split the body up into sections, and note the minimum index it can
24844
+ // be found at (start with the length of all previous segments)
24845
+ // [section, before, after]
24846
+ const bodySegments = [[[], 0]];
24847
+ let currentBody = bodySegments[0];
24848
+ let nonGsParts = 0;
24849
+ const nonGsPartsSums = [0];
24850
+ for (const b of body) {
24851
+ if (b === exports$1.GLOBSTAR) {
24852
+ nonGsPartsSums.push(nonGsParts);
24853
+ currentBody = [[], 0];
24854
+ bodySegments.push(currentBody);
24855
+ }
24856
+ else {
24857
+ currentBody[0].push(b);
24858
+ nonGsParts++;
24859
+ }
24860
+ }
24861
+ let i = bodySegments.length - 1;
24862
+ const fileLength = file.length - fileTailMatch;
24863
+ for (const b of bodySegments) {
24864
+ b[1] = fileLength - (nonGsPartsSums[i--] + b[0].length);
24865
+ }
24866
+ return !!this.#matchGlobStarBodySections(file, bodySegments, fileIndex, 0, partial, 0, !!fileTailMatch);
24867
+ }
24868
+ // return false for "nope, not matching"
24869
+ // return null for "not matching, cannot keep trying"
24870
+ #matchGlobStarBodySections(file,
24871
+ // pattern section, last possible position for it
24872
+ bodySegments, fileIndex, bodyIndex, partial, globStarDepth, sawTail) {
24873
+ // take the first body segment, and walk from fileIndex to its "after"
24874
+ // value at the end
24875
+ // If it doesn't match at that position, we increment, until we hit
24876
+ // that final possible position, and give up.
24877
+ // If it does match, then advance and try to rest.
24878
+ // If any of them fail we keep walking forward.
24879
+ // this is still a bit recursively painful, but it's more constrained
24880
+ // than previous implementations, because we never test something that
24881
+ // can't possibly be a valid matching condition.
24882
+ const bs = bodySegments[bodyIndex];
24883
+ if (!bs) {
24884
+ // just make sure that there's no bad dots
24885
+ for (let i = fileIndex; i < file.length; i++) {
24886
+ sawTail = true;
24887
+ const f = file[i];
24888
+ if (f === '.' ||
24889
+ f === '..' ||
24890
+ (!this.options.dot && f.startsWith('.'))) {
24891
+ return false;
24892
+ }
24893
+ }
24894
+ return sawTail;
24895
+ }
24896
+ // have a non-globstar body section to test
24897
+ const [body, after] = bs;
24898
+ while (fileIndex <= after) {
24899
+ const m = this.#matchOne(file.slice(0, fileIndex + body.length), body, partial, fileIndex, 0);
24900
+ // if limit exceeded, no match. intentional false negative,
24901
+ // acceptable break in correctness for security.
24902
+ if (m && globStarDepth < this.maxGlobstarRecursion) {
24903
+ // match! see if the rest match. if so, we're done!
24904
+ const sub = this.#matchGlobStarBodySections(file, bodySegments, fileIndex + body.length, bodyIndex + 1, partial, globStarDepth + 1, sawTail);
24905
+ if (sub !== false) {
24906
+ return sub;
24907
+ }
24908
+ }
24909
+ const f = file[fileIndex];
24910
+ if (f === '.' ||
24911
+ f === '..' ||
24912
+ (!this.options.dot && f.startsWith('.'))) {
24913
+ return false;
24914
+ }
24915
+ fileIndex++;
24916
+ }
24917
+ // walked off. no point continuing
24918
+ return partial || null;
24919
+ }
24920
+ #matchOne(file, pattern, partial, fileIndex, patternIndex) {
24921
+ let fi;
24922
+ let pi;
24923
+ let pl;
24924
+ let fl;
24925
+ for (fi = fileIndex,
24926
+ pi = patternIndex,
24927
+ fl = file.length,
24928
+ pl = pattern.length; fi < fl && pi < pl; fi++, pi++) {
24519
24929
  this.debug('matchOne loop');
24520
- var p = pattern[pi];
24521
- var f = file[fi];
24930
+ let p = pattern[pi];
24931
+ let f = file[fi];
24522
24932
  this.debug(pattern, p, f);
24523
24933
  // should be impossible.
24524
24934
  // some invalid regexp stuff in the set.
24525
24935
  /* c8 ignore start */
24526
- if (p === false) {
24936
+ if (p === false || p === exports$1.GLOBSTAR) {
24527
24937
  return false;
24528
24938
  }
24529
24939
  /* c8 ignore stop */
24530
- if (p === exports$1.GLOBSTAR) {
24531
- this.debug('GLOBSTAR', [pattern, p, f]);
24532
- // "**"
24533
- // a/**/b/**/c would match the following:
24534
- // a/b/x/y/z/c
24535
- // a/x/y/z/b/c
24536
- // a/b/x/b/x/c
24537
- // a/b/c
24538
- // To do this, take the rest of the pattern after
24539
- // the **, and see if it would match the file remainder.
24540
- // If so, return success.
24541
- // If not, the ** "swallows" a segment, and try again.
24542
- // This is recursively awful.
24543
- //
24544
- // a/**/b/**/c matching a/b/x/y/z/c
24545
- // - a matches a
24546
- // - doublestar
24547
- // - matchOne(b/x/y/z/c, b/**/c)
24548
- // - b matches b
24549
- // - doublestar
24550
- // - matchOne(x/y/z/c, c) -> no
24551
- // - matchOne(y/z/c, c) -> no
24552
- // - matchOne(z/c, c) -> no
24553
- // - matchOne(c, c) yes, hit
24554
- var fr = fi;
24555
- var pr = pi + 1;
24556
- if (pr === pl) {
24557
- this.debug('** at the end');
24558
- // a ** at the end will just swallow the rest.
24559
- // We have found a match.
24560
- // however, it will not swallow /.x, unless
24561
- // options.dot is set.
24562
- // . and .. are *never* matched by **, for explosively
24563
- // exponential reasons.
24564
- for (; fi < fl; fi++) {
24565
- if (file[fi] === '.' ||
24566
- file[fi] === '..' ||
24567
- (!options.dot && file[fi].charAt(0) === '.'))
24568
- return false;
24569
- }
24570
- return true;
24571
- }
24572
- // ok, let's see if we can swallow whatever we can.
24573
- while (fr < fl) {
24574
- var swallowee = file[fr];
24575
- this.debug('\nglobstar while', file, fr, pattern, pr, swallowee);
24576
- // XXX remove this slice. Just pass the start index.
24577
- if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
24578
- this.debug('globstar found match!', fr, fl, swallowee);
24579
- // found a match.
24580
- return true;
24581
- }
24582
- else {
24583
- // can't swallow "." or ".." ever.
24584
- // can only swallow ".foo" when explicitly asked.
24585
- if (swallowee === '.' ||
24586
- swallowee === '..' ||
24587
- (!options.dot && swallowee.charAt(0) === '.')) {
24588
- this.debug('dot detected!', file, fr, pattern, pr);
24589
- break;
24590
- }
24591
- // ** swallows a segment, and continue.
24592
- this.debug('globstar swallow a segment, and continue');
24593
- fr++;
24594
- }
24595
- }
24596
- // no match was found.
24597
- // However, in partial mode, we can't say this is necessarily over.
24598
- /* c8 ignore start */
24599
- if (partial) {
24600
- // ran out of file
24601
- this.debug('\n>>> no match, partial?', file, fr, pattern, pr);
24602
- if (fr === fl) {
24603
- return true;
24604
- }
24605
- }
24606
- /* c8 ignore stop */
24607
- return false;
24608
- }
24609
24940
  // something other than **
24610
24941
  // non-magic patterns just have to match exactly
24611
24942
  // patterns with magic have been turned into regexps.
@@ -25065,8 +25396,12 @@ function requireCjs$1 () {
25065
25396
  /** @import * as $typests from "./types.ts"; */
25066
25397
  /** @typedef {$typests.BuiltInMergeStrategy} BuiltInMergeStrategy */
25067
25398
  /** @typedef {$typests.BuiltInValidationStrategy} BuiltInValidationStrategy */
25399
+ /** @typedef {$typests.CustomMergeStrategy} CustomMergeStrategy */
25400
+ /** @typedef {$typests.CustomValidationStrategy} CustomValidationStrategy */
25068
25401
  /** @typedef {$typests.ObjectDefinition} ObjectDefinition */
25069
25402
  /** @typedef {$typests.PropertyDefinition} PropertyDefinition */
25403
+ /** @typedef {$typests.PropertyDefinitionWithSchema} PropertyDefinitionWithSchema */
25404
+ /** @typedef {$typests.PropertyDefinitionWithStrategies} PropertyDefinitionWithStrategies */
25070
25405
 
25071
25406
  //-----------------------------------------------------------------------------
25072
25407
  // Private
@@ -25579,6 +25914,9 @@ function requireCjs () {
25579
25914
 
25580
25915
  /** @import * as $typests from "./types.ts"; */
25581
25916
  /** @typedef {$typests.ConfigObject} ConfigObject */
25917
+ /** @typedef {$typests.FileMatcher} FileMatcher */
25918
+ /** @typedef {$typests.FilesMatcher} FilesMatcher */
25919
+ /** @typedef {$typests.ExtraConfigType} ExtraConfigType */
25582
25920
  /** @import * as $minimatch from "minimatch"; */
25583
25921
  /** @typedef {$minimatch.MinimatchOptions} MinimatchOptions */
25584
25922
  /** @import * as PathImpl from "@jsr/std__path" */
@@ -25621,7 +25959,7 @@ function requireCjs () {
25621
25959
 
25622
25960
  /**
25623
25961
  * The types of config objects that are supported.
25624
- * @type {Set<string>}
25962
+ * @type {Set<ExtraConfigType>}
25625
25963
  */
25626
25964
  const CONFIG_TYPES = new Set(["array", "function"]);
25627
25965
 
@@ -25706,7 +26044,7 @@ function requireCjs () {
25706
26044
 
25707
26045
  /**
25708
26046
  * Rethrows a config error with additional information about the config object.
25709
- * @param {object} config The config object to get the name of.
26047
+ * @param {ConfigObject} config The config object to get the name of.
25710
26048
  * @param {number} index The index of the config object in the array.
25711
26049
  * @param {Error} error The error to rethrow.
25712
26050
  * @throws {ConfigError} When the error is rethrown for a config.
@@ -25719,7 +26057,7 @@ function requireCjs () {
25719
26057
  /**
25720
26058
  * Shorthand for checking if a value is a string.
25721
26059
  * @param {any} value The value to check.
25722
- * @returns {boolean} True if a string, false if not.
26060
+ * @returns {value is string} True if a string, false if not.
25723
26061
  */
25724
26062
  function isString(value) {
25725
26063
  return typeof value === "string";
@@ -25779,8 +26117,8 @@ function requireCjs () {
25779
26117
  * faster matching speed over multiple file path evaluations.
25780
26118
  * @param {string} filepath The file path to match.
25781
26119
  * @param {string} pattern The glob pattern to match against.
25782
- * @param {object} options The minimatch options to use.
25783
- * @returns
26120
+ * @param {MinimatchOptions} options The minimatch options to use.
26121
+ * @returns {boolean} True if the file path matches, false if not.
25784
26122
  */
25785
26123
  function doMatch(filepath, pattern, options = {}) {
25786
26124
  let cache = minimatchCache;
@@ -25804,8 +26142,8 @@ function requireCjs () {
25804
26142
 
25805
26143
  /**
25806
26144
  * Normalizes a pattern by removing the leading "./" if present.
25807
- * @param {string} pattern The pattern to normalize.
25808
- * @returns {string} The normalized pattern.
26145
+ * @param {FileMatcher} pattern The pattern to normalize.
26146
+ * @returns {FileMatcher} The normalized pattern.
25809
26147
  */
25810
26148
  function normalizePattern(pattern) {
25811
26149
  if (isString(pattern)) {
@@ -25906,7 +26244,7 @@ function requireCjs () {
25906
26244
  * @param {Array} items The items in a `ConfigArray`.
25907
26245
  * @param {Object} context The context object to pass into any function
25908
26246
  * found.
25909
- * @param {Array<string>} extraConfigTypes The config types to check.
26247
+ * @param {ReadonlyArray<ExtraConfigType>} extraConfigTypes The config types to check.
25910
26248
  * @param {string} namespacedBasePath The namespaced base path of the directory to which config base paths are relative.
25911
26249
  * @param {PathImpl} path Path-handling implementation.
25912
26250
  * @returns {Promise<Array>} A flattened array containing only config objects.
@@ -25954,7 +26292,7 @@ function requireCjs () {
25954
26292
  * Async iterables cannot be used with the spread operator, so we need to manually
25955
26293
  * create the array to return.
25956
26294
  */
25957
- const asyncIterable = await flatTraverse(items);
26295
+ const asyncIterable = flatTraverse(items);
25958
26296
  const configs = [];
25959
26297
 
25960
26298
  for await (const config of asyncIterable) {
@@ -25970,7 +26308,7 @@ function requireCjs () {
25970
26308
  * @param {Array} items The items in a `ConfigArray`.
25971
26309
  * @param {Object} context The context object to pass into any function
25972
26310
  * found.
25973
- * @param {Array<string>} extraConfigTypes The config types to check.
26311
+ * @param {ReadonlyArray<ExtraConfigType>} extraConfigTypes The config types to check.
25974
26312
  * @param {string} namespacedBasePath The namespaced base path of the directory to which config base paths are relative.
25975
26313
  * @param {PathImpl} path Path-handling implementation
25976
26314
  * @returns {Array} A flattened array containing only config objects.
@@ -26043,13 +26381,13 @@ function requireCjs () {
26043
26381
  /**
26044
26382
  * Determines if a given file path should be ignored based on the given
26045
26383
  * matcher.
26046
- * @param {Array<{ basePath?: string, ignores: Array<string|((string) => boolean)>}>} configs Configuration objects containing `ignores`.
26384
+ * @param {Array<{ basePath?: string, ignores: FileMatcher[] }>} configs Configuration objects containing `ignores`.
26047
26385
  * @param {string} filePath The unprocessed file path to check.
26048
26386
  * @param {string} relativeFilePath The path of the file to check relative to the base path,
26049
26387
  * using forward slash (`"/"`) as a separator.
26050
26388
  * @param {Object} [basePathData] Additional data needed to recalculate paths for configuration objects
26051
26389
  * that have `basePath` property.
26052
- * @param {string} [basePathData.basePath] Namespaced path to witch `relativeFilePath` is relative.
26390
+ * @param {string} [basePathData.basePath] Namespaced path to which `relativeFilePath` is relative.
26053
26391
  * @param {PathImpl} [basePathData.path] Path-handling implementation.
26054
26392
  * @returns {boolean} True if the path should be ignored and false if not.
26055
26393
  */
@@ -26118,7 +26456,7 @@ function requireCjs () {
26118
26456
  * @param {string} filePath The unprocessed file path to check.
26119
26457
  * @param {string} relativeFilePath The path of the file to check relative to the base path,
26120
26458
  * using forward slash (`"/"`) as a separator.
26121
- * @param {Object} config The config object to check.
26459
+ * @param {ConfigObject & { files: FilesMatcher[] }} config The config object to check.
26122
26460
  * @returns {boolean} True if the file path is matched by the config,
26123
26461
  * false if not.
26124
26462
  */
@@ -26181,21 +26519,23 @@ function requireCjs () {
26181
26519
 
26182
26520
  /**
26183
26521
  * Ensures that config types are valid.
26184
- * @param {Array<string>} extraConfigTypes The config types to check.
26522
+ * @param {ReadonlyArray<ExtraConfigType>} extraConfigTypes The config types to check.
26185
26523
  * @returns {void}
26186
26524
  * @throws {TypeError} When the config types array is invalid.
26187
26525
  */
26188
26526
  function assertExtraConfigTypes(extraConfigTypes) {
26527
+ if (!Array.isArray(extraConfigTypes)) {
26528
+ throw new TypeError("extraConfigTypes must be an array.");
26529
+ }
26530
+
26189
26531
  if (extraConfigTypes.length > 2) {
26190
- throw new TypeError(
26191
- "configTypes must be an array with at most two items.",
26192
- );
26532
+ throw new TypeError("extraConfigTypes must contain at most two items.");
26193
26533
  }
26194
26534
 
26195
26535
  for (const configType of extraConfigTypes) {
26196
26536
  if (!CONFIG_TYPES.has(configType)) {
26197
26537
  throw new TypeError(
26198
- `Unexpected config type "${configType}" found. Expected one of: "object", "array", "function".`,
26538
+ `Unexpected config type "${configType}" in extraConfigTypes. Expected one of: "array", "function".`,
26199
26539
  );
26200
26540
  }
26201
26541
  }
@@ -26266,9 +26606,9 @@ function requireCjs () {
26266
26606
  * Defaults to `"/"`.
26267
26607
  * @param {boolean} [options.normalized=false] Flag indicating if the
26268
26608
  * configs have already been normalized.
26269
- * @param {Object} [options.schema] The additional schema
26609
+ * @param {ObjectDefinition} [options.schema] The additional schema
26270
26610
  * definitions to use for the ConfigArray schema.
26271
- * @param {Array<string>} [options.extraConfigTypes] List of config types supported.
26611
+ * @param {ReadonlyArray<ExtraConfigType>} [options.extraConfigTypes] List of config types supported.
26272
26612
  * @throws {TypeError} When the `basePath` is not a non-empty string,
26273
26613
  */
26274
26614
  constructor(
@@ -26316,7 +26656,7 @@ function requireCjs () {
26316
26656
 
26317
26657
  /**
26318
26658
  * The supported config types.
26319
- * @type {Array<string>}
26659
+ * @type {ReadonlyArray<ExtraConfigType>}
26320
26660
  */
26321
26661
  this.extraConfigTypes = [...extraConfigTypes];
26322
26662
  Object.freeze(this.extraConfigTypes);
@@ -26369,7 +26709,7 @@ function requireCjs () {
26369
26709
  * This can be used to determine which files will be matched by a
26370
26710
  * config array or to use as a glob pattern when no patterns are provided
26371
26711
  * for a command line interface.
26372
- * @returns {Array<string|Function>} An array of matchers.
26712
+ * @returns {Array<FilesMatcher>} An array of matchers.
26373
26713
  */
26374
26714
  get files() {
26375
26715
  assertNormalized(this);
@@ -26405,7 +26745,7 @@ function requireCjs () {
26405
26745
  * the matching `files` fields in any configs. This is necessary to mimic
26406
26746
  * the behavior of things like .gitignore and .eslintignore, allowing a
26407
26747
  * globbing operation to be faster.
26408
- * @returns {Object[]} An array of config objects representing global ignores.
26748
+ * @returns {Array<{ basePath?: string, name?: string, ignores: FileMatcher[] }>} An array of config objects representing global ignores.
26409
26749
  */
26410
26750
  get ignores() {
26411
26751
  assertNormalized(this);
@@ -26424,7 +26764,7 @@ function requireCjs () {
26424
26764
  for (const config of this) {
26425
26765
  /*
26426
26766
  * We only count ignores if there are no other keys in the object.
26427
- * In this case, it acts list a globally ignored pattern. If there
26767
+ * In this case, it acts like a globally ignored pattern. If there
26428
26768
  * are additional keys, then ignores act like exclusions.
26429
26769
  */
26430
26770
  if (
@@ -88985,10 +89325,10 @@ function requireIsCombiningCharacter () {
88985
89325
  /**
88986
89326
  * Check whether a given character is a combining mark or not.
88987
89327
  * @param {number} codePoint The character code to check.
88988
- * @returns {boolean} `true` if the character belongs to the category, any of `Mc`, `Me`, and `Mn`.
89328
+ * @returns {boolean} `true` if the character has the General Category of Combining Mark (M), consisting of `Mc`, `Me`, and `Mn`.
88989
89329
  */
88990
89330
  isCombiningCharacter = function isCombiningCharacter(codePoint) {
88991
- return /^[\p{Mc}\p{Me}\p{Mn}]$/u.test(String.fromCodePoint(codePoint));
89331
+ return /^\p{M}$/u.test(String.fromCodePoint(codePoint));
88992
89332
  };
88993
89333
  return isCombiningCharacter;
88994
89334
  }
@@ -105404,7 +105744,7 @@ function requireNoUselessAssignment () {
105404
105744
 
105405
105745
  messages: {
105406
105746
  unnecessaryAssignment:
105407
- "This assigned value is not used in subsequent statements.",
105747
+ "The value assigned to '{{name}}' is not used in subsequent statements.",
105408
105748
  },
105409
105749
  },
105410
105750
 
@@ -105752,6 +106092,7 @@ function requireNoUselessAssignment () {
105752
106092
  context.report({
105753
106093
  node: targetAssignment.identifier,
105754
106094
  messageId: "unnecessaryAssignment",
106095
+ data: { name: targetAssignment.identifier.name },
105755
106096
  });
105756
106097
  }
105757
106098