html-validate 8.23.0 → 8.24.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/es/core.js CHANGED
@@ -242,139 +242,149 @@ function getDefaultExportFromCjs (x) {
242
242
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
243
243
  }
244
244
 
245
- var isMergeableObject = function isMergeableObject(value) {
246
- return isNonNullObject(value)
247
- && !isSpecial(value)
248
- };
245
+ var cjs;
246
+ var hasRequiredCjs;
249
247
 
250
- function isNonNullObject(value) {
251
- return !!value && typeof value === 'object'
252
- }
248
+ function requireCjs () {
249
+ if (hasRequiredCjs) return cjs;
250
+ hasRequiredCjs = 1;
253
251
 
254
- function isSpecial(value) {
255
- var stringValue = Object.prototype.toString.call(value);
252
+ var isMergeableObject = function isMergeableObject(value) {
253
+ return isNonNullObject(value)
254
+ && !isSpecial(value)
255
+ };
256
256
 
257
- return stringValue === '[object RegExp]'
258
- || stringValue === '[object Date]'
259
- || isReactElement(value)
260
- }
257
+ function isNonNullObject(value) {
258
+ return !!value && typeof value === 'object'
259
+ }
261
260
 
262
- // see https://github.com/facebook/react/blob/b5ac963fb791d1298e7f396236383bc955f916c1/src/isomorphic/classic/element/ReactElement.js#L21-L25
263
- var canUseSymbol = typeof Symbol === 'function' && Symbol.for;
264
- var REACT_ELEMENT_TYPE = canUseSymbol ? Symbol.for('react.element') : 0xeac7;
261
+ function isSpecial(value) {
262
+ var stringValue = Object.prototype.toString.call(value);
265
263
 
266
- function isReactElement(value) {
267
- return value.$$typeof === REACT_ELEMENT_TYPE
268
- }
264
+ return stringValue === '[object RegExp]'
265
+ || stringValue === '[object Date]'
266
+ || isReactElement(value)
267
+ }
269
268
 
270
- function emptyTarget(val) {
271
- return Array.isArray(val) ? [] : {}
272
- }
269
+ // see https://github.com/facebook/react/blob/b5ac963fb791d1298e7f396236383bc955f916c1/src/isomorphic/classic/element/ReactElement.js#L21-L25
270
+ var canUseSymbol = typeof Symbol === 'function' && Symbol.for;
271
+ var REACT_ELEMENT_TYPE = canUseSymbol ? Symbol.for('react.element') : 0xeac7;
273
272
 
274
- function cloneUnlessOtherwiseSpecified(value, options) {
275
- return (options.clone !== false && options.isMergeableObject(value))
276
- ? deepmerge(emptyTarget(value), value, options)
277
- : value
278
- }
273
+ function isReactElement(value) {
274
+ return value.$$typeof === REACT_ELEMENT_TYPE
275
+ }
279
276
 
280
- function defaultArrayMerge(target, source, options) {
281
- return target.concat(source).map(function(element) {
282
- return cloneUnlessOtherwiseSpecified(element, options)
283
- })
284
- }
277
+ function emptyTarget(val) {
278
+ return Array.isArray(val) ? [] : {}
279
+ }
285
280
 
286
- function getMergeFunction(key, options) {
287
- if (!options.customMerge) {
288
- return deepmerge
281
+ function cloneUnlessOtherwiseSpecified(value, options) {
282
+ return (options.clone !== false && options.isMergeableObject(value))
283
+ ? deepmerge(emptyTarget(value), value, options)
284
+ : value
289
285
  }
290
- var customMerge = options.customMerge(key);
291
- return typeof customMerge === 'function' ? customMerge : deepmerge
292
- }
293
286
 
294
- function getEnumerableOwnPropertySymbols(target) {
295
- return Object.getOwnPropertySymbols
296
- ? Object.getOwnPropertySymbols(target).filter(function(symbol) {
297
- return Object.propertyIsEnumerable.call(target, symbol)
287
+ function defaultArrayMerge(target, source, options) {
288
+ return target.concat(source).map(function(element) {
289
+ return cloneUnlessOtherwiseSpecified(element, options)
298
290
  })
299
- : []
300
- }
291
+ }
301
292
 
302
- function getKeys(target) {
303
- return Object.keys(target).concat(getEnumerableOwnPropertySymbols(target))
304
- }
293
+ function getMergeFunction(key, options) {
294
+ if (!options.customMerge) {
295
+ return deepmerge
296
+ }
297
+ var customMerge = options.customMerge(key);
298
+ return typeof customMerge === 'function' ? customMerge : deepmerge
299
+ }
305
300
 
306
- function propertyIsOnObject(object, property) {
307
- try {
308
- return property in object
309
- } catch(_) {
310
- return false
301
+ function getEnumerableOwnPropertySymbols(target) {
302
+ return Object.getOwnPropertySymbols
303
+ ? Object.getOwnPropertySymbols(target).filter(function(symbol) {
304
+ return Object.propertyIsEnumerable.call(target, symbol)
305
+ })
306
+ : []
311
307
  }
312
- }
313
308
 
314
- // Protects from prototype poisoning and unexpected merging up the prototype chain.
315
- function propertyIsUnsafe(target, key) {
316
- return propertyIsOnObject(target, key) // Properties are safe to merge if they don't exist in the target yet,
317
- && !(Object.hasOwnProperty.call(target, key) // unsafe if they exist up the prototype chain,
318
- && Object.propertyIsEnumerable.call(target, key)) // and also unsafe if they're nonenumerable.
319
- }
309
+ function getKeys(target) {
310
+ return Object.keys(target).concat(getEnumerableOwnPropertySymbols(target))
311
+ }
320
312
 
321
- function mergeObject(target, source, options) {
322
- var destination = {};
323
- if (options.isMergeableObject(target)) {
324
- getKeys(target).forEach(function(key) {
325
- destination[key] = cloneUnlessOtherwiseSpecified(target[key], options);
326
- });
313
+ function propertyIsOnObject(object, property) {
314
+ try {
315
+ return property in object
316
+ } catch(_) {
317
+ return false
318
+ }
319
+ }
320
+
321
+ // Protects from prototype poisoning and unexpected merging up the prototype chain.
322
+ function propertyIsUnsafe(target, key) {
323
+ return propertyIsOnObject(target, key) // Properties are safe to merge if they don't exist in the target yet,
324
+ && !(Object.hasOwnProperty.call(target, key) // unsafe if they exist up the prototype chain,
325
+ && Object.propertyIsEnumerable.call(target, key)) // and also unsafe if they're nonenumerable.
327
326
  }
328
- getKeys(source).forEach(function(key) {
329
- if (propertyIsUnsafe(target, key)) {
330
- return
327
+
328
+ function mergeObject(target, source, options) {
329
+ var destination = {};
330
+ if (options.isMergeableObject(target)) {
331
+ getKeys(target).forEach(function(key) {
332
+ destination[key] = cloneUnlessOtherwiseSpecified(target[key], options);
333
+ });
331
334
  }
335
+ getKeys(source).forEach(function(key) {
336
+ if (propertyIsUnsafe(target, key)) {
337
+ return
338
+ }
332
339
 
333
- if (propertyIsOnObject(target, key) && options.isMergeableObject(source[key])) {
334
- destination[key] = getMergeFunction(key, options)(target[key], source[key], options);
340
+ if (propertyIsOnObject(target, key) && options.isMergeableObject(source[key])) {
341
+ destination[key] = getMergeFunction(key, options)(target[key], source[key], options);
342
+ } else {
343
+ destination[key] = cloneUnlessOtherwiseSpecified(source[key], options);
344
+ }
345
+ });
346
+ return destination
347
+ }
348
+
349
+ function deepmerge(target, source, options) {
350
+ options = options || {};
351
+ options.arrayMerge = options.arrayMerge || defaultArrayMerge;
352
+ options.isMergeableObject = options.isMergeableObject || isMergeableObject;
353
+ // cloneUnlessOtherwiseSpecified is added to `options` so that custom arrayMerge()
354
+ // implementations can use it. The caller may not replace it.
355
+ options.cloneUnlessOtherwiseSpecified = cloneUnlessOtherwiseSpecified;
356
+
357
+ var sourceIsArray = Array.isArray(source);
358
+ var targetIsArray = Array.isArray(target);
359
+ var sourceAndTargetTypesMatch = sourceIsArray === targetIsArray;
360
+
361
+ if (!sourceAndTargetTypesMatch) {
362
+ return cloneUnlessOtherwiseSpecified(source, options)
363
+ } else if (sourceIsArray) {
364
+ return options.arrayMerge(target, source, options)
335
365
  } else {
336
- destination[key] = cloneUnlessOtherwiseSpecified(source[key], options);
366
+ return mergeObject(target, source, options)
337
367
  }
338
- });
339
- return destination
340
- }
341
-
342
- function deepmerge(target, source, options) {
343
- options = options || {};
344
- options.arrayMerge = options.arrayMerge || defaultArrayMerge;
345
- options.isMergeableObject = options.isMergeableObject || isMergeableObject;
346
- // cloneUnlessOtherwiseSpecified is added to `options` so that custom arrayMerge()
347
- // implementations can use it. The caller may not replace it.
348
- options.cloneUnlessOtherwiseSpecified = cloneUnlessOtherwiseSpecified;
349
-
350
- var sourceIsArray = Array.isArray(source);
351
- var targetIsArray = Array.isArray(target);
352
- var sourceAndTargetTypesMatch = sourceIsArray === targetIsArray;
353
-
354
- if (!sourceAndTargetTypesMatch) {
355
- return cloneUnlessOtherwiseSpecified(source, options)
356
- } else if (sourceIsArray) {
357
- return options.arrayMerge(target, source, options)
358
- } else {
359
- return mergeObject(target, source, options)
360
368
  }
361
- }
362
369
 
363
- deepmerge.all = function deepmergeAll(array, options) {
364
- if (!Array.isArray(array)) {
365
- throw new Error('first argument should be an array')
366
- }
370
+ deepmerge.all = function deepmergeAll(array, options) {
371
+ if (!Array.isArray(array)) {
372
+ throw new Error('first argument should be an array')
373
+ }
367
374
 
368
- return array.reduce(function(prev, next) {
369
- return deepmerge(prev, next, options)
370
- }, {})
371
- };
375
+ return array.reduce(function(prev, next) {
376
+ return deepmerge(prev, next, options)
377
+ }, {})
378
+ };
372
379
 
373
- var deepmerge_1 = deepmerge;
380
+ var deepmerge_1 = deepmerge;
374
381
 
375
- var cjs = deepmerge_1;
382
+ cjs = deepmerge_1;
383
+ return cjs;
384
+ }
376
385
 
377
- var deepmerge$1 = /*@__PURE__*/getDefaultExportFromCjs(cjs);
386
+ var cjsExports = /*@__PURE__*/ requireCjs();
387
+ var deepmerge = /*@__PURE__*/getDefaultExportFromCjs(cjsExports);
378
388
 
379
389
  function stringify(value) {
380
390
  if (typeof value === "string") {
@@ -1207,7 +1217,7 @@ class MetaTable {
1207
1217
  */
1208
1218
  extendValidationSchema(patch) {
1209
1219
  if (patch.properties) {
1210
- this.schema = deepmerge$1(this.schema, {
1220
+ this.schema = deepmerge(this.schema, {
1211
1221
  patternProperties: {
1212
1222
  "^[^$].*$": {
1213
1223
  properties: patch.properties
@@ -1216,7 +1226,7 @@ class MetaTable {
1216
1226
  });
1217
1227
  }
1218
1228
  if (patch.definitions) {
1219
- this.schema = deepmerge$1(this.schema, {
1229
+ this.schema = deepmerge(this.schema, {
1220
1230
  definitions: patch.definitions
1221
1231
  });
1222
1232
  }
@@ -1354,7 +1364,7 @@ class MetaTable {
1354
1364
  }
1355
1365
  }
1356
1366
  mergeElement(a, b) {
1357
- const merged = deepmerge$1(a, b, { arrayMerge: overwriteMerge$1 });
1367
+ const merged = deepmerge(a, b, { arrayMerge: overwriteMerge$1 });
1358
1368
  const filteredAttrs = Object.entries(
1359
1369
  merged.attributes
1360
1370
  ).filter(([, attr]) => {
@@ -1970,7 +1980,7 @@ const table = {
1970
1980
  "nth-child": nthChild,
1971
1981
  scope
1972
1982
  };
1973
- function factory$1(name, context) {
1983
+ function factory(name, context) {
1974
1984
  const fn = table[name];
1975
1985
  if (fn) {
1976
1986
  return fn.bind(context);
@@ -2069,7 +2079,7 @@ function isQuotationMark(ch) {
2069
2079
  function isPseudoElement(ch, buffer) {
2070
2080
  return ch === ":" && buffer === ":";
2071
2081
  }
2072
- function* splitPattern$1(pattern) {
2082
+ function* splitPattern(pattern) {
2073
2083
  if (pattern === "") {
2074
2084
  return;
2075
2085
  }
@@ -2163,7 +2173,7 @@ class PseudoClassMatcher extends Matcher {
2163
2173
  this.args = args;
2164
2174
  }
2165
2175
  match(node, context) {
2166
- const fn = factory$1(this.name, context);
2176
+ const fn = factory(this.name, context);
2167
2177
  return fn(node, this.args);
2168
2178
  }
2169
2179
  }
@@ -2177,7 +2187,7 @@ class Pattern {
2177
2187
  this.selector = pattern;
2178
2188
  this.combinator = parseCombinator(match.shift(), pattern);
2179
2189
  this.tagName = match.shift() || "*";
2180
- this.pattern = Array.from(splitPattern$1(match[0]), (it) => this.createMatcher(it));
2190
+ this.pattern = Array.from(splitPattern(match[0]), (it) => this.createMatcher(it));
2181
2191
  }
2182
2192
  match(node, context) {
2183
2193
  return node.is(this.tagName) && this.pattern.every((cur) => cur.match(node, context));
@@ -4504,6 +4514,9 @@ class AttrQuotes extends Rule {
4504
4514
  }
4505
4515
  setup() {
4506
4516
  this.on("attr", (event) => {
4517
+ if (event.originalAttribute) {
4518
+ return;
4519
+ }
4507
4520
  if (event.value === null) {
4508
4521
  return;
4509
4522
  }
@@ -10435,7 +10448,7 @@ const TRANSFORMER_API = {
10435
10448
 
10436
10449
  var defaultConfig = {};
10437
10450
 
10438
- const config$4 = {
10451
+ const config$5 = {
10439
10452
  rules: {
10440
10453
  "area-alt": ["error", { accessible: true }],
10441
10454
  "aria-hidden-body": "error",
@@ -10468,6 +10481,25 @@ const config$4 = {
10468
10481
  }
10469
10482
  };
10470
10483
 
10484
+ const config$4 = {
10485
+ rules: {
10486
+ /* doctype is usually not included when fetching source code from browser */
10487
+ "missing-doctype": "off",
10488
+ /* some frameworks (such as jQuery) often uses inline style, e.g. for
10489
+ * showing/hiding elements so it is counter-productive to check for inline
10490
+ * style. If anything it should be used on original sorce code only. */
10491
+ "no-inline-style": "off",
10492
+ /* scripts will often add markup with trailing whitespace */
10493
+ "no-trailing-whitespace": "off",
10494
+ /* browser normalizes boolean attributes */
10495
+ "attribute-boolean-style": "off",
10496
+ "attribute-empty-style": "off",
10497
+ /* the browser will often do what it wants, out of users control */
10498
+ "void-style": "off",
10499
+ "no-self-closing": "off"
10500
+ }
10501
+ };
10502
+
10471
10503
  const config$3 = {
10472
10504
  rules: {
10473
10505
  "input-missing-label": "error",
@@ -10608,7 +10640,8 @@ const config = {
10608
10640
  };
10609
10641
 
10610
10642
  const presets = {
10611
- "html-validate:a11y": config$4,
10643
+ "html-validate:a11y": config$5,
10644
+ "html-validate:browser": config$4,
10612
10645
  "html-validate:document": config$3,
10613
10646
  "html-validate:prettier": config$2,
10614
10647
  "html-validate:recommended": config$1,
@@ -10616,9 +10649,8 @@ const presets = {
10616
10649
  /* @deprecated aliases */
10617
10650
  "htmlvalidate:recommended": config$1,
10618
10651
  "htmlvalidate:document": config$3,
10619
- "html-validate:a17y": config$4
10652
+ "html-validate:a17y": config$5
10620
10653
  };
10621
- var Presets = presets;
10622
10654
 
10623
10655
  class ResolvedConfig {
10624
10656
  /**
@@ -10810,9 +10842,9 @@ function overwriteMerge(a, b) {
10810
10842
  return b;
10811
10843
  }
10812
10844
  function mergeInternal(base, rhs) {
10813
- const dst = deepmerge$1(base, { ...rhs, rules: {} });
10845
+ const dst = deepmerge(base, { ...rhs, rules: {} });
10814
10846
  if (rhs.rules) {
10815
- dst.rules = deepmerge$1(dst.rules, rhs.rules, { arrayMerge: overwriteMerge });
10847
+ dst.rules = deepmerge(dst.rules, rhs.rules, { arrayMerge: overwriteMerge });
10816
10848
  }
10817
10849
  const root = Boolean(base.root) || Boolean(rhs.root);
10818
10850
  if (root) {
@@ -11076,7 +11108,7 @@ class Config {
11076
11108
  }
11077
11109
  loadConfigurations(plugins) {
11078
11110
  const configs = /* @__PURE__ */ new Map();
11079
- for (const [name, config] of Object.entries(Presets)) {
11111
+ for (const [name, config] of Object.entries(presets)) {
11080
11112
  Config.validate(config, name);
11081
11113
  configs.set(name, config);
11082
11114
  }
@@ -12839,651 +12871,660 @@ class HtmlValidate {
12839
12871
  }
12840
12872
 
12841
12873
  const name = "html-validate";
12842
- const version = "8.23.0";
12874
+ const version = "8.24.1";
12843
12875
  const bugs = "https://gitlab.com/html-validate/html-validate/issues/new";
12844
12876
 
12845
12877
  function definePlugin(plugin) {
12846
12878
  return plugin;
12847
12879
  }
12848
12880
 
12849
- // A simple implementation of make-array
12850
- function makeArray (subject) {
12851
- return Array.isArray(subject)
12852
- ? subject
12853
- : [subject]
12854
- }
12855
-
12856
- const EMPTY = '';
12857
- const SPACE = ' ';
12858
- const ESCAPE = '\\';
12859
- const REGEX_TEST_BLANK_LINE = /^\s+$/;
12860
- const REGEX_INVALID_TRAILING_BACKSLASH = /(?:[^\\]|^)\\$/;
12861
- const REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION = /^\\!/;
12862
- const REGEX_REPLACE_LEADING_EXCAPED_HASH = /^\\#/;
12863
- const REGEX_SPLITALL_CRLF = /\r?\n/g;
12864
- // /foo,
12865
- // ./foo,
12866
- // ../foo,
12867
- // .
12868
- // ..
12869
- const REGEX_TEST_INVALID_PATH = /^\.*\/|^\.+$/;
12870
-
12871
- const SLASH = '/';
12872
-
12873
- // Do not use ternary expression here, since "istanbul ignore next" is buggy
12874
- let TMP_KEY_IGNORE = 'node-ignore';
12875
- /* istanbul ignore else */
12876
- if (typeof Symbol !== 'undefined') {
12877
- TMP_KEY_IGNORE = Symbol.for('node-ignore');
12878
- }
12879
- const KEY_IGNORE = TMP_KEY_IGNORE;
12880
-
12881
- const define = (object, key, value) =>
12882
- Object.defineProperty(object, key, {value});
12883
-
12884
- const REGEX_REGEXP_RANGE = /([0-z])-([0-z])/g;
12885
-
12886
- const RETURN_FALSE = () => false;
12887
-
12888
- // Sanitize the range of a regular expression
12889
- // The cases are complicated, see test cases for details
12890
- const sanitizeRange = range => range.replace(
12891
- REGEX_REGEXP_RANGE,
12892
- (match, from, to) => from.charCodeAt(0) <= to.charCodeAt(0)
12893
- ? match
12894
- // Invalid range (out of order) which is ok for gitignore rules but
12895
- // fatal for JavaScript regular expression, so eliminate it.
12896
- : EMPTY
12897
- );
12898
-
12899
- // See fixtures #59
12900
- const cleanRangeBackSlash = slashes => {
12901
- const {length} = slashes;
12902
- return slashes.slice(0, length - length % 2)
12903
- };
12904
-
12905
- // > If the pattern ends with a slash,
12906
- // > it is removed for the purpose of the following description,
12907
- // > but it would only find a match with a directory.
12908
- // > In other words, foo/ will match a directory foo and paths underneath it,
12909
- // > but will not match a regular file or a symbolic link foo
12910
- // > (this is consistent with the way how pathspec works in general in Git).
12911
- // '`foo/`' will not match regular file '`foo`' or symbolic link '`foo`'
12912
- // -> ignore-rules will not deal with it, because it costs extra `fs.stat` call
12913
- // you could use option `mark: true` with `glob`
12914
-
12915
- // '`foo/`' should not continue with the '`..`'
12916
- const REPLACERS = [
12917
-
12918
- [
12919
- // remove BOM
12920
- // TODO:
12921
- // Other similar zero-width characters?
12922
- /^\uFEFF/,
12923
- () => EMPTY
12924
- ],
12925
-
12926
- // > Trailing spaces are ignored unless they are quoted with backslash ("\")
12927
- [
12928
- // (a\ ) -> (a )
12929
- // (a ) -> (a)
12930
- // (a ) -> (a)
12931
- // (a \ ) -> (a )
12932
- /((?:\\\\)*?)(\\?\s+)$/,
12933
- (_, m1, m2) => m1 + (
12934
- m2.indexOf('\\') === 0
12935
- ? SPACE
12936
- : EMPTY
12937
- )
12938
- ],
12939
-
12940
- // replace (\ ) with ' '
12941
- // (\ ) -> ' '
12942
- // (\\ ) -> '\\ '
12943
- // (\\\ ) -> '\\ '
12944
- [
12945
- /(\\+?)\s/g,
12946
- (_, m1) => {
12947
- const {length} = m1;
12948
- return m1.slice(0, length - length % 2) + SPACE
12949
- }
12950
- ],
12951
-
12952
- // Escape metacharacters
12953
- // which is written down by users but means special for regular expressions.
12954
-
12955
- // > There are 12 characters with special meanings:
12956
- // > - the backslash \,
12957
- // > - the caret ^,
12958
- // > - the dollar sign $,
12959
- // > - the period or dot .,
12960
- // > - the vertical bar or pipe symbol |,
12961
- // > - the question mark ?,
12962
- // > - the asterisk or star *,
12963
- // > - the plus sign +,
12964
- // > - the opening parenthesis (,
12965
- // > - the closing parenthesis ),
12966
- // > - and the opening square bracket [,
12967
- // > - the opening curly brace {,
12968
- // > These special characters are often called "metacharacters".
12969
- [
12970
- /[\\$.|*+(){^]/g,
12971
- match => `\\${match}`
12972
- ],
12973
-
12974
- [
12975
- // > a question mark (?) matches a single character
12976
- /(?!\\)\?/g,
12977
- () => '[^/]'
12978
- ],
12979
-
12980
- // leading slash
12981
- [
12982
-
12983
- // > A leading slash matches the beginning of the pathname.
12984
- // > For example, "/*.c" matches "cat-file.c" but not "mozilla-sha1/sha1.c".
12985
- // A leading slash matches the beginning of the pathname
12986
- /^\//,
12987
- () => '^'
12988
- ],
12989
-
12990
- // replace special metacharacter slash after the leading slash
12991
- [
12992
- /\//g,
12993
- () => '\\/'
12994
- ],
12995
-
12996
- [
12997
- // > A leading "**" followed by a slash means match in all directories.
12998
- // > For example, "**/foo" matches file or directory "foo" anywhere,
12999
- // > the same as pattern "foo".
13000
- // > "**/foo/bar" matches file or directory "bar" anywhere that is directly
13001
- // > under directory "foo".
13002
- // Notice that the '*'s have been replaced as '\\*'
13003
- /^\^*\\\*\\\*\\\//,
13004
-
13005
- // '**/foo' <-> 'foo'
13006
- () => '^(?:.*\\/)?'
13007
- ],
13008
-
13009
- // starting
13010
- [
13011
- // there will be no leading '/'
13012
- // (which has been replaced by section "leading slash")
13013
- // If starts with '**', adding a '^' to the regular expression also works
13014
- /^(?=[^^])/,
13015
- function startingReplacer () {
13016
- // If has a slash `/` at the beginning or middle
13017
- return !/\/(?!$)/.test(this)
13018
- // > Prior to 2.22.1
13019
- // > If the pattern does not contain a slash /,
13020
- // > Git treats it as a shell glob pattern
13021
- // Actually, if there is only a trailing slash,
13022
- // git also treats it as a shell glob pattern
13023
-
13024
- // After 2.22.1 (compatible but clearer)
13025
- // > If there is a separator at the beginning or middle (or both)
13026
- // > of the pattern, then the pattern is relative to the directory
13027
- // > level of the particular .gitignore file itself.
13028
- // > Otherwise the pattern may also match at any level below
13029
- // > the .gitignore level.
13030
- ? '(?:^|\\/)'
13031
-
13032
- // > Otherwise, Git treats the pattern as a shell glob suitable for
13033
- // > consumption by fnmatch(3)
13034
- : '^'
13035
- }
13036
- ],
13037
-
13038
- // two globstars
13039
- [
13040
- // Use lookahead assertions so that we could match more than one `'/**'`
13041
- /\\\/\\\*\\\*(?=\\\/|$)/g,
13042
-
13043
- // Zero, one or several directories
13044
- // should not use '*', or it will be replaced by the next replacer
13045
-
13046
- // Check if it is not the last `'/**'`
13047
- (_, index, str) => index + 6 < str.length
13048
-
13049
- // case: /**/
13050
- // > A slash followed by two consecutive asterisks then a slash matches
13051
- // > zero or more directories.
13052
- // > For example, "a/**/b" matches "a/b", "a/x/b", "a/x/y/b" and so on.
13053
- // '/**/'
13054
- ? '(?:\\/[^\\/]+)*'
13055
-
13056
- // case: /**
13057
- // > A trailing `"/**"` matches everything inside.
13058
-
13059
- // #21: everything inside but it should not include the current folder
13060
- : '\\/.+'
13061
- ],
13062
-
13063
- // normal intermediate wildcards
13064
- [
13065
- // Never replace escaped '*'
13066
- // ignore rule '\*' will match the path '*'
13067
-
13068
- // 'abc.*/' -> go
13069
- // 'abc.*' -> skip this rule,
13070
- // coz trailing single wildcard will be handed by [trailing wildcard]
13071
- /(^|[^\\]+)(\\\*)+(?=.+)/g,
13072
-
13073
- // '*.js' matches '.js'
13074
- // '*.js' doesn't match 'abc'
13075
- (_, p1, p2) => {
13076
- // 1.
13077
- // > An asterisk "*" matches anything except a slash.
13078
- // 2.
13079
- // > Other consecutive asterisks are considered regular asterisks
13080
- // > and will match according to the previous rules.
13081
- const unescaped = p2.replace(/\\\*/g, '[^\\/]*');
13082
- return p1 + unescaped
13083
- }
13084
- ],
13085
-
13086
- [
13087
- // unescape, revert step 3 except for back slash
13088
- // For example, if a user escape a '\\*',
13089
- // after step 3, the result will be '\\\\\\*'
13090
- /\\\\\\(?=[$.|*+(){^])/g,
13091
- () => ESCAPE
13092
- ],
13093
-
13094
- [
13095
- // '\\\\' -> '\\'
13096
- /\\\\/g,
13097
- () => ESCAPE
13098
- ],
13099
-
13100
- [
13101
- // > The range notation, e.g. [a-zA-Z],
13102
- // > can be used to match one of the characters in a range.
13103
-
13104
- // `\` is escaped by step 3
13105
- /(\\)?\[([^\]/]*?)(\\*)($|\])/g,
13106
- (match, leadEscape, range, endEscape, close) => leadEscape === ESCAPE
13107
- // '\\[bar]' -> '\\\\[bar\\]'
13108
- ? `\\[${range}${cleanRangeBackSlash(endEscape)}${close}`
13109
- : close === ']'
13110
- ? endEscape.length % 2 === 0
13111
- // A normal case, and it is a range notation
13112
- // '[bar]'
13113
- // '[bar\\\\]'
13114
- ? `[${sanitizeRange(range)}${endEscape}]`
13115
- // Invalid range notaton
13116
- // '[bar\\]' -> '[bar\\\\]'
13117
- : '[]'
13118
- : '[]'
13119
- ],
13120
-
13121
- // ending
13122
- [
13123
- // 'js' will not match 'js.'
13124
- // 'ab' will not match 'abc'
13125
- /(?:[^*])$/,
13126
-
13127
- // WTF!
13128
- // https://git-scm.com/docs/gitignore
13129
- // changes in [2.22.1](https://git-scm.com/docs/gitignore/2.22.1)
13130
- // which re-fixes #24, #38
13131
-
13132
- // > If there is a separator at the end of the pattern then the pattern
13133
- // > will only match directories, otherwise the pattern can match both
13134
- // > files and directories.
13135
-
13136
- // 'js*' will not match 'a.js'
13137
- // 'js/' will not match 'a.js'
13138
- // 'js' will match 'a.js' and 'a.js/'
13139
- match => /\/$/.test(match)
13140
- // foo/ will not match 'foo'
13141
- ? `${match}$`
13142
- // foo matches 'foo' and 'foo/'
13143
- : `${match}(?=$|\\/$)`
13144
- ],
13145
-
13146
- // trailing wildcard
13147
- [
13148
- /(\^|\\\/)?\\\*$/,
13149
- (_, p1) => {
13150
- const prefix = p1
13151
- // '\^':
13152
- // '/*' does not match EMPTY
13153
- // '/*' does not match everything
13154
-
13155
- // '\\\/':
13156
- // 'abc/*' does not match 'abc/'
13157
- ? `${p1}[^/]+`
13158
-
13159
- // 'a*' matches 'a'
13160
- // 'a*' matches 'aa'
13161
- : '[^/]*';
13162
-
13163
- return `${prefix}(?=$|\\/$)`
13164
- }
13165
- ],
13166
- ];
13167
-
13168
- // A simple cache, because an ignore rule only has only one certain meaning
13169
- const regexCache = Object.create(null);
13170
-
13171
- // @param {pattern}
13172
- const makeRegex = (pattern, ignoreCase) => {
13173
- let source = regexCache[pattern];
13174
-
13175
- if (!source) {
13176
- source = REPLACERS.reduce(
13177
- (prev, [matcher, replacer]) =>
13178
- prev.replace(matcher, replacer.bind(pattern)),
13179
- pattern
13180
- );
13181
- regexCache[pattern] = source;
13182
- }
13183
-
13184
- return ignoreCase
13185
- ? new RegExp(source, 'i')
13186
- : new RegExp(source)
13187
- };
13188
-
13189
- const isString = subject => typeof subject === 'string';
13190
-
13191
- // > A blank line matches no files, so it can serve as a separator for readability.
13192
- const checkPattern = pattern => pattern
13193
- && isString(pattern)
13194
- && !REGEX_TEST_BLANK_LINE.test(pattern)
13195
- && !REGEX_INVALID_TRAILING_BACKSLASH.test(pattern)
13196
-
13197
- // > A line starting with # serves as a comment.
13198
- && pattern.indexOf('#') !== 0;
13199
-
13200
- const splitPattern = pattern => pattern.split(REGEX_SPLITALL_CRLF);
13201
-
13202
- class IgnoreRule {
13203
- constructor (
13204
- origin,
13205
- pattern,
13206
- negative,
13207
- regex
13208
- ) {
13209
- this.origin = origin;
13210
- this.pattern = pattern;
13211
- this.negative = negative;
13212
- this.regex = regex;
13213
- }
13214
- }
13215
-
13216
- const createRule = (pattern, ignoreCase) => {
13217
- const origin = pattern;
13218
- let negative = false;
13219
-
13220
- // > An optional prefix "!" which negates the pattern;
13221
- if (pattern.indexOf('!') === 0) {
13222
- negative = true;
13223
- pattern = pattern.substr(1);
13224
- }
13225
-
13226
- pattern = pattern
13227
- // > Put a backslash ("\") in front of the first "!" for patterns that
13228
- // > begin with a literal "!", for example, `"\!important!.txt"`.
13229
- .replace(REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION, '!')
13230
- // > Put a backslash ("\") in front of the first hash for patterns that
13231
- // > begin with a hash.
13232
- .replace(REGEX_REPLACE_LEADING_EXCAPED_HASH, '#');
13233
-
13234
- const regex = makeRegex(pattern, ignoreCase);
13235
-
13236
- return new IgnoreRule(
13237
- origin,
13238
- pattern,
13239
- negative,
13240
- regex
13241
- )
13242
- };
13243
-
13244
- const throwError = (message, Ctor) => {
13245
- throw new Ctor(message)
13246
- };
13247
-
13248
- const checkPath = (path, originalPath, doThrow) => {
13249
- if (!isString(path)) {
13250
- return doThrow(
13251
- `path must be a string, but got \`${originalPath}\``,
13252
- TypeError
13253
- )
13254
- }
13255
-
13256
- // We don't know if we should ignore EMPTY, so throw
13257
- if (!path) {
13258
- return doThrow(`path must not be empty`, TypeError)
13259
- }
13260
-
13261
- // Check if it is a relative path
13262
- if (checkPath.isNotRelative(path)) {
13263
- const r = '`path.relative()`d';
13264
- return doThrow(
13265
- `path should be a ${r} string, but got "${originalPath}"`,
13266
- RangeError
13267
- )
13268
- }
13269
-
13270
- return true
13271
- };
13272
-
13273
- const isNotRelative = path => REGEX_TEST_INVALID_PATH.test(path);
13274
-
13275
- checkPath.isNotRelative = isNotRelative;
13276
- checkPath.convert = p => p;
13277
-
13278
- class Ignore {
13279
- constructor ({
13280
- ignorecase = true,
13281
- ignoreCase = ignorecase,
13282
- allowRelativePaths = false
13283
- } = {}) {
13284
- define(this, KEY_IGNORE, true);
13285
-
13286
- this._rules = [];
13287
- this._ignoreCase = ignoreCase;
13288
- this._allowRelativePaths = allowRelativePaths;
13289
- this._initCache();
13290
- }
13291
-
13292
- _initCache () {
13293
- this._ignoreCache = Object.create(null);
13294
- this._testCache = Object.create(null);
13295
- }
13296
-
13297
- _addPattern (pattern) {
13298
- // #32
13299
- if (pattern && pattern[KEY_IGNORE]) {
13300
- this._rules = this._rules.concat(pattern._rules);
13301
- this._added = true;
13302
- return
13303
- }
13304
-
13305
- if (checkPattern(pattern)) {
13306
- const rule = createRule(pattern, this._ignoreCase);
13307
- this._added = true;
13308
- this._rules.push(rule);
13309
- }
13310
- }
13311
-
13312
- // @param {Array<string> | string | Ignore} pattern
13313
- add (pattern) {
13314
- this._added = false;
13315
-
13316
- makeArray(
13317
- isString(pattern)
13318
- ? splitPattern(pattern)
13319
- : pattern
13320
- ).forEach(this._addPattern, this);
13321
-
13322
- // Some rules have just added to the ignore,
13323
- // making the behavior changed.
13324
- if (this._added) {
13325
- this._initCache();
13326
- }
13327
-
13328
- return this
13329
- }
13330
-
13331
- // legacy
13332
- addPattern (pattern) {
13333
- return this.add(pattern)
13334
- }
13335
-
13336
- // | ignored : unignored
13337
- // negative | 0:0 | 0:1 | 1:0 | 1:1
13338
- // -------- | ------- | ------- | ------- | --------
13339
- // 0 | TEST | TEST | SKIP | X
13340
- // 1 | TESTIF | SKIP | TEST | X
13341
-
13342
- // - SKIP: always skip
13343
- // - TEST: always test
13344
- // - TESTIF: only test if checkUnignored
13345
- // - X: that never happen
13346
-
13347
- // @param {boolean} whether should check if the path is unignored,
13348
- // setting `checkUnignored` to `false` could reduce additional
13349
- // path matching.
13350
-
13351
- // @returns {TestResult} true if a file is ignored
13352
- _testOne (path, checkUnignored) {
13353
- let ignored = false;
13354
- let unignored = false;
13355
-
13356
- this._rules.forEach(rule => {
13357
- const {negative} = rule;
13358
- if (
13359
- unignored === negative && ignored !== unignored
13360
- || negative && !ignored && !unignored && !checkUnignored
13361
- ) {
13362
- return
13363
- }
13364
-
13365
- const matched = rule.regex.test(path);
13366
-
13367
- if (matched) {
13368
- ignored = !negative;
13369
- unignored = negative;
13370
- }
13371
- });
13372
-
13373
- return {
13374
- ignored,
13375
- unignored
13376
- }
13377
- }
13378
-
13379
- // @returns {TestResult}
13380
- _test (originalPath, cache, checkUnignored, slices) {
13381
- const path = originalPath
13382
- // Supports nullable path
13383
- && checkPath.convert(originalPath);
13384
-
13385
- checkPath(
13386
- path,
13387
- originalPath,
13388
- this._allowRelativePaths
13389
- ? RETURN_FALSE
13390
- : throwError
13391
- );
13392
-
13393
- return this._t(path, cache, checkUnignored, slices)
13394
- }
13395
-
13396
- _t (path, cache, checkUnignored, slices) {
13397
- if (path in cache) {
13398
- return cache[path]
13399
- }
13400
-
13401
- if (!slices) {
13402
- // path/to/a.js
13403
- // ['path', 'to', 'a.js']
13404
- slices = path.split(SLASH);
13405
- }
13406
-
13407
- slices.pop();
13408
-
13409
- // If the path has no parent directory, just test it
13410
- if (!slices.length) {
13411
- return cache[path] = this._testOne(path, checkUnignored)
13412
- }
13413
-
13414
- const parent = this._t(
13415
- slices.join(SLASH) + SLASH,
13416
- cache,
13417
- checkUnignored,
13418
- slices
13419
- );
13420
-
13421
- // If the path contains a parent directory, check the parent first
13422
- return cache[path] = parent.ignored
13423
- // > It is not possible to re-include a file if a parent directory of
13424
- // > that file is excluded.
13425
- ? parent
13426
- : this._testOne(path, checkUnignored)
13427
- }
13428
-
13429
- ignores (path) {
13430
- return this._test(path, this._ignoreCache, false).ignored
13431
- }
13432
-
13433
- createFilter () {
13434
- return path => !this.ignores(path)
13435
- }
13436
-
13437
- filter (paths) {
13438
- return makeArray(paths).filter(this.createFilter())
13439
- }
13440
-
13441
- // @returns {TestResult}
13442
- test (path) {
13443
- return this._test(path, this._testCache, true)
13444
- }
13445
- }
13446
-
13447
- const factory = options => new Ignore(options);
13448
-
13449
- const isPathValid = path =>
13450
- checkPath(path && checkPath.convert(path), path, RETURN_FALSE);
13451
-
13452
- factory.isPathValid = isPathValid;
12881
+ var ignore$1;
12882
+ var hasRequiredIgnore;
13453
12883
 
13454
- // Fixes typescript
13455
- factory.default = factory;
13456
-
13457
- var ignore = factory;
12884
+ function requireIgnore () {
12885
+ if (hasRequiredIgnore) return ignore$1;
12886
+ hasRequiredIgnore = 1;
12887
+ // A simple implementation of make-array
12888
+ function makeArray (subject) {
12889
+ return Array.isArray(subject)
12890
+ ? subject
12891
+ : [subject]
12892
+ }
13458
12893
 
13459
- // Windows
13460
- // --------------------------------------------------------------
13461
- /* istanbul ignore if */
13462
- if (
13463
- // Detect `process` so that it can run in browsers.
13464
- typeof process !== 'undefined'
13465
- && (
13466
- process.env && process.env.IGNORE_TEST_WIN32
13467
- || process.platform === 'win32'
13468
- )
13469
- ) {
13470
- /* eslint no-control-regex: "off" */
13471
- const makePosix = str => /^\\\\\?\\/.test(str)
13472
- || /["<>|\u0000-\u001F]+/u.test(str)
13473
- ? str
13474
- : str.replace(/\\/g, '/');
12894
+ const EMPTY = '';
12895
+ const SPACE = ' ';
12896
+ const ESCAPE = '\\';
12897
+ const REGEX_TEST_BLANK_LINE = /^\s+$/;
12898
+ const REGEX_INVALID_TRAILING_BACKSLASH = /(?:[^\\]|^)\\$/;
12899
+ const REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION = /^\\!/;
12900
+ const REGEX_REPLACE_LEADING_EXCAPED_HASH = /^\\#/;
12901
+ const REGEX_SPLITALL_CRLF = /\r?\n/g;
12902
+ // /foo,
12903
+ // ./foo,
12904
+ // ../foo,
12905
+ // .
12906
+ // ..
12907
+ const REGEX_TEST_INVALID_PATH = /^\.*\/|^\.+$/;
12908
+
12909
+ const SLASH = '/';
12910
+
12911
+ // Do not use ternary expression here, since "istanbul ignore next" is buggy
12912
+ let TMP_KEY_IGNORE = 'node-ignore';
12913
+ /* istanbul ignore else */
12914
+ if (typeof Symbol !== 'undefined') {
12915
+ TMP_KEY_IGNORE = Symbol.for('node-ignore');
12916
+ }
12917
+ const KEY_IGNORE = TMP_KEY_IGNORE;
12918
+
12919
+ const define = (object, key, value) =>
12920
+ Object.defineProperty(object, key, {value});
12921
+
12922
+ const REGEX_REGEXP_RANGE = /([0-z])-([0-z])/g;
12923
+
12924
+ const RETURN_FALSE = () => false;
12925
+
12926
+ // Sanitize the range of a regular expression
12927
+ // The cases are complicated, see test cases for details
12928
+ const sanitizeRange = range => range.replace(
12929
+ REGEX_REGEXP_RANGE,
12930
+ (match, from, to) => from.charCodeAt(0) <= to.charCodeAt(0)
12931
+ ? match
12932
+ // Invalid range (out of order) which is ok for gitignore rules but
12933
+ // fatal for JavaScript regular expression, so eliminate it.
12934
+ : EMPTY
12935
+ );
12936
+
12937
+ // See fixtures #59
12938
+ const cleanRangeBackSlash = slashes => {
12939
+ const {length} = slashes;
12940
+ return slashes.slice(0, length - length % 2)
12941
+ };
12942
+
12943
+ // > If the pattern ends with a slash,
12944
+ // > it is removed for the purpose of the following description,
12945
+ // > but it would only find a match with a directory.
12946
+ // > In other words, foo/ will match a directory foo and paths underneath it,
12947
+ // > but will not match a regular file or a symbolic link foo
12948
+ // > (this is consistent with the way how pathspec works in general in Git).
12949
+ // '`foo/`' will not match regular file '`foo`' or symbolic link '`foo`'
12950
+ // -> ignore-rules will not deal with it, because it costs extra `fs.stat` call
12951
+ // you could use option `mark: true` with `glob`
12952
+
12953
+ // '`foo/`' should not continue with the '`..`'
12954
+ const REPLACERS = [
12955
+
12956
+ [
12957
+ // remove BOM
12958
+ // TODO:
12959
+ // Other similar zero-width characters?
12960
+ /^\uFEFF/,
12961
+ () => EMPTY
12962
+ ],
12963
+
12964
+ // > Trailing spaces are ignored unless they are quoted with backslash ("\")
12965
+ [
12966
+ // (a\ ) -> (a )
12967
+ // (a ) -> (a)
12968
+ // (a ) -> (a)
12969
+ // (a \ ) -> (a )
12970
+ /((?:\\\\)*?)(\\?\s+)$/,
12971
+ (_, m1, m2) => m1 + (
12972
+ m2.indexOf('\\') === 0
12973
+ ? SPACE
12974
+ : EMPTY
12975
+ )
12976
+ ],
12977
+
12978
+ // replace (\ ) with ' '
12979
+ // (\ ) -> ' '
12980
+ // (\\ ) -> '\\ '
12981
+ // (\\\ ) -> '\\ '
12982
+ [
12983
+ /(\\+?)\s/g,
12984
+ (_, m1) => {
12985
+ const {length} = m1;
12986
+ return m1.slice(0, length - length % 2) + SPACE
12987
+ }
12988
+ ],
12989
+
12990
+ // Escape metacharacters
12991
+ // which is written down by users but means special for regular expressions.
12992
+
12993
+ // > There are 12 characters with special meanings:
12994
+ // > - the backslash \,
12995
+ // > - the caret ^,
12996
+ // > - the dollar sign $,
12997
+ // > - the period or dot .,
12998
+ // > - the vertical bar or pipe symbol |,
12999
+ // > - the question mark ?,
13000
+ // > - the asterisk or star *,
13001
+ // > - the plus sign +,
13002
+ // > - the opening parenthesis (,
13003
+ // > - the closing parenthesis ),
13004
+ // > - and the opening square bracket [,
13005
+ // > - the opening curly brace {,
13006
+ // > These special characters are often called "metacharacters".
13007
+ [
13008
+ /[\\$.|*+(){^]/g,
13009
+ match => `\\${match}`
13010
+ ],
13011
+
13012
+ [
13013
+ // > a question mark (?) matches a single character
13014
+ /(?!\\)\?/g,
13015
+ () => '[^/]'
13016
+ ],
13017
+
13018
+ // leading slash
13019
+ [
13020
+
13021
+ // > A leading slash matches the beginning of the pathname.
13022
+ // > For example, "/*.c" matches "cat-file.c" but not "mozilla-sha1/sha1.c".
13023
+ // A leading slash matches the beginning of the pathname
13024
+ /^\//,
13025
+ () => '^'
13026
+ ],
13027
+
13028
+ // replace special metacharacter slash after the leading slash
13029
+ [
13030
+ /\//g,
13031
+ () => '\\/'
13032
+ ],
13033
+
13034
+ [
13035
+ // > A leading "**" followed by a slash means match in all directories.
13036
+ // > For example, "**/foo" matches file or directory "foo" anywhere,
13037
+ // > the same as pattern "foo".
13038
+ // > "**/foo/bar" matches file or directory "bar" anywhere that is directly
13039
+ // > under directory "foo".
13040
+ // Notice that the '*'s have been replaced as '\\*'
13041
+ /^\^*\\\*\\\*\\\//,
13042
+
13043
+ // '**/foo' <-> 'foo'
13044
+ () => '^(?:.*\\/)?'
13045
+ ],
13046
+
13047
+ // starting
13048
+ [
13049
+ // there will be no leading '/'
13050
+ // (which has been replaced by section "leading slash")
13051
+ // If starts with '**', adding a '^' to the regular expression also works
13052
+ /^(?=[^^])/,
13053
+ function startingReplacer () {
13054
+ // If has a slash `/` at the beginning or middle
13055
+ return !/\/(?!$)/.test(this)
13056
+ // > Prior to 2.22.1
13057
+ // > If the pattern does not contain a slash /,
13058
+ // > Git treats it as a shell glob pattern
13059
+ // Actually, if there is only a trailing slash,
13060
+ // git also treats it as a shell glob pattern
13061
+
13062
+ // After 2.22.1 (compatible but clearer)
13063
+ // > If there is a separator at the beginning or middle (or both)
13064
+ // > of the pattern, then the pattern is relative to the directory
13065
+ // > level of the particular .gitignore file itself.
13066
+ // > Otherwise the pattern may also match at any level below
13067
+ // > the .gitignore level.
13068
+ ? '(?:^|\\/)'
13069
+
13070
+ // > Otherwise, Git treats the pattern as a shell glob suitable for
13071
+ // > consumption by fnmatch(3)
13072
+ : '^'
13073
+ }
13074
+ ],
13075
+
13076
+ // two globstars
13077
+ [
13078
+ // Use lookahead assertions so that we could match more than one `'/**'`
13079
+ /\\\/\\\*\\\*(?=\\\/|$)/g,
13080
+
13081
+ // Zero, one or several directories
13082
+ // should not use '*', or it will be replaced by the next replacer
13083
+
13084
+ // Check if it is not the last `'/**'`
13085
+ (_, index, str) => index + 6 < str.length
13086
+
13087
+ // case: /**/
13088
+ // > A slash followed by two consecutive asterisks then a slash matches
13089
+ // > zero or more directories.
13090
+ // > For example, "a/**/b" matches "a/b", "a/x/b", "a/x/y/b" and so on.
13091
+ // '/**/'
13092
+ ? '(?:\\/[^\\/]+)*'
13093
+
13094
+ // case: /**
13095
+ // > A trailing `"/**"` matches everything inside.
13096
+
13097
+ // #21: everything inside but it should not include the current folder
13098
+ : '\\/.+'
13099
+ ],
13100
+
13101
+ // normal intermediate wildcards
13102
+ [
13103
+ // Never replace escaped '*'
13104
+ // ignore rule '\*' will match the path '*'
13105
+
13106
+ // 'abc.*/' -> go
13107
+ // 'abc.*' -> skip this rule,
13108
+ // coz trailing single wildcard will be handed by [trailing wildcard]
13109
+ /(^|[^\\]+)(\\\*)+(?=.+)/g,
13110
+
13111
+ // '*.js' matches '.js'
13112
+ // '*.js' doesn't match 'abc'
13113
+ (_, p1, p2) => {
13114
+ // 1.
13115
+ // > An asterisk "*" matches anything except a slash.
13116
+ // 2.
13117
+ // > Other consecutive asterisks are considered regular asterisks
13118
+ // > and will match according to the previous rules.
13119
+ const unescaped = p2.replace(/\\\*/g, '[^\\/]*');
13120
+ return p1 + unescaped
13121
+ }
13122
+ ],
13123
+
13124
+ [
13125
+ // unescape, revert step 3 except for back slash
13126
+ // For example, if a user escape a '\\*',
13127
+ // after step 3, the result will be '\\\\\\*'
13128
+ /\\\\\\(?=[$.|*+(){^])/g,
13129
+ () => ESCAPE
13130
+ ],
13131
+
13132
+ [
13133
+ // '\\\\' -> '\\'
13134
+ /\\\\/g,
13135
+ () => ESCAPE
13136
+ ],
13137
+
13138
+ [
13139
+ // > The range notation, e.g. [a-zA-Z],
13140
+ // > can be used to match one of the characters in a range.
13141
+
13142
+ // `\` is escaped by step 3
13143
+ /(\\)?\[([^\]/]*?)(\\*)($|\])/g,
13144
+ (match, leadEscape, range, endEscape, close) => leadEscape === ESCAPE
13145
+ // '\\[bar]' -> '\\\\[bar\\]'
13146
+ ? `\\[${range}${cleanRangeBackSlash(endEscape)}${close}`
13147
+ : close === ']'
13148
+ ? endEscape.length % 2 === 0
13149
+ // A normal case, and it is a range notation
13150
+ // '[bar]'
13151
+ // '[bar\\\\]'
13152
+ ? `[${sanitizeRange(range)}${endEscape}]`
13153
+ // Invalid range notaton
13154
+ // '[bar\\]' -> '[bar\\\\]'
13155
+ : '[]'
13156
+ : '[]'
13157
+ ],
13158
+
13159
+ // ending
13160
+ [
13161
+ // 'js' will not match 'js.'
13162
+ // 'ab' will not match 'abc'
13163
+ /(?:[^*])$/,
13164
+
13165
+ // WTF!
13166
+ // https://git-scm.com/docs/gitignore
13167
+ // changes in [2.22.1](https://git-scm.com/docs/gitignore/2.22.1)
13168
+ // which re-fixes #24, #38
13169
+
13170
+ // > If there is a separator at the end of the pattern then the pattern
13171
+ // > will only match directories, otherwise the pattern can match both
13172
+ // > files and directories.
13173
+
13174
+ // 'js*' will not match 'a.js'
13175
+ // 'js/' will not match 'a.js'
13176
+ // 'js' will match 'a.js' and 'a.js/'
13177
+ match => /\/$/.test(match)
13178
+ // foo/ will not match 'foo'
13179
+ ? `${match}$`
13180
+ // foo matches 'foo' and 'foo/'
13181
+ : `${match}(?=$|\\/$)`
13182
+ ],
13183
+
13184
+ // trailing wildcard
13185
+ [
13186
+ /(\^|\\\/)?\\\*$/,
13187
+ (_, p1) => {
13188
+ const prefix = p1
13189
+ // '\^':
13190
+ // '/*' does not match EMPTY
13191
+ // '/*' does not match everything
13192
+
13193
+ // '\\\/':
13194
+ // 'abc/*' does not match 'abc/'
13195
+ ? `${p1}[^/]+`
13196
+
13197
+ // 'a*' matches 'a'
13198
+ // 'a*' matches 'aa'
13199
+ : '[^/]*';
13200
+
13201
+ return `${prefix}(?=$|\\/$)`
13202
+ }
13203
+ ],
13204
+ ];
13205
+
13206
+ // A simple cache, because an ignore rule only has only one certain meaning
13207
+ const regexCache = Object.create(null);
13208
+
13209
+ // @param {pattern}
13210
+ const makeRegex = (pattern, ignoreCase) => {
13211
+ let source = regexCache[pattern];
13212
+
13213
+ if (!source) {
13214
+ source = REPLACERS.reduce(
13215
+ (prev, [matcher, replacer]) =>
13216
+ prev.replace(matcher, replacer.bind(pattern)),
13217
+ pattern
13218
+ );
13219
+ regexCache[pattern] = source;
13220
+ }
13221
+
13222
+ return ignoreCase
13223
+ ? new RegExp(source, 'i')
13224
+ : new RegExp(source)
13225
+ };
13226
+
13227
+ const isString = subject => typeof subject === 'string';
13228
+
13229
+ // > A blank line matches no files, so it can serve as a separator for readability.
13230
+ const checkPattern = pattern => pattern
13231
+ && isString(pattern)
13232
+ && !REGEX_TEST_BLANK_LINE.test(pattern)
13233
+ && !REGEX_INVALID_TRAILING_BACKSLASH.test(pattern)
13234
+
13235
+ // > A line starting with # serves as a comment.
13236
+ && pattern.indexOf('#') !== 0;
13237
+
13238
+ const splitPattern = pattern => pattern.split(REGEX_SPLITALL_CRLF);
13239
+
13240
+ class IgnoreRule {
13241
+ constructor (
13242
+ origin,
13243
+ pattern,
13244
+ negative,
13245
+ regex
13246
+ ) {
13247
+ this.origin = origin;
13248
+ this.pattern = pattern;
13249
+ this.negative = negative;
13250
+ this.regex = regex;
13251
+ }
13252
+ }
13475
13253
 
13476
- checkPath.convert = makePosix;
13254
+ const createRule = (pattern, ignoreCase) => {
13255
+ const origin = pattern;
13256
+ let negative = false;
13257
+
13258
+ // > An optional prefix "!" which negates the pattern;
13259
+ if (pattern.indexOf('!') === 0) {
13260
+ negative = true;
13261
+ pattern = pattern.substr(1);
13262
+ }
13263
+
13264
+ pattern = pattern
13265
+ // > Put a backslash ("\") in front of the first "!" for patterns that
13266
+ // > begin with a literal "!", for example, `"\!important!.txt"`.
13267
+ .replace(REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION, '!')
13268
+ // > Put a backslash ("\") in front of the first hash for patterns that
13269
+ // > begin with a hash.
13270
+ .replace(REGEX_REPLACE_LEADING_EXCAPED_HASH, '#');
13271
+
13272
+ const regex = makeRegex(pattern, ignoreCase);
13273
+
13274
+ return new IgnoreRule(
13275
+ origin,
13276
+ pattern,
13277
+ negative,
13278
+ regex
13279
+ )
13280
+ };
13281
+
13282
+ const throwError = (message, Ctor) => {
13283
+ throw new Ctor(message)
13284
+ };
13285
+
13286
+ const checkPath = (path, originalPath, doThrow) => {
13287
+ if (!isString(path)) {
13288
+ return doThrow(
13289
+ `path must be a string, but got \`${originalPath}\``,
13290
+ TypeError
13291
+ )
13292
+ }
13293
+
13294
+ // We don't know if we should ignore EMPTY, so throw
13295
+ if (!path) {
13296
+ return doThrow(`path must not be empty`, TypeError)
13297
+ }
13298
+
13299
+ // Check if it is a relative path
13300
+ if (checkPath.isNotRelative(path)) {
13301
+ const r = '`path.relative()`d';
13302
+ return doThrow(
13303
+ `path should be a ${r} string, but got "${originalPath}"`,
13304
+ RangeError
13305
+ )
13306
+ }
13307
+
13308
+ return true
13309
+ };
13310
+
13311
+ const isNotRelative = path => REGEX_TEST_INVALID_PATH.test(path);
13312
+
13313
+ checkPath.isNotRelative = isNotRelative;
13314
+ checkPath.convert = p => p;
13315
+
13316
+ class Ignore {
13317
+ constructor ({
13318
+ ignorecase = true,
13319
+ ignoreCase = ignorecase,
13320
+ allowRelativePaths = false
13321
+ } = {}) {
13322
+ define(this, KEY_IGNORE, true);
13323
+
13324
+ this._rules = [];
13325
+ this._ignoreCase = ignoreCase;
13326
+ this._allowRelativePaths = allowRelativePaths;
13327
+ this._initCache();
13328
+ }
13329
+
13330
+ _initCache () {
13331
+ this._ignoreCache = Object.create(null);
13332
+ this._testCache = Object.create(null);
13333
+ }
13334
+
13335
+ _addPattern (pattern) {
13336
+ // #32
13337
+ if (pattern && pattern[KEY_IGNORE]) {
13338
+ this._rules = this._rules.concat(pattern._rules);
13339
+ this._added = true;
13340
+ return
13341
+ }
13342
+
13343
+ if (checkPattern(pattern)) {
13344
+ const rule = createRule(pattern, this._ignoreCase);
13345
+ this._added = true;
13346
+ this._rules.push(rule);
13347
+ }
13348
+ }
13349
+
13350
+ // @param {Array<string> | string | Ignore} pattern
13351
+ add (pattern) {
13352
+ this._added = false;
13353
+
13354
+ makeArray(
13355
+ isString(pattern)
13356
+ ? splitPattern(pattern)
13357
+ : pattern
13358
+ ).forEach(this._addPattern, this);
13359
+
13360
+ // Some rules have just added to the ignore,
13361
+ // making the behavior changed.
13362
+ if (this._added) {
13363
+ this._initCache();
13364
+ }
13365
+
13366
+ return this
13367
+ }
13368
+
13369
+ // legacy
13370
+ addPattern (pattern) {
13371
+ return this.add(pattern)
13372
+ }
13373
+
13374
+ // | ignored : unignored
13375
+ // negative | 0:0 | 0:1 | 1:0 | 1:1
13376
+ // -------- | ------- | ------- | ------- | --------
13377
+ // 0 | TEST | TEST | SKIP | X
13378
+ // 1 | TESTIF | SKIP | TEST | X
13379
+
13380
+ // - SKIP: always skip
13381
+ // - TEST: always test
13382
+ // - TESTIF: only test if checkUnignored
13383
+ // - X: that never happen
13384
+
13385
+ // @param {boolean} whether should check if the path is unignored,
13386
+ // setting `checkUnignored` to `false` could reduce additional
13387
+ // path matching.
13388
+
13389
+ // @returns {TestResult} true if a file is ignored
13390
+ _testOne (path, checkUnignored) {
13391
+ let ignored = false;
13392
+ let unignored = false;
13393
+
13394
+ this._rules.forEach(rule => {
13395
+ const {negative} = rule;
13396
+ if (
13397
+ unignored === negative && ignored !== unignored
13398
+ || negative && !ignored && !unignored && !checkUnignored
13399
+ ) {
13400
+ return
13401
+ }
13402
+
13403
+ const matched = rule.regex.test(path);
13404
+
13405
+ if (matched) {
13406
+ ignored = !negative;
13407
+ unignored = negative;
13408
+ }
13409
+ });
13410
+
13411
+ return {
13412
+ ignored,
13413
+ unignored
13414
+ }
13415
+ }
13416
+
13417
+ // @returns {TestResult}
13418
+ _test (originalPath, cache, checkUnignored, slices) {
13419
+ const path = originalPath
13420
+ // Supports nullable path
13421
+ && checkPath.convert(originalPath);
13422
+
13423
+ checkPath(
13424
+ path,
13425
+ originalPath,
13426
+ this._allowRelativePaths
13427
+ ? RETURN_FALSE
13428
+ : throwError
13429
+ );
13430
+
13431
+ return this._t(path, cache, checkUnignored, slices)
13432
+ }
13433
+
13434
+ _t (path, cache, checkUnignored, slices) {
13435
+ if (path in cache) {
13436
+ return cache[path]
13437
+ }
13438
+
13439
+ if (!slices) {
13440
+ // path/to/a.js
13441
+ // ['path', 'to', 'a.js']
13442
+ slices = path.split(SLASH);
13443
+ }
13444
+
13445
+ slices.pop();
13446
+
13447
+ // If the path has no parent directory, just test it
13448
+ if (!slices.length) {
13449
+ return cache[path] = this._testOne(path, checkUnignored)
13450
+ }
13451
+
13452
+ const parent = this._t(
13453
+ slices.join(SLASH) + SLASH,
13454
+ cache,
13455
+ checkUnignored,
13456
+ slices
13457
+ );
13458
+
13459
+ // If the path contains a parent directory, check the parent first
13460
+ return cache[path] = parent.ignored
13461
+ // > It is not possible to re-include a file if a parent directory of
13462
+ // > that file is excluded.
13463
+ ? parent
13464
+ : this._testOne(path, checkUnignored)
13465
+ }
13466
+
13467
+ ignores (path) {
13468
+ return this._test(path, this._ignoreCache, false).ignored
13469
+ }
13470
+
13471
+ createFilter () {
13472
+ return path => !this.ignores(path)
13473
+ }
13474
+
13475
+ filter (paths) {
13476
+ return makeArray(paths).filter(this.createFilter())
13477
+ }
13478
+
13479
+ // @returns {TestResult}
13480
+ test (path) {
13481
+ return this._test(path, this._testCache, true)
13482
+ }
13483
+ }
13477
13484
 
13478
- // 'C:\\foo' <- 'C:\\foo' has been converted to 'C:/'
13479
- // 'd:\\foo'
13480
- const REGIX_IS_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i;
13481
- checkPath.isNotRelative = path =>
13482
- REGIX_IS_WINDOWS_PATH_ABSOLUTE.test(path)
13483
- || isNotRelative(path);
13485
+ const factory = options => new Ignore(options);
13486
+
13487
+ const isPathValid = path =>
13488
+ checkPath(path && checkPath.convert(path), path, RETURN_FALSE);
13489
+
13490
+ factory.isPathValid = isPathValid;
13491
+
13492
+ // Fixes typescript
13493
+ factory.default = factory;
13494
+
13495
+ ignore$1 = factory;
13496
+
13497
+ // Windows
13498
+ // --------------------------------------------------------------
13499
+ /* istanbul ignore if */
13500
+ if (
13501
+ // Detect `process` so that it can run in browsers.
13502
+ typeof process !== 'undefined'
13503
+ && (
13504
+ process.env && process.env.IGNORE_TEST_WIN32
13505
+ || process.platform === 'win32'
13506
+ )
13507
+ ) {
13508
+ /* eslint no-control-regex: "off" */
13509
+ const makePosix = str => /^\\\\\?\\/.test(str)
13510
+ || /["<>|\u0000-\u001F]+/u.test(str)
13511
+ ? str
13512
+ : str.replace(/\\/g, '/');
13513
+
13514
+ checkPath.convert = makePosix;
13515
+
13516
+ // 'C:\\foo' <- 'C:\\foo' has been converted to 'C:/'
13517
+ // 'd:\\foo'
13518
+ const REGIX_IS_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i;
13519
+ checkPath.isNotRelative = path =>
13520
+ REGIX_IS_WINDOWS_PATH_ABSOLUTE.test(path)
13521
+ || isNotRelative(path);
13522
+ }
13523
+ return ignore$1;
13484
13524
  }
13485
13525
 
13486
- var ignore$1 = /*@__PURE__*/getDefaultExportFromCjs(ignore);
13526
+ var ignoreExports = /*@__PURE__*/ requireIgnore();
13527
+ var ignore = /*@__PURE__*/getDefaultExportFromCjs(ignoreExports);
13487
13528
 
13488
13529
  const entities = {
13489
13530
  ">": "&gt;",
@@ -13794,5 +13835,5 @@ function compatibilityCheckImpl(name, declared, options) {
13794
13835
  return false;
13795
13836
  }
13796
13837
 
13797
- export { Attribute as A, definePlugin as B, Config as C, DOMNode as D, Parser as E, ruleExists as F, walk as G, HtmlValidate as H, EventHandler as I, compatibilityCheckImpl as J, codeframe as K, name as L, MetaCopyableProperty as M, NodeClosed as N, bugs as O, Presets as P, ResolvedConfig as R, Severity as S, TextNode as T, UserError as U, Validator as V, WrappedError as W, ConfigError as a, ConfigLoader as b, defineConfig as c, deepmerge$1 as d, ensureError as e, StaticConfigLoader as f, getFormatter as g, DOMTokenList as h, ignore$1 as i, DOMTree as j, DynamicValue as k, HtmlElement as l, NodeType as m, NestedError as n, SchemaValidationError as o, MetaTable as p, TextContent$1 as q, Rule as r, staticResolver as s, ariaNaming as t, TextClassification as u, version as v, classifyNodeText as w, keywordPatternMatcher as x, sliceLocation as y, Reporter as z };
13838
+ export { Attribute as A, Reporter as B, Config as C, DOMNode as D, definePlugin as E, ruleExists as F, walk as G, HtmlValidate as H, EventHandler as I, compatibilityCheckImpl as J, codeframe as K, name as L, MetaCopyableProperty as M, NodeClosed as N, bugs as O, Parser as P, ResolvedConfig as R, Severity as S, TextNode as T, UserError as U, Validator as V, WrappedError as W, ConfigError as a, ConfigLoader as b, defineConfig as c, deepmerge as d, ensureError as e, StaticConfigLoader as f, getFormatter as g, DOMTokenList as h, ignore as i, DOMTree as j, DynamicValue as k, HtmlElement as l, NodeType as m, NestedError as n, SchemaValidationError as o, presets as p, MetaTable as q, TextContent$1 as r, staticResolver as s, Rule as t, ariaNaming as u, version as v, TextClassification as w, classifyNodeText as x, keywordPatternMatcher as y, sliceLocation as z };
13798
13839
  //# sourceMappingURL=core.js.map