@lousy-agents/mcp 5.22.16 → 5.22.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/mcp-server.js +585 -237
  2. package/package.json +1 -1
@@ -61621,7 +61621,8 @@ const lockFiles = [
61621
61621
  "npm-shrinkwrap.json",
61622
61622
  "bun.lockb",
61623
61623
  "bun.lock",
61624
- "deno.lock"
61624
+ "deno.lock",
61625
+ "upm.lock"
61625
61626
  ];
61626
61627
  const packageFiles = [
61627
61628
  "package.json",
@@ -61855,11 +61856,27 @@ async function readGitConfig(dir, opts) {
61855
61856
  async function writeGitConfig(path, config) {
61856
61857
  await writeFile(path, stringifyGitConfig(config));
61857
61858
  }
61859
+ const _unescapeGitSubsection = (name) => name.replaceAll(/\\(.)/g, "$1");
61860
+ const _escapeGitSubsection = (name) => name.replaceAll(/(["\\])/g, "\\$1");
61861
+ const _escapeINISection = (name) => name.replaceAll("\\", String.raw`\\`).replaceAll(".", String.raw`\.`);
61862
+ const _encodeINISection = (name) => encodeURIComponent(name).replaceAll(".", "%2E");
61863
+ const _decodeINISection = (name) => decodeURIComponent(name);
61864
+ const _isSubsection = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
61858
61865
  function parseGitConfig(ini) {
61859
- return parseINI(ini.replaceAll(/^\[(\w+) "(.+)"\]$/gm, "[$1.$2]"));
61866
+ return parseINI(ini.replaceAll(/^\[(\w+) "(.*)"\]$/gm, (_, section, subsection) => `[${section}.${_escapeINISection(_unescapeGitSubsection(subsection))}]`));
61860
61867
  }
61861
61868
  function stringifyGitConfig(config) {
61862
- return stringifyINI(config).replaceAll(/^\[(\w+)\.(\w+)\]$/gm, "[$1 \"$2\"]");
61869
+ const encoded = {};
61870
+ for (const [section, value] of Object.entries(config)) {
61871
+ if (!_isSubsection(value)) {
61872
+ encoded[section] = value;
61873
+ continue;
61874
+ }
61875
+ const entries = {};
61876
+ for (const [key, subValue] of Object.entries(value)) entries[_isSubsection(subValue) ? _encodeINISection(key) : key] = subValue;
61877
+ encoded[section] = entries;
61878
+ }
61879
+ return stringifyINI(encoded).replaceAll(/^\[(\w+)\.(.*)\]$/gm, (_, section, subsection) => `[${section} "${_escapeGitSubsection(_decodeINISection(subsection))}"]`);
61863
61880
  }
61864
61881
 
61865
61882
 
@@ -90330,8 +90347,12 @@ function encodeCharacterReference(code) {
90330
90347
 
90331
90348
  ;// CONCATENATED MODULE: ../../node_modules/unist-util-visit-parents/lib/color.node.js
90332
90349
  /**
90350
+ * Color a string.
90351
+ *
90333
90352
  * @param {string} d
90353
+ * Value.
90334
90354
  * @returns {string}
90355
+ * Colored value.
90335
90356
  */
90336
90357
  function color_node_color(d) {
90337
90358
  return '\u001B[33m' + d + '\u001B[39m'
@@ -90507,46 +90528,98 @@ function color_node_color(d) {
90507
90528
  * List with one or two values, the first an action, the second an index.
90508
90529
  *
90509
90530
  * @typedef {Action | ActionTuple | Index | null | undefined | void} VisitorResult
90510
- * Any value that can be returned from a visitor.
90531
+ * Any value that can be returned from an enter visitor.
90532
+ *
90533
+ * Like `VisitorResultExit`,
90534
+ * but `SKIP` can also be returned,
90535
+ * to not walk the children of the node,
90536
+ * and `ActionTuple` can be used to combine an action with an index.
90537
+ *
90538
+ * @typedef {Index | boolean | null | undefined | void} VisitorResultExit
90539
+ * Any value that can be returned from an exit visitor.
90511
90540
  */
90512
90541
 
90513
90542
  /**
90514
90543
  * @callback Visitor
90515
- * Handle a node (matching `test`, if given).
90516
- *
90517
- * Visitors are free to transform `node`.
90518
- * They can also transform the parent of node (the last of `ancestors`).
90519
- *
90520
- * Replacing `node` itself, if `SKIP` is not returned, still causes its
90521
- * descendants to be walked (which is a bug).
90522
- *
90523
- * When adding or removing previous siblings of `node` (or next siblings, in
90524
- * case of reverse), the `Visitor` should return a new `Index` to specify the
90525
- * sibling to traverse after `node` is traversed.
90526
- * Adding or removing next siblings of `node` (or previous siblings, in case
90527
- * of reverse) is handled as expected without needing to return a new `Index`.
90528
- *
90529
- * Removing the children property of an ancestor still results in them being
90530
- * traversed.
90544
+ * Handle a node (matching `test`, if given) before its children.
90545
+ *
90546
+ * Changes inside `node` are walked next.
90547
+ * Replacing or removing it is easier in `exit`.
90548
+ * When replacing or removing it here,
90549
+ * return `SKIP` (as otherwise its old children are walked),
90550
+ * or `[SKIP, index]` to continue with the node now at `index`.
90551
+ * Changing next siblings (in walk order) is fine;
90552
+ * changing previous siblings needs a new `Index`.
90553
+ * Removing an ancestor or changing its previous siblings is not supported.
90531
90554
  * @param {Visited} node
90532
90555
  * Found node.
90533
90556
  * @param {Array<VisitedParents>} ancestors
90534
90557
  * Ancestors of `node`.
90558
+ * @param {number | undefined} index
90559
+ * Index of `node` in its parent (the last of `ancestors`),
90560
+ * or `undefined` for the tree itself.
90535
90561
  * @returns {VisitorResult}
90536
90562
  * What to do next.
90537
90563
  *
90538
- * An `Index` is treated as a tuple of `[CONTINUE, Index]`.
90539
- * An `Action` is treated as a tuple of `[Action]`.
90564
+ * Like `VisitorExit`,
90565
+ * but `SKIP` can also be returned,
90566
+ * to not walk the children of `node`.
90567
+ * Passing a tuple back (`ActionTuple`) only makes sense as `[SKIP, Index]`.
90568
+ * @template {UnistNode} [Visited=UnistNode]
90569
+ * Visited node type.
90570
+ * @template {UnistParent} [VisitedParents=UnistParent]
90571
+ * Ancestor type.
90572
+ */
90573
+
90574
+ /**
90575
+ * @callback VisitorExit
90576
+ * Handle a node (matching `test`, if given) after its children.
90540
90577
  *
90541
- * Passing a tuple back only makes sense if the `Action` is `SKIP`.
90542
- * When the `Action` is `EXIT`, that action can be returned.
90543
- * When the `Action` is `CONTINUE`, `Index` can be returned.
90578
+ * Changes inside `node` are not walked,
90579
+ * which makes this a good place to change `node` based on its children,
90580
+ * or to replace or remove it.
90581
+ * When removing `node` or changing previous siblings (in walk order),
90582
+ * return a new `Index`.
90583
+ * Removing an ancestor or changing its previous siblings is not supported.
90584
+ * @param {Visited} node
90585
+ * Found node.
90586
+ * @param {Array<VisitedParents>} ancestors
90587
+ * Ancestors of `node`.
90588
+ * @param {number | undefined} index
90589
+ * Index of `node` in its parent (the last of `ancestors`),
90590
+ * or `undefined` for the tree itself.
90591
+ * @returns {VisitorResultExit}
90592
+ * What to do next.
90593
+ *
90594
+ * `CONTINUE` (`true`, nothing) continues as normal,
90595
+ * `EXIT` (`false`) stops traversing,
90596
+ * and `Index` continues at that sibling.
90544
90597
  * @template {UnistNode} [Visited=UnistNode]
90545
90598
  * Visited node type.
90546
90599
  * @template {UnistParent} [VisitedParents=UnistParent]
90547
90600
  * Ancestor type.
90548
90601
  */
90549
90602
 
90603
+ /**
90604
+ * @template {UnistNode} [Visited=UnistNode]
90605
+ * Visited node type.
90606
+ * @template {UnistParent} [VisitedParents=UnistParent]
90607
+ * Ancestor type.
90608
+ * @typedef Visitors
90609
+ * Handle nodes when entering and exiting them.
90610
+ * The `enter` visitor is optional while `exit` is required.
90611
+ *
90612
+ * Pass an `enter` visitor directly to only handle nodes when entering them.
90613
+ *
90614
+ * `enter` is called before children (if any) are walked and `exit` after that.
90615
+ * `exit` is still called when `enter` returns `SKIP`.
90616
+ * Both `enter` and `exit` are only called for nodes that match an optional `test`.
90617
+ * @property {Visitor<Visited, VisitedParents> | null | undefined} [enter]
90618
+ * Handle a node before its children (optional).
90619
+ * @property {VisitorExit<Visited, VisitedParents>} exit
90620
+ * Handle a node after its children.
90621
+ */
90622
+
90550
90623
  /**
90551
90624
  * @typedef {Visitor<Matches<InclusiveDescendant<Tree>, Check>, Ancestor<Tree, Matches<InclusiveDescendant<Tree>, Check>>>} BuildVisitor
90552
90625
  * Build a typed `Visitor` function from a tree and a test.
@@ -90558,6 +90631,17 @@ function color_node_color(d) {
90558
90631
  * Test type.
90559
90632
  */
90560
90633
 
90634
+ /**
90635
+ * @typedef {Visitors<Matches<InclusiveDescendant<Tree>, Check>, Ancestor<Tree, Matches<InclusiveDescendant<Tree>, Check>>>} BuildVisitors
90636
+ * Build typed `Visitors` from a tree and a test.
90637
+ *
90638
+ * It will infer which values are passed as `node` and which as `parents`.
90639
+ * @template {UnistNode} [Tree=UnistNode]
90640
+ * Tree type.
90641
+ * @template {Test} [Check=Test]
90642
+ * Test type.
90643
+ */
90644
+
90561
90645
 
90562
90646
 
90563
90647
 
@@ -90576,6 +90660,7 @@ const EXIT = false
90576
90660
 
90577
90661
  /**
90578
90662
  * Do not traverse this node’s children.
90663
+ * Only works when entering a node.
90579
90664
  */
90580
90665
  const SKIP = 'skip'
90581
90666
 
@@ -90583,10 +90668,13 @@ const SKIP = 'skip'
90583
90668
  * Visit nodes, with ancestral information.
90584
90669
  *
90585
90670
  * This algorithm performs *depth-first* *tree traversal* in *preorder*
90586
- * (**NLR**) or if `reverse` is given, in *reverse preorder* (**NRL**).
90671
+ * (**NLR**) or if `reverse` is given,
90672
+ * in *reverse preorder* (**NRL**).
90673
+ * An `exit` visitor is called in *postorder* (**LRN**)
90674
+ * or if `reverse` is given, in *reverse postorder* (**RLN**).
90587
90675
  *
90588
- * You can choose for which nodes `visitor` is called by passing a `test`.
90589
- * For complex tests, you should test yourself in `visitor`, as it will be
90676
+ * You can choose which nodes are visited by passing a `test`.
90677
+ * For complex tests, you should test yourself in a visitor, as it will be
90590
90678
  * faster and will have improved type information.
90591
90679
  *
90592
90680
  * Walking the tree is an intensive task.
@@ -90595,29 +90683,72 @@ const SKIP = 'skip'
90595
90683
  * to check if a node matches, and then perform different operations.
90596
90684
  *
90597
90685
  * You can change the tree.
90598
- * See `Visitor` for more info.
90686
+ * Changes inside a node made when entering it are walked,
90687
+ * changes made when exiting it are not.
90688
+ * See `Visitor` and `VisitorExit` for more info.
90599
90689
  *
90600
90690
  * @overload
90601
90691
  * @param {Tree} tree
90692
+ * Tree to traverse.
90602
90693
  * @param {Check} check
90603
- * @param {BuildVisitor<Tree, Check>} visitor
90694
+ * `unist-util-is`-compatible test.
90695
+ * @param {BuildVisitor<Tree, Check>} enter
90696
+ * Handle each node when entering it.
90697
+ * @param {boolean | null | undefined} [reverse]
90698
+ * Walk children from last to first;
90699
+ * for `enter`, reverse preorder (NRL) instead of preorder (NLR);
90700
+ * for `exit`, reverse postorder (RLN) instead of postorder (LRN).
90701
+ * @returns {undefined}
90702
+ * Nothing.
90703
+ *
90704
+ * @overload
90705
+ * @param {Tree} tree
90706
+ * Tree to traverse.
90707
+ * @param {Check} check
90708
+ * `unist-util-is`-compatible test.
90709
+ * @param {BuildVisitors<Tree, Check>} visitors
90710
+ * Handle each node when exiting it, and optionally when entering it.
90711
+ * @param {boolean | null | undefined} [reverse]
90712
+ * Walk children from last to first;
90713
+ * for `enter`, reverse preorder (NRL) instead of preorder (NLR);
90714
+ * for `exit`, reverse postorder (RLN) instead of postorder (LRN).
90715
+ * @returns {undefined}
90716
+ * Nothing.
90717
+ *
90718
+ * @overload
90719
+ * @param {Tree} tree
90720
+ * Tree to traverse.
90721
+ * @param {BuildVisitor<Tree>} enter
90722
+ * Handle each node when entering it.
90604
90723
  * @param {boolean | null | undefined} [reverse]
90724
+ * Walk children from last to first;
90725
+ * for `enter`, reverse preorder (NRL) instead of preorder (NLR);
90726
+ * for `exit`, reverse postorder (RLN) instead of postorder (LRN).
90605
90727
  * @returns {undefined}
90728
+ * Nothing.
90606
90729
  *
90607
90730
  * @overload
90608
90731
  * @param {Tree} tree
90609
- * @param {BuildVisitor<Tree>} visitor
90732
+ * Tree to traverse.
90733
+ * @param {BuildVisitors<Tree>} visitors
90734
+ * Handle each node when exiting it, and optionally when entering it.
90610
90735
  * @param {boolean | null | undefined} [reverse]
90736
+ * Walk children from last to first;
90737
+ * for `enter`, reverse preorder (NRL) instead of preorder (NLR);
90738
+ * for `exit`, reverse postorder (RLN) instead of postorder (LRN).
90611
90739
  * @returns {undefined}
90740
+ * Nothing.
90612
90741
  *
90613
90742
  * @param {UnistNode} tree
90614
90743
  * Tree to traverse.
90615
- * @param {Visitor | Test} test
90616
- * `unist-util-is`-compatible test
90617
- * @param {Visitor | boolean | null | undefined} [visitor]
90618
- * Handle each node.
90744
+ * @param {Visitor | Visitors | Test} testOrEnterOrVisitors
90745
+ * `unist-util-is`-compatible test, `enter`, or `visitors`.
90746
+ * @param {Visitor | Visitors | boolean | null | undefined} [enterOrVisitorsOrReverse]
90747
+ * `enter`, `visitors`, or `reverse` after a test.
90619
90748
  * @param {boolean | null | undefined} [reverse]
90620
- * Traverse in reverse preorder (NRL) instead of the default preorder (NLR).
90749
+ * Walk children from last to first;
90750
+ * for `enter`, reverse preorder (NRL) instead of preorder (NLR);
90751
+ * for `exit`, reverse postorder (RLN) instead of postorder (LRN).
90621
90752
  * @returns {undefined}
90622
90753
  * Nothing.
90623
90754
  *
@@ -90626,28 +90757,89 @@ const SKIP = 'skip'
90626
90757
  * @template {Test} Check
90627
90758
  * `unist-util-is`-compatible test.
90628
90759
  */
90629
- function visitParents(tree, test, visitor, reverse) {
90760
+ function visitParents(
90761
+ tree,
90762
+ testOrEnterOrVisitors,
90763
+ enterOrVisitorsOrReverse,
90764
+ reverse
90765
+ ) {
90766
+ if (!tree || typeof tree !== 'object') {
90767
+ throw new Error('Unexpected value `' + tree + '` for `tree`, expected node')
90768
+ }
90769
+
90770
+ let preorder = true
90630
90771
  /** @type {Test} */
90631
90772
  let check
90773
+ /** @type {Visitors | Visitor} */
90774
+ let visitors
90775
+ /** @type {Visitor | null | undefined} */
90776
+ let enter
90777
+ /** @type {VisitorExit | null | undefined} */
90778
+ let exit
90779
+
90780
+ // Third parameter is an enter visitor or a visitors object, so expect a `test` too.
90781
+ if (
90782
+ typeof enterOrVisitorsOrReverse === 'function' ||
90783
+ (enterOrVisitorsOrReverse && typeof enterOrVisitorsOrReverse === 'object')
90784
+ ) {
90785
+ check = /** @type {Test} */ (testOrEnterOrVisitors)
90786
+ visitors = enterOrVisitorsOrReverse
90787
+ if (reverse) preorder = false
90788
+ }
90789
+ // Assume no test.
90790
+ else {
90791
+ visitors = /** @type {Visitors | Visitor} */ (testOrEnterOrVisitors)
90792
+ if (enterOrVisitorsOrReverse) preorder = false
90793
+ }
90632
90794
 
90633
- if (typeof test === 'function' && typeof visitor !== 'function') {
90634
- reverse = visitor
90635
- // @ts-expect-error no visitor given, so `visitor` is test.
90636
- visitor = test
90795
+ if (typeof visitors === 'function') {
90796
+ enter = visitors
90797
+ } else if (visitors && typeof visitors === 'object') {
90798
+ if (visitors.enter === null || visitors.enter === undefined) {
90799
+ // Empty.
90800
+ } else if (typeof visitors.enter === 'function') {
90801
+ enter = visitors.enter
90802
+ } else {
90803
+ throw new Error(
90804
+ 'Unexpected value `' +
90805
+ visitors.enter +
90806
+ '` for `visitors.enter`, expected optional visitor'
90807
+ )
90808
+ }
90809
+
90810
+ if (typeof visitors.exit === 'function') {
90811
+ exit = visitors.exit
90812
+ } else {
90813
+ throw new Error(
90814
+ 'Unexpected value `' +
90815
+ visitors.exit +
90816
+ '` for `visitors.exit`, expected visitor (pass a visitor directly if you only want an enter visitor)'
90817
+ )
90818
+ }
90637
90819
  } else {
90638
- // @ts-expect-error visitor given, so `test` isn’t a visitor.
90639
- check = test
90820
+ throw new Error(
90821
+ 'Unexpected value `' +
90822
+ visitors +
90823
+ '` for `enter` or `visitors`, expected visitor or object with visitors'
90824
+ )
90640
90825
  }
90641
90826
 
90642
90827
  const is = convert(check)
90643
- const step = reverse ? -1 : 1
90828
+ const step = preorder ? 1 : -1
90644
90829
 
90645
90830
  factory(tree, undefined, [])()
90646
90831
 
90647
90832
  /**
90833
+ * Create a function to visit a node.
90834
+ *
90648
90835
  * @param {UnistNode} node
90836
+ * Node to visit.
90649
90837
  * @param {number | undefined} index
90838
+ * Index of `node` in its parent.
90650
90839
  * @param {Array<UnistParent>} parents
90840
+ * Ancestors of `node`.
90841
+ * @returns {() => Readonly<ActionTuple>}
90842
+ * Visit `node`.
90651
90843
  */
90652
90844
  function factory(node, index, parents) {
90653
90845
  const value = /** @type {Record<string, unknown>} */ (
@@ -90673,18 +90865,13 @@ function visitParents(tree, test, visitor, reverse) {
90673
90865
  return visit
90674
90866
 
90675
90867
  function visit() {
90868
+ const matches =
90869
+ !check || is(node, index, parents[parents.length - 1] || undefined)
90676
90870
  /** @type {Readonly<ActionTuple>} */
90677
90871
  let result = lib_empty
90678
- /** @type {Readonly<ActionTuple>} */
90679
- let subresult
90680
- /** @type {number} */
90681
- let offset
90682
- /** @type {Array<UnistParent>} */
90683
- let grandparents
90684
90872
 
90685
- if (!test || is(node, index, parents[parents.length - 1] || undefined)) {
90686
- // @ts-expect-error: `visitor` is now a visitor.
90687
- result = toResult(visitor(node, parents))
90873
+ if (enter && matches) {
90874
+ result = toResult(enter(node, parents, index))
90688
90875
 
90689
90876
  if (result[0] === EXIT) {
90690
90877
  return result
@@ -90695,13 +90882,13 @@ function visitParents(tree, test, visitor, reverse) {
90695
90882
  const nodeAsParent = /** @type {UnistParent} */ (node)
90696
90883
 
90697
90884
  if (nodeAsParent.children && result[0] !== SKIP) {
90698
- offset = (reverse ? nodeAsParent.children.length : -1) + step
90699
- grandparents = parents.concat(nodeAsParent)
90885
+ let offset = (preorder ? -1 : nodeAsParent.children.length) + step
90886
+ const grandparents = [...parents, nodeAsParent]
90700
90887
 
90701
90888
  while (offset > -1 && offset < nodeAsParent.children.length) {
90702
90889
  const child = nodeAsParent.children[offset]
90703
90890
 
90704
- subresult = factory(child, offset, grandparents)()
90891
+ const subresult = factory(child, offset, grandparents)()
90705
90892
 
90706
90893
  if (subresult[0] === EXIT) {
90707
90894
  return subresult
@@ -90713,6 +90900,23 @@ function visitParents(tree, test, visitor, reverse) {
90713
90900
  }
90714
90901
  }
90715
90902
 
90903
+ if (exit && matches) {
90904
+ const exitResult = toResult(exit(node, parents, index))
90905
+
90906
+ if (exitResult[0] === SKIP) {
90907
+ throw new Error(
90908
+ 'Unexpected value `' +
90909
+ exitResult[0] +
90910
+ '` from `exit`, expected `CONTINUE`, `EXIT`, index, or nothing'
90911
+ )
90912
+ }
90913
+
90914
+ // Prefer a result from `exit` over `enter`.
90915
+ if (exitResult[0] === EXIT || typeof exitResult[1] === 'number') {
90916
+ return exitResult
90917
+ }
90918
+ }
90919
+
90716
90920
  return result
90717
90921
  }
90718
90922
  }
@@ -90741,7 +90945,13 @@ function toResult(value) {
90741
90945
  ;// CONCATENATED MODULE: ../../node_modules/unist-util-visit/lib/index.js
90742
90946
  /**
90743
90947
  * @import {Node as UnistNode, Parent as UnistParent} from 'unist'
90744
- * @import {VisitorResult} from 'unist-util-visit-parents'
90948
+ * @import {
90949
+ * InclusiveDescendant,
90950
+ * Matches,
90951
+ * Visitors as ParentsVisitors,
90952
+ * VisitorResult,
90953
+ * VisitorResultExit
90954
+ * } from 'unist-util-visit-parents'
90745
90955
  */
90746
90956
 
90747
90957
  /**
@@ -90753,67 +90963,6 @@ function toResult(value) {
90753
90963
  * which doesn’t work when publishing on npm.
90754
90964
  */
90755
90965
 
90756
- // To do: use types from `unist-util-visit-parents` when it’s released.
90757
-
90758
- /**
90759
- * @typedef {(
90760
- * Fn extends (value: any) => value is infer Thing
90761
- * ? Thing
90762
- * : Fallback
90763
- * )} Predicate
90764
- * Get the value of a type guard `Fn`.
90765
- * @template Fn
90766
- * Value; typically function that is a type guard (such as `(x): x is Y`).
90767
- * @template Fallback
90768
- * Value to yield if `Fn` is not a type guard.
90769
- */
90770
-
90771
- /**
90772
- * @typedef {(
90773
- * Check extends null | undefined // No test.
90774
- * ? Value
90775
- * : Value extends {type: Check} // String (type) test.
90776
- * ? Value
90777
- * : Value extends Check // Partial test.
90778
- * ? Value
90779
- * : Check extends Function // Function test.
90780
- * ? Predicate<Check, Value> extends Value
90781
- * ? Predicate<Check, Value>
90782
- * : never
90783
- * : never // Some other test?
90784
- * )} MatchesOne
90785
- * Check whether a node matches a primitive check in the type system.
90786
- * @template Value
90787
- * Value; typically unist `Node`.
90788
- * @template Check
90789
- * Value; typically `unist-util-is`-compatible test, but not arrays.
90790
- */
90791
-
90792
- /**
90793
- * @typedef {(
90794
- * Check extends ReadonlyArray<any>
90795
- * ? MatchesOne<Value, Check[number]>
90796
- * : MatchesOne<Value, Check>
90797
- * )} Matches
90798
- * Check whether a node matches a check in the type system.
90799
- * @template Value
90800
- * Value; typically unist `Node`.
90801
- * @template Check
90802
- * Value; typically `unist-util-is`-compatible test.
90803
- */
90804
-
90805
- /**
90806
- * @typedef {0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10} Uint
90807
- * Number; capped reasonably.
90808
- */
90809
-
90810
- /**
90811
- * @typedef {I extends 0 ? 1 : I extends 1 ? 2 : I extends 2 ? 3 : I extends 3 ? 4 : I extends 4 ? 5 : I extends 5 ? 6 : I extends 6 ? 7 : I extends 7 ? 8 : I extends 8 ? 9 : 10} Increment
90812
- * Increment a number in the type system.
90813
- * @template {Uint} [I=0]
90814
- * Index.
90815
- */
90816
-
90817
90966
  /**
90818
90967
  * @typedef {(
90819
90968
  * Node extends UnistParent
@@ -90839,89 +90988,64 @@ function toResult(value) {
90839
90988
  */
90840
90989
 
90841
90990
  /**
90842
- * @typedef {(
90843
- * Depth extends Max
90844
- * ? never
90845
- * :
90846
- * | InternalParent<Node, Child>
90847
- * | InternalAncestor<Node, InternalParent<Node, Child>, Max, Increment<Depth>>
90848
- * )} InternalAncestor
90849
- * Collect nodes in `Tree` that can be ancestors of `Child`.
90850
- * @template {UnistNode} Node
90851
- * All node types in a tree.
90852
- * @template {UnistNode} Child
90853
- * Node to search for.
90854
- * @template {Uint} [Max=10]
90855
- * Max; searches up to this depth.
90856
- * @template {Uint} [Depth=0]
90857
- * Current depth.
90858
- */
90859
-
90860
- /**
90861
- * @typedef {(
90862
- * Tree extends UnistParent
90863
- * ? Depth extends Max
90864
- * ? Tree
90865
- * : Tree | InclusiveDescendant<Tree['children'][number], Max, Increment<Depth>>
90866
- * : Tree
90867
- * )} InclusiveDescendant
90868
- * Collect all (inclusive) descendants of `Tree`.
90991
+ * @callback Visitor
90992
+ * Handle a node (matching `test`, if given) before its children.
90869
90993
  *
90870
- * > 👉 **Note**: for performance reasons, this seems to be the fastest way to
90871
- * > recurse without actually running into an infinite loop, which the
90872
- * > previous version did.
90873
- * >
90874
- * > Practically, a max of `2` is typically enough assuming a `Root` is
90875
- * > passed, but it doesn’t improve performance.
90876
- * > It gets higher with `List > ListItem > Table > TableRow > TableCell`.
90877
- * > Using up to `10` doesn’t hurt or help either.
90878
- * @template {UnistNode} Tree
90879
- * Tree type.
90880
- * @template {Uint} [Max=10]
90881
- * Max; searches up to this depth.
90882
- * @template {Uint} [Depth=0]
90883
- * Current depth.
90994
+ * Like `Visitor` in `unist-util-visit-parents`,
90995
+ * but with `index` and `parent` instead of `parents`.
90996
+ * @param {Visited} node
90997
+ * Found node.
90998
+ * @param {Visited extends UnistNode ? number | undefined : never} index
90999
+ * Index of `node` in `parent`,
91000
+ * or `undefined` for the tree itself.
91001
+ * @param {Ancestor extends UnistParent ? Ancestor | undefined : never} parent
91002
+ * Parent of `node`,
91003
+ * or `undefined` for the tree itself.
91004
+ * @returns {VisitorResult}
91005
+ * What to do next.
91006
+ * @template {UnistNode} [Visited=UnistNode]
91007
+ * Visited node type.
91008
+ * @template {UnistParent} [Ancestor=UnistParent]
91009
+ * Ancestor type.
90884
91010
  */
90885
91011
 
90886
91012
  /**
90887
- * @callback Visitor
90888
- * Handle a node (matching `test`, if given).
90889
- *
90890
- * Visitors are free to transform `node`.
90891
- * They can also transform `parent`.
90892
- *
90893
- * Replacing `node` itself, if `SKIP` is not returned, still causes its
90894
- * descendants to be walked (which is a bug).
90895
- *
90896
- * When adding or removing previous siblings of `node` (or next siblings, in
90897
- * case of reverse), the `Visitor` should return a new `Index` to specify the
90898
- * sibling to traverse after `node` is traversed.
90899
- * Adding or removing next siblings of `node` (or previous siblings, in case
90900
- * of reverse) is handled as expected without needing to return a new `Index`.
91013
+ * @callback VisitorExit
91014
+ * Handle a node (matching `test`, if given) after its children.
90901
91015
  *
90902
- * Removing the children property of `parent` still results in them being
90903
- * traversed.
91016
+ * Like `VisitorExit` in `unist-util-visit-parents`,
91017
+ * but with `index` and `parent` instead of `parents`.
90904
91018
  * @param {Visited} node
90905
91019
  * Found node.
90906
91020
  * @param {Visited extends UnistNode ? number | undefined : never} index
90907
- * Index of `node` in `parent`.
91021
+ * Index of `node` in `parent`,
91022
+ * or `undefined` for the tree itself.
90908
91023
  * @param {Ancestor extends UnistParent ? Ancestor | undefined : never} parent
90909
- * Parent of `node`.
90910
- * @returns {VisitorResult}
91024
+ * Parent of `node`,
91025
+ * or `undefined` for the tree itself.
91026
+ * @returns {VisitorResultExit}
90911
91027
  * What to do next.
90912
- *
90913
- * An `Index` is treated as a tuple of `[CONTINUE, Index]`.
90914
- * An `Action` is treated as a tuple of `[Action]`.
90915
- *
90916
- * Passing a tuple back only makes sense if the `Action` is `SKIP`.
90917
- * When the `Action` is `EXIT`, that action can be returned.
90918
- * When the `Action` is `CONTINUE`, `Index` can be returned.
90919
91028
  * @template {UnistNode} [Visited=UnistNode]
90920
91029
  * Visited node type.
90921
91030
  * @template {UnistParent} [Ancestor=UnistParent]
90922
91031
  * Ancestor type.
90923
91032
  */
90924
91033
 
91034
+ /**
91035
+ * @template {UnistNode} [Visited=UnistNode]
91036
+ * Visited node type.
91037
+ * @template {UnistParent} [Ancestor=UnistParent]
91038
+ * Ancestor type.
91039
+ * @typedef Visitors
91040
+ * Handle nodes when entering and exiting them.
91041
+ *
91042
+ * Like `Visitors` in `unist-util-visit-parents`.
91043
+ * @property {Visitor<Visited, Ancestor> | null | undefined} [enter]
91044
+ * Handle a node before its children (optional).
91045
+ * @property {VisitorExit<Visited, Ancestor>} exit
91046
+ * Handle a node after its children.
91047
+ */
91048
+
90925
91049
  /**
90926
91050
  * @typedef {Visitor<Visited, Parent<Ancestor, Visited>>} BuildVisitorFromMatch
90927
91051
  * Build a typed `Visitor` function from a node and all possible parents.
@@ -90965,6 +91089,25 @@ function toResult(value) {
90965
91089
  * Test type.
90966
91090
  */
90967
91091
 
91092
+ /**
91093
+ * @typedef {(
91094
+ * Visitors<
91095
+ * Matches<InclusiveDescendant<Tree>, Check>,
91096
+ * Parent<
91097
+ * Extract<InclusiveDescendant<Tree>, UnistParent>,
91098
+ * Matches<InclusiveDescendant<Tree>, Check>
91099
+ * >
91100
+ * >
91101
+ * )} BuildVisitors
91102
+ * Build typed `Visitors` from a tree and a test.
91103
+ *
91104
+ * It will infer which values are passed as `node` and which as `parent`.
91105
+ * @template {UnistNode} [Tree=UnistNode]
91106
+ * Node type.
91107
+ * @template {Test} [Check=Test]
91108
+ * Test type.
91109
+ */
91110
+
90968
91111
 
90969
91112
 
90970
91113
 
@@ -90973,10 +91116,13 @@ function toResult(value) {
90973
91116
  * Visit nodes.
90974
91117
  *
90975
91118
  * This algorithm performs *depth-first* *tree traversal* in *preorder*
90976
- * (**NLR**) or if `reverse` is given, in *reverse preorder* (**NRL**).
91119
+ * (**NLR**) or if `reverse` is given,
91120
+ * in *reverse preorder* (**NRL**).
91121
+ * An `exit` visitor is called in *postorder* (**LRN**)
91122
+ * or if `reverse` is given, in *reverse postorder* (**RLN**).
90977
91123
  *
90978
- * You can choose for which nodes `visitor` is called by passing a `test`.
90979
- * For complex tests, you should test yourself in `visitor`, as it will be
91124
+ * You can choose which nodes are visited by passing a `test`.
91125
+ * For complex tests, you should test yourself in a visitor, as it will be
90980
91126
  * faster and will have improved type information.
90981
91127
  *
90982
91128
  * Walking the tree is an intensive task.
@@ -90985,29 +91131,48 @@ function toResult(value) {
90985
91131
  * to check if a node matches, and then perform different operations.
90986
91132
  *
90987
91133
  * You can change the tree.
90988
- * See `Visitor` for more info.
91134
+ * Changes inside a node made when entering it are walked,
91135
+ * changes made when exiting it are not.
91136
+ * See `Visitor` and `VisitorExit` for more info.
90989
91137
  *
90990
91138
  * @overload
90991
91139
  * @param {Tree} tree
91140
+ * Tree to traverse.
90992
91141
  * @param {Check} check
90993
- * @param {BuildVisitor<Tree, Check>} visitor
91142
+ * `unist-util-is`-compatible test.
91143
+ * @param {BuildVisitor<Tree, Check> | BuildVisitors<Tree, Check>} visitors
91144
+ * Handle each node when entering it,
91145
+ * or `{enter, exit}` to also handle it when exiting it.
90994
91146
  * @param {boolean | null | undefined} [reverse]
91147
+ * Walk children from last to first;
91148
+ * for `enter`, reverse preorder (NRL) instead of preorder (NLR);
91149
+ * for `exit`, reverse postorder (RLN) instead of postorder (LRN).
90995
91150
  * @returns {undefined}
91151
+ * Nothing.
90996
91152
  *
90997
91153
  * @overload
90998
91154
  * @param {Tree} tree
90999
- * @param {BuildVisitor<Tree>} visitor
91155
+ * Tree to traverse.
91156
+ * @param {BuildVisitor<Tree> | BuildVisitors<Tree>} visitors
91157
+ * Handle each node when entering it,
91158
+ * or `{enter, exit}` to also handle it when exiting it.
91000
91159
  * @param {boolean | null | undefined} [reverse]
91160
+ * Walk children from last to first;
91161
+ * for `enter`, reverse preorder (NRL) instead of preorder (NLR);
91162
+ * for `exit`, reverse postorder (RLN) instead of postorder (LRN).
91001
91163
  * @returns {undefined}
91164
+ * Nothing.
91002
91165
  *
91003
91166
  * @param {UnistNode} tree
91004
91167
  * Tree to traverse.
91005
- * @param {Visitor | Test} testOrVisitor
91006
- * `unist-util-is`-compatible test (optional, omit to pass a visitor).
91007
- * @param {Visitor | boolean | null | undefined} [visitorOrReverse]
91008
- * Handle each node (when test is omitted, pass `reverse`).
91009
- * @param {boolean | null | undefined} [maybeReverse=false]
91010
- * Traverse in reverse preorder (NRL) instead of the default preorder (NLR).
91168
+ * @param {Visitor | Visitors | Test} testOrEnterOrVisitors
91169
+ * `unist-util-is`-compatible test, `enter`, or `visitors`.
91170
+ * @param {Visitor | Visitors | boolean | null | undefined} [enterOrVisitorsOrReverse]
91171
+ * `enter`, `visitors`, or `reverse` after a test.
91172
+ * @param {boolean | null | undefined} [maybeReverse]
91173
+ * Walk children from last to first;
91174
+ * for `enter`, reverse preorder (NRL) instead of preorder (NLR);
91175
+ * for `exit`, reverse postorder (RLN) instead of postorder (LRN).
91011
91176
  * @returns {undefined}
91012
91177
  * Nothing.
91013
91178
  *
@@ -91016,39 +91181,90 @@ function toResult(value) {
91016
91181
  * @template {Test} Check
91017
91182
  * `unist-util-is`-compatible test.
91018
91183
  */
91019
- function lib_visit(tree, testOrVisitor, visitorOrReverse, maybeReverse) {
91184
+ function lib_visit(
91185
+ tree,
91186
+ testOrEnterOrVisitors,
91187
+ enterOrVisitorsOrReverse,
91188
+ maybeReverse
91189
+ ) {
91190
+ /** @type {Test} */
91191
+ let check
91192
+ /** @type {Visitor | Visitors} */
91193
+ let visitors
91020
91194
  /** @type {boolean | null | undefined} */
91021
91195
  let reverse
91022
- /** @type {Test} */
91023
- let test
91024
- /** @type {Visitor} */
91025
- let visitor
91026
91196
 
91197
+ // Third parameter is an enter visitor or a visitors object, so expect a `test` too.
91027
91198
  if (
91028
- typeof testOrVisitor === 'function' &&
91029
- typeof visitorOrReverse !== 'function'
91199
+ typeof enterOrVisitorsOrReverse === 'function' ||
91200
+ (enterOrVisitorsOrReverse && typeof enterOrVisitorsOrReverse === 'object')
91030
91201
  ) {
91031
- test = undefined
91032
- visitor = testOrVisitor
91033
- reverse = visitorOrReverse
91034
- } else {
91035
- // @ts-expect-error: assume the overload with test was given.
91036
- test = testOrVisitor
91037
- // @ts-expect-error: assume the overload with test was given.
91038
- visitor = visitorOrReverse
91202
+ check = /** @type {Test} */ (testOrEnterOrVisitors)
91203
+ visitors = enterOrVisitorsOrReverse
91039
91204
  reverse = maybeReverse
91040
91205
  }
91206
+ // Assume no test.
91207
+ else {
91208
+ visitors = /** @type {Visitor | Visitors} */ (testOrEnterOrVisitors)
91209
+ reverse = enterOrVisitorsOrReverse
91210
+ }
91211
+
91212
+ if (typeof visitors === 'function') {
91213
+ visitParents(tree, check, lib_wrap(visitors), reverse)
91214
+ } else {
91215
+ visitParents(tree, check, wrapVisitors(visitors), reverse)
91216
+ }
91217
+ }
91218
+
91219
+ /**
91220
+ * Turn `visit` visitors into `visitParents` visitors.
91221
+ *
91222
+ * @param {Visitors} visitors
91223
+ * Visitors for `visit`.
91224
+ * @returns {ParentsVisitors}
91225
+ * Visitors for `visitParents`.
91226
+ */
91227
+ function wrapVisitors(visitors) {
91228
+ // Pass anything else straight to `visitParents` to get its errors.
91229
+ if (!visitors || typeof visitors !== 'object') return visitors
91230
+
91231
+ return {
91232
+ enter:
91233
+ typeof visitors.enter === 'function'
91234
+ ? lib_wrap(visitors.enter)
91235
+ : visitors.enter,
91236
+ exit:
91237
+ typeof visitors.exit === 'function' ? lib_wrap(visitors.exit) : visitors.exit
91238
+ }
91239
+ }
91041
91240
 
91042
- visitParents(tree, test, overload, reverse)
91241
+ /**
91242
+ * Turn a `visit` visitor into a `visitParents` one.
91243
+ *
91244
+ * @template {VisitorResult} Result
91245
+ * Result type.
91246
+ * @param {(node: UnistNode, index: number | undefined, parent: UnistParent | undefined) => Result} visitor
91247
+ * Visitor for `visit`.
91248
+ * @returns {(node: UnistNode, parents: Array<UnistParent>, index: number | undefined) => Result}
91249
+ * Visitor for `visitParents`.
91250
+ */
91251
+ function lib_wrap(visitor) {
91252
+ return overload
91043
91253
 
91044
91254
  /**
91255
+ * Call `visitor` with `index` and `parent` instead of `parents`.
91256
+ *
91045
91257
  * @param {UnistNode} node
91258
+ * Visited node.
91046
91259
  * @param {Array<UnistParent>} parents
91260
+ * Ancestors of `node`.
91261
+ * @param {number | undefined} index
91262
+ * Index of `node` in its parent.
91263
+ * @returns {Result}
91264
+ * What to do next.
91047
91265
  */
91048
- function overload(node, parents) {
91049
- const parent = parents[parents.length - 1]
91050
- const index = parent ? parent.children.indexOf(node) : undefined
91051
- return visitor(node, index, parent)
91266
+ function overload(node, parents, index) {
91267
+ return visitor(node, index, parents[parents.length - 1])
91052
91268
  }
91053
91269
  }
91054
91270
 
@@ -94371,7 +94587,7 @@ function trough() {
94371
94587
 
94372
94588
  // Next or done.
94373
94589
  if (fn) {
94374
- lib_wrap(fn, next)(...output)
94590
+ trough_lib_wrap(fn, next)(...output)
94375
94591
  } else {
94376
94592
  callback(null, ...output)
94377
94593
  }
@@ -94423,7 +94639,7 @@ function trough() {
94423
94639
  * @returns {Run}
94424
94640
  * Wrapped middleware.
94425
94641
  */
94426
- function lib_wrap(middleware, callback) {
94642
+ function trough_lib_wrap(middleware, callback) {
94427
94643
  /** @type {boolean} */
94428
94644
  let called
94429
94645
 
@@ -99769,22 +99985,30 @@ module.exports = __rspack_createRequire_require("zlib");
99769
99985
  4800(module, __unused_rspack_exports, __webpack_require__) {
99770
99986
 
99771
99987
 
99772
- const { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, serializePathEncoding, normalizeQueryFragmentEncoding, encodeQuery, encodeFragment, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = __webpack_require__(5365)
99988
+ const { normalizeIPv6, removeDotSegments, removeDotSegmentsRelative, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, serializePathEncoding, normalizeQueryFragmentEncoding, encodeQuery, encodeFragment, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = __webpack_require__(5365)
99773
99989
  const { SCHEMES, getSchemeHandler } = __webpack_require__(3956)
99774
99990
 
99775
99991
  const VALID_SCHEME = /^[A-Za-z][A-Za-z0-9+.-]*$/u
99776
99992
  const MALFORMED_SCHEME_ERROR = 'URI scheme is malformed.'
99993
+ const MALFORMED_HOST_ERROR = 'URI host is malformed.'
99994
+ // ASCII characters outside the RFC 3986 reg-name set (unreserved, sub-delims
99995
+ // and "%" for pct-encoded): C0 controls, space, DEL, and "#/:<>?@[\]^`{|}.
99996
+ const FORBIDDEN_DOMAIN_HOST_CHARACTER = /[\0-\x20"#/:<>?@[\\\]^`{|}\x7F]/u
99777
99997
 
99778
99998
  /**
99999
+ * RFC 3986 section 3.1 does not allow percent-encoding in a scheme, so the
100000
+ * scheme is validated as-is and never decoded. Decoding would let inert input
100001
+ * such as `%6Aavascript:` become a live `javascript:` scheme.
100002
+ *
99779
100003
  * @param {string} scheme
99780
100004
  * @returns {string}
99781
100005
  */
99782
- function decodeValidScheme (scheme) {
99783
- const decodedScheme = unescape(String(scheme))
99784
- if (!VALID_SCHEME.test(decodedScheme)) {
100006
+ function validateScheme (scheme) {
100007
+ const stringScheme = String(scheme)
100008
+ if (!VALID_SCHEME.test(stringScheme)) {
99785
100009
  throw new TypeError(MALFORMED_SCHEME_ERROR)
99786
100010
  }
99787
- return decodedScheme
100011
+ return stringScheme
99788
100012
  }
99789
100013
 
99790
100014
  /**
@@ -99845,6 +100069,12 @@ function resolve (baseURI, relativeURI, options) {
99845
100069
  const resolvedHost = resolved.host
99846
100070
  const resolvedHostIsIP = resolvedHost !== undefined && resolvedHost !== '' &&
99847
100071
  (isIPv4(resolvedHost) || normalizeIPv6(resolvedHost).isIPV6)
100072
+ // Inputs are parsed scheme-neutrally, so delimiters and controls in a domain
100073
+ // host are only detected here, once the final scheme is known. They always
100074
+ // fail closed, including in percent-encoded hosts.
100075
+ if (hasForbiddenDomainHost(resolved, options || {}, resolvedSchemeHandler, resolvedHostIsIP)) {
100076
+ throw new Error(MALFORMED_HOST_ERROR)
100077
+ }
99848
100078
  canonicalizeHost(resolved, options || {}, resolvedSchemeHandler, resolvedHostIsIP)
99849
100079
  // Percent escapes in an ASCII reg-name are encoded data. The WHATWG hostname
99850
100080
  // parser can reject them even though fast-uri preserves them safely as RFC
@@ -99902,14 +100132,17 @@ function resolveComponent (base, relative, options, skipNormalization) {
99902
100132
  if (relative.path[0] === '/') {
99903
100133
  target.path = removeDotSegments(relative.path)
99904
100134
  } else {
99905
- if ((base.userinfo !== undefined || base.host !== undefined || base.port !== undefined) && !base.path) {
100135
+ const baseHasAuthority = base.userinfo !== undefined || base.host !== undefined || base.port !== undefined
100136
+ if (baseHasAuthority && !base.path) {
99906
100137
  target.path = '/' + relative.path
99907
100138
  } else if (!base.path) {
99908
100139
  target.path = relative.path
99909
100140
  } else {
99910
100141
  target.path = base.path.slice(0, base.path.lastIndexOf('/') + 1) + relative.path
99911
100142
  }
99912
- target.path = removeDotSegments(target.path)
100143
+ target.path = base.scheme === undefined && !baseHasAuthority && target.path[0] !== '/'
100144
+ ? removeDotSegmentsRelative(target.path)
100145
+ : removeDotSegments(target.path)
99913
100146
  }
99914
100147
  target.query = relative.query
99915
100148
  }
@@ -99965,7 +100198,7 @@ function serialize (cmpts, opts) {
99965
100198
  const uriTokens = []
99966
100199
 
99967
100200
  if (component.scheme) {
99968
- component.scheme = decodeValidScheme(component.scheme)
100201
+ component.scheme = validateScheme(component.scheme)
99969
100202
  }
99970
100203
 
99971
100204
  // find scheme handler
@@ -99975,7 +100208,11 @@ function serialize (cmpts, opts) {
99975
100208
  if (schemeHandler && schemeHandler.serialize) schemeHandler.serialize(component, options)
99976
100209
 
99977
100210
  const hasAuthority = component.userinfo !== undefined || component.host !== undefined || component.port !== undefined
99978
- const pathNoScheme = !options.skipEscape && component.scheme === undefined && !hasAuthority
100211
+ // A reference with no emitted scheme is path-noscheme: a bare ':' in its
100212
+ // first path segment would reparse as a scheme (RFC 3986 3.3/4.2). Enforced
100213
+ // under skipEscape too (resolve()), so the reapply below gates on this flag.
100214
+ const schemelessReference = (component.scheme === undefined || options.reference === 'suffix') && !hasAuthority
100215
+ const pathNoScheme = !options.skipEscape && schemelessReference
99979
100216
 
99980
100217
  if (component.path !== undefined) {
99981
100218
  if (!options.skipEscape) {
@@ -99987,7 +100224,7 @@ function serialize (cmpts, opts) {
99987
100224
 
99988
100225
  if (options.reference !== 'suffix' && component.scheme) {
99989
100226
  // Scheme handlers may replace the scheme during serialization.
99990
- component.scheme = decodeValidScheme(component.scheme)
100227
+ component.scheme = validateScheme(component.scheme)
99991
100228
  uriTokens.push(component.scheme, ':')
99992
100229
  }
99993
100230
 
@@ -100007,13 +100244,18 @@ function serialize (cmpts, opts) {
100007
100244
  let s = component.path
100008
100245
 
100009
100246
  if (!options.absolutePath && (!schemeHandler || !schemeHandler.absolutePath)) {
100010
- s = removeDotSegments(s)
100247
+ // A relative-path reference keeps its unresolvable leading ".." segments
100248
+ // and must never become root-relative (RFC 3986 section 5.2.4 applies to
100249
+ // merged target paths, not to the reference itself).
100250
+ s = schemelessReference && s[0] !== '/'
100251
+ ? removeDotSegmentsRelative(s)
100252
+ : removeDotSegments(s)
100011
100253
  }
100012
100254
 
100013
100255
  // Dot-segment removal can expose a colon that was not originally in the
100014
100256
  // first segment (for example, "./a:b"). Reapply path-noscheme encoding so
100015
100257
  // the serialized relative reference cannot be reparsed as a URI scheme.
100016
- if (pathNoScheme) {
100258
+ if (schemelessReference) {
100017
100259
  s = serializePathEncoding(s, true)
100018
100260
  }
100019
100261
 
@@ -100128,6 +100370,11 @@ function hasMalformedComponentPercentEncoding (matches) {
100128
100370
  * @returns {boolean} whether host conversion failed
100129
100371
  */
100130
100372
  function canonicalizeHost (parsed, options, schemeHandler, isIP) {
100373
+ if (hasForbiddenDomainHost(parsed, options, schemeHandler, isIP)) {
100374
+ parsed.error = parsed.error || MALFORMED_HOST_ERROR
100375
+ return true
100376
+ }
100377
+
100131
100378
  if (
100132
100379
  !options.unicodeSupport &&
100133
100380
  (!schemeHandler || !schemeHandler.unicodeSupport) &&
@@ -100137,16 +100384,62 @@ function canonicalizeHost (parsed, options, schemeHandler, isIP) {
100137
100384
  isIP === false &&
100138
100385
  nonSimpleDomain(parsed.host)
100139
100386
  ) {
100387
+ let url
100140
100388
  try {
100141
- parsed.host = new URL('http://' + parsed.host).hostname
100389
+ url = new URL('http://' + parsed.host)
100142
100390
  } catch (e) {
100143
100391
  parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e
100144
100392
  return true
100145
100393
  }
100394
+ // The WHATWG parser must have read the whole input as a host. Anything
100395
+ // else means it found a delimiter fast-uri did not, so its hostname would
100396
+ // describe a different authority.
100397
+ if (!isHostOnlyURL(url)) {
100398
+ parsed.error = parsed.error || MALFORMED_HOST_ERROR
100399
+ return true
100400
+ }
100401
+ parsed.host = url.hostname
100146
100402
  }
100147
100403
  return false
100148
100404
  }
100149
100405
 
100406
+ /**
100407
+ * Whether a domain host contains an ASCII character that RFC 3986 does not
100408
+ * allow in a reg-name (unreserved, sub-delims, or pct-encoded). Such a host is
100409
+ * rejected instead of being handed to the WHATWG URL parser, which would treat
100410
+ * "@" as a userinfo delimiter (silently dropping the data before it) and strip
100411
+ * TAB, LF, and CR. Non-ASCII characters remain allowed for IDNs.
100412
+ *
100413
+ * @param {import('./types/index').URIComponent} parsed
100414
+ * @param {import('./types/index').Options} options
100415
+ * @param {{ domainHost?: boolean }|undefined} schemeHandler
100416
+ * @param {boolean} isIP
100417
+ * @returns {boolean}
100418
+ */
100419
+ function hasForbiddenDomainHost (parsed, options, schemeHandler, isIP) {
100420
+ return Boolean(
100421
+ parsed.host &&
100422
+ isIP === false &&
100423
+ !isIPLiteral(parsed.host) &&
100424
+ (options.domainHost || (schemeHandler && schemeHandler.domainHost)) &&
100425
+ FORBIDDEN_DOMAIN_HOST_CHARACTER.test(parsed.host)
100426
+ )
100427
+ }
100428
+
100429
+ /**
100430
+ * @param {URL} url
100431
+ * @returns {boolean}
100432
+ */
100433
+ function isHostOnlyURL (url) {
100434
+ return url.username === '' &&
100435
+ url.password === '' &&
100436
+ url.port === '' &&
100437
+ url.pathname === '/' &&
100438
+ url.search === '' &&
100439
+ url.hash === '' &&
100440
+ url.hostname !== ''
100441
+ }
100442
+
100150
100443
  /**
100151
100444
  * @param {string} uri
100152
100445
  * @param {import('./types/index').Options} [opts]
@@ -100229,9 +100522,8 @@ function parseWithStatus (uri, opts) {
100229
100522
  parsed.fragment = matches[8]
100230
100523
 
100231
100524
  if (parsed.scheme !== undefined) {
100232
- const decodedScheme = unescape(parsed.scheme)
100233
- if (VALID_SCHEME.test(decodedScheme)) {
100234
- parsed.scheme = decodedScheme.toLowerCase()
100525
+ if (VALID_SCHEME.test(parsed.scheme)) {
100526
+ parsed.scheme = parsed.scheme.toLowerCase()
100235
100527
  } else {
100236
100528
  parsed.error = parsed.error || MALFORMED_SCHEME_ERROR
100237
100529
  malformedScheme = true
@@ -100265,7 +100557,7 @@ function parseWithStatus (uri, opts) {
100265
100557
  parsed.host = isIP ? ipv6result.host : ipv6result.host.toLowerCase()
100266
100558
 
100267
100559
  if (malformedIPLiteral) {
100268
- parsed.error = parsed.error || 'URI host is malformed.'
100560
+ parsed.error = parsed.error || MALFORMED_HOST_ERROR
100269
100561
  malformedAuthorityOrPort = true
100270
100562
  }
100271
100563
  } else {
@@ -100302,7 +100594,11 @@ function parseWithStatus (uri, opts) {
100302
100594
  // pass only restores uppercase hex in escapes that remain encoded.
100303
100595
  host = normalizePercentEncoding(host.toLowerCase())
100304
100596
  }
100305
- parsed.host = reescapeHostDelimiters(host, isIP)
100597
+ // Resolution parses both inputs with the internal `null` scheme before
100598
+ // the effective scheme is known. Keep raw host delimiters for that step
100599
+ // so resolve() can reject them for domain-host schemes; the resolved
100600
+ // authority is encoded when it is serialized.
100601
+ parsed.host = isIP || options.scheme !== 'null' ? reescapeHostDelimiters(host, isIP) : host
100306
100602
  }
100307
100603
 
100308
100604
  if (!schemeHandler || (schemeHandler && !schemeHandler.skipNormalize)) {
@@ -101025,6 +101321,57 @@ function removeDotSegments (path) {
101025
101321
  return output.join('')
101026
101322
  }
101027
101323
 
101324
+ /**
101325
+ * Removes dot segments from the path of a relative reference (a path that does
101326
+ * not start with "/") without changing what it resolves to against any base.
101327
+ * Unlike `removeDotSegments`, leading ".." segments that cannot be collapsed
101328
+ * are kept, the result never becomes root-relative, and a result that would be
101329
+ * empty or start with an empty segment is prefixed with "." (an empty path
101330
+ * means "same document" and a leading "//" would introduce an authority).
101331
+ *
101332
+ * @param {string} path
101333
+ * @returns {string}
101334
+ */
101335
+ function removeDotSegmentsRelative (path) {
101336
+ if (path === '' || path[0] === '/') {
101337
+ return removeDotSegments(path)
101338
+ }
101339
+
101340
+ const segments = path.split('/')
101341
+ const last = segments.length - 1
101342
+ /** @type {string[]} */
101343
+ const output = []
101344
+ let trailingDirectory = false
101345
+
101346
+ for (let i = 0; i <= last; i++) {
101347
+ const segment = segments[i]
101348
+ if (segment === '.' || segment === '..') {
101349
+ if (segment === '..') {
101350
+ if (output.length !== 0 && output[output.length - 1] !== '..') {
101351
+ output.pop()
101352
+ } else {
101353
+ output.push('..')
101354
+ }
101355
+ }
101356
+ trailingDirectory = i === last
101357
+ } else {
101358
+ output.push(segment)
101359
+ }
101360
+ }
101361
+
101362
+ if (trailingDirectory && output[output.length - 1] !== '..') {
101363
+ output.push('')
101364
+ }
101365
+ if (output.length === 0 || output[0] === '' || output[0].includes(':')) {
101366
+ // An empty path, a leading empty segment ("//"), or a first segment
101367
+ // containing ":" (which would be mistaken for a scheme, RFC 3986 section
101368
+ // 4.2) must stay behind a "." segment so the reference keeps its meaning.
101369
+ output.unshift('.')
101370
+ }
101371
+
101372
+ return output.join('/')
101373
+ }
101374
+
101028
101375
  /**
101029
101376
  * Re-escape RFC 3986 gen-delims that must not appear literally in the host.
101030
101377
  * After the URI regex parses, these characters cannot be literal in the host
@@ -101420,6 +101767,7 @@ module.exports = {
101420
101767
  encodeFragment,
101421
101768
  escapePreservingEscapes,
101422
101769
  removeDotSegments,
101770
+ removeDotSegmentsRelative,
101423
101771
  isIPv4,
101424
101772
  isUUID,
101425
101773
  normalizeIPv6,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lousy-agents/mcp",
3
- "version": "5.22.16",
3
+ "version": "5.22.18",
4
4
  "description": "MCP server for lousy-agents - provides AI coding assistant tools via the Model Context Protocol",
5
5
  "type": "module",
6
6
  "repository": {