@jobber/components 6.100.0 → 6.101.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,7 +6,7 @@ import { C as Content } from './Content-es.js';
6
6
  import { Fragment, jsx, jsxs } from 'react/jsx-runtime';
7
7
  import { c as commonjsGlobal, g as getDefaultExportFromCjs } from './_commonjsHelpers-es.js';
8
8
 
9
- function ok$1() {}
9
+ function ok$2() {}
10
10
 
11
11
  function unreachable() {}
12
12
 
@@ -31,7 +31,7 @@ function unreachable() {}
31
31
  * Comma-separated tokens.
32
32
  */
33
33
  function stringify$1(values, options) {
34
- const settings = options || {};
34
+ const settings = {};
35
35
 
36
36
  // Ensure the last empty entry is seen.
37
37
  const input = values[values.length - 1] === '' ? [...values, ''] : values;
@@ -69,7 +69,7 @@ const emptyOptions$2 = {};
69
69
  * Whether `name` can be an identifier.
70
70
  */
71
71
  function name(name, options) {
72
- const settings = options || emptyOptions$2;
72
+ const settings = emptyOptions$2;
73
73
  const re = settings.jsx ? nameReJsx : nameRe;
74
74
  return re.test(name)
75
75
  }
@@ -96,16 +96,16 @@ const re = /[ \t\n\f\r]/g;
96
96
  function whitespace(thing) {
97
97
  return typeof thing === 'object'
98
98
  ? thing.type === 'text'
99
- ? empty$1(thing.value)
99
+ ? empty$2(thing.value)
100
100
  : false
101
- : empty$1(thing)
101
+ : empty$2(thing)
102
102
  }
103
103
 
104
104
  /**
105
105
  * @param {string} value
106
106
  * @returns {boolean}
107
107
  */
108
- function empty$1(value) {
108
+ function empty$2(value) {
109
109
  return value.replace(re, '') === ''
110
110
  }
111
111
 
@@ -168,7 +168,7 @@ function merge(definitions, space) {
168
168
  * @param {string} value
169
169
  * @returns {string}
170
170
  */
171
- function normalize$2(value) {
171
+ function normalize$1(value) {
172
172
  return value.toLowerCase()
173
173
  }
174
174
 
@@ -313,8 +313,8 @@ function create(definition) {
313
313
 
314
314
  property[prop] = info;
315
315
 
316
- normal[normalize$2(prop)] = prop;
317
- normal[normalize$2(info.attribute)] = prop;
316
+ normal[normalize$1(prop)] = prop;
317
+ normal[normalize$1(info.attribute)] = prop;
318
318
  }
319
319
  }
320
320
 
@@ -1312,7 +1312,7 @@ const cap$1 = /[A-Z]/g;
1312
1312
  * @returns {Info}
1313
1313
  */
1314
1314
  function find(schema, value) {
1315
- const normal = normalize$2(value);
1315
+ const normal = normalize$1(value);
1316
1316
  let prop = value;
1317
1317
  let Type = Info;
1318
1318
 
@@ -1756,7 +1756,7 @@ var styleToObject = _default.default || _default;
1756
1756
  * @returns
1757
1757
  * Point.
1758
1758
  */
1759
- const pointEnd = point$5('end');
1759
+ const pointEnd = point$3('end');
1760
1760
 
1761
1761
  /**
1762
1762
  * Get the starting point of `node`.
@@ -1766,7 +1766,7 @@ const pointEnd = point$5('end');
1766
1766
  * @returns
1767
1767
  * Point.
1768
1768
  */
1769
- const pointStart = point$5('start');
1769
+ const pointStart = point$3('start');
1770
1770
 
1771
1771
  /**
1772
1772
  * Get the positional info of `node`.
@@ -1776,7 +1776,7 @@ const pointStart = point$5('start');
1776
1776
  * @returns
1777
1777
  * Getter.
1778
1778
  */
1779
- function point$5(type) {
1779
+ function point$3(type) {
1780
1780
  return point
1781
1781
 
1782
1782
  /**
@@ -1814,7 +1814,7 @@ function point$5(type) {
1814
1814
  * @returns {Position | undefined}
1815
1815
  * Position.
1816
1816
  */
1817
- function position$4(node) {
1817
+ function position$2(node) {
1818
1818
  const start = pointStart(node);
1819
1819
  const end = pointEnd(node);
1820
1820
 
@@ -1859,7 +1859,7 @@ function position$4(node) {
1859
1859
  * An empty string (`''`) is returned if the given value is neither `node`,
1860
1860
  * `position`, nor `point`.
1861
1861
  */
1862
- function stringifyPosition$3(value) {
1862
+ function stringifyPosition$1(value) {
1863
1863
  // Nothing.
1864
1864
  if (!value || typeof value !== 'object') {
1865
1865
  return ''
@@ -1867,17 +1867,17 @@ function stringifyPosition$3(value) {
1867
1867
 
1868
1868
  // Node.
1869
1869
  if ('position' in value || 'type' in value) {
1870
- return position$3(value.position)
1870
+ return position$1(value.position)
1871
1871
  }
1872
1872
 
1873
1873
  // Position.
1874
1874
  if ('start' in value || 'end' in value) {
1875
- return position$3(value)
1875
+ return position$1(value)
1876
1876
  }
1877
1877
 
1878
1878
  // Point.
1879
1879
  if ('line' in value || 'column' in value) {
1880
- return point$4(value)
1880
+ return point$2(value)
1881
1881
  }
1882
1882
 
1883
1883
  // ?
@@ -1888,23 +1888,23 @@ function stringifyPosition$3(value) {
1888
1888
  * @param {Point | PointLike | null | undefined} point
1889
1889
  * @returns {string}
1890
1890
  */
1891
- function point$4(point) {
1892
- return index$3(point && point.line) + ':' + index$3(point && point.column)
1891
+ function point$2(point) {
1892
+ return index$1(point && point.line) + ':' + index$1(point && point.column)
1893
1893
  }
1894
1894
 
1895
1895
  /**
1896
1896
  * @param {Position | PositionLike | null | undefined} pos
1897
1897
  * @returns {string}
1898
1898
  */
1899
- function position$3(pos) {
1900
- return point$4(pos && pos.start) + '-' + point$4(pos && pos.end)
1899
+ function position$1(pos) {
1900
+ return point$2(pos && pos.start) + '-' + point$2(pos && pos.end)
1901
1901
  }
1902
1902
 
1903
1903
  /**
1904
1904
  * @param {number | null | undefined} value
1905
1905
  * @returns {number}
1906
1906
  */
1907
- function index$3(value) {
1907
+ function index$1(value) {
1908
1908
  return value && typeof value === 'number' ? value : 1
1909
1909
  }
1910
1910
 
@@ -1918,7 +1918,7 @@ function index$3(value) {
1918
1918
  /**
1919
1919
  * Message.
1920
1920
  */
1921
- let VFileMessage$2 = class VFileMessage extends Error {
1921
+ let VFileMessage$1 = class VFileMessage extends Error {
1922
1922
  /**
1923
1923
  * Create a message for `reason`.
1924
1924
  *
@@ -2112,7 +2112,7 @@ let VFileMessage$2 = class VFileMessage extends Error {
2112
2112
  * On normal errors, this would be something like `ParseError`, buit in
2113
2113
  * `VFile` messages we use this space to show where an error happened.
2114
2114
  */
2115
- this.name = stringifyPosition$3(options.place) || '1:1';
2115
+ this.name = stringifyPosition$1(options.place) || '1:1';
2116
2116
 
2117
2117
  /**
2118
2118
  * Place of message.
@@ -2195,19 +2195,19 @@ let VFileMessage$2 = class VFileMessage extends Error {
2195
2195
  }
2196
2196
  };
2197
2197
 
2198
- VFileMessage$2.prototype.file = '';
2199
- VFileMessage$2.prototype.name = '';
2200
- VFileMessage$2.prototype.reason = '';
2201
- VFileMessage$2.prototype.message = '';
2202
- VFileMessage$2.prototype.stack = '';
2203
- VFileMessage$2.prototype.column = undefined;
2204
- VFileMessage$2.prototype.line = undefined;
2205
- VFileMessage$2.prototype.ancestors = undefined;
2206
- VFileMessage$2.prototype.cause = undefined;
2207
- VFileMessage$2.prototype.fatal = undefined;
2208
- VFileMessage$2.prototype.place = undefined;
2209
- VFileMessage$2.prototype.ruleId = undefined;
2210
- VFileMessage$2.prototype.source = undefined;
2198
+ VFileMessage$1.prototype.file = '';
2199
+ VFileMessage$1.prototype.name = '';
2200
+ VFileMessage$1.prototype.reason = '';
2201
+ VFileMessage$1.prototype.message = '';
2202
+ VFileMessage$1.prototype.stack = '';
2203
+ VFileMessage$1.prototype.column = undefined;
2204
+ VFileMessage$1.prototype.line = undefined;
2205
+ VFileMessage$1.prototype.ancestors = undefined;
2206
+ VFileMessage$1.prototype.cause = undefined;
2207
+ VFileMessage$1.prototype.fatal = undefined;
2208
+ VFileMessage$1.prototype.place = undefined;
2209
+ VFileMessage$1.prototype.ruleId = undefined;
2210
+ VFileMessage$1.prototype.source = undefined;
2211
2211
 
2212
2212
  /**
2213
2213
  * @import {Identifier, Literal, MemberExpression} from 'estree'
@@ -2416,7 +2416,7 @@ function mdxExpression(state, node) {
2416
2416
  if (node.data && node.data.estree && state.evaluater) {
2417
2417
  const program = node.data.estree;
2418
2418
  const expression = program.body[0];
2419
- ok$1(expression.type === 'ExpressionStatement');
2419
+ ok$2(expression.type === 'ExpressionStatement');
2420
2420
 
2421
2421
  // Assume result is a child.
2422
2422
  return /** @type {Child | undefined} */ (
@@ -2683,11 +2683,11 @@ function createJsxElementProps(state, node) {
2683
2683
  if (attribute.data && attribute.data.estree && state.evaluater) {
2684
2684
  const program = attribute.data.estree;
2685
2685
  const expression = program.body[0];
2686
- ok$1(expression.type === 'ExpressionStatement');
2686
+ ok$2(expression.type === 'ExpressionStatement');
2687
2687
  const objectExpression = expression.expression;
2688
- ok$1(objectExpression.type === 'ObjectExpression');
2688
+ ok$2(objectExpression.type === 'ObjectExpression');
2689
2689
  const property = objectExpression.properties[0];
2690
- ok$1(property.type === 'SpreadElement');
2690
+ ok$2(property.type === 'SpreadElement');
2691
2691
 
2692
2692
  Object.assign(
2693
2693
  props,
@@ -2710,7 +2710,7 @@ function createJsxElementProps(state, node) {
2710
2710
  ) {
2711
2711
  const program = attribute.value.data.estree;
2712
2712
  const expression = program.body[0];
2713
- ok$1(expression.type === 'ExpressionStatement');
2713
+ ok$2(expression.type === 'ExpressionStatement');
2714
2714
  value = state.evaluater.evaluateExpression(expression.expression);
2715
2715
  } else {
2716
2716
  crashEstree(state, node.position);
@@ -2845,7 +2845,7 @@ function parseStyle(state, value) {
2845
2845
  } catch (error) {
2846
2846
  if (!state.ignoreInvalidStyle) {
2847
2847
  const cause = /** @type {Error} */ (error);
2848
- const message = new VFileMessage$2('Cannot parse `style` attribute', {
2848
+ const message = new VFileMessage$1('Cannot parse `style` attribute', {
2849
2849
  ancestors: state.ancestors,
2850
2850
  cause,
2851
2851
  ruleId: 'style',
@@ -2952,7 +2952,7 @@ function findComponentFromName(state, name$1, allowExpression) {
2952
2952
  * @returns {never}
2953
2953
  */
2954
2954
  function crashEstree(state, place) {
2955
- const message = new VFileMessage$2(
2955
+ const message = new VFileMessage$1(
2956
2956
  'Cannot handle MDX estrees without `createEvaluater`',
2957
2957
  {
2958
2958
  ancestors: state.ancestors,
@@ -3087,7 +3087,7 @@ const emptyOptions$1 = {};
3087
3087
  * Serialized `value`.
3088
3088
  */
3089
3089
  function toString$1(value, options) {
3090
- const settings = options || emptyOptions$1;
3090
+ const settings = emptyOptions$1;
3091
3091
  const includeImageAlt =
3092
3092
  typeof settings.includeImageAlt === 'boolean'
3093
3093
  ? settings.includeImageAlt
@@ -5580,7 +5580,7 @@ function normalizeIdentifier(value) {
5580
5580
  * @returns {boolean}
5581
5581
  * Whether it matches.
5582
5582
  */
5583
- const asciiAlpha = regexCheck(/[A-Za-z]/);
5583
+ const asciiAlpha = regexCheck$1(/[A-Za-z]/);
5584
5584
 
5585
5585
  /**
5586
5586
  * Check whether the character code represents an ASCII alphanumeric (`a`
@@ -5594,7 +5594,7 @@ const asciiAlpha = regexCheck(/[A-Za-z]/);
5594
5594
  * @returns {boolean}
5595
5595
  * Whether it matches.
5596
5596
  */
5597
- const asciiAlphanumeric = regexCheck(/[\dA-Za-z]/);
5597
+ const asciiAlphanumeric$1 = regexCheck$1(/[\dA-Za-z]/);
5598
5598
 
5599
5599
  /**
5600
5600
  * Check whether the character code represents an ASCII atext.
@@ -5617,7 +5617,7 @@ const asciiAlphanumeric = regexCheck(/[\dA-Za-z]/);
5617
5617
  * @returns {boolean}
5618
5618
  * Whether it matches.
5619
5619
  */
5620
- const asciiAtext = regexCheck(/[#-'*+\--9=?A-Z^-~]/);
5620
+ const asciiAtext = regexCheck$1(/[#-'*+\--9=?A-Z^-~]/);
5621
5621
 
5622
5622
  /**
5623
5623
  * Check whether a character code is an ASCII control character.
@@ -5649,7 +5649,7 @@ function asciiControl(code) {
5649
5649
  * @returns {boolean}
5650
5650
  * Whether it matches.
5651
5651
  */
5652
- const asciiDigit = regexCheck(/\d/);
5652
+ const asciiDigit = regexCheck$1(/\d/);
5653
5653
 
5654
5654
  /**
5655
5655
  * Check whether the character code represents an ASCII hex digit (`a` through
@@ -5669,7 +5669,7 @@ const asciiDigit = regexCheck(/\d/);
5669
5669
  * @returns {boolean}
5670
5670
  * Whether it matches.
5671
5671
  */
5672
- const asciiHexDigit = regexCheck(/[\dA-Fa-f]/);
5672
+ const asciiHexDigit = regexCheck$1(/[\dA-Fa-f]/);
5673
5673
 
5674
5674
  /**
5675
5675
  * Check whether the character code represents ASCII punctuation.
@@ -5684,7 +5684,7 @@ const asciiHexDigit = regexCheck(/[\dA-Fa-f]/);
5684
5684
  * @returns {boolean}
5685
5685
  * Whether it matches.
5686
5686
  */
5687
- const asciiPunctuation = regexCheck(/[!-/:-@[-`{-~]/);
5687
+ const asciiPunctuation = regexCheck$1(/[!-/:-@[-`{-~]/);
5688
5688
 
5689
5689
  /**
5690
5690
  * Check whether a character code is a markdown line ending.
@@ -5758,7 +5758,7 @@ function markdownSpace(code) {
5758
5758
  * @returns
5759
5759
  * Whether it matches.
5760
5760
  */
5761
- const unicodePunctuation = regexCheck(/\p{P}|\p{S}/u);
5761
+ const unicodePunctuation = regexCheck$1(/\p{P}|\p{S}/u);
5762
5762
 
5763
5763
  /**
5764
5764
  * Check whether the character code represents Unicode whitespace.
@@ -5780,7 +5780,7 @@ const unicodePunctuation = regexCheck(/\p{P}|\p{S}/u);
5780
5780
  * @returns
5781
5781
  * Whether it matches.
5782
5782
  */
5783
- const unicodeWhitespace = regexCheck(/\s/);
5783
+ const unicodeWhitespace = regexCheck$1(/\s/);
5784
5784
 
5785
5785
  /**
5786
5786
  * Create a code check from a regex.
@@ -5790,7 +5790,7 @@ const unicodeWhitespace = regexCheck(/\s/);
5790
5790
  * @returns {(code: Code) => boolean}
5791
5791
  * Check.
5792
5792
  */
5793
- function regexCheck(regex) {
5793
+ function regexCheck$1(regex) {
5794
5794
  return check;
5795
5795
 
5796
5796
  /**
@@ -5806,69 +5806,6 @@ function regexCheck(regex) {
5806
5806
  }
5807
5807
  }
5808
5808
 
5809
- /**
5810
- * Normalize a URL.
5811
- *
5812
- * Encode unsafe characters with percent-encoding, skipping already encoded
5813
- * sequences.
5814
- *
5815
- * @param {string} value
5816
- * URI to normalize.
5817
- * @returns {string}
5818
- * Normalized URI.
5819
- */
5820
- function normalizeUri(value) {
5821
- /** @type {Array<string>} */
5822
- const result = [];
5823
- let index = -1;
5824
- let start = 0;
5825
- let skip = 0;
5826
- while (++index < value.length) {
5827
- const code = value.charCodeAt(index);
5828
- /** @type {string} */
5829
- let replace = '';
5830
-
5831
- // A correct percent encoded value.
5832
- if (code === 37 && asciiAlphanumeric(value.charCodeAt(index + 1)) && asciiAlphanumeric(value.charCodeAt(index + 2))) {
5833
- skip = 2;
5834
- }
5835
- // ASCII.
5836
- else if (code < 128) {
5837
- if (!/[!#$&-;=?-Z_a-z~]/.test(String.fromCharCode(code))) {
5838
- replace = String.fromCharCode(code);
5839
- }
5840
- }
5841
- // Astral.
5842
- else if (code > 55_295 && code < 57_344) {
5843
- const next = value.charCodeAt(index + 1);
5844
-
5845
- // A correct surrogate pair.
5846
- if (code < 56_320 && next > 56_319 && next < 57_344) {
5847
- replace = String.fromCharCode(code, next);
5848
- skip = 1;
5849
- }
5850
- // Lone surrogate.
5851
- else {
5852
- replace = "\uFFFD";
5853
- }
5854
- }
5855
- // Unicode.
5856
- else {
5857
- replace = String.fromCharCode(code);
5858
- }
5859
- if (replace) {
5860
- result.push(value.slice(start, index), encodeURIComponent(replace));
5861
- start = index + skip + 1;
5862
- replace = '';
5863
- }
5864
- if (skip) {
5865
- index += skip;
5866
- skip = 0;
5867
- }
5868
- }
5869
- return result.join('') + value.slice(start);
5870
- }
5871
-
5872
5809
  /**
5873
5810
  * @import {Effects, State, TokenType} from 'micromark-util-types'
5874
5811
  */
@@ -6747,7 +6684,7 @@ function tokenizeAutolink(effects, ok, nok) {
6747
6684
  */
6748
6685
  function schemeOrEmailAtext(code) {
6749
6686
  // ASCII alphanumeric and `+`, `-`, and `.`.
6750
- if (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) {
6687
+ if (code === 43 || code === 45 || code === 46 || asciiAlphanumeric$1(code)) {
6751
6688
  // Count the previous alphabetical from `open` too.
6752
6689
  size = 1;
6753
6690
  return schemeInsideOrEmailAtext(code);
@@ -6775,7 +6712,7 @@ function tokenizeAutolink(effects, ok, nok) {
6775
6712
  }
6776
6713
 
6777
6714
  // ASCII alphanumeric and `+`, `-`, and `.`.
6778
- if ((code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) && size++ < 32) {
6715
+ if ((code === 43 || code === 45 || code === 46 || asciiAlphanumeric$1(code)) && size++ < 32) {
6779
6716
  effects.consume(code);
6780
6717
  return schemeInsideOrEmailAtext;
6781
6718
  }
@@ -6844,7 +6781,7 @@ function tokenizeAutolink(effects, ok, nok) {
6844
6781
  * @type {State}
6845
6782
  */
6846
6783
  function emailAtSignOrDot(code) {
6847
- return asciiAlphanumeric(code) ? emailLabel(code) : nok(code);
6784
+ return asciiAlphanumeric$1(code) ? emailLabel(code) : nok(code);
6848
6785
  }
6849
6786
 
6850
6787
  /**
@@ -6889,7 +6826,7 @@ function tokenizeAutolink(effects, ok, nok) {
6889
6826
  */
6890
6827
  function emailValue(code) {
6891
6828
  // ASCII alphanumeric or `-`.
6892
- if ((code === 45 || asciiAlphanumeric(code)) && size++ < 63) {
6829
+ if ((code === 45 || asciiAlphanumeric$1(code)) && size++ < 63) {
6893
6830
  const next = code === 45 ? emailValue : emailLabel;
6894
6831
  effects.consume(code);
6895
6832
  return next;
@@ -7240,7 +7177,7 @@ function tokenizeCharacterReference(effects, ok, nok) {
7240
7177
  }
7241
7178
  effects.enter("characterReferenceValue");
7242
7179
  max = 31;
7243
- test = asciiAlphanumeric;
7180
+ test = asciiAlphanumeric$1;
7244
7181
  return value(code);
7245
7182
  }
7246
7183
 
@@ -7292,7 +7229,7 @@ function tokenizeCharacterReference(effects, ok, nok) {
7292
7229
  function value(code) {
7293
7230
  if (code === 59 && size) {
7294
7231
  const token = effects.exit("characterReferenceValue");
7295
- if (test === asciiAlphanumeric && !decodeNamedCharacterReference(self.sliceSerialize(token))) {
7232
+ if (test === asciiAlphanumeric$1 && !decodeNamedCharacterReference(self.sliceSerialize(token))) {
7296
7233
  return nok(code);
7297
7234
  }
7298
7235
 
@@ -10241,7 +10178,7 @@ function tokenizeHtmlFlow(effects, ok, nok) {
10241
10178
  }
10242
10179
 
10243
10180
  // ASCII alphanumerical and `-`.
10244
- if (code === 45 || asciiAlphanumeric(code)) {
10181
+ if (code === 45 || asciiAlphanumeric$1(code)) {
10245
10182
  effects.consume(code);
10246
10183
  buffer += String.fromCharCode(code);
10247
10184
  return tagName;
@@ -10344,7 +10281,7 @@ function tokenizeHtmlFlow(effects, ok, nok) {
10344
10281
  */
10345
10282
  function completeAttributeName(code) {
10346
10283
  // ASCII alphanumerical and `-`, `.`, `:`, and `_`.
10347
- if (code === 45 || code === 46 || code === 58 || code === 95 || asciiAlphanumeric(code)) {
10284
+ if (code === 45 || code === 46 || code === 58 || code === 95 || asciiAlphanumeric$1(code)) {
10348
10285
  effects.consume(code);
10349
10286
  return completeAttributeName;
10350
10287
  }
@@ -11197,7 +11134,7 @@ function tokenizeHtmlText(effects, ok, nok) {
11197
11134
  */
11198
11135
  function tagClose(code) {
11199
11136
  // ASCII alphanumerical and `-`.
11200
- if (code === 45 || asciiAlphanumeric(code)) {
11137
+ if (code === 45 || asciiAlphanumeric$1(code)) {
11201
11138
  effects.consume(code);
11202
11139
  return tagClose;
11203
11140
  }
@@ -11238,7 +11175,7 @@ function tokenizeHtmlText(effects, ok, nok) {
11238
11175
  */
11239
11176
  function tagOpen(code) {
11240
11177
  // ASCII alphanumerical and `-`.
11241
- if (code === 45 || asciiAlphanumeric(code)) {
11178
+ if (code === 45 || asciiAlphanumeric$1(code)) {
11242
11179
  effects.consume(code);
11243
11180
  return tagOpen;
11244
11181
  }
@@ -11292,7 +11229,7 @@ function tokenizeHtmlText(effects, ok, nok) {
11292
11229
  */
11293
11230
  function tagOpenAttributeName(code) {
11294
11231
  // ASCII alphabetical and `-`, `.`, `:`, and `_`.
11295
- if (code === 45 || code === 46 || code === 58 || code === 95 || asciiAlphanumeric(code)) {
11232
+ if (code === 45 || code === 46 || code === 58 || code === 95 || asciiAlphanumeric$1(code)) {
11296
11233
  effects.consume(code);
11297
11234
  return tagOpenAttributeName;
11298
11235
  }
@@ -13941,7 +13878,7 @@ function decode($0, $1, $2) {
13941
13878
  * An empty string (`''`) is returned if the given value is neither `node`,
13942
13879
  * `position`, nor `point`.
13943
13880
  */
13944
- function stringifyPosition$2(value) {
13881
+ function stringifyPosition(value) {
13945
13882
  // Nothing.
13946
13883
  if (!value || typeof value !== 'object') {
13947
13884
  return ''
@@ -13949,17 +13886,17 @@ function stringifyPosition$2(value) {
13949
13886
 
13950
13887
  // Node.
13951
13888
  if ('position' in value || 'type' in value) {
13952
- return position$2(value.position)
13889
+ return position(value.position)
13953
13890
  }
13954
13891
 
13955
13892
  // Position.
13956
13893
  if ('start' in value || 'end' in value) {
13957
- return position$2(value)
13894
+ return position(value)
13958
13895
  }
13959
13896
 
13960
13897
  // Point.
13961
13898
  if ('line' in value || 'column' in value) {
13962
- return point$3(value)
13899
+ return point$1(value)
13963
13900
  }
13964
13901
 
13965
13902
  // ?
@@ -13970,23 +13907,23 @@ function stringifyPosition$2(value) {
13970
13907
  * @param {Point | PointLike | null | undefined} point
13971
13908
  * @returns {string}
13972
13909
  */
13973
- function point$3(point) {
13974
- return index$2(point && point.line) + ':' + index$2(point && point.column)
13910
+ function point$1(point) {
13911
+ return index(point && point.line) + ':' + index(point && point.column)
13975
13912
  }
13976
13913
 
13977
13914
  /**
13978
13915
  * @param {Position | PositionLike | null | undefined} pos
13979
13916
  * @returns {string}
13980
13917
  */
13981
- function position$2(pos) {
13982
- return point$3(pos && pos.start) + '-' + point$3(pos && pos.end)
13918
+ function position(pos) {
13919
+ return point$1(pos && pos.start) + '-' + point$1(pos && pos.end)
13983
13920
  }
13984
13921
 
13985
13922
  /**
13986
13923
  * @param {number | null | undefined} value
13987
13924
  * @returns {number}
13988
13925
  */
13989
- function index$2(value) {
13926
+ function index(value) {
13990
13927
  return value && typeof value === 'number' ? value : 1
13991
13928
  }
13992
13929
 
@@ -14234,12 +14171,12 @@ function compiler(options) {
14234
14171
 
14235
14172
  // Figure out `root` position.
14236
14173
  tree.position = {
14237
- start: point$2(events.length > 0 ? events[0][1].start : {
14174
+ start: point(events.length > 0 ? events[0][1].start : {
14238
14175
  line: 1,
14239
14176
  column: 1,
14240
14177
  offset: 0
14241
14178
  }),
14242
- end: point$2(events.length > 0 ? events[events.length - 2][1].end : {
14179
+ end: point(events.length > 0 ? events[events.length - 2][1].end : {
14243
14180
  line: 1,
14244
14181
  column: 1,
14245
14182
  offset: 0
@@ -14409,7 +14346,7 @@ function compiler(options) {
14409
14346
  this.stack.push(node);
14410
14347
  this.tokenStack.push([token, errorHandler || undefined]);
14411
14348
  node.position = {
14412
- start: point$2(token.start),
14349
+ start: point(token.start),
14413
14350
  // @ts-expect-error: `end` will be patched later.
14414
14351
  end: undefined
14415
14352
  };
@@ -14444,7 +14381,7 @@ function compiler(options) {
14444
14381
  const node = this.stack.pop();
14445
14382
  const open = this.tokenStack.pop();
14446
14383
  if (!open) {
14447
- throw new Error('Cannot close `' + token.type + '` (' + stringifyPosition$2({
14384
+ throw new Error('Cannot close `' + token.type + '` (' + stringifyPosition({
14448
14385
  start: token.start,
14449
14386
  end: token.end
14450
14387
  }) + '): it’s not open');
@@ -14456,7 +14393,7 @@ function compiler(options) {
14456
14393
  handler.call(this, token, open[0]);
14457
14394
  }
14458
14395
  }
14459
- node.position.end = point$2(token.end);
14396
+ node.position.end = point(token.end);
14460
14397
  }
14461
14398
 
14462
14399
  /**
@@ -14624,7 +14561,7 @@ function compiler(options) {
14624
14561
  // Add a new text node.
14625
14562
  tail = text();
14626
14563
  tail.position = {
14627
- start: point$2(token.start),
14564
+ start: point(token.start),
14628
14565
  // @ts-expect-error: we’ll add `end` later.
14629
14566
  end: undefined
14630
14567
  };
@@ -14641,7 +14578,7 @@ function compiler(options) {
14641
14578
  function onexitdata(token) {
14642
14579
  const tail = this.stack.pop();
14643
14580
  tail.value += this.sliceSerialize(token);
14644
- tail.position.end = point$2(token.end);
14581
+ tail.position.end = point(token.end);
14645
14582
  }
14646
14583
 
14647
14584
  /**
@@ -14654,7 +14591,7 @@ function compiler(options) {
14654
14591
  // If we’re at a hard break, include the line ending in there.
14655
14592
  if (this.data.atHardBreak) {
14656
14593
  const tail = context.children[context.children.length - 1];
14657
- tail.position.end = point$2(token.end);
14594
+ tail.position.end = point(token.end);
14658
14595
  this.data.atHardBreak = undefined;
14659
14596
  return;
14660
14597
  }
@@ -14890,7 +14827,7 @@ function compiler(options) {
14890
14827
  */
14891
14828
  function onexitcharacterreference(token) {
14892
14829
  const tail = this.stack.pop();
14893
- tail.position.end = point$2(token.end);
14830
+ tail.position.end = point(token.end);
14894
14831
  }
14895
14832
 
14896
14833
  /**
@@ -15074,7 +15011,7 @@ function compiler(options) {
15074
15011
  * @returns {Point}
15075
15012
  * unist point.
15076
15013
  */
15077
- function point$2(d) {
15014
+ function point(d) {
15078
15015
  return {
15079
15016
  line: d.line,
15080
15017
  column: d.column,
@@ -15144,15 +15081,15 @@ function extension(combined, extension) {
15144
15081
  /** @type {OnEnterError} */
15145
15082
  function defaultOnError(left, right) {
15146
15083
  if (left) {
15147
- throw new Error('Cannot close `' + left.type + '` (' + stringifyPosition$2({
15084
+ throw new Error('Cannot close `' + left.type + '` (' + stringifyPosition({
15148
15085
  start: left.start,
15149
15086
  end: left.end
15150
- }) + '): a different token (`' + right.type + '`, ' + stringifyPosition$2({
15087
+ }) + '): a different token (`' + right.type + '`, ' + stringifyPosition({
15151
15088
  start: right.start,
15152
15089
  end: right.end
15153
15090
  }) + ') is open');
15154
15091
  } else {
15155
- throw new Error('Cannot close document, a token (`' + right.type + '`, ' + stringifyPosition$2({
15092
+ throw new Error('Cannot close document, a token (`' + right.type + '`, ' + stringifyPosition({
15156
15093
  start: right.start,
15157
15094
  end: right.end
15158
15095
  }) + ') is still open');
@@ -15359,6 +15296,114 @@ function emphasis(state, node) {
15359
15296
  return state.applyData(node, result)
15360
15297
  }
15361
15298
 
15299
+ /**
15300
+ * @typedef {import('micromark-util-types').Code} Code
15301
+ */
15302
+
15303
+
15304
+ /**
15305
+ * Check whether the character code represents an ASCII alphanumeric (`a`
15306
+ * through `z`, case insensitive, or `0` through `9`).
15307
+ *
15308
+ * An **ASCII alphanumeric** is an ASCII digit (see `asciiDigit`) or ASCII alpha
15309
+ * (see `asciiAlpha`).
15310
+ *
15311
+ * @param code
15312
+ * Code.
15313
+ * @returns {boolean}
15314
+ * Whether it matches.
15315
+ */
15316
+ const asciiAlphanumeric = regexCheck(/[\dA-Za-z]/);
15317
+
15318
+ /**
15319
+ * Create a code check from a regex.
15320
+ *
15321
+ * @param {RegExp} regex
15322
+ * @returns {(code: Code) => boolean}
15323
+ */
15324
+ function regexCheck(regex) {
15325
+ return check;
15326
+
15327
+ /**
15328
+ * Check whether a code matches the bound regex.
15329
+ *
15330
+ * @param {Code} code
15331
+ * Character code.
15332
+ * @returns {boolean}
15333
+ * Whether the character code matches the bound regex.
15334
+ */
15335
+ function check(code) {
15336
+ return code !== null && code > -1 && regex.test(String.fromCharCode(code));
15337
+ }
15338
+ }
15339
+
15340
+ /**
15341
+ * Normalize a URL.
15342
+ *
15343
+ * Encode unsafe characters with percent-encoding, skipping already encoded
15344
+ * sequences.
15345
+ *
15346
+ * @param {string} value
15347
+ * URI to normalize.
15348
+ * @returns {string}
15349
+ * Normalized URI.
15350
+ */
15351
+ function normalizeUri(value) {
15352
+ /** @type {Array<string>} */
15353
+ const result = [];
15354
+ let index = -1;
15355
+ let start = 0;
15356
+ let skip = 0;
15357
+ while (++index < value.length) {
15358
+ const code = value.charCodeAt(index);
15359
+ /** @type {string} */
15360
+ let replace = '';
15361
+
15362
+ // A correct percent encoded value.
15363
+ if (
15364
+ code === 37 &&
15365
+ asciiAlphanumeric(value.charCodeAt(index + 1)) &&
15366
+ asciiAlphanumeric(value.charCodeAt(index + 2))
15367
+ ) {
15368
+ skip = 2;
15369
+ }
15370
+ // ASCII.
15371
+ else if (code < 128) {
15372
+ if (!/[!#$&-;=?-Z_a-z~]/.test(String.fromCharCode(code))) {
15373
+ replace = String.fromCharCode(code);
15374
+ }
15375
+ }
15376
+ // Astral.
15377
+ else if (code > 55_295 && code < 57_344) {
15378
+ const next = value.charCodeAt(index + 1);
15379
+
15380
+ // A correct surrogate pair.
15381
+ if (code < 56_320 && next > 56_319 && next < 57_344) {
15382
+ replace = String.fromCharCode(code, next);
15383
+ skip = 1;
15384
+ }
15385
+ // Lone surrogate.
15386
+ else {
15387
+ replace = '\uFFFD';
15388
+ }
15389
+ }
15390
+ // Unicode.
15391
+ else {
15392
+ replace = String.fromCharCode(code);
15393
+ }
15394
+ if (replace) {
15395
+ result.push(value.slice(start, index), encodeURIComponent(replace));
15396
+ start = index + skip + 1;
15397
+ replace = '';
15398
+ }
15399
+ if (skip) {
15400
+ index += skip;
15401
+ skip = 0;
15402
+ }
15403
+ }
15404
+ return result.join('') + value.slice(start)
15405
+ }
15406
+
15362
15407
  /**
15363
15408
  * @typedef {import('hast').Element} Element
15364
15409
  * @typedef {import('mdast').FootnoteReference} FootnoteReference
@@ -16797,7 +16842,7 @@ function footer(state) {
16797
16842
  * @returns {Check}
16798
16843
  * An assertion.
16799
16844
  */
16800
- const convert =
16845
+ const convert$1 =
16801
16846
  // Note: overloads in JSDoc can’t yet use different `@template`s.
16802
16847
  /**
16803
16848
  * @type {(
@@ -16815,19 +16860,19 @@ const convert =
16815
16860
  */
16816
16861
  function (test) {
16817
16862
  if (test === null || test === undefined) {
16818
- return ok
16863
+ return ok$1
16819
16864
  }
16820
16865
 
16821
16866
  if (typeof test === 'function') {
16822
- return castFactory(test)
16867
+ return castFactory$1(test)
16823
16868
  }
16824
16869
 
16825
16870
  if (typeof test === 'object') {
16826
- return Array.isArray(test) ? anyFactory(test) : propsFactory(test)
16871
+ return Array.isArray(test) ? anyFactory$1(test) : propsFactory$1(test)
16827
16872
  }
16828
16873
 
16829
16874
  if (typeof test === 'string') {
16830
- return typeFactory(test)
16875
+ return typeFactory$1(test)
16831
16876
  }
16832
16877
 
16833
16878
  throw new Error('Expected function, string, or object as test')
@@ -16838,16 +16883,16 @@ const convert =
16838
16883
  * @param {Array<Props | TestFunction | string>} tests
16839
16884
  * @returns {Check}
16840
16885
  */
16841
- function anyFactory(tests) {
16886
+ function anyFactory$1(tests) {
16842
16887
  /** @type {Array<Check>} */
16843
16888
  const checks = [];
16844
16889
  let index = -1;
16845
16890
 
16846
16891
  while (++index < tests.length) {
16847
- checks[index] = convert(tests[index]);
16892
+ checks[index] = convert$1(tests[index]);
16848
16893
  }
16849
16894
 
16850
- return castFactory(any)
16895
+ return castFactory$1(any)
16851
16896
 
16852
16897
  /**
16853
16898
  * @this {unknown}
@@ -16870,10 +16915,10 @@ function anyFactory(tests) {
16870
16915
  * @param {Props} check
16871
16916
  * @returns {Check}
16872
16917
  */
16873
- function propsFactory(check) {
16918
+ function propsFactory$1(check) {
16874
16919
  const checkAsRecord = /** @type {Record<string, unknown>} */ (check);
16875
16920
 
16876
- return castFactory(all)
16921
+ return castFactory$1(all)
16877
16922
 
16878
16923
  /**
16879
16924
  * @param {Node} node
@@ -16901,8 +16946,8 @@ function propsFactory(check) {
16901
16946
  * @param {string} check
16902
16947
  * @returns {Check}
16903
16948
  */
16904
- function typeFactory(check) {
16905
- return castFactory(type)
16949
+ function typeFactory$1(check) {
16950
+ return castFactory$1(type)
16906
16951
 
16907
16952
  /**
16908
16953
  * @param {Node} node
@@ -16918,7 +16963,7 @@ function typeFactory(check) {
16918
16963
  * @param {TestFunction} testFunction
16919
16964
  * @returns {Check}
16920
16965
  */
16921
- function castFactory(testFunction) {
16966
+ function castFactory$1(testFunction) {
16922
16967
  return check
16923
16968
 
16924
16969
  /**
@@ -16927,7 +16972,7 @@ function castFactory(testFunction) {
16927
16972
  */
16928
16973
  function check(value, index, parent) {
16929
16974
  return Boolean(
16930
- looksLikeANode(value) &&
16975
+ looksLikeANode$1(value) &&
16931
16976
  testFunction.call(
16932
16977
  this,
16933
16978
  value,
@@ -16938,7 +16983,7 @@ function castFactory(testFunction) {
16938
16983
  }
16939
16984
  }
16940
16985
 
16941
- function ok() {
16986
+ function ok$1() {
16942
16987
  return true
16943
16988
  }
16944
16989
 
@@ -16946,7 +16991,7 @@ function ok() {
16946
16991
  * @param {unknown} value
16947
16992
  * @returns {value is Node}
16948
16993
  */
16949
- function looksLikeANode(value) {
16994
+ function looksLikeANode$1(value) {
16950
16995
  return value !== null && typeof value === 'object' && 'type' in value
16951
16996
  }
16952
16997
 
@@ -16954,7 +16999,7 @@ function looksLikeANode(value) {
16954
16999
  * @param {string} d
16955
17000
  * @returns {string}
16956
17001
  */
16957
- function color(d) {
17002
+ function color$1(d) {
16958
17003
  return d
16959
17004
  }
16960
17005
 
@@ -16965,22 +17010,22 @@ function color(d) {
16965
17010
 
16966
17011
 
16967
17012
  /** @type {Readonly<ActionTuple>} */
16968
- const empty = [];
17013
+ const empty$1 = [];
16969
17014
 
16970
17015
  /**
16971
17016
  * Continue traversing as normal.
16972
17017
  */
16973
- const CONTINUE = true;
17018
+ const CONTINUE$1 = true;
16974
17019
 
16975
17020
  /**
16976
17021
  * Stop traversing immediately.
16977
17022
  */
16978
- const EXIT = false;
17023
+ const EXIT$1 = false;
16979
17024
 
16980
17025
  /**
16981
17026
  * Do not traverse this node’s children.
16982
17027
  */
16983
- const SKIP = 'skip';
17028
+ const SKIP$1 = 'skip';
16984
17029
 
16985
17030
  /**
16986
17031
  * Visit nodes, with ancestral information.
@@ -17029,7 +17074,7 @@ const SKIP = 'skip';
17029
17074
  * @template {Test} Check
17030
17075
  * `unist-util-is`-compatible test.
17031
17076
  */
17032
- function visitParents(tree, test, visitor, reverse) {
17077
+ function visitParents$1(tree, test, visitor, reverse) {
17033
17078
  /** @type {Test} */
17034
17079
  let check;
17035
17080
 
@@ -17042,7 +17087,7 @@ function visitParents(tree, test, visitor, reverse) {
17042
17087
  check = test;
17043
17088
  }
17044
17089
 
17045
- const is = convert(check);
17090
+ const is = convert$1(check);
17046
17091
  const step = reverse ? -1 : 1;
17047
17092
 
17048
17093
  factory(tree, undefined, [])();
@@ -17069,7 +17114,7 @@ function visitParents(tree, test, visitor, reverse) {
17069
17114
 
17070
17115
  Object.defineProperty(visit, 'name', {
17071
17116
  value:
17072
- 'node (' + color(node.type + (name ? '<' + name + '>' : '')) + ')'
17117
+ 'node (' + color$1(node.type + (name ? '<' + name + '>' : '')) + ')'
17073
17118
  });
17074
17119
  }
17075
17120
 
@@ -17077,7 +17122,7 @@ function visitParents(tree, test, visitor, reverse) {
17077
17122
 
17078
17123
  function visit() {
17079
17124
  /** @type {Readonly<ActionTuple>} */
17080
- let result = empty;
17125
+ let result = empty$1;
17081
17126
  /** @type {Readonly<ActionTuple>} */
17082
17127
  let subresult;
17083
17128
  /** @type {number} */
@@ -17087,9 +17132,9 @@ function visitParents(tree, test, visitor, reverse) {
17087
17132
 
17088
17133
  if (!test || is(node, index, parents[parents.length - 1] || undefined)) {
17089
17134
  // @ts-expect-error: `visitor` is now a visitor.
17090
- result = toResult(visitor(node, parents));
17135
+ result = toResult$1(visitor(node, parents));
17091
17136
 
17092
- if (result[0] === EXIT) {
17137
+ if (result[0] === EXIT$1) {
17093
17138
  return result
17094
17139
  }
17095
17140
  }
@@ -17097,7 +17142,7 @@ function visitParents(tree, test, visitor, reverse) {
17097
17142
  if ('children' in node && node.children) {
17098
17143
  const nodeAsParent = /** @type {UnistParent} */ (node);
17099
17144
 
17100
- if (nodeAsParent.children && result[0] !== SKIP) {
17145
+ if (nodeAsParent.children && result[0] !== SKIP$1) {
17101
17146
  offset = (reverse ? nodeAsParent.children.length : -1) + step;
17102
17147
  grandparents = parents.concat(nodeAsParent);
17103
17148
 
@@ -17106,7 +17151,7 @@ function visitParents(tree, test, visitor, reverse) {
17106
17151
 
17107
17152
  subresult = factory(child, offset, grandparents)();
17108
17153
 
17109
- if (subresult[0] === EXIT) {
17154
+ if (subresult[0] === EXIT$1) {
17110
17155
  return subresult
17111
17156
  }
17112
17157
 
@@ -17129,16 +17174,16 @@ function visitParents(tree, test, visitor, reverse) {
17129
17174
  * @returns {Readonly<ActionTuple>}
17130
17175
  * Clean result.
17131
17176
  */
17132
- function toResult(value) {
17177
+ function toResult$1(value) {
17133
17178
  if (Array.isArray(value)) {
17134
17179
  return value
17135
17180
  }
17136
17181
 
17137
17182
  if (typeof value === 'number') {
17138
- return [CONTINUE, value]
17183
+ return [CONTINUE$1, value]
17139
17184
  }
17140
17185
 
17141
- return value === null || value === undefined ? empty : [value]
17186
+ return value === null || value === undefined ? empty$1 : [value]
17142
17187
  }
17143
17188
 
17144
17189
  /**
@@ -17195,7 +17240,7 @@ function toResult(value) {
17195
17240
  * @template {Test} Check
17196
17241
  * `unist-util-is`-compatible test.
17197
17242
  */
17198
- function visit(tree, testOrVisitor, visitorOrReverse, maybeReverse) {
17243
+ function visit$1(tree, testOrVisitor, visitorOrReverse, maybeReverse) {
17199
17244
  /** @type {boolean | null | undefined} */
17200
17245
  let reverse;
17201
17246
  /** @type {Test} */
@@ -17218,7 +17263,7 @@ function visit(tree, testOrVisitor, visitorOrReverse, maybeReverse) {
17218
17263
  reverse = maybeReverse;
17219
17264
  }
17220
17265
 
17221
- visitParents(tree, test, overload, reverse);
17266
+ visitParents$1(tree, test, overload, reverse);
17222
17267
 
17223
17268
  /**
17224
17269
  * @param {UnistNode} node
@@ -17294,7 +17339,7 @@ function createState(tree, options) {
17294
17339
  wrap: wrap$1
17295
17340
  };
17296
17341
 
17297
- visit(tree, function (node) {
17342
+ visit$1(tree, function (node) {
17298
17343
  if (node.type === 'definition' || node.type === 'footnoteDefinition') {
17299
17344
  const map = node.type === 'definition' ? definitionById : footnoteById;
17300
17345
  const id = String(node.identifier).toUpperCase();
@@ -17405,7 +17450,7 @@ function createState(tree, options) {
17405
17450
  * Nothing.
17406
17451
  */
17407
17452
  function patch(from, to) {
17408
- if (from.position) to.position = position$4(from);
17453
+ if (from.position) to.position = position$2(from);
17409
17454
  }
17410
17455
 
17411
17456
  /**
@@ -18142,99 +18187,14 @@ function wrap(middleware, callback) {
18142
18187
  }
18143
18188
 
18144
18189
  /**
18145
- * @typedef {import('unist').Node} Node
18146
- * @typedef {import('unist').Point} Point
18147
- * @typedef {import('unist').Position} Position
18148
- */
18149
-
18150
- /**
18151
- * @typedef NodeLike
18152
- * @property {string} type
18153
- * @property {PositionLike | null | undefined} [position]
18154
- *
18155
- * @typedef PointLike
18156
- * @property {number | null | undefined} [line]
18157
- * @property {number | null | undefined} [column]
18158
- * @property {number | null | undefined} [offset]
18159
- *
18160
- * @typedef PositionLike
18161
- * @property {PointLike | null | undefined} [start]
18162
- * @property {PointLike | null | undefined} [end]
18163
- */
18164
-
18165
- /**
18166
- * Serialize the positional info of a point, position (start and end points),
18167
- * or node.
18168
- *
18169
- * @param {Node | NodeLike | Point | PointLike | Position | PositionLike | null | undefined} [value]
18170
- * Node, position, or point.
18171
- * @returns {string}
18172
- * Pretty printed positional info of a node (`string`).
18173
- *
18174
- * In the format of a range `ls:cs-le:ce` (when given `node` or `position`)
18175
- * or a point `l:c` (when given `point`), where `l` stands for line, `c` for
18176
- * column, `s` for `start`, and `e` for end.
18177
- * An empty string (`''`) is returned if the given value is neither `node`,
18178
- * `position`, nor `point`.
18179
- */
18180
- function stringifyPosition$1(value) {
18181
- // Nothing.
18182
- if (!value || typeof value !== 'object') {
18183
- return ''
18184
- }
18185
-
18186
- // Node.
18187
- if ('position' in value || 'type' in value) {
18188
- return position$1(value.position)
18189
- }
18190
-
18191
- // Position.
18192
- if ('start' in value || 'end' in value) {
18193
- return position$1(value)
18194
- }
18195
-
18196
- // Point.
18197
- if ('line' in value || 'column' in value) {
18198
- return point$1(value)
18199
- }
18200
-
18201
- // ?
18202
- return ''
18203
- }
18204
-
18205
- /**
18206
- * @param {Point | PointLike | null | undefined} point
18207
- * @returns {string}
18208
- */
18209
- function point$1(point) {
18210
- return index$1(point && point.line) + ':' + index$1(point && point.column)
18211
- }
18212
-
18213
- /**
18214
- * @param {Position | PositionLike | null | undefined} pos
18215
- * @returns {string}
18216
- */
18217
- function position$1(pos) {
18218
- return point$1(pos && pos.start) + '-' + point$1(pos && pos.end)
18219
- }
18220
-
18221
- /**
18222
- * @param {number | null | undefined} value
18223
- * @returns {number}
18224
- */
18225
- function index$1(value) {
18226
- return value && typeof value === 'number' ? value : 1
18227
- }
18228
-
18229
- /**
18230
- * @import {Node, Point, Position} from 'unist'
18190
+ * @import {Node, Point, Position} from 'unist'
18231
18191
  */
18232
18192
 
18233
18193
 
18234
18194
  /**
18235
18195
  * Message.
18236
18196
  */
18237
- let VFileMessage$1 = class VFileMessage extends Error {
18197
+ class VFileMessage extends Error {
18238
18198
  /**
18239
18199
  * Create a message for `reason`.
18240
18200
  *
@@ -18427,7 +18387,7 @@ let VFileMessage$1 = class VFileMessage extends Error {
18427
18387
  * On normal errors, this would be something like `ParseError`, buit in
18428
18388
  * `VFile` messages we use this space to show where an error happened.
18429
18389
  */
18430
- this.name = stringifyPosition$1(options.place) || '1:1';
18390
+ this.name = stringifyPosition(options.place) || '1:1';
18431
18391
 
18432
18392
  /**
18433
18393
  * Place of message.
@@ -18507,21 +18467,21 @@ let VFileMessage$1 = class VFileMessage extends Error {
18507
18467
  */
18508
18468
  this.url = undefined;
18509
18469
  }
18510
- };
18470
+ }
18511
18471
 
18512
- VFileMessage$1.prototype.file = '';
18513
- VFileMessage$1.prototype.name = '';
18514
- VFileMessage$1.prototype.reason = '';
18515
- VFileMessage$1.prototype.message = '';
18516
- VFileMessage$1.prototype.stack = '';
18517
- VFileMessage$1.prototype.column = undefined;
18518
- VFileMessage$1.prototype.line = undefined;
18519
- VFileMessage$1.prototype.ancestors = undefined;
18520
- VFileMessage$1.prototype.cause = undefined;
18521
- VFileMessage$1.prototype.fatal = undefined;
18522
- VFileMessage$1.prototype.place = undefined;
18523
- VFileMessage$1.prototype.ruleId = undefined;
18524
- VFileMessage$1.prototype.source = undefined;
18472
+ VFileMessage.prototype.file = '';
18473
+ VFileMessage.prototype.name = '';
18474
+ VFileMessage.prototype.reason = '';
18475
+ VFileMessage.prototype.message = '';
18476
+ VFileMessage.prototype.stack = '';
18477
+ VFileMessage.prototype.column = undefined;
18478
+ VFileMessage.prototype.line = undefined;
18479
+ VFileMessage.prototype.ancestors = undefined;
18480
+ VFileMessage.prototype.cause = undefined;
18481
+ VFileMessage.prototype.fatal = undefined;
18482
+ VFileMessage.prototype.place = undefined;
18483
+ VFileMessage.prototype.ruleId = undefined;
18484
+ VFileMessage.prototype.source = undefined;
18525
18485
 
18526
18486
  // A derivative work based on:
18527
18487
  // <https://github.com/browserify/path-browserify>.
@@ -18574,7 +18534,7 @@ VFileMessage$1.prototype.source = undefined;
18574
18534
  // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
18575
18535
  // USE OR OTHER DEALINGS IN THE SOFTWARE.
18576
18536
 
18577
- const minpath$1 = {basename: basename$1, dirname: dirname$1, extname: extname$1, join: join$1, sep: '/'};
18537
+ const minpath = {basename, dirname, extname, join, sep: '/'};
18578
18538
 
18579
18539
  /* eslint-disable max-depth, complexity */
18580
18540
 
@@ -18588,12 +18548,12 @@ const minpath$1 = {basename: basename$1, dirname: dirname$1, extname: extname$1,
18588
18548
  * @returns {string}
18589
18549
  * Stem or basename.
18590
18550
  */
18591
- function basename$1(path, extname) {
18551
+ function basename(path, extname) {
18592
18552
  if (extname !== undefined && typeof extname !== 'string') {
18593
18553
  throw new TypeError('"ext" argument must be a string')
18594
18554
  }
18595
18555
 
18596
- assertPath$3(path);
18556
+ assertPath$1(path);
18597
18557
  let start = 0;
18598
18558
  let end = -1;
18599
18559
  let index = path.length;
@@ -18682,8 +18642,8 @@ function basename$1(path, extname) {
18682
18642
  * @returns {string}
18683
18643
  * File path.
18684
18644
  */
18685
- function dirname$1(path) {
18686
- assertPath$3(path);
18645
+ function dirname(path) {
18646
+ assertPath$1(path);
18687
18647
 
18688
18648
  if (path.length === 0) {
18689
18649
  return '.'
@@ -18724,8 +18684,8 @@ function dirname$1(path) {
18724
18684
  * @returns {string}
18725
18685
  * Extname.
18726
18686
  */
18727
- function extname$1(path) {
18728
- assertPath$3(path);
18687
+ function extname(path) {
18688
+ assertPath$1(path);
18729
18689
 
18730
18690
  let index = path.length;
18731
18691
 
@@ -18795,13 +18755,13 @@ function extname$1(path) {
18795
18755
  * @returns {string}
18796
18756
  * File path.
18797
18757
  */
18798
- function join$1(...segments) {
18758
+ function join(...segments) {
18799
18759
  let index = -1;
18800
18760
  /** @type {string | undefined} */
18801
18761
  let joined;
18802
18762
 
18803
18763
  while (++index < segments.length) {
18804
- assertPath$3(segments[index]);
18764
+ assertPath$1(segments[index]);
18805
18765
 
18806
18766
  if (segments[index]) {
18807
18767
  joined =
@@ -18809,7 +18769,7 @@ function join$1(...segments) {
18809
18769
  }
18810
18770
  }
18811
18771
 
18812
- return joined === undefined ? '.' : normalize$1(joined)
18772
+ return joined === undefined ? '.' : normalize(joined)
18813
18773
  }
18814
18774
 
18815
18775
  /**
@@ -18822,13 +18782,13 @@ function join$1(...segments) {
18822
18782
  */
18823
18783
  // Note: `normalize` is not exposed as `path.normalize`, so some code is
18824
18784
  // manually removed from it.
18825
- function normalize$1(path) {
18826
- assertPath$3(path);
18785
+ function normalize(path) {
18786
+ assertPath$1(path);
18827
18787
 
18828
18788
  const absolute = path.codePointAt(0) === 47; /* `/` */
18829
18789
 
18830
18790
  // Normalize the path according to POSIX rules.
18831
- let value = normalizeString$1(path, !absolute);
18791
+ let value = normalizeString(path, !absolute);
18832
18792
 
18833
18793
  if (value.length === 0 && !absolute) {
18834
18794
  value = '.';
@@ -18851,7 +18811,7 @@ function normalize$1(path) {
18851
18811
  * @returns {string}
18852
18812
  * File path.
18853
18813
  */
18854
- function normalizeString$1(path, allowAboveRoot) {
18814
+ function normalizeString(path, allowAboveRoot) {
18855
18815
  let result = '';
18856
18816
  let lastSegmentLength = 0;
18857
18817
  let lastSlash = -1;
@@ -18938,7 +18898,7 @@ function normalizeString$1(path, allowAboveRoot) {
18938
18898
  * @returns {asserts path is string}
18939
18899
  * Nothing.
18940
18900
  */
18941
- function assertPath$3(path) {
18901
+ function assertPath$1(path) {
18942
18902
  if (typeof path !== 'string') {
18943
18903
  throw new TypeError(
18944
18904
  'Path must be a string. Received ' + JSON.stringify(path)
@@ -18951,9 +18911,9 @@ function assertPath$3(path) {
18951
18911
  // Somewhat based on:
18952
18912
  // <https://github.com/defunctzombie/node-process/blob/master/browser.js>.
18953
18913
  // But I don’t think one tiny line of code can be copyrighted. 😅
18954
- const minproc$1 = {cwd: cwd$1};
18914
+ const minproc = {cwd};
18955
18915
 
18956
- function cwd$1() {
18916
+ function cwd() {
18957
18917
  return '/'
18958
18918
  }
18959
18919
 
@@ -18976,7 +18936,7 @@ function cwd$1() {
18976
18936
  * Whether it’s a URL.
18977
18937
  */
18978
18938
  // From: <https://github.com/nodejs/node/blob/6a3403c/lib/internal/url.js#L720>
18979
- function isUrl$1(fileUrlOrPath) {
18939
+ function isUrl(fileUrlOrPath) {
18980
18940
  return Boolean(
18981
18941
  fileUrlOrPath !== null &&
18982
18942
  typeof fileUrlOrPath === 'object' &&
@@ -18997,10 +18957,10 @@ function isUrl$1(fileUrlOrPath) {
18997
18957
  * @returns {string}
18998
18958
  * File URL.
18999
18959
  */
19000
- function urlToPath$1(path) {
18960
+ function urlToPath(path) {
19001
18961
  if (typeof path === 'string') {
19002
18962
  path = new URL(path);
19003
- } else if (!isUrl$1(path)) {
18963
+ } else if (!isUrl(path)) {
19004
18964
  /** @type {NodeJS.ErrnoException} */
19005
18965
  const error = new TypeError(
19006
18966
  'The "path" argument must be of type string or an instance of URL. Received `' +
@@ -19018,7 +18978,7 @@ function urlToPath$1(path) {
19018
18978
  throw error
19019
18979
  }
19020
18980
 
19021
- return getPathFromURLPosix$1(path)
18981
+ return getPathFromURLPosix(path)
19022
18982
  }
19023
18983
 
19024
18984
  /**
@@ -19029,7 +18989,7 @@ function urlToPath$1(path) {
19029
18989
  * @returns {string}
19030
18990
  * File path.
19031
18991
  */
19032
- function getPathFromURLPosix$1(url) {
18992
+ function getPathFromURLPosix(url) {
19033
18993
  if (url.hostname !== '') {
19034
18994
  /** @type {NodeJS.ErrnoException} */
19035
18995
  const error = new TypeError(
@@ -19074,7 +19034,7 @@ function getPathFromURLPosix$1(url) {
19074
19034
  * `{stem: 'a', path: '~/b.js'}` would throw, as a path is needed before a
19075
19035
  * stem can be set.
19076
19036
  */
19077
- const order$1 = /** @type {const} */ ([
19037
+ const order = /** @type {const} */ ([
19078
19038
  'history',
19079
19039
  'path',
19080
19040
  'basename',
@@ -19083,7 +19043,7 @@ const order$1 = /** @type {const} */ ([
19083
19043
  'dirname'
19084
19044
  ]);
19085
19045
 
19086
- let VFile$1 = class VFile {
19046
+ class VFile {
19087
19047
  /**
19088
19048
  * Create a new virtual file.
19089
19049
  *
@@ -19112,9 +19072,9 @@ let VFile$1 = class VFile {
19112
19072
 
19113
19073
  if (!value) {
19114
19074
  options = {};
19115
- } else if (isUrl$1(value)) {
19075
+ } else if (isUrl(value)) {
19116
19076
  options = {path: value};
19117
- } else if (typeof value === 'string' || isUint8Array$2(value)) {
19077
+ } else if (typeof value === 'string' || isUint8Array$1(value)) {
19118
19078
  options = {value};
19119
19079
  } else {
19120
19080
  options = value;
@@ -19129,7 +19089,7 @@ let VFile$1 = class VFile {
19129
19089
  */
19130
19090
  // Prevent calling `cwd` (which could be expensive) if it’s not needed;
19131
19091
  // the empty string will be overridden in the next block.
19132
- this.cwd = 'cwd' in options ? '' : minproc$1.cwd();
19092
+ this.cwd = 'cwd' in options ? '' : minproc.cwd();
19133
19093
 
19134
19094
  /**
19135
19095
  * Place to store custom info (default: `{}`).
@@ -19199,8 +19159,8 @@ let VFile$1 = class VFile {
19199
19159
  // Set path related properties in the correct order.
19200
19160
  let index = -1;
19201
19161
 
19202
- while (++index < order$1.length) {
19203
- const field = order$1[index];
19162
+ while (++index < order.length) {
19163
+ const field = order[index];
19204
19164
 
19205
19165
  // Note: we specifically use `in` instead of `hasOwnProperty` to accept
19206
19166
  // `vfile`s too.
@@ -19220,7 +19180,7 @@ let VFile$1 = class VFile {
19220
19180
  // Set non-path related properties.
19221
19181
  for (field in options) {
19222
19182
  // @ts-expect-error: fine to set other things.
19223
- if (!order$1.includes(field)) {
19183
+ if (!order.includes(field)) {
19224
19184
  // @ts-expect-error: fine to set other things.
19225
19185
  this[field] = options[field];
19226
19186
  }
@@ -19235,7 +19195,7 @@ let VFile$1 = class VFile {
19235
19195
  */
19236
19196
  get basename() {
19237
19197
  return typeof this.path === 'string'
19238
- ? minpath$1.basename(this.path)
19198
+ ? minpath.basename(this.path)
19239
19199
  : undefined
19240
19200
  }
19241
19201
 
@@ -19252,9 +19212,9 @@ let VFile$1 = class VFile {
19252
19212
  * Nothing.
19253
19213
  */
19254
19214
  set basename(basename) {
19255
- assertNonEmpty$1(basename, 'basename');
19256
- assertPart$1(basename, 'basename');
19257
- this.path = minpath$1.join(this.dirname || '', basename);
19215
+ assertNonEmpty(basename, 'basename');
19216
+ assertPart(basename, 'basename');
19217
+ this.path = minpath.join(this.dirname || '', basename);
19258
19218
  }
19259
19219
 
19260
19220
  /**
@@ -19265,7 +19225,7 @@ let VFile$1 = class VFile {
19265
19225
  */
19266
19226
  get dirname() {
19267
19227
  return typeof this.path === 'string'
19268
- ? minpath$1.dirname(this.path)
19228
+ ? minpath.dirname(this.path)
19269
19229
  : undefined
19270
19230
  }
19271
19231
 
@@ -19280,8 +19240,8 @@ let VFile$1 = class VFile {
19280
19240
  * Nothing.
19281
19241
  */
19282
19242
  set dirname(dirname) {
19283
- assertPath$2(this.basename, 'dirname');
19284
- this.path = minpath$1.join(dirname || '', this.basename);
19243
+ assertPath(this.basename, 'dirname');
19244
+ this.path = minpath.join(dirname || '', this.basename);
19285
19245
  }
19286
19246
 
19287
19247
  /**
@@ -19292,7 +19252,7 @@ let VFile$1 = class VFile {
19292
19252
  */
19293
19253
  get extname() {
19294
19254
  return typeof this.path === 'string'
19295
- ? minpath$1.extname(this.path)
19255
+ ? minpath.extname(this.path)
19296
19256
  : undefined
19297
19257
  }
19298
19258
 
@@ -19309,8 +19269,8 @@ let VFile$1 = class VFile {
19309
19269
  * Nothing.
19310
19270
  */
19311
19271
  set extname(extname) {
19312
- assertPart$1(extname, 'extname');
19313
- assertPath$2(this.dirname, 'extname');
19272
+ assertPart(extname, 'extname');
19273
+ assertPath(this.dirname, 'extname');
19314
19274
 
19315
19275
  if (extname) {
19316
19276
  if (extname.codePointAt(0) !== 46 /* `.` */) {
@@ -19322,7 +19282,7 @@ let VFile$1 = class VFile {
19322
19282
  }
19323
19283
  }
19324
19284
 
19325
- this.path = minpath$1.join(this.dirname, this.stem + (extname || ''));
19285
+ this.path = minpath.join(this.dirname, this.stem + (extname || ''));
19326
19286
  }
19327
19287
 
19328
19288
  /**
@@ -19348,11 +19308,11 @@ let VFile$1 = class VFile {
19348
19308
  * Nothing.
19349
19309
  */
19350
19310
  set path(path) {
19351
- if (isUrl$1(path)) {
19352
- path = urlToPath$1(path);
19311
+ if (isUrl(path)) {
19312
+ path = urlToPath(path);
19353
19313
  }
19354
19314
 
19355
- assertNonEmpty$1(path, 'path');
19315
+ assertNonEmpty(path, 'path');
19356
19316
 
19357
19317
  if (this.path !== path) {
19358
19318
  this.history.push(path);
@@ -19367,7 +19327,7 @@ let VFile$1 = class VFile {
19367
19327
  */
19368
19328
  get stem() {
19369
19329
  return typeof this.path === 'string'
19370
- ? minpath$1.basename(this.path, this.extname)
19330
+ ? minpath.basename(this.path, this.extname)
19371
19331
  : undefined
19372
19332
  }
19373
19333
 
@@ -19384,9 +19344,9 @@ let VFile$1 = class VFile {
19384
19344
  * Nothing.
19385
19345
  */
19386
19346
  set stem(stem) {
19387
- assertNonEmpty$1(stem, 'stem');
19388
- assertPart$1(stem, 'stem');
19389
- this.path = minpath$1.join(this.dirname || '', stem + (this.extname || ''));
19347
+ assertNonEmpty(stem, 'stem');
19348
+ assertPart(stem, 'stem');
19349
+ this.path = minpath.join(this.dirname || '', stem + (this.extname || ''));
19390
19350
  }
19391
19351
 
19392
19352
  // Normal prototypal methods.
@@ -19585,7 +19545,7 @@ let VFile$1 = class VFile {
19585
19545
  * Message.
19586
19546
  */
19587
19547
  message(causeOrReason, optionsOrParentOrPlace, origin) {
19588
- const message = new VFileMessage$1(
19548
+ const message = new VFileMessage(
19589
19549
  // @ts-expect-error: the overloads are fine.
19590
19550
  causeOrReason,
19591
19551
  optionsOrParentOrPlace,
@@ -19629,7 +19589,7 @@ let VFile$1 = class VFile {
19629
19589
  const decoder = new TextDecoder(encoding || undefined);
19630
19590
  return decoder.decode(this.value)
19631
19591
  }
19632
- };
19592
+ }
19633
19593
 
19634
19594
  /**
19635
19595
  * Assert that `part` is not a path (as in, does not contain `path.sep`).
@@ -19641,10 +19601,10 @@ let VFile$1 = class VFile {
19641
19601
  * @returns {undefined}
19642
19602
  * Nothing.
19643
19603
  */
19644
- function assertPart$1(part, name) {
19645
- if (part && part.includes(minpath$1.sep)) {
19604
+ function assertPart(part, name) {
19605
+ if (part && part.includes(minpath.sep)) {
19646
19606
  throw new Error(
19647
- '`' + name + '` cannot be a path: did not expect `' + minpath$1.sep + '`'
19607
+ '`' + name + '` cannot be a path: did not expect `' + minpath.sep + '`'
19648
19608
  )
19649
19609
  }
19650
19610
  }
@@ -19659,7 +19619,7 @@ function assertPart$1(part, name) {
19659
19619
  * @returns {asserts part is string}
19660
19620
  * Nothing.
19661
19621
  */
19662
- function assertNonEmpty$1(part, name) {
19622
+ function assertNonEmpty(part, name) {
19663
19623
  if (!part) {
19664
19624
  throw new Error('`' + name + '` cannot be empty')
19665
19625
  }
@@ -19675,7 +19635,7 @@ function assertNonEmpty$1(part, name) {
19675
19635
  * @returns {asserts path is string}
19676
19636
  * Nothing.
19677
19637
  */
19678
- function assertPath$2(path, name) {
19638
+ function assertPath(path, name) {
19679
19639
  if (!path) {
19680
19640
  throw new Error('Setting `' + name + '` requires `path` to be set too')
19681
19641
  }
@@ -19689,7 +19649,7 @@ function assertPath$2(path, name) {
19689
19649
  * @returns {value is Uint8Array}
19690
19650
  * Whether `value` is an `Uint8Array`.
19691
19651
  */
19692
- function isUint8Array$2(value) {
19652
+ function isUint8Array$1(value) {
19693
19653
  return Boolean(
19694
19654
  value &&
19695
19655
  typeof value === 'object' &&
@@ -20672,7 +20632,7 @@ function assertDone(name, asyncName, complete) {
20672
20632
  * @returns {VFile}
20673
20633
  */
20674
20634
  function vfile(value) {
20675
- return looksLikeAVFile(value) ? value : new VFile$1(value)
20635
+ return looksLikeAVFile(value) ? value : new VFile(value)
20676
20636
  }
20677
20637
 
20678
20638
  /**
@@ -20693,7 +20653,7 @@ function looksLikeAVFile(value) {
20693
20653
  * @returns {value is Value}
20694
20654
  */
20695
20655
  function looksLikeAValue(value) {
20696
- return typeof value === 'string' || isUint8Array$1(value)
20656
+ return typeof value === 'string' || isUint8Array(value)
20697
20657
  }
20698
20658
 
20699
20659
  /**
@@ -20704,7 +20664,7 @@ function looksLikeAValue(value) {
20704
20664
  * @returns {value is Uint8Array}
20705
20665
  * Whether `value` is an `Uint8Array`.
20706
20666
  */
20707
- function isUint8Array$1(value) {
20667
+ function isUint8Array(value) {
20708
20668
  return Boolean(
20709
20669
  value &&
20710
20670
  typeof value === 'object' &&
@@ -20715,1559 +20675,460 @@ function isUint8Array$1(value) {
20715
20675
 
20716
20676
  /**
20717
20677
  * @typedef {import('unist').Node} Node
20718
- * @typedef {import('unist').Point} Point
20719
- * @typedef {import('unist').Position} Position
20678
+ * @typedef {import('unist').Parent} Parent
20720
20679
  */
20721
20680
 
20722
- /**
20723
- * @typedef NodeLike
20724
- * @property {string} type
20725
- * @property {PositionLike | null | undefined} [position]
20726
- *
20727
- * @typedef PointLike
20728
- * @property {number | null | undefined} [line]
20729
- * @property {number | null | undefined} [column]
20730
- * @property {number | null | undefined} [offset]
20731
- *
20732
- * @typedef PositionLike
20733
- * @property {PointLike | null | undefined} [start]
20734
- * @property {PointLike | null | undefined} [end]
20735
- */
20736
20681
 
20737
20682
  /**
20738
- * Serialize the positional info of a point, position (start and end points),
20739
- * or node.
20683
+ * Generate an assertion from a test.
20740
20684
  *
20741
- * @param {Node | NodeLike | Point | PointLike | Position | PositionLike | null | undefined} [value]
20742
- * Node, position, or point.
20743
- * @returns {string}
20744
- * Pretty printed positional info of a node (`string`).
20685
+ * Useful if you’re going to test many nodes, for example when creating a
20686
+ * utility where something else passes a compatible test.
20745
20687
  *
20746
- * In the format of a range `ls:cs-le:ce` (when given `node` or `position`)
20747
- * or a point `l:c` (when given `point`), where `l` stands for line, `c` for
20748
- * column, `s` for `start`, and `e` for end.
20749
- * An empty string (`''`) is returned if the given value is neither `node`,
20750
- * `position`, nor `point`.
20688
+ * The created function is a bit faster because it expects valid input only:
20689
+ * a `node`, `index`, and `parent`.
20690
+ *
20691
+ * @param {Test} test
20692
+ * * when nullish, checks if `node` is a `Node`.
20693
+ * * when `string`, works like passing `(node) => node.type === test`.
20694
+ * * when `function` checks if function passed the node is true.
20695
+ * * when `object`, checks that all keys in test are in node, and that they have (strictly) equal values.
20696
+ * * when `array`, checks if any one of the subtests pass.
20697
+ * @returns {Check}
20698
+ * An assertion.
20751
20699
  */
20752
- function stringifyPosition(value) {
20753
- // Nothing.
20754
- if (!value || typeof value !== 'object') {
20755
- return ''
20756
- }
20700
+ const convert =
20701
+ // Note: overloads in JSDoc can’t yet use different `@template`s.
20702
+ /**
20703
+ * @type {(
20704
+ * (<Condition extends string>(test: Condition) => (node: unknown, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node & {type: Condition}) &
20705
+ * (<Condition extends Props>(test: Condition) => (node: unknown, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node & Condition) &
20706
+ * (<Condition extends TestFunction>(test: Condition) => (node: unknown, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node & Predicate<Condition, Node>) &
20707
+ * ((test?: null | undefined) => (node?: unknown, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node) &
20708
+ * ((test?: Test) => Check)
20709
+ * )}
20710
+ */
20711
+ (
20712
+ /**
20713
+ * @param {Test} [test]
20714
+ * @returns {Check}
20715
+ */
20716
+ function (test) {
20717
+ if (test === null || test === undefined) {
20718
+ return ok
20719
+ }
20757
20720
 
20758
- // Node.
20759
- if ('position' in value || 'type' in value) {
20760
- return position(value.position)
20761
- }
20721
+ if (typeof test === 'function') {
20722
+ return castFactory(test)
20723
+ }
20762
20724
 
20763
- // Position.
20764
- if ('start' in value || 'end' in value) {
20765
- return position(value)
20766
- }
20725
+ if (typeof test === 'object') {
20726
+ return Array.isArray(test) ? anyFactory(test) : propsFactory(test)
20727
+ }
20767
20728
 
20768
- // Point.
20769
- if ('line' in value || 'column' in value) {
20770
- return point(value)
20771
- }
20729
+ if (typeof test === 'string') {
20730
+ return typeFactory(test)
20731
+ }
20772
20732
 
20773
- // ?
20774
- return ''
20775
- }
20733
+ throw new Error('Expected function, string, or object as test')
20734
+ }
20735
+ );
20776
20736
 
20777
20737
  /**
20778
- * @param {Point | PointLike | null | undefined} point
20779
- * @returns {string}
20738
+ * @param {Array<Props | TestFunction | string>} tests
20739
+ * @returns {Check}
20780
20740
  */
20781
- function point(point) {
20782
- return index(point && point.line) + ':' + index(point && point.column)
20783
- }
20741
+ function anyFactory(tests) {
20742
+ /** @type {Array<Check>} */
20743
+ const checks = [];
20744
+ let index = -1;
20784
20745
 
20785
- /**
20786
- * @param {Position | PositionLike | null | undefined} pos
20787
- * @returns {string}
20788
- */
20789
- function position(pos) {
20790
- return point(pos && pos.start) + '-' + point(pos && pos.end)
20746
+ while (++index < tests.length) {
20747
+ checks[index] = convert(tests[index]);
20748
+ }
20749
+
20750
+ return castFactory(any)
20751
+
20752
+ /**
20753
+ * @this {unknown}
20754
+ * @type {TestFunction}
20755
+ */
20756
+ function any(...parameters) {
20757
+ let index = -1;
20758
+
20759
+ while (++index < checks.length) {
20760
+ if (checks[index].apply(this, parameters)) return true
20761
+ }
20762
+
20763
+ return false
20764
+ }
20791
20765
  }
20792
20766
 
20793
20767
  /**
20794
- * @param {number | null | undefined} value
20795
- * @returns {number}
20768
+ * Turn an object into a test for a node with a certain fields.
20769
+ *
20770
+ * @param {Props} check
20771
+ * @returns {Check}
20796
20772
  */
20797
- function index(value) {
20798
- return value && typeof value === 'number' ? value : 1
20773
+ function propsFactory(check) {
20774
+ const checkAsRecord = /** @type {Record<string, unknown>} */ (check);
20775
+
20776
+ return castFactory(all)
20777
+
20778
+ /**
20779
+ * @param {Node} node
20780
+ * @returns {boolean}
20781
+ */
20782
+ function all(node) {
20783
+ const nodeAsRecord = /** @type {Record<string, unknown>} */ (
20784
+ /** @type {unknown} */ (node)
20785
+ );
20786
+
20787
+ /** @type {string} */
20788
+ let key;
20789
+
20790
+ for (key in check) {
20791
+ if (nodeAsRecord[key] !== checkAsRecord[key]) return false
20792
+ }
20793
+
20794
+ return true
20795
+ }
20799
20796
  }
20800
20797
 
20801
20798
  /**
20802
- * @import {Node, Point, Position} from 'unist'
20799
+ * Turn a string into a test for a node with a certain type.
20800
+ *
20801
+ * @param {string} check
20802
+ * @returns {Check}
20803
20803
  */
20804
+ function typeFactory(check) {
20805
+ return castFactory(type)
20804
20806
 
20807
+ /**
20808
+ * @param {Node} node
20809
+ */
20810
+ function type(node) {
20811
+ return node && node.type === check
20812
+ }
20813
+ }
20805
20814
 
20806
20815
  /**
20807
- * Message.
20816
+ * Turn a custom test into a test for a node that passes that test.
20817
+ *
20818
+ * @param {TestFunction} testFunction
20819
+ * @returns {Check}
20808
20820
  */
20809
- class VFileMessage extends Error {
20821
+ function castFactory(testFunction) {
20822
+ return check
20823
+
20810
20824
  /**
20811
- * Create a message for `reason`.
20812
- *
20813
- * > 🪦 **Note**: also has obsolete signatures.
20814
- *
20815
- * @overload
20816
- * @param {string} reason
20817
- * @param {Options | null | undefined} [options]
20818
- * @returns
20819
- *
20820
- * @overload
20821
- * @param {string} reason
20822
- * @param {Node | NodeLike | null | undefined} parent
20823
- * @param {string | null | undefined} [origin]
20824
- * @returns
20825
- *
20826
- * @overload
20827
- * @param {string} reason
20828
- * @param {Point | Position | null | undefined} place
20829
- * @param {string | null | undefined} [origin]
20830
- * @returns
20831
- *
20832
- * @overload
20833
- * @param {string} reason
20834
- * @param {string | null | undefined} [origin]
20835
- * @returns
20836
- *
20837
- * @overload
20838
- * @param {Error | VFileMessage} cause
20839
- * @param {Node | NodeLike | null | undefined} parent
20840
- * @param {string | null | undefined} [origin]
20841
- * @returns
20842
- *
20843
- * @overload
20844
- * @param {Error | VFileMessage} cause
20845
- * @param {Point | Position | null | undefined} place
20846
- * @param {string | null | undefined} [origin]
20847
- * @returns
20848
- *
20849
- * @overload
20850
- * @param {Error | VFileMessage} cause
20851
- * @param {string | null | undefined} [origin]
20852
- * @returns
20853
- *
20854
- * @param {Error | VFileMessage | string} causeOrReason
20855
- * Reason for message, should use markdown.
20856
- * @param {Node | NodeLike | Options | Point | Position | string | null | undefined} [optionsOrParentOrPlace]
20857
- * Configuration (optional).
20858
- * @param {string | null | undefined} [origin]
20859
- * Place in code where the message originates (example:
20860
- * `'my-package:my-rule'` or `'my-rule'`).
20861
- * @returns
20862
- * Instance of `VFileMessage`.
20825
+ * @this {unknown}
20826
+ * @type {Check}
20863
20827
  */
20864
- // eslint-disable-next-line complexity
20865
- constructor(causeOrReason, optionsOrParentOrPlace, origin) {
20866
- super();
20867
-
20868
- if (typeof optionsOrParentOrPlace === 'string') {
20869
- origin = optionsOrParentOrPlace;
20870
- optionsOrParentOrPlace = undefined;
20871
- }
20828
+ function check(value, index, parent) {
20829
+ return Boolean(
20830
+ looksLikeANode(value) &&
20831
+ testFunction.call(
20832
+ this,
20833
+ value,
20834
+ typeof index === 'number' ? index : undefined,
20835
+ parent || undefined
20836
+ )
20837
+ )
20838
+ }
20839
+ }
20872
20840
 
20873
- /** @type {string} */
20874
- let reason = '';
20875
- /** @type {Options} */
20876
- let options = {};
20877
- let legacyCause = false;
20841
+ function ok() {
20842
+ return true
20843
+ }
20878
20844
 
20879
- if (optionsOrParentOrPlace) {
20880
- // Point.
20881
- if (
20882
- 'line' in optionsOrParentOrPlace &&
20883
- 'column' in optionsOrParentOrPlace
20884
- ) {
20885
- options = {place: optionsOrParentOrPlace};
20886
- }
20887
- // Position.
20888
- else if (
20889
- 'start' in optionsOrParentOrPlace &&
20890
- 'end' in optionsOrParentOrPlace
20891
- ) {
20892
- options = {place: optionsOrParentOrPlace};
20893
- }
20894
- // Node.
20895
- else if ('type' in optionsOrParentOrPlace) {
20896
- options = {
20897
- ancestors: [optionsOrParentOrPlace],
20898
- place: optionsOrParentOrPlace.position
20899
- };
20900
- }
20901
- // Options.
20902
- else {
20903
- options = {...optionsOrParentOrPlace};
20904
- }
20905
- }
20845
+ /**
20846
+ * @param {unknown} value
20847
+ * @returns {value is Node}
20848
+ */
20849
+ function looksLikeANode(value) {
20850
+ return value !== null && typeof value === 'object' && 'type' in value
20851
+ }
20906
20852
 
20907
- if (typeof causeOrReason === 'string') {
20908
- reason = causeOrReason;
20909
- }
20910
- // Error.
20911
- else if (!options.cause && causeOrReason) {
20912
- legacyCause = true;
20913
- reason = causeOrReason.message;
20914
- options.cause = causeOrReason;
20915
- }
20853
+ /**
20854
+ * @param {string} d
20855
+ * @returns {string}
20856
+ */
20857
+ function color(d) {
20858
+ return d
20859
+ }
20916
20860
 
20917
- if (!options.ruleId && !options.source && typeof origin === 'string') {
20918
- const index = origin.indexOf(':');
20861
+ /**
20862
+ * @typedef {import('unist').Node} UnistNode
20863
+ * @typedef {import('unist').Parent} UnistParent
20864
+ */
20919
20865
 
20920
- if (index === -1) {
20921
- options.ruleId = origin;
20922
- } else {
20923
- options.source = origin.slice(0, index);
20924
- options.ruleId = origin.slice(index + 1);
20925
- }
20926
- }
20927
20866
 
20928
- if (!options.place && options.ancestors && options.ancestors) {
20929
- const parent = options.ancestors[options.ancestors.length - 1];
20867
+ /** @type {Readonly<ActionTuple>} */
20868
+ const empty = [];
20930
20869
 
20931
- if (parent) {
20932
- options.place = parent.position;
20933
- }
20934
- }
20870
+ /**
20871
+ * Continue traversing as normal.
20872
+ */
20873
+ const CONTINUE = true;
20935
20874
 
20936
- const start =
20937
- options.place && 'start' in options.place
20938
- ? options.place.start
20939
- : options.place;
20875
+ /**
20876
+ * Stop traversing immediately.
20877
+ */
20878
+ const EXIT = false;
20940
20879
 
20941
- /**
20942
- * Stack of ancestor nodes surrounding the message.
20943
- *
20944
- * @type {Array<Node> | undefined}
20945
- */
20946
- this.ancestors = options.ancestors || undefined;
20947
-
20948
- /**
20949
- * Original error cause of the message.
20950
- *
20951
- * @type {Error | undefined}
20952
- */
20953
- this.cause = options.cause || undefined;
20954
-
20955
- /**
20956
- * Starting column of message.
20957
- *
20958
- * @type {number | undefined}
20959
- */
20960
- this.column = start ? start.column : undefined;
20961
-
20962
- /**
20963
- * State of problem.
20964
- *
20965
- * * `true` — error, file not usable
20966
- * * `false` — warning, change may be needed
20967
- * * `undefined` — change likely not needed
20968
- *
20969
- * @type {boolean | null | undefined}
20970
- */
20971
- this.fatal = undefined;
20972
-
20973
- /**
20974
- * Path of a file (used throughout the `VFile` ecosystem).
20975
- *
20976
- * @type {string | undefined}
20977
- */
20978
- this.file = '';
20979
-
20980
- // Field from `Error`.
20981
- /**
20982
- * Reason for message.
20983
- *
20984
- * @type {string}
20985
- */
20986
- this.message = reason;
20987
-
20988
- /**
20989
- * Starting line of error.
20990
- *
20991
- * @type {number | undefined}
20992
- */
20993
- this.line = start ? start.line : undefined;
20994
-
20995
- // Field from `Error`.
20996
- /**
20997
- * Serialized positional info of message.
20998
- *
20999
- * On normal errors, this would be something like `ParseError`, buit in
21000
- * `VFile` messages we use this space to show where an error happened.
21001
- */
21002
- this.name = stringifyPosition(options.place) || '1:1';
21003
-
21004
- /**
21005
- * Place of message.
21006
- *
21007
- * @type {Point | Position | undefined}
21008
- */
21009
- this.place = options.place || undefined;
21010
-
21011
- /**
21012
- * Reason for message, should use markdown.
21013
- *
21014
- * @type {string}
21015
- */
21016
- this.reason = this.message;
21017
-
21018
- /**
21019
- * Category of message (example: `'my-rule'`).
21020
- *
21021
- * @type {string | undefined}
21022
- */
21023
- this.ruleId = options.ruleId || undefined;
21024
-
21025
- /**
21026
- * Namespace of message (example: `'my-package'`).
21027
- *
21028
- * @type {string | undefined}
21029
- */
21030
- this.source = options.source || undefined;
21031
-
21032
- // Field from `Error`.
21033
- /**
21034
- * Stack of message.
21035
- *
21036
- * This is used by normal errors to show where something happened in
21037
- * programming code, irrelevant for `VFile` messages,
21038
- *
21039
- * @type {string}
21040
- */
21041
- this.stack =
21042
- legacyCause && options.cause && typeof options.cause.stack === 'string'
21043
- ? options.cause.stack
21044
- : '';
21045
-
21046
- // The following fields are “well known”.
21047
- // Not standard.
21048
- // Feel free to add other non-standard fields to your messages.
21049
-
21050
- /**
21051
- * Specify the source value that’s being reported, which is deemed
21052
- * incorrect.
21053
- *
21054
- * @type {string | undefined}
21055
- */
21056
- this.actual = undefined;
21057
-
21058
- /**
21059
- * Suggest acceptable values that can be used instead of `actual`.
21060
- *
21061
- * @type {Array<string> | undefined}
21062
- */
21063
- this.expected = undefined;
21064
-
21065
- /**
21066
- * Long form description of the message (you should use markdown).
21067
- *
21068
- * @type {string | undefined}
21069
- */
21070
- this.note = undefined;
21071
-
21072
- /**
21073
- * Link to docs for the message.
21074
- *
21075
- * > 👉 **Note**: this must be an absolute URL that can be passed as `x`
21076
- * > to `new URL(x)`.
21077
- *
21078
- * @type {string | undefined}
21079
- */
21080
- this.url = undefined;
21081
- }
21082
- }
21083
-
21084
- VFileMessage.prototype.file = '';
21085
- VFileMessage.prototype.name = '';
21086
- VFileMessage.prototype.reason = '';
21087
- VFileMessage.prototype.message = '';
21088
- VFileMessage.prototype.stack = '';
21089
- VFileMessage.prototype.column = undefined;
21090
- VFileMessage.prototype.line = undefined;
21091
- VFileMessage.prototype.ancestors = undefined;
21092
- VFileMessage.prototype.cause = undefined;
21093
- VFileMessage.prototype.fatal = undefined;
21094
- VFileMessage.prototype.place = undefined;
21095
- VFileMessage.prototype.ruleId = undefined;
21096
- VFileMessage.prototype.source = undefined;
21097
-
21098
- // A derivative work based on:
21099
- // <https://github.com/browserify/path-browserify>.
21100
- // Which is licensed:
21101
- //
21102
- // MIT License
21103
- //
21104
- // Copyright (c) 2013 James Halliday
21105
- //
21106
- // Permission is hereby granted, free of charge, to any person obtaining a copy of
21107
- // this software and associated documentation files (the "Software"), to deal in
21108
- // the Software without restriction, including without limitation the rights to
21109
- // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
21110
- // the Software, and to permit persons to whom the Software is furnished to do so,
21111
- // subject to the following conditions:
21112
- //
21113
- // The above copyright notice and this permission notice shall be included in all
21114
- // copies or substantial portions of the Software.
21115
- //
21116
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21117
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
21118
- // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
21119
- // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21120
- // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21121
- // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21122
- // A derivative work based on:
21123
- //
21124
- // Parts of that are extracted from Node’s internal `path` module:
21125
- // <https://github.com/nodejs/node/blob/master/lib/path.js>.
21126
- // Which is licensed:
21127
- //
21128
- // Copyright Joyent, Inc. and other Node contributors.
21129
- //
21130
- // Permission is hereby granted, free of charge, to any person obtaining a
21131
- // copy of this software and associated documentation files (the
21132
- // "Software"), to deal in the Software without restriction, including
21133
- // without limitation the rights to use, copy, modify, merge, publish,
21134
- // distribute, sublicense, and/or sell copies of the Software, and to permit
21135
- // persons to whom the Software is furnished to do so, subject to the
21136
- // following conditions:
21137
- //
21138
- // The above copyright notice and this permission notice shall be included
21139
- // in all copies or substantial portions of the Software.
21140
- //
21141
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21142
- // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21143
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
21144
- // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
21145
- // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21146
- // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21147
- // USE OR OTHER DEALINGS IN THE SOFTWARE.
21148
-
21149
- const minpath = {basename, dirname, extname, join, sep: '/'};
21150
-
21151
- /* eslint-disable max-depth, complexity */
20880
+ /**
20881
+ * Do not traverse this node’s children.
20882
+ */
20883
+ const SKIP = 'skip';
21152
20884
 
21153
20885
  /**
21154
- * Get the basename from a path.
20886
+ * Visit nodes, with ancestral information.
21155
20887
  *
21156
- * @param {string} path
21157
- * File path.
21158
- * @param {string | null | undefined} [extname]
21159
- * Extension to strip.
21160
- * @returns {string}
21161
- * Stem or basename.
20888
+ * This algorithm performs *depth-first* *tree traversal* in *preorder*
20889
+ * (**NLR**) or if `reverse` is given, in *reverse preorder* (**NRL**).
20890
+ *
20891
+ * You can choose for which nodes `visitor` is called by passing a `test`.
20892
+ * For complex tests, you should test yourself in `visitor`, as it will be
20893
+ * faster and will have improved type information.
20894
+ *
20895
+ * Walking the tree is an intensive task.
20896
+ * Make use of the return values of the visitor when possible.
20897
+ * Instead of walking a tree multiple times, walk it once, use `unist-util-is`
20898
+ * to check if a node matches, and then perform different operations.
20899
+ *
20900
+ * You can change the tree.
20901
+ * See `Visitor` for more info.
20902
+ *
20903
+ * @overload
20904
+ * @param {Tree} tree
20905
+ * @param {Check} check
20906
+ * @param {BuildVisitor<Tree, Check>} visitor
20907
+ * @param {boolean | null | undefined} [reverse]
20908
+ * @returns {undefined}
20909
+ *
20910
+ * @overload
20911
+ * @param {Tree} tree
20912
+ * @param {BuildVisitor<Tree>} visitor
20913
+ * @param {boolean | null | undefined} [reverse]
20914
+ * @returns {undefined}
20915
+ *
20916
+ * @param {UnistNode} tree
20917
+ * Tree to traverse.
20918
+ * @param {Visitor | Test} test
20919
+ * `unist-util-is`-compatible test
20920
+ * @param {Visitor | boolean | null | undefined} [visitor]
20921
+ * Handle each node.
20922
+ * @param {boolean | null | undefined} [reverse]
20923
+ * Traverse in reverse preorder (NRL) instead of the default preorder (NLR).
20924
+ * @returns {undefined}
20925
+ * Nothing.
20926
+ *
20927
+ * @template {UnistNode} Tree
20928
+ * Node type.
20929
+ * @template {Test} Check
20930
+ * `unist-util-is`-compatible test.
21162
20931
  */
21163
- function basename(path, extname) {
21164
- if (extname !== undefined && typeof extname !== 'string') {
21165
- throw new TypeError('"ext" argument must be a string')
21166
- }
21167
-
21168
- assertPath$1(path);
21169
- let start = 0;
21170
- let end = -1;
21171
- let index = path.length;
21172
- /** @type {boolean | undefined} */
21173
- let seenNonSlash;
21174
-
21175
- if (
21176
- extname === undefined ||
21177
- extname.length === 0 ||
21178
- extname.length > path.length
21179
- ) {
21180
- while (index--) {
21181
- if (path.codePointAt(index) === 47 /* `/` */) {
21182
- // If we reached a path separator that was not part of a set of path
21183
- // separators at the end of the string, stop now.
21184
- if (seenNonSlash) {
21185
- start = index + 1;
21186
- break
21187
- }
21188
- } else if (end < 0) {
21189
- // We saw the first non-path separator, mark this as the end of our
21190
- // path component.
21191
- seenNonSlash = true;
21192
- end = index + 1;
21193
- }
21194
- }
21195
-
21196
- return end < 0 ? '' : path.slice(start, end)
21197
- }
21198
-
21199
- if (extname === path) {
21200
- return ''
21201
- }
21202
-
21203
- let firstNonSlashEnd = -1;
21204
- let extnameIndex = extname.length - 1;
21205
-
21206
- while (index--) {
21207
- if (path.codePointAt(index) === 47 /* `/` */) {
21208
- // If we reached a path separator that was not part of a set of path
21209
- // separators at the end of the string, stop now.
21210
- if (seenNonSlash) {
21211
- start = index + 1;
21212
- break
21213
- }
21214
- } else {
21215
- if (firstNonSlashEnd < 0) {
21216
- // We saw the first non-path separator, remember this index in case
21217
- // we need it if the extension ends up not matching.
21218
- seenNonSlash = true;
21219
- firstNonSlashEnd = index + 1;
21220
- }
21221
-
21222
- if (extnameIndex > -1) {
21223
- // Try to match the explicit extension.
21224
- if (path.codePointAt(index) === extname.codePointAt(extnameIndex--)) {
21225
- if (extnameIndex < 0) {
21226
- // We matched the extension, so mark this as the end of our path
21227
- // component
21228
- end = index;
21229
- }
21230
- } else {
21231
- // Extension does not match, so our result is the entire path
21232
- // component
21233
- extnameIndex = -1;
21234
- end = firstNonSlashEnd;
21235
- }
21236
- }
21237
- }
21238
- }
21239
-
21240
- if (start === end) {
21241
- end = firstNonSlashEnd;
21242
- } else if (end < 0) {
21243
- end = path.length;
21244
- }
21245
-
21246
- return path.slice(start, end)
21247
- }
21248
-
21249
- /**
21250
- * Get the dirname from a path.
21251
- *
21252
- * @param {string} path
21253
- * File path.
21254
- * @returns {string}
21255
- * File path.
21256
- */
21257
- function dirname(path) {
21258
- assertPath$1(path);
21259
-
21260
- if (path.length === 0) {
21261
- return '.'
21262
- }
21263
-
21264
- let end = -1;
21265
- let index = path.length;
21266
- /** @type {boolean | undefined} */
21267
- let unmatchedSlash;
21268
-
21269
- // Prefix `--` is important to not run on `0`.
21270
- while (--index) {
21271
- if (path.codePointAt(index) === 47 /* `/` */) {
21272
- if (unmatchedSlash) {
21273
- end = index;
21274
- break
21275
- }
21276
- } else if (!unmatchedSlash) {
21277
- // We saw the first non-path separator
21278
- unmatchedSlash = true;
21279
- }
21280
- }
21281
-
21282
- return end < 0
21283
- ? path.codePointAt(0) === 47 /* `/` */
21284
- ? '/'
21285
- : '.'
21286
- : end === 1 && path.codePointAt(0) === 47 /* `/` */
21287
- ? '//'
21288
- : path.slice(0, end)
21289
- }
21290
-
21291
- /**
21292
- * Get an extname from a path.
21293
- *
21294
- * @param {string} path
21295
- * File path.
21296
- * @returns {string}
21297
- * Extname.
21298
- */
21299
- function extname(path) {
21300
- assertPath$1(path);
21301
-
21302
- let index = path.length;
21303
-
21304
- let end = -1;
21305
- let startPart = 0;
21306
- let startDot = -1;
21307
- // Track the state of characters (if any) we see before our first dot and
21308
- // after any path separator we find.
21309
- let preDotState = 0;
21310
- /** @type {boolean | undefined} */
21311
- let unmatchedSlash;
21312
-
21313
- while (index--) {
21314
- const code = path.codePointAt(index);
21315
-
21316
- if (code === 47 /* `/` */) {
21317
- // If we reached a path separator that was not part of a set of path
21318
- // separators at the end of the string, stop now.
21319
- if (unmatchedSlash) {
21320
- startPart = index + 1;
21321
- break
21322
- }
21323
-
21324
- continue
21325
- }
21326
-
21327
- if (end < 0) {
21328
- // We saw the first non-path separator, mark this as the end of our
21329
- // extension.
21330
- unmatchedSlash = true;
21331
- end = index + 1;
21332
- }
21333
-
21334
- if (code === 46 /* `.` */) {
21335
- // If this is our first dot, mark it as the start of our extension.
21336
- if (startDot < 0) {
21337
- startDot = index;
21338
- } else if (preDotState !== 1) {
21339
- preDotState = 1;
21340
- }
21341
- } else if (startDot > -1) {
21342
- // We saw a non-dot and non-path separator before our dot, so we should
21343
- // have a good chance at having a non-empty extension.
21344
- preDotState = -1;
21345
- }
21346
- }
21347
-
21348
- if (
21349
- startDot < 0 ||
21350
- end < 0 ||
21351
- // We saw a non-dot character immediately before the dot.
21352
- preDotState === 0 ||
21353
- // The (right-most) trimmed path component is exactly `..`.
21354
- (preDotState === 1 && startDot === end - 1 && startDot === startPart + 1)
21355
- ) {
21356
- return ''
21357
- }
21358
-
21359
- return path.slice(startDot, end)
21360
- }
21361
-
21362
- /**
21363
- * Join segments from a path.
21364
- *
21365
- * @param {Array<string>} segments
21366
- * Path segments.
21367
- * @returns {string}
21368
- * File path.
21369
- */
21370
- function join(...segments) {
21371
- let index = -1;
21372
- /** @type {string | undefined} */
21373
- let joined;
21374
-
21375
- while (++index < segments.length) {
21376
- assertPath$1(segments[index]);
21377
-
21378
- if (segments[index]) {
21379
- joined =
21380
- joined === undefined ? segments[index] : joined + '/' + segments[index];
21381
- }
21382
- }
21383
-
21384
- return joined === undefined ? '.' : normalize(joined)
21385
- }
21386
-
21387
- /**
21388
- * Normalize a basic file path.
21389
- *
21390
- * @param {string} path
21391
- * File path.
21392
- * @returns {string}
21393
- * File path.
21394
- */
21395
- // Note: `normalize` is not exposed as `path.normalize`, so some code is
21396
- // manually removed from it.
21397
- function normalize(path) {
21398
- assertPath$1(path);
21399
-
21400
- const absolute = path.codePointAt(0) === 47; /* `/` */
21401
-
21402
- // Normalize the path according to POSIX rules.
21403
- let value = normalizeString(path, !absolute);
21404
-
21405
- if (value.length === 0 && !absolute) {
21406
- value = '.';
21407
- }
21408
-
21409
- if (value.length > 0 && path.codePointAt(path.length - 1) === 47 /* / */) {
21410
- value += '/';
21411
- }
21412
-
21413
- return absolute ? '/' + value : value
21414
- }
21415
-
21416
- /**
21417
- * Resolve `.` and `..` elements in a path with directory names.
21418
- *
21419
- * @param {string} path
21420
- * File path.
21421
- * @param {boolean} allowAboveRoot
21422
- * Whether `..` can move above root.
21423
- * @returns {string}
21424
- * File path.
21425
- */
21426
- function normalizeString(path, allowAboveRoot) {
21427
- let result = '';
21428
- let lastSegmentLength = 0;
21429
- let lastSlash = -1;
21430
- let dots = 0;
21431
- let index = -1;
21432
- /** @type {number | undefined} */
21433
- let code;
21434
- /** @type {number} */
21435
- let lastSlashIndex;
21436
-
21437
- while (++index <= path.length) {
21438
- if (index < path.length) {
21439
- code = path.codePointAt(index);
21440
- } else if (code === 47 /* `/` */) {
21441
- break
21442
- } else {
21443
- code = 47; /* `/` */
21444
- }
21445
-
21446
- if (code === 47 /* `/` */) {
21447
- if (lastSlash === index - 1 || dots === 1) ; else if (lastSlash !== index - 1 && dots === 2) {
21448
- if (
21449
- result.length < 2 ||
21450
- lastSegmentLength !== 2 ||
21451
- result.codePointAt(result.length - 1) !== 46 /* `.` */ ||
21452
- result.codePointAt(result.length - 2) !== 46 /* `.` */
21453
- ) {
21454
- if (result.length > 2) {
21455
- lastSlashIndex = result.lastIndexOf('/');
21456
-
21457
- if (lastSlashIndex !== result.length - 1) {
21458
- if (lastSlashIndex < 0) {
21459
- result = '';
21460
- lastSegmentLength = 0;
21461
- } else {
21462
- result = result.slice(0, lastSlashIndex);
21463
- lastSegmentLength = result.length - 1 - result.lastIndexOf('/');
21464
- }
21465
-
21466
- lastSlash = index;
21467
- dots = 0;
21468
- continue
21469
- }
21470
- } else if (result.length > 0) {
21471
- result = '';
21472
- lastSegmentLength = 0;
21473
- lastSlash = index;
21474
- dots = 0;
21475
- continue
21476
- }
21477
- }
21478
-
21479
- if (allowAboveRoot) {
21480
- result = result.length > 0 ? result + '/..' : '..';
21481
- lastSegmentLength = 2;
21482
- }
21483
- } else {
21484
- if (result.length > 0) {
21485
- result += '/' + path.slice(lastSlash + 1, index);
21486
- } else {
21487
- result = path.slice(lastSlash + 1, index);
21488
- }
21489
-
21490
- lastSegmentLength = index - lastSlash - 1;
21491
- }
21492
-
21493
- lastSlash = index;
21494
- dots = 0;
21495
- } else if (code === 46 /* `.` */ && dots > -1) {
21496
- dots++;
21497
- } else {
21498
- dots = -1;
21499
- }
21500
- }
21501
-
21502
- return result
21503
- }
21504
-
21505
- /**
21506
- * Make sure `path` is a string.
21507
- *
21508
- * @param {string} path
21509
- * File path.
21510
- * @returns {asserts path is string}
21511
- * Nothing.
21512
- */
21513
- function assertPath$1(path) {
21514
- if (typeof path !== 'string') {
21515
- throw new TypeError(
21516
- 'Path must be a string. Received ' + JSON.stringify(path)
21517
- )
21518
- }
21519
- }
21520
-
21521
- /* eslint-enable max-depth, complexity */
21522
-
21523
- // Somewhat based on:
21524
- // <https://github.com/defunctzombie/node-process/blob/master/browser.js>.
21525
- // But I don’t think one tiny line of code can be copyrighted. 😅
21526
- const minproc = {cwd};
21527
-
21528
- function cwd() {
21529
- return '/'
21530
- }
21531
-
21532
- /**
21533
- * Checks if a value has the shape of a WHATWG URL object.
21534
- *
21535
- * Using a symbol or instanceof would not be able to recognize URL objects
21536
- * coming from other implementations (e.g. in Electron), so instead we are
21537
- * checking some well known properties for a lack of a better test.
21538
- *
21539
- * We use `href` and `protocol` as they are the only properties that are
21540
- * easy to retrieve and calculate due to the lazy nature of the getters.
21541
- *
21542
- * We check for auth attribute to distinguish legacy url instance with
21543
- * WHATWG URL instance.
21544
- *
21545
- * @param {unknown} fileUrlOrPath
21546
- * File path or URL.
21547
- * @returns {fileUrlOrPath is URL}
21548
- * Whether it’s a URL.
21549
- */
21550
- // From: <https://github.com/nodejs/node/blob/6a3403c/lib/internal/url.js#L720>
21551
- function isUrl(fileUrlOrPath) {
21552
- return Boolean(
21553
- fileUrlOrPath !== null &&
21554
- typeof fileUrlOrPath === 'object' &&
21555
- 'href' in fileUrlOrPath &&
21556
- fileUrlOrPath.href &&
21557
- 'protocol' in fileUrlOrPath &&
21558
- fileUrlOrPath.protocol &&
21559
- // @ts-expect-error: indexing is fine.
21560
- fileUrlOrPath.auth === undefined
21561
- )
21562
- }
21563
-
21564
- // See: <https://github.com/nodejs/node/blob/6a3403c/lib/internal/url.js>
21565
-
21566
- /**
21567
- * @param {URL | string} path
21568
- * File URL.
21569
- * @returns {string}
21570
- * File URL.
21571
- */
21572
- function urlToPath(path) {
21573
- if (typeof path === 'string') {
21574
- path = new URL(path);
21575
- } else if (!isUrl(path)) {
21576
- /** @type {NodeJS.ErrnoException} */
21577
- const error = new TypeError(
21578
- 'The "path" argument must be of type string or an instance of URL. Received `' +
21579
- path +
21580
- '`'
21581
- );
21582
- error.code = 'ERR_INVALID_ARG_TYPE';
21583
- throw error
21584
- }
21585
-
21586
- if (path.protocol !== 'file:') {
21587
- /** @type {NodeJS.ErrnoException} */
21588
- const error = new TypeError('The URL must be of scheme file');
21589
- error.code = 'ERR_INVALID_URL_SCHEME';
21590
- throw error
21591
- }
21592
-
21593
- return getPathFromURLPosix(path)
21594
- }
21595
-
21596
- /**
21597
- * Get a path from a POSIX URL.
21598
- *
21599
- * @param {URL} url
21600
- * URL.
21601
- * @returns {string}
21602
- * File path.
21603
- */
21604
- function getPathFromURLPosix(url) {
21605
- if (url.hostname !== '') {
21606
- /** @type {NodeJS.ErrnoException} */
21607
- const error = new TypeError(
21608
- 'File URL host must be "localhost" or empty on darwin'
21609
- );
21610
- error.code = 'ERR_INVALID_FILE_URL_HOST';
21611
- throw error
21612
- }
21613
-
21614
- const pathname = url.pathname;
21615
- let index = -1;
21616
-
21617
- while (++index < pathname.length) {
21618
- if (
21619
- pathname.codePointAt(index) === 37 /* `%` */ &&
21620
- pathname.codePointAt(index + 1) === 50 /* `2` */
21621
- ) {
21622
- const third = pathname.codePointAt(index + 2);
21623
- if (third === 70 /* `F` */ || third === 102 /* `f` */) {
21624
- /** @type {NodeJS.ErrnoException} */
21625
- const error = new TypeError(
21626
- 'File URL path must not include encoded / characters'
21627
- );
21628
- error.code = 'ERR_INVALID_FILE_URL_PATH';
21629
- throw error
21630
- }
21631
- }
21632
- }
21633
-
21634
- return decodeURIComponent(pathname)
21635
- }
21636
-
21637
- /**
21638
- * @import {Node, Point, Position} from 'unist'
21639
- * @import {Options as MessageOptions} from 'vfile-message'
21640
- * @import {Compatible, Data, Map, Options, Value} from 'vfile'
21641
- */
21642
-
21643
-
21644
- /**
21645
- * Order of setting (least specific to most), we need this because otherwise
21646
- * `{stem: 'a', path: '~/b.js'}` would throw, as a path is needed before a
21647
- * stem can be set.
21648
- */
21649
- const order = /** @type {const} */ ([
21650
- 'history',
21651
- 'path',
21652
- 'basename',
21653
- 'stem',
21654
- 'extname',
21655
- 'dirname'
21656
- ]);
21657
-
21658
- class VFile {
21659
- /**
21660
- * Create a new virtual file.
21661
- *
21662
- * `options` is treated as:
21663
- *
21664
- * * `string` or `Uint8Array` — `{value: options}`
21665
- * * `URL` — `{path: options}`
21666
- * * `VFile` — shallow copies its data over to the new file
21667
- * * `object` — all fields are shallow copied over to the new file
21668
- *
21669
- * Path related fields are set in the following order (least specific to
21670
- * most specific): `history`, `path`, `basename`, `stem`, `extname`,
21671
- * `dirname`.
21672
- *
21673
- * You cannot set `dirname` or `extname` without setting either `history`,
21674
- * `path`, `basename`, or `stem` too.
21675
- *
21676
- * @param {Compatible | null | undefined} [value]
21677
- * File value.
21678
- * @returns
21679
- * New instance.
21680
- */
21681
- constructor(value) {
21682
- /** @type {Options | VFile} */
21683
- let options;
21684
-
21685
- if (!value) {
21686
- options = {};
21687
- } else if (isUrl(value)) {
21688
- options = {path: value};
21689
- } else if (typeof value === 'string' || isUint8Array(value)) {
21690
- options = {value};
21691
- } else {
21692
- options = value;
21693
- }
21694
-
21695
- /* eslint-disable no-unused-expressions */
21696
-
21697
- /**
21698
- * Base of `path` (default: `process.cwd()` or `'/'` in browsers).
21699
- *
21700
- * @type {string}
21701
- */
21702
- // Prevent calling `cwd` (which could be expensive) if it’s not needed;
21703
- // the empty string will be overridden in the next block.
21704
- this.cwd = 'cwd' in options ? '' : minproc.cwd();
21705
-
21706
- /**
21707
- * Place to store custom info (default: `{}`).
21708
- *
21709
- * It’s OK to store custom data directly on the file but moving it to
21710
- * `data` is recommended.
21711
- *
21712
- * @type {Data}
21713
- */
21714
- this.data = {};
21715
-
21716
- /**
21717
- * List of file paths the file moved between.
21718
- *
21719
- * The first is the original path and the last is the current path.
21720
- *
21721
- * @type {Array<string>}
21722
- */
21723
- this.history = [];
21724
-
21725
- /**
21726
- * List of messages associated with the file.
21727
- *
21728
- * @type {Array<VFileMessage>}
21729
- */
21730
- this.messages = [];
21731
-
21732
- /**
21733
- * Raw value.
21734
- *
21735
- * @type {Value}
21736
- */
21737
- this.value;
21738
-
21739
- // The below are non-standard, they are “well-known”.
21740
- // As in, used in several tools.
21741
- /**
21742
- * Source map.
21743
- *
21744
- * This type is equivalent to the `RawSourceMap` type from the `source-map`
21745
- * module.
21746
- *
21747
- * @type {Map | null | undefined}
21748
- */
21749
- this.map;
21750
-
21751
- /**
21752
- * Custom, non-string, compiled, representation.
21753
- *
21754
- * This is used by unified to store non-string results.
21755
- * One example is when turning markdown into React nodes.
21756
- *
21757
- * @type {unknown}
21758
- */
21759
- this.result;
21760
-
21761
- /**
21762
- * Whether a file was saved to disk.
21763
- *
21764
- * This is used by vfile reporters.
21765
- *
21766
- * @type {boolean}
21767
- */
21768
- this.stored;
21769
- /* eslint-enable no-unused-expressions */
21770
-
21771
- // Set path related properties in the correct order.
21772
- let index = -1;
21773
-
21774
- while (++index < order.length) {
21775
- const field = order[index];
21776
-
21777
- // Note: we specifically use `in` instead of `hasOwnProperty` to accept
21778
- // `vfile`s too.
21779
- if (
21780
- field in options &&
21781
- options[field] !== undefined &&
21782
- options[field] !== null
21783
- ) {
21784
- // @ts-expect-error: TS doesn’t understand basic reality.
21785
- this[field] = field === 'history' ? [...options[field]] : options[field];
21786
- }
21787
- }
21788
-
21789
- /** @type {string} */
21790
- let field;
21791
-
21792
- // Set non-path related properties.
21793
- for (field in options) {
21794
- // @ts-expect-error: fine to set other things.
21795
- if (!order.includes(field)) {
21796
- // @ts-expect-error: fine to set other things.
21797
- this[field] = options[field];
21798
- }
21799
- }
21800
- }
21801
-
21802
- /**
21803
- * Get the basename (including extname) (example: `'index.min.js'`).
21804
- *
21805
- * @returns {string | undefined}
21806
- * Basename.
21807
- */
21808
- get basename() {
21809
- return typeof this.path === 'string'
21810
- ? minpath.basename(this.path)
21811
- : undefined
21812
- }
21813
-
21814
- /**
21815
- * Set basename (including extname) (`'index.min.js'`).
21816
- *
21817
- * Cannot contain path separators (`'/'` on unix, macOS, and browsers, `'\'`
21818
- * on windows).
21819
- * Cannot be nullified (use `file.path = file.dirname` instead).
21820
- *
21821
- * @param {string} basename
21822
- * Basename.
21823
- * @returns {undefined}
21824
- * Nothing.
21825
- */
21826
- set basename(basename) {
21827
- assertNonEmpty(basename, 'basename');
21828
- assertPart(basename, 'basename');
21829
- this.path = minpath.join(this.dirname || '', basename);
21830
- }
21831
-
21832
- /**
21833
- * Get the parent path (example: `'~'`).
21834
- *
21835
- * @returns {string | undefined}
21836
- * Dirname.
21837
- */
21838
- get dirname() {
21839
- return typeof this.path === 'string'
21840
- ? minpath.dirname(this.path)
21841
- : undefined
21842
- }
21843
-
21844
- /**
21845
- * Set the parent path (example: `'~'`).
21846
- *
21847
- * Cannot be set if there’s no `path` yet.
21848
- *
21849
- * @param {string | undefined} dirname
21850
- * Dirname.
21851
- * @returns {undefined}
21852
- * Nothing.
21853
- */
21854
- set dirname(dirname) {
21855
- assertPath(this.basename, 'dirname');
21856
- this.path = minpath.join(dirname || '', this.basename);
21857
- }
21858
-
21859
- /**
21860
- * Get the extname (including dot) (example: `'.js'`).
21861
- *
21862
- * @returns {string | undefined}
21863
- * Extname.
21864
- */
21865
- get extname() {
21866
- return typeof this.path === 'string'
21867
- ? minpath.extname(this.path)
21868
- : undefined
21869
- }
21870
-
21871
- /**
21872
- * Set the extname (including dot) (example: `'.js'`).
21873
- *
21874
- * Cannot contain path separators (`'/'` on unix, macOS, and browsers, `'\'`
21875
- * on windows).
21876
- * Cannot be set if there’s no `path` yet.
21877
- *
21878
- * @param {string | undefined} extname
21879
- * Extname.
21880
- * @returns {undefined}
21881
- * Nothing.
21882
- */
21883
- set extname(extname) {
21884
- assertPart(extname, 'extname');
21885
- assertPath(this.dirname, 'extname');
21886
-
21887
- if (extname) {
21888
- if (extname.codePointAt(0) !== 46 /* `.` */) {
21889
- throw new Error('`extname` must start with `.`')
21890
- }
21891
-
21892
- if (extname.includes('.', 1)) {
21893
- throw new Error('`extname` cannot contain multiple dots')
21894
- }
21895
- }
21896
-
21897
- this.path = minpath.join(this.dirname, this.stem + (extname || ''));
21898
- }
21899
-
21900
- /**
21901
- * Get the full path (example: `'~/index.min.js'`).
21902
- *
21903
- * @returns {string}
21904
- * Path.
21905
- */
21906
- get path() {
21907
- return this.history[this.history.length - 1]
21908
- }
21909
-
21910
- /**
21911
- * Set the full path (example: `'~/index.min.js'`).
21912
- *
21913
- * Cannot be nullified.
21914
- * You can set a file URL (a `URL` object with a `file:` protocol) which will
21915
- * be turned into a path with `url.fileURLToPath`.
21916
- *
21917
- * @param {URL | string} path
21918
- * Path.
21919
- * @returns {undefined}
21920
- * Nothing.
21921
- */
21922
- set path(path) {
21923
- if (isUrl(path)) {
21924
- path = urlToPath(path);
21925
- }
21926
-
21927
- assertNonEmpty(path, 'path');
21928
-
21929
- if (this.path !== path) {
21930
- this.history.push(path);
21931
- }
21932
- }
21933
-
21934
- /**
21935
- * Get the stem (basename w/o extname) (example: `'index.min'`).
21936
- *
21937
- * @returns {string | undefined}
21938
- * Stem.
21939
- */
21940
- get stem() {
21941
- return typeof this.path === 'string'
21942
- ? minpath.basename(this.path, this.extname)
21943
- : undefined
21944
- }
21945
-
21946
- /**
21947
- * Set the stem (basename w/o extname) (example: `'index.min'`).
21948
- *
21949
- * Cannot contain path separators (`'/'` on unix, macOS, and browsers, `'\'`
21950
- * on windows).
21951
- * Cannot be nullified (use `file.path = file.dirname` instead).
21952
- *
21953
- * @param {string} stem
21954
- * Stem.
21955
- * @returns {undefined}
21956
- * Nothing.
21957
- */
21958
- set stem(stem) {
21959
- assertNonEmpty(stem, 'stem');
21960
- assertPart(stem, 'stem');
21961
- this.path = minpath.join(this.dirname || '', stem + (this.extname || ''));
21962
- }
21963
-
21964
- // Normal prototypal methods.
21965
- /**
21966
- * Create a fatal message for `reason` associated with the file.
21967
- *
21968
- * The `fatal` field of the message is set to `true` (error; file not usable)
21969
- * and the `file` field is set to the current file path.
21970
- * The message is added to the `messages` field on `file`.
21971
- *
21972
- * > 🪦 **Note**: also has obsolete signatures.
21973
- *
21974
- * @overload
21975
- * @param {string} reason
21976
- * @param {MessageOptions | null | undefined} [options]
21977
- * @returns {never}
21978
- *
21979
- * @overload
21980
- * @param {string} reason
21981
- * @param {Node | NodeLike | null | undefined} parent
21982
- * @param {string | null | undefined} [origin]
21983
- * @returns {never}
21984
- *
21985
- * @overload
21986
- * @param {string} reason
21987
- * @param {Point | Position | null | undefined} place
21988
- * @param {string | null | undefined} [origin]
21989
- * @returns {never}
21990
- *
21991
- * @overload
21992
- * @param {string} reason
21993
- * @param {string | null | undefined} [origin]
21994
- * @returns {never}
21995
- *
21996
- * @overload
21997
- * @param {Error | VFileMessage} cause
21998
- * @param {Node | NodeLike | null | undefined} parent
21999
- * @param {string | null | undefined} [origin]
22000
- * @returns {never}
22001
- *
22002
- * @overload
22003
- * @param {Error | VFileMessage} cause
22004
- * @param {Point | Position | null | undefined} place
22005
- * @param {string | null | undefined} [origin]
22006
- * @returns {never}
22007
- *
22008
- * @overload
22009
- * @param {Error | VFileMessage} cause
22010
- * @param {string | null | undefined} [origin]
22011
- * @returns {never}
22012
- *
22013
- * @param {Error | VFileMessage | string} causeOrReason
22014
- * Reason for message, should use markdown.
22015
- * @param {Node | NodeLike | MessageOptions | Point | Position | string | null | undefined} [optionsOrParentOrPlace]
22016
- * Configuration (optional).
22017
- * @param {string | null | undefined} [origin]
22018
- * Place in code where the message originates (example:
22019
- * `'my-package:my-rule'` or `'my-rule'`).
22020
- * @returns {never}
22021
- * Never.
22022
- * @throws {VFileMessage}
22023
- * Message.
22024
- */
22025
- fail(causeOrReason, optionsOrParentOrPlace, origin) {
22026
- // @ts-expect-error: the overloads are fine.
22027
- const message = this.message(causeOrReason, optionsOrParentOrPlace, origin);
22028
-
22029
- message.fatal = true;
22030
-
22031
- throw message
22032
- }
22033
-
22034
- /**
22035
- * Create an info message for `reason` associated with the file.
22036
- *
22037
- * The `fatal` field of the message is set to `undefined` (info; change
22038
- * likely not needed) and the `file` field is set to the current file path.
22039
- * The message is added to the `messages` field on `file`.
22040
- *
22041
- * > 🪦 **Note**: also has obsolete signatures.
22042
- *
22043
- * @overload
22044
- * @param {string} reason
22045
- * @param {MessageOptions | null | undefined} [options]
22046
- * @returns {VFileMessage}
22047
- *
22048
- * @overload
22049
- * @param {string} reason
22050
- * @param {Node | NodeLike | null | undefined} parent
22051
- * @param {string | null | undefined} [origin]
22052
- * @returns {VFileMessage}
22053
- *
22054
- * @overload
22055
- * @param {string} reason
22056
- * @param {Point | Position | null | undefined} place
22057
- * @param {string | null | undefined} [origin]
22058
- * @returns {VFileMessage}
22059
- *
22060
- * @overload
22061
- * @param {string} reason
22062
- * @param {string | null | undefined} [origin]
22063
- * @returns {VFileMessage}
22064
- *
22065
- * @overload
22066
- * @param {Error | VFileMessage} cause
22067
- * @param {Node | NodeLike | null | undefined} parent
22068
- * @param {string | null | undefined} [origin]
22069
- * @returns {VFileMessage}
22070
- *
22071
- * @overload
22072
- * @param {Error | VFileMessage} cause
22073
- * @param {Point | Position | null | undefined} place
22074
- * @param {string | null | undefined} [origin]
22075
- * @returns {VFileMessage}
22076
- *
22077
- * @overload
22078
- * @param {Error | VFileMessage} cause
22079
- * @param {string | null | undefined} [origin]
22080
- * @returns {VFileMessage}
22081
- *
22082
- * @param {Error | VFileMessage | string} causeOrReason
22083
- * Reason for message, should use markdown.
22084
- * @param {Node | NodeLike | MessageOptions | Point | Position | string | null | undefined} [optionsOrParentOrPlace]
22085
- * Configuration (optional).
22086
- * @param {string | null | undefined} [origin]
22087
- * Place in code where the message originates (example:
22088
- * `'my-package:my-rule'` or `'my-rule'`).
22089
- * @returns {VFileMessage}
22090
- * Message.
22091
- */
22092
- info(causeOrReason, optionsOrParentOrPlace, origin) {
22093
- // @ts-expect-error: the overloads are fine.
22094
- const message = this.message(causeOrReason, optionsOrParentOrPlace, origin);
22095
-
22096
- message.fatal = undefined;
22097
-
22098
- return message
22099
- }
22100
-
22101
- /**
22102
- * Create a message for `reason` associated with the file.
22103
- *
22104
- * The `fatal` field of the message is set to `false` (warning; change may be
22105
- * needed) and the `file` field is set to the current file path.
22106
- * The message is added to the `messages` field on `file`.
22107
- *
22108
- * > 🪦 **Note**: also has obsolete signatures.
22109
- *
22110
- * @overload
22111
- * @param {string} reason
22112
- * @param {MessageOptions | null | undefined} [options]
22113
- * @returns {VFileMessage}
22114
- *
22115
- * @overload
22116
- * @param {string} reason
22117
- * @param {Node | NodeLike | null | undefined} parent
22118
- * @param {string | null | undefined} [origin]
22119
- * @returns {VFileMessage}
22120
- *
22121
- * @overload
22122
- * @param {string} reason
22123
- * @param {Point | Position | null | undefined} place
22124
- * @param {string | null | undefined} [origin]
22125
- * @returns {VFileMessage}
22126
- *
22127
- * @overload
22128
- * @param {string} reason
22129
- * @param {string | null | undefined} [origin]
22130
- * @returns {VFileMessage}
22131
- *
22132
- * @overload
22133
- * @param {Error | VFileMessage} cause
22134
- * @param {Node | NodeLike | null | undefined} parent
22135
- * @param {string | null | undefined} [origin]
22136
- * @returns {VFileMessage}
22137
- *
22138
- * @overload
22139
- * @param {Error | VFileMessage} cause
22140
- * @param {Point | Position | null | undefined} place
22141
- * @param {string | null | undefined} [origin]
22142
- * @returns {VFileMessage}
22143
- *
22144
- * @overload
22145
- * @param {Error | VFileMessage} cause
22146
- * @param {string | null | undefined} [origin]
22147
- * @returns {VFileMessage}
22148
- *
22149
- * @param {Error | VFileMessage | string} causeOrReason
22150
- * Reason for message, should use markdown.
22151
- * @param {Node | NodeLike | MessageOptions | Point | Position | string | null | undefined} [optionsOrParentOrPlace]
22152
- * Configuration (optional).
22153
- * @param {string | null | undefined} [origin]
22154
- * Place in code where the message originates (example:
22155
- * `'my-package:my-rule'` or `'my-rule'`).
22156
- * @returns {VFileMessage}
22157
- * Message.
20932
+ function visitParents(tree, test, visitor, reverse) {
20933
+ /** @type {Test} */
20934
+ let check;
20935
+
20936
+ if (typeof test === 'function' && typeof visitor !== 'function') {
20937
+ reverse = visitor;
20938
+ // @ts-expect-error no visitor given, so `visitor` is test.
20939
+ visitor = test;
20940
+ } else {
20941
+ // @ts-expect-error visitor given, so `test` isn’t a visitor.
20942
+ check = test;
20943
+ }
20944
+
20945
+ const is = convert(check);
20946
+ const step = reverse ? -1 : 1;
20947
+
20948
+ factory(tree, undefined, [])();
20949
+
20950
+ /**
20951
+ * @param {UnistNode} node
20952
+ * @param {number | undefined} index
20953
+ * @param {Array<UnistParent>} parents
22158
20954
  */
22159
- message(causeOrReason, optionsOrParentOrPlace, origin) {
22160
- const message = new VFileMessage(
22161
- // @ts-expect-error: the overloads are fine.
22162
- causeOrReason,
22163
- optionsOrParentOrPlace,
22164
- origin
20955
+ function factory(node, index, parents) {
20956
+ const value = /** @type {Record<string, unknown>} */ (
20957
+ node && typeof node === 'object' ? node : {}
22165
20958
  );
22166
20959
 
22167
- if (this.path) {
22168
- message.name = this.path + ':' + message.name;
22169
- message.file = this.path;
20960
+ if (typeof value.type === 'string') {
20961
+ const name =
20962
+ // `hast`
20963
+ typeof value.tagName === 'string'
20964
+ ? value.tagName
20965
+ : // `xast`
20966
+ typeof value.name === 'string'
20967
+ ? value.name
20968
+ : undefined;
20969
+
20970
+ Object.defineProperty(visit, 'name', {
20971
+ value:
20972
+ 'node (' + color(node.type + (name ? '<' + name + '>' : '')) + ')'
20973
+ });
22170
20974
  }
22171
20975
 
22172
- message.fatal = false;
20976
+ return visit
22173
20977
 
22174
- this.messages.push(message);
20978
+ function visit() {
20979
+ /** @type {Readonly<ActionTuple>} */
20980
+ let result = empty;
20981
+ /** @type {Readonly<ActionTuple>} */
20982
+ let subresult;
20983
+ /** @type {number} */
20984
+ let offset;
20985
+ /** @type {Array<UnistParent>} */
20986
+ let grandparents;
22175
20987
 
22176
- return message
22177
- }
20988
+ if (!test || is(node, index, parents[parents.length - 1] || undefined)) {
20989
+ // @ts-expect-error: `visitor` is now a visitor.
20990
+ result = toResult(visitor(node, parents));
22178
20991
 
22179
- /**
22180
- * Serialize the file.
22181
- *
22182
- * > **Note**: which encodings are supported depends on the engine.
22183
- * > For info on Node.js, see:
22184
- * > <https://nodejs.org/api/util.html#whatwg-supported-encodings>.
22185
- *
22186
- * @param {string | null | undefined} [encoding='utf8']
22187
- * Character encoding to understand `value` as when it’s a `Uint8Array`
22188
- * (default: `'utf-8'`).
22189
- * @returns {string}
22190
- * Serialized file.
22191
- */
22192
- toString(encoding) {
22193
- if (this.value === undefined) {
22194
- return ''
22195
- }
20992
+ if (result[0] === EXIT) {
20993
+ return result
20994
+ }
20995
+ }
22196
20996
 
22197
- if (typeof this.value === 'string') {
22198
- return this.value
22199
- }
20997
+ if ('children' in node && node.children) {
20998
+ const nodeAsParent = /** @type {UnistParent} */ (node);
22200
20999
 
22201
- const decoder = new TextDecoder(encoding || undefined);
22202
- return decoder.decode(this.value)
21000
+ if (nodeAsParent.children && result[0] !== SKIP) {
21001
+ offset = (reverse ? nodeAsParent.children.length : -1) + step;
21002
+ grandparents = parents.concat(nodeAsParent);
21003
+
21004
+ while (offset > -1 && offset < nodeAsParent.children.length) {
21005
+ const child = nodeAsParent.children[offset];
21006
+
21007
+ subresult = factory(child, offset, grandparents)();
21008
+
21009
+ if (subresult[0] === EXIT) {
21010
+ return subresult
21011
+ }
21012
+
21013
+ offset =
21014
+ typeof subresult[1] === 'number' ? subresult[1] : offset + step;
21015
+ }
21016
+ }
21017
+ }
21018
+
21019
+ return result
21020
+ }
22203
21021
  }
22204
21022
  }
22205
21023
 
22206
21024
  /**
22207
- * Assert that `part` is not a path (as in, does not contain `path.sep`).
21025
+ * Turn a return value into a clean result.
22208
21026
  *
22209
- * @param {string | null | undefined} part
22210
- * File path part.
22211
- * @param {string} name
22212
- * Part name.
22213
- * @returns {undefined}
22214
- * Nothing.
21027
+ * @param {VisitorResult} value
21028
+ * Valid return values from visitors.
21029
+ * @returns {Readonly<ActionTuple>}
21030
+ * Clean result.
22215
21031
  */
22216
- function assertPart(part, name) {
22217
- if (part && part.includes(minpath.sep)) {
22218
- throw new Error(
22219
- '`' + name + '` cannot be a path: did not expect `' + minpath.sep + '`'
22220
- )
21032
+ function toResult(value) {
21033
+ if (Array.isArray(value)) {
21034
+ return value
21035
+ }
21036
+
21037
+ if (typeof value === 'number') {
21038
+ return [CONTINUE, value]
22221
21039
  }
21040
+
21041
+ return value === null || value === undefined ? empty : [value]
22222
21042
  }
22223
21043
 
22224
21044
  /**
22225
- * Assert that `part` is not empty.
22226
- *
22227
- * @param {string | undefined} part
22228
- * Thing.
22229
- * @param {string} name
22230
- * Part name.
22231
- * @returns {asserts part is string}
22232
- * Nothing.
21045
+ * @typedef {import('unist').Node} UnistNode
21046
+ * @typedef {import('unist').Parent} UnistParent
21047
+ * @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult
22233
21048
  */
22234
- function assertNonEmpty(part, name) {
22235
- if (!part) {
22236
- throw new Error('`' + name + '` cannot be empty')
22237
- }
22238
- }
21049
+
22239
21050
 
22240
21051
  /**
22241
- * Assert `path` exists.
21052
+ * Visit nodes.
22242
21053
  *
22243
- * @param {string | undefined} path
22244
- * Path.
22245
- * @param {string} name
22246
- * Dependency name.
22247
- * @returns {asserts path is string}
21054
+ * This algorithm performs *depth-first* *tree traversal* in *preorder*
21055
+ * (**NLR**) or if `reverse` is given, in *reverse preorder* (**NRL**).
21056
+ *
21057
+ * You can choose for which nodes `visitor` is called by passing a `test`.
21058
+ * For complex tests, you should test yourself in `visitor`, as it will be
21059
+ * faster and will have improved type information.
21060
+ *
21061
+ * Walking the tree is an intensive task.
21062
+ * Make use of the return values of the visitor when possible.
21063
+ * Instead of walking a tree multiple times, walk it once, use `unist-util-is`
21064
+ * to check if a node matches, and then perform different operations.
21065
+ *
21066
+ * You can change the tree.
21067
+ * See `Visitor` for more info.
21068
+ *
21069
+ * @overload
21070
+ * @param {Tree} tree
21071
+ * @param {Check} check
21072
+ * @param {BuildVisitor<Tree, Check>} visitor
21073
+ * @param {boolean | null | undefined} [reverse]
21074
+ * @returns {undefined}
21075
+ *
21076
+ * @overload
21077
+ * @param {Tree} tree
21078
+ * @param {BuildVisitor<Tree>} visitor
21079
+ * @param {boolean | null | undefined} [reverse]
21080
+ * @returns {undefined}
21081
+ *
21082
+ * @param {UnistNode} tree
21083
+ * Tree to traverse.
21084
+ * @param {Visitor | Test} testOrVisitor
21085
+ * `unist-util-is`-compatible test (optional, omit to pass a visitor).
21086
+ * @param {Visitor | boolean | null | undefined} [visitorOrReverse]
21087
+ * Handle each node (when test is omitted, pass `reverse`).
21088
+ * @param {boolean | null | undefined} [maybeReverse=false]
21089
+ * Traverse in reverse preorder (NRL) instead of the default preorder (NLR).
21090
+ * @returns {undefined}
22248
21091
  * Nothing.
21092
+ *
21093
+ * @template {UnistNode} Tree
21094
+ * Node type.
21095
+ * @template {Test} Check
21096
+ * `unist-util-is`-compatible test.
22249
21097
  */
22250
- function assertPath(path, name) {
22251
- if (!path) {
22252
- throw new Error('Setting `' + name + '` requires `path` to be set too')
21098
+ function visit(tree, testOrVisitor, visitorOrReverse, maybeReverse) {
21099
+ /** @type {boolean | null | undefined} */
21100
+ let reverse;
21101
+ /** @type {Test} */
21102
+ let test;
21103
+ /** @type {Visitor} */
21104
+ let visitor;
21105
+
21106
+ if (
21107
+ typeof testOrVisitor === 'function' &&
21108
+ typeof visitorOrReverse !== 'function'
21109
+ ) {
21110
+ test = undefined;
21111
+ visitor = testOrVisitor;
21112
+ reverse = visitorOrReverse;
21113
+ } else {
21114
+ // @ts-expect-error: assume the overload with test was given.
21115
+ test = testOrVisitor;
21116
+ // @ts-expect-error: assume the overload with test was given.
21117
+ visitor = visitorOrReverse;
21118
+ reverse = maybeReverse;
22253
21119
  }
22254
- }
22255
21120
 
22256
- /**
22257
- * Assert `value` is an `Uint8Array`.
22258
- *
22259
- * @param {unknown} value
22260
- * thing.
22261
- * @returns {value is Uint8Array}
22262
- * Whether `value` is an `Uint8Array`.
22263
- */
22264
- function isUint8Array(value) {
22265
- return Boolean(
22266
- value &&
22267
- typeof value === 'object' &&
22268
- 'byteLength' in value &&
22269
- 'byteOffset' in value
22270
- )
21121
+ visitParents(tree, test, overload, reverse);
21122
+
21123
+ /**
21124
+ * @param {UnistNode} node
21125
+ * @param {Array<UnistParent>} parents
21126
+ */
21127
+ function overload(node, parents) {
21128
+ const parent = parents[parents.length - 1];
21129
+ const index = parent ? parent.children.indexOf(node) : undefined;
21130
+ return visitor(node, index, parent)
21131
+ }
22271
21132
  }
22272
21133
 
22273
21134
  /**